2 * $Id: psorder.c,v 1.10 2010-04-12 14:28:47 franklahm Exp $
4 * Copyright (c) 1990,1991 Regents of The University of Michigan.
7 * Permission to use, copy, modify, and distribute this software and
8 * its documentation for any purpose and without fee is hereby granted,
9 * provided that the above copyright notice appears in all copies and
10 * that both that copyright notice and this permission notice appear
11 * in supporting documentation, and that the name of The University
12 * of Michigan not be used in advertising or publicity pertaining to
13 * distribution of the software without specific, written prior
14 * permission. This software is supplied as is without expressed or
15 * implied warranties of any kind.
17 * Research Systems Unix Group
18 * The University of Michigan
20 * 535 W. William Street
23 * netatalk@itd.umich.edu
28 #endif /* HAVE_CONFIG_H */
31 #include <sys/types.h>
32 #include <sys/param.h>
41 #endif /* HAVE_FCNTL_H */
47 #endif /* HAVE_UNISTD_H */
51 #include <atalk/paths.h>
57 static u_char psbuf[ 8192 ];
58 static struct psinfo_st psinfo;
59 static int orderflag, forceflag;
62 filecleanup( int errorcode, int tfd, char *tfile)
66 Close and unlink the temporary file.
70 if ( close( tfd ) != 0 ) {
74 if ( unlink( tfile ) != 0 ) {
84 filesetup( char *inputfile, int *infd, char *tfile, int *tfd)
87 char *template = _PATH_TMPPAGEORDER;
89 if ( strcmp( inputfile, STDIN ) != 0 ) {
90 if ( stat( inputfile, &st ) < 0 ) {
92 filecleanup( -1, -1, "" );
94 if ( st.st_mode & S_IFMT & S_IFDIR ) {
95 fprintf( stderr, "%s is a directory.\n", inputfile );
96 filecleanup( 0, -1, "" );
98 if (( *infd = open( inputfile, O_RDONLY, 0600 )) < 0 ) {
100 filecleanup( -1, -1, "" );
107 fprintf( stderr, "Input file or stdin and stdout opened.\n" );
108 fprintf( stderr, "Input file descriptor is %d .\n", *infd );
115 #if defined(NAME_MAX)
116 (void *)strncpy( tfile, template, NAME_MAX );
118 (void *)strncpy( tfile, template, MAXNAMLEN );
120 if (( *tfd = mkstemp( tfile )) == -1 ) {
121 fprintf( stderr, "can't create temporary file %s\n", tfile );
122 filecleanup( -1, -1, "" );
126 fprintf( stderr, "Temporary file %s created and opened.\n", tfile );
127 fprintf( stderr, "Temporary file descriptor is %d .\n", *tfd );
130 psinfo.firstpage = NULL;
131 psinfo.lastpage = NULL;
133 psinfo.pages.offset = 0;
134 psinfo.pages.end = 0;
135 psinfo.pages.num[0] = '\0';
136 psinfo.pages.order[0] = '\0';
141 static struct pspage_st
142 *getpspage(off_t off)
144 struct pspage_st *newpspage;
146 newpspage = (struct pspage_st *)malloc( sizeof( struct pspage_st ));
147 if ( newpspage != NULL ) {
148 newpspage->offset = off;
149 newpspage->nextpage = NULL;
150 *newpspage->lable = '\0';
151 *newpspage->ord = '\0';
157 handletok(off_t count, char *token)
160 struct pspage_st *newpage;
163 if (( strncmp( PENDDOC, token, strlen( PENDDOC )) == 0 ) && incdoc ) {
166 fprintf( stderr, "found an EndDoc\n" );
169 } else if ( strncmp( PBEGINDOC, token, strlen( PBEGINDOC )) == 0 ) {
172 fprintf( stderr, "found a BeginDoc\n" );
175 } else if ( !incdoc &&
176 ( strncmp( PPAGE, token, strlen( PPAGE )) == 0 )) {
178 fprintf( stderr, "found a Page\n" );
180 if (( newpage = getpspage( count )) == NULL ) {
183 if ( psinfo.firstpage == NULL ) {
184 newpage->prevpage = NULL;
185 psinfo.firstpage = newpage;
187 newpage->prevpage = psinfo.lastpage;
188 psinfo.lastpage->nextpage = newpage;
190 psinfo.lastpage = newpage;
191 while ( *token++ != ':' );
192 if (( tmp = strtok( token, WHITESPACE )) != NULL ) {
193 (void)strncpy( newpage->lable, tmp, NUMLEN );
194 if (( tmp = strtok( NULL, WHITESPACE )) != NULL ) {
195 (void)strncpy( newpage->ord, tmp, ORDLEN );
199 fprintf( stderr, "page lable %s, page ord %s\n", newpage->lable,
203 } else if ( !incdoc &&
204 ( strncmp( PPAGES, token, strlen( PPAGES )) == 0 )) {
206 fprintf( stderr, "found a Pages\n" );
208 psinfo.pages.offset = count;
209 psinfo.pages.end = strlen( token ) + count;
210 while ( *token++ != ':' );
211 while ( isspace( *token )) token++;
212 if ( strncmp( ATEND, token, strlen( ATEND )) == 0 ) {
214 fprintf( stderr, "it is a Pages: (atend)\n" );
216 psinfo.pages.offset = 0;
217 psinfo.pages.end = 0;
219 if (( tmp = strtok( token, WHITESPACE )) != NULL ) {
220 (void)strncpy( psinfo.pages.num, tmp, NUMLEN );
221 if (( tmp = strtok( NULL, WHITESPACE )) != NULL ) {
222 (void)strncpy( psinfo.pages.order, tmp, ORDERLEN );
226 fprintf( stderr, "number of pages %s\n", psinfo.pages.num );
227 fprintf( stderr, "order control number %s\n", psinfo.pages.order );
231 } else if ( !incdoc &&
232 ( strncmp( PTRAILER, token, strlen( PTRAILER )) == 0 )) {
234 fprintf( stderr, "found the Trailer\n" );
236 if ( psinfo.trailer == 0 ) {
237 psinfo.trailer = count;
245 readps(int inputfd, int tempfd, char *tempfile)
256 pb = pa_init( inputfd );
257 if (( tempstream = fdopen( tempfd, "w" )) == NULL ) {
258 perror( "fdopen fails for tempfile" );
259 filecleanup( -1, tempfd, tempfile );
262 if (( c = pa_getchar( pb )) != 0 ) {
264 (void)putc( c, tempstream );
268 n = strlen( PPSADOBE );
269 for ( ; ( n > 0 ) && (( c = pa_getchar( pb )) != 0 ) ; n-- ) {
271 (void)putc( c, tempstream );
275 curtok = pa_gettok( pb );
278 fprintf( stderr, "%s\n", curtok );
284 if ( strcmp( curtok, PPSADOBE ) != 0 ) {
286 fprintf( stderr, "in the not postscript section of readps\n" );
288 while (( c = pa_getchar( pb )) != 0 ) {
290 (void)putc( c, tempstream );
295 (void)fflush( tempstream );
303 fprintf( stderr, "in the postscript section of readps\n" );
305 while (( c = pa_getchar( pb )) != 0 ) {
307 (void)putc( c, tempstream );
310 if ((( pc == '\r' ) || ( pc == '\n' )) && ( cc == '%' )) {
312 fprintf( stderr, "supposed start of match, cc = %c\n", cc );
315 ccmatch = ccread - 1;
316 while ( ( c = pa_getchar( pb ) ) ) {
319 (void)putc( c, tempstream );
323 if (( c == '\r' ) || ( c == '\n' ) || ( cc == '\0' )) {
324 curtok = pa_gettok( pb );
326 fprintf( stderr, "%s\n", curtok );
328 if ( handletok( ccmatch, curtok ) < 0 ) {
329 perror( "malloc died" );
330 filecleanup( -1, tempfd, tempfile );
340 (void)fflush( tempstream );
345 temp2out(int tempfd, char *tempfile, off_t length)
351 while ( length > 0 ) {
352 if ( length > sizeof( psbuf )) {
353 size = sizeof( psbuf );
354 } else size = length;
355 if (( ccread = read( tempfd, psbuf, size )) > 0 ) {
357 while ( ccread > 0 ) {
358 ccwrite = write( 1, psbuf, ccread );
361 filecleanup( ccwrite, tempfd, tempfile );
368 perror( "temporary file" );
369 filecleanup( ccread, tempfd, tempfile );
376 writelable(int tempfd, char *tempfile, char *lable)
384 if ( strcmp( lable, PPAGES ) == 0 ) {
385 argone = psinfo.pages.num;
386 argtwo = psinfo.pages.order;
388 argone = argtwo = NULL;
390 (void)sprintf( line, "%s %s %s", lable, argone, argtwo );
391 linelen = strlen( line );
393 ccwrite = write( 1, line, linelen );
396 filecleanup( ccwrite, tempfd, tempfile );
403 writeps(int tempfd, char *tempfile)
409 if ( stat( tempfile, &st ) < 0 ) {
410 perror( "stat failed" );
411 filecleanup( -1, tempfd, tempfile );
413 if ( psinfo.trailer == 0 ) {
414 endofpage = st.st_size;
415 } else endofpage = psinfo.trailer;
417 if (( psinfo.firstpage == NULL ) ||
418 ( psinfo.firstpage == psinfo.lastpage )) {
420 } else if ( psinfo.pages.offset == 0 ) {
422 } else if (( strncmp( psinfo.pages.order, "", ORDERLEN ) == 0 ) ||
423 ( strncmp( psinfo.pages.order, "1", ORDERLEN ) == 0 )) {
425 if ( order == REVERSE ) strcpy( psinfo.pages.order, "-1" );
426 } else if ( strncmp( psinfo.pages.order, "-1", ORDERLEN ) == 0 ) {
427 if ( orderflag == FORWARD ) {
429 strcpy( psinfo.pages.order, "1" );
430 } else order = FORWARD;
431 } else if (( strncmp( psinfo.pages.order, "0", ORDERLEN ) == 0 ) &&
434 } else order = FORWARD;
436 if ( order == FORWARD ) {
437 temp2out( tempfd, tempfile, st.st_size );
440 * output the header stuff and rewrite the $$Pages line
441 * if it is in the header and not %%Pages: (atend)
443 if ( psinfo.firstpage->offset > 0 ) {
444 if (( psinfo.firstpage->offset > psinfo.pages.offset ) &&
445 ( psinfo.pages.offset != 0 )) {
446 temp2out( tempfd, tempfile, psinfo.pages.offset );
447 writelable( tempfd, tempfile, PPAGES );
448 if ( lseek( tempfd, psinfo.pages.end, SEEK_SET ) < 0 ) {
450 filecleanup( -1, tempfd, tempfile );
452 temp2out( tempfd, tempfile,
453 psinfo.firstpage->offset - psinfo.pages.end );
454 } else temp2out( tempfd, tempfile, psinfo.firstpage->offset );
457 * output the pages, last to first
459 while ( psinfo.lastpage != NULL ) {
460 if ( lseek( tempfd, psinfo.lastpage->offset, SEEK_SET ) < 0 ) {
462 filecleanup( -1, tempfd, tempfile );
464 temp2out( tempfd, tempfile, endofpage - psinfo.lastpage->offset );
465 endofpage = psinfo.lastpage->offset;
466 psinfo.lastpage = psinfo.lastpage->prevpage;
467 if ( psinfo.lastpage != NULL ) {
468 (void)free( psinfo.lastpage->nextpage );
469 psinfo.lastpage->nextpage = NULL;
473 * output the trailer stuff and rewrite the $$Pages line
474 * if it is in the trailer
476 if ( psinfo.trailer != 0 ) {
477 if ( lseek( tempfd, psinfo.trailer, SEEK_SET ) < 0 ) {
479 filecleanup( -1, tempfd, tempfile );
481 if ( psinfo.trailer < psinfo.pages.offset ) {
482 temp2out( tempfd, tempfile,
483 psinfo.pages.offset - psinfo.trailer );
484 writelable( tempfd, tempfile, PPAGES );
485 if ( lseek( tempfd, psinfo.pages.end, SEEK_SET ) < 0 ) {
487 filecleanup( -1, tempfd, tempfile );
489 temp2out( tempfd, tempfile, st.st_size - psinfo.pages.end );
490 } else temp2out( tempfd, tempfile, st.st_size - psinfo.trailer );
502 #if defined(NAME_MAX)
503 char tempfile[NAME_MAX];
505 char tempfile[MAXNAMLEN];
508 filesetup( path, &inputfd, tempfile, &tempfd );
509 readps( inputfd, tempfd, tempfile );
510 if ( lseek( tempfd, REWIND, SEEK_SET ) < 0 ) {
512 filecleanup( -1, tempfd, tempfile );
514 writeps( tempfd, tempfile );
515 filecleanup( 0, tempfd, tempfile );
519 int main(int argc, char **argv)
526 while (( c = getopt( argc, argv, OPTSTR )) != -1 ) {
529 if ( orderflag ) errflag++;
530 else orderflag = REVERSE;
533 if ( orderflag ) errflag++;
534 else orderflag = FORWARD;
537 if ( forceflag ) errflag++;
543 if (( progname = strrchr( argv[ 0 ], '/' )) == NULL ) {
544 progname = argv[ 0 ];
546 fprintf( stderr, "usage: %s [-duf] [sourcefile]\n", progname );
548 } else if ( !orderflag ) orderflag = FORWARD;
550 if ( optind >= argc ) {
551 return( psorder( STDIN ));
553 return( psorder( argv[ optind ] ));