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