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