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 / fio.c < prev    next >
C/C++ Source or Header  |  1980-02-17  |  5KB  |  292 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.  * File I/O.
  11.  */
  12.  
  13. /*
  14.  * Set up the input pointers while copying the mail file into
  15.  * /tmp.
  16.  */
  17.  
  18. setptr(ibuf)
  19.     FILE *ibuf;
  20. {
  21.     register int count, s, l;
  22.     off_t offset;
  23.     char linebuf[LINESIZE];
  24.     int maybe, mestmp;
  25.     struct message this;
  26.     extern char tempSet[];
  27.  
  28.     if ((mestmp = opentemp(tempSet)) < 0)
  29.         exit(1);
  30.     msgCount = 0;
  31.     offset = 0;
  32.     s = 0;
  33.     l = 0;
  34.     maybe = 1;
  35.     for (;;) {
  36.         if ((count = readline(ibuf, linebuf)) == 0) {
  37.             this.m_offset = offsetof(offset);
  38.             this.m_block = blockof(offset);
  39.             this.m_size = s;
  40.             this.m_lines = l;
  41.             if (append(&this, mestmp)) {
  42.                 perror(tempSet);
  43.                 exit(1);
  44.             }
  45.             fclose(ibuf);
  46.             makemessage(mestmp);
  47.             close(mestmp);
  48.             return;
  49.         }
  50.         if (putline(otf, linebuf) < 0) {
  51.             perror("/tmp");
  52.             exit(1);
  53.         }
  54.         if (maybe && ishead(linebuf)) {
  55.             msgCount++;
  56.             this.m_flag = MUSED;
  57.             this.m_block = blockof(offset);
  58.             this.m_offset = offsetof(offset);
  59.             this.m_size = s;
  60.             this.m_lines = l;
  61.             s = 0;
  62.             l = 0;
  63.             if (append(&this, mestmp)) {
  64.                 perror(tempSet);
  65.                 exit(1);
  66.             }
  67.         }
  68.         offset += count;
  69.         s += count;
  70.         l++;
  71.         maybe = 0;
  72.         if (linebuf[0] == 0)
  73.             maybe = 1;
  74.     }
  75. }
  76.  
  77. /*
  78.  * Drop the passed line onto the passed output buffer.
  79.  * If a write error occurs, return -1, else the count of
  80.  * characters written, including the newline.
  81.  */
  82.  
  83. putline(obuf, linebuf)
  84.     FILE *obuf;
  85.     char *linebuf;
  86. {
  87.     register int c;
  88.  
  89.     c = strlen(linebuf);
  90.     fputs(linebuf, obuf);
  91.     putc('\n', obuf);
  92.     if (ferror(obuf))
  93.         return(-1);
  94.     return(c+1);
  95. }
  96.  
  97. /*
  98.  * Read up a line from the specified input into the line
  99.  * buffer.  Return the number of characters read.  Do not
  100.  * include the newline at the end.
  101.  */
  102.  
  103. readline(ibuf, linebuf)
  104.     FILE *ibuf;
  105.     char *linebuf;
  106. {
  107.     register char *cp;
  108.     register c;
  109.  
  110. again:
  111.     do {
  112.         clearerr(ibuf);
  113.         for (cp=linebuf, c=getc(ibuf); c!='\n' && c!= EOF; c=getc(ibuf))
  114.             if (cp - linebuf < LINESIZE-1)
  115.                     *cp++ = c;
  116.     } while (ferror(ibuf) && ibuf == stdin);
  117.     *cp = 0;
  118.     if (c == EOF && cp == linebuf)
  119.         return(0);
  120.     return(cp - linebuf + 1);
  121. }
  122.  
  123. /*
  124.  * Return a file buffer all ready to read up the
  125.  * passed message pointer.
  126.  */
  127.  
  128. FILE *
  129. setinput(mp)
  130.     register struct message *mp;
  131. {
  132.     off_t off;
  133.  
  134.     fflush(otf);
  135.     off = mp->m_block;
  136.     off <<= 9;
  137.     off += mp->m_offset;
  138.     if (fseek(itf, off, 0) < 0) {
  139.         perror("fseek");
  140.         panic("temporary file seek");
  141.     }
  142.     return(itf);
  143. }
  144.  
  145. /*
  146.  * Take the data out of the passed ghost file and toss it into
  147.  * a dynamically allocated message structure.
  148.  */
  149.  
  150. makemessage(f)
  151. {
  152.     register struct message *m;
  153.     register char *mp;
  154.     register count;
  155.  
  156.     mp = calloc((unsigned) (msgCount + 1), sizeof *m);
  157.     if (mp == NOSTR) {
  158.         printf("Insufficient memory for %d messages\n", msgCount);
  159.         exit(1);
  160.     }
  161.     message = (struct message *) mp;
  162.     dot = message;
  163.     lseek(f, 0L, 0);
  164.     while (count = read(f, mp, 512))
  165.         mp += count;
  166.     for (m = &message[0]; m < &message[msgCount]; m++) {
  167.         m->m_size = (m+1)->m_size;
  168.         m->m_lines = (m+1)->m_lines;
  169.     }
  170.     message[msgCount].m_size = 0;
  171.     message[msgCount].m_lines = 0;
  172. }
  173.  
  174. /*
  175.  * Append the passed message descriptor onto the temp file.
  176.  * If the write fails, return 1, else 0
  177.  */
  178.  
  179. append(mp, f)
  180.     struct message *mp;
  181. {
  182.     if (write(f, (char *) mp, sizeof *mp) != sizeof *mp)
  183.         return(1);
  184.     return(0);
  185. }
  186.  
  187. /*
  188.  * Terminate an editing session by attempting to write out the user's
  189.  * file from the temporary.
  190.  */
  191.  
  192. edstop()
  193. {
  194.     register int gotcha;
  195.     register struct message *mp;
  196.     FILE *obuf;
  197.  
  198.     for (mp = &message[0], gotcha = 0; mp < &message[msgCount]; mp++)
  199.         if (mp->m_flag & (MODIFY|MDELETED)) {
  200.             gotcha++;
  201.             break;
  202.         }
  203.     if (!gotcha)
  204.         return;
  205.     printf("\"%s\" ", editfile);
  206.     flush();
  207.     if ((obuf = fopen(editfile, "w")) == NULL) {
  208.         perror(editfile);
  209.         reset();
  210.     }
  211.     for (mp = &message[0]; mp < &message[msgCount]; mp++) {
  212.         if ((mp->m_flag & (MDELETED|MSAVED)) != 0)
  213.             continue;
  214.         if (send(mp, obuf) < 0) {
  215.             perror(editfile);
  216.             reset();
  217.         }
  218.     }
  219.     fflush(obuf);
  220.     if (ferror(obuf)) {
  221.         perror(editfile);
  222.         reset();
  223.     }
  224.     printf("complete\n");
  225.     flush();
  226. }
  227.  
  228. /*
  229.  * Empty the output buffer.
  230.  */
  231.  
  232. clrbuf(buf)
  233.     register FILE *buf;
  234. {
  235.  
  236.     buf = stdout;
  237.     buf->_ptr = buf->_base;
  238.     buf->_cnt = BUFSIZ;
  239. }
  240.  
  241. /*
  242.  * Open a temp file by creating, closing, unlinking, and
  243.  * reopening.  Return the open file descriptor.
  244.  */
  245.  
  246. opentemp(file)
  247.     char file[];
  248. {
  249.     register int f;
  250.  
  251.     if ((f = creat(file, 0600)) < 0) {
  252.         perror(file);
  253.         return(-1);
  254.     }
  255.     close(f);
  256.     if ((f = open(file, 2)) < 0) {
  257.         perror(file);
  258.         unlink(file);
  259.         return(-1);
  260.     }
  261.     unlink(file);
  262.     return(f);
  263. }
  264.  
  265. /*
  266.  * Flush the standard output.
  267.  */
  268.  
  269. flush()
  270. {
  271.     fflush(stdout);
  272.     fflush(stderr);
  273. }
  274.  
  275. /*
  276.  * Determine the size of the file possessed by
  277.  * the passed buffer.
  278.  */
  279.  
  280. off_t
  281. fsize(iob)
  282.     FILE *iob;
  283. {
  284.     register int f;
  285.     struct stat sbuf;
  286.  
  287.     f = fileno(iob);
  288.     if (fstat(f, &sbuf) < 0)
  289.         return(0);
  290.     return(sbuf.st_size);
  291. }
  292.