1:
2: /* @(#)main.c 1.5 92/02/17
3: *
4: * Takes a mail file, a news article or an ordinary file
5: * and pretty prints it on a Postscript printer.
6: *
7: * Copyright (c) Steve Holden and Rich Burridge.
8: * All rights reserved.
9: *
10: * Permission is given to distribute these sources, as long as the
11: * copyright messages are not removed, and no monies are exchanged.
12: *
13: * No responsibility is taken for any errors inherent either
14: * to the comments or the code of this program, but if reported
15: * to me then an attempt will be made to fix them.
16: */
17:
18: #include "mp.h"
19:
20: /* Command line option flags */
21:
22: bool article = FALSE ; /* Set for news in "Article from " format. */
23: bool content = FALSE ; /* Set if Content-Length: has message length. */
24: bool digest = FALSE ; /* Are we are printing a mail digest (-d) */
25: bool elm_if = FALSE ; /* ELM mail frontend intermediate file format */
26: bool folder = FALSE ; /* Set if we are printing a mail folder. */
27: bool landscape = FALSE ; /* Set if we are printing in landscape mode. */
28: bool print_orig = FALSE ; /* Print From rather than To in mail header. */
29: bool print_ps = TRUE ; /* Print PostScript files if set. */
30: bool text_doc = FALSE ; /* Printing normal text (-o) */
31:
32: /* Header definitions. */
33:
34: char *POSTSCRIPT_MAGIC = "%!" ; /* First line of PS file. */
35: char *FROMHDR = "From:" ;
36: char *FROM_HDR = "From " ; /* UNIX From header */
37: char *APP_FROMHDR = "Apparently_from:" ;
38: char *TOHDR = "To:" ;
39: char *APP_TOHDR = "Apparently_to:" ;
40: char *CCHDR = "Cc:" ;
41: char *SUBJECTHDR = "Subject:" ;
42: char *DATEHDR = "Date:" ;
43: char *NEWSGROUPSHDR = "Newsgroups:" ;
44: char *NEWSGROUPHDR = "Newsgroup:" ;
45: char *REPLYHDR = "Reply_to:" ;
46: char *CONTENT_LEN = "Content-Length:" ;
47:
48: /* Header lines. */
49:
50: char *from = NULL ; /* From: */
51: char *from_ = NULL ; /* From_ (UNIX from) */
52: char *apparently_from = NULL ; /* Apparently_from: */
53: char *to[MAXCONT+1] ; /* To: (can have multiple lines) */
54: char *apparently_to = NULL ; /* Apparently_to: */
55: char *cc[MAXCONT+1] ; /* Cc: (can have multiple lines) */
56: char *subject = NULL ; /* Subject: (can be set from command line) */
57: char *gsubject = NULL ; /* Global subject set from command line. */
58: char *date = NULL ; /* Date: */
59: char *newsgroups = NULL ; /* Newsgroups: (news articles only) */
60: char *reply_to = NULL ; /* Reply-to: */
61: char *content_len = NULL ; /* Content-Length: */
62:
63: /* Strings used in page processing. */
64:
65: char curfname[MAXPATHLEN] ; /* Current file being printed. */
66: char *message_for = "" ; /* "[Mail,News,Listing] for " line */
67: char *nameptr ; /* Used to getenv the NAME variable. */
68: char *optarg ; /* Optional command line argument. */
69: char *owner = NULL ; /* Name of owner (usually equal to 'to') */
70: char *progname = NULL ; /* Name of this program. */
71: char *prologue = PROLOGUE ; /* Name of PostScript prologue file. */
72: char proname[MAXPATHLEN] ; /* Full pathname of the prologue file. */
73: char *whoami = NULL ; /* Login name of user. */
74:
75: /* Other globals. */
76:
77: document_type doc_type = DO_MAIL ; /* Printing type - default mail */
78: paper_type paper_size = US ; /* Paper size - default US */
79:
80: int clen = 0 ; /* Current line length (including newline). */
81: int colct = 0; /* Column count on current page. */
82: int cmdfiles = 0 ; /* Set if file to print given on command line. */
83: int linect = 0 ; /* Line count on current page. */
84: int llen = LINELENGTH ; /* Number of characters per line. */
85: int mlen = 0 ; /* Number of characters in message (-C option). */
86: int numcols = 1 ; /* Number of columns per page */
87: int optind ; /* Optional command line argument indicator. */
88: int pageno = 1 ; /* Page number within message. */
89: int plen = PAGELENGTH ; /* Number of lines per page. */
90: int tpn = 0 ; /* Total number of pages printed. */
91:
92: /* Read-ahead variables. */
93:
94: char nextline[MAXLINE] ; /* Read-ahead of the mail message, minus nl */
95:
96: bool end_of_file = FALSE ; /* EOF indicator */
97: bool end_of_line ; /* Is a newline removed from this line */
98: bool end_of_page = FALSE ; /* end-of-page indicator - ^L on input */
99:
100: FILE *fp ; /* File pointer for current file. */
101:
102:
103: int
104: main(argc, argv)
105: int argc ;
106: char **argv ;
107: {
108: to[0] = cc[0] = NULL ;
109:
110: progname = argv[0] ; /* Save this program name. */
111:
112: /* Try to get location of the mp prologue file from an environment variable.
113: * If it's not found, then use the default value.
114: */
115:
116: if ((prologue = getenv("MP_PROLOGUE")) == NULL) prologue = PROLOGUE ;
117: SPRINTF(proname, "%s/mp.pro.ps", prologue) ;
118:
119: get_options(argc, argv) ; /* Read and process command line options. */
120:
121: show_prologue(proname) ; /* Send prologue file to output. */
122:
123: FPUTS("%%EndProlog\n", stdout) ;
124:
125: if (argc - optind != 0) cmdfiles = 1 ;
126: if (!cmdfiles)
127: {
128: fp = stdin ; /* Get input from standard input. */
129: STRCPY(curfname, "stdin") ;
130: printfile() ; /* Pretty print *just* standard input. */
131: }
132: else
133: for (; optind < argc; ++optind)
134: {
135: STRCPY(curfname, argv[optind]) ; /* Current file to print. */
136: if ((fp = fopen(curfname, "r")) == NULL)
137: {
138: FPRINTF(stderr, "%s: cannot open %s\n", progname, curfname) ;
139: continue ;
140: }
141: colct = 0 ;
142: pageno = 1 ; /* Initialise current page number. */
143: end_of_file = 0 ; /* Reset in case there's another file to print. */
144: printfile() ; /* Pretty print current file. */
145: }
146:
147: show_trailer() ; /* Send trailer file to output. */
148:
149: exit(0) ;
150: /*NOTREACHED*/
151: }
152:
153:
154: int
155: printfile() /* Create PostScript to pretty print the current file. */
156: {
157: int blankslate ; /* Nothing set up for printing. */
158: bool eop ; /* Set if ^L (form-feed) found. */
159:
160: readline() ;
161: if (end_of_file)
162: {
163: FPRINTF(stderr, "mp: empty input file, nothing printed\n") ;
164: exit(1) ;
165: }
166:
167: if (!text_doc)
168: parse_headers(FALSE) ; /* Parse headers of mail or news article */
169: init_setup() ; /* Set values for remaining globals. */
170:
171: startfile();
172: startpage() ; /* Output initial definitions. */
173: blankslate = 0 ;
174: eop = FALSE ;
175:
176: /* Print the document */
177:
178: if (doc_type != DO_TEXT)
179: {
180: show_headers(FALSE) ;
181: #ifdef WANTED
182: FPUTS("sf ", stdout) ;
183: #endif /*WANTED*/
184: }
185:
186: while (!end_of_file)
187: {
188: if (blankslate)
189: {
190: startfile() ;
191: startpage() ; /* Output initial definitions. */
192: blankslate = 0 ;
193: }
194:
195: if (content && folder && mlen <= 0)
196: {
197:
198: /* If the count has gone negative, then the Content-Length is wrong, so go
199: * back to looking for "\nFrom".
200: */
201:
202: if (mlen < 0) content = FALSE ;
203: else if ((hdr_equal(FROM_HDR) || hdr_equal(FROMHDR)) &&
204: isupper(nextline[0]))
205: {
206: eop = FALSE ;
207: linect = plen ;
208: reset_headers() ;
209: parse_headers(FALSE) ;
210: show_headers(FALSE) ;
211: }
212: else content = FALSE ;
213: }
214:
215: if (!content && folder &&
216: (!elm_if && hdr_equal(FROM_HDR) ||
217: elm_if && hdr_equal(FROMHDR)) && isupper(nextline[0]))
218: {
219: eop = FALSE ;
220: linect = plen ;
221: reset_headers() ;
222: parse_headers(FALSE) ;
223: show_headers(FALSE) ;
224: }
225: if (digest &&
226: (hdr_equal(FROMHDR) || hdr_equal(DATEHDR) || hdr_equal(SUBJECTHDR)) &&
227: isupper(nextline[0]))
228: {
229: linect = plen ;
230: parse_headers(TRUE) ;
231: show_headers(TRUE) ;
232: }
233:
234: if (print_ps && hdr_equal(POSTSCRIPT_MAGIC))
235: {
236: if (numcols) endcol() ;
237: endpage() ;
238: endfile() ;
239: process_postscript() ;
240: blankslate = 1 ;
241: }
242: else if (folder && end_of_page) eop = TRUE ;
243: else
244: {
245: if (eop == TRUE) end_of_page = TRUE ;
246: textshow(nextline) ;
247: eop = FALSE ;
248: }
249:
250: if (content) mlen -= clen ;
251:
252: readline() ;
253: }
254:
255: if (!blankslate)
256: {
257: if (numcols) endcol() ;
258: endpage() ;
259: endfile() ;
260: }
261:
262: FCLOSE(fp) ;
263: }
264:
265:
266: int
267: process_postscript()
268: {
269: int firstline = 1 ; /* To allow a newline after the first line. */
270:
271: startpage() ;
272: while (!hdr_equal(FROMHDR) && !hdr_equal(DATEHDR) &&
273: !hdr_equal(SUBJECTHDR) && !end_of_file)
274: {
275: PRINTF("%s", nextline) ;
276: if (firstline) FPUTS("\n", stdout) ;
277: firstline = 0 ;
278: if (fgets(nextline, MAXLINE, fp) == NULL) end_of_file = TRUE ;
279: }
280: endpage() ;
281: }
282:
283:
284: int
285: show_trailer()
286: {
287: FPUTS("%%Trailer\n", stdout) ;
288: PRINTF("%%%%Pages: %1d\n", tpn) ;
289: }
Defined functions
main
defined in line
103;
never used
Defined variables
CCHDR
defined in line
40; used 3 times
TOHDR
defined in line
38; used 3 times
cc
defined in line
55; used 7 times
clen
defined in line
80; used 2 times
colct
defined in line
81; used 8 times
date
defined in line
58; used 10 times
from
defined in line
50; used 12 times
from_
defined in line
51; used 6 times
llen
defined in line
84; used 4 times
mlen
defined in line
85; used 5 times
nextline
defined in line
94; used 22 times
- in line 204,
217,
227,
246,
275-278(2)
- in /usr/src/local/mp/header.c line
30-31(2),
52-55(4),
72,
126,
132,
148,
160-163(2),
179
- in /usr/src/local/mp/io.c line
54,
61,
70
optarg
defined in line
68; used 14 times
owner
defined in line
69; used 18 times
plen
defined in line
89; used 5 times
to
defined in line
53; used 7 times
tpn
defined in line
90; used 4 times