|
|
1.1 ! root 1: #include <stdio.h> ! 2: #include <signal.h> ! 3: #include <sys/ttyio.h> ! 4: #include <sys/filio.h> ! 5: #include <ctype.h> ! 6: /* ! 7: * cu telno [ class ] ! 8: * Escape with `~' at beginning of line. ! 9: * Ordinary diversions are ~<, ~> and ~>>. ! 10: * Silent output diversions are ~>: and ~>>:. ! 11: * Terminate output diversion with ~> alone. ! 12: * Output command requests are ~! and ~:! (silent). ! 13: * Quit is ~. and ~! gives local command or shell. ! 14: * Also ~$ for canned procedure pumping remote. ! 15: * ~%put from [to] and ~%take from [to] invoke builtins ! 16: */ ! 17: ! 18: char CRLF[2] = {'\r', '\n'}; ! 19: #define equal(s1,s2) (strcmp(s1, s2)==0) ! 20: char *cunfile; ! 21: int ln; /* fd for comm line */ ! 22: char tkill, terase; /* current input kill & erase */ ! 23: char c; ! 24: int intr; ! 25: int nhup; ! 26: int nflag; ! 27: int tandm; ! 28: int hduplx; ! 29: int errflg; ! 30: int speed = B9600; /* used only for direct */ ! 31: int parity = 0; ! 32: extern int optind, opterr; ! 33: extern char *optarg; ! 34: struct sgttyb realtty; ! 35: struct tchars realtch; ! 36: int sig2(); ! 37: ! 38: char *connmsg[] = { ! 39: "", ! 40: "ACU busy", ! 41: "call dropped", ! 42: "no carrier", ! 43: "can't fork", ! 44: "acu access", ! 45: "tty access", ! 46: "tty hung", ! 47: "usage: cu [-hnt] telno [ class ]", ! 48: "unknown service class", ! 49: "stuff dk error message here", /* hack */ ! 50: }; ! 51: ! 52: struct dial { ! 53: char *telno; ! 54: char *dialtype; ! 55: char *comment; ! 56: }; ! 57: ! 58: char partab[] = { ! 59: 0001,0201,0201,0001,0201,0001,0001,0201, ! 60: 0202,0004,0003,0201,0005,0206,0201,0001, ! 61: 0201,0001,0001,0201,0001,0201,0201,0001, ! 62: 0001,0201,0201,0001,0201,0001,0001,0201, ! 63: 0200,0000,0000,0200,0000,0200,0200,0000, ! 64: 0000,0200,0200,0000,0200,0000,0000,0200, ! 65: 0000,0200,0200,0000,0200,0000,0000,0200, ! 66: 0200,0000,0000,0200,0000,0200,0200,0000, ! 67: 0200,0000,0000,0200,0000,0200,0200,0000, ! 68: 0000,0200,0200,0000,0200,0000,0000,0200, ! 69: 0000,0200,0200,0000,0200,0000,0000,0200, ! 70: 0200,0000,0000,0200,0000,0200,0200,0000, ! 71: 0000,0200,0200,0000,0200,0000,0000,0200, ! 72: 0200,0000,0000,0200,0000,0200,0200,0000, ! 73: 0200,0000,0000,0200,0000,0200,0200,0000, ! 74: 0000,0200,0200,0000,0200,0000,0000,0201 ! 75: }; ! 76: ! 77: /* ! 78: * spawn child to invoke rd to read from line, output to fd 1 ! 79: * main line invokes wr to read tty, write to line ! 80: */ ! 81: ! 82: main(ac, av) ! 83: char *av[]; ! 84: { ! 85: int fk; ! 86: struct sgttyb stbuf; ! 87: struct ttydevb tdbuf; ! 88: struct dial d; ! 89: ! 90: signal(SIGPIPE, SIG_IGN); ! 91: d.telno = NULL; ! 92: d.dialtype = NULL; ! 93: d.comment = ""; ! 94: options(ac, av); ! 95: if (optind >= ac || errflg) { ! 96: prf(connmsg[8]); ! 97: exit(8); ! 98: } ! 99: ioctl(0, TIOCGETP, &realtty); ! 100: ioctl(0, TIOCGETC, &realtch); ! 101: gettelno(av[optind], &d); ! 102: if (optind+1 < ac) ! 103: d.dialtype = av[optind+1]; ! 104: if (d.dialtype==NULL || *d.dialtype=='\0') ! 105: d.dialtype = "D1200"; ! 106: if (nflag) { ! 107: printf("%s %s %s\n", d.telno, d.dialtype, d.comment); ! 108: exit(0); ! 109: } ! 110: if (equal(d.dialtype, "direct")) { ! 111: ln = open(d.telno, 2); ! 112: if (ln>=0) { ! 113: struct tchars tcr; ! 114: ! 115: ioctl(ln, TIOCGETP, &stbuf); ! 116: stbuf.sg_flags &= ~ECHO; ! 117: stbuf.sg_flags |= RAW|EVENP|ODDP; ! 118: stbuf.sg_ispeed = speed; /* obsolete */ ! 119: stbuf.sg_ospeed = speed; /* obsolete */ ! 120: ioctl(ln, TIOCGETC, &tcr); ! 121: tcr.t_stopc = '\027'; ! 122: tcr.t_startc = '\031'; ! 123: ioctl(ln, TIOCGDEV, &tdbuf); ! 124: tdbuf.ispeed = tdbuf.ospeed = speed; ! 125: tdbuf.flags |= F8BIT|EVENP|ODDP; ! 126: ioctl(ln, TIOCSETP, &stbuf); ! 127: ioctl(ln, TIOCSETC, &tcr); ! 128: ioctl(ln, TIOCSDEV, &tdbuf); ! 129: ioctl(ln, TIOCHPCL, 0); ! 130: ioctl(ln, TIOCEXCL, 0); ! 131: } ! 132: } else{ ! 133: ln = -1; ! 134: } ! 135: if (ln < 0) { ! 136: prf("Connect failed: %s",connmsg[-ln]); ! 137: exit(-ln); ! 138: } ! 139: ioctl(ln, TIOCGETP, &stbuf); ! 140: prf("Connected"); ! 141: if (d.comment && *d.comment && *d.comment!='\n') ! 142: prf(d.comment); ! 143: if (tandm) { ! 144: ioctl(ln, TIOCGETP, &stbuf); ! 145: stbuf.sg_flags = ODDP+EVENP+TANDEM+CBREAK; ! 146: ioctl(ln, TIOCSETN, &stbuf); ! 147: } ! 148: fk = fork(); ! 149: nhup = (int)signal(SIGINT, SIG_IGN); ! 150: if (fk == 0) { ! 151: rd(); ! 152: prf("\007Lost carrier"); ! 153: exit(3); ! 154: } ! 155: mode(1); ! 156: wr(); ! 157: mode(0); ! 158: kill(fk, SIGKILL); ! 159: stbuf.sg_ispeed = 0; ! 160: stbuf.sg_ospeed = 0; ! 161: ioctl(ln, TIOCSETN, &stbuf); ! 162: tdbuf.ispeed = tdbuf.ospeed = 0; ! 163: ioctl(ln, TIOCSDEV, &tdbuf); ! 164: prf("Disconnected"); ! 165: exit(0); ! 166: } ! 167: ! 168: /* ! 169: * wr: write to remote: 0 -> line. ! 170: * ~. terminate ! 171: * ~<file send file ! 172: * ~! local login-style shell ! 173: * ~!cmd execute cmd locally ! 174: * ~$proc execute proc locally, send output to line ! 175: * ~%cmd execute builtin cmd (put and take) ! 176: */ ! 177: ! 178: wr() ! 179: { ! 180: int ds, fk, lcl, x, nc; ! 181: char *p, b[600]; ! 182: ! 183: for (;;) { ! 184: p = b; ! 185: while (rdc(0) >= 1) { ! 186: if (p == b) ! 187: lcl=(c == '~'); ! 188: if (p == b+1 && b[0] == '~') ! 189: lcl=(c!='~'); ! 190: if (c == 0) ! 191: c = 0177; ! 192: if (!lcl) { ! 193: if (c==0177) ! 194: ioctl(ln, TIOCFLUSH, 0); ! 195: if (wrc(ln, c, 1) <= 0) { ! 196: prf("line gone"); ! 197: return; ! 198: } ! 199: if (c==0177) ! 200: ioctl(0, TIOCFLUSH, 0); ! 201: } ! 202: if (lcl) { ! 203: if (c == 0177) ! 204: c = tkill; ! 205: if (c == '\r' || c == '\n') ! 206: goto A; ! 207: if (!hduplx) ! 208: wrc(1, c, 1); ! 209: } ! 210: *p++ = c; ! 211: if (c == terase) { ! 212: p = p-2; ! 213: if (p<b) ! 214: p = b; ! 215: } ! 216: if (c == tkill || c == 0177 || c == '\r' || c == '\n') ! 217: p = b; ! 218: } ! 219: return; ! 220: A: ! 221: if (!hduplx || realtty.sg_flags&CRMOD) ! 222: echo(""); ! 223: *p = 0; ! 224: switch (b[1]) { ! 225: case '.': ! 226: case '\004': ! 227: return; ! 228: case 'b': ! 229: sendbreak(); ! 230: break; ! 231: ! 232: case '!': ! 233: case '$': ! 234: fk = fork(); ! 235: if (fk == 0) { ! 236: close(1); ! 237: dup(b[1] == '$'? ln:2); ! 238: close(ln); ! 239: mode(0); ! 240: if (!nhup) ! 241: signal(SIGINT, SIG_DFL); ! 242: if (b[2] == 0) ! 243: execl("/bin/sh","sh",0); ! 244: else ! 245: execl("/bin/sh","sh","-c",b+2,(char *)0); ! 246: prf("Can't execute shell"); ! 247: exit(1); ! 248: } ! 249: if (fk!=(-1)) { ! 250: while (wait((int *)0)!=fk) ! 251: ; ! 252: } ! 253: mode(1); ! 254: if (b[1] == '!') ! 255: echo("!"); ! 256: break; ! 257: case '<': ! 258: if (b[2] == 0) break; ! 259: if ((ds = open(b+2,0))<0) { ! 260: prf("Can't divert %s",b+1); ! 261: break; ! 262: } ! 263: intr = x = 0; ! 264: mode(2); ! 265: if (!nhup) ! 266: signal(SIGINT, sig2); ! 267: while (!intr && (nc = rdc(ds)) >= 1) { ! 268: if (wrc(ln, c, nc==1) <= 0) { ! 269: x = 1; ! 270: break; ! 271: } ! 272: } ! 273: signal(SIGINT, SIG_IGN); ! 274: close(ds); ! 275: mode(1); ! 276: if (x) ! 277: return; ! 278: break; ! 279: case '%': ! 280: dopercen(&b[2]); ! 281: break; ! 282: default: ! 283: prf("Use `~~' to start line with `~'"); ! 284: } ! 285: continue; ! 286: } ! 287: } ! 288: ! 289: dopercen(line) ! 290: register char *line; ! 291: { ! 292: char *args[10]; ! 293: register narg, f; ! 294: int rcount, nc; ! 295: ! 296: for (narg = 0; narg < 10;) { ! 297: while(*line == ' ' || *line == '\t') ! 298: line++; ! 299: if (*line == '\0') ! 300: break; ! 301: args[narg++] = line; ! 302: while(*line != '\0' && *line != ' ' && *line != '\t') ! 303: line++; ! 304: if (*line == '\0') ! 305: break; ! 306: *line++ = '\0'; ! 307: } ! 308: if (equal(args[0], "break")) { ! 309: sendbreak(); ! 310: return; ! 311: } else if (equal(args[0], "take")) { ! 312: if (narg < 2) { ! 313: prf("usage: ~%%take from [to]"); ! 314: return; ! 315: } ! 316: if (narg < 3) ! 317: args[2] = args[1]; ! 318: wrln("echo '~>:'"); ! 319: wrln(args[2]); ! 320: wrln(";tee /dev/null <"); ! 321: wrln(args[1]); ! 322: wrln(";echo '~>'\n"); ! 323: return; ! 324: } else if (equal(args[0], "put")) { ! 325: if (narg < 2) { ! 326: prf("usage: ~%%put from [to]"); ! 327: return; ! 328: } ! 329: if (narg < 3) ! 330: args[2] = args[1]; ! 331: if ((f = open(args[1], 0)) < 0) { ! 332: prf("cannot open: %s", args[1]); ! 333: return; ! 334: } ! 335: wrln("stty -echo;cat >"); ! 336: wrln(args[2]); ! 337: wrln(";stty echo\n"); ! 338: sleep(5); ! 339: intr = 0; ! 340: if (!nhup) ! 341: signal(SIGINT, sig2); ! 342: mode(2); ! 343: rcount = 0; ! 344: while(!intr && (nc = rdc(f)) >= 1) { ! 345: rcount++; ! 346: if (c == tkill || c == terase) ! 347: wrc(ln, '\\', 0); ! 348: if (wrc(ln, c, nc == 1) <= 0) ! 349: intr = 1; ! 350: } ! 351: signal(SIGINT, SIG_IGN); ! 352: close(f); ! 353: if (intr) { ! 354: wrc(ln, '\n', 1); ! 355: prf("stopped after %d bytes", rcount); ! 356: } ! 357: wrc(ln, '\004', 1); ! 358: sleep(5); ! 359: mode(1); ! 360: return; ! 361: } ! 362: prf("~%%%s unknown\n", args[0]); ! 363: } ! 364: ! 365: wrln(s) ! 366: register char *s; ! 367: { ! 368: register n = strlen(s); ! 369: ! 370: write(ln, s, n); ! 371: } ! 372: ! 373: /* ! 374: * rd: read from remote: line -> 1 ! 375: * catch: ! 376: * ~>[>][:][file] ! 377: * stuff from file... ! 378: * ~> (ends diversion) ! 379: * ways for remote to run local command: ! 380: * ~!command (run command locally) ! 381: * ~:!command (run silently locally) ! 382: */ ! 383: ! 384: rd() ! 385: { ! 386: int ds, slnt, pid, hold=0, nc; ! 387: char *p, *q, b[600]; ! 388: ! 389: p = b; ! 390: ds = -1; ! 391: while ((nc = rdc(ln)) >= 1) { ! 392: if (ds < 0 && hold==0) ! 393: slnt = 0; ! 394: if (p==b && c=='~') ! 395: hold= ++slnt; ! 396: if (hold && slnt && p==b+1 && c!=':') { ! 397: wrc(1, '~', 1); ! 398: slnt--; ! 399: hold = 0; ! 400: } ! 401: if (!slnt) ! 402: wrc(1, c, nc==1); ! 403: *p++ = c; ! 404: if (c!='\n' && p < &b[599]) ! 405: continue; ! 406: q = p; ! 407: p = b; ! 408: hold = 0; ! 409: if (strncmp(b, "~:!",3)==0||strncmp(b, "~!", 2)==0) { ! 410: *--q= '\0'; ! 411: if (*--q == '\r') ! 412: *q= '\0'; ! 413: mode(0); ! 414: if ((pid=fork())==0) { ! 415: p = b+2; ! 416: if (*p=='!') ! 417: p++; ! 418: execl("/bin/sh", "sh", "-c", p, (char *)0); ! 419: exit(0); ! 420: } ! 421: while (wait((int *)0)!=pid) ! 422: ; ! 423: mode(1); ! 424: continue; ! 425: } ! 426: if (b[0]!='~' || b[1]!='>') { ! 427: if (*(q-2) == '\r') { ! 428: q--; ! 429: *(q-1)=(*q); ! 430: } ! 431: if (ds>=0) ! 432: write(ds, b, q-b); ! 433: continue; ! 434: } ! 435: if (ds>=0) ! 436: close(ds); ! 437: if (slnt) { ! 438: write(1, b, q - b); ! 439: write(1, CRLF, sizeof(CRLF)); ! 440: } ! 441: if (*(q-2) == '\r') ! 442: q--; ! 443: *(q-1) = 0; ! 444: slnt = 0; ! 445: q = b+2; ! 446: if (*q == '>') ! 447: q++; ! 448: if (*q == ':') { ! 449: slnt = 1; ! 450: q++; ! 451: } ! 452: if (*q == 0) { ! 453: ds = -1; ! 454: continue; ! 455: } ! 456: if (b[2]!='>' || (ds = open(q,1))<0) ! 457: ds = creat(q, 0644); ! 458: lseek(ds, (long)0, 2); ! 459: if (ds<0) ! 460: prf("Can't divert %s",b+1); ! 461: } ! 462: } ! 463: ! 464: mode(f) ! 465: { ! 466: struct sgttyb stbuf; ! 467: static struct tchars nochars = { -1, -1, -1, -1, -1, -1}; ! 468: ! 469: ioctl(0, TIOCGETP, &stbuf); ! 470: tkill = stbuf.sg_kill; ! 471: terase = stbuf.sg_erase; ! 472: if (f == 0) { ! 473: ioctl(0, TIOCSETP, &realtty); ! 474: ioctl(0, TIOCSETC, &realtch); ! 475: return; ! 476: } ! 477: if (f == 1) { ! 478: stbuf.sg_flags |= CBREAK; ! 479: stbuf.sg_flags &= ~CRMOD; ! 480: if (!hduplx) ! 481: stbuf.sg_flags &= ~ECHO; ! 482: ioctl(0, TIOCSETP, &stbuf); ! 483: ioctl(0, TIOCSETC, &nochars); ! 484: return; ! 485: } ! 486: if (f == 2) { ! 487: stbuf.sg_flags &= ~(ECHO|CRMOD); ! 488: ioctl(0, TIOCSETP, &stbuf); ! 489: ioctl(0, TIOCSETC, &realtch); ! 490: return; ! 491: } ! 492: } ! 493: ! 494: echo(s) ! 495: char *s; ! 496: { ! 497: register n = strlen(s); ! 498: ! 499: if (n>0) ! 500: write(1, s, n); ! 501: write(1, CRLF, sizeof(CRLF)); ! 502: } ! 503: ! 504: /* VARARGS1 */ ! 505: prf(f, s) ! 506: char *f; ! 507: char *s; ! 508: { ! 509: printf(f, s); ! 510: printf(CRLF); ! 511: } ! 512: ! 513: sendbreak() ! 514: { ! 515: struct sgttyb b; ! 516: int olds; ! 517: ! 518: #ifdef TIOCSBRK ! 519: ioctl(ln, TIOCSBRK, 0); ! 520: #else TIOCSBRK ! 521: ioctl(ln, TIOCGETP, &b); ! 522: olds = b.sg_ispeed; ! 523: b.sg_ispeed = B50; ! 524: b.sg_ospeed = B50; ! 525: ioctl(ln, TIOCSETP, &b); ! 526: write(ln, "\0\0\0", 3); ! 527: b.sg_ispeed = olds; ! 528: b.sg_ospeed = olds; ! 529: ioctl(ln, TIOCSETP, &b); ! 530: #endif TIOCSBRK ! 531: } ! 532: ! 533: /* ! 534: * Symbolic phone numbers ! 535: */ ! 536: gettelno(np, dp) ! 537: char *np; ! 538: register struct dial *dp; ! 539: { ! 540: char cunumber[128]; ! 541: char *hp; ! 542: register char *xnp; ! 543: char *getenv(); ! 544: ! 545: if (cunfile) { ! 546: if (look(np, dp, cunfile)) ! 547: return; ! 548: } else { ! 549: hp = getenv("HOME"); ! 550: if (hp) { ! 551: strcpy(cunumber, hp); ! 552: strcat(cunumber, "/lib/cunumber"); ! 553: if (look(np, dp, cunumber)) ! 554: return; ! 555: } ! 556: if (look(np, dp, "/usr/lib/cunumber")) ! 557: return; ! 558: } ! 559: xnp = np; ! 560: if (*np != '/') ! 561: while (*xnp) { ! 562: if (*xnp!=';' && *xnp!=':' && *xnp!='-' && *xnp!='*' ! 563: && *xnp!='#' && !isdigit(*xnp)) { ! 564: prf("Symbolic number not found"); ! 565: exit(1); ! 566: } ! 567: xnp++; ! 568: } ! 569: dp->telno = np; ! 570: } ! 571: ! 572: look(np, dp, fnp) ! 573: register char *np; ! 574: register struct dial *dp; ! 575: char *fnp; ! 576: { ! 577: FILE *fp; ! 578: static char line[128]; ! 579: register char *lp; ! 580: register i; ! 581: char *opts[8]; ! 582: register char **optp; ! 583: char *w[4]; ! 584: ! 585: if ((fp = fopen(fnp, "r")) == NULL) ! 586: return(0); ! 587: while (fgets(line, sizeof(line), fp)) { ! 588: lp = line; ! 589: optp = opts; ! 590: for (i = 0; i<4; i++) { ! 591: while (isspace(*lp)) ! 592: lp++; ! 593: if (i==1 && *lp=='-') { ! 594: *optp++ = lp; ! 595: i--; ! 596: } else ! 597: w[i] = lp; ! 598: while ((!isspace(*lp) || i==3) && *lp) ! 599: lp++; ! 600: if (*lp) ! 601: *lp++ = '\0'; ! 602: } ! 603: if (strcmp(w[0], np)) ! 604: continue; ! 605: i = optind; ! 606: optind = 0; ! 607: options(optp-opts, opts); ! 608: optind = i; ! 609: dp->telno = w[1]; ! 610: dp->dialtype = w[2]; ! 611: dp->comment = w[3]; ! 612: fclose(fp); ! 613: return(1); ! 614: } ! 615: fclose(fp); ! 616: return(0); ! 617: } ! 618: ! 619: options(ac, av) ! 620: char **av; ! 621: { ! 622: register o; ! 623: ! 624: opterr = 0; ! 625: while ((o = getopt(ac, av, "hntf:s:p:")) != EOF) { ! 626: switch(o) { ! 627: ! 628: case '?': ! 629: errflg++; ! 630: continue; ! 631: ! 632: case 'h': ! 633: hduplx++; ! 634: continue; ! 635: ! 636: case 'f': ! 637: cunfile = optarg; ! 638: continue; ! 639: ! 640: case 't': ! 641: tandm++; ! 642: continue; ! 643: ! 644: case 'n': ! 645: nflag++; ! 646: continue; ! 647: ! 648: case 's': ! 649: if ((speed = getspeed(optarg)) < 0) { ! 650: fprintf(stderr, "-s %s: illegal speed\n"); ! 651: errflg++; ! 652: } ! 653: continue; ! 654: ! 655: case 'p': ! 656: if ((parity = getpar(optarg)) < 0) { ! 657: fprintf(stderr, "-p %s: illegal parity\n"); ! 658: errflg++; ! 659: } ! 660: continue; ! 661: } ! 662: } ! 663: } ! 664: ! 665: struct speeds{ ! 666: char *s_name; ! 667: int s_define; ! 668: } speeds[] = { ! 669: "0", B0, ! 670: "50", B50, ! 671: "75", B75, ! 672: "110", B110, ! 673: "134", B134, ! 674: "150", B150, ! 675: "200", B200, ! 676: "300", B300, ! 677: "600", B600, ! 678: "1200", B1200, ! 679: "1800", B1800, ! 680: "2400", B2400, ! 681: "4800", B4800, ! 682: "9600", B9600, ! 683: "exta", EXTA, ! 684: "extb", EXTB, ! 685: "19200", EXTA, ! 686: 0 ! 687: }; ! 688: ! 689: getspeed(s) ! 690: char *s; ! 691: { ! 692: register struct speeds *sp; ! 693: ! 694: for (sp = speeds; sp->s_name; sp++) ! 695: if (strcmp(sp->s_name, s) == 0) ! 696: return (sp->s_define); ! 697: return (-1); ! 698: } ! 699: ! 700: getpar(s) ! 701: char *s; ! 702: { ! 703: switch (s[0]) { ! 704: case '0': ! 705: return (0); ! 706: case '1': ! 707: return (EVENP|ODDP); ! 708: case 'e': ! 709: return (EVENP); ! 710: case 'o': ! 711: return (ODDP); ! 712: } ! 713: return (-1); ! 714: } ! 715: ! 716: wrc(f, c, flush) ! 717: register c; ! 718: { ! 719: static char buf[64]; ! 720: static char *bp = buf; ! 721: register r; ! 722: ! 723: c &= 0177; ! 724: if (f==ln) { ! 725: switch (parity) { ! 726: case EVENP: ! 727: c |= (partab[c] & 0200); ! 728: break; ! 729: case ODDP: ! 730: c |= (partab[c] & 0200) ^ 0200; ! 731: break; ! 732: case EVENP|ODDP: ! 733: c |= 0200; ! 734: break; ! 735: } ! 736: } ! 737: *bp++ = c; ! 738: r = 1; ! 739: if (flush || bp >= &buf[64]) { ! 740: r = write(f, buf, bp-buf); ! 741: bp = buf; ! 742: } ! 743: return(r); ! 744: } ! 745: ! 746: rdc(ds) ! 747: { ! 748: static char buf[64]; ! 749: static nc = 0; ! 750: static char *bp; ! 751: ! 752: if (nc <= 0) { ! 753: nc = read(ds, buf, 64); ! 754: bp = buf; ! 755: } ! 756: if (nc <= 0) ! 757: return(nc); ! 758: nc--; ! 759: c = *bp++ & 0177; ! 760: return(nc+1); ! 761: } ! 762: ! 763: sig2() ! 764: { ! 765: signal(SIGINT, SIG_IGN); ! 766: intr = 1; ! 767: } ! 768:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.