17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
55699d47bSps * Common Development and Distribution License (the "License").
65699d47bSps * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
225699d47bSps * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
237c478bd9Sstevel@tonic-gate * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate */
257c478bd9Sstevel@tonic-gate
267c478bd9Sstevel@tonic-gate #include <stdio.h>
277c478bd9Sstevel@tonic-gate #include <stdlib.h>
287c478bd9Sstevel@tonic-gate #include <sys/types.h>
297c478bd9Sstevel@tonic-gate #include <sys/file.h>
307c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
317c478bd9Sstevel@tonic-gate #include <sys/stat.h>
327c478bd9Sstevel@tonic-gate #include <sys/mman.h>
337c478bd9Sstevel@tonic-gate #include <string.h>
347c478bd9Sstevel@tonic-gate #include <errno.h>
357c478bd9Sstevel@tonic-gate #include "postreverse.h"
367c478bd9Sstevel@tonic-gate
377c478bd9Sstevel@tonic-gate /*
387c478bd9Sstevel@tonic-gate * This version of postreverse should parse any Adobe DSC conforming
397c478bd9Sstevel@tonic-gate * PostScript file and most that are not conforming, but minimally have the
407c478bd9Sstevel@tonic-gate * page (%%Page:) and trailer (%%Trailer) comments in them at the begining of
417c478bd9Sstevel@tonic-gate * the line.
427c478bd9Sstevel@tonic-gate *
437c478bd9Sstevel@tonic-gate * If a document cannot be parsed (no page and trailer comments), it is passed
447c478bd9Sstevel@tonic-gate * through untouched. If you look through the code you will find that it
457c478bd9Sstevel@tonic-gate * doesn't ever look for the PostScript magic (%!). This is because it
467c478bd9Sstevel@tonic-gate * assumes that PostScript is sent in. If PostScript is in sent in, it will
477c478bd9Sstevel@tonic-gate * still attempt to parse it based on DSC page and trailer comments as if it
487c478bd9Sstevel@tonic-gate * were postscript.
497c478bd9Sstevel@tonic-gate *
507c478bd9Sstevel@tonic-gate * flow goes as follows:
517c478bd9Sstevel@tonic-gate * 1) get command line options (including parsing a page
527c478bd9Sstevel@tonic-gate * list if supplied)
537c478bd9Sstevel@tonic-gate * 2) if no filename is supplied in command line, copy
547c478bd9Sstevel@tonic-gate * stdin to temp file.
557c478bd9Sstevel@tonic-gate * 3) parse the document:
567c478bd9Sstevel@tonic-gate * start from begining looking for a DSC page comment
577c478bd9Sstevel@tonic-gate * (that is the header) start from the end looking for
587c478bd9Sstevel@tonic-gate * a DSC trailer comment (that is the trailer) start from
597c478bd9Sstevel@tonic-gate * the header until the trailer looking for DSC page
607c478bd9Sstevel@tonic-gate * comments. Each one signifies a new page.
617c478bd9Sstevel@tonic-gate * start from the header until the trailer looking for BSD
627c478bd9Sstevel@tonic-gate * global comments. Each one violates page independence and
637c478bd9Sstevel@tonic-gate * will be stored so it can be printed after the header and
647c478bd9Sstevel@tonic-gate * before any pages.
657c478bd9Sstevel@tonic-gate * 4) print the document: if there is no header, trailer, or
667c478bd9Sstevel@tonic-gate * pages, print it from start to end unaltered if they all
677c478bd9Sstevel@tonic-gate * exist, print the header, pages, and trailer the pages
687c478bd9Sstevel@tonic-gate * are compared against a page list before being printed,
697c478bd9Sstevel@tonic-gate * and are reversed if the reverse flag has been set.
707c478bd9Sstevel@tonic-gate * If global definitions were found in the pages of a
717c478bd9Sstevel@tonic-gate * document, they are printed after the header and before
727c478bd9Sstevel@tonic-gate * the pages.
737c478bd9Sstevel@tonic-gate */
747c478bd9Sstevel@tonic-gate
757c478bd9Sstevel@tonic-gate static void *
nmalloc(size_t size)767c478bd9Sstevel@tonic-gate nmalloc(size_t size)
777c478bd9Sstevel@tonic-gate {
787c478bd9Sstevel@tonic-gate void *ret = malloc(size);
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate if (!ret) {
817c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
827c478bd9Sstevel@tonic-gate "postreverse : malloc() failed : Out of memory\n");
837c478bd9Sstevel@tonic-gate exit(2);
847c478bd9Sstevel@tonic-gate }
857c478bd9Sstevel@tonic-gate return (ret);
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate
887c478bd9Sstevel@tonic-gate static void *
nrealloc(void * ptr,size_t size)897c478bd9Sstevel@tonic-gate nrealloc(void *ptr, size_t size)
907c478bd9Sstevel@tonic-gate {
917c478bd9Sstevel@tonic-gate void *ret = realloc(ptr, size);
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate if (!ret) {
947c478bd9Sstevel@tonic-gate (void) fprintf(stderr,
957c478bd9Sstevel@tonic-gate "postreverse : realloc() failed - Out of memory\n");
967c478bd9Sstevel@tonic-gate exit(2);
977c478bd9Sstevel@tonic-gate }
987c478bd9Sstevel@tonic-gate return (ret);
997c478bd9Sstevel@tonic-gate }
1007c478bd9Sstevel@tonic-gate
1017c478bd9Sstevel@tonic-gate /*
1027c478bd9Sstevel@tonic-gate * nstrlen() provides the same functionality as strlen() while also checking
1037c478bd9Sstevel@tonic-gate * that the pointer does not cross the end of file.
1047c478bd9Sstevel@tonic-gate *
1057c478bd9Sstevel@tonic-gate * Returns the number of non-NULL bytes in string argument.
1067c478bd9Sstevel@tonic-gate */
1077c478bd9Sstevel@tonic-gate
1087c478bd9Sstevel@tonic-gate static size_t
nstrlen(const char * s,char * bptr)1097c478bd9Sstevel@tonic-gate nstrlen(const char *s, char *bptr)
1107c478bd9Sstevel@tonic-gate {
1117c478bd9Sstevel@tonic-gate const char *s0 = s;
1127c478bd9Sstevel@tonic-gate
1137c478bd9Sstevel@tonic-gate while (s < bptr && *s != '\0')
1147c478bd9Sstevel@tonic-gate s++;
1157c478bd9Sstevel@tonic-gate return (s - s0);
1167c478bd9Sstevel@tonic-gate }
1177c478bd9Sstevel@tonic-gate
1187c478bd9Sstevel@tonic-gate /*
1197c478bd9Sstevel@tonic-gate * nstrstr() provides the same functionality as strstr() while also checking
1207c478bd9Sstevel@tonic-gate * that the pointers do not cross the end of the file.
1217c478bd9Sstevel@tonic-gate *
1227c478bd9Sstevel@tonic-gate * nstrstr() locates the first occurrence in the string as1 of the sequence of
1237c478bd9Sstevel@tonic-gate * characters (excluding the terminating null character) in the string as2.
1247c478bd9Sstevel@tonic-gate * nstrstr() returns a pointer to the located string, or a null pointer if
1257c478bd9Sstevel@tonic-gate * the string is not found. If as2 is "", the function returns as1.
1267c478bd9Sstevel@tonic-gate */
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate static char *
nstrstr(const char * as1,const char * as2,char * bptr)1297c478bd9Sstevel@tonic-gate nstrstr(const char *as1, const char *as2, char *bptr)
1307c478bd9Sstevel@tonic-gate {
1317c478bd9Sstevel@tonic-gate const char *s1, *s2;
1327c478bd9Sstevel@tonic-gate const char *tptr;
1337c478bd9Sstevel@tonic-gate char c;
1347c478bd9Sstevel@tonic-gate
1357c478bd9Sstevel@tonic-gate s1 = as1;
1367c478bd9Sstevel@tonic-gate s2 = as2;
1377c478bd9Sstevel@tonic-gate
1387c478bd9Sstevel@tonic-gate if (s2 == NULL || *s2 == '\0')
1397c478bd9Sstevel@tonic-gate return ((char *)s1);
1407c478bd9Sstevel@tonic-gate c = *s2;
1417c478bd9Sstevel@tonic-gate
1427c478bd9Sstevel@tonic-gate while (s1 < bptr && *s1)
1437c478bd9Sstevel@tonic-gate if (*s1++ == c) {
1447c478bd9Sstevel@tonic-gate tptr = s1;
1457c478bd9Sstevel@tonic-gate while ((s1 < bptr) &&
1467c478bd9Sstevel@tonic-gate (c = *++s2) == *s1++ && c);
1477c478bd9Sstevel@tonic-gate if (c == 0)
1487c478bd9Sstevel@tonic-gate return ((char *)tptr - 1);
1497c478bd9Sstevel@tonic-gate s1 = tptr;
1507c478bd9Sstevel@tonic-gate s2 = as2;
1517c478bd9Sstevel@tonic-gate c = *s2;
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate return (NULL);
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate
1567c478bd9Sstevel@tonic-gate
1577c478bd9Sstevel@tonic-gate /*
1587c478bd9Sstevel@tonic-gate * caddr_t strrstr(caddr_t as1, caddr_t as2 char *bptr1)
1597c478bd9Sstevel@tonic-gate * return the address of the beginning of the last occruence of as2
1607c478bd9Sstevel@tonic-gate * in as1 or NULL if not found
1617c478bd9Sstevel@tonic-gate */
1627c478bd9Sstevel@tonic-gate caddr_t
strrstr(caddr_t s1,caddr_t s2,char * bptr)1637c478bd9Sstevel@tonic-gate strrstr(caddr_t s1, caddr_t s2, char *bptr)
1647c478bd9Sstevel@tonic-gate {
1657c478bd9Sstevel@tonic-gate char *t1, *t2;
1667c478bd9Sstevel@tonic-gate char c;
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate t1 = s1 + nstrlen(s1, bptr) - 1;
1707c478bd9Sstevel@tonic-gate t2 = s2 + nstrlen(s2, bptr) - 1;
1717c478bd9Sstevel@tonic-gate
1727c478bd9Sstevel@tonic-gate if (t2 == NULL || *t2 == '\0')
1737c478bd9Sstevel@tonic-gate return ((char *)t1);
1747c478bd9Sstevel@tonic-gate c = *t2;
1757c478bd9Sstevel@tonic-gate
1767c478bd9Sstevel@tonic-gate while (s1 <= t1)
1777c478bd9Sstevel@tonic-gate if (*t1-- == c) {
1787c478bd9Sstevel@tonic-gate while ((c = *--t2) == *t1-- && t2 > s2);
1797c478bd9Sstevel@tonic-gate if (t2 <= s2)
1807c478bd9Sstevel@tonic-gate return ((char *)t1 + 1);
1817c478bd9Sstevel@tonic-gate t2 = s2 + nstrlen(s2, bptr) - 1;
1827c478bd9Sstevel@tonic-gate c = *t2;
1837c478bd9Sstevel@tonic-gate }
1847c478bd9Sstevel@tonic-gate return (NULL);
1857c478bd9Sstevel@tonic-gate }
1867c478bd9Sstevel@tonic-gate
1877c478bd9Sstevel@tonic-gate /*
1887c478bd9Sstevel@tonic-gate * Copy stdin to a temp file and return the name
1897c478bd9Sstevel@tonic-gate */
1907c478bd9Sstevel@tonic-gate char *
StdinToFile()1917c478bd9Sstevel@tonic-gate StdinToFile()
1927c478bd9Sstevel@tonic-gate {
1937c478bd9Sstevel@tonic-gate char *fileName = tmpnam(NULL);
1947c478bd9Sstevel@tonic-gate int fd;
1957c478bd9Sstevel@tonic-gate int count;
1967c478bd9Sstevel@tonic-gate char buf[BUFSIZ];
1977c478bd9Sstevel@tonic-gate
1987c478bd9Sstevel@tonic-gate if ((fd = open(fileName, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) {
1997c478bd9Sstevel@tonic-gate fprintf(stderr, "open(%s): %s\n", fileName,
2007c478bd9Sstevel@tonic-gate strerror(errno));
2017c478bd9Sstevel@tonic-gate return (NULL);
2027c478bd9Sstevel@tonic-gate }
2037c478bd9Sstevel@tonic-gate while ((count = read(0, buf, sizeof (buf))) > 0)
2047c478bd9Sstevel@tonic-gate if (write(fd, buf, count) != count) {
2057c478bd9Sstevel@tonic-gate fprintf(stderr, "write(%d, 0x%x, %d): %s\n", fd, buf,
2067c478bd9Sstevel@tonic-gate count, strerror(errno));
2077c478bd9Sstevel@tonic-gate close(fd);
2087c478bd9Sstevel@tonic-gate unlink(fileName);
2097c478bd9Sstevel@tonic-gate return (NULL);
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate return (fileName);
2127c478bd9Sstevel@tonic-gate }
2137c478bd9Sstevel@tonic-gate
2147c478bd9Sstevel@tonic-gate /*
2157c478bd9Sstevel@tonic-gate * Usage(char *name) - program usage
2167c478bd9Sstevel@tonic-gate */
2177c478bd9Sstevel@tonic-gate void
Usage(char * name)2187c478bd9Sstevel@tonic-gate Usage(char *name)
2197c478bd9Sstevel@tonic-gate {
2207c478bd9Sstevel@tonic-gate fprintf(stderr, "Usage: %s [ -o list ] [ -r ] [ filename ]\n", name);
2217c478bd9Sstevel@tonic-gate exit(1);
2227c478bd9Sstevel@tonic-gate }
2237c478bd9Sstevel@tonic-gate
2247c478bd9Sstevel@tonic-gate
2257c478bd9Sstevel@tonic-gate /*
2267c478bd9Sstevel@tonic-gate * int **ParsePageList(char *list)
2277c478bd9Sstevel@tonic-gate * This will parse as string #,#,#-#,#... into an array of pointers
2287c478bd9Sstevel@tonic-gate * to integers. This array will contain all numbers in the list including
2297c478bd9Sstevel@tonic-gate * those int the range #-#. The list returned is NULL terminated.
2307c478bd9Sstevel@tonic-gate * It uses 2 passes to build the list. pass 1 counts the # of ints and
2317c478bd9Sstevel@tonic-gate * allocates the space, and pass 2 fills in the list.
2327c478bd9Sstevel@tonic-gate */
2337c478bd9Sstevel@tonic-gate int **
ParsePageList(char * list)2347c478bd9Sstevel@tonic-gate ParsePageList(char *list)
2357c478bd9Sstevel@tonic-gate {
2367c478bd9Sstevel@tonic-gate int **pageList = NULL;
2377c478bd9Sstevel@tonic-gate int pass = 0;
2387c478bd9Sstevel@tonic-gate
2397c478bd9Sstevel@tonic-gate if (list == NULL)
2407c478bd9Sstevel@tonic-gate return (NULL);
2417c478bd9Sstevel@tonic-gate
2427c478bd9Sstevel@tonic-gate while (pass++ < 2) {
2437c478bd9Sstevel@tonic-gate char *page;
2447c478bd9Sstevel@tonic-gate char *tmplist;
2457c478bd9Sstevel@tonic-gate int size = 0;
2467c478bd9Sstevel@tonic-gate
2477c478bd9Sstevel@tonic-gate tmplist = strdup(list);
2487c478bd9Sstevel@tonic-gate page = strtok(tmplist, ",");
2497c478bd9Sstevel@tonic-gate
2507c478bd9Sstevel@tonic-gate do {
2517c478bd9Sstevel@tonic-gate int start, end;
2527c478bd9Sstevel@tonic-gate char *s1 = page, *s2;
2537c478bd9Sstevel@tonic-gate
2547c478bd9Sstevel@tonic-gate if (s2 = strchr(page, '-')) {
255*e4fb8a5fSToomas Soome *s2++ = '\0';
2567c478bd9Sstevel@tonic-gate start = atoi(s1);
2577c478bd9Sstevel@tonic-gate end = atoi(s2);
2587c478bd9Sstevel@tonic-gate if (end < start) {
2597c478bd9Sstevel@tonic-gate int tmp = end;
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate end = start;
2627c478bd9Sstevel@tonic-gate start = tmp;
2637c478bd9Sstevel@tonic-gate }
2647c478bd9Sstevel@tonic-gate } else
2657c478bd9Sstevel@tonic-gate start = end = atoi(s1);
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate while (start <= end)
2687c478bd9Sstevel@tonic-gate if (pass == 1)
2697c478bd9Sstevel@tonic-gate /* count the pages for allocation */
2707c478bd9Sstevel@tonic-gate size++, start++;
2717c478bd9Sstevel@tonic-gate else { /* fill in the page list */
2727c478bd9Sstevel@tonic-gate int *tmp = (int *)nmalloc(sizeof (int));
2737c478bd9Sstevel@tonic-gate *tmp = start++;
2747c478bd9Sstevel@tonic-gate pageList[size++] = tmp;
2757c478bd9Sstevel@tonic-gate }
2767c478bd9Sstevel@tonic-gate } while (page = strtok(NULL, ","));
2777c478bd9Sstevel@tonic-gate free(tmplist);
2787c478bd9Sstevel@tonic-gate if (pass == 1)
2797c478bd9Sstevel@tonic-gate pageList = (int **)calloc(sizeof (int *), (size + 1));
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate return (pageList);
2827c478bd9Sstevel@tonic-gate }
2837c478bd9Sstevel@tonic-gate
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate /*
2867c478bd9Sstevel@tonic-gate * int PageIsListed(int page, int **pageList)
2877c478bd9Sstevel@tonic-gate * returns 1 if the pagelist is empty or if the page is in the
2887c478bd9Sstevel@tonic-gate * NULL terminated pageList. returns 0 if the page is not listed
2897c478bd9Sstevel@tonic-gate */
2907c478bd9Sstevel@tonic-gate int
PageIsListed(int page,int ** pageList)2917c478bd9Sstevel@tonic-gate PageIsListed(int page, int **pageList)
2927c478bd9Sstevel@tonic-gate {
2937c478bd9Sstevel@tonic-gate int count = 0;
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate if (!pageList)
2967c478bd9Sstevel@tonic-gate return (1);
2977c478bd9Sstevel@tonic-gate
2987c478bd9Sstevel@tonic-gate for (count = 0; pageList[count] != NULL; count++)
2997c478bd9Sstevel@tonic-gate if (*pageList[count] == page)
3007c478bd9Sstevel@tonic-gate return (1);
3017c478bd9Sstevel@tonic-gate return (0);
3027c478bd9Sstevel@tonic-gate }
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate
3057c478bd9Sstevel@tonic-gate /*
3067c478bd9Sstevel@tonic-gate * Writes the document Header to the fd
3077c478bd9Sstevel@tonic-gate */
3087c478bd9Sstevel@tonic-gate int
WriteDocumentHeader(int fd,DOCUMENT * d)3097c478bd9Sstevel@tonic-gate WriteDocumentHeader(int fd, DOCUMENT * d)
3107c478bd9Sstevel@tonic-gate {
3117c478bd9Sstevel@tonic-gate if (d) {
3127c478bd9Sstevel@tonic-gate HEADER *h = d->header;
3137c478bd9Sstevel@tonic-gate
3147c478bd9Sstevel@tonic-gate if (h)
3157c478bd9Sstevel@tonic-gate return (write(fd, h->start, h->size));
3167c478bd9Sstevel@tonic-gate }
3177c478bd9Sstevel@tonic-gate errno = EINVAL;
3187c478bd9Sstevel@tonic-gate return (-1);
3197c478bd9Sstevel@tonic-gate }
3207c478bd9Sstevel@tonic-gate
3217c478bd9Sstevel@tonic-gate /*
3227c478bd9Sstevel@tonic-gate * Writes the document global block to the fd
3237c478bd9Sstevel@tonic-gate */
3247c478bd9Sstevel@tonic-gate int
WriteGlobal(int fd,GLOBAL * g)3257c478bd9Sstevel@tonic-gate WriteGlobal(int fd, GLOBAL * g)
3267c478bd9Sstevel@tonic-gate {
3277c478bd9Sstevel@tonic-gate if (g)
3287c478bd9Sstevel@tonic-gate return (write(fd, g->start, g->size));
3297c478bd9Sstevel@tonic-gate errno = EINVAL;
3307c478bd9Sstevel@tonic-gate return (-1);
3317c478bd9Sstevel@tonic-gate }
3327c478bd9Sstevel@tonic-gate
3337c478bd9Sstevel@tonic-gate /*
3347c478bd9Sstevel@tonic-gate * Writes the document Trailer to the fd
3357c478bd9Sstevel@tonic-gate */
3367c478bd9Sstevel@tonic-gate int
WriteDocumentTrailer(int fd,DOCUMENT * d)3377c478bd9Sstevel@tonic-gate WriteDocumentTrailer(int fd, DOCUMENT * d)
3387c478bd9Sstevel@tonic-gate {
3397c478bd9Sstevel@tonic-gate if (d) {
3407c478bd9Sstevel@tonic-gate TRAILER *t = d->trailer;
3417c478bd9Sstevel@tonic-gate
3427c478bd9Sstevel@tonic-gate if (t)
3437c478bd9Sstevel@tonic-gate return (write(fd, t->start, t->size));
3447c478bd9Sstevel@tonic-gate }
3457c478bd9Sstevel@tonic-gate errno = EINVAL;
3467c478bd9Sstevel@tonic-gate return (-1);
3477c478bd9Sstevel@tonic-gate }
3487c478bd9Sstevel@tonic-gate
3497c478bd9Sstevel@tonic-gate /*
3507c478bd9Sstevel@tonic-gate * Writes the document page to the fd
3517c478bd9Sstevel@tonic-gate */
3527c478bd9Sstevel@tonic-gate int
WritePage(int fd,PAGE * p,int global,char * bptr)3537c478bd9Sstevel@tonic-gate WritePage(int fd, PAGE * p, int global, char *bptr)
3547c478bd9Sstevel@tonic-gate {
3557c478bd9Sstevel@tonic-gate if (p) {
3567c478bd9Sstevel@tonic-gate caddr_t ptr1;
3577c478bd9Sstevel@tonic-gate
3587c478bd9Sstevel@tonic-gate if (((ptr1 = nstrstr(p->start, PS_BEGIN_GLOBAL, bptr))
3597c478bd9Sstevel@tonic-gate != NULL) && (ptr1 < p->start + p->size) &&
3607c478bd9Sstevel@tonic-gate (global != 0)) {
3617c478bd9Sstevel@tonic-gate /* BeginGlobal/EndGlobal in the page... */
3627c478bd9Sstevel@tonic-gate write(fd, p->start, ptr1 - p->start);
3637c478bd9Sstevel@tonic-gate ptr1 = nstrstr(ptr1, PS_END_GLOBAL, bptr);
3647c478bd9Sstevel@tonic-gate ptr1 += nstrlen(PS_END_GLOBAL, bptr);
3657c478bd9Sstevel@tonic-gate return (write(fd, ptr1, (p->size - (ptr1 - p->start))));
3667c478bd9Sstevel@tonic-gate } else
3677c478bd9Sstevel@tonic-gate return (write(fd, p->start, p->size));
3687c478bd9Sstevel@tonic-gate }
3697c478bd9Sstevel@tonic-gate errno = EINVAL;
3707c478bd9Sstevel@tonic-gate return (-1);
3717c478bd9Sstevel@tonic-gate }
3727c478bd9Sstevel@tonic-gate
3737c478bd9Sstevel@tonic-gate /*
3747c478bd9Sstevel@tonic-gate * Writes out the document pages in pageList (or all if NULL) and reverse
3757c478bd9Sstevel@tonic-gate * the output if reverse == 1
3767c478bd9Sstevel@tonic-gate */
3777c478bd9Sstevel@tonic-gate void
WriteDocument(DOCUMENT * document,int reverse,int ** pageList)3787c478bd9Sstevel@tonic-gate WriteDocument(DOCUMENT * document, int reverse, int **pageList)
3797c478bd9Sstevel@tonic-gate {
3807c478bd9Sstevel@tonic-gate int count = 0;
3817c478bd9Sstevel@tonic-gate int prnindex;
3827c478bd9Sstevel@tonic-gate
3837c478bd9Sstevel@tonic-gate if (document->header && document->trailer && document->page) {
3847c478bd9Sstevel@tonic-gate WriteDocumentHeader(1, document);
3857c478bd9Sstevel@tonic-gate
3867c478bd9Sstevel@tonic-gate if (document->global != NULL) {
3877c478bd9Sstevel@tonic-gate while (document->global[count] != NULL) {
3887c478bd9Sstevel@tonic-gate GLOBAL *global = document->global[count++];
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate if (global)
3917c478bd9Sstevel@tonic-gate WriteGlobal(1, global);
3927c478bd9Sstevel@tonic-gate }
3937c478bd9Sstevel@tonic-gate }
3947c478bd9Sstevel@tonic-gate count = reverse ? (document->pages-1) : 0;
3957c478bd9Sstevel@tonic-gate
3967c478bd9Sstevel@tonic-gate for (prnindex = 0; prnindex < document->pages; prnindex++) {
3977c478bd9Sstevel@tonic-gate PAGE *page = document->page[count];
3987c478bd9Sstevel@tonic-gate
3997c478bd9Sstevel@tonic-gate if (page && PageIsListed(page->number, pageList))
4007c478bd9Sstevel@tonic-gate WritePage(1, page, document->global != NULL,
4017c478bd9Sstevel@tonic-gate document->start + document->size);
4027c478bd9Sstevel@tonic-gate
4037c478bd9Sstevel@tonic-gate count = reverse ? count - 1 : count + 1;
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate WriteDocumentTrailer(1, document);
4077c478bd9Sstevel@tonic-gate } else {
4087c478bd9Sstevel@tonic-gate write(1, document->start, document->size);
4097c478bd9Sstevel@tonic-gate }
4107c478bd9Sstevel@tonic-gate }
4117c478bd9Sstevel@tonic-gate
4127c478bd9Sstevel@tonic-gate /*
4137c478bd9Sstevel@tonic-gate * get a document header from document and return a pointer to a HEADER
4147c478bd9Sstevel@tonic-gate * structure.
4157c478bd9Sstevel@tonic-gate */
4167c478bd9Sstevel@tonic-gate HEADER *
DocumentHeader(DOCUMENT * document)4177c478bd9Sstevel@tonic-gate DocumentHeader(DOCUMENT * document)
4187c478bd9Sstevel@tonic-gate {
4197c478bd9Sstevel@tonic-gate HEADER *header;
4207c478bd9Sstevel@tonic-gate caddr_t start;
4217c478bd9Sstevel@tonic-gate
4227c478bd9Sstevel@tonic-gate header = (HEADER *) nmalloc(sizeof (*header));
4237c478bd9Sstevel@tonic-gate memset(header, 0, sizeof (*header));
4247c478bd9Sstevel@tonic-gate if (start = nstrstr(document->start, PS_PAGE,
4257c478bd9Sstevel@tonic-gate document->start + document->size)) {
4267c478bd9Sstevel@tonic-gate header->label = "Document Header";
4277c478bd9Sstevel@tonic-gate header->start = document->start;
4287c478bd9Sstevel@tonic-gate header->size = (start - document->start + 1);
4297c478bd9Sstevel@tonic-gate } else {
4307c478bd9Sstevel@tonic-gate free(header);
4317c478bd9Sstevel@tonic-gate header = NULL;
4327c478bd9Sstevel@tonic-gate }
4337c478bd9Sstevel@tonic-gate return (header);
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate
4367c478bd9Sstevel@tonic-gate
4377c478bd9Sstevel@tonic-gate /*
4387c478bd9Sstevel@tonic-gate * get a document trailer from document and return a pointer to a trailer
4397c478bd9Sstevel@tonic-gate * structure.
4407c478bd9Sstevel@tonic-gate */
4417c478bd9Sstevel@tonic-gate TRAILER *
DocumentTrailer(DOCUMENT * document)4427c478bd9Sstevel@tonic-gate DocumentTrailer(DOCUMENT * document)
4437c478bd9Sstevel@tonic-gate {
4447c478bd9Sstevel@tonic-gate TRAILER *trailer;
4457c478bd9Sstevel@tonic-gate
4467c478bd9Sstevel@tonic-gate trailer = (TRAILER *) nmalloc(sizeof (*trailer));
4477c478bd9Sstevel@tonic-gate memset(trailer, 0, sizeof (trailer));
4487c478bd9Sstevel@tonic-gate if (trailer->start = strrstr(document->start, PS_TRAILER,
4497c478bd9Sstevel@tonic-gate document->start + document->size)) {
4507c478bd9Sstevel@tonic-gate trailer->label = "Document Trailer";
4517c478bd9Sstevel@tonic-gate trailer->start += 1;
4527c478bd9Sstevel@tonic-gate trailer->size = nstrlen(trailer->start,
4537c478bd9Sstevel@tonic-gate document->start + document->size);
4547c478bd9Sstevel@tonic-gate } else {
4557c478bd9Sstevel@tonic-gate free(trailer);
4567c478bd9Sstevel@tonic-gate trailer = NULL;
4577c478bd9Sstevel@tonic-gate }
4587c478bd9Sstevel@tonic-gate return (trailer);
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate
4617c478bd9Sstevel@tonic-gate GLOBAL **
DocumentGlobals(DOCUMENT * document)4627c478bd9Sstevel@tonic-gate DocumentGlobals(DOCUMENT * document)
4637c478bd9Sstevel@tonic-gate {
4647c478bd9Sstevel@tonic-gate GLOBAL **globals = NULL, *global;
4657c478bd9Sstevel@tonic-gate caddr_t start, ptr1;
4667c478bd9Sstevel@tonic-gate int count = 0;
4677c478bd9Sstevel@tonic-gate char *bptr = document->start + document->size;
4687c478bd9Sstevel@tonic-gate long allocated_slots = 0;
4697c478bd9Sstevel@tonic-gate caddr_t global_end;
4707c478bd9Sstevel@tonic-gate
4717c478bd9Sstevel@tonic-gate start = nstrstr(document->start, PS_PAGE, bptr);
4727c478bd9Sstevel@tonic-gate if (start != NULL) {
4737c478bd9Sstevel@tonic-gate for (ptr1 = nstrstr(start, PS_BEGIN_GLOBAL, bptr); ptr1 != NULL;
4747c478bd9Sstevel@tonic-gate ptr1 = nstrstr(++ptr1, PS_BEGIN_GLOBAL, bptr)) {
4757c478bd9Sstevel@tonic-gate count++;
4767c478bd9Sstevel@tonic-gate
4777c478bd9Sstevel@tonic-gate global = (GLOBAL *) nmalloc(sizeof (GLOBAL));
4787c478bd9Sstevel@tonic-gate if ((global_end = nstrstr(++ptr1, PS_END_GLOBAL, bptr))
4797c478bd9Sstevel@tonic-gate == NULL) {
4807c478bd9Sstevel@tonic-gate fprintf(stderr,
4817c478bd9Sstevel@tonic-gate "DSC violation: %%%%BeginGlobal "
4827c478bd9Sstevel@tonic-gate "with no %%%%EndGlobal\n");
4837c478bd9Sstevel@tonic-gate exit(-1);
4847c478bd9Sstevel@tonic-gate }
4857c478bd9Sstevel@tonic-gate memset(global, 0, sizeof (GLOBAL));
4867c478bd9Sstevel@tonic-gate global->start = ptr1;
4877c478bd9Sstevel@tonic-gate global->size = strchr(++global_end, '\n') - ptr1 + 1;
4887c478bd9Sstevel@tonic-gate
4897c478bd9Sstevel@tonic-gate if (count > allocated_slots) {
4907c478bd9Sstevel@tonic-gate globals = (GLOBAL **) nrealloc(globals,
4917c478bd9Sstevel@tonic-gate (allocated_slots + BLOCKSIZE) *
4927c478bd9Sstevel@tonic-gate sizeof (GLOBAL *));
4937c478bd9Sstevel@tonic-gate memset(globals +
4947c478bd9Sstevel@tonic-gate allocated_slots * sizeof (GLOBAL *), 0,
4957c478bd9Sstevel@tonic-gate BLOCKSIZE *
4967c478bd9Sstevel@tonic-gate sizeof (GLOBAL *));
4977c478bd9Sstevel@tonic-gate allocated_slots += BLOCKSIZE;
4987c478bd9Sstevel@tonic-gate }
4997c478bd9Sstevel@tonic-gate
5007c478bd9Sstevel@tonic-gate globals[count - 1] = global;
5017c478bd9Sstevel@tonic-gate ptr1 = global->start + global->size;
5027c478bd9Sstevel@tonic-gate }
5037c478bd9Sstevel@tonic-gate }
5047c478bd9Sstevel@tonic-gate return (globals);
5057c478bd9Sstevel@tonic-gate }
5067c478bd9Sstevel@tonic-gate
5077c478bd9Sstevel@tonic-gate
5087c478bd9Sstevel@tonic-gate /*
5097c478bd9Sstevel@tonic-gate * get the pages from a document and return a pointer a list of PAGE
5107c478bd9Sstevel@tonic-gate * structures.
5117c478bd9Sstevel@tonic-gate */
5127c478bd9Sstevel@tonic-gate PAGE **
DocumentPages(DOCUMENT * document)5137c478bd9Sstevel@tonic-gate DocumentPages(DOCUMENT * document)
5147c478bd9Sstevel@tonic-gate {
5157c478bd9Sstevel@tonic-gate PAGE **pages = NULL, *page;
5167c478bd9Sstevel@tonic-gate caddr_t ptr1, page_end;
5177c478bd9Sstevel@tonic-gate char *bptr = document->start + document->size;
5187c478bd9Sstevel@tonic-gate long allocated_slots = 0;
5197c478bd9Sstevel@tonic-gate long no_pages = 0;
5207c478bd9Sstevel@tonic-gate long number;
5217c478bd9Sstevel@tonic-gate char *label, *tmp, *tmp_end;
5227c478bd9Sstevel@tonic-gate
5237c478bd9Sstevel@tonic-gate for (ptr1 = nstrstr(document->start, PS_PAGE, bptr); ptr1 != NULL;
5245699d47bSps ptr1 = nstrstr(++ptr1, PS_PAGE, bptr)) {
5257c478bd9Sstevel@tonic-gate no_pages++;
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate if (no_pages > allocated_slots) {
5287c478bd9Sstevel@tonic-gate pages = (PAGE **) nrealloc(pages,
5295699d47bSps (allocated_slots + BLOCKSIZE) * sizeof (PAGE *));
5305699d47bSps memset(pages + allocated_slots, 0,
5315699d47bSps BLOCKSIZE * sizeof (PAGE *));
5327c478bd9Sstevel@tonic-gate allocated_slots += BLOCKSIZE;
5337c478bd9Sstevel@tonic-gate }
5347c478bd9Sstevel@tonic-gate page = (PAGE *) nmalloc(sizeof (PAGE));
5357c478bd9Sstevel@tonic-gate label = NULL;
5367c478bd9Sstevel@tonic-gate number = -1;
5377c478bd9Sstevel@tonic-gate
5387c478bd9Sstevel@tonic-gate /* page start & end */
5397c478bd9Sstevel@tonic-gate if ((page_end = nstrstr(++ptr1, PS_PAGE, bptr)) == NULL)
5407c478bd9Sstevel@tonic-gate if (document->trailer)
5417c478bd9Sstevel@tonic-gate page_end = document->trailer->start - 1;
5427c478bd9Sstevel@tonic-gate else
5437c478bd9Sstevel@tonic-gate page_end = document->start + document->size;
5447c478bd9Sstevel@tonic-gate
5457c478bd9Sstevel@tonic-gate /* page label & number */
5467c478bd9Sstevel@tonic-gate if (tmp = strchr(ptr1, ' ')) {
5477c478bd9Sstevel@tonic-gate
5487c478bd9Sstevel@tonic-gate if (tmp_end = strchr(++tmp, ' ')) {
5497c478bd9Sstevel@tonic-gate label = (char *)nmalloc((tmp_end - tmp) + 1);
5507c478bd9Sstevel@tonic-gate memset(label, 0, (tmp_end - tmp) + 1);
5517c478bd9Sstevel@tonic-gate strncpy(label, tmp, (tmp_end - tmp));
5527c478bd9Sstevel@tonic-gate number = atol(++tmp_end);
5537c478bd9Sstevel@tonic-gate }
5547c478bd9Sstevel@tonic-gate }
5557c478bd9Sstevel@tonic-gate memset(page, 0, sizeof (PAGE));
5567c478bd9Sstevel@tonic-gate page->label = label;
5577c478bd9Sstevel@tonic-gate page->number = number;
5587c478bd9Sstevel@tonic-gate page->start = ptr1;
5597c478bd9Sstevel@tonic-gate page->size = page_end - ptr1 + 1;
5607c478bd9Sstevel@tonic-gate
5617c478bd9Sstevel@tonic-gate pages[document->pages++] = page;
5627c478bd9Sstevel@tonic-gate }
5637c478bd9Sstevel@tonic-gate return (pages);
5647c478bd9Sstevel@tonic-gate }
5657c478bd9Sstevel@tonic-gate
5667c478bd9Sstevel@tonic-gate /*
5677c478bd9Sstevel@tonic-gate * parse a document and return a pointer to a DOCUMENT structure
5687c478bd9Sstevel@tonic-gate */
5697c478bd9Sstevel@tonic-gate DOCUMENT *
DocumentParse(char * name)5707c478bd9Sstevel@tonic-gate DocumentParse(char *name)
5717c478bd9Sstevel@tonic-gate {
5727c478bd9Sstevel@tonic-gate DOCUMENT *document = NULL;
5737c478bd9Sstevel@tonic-gate int fd;
5747c478bd9Sstevel@tonic-gate struct stat st;
5757c478bd9Sstevel@tonic-gate
5767c478bd9Sstevel@tonic-gate if (stat(name, &st) < 0) {
5777c478bd9Sstevel@tonic-gate fprintf(stderr, "stat(%s): %s\n", name, strerror(errno));
5787c478bd9Sstevel@tonic-gate return (NULL);
5797c478bd9Sstevel@tonic-gate }
5807c478bd9Sstevel@tonic-gate if (st.st_size == 0) {
5817c478bd9Sstevel@tonic-gate fprintf(stderr, "%s: empty file\n", name);
5827c478bd9Sstevel@tonic-gate return (NULL);
5837c478bd9Sstevel@tonic-gate }
5847c478bd9Sstevel@tonic-gate if ((fd = open(name, O_RDONLY)) < 0) {
5857c478bd9Sstevel@tonic-gate fprintf(stderr, "open(%s, O_RDONLY): %s\n", name,
5867c478bd9Sstevel@tonic-gate strerror(errno));
5877c478bd9Sstevel@tonic-gate return (NULL);
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate document = (DOCUMENT *) nmalloc(sizeof (DOCUMENT));
5907c478bd9Sstevel@tonic-gate memset(document, 0, sizeof (DOCUMENT));
5917c478bd9Sstevel@tonic-gate if ((document->start = mmap((void *)0, (size_t)st.st_size, PROT_READ,
5927c478bd9Sstevel@tonic-gate MAP_SHARED, fd, (off_t)0)) == MAP_FAILED) {
5937c478bd9Sstevel@tonic-gate fprintf(stderr, "mmap(0, %ld, PROT_READ,"
5947c478bd9Sstevel@tonic-gate " MAP_SHARED, %d, 0): %s\n",
5957c478bd9Sstevel@tonic-gate st.st_size, fd, strerror(errno));
5967c478bd9Sstevel@tonic-gate free(document);
5977c478bd9Sstevel@tonic-gate document = NULL;
5987c478bd9Sstevel@tonic-gate } else {
5997c478bd9Sstevel@tonic-gate /* order in important */
6007c478bd9Sstevel@tonic-gate document->name = strdup(name);
6017c478bd9Sstevel@tonic-gate document->size = nstrlen(document->start,
6027c478bd9Sstevel@tonic-gate document->start + st.st_size);
6037c478bd9Sstevel@tonic-gate document->header = DocumentHeader(document);
6047c478bd9Sstevel@tonic-gate document->trailer = DocumentTrailer(document);
6057c478bd9Sstevel@tonic-gate document->page = DocumentPages(document);
6067c478bd9Sstevel@tonic-gate document->global = DocumentGlobals(document);
6077c478bd9Sstevel@tonic-gate }
6087c478bd9Sstevel@tonic-gate close(fd);
6097c478bd9Sstevel@tonic-gate return (document);
6107c478bd9Sstevel@tonic-gate }
6117c478bd9Sstevel@tonic-gate
6127c478bd9Sstevel@tonic-gate
6137c478bd9Sstevel@tonic-gate #if defined(DEBUG)
6147c478bd9Sstevel@tonic-gate /*
6157c478bd9Sstevel@tonic-gate * Print out the contents of the document structure
6167c478bd9Sstevel@tonic-gate */
6177c478bd9Sstevel@tonic-gate void
PrintDocumentInfo(DOCUMENT * d)6187c478bd9Sstevel@tonic-gate PrintDocumentInfo(DOCUMENT * d)
6197c478bd9Sstevel@tonic-gate {
6207c478bd9Sstevel@tonic-gate if (d) {
6217c478bd9Sstevel@tonic-gate printf("Document:\n\tname: %s\n\tstart: 0x%x\n\tsize: %ld\n",
6227c478bd9Sstevel@tonic-gate d->name, d->start, d->size);
6237c478bd9Sstevel@tonic-gate if (d->header) {
6247c478bd9Sstevel@tonic-gate HEADER *h = d->header;
6257c478bd9Sstevel@tonic-gate
6267c478bd9Sstevel@tonic-gate printf("\tHeader: %s (0x%x, %ld)\n",
6277c478bd9Sstevel@tonic-gate h->label, h->start, h->size);
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate if (d->global) {
6307c478bd9Sstevel@tonic-gate int count = 0;
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate while (d->global[count++] != NULL);
6337c478bd9Sstevel@tonic-gate printf("\tDSC violating BeginGlobals: %d\n", count);
6347c478bd9Sstevel@tonic-gate }
6357c478bd9Sstevel@tonic-gate if (d->page) {
6367c478bd9Sstevel@tonic-gate PAGE *p;
6377c478bd9Sstevel@tonic-gate int count = 0;
6387c478bd9Sstevel@tonic-gate
6397c478bd9Sstevel@tonic-gate printf("\tPages: (%d)\n", d->pages);
6407c478bd9Sstevel@tonic-gate for (p = d->page[0]; p != NULL; p = d->page[++count])
6417c478bd9Sstevel@tonic-gate printf("\t\t %4d (%s) - (0x%x, %ld)\n",
6427c478bd9Sstevel@tonic-gate p->number,
6437c478bd9Sstevel@tonic-gate (p->label ? p->label : "Page"),
6447c478bd9Sstevel@tonic-gate p->start, p->size);
6457c478bd9Sstevel@tonic-gate }
6467c478bd9Sstevel@tonic-gate if (d->trailer) {
6477c478bd9Sstevel@tonic-gate TRAILER *t = d->trailer;
6487c478bd9Sstevel@tonic-gate
6497c478bd9Sstevel@tonic-gate printf("\tTrailer: %s (0x%x, %ld)\n",
6507c478bd9Sstevel@tonic-gate t->label, t->start, t->size);
6517c478bd9Sstevel@tonic-gate }
6527c478bd9Sstevel@tonic-gate }
6537c478bd9Sstevel@tonic-gate }
6547c478bd9Sstevel@tonic-gate #endif /* DEBUG */
6557c478bd9Sstevel@tonic-gate
6567c478bd9Sstevel@tonic-gate
657f928ce67Sceastha int
main(int ac,char * av[])6587c478bd9Sstevel@tonic-gate main(int ac, char *av[])
6597c478bd9Sstevel@tonic-gate {
6607c478bd9Sstevel@tonic-gate DOCUMENT *document;
6617c478bd9Sstevel@tonic-gate char *fileName = NULL;
6627c478bd9Sstevel@tonic-gate char *programName = NULL;
6637c478bd9Sstevel@tonic-gate char *unlinkFile = NULL;
6647c478bd9Sstevel@tonic-gate int reversePages = 1;
6657c478bd9Sstevel@tonic-gate int **pageList = NULL;
6667c478bd9Sstevel@tonic-gate int option;
6677c478bd9Sstevel@tonic-gate
6687c478bd9Sstevel@tonic-gate if (programName = strrchr(av[0], '/'))
6697c478bd9Sstevel@tonic-gate programName++;
6707c478bd9Sstevel@tonic-gate else
6717c478bd9Sstevel@tonic-gate programName = av[0];
6727c478bd9Sstevel@tonic-gate
6737c478bd9Sstevel@tonic-gate while ((option = getopt(ac, av, "o:r")) != EOF)
6747c478bd9Sstevel@tonic-gate switch (option) {
6757c478bd9Sstevel@tonic-gate case 'o':
6767c478bd9Sstevel@tonic-gate pageList = ParsePageList(optarg);
6777c478bd9Sstevel@tonic-gate break;
6787c478bd9Sstevel@tonic-gate case 'r':
6797c478bd9Sstevel@tonic-gate reversePages = 0;
6807c478bd9Sstevel@tonic-gate break;
6817c478bd9Sstevel@tonic-gate case '?':
6827c478bd9Sstevel@tonic-gate Usage(programName);
6837c478bd9Sstevel@tonic-gate break;
6847c478bd9Sstevel@tonic-gate default:
6857c478bd9Sstevel@tonic-gate fprintf(stderr, "missing case for option %c\n", option);
6867c478bd9Sstevel@tonic-gate Usage(programName);
6877c478bd9Sstevel@tonic-gate break;
6887c478bd9Sstevel@tonic-gate }
6897c478bd9Sstevel@tonic-gate
6907c478bd9Sstevel@tonic-gate ac -= optind;
6917c478bd9Sstevel@tonic-gate av += optind;
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate switch (ac) {
6947c478bd9Sstevel@tonic-gate case 0:
6957c478bd9Sstevel@tonic-gate unlinkFile = fileName = StdinToFile();
6967c478bd9Sstevel@tonic-gate break;
6977c478bd9Sstevel@tonic-gate case 1:
6987c478bd9Sstevel@tonic-gate fileName = av[0];
6997c478bd9Sstevel@tonic-gate break;
7007c478bd9Sstevel@tonic-gate default:
7017c478bd9Sstevel@tonic-gate Usage(programName);
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate if ((document = DocumentParse(fileName)) == NULL) {
7057c478bd9Sstevel@tonic-gate fprintf(stderr, "Unable to parse document (%s)\n", fileName);
7067c478bd9Sstevel@tonic-gate exit(0);
7077c478bd9Sstevel@tonic-gate }
7087c478bd9Sstevel@tonic-gate #if defined(DEBUG) && defined(NOTDEF)
7097c478bd9Sstevel@tonic-gate PrintDocumentInfo(document);
7107c478bd9Sstevel@tonic-gate #endif /* DEBUG */
7117c478bd9Sstevel@tonic-gate
7127c478bd9Sstevel@tonic-gate WriteDocument(document, reversePages, pageList);
7137c478bd9Sstevel@tonic-gate
7147c478bd9Sstevel@tonic-gate if (unlinkFile)
7157c478bd9Sstevel@tonic-gate unlink(unlinkFile);
7167c478bd9Sstevel@tonic-gate
717f928ce67Sceastha return (0);
7187c478bd9Sstevel@tonic-gate }
719