home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume22 / psutils / part01 / psutil.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-09-04  |  5.1 KB  |  240 lines

  1. /* psutil.c
  2.  * AJCD 29/1/91
  3.  * utilities for PS programs
  4.  */
  5.  
  6. #define LOCAL
  7. #include "psutil.h"
  8.  
  9. #include <fcntl.h>
  10. #include <ctype.h>
  11. #include <string.h>
  12.  
  13. static char buffer[BUFSIZ];
  14. static long bytes = 0;
  15. static long pagescmt = 0;
  16. static long headerlen = 0;
  17. static int outputpage = 0;
  18. static char pagelabel[BUFSIZ];
  19. static int pageno;
  20. static long pagelength;
  21.  
  22. /* make a file seekable; trick stolen from Chris Torek's libdvi */
  23.  
  24. FILE *seekable(fp)
  25.      FILE *fp;
  26. {
  27.    int fd, tf, n, w;
  28.    char *tmpdir, *p;
  29.  
  30.    fd = fileno(fp);
  31.    if (lseek(fd, 0L, 1) >= 0 && !isatty(fd))
  32.       return (fp);
  33.  
  34.    if ((tmpdir = getenv("TMPDIR")) == NULL)
  35.       tmpdir = TMPDIR;
  36.    (void) sprintf(buffer, "%s/#%d", tmpdir, getpid());
  37.    if ((tf = open(buffer, O_RDWR | O_CREAT | O_EXCL, 0666)) == -1)
  38.       return (NULL);
  39.    (void) unlink(buffer);
  40.  
  41.    while ((n = read(fd, p = buffer, BUFSIZ)) > 0) {
  42.       do {
  43.      if ((w = write(tf, p, n)) < 0) {
  44.         (void) close(tf);
  45.         (void) fclose(fp);
  46.         return (NULL);
  47.      }
  48.      p += w;
  49.       } while ((n -= w) > 0);
  50.    }
  51.    if (n < 0) {
  52.       (void) close(tf);
  53.       (void) fclose(fp);
  54.       return (NULL);
  55.    }
  56.  
  57.    /* discard the input file, and rewind and open the temporary */
  58.    (void) fclose(fp);
  59.    (void) lseek(tf, 0L, 0);
  60.    if ((fp = fdopen(tf, "r")) == NULL) {
  61.       (void) close(tf);
  62.    }
  63.    return (fp);
  64. }
  65.  
  66.  
  67. int fcopy(len)
  68.      long len;
  69. {
  70.    while (len) {
  71.       int n = (len > BUFSIZ) ? BUFSIZ : len;
  72.       if (!(fread(buffer, sizeof(char), n, infile) &&
  73.         fwrite(buffer, sizeof(char), n, outfile)))
  74.      return (0);
  75.       len -= n;
  76.       bytes += n;
  77.    }
  78.    return (1);
  79. }
  80.  
  81. /* build array of pointers to start/end of pages */
  82.  
  83. scanpages()
  84. {
  85.    register char *comment = buffer+2;
  86.    register int nesting = 0;
  87.  
  88.    pages = 0;
  89.    fseek(infile, 0L, 0);
  90.    while (fgets(buffer, BUFSIZ, infile) != NULL)
  91.       if (*buffer == '%') {
  92.      if (buffer[1] == '%') {
  93.         if (strncmp(comment, "Page:", 5) == 0)
  94.            pageptr[pages++] = ftell(infile)-strlen(buffer);
  95.         else if (headerlen == 0 && strncmp(comment, "Pages:", 6) == 0)
  96.            pagescmt = ftell(infile)-strlen(buffer);
  97.         else if (headerlen == 0 &&
  98.              strncmp(comment, "EndComments", 11) == 0)
  99.            headerlen = ftell(infile);
  100.         else if (strncmp(comment, "BeginDocument", 13) == 0)
  101.            nesting++;
  102.         else if (strncmp(comment, "EndDocument", 11) == 0)
  103.            nesting--;
  104.         else if (strncmp(comment, "BeginBinary", 11) == 0)
  105.            nesting++;
  106.         else if (strncmp(comment, "EndBinary", 9) == 0)
  107.            nesting--;
  108.         else if (nesting == 0 && strncmp(comment, "Trailer", 7) == 0) {
  109.            fseek(infile, (long)(-strlen(buffer)), 1);
  110.            break;
  111.         }
  112.      } else if (headerlen == 0 && buffer[1] != '!')
  113.         headerlen = ftell(infile)-strlen(buffer);
  114.       }
  115.    pageptr[pages] = ftell(infile);
  116. }
  117.  
  118. seekpage(p)
  119.      int p;
  120. {
  121.    fseek(infile, pageptr[p], 0);
  122.    if (fgets(buffer, BUFSIZ, infile) != NULL &&
  123.        sscanf(buffer, "%%%%Page: %s %d\n", pagelabel, &pageno) == 2) {
  124.       pagelength = pageptr[p+1]-pageptr[p]-strlen(buffer);
  125.    } else {
  126.       fprintf(stderr, "%s: I/O error seeking page %d\n", prog, p);
  127.       fflush(stderr);
  128.       exit(1);
  129.    }
  130. }
  131.  
  132. writestring(s)
  133.      char *s;
  134. {
  135.    fputs(s, outfile);
  136.    bytes += strlen(s);
  137. }
  138.  
  139. writepageheader(label, page)
  140.      char *label;
  141.      int page;
  142. {
  143.    if (verbose) {
  144.       sprintf(buffer, "[%d] ", page);
  145.       message(buffer);
  146.    }
  147.    sprintf(buffer, "%%%%Page: %s %d\n", label, ++outputpage);
  148.    writestring(buffer);
  149. }
  150.  
  151. writepagebody()
  152. {
  153.    if (!fcopy(pagelength)) {
  154.       fprintf(stderr, "%s: I/O error writing page %d\n", prog, outputpage);
  155.       fflush(stderr);
  156.       exit(1);
  157.    }
  158. }
  159.  
  160. writepage(p)
  161.      int p;
  162. {
  163.    seekpage(p);
  164.    writepageheader(pagelabel, p+1);
  165.    writepagebody();
  166. }
  167.  
  168. /* write header: should alter %%Pages: comment */
  169. writeheader(p)
  170.      int p;
  171. {
  172.    long len = headerlen;
  173.    fseek(infile, 0L, 0);
  174.    if (pagescmt && pagescmt < len) {
  175.       if (!fcopy(pagescmt) || fgets(buffer, BUFSIZ, infile) == NULL) {
  176.      fprintf(stderr, "%s: I/O error in header\n", prog);
  177.      fflush(stderr);
  178.      exit(1);
  179.       }
  180.       len -= pagescmt+strlen(buffer);
  181.       sprintf(buffer, "%%%%Pages: %d 0\n", p);
  182.       writestring(buffer);
  183.    }
  184.    if (!fcopy(len)) {
  185.       fprintf(stderr, "%s: I/O error in header\n", prog);
  186.       fflush(stderr);
  187.       exit(1);
  188.    }
  189. }
  190.  
  191.  
  192. writeprolog()
  193. {
  194.    if (!fcopy(pageptr[0]-headerlen)) {
  195.       fprintf(stderr, "%s: I/O error in prologue\n", prog);
  196.       fflush(stderr);
  197.       exit(1);
  198.    }
  199. }
  200.  
  201. /* write trailer */
  202. writetrailer()
  203. {
  204.    fseek(infile, pageptr[pages], 0);
  205.    while (fgets(buffer, BUFSIZ, infile) != NULL) {
  206.       writestring(buffer);
  207.    }
  208.    if (verbose) {
  209.       sprintf(buffer, "Wrote %d pages, %ld bytes\n", outputpage, bytes);
  210.       message(buffer);
  211.    }
  212. }
  213.  
  214. /* write message to stderr */
  215. message(s)
  216.      char *s;
  217. {
  218.    static int pos = 0;
  219.    char *nl = strchr(s, '\n');
  220.    int len = nl ? (nl-s) : strlen(s);
  221.  
  222.    if (pos+len > 79 && (pos > 79 || len < 80)) {
  223.       fputc('\n', stderr);
  224.       pos = 0;
  225.    }
  226.    fputs(s, stderr);
  227.    fflush(stderr);
  228.    pos += len;
  229. }
  230.  
  231.  
  232. int writeemptypage()
  233. {
  234.    if (verbose)
  235.       message("[*] ");
  236.    sprintf(buffer, "%%%%Page: * %d\nshowpage\n", ++outputpage);
  237.    writestring(buffer);
  238. }
  239.  
  240.