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