|
|
1.1 ! root 1: #include <ctype.h> ! 2: #include <stdio.h> ! 3: #include <pwd.h> ! 4: #include <utmp.h> ! 5: #include <signal.h> ! 6: #include <sys/types.h> ! 7: #include <sys/stat.h> ! 8: #include <setjmp.h> ! 9: #include <whoami.h> ! 10: ! 11: /*copylet flags */ ! 12: /*remote mail, add rmtmsg */ ! 13: #define REMOTE 1 ! 14: /* zap header and trailing empty line */ ! 15: #define ZAP 3 ! 16: #define ORDINARY 2 ! 17: #define FORWARD 4 ! 18: #define LSIZE 256 ! 19: #define MAXLET 300 /* maximum number of letters */ ! 20: #define MAILMODE (~0644) /* mode of created mail */ ! 21: #define RMAIL "/usr/net/bin/sendberkmail" ! 22: #define LOCNAM1 "csvax" ! 23: #define LOCNAM2 "ucbvax" ! 24: #define LOCNAM3 "vax" ! 25: #define LOCNAM4 "v" ! 26: ! 27: char line[LSIZE]; ! 28: char resp[LSIZE]; ! 29: struct let { ! 30: long adr; ! 31: char change; ! 32: } let[MAXLET]; ! 33: int nlet = 0; ! 34: char lfil[50]; ! 35: long iop, time(); ! 36: char *getenv(); ! 37: char *index(); ! 38: char lettmp[] = "/tmp/maXXXXX"; ! 39: char maildir[] = "/usr/spool/mail/"; ! 40: char mailfile[] = "/usr/spool/mail/xxxxxxxxxxxxxxxxxxxxxxx"; ! 41: char dead[] = "dead.letter"; ! 42: char *thissys = sysname; ! 43: char *netname = "vax"; ! 44: char forwmsg[] = " forwarded\n"; ! 45: FILE *tmpf; ! 46: FILE *malf; ! 47: char *my_name; ! 48: char *getlogin(); ! 49: struct passwd *getpwuid(); ! 50: int error; ! 51: int changed; ! 52: int forward; ! 53: char from[] = "From "; ! 54: long ftell(); ! 55: int delete(); ! 56: char *ctime(); ! 57: int flgf; ! 58: int flgp; ! 59: int delflg = 1; ! 60: int hseqno; ! 61: jmp_buf sjbuf; ! 62: ! 63: main(argc, argv) ! 64: char **argv; ! 65: { ! 66: register i; ! 67: char sobuf[BUFSIZ]; ! 68: ! 69: setbuf(stdout, sobuf); ! 70: mktemp(lettmp); ! 71: unlink(lettmp); ! 72: my_name = getlogin(); ! 73: if (my_name == NULL || strlen(my_name) == 0) { ! 74: struct passwd *pwent; ! 75: pwent = getpwuid(getuid()); ! 76: if (pwent==NULL) ! 77: my_name = "???"; ! 78: else ! 79: my_name = pwent->pw_name; ! 80: } ! 81: if(setjmp(sjbuf)) done(); ! 82: for (i=0; i<20; i++) ! 83: setsig(i, delete); ! 84: tmpf = fopen(lettmp, "w"); ! 85: if (tmpf == NULL) { ! 86: fprintf(stderr, "mail: cannot open %s for writing\n", lettmp); ! 87: done(); ! 88: } ! 89: if (argv[0][0] != 'r' && /* no favors for rmail*/ ! 90: (argc == 1 || argv[1][0] == '-' && !any(argv[1][1], "rh"))) ! 91: printmail(argc, argv); ! 92: else ! 93: sendmail(argc, argv); ! 94: done(); ! 95: } ! 96: ! 97: setsig(i, f) ! 98: int i; ! 99: int (*f)(); ! 100: { ! 101: if(signal(i, SIG_IGN)!=SIG_IGN) ! 102: signal(i, f); ! 103: } ! 104: ! 105: any(c, str) ! 106: register int c; ! 107: register char *str; ! 108: { ! 109: ! 110: while (*str) ! 111: if (c == *str++) ! 112: return(1); ! 113: return(0); ! 114: } ! 115: ! 116: printmail(argc, argv) ! 117: char **argv; ! 118: { ! 119: int flg, i, j, print; ! 120: char *p, *getarg(); ! 121: ! 122: setuid(getuid()); ! 123: cat(mailfile, maildir, my_name); ! 124: for (; argc>1; argv++, argc--) { ! 125: if (argv[1][0]=='-') { ! 126: if (argv[1][1]=='q') ! 127: delflg = 0; ! 128: else if (argv[1][1]=='p') { ! 129: flgp++; ! 130: delflg = 0; ! 131: } else if (argv[1][1]=='f') { ! 132: if (argc>=3) { ! 133: strcpy(mailfile, argv[2]); ! 134: argv++; ! 135: argc--; ! 136: } ! 137: } else if (argv[1][1]=='r') { ! 138: forward = 1; ! 139: } else if (argv[1][1]=='h') { ! 140: forward = 1; ! 141: } else { ! 142: fprintf(stderr, "mail: unknown option %c\n", argv[1][1]); ! 143: done(); ! 144: } ! 145: } else ! 146: break; ! 147: } ! 148: malf = fopen(mailfile, "r"); ! 149: if (malf == NULL) { ! 150: fprintf(stdout, "No mail.\n"); ! 151: return; ! 152: } ! 153: lock(mailfile); ! 154: copymt(malf, tmpf); ! 155: fclose(malf); ! 156: fclose(tmpf); ! 157: unlock(); ! 158: tmpf = fopen(lettmp, "r"); ! 159: ! 160: changed = 0; ! 161: print = 1; ! 162: for (i = 0; i < nlet; ) { ! 163: j = forward ? i : nlet - i - 1; ! 164: if(setjmp(sjbuf)) { ! 165: print=0; ! 166: } else { ! 167: if (print) ! 168: copylet(j, stdout, ORDINARY); ! 169: print = 1; ! 170: } ! 171: if (flgp) { ! 172: i++; ! 173: continue; ! 174: } ! 175: setjmp(sjbuf); ! 176: fprintf(stdout, "? "); ! 177: fflush(stdout); ! 178: if (fgets(resp, LSIZE, stdin) == NULL) ! 179: break; ! 180: switch (resp[0]) { ! 181: ! 182: default: ! 183: fprintf(stderr, "usage\n"); ! 184: case '?': ! 185: print = 0; ! 186: fprintf(stderr, "q\tquit\n"); ! 187: fprintf(stderr, "x\texit without changing mail\n"); ! 188: fprintf(stderr, "p\tprint\n"); ! 189: fprintf(stderr, "s[file]\tsave (default mbox)\n"); ! 190: fprintf(stderr, "w[file]\tsame without header\n"); ! 191: fprintf(stderr, "-\tprint previous\n"); ! 192: fprintf(stderr, "d\tdelete\n"); ! 193: fprintf(stderr, "+\tnext (no delete)\n"); ! 194: fprintf(stderr, "m user\tmail to user\n"); ! 195: fprintf(stderr, "! cmd\texecute cmd\n"); ! 196: break; ! 197: ! 198: case '+': ! 199: case 'n': ! 200: case '\n': ! 201: i++; ! 202: break; ! 203: case 'x': ! 204: changed = 0; ! 205: case 'q': ! 206: goto donep; ! 207: case 'p': ! 208: break; ! 209: case '^': ! 210: case '-': ! 211: if (--i < 0) ! 212: i = 0; ! 213: break; ! 214: case 'y': ! 215: case 'w': ! 216: case 's': ! 217: flg = 0; ! 218: if (resp[1] != '\n' && resp[1] != ' ') { ! 219: printf("illegal\n"); ! 220: flg++; ! 221: print = 0; ! 222: continue; ! 223: } ! 224: if (resp[1] == '\n' || resp[1] == '\0') { ! 225: p = getenv("HOME"); ! 226: if(p != 0) ! 227: cat(resp+1, p, "/mbox"); ! 228: else ! 229: cat(resp+1, "", "mbox"); ! 230: } ! 231: for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) { ! 232: malf = fopen(lfil, "a"); ! 233: if (malf == NULL) { ! 234: fprintf(stdout, "mail: cannot append to %s\n", lfil); ! 235: flg++; ! 236: continue; ! 237: } ! 238: copylet(j, malf, resp[0]=='w'? ZAP: ORDINARY); ! 239: fclose(malf); ! 240: } ! 241: if (flg) ! 242: print = 0; ! 243: else { ! 244: let[j].change = 'd'; ! 245: changed++; ! 246: i++; ! 247: } ! 248: break; ! 249: case 'm': ! 250: flg = 0; ! 251: if (resp[1] == '\n' || resp[1] == '\0') { ! 252: i++; ! 253: continue; ! 254: } ! 255: if (resp[1] != ' ') { ! 256: printf("invalid command\n"); ! 257: flg++; ! 258: print = 0; ! 259: continue; ! 260: } ! 261: for (p = resp+1; (p = getarg(lfil, p)) != NULL; ) ! 262: if (!sendrmt(j, lfil, "/bin/mail")) /* couldn't send it */ ! 263: flg++; ! 264: if (flg) ! 265: print = 0; ! 266: else { ! 267: let[j].change = 'd'; ! 268: changed++; ! 269: i++; ! 270: } ! 271: break; ! 272: case '!': ! 273: system(resp+1); ! 274: printf("!\n"); ! 275: print = 0; ! 276: break; ! 277: case 'd': ! 278: let[j].change = 'd'; ! 279: changed++; ! 280: i++; ! 281: if (resp[1] == 'q') ! 282: goto donep; ! 283: break; ! 284: } ! 285: } ! 286: donep: ! 287: if (changed) ! 288: copyback(); ! 289: } ! 290: ! 291: copyback() /* copy temp or whatever back to /usr/spool/mail */ ! 292: { ! 293: register i, n, c; ! 294: int new = 0; ! 295: struct stat stbuf; ! 296: ! 297: signal(SIGINT, SIG_IGN); ! 298: signal(SIGHUP, SIG_IGN); ! 299: signal(SIGQUIT, SIG_IGN); ! 300: lock(mailfile); ! 301: stat(mailfile, &stbuf); ! 302: if (stbuf.st_size != let[nlet].adr) { /* new mail has arrived */ ! 303: malf = fopen(mailfile, "r"); ! 304: if (malf == NULL) { ! 305: fprintf(stdout, "mail: can't re-read %s\n", mailfile); ! 306: done(); ! 307: } ! 308: fseek(malf, let[nlet].adr, 0); ! 309: fclose(tmpf); ! 310: tmpf = fopen(lettmp, "a"); ! 311: fseek(tmpf, let[nlet].adr, 0); ! 312: while ((c = fgetc(malf)) != EOF) ! 313: fputc(c, tmpf); ! 314: fclose(malf); ! 315: fclose(tmpf); ! 316: tmpf = fopen(lettmp, "r"); ! 317: let[++nlet].adr = stbuf.st_size; ! 318: new = 1; ! 319: } ! 320: malf = fopen(mailfile, "w"); ! 321: if (malf == NULL) { ! 322: fprintf(stderr, "mail: can't rewrite %s\n", lfil); ! 323: done(); ! 324: } ! 325: n = 0; ! 326: for (i = 0; i < nlet; i++) ! 327: if (let[i].change != 'd') { ! 328: copylet(i, malf, ORDINARY); ! 329: n++; ! 330: } ! 331: fclose(malf); ! 332: if (new) ! 333: fprintf(stdout, "new mail arrived\n"); ! 334: unlock(); ! 335: } ! 336: ! 337: copymt(f1, f2) /* copy mail (f1) to temp (f2) */ ! 338: FILE *f1, *f2; ! 339: { ! 340: long nextadr; ! 341: ! 342: nlet = nextadr = 0; ! 343: let[0].adr = 0; ! 344: while (fgets(line, LSIZE, f1) != NULL) { ! 345: if (isfrom(line)) ! 346: let[nlet++].adr = nextadr; ! 347: nextadr += strlen(line); ! 348: fputs(line, f2); ! 349: } ! 350: let[nlet].adr = nextadr; /* last plus 1 */ ! 351: } ! 352: ! 353: copylet(n, f, type) FILE *f; ! 354: { int ch, k; ! 355: fseek(tmpf, let[n].adr, 0); ! 356: k = let[n+1].adr - let[n].adr; ! 357: while(k-- > 1 && (ch=fgetc(tmpf))!='\n') ! 358: if(type!=ZAP) fputc(ch,f); ! 359: if(type==REMOTE) ! 360: fprintf(f, " remote from %s\n", thissys); ! 361: else if (type==FORWARD) ! 362: fprintf(f, forwmsg); ! 363: else if(type==ORDINARY) ! 364: fputc(ch,f); ! 365: while(k-->1) ! 366: fputc(ch=fgetc(tmpf), f); ! 367: if(type!=ZAP || ch!= '\n') ! 368: fputc(fgetc(tmpf), f); ! 369: } ! 370: ! 371: isfrom(lp) ! 372: register char *lp; ! 373: { ! 374: register char *p; ! 375: ! 376: for (p = from; *p; ) ! 377: if (*lp++ != *p++) ! 378: return(0); ! 379: return(1); ! 380: } ! 381: ! 382: sendmail(argc, argv) ! 383: char **argv; ! 384: { ! 385: char truename[100]; ! 386: int first; ! 387: register char *cp; ! 388: int gaver = 0; ! 389: ! 390: truename[0] = 0; ! 391: line[0] = '\0'; ! 392: ! 393: /* ! 394: * When we fall out of this, argv[1] should be first name, ! 395: * argc should be number of names + 1. ! 396: */ ! 397: ! 398: while (argc > 1 && *argv[1] == '-') { ! 399: cp = *++argv; ! 400: argc--; ! 401: switch (cp[1]) { ! 402: case 'r': ! 403: if (argc <= 0) { ! 404: usage(); ! 405: done(); ! 406: } ! 407: gaver++; ! 408: strcpy(truename, argv[1]); ! 409: fgets(line, LSIZE, stdin); ! 410: if (strcmpn("From", line, 4) == 0) ! 411: line[0] = '\0'; ! 412: argv++; ! 413: argc--; ! 414: break; ! 415: ! 416: case 'h': ! 417: if (argc <= 0) { ! 418: usage(); ! 419: done(); ! 420: } ! 421: hseqno = atoi(argv[1]); ! 422: argv++; ! 423: argc--; ! 424: break; ! 425: ! 426: default: ! 427: usage(); ! 428: done(); ! 429: } ! 430: } ! 431: if (argc <= 1) { ! 432: usage(); ! 433: done(); ! 434: } ! 435: if (gaver == 0) ! 436: strcpy(truename, my_name); ! 437: /* ! 438: if (argc > 4 && strcmp(argv[1], "-r") == 0) { ! 439: strcpy(truename, argv[2]); ! 440: argc -= 2; ! 441: argv += 2; ! 442: fgets(line, LSIZE, stdin); ! 443: if (strcmpn("From", line, 4) == 0) ! 444: line[0] = '\0'; ! 445: } else ! 446: strcpy(truename, my_name); ! 447: */ ! 448: time(&iop); ! 449: fprintf(tmpf, "%s%s %s", from, truename, ctime(&iop)); ! 450: iop = ftell(tmpf); ! 451: flgf = 1; ! 452: for (first = 1;; first = 0) { ! 453: if (first && line[0] == '\0' && fgets(line, LSIZE, stdin) == NULL) ! 454: break; ! 455: if (!first && fgets(line, LSIZE, stdin) == NULL) ! 456: break; ! 457: if (line[0] == '.' && line[1] == '\n' && isatty(fileno(stdin))) ! 458: break; ! 459: if (isfrom(line)) ! 460: fputs(">", tmpf); ! 461: fputs(line, tmpf); ! 462: flgf = 0; ! 463: } ! 464: fputs("\n", tmpf); ! 465: nlet = 1; ! 466: let[0].adr = 0; ! 467: let[1].adr = ftell(tmpf); ! 468: fclose(tmpf); ! 469: if (flgf) ! 470: return; ! 471: tmpf = fopen(lettmp, "r"); ! 472: if (tmpf == NULL) { ! 473: fprintf(stderr, "mail: cannot reopen %s for reading\n", lettmp); ! 474: return; ! 475: } ! 476: while (--argc > 0) ! 477: if (!send(0, *++argv, truename)) ! 478: error++; ! 479: if (error) { ! 480: setuid(getuid()); ! 481: malf = fopen(dead, "w"); ! 482: if (malf == NULL) { ! 483: fprintf(stdout, "mail: cannot open %s\n", dead); ! 484: fclose(tmpf); ! 485: return; ! 486: } ! 487: copylet(0, malf, ZAP); ! 488: fclose(malf); ! 489: fprintf(stdout, "Mail saved in %s\n", dead); ! 490: } ! 491: fclose(tmpf); ! 492: } ! 493: ! 494: sendrmt(n, name, rcmd) ! 495: char *name; ! 496: char *rcmd; ! 497: { ! 498: FILE *rmf, *popen(); ! 499: register char *p; ! 500: char rsys[64], cmd[64]; ! 501: register local, pid; ! 502: int sts; ! 503: ! 504: local = 0; ! 505: if (index(name, '^')) { ! 506: while (p = index(name, '^')) ! 507: *p = '!'; ! 508: if (strncmp(name, "researc", 7)) { ! 509: strcpy(rsys, "research"); ! 510: if (*name != '!') ! 511: --name; ! 512: goto skip; ! 513: } ! 514: } ! 515: if (*name=='!') ! 516: name++; ! 517: for(p=rsys; *name!='!'; *p++ = *name++) ! 518: if (*name=='\0') { ! 519: local++; ! 520: break; ! 521: } ! 522: *p = '\0'; ! 523: if ((!local && *name=='\0') || (local && *rsys=='\0')) { ! 524: fprintf(stdout, "null name\n"); ! 525: return(0); ! 526: } ! 527: skip: ! 528: if ((pid = fork()) == -1) { ! 529: fprintf(stderr, "mail: can't create proc for remote\n"); ! 530: return(0); ! 531: } ! 532: if (pid) { ! 533: while (wait(&sts) != pid) { ! 534: if (wait(&sts)==-1) ! 535: return(0); ! 536: } ! 537: return(!sts); ! 538: } ! 539: setuid(getuid()); ! 540: if (local) ! 541: sprintf(cmd, "%s %s", rcmd, rsys); ! 542: else { ! 543: if (index(name+1, '!')) ! 544: sprintf(cmd, "uux - %s!rmail \\(%s\\)", rsys, name+1); ! 545: else ! 546: sprintf(cmd, "uux - %s!rmail %s", rsys, name+1); ! 547: } ! 548: if ((rmf=popen(cmd, "w")) == NULL) ! 549: exit(1); ! 550: copylet(n, rmf, local ? !strcmp(rcmd, "/bin/mail") ? FORWARD : ORDINARY : REMOTE); ! 551: pclose(rmf); ! 552: exit(0); ! 553: } ! 554: ! 555: /* ! 556: * Send mail on the Berkeley network. ! 557: * Sorry Bill, sendrmt() is so awful we just gave up. ! 558: */ ! 559: ! 560: sendberkmail(n, name, fromaddr) ! 561: char name[]; ! 562: char fromaddr[]; ! 563: { ! 564: char cmd[200]; ! 565: register FILE *cmdf; ! 566: ! 567: sprintf(cmd, "%s -h %d -f %s -t %s", RMAIL, hseqno, fromaddr, name); ! 568: if ((cmdf = popen(cmd, "w")) == NULL) { ! 569: perror(RMAIL); ! 570: return(0); ! 571: } ! 572: copylet(n, cmdf, ORDINARY); ! 573: pclose(cmdf); ! 574: return(9); ! 575: } ! 576: ! 577: usage() ! 578: { ! 579: ! 580: fprintf(stderr, "Usage: mail [ -f ] people . . .\n"); ! 581: } ! 582: ! 583: send(n, name, fromaddr) ! 584: int n; ! 585: char *name; ! 586: char *fromaddr; ! 587: { ! 588: char file[50]; ! 589: register char *p; ! 590: register mask; ! 591: struct passwd *pw, *getpwnam(); ! 592: ! 593: stripfx(LOCNAM1, &name); ! 594: stripfx(LOCNAM2, &name); ! 595: stripfx(LOCNAM3, &name); ! 596: stripfx(LOCNAM4, &name); ! 597: if(*name == ':')name++; /* skip colon in to-name */ ! 598: for(p=name; *p!=':' &&*p!='\0'; p++); ! 599: /* if(*p == ':') return(sendrmt(n, name, RMAIL)); */ ! 600: if (*p == ':') ! 601: return(sendberkmail(n, name, fromaddr)); ! 602: else if (strcmp(name, "msgs") == 0) return(sendrmt(n, "-s", "/usr/ucb/msgs")); ! 603: for(p=name; *p!='!'&&*p!='^' &&*p!='\0'; p++) ! 604: ; ! 605: if (*p == '!'|| *p=='^') ! 606: return(sendrmt(n, name, 0)); ! 607: if ((pw = getpwnam(name)) == NULL) { ! 608: fprintf(stdout, "mail: can't send to %s\n", name); ! 609: return(0); ! 610: } ! 611: cat(file, maildir, name); ! 612: mask = umask(MAILMODE); ! 613: malf = fopen(file, "a"); ! 614: umask(mask); ! 615: if (malf == NULL) { ! 616: fprintf(stdout, "mail: cannot append to %s\n", file); ! 617: return(0); ! 618: } ! 619: lock(file); ! 620: chown(file, pw->pw_uid, pw->pw_gid); ! 621: copylet(n, malf, ORDINARY); ! 622: fclose(malf); ! 623: unlock(); ! 624: return(1); ! 625: } ! 626: ! 627: delete(i) ! 628: { ! 629: setsig(i, delete); ! 630: fprintf(stderr, "\n"); ! 631: if(delflg) ! 632: longjmp(sjbuf, 1); ! 633: done(); ! 634: } ! 635: ! 636: /* ! 637: * Lock the specified mail file by setting the file mailfile.lock. ! 638: * We must, of course, be careful to unlink the lock file by a call ! 639: * to unlock before we stop. The algorithm used here is to see if ! 640: * the lock exists, and if it does, to check its modify time. If it ! 641: * is older than 30 seconds, we assume error and set our own file. ! 642: * Otherwise, we wait for 5 seconds and try again. ! 643: */ ! 644: ! 645: char *maillock = ".lock"; /* Lock suffix for mailname */ ! 646: char *lockname = "/usr/spool/mail/tmXXXXXX"; ! 647: char locktmp[30]; /* Usable lock temporary */ ! 648: char curlock[50]; /* Last used name of lock */ ! 649: int locked; /* To note that we locked it */ ! 650: ! 651: lock(file) ! 652: char *file; ! 653: { ! 654: register int f; ! 655: struct stat sbuf; ! 656: long curtime; ! 657: int statfailed; ! 658: ! 659: if (locked || flgf) ! 660: return(0); ! 661: strcpy(curlock, file); ! 662: strcat(curlock, maillock); ! 663: strcpy(locktmp, lockname); ! 664: mktemp(locktmp); ! 665: unlink(locktmp); ! 666: statfailed = 0; ! 667: for (;;) { ! 668: f = lock1(locktmp, curlock); ! 669: if (f == 0) { ! 670: locked = 1; ! 671: return(0); ! 672: } ! 673: if (stat(curlock, &sbuf) < 0) { ! 674: if (statfailed++ > 5) ! 675: return(-1); ! 676: sleep(5); ! 677: continue; ! 678: } ! 679: statfailed = 0; ! 680: time(&curtime); ! 681: if (curtime < sbuf.st_ctime + 30) { ! 682: sleep(5); ! 683: continue; ! 684: } ! 685: unlink(curlock); ! 686: } ! 687: } ! 688: ! 689: /* ! 690: * Remove the mail lock, and note that we no longer ! 691: * have it locked. ! 692: */ ! 693: ! 694: unlock() ! 695: { ! 696: ! 697: unlink(curlock); ! 698: locked = 0; ! 699: } ! 700: ! 701: /* ! 702: * Attempt to set the lock by creating the temporary file, ! 703: * then doing a link/unlink. If it fails, return -1 else 0 ! 704: */ ! 705: ! 706: lock1(tempfile, name) ! 707: char tempfile[], name[]; ! 708: { ! 709: register int fd; ! 710: ! 711: fd = creat(tempfile, 0); ! 712: if (fd < 0) ! 713: return(-1); ! 714: close(fd); ! 715: if (link(tempfile, name) < 0) { ! 716: unlink(tempfile); ! 717: return(-1); ! 718: } ! 719: unlink(tempfile); ! 720: return(0); ! 721: } ! 722: ! 723: done() ! 724: { ! 725: if(locked) ! 726: unlock(); ! 727: unlink(lettmp); ! 728: unlink(locktmp); ! 729: exit(error); ! 730: } ! 731: ! 732: cat(to, from1, from2) ! 733: char *to, *from1, *from2; ! 734: { ! 735: int i, j; ! 736: ! 737: j = 0; ! 738: for (i=0; from1[i]; i++) ! 739: to[j++] = from1[i]; ! 740: for (i=0; from2[i]; i++) ! 741: to[j++] = from2[i]; ! 742: to[j] = 0; ! 743: } ! 744: ! 745: char *getarg(s, p) /* copy p... into s, update p */ ! 746: register char *s, *p; ! 747: { ! 748: while (*p == ' ' || *p == '\t') ! 749: p++; ! 750: if (*p == '\n' || *p == '\0') ! 751: return(NULL); ! 752: while (*p != ' ' && *p != '\t' && *p != '\n' && *p != '\0') ! 753: *s++ = *p++; ! 754: *s = '\0'; ! 755: return(p); ! 756: } ! 757: /* ! 758: stripfx(prefix string, pointer to string) ! 759: ! 760: takes a ptr to string and compares it to prefix string. ! 761: may be called multiple times ! 762: */ ! 763: stripfx(pfx, name) ! 764: char *pfx; ! 765: char **name; ! 766: { ! 767: register char *cp = *name; ! 768: ! 769: while (*pfx && (*cp == *pfx || *cp == toupper(*pfx))) ! 770: cp++, pfx++; ! 771: if (*cp != ':' || *pfx != 0) ! 772: return; ! 773: *name = cp; ! 774: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.