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 / cmd2.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  5KB  |  308 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.  * More user commands.
  11.  */
  12.  
  13. /*
  14.  * If any arguments were given, go to the next applicable argument
  15.  * following dot, otherwise, go to the next applicable message.
  16.  * If given as first command with no arguments, print first message.
  17.  */
  18.  
  19. next(msgvec)
  20.     int *msgvec;
  21. {
  22.     register struct message *mp;
  23.     register int *ip, *ip2;
  24.     int list[2], mdot;
  25.  
  26.     if (*msgvec != NULL) {
  27.  
  28.         /*
  29.          * If some messages were supplied, find the 
  30.          * first applicable one following dot using
  31.          * wrap around.
  32.          */
  33.  
  34.         mdot = dot - &message[0] + 1;
  35.         for (ip = msgvec; *ip != NULL; ip++)
  36.             if (*ip > mdot)
  37.                 break;
  38.         if (*ip == NULL)
  39.             ip = msgvec;
  40.         ip2 = ip;
  41.         do {
  42.             if (*ip2 != NULL)
  43.                 ip2++;
  44.             if (*ip2 == NULL)
  45.                 ip2 = msgvec;
  46.             mp = &message[*ip2 - 1];
  47.             if ((mp->m_flag & (MDELETED|MSAVED)) == 0) {
  48.                 dot = mp;
  49.                 goto hitit;
  50.             }
  51.         } while (ip2 != ip);
  52.         printf("No messages applicable\n");
  53.         return(1);
  54.     }
  55.  
  56.     /*
  57.      * If this is the first command, select message 1.
  58.      * Note that this must exist for us to get here at all.
  59.      */
  60.  
  61.     if (!sawcom) {
  62.         dot = &message[0];
  63.         goto hitit;
  64.     }
  65.  
  66.     /*
  67.      * Just find the next good message after dot, no
  68.      * wraparound.
  69.      */
  70.  
  71.     for (mp = dot+1; mp < &message[msgCount]; mp++)
  72.         if ((mp->m_flag & (MDELETED|MSAVED)) == 0)
  73.             break;
  74.     if (mp >= &message[msgCount]) {
  75.         printf("At EOF\n");
  76.         return(0);
  77.     }
  78.     dot = mp;
  79. hitit:
  80.     /*
  81.      * Print dot.
  82.      */
  83.  
  84.     list[0] = dot - &message[0] + 1;
  85.     list[1] = NULL;
  86.     return(type(list));
  87. }
  88.  
  89. /*
  90.  * Save the indicated messages at the end of the passed file name.
  91.  */
  92.  
  93. save(str)
  94.     char str[];
  95. {
  96.     register int *ip, mesg;
  97.     register struct message *mp;
  98.     char *file;
  99.     int f, *msgvec, lc, cc, t;
  100.     FILE *obuf;
  101.  
  102.     msgvec = (int *) salloc((msgCount * sizeof *msgvec) + 2);
  103.     if ((file = snarf(str, &f)) == NOSTR)
  104.         return(1);
  105.     if (!f) {
  106.         *msgvec = first(0, MMNORM);
  107.         if (*msgvec == NULL) {
  108.             printf("No messages to save.\n");
  109.             return(1);
  110.         }
  111.         msgvec[1] = NULL;
  112.     }
  113.     if (f && getmsglist(str, msgvec, 0) < 0)
  114.         return(1);
  115.     if ((obuf = fopen(file, "a")) == NULL) {
  116.         perror(file);
  117.         return(1);
  118.     }
  119.     printf("\"%s\" ", file);
  120.     flush();
  121.     cc = lc = 0;
  122.     for (ip = msgvec; *ip && ip-msgvec < msgCount; ip++) {
  123.         mesg = *ip;
  124.         touch(mesg);
  125.         mp = &message[mesg-1];
  126.         if ((t = send(mp, obuf)) < 0) {
  127.             perror(file);
  128.             fclose(obuf);
  129.             return(1);
  130.         }
  131.         lc += t;
  132.         cc += msize(mp);
  133.         mp->m_flag |= MSAVED;
  134.     }
  135.     fflush(obuf);
  136.     if (ferror(obuf))
  137.         perror(file);
  138.     fclose(obuf);
  139.     printf("%d/%d\n", lc, cc);
  140.     return(0);
  141. }
  142.  
  143. /*
  144.  * Snarf the file from the end of the command line and
  145.  * return a pointer to it.  If there is no file attached,
  146.  * just return NOSTR.  Put a null in front of the file
  147.  * name so that the message list processing won't see it,
  148.  * unless the file name is the only thing on the line, in
  149.  * which case, return 0 in the reference flag variable.
  150.  */
  151.  
  152. char *
  153. snarf(linebuf, flag)
  154.     char linebuf[];
  155.     int *flag;
  156. {
  157.     register char *cp;
  158.  
  159.     *flag = 1;
  160.     cp = strlen(linebuf) + linebuf - 1;
  161.  
  162.     /*
  163.      * Strip away trailing blanks.
  164.      */
  165.  
  166.     while (*cp == ' ' && cp > linebuf)
  167.         cp--;
  168.     *++cp = 0;
  169.  
  170.     /*
  171.      * Now search for the beginning of the file name.
  172.      */
  173.  
  174.     while (cp > linebuf && !any(*cp, "\t "))
  175.         cp--;
  176.     if (*cp == '\0') {
  177.         printf("No file specified.\n");
  178.         return(NOSTR);
  179.     }
  180.     if (any(*cp, " \t"))
  181.         *cp++ = 0;
  182.     else
  183.         *flag = 0;
  184.     return(cp);
  185. }
  186.  
  187. /*
  188.  * Delete messages.
  189.  */
  190.  
  191. delete(msgvec)
  192.     int msgvec[];
  193. {
  194.     return(delm(msgvec));
  195. }
  196.  
  197. /*
  198.  * Delete messages, then type the new dot.
  199.  */
  200.  
  201. deltype(msgvec)
  202.     int msgvec[];
  203. {
  204.     int list[2];
  205.  
  206.     if (delm(msgvec) >= 0) {
  207.         list[0] = dot - &message[0];
  208.         list[0]++;
  209.         touch(list[0]);
  210.         list[1] = NULL;
  211.         return(type(list));
  212.     }
  213.     else {
  214.         printf("No more messages\n");
  215.         return(0);
  216.     }
  217. }
  218.  
  219. /*
  220.  * Delete the indicated messages.
  221.  * Set dot to some nice place afterwards.
  222.  * Internal interface.
  223.  */
  224.  
  225. delm(msgvec)
  226.     int *msgvec;
  227. {
  228.     register struct message *mp;
  229.     register *ip, mesg;
  230.     int last;
  231.  
  232.     last = NULL;
  233.     for (ip = msgvec; *ip != NULL; ip++) {
  234.         mesg = *ip;
  235.         touch(mesg);
  236.         mp = &message[mesg-1];
  237.         mp->m_flag |= MDELETED;
  238.         mp->m_flag &= ~MPRESERVE;
  239.         last = mesg;
  240.     }
  241.     if (last != NULL) {
  242.         dot = &message[last-1];
  243.         last = first(0, MDELETED);
  244.         if (last != NULL) {
  245.             dot = &message[last-1];
  246.             return(0);
  247.         }
  248.         else {
  249.             dot = &message[0];
  250.             return(-1);
  251.         }
  252.     }
  253.  
  254.     /*
  255.      * Following can't happen -- it keeps lint happy
  256.      */
  257.  
  258.     return(-1);
  259. }
  260.  
  261. /*
  262.  * Undelete the indicated messages.
  263.  */
  264.  
  265. undelete(msgvec)
  266.     int *msgvec;
  267. {
  268.     register struct message *mp;
  269.     register *ip, mesg;
  270.  
  271.     for (ip = msgvec; ip-msgvec < msgCount; ip++) {
  272.         mesg = *ip;
  273.         if (mesg == 0)
  274.             return;
  275.         touch(mesg);
  276.         mp = &message[mesg-1];
  277.         dot = mp;
  278.         mp->m_flag &= ~MDELETED;
  279.     }
  280. }
  281.  
  282. /*
  283.  * Interactively dump core on "core"
  284.  */
  285.  
  286. core()
  287. {
  288.     register int pid;
  289.     int status;
  290.  
  291.     if ((pid = fork()) == -1) {
  292.         perror("fork");
  293.         return(1);
  294.     }
  295.     if (pid == 0) {
  296.         abort();
  297.         exit(1);
  298.     }
  299.     printf("Okie dokie");
  300.     fflush(stdout);
  301.     while (wait(&status) != pid)
  302.         ;
  303.     if (status & 0200)
  304.         printf(" -- Core dumped\n");
  305.     else
  306.         printf("\n");
  307. }
  308.