~ubuntu-branches/debian/lenny/netatalk/lenny

« back to all changes in this revision

Viewing changes to bin/psorder/psorder.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastian Rittau
  • Date: 2004-01-19 12:43:49 UTC
  • Revision ID: james.westby@ubuntu.com-20040119124349-es563jbp0hk0ae51
Tags: upstream-1.6.4
ImportĀ upstreamĀ versionĀ 1.6.4

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * $Id: psorder.c,v 1.5 2001/06/29 14:14:46 rufustfirefly Exp $
 
3
 *
 
4
 * Copyright (c) 1990,1991 Regents of The University of Michigan.
 
5
 * All Rights Reserved.
 
6
 *
 
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.
 
16
 *
 
17
 *      Research Systems Unix Group
 
18
 *      The University of Michigan
 
19
 *      c/o Mike Clark
 
20
 *      535 W. William Street
 
21
 *      Ann Arbor, Michigan
 
22
 *      +1-313-763-0525
 
23
 *      netatalk@itd.umich.edu
 
24
 */
 
25
 
 
26
#ifdef HAVE_CONFIG_H
 
27
#include "config.h"
 
28
#endif /* HAVE_CONFIG_H */
 
29
 
 
30
#include <stdlib.h>
 
31
#include <sys/types.h>
 
32
#include <sys/param.h>
 
33
#include <sys/time.h>
 
34
#include <sys/stat.h>
 
35
#include <sys/uio.h>
 
36
#include <sys/file.h>
 
37
#include <ctype.h>
 
38
#ifdef HAVE_FCNTL_H
 
39
#include <fcntl.h>
 
40
#endif /* HAVE_FCNTL_H */
 
41
#include <stdio.h>
 
42
#include <string.h>
 
43
#include <dirent.h>
 
44
#ifdef HAVE_UNISTD_H
 
45
#include <unistd.h>
 
46
#endif /* HAVE_UNISTD_H */
 
47
#include "pa.h"
 
48
#include "psorder.h"
 
49
 
 
50
#include <atalk/paths.h>
 
51
 
 
52
/*
 
53
 *                      Global Variables
 
54
 */
 
55
 
 
56
u_char                  psbuf[ 8192 ];
 
57
struct psinfo_st        psinfo;
 
58
int                     orderflag, forceflag;
 
59
 
 
60
int main( argc, argv )
 
61
    int         argc;
 
62
    char        **argv;
 
63
{
 
64
    extern int  optind;
 
65
    char        *progname;
 
66
    int         errflag = 0;
 
67
    int         c;
 
68
 
 
69
    while (( c = getopt( argc, argv, OPTSTR )) != -1 ) {
 
70
        switch ( c ) {
 
71
        case REVCHAR:
 
72
            if ( orderflag ) errflag++;
 
73
            else orderflag = REVERSE;
 
74
            break;
 
75
        case FORWCHAR:
 
76
            if ( orderflag ) errflag++;
 
77
            else orderflag = FORWARD;
 
78
            break;
 
79
        case FORCECHAR:
 
80
            if ( forceflag ) errflag++;
 
81
            else forceflag++;
 
82
            break;
 
83
        }
 
84
    }
 
85
    if ( errflag ) {
 
86
        if (( progname = strrchr( argv[ 0 ], '/' )) == NULL ) {
 
87
            progname = argv[ 0 ];
 
88
        } else progname++;
 
89
        fprintf( stderr, "usage: %s [-duf] [sourcefile]\n", progname );
 
90
        return( -1 );
 
91
    } else if ( !orderflag ) orderflag = FORWARD;
 
92
 
 
93
    if ( optind >= argc ) {
 
94
        return( psorder( STDIN ));
 
95
    }
 
96
    return( psorder( argv[ optind ] ));
 
97
}
 
98
 
 
99
int
 
100
psorder( path )
 
101
    char        *path;
 
