File: file.c

package info (click to toggle)
mpage 2.5-6
  • links: PTS
  • area: main
  • in suites: hamm
  • size: 332 kB
  • ctags: 289
  • sloc: ansic: 2,794; makefile: 75; sh: 68
file content (339 lines) | stat: -rw-r--r-- 9,291 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
/*
 * file.c
 */

/*
 * mpage:    a program to reduce pages of print so that several pages
 *           of output appear on one printed page.
 *
 * Written by:
 *   ...!uunet!\                       Mark Hahn, Sr Systems Engineer
 *              >pyrdc!mark            Pyramid Technology Corporation
 * ...!pyramid!/                       Vienna, Va    (703)848-2050
 *
 *
 * Copyright (c) 1988 Mark P. Hahn, Herndon, Virginia
 * Copyright (c) 1994-1997 Marcel J.E. Mol, The Netherlands
 *                    marcel@mesa.nl
 *  
 *     Permission is granted to anyone to make or distribute verbatim
 *     copies of this document as received, in any medium, provided
 *     that this copyright notice is preserved, and that the
 *     distributor grants the recipient permission for further
 *     redistribution as permitted by this notice.
 *
 */


#include "mpage.h"


/*
 * do_file converts one file into postscript for output.  The file type is
 * determined then the proper conversion routine is selected.
 */
void
do_file(fname, asheet, outfd)
 char *fname;
 struct sheet *asheet;
 FILE *outfd;
{
    FILE *fd;

    /*
     * if we have the pr option, then we have to assume it's a text file
     */
    if (opt_pr) {
        do_pr_file(fname, asheet, outfd);
        return;
    }
    /*
     * if not using pr(1), open fname and try to figure out what type of
     * file it is
     */
    if ((fd = fopen(fname, "r")) == NULL) {
        fprintf(stderr, "%s: cannot open %s\n", MPAGE, fname);
        perror(MPAGE);
        return;
    }

    /*
     * is input type forced?
     */
    switch (opt_input) {
	case IN_ASCII:  do_text_doc(fd, asheet, outfd, fname);
			break;
	case IN_PS:     do_ps_doc(fd, asheet, outfd, fname);
			break;
        /* Default figure out ourselfes */
    }

    /*
     * check for the cutomary characters that flag a postscript file
     */
    if (ps_check(fd))
        /*
         * found the flag signaling PS input
         */
        do_ps_doc(fd, asheet, outfd, fname);
    else
        /*
         * no postscript flag, print the ascii text
         */
        do_text_doc(fd, asheet, outfd, fname);

    (void) fclose(fd);

    return;

} /* do_file */



/*
 * do_file processes one text file into postscript, but first runs the file
 * through pr(1).
 */
void
do_pr_file(fname, asheet, outfd)
 char *fname;
 struct sheet *asheet;
 FILE *outfd;
{
    FILE *fd;
    char command[LINESIZE];

    /*
     * build the proper command based upon a specified
     * header or not
     */
    if (opt_header != NULL)
        (void)sprintf(command, "%s -l%d -w%d -h \"%s\" %s", prprog,
                  asheet->sh_plength, asheet->sh_cwidth, opt_header, fname);
    else
        (void)sprintf(command, "%s -l%d -w%d %s", prprog,
                  asheet->sh_plength, asheet->sh_cwidth, fname);
    /*
     * open a pipe to the proper pr(1) command, and pr provides
     * us with the input
     */
    if ((fd = popen(command, "r")) == NULL) {
        fprintf(stderr, "%s: cannot create pipe for '%s'\n", MPAGE, command);
        perror(MPAGE);
    }
    else {
        do_text_doc(fd, asheet, outfd, command);
        (void)pclose(fd);
    }

    return;

} /* do_pr_file */



/*
 * do_stdin uses do_????_doc to process the standard input
 */
