home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Distributions / ucb / spencer_2bsd.tar.gz / 2bsd.tar / src / Mail / cmd3.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  6KB  |  359 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #
  3.  
  4. #include "rcv.h"
  5. #include <sys/stat.h>
  6.  
  7. /*
  8.  * Mail -- a mail program
  9.  *
  10.  * Still more user commands.
  11.  */
  12.  
  13. /*
  14.  * Process a shell escape by saving signals, ignoring signals,
  15.  * and forking a sh -c
  16.  */
  17.  
  18. shell(str)
  19.     char *str;
  20. {
  21.     int (*sig[2])(), stat[1];
  22.     register int t;
  23.     char *Shell;
  24.  
  25.     if ((Shell = value("SHELL")) == NOSTR)
  26.         Shell = "/bin/sh";
  27.     for (t = 2; t < 4; t++)
  28.         sig[t-2] = signal(t, SIG_IGN);
  29.     t = fork();
  30.     if (t == 0) {
  31.         for (t = 2; t < 4; t++)
  32.             if (sig[t-2] != SIG_IGN)
  33.                 signal(t, SIG_DFL);
  34.         execl(Shell, Shell, "-c", str, 0);
  35.         perror(Shell);
  36.         exit(1);
  37.     }
  38.     while (wait(stat) != t)
  39.         ;
  40.     if (t == -1)
  41.         perror("fork");
  42.     for (t = 2; t < 4; t++)
  43.         signal(t, sig[t-2]);
  44.     printf("!\n");
  45.     return(0);
  46. }
  47.  
  48. /*
  49.  * Print out a nice help message from some file or another.
  50.  */
  51.  
  52. help()
  53. {
  54.     register c;
  55.     register FILE *f;
  56.  
  57.     if ((f = fopen(HELPFILE, "r")) == NULL) {
  58.         printf("No help just now.\n");
  59.         return(1);
  60.     }
  61.     while ((c = getc(f)) != EOF)
  62.         putchar(c);
  63.     fclose(f);
  64.     return(0);
  65. }
  66.  
  67. /*
  68.  * Change user's working directory.
  69.  */
  70.  
  71. schdir(str)
  72.     char *str;
  73. {
  74.     register char *cp;
  75.  
  76.     for (cp = str; *cp == ' '; cp++)
  77.         ;
  78.     if (*cp == '\0')
  79.         cp = homedir;
  80.     if (chdir(cp) < 0) {
  81.         perror(cp);
  82.         return(1);
  83.     }
  84.     return(0);
  85. }
  86.  
  87. /*
  88.  * Reply to a list of messages.  Extract each name from the
  89.  * message header and send them off to mail()
  90.  */
  91.  
  92. respond(msgvec)
  93.     int *msgvec;
  94. {
  95.     register struct message *mp;
  96.     register char **ap;
  97.     register int *ip;
  98.     int s;
  99.     char *cp2, *buf;
  100.     struct header head;
  101.  
  102.     for (ip = msgvec, s = 0; *ip; ip++) {
  103.         mp = &message[*ip - 1];
  104.         s += strlen(nameof(mp))+1;
  105.     }
  106.     buf = salloc(s+1);
  107.     cp2 = buf;
  108.     for (ip = msgvec; *ip; ip++) {
  109.         touch(*ip);
  110.         mp = &message[*ip - 1];
  111.         dot = mp;
  112.         cp2 = copy(nameof(mp), cp2);
  113.         *cp2++ = ' ';
  114.     }
  115.     if (cp2 != buf)
  116.         cp2--;
  117.     *cp2 = '\0';
  118.     mp = &message[msgvec[0]-1];
  119.     head.h_seq = 1;
  120.     head.h_to = buf;
  121.     head.h_subj = hfield("subj", mp);
  122.     head.h_cc = hfield("cc", mp);
  123.     mail1(&head);
  124.     return(0);
  125. }
  126.  
  127. /*
  128.  * Preserve the named messages, so that they will be sent
  129.  * back to the system mailbox.
  130.  */
  131.  
  132. preserve(msgvec)
  133.     int *msgvec;
  134. {
  135.     register struct message *mp;
  136.     register int *ip, mesg;
  137.  
  138.     if (edit) {
  139.         printf("Cannot \"preserve\" in edit mode\n");
  140.         return(1);
  141.     }
  142.     for (ip = msgvec; *ip != NULL; ip++) {
  143.         mesg = *ip;
  144.         mp = &message[mesg-1];
  145.         mp->m_flag |= MPRESERVE;
  146.         dot = mp;
  147.     }
  148.     return(0);
  149. }
  150.  
  151. /*
  152.  * Print the size of each message.
  153.  */
  154.  
  155. messize(msgvec)
  156.     int *msgvec;
  157. {
  158.     register struct message *mp;
  159.     register int *ip, mesg;
  160.  
  161.     for (ip = msgvec; *ip != NULL; ip++) {
  162.         mesg = *ip;
  163.         mp = &message[mesg-1];
  164.         printf("%d: %d\n", mesg, msize(mp));
  165.     }
  166.     return(0);
  167. }
  168.  
  169. /*
  170.  * Quit quickly.  If we are sourcing, just pop the input level
  171.  * by returning an error.
  172.  */
  173.  
  174. rexit(e)
  175. {
  176.     if (sourcing)
  177.         return(1);
  178.     exit(e);
  179. }
  180.  
  181. /*
  182.  * Set or display a variable value.  Syntax is similar to that
  183.  * of csh.
  184.  */
  185.  
  186. set(arglist)
  187.     char **arglist;
  188. {
  189.     register struct var *vp;
  190.     register char *cp, *cp2;
  191.     char varbuf[BUFSIZ], **ap, **p;
  192.     int errs, h, s;
  193.  
  194.     if (argcount(arglist) == 0) {
  195.         for (h = 0, s = 1; h < HSHSIZE; h++)
  196.             for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
  197.                 s++;
  198.         ap = (char **) salloc(s * sizeof *ap);
  199.         for (h = 0, p = ap; h < HSHSIZE; h++)
  200.             for (vp = variables[h]; vp != NOVAR; vp = vp->v_link)
  201.                 *p++ = vp->v_name;
  202.         *p = NOSTR;
  203.         sort(ap);
  204.         for (p = ap; *p != NOSTR; p++)
  205.             printf("%s\t%s\n", *p, value(*p));
  206.         return(0);
  207.     }
  208.     errs = 0;
  209.     for (ap = arglist; *ap != NOSTR; ap++) {
  210.         cp = *ap;
  211.         cp2 = varbuf;
  212.         while (*cp != '=' && *cp != '\0')
  213.             *cp2++ = *cp++;
  214.         *cp2 = '\0';
  215.         if (*cp == '\0')
  216.             cp = "";
  217.         else
  218.             cp++;
  219.         if (equal(varbuf, "")) {
  220.             printf("Non-null variable name required\n");
  221.             errs++;
  222.             continue;
  223.         }
  224.         assign(varbuf, cp);
  225.     }
  226.     return(errs);
  227. }
  228.  
  229. /*
  230.  * Unset a bunch of variable values.
  231.  */
  232.  
  233. unset(arglist)
  234.     char **arglist;
  235. {
  236.     register struct var *vp, *vp2;
  237.     register char *cp;
  238.     int errs, h;
  239.     char **ap;
  240.  
  241.     errs = 0;
  242.     for (ap = arglist; *ap != NOSTR; ap++) {
  243.         if ((vp2 = lookup(*ap)) == NOVAR) {
  244.             printf("\"%s\": undefined variable\n", *ap);
  245.             errs++;
  246.             continue;
  247.         }
  248.         h = hash(*ap);
  249.         if (vp2 == variables[h]) {
  250.             variables[h] = variables[h]->v_link;
  251.             vfree(vp2->v_name);
  252.             vfree(vp2->v_value);
  253.             cfree(vp2);
  254.             continue;
  255.         }
  256.         for (vp = variables[h]; vp->v_link != vp2; vp = vp->v_link)
  257.             ;
  258.         vp->v_link = vp2->v_link;
  259.         vfree(vp2->v_name);
  260.         vfree(vp2->v_value);
  261.         cfree(vp2);
  262.     }
  263.     return(errs);
  264. }
  265.  
  266. /*
  267.  * Put add users to a group.
  268.  */
  269.  
  270. group(argv)
  271.     char **argv;
  272. {
  273.     register struct grouphead *gh;
  274.     register struct group *gp;
  275.     register int h;
  276.     int s;
  277.     char **ap, *gname, **p;
  278.  
  279.     if (argcount(argv) == 0) {
  280.         for (h = 0, s = 1; h < HSHSIZE; h++)
  281.             for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
  282.                 s++;
  283.         ap = (char **) salloc(s * sizeof *ap);
  284.         for (h = 0, p = ap; h < HSHSIZE; h++)
  285.             for (gh = groups[h]; gh != NOGRP; gh = gh->g_link)
  286.                 *p++ = gh->g_name;
  287.         *p = NOSTR;
  288.         sort(ap);
  289.         for (p = ap; *p != NOSTR; p++)
  290.             printgroup(*p);
  291.         return(0);
  292.     }
  293.     if (argcount(argv) == 1) {
  294.         printgroup(*argv);
  295.         return(0);
  296.     }
  297.     gname = *argv;
  298.     h = hash(gname);
  299.     if ((gh = findgroup(gname)) == NOGRP) {
  300.         gh = (struct grouphead *) calloc(sizeof *gh, 1);
  301.         gh->g_name = vcopy(gname);
  302.         gh->g_list = NOGE;
  303.         gh->g_link = groups[h];
  304.         groups[h] = gh;
  305.     }
  306.  
  307.     /*
  308.      * Insert names from the command list into the group.
  309.      * Who cares if there are duplicates?  They got tossed
  310.      * later anyway.
  311.      */
  312.  
  313.     for (ap = argv+1; *ap != NOSTR; ap++) {
  314.         gp = (struct group *) calloc(sizeof *gp, 1);
  315.         gp->ge_name = vcopy(*ap);
  316.         gp->ge_link = gh->g_list;
  317.         gh->g_list = gp;
  318.     }
  319.     return(0);
  320. }
  321.  
  322. /*
  323.  * Sort the passed string vecotor into ascending dictionary
  324.  * order.
  325.  */
  326.  
  327. sort(list)
  328.     char **list;
  329. {
  330.     register char **ap;
  331.     int diction();
  332.  
  333.     for (ap = list; *ap != NOSTR; ap++)
  334.         ;
  335.     if (ap-list < 2)
  336.         return;
  337.     qsort(list, ap-list, sizeof *list, diction);
  338. }
  339.  
  340. /*
  341.  * Do a dictionary order comparison of the arguments from
  342.  * qsort.
  343.  */
  344.  
  345. diction(a, b)
  346.     register char **a, **b;
  347. {
  348.     return(strcmp(*a, *b));
  349. }
  350.  
  351. /*
  352.  * The do nothing command for comments.
  353.  */
  354.  
  355. null(e)
  356. {
  357.     return(0);
  358. }
  359.