102
{
 
103
    int                 tempfd;
 
104
    int                 inputfd;
 
105
    char                tempfile[MAXNAMLEN];
 
106
 
 
107
    filesetup( path, &inputfd, tempfile, &tempfd );
 
108
    readps( inputfd, tempfd, tempfile );
 
109
    if ( lseek( tempfd, REWIND, SEEK_SET ) < 0 ) {
 
110
        perror( tempfile );
 
111
        filecleanup( -1, tempfd, tempfile );
 
112
    }
 
113
    writeps( tempfd, tempfile );
 
114
    filecleanup( 0, tempfd, tempfile );
 
115
    return( 0 );
 
116
}
 
117
 
 
118
void
 
119
filesetup( inputfile, infd, tfile, tfd )
 
120
    char        *inputfile;
 
121
    int         *infd;
 
122
    char        *tfile;
 
123
    int         *tfd;
 
124
{
 
125
    struct stat         st;
 
126
    char                *template = _PATH_TMPPAGEORDER;
 
127
 
 
128
    if ( strcmp( inputfile, STDIN ) != 0 ) {
 
129
        if ( stat( inputfile, &st ) < 0 ) {
 
130
            perror( inputfile );
 
131
            filecleanup( -1, -1, "" );
 
132
        }
 
133
        if ( st.st_mode & S_IFMT & S_IFDIR ) {
 
134
            fprintf( stderr, "%s is a directory.\n", inputfile );
 
135
            filecleanup( 0, -1, "" );
 
136
        }
 
137
        if (( *infd = open( inputfile, O_RDONLY, 0600 )) < 0 ) {
 
138
            perror( inputfile );
 
139
            filecleanup( -1, -1, "" );
 
140
        }
 
141
    } else {
 
142
        *infd = 0;
 
143
    }
 
144
 
 
145
#if DEBUG
 
146
    fprintf( stderr, "Input file or stdin and stdout opened.\n" );
 
147
    fprintf( stderr, "Input file descriptor is %d .\n", *infd );
 
148
#endif /* DEBUG */
 
149
 
 
150
/*
 
151
        make temporary file
 
152
 */
 
153
 
 
154
    (void *)strncpy( tfile, template, MAXNAMLEN );
 
155
    if (( *tfd = mkstemp( tfile )) == -1 ) {
 
156
        fprintf( stderr, "can't create temporary file %s\n", tfile );
 
157
        filecleanup( -1, -1, "" );
 
158
    }
 
159
 
 
160
#if DEBUG
 
161
    fprintf( stderr, "Temporary file %s created and opened.\n", tfile );
 
162
    fprintf( stderr, "Temporary file descriptor is %d .\n", *tfd );
 
163
#endif /* DEBUG */
 
164
 
 
165
    psinfo.firstpage = NULL;
 
166
    psinfo.lastpage = NULL;
 
167
    psinfo.trailer = 0;
 
168
    psinfo.pages.offset = 0;
 
169
    psinfo.pages.end = 0;
 
170
    psinfo.pages.num[0] = '\0';
 
171
    psinfo.pages.order[0] = '\0';
 
172
 
 
173
    return;
 
174
}
 
175
 
 
176
void
 
177
readps( inputfd, tempfd, tempfile )
 
178
    int                 inputfd;
 
179
    int                 tempfd;
 
180
    char                *tempfile;
 
