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