home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / misc / volume35 / psutils / part03 / psutil.c < prev    next >
C/C++ Source or Header  |  1993-02-04  |  5KB  |  241 lines

  1. /* psutil.c
  2.  * AJCD 29/1/91
  3.  * utilities for PS programs
  4.  */
  5.  
  6. #define LOCAL
  7. #include "psutil.h"
  8. #include "patchlevel.h"
  9.  
  10. #include <fcntl.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 (nesting == 0 && 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.       } else if (headerlen == 0)
  115.      headerlen = ftell(infile)-strlen(buffer);
  116.    pageptr[pages] = ftell(infile);
  117. }
  118.  
  119. seekpage(p)
  120.      int p;
  121. {
  122.    fseek(infile, pageptr[p], 0);
  123.    if (fgets(buffer, BUFSIZ, infile) != NULL &&
  124.        sscanf(buffer, "%%%%Page: %s %d\n", pagelabel, &pageno) == 2) {
  125.       pagelength = pageptr[p+1]-pageptr[p]-strlen(buffer);
  126.    } else {
  127.       fprintf(stderr, "%s: I/O error seeking page %d\n", prog, p);
  128.       fflush(stderr);
  129.       exit(1);
  130.    }
  131. }
  132.  
  133. writestring(s)
  134.      char *s;
  135. {
  136.    fputs(s, outfile);
  137.    bytes += strlen(s);
  138. }
  139.  
  140. writepageheader(label, page)
  141.      char *label;
  142.      int page;
  143. {
  144.    if (verbose) {
  145.       sprintf(buffer, "[%d] ", page);
  146.       message(buffer);
  147.    }
  148.    sprintf(buffer, "%%%%Page: %s %d\n", label, ++outputpage);
  149.    writestring(buffer);
  150. }
  151.  
  152. writepagebody()
  153. {
  154.    if (!fcopy(pagelength)) {
  155.       fprintf(stderr, "%s: I/O error writing page %d\n", prog, outputpage);
  156.       fflush(stderr);
  157.       exit(1);
  158.    }
  159. }
  160.  
  161. writepage(p)
  162.      int p;
  163. {
  164.    seekpage(p);
  165.    writepageheader(pagelabel, p+1);
  166.    writepagebody();
  167. }
  168.  
  169. /* write header: should alter %%Pages: comment */
  170. writeheader(p)
  171.      int p;
  172. {
  173.    long len = headerlen;
  174.    fseek(infile, 0L, 0);
  175.    if (pagescmt && pagescmt < len) {
  176.       if (!fcopy(pagescmt) || fgets(buffer, BUFSIZ, infile) == NULL) {
  177.      fprintf(stderr, "%s: I/O error in header\n", prog);
  178.      fflush(stderr);
  179.      exit(1);
  180.       }
  181.       len -= pagescmt+strlen(buffer);
  182.       sprintf(buffer, "%%%%Pages: %d 0\n", p);
  183.       writestring(buffer);
  184.    }
  185.    if (!fcopy(len)) {
  186.       fprintf(stderr, "%s: I/O error in header\n", prog);
  187.       fflush(stderr);
  188.       exit(1);
  189.    }
  190. }
  191.  
  192.  
  193. writeprolog()
  194. {
  195.    if (!fcopy(pageptr[0]-headerlen)) {
  196.       fprintf(stderr, "%s: I/O error in prologue\n", prog);
  197.       fflush(stderr);
  198.       exit(1);
  199.    }
  200. }
  201.  
  202. /* write trailer */
  203. writetrailer()
  204. {
  205.    fseek(infile, pageptr[pages], 0);
  206.    while (fgets(buffer, BUFSIZ, infile) != NULL) {
  207.       writestring(buffer);
  208.    }
  209.    if (verbose) {
  210.       sprintf(buffer, "Wrote %d pages, %ld bytes\n", outputpage, bytes);
  211.       message(buffer);
  212.    }
  213. }
  214.  
  215. /* write message to stderr */
  216. message(s)
  217.      char *s;
  218. {
  219.    static int pos = 0;
  220.    char *nl = strchr(s, '\n');
  221.    int len = nl ? (nl-s) : strlen(s);
  222.  
  223.    if (pos+len > 79 && (pos > 79 || len < 80)) {
  224.       fputc('\n', stderr);
  225.       pos = 0;
  226.    }
  227.    fputs(s, stderr);
  228.    fflush(stderr);
  229.    pos += len;
  230. }
  231.  
  232.  
  233. int writeemptypage()
  234. {
  235.    if (verbose)
  236.       message("[*] ");
  237.    sprintf(buffer, "%%%%Page: * %d\nshowpage\n", ++outputpage);
  238.    writestring(buffer);
  239. }
  240.  
  241.