1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 6633 ps29005 * Common Development and Distribution License (the "License"). 6 6633 ps29005 * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 6633 ps29005 * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel #pragma ident "%Z%%M% %I% %E% SMI" 27 0 stevel 28 0 stevel #include <stdio.h> 29 0 stevel #include <stdlib.h> 30 0 stevel #include <sys/types.h> 31 0 stevel #include <sys/file.h> 32 0 stevel #include <sys/fcntl.h> 33 0 stevel #include <sys/stat.h> 34 0 stevel #include <sys/mman.h> 35 0 stevel #include <string.h> 36 0 stevel #include <errno.h> 37 0 stevel #include "postreverse.h" 38 0 stevel 39 0 stevel /* 40 0 stevel * This version of postreverse should parse any Adobe DSC conforming 41 0 stevel * PostScript file and most that are not conforming, but minimally have the 42 0 stevel * page (%%Page:) and trailer (%%Trailer) comments in them at the begining of 43 0 stevel * the line. 44 0 stevel * 45 0 stevel * If a document cannot be parsed (no page and trailer comments), it is passed 46 0 stevel * through untouched. If you look through the code you will find that it 47 0 stevel * doesn't ever look for the PostScript magic (%!). This is because it 48 0 stevel * assumes that PostScript is sent in. If PostScript is in sent in, it will 49 0 stevel * still attempt to parse it based on DSC page and trailer comments as if it 50 0 stevel * were postscript. 51 0 stevel * 52 0 stevel * flow goes as follows: 53 0 stevel * 1) get command line options (including parsing a page 54 0 stevel * list if supplied) 55 0 stevel * 2) if no filename is supplied in command line, copy 56 0 stevel * stdin to temp file. 57 0 stevel * 3) parse the document: 58 0 stevel * start from begining looking for a DSC page comment 59 0 stevel * (that is the header) start from the end looking for 60 0 stevel * a DSC trailer comment (that is the trailer) start from 61 0 stevel * the header until the trailer looking for DSC page 62 0 stevel * comments. Each one signifies a new page. 63 0 stevel * start from the header until the trailer looking for BSD 64 0 stevel * global comments. Each one violates page independence and 65 0 stevel * will be stored so it can be printed after the header and 66 0 stevel * before any pages. 67 0 stevel * 4) print the document: if there is no header, trailer, or 68 0 stevel * pages, print it from start to end unaltered if they all 69 0 stevel * exist, print the header, pages, and trailer the pages 70 0 stevel * are compared against a page list before being printed, 71 0 stevel * and are reversed if the reverse flag has been set. 72 0 stevel * If global definitions were found in the pages of a 73 0 stevel * document, they are printed after the header and before 74 0 stevel * the pages. 75 0 stevel */ 76 0 stevel 77 0 stevel static void * 78 0 stevel nmalloc(size_t size) 79 0 stevel { 80 0 stevel void *ret = malloc(size); 81 0 stevel 82 0 stevel if (!ret) { 83 0 stevel (void) fprintf(stderr, 84 0 stevel "postreverse : malloc() failed : Out of memory\n"); 85 0 stevel exit(2); 86 0 stevel } 87 0 stevel return (ret); 88 0 stevel } 89 0 stevel 90 0 stevel static void * 91 0 stevel nrealloc(void *ptr, size_t size) 92 0 stevel { 93 0 stevel void *ret = realloc(ptr, size); 94 0 stevel 95 0 stevel if (!ret) { 96 0 stevel (void) fprintf(stderr, 97 0 stevel "postreverse : realloc() failed - Out of memory\n"); 98 0 stevel exit(2); 99 0 stevel } 100 0 stevel return (ret); 101 0 stevel } 102 0 stevel 103 0 stevel /* 104 0 stevel * nstrlen() provides the same functionality as strlen() while also checking 105 0 stevel * that the pointer does not cross the end of file. 106 0 stevel * 107 0 stevel * Returns the number of non-NULL bytes in string argument. 108 0 stevel */ 109 0 stevel 110 0 stevel static size_t 111 0 stevel nstrlen(const char *s, char *bptr) 112 0 stevel { 113 0 stevel const char *s0 = s; 114 0 stevel 115 0 stevel while (s < bptr && *s != '\0') 116 0 stevel s++; 117 0 stevel return (s - s0); 118 0 stevel } 119 0 stevel 120 0 stevel /* 121 0 stevel * nstrstr() provides the same functionality as strstr() while also checking 122 0 stevel * that the pointers do not cross the end of the file. 123 0 stevel * 124 0 stevel * nstrstr() locates the first occurrence in the string as1 of the sequence of 125 0 stevel * characters (excluding the terminating null character) in the string as2. 126 0 stevel * nstrstr() returns a pointer to the located string, or a null pointer if 127 0 stevel * the string is not found. If as2 is "", the function returns as1. 128 0 stevel */ 129 0 stevel 130 0 stevel static char * 131 0 stevel nstrstr(const char *as1, const char *as2, char *bptr) 132 0 stevel { 133 0 stevel const char *s1, *s2; 134 0 stevel const char *tptr; 135 0 stevel char c; 136 0 stevel 137 0 stevel s1 = as1; 138 0 stevel s2 = as2; 139 0 stevel 140 0 stevel if (s2 == NULL || *s2 == '\0') 141 0 stevel return ((char *)s1); 142 0 stevel c = *s2; 143 0 stevel 144 0 stevel while (s1 < bptr && *s1) 145 0 stevel if (*s1++ == c) { 146 0 stevel tptr = s1; 147 0 stevel while ((s1 < bptr) && 148 0 stevel (c = *++s2) == *s1++ && c); 149 0 stevel if (c == 0) 150 0 stevel return ((char *)tptr - 1); 151 0 stevel s1 = tptr; 152 0 stevel s2 = as2; 153 0 stevel c = *s2; 154 0 stevel } 155 0 stevel return (NULL); 156 0 stevel } 157 0 stevel 158 0 stevel 159 0 stevel /* 160 0 stevel * caddr_t strrstr(caddr_t as1, caddr_t as2 char *bptr1) 161 0 stevel * return the address of the beginning of the last occruence of as2 162 0 stevel * in as1 or NULL if not found 163 0 stevel */ 164 0 stevel caddr_t 165 0 stevel strrstr(caddr_t s1, caddr_t s2, char *bptr) 166 0 stevel { 167 0 stevel char *t1, *t2; 168 0 stevel char c; 169 0 stevel 170 0 stevel 171 0 stevel t1 = s1 + nstrlen(s1, bptr) - 1; 172 0 stevel t2 = s2 + nstrlen(s2, bptr) - 1; 173 0 stevel 174 0 stevel if (t2 == NULL || *t2 == '\0') 175 0 stevel return ((char *)t1); 176 0 stevel c = *t2; 177 0 stevel 178 0 stevel while (s1 <= t1) 179 0 stevel if (*t1-- == c) { 180 0 stevel while ((c = *--t2) == *t1-- && t2 > s2); 181 0 stevel if (t2 <= s2) 182 0 stevel return ((char *)t1 + 1); 183 0 stevel t2 = s2 + nstrlen(s2, bptr) - 1; 184 0 stevel c = *t2; 185 0 stevel } 186 0 stevel return (NULL); 187 0 stevel } 188 0 stevel 189 0 stevel /* 190 0 stevel * Copy stdin to a temp file and return the name 191 0 stevel */ 192 0 stevel char * 193 0 stevel StdinToFile() 194 0 stevel { 195 0 stevel char *fileName = tmpnam(NULL); 196 0 stevel int fd; 197 0 stevel int count; 198 0 stevel char buf[BUFSIZ]; 199 0 stevel 200 0 stevel if ((fd = open(fileName, O_RDWR | O_CREAT | O_EXCL, 0600)) < 0) { 201 0 stevel fprintf(stderr, "open(%s): %s\n", fileName, 202 0 stevel strerror(errno)); 203 0 stevel return (NULL); 204 0 stevel } 205 0 stevel while ((count = read(0, buf, sizeof (buf))) > 0) 206 0 stevel if (write(fd, buf, count) != count) { 207 0 stevel fprintf(stderr, "write(%d, 0x%x, %d): %s\n", fd, buf, 208 0 stevel count, strerror(errno)); 209 0 stevel close(fd); 210 0 stevel unlink(fileName); 211 0 stevel return (NULL); 212 0 stevel } 213 0 stevel return (fileName); 214 0 stevel } 215 0 stevel 216 0 stevel /* 217 0 stevel * Usage(char *name) - program usage 218 0 stevel */ 219 0 stevel void 220 0 stevel Usage(char *name) 221 0 stevel { 222 0 stevel fprintf(stderr, "Usage: %s [ -o list ] [ -r ] [ filename ]\n", name); 223 0 stevel exit(1); 224 0 stevel } 225 0 stevel 226 0 stevel 227 0 stevel /* 228 0 stevel * int **ParsePageList(char *list) 229 0 stevel * This will parse as string #,#,#-#,#... into an array of pointers 230 0 stevel * to integers. This array will contain all numbers in the list including 231 0 stevel * those int the range #-#. The list returned is NULL terminated. 232 0 stevel * It uses 2 passes to build the list. pass 1 counts the # of ints and 233 0 stevel * allocates the space, and pass 2 fills in the list. 234 0 stevel */ 235 0 stevel int ** 236 0 stevel ParsePageList(char *list) 237 0 stevel { 238 0 stevel int **pageList = NULL; 239 0 stevel int pass = 0; 240 0 stevel 241 0 stevel if (list == NULL) 242 0 stevel return (NULL); 243 0 stevel 244 0 stevel while (pass++ < 2) { 245 0 stevel char *page; 246 0 stevel char *tmplist; 247 0 stevel int size = 0; 248 0 stevel 249 0 stevel tmplist = strdup(list); 250 0 stevel page = strtok(tmplist, ","); 251 0 stevel 252 0 stevel do { 253 0 stevel int start, end; 254 0 stevel char *s1 = page, *s2; 255 0 stevel 256 0 stevel if (s2 = strchr(page, '-')) { 257 0 stevel *s2++ = NULL; 258 0 stevel start = atoi(s1); 259 0 stevel end = atoi(s2); 260 0 stevel if (end < start) { 261 0 stevel int tmp = end; 262 0 stevel 263 0 stevel end = start; 264 0 stevel start = tmp; 265 0 stevel } 266 0 stevel } else 267 0 stevel start = end = atoi(s1); 268 0 stevel 269 0 stevel while (start <= end) 270 0 stevel if (pass == 1) 271 0 stevel /* count the pages for allocation */ 272 0 stevel size++, start++; 273 0 stevel else { /* fill in the page list */ 274 0 stevel int *tmp = (int *)nmalloc(sizeof (int)); 275 0 stevel *tmp = start++; 276 0 stevel pageList[size++] = tmp; 277 0 stevel } 278 0 stevel } while (page = strtok(NULL, ",")); 279 0 stevel free(tmplist); 280 0 stevel if (pass == 1) 281 0 stevel pageList = (int **)calloc(sizeof (int *), (size + 1)); 282 0 stevel } 283 0 stevel return (pageList); 284 0 stevel } 285 0 stevel 286 0 stevel 287 0 stevel /* 288 0 stevel * int PageIsListed(int page, int **pageList) 289 0 stevel * returns 1 if the pagelist is empty or if the page is in the 290 0 stevel * NULL terminated pageList. returns 0 if the page is not listed 291 0 stevel */ 292 0 stevel int 293 0 stevel PageIsListed(int page, int **pageList) 294 0 stevel { 295 0 stevel int count = 0; 296 0 stevel 297 0 stevel if (!pageList) 298 0 stevel return (1); 299 0 stevel 300 0 stevel for (count = 0; pageList[count] != NULL; count++) 301 0 stevel if (*pageList[count] == page) 302 0 stevel return (1); 303 0 stevel return (0); 304 0 stevel } 305 0 stevel 306 0 stevel 307 0 stevel /* 308 0 stevel * Writes the document Header to the fd 309 0 stevel */ 310 0 stevel int 311 0 stevel WriteDocumentHeader(int fd, DOCUMENT * d) 312 0 stevel { 313 0 stevel if (d) { 314 0 stevel HEADER *h = d->header; 315 0 stevel 316 0 stevel if (h) 317 0 stevel return (write(fd, h->start, h->size)); 318 0 stevel } 319 0 stevel errno = EINVAL; 320 0 stevel return (-1); 321 0 stevel } 322 0 stevel 323 0 stevel /* 324 0 stevel * Writes the document global block to the fd 325 0 stevel */ 326 0 stevel int 327 0 stevel WriteGlobal(int fd, GLOBAL * g) 328 0 stevel { 329 0 stevel if (g) 330 0 stevel return (write(fd, g->start, g->size)); 331 0 stevel errno = EINVAL; 332 0 stevel return (-1); 333 0 stevel } 334 0 stevel 335 0 stevel /* 336 0 stevel * Writes the document Trailer to the fd 337 0 stevel */ 338 0 stevel int 339 0 stevel WriteDocumentTrailer(int fd, DOCUMENT * d) 340 0 stevel { 341 0 stevel if (d) { 342 0 stevel TRAILER *t = d->trailer; 343 0 stevel 344 0 stevel if (t) 345 0 stevel return (write(fd, t->start, t->size)); 346 0 stevel } 347 0 stevel errno = EINVAL; 348 0 stevel return (-1); 349 0 stevel } 350 0 stevel 351 0 stevel /* 352 0 stevel * Writes the document page to the fd 353 0 stevel */ 354 0 stevel int 355 0 stevel WritePage(int fd, PAGE * p, int global, char *bptr) 356 0 stevel { 357 0 stevel if (p) { 358 0 stevel caddr_t ptr1; 359 0 stevel 360 0 stevel if (((ptr1 = nstrstr(p->start, PS_BEGIN_GLOBAL, bptr)) 361 0 stevel != NULL) && (ptr1 < p->start + p->size) && 362 0 stevel (global != 0)) { 363 0 stevel /* BeginGlobal/EndGlobal in the page... */ 364 0 stevel write(fd, p->start, ptr1 - p->start); 365 0 stevel ptr1 = nstrstr(ptr1, PS_END_GLOBAL, bptr); 366 0 stevel ptr1 += nstrlen(PS_END_GLOBAL, bptr); 367 0 stevel return (write(fd, ptr1, (p->size - (ptr1 - p->start)))); 368 0 stevel } else 369 0 stevel return (write(fd, p->start, p->size)); 370 0 stevel } 371 0 stevel errno = EINVAL; 372 0 stevel return (-1); 373 0 stevel } 374 0 stevel 375 0 stevel /* 376 0 stevel * Writes out the document pages in pageList (or all if NULL) and reverse 377 0 stevel * the output if reverse == 1 378 0 stevel */ 379 0 stevel void 380 0 stevel WriteDocument(DOCUMENT * document, int reverse, int **pageList) 381 0 stevel { 382 0 stevel int count = 0; 383 0 stevel int prnindex; 384 0 stevel 385 0 stevel if (document->header && document->trailer && document->page) { 386 0 stevel WriteDocumentHeader(1, document); 387 0 stevel 388 0 stevel if (document->global != NULL) { 389 0 stevel while (document->global[count] != NULL) { 390 0 stevel GLOBAL *global = document->global[count++]; 391 0 stevel 392 0 stevel if (global) 393 0 stevel WriteGlobal(1, global); 394 0 stevel } 395 0 stevel } 396 0 stevel count = reverse ? (document->pages-1) : 0; 397 0 stevel 398 0 stevel for (prnindex = 0; prnindex < document->pages; prnindex++) { 399 0 stevel PAGE *page = document->page[count]; 400 0 stevel 401 0 stevel if (page && PageIsListed(page->number, pageList)) 402 0 stevel WritePage(1, page, document->global != NULL, 403 0 stevel document->start + document->size); 404 0 stevel 405 0 stevel count = reverse ? count - 1 : count + 1; 406 0 stevel } 407 0 stevel 408 0 stevel WriteDocumentTrailer(1, document); 409 0 stevel } else { 410 0 stevel write(1, document->start, document->size); 411 0 stevel } 412 0 stevel } 413 0 stevel 414 0 stevel /* 415 0 stevel * get a document header from document and return a pointer to a HEADER 416 0 stevel * structure. 417 0 stevel */ 418 0 stevel HEADER * 419 0 stevel DocumentHeader(DOCUMENT * document) 420 0 stevel { 421 0 stevel HEADER *header; 422 0 stevel caddr_t start; 423 0 stevel 424 0 stevel header = (HEADER *) nmalloc(sizeof (*header)); 425 0 stevel memset(header, 0, sizeof (*header)); 426 0 stevel if (start = nstrstr(document->start, PS_PAGE, 427 0 stevel document->start + document->size)) { 428 0 stevel header->label = "Document Header"; 429 0 stevel header->start = document->start; 430 0 stevel header->size = (start - document->start + 1); 431 0 stevel } else { 432 0 stevel free(header); 433 0 stevel header = NULL; 434 0 stevel } 435 0 stevel return (header); 436 0 stevel } 437 0 stevel 438 0 stevel 439 0 stevel /* 440 0 stevel * get a document trailer from document and return a pointer to a trailer 441 0 stevel * structure. 442 0 stevel */ 443 0 stevel TRAILER * 444 0 stevel DocumentTrailer(DOCUMENT * document) 445 0 stevel { 446 0 stevel TRAILER *trailer; 447 0 stevel 448 0 stevel trailer = (TRAILER *) nmalloc(sizeof (*trailer)); 449 0 stevel memset(trailer, 0, sizeof (trailer)); 450 0 stevel if (trailer->start = strrstr(document->start, PS_TRAILER, 451 0 stevel document->start + document->size)) { 452 0 stevel trailer->label = "Document Trailer"; 453 0 stevel trailer->start += 1; 454 0 stevel trailer->size = nstrlen(trailer->start, 455 0 stevel document->start + document->size); 456 0 stevel } else { 457 0 stevel free(trailer); 458 0 stevel trailer = NULL; 459 0 stevel } 460 0 stevel return (trailer); 461 0 stevel } 462 0 stevel 463 0 stevel GLOBAL ** 464 0 stevel DocumentGlobals(DOCUMENT * document) 465 0 stevel { 466 0 stevel GLOBAL **globals = NULL, *global; 467 0 stevel caddr_t start, ptr1; 468 0 stevel int count = 0; 469 0 stevel char *bptr = document->start + document->size; 470 0 stevel long allocated_slots = 0; 471 0 stevel caddr_t global_end; 472 0 stevel 473 0 stevel start = nstrstr(document->start, PS_PAGE, bptr); 474 0 stevel if (start != NULL) { 475 0 stevel for (ptr1 = nstrstr(start, PS_BEGIN_GLOBAL, bptr); ptr1 != NULL; 476 0 stevel ptr1 = nstrstr(++ptr1, PS_BEGIN_GLOBAL, bptr)) { 477 0 stevel count++; 478 0 stevel 479 0 stevel global = (GLOBAL *) nmalloc(sizeof (GLOBAL)); 480 0 stevel if ((global_end = nstrstr(++ptr1, PS_END_GLOBAL, bptr)) 481 0 stevel == NULL) { 482 0 stevel fprintf(stderr, 483 0 stevel "DSC violation: %%%%BeginGlobal " 484 0 stevel "with no %%%%EndGlobal\n"); 485 0 stevel exit(-1); 486 0 stevel } 487 0 stevel memset(global, 0, sizeof (GLOBAL)); 488 0 stevel global->start = ptr1; 489 0 stevel global->size = strchr(++global_end, '\n') - ptr1 + 1; 490 0 stevel 491 0 stevel if (count > allocated_slots) { 492 0 stevel globals = (GLOBAL **) nrealloc(globals, 493 0 stevel (allocated_slots + BLOCKSIZE) * 494 0 stevel sizeof (GLOBAL *)); 495 0 stevel memset(globals + 496 0 stevel allocated_slots * sizeof (GLOBAL *), 0, 497 0 stevel BLOCKSIZE * 498 0 stevel sizeof (GLOBAL *)); 499 0 stevel allocated_slots += BLOCKSIZE; 500 0 stevel } 501 0 stevel 502 0 stevel globals[count - 1] = global; 503 0 stevel ptr1 = global->start + global->size; 504 0 stevel } 505 0 stevel } 506 0 stevel return (globals); 507 0 stevel } 508 0 stevel 509 0 stevel 510 0 stevel /* 511 0 stevel * get the pages from a document and return a pointer a list of PAGE 512 0 stevel * structures. 513 0 stevel */ 514 0 stevel PAGE ** 515 0 stevel DocumentPages(DOCUMENT * document) 516 0 stevel { 517 0 stevel PAGE **pages = NULL, *page; 518 0 stevel caddr_t ptr1, page_end; 519 0 stevel char *bptr = document->start + document->size; 520 0 stevel long allocated_slots = 0; 521 0 stevel long no_pages = 0; 522 0 stevel long number; 523 0 stevel char *label, *tmp, *tmp_end; 524 0 stevel 525 0 stevel for (ptr1 = nstrstr(document->start, PS_PAGE, bptr); ptr1 != NULL; 526 6633 ps29005 ptr1 = nstrstr(++ptr1, PS_PAGE, bptr)) { 527 0 stevel no_pages++; 528 0 stevel 529 0 stevel if (no_pages > allocated_slots) { 530 0 stevel pages = (PAGE **) nrealloc(pages, 531 6633 ps29005 (allocated_slots + BLOCKSIZE) * sizeof (PAGE *)); 532 6633 ps29005 memset(pages + allocated_slots, 0, 533 6633 ps29005 BLOCKSIZE * sizeof (PAGE *)); 534 0 stevel allocated_slots += BLOCKSIZE; 535 0 stevel } 536 0 stevel page = (PAGE *) nmalloc(sizeof (PAGE)); 537 0 stevel label = NULL; 538 0 stevel number = -1; 539 0 stevel 540 0 stevel /* page start & end */ 541 0 stevel if ((page_end = nstrstr(++ptr1, PS_PAGE, bptr)) == NULL) 542 0 stevel if (document->trailer) 543 0 stevel page_end = document->trailer->start - 1; 544 0 stevel else 545 0 stevel page_end = document->start + document->size; 546 0 stevel 547 0 stevel /* page label & number */ 548 0 stevel if (tmp = strchr(ptr1, ' ')) { 549 0 stevel 550 0 stevel if (tmp_end = strchr(++tmp, ' ')) { 551 0 stevel label = (char *)nmalloc((tmp_end - tmp) + 1); 552 0 stevel memset(label, 0, (tmp_end - tmp) + 1); 553 0 stevel strncpy(label, tmp, (tmp_end - tmp)); 554 0 stevel number = atol(++tmp_end); 555 0 stevel } 556 0 stevel } 557 0 stevel memset(page, 0, sizeof (PAGE)); 558 0 stevel page->label = label; 559 0 stevel page->number = number; 560 0 stevel page->start = ptr1; 561 0 stevel page->size = page_end - ptr1 + 1; 562 0 stevel 563 0 stevel pages[document->pages++] = page; 564 0 stevel } 565 0 stevel return (pages); 566 0 stevel } 567 0 stevel 568 0 stevel /* 569 0 stevel * parse a document and return a pointer to a DOCUMENT structure 570 0 stevel */ 571 0 stevel DOCUMENT * 572 0 stevel DocumentParse(char *name) 573 0 stevel { 574 0 stevel DOCUMENT *document = NULL; 575 0 stevel int fd; 576 0 stevel struct stat st; 577 0 stevel 578 0 stevel if (stat(name, &st) < 0) { 579 0 stevel fprintf(stderr, "stat(%s): %s\n", name, strerror(errno)); 580 0 stevel return (NULL); 581 0 stevel } 582 0 stevel if (st.st_size == 0) { 583 0 stevel fprintf(stderr, "%s: empty file\n", name); 584 0 stevel return (NULL); 585 0 stevel } 586 0 stevel if ((fd = open(name, O_RDONLY)) < 0) { 587 0 stevel fprintf(stderr, "open(%s, O_RDONLY): %s\n", name, 588 0 stevel strerror(errno)); 589 0 stevel return (NULL); 590 0 stevel } 591 0 stevel document = (DOCUMENT *) nmalloc(sizeof (DOCUMENT)); 592 0 stevel memset(document, 0, sizeof (DOCUMENT)); 593 0 stevel if ((document->start = mmap((void *)0, (size_t)st.st_size, PROT_READ, 594 0 stevel MAP_SHARED, fd, (off_t)0)) == MAP_FAILED) { 595 0 stevel fprintf(stderr, "mmap(0, %ld, PROT_READ," 596 0 stevel " MAP_SHARED, %d, 0): %s\n", 597 0 stevel st.st_size, fd, strerror(errno)); 598 0 stevel free(document); 599 0 stevel document = NULL; 600 0 stevel } else { 601 0 stevel /* order in important */ 602 0 stevel document->name = strdup(name); 603 0 stevel document->size = nstrlen(document->start, 604 0 stevel document->start + st.st_size); 605 0 stevel document->header = DocumentHeader(document); 606 0 stevel document->trailer = DocumentTrailer(document); 607 0 stevel document->page = DocumentPages(document); 608 0 stevel document->global = DocumentGlobals(document); 609 0 stevel } 610 0 stevel close(fd); 611 0 stevel return (document); 612 0 stevel } 613 0 stevel 614 0 stevel 615 0 stevel #if defined(DEBUG) 616 0 stevel /* 617 0 stevel * Print out the contents of the document structure 618 0 stevel */ 619 0 stevel void 620 0 stevel PrintDocumentInfo(DOCUMENT * d) 621 0 stevel { 622 0 stevel if (d) { 623 0 stevel printf("Document:\n\tname: %s\n\tstart: 0x%x\n\tsize: %ld\n", 624 0 stevel d->name, d->start, d->size); 625 0 stevel if (d->header) { 626 0 stevel HEADER *h = d->header; 627 0 stevel 628 0 stevel printf("\tHeader: %s (0x%x, %ld)\n", 629 0 stevel h->label, h->start, h->size); 630 0 stevel } 631 0 stevel if (d->global) { 632 0 stevel int count = 0; 633 0 stevel 634 0 stevel while (d->global[count++] != NULL); 635 0 stevel printf("\tDSC violating BeginGlobals: %d\n", count); 636 0 stevel } 637 0 stevel if (d->page) { 638 0 stevel PAGE *p; 639 0 stevel int count = 0; 640 0 stevel 641 0 stevel printf("\tPages: (%d)\n", d->pages); 642 0 stevel for (p = d->page[0]; p != NULL; p = d->page[++count]) 643 0 stevel printf("\t\t %4d (%s) - (0x%x, %ld)\n", 644 0 stevel p->number, 645 0 stevel (p->label ? p->label : "Page"), 646 0 stevel p->start, p->size); 647 0 stevel } 648 0 stevel if (d->trailer) { 649 0 stevel TRAILER *t = d->trailer; 650 0 stevel 651 0 stevel printf("\tTrailer: %s (0x%x, %ld)\n", 652 0 stevel t->label, t->start, t->size); 653 0 stevel } 654 0 stevel } 655 0 stevel } 656 0 stevel #endif /* DEBUG */ 657 0 stevel 658 0 stevel 659 320 ceastha int 660 0 stevel main(int ac, char *av[]) 661 0 stevel { 662 0 stevel DOCUMENT *document; 663 0 stevel char *fileName = NULL; 664 0 stevel char *programName = NULL; 665 0 stevel char *unlinkFile = NULL; 666 0 stevel int reversePages = 1; 667 0 stevel int **pageList = NULL; 668 0 stevel int option; 669 0 stevel 670 0 stevel if (programName = strrchr(av[0], '/')) 671 0 stevel programName++; 672 0 stevel else 673 0 stevel programName = av[0]; 674 0 stevel 675 0 stevel while ((option = getopt(ac, av, "o:r")) != EOF) 676 0 stevel switch (option) { 677 0 stevel case 'o': 678 0 stevel pageList = ParsePageList(optarg); 679 0 stevel break; 680 0 stevel case 'r': 681 0 stevel reversePages = 0; 682 0 stevel break; 683 0 stevel case '?': 684 0 stevel Usage(programName); 685 0 stevel break; 686 0 stevel default: 687 0 stevel fprintf(stderr, "missing case for option %c\n", option); 688 0 stevel Usage(programName); 689 0 stevel break; 690 0 stevel } 691 0 stevel 692 0 stevel ac -= optind; 693 0 stevel av += optind; 694 0 stevel 695 0 stevel switch (ac) { 696 0 stevel case 0: 697 0 stevel unlinkFile = fileName = StdinToFile(); 698 0 stevel break; 699 0 stevel case 1: 700 0 stevel fileName = av[0]; 701 0 stevel break; 702 0 stevel default: 703 0 stevel Usage(programName); 704 0 stevel } 705 0 stevel 706 0 stevel if ((document = DocumentParse(fileName)) == NULL) { 707 0 stevel fprintf(stderr, "Unable to parse document (%s)\n", fileName); 708 0 stevel exit(0); 709 0 stevel } 710 0 stevel #if defined(DEBUG) && defined(NOTDEF) 711 0 stevel PrintDocumentInfo(document); 712 0 stevel #endif /* DEBUG */ 713 0 stevel 714 0 stevel WriteDocument(document, reversePages, pageList); 715 0 stevel 716 0 stevel if (unlinkFile) 717 0 stevel unlink(unlinkFile); 718 0 stevel 719 320 ceastha return (0); 720 0 stevel } 721