181
{
 
182
    off_t               ccread = 0;
 
183
    off_t               ccmatch;
 
184
    char                *curtok = 0;
 
185
    FILE                *tempstream;
 
186
    pa_buf_t            *pb;
 
187
    int                 n;
 
188
    char                c = -1;
 
189
    char                pc, cc = 0;
 
190
 
 
191
    pb = pa_init( inputfd );
 
192
    if (( tempstream = fdopen( tempfd, "w" )) == NULL ) {
 
193
        perror( "fdopen fails for tempfile" );
 
194
        filecleanup( -1, tempfd, tempfile );
 
195
    }
 
196
 
 
197
    if (( c = pa_getchar( pb )) != 0 ) {
 
198
        ccread++;
 
199
        (void)putc( c, tempstream );
 
200
        pc = 0;
 
201
        cc = c;
 
202
        pa_match( pb );
 
203
        n = strlen( PPSADOBE );
 
204
        for ( ; ( n > 0 ) && (( c = pa_getchar( pb )) != 0 ) ; n-- ) {
 
205
            ccread++ ;
 
206
            (void)putc( c, tempstream );
 
207
            pc = cc;
 
208
            cc = c;
 
209
        }
 
210
        curtok = pa_gettok( pb );
 
211
    }
 
212
#if DEBUG
 
213
    fprintf( stderr, "%s\n", curtok );
 
214
#endif /* DEBUG */
 
215
 
 
216
/*
 
217
 * not postscript
 
218
 */
 
219
    if ( strcmp( curtok, PPSADOBE ) != 0 ) {
 
220
#if DEBUG
 
221
    fprintf( stderr, "in the not postscript section of readps\n" );
 
222
#endif /* DEBUG */
 
223
        while (( c = pa_getchar( pb )) != 0 ) {
 
224
            ccread++;
 
225
            (void)putc( c, tempstream );
 
226
            pc = cc;
 
227
            cc = c;
 
228
        }
 
229
 
 
230
        (void)fflush( tempstream );
 
231
        return;
 
232
    }
 
233
 
 
234
/*
 
235
 * postscript
 
236
 */
 
237
#if DEBUG
 
238
    fprintf( stderr, "in the postscript section of readps\n" );
 
239
#endif /* DEBUG */
 
240
    while (( c = pa_getchar( pb )) != 0 ) {
 
241
        ccread++;
 
242
        (void)putc( c, tempstream );
 
243
        pc = cc;
 
244
        cc = c;
 
245
        if ((( pc == '\r' ) || ( pc == '\n' )) && ( cc == '%' )) {
 
246
#if DEBUG
 
247
            fprintf( stderr, "supposed start of match, cc = %c\n", cc );
 
248
#endif /* DEBUG */
 
249
            pa_match( pb );
 
250
            ccmatch = ccread - 1;
 
251
            while ( ( c = pa_getchar( pb ) ) ) {
 
252
                if ( c != 0 ) {
 
253
                    ccread++;
 
254
                    (void)putc( c, tempstream );
 
255
                    pc = cc;
 
256
                    cc = c;
 
257
                }
 
258
                if (( c == '\r' ) || ( c == '\n' ) || ( cc == '\0' )) {
 
259
                    curtok = pa_gettok( pb );
 
260
#if DEBUG
 
261
                    fprintf( stderr, "%s\n", curtok );
 
262
#endif /* DEBUG */
 
263
                    if ( handletok( ccmatch, curtok ) < 0 ) {
 
264
                        perror( "malloc died" );
 
265
                        filecleanup( -1, tempfd, tempfile );
 
266
                    }
 
267
                    break;
 
268
                }
 
269
                if ( c == 0 ) break;
 
270
            }
 
271
            if ( c == 0 ) break;
 
272
        }
 
273
    }
 
274
 
 
275
    (void)fflush( tempstream );
 
276
    return;
 
277
}
 
278
 
 
279
int
 
280
handletok( count, token )
 
281
    off_t               count;
 
282
    char                *token;
 
