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: }

Defined functions

Respond defined in line 690; used 3 times
_Respond defined in line 705; used 2 times
_respond defined in line 204; used 2 times
alternates defined in line 826; used 2 times
bangexp defined in line 101; used 1 times
  • in line 34
diction defined in line 546; used 2 times
dosh defined in line 64; used 2 times
echo defined in line 676; used 2 times
elsecmd defined in line 784; used 2 times
endifcmd defined in line 812; used 2 times
file defined in line 567; used 3 times
getfilename defined in line 612; used 2 times
group defined in line 471; used 3 times
help defined in line 152; used 3 times
ifcmd defined in line 752; used 2 times
messize defined in line 352; used 2 times
null defined in line 556; used 2 times
preserve defined in line 312; used 3 times
reedit defined in line 289; used 3 times
respond defined in line 190; used 3 times
rexit defined in line 371; used 3 times
schdir defined in line 171; used 3 times
set defined in line 385; used 2 times
shell defined in line 25; used 4 times
sort defined in line 528; used 2 times
unread defined in line 335; used 5 times
unset defined in line 432; used 2 times

Defined variables

lastbang defined in line 99; used 6 times
prevfile defined in line 610; used 6 times
sccsid defined in line 8; never used
Last modified: 1985-09-18
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2473
Valid CSS Valid XHTML 1.0 Strict