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 / aux.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  5KB  |  359 lines

  1. /* Copyright (c) 1979 Regents of the University of California */
  2. #
  3.  
  4. #include "rcv.h"
  5. #include <sys/stat.h>
  6. #include <sgtty.h>
  7.  
  8. /*
  9.  * Mail -- a mail program
  10.  *
  11.  * Auxiliary functions.
  12.  */
  13.  
  14. /*
  15.  * Return a pointer to a dynamic copy of the argument.
  16.  */
  17.  
  18. char *
  19. savestr(str)
  20.     char *str;
  21. {
  22.     register char *cp, *cp2, *top;
  23.  
  24.     for (cp = str; *cp; cp++)
  25.         ;
  26.     top = salloc(cp-str + 1);
  27.     if (top == NOSTR)
  28.         return(NOSTR);
  29.     for (cp = str, cp2 = top; *cp; cp++)
  30.         *cp2++ = *cp;
  31.     *cp2 = 0;
  32.     return(top);
  33. }
  34.  
  35. /*
  36.  * Copy the name from the passed header line into the passed
  37.  * name buffer.  Null pad the name buffer.
  38.  */
  39.  
  40. copyname(linebuf, nbuf)
  41.     char *linebuf, *nbuf;
  42. {
  43.     register char *cp, *cp2;
  44.  
  45.     for (cp = linebuf + 5, cp2 = nbuf; *cp != ' ' && cp2-nbuf < 8; cp++)
  46.         *cp2++ = *cp;
  47.     while (cp2-nbuf < 8)
  48.         *cp2++ = 0;
  49. }
  50.  
  51. /*
  52.  * Announce a fatal error and die.
  53.  */
  54.  
  55. panic(str)
  56.     char *str;
  57. {
  58.     prs("panic: ");
  59.     prs(str);
  60.     prs("\n");
  61.     exit(1);
  62. }
  63.  
  64. /*
  65.  * Catch stdio errors and report them more nicely.
  66.  */
  67.  
  68. _error(str)
  69.     char *str;
  70. {
  71.     prs("Stdio Error: ");
  72.     prs(str);
  73.     prs("\n");
  74.     abort();
  75. }
  76.  
  77. /*
  78.  * Print a string on diagnostic output.
  79.  */
  80.  
  81. prs(str)
  82.     char *str;
  83. {
  84.     register char *s;
  85.  
  86.     for (s = str; *s; s++)
  87.         ;
  88.     write(2, str, s-str);
  89. }
  90.  
  91. /*
  92.  * Touch the named message by setting its MTOUCH flag.
  93.  * Touched messages have the effect of not being sent
  94.  * back to the system mailbox on exit.
  95.  */
  96.  
  97. touch(mesg)
  98. {
  99.     if (mesg >= 1 && mesg <= msgCount)
  100.         message[mesg-1].m_flag |= MTOUCH;
  101. }
  102.  
  103. /*
  104.  * Test to see if the passed file name is a directory.
  105.  * Return true if it is.
  106.  */
  107.  
  108. isdir(name)
  109.     char name[];
  110. {
  111.     struct stat sbuf;
  112.  
  113.     if (stat(name, &sbuf) < 0)
  114.         return(0);
  115.     return((sbuf.st_mode & S_IFMT) == S_IFDIR);
  116. }
  117.  
  118. /*
  119.  * Compute the size in characters of the passed message
  120.  */
  121.  
  122. unsigned int
  123. msize(messp)
  124.     struct message *messp;
  125. {
  126.     register struct message *mp;
  127.  
  128.     mp = messp;
  129.     return(mp->m_size);
  130. }
  131.  
  132. /*
  133.  * Count the number of arguments in the given string raw list.
  134.  */
  135.  
  136. argcount(argv)
  137.     char **argv;
  138. {
  139.     register char **ap;
  140.  
  141.     for (ap = argv; *ap != NOSTR; ap++)
  142.         ;    
  143.     return(ap-argv);
  144. }
  145.  
  146. /*
  147.  * Given a file address, determine the
  148.  * block number it represents.
  149.  */
  150.  
  151. blockof(off)
  152.     off_t off;
  153. {
  154.     off_t a;
  155.  
  156.     a = off >> 9;
  157.     a &= 077777;
  158.     return((int) a);
  159. }
  160.  
  161. /*
  162.  * Take a file address, and determine
  163.  * its offset in the current block.
  164.  */
  165.  
  166. offsetof(off)
  167.     off_t off;
  168. {
  169.     off_t a;
  170.  
  171.     a = off & 0777;
  172.     return((int) a);
  173. }
  174.  
  175. /*
  176.  * Determine if the passed file is actually a tty, via a call to
  177.  * gtty.  This is not totally reliable, but . . .
  178.  */
  179.  
  180. isatty(f)
  181. {
  182.     struct sgttyb buf;
  183.  
  184.     if (gtty(f, &buf) < 0)
  185.         return(0);
  186.     return(1);
  187. }
  188.  
  189. /*
  190.  * Return the desired header line from the passed message
  191.  * pointer (or NOSTR if the desired header field is not available.
  192.  */
  193.  
  194. char *
  195. hfield(field, mp)
  196.     char field[];
  197.     struct message *mp;
  198. {
  199.     FILE *ibuf;
  200.     char linebuf[LINESIZE];
  201.     register char *cp, *cp2;
  202.     int hfc;
  203.  
  204.     ibuf = setinput(mp);
  205.     hfc = 0;
  206.     while (readline(ibuf, linebuf) > 0 && hfc < HDRFIELDS) {
  207.         if (equal(linebuf, ""))
  208.             return(NOSTR);
  209.         cp = linebuf;
  210.         cp2 = field;
  211.         while (raise(*cp++) == raise(*cp2++))
  212.             ;
  213.         if (*--cp == ':' && *--cp2 == '\0') {
  214.             cp++;
  215.             while (any(*cp, " \t"))
  216.                 cp++;
  217.             return(savestr(cp));
  218.         }
  219.         hfc++;
  220.     }
  221.     return(NOSTR);
  222. }
  223.  
  224. /*
  225.  * The following code deals with input stacking to do source
  226.  * commands.  All but the current file pointer are saved on
  227.  * the stack.
  228.  */
  229.  
  230. static    int    ssp = -1;        /* Top of file stack */
  231. static    FILE    *sstack[_NFILE];    /* Saved input files */
  232.  
  233. /*
  234.  * Pushdown current input file and switch to a new one.
  235.  * Set the global flag "sourcing" so that others will realize
  236.  * that they are no longer reading from a tty (in all probability).
  237.  */
  238.  
  239. source(name)
  240.     char name[];
  241. {
  242.     register FILE *fi;
  243.  
  244.     if ((fi = fopen(name, "r")) == NULL) {
  245.         perror(name);
  246.         return(1);
  247.     }
  248.     if (ssp >= _NFILE-2) {
  249.         printf("Too much \"sourcing\" going on.\n");
  250.         fclose(fi);
  251.         return(1);
  252.     }
  253.     sstack[++ssp] = input;
  254.     input = fi;
  255.     sourcing++;
  256.     return(0);
  257. }
  258.  
  259. /*
  260.  * Source a file, but do nothing if the file cannot be opened.
  261.  */
  262.  
  263. source1(name)
  264.     char name[];
  265. {
  266.     register int f;
  267.  
  268.     if ((f = open(name, 0)) < 0)
  269.         return(0);
  270.     close(f);
  271.     source(name);
  272. }
  273.  
  274. /*
  275.  * Pop the current input back to the previous level.
  276.  * Update the "sourcing" flag as appropriate.
  277.  */
  278.  
  279. unstack()
  280. {
  281.     if (ssp < 0) {
  282.         printf("\"Source\" stack over-pop.\n");
  283.         sourcing = 0;
  284.         return(1);
  285.     }
  286.     fclose(input);
  287.     input = sstack[ssp--];
  288.     if (ssp < 0)
  289.         sourcing = 0;
  290.     return(0);
  291. }
  292.  
  293. /*
  294.  * Touch the indicated file.
  295.  * This is nifty for the shell.
  296.  */
  297.  
  298. alter(name)
  299.     char name[];
  300. {
  301.     register int pid, f;
  302.     char w;
  303.  
  304.     if ((pid = fork()) != 0)
  305.         return;
  306.     clrbuf(stdout);
  307.     clrbuf(stderr);
  308.     clrbuf(stdin);
  309.     sleep(1);
  310.     if ((f = open(name, 0)) < 0)
  311.         exit(1);
  312.     read(f, &w, 1);
  313.     exit(0);
  314. }
  315.  
  316. /*
  317.  * Examine the passed line buffer and
  318.  * return true if it is all blanks and tabs.
  319.  */
  320.  
  321. blankline(linebuf)
  322.     char linebuf[];
  323. {
  324.     register char *cp;
  325.  
  326.     for (cp = linebuf; *cp; cp++)
  327.         if (!any(*cp, " \t"))
  328.             return(0);
  329.     return(1);
  330. }
  331.  
  332. /*
  333.  * Fetch the sender's name from the passed message.
  334.  */
  335.  
  336. char *
  337. nameof(mp)
  338.     register struct message *mp;
  339. {
  340.     static char namebuf[NAMESIZE];
  341.     char linebuf[LINESIZE];
  342.     register char *cp, *cp2;
  343.     register FILE *ibuf;
  344.  
  345.     ibuf = setinput(mp);
  346.     copy("", namebuf);
  347.     if (readline(ibuf, linebuf) <= 0)
  348.         return(namebuf);
  349.     for (cp = linebuf; *cp != ' '; cp++)
  350.         ;
  351.     while (any(*cp, " \t"))
  352.         cp++;
  353.     for (cp2 = namebuf; *cp && !any(*cp, " \t") &&
  354.         cp2-namebuf < NAMESIZE-1; *cp2++ = *cp++)
  355.         ;
  356.     *cp2 = '\0';
  357.     return(namebuf);
  358. }
  359.