|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1980 Regents of the University of California. ! 3: * All rights reserved. ! 4: * ! 5: * Redistribution and use in source and binary forms are permitted ! 6: * provided that this notice is preserved and that due credit is given ! 7: * to the University of California at Berkeley. The name of the University ! 8: * may not be used to endorse or promote products derived from this ! 9: * software without specific prior written permission. This software ! 10: * is provided ``as is'' without express or implied warranty. ! 11: */ ! 12: ! 13: #ifdef notdef ! 14: static char sccsid[] = "@(#)cmd3.c 5.5 (Berkeley) 2/18/88"; ! 15: #endif /* notdef */ ! 16: ! 17: #include "rcv.h" ! 18: #include <sys/stat.h> ! 19: #include <sys/wait.h> ! 20: ! 21: /* ! 22: * Mail -- a mail program ! 23: * ! 24: * Still more user commands. ! 25: */ ! 26: ! 27: /* ! 28: * Process a shell escape by saving signals, ignoring signals, ! 29: * and forking a sh -c ! 30: */ ! 31: ! 32: shell(str) ! 33: char *str; ! 34: { ! 35: int (*sigint)(), (*sigquit)(); ! 36: union wait stat; ! 37: register int t; ! 38: char *Shell; ! 39: char cmd[BUFSIZ]; ! 40: ! 41: strcpy(cmd, str); ! 42: if (bangexp(cmd) < 0) ! 43: return(-1); ! 44: if ((Shell = value("SHELL")) == NOSTR) ! 45: Shell = SHELL; ! 46: sigint = signal(SIGINT, SIG_IGN); ! 47: sigquit = signal(SIGQUIT, SIG_IGN); ! 48: t = vfork(); ! 49: if (t == 0) { ! 50: if (sigint != SIG_IGN) ! 51: signal(SIGINT, SIG_DFL); ! 52: if (sigquit != SIG_IGN) ! 53: signal(SIGQUIT, SIG_DFL); ! 54: execl(Shell, Shell, "-c", cmd, (char *)0); ! 55: perror(Shell); ! 56: _exit(1); ! 57: } ! 58: while (wait(&stat) != t) ! 59: ; ! 60: if (t == -1) ! 61: perror("fork"); ! 62: signal(SIGINT, sigint); ! 63: signal(SIGQUIT, sigquit); ! 64: printf("!\n"); ! 65: return(0); ! 66: } ! 67: ! 68: /* ! 69: * Fork an interactive shell. ! 70: */ ! 71: ! 72: /*ARGSUSED*/ ! 73: dosh(str) ! 74: char *str; ! 75: { ! 76: int (*sigint)(), (*sigquit)(); ! 77: union wait stat; ! 78: register int t; ! 79: char *Shell; ! 80: ! 81: if ((Shell = value("SHELL")) == NOSTR) ! 82: Shell = SHELL; ! 83: sigint = signal(SIGINT, SIG_IGN); ! 84: sigquit = signal(SIGQUIT, SIG_IGN); ! 85: t = vfork(); ! 86: if (t == 0) { ! 87: if (sigint != SIG_IGN) ! 88: signal(SIGINT, SIG_DFL); ! 89: if (sigquit != SIG_IGN) ! 90: signal(SIGQUIT, SIG_DFL); ! 91: execl(Shell, Shell, (char *)0); ! 92: perror(Shell); ! 93: _exit(1); ! 94: } ! 95: while (wait(&stat) != t) ! 96: ; ! 97: if (t == -1) ! 98: perror("fork"); ! 99: signal(SIGINT, sigint); ! 100: signal(SIGQUIT, sigquit); ! 101: putchar('\n'); ! 102: return(0); ! 103: } ! 104: ! 105: /* ! 106: * Expand the shell escape by expanding unescaped !'s into the ! 107: * last issued command where possible. ! 108: */ ! 109: ! 110: char lastbang[128]; ! 111: ! 112: bangexp(str) ! 113: char *str; ! 114: { ! 115: char bangbuf[BUFSIZ]; ! 116: register char *cp, *cp2; ! 117: register int n; ! 118: int changed = 0; ! 119: ! 120: cp = str; ! 121: cp2 = bangbuf; ! 122: n = BUFSIZ; ! 123: while (*cp) { ! 124: if (*cp == '!') { ! 125: if (n < strlen(lastbang)) { ! 126: overf: ! 127: printf("Command buffer overflow\n"); ! 128: return(-1); ! 129: } ! 130: changed++; ! 131: strcpy(cp2, lastbang); ! 132: cp2 += strlen(lastbang); ! 133: n -= strlen(lastbang); ! 134: cp++; ! 135: continue; ! 136: } ! 137: if (*cp == '\\' && cp[1] == '!') { ! 138: if (--n <= 1) ! 139: goto overf; ! 140: *cp2++ = '!'; ! 141: cp += 2; ! 142: changed++; ! 143: } ! 144: if (--n <= 1) ! 145: goto overf; ! 146: *cp2++ = *cp++; ! 147: } ! 148: *cp2 = 0; ! 149: if (changed) { ! 150: printf("!%s\n", bangbuf); ! 151: fflush(stdout); ! 152: } ! 153: strcpy(str, bangbuf); ! 154: strncpy(lastbang, bangbuf, 128); ! 155: lastbang[127] = 0; ! 156: return(0); ! 157: } ! 158: ! 159: /* ! 160: * Print out a nice help message from some file or another. ! 161: */ ! 162: ! 163: help() ! 164: { ! 165: register c; ! 166: register FILE *f; ! 167: ! 168: if ((f = fopen(HELPFILE, "r")) == NULL) { ! 169: perror(HELPFILE); ! 170: return(1); ! 171: } ! 172: while ((c = getc(f)) != EOF) ! 173: putchar(c); ! 174: fclose(f); ! 175: return(0); ! 176: } ! 177: ! 178: /* ! 179: * Change user's working directory. ! 180: */ ! 181: ! 182: schdir(str) ! 183: char *str; ! 184: { ! 185: register char *cp; ! 186: ! 187: for (cp = str; *cp == ' '; cp++) ! 188: ; ! 189: if (*cp == '\0') ! 190: cp = homedir; ! 191: else ! 192: if ((cp = expand(cp)) == NOSTR) ! 193: return(1); ! 194: if (chdir(cp) < 0) { ! 195: perror(cp); ! 196: return(1); ! 197: } ! 198: return(0); ! 199: } ! 200: ! 201: respond(msgvec) ! 202: int *msgvec; ! 203: { ! 204: if (value("Replyall") == NOSTR) ! 205: return (_respond(msgvec)); ! 206: else ! 207: return (_Respond(msgvec)); ! 208: } ! 209: ! 210: /* ! 211: * Reply to a list of messages. Extract each name from the ! 212: * message header and send them off to mail1() ! 213: */ ! 214: ! 215: _respond(msgvec) ! 216: int *msgvec; ! 217: { ! 218: struct message *mp; ! 219: char *cp, *rcv, *replyto; ! 220: char buf[2 * LINESIZE], **ap; ! 221: struct name *np; ! 222: struct header head; ! 223: ! 224: if (msgvec[1] != 0) { ! 225: printf("Sorry, can't reply to multiple messages at once\n"); ! 226: return(1); ! 227: } ! 228: mp = &message[msgvec[0] - 1]; ! 229: dot = mp; ! 230: rcv = NOSTR; ! 231: cp = skin(nameof(mp, 1)); ! 232: if (cp != NOSTR) ! 233: rcv = cp; ! 234: cp = skin(hfield("from", mp)); ! 235: if (cp != NOSTR) ! 236: rcv = cp; ! 237: replyto = skin(hfield("reply-to", mp)); ! 238: strcpy(buf, ""); ! 239: if (replyto != NOSTR) ! 240: strcpy(buf, replyto); ! 241: else { ! 242: cp = skin(hfield("to", mp)); ! 243: if (cp != NOSTR) ! 244: strcpy(buf, cp); ! 245: } ! 246: np = elide(extract(buf, GTO)); ! 247: mapf(np, rcv); ! 248: /* ! 249: * Delete my name from the reply list, ! 250: * and with it, all my alternate names. ! 251: */ ! 252: np = delname(np, myname, icequal); ! 253: if (altnames) ! 254: for (ap = altnames; *ap; ap++) ! 255: np = delname(np, *ap, icequal); ! 256: head.h_seq = 1; ! 257: cp = detract(np, 0); ! 258: if (cp != NOSTR && replyto == NOSTR) { ! 259: strcpy(buf, cp); ! 260: strcat(buf, " "); ! 261: strcat(buf, rcv); ! 262: } ! 263: else { ! 264: if (cp == NOSTR && replyto != NOSTR) ! 265: printf("Empty reply-to field -- replying to author\n"); ! 266: if (cp == NOSTR) ! 267: strcpy(buf, rcv); ! 268: else ! 269: strcpy(buf, cp); ! 270: } ! 271: head.h_to = buf; ! 272: head.h_subject = hfield("subject", mp); ! 273: if (head.h_subject == NOSTR) ! 274: head.h_subject = hfield("subj", mp); ! 275: head.h_subject = reedit(head.h_subject); ! 276: head.h_cc = NOSTR; ! 277: if (replyto == NOSTR) { ! 278: cp = skin(hfield("cc", mp)); ! 279: if (cp != NOSTR) { ! 280: np = elide(extract(cp, GCC)); ! 281: mapf(np, rcv); ! 282: np = delname(np, myname, icequal); ! 283: if (altnames != 0) ! 284: for (ap = altnames; *ap; ap++) ! 285: np = delname(np, *ap, icequal); ! 286: head.h_cc = detract(np, 0); ! 287: } ! 288: } ! 289: head.h_bcc = NOSTR; ! 290: mail1(&head); ! 291: return(0); ! 292: } ! 293: ! 294: /* ! 295: * Modify the subject we are replying to to begin with Re: if ! 296: * it does not already. ! 297: */ ! 298: ! 299: char * ! 300: reedit(subj) ! 301: char *subj; ! 302: { ! 303: char sbuf[10]; ! 304: register char *newsubj; ! 305: ! 306: if (subj == NOSTR) ! 307: return(NOSTR); ! 308: strncpy(sbuf, subj, 3); ! 309: sbuf[3] = 0; ! 310: if (icequal(sbuf, "re:")) ! 311: return(subj); ! 312: newsubj = salloc(strlen(subj) + 6); ! 313: sprintf(newsubj, "Re: %s", subj); ! 314: return(newsubj); ! 315: } ! 316: ! 317: /* ! 318: * Preserve the named messages, so that they will be sent ! 319: * back to the system mailbox. ! 320: */ ! 321: ! 322: preserve(msgvec) ! 323: int *msgvec; ! 324: { ! 325: register struct message *mp; ! 326: register int *ip, mesg; ! 327: ! 328: if (edit) { ! 329: printf("Cannot \"preserve\" in edit mode\n"); ! 330: return(1); ! 331: } ! 332: for (ip = msgvec; *ip != NULL; ip++) { ! 333: mesg = *ip; ! 334: mp = &message[mesg-1]; ! 335: mp->m_flag |= MPRESERVE; ! 336: mp->m_flag &= ~MBOX; ! 337: dot = mp; ! 338: } ! 339: return(0); ! 340: } ! 341: ! 342: /* ! 343: * Mark all given messages as unread. ! 344: */ ! 345: unread(msgvec) ! 346: int msgvec[]; ! 347: { ! 348: register int *ip; ! 349: ! 350: for (ip = msgvec; *ip != NULL; ip++) { ! 351: dot = &message[*ip-1]; ! 352: dot->m_flag &= ~(MREAD|MTOUCH); ! 353: dot->m_flag |= MSTATUS; ! 354: } ! 355: return(0); ! 356: } ! 357: ! 358: /* ! 359: * Print the size of each message. ! 360: */ ! 361: ! 362: messize(msgvec) ! 363: int *msgvec; ! 364: { ! 365: register struct message *mp; ! 366: register int *ip, mesg; ! 367: ! 368: for (ip = msgvec; *ip != NULL; ip++) { ! 369: mesg = *ip; ! 370: mp = &message[mesg-1]; ! 371: printf("%d: %d/%ld\n", mesg, mp->m_lines, mp->m_size); ! 372: } ! 373: return(0); ! 374: } ! 375: ! 376: /* ! 377: * Quit quickly. If we are sourcing, just pop the input level ! 378: * by returning an error. ! 379: */ ! 380: ! 381: rexit(e) ! 382: { ! 383: if (sourcing) ! 384: return(1); ! 385: if (Tflag != NOSTR) ! 386: close(creat(Tflag, 0600)); ! 387: exit(e); ! 388: /*NOTREACHED*/ ! 389: } ! 390: ! 391: /* ! 392: * Set or display a variable value. Syntax is similar to that ! 393: * of csh. ! 394: */ ! 395: ! 396: set(arglist) ! 397: char **arglist; ! 398: { ! 399: register struct var *vp; ! 400: register char *cp, *cp2; ! 401: char varbuf[BUFSIZ], **ap, **p; ! 402: int errs, h, s; ! 403: ! 404: if (argcount(arglist) == 0) { ! 405: for (h = 0, s = 1; h < HSHSIZE; h++) ! 406: for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) ! 407: s++; ! 408: ap = (char **) salloc(s * sizeof *ap); ! 409: for (h = 0, p = ap; h < HSHSIZE; h++) ! 410: for (vp = variables[h]; vp != NOVAR; vp = vp->v_link) ! 411: *p++ = vp->v_name; ! 412: *p = NOSTR; ! 413: sort(ap); ! 414: for (p = ap; *p != NOSTR; p++) ! 415: printf("%s\t%s\n", *p, value(*p)); ! 416: return(0); ! 417: } ! 418: errs = 0; ! 419: for (ap = arglist; *ap != NOSTR; ap++) { ! 420: cp = *ap; ! 421: cp2 = varbuf; ! 422: while (*cp != '=' && *cp != '\0') ! 423: *cp2++ = *cp++; ! 424: *cp2 = '\0'; ! 425: if (*cp == '\0') ! 426: cp = ""; ! 427: else ! 428: cp++; ! 429: if (equal(varbuf, "")) { ! 430: printf("Non-null variable name required\n"); ! 431: errs++; ! 432: continue; ! 433: } ! 434: assign(varbuf, cp); ! 435: } ! 436: return(errs); ! 437: } ! 438: ! 439: /* ! 440: * Unset a bunch of variable values. ! 441: */ ! 442: ! 443: unset(arglist) ! 444: char **arglist; ! 445: { ! 446: register struct var *vp, *vp2; ! 447: int errs, h; ! 448: char **ap; ! 449: ! 450: errs = 0; ! 451: for (ap = arglist; *ap != NOSTR; ap++) { ! 452: if ((vp2 = lookup(*ap)) == NOVAR) { ! 453: if (!sourcing) { ! 454: printf("\"%s\": undefined variable\n", *ap); ! 455: errs++; ! 456: } ! 457: continue; ! 458: } ! 459: h = hash(*ap); ! 460: if (vp2 == variables[h]) { ! 461: variables[h] = variables[h]->v_link; ! 462: vfree(vp2->v_name); ! 463: vfree(vp2->v_value); ! 464: cfree((char *)vp2); ! 465: continue; ! 466: } ! 467: for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link) ! 468: ; ! 469: vp->v_link = vp2->v_link; ! 470: vfree(vp2->v_name); ! 471: vfree(vp2->v_value); ! 472: cfree((char *) vp2); ! 473: } ! 474: return(errs); ! 475: } ! 476: ! 477: /* ! 478: * Put add users to a group. ! 479: */ ! 480: ! 481: group(argv) ! 482: char **argv; ! 483: { ! 484: register struct grouphead *gh; ! 485: register struct group *gp; ! 486: register int h; ! 487: int s; ! 488: char **ap, *gname, **p; ! 489: ! 490: if (argcount(argv) == 0) { ! 491: for (h = 0, s = 1; h < HSHSIZE; h++) ! 492: for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) ! 493: s++; ! 494: ap = (char **) salloc(s * sizeof *ap); ! 495: for (h = 0, p = ap; h < HSHSIZE; h++) ! 496: for (gh = groups[h]; gh != NOGRP; gh = gh->g_link) ! 497: *p++ = gh->g_name; ! 498: *p = NOSTR; ! 499: sort(ap); ! 500: for (p = ap; *p != NOSTR; p++) ! 501: printgroup(*p); ! 502: return(0); ! 503: } ! 504: if (argcount(argv) == 1) { ! 505: printgroup(*argv); ! 506: return(0); ! 507: } ! 508: gname = *argv; ! 509: h = hash(gname); ! 510: if ((gh = findgroup(gname)) == NOGRP) { ! 511: gh = (struct grouphead *) calloc(sizeof *gh, 1); ! 512: gh->g_name = vcopy(gname); ! 513: gh->g_list = NOGE; ! 514: gh->g_link = groups[h]; ! 515: groups[h] = gh; ! 516: } ! 517: ! 518: /* ! 519: * Insert names from the command list into the group. ! 520: * Who cares if there are duplicates? They get tossed ! 521: * later anyway. ! 522: */ ! 523: ! 524: for (ap = argv+1; *ap != NOSTR; ap++) { ! 525: gp = (struct group *) calloc(sizeof *gp, 1); ! 526: gp->ge_name = vcopy(*ap); ! 527: gp->ge_link = gh->g_list; ! 528: gh->g_list = gp; ! 529: } ! 530: return(0); ! 531: } ! 532: ! 533: /* ! 534: * Sort the passed string vecotor into ascending dictionary ! 535: * order. ! 536: */ ! 537: ! 538: sort(list) ! 539: char **list; ! 540: { ! 541: register char **ap; ! 542: int diction(); ! 543: ! 544: for (ap = list; *ap != NOSTR; ap++) ! 545: ; ! 546: if (ap-list < 2) ! 547: return; ! 548: qsort((char *)list, ap-list, sizeof *list, diction); ! 549: } ! 550: ! 551: /* ! 552: * Do a dictionary order comparison of the arguments from ! 553: * qsort. ! 554: */ ! 555: ! 556: diction(a, b) ! 557: register char **a, **b; ! 558: { ! 559: return(strcmp(*a, *b)); ! 560: } ! 561: ! 562: /* ! 563: * The do nothing command for comments. ! 564: */ ! 565: ! 566: /*ARGSUSED*/ ! 567: null(e) ! 568: { ! 569: return 0; ! 570: } ! 571: ! 572: /* ! 573: * Print out the current edit file, if we are editing. ! 574: * Otherwise, print the name of the person who's mail ! 575: * we are reading. ! 576: */ ! 577: ! 578: file(argv) ! 579: char **argv; ! 580: { ! 581: register char *cp; ! 582: int edit; ! 583: ! 584: if (argv[0] == NOSTR) { ! 585: newfileinfo(); ! 586: return(0); ! 587: } ! 588: ! 589: /* ! 590: * Acker's! Must switch to the new file. ! 591: * We use a funny interpretation -- ! 592: * # -- gets the previous file ! 593: * % -- gets the invoker's post office box ! 594: * %user -- gets someone else's post office box ! 595: * & -- gets invoker's mbox file ! 596: * string -- reads the given file ! 597: */ ! 598: ! 599: cp = getfilename(argv[0], &edit); ! 600: if (cp == NOSTR) ! 601: return(-1); ! 602: if (setfile(cp, edit)) { ! 603: perror(cp); ! 604: return(-1); ! 605: } ! 606: announce(0); ! 607: return 0; ! 608: } ! 609: ! 610: /* ! 611: * Evaluate the string given as a new mailbox name. ! 612: * Ultimately, we want this to support a number of meta characters. ! 613: * Possibly: ! 614: * % -- for my system mail box ! 615: * %user -- for user's system mail box ! 616: * # -- for previous file ! 617: * & -- get's invoker's mbox file ! 618: * file name -- for any other file ! 619: */ ! 620: ! 621: char prevfile[PATHSIZE]; ! 622: ! 623: char * ! 624: getfilename(name, aedit) ! 625: char *name; ! 626: int *aedit; ! 627: { ! 628: register char *cp; ! 629: char savename[BUFSIZ]; ! 630: char oldmailname[BUFSIZ]; ! 631: ! 632: /* ! 633: * Assume we will be in "edit file" mode, until ! 634: * proven wrong. ! 635: */ ! 636: *aedit = 1; ! 637: switch (*name) { ! 638: case '%': ! 639: *aedit = 0; ! 640: strcpy(prevfile, mailname); ! 641: if (name[1] != 0) { ! 642: strcpy(savename, myname); ! 643: strcpy(oldmailname, mailname); ! 644: strncpy(myname, name+1, PATHSIZE-1); ! 645: myname[PATHSIZE-1] = 0; ! 646: findmail(); ! 647: cp = savestr(mailname); ! 648: strcpy(myname, savename); ! 649: strcpy(mailname, oldmailname); ! 650: return(cp); ! 651: } ! 652: strcpy(oldmailname, mailname); ! 653: findmail(); ! 654: cp = savestr(mailname); ! 655: strcpy(mailname, oldmailname); ! 656: return(cp); ! 657: ! 658: case '#': ! 659: if (name[1] != 0) ! 660: goto regular; ! 661: if (prevfile[0] == 0) { ! 662: printf("No previous file\n"); ! 663: return(NOSTR); ! 664: } ! 665: cp = savestr(prevfile); ! 666: strcpy(prevfile, mailname); ! 667: return(cp); ! 668: ! 669: case '&': ! 670: strcpy(prevfile, mailname); ! 671: if (name[1] == 0) ! 672: return(mbox); ! 673: /* Fall into . . . */ ! 674: ! 675: default: ! 676: regular: ! 677: strcpy(prevfile, mailname); ! 678: cp = expand(name); ! 679: return(cp); ! 680: } ! 681: } ! 682: ! 683: /* ! 684: * Expand file names like echo ! 685: */ ! 686: ! 687: echo(argv) ! 688: char **argv; ! 689: { ! 690: register char **ap; ! 691: register char *cp; ! 692: ! 693: for (ap = argv; *ap != NOSTR; ap++) { ! 694: cp = *ap; ! 695: if ((cp = expand(cp)) != NOSTR) ! 696: printf("%s ", cp); ! 697: } ! 698: return(0); ! 699: } ! 700: ! 701: Respond(msgvec) ! 702: int *msgvec; ! 703: { ! 704: if (value("Replyall") == NOSTR) ! 705: return (_Respond(msgvec)); ! 706: else ! 707: return (_respond(msgvec)); ! 708: } ! 709: ! 710: /* ! 711: * Reply to a series of messages by simply mailing to the senders ! 712: * and not messing around with the To: and Cc: lists as in normal ! 713: * reply. ! 714: */ ! 715: ! 716: _Respond(msgvec) ! 717: int msgvec[]; ! 718: { ! 719: struct header head; ! 720: struct message *mp; ! 721: register int s, *ap; ! 722: register char *cp, *cp2, *subject; ! 723: ! 724: for (s = 0, ap = msgvec; *ap != 0; ap++) { ! 725: mp = &message[*ap - 1]; ! 726: dot = mp; ! 727: if ((cp = skin(hfield("from", mp))) != NOSTR) ! 728: s+= strlen(cp) + 1; ! 729: else ! 730: s += strlen(skin(nameof(mp, 2))) + 1; ! 731: } ! 732: if (s == 0) ! 733: return(0); ! 734: cp = salloc(s + 2); ! 735: head.h_to = cp; ! 736: for (ap = msgvec; *ap != 0; ap++) { ! 737: mp = &message[*ap - 1]; ! 738: if ((cp2 = skin(hfield("from", mp))) == NOSTR) ! 739: cp2 = skin(nameof(mp, 2)); ! 740: cp = copy(cp2, cp); ! 741: *cp++ = ' '; ! 742: } ! 743: *--cp = 0; ! 744: mp = &message[msgvec[0] - 1]; ! 745: subject = hfield("subject", mp); ! 746: head.h_seq = 0; ! 747: if (subject == NOSTR) ! 748: subject = hfield("subj", mp); ! 749: head.h_subject = reedit(subject); ! 750: if (subject != NOSTR) ! 751: head.h_seq++; ! 752: head.h_cc = NOSTR; ! 753: head.h_bcc = NOSTR; ! 754: mail1(&head); ! 755: return(0); ! 756: } ! 757: ! 758: /* ! 759: * Conditional commands. These allow one to parameterize one's ! 760: * .mailrc and do some things if sending, others if receiving. ! 761: */ ! 762: ! 763: ifcmd(argv) ! 764: char **argv; ! 765: { ! 766: register char *cp; ! 767: ! 768: if (cond != CANY) { ! 769: printf("Illegal nested \"if\"\n"); ! 770: return(1); ! 771: } ! 772: cond = CANY; ! 773: cp = argv[0]; ! 774: switch (*cp) { ! 775: case 'r': case 'R': ! 776: cond = CRCV; ! 777: break; ! 778: ! 779: case 's': case 'S': ! 780: cond = CSEND; ! 781: break; ! 782: ! 783: default: ! 784: printf("Unrecognized if-keyword: \"%s\"\n", cp); ! 785: return(1); ! 786: } ! 787: return(0); ! 788: } ! 789: ! 790: /* ! 791: * Implement 'else'. This is pretty simple -- we just ! 792: * flip over the conditional flag. ! 793: */ ! 794: ! 795: elsecmd() ! 796: { ! 797: ! 798: switch (cond) { ! 799: case CANY: ! 800: printf("\"Else\" without matching \"if\"\n"); ! 801: return(1); ! 802: ! 803: case CSEND: ! 804: cond = CRCV; ! 805: break; ! 806: ! 807: case CRCV: ! 808: cond = CSEND; ! 809: break; ! 810: ! 811: default: ! 812: printf("Mail's idea of conditions is screwed up\n"); ! 813: cond = CANY; ! 814: break; ! 815: } ! 816: return(0); ! 817: } ! 818: ! 819: /* ! 820: * End of if statement. Just set cond back to anything. ! 821: */ ! 822: ! 823: endifcmd() ! 824: { ! 825: ! 826: if (cond == CANY) { ! 827: printf("\"Endif\" without matching \"if\"\n"); ! 828: return(1); ! 829: } ! 830: cond = CANY; ! 831: return(0); ! 832: } ! 833: ! 834: /* ! 835: * Set the list of alternate names. ! 836: */ ! 837: alternates(namelist) ! 838: char **namelist; ! 839: { ! 840: register int c; ! 841: register char **ap, **ap2, *cp; ! 842: ! 843: c = argcount(namelist) + 1; ! 844: if (c == 1) { ! 845: if (altnames == 0) ! 846: return(0); ! 847: for (ap = altnames; *ap; ap++) ! 848: printf("%s ", *ap); ! 849: printf("\n"); ! 850: return(0); ! 851: } ! 852: if (altnames != 0) ! 853: cfree((char *) altnames); ! 854: altnames = (char **) calloc((unsigned) c, sizeof (char *)); ! 855: for (ap = namelist, ap2 = altnames; *ap; ap++, ap2++) { ! 856: cp = (char *) calloc((unsigned) strlen(*ap) + 1, sizeof (char)); ! 857: strcpy(cp, *ap); ! 858: *ap2 = cp; ! 859: } ! 860: *ap2 = 0; ! 861: return(0); ! 862: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.