Annotation of researchv9/cmd/emacs/emacs_main.c, revision 1.1.1.2

1.1       root        1: /* EMACS_MODES: c !fill */
                      2: 
                      3: /* Expand global variables here */
                      4: 
                      5: #define OWNER 1
                      6: 
                      7: #include <sys/types.h>
                      8: #include <sys/stat.h>
                      9: #include <signal.h>
                     10: #include <setjmp.h>
                     11: #include "emacs_io.h"
                     12: #include "emacs_gb.h"
                     13: #include "emacs_main.h"
                     14: 
                     15: #ifdef ux3
                     16: #include <fcntl.h>
                     17: #endif
                     18: 
                     19: /* screen editor for unix */
                     20: 
                     21: 
                     22: 
                     23: /*             Main Loop               */
                     24: 
                     25: /* interprets characters, setting arguments and meta.  When a
                     26:  * 'virtual character' is entered, it is executed via the do_it array */
                     27: 
                     28: char *cprompt[2] = {"M-","^X"};
                     29: 
                     30: 
                     31: /* VARARGS */
                     32: 
                     33: edit(edisp,echar,earg)
                     34: 
                     35: int edisp;                             /* disposition flag */
                     36: int echar;                             /* optional character for disp = 2*/
                     37: int earg;                              /* optional argument for disp = 3*/
                     38: {
                     39:        register int c;                 /* virtual character being interpreted */
                     40:        
                     41:        register int realc;             /* last real character read */
                     42:        int metf;
                     43:        int dochar;
                     44:        register int arg;
                     45:        int eresult;                    /* result of last command */
                     46:        
                     47: /* Keywords: user-interface argument-processing:40 macro-programming:30 */
                     48: /* Keywords: key-bindings:30 display-update:5 */
                     49:        
                     50: #ifdef pdp11
                     51: #define BUFMAX 077000                  /* Buffer file size at which to GC */
                     52: #else
                     53: #define BUFMAX 0777000                 /* Bigger for VAX, since not constrainted by address space */
                     54: #endif
                     55: 
                     56:        for (;;) {
                     57:                arg = 1;
                     58:                metf = 0;
                     59:                numarg = 0;
                     60:                if (BUFEND > BUFMAX) collect(); /* garbage collection */
                     61:                if (edisp == 2) {       /* execute command */
                     62:                        if ((echar < 0) || (echar > 0600)) echar = CTRLG;
                     63:                        c = echar;
                     64:                        arg = earg;
                     65:                        edisp = 0;              /* do one command */
                     66:                        goto dispose;
                     67:                }
                     68: 
                     69: re_get:
                     70:                if (infrn >= 0) {
                     71:                        
                     72:                        if (SAVEMD) {
                     73:                                if (NSCHAR++>SAVECHAR) {
                     74:                                        IGNORE(fsave(0));
                     75:                                        NSCHAR=0;
                     76:                                }
                     77:                        }
                     78:                        if (etrace == 0) disup();               /* update display */
                     79:                        if ((VERBOSE) && (MOREIN == 0) && ((numarg) || (metf))){
                     80:                                if (metf) {
                     81:                                        if (numarg) {
                     82:                                                if (numarg == 8) prompt1("%o %s: ",arg,cprompt[metf>>8]);
                     83:                                                else prompt1("%d %s: ",arg,cprompt[metf>>8]);
                     84:                                        } else {
                     85:                                                prompt1("%s: ",cprompt[metf>>8]);
                     86:                                        }
                     87:                                } else {
                     88:                                        if (numarg == 8) prompt1 ("%o: ", arg);
                     89:                                        else prompt1("%d: ", arg);
                     90:                                }
                     91:                                c = (getchar()) + metf;
                     92:                                unprompt();
                     93:                        } else c = (getchar()) + metf;
                     94: #ifdef CMON
                     95:                        if (infrn == 0) cmcnt[c]++;             /* count command statistics */
                     96: #endif
                     97:                        dochar = map_it[c];
                     98:                } else {
                     99: 
                    100: /* The following code for macros bypasses the normal getchar for speed! */
                    101:                        
                    102:                        c = metf + Mgetchar();
                    103: 
                    104: dispose:                               /* dispose of character command */
                    105:                        dochar = doit[c];
                    106:                        if (dochar == 0) { /* no default binding, check for macro */
                    107:                                dochar = map_it[c];
                    108:                                if (dochar < ISIZE) dochar = 0; /* Only for macros */
                    109:                        }
                    110:                }
                    111: 
                    112: 
                    113:                if (dochar >= ISIZE) {
                    114:                        eresult = xmac(dochar-ISIZE,arg,c);
                    115:                } else if (dochar >= NIFUNC) {
                    116:                        eresult = (*runit[dochar-NIFUNC]) (arg,c);
                    117:                } else {
                    118:                        metf = c & META;
                    119:                        realc = c & META-1; /* set up real character and meta flags; */
                    120:                        switch(dochar) {
                    121:                                        
                    122:                        case CMETA:
                    123:                                metf=META;
                    124:                                goto re_get;
                    125:                        case CCTLX:
                    126:                                metf = CTLX;
                    127:                                goto re_get;
                    128:                        case CEXIT:
                    129:                                return(arg);
                    130:                        case CLRES:
                    131:                                arg = eresult;
                    132:                                numarg = 10;
                    133:                                goto re_get;
                    134:                        case CCTLU:
                    135:                                arg *= 4;
                    136:                                if (numarg == 0) numarg = 1;
                    137:                                goto re_get;
                    138:                        case CMARG:
                    139:                                if ((arg >= 0) && (arg < NMVAR) && (marg != NULL)) {
                    140:                                        arg = marg[arg];
                    141:                                        numarg = 10;
                    142:                                }
                    143:                                goto re_get;
                    144:                        case CMNUS:
                    145:                                if ((numarg == 1) || (metf && (numarg == 0))) {
                    146:                                        arg = -1;
                    147:                                        metf = 0;
                    148:                                        numarg = -1;
                    149:                                        goto re_get;
                    150:                                }
                    151:                                eresult = insertc(arg,c);
                    152:                                break; /* other minus's insert */
                    153:                        case CNUMB:
                    154:                                if (metf || numarg) {
                    155:                                        metf = 0;
                    156:                                        if (numarg>1) {
                    157:                                                arg = arg*numarg+realc-'0';
                    158:                                                if (arg < 0) arg -= 2*(realc-'0');
                    159:                                        } else {
                    160:                                                arg = realc-'0';
                    161:                                                if (numarg < 0) {
                    162:                                                        arg = -arg;
                    163:                                                }
                    164:                                                numarg = (realc == '0') ? 8:10;
                    165:                                        }
                    166:                                        goto re_get;
                    167:                                }
                    168:                                eresult = insertc(arg,c);
                    169:                                break;          /* some numbers self insert */
                    170:                        case CBEEP: beep();
                    171:                        }
                    172: 
                    173:                }
                    174:                if (etrace) {
                    175:                        int tc;
                    176:                        
                    177:                        if (c & 0400) {
                    178:                                putout ("^X%c   %d      %d",c-0400,arg,eresult);
                    179:                        } else {
                    180:                                putout ("%c     %d      %d",c,arg,eresult);
                    181:                        }
                    182:                        mflush(stdout); /* Force output! */
                    183:                        read(0,&tc,1); /* pause */
                    184:                        switch(tc&0177) {
                    185:                        
                    186:                        case 'e':
                    187:                                etrace = 0;
                    188:                                recurse(1); /* Recursively edit */
                    189:                                etrace = 1;
                    190:                                break;
                    191:                        case '?':
                    192:                                {
                    193:                                        char hbuf[128];
                    194:                                        
                    195:                                        helpin(c,hbuf);
                    196:                                        putout(hbuf);
                    197:                                        break;
                    198:                                }
                    199: 
                    200:                        case CTRLG:
                    201:                        case CTRLZ:
                    202:                                return(eresult); /* Bomb out of here */
                    203:                        }
                    204:                }
                    205:                if (edisp == 0) return(eresult);
                    206:        }
                    207: }
                    208: 
                    209: trce()
                    210: {
                    211: /* Keywords: commands macro-programming */
                    212: 
                    213:        mtop();
                    214:        putout("Command Argument        Result");
                    215:        etrace = 1;
                    216:        edit(0);
                    217:        etrace = 0;
                    218: }
                    219: 
                    220: /* issrch - is character a search invocation */
                    221: 
                    222: /* returns 1 for ^S, -1 for ^R, and 0 for others */
                    223: 
                    224: issrch(chr)
                    225: int chr;
                    226: 
                    227: {
                    228: /* Keywords: searching key-bindings */
                    229:        
                    230:        if (map_it[chr] ==  27) return(1);
                    231:        if (map_it[chr] == 26) return(-1);
                    232:        return(0);
                    233: }
                    234: isquote(chr)
                    235: int chr;
                    236: {
                    237: /* Keywords: key-bindings quoting */
                    238:        if (map_it[chr] == 25) return(1);
                    239:        return(0);
                    240: }
                    241: 
                    242: /* xqt -- execute a command through argument 0. */
                    243: 
                    244: /* the character command designated by macro argument 0 is run with the  */
                    245: /* current argument */
                    246: 
                    247: xqt(arg)
                    248: 
                    249: int arg;
                    250: {
                    251: /* Keywords: commands macro-programming:40 */
                    252: 
                    253:        int res;
                    254:        if (marg == NULL) return(0);
                    255:        pushin(NULL);           /* if command needs input, from tty */
                    256:        res = edit(2,marg[0],arg);              /* run command */
                    257:        inpop();
                    258:        return(res);
                    259: }
                    260: /* ckmail -- check for user mail */
                    261: 
                    262: ckmail()
                    263: {
                    264: /* Keywords: user-interface:50 mail-processing unix-interface */
                    265:        
                    266:        extern int CKMAIL;
                    267: #ifndef PC
                    268:        register char *cp;
                    269:        struct stat statb;
                    270:        static time_t mailtime;
                    271: 
                    272: 
                    273:        if (cp = getenv("MAIL")) {
                    274:                if ((stat(cp,&statb)>=0) && (statb.st_size>30) ) {
                    275:                        if (statb.st_mtime != mailtime) {
                    276:                                newmail = -1;
                    277:                                mailtime = statb.st_mtime;
                    278:                        } else {
                    279:                                newmail = 1;
                    280:                        }
                    281:                } else {
                    282:                        if (newmail) disptime = 1; /* Force redisplay of mail/time line */
                    283:                        newmail = 0;
                    284:                }
                    285:        }
                    286: #endif
                    287:        mailcnt = CKMAIL;
                    288: }
                    289: 
                    290: 
                    291: /* dtime -- display the time on the screen */
                    292: 
                    293: long clock;
                    294: 
                    295: dtime(flag)
                    296: 
                    297: int flag;
                    298: {
                    299: /* Keywords: user-interface:50 time-processing unix-interface */
                    300:        
                    301: #ifndef PC
                    302: register char *tp;
                    303: 
                    304:        
                    305: 
                    306:        if (timemd) {
                    307:                time(&clock); /* get time */
                    308:                if ((clock-oclock > 60) || flag) {
                    309:                        tp = ctime(&clock); /* convert */
                    310:                        tp[16] = 0;     /* wipe out newline */
                    311:                        disptime = 1;
                    312:                }
                    313:        }
                    314: #endif PC
                    315: }
                    316: 
                    317: /* break interrupt handler */
                    318: 
                    319: bkfg()
                    320: {
                    321: /* Keywords: break-handling unix-interface user-interface:10 */
                    322:        
                    323:        signal(SIGINT,bkfg);
                    324: #ifdef bsd
                    325:        dclear();                       /* Berkeley flushes tty output on break */
                    326: #endif 
                    327:        brkflg++;                       /* just flag what happened */
                    328: }
                    329: 
                    330: 
                    331: 
                    332: /* init -- initialize editor data */
                    333: 
                    334: /* initializes EMACS, goes into raw mode, creates the buffer main, and
                    335:  * reads in the file specified by the argument to the emacs command */
                    336: 
                    337: 
                    338: init()
                    339: 
                    340: {
                    341:        register int i;
                    342:        
                    343: /* Keywords: unix-interface internal-initialization filenames:10 */
                    344:        
                    345:        procbuf = -1;                   /* Initialize global */
                    346:        uncook();
1.1.1.2 ! root      347: /*     for (i = 0; i < 16; i++) signal(i,eabort); /* trap various problems */
1.1       root      348: 
                    349: /* some signals cause attempt to save */
                    350: 
                    351:        signal (SIGTERM,crash);
                    352:        signal (SIGHUP,crash);
                    353:        signal (SIGINT,bkfg);
                    354:        signal (SIGPIPE,SIG_IGN);
                    355:        for (i = 0; i < 128; i++) casem[i] = i; /* search map */
                    356:        ioinit();
                    357:        curln = 1;
                    358:        column = 0;
                    359:        IGNORE(chgbuf("Main"));
                    360: 
                    361: /* The following must take place after I/O is initialized and the 
                    362:  *     terminal is in raw mode but before any initializations that
                    363:  *     use the emacs home directory */
                    364:        
                    365:        strcpy(em_dir,expenv(emd_source)); /* expand emacs home directory */
                    366: }
                    367: brkit()                                        /* break interrupt handler */
                    368: {
                    369:        int res;
                    370: /* Keywords: unix-interface break-handling user-interface:50 */
                    371:        
                    372:        brkflg=0;
                    373: bkagain:res = error(WARN,74);          /* BREAK!! */
                    374:        
                    375:        if (res > 0) return;
                    376:        
                    377:        if (res == 0) {
                    378:                                        /* recursive edit time */
                    379:                recurse(1);             /* Hope that this works out OK */
                    380:                goto bkagain;
                    381:        }
                    382:        
                    383:        marg=NULL;                      /* wipe out macro backtrace */
                    384:        myname = svname;                /* save name */
                    385:        longjmp(retjmp,1);              /* EXIT!!! */
                    386: }
                    387: 
                    388: main(argc, argv)
                    389: 
                    390: int argc;
                    391: char *argv [];
                    392: 
                    393: {
                    394:        char itbuf[128];
                    395: #ifdef DIRED
                    396:        extern int LNOMOD;
                    397:        extern int FILLMD;
                    398:        extern int OVERW;
                    399:        extern int NODEL;
                    400: #endif
                    401:        extern int fbkno, macptr;
                    402:        int line;
                    403:        register char *ap;
                    404:        char *cp;
                    405:        int tset;
                    406: 
                    407: #ifdef MONITOR
                    408: 
                    409: #define MONSIZ 5000
                    410:        short monbuf[MONSIZ];
                    411:        extern int etext;
                    412: 
                    413:        monitor(2,&etext,monbuf,MONSIZ,0); /* profile on */
                    414: #endif
                    415: 
                    416: /* Keywords: command-line-processing:90 user-interface:10 */
                    417: /* Keywords: internal-initialization terminal-initialization:30 */
                    418: /* Keywords: dired:20 */
                    419: 
                    420:                                        /* find our name */
                    421: 
                    422: #ifdef PC
                    423:        myname = "PC EMACS";
                    424: #else
                    425:        for (ap= myname = argv[0]; *ap; ap++) {
                    426:                if (*ap>0140) *ap = (*ap) - 040;
                    427:                if (*ap == '/') myname = ap+1; /* Seek to last '/' */
                    428:        }
                    429: #endif PC      
                    430:        svname=myname;                  /* save myname */
                    431:        
                    432:        NPTRS = 0;                      /* no memory */
                    433: 
                    434:        
                    435: /* special initialization for DIRED */
                    436: 
                    437: #ifdef DIRED
                    438: 
                    439: #define CTX(xchar) ((xchar)+0400)
                    440: 
                    441:        LNOMOD = 0;
                    442:        FILLMD = 0;
                    443:        OVERW = 1;
                    444:        NODEL = 1;
                    445:        
                    446:        doit['d'] = doit['D'] = 81;
                    447:        doit[CTRLD] = doit[CTRLK] = doit[RUBOUT] =80;
                    448:        doit['u'] = doit['U'] = 82;
                    449:        doit['e'] = doit['E'] = 83;
                    450:        
                    451: #endif
                    452:        mapch(0);                       /* initialize key bindings */
                    453:        fbkno = macptr = 0;                     /* no macros */
                    454: #ifndef PC
                    455:        myuid = getuid();               /* get my user ID */
                    456:        mypid = getpid();
                    457:        mymask = umask(0);
                    458:        umask(mymask&077);              /* Make sure I can read/write my own files */
                    459:        
                    460: #endif PC
                    461: #ifdef CRYPTO
                    462: 
                    463: /* Set up for encrypting the buffer */
                    464: 
                    465:        time (&bufkey);
                    466:        tset = myuid & 077777;          /* Make sure it's +! */
                    467:        while (tset) {
                    468:                bufkey = bufkey * bufkey + tset;
                    469:                tset = tset >> 1;
                    470:        }
                    471: #endif 
                    472:        init();                         /* initialize */
                    473: #ifdef PC
                    474:        sttype(NULL);
                    475:        tset = 1;
                    476: #else
                    477:        if ((cp=getenv("TERM"))!= NULL) {
                    478:                sttype(cp);             /* set up for terminal */
                    479:                tset = 1;
                    480:        } else {
                    481:                sttype(NULL);           /* default terminal type */
                    482:                tset = 0;
                    483:        }
                    484: #endif
                    485:        nsharg = argc-1;
                    486:        sharg = argv+1;                 /* pointer to first argument */
                    487:                
                    488:        if (setjmp(retjmp)) goto main_loop;
                    489:        
                    490:        if (nsharg && streq(*sharg,".i")) {
                    491:                **sharg = '-';          /* user's init only */
                    492:        } else {
                    493: #ifdef PC
                    494:                if (infile("c:emacs.ini")<=0) {
                    495:                        infile("emacs.ini");
                    496:                }
                    497: #else
                    498: #ifdef DIRED
                    499:                if (infile("$HOME/.dired_init")<=0) { /* run user's init file */
                    500: #else
                    501:                if (infile("$HOME/.emacs_init")<=0) { /* run user's init file */
                    502:                        seprintf(itbuf,"%s/.emacs_init",em_dir);
                    503:                        infile (itbuf); /* run default init file */
                    504: #endif
                    505:                }
                    506: #endif
                    507:        }
                    508:        if (nsharg && streq(*sharg,"-i")) {
                    509:                sharg+=2;
                    510:                nsharg-=2;
                    511:                infile(sharg[-1]);
                    512:        }
                    513:        if (tset == 0) ttype(); 
                    514:        line = 0;
                    515: #ifdef DIRED
                    516:        if ((nsharg) && (**sharg == '-')) {
                    517:                strcpy(dired_args+3,((*sharg)+1));
                    518:                nsharg;
                    519:                sharg++;
                    520:        }
                    521: #else 
                    522:        if (nsharg&& (**sharg == '+')) {
                    523:                cp = nscan(((*sharg)+1),&line);
                    524:                sharg++;
                    525:                nsharg--;
                    526:        }
                    527: #ifdef CRYPTO
                    528:        if (nsharg && (streq(*sharg,"-x"))) {
                    529:                sharg++;
                    530:                nsharg--;
                    531:                setkey(1,1);            /* Ask user for key */
                    532:        }
                    533: #endif
                    534: #endif
                    535:        if (nsharg) {
                    536:                readin(*sharg,1);
                    537:                nsharg--;
                    538:                sharg++;
                    539: #ifdef DIRED
                    540:        } else readin (".",1);
                    541: #else
                    542:        }
                    543:        if (line) absgoto(line);
                    544: #endif
                    545: main_loop:setjmp(retjmp);                      /* establish return point */
                    546: #ifdef PC
                    547:        prompt(MODLN+1,"Proprietary and a Trade Secret of Bell Laboratories, No Unauthorized Copying");
                    548: #endif
                    549:        while (1) {
                    550:                edit(1);
                    551:                gquit();                        /* quit if done */
                    552:        }
                    553: }
                    554: 
                    555: /* mapch -- map a character */
                    556: 
                    557: mapch(arg)
                    558: int arg;
                    559: {
                    560:        register int fromc;
                    561:        register int toc;
                    562:        register char *fromp;
                    563:        char *fromac;
                    564:        extern char *maclook();
                    565: 
                    566:        if (arg == 0) {
                    567:                for (toc = 0; toc < NCHARS; toc++) map_it[toc] = doit[toc];
                    568:                return;
                    569:        }
                    570: /* Keywords: commands key-bindings user-interface */
                    571:        
                    572:        toc = gechar("Map character");
                    573:        switch(arg) {
                    574:                
                    575:        case 1:
                    576:        
                    577:                fromc = gechar("To command");
                    578:                mapkey(toc,fromc);
                    579:                break;
                    580:        case 2:
                    581:        case 4:
                    582:                fromp = getname ("To macro: ");
                    583:                if (fromac = maclook(fromp)) {
                    584:                        map_it[toc] = (fromac-&bbuf[0][0]+ISIZE);
                    585:                } else error(WARN,51,fromp); /* Macro not found */
                    586:                break;
                    587:        }
                    588: }
                    589: 
                    590: mapkey(toc,fromc)
                    591: int toc;
                    592: int fromc;
                    593: 
                    594: /* Keywords: key_bindings user_interface:10  */
                    595: {
                    596:        map_it[toc] = doit[fromc];
                    597: }
                    598: 
                    599: #ifdef ASSKEY
                    600: asskey(string,key)
                    601: char *string;
                    602: int key;
                    603: 
                    604: 
                    605: /* Keywords: key_bindings:50 terminal_initialization terminal_parameters */
                    606: 
                    607: {
                    608:        int tokey;
                    609:        
                    610:        if (string == NULL) return;
                    611:        tokey = *string++;
                    612:        if (tokey == ESC) {
                    613:                tokey = 0200 + *string++;
                    614:        }
                    615:        if (tokey == CTRLX) {
                    616:                tokey == 0400 + *string++;
                    617:        }
                    618:        if (*string) return;
                    619:        
                    620:        if (map_it[tokey]) return;
                    621:        mapkey(tokey,key);
                    622: }
                    623: #endif
                    624: 
                    625: #ifdef PC
                    626: mapk(arg)
                    627: int arg;
                    628: {
                    629:        char *cp;
                    630:        extern char *rrxtab;
                    631:        int c;
                    632: /* Keywords: commands key-bindings  PC-only */
                    633:        cp = &rrxtab[2*arg];
                    634:        c = gechar("command");
                    635:        if (c & 0400) {
                    636:                *cp++ = '';
                    637:                c-=0400;
                    638:        }
                    639:        if (c & META) {
                    640:                *cp++ = 033;
                    641:                c -= META;
                    642:        }
                    643:        *cp = c;
                    644: }
                    645: #endif         
                    646: /* help prompts for a character, and displays the function of that
                    647: character.  * displays all non self inserting and defined character
                    648: commands, ^X prompts for another character to describe a ^X sequence */
                    649: 
                    650: help()         /* help function */
                    651: 
                    652: {
                    653:        register int c;
                    654:        register int x;
                    655:        char hbuf[HELSIZE];
                    656: 
                    657: /* Keywords: help-messages commands user-interface character-display:10 */
                    658:        
                    659:        prompt1("M-?: ");
                    660:        c = getchar();
                    661:        if (c == ESC) c = (getchar()) + META;
                    662:        mtop();
                    663:        if (c == '*') {
                    664:                for (c = 0; c < 0377; c++) {
                    665:                        if ((x=map_it[c]) && (x != HINSERT)) {
                    666:                                helpin(c,hbuf);
                    667:                                if(putout("The character '%c'  %s",c, hbuf)) return;
                    668:                        }
                    669:                }
                    670:        } else {
                    671:                helpin(c,hbuf);
                    672:                putout("The character '%c'  %s",c, hbuf);
                    673:        }
                    674:        putout (endput);
                    675:        if (c != 030) {
                    676:                IGNORE(contin());
                    677:                if (helfile>0) close(helfile);
                    678:                helfile = 0;
                    679:                return;
                    680:        }
                    681:        c = getchar();
                    682:        if (c != '*') {
                    683:                helpin(c+CTLX,hbuf);
                    684:                putout ("The sequence '^X%c' %s", c, hbuf);
                    685:        } else for (c =0; c<128; c++) {
                    686:                if (map_it[c+CTLX]) {
                    687:                        helpin(c+CTLX,hbuf);
                    688:                        if(putout ("The sequence '^X%c' %s", c, hbuf)) return;
                    689:                }
                    690:        }
                    691:        putout (endput);
                    692:        IGNORE(contin());
                    693:        if (helfile>0) {
                    694:                close(helfile);
                    695:                helfile = 0;
                    696:        }
                    697:        return;
                    698: }
                    699: 
                    700: /* wall chart -- produce a wall chart of all emacs characters */
                    701: 
                    702: 
                    703: wallc()
                    704: {
                    705:        register int i;
                    706:        register int x;
                    707:        int oldln,oldcol;
                    708:        int oldtab;
                    709:        char hbuf[HELSIZE];
                    710:        
                    711: /* Keywords: help-messages commands insertion character-display:10 */
                    712: 
                    713:        
                    714:        oldtab = TABMD; 
                    715:        oldln = curln;
                    716:        oldcol = column;
                    717:        TABMD = 0;                      /* flush C mode */
                    718:        putin(myname);
                    719:        putin(" version ");
                    720:        putin(version);
                    721:        putin(" Date: ");
                    722:        putin(hdate);
                    723:        nl(2);
                    724:        for (i = 0; i < NCHARS; i++) {
                    725: 
                    726:                if (i == CTLX) {
                    727:                        nl(1);
                    728:                        putin("Control-X commands:");
                    729:                        nl(2);
                    730:                }
                    731:                if ((x=map_it[i])&& (x != 9)){
                    732: 
                    733:                        if (i&CTLX) {
                    734:                                cput(CTRLX);
                    735:                                cput(i-CTLX);
                    736:                        } else {
                    737:                                cput(i);
                    738:                        }
                    739:                        put(':');
                    740:                        put('   ');
                    741:                        helpin(i,hbuf);
                    742:                        putin(hbuf);
                    743:                        nl(1);
                    744:                }
                    745:        }
                    746:        if (helfile>0) {
                    747:                close(helfile);
                    748:                helfile = 0;
                    749:        }
                    750:        unins(oldln,oldcol);
                    751:        TABMD = oldtab;
                    752: }
                    753: 
                    754: 
                    755: /* print an error message and wait for response.  ^Z exits emacs
                    756:  * immediately, ^G tries  to stop the current command by returning 1
                    757:  * from error, any other character just continues (returns 0)*/
                    758: 
                    759: /*VARARGS1*/
                    760: 
                    761: error(sev,enumb,arg1,arg2,arg3)
                    762: 
                    763: int sev;
                    764: int enumb;
                    765: int arg1;
                    766: int arg2;
                    767: int arg3;
                    768: 
                    769: {
                    770:        char c;
                    771:        int cc;
                    772:        long skadd;
                    773:        char string[HELSIZE];
                    774:        char errpath[128];
                    775:        int errfile;
                    776: /* Keywords: error-messages unix-interface user-interface */
                    777: 
                    778:        unprompt();                     /* remove spurious messages */
                    779:        if (SCRWID==0) sttype(NULL); /* Fix Null terminal type */
                    780: 
                    781: #ifdef PC
                    782:        if (enumb == 0) enumb = 13;
                    783:        errfile = open("a:error.blk",4);            /* open errmsg file */
                    784:        if (errfile < 0) errfile = open("b:error.blk",4);
                    785: #else
                    786:        seprintf(errpath,"%s/errfile",em_dir);
                    787:        errfile = open(errpath,0);      /* open errmsg file */
                    788: #endif  PC
                    789:        skadd = (long) (enumb-1) * HELSIZE; /* 0 is no error */
                    790: 
                    791: 
                    792:        if (errfile>0) {
                    793:                 do {
                    794:                         lseek(errfile,skadd,0);
                    795:                         cc = read(errfile,string,HELSIZE);
                    796:                 } while ((cc != HELSIZE) && (errno == 4));
                    797:                 close(errfile);
                    798:        } else {
                    799:                seprintf(string,"Can't access %s/errfile for error %d",em_dir,enumb);
                    800:        }
                    801:        mtop();
                    802:        putout(string,arg1,arg2,arg3);
                    803:        putout(endput);
                    804:        beep();
                    805:        mflush(stdout);                 /* flush output */
                    806: reread:
                    807: #ifdef PC
                    808:        rawread(&c);
                    809: #else  
                    810:        cc = 0;
                    811:        if (no_io) {
                    812:                c = CTRLZ;
                    813:        } else {
                    814:                
                    815:                while (read(0,&c,1) !=1) {      /* always from tty */
                    816:                        c=CTRLZ;                /* Default to quit */
                    817:                        if (++cc > 60) break;   /* Quit after 1 hour */
                    818:                }
                    819:        }
                    820: #endif
                    821:        if ((c&0177) == CTRLBRAK) eabort(0);    /* crash dump */
                    822:        if (sev == FATAL) crash(0);
                    823:        switch(c&0177) {
                    824: 
                    825:        case CTRLG:
                    826:        case RUBOUT:
                    827:                while (infrn) inpop();  /* get out of any init files */
                    828:                return(-1);
                    829:        case 'n':
                    830:                return(1);                              /* CTRL -G */
                    831:        case CTRLZ: gquit();            /* get out of emacs */
                    832: 
                    833:        case CTRLS:
                    834:        case CTRLQ:
                    835:                goto reread;            /* Ignore ^S/^Q from terminal */
                    836: 
                    837:        default: return(0);             /* normal return */
                    838:        }
                    839: }
                    840: 
                    841: 
                    842: char *         
                    843: hmap(helno)
                    844: /* Keywords help-messages macro-programming user-interface:10 */
                    845: 
                    846: int helno;
                    847: {
                    848:        register char *macp;
                    849:        macp = &(bbuf[0][helno-2]);
                    850:        while (*(--macp));
                    851:        return(macp+1);
                    852: }
                    853: 
                    854: helpin(helno,hbuf)
                    855: 
                    856: register int helno;
                    857: register char *hbuf;
                    858: 
                    859: {
                    860: /* Keywords: help-messages unix-interface  */
                    861:        
                    862:        register int cc;
                    863:        long skadd;
                    864:        char helname[128];
                    865:        
                    866:        helno = map_it[helno];
                    867:        if (helno>ISIZE) {
                    868:                strcpy(hbuf,hmap(helno-ISIZE));
                    869:                return;
                    870:        }
                    871:        if (helfile == 0) {
                    872: #ifdef PC
                    873:                helfile = open ("a:help.blk",4);
                    874:                if (helfile < 0) helfile = open ("b:help.blk",4);
                    875: #else
                    876:                seprintf(helname,"%s/helpfile",em_dir); /* construct path */
                    877:                helfile = open (helname,0);
                    878:                if (helfile < 0) {
                    879:                        helfile = 0;
                    880:                        seprintf(hbuf,"Can't open help message file: %s",helname);
                    881:                }
                    882: #endif PC
                    883:        }
                    884:        skadd = (long) (helno) * HELSIZE;
                    885: #ifdef PC
                    886:        if (helfile > 0) {
                    887:                lseek(helfile,skadd,0);
                    888:                cc = read(helfile,hbuf,HELSIZE);
                    889:        }
                    890: #else
                    891:        do {
                    892:                lseek(helfile,skadd,0);
                    893:                cc = read(helfile,hbuf,HELSIZE);
                    894:        } while ((cc != HELSIZE) && (errno == 4));
                    895: #endif PC
                    896: }
                    897: 
                    898: 
                    899: statout()
                    900: 
                    901: {
                    902: #ifndef PC
                    903:        char stbuf[256];
                    904:        register int fid;
                    905:        register int i;
                    906:        char fbuf[128];
                    907: /* Keywords: user-interface:10 statistics exit-processing */
                    908:        
                    909:        struct tstruct {
                    910:                long usrtime;
                    911:                long systime;
                    912:                long xt1;
                    913:                long xt2;
                    914:        } tbf;
                    915:        
                    916:        times(&tbf);
                    917: 
                    918:        seprintf(stbuf,"%d %D %D %d %D %d %d %d %d %d\n",
                    919:                myuid,tbf.usrtime,tbf.systime,ninch,noutc,
                    920:                nmkline,nbread,nbwrite,nbseek,TERMIQ);
                    921:        seprintf(fbuf,"%s/s%s",em_dir,version);
                    922: 
                    923: #ifdef ux3
                    924:        fid = open(fbuf,O_WRONLY+O_APPEND);
                    925:        if (fid) {
                    926: #else
                    927:        fid = open(fbuf,1);
                    928:        if (fid) {
                    929:                lseek(fid,0L,2);
                    930: #endif ux3
                    931:                write(fid,stbuf,lng(stbuf));
                    932:                close(fid);
                    933:        }
                    934: #ifdef CMON
                    935:        seprintf(fbuf,"%s/cmcnt",emd_source);
                    936:        fid = open (fbuf,1);
                    937:        if (fid>=0) {
                    938:                lseek(fid,0L,2);
                    939:                write(fid,cmcnt,sizeof(cmcnt));
                    940:                close(fid);
                    941:        }
                    942: #endif CMON
                    943: #ifdef MONITOR
                    944:        monitor(0);
                    945: #endif MONITOR
                    946: #endif PC
                    947: }
                    948: #ifdef DIRED
                    949: 
                    950: char *
                    951: 
                    952: fxname(line,fbuf)
                    953: 
                    954: int line;
                    955: char *fbuf;
                    956: /* Keywords: dired user-interface file-selection */
                    957: 
                    958: {
                    959:        register char *xp;
                    960:        register char *lp;
                    961:        register char *fp;
                    962: 
                    963:        lp = mkline(line)+leng(line)-1;
                    964:        while (*lp == ' ') lp--;
                    965:        fp = lp;
                    966:        while ((*fp != ' ') || ((fp[-3] != ':') && (fp[-3] != '9'))) fp--;
                    967:        xp = fbuf;
                    968:        while (fp != lp) *xp++= *(++fp);
                    969:        *xp = 0;
                    970:        return(fbuf);
                    971: }
                    972: dcdel(count,arg)
                    973: /* Keywords: dired commands deletion */
                    974: 
                    975: {
                    976:        if ((diron == 0) || (column)) insertc(count,arg); /* not at BOL */
                    977:        else ddel(count);
                    978: }
                    979: 
                    980: /* delete an entry */
                    981: 
                    982: ddel(count,arg)
                    983: 
                    984: register int count,arg;
                    985: /* Keywords: dired commands deletion */
                    986: 
                    987: {
                    988:        if (diron) {
                    989:                while (count--) {
                    990:                        move(curln,0);
                    991:                        if (*clptr != EOL) insertc(1,'D');
                    992:                        if (curln<nlines)move(curln+1,0);
                    993:                }
                    994:        } else {
                    995:                switch(arg) {
                    996:                case CTRLD:
                    997:                        fdel(count,arg);
                    998:                        break;
                    999:                case CTRLH:
                   1000:                case RUBOUT:
                   1001:                        bdel(count,arg);
                   1002:                        break;
                   1003:                case CTRLK:
                   1004:                        ekill(count,arg);
                   1005:                        break;
                   1006:                default: beep();        /* I don't know how we got here */
                   1007:                }
                   1008:        }
                   1009: }
                   1010: 
                   1011: dundel(count,arg)
                   1012: 
                   1013: /* Keyword dired commands undoing */
                   1014: 
                   1015: register int count;
                   1016: {
                   1017:        if ((diron == 0) || column) {
                   1018:                return(insertc(count,arg));
                   1019:        }
                   1020:        while (count--) {
                   1021:                if (*clptr != EOL) insertc(1,' ');
                   1022:                if (curln<nlines) move(curln+1,0);
                   1023:        }
                   1024: }
                   1025: 
                   1026: dview(count,arg)
                   1027: /* Keywords: dired commands recursive-editing */
                   1028: 
                   1029: {
                   1030: 
                   1031:        char fxb[64];
                   1032:        char dxb[128];
                   1033:        int obuf,nbuf;
                   1034:        
                   1035:        if (column || (diron == 0)) insertc(count,arg);
                   1036:        else {
                   1037:                seprintf(dxb,"%s/%s",fname(),fxname(curln,fxb));
                   1038:                obuf = curbf;
                   1039:                if (chgbuf(dxb) && readin(dxb,1)) {
                   1040:                        nbuf = curbf;
                   1041:                        recurse(1);
                   1042:                        if (nbuf != curbf) chbuf(nbuf);
                   1043:                        if (diron) fsave(0);
                   1044:                }
                   1045:                if (obuf != curbf) {
                   1046:                        nbuf = curbf;
                   1047:                        chbuf(obuf);
                   1048:                        klbfr(nbuf);
                   1049:                }
                   1050:        }
                   1051: };
                   1052: 
                   1053: catstr(dp,sp1,sp2)
                   1054: 
                   1055: /* concatenate */
                   1056: 
                   1057: /* Keywords: string-handling */
                   1058: 
                   1059: register char *dp;
                   1060: register char *sp1;
                   1061: register char *sp2;
                   1062: 
                   1063: {
                   1064:        while (*dp++ = *sp1++);
                   1065:        *(dp-1)='/';
                   1066:        while (*dp++ = *sp2++);
                   1067: }
                   1068: dclean()
                   1069: /* Keywords: dired exit-processing:10 user-interface:40 deletion:30 unix-interface */
                   1070: 
                   1071: {
                   1072:        register int i;
                   1073:        register char *lp;
                   1074:        register int status;
                   1075:        char *cp;
                   1076:        int ndel;
                   1077:        char obuf[16];
                   1078:        int ouid,guid;
                   1079:        char *cp1,*cp2;
                   1080:        extern int cstatus;     
                   1081:        char nbuf[256];
                   1082:        
                   1083:        
                   1084:        if (streq(fname(),".passwd")) return; /* don't edit .passwd! */
                   1085:        ndel = 0;
                   1086:        for (i = 1; i <= nlines; i++) {
                   1087:                lp = mkline(i);
                   1088:                if ((*lp == 'D') || (lp[1] == 'M')|| (lp[2] == 'O')){
                   1089:                        if (ndel == 0) {
                   1090:                                clear();
                   1091:                                putout ("Editing the following files from directory %s:", fname());
                   1092:                                putout ("");
                   1093:                        }
                   1094:                        putout ("%c%c%c %s",lp[0],lp[1],lp[2],fxname(i,nbuf));
                   1095:                        ndel++;
                   1096:                }
                   1097:        }
                   1098:        if (ndel == 0) return;
                   1099:        i = gyn("OK?");
                   1100:        if (i==0) return(0);
                   1101:        if (i<0) quit();
                   1102:        
                   1103:        cp = mstrcpy(nbuf,fname());
                   1104:        *cp++ = '/';
                   1105:        for (i = 1; i < nlines; i++) {
                   1106:                lp = mkline(i);
                   1107:                if (*lp == 'D') {
                   1108:                        fxname(i,cp);
                   1109:                        if (lp[4] == 'd') {
                   1110:                                char xbuf[256];
                   1111: 
                   1112:                                seprintf(xbuf,"rm -fr %s",nbuf);
                   1113:                                unx(xbuf,4); /* Run rm command on it */
                   1114:                                status = cstatus;
                   1115:                                errno = 66; /* Can't remove directory */
                   1116:                        } else {
                   1117:                                status = unlink (nbuf);
                   1118:                        }
                   1119:                        if (status){
                   1120:                                error (WARN,errno,nbuf);
                   1121:                        } else {
                   1122:                                move(i,0);
                   1123:                                ekill(1); /* kill line */
                   1124:                        }
                   1125:                } else {
                   1126:                        if (lp[1] == 'M') {
                   1127:                                fxname(i,cp);
                   1128:                                status = chmod (nbuf,mkmode(lp+5));
                   1129:                                if (status) {
                   1130:                                        error (WARN,errno,nbuf);
                   1131:                                } else {
                   1132:                                        move(i,1);
                   1133:                                        insertc(1,' ');
                   1134:                                }
                   1135:                        }
                   1136:                        if (lp[2] == 'O') {
                   1137:                                fxname(i,cp);
                   1138:                                cp1 =obuf;
                   1139:                                cp2 = lp+19;
                   1140:                                while ((*cp1++ = *cp2++) != ' ');
                   1141:                                *(--cp1) = 0;
                   1142:                                if ((ouid = gtuid(obuf))== -1) goto badpw;
                   1143:                                lp = mkline(i);
                   1144:                                cp1 = obuf;
                   1145:                                cp2 = lp+28;
                   1146:                                while ((*cp1++ = *cp2++) != ' ');
                   1147:                                *(--cp1) = 0;
                   1148:                                if ((guid = gtuid(obuf))== -1) {
                   1149: badpw:                                 error (WARN,67,obuf,nbuf);
                   1150:                                        continue;
                   1151:                                }
                   1152:                                lp = mkline(i);
                   1153:                                status = chown(nbuf,ouid,guid);
                   1154:                                if (status) {
                   1155:                                        error (WARN,errno,nbuf);
                   1156:                                } else {
                   1157:                                        move(i,2);
                   1158:                                        insertc(1,' ');
                   1159:                                }
                   1160:                        }
                   1161:                }
                   1162:        }
                   1163:        unmod(1);                       /* buffer is now up to date */
                   1164:        return(1);
                   1165: }
                   1166: 
                   1167: /* mkmode -- translate from ls -l style mode representation to */
                   1168: /* a 16 bit mode number */
                   1169: 
                   1170: /* mode bit table.  one entry per character, contains characters followed */
                   1171: /* by bit number to turn on */
                   1172: 
                   1173: char *modebits[10] = {
                   1174:        "r\011",
                   1175:        "w\010",
                   1176:        "x\007s\014s\007",
                   1177:        "r\006",
                   1178:        "w\005",
                   1179:        "x\004s\013s\004",
                   1180:        "r\003",
                   1181:        "w\002",
                   1182:        "x\001t\012t\001",
                   1183:        0};
                   1184: 
                   1185: mkmode(sp)
                   1186: char *sp;
                   1187: 
                   1188: /* Keywords: dired file-modes user-interface:10 unix-interface:30 */
                   1189: 
                   1190: 
                   1191: {
                   1192:        int newmode;
                   1193:        char *mp;
                   1194:        char **mep;
                   1195:        
                   1196:        newmode = 0;
                   1197:        mep = modebits;
                   1198:        while (mp = *mep++) {
                   1199:                while (*mp) {
                   1200:                        if (*mp == *sp) {
                   1201:                                newmode |= (1<< (mp[1]-1));
                   1202:                        }
                   1203:                        mp+= 2;
                   1204:                }
                   1205:                sp++;
                   1206:        }
                   1207:        return(newmode);
                   1208: }
                   1209: 
                   1210: /* gtuid -- get uid from user name */
                   1211: 
                   1212: /* **** NOTE, we can't use getpwnam, because it uses standard I/O */
                   1213: 
                   1214: gtuid(name)
                   1215: 
                   1216: register char *name;
                   1217: /* Keywords: dired unix-interface:10 password-file user-id-processing */
                   1218: 
                   1219: {
                   1220:        int oldbf;
                   1221:        unsigned uid;
                   1222:        char xbuf[100];
                   1223:        register char *cp;
                   1224:        oldbf = curbf;
                   1225:        
                   1226:        chgbuf (".passwd");
                   1227:        if (nlines < 10) {
                   1228:                readin ("/etc/passwd",1);
                   1229:        }
                   1230:        seprintf (xbuf,"^%s:",name);
                   1231:        
                   1232:        if (rgsrch(1,0,xbuf,0,1)) {
                   1233:                srch(kline,kcol,":",1);
                   1234:                srch(kline,kcol+1,":",1);
                   1235:                uid = 0;
                   1236:                cp = mkline(kline)+kcol+1;
                   1237:                while (*cp != ':') {
                   1238:                        uid = (uid*10)+(*cp-'0');
                   1239:                        cp++;
                   1240:                }
                   1241:        } else uid = -1;
                   1242:        chbuf(oldbf);
                   1243:        return(uid);
                   1244: }
                   1245: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.