283
{
 
284
    int                 incdoc = 0;
 
285
    struct pspage_st    *newpage;
 
286
    char                *tmp;
 
287
 
 
288
    if (( strncmp( PENDDOC, token, strlen( PENDDOC )) == 0 ) && incdoc ) {
 
289
        incdoc--;
 
290
#if DEBUG
 
291
        fprintf( stderr, "found an EndDoc\n" );
 
292
#endif /* DEBUG */
 
293
 
 
294
    } else if ( strncmp( PBEGINDOC, token, strlen( PBEGINDOC )) == 0 ) {
 
295
        incdoc++;
 
296
#if DEBUG
 
297
        fprintf( stderr, "found a BeginDoc\n" );
 
298
#endif /* DEBUG */
 
299
 
 
300
    } else if ( !incdoc && 
 
301
            ( strncmp( PPAGE, token, strlen( PPAGE )) == 0 )) {
 
302
#if DEBUG
 
303
        fprintf( stderr, "found a Page\n" );
 
304
#endif /* DEBUG */
 
305
        if (( newpage = getpspage( count )) == NULL ) {
 
306
            return( -1 );
 
307
        }
 
308
        if ( psinfo.firstpage == NULL ) {
 
309
            newpage->prevpage = NULL;
 
310
            psinfo.firstpage = newpage;
 
311
        } else {
 
312
            newpage->prevpage = psinfo.lastpage;
 
313
            psinfo.lastpage->nextpage = newpage;
 
314
        }
 
315
        psinfo.lastpage = newpage;
 
316
        while ( *token++ != ':' );
 
317
        if (( tmp = strtok( token, WHITESPACE )) != NULL ) {
 
318
            (void)strncpy( newpage->lable, tmp, NUMLEN );
 
319
            if (( tmp = strtok( NULL, WHITESPACE )) != NULL ) {
 
320
                (void)strncpy( newpage->ord, tmp, ORDLEN );
 
321
            }
 
322
        }
 
323
#if DEBUG
 
324
        fprintf( stderr, "page lable %s, page ord %s\n", newpage->lable,
 
325
                newpage->ord );
 
326
#endif /* DEBUG */
 
327
 
 
328
    } else if ( !incdoc && 
 
329
            ( strncmp( PPAGES, token, strlen( PPAGES )) == 0 )) {
 
330
#if DEBUG
 
331
        fprintf( stderr, "found a Pages\n" );
 
332
#endif /* DEBUG */
 
333
        psinfo.pages.offset = count;
 
334
        psinfo.pages.end = strlen( token ) + count;
 
335
        while ( *token++ != ':' );
 
336
        while ( isspace( *token )) token++;
 
337
        if ( strncmp( ATEND, token, strlen( ATEND )) == 0 ) {
 
338
#if DEBUG
 
339
            fprintf( stderr, "it is a Pages: (atend)\n" );
 
340
#endif /* DEBUG */
 
341
            psinfo.pages.offset = 0;
 
342
            psinfo.pages.end = 0;
 
343
        } else {
 
344
            if (( tmp = strtok( token, WHITESPACE )) != NULL ) {
 
345
                (void)strncpy( psinfo.pages.num, tmp, NUMLEN );
 
346
                if (( tmp = strtok( NULL, WHITESPACE )) != NULL ) {
 
347
                    (void)strncpy( psinfo.pages.order, tmp, ORDERLEN );
 
348
                }
 
349
            }
 
350
#if DEBUG
 
351
            fprintf( stderr, "number of pages %s\n", psinfo.pages.num );
 
352
            fprintf( stderr, "order control number %s\n", psinfo.pages.order );
 
353
#endif /* DEBUG */
 
354
        }
 
355
 
 
356
    } else if ( !incdoc && 
 
357
            ( strncmp( PTRAILER, token, strlen( PTRAILER )) == 0 )) {
 
358
#if DEBUG
 
359
        fprintf( stderr, "found the Trailer\n" );
 
360
#endif /* DEBUG */
 
361
        if  ( psinfo.trailer == 0 ) {
 
362
            psinfo.trailer = count;
 
363
        }
 
364
    }
 
365
 
 
366
    return( 0 );
 
367
}
 
368
 
 
369
void
 
370
writeps( tempfd, tempfile )
 
371
    int                 tempfd;
 
372
    char                *tempfile;
 