void
do_stdin(asheet, outfd)
 struct sheet *asheet;
 FILE *outfd;
{
    FILE *fd;
    char command[LINESIZE];
    char tmpfile[LINESIZE];
    char buffer[LINESIZE];
    int incnt, outcnt;

    if (opt_pr) {
        Debug(DB_STDIN, "%%do_stdin: pr option selects text\n", 0);
        /*
         * if pr(1) is to be used we need to read the input
         * and pass it to a pr(1) command which will write
         * a temporary file; this temporary file will then
         * be used as input to the do_doc routine
         */
        (void)strcpy(tmpfile, "/usr/tmp/mpageXXXXXX");
        (void)mktemp(tmpfile);
        if (opt_header != NULL)
            (void)sprintf(command, "pr -l%d -w%d -h \"%s\"> %s",
                      asheet->sh_plength, asheet->sh_cwidth,
                      opt_header, tmpfile);
        else
            (void)sprintf(command, "pr -l%d -w%d > %s",
                      asheet->sh_plength, asheet->sh_cwidth, tmpfile);
        /*
         * open a pipe to the pr(1) command which will create a
         * temporary file for convertin into PS
         */
        if ((fd = popen(command, "w")) == NULL) {
            fprintf(stderr, "%s: cannot create pipe for '%s'\n",
                MPAGE, command);
            perror(MPAGE);
            return;
        }
#ifdef DEBUG
        errno = 0;
        Debug(DB_STDIN, "%% sizeof buffer == %d\n", sizeof buffer);
#endif
        /*
         * read input to mpage and pass it onto the pr(1) command
         */
        do {
            incnt = fread(buffer, 1, sizeof buffer, stdin);
            outcnt = fwrite(buffer, 1, incnt, fd);
            Debug(DB_STDIN, "%% incnt == %d,", incnt);
            Debug(DB_STDIN, " outcnt == %d,", outcnt);
            Debug(DB_STDIN, " errno == %d\n", errno);
        } while (incnt && outcnt);
        Debug(DB_STDIN, "%% Done with while\n", 0);
        (void)pclose(fd);
        Debug(DB_STDIN, "%% closed pipe, looking for tmpfile\n", 0);
        /*
         * now open the temporary file and use do_doc to
         * convert it to PS
         */
        if ((fd = fopen(tmpfile, "r")) == NULL) {
            fprintf(stderr, "%s: cannot open %s\n", MPAGE, tmpfile);
            perror(MPAGE);
        } else {
            Debug(DB_STDIN, "%% got tmpfile, now do_doc\n", 0);
            do_text_doc(fd, asheet, outfd, command);
            (void)fclose(fd);
        }
        /*
         * tidy up by removing our temp file
         */
        Debug(DB_STDIN, "%% now remove '%s'\n", tmpfile);
        (void)unlink(tmpfile);
    }
    else {
        /*
         * check for the cutomary flag at the start of postscript files
         */
        if (ps_check(stdin)) {
            /*
             * found the flag signaling PS input
             */
            Debug(DB_STDIN, "%%do_stdin: is postscript\n", 0);
            do_ps_doc(stdin, asheet, outfd, "stdin");
        }
        else {
            /*
             * no postscript flag, print the ascii text
             */
            Debug(DB_STDIN, "%%do_stdin: not postscript\n", 0);
            do_text_doc(stdin, asheet, outfd, "stdin");
        }
    }

    return;

} /* do_stdin */



/*
 * do_sheets() is called from do_xxx_doc() to render the sheets;
 * it does sheet selection and reversal.
 */
void
do_sheets(sheetfunc, inf, asheet, outf)
    int (*sheetfunc)();
    FILE *inf;
    struct sheet *asheet;
    FILE *outf;
{
    FILE *nullf = NULL;
    register int sheetno;

#define    WANTED(sn) \
    (sn >= opt_first && (opt_alt <= 1 || (sn - opt_first) % opt_alt == 0))

    if (opt_last == 0)
        opt_last = MAXINT;

    if (opt_alt > 1 || opt_first > 1)
        nullf = fopen("/dev/null", "w");

    if (opt_reverse) {
        FILE *revf;
        long *pagebase;
        int pageroom;

        revf = tmpfile();
        if (revf == NULL) {
            fprintf(stderr, "%s: can't create temporary file\n", MPAGE);
            exit(1);
        }
        pageroom = 50;
        pagebase = (long *)malloc(pageroom * sizeof(long));
        if(pagebase == NULL) {
            fprintf(stderr, "%s: can't malloc 50 words\n", MPAGE);
            exit(1);
        }
        pagebase[0] = 0;

        for (sheetno = 1; sheetno <= opt_last; ) {
            if ((*sheetfunc)(inf, asheet, WANTED(sheetno) ? revf : nullf)
                  == FILE_EOF)
                break;

            if (ferror(revf))
                break;

            pagebase[sheetno++] = ftell(revf);
            if (sheetno >= pageroom) {
                pageroom *= 4;
                pagebase = (long *)realloc(pagebase, pageroom * sizeof(long));
                if (pagebase == NULL) {
                    fprintf(stderr, "%s: can't malloc %d words\n",
                                    MPAGE, pageroom);
                    exit(1);
                }
        
            }
        }

        if (ferror(revf))
            fprintf(stderr, "%s: error writing to temporary file\n", MPAGE);
        else {
            pagebase[sheetno] = ftell(revf);
            rewind(revf);

            while (--sheetno >= 0) {
                register int i, n;
                char buf[BUFSIZ];

                fseek(revf, pagebase[sheetno], 0);
                for(i = pagebase[sheetno+1]-pagebase[sheetno]; i>0; i-=n) {
                    n = i < BUFSIZ ? i : BUFSIZ;
                    if (fread(buf, n, 1, revf) != 1) {
                        fprintf(stderr, "%s: Premature EOF on temp file\n",
                        MPAGE);
                        break;
                    }
                    (void) fwrite(buf, n, 1, outf);
                }
            }
        }
        fclose(revf);
        free(pagebase);

    }
    else {
        /* Normal, non-reversed pages */
        sheetno = 1;
        while (sheetno <= opt_last &&
               (*sheetfunc)(inf, asheet, WANTED(sheetno) ?
                        outf : nullf) != FILE_EOF)
            sheetno++;
    }

    if (nullf)
        fclose(nullf);

    return;

} /* do_sheets */