ftp.nice.ch/pub/next/unix/graphics/psutils.5Nov92.N.bs.tar.gz#/psutils/psutil.c

This is psutil.c in view mode; [Download] [Up]

/* psutil.c
 * AJCD 29/1/91
 * utilities for PS programs
 */

#define LOCAL
#include "psutil.h"

#include <fcntl.h>
#include <string.h>

static char buffer[BUFSIZ];
static long bytes = 0;
static long pagescmt = 0;
static long headerlen = 0;
static int outputpage = 0;
static char pagelabel[BUFSIZ];
static int pageno;
static long pagelength;

/* make a file seekable; trick stolen from Chris Torek's libdvi */

FILE *seekable(fp)
     FILE *fp;
{
   int fd, tf, n, w;
   char *tmpdir, *p;

   fd = fileno(fp);
   if (lseek(fd, 0L, 1) >= 0 && !isatty(fd))
      return (fp);

   if ((tmpdir = getenv("TMPDIR")) == NULL)
      tmpdir = TMPDIR;
   (void) sprintf(buffer, "%s/#%d", tmpdir, getpid());
   if ((tf = open(buffer, O_RDWR | O_CREAT | O_EXCL, 0666)) == -1)
      return (NULL);
   (void) unlink(buffer);

   while ((n = read(fd, p = buffer, BUFSIZ)) > 0) {
      do {
	 if ((w = write(tf, p, n)) < 0) {
	    (void) close(tf);
	    (void) fclose(fp);
	    return (NULL);
	 }
	 p += w;
      } while ((n -= w) > 0);
   }
   if (n < 0) {
      (void) close(tf);
      (void) fclose(fp);
      return (NULL);
   }

   /* discard the input file, and rewind and open the temporary */
   (void) fclose(fp);
   (void) lseek(tf, 0L, 0);
   if ((fp = fdopen(tf, "r")) == NULL) {
      (void) close(tf);
   }
   return (fp);
}


int fcopy(len)
     long len;
{
   while (len) {
      int n = (len > BUFSIZ) ? BUFSIZ : len;
      if (!(fread(buffer, sizeof(char), n, infile) &&
	    fwrite(buffer, sizeof(char), n, outfile)))
	 return (0);
      len -= n;
      bytes += n;
   }
   return (1);
}

/* build array of pointers to start/end of pages */

scanpages()
{
   register char *comment = buffer+2;
   register int nesting = 0;

   pages = 0;
   fseek(infile, 0L, 0);
   while (fgets(buffer, BUFSIZ, infile) != NULL)
      if (*buffer == '%') {
	 if (buffer[1] == '%') {
	    if (nesting == 0 && strncmp(comment, "Page:", 5) == 0)
	       pageptr[pages++] = ftell(infile)-strlen(buffer);
	    else if (headerlen == 0 && strncmp(comment, "Pages:", 6) == 0)
	       pagescmt = ftell(infile)-strlen(buffer);
	    else if (headerlen == 0 &&
		     strncmp(comment, "EndComments", 11) == 0)
	       headerlen = ftell(infile);
	    else if (strncmp(comment, "BeginDocument", 13) == 0)
	       nesting++;
	    else if (strncmp(comment, "EndDocument", 11) == 0)
	       nesting--;
	    else if (strncmp(comment, "BeginBinary", 11) == 0)
	       nesting++;
	    else if (strncmp(comment, "EndBinary", 9) == 0)
	       nesting--;
	    else if (nesting == 0 && strncmp(comment, "Trailer", 7) == 0) {
	       fseek(infile, (long)(-strlen(buffer)), 1);
	       break;
	    }
	 } else if (headerlen == 0 && buffer[1] != '!')
	    headerlen = ftell(infile)-strlen(buffer);
      } else if (headerlen == 0)
	 headerlen = ftell(infile)-strlen(buffer);
   pageptr[pages] = ftell(infile);
}

seekpage(p)
     int p;
{
   fseek(infile, pageptr[p], 0);
   if (fgets(buffer, BUFSIZ, infile) != NULL &&
       sscanf(buffer, "%%%%Page: %s %d\n", pagelabel, &pageno) == 2) {
      pagelength = pageptr[p+1]-pageptr[p]-strlen(buffer);
   } else {
      fprintf(stderr, "%s: I/O error seeking page %d\n", prog, p);
      fflush(stderr);
      exit(1);
   }
}

writestring(s)
     char *s;
{
   fputs(s, outfile);
   bytes += strlen(s);
}

writepageheader(label, page)
     char *label;
     int page;
{
   if (verbose) {
      sprintf(buffer, "[%d] ", page);
      message(buffer);
   }
   sprintf(buffer, "%%%%Page: %s %d\n", label, ++outputpage);
   writestring(buffer);
}

writepagebody()
{
   if (!fcopy(pagelength)) {
      fprintf(stderr, "%s: I/O error writing page %d\n", prog, outputpage);
      fflush(stderr);
      exit(1);
   }
}

writepage(p)
     int p;
{
   seekpage(p);
   writepageheader(pagelabel, p+1);
   writepagebody();
}

/* write header: should alter %%Pages: comment */
writeheader(p)
     int p;
{
   long len = headerlen;
   fseek(infile, 0L, 0);
   if (pagescmt && pagescmt < len) {
      if (!fcopy(pagescmt) || fgets(buffer, BUFSIZ, infile) == NULL) {
	 fprintf(stderr, "%s: I/O error in header\n", prog);
	 fflush(stderr);
	 exit(1);
      }
      len -= pagescmt+strlen(buffer);
      sprintf(buffer, "%%%%Pages: %d 0\n", p);
      writestring(buffer);
   }
   if (!fcopy(len)) {
      fprintf(stderr, "%s: I/O error in header\n", prog);
      fflush(stderr);
      exit(1);
   }
}


writeprolog()
{
   if (!fcopy(pageptr[0]-headerlen)) {
      fprintf(stderr, "%s: I/O error in prologue\n", prog);
      fflush(stderr);
      exit(1);
   }
}

/* write trailer */
writetrailer()
{
   fseek(infile, pageptr[pages], 0);
   while (fgets(buffer, BUFSIZ, infile) != NULL) {
      writestring(buffer);
   }
   if (verbose) {
      sprintf(buffer, "Wrote %d pages, %ld bytes\n", outputpage, bytes);
      message(buffer);
   }
}

/* write message to stderr */
message(s)
     char *s;
{
   static int pos = 0;
   char *nl = strchr(s, '\n');
   int len = nl ? (nl-s) : strlen(s);

   if (pos+len > 79 && (pos > 79 || len < 80)) {
      fputc('\n', stderr);
      pos = 0;
   }
   fputs(s, stderr);
   fflush(stderr);
   pos += len;
}


int writeemptypage()
{
   if (verbose)
      message("[*] ");
   sprintf(buffer, "%%%%Page: * %d\nshowpage\n", ++outputpage);
   writestring(buffer);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.