373
{
 
374
    struct stat         st;
 
375
    off_t               endofpage;
 
376
    int                 order;
 
377
 
 
378
    if ( stat( tempfile, &st ) < 0 ) {
 
379
        perror( "stat failed" );
 
380
        filecleanup( -1, tempfd, tempfile );
 
381
    }
 
382
    if ( psinfo.trailer == 0 ) {
 
383
        endofpage = st.st_size;
 
384
    } else endofpage = psinfo.trailer;
 
385
 
 
386
    if (( psinfo.firstpage == NULL ) || 
 
387
            ( psinfo.firstpage == psinfo.lastpage )) {
 
388
        order = FORWARD;
 
389
    } else if ( psinfo.pages.offset == 0 ) {
 
390
        order = orderflag;
 
391
    } else if (( strncmp( psinfo.pages.order, "", ORDERLEN ) == 0 ) ||
 
392
            ( strncmp( psinfo.pages.order, "1", ORDERLEN ) == 0 )) {
 
393
        order = orderflag;
 
394
        if ( order == REVERSE ) strcpy( psinfo.pages.order, "-1" );
 
395
    } else if ( strncmp( psinfo.pages.order, "-1", ORDERLEN ) == 0 ) {
 
396
        if ( orderflag == FORWARD ) {
 
397
            order = REVERSE;
 
398
            strcpy( psinfo.pages.order, "1" );
 
399
        } else order = FORWARD;
 
400
    } else if (( strncmp( psinfo.pages.order, "0", ORDERLEN ) == 0 ) &&
 
401
            forceflag ) {
 
402
        order = orderflag;
 
403
    } else order = FORWARD;
 
404
 
 
405
    if ( order == FORWARD ) {
 
406
        temp2out( tempfd, tempfile, st.st_size );
 
407
    } else {
 
408
/*
 
409
 *      output the header stuff and rewrite the $$Pages line
 
410
 *      if it is in the header and not %%Pages: (atend)
 
411
 */
 
412
        if ( psinfo.firstpage->offset > 0 ) {
 
413
            if (( psinfo.firstpage->offset > psinfo.pages.offset ) &&
 
414
                    ( psinfo.pages.offset != 0 )) {
 
415
                temp2out( tempfd, tempfile, psinfo.pages.offset );
 
416
                writelable( tempfd, tempfile, PPAGES );
 
417
                if ( lseek( tempfd, psinfo.pages.end, SEEK_SET ) < 0 ) {
 
418
                    perror( tempfile );
 
419
                    filecleanup( -1, tempfd, tempfile );
 
420
                }
 
421
                temp2out( tempfd, tempfile, 
 
422
                        psinfo.firstpage->offset - psinfo.pages.end );
 
423
            } else temp2out( tempfd, tempfile, psinfo.firstpage->offset );
 
424
        }
 
425
/*
 
426
 *      output the pages, last to first
 
427
 */
 
428
        while ( psinfo.lastpage != NULL ) {
 
429
            if ( lseek( tempfd, psinfo.lastpage->offset, SEEK_SET ) < 0 ) {
 
430
                perror( tempfile );
 
431
                filecleanup( -1, tempfd, tempfile );
 
432
            }
 
433
            temp2out( tempfd, tempfile, endofpage - psinfo.lastpage->offset );
 
434
            endofpage = psinfo.lastpage->offset;
 
435
            psinfo.lastpage = psinfo.lastpage->prevpage;
 
436
            if ( psinfo.lastpage != NULL ) {
 
437
                (void)free( psinfo.lastpage->nextpage );
 
438
                psinfo.lastpage->nextpage = NULL;
 
439
            }
 
440
        }
 
441
/*
 
442
 *      output the trailer stuff and rewrite the $$Pages line
 
443
 *      if it is in the trailer
 
444
 */
 
445
        if ( psinfo.trailer != 0 ) {
 
446
            if ( lseek( tempfd, psinfo.trailer, SEEK_SET ) < 0 ) {
 
447
                perror( tempfile );
 
448
                filecleanup( -1, tempfd, tempfile );
 
449
            }
 
450
            if ( psinfo.trailer < psinfo.pages.offset ) {
 
451
                temp2out( tempfd, tempfile,
 
452
                        psinfo.pages.offset - psinfo.trailer );
 
453
                writelable( tempfd, tempfile, PPAGES );
 
454
                if ( lseek( tempfd, psinfo.pages.end, SEEK_SET ) < 0 ) {
 
455
                    perror( tempfile );
 
456
                    filecleanup( -1, tempfd, tempfile );
 
457
                }
 
458
                temp2out( tempfd, tempfile, st.st_size - psinfo.pages.end );
 
459
            } else temp2out( tempfd, tempfile, st.st_size - psinfo.trailer );
 
460
        }
 
461
    }
 
462
 
 
463
    return;
 
464
}
 
465
 
 
466
void
 
467
writelable( tempfd, tempfile, lable )
 
468
    int                 tempfd;
 
469
    char                *tempfile;
 
470
    char                *lable;
 
471
{
 
472
    char                line[256];
 
473
    int                 ccwrite;
 
474
    int                 linelen;
 
475
    char                *argone;
 
476
    char                *argtwo;
 
477
 
 
478
    if ( strcmp( lable, PPAGES ) == 0 ) {
 
479
        argone = psinfo.pages.num;
 
480
        argtwo = psinfo.pages.order;
 
481
    } else {
 
482
        argone = argtwo = NULL;
 
483
    }
 
484
    (void)sprintf( line, "%s %s %s", lable, argone, argtwo );
 
485
    linelen = strlen( line );
 
486
 
 
487
    ccwrite = write( 1, line, linelen );
 
488
    if ( ccwrite < 0 ) {
 
489
        perror( "stdout" );
 
490
        filecleanup( ccwrite, tempfd, tempfile );
 
491
    } else {
 
492
        linelen -= ccwrite;
 
493
    }
 
494
}
 
495
 
 
496
void
 
497
temp2out( tempfd, tempfile, length )
 
498
    int                 tempfd;
 
499
    char                *tempfile;
 
500
    off_t               length;
 
501
{
 
502
    int                 ccread;
 
503
    int                 ccwrite;
 
504
    int                 size;
 
505
 
 
506
    while ( length > 0 ) {
 
507
        if ( length > sizeof( psbuf )) {
 
508
            size = sizeof( psbuf );
 
509
        } else size = length;
 
510
        if (( ccread = read( tempfd, psbuf, size )) > 0 ) {
 
511
            size = ccread;
 
512
            while ( ccread > 0 ) {
 
513
                ccwrite = write( 1, psbuf, ccread );
 
514
                if ( ccwrite < 0 ) {
 
515
                    perror( "stdout" );
 
516
                    filecleanup( ccwrite, tempfd, tempfile );
 
517
                } else {
 
518
                    ccread -= ccwrite;
 
519
                }
 
520
            }
 
521
        }
 
522
        if ( ccread < 0 ) {
 
523
            perror( "temporary file" );
 
524
            filecleanup( ccread, tempfd, tempfile );
 
525
        }
 
526
        length -= size;
 
527
    }
 
528
}
 
529
 
 
530
struct pspage_st
 
531
*getpspage( off )
 
532
    off_t               off;
 
533
{
 
534
    struct pspage_st    *newpspage;
 
535
 
 
536
    newpspage = (struct pspage_st *)malloc( sizeof( struct pspage_st )); 
 
537
    if ( newpspage != NULL ) {
 
538
        newpspage->offset = off;
 
539
        newpspage->nextpage = NULL;
 
540
        *newpspage->lable = '\0';
 
541
        *newpspage->ord = '\0';
 
542
    }
 
543
    return( newpspage );
 
544
}
 
545
 
 
546
void
 
547
filecleanup( errorcode, tfd, tfile )
 
548
    int                 errorcode;
 
549
    int                 tfd;
 
550
    char                *tfile;
 
551
{
 
552
 
 
553
/*
 
554
        Close and unlink the temporary file.
 
555
 */
 
556
 
 
557
    if ( tfd != 0 ) {
 
558
        if ( close( tfd ) != 0 ) {
 
559
            perror( tfile );
 
560
            exit( errorcode );
 
561
        }
 
562
        if ( unlink( tfile ) != 0 ) {
 
563
            perror( tfile );
 
564
            exit( errorcode );
 
565
        }
 
566
    }
 
567
 
 
568
    exit( errorcode );
 
569
}