2 * $Id: psorder.c,v 1.8 2009-10-14 01:38:28 didg 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>
40 #endif /* HAVE_FCNTL_H */
46 #endif /* HAVE_UNISTD_H */
50 #include <atalk/paths.h>
56 static u_char psbuf[ 8192 ];
57 static struct psinfo_st psinfo;
58 static int orderflag, forceflag;
61 filecleanup( int errorcode, int tfd, char *tfile)
65 Close and unlink the temporary file.
69 if ( close( tfd ) != 0 ) {
73 if ( unlink( tfile ) != 0 ) {
83 filesetup( char *inputfile, int *infd, char *tfile, int *tfd)
86 char *template = _PATH_TMPPAGEORDER;
88 if ( strcmp( inputfile, STDIN ) != 0 ) {
89 if ( stat( inputfile, &st ) < 0 ) {
91 filecleanup( -1, -1, "" );
93 if ( st.st_mode & S_IFMT & S_IFDIR ) {
94 fprintf( stderr, "%s is a directory.\n", inputfile );
95 filecleanup( 0, -1, "" );
97 if (( *infd = open( inputfile, O_RDONLY, 0600 )) < 0 ) {
99 filecleanup( -1, -1, "" );
106 fprintf( stderr, "Input file or stdin and stdout opened.\n" );
107 fprintf( stderr, "Input file descriptor is %d .\n", *infd );
114 strncpy( tfile, template, MAXNAMLEN );
115 if (( *tfd = mkstemp( tfile )) == -1 ) {
116 fprintf( stderr, "can't create temporary file %s\n", tfile );
117 filecleanup( -1, -1, "" );
121 fprintf( stderr, "Temporary file %s created and opened.\n", tfile );
122 fprintf( stderr, "Temporary file descriptor is %d .\n", *tfd );
125 psinfo.firstpage = NULL;
126 psinfo.lastpage = NULL;
128 psinfo.pages.offset = 0;
129 psinfo.pages.end = 0;
130 psinfo.pages.num[0] = '\0';
131 psinfo.pages.order[0] = '\0';
136 static struct pspage_st
137 *getpspage(off_t off)
139 struct pspage_st *newpspage;
141 newpspage = (struct pspage_st *)malloc( sizeof( struct pspage_st ));
142 if ( newpspage != NULL ) {
143 newpspage->offset = off;
144 newpspage->nextpage = NULL;
145 *newpspage->lable = '\0';
146 *newpspage->ord = '\0';
152 handletok(off_t count, char *token)
155 struct pspage_st *newpage;
158 if (( strncmp( PENDDOC, token, strlen( PENDDOC )) == 0 ) && incdoc ) {
161 fprintf( stderr, "found an EndDoc\n" );
164 } else if ( strncmp( PBEGINDOC, token, strlen( PBEGINDOC )) == 0 ) {
167 fprintf( stderr, "found a BeginDoc\n" );
170 } else if ( !incdoc &&
171 ( strncmp( PPAGE, token, strlen( PPAGE )) == 0 )) {
173 fprintf( stderr, "found a Page\n" );
175 if (( newpage = getpspage( count )) == NULL ) {
178 if ( psinfo.firstpage == NULL ) {
179 newpage->prevpage = NULL;
180 psinfo.firstpage = newpage;
182 newpage->prevpage = psinfo.lastpage;
183 psinfo.lastpage->nextpage = newpage;
185 psinfo.lastpage = newpage;
186 while ( *token++ != ':' );
187 if (( tmp = strtok( token, WHITESPACE )) != NULL ) {
188 (void)strncpy( newpage->lable, tmp, NUMLEN );
189 if (( tmp = strtok( NULL, WHITESPACE )) != NULL ) {
190 (void)strncpy( newpage->ord, tmp, ORDLEN );
194 fprintf( stderr, "page lable %s, page ord %s\n", newpage->lable,
198 } else if ( !incdoc &&
199 ( strncmp( PPAGES, token, strlen( PPAGES )) == 0 )) {
201 fprintf( stderr, "found a Pages\n" );
203 psinfo.pages.offset = count;
204 psinfo.pages.end = strlen( token ) + count;
205 while ( *token++ != ':' );
206 while ( isspace( *token )) token++;
207 if ( strncmp( ATEND, token, strlen( ATEND )) == 0 ) {
209 fprintf( stderr, "it is a Pages: (atend)\n" );
211 psinfo.pages.offset = 0;
212 psinfo.pages.end = 0;
214 if (( tmp = strtok( token, WHITESPACE )) != NULL ) {
215 (void)strncpy( psinfo.pages.num, tmp, NUMLEN );
216 if (( tmp = strtok( NULL, WHITESPACE )) != NULL ) {
217 (void)strncpy( psinfo.pages.order, tmp, ORDERLEN );
221 fprintf( stderr, "number of pages %s\n", psinfo.pages.num );
222 fprintf( stderr, "order control number %s\n", psinfo.pages.order );
226 } else if ( !incdoc &&
227 ( strncmp( PTRAILER, token, strlen( PTRAILER )) == 0 )) {
229 fprintf( stderr, "found the Trailer\n" );
231 if ( psinfo.trailer == 0 ) {
232 psinfo.trailer = count;
240 readps(int inputfd, int tempfd, char *tempfile)
251 pb = pa_init( inputfd );
252 if (( tempstream = fdopen( tempfd, "w" )) == NULL ) {
253 perror( "fdopen fails for tempfile" );
254 filecleanup( -1, tempfd, tempfile );
257 if (( c = pa_getchar( pb )) != 0 ) {
259 (void)putc( c, tempstream );
263 n = strlen( PPSADOBE );
264 for ( ; ( n > 0 ) && (( c = pa_getchar( pb )) != 0 ) ; n-- ) {
266 (void)putc( c, tempstream );
270 curtok = pa_gettok( pb );
273 fprintf( stderr, "%s\n", curtok );
279 if ( strcmp( curtok, PPSADOBE ) != 0 ) {
281 fprintf( stderr, "in the not postscript section of readps\n" );
283 while (( c = pa_getchar( pb )) != 0 ) {
285 (void)putc( c, tempstream );
290 (void)fflush( tempstream );
298 fprintf( stderr, "in the postscript section of readps\n" );
300 while (( c = pa_getchar( pb )) != 0 ) {
302 (void)putc( c, tempstream );
305 if ((( pc == '\r' ) || ( pc == '\n' )) && ( cc == '%' )) {
307 fprintf( stderr, "supposed start of match, cc = %c\n", cc );
310 ccmatch = ccread - 1;
311 while ( ( c = pa_getchar( pb ) ) ) {
314 (void)putc( c, tempstream );
318 if (( c == '\r' ) || ( c == '\n' ) || ( cc == '\0' )) {
319 curtok = pa_gettok( pb );
321 fprintf( stderr, "%s\n", curtok );
323 if ( handletok( ccmatch, curtok ) < 0 ) {
324 perror( "malloc died" );
325 filecleanup( -1, tempfd, tempfile );
335 (void)fflush( tempstream );
340 temp2out(int tempfd, char *tempfile, off_t length)
346 while ( length > 0 ) {
347 if ( length > sizeof( psbuf )) {
348 size = sizeof( psbuf );
349 } else size = length;
350 if (( ccread = read( tempfd, psbuf, size )) > 0 ) {
352 while ( ccread > 0 ) {
353 ccwrite = write( 1, psbuf, ccread );
356 filecleanup( ccwrite, tempfd, tempfile );
363 perror( "temporary file" );
364 filecleanup( ccread, tempfd, tempfile );
371 writelable(int tempfd, char *tempfile, char *lable)
379 if ( strcmp( lable, PPAGES ) == 0 ) {
380 argone = psinfo.pages.num;
381 argtwo = psinfo.pages.order;
383 argone = argtwo = NULL;
385 (void)sprintf( line, "%s %s %s", lable, argone, argtwo );
386 linelen = strlen( line );
388 ccwrite = write( 1, line, linelen );
391 filecleanup( ccwrite, tempfd, tempfile );
398 writeps(int tempfd, char *tempfile)
404 if ( stat( tempfile, &st ) < 0 ) {
405 perror( "stat failed" );
406 filecleanup( -1, tempfd, tempfile );
408 if ( psinfo.trailer == 0 ) {
409 endofpage = st.st_size;
410 } else endofpage = psinfo.trailer;
412 if (( psinfo.firstpage == NULL ) ||
413 ( psinfo.firstpage == psinfo.lastpage )) {
415 } else if ( psinfo.pages.offset == 0 ) {
417 } else if (( strncmp( psinfo.pages.order, "", ORDERLEN ) == 0 ) ||
418 ( strncmp( psinfo.pages.order, "1", ORDERLEN ) == 0 )) {
420 if ( order == REVERSE ) strcpy( psinfo.pages.order, "-1" );
421 } else if ( strncmp( psinfo.pages.order, "-1", ORDERLEN ) == 0 ) {
422 if ( orderflag == FORWARD ) {
424 strcpy( psinfo.pages.order, "1" );
425 } else order = FORWARD;
426 } else if (( strncmp( psinfo.pages.order, "0", ORDERLEN ) == 0 ) &&
429 } else order = FORWARD;
431 if ( order == FORWARD ) {
432 temp2out( tempfd, tempfile, st.st_size );
435 * output the header stuff and rewrite the $$Pages line
436 * if it is in the header and not %%Pages: (atend)
438 if ( psinfo.firstpage->offset > 0 ) {
439 if (( psinfo.firstpage->offset > psinfo.pages.offset ) &&
440 ( psinfo.pages.offset != 0 )) {
441 temp2out( tempfd, tempfile, psinfo.pages.offset );
442 writelable( tempfd, tempfile, PPAGES );
443 if ( lseek( tempfd, psinfo.pages.end, SEEK_SET ) < 0 ) {
445 filecleanup( -1, tempfd, tempfile );
447 temp2out( tempfd, tempfile,
448 psinfo.firstpage->offset - psinfo.pages.end );
449 } else temp2out( tempfd, tempfile, psinfo.firstpage->offset );
452 * output the pages, last to first
454 while ( psinfo.lastpage != NULL ) {
455 if ( lseek( tempfd, psinfo.lastpage->offset, SEEK_SET ) < 0 ) {
457 filecleanup( -1, tempfd, tempfile );
459 temp2out( tempfd, tempfile, endofpage - psinfo.lastpage->offset );
460 endofpage = psinfo.lastpage->offset;
461 psinfo.lastpage = psinfo.lastpage->prevpage;
462 if ( psinfo.lastpage != NULL ) {
463 (void)free( psinfo.lastpage->nextpage );
464 psinfo.lastpage->nextpage = NULL;
468 * output the trailer stuff and rewrite the $$Pages line
469 * if it is in the trailer
471 if ( psinfo.trailer != 0 ) {
472 if ( lseek( tempfd, psinfo.trailer, SEEK_SET ) < 0 ) {
474 filecleanup( -1, tempfd, tempfile );
476 if ( psinfo.trailer < psinfo.pages.offset ) {
477 temp2out( tempfd, tempfile,
478 psinfo.pages.offset - psinfo.trailer );
479 writelable( tempfd, tempfile, PPAGES );
480 if ( lseek( tempfd, psinfo.pages.end, SEEK_SET ) < 0 ) {
482 filecleanup( -1, tempfd, tempfile );
484 temp2out( tempfd, tempfile, st.st_size - psinfo.pages.end );
485 } else temp2out( tempfd, tempfile, st.st_size - psinfo.trailer );
497 char tempfile[MAXNAMLEN];
499 filesetup( path, &inputfd, tempfile, &tempfd );
500 readps( inputfd, tempfd, tempfile );
501 if ( lseek( tempfd, REWIND, SEEK_SET ) < 0 ) {
503 filecleanup( -1, tempfd, tempfile );
505 writeps( tempfd, tempfile );
506 filecleanup( 0, tempfd, tempfile );
510 int main(int argc, char **argv)
517 while (( c = getopt( argc, argv, OPTSTR )) != -1 ) {
520 if ( orderflag ) errflag++;
521 else orderflag = REVERSE;
524 if ( orderflag ) errflag++;
525 else orderflag = FORWARD;
528 if ( forceflag ) errflag++;
534 if (( progname = strrchr( argv[ 0 ], '/' )) == NULL ) {
535 progname = argv[ 0 ];
537 fprintf( stderr, "usage: %s [-duf] [sourcefile]\n", progname );
539 } else if ( !orderflag ) orderflag = FORWARD;
541 if ( optind >= argc ) {
542 return( psorder( STDIN ));
544 return( psorder( argv[ optind ] ));