|
|
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(); ! 347: for (i = 0; i < 16; i++) signal(i,eabort); /* trap various problems */ ! 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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.