home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume10 / mp23 / part01 next >
Text File  |  1990-01-19  |  47KB  |  1,558 lines

  1. Newsgroups: comp.sources.misc
  2. subject: v10i013: mp V2.3 - a PostScript pretty printer for mail etc.. (Part 1 of 2).
  3. from: richb@Aus.Sun.COM (Rich Burridge)
  4. Sender: allbery@uunet.UU.NET (Brandon S. Allbery - comp.sources.misc)
  5.  
  6. Posting-number: Volume 10, Issue 13
  7. Submitted-by: richb@Aus.Sun.COM (Rich Burridge)
  8. Archive-name: mp23/part01
  9.  
  10. [When things go wrong, they *really* go wrong.  (Don't ask; the crash at uunet
  11. is a decidedly minor contributor.)  Here comes a large load backed up from last
  12. weekend.  ++bsa]
  13.  
  14. Mp v2.3 - October 1989.
  15.  
  16. The mp program will pretty print various files for you. It can be used
  17. in conjunction with a mail reading utility for producing a pretty print
  18. of your mail items. It can be used with a news reading tool to pretty
  19. print news articles. Digests can also be printed, and this version can
  20. pretty print ordinary ASCII files as well. Support for personal organiser
  21. printing was added into the last released version.
  22.  
  23. It uses a PostScript prologue file which normally resides in
  24. /usr/local/lib, but this can be overwritten by use of the -p option.
  25.  
  26. See the README file and manual pages for more details.
  27.  
  28. Do a "make" followed by a "make install" which will compile the mp program
  29. and put the files in their default locations. You will probably have to
  30. be super-user when you do the "make install"
  31.  
  32. I welcome further bug reports and suggestions for improvements.
  33.  
  34.     Rich.
  35.  
  36. Rich Burridge,          DOMAIN: richb@sunaus.oz.au
  37. PHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  38.  
  39. ---- Cut Here and unpack ----
  40. #!/bin/sh
  41. # shar:    Shell Archiver  (v1.22)
  42. #    Packed Tue Jan  9 12:38:10 EST 1990 by stard!richb
  43. #    from directory /extra/richb/rich_stuff/mp
  44. #
  45. # This is part 1 of a multipart archive                                    
  46. # do not concatenate these parts, unpack them in order with /bin/sh        
  47. #
  48. #    Run the following text with /bin/sh to create:
  49. #      README
  50. #      Makefile
  51. #      header.c
  52. #      io.c
  53. #      main.c
  54. #      misc.c
  55. #      print.c
  56. #      extern.h
  57. #      mp.h
  58. #      patchlevel.h
  59. #      mailp
  60. #      mp.1
  61. #      mp.pro.ps
  62. #      mp.pro.filofax.ps
  63. #      mp.pro.timeman.ps
  64. #
  65. if test -r s2_seq_.tmp
  66. then echo "Must unpack archives in sequence!"
  67.      next=`cat s2_seq_.tmp`; echo "Please unpack part $next next"
  68.      exit 1; fi
  69. echo "x - extracting README (Text)"
  70. sed 's/^X//' << 'SHAR_EOF' > README &&
  71. X
  72. XREADME for mp, the PostScript pretty printer.
  73. X
  74. XVersion 2.3 October 1989.
  75. X
  76. XPermission is given to distribute these sources, as long as the
  77. Xauthorship messages are not removed, and no monies are exchanged.
  78. X
  79. XThe mp program will pretty print various files for you. It can be used
  80. Xin conjunction with a mail reading utility for producing a pretty print
  81. Xof your mail items. It can be used with a news reading tool to pretty
  82. Xprint news articles. Digests can also be printed, and this version can
  83. Xpretty print ordinary ASCII files as well. Support for personal organiser
  84. Xprinting was added into the last released version.
  85. X
  86. XIt uses a PostScript prologue file which normally resides in
  87. X/usr/local/lib, but this can be overwritten by use of the -p option.
  88. X
  89. XSee the manual pages for more details on these various options.
  90. X
  91. XDo a "make" followed by a "make install" which will compile the mp program
  92. Xand put the files in their default locations. You will probably have to
  93. Xbe super-user when you do the "make install"
  94. X
  95. XAcknowledgements.
  96. X
  97. XThe original version of mp was written by Steve Holden in the ICON language,
  98. Xwhen Steve worked for Sun Microsystems UK. I converted it to the C language
  99. Xand added a few features. Bruno Pillard of Chorus Systemes, France added
  100. Xsupport for MH mail and news article printing, plus a shell script (mailp)
  101. Xwhich tidies up the user interface to mp. Dave Glowacki of Public Works
  102. XComputer Services, St Paul, MN. added the ability to print digests and
  103. Xtidied up some of the other options. Rick Rodgers, UCSF School of Pharmacy,
  104. XSan Francicso revised the initial version of the mp manual page. Doug
  105. XBuchanan added support for printing in filofax and Time Manager format.
  106. XMany thanks go to Jerermy Webber, Computer Science Department of the
  107. XUniversity of Adelaide who rewrote the message parsing and option code and
  108. Xmade substantial improvements to the programs user friendliness and
  109. Xrobustness. Sam Manogharan added support for printing multiple files
  110. Xspecified on the command line, and subject line filename print for ordinary
  111. Xfiles.
  112. X
  113. XThanks go also to Bill Shannon, Roger De Salis, L. Jill Debord, Frederick
  114. XAvolio, Mark Prior, Stephen Frede, Craig Bishop, Jimmy Aitken, Hugues Leroy,
  115. XBertrand Decouty, David Fiedler, Scott A. Jordahl, David Boone and Maureen
  116. XChew for bug reports and/or bug fixes.
  117. X
  118. XMy thanks also goes to Glenn Reid from Adobe Systems for the backspacefont.ps
  119. Xcode used in the prologue files. I'm grateful to all these people, plus
  120. Xeverybody who has suggested enhancements, and fixed bugs in the previous
  121. Xversions.
  122. X
  123. XI welcome further bug reports and suggestions for improvements.
  124. X
  125. X    Rich.
  126. X
  127. XRich Burridge,          DOMAIN: richb@sunaus.oz.au
  128. XPHONE: +61 2 413 2666   UUCP:   {uunet,mcvax,ukc}!munnari!sunaus.oz!richb
  129. SHAR_EOF
  130. chmod 0444 README || echo "restore of README fails"
  131. set `wc -c README`;Sum=$1
  132. if test "$Sum" != "2752"
  133. then echo original size 2752, current size $Sum;fi
  134. echo "x - extracting Makefile (Text)"
  135. sed 's/^X//' << 'SHAR_EOF' > Makefile &&
  136. X#
  137. X#  Makefile for mp, the PostScript pretty printer.
  138. X#
  139. X#  @(#)Makefile 1.2 89/10/16
  140. X#
  141. X#  Copyright (c) Steve Holden and Rich Burridge.
  142. X#                All rights reserved.
  143. X#
  144. X#  Permission is given to distribute these sources, as long as the
  145. X#  copyright messages are not removed, and no monies are exchanged.
  146. X#
  147. X#  No responsibility is taken for any errors inherent either
  148. X#  to the comments or the code of this program, but if reported
  149. X#  to me then an attempt will be made to fix them.
  150. X#
  151. X#=====================================================================
  152. X#
  153. X#  It is possible to change the location of the mp prologue file
  154. X#  with the -p command line option. It can also be defined at compile
  155. X#  time, by uncommenting the macro definition below and setting
  156. X#  appropriately. If it's not present, then a sensible default value
  157. X#  is used.
  158. X#
  159. X#PROLOGUE = -DPROLOGUE=\"$(LIBDIR)\"
  160. X#=====================================================================
  161. X#
  162. X#  Default locations where mp files will be installed.
  163. X#  You might wish to alter these values.
  164. X#
  165. XBINDIR   = /usr/local/bin
  166. XLIBDIR   = /usr/local/lib
  167. XMANDIR   = /usr/man/man$(MANSECT)
  168. XMANSECT  = l
  169. X#
  170. X#  Compilation flags and standard macro definitions.
  171. X#
  172. XCFLAGS   = -g $(PROLOGUE)
  173. XLDFLAGS  =
  174. X#=================================================================
  175. X
  176. X.KEEPSTATE:
  177. X
  178. XBINARIES = mp
  179. X
  180. XSRCS     = header.c io.c main.c misc.c print.c
  181. XOBJS     = $(SRCS:.c=.o)
  182. X
  183. XHDRS     = extern.h mp.h patchlevel.h
  184. XOTHERS   = README Makefile mailp mp.1 \
  185. X       mp.pro.ps mp.pro.filofax.ps mp.pro.timeman.ps
  186. X
  187. Xall:       $(BINARIES)
  188. X
  189. Xmp:        $(OBJS)
  190. X       cc $(LDFLAGS) -o mp $(OBJS)
  191. X
  192. Xinstall:   $(BINARIES)
  193. X       install -s -m 751 mp $(BINDIR)
  194. X       install -c -m 644 mp.1 $(MANDIR)/mp.$(MANSECT)
  195. X       install -c -m 644 mp.pro.ps $(LIBDIR)
  196. X       install -c -m 644 mp.pro.filofax.ps $(LIBDIR)
  197. X       install -c -m 644 mp.pro.timeman.ps $(LIBDIR)
  198. X
  199. Xclean:;    rm -rf mp *.o core
  200. X
  201. Xcreate:    SCCS
  202. X       -sccs create $(SRCS) $(OTHERS)
  203. X
  204. Xlint:;     lint $(SRCS)
  205. X
  206. Xshar:;     shar.script $(SRCS) $(HDRS) $(OTHERS) > archive
  207. X
  208. XSCCS:
  209. X       mkdir SCCS
  210. X       chmod 755 SCCS
  211. SHAR_EOF
  212. chmod 0444 Makefile || echo "restore of Makefile fails"
  213. set `wc -c Makefile`;Sum=$1
  214. if test "$Sum" != "2080"
  215. then echo original size 2080, current size $Sum;fi
  216. echo "x - extracting header.c (Text)"
  217. sed 's/^X//' << 'SHAR_EOF' > header.c &&
  218. X
  219. X/*  @(#)header.c 1.1 89/10/16
  220. X *
  221. X *  Copyright (c) Steve Holden and Rich Burridge.
  222. X *                All rights reserved.
  223. X *
  224. X *  Permission is given to distribute these sources, as long as the
  225. X *  copyright messages are not removed, and no monies are exchanged.
  226. X *
  227. X *  No responsibility is taken for any errors inherent either
  228. X *  to the comments or the code of this program, but if reported
  229. X *  to me then an attempt will be made to fix them.
  230. X */
  231. X
  232. X#include "mp.h"
  233. X#include "extern.h"
  234. X
  235. X
  236. X/*  If input line is header of type 'hdr', get the contents of the header
  237. X *  into 'dest' (dynamically allocated).
  238. X */
  239. X
  240. Xvoid
  241. Xget_header(hdr, dest)
  242. Xchar *hdr ;
  243. Xchar **dest ;
  244. X{
  245. X  if (EQUAL(hdr))
  246. X    {
  247. X      *dest = malloc((unsigned) (strlen(nextline) - strlen(hdr) + 1)) ;
  248. X      STRCPY(*dest, nextline + strlen(hdr)) ;
  249. X    }
  250. X}
  251. X
  252. X
  253. X/*  If input line is header of type 'hdr', get header into dest. The header
  254. X *  may have multiple lines. This skips input to next line.
  255. X */
  256. Xvoid
  257. Xget_mult_hdr(hdr, dest)
  258. Xchar *hdr ;
  259. Xchar *dest[] ;
  260. X{ 
  261. X  int i = 0 ;
  262. X  
  263. X  if (EQUAL(hdr))
  264. X    {
  265. X      get_header(hdr, dest) ;
  266. X      i++ ;
  267. X      readline() ;
  268. X      while (i < MAXCONT && !emptyline(nextline) && isspace(nextline[0]))
  269. X        {
  270. X          dest[i] = malloc((unsigned) (strlen(nextline) + 1)) ;
  271. X          STRCPY(dest[i], nextline) ;
  272. X          i++ ;
  273. X          readline() ;
  274. X        }
  275. X      dest[i] = NULL ;
  276. X    }
  277. X}
  278. X
  279. X
  280. X/*  Parse_headers is a function which reads and parses the message headers,
  281. X *  extracting the bits which are of interest.
  282. X *
  283. X *  The document is on standard input; the document is read up to the end of
  284. X *  the header; the next line is read ahead into 'nextline'.
  285. X *
  286. X *  Parameter:
  287. X *  digest  indicates if parsing is of digest headers instead of message
  288. X *          headers
  289. X *
  290. X *  Implicit Input:
  291. X *  nextline  contains the next line from standard input
  292. X *
  293. X *  Side-effects:
  294. X *  The function fills in the global header variables with headers found.
  295. X *  The global variable doc_type is set to the document type
  296. X *  The global variable nextline is set
  297. X *  The document is read up to the line following the headers
  298. X */
  299. X
  300. X
  301. Xvoid
  302. Xparse_headers(digest)
  303. Xbool digest ;           /* Parsing digest headers */
  304. X{
  305. X  char *colon ;         /* Pointer to colon in line */
  306. X  char *c ;             /* General character pointer */
  307. X
  308. X/*  If not processing digest headers, determine if this article is an
  309. X *  ordinary text file.
  310. X */
  311. X
  312. X  if (!digest)
  313. X    {
  314. X      if (!EQUAL(FROM_HDR))         /* UNIX From_ header? */
  315. X        {
  316. X          colon = index(nextline, ':') ;
  317. X          if (colon == NULL)        /* No colon => not a header line */
  318. X            {
  319. X              doc_type = DO_TEXT ;
  320. X              return ;
  321. X            }
  322. X          c = nextline ;
  323. X          while (c < colon && (!isspace(*c))) c++ ;
  324. X          if (c != colon)      /* Whitespace in header name => not header */
  325. X            {
  326. X              doc_type = DO_TEXT ;
  327. X              return ;
  328. X            }
  329. X        }    
  330. X    }    
  331. X
  332. X  doc_type = DO_MAIL ;    /* Default to mail document */
  333. X
  334. X/* Parse headers */
  335. X
  336. X  while (TRUE)
  337. X    {
  338. X      if (emptyline(nextline)) break ;    /* End of headers */
  339. X
  340. X      if (!digest)
  341. X        {
  342. X          get_header(FROM_HDR,      &from_) ;
  343. X          get_header(APP_FROMHDR,   &apparently_from) ;
  344. X          get_header(APP_TOHDR,     &apparently_to) ;
  345. X          get_header(NEWSGROUPSHDR, &newsgroups) ;
  346. X          get_header(REPLYHDR,      &reply_to) ;
  347. X
  348. X          get_mult_hdr(TOHDR,       to) ;
  349. X          if (emptyline(nextline)) break ;
  350. X
  351. X          get_mult_hdr(CCHDR,       cc) ;
  352. X          if (emptyline(nextline)) break ;
  353. X
  354. X          if (doc_type != DO_NEWS && EQUAL(NEWSGROUPSHDR))
  355. X            doc_type = DO_NEWS ;
  356. X        }
  357. X      get_header(FROMHDR, &from) ;
  358. X      if (digest || *subject == '\0')
  359. X        get_header(SUBJECTHDR, &subject) ;
  360. X      get_header(DATEHDR, &date) ;
  361. X
  362. X      if (!EQUAL(TOHDR) && !EQUAL(CCHDR))
  363. X        {
  364. X          while (!end_of_file && !end_of_line)
  365. X            readline() ;                       /* Skip rest of long lines */
  366. X          readline() ;
  367. X        }
  368. X    }    
  369. X}
  370. X
  371. X
  372. Xvoid
  373. Xreset_headers()          /* Reset header values for next message. */
  374. X{
  375. X  int i ;
  376. X  if (from != NULL) free(from) ;
  377. X  if (from_ != NULL) free(from_) ;
  378. X  if (apparently_from != NULL) free(apparently_from) ;
  379. X  if (apparently_to != NULL) free(apparently_to) ;
  380. X  if (date != NULL) free(date) ;
  381. X  if (newsgroups != NULL) free(newsgroups) ;
  382. X  if (reply_to != NULL) free(reply_to) ;
  383. X  from = from_ = apparently_from = apparently_to = NULL ;
  384. X  date = newsgroups = reply_to = NULL ;
  385. X  STRCPY(subject, "") ;
  386. X  for (i = 0; i < MAXCONT+1; i++)
  387. X    {
  388. X      if (to[i] != NULL) free(to[i]) ;
  389. X      if (cc[i] != NULL) free(cc[i]) ;
  390. X      to[i] = cc[i] = NULL ;
  391. X    }
  392. X}
  393. X
  394. X
  395. X/*  Show_headers outputs the headers in PostScript. Different headers are
  396. X *  output depending 'digest'.
  397. X */
  398. X
  399. Xvoid
  400. Xshow_headers(digest)
  401. Xbool digest ;
  402. X{
  403. X  if (digest)
  404. X    {
  405. X      if (from)       mixedshow(FROMHDR,    from) ;
  406. X      if (subject[0]) mixedshow(SUBJECTHDR, subject) ;
  407. X      if (date)       mixedshow(DATEHDR,    date) ;
  408. X    }
  409. X  else
  410. X    {
  411. X      if (from_)           boldshow(FROM_HDR,       from_) ;
  412. X      if (from)            mixedshow(FROMHDR,       from) ;
  413. X      if (apparently_from) mixedshow(APP_FROMHDR,   apparently_from) ;
  414. X      if (to[0])           show_mult_hdr(TOHDR,     to) ;
  415. X      if (apparently_to)   mixedshow(APP_TOHDR,     apparently_to) ;
  416. X      if (cc[0])           show_mult_hdr(CCHDR,     cc) ;
  417. X      if (reply_to)        mixedshow(REPLYHDR,      reply_to) ;
  418. X      if (newsgroups)      mixedshow(NEWSGROUPSHDR, newsgroups) ;
  419. X      if (subject[0])      mixedshow(SUBJECTHDR,    subject) ;
  420. X      if (date)            mixedshow(DATEHDR,       date) ;
  421. X    }
  422. X}
  423. X
  424. X
  425. Xvoid
  426. Xshow_mult_hdr(hdr, val)
  427. Xchar *hdr ;              /* Name of header */
  428. Xchar *val[] ;            /* Value of header */
  429. X{
  430. X  mixedshow(hdr, *val) ;
  431. X  val++ ;
  432. X  while (*val) romanshow(*val++) ;
  433. X}
  434. X
  435. SHAR_EOF
  436. chmod 0444 header.c || echo "restore of header.c fails"
  437. set `wc -c header.c`;Sum=$1
  438. if test "$Sum" != "5904"
  439. then echo original size 5904, current size $Sum;fi
  440. echo "x - extracting io.c (Text)"
  441. sed 's/^X//' << 'SHAR_EOF' > io.c &&
  442. X
  443. X/*  @(#)io.c 1.3 89/10/18
  444. X *
  445. X *  Copyright (c) Steve Holden and Rich Burridge.
  446. X *                All rights reserved.
  447. X *
  448. X *  Permission is given to distribute these sources, as long as the
  449. X *  copyright messages are not removed, and no monies are exchanged.
  450. X *
  451. X *  No responsibility is taken for any errors inherent either
  452. X *  to the comments or the code of this program, but if reported
  453. X *  to me then an attempt will be made to fix them.
  454. X */
  455. X
  456. X#include "mp.h"
  457. X#include "extern.h"
  458. X
  459. X
  460. X/* Emptyline returns true if its argument is empty or whitespace only */
  461. X         
  462. Xbool
  463. Xemptyline(str)
  464. Xchar *str ;
  465. X{
  466. X  while (*str)
  467. X    {
  468. X      if (!isspace(*str)) return(FALSE) ;
  469. X      str++ ;
  470. X    }
  471. X  return(TRUE) ;
  472. X}
  473. X
  474. X
  475. X/*  Read an input line into nextline, setting end_of_file, end_of_page
  476. X *  and end_of_line appropriately.
  477. X */
  478. X
  479. Xvoid
  480. Xreadline()
  481. X{
  482. X  int c ;
  483. X  int i = 0 ;      /* Index into current line being read. */
  484. X  int len = 0 ;    /* Length of the current line. */
  485. X
  486. X  if (end_of_file) return ;
  487. X  end_of_page = end_of_line = FALSE ;
  488. X
  489. X  while (len < llen && (c = getc(fp)) != EOF && c != '\n' && c != '\f')
  490. X    {
  491. X      if (c == '\t')
  492. X        {
  493. X          do
  494. X            {
  495. X              nextline[i++] = ' ' ;
  496. X              len++ ;
  497. X            }
  498. X          while (len % 8 != 0 && len <= llen) ;
  499. X        }
  500. X      else
  501. X        { 
  502. X          nextline[i++] = c ;
  503. X          len++ ;
  504. X        }
  505. X      if (c == '\b') len -= 2 ;
  506. X    }
  507. X  nextline[i] = '\0' ;
  508. X
  509. X  if (len == llen && c != EOF && c != '\n' && c != '\f')
  510. X    {
  511. X      c = getc(fp) ;
  512. X      if (c != EOF && c != '\n' && c != '\f') UNGETC(c, fp) ;
  513. X    }
  514. X
  515. X  switch (c)
  516. X    {
  517. X      case EOF  : if (i == 0) end_of_file = TRUE ;
  518. X                  else
  519. X                    { 
  520. X                      UNGETC(c, fp) ;
  521. X                      end_of_line = TRUE ;
  522. X                    }
  523. X                  break ;
  524. X      case '\n' : end_of_line = TRUE ;
  525. X                  break ;
  526. X
  527. X/*  /usr/ucb/mail for some unknown reason, appends a bogus formfeed at
  528. X *  the end of piped output. The next character is checked; if it's an
  529. X *  EOF, then end_of_file is set, else the character is put back.
  530. X */
  531. X
  532. X      case '\f' : if ((c = getc(fp)) == EOF) end_of_file = TRUE ;
  533. X                  else UNGETC(c, fp) ;
  534. X
  535. X                  end_of_line = TRUE ;
  536. X                  end_of_page = TRUE ;
  537. X                  break ;
  538. X    }
  539. X}
  540. SHAR_EOF
  541. chmod 0444 io.c || echo "restore of io.c fails"
  542. set `wc -c io.c`;Sum=$1
  543. if test "$Sum" != "2329"
  544. then echo original size 2329, current size $Sum;fi
  545. echo "x - extracting main.c (Text)"
  546. sed 's/^X//' << 'SHAR_EOF' > main.c &&
  547. X
  548. X/*  @(#)main.c 1.2 89/10/16
  549. X *
  550. X *  Takes a mail file, a news article or an ordinary file
  551. X *  and pretty prints it on a Postscript printer.
  552. X *
  553. X *-----------------------------------------------------------------------
  554. X *
  555. X *  Credits:
  556. X *
  557. X *  Original written in the Icon language by Steve Holden.
  558. X *
  559. X *  Converted to C, modified and maintained
  560. X *  by Rich Burridge - Sun Microsystems Australia.
  561. X *
  562. X *  Further modifications to handle news articles and MH mail,
  563. X *  by Bruno Pillard  - Chorus Systemes, St Quentin en Yvelines, France
  564. X *
  565. X *  Addition of digest printing by Dave Glowacki of Public
  566. X *  Works Computer Services, St Paul, MN.
  567. X *
  568. X *  Ordinary text file pretty printing by Rich Burridge.
  569. X *
  570. X *  Substantial modifications to header parsing and command options
  571. X *  by Jeremy Webber, Computer Science Dept, University of Adelaide,
  572. X *  Australia.
  573. X *
  574. X *  Support for printing multiple files and subject line filename print
  575. X *  for ordinary files added by S. Manoharan, Edinburgh University.
  576. X *
  577. X *----------------------------------------------------------------------
  578. X *
  579. X *  Copyright (c) Steve Holden and Rich Burridge.
  580. X *                All rights reserved.
  581. X *
  582. X *  Permission is given to distribute these sources, as long as the
  583. X *  copyright messages are not removed, and no monies are exchanged.
  584. X *
  585. X *  No responsibility is taken for any errors inherent either
  586. X *  to the comments or the code of this program, but if reported
  587. X *  to me then an attempt will be made to fix them.
  588. X */
  589. X
  590. X#include "mp.h"
  591. X
  592. X/* Command line option flags */
  593. Xbool article  = FALSE ;       /* Set for news in "Article from " format. */
  594. Xbool digest   = FALSE ;       /* Are we are printing a mail digest (-d) */
  595. Xbool filofax  = FALSE ;       /* Set if we are printing a filofax file. */
  596. Xbool folder   = FALSE ;       /* Set if we are printing a mail folder. */
  597. Xbool text_doc = FALSE ;       /* Printing normal text (-o) */
  598. Xbool timeman  = FALSE ;       /* Set if we are printing a Time Manager file. */
  599. X/* Header definitions. */
  600. Xchar *FROMHDR       = "From:" ;
  601. Xchar *FROM_HDR      = "From " ;            /* UNIX From header */
  602. Xchar *APP_FROMHDR   = "Apparently_from:" ;
  603. Xchar *TOHDR         = "To:" ;
  604. Xchar *APP_TOHDR     = "Apparently_to:" ;
  605. Xchar *CCHDR         = "Cc:" ;
  606. Xchar *SUBJECTHDR    = "Subject:" ;
  607. Xchar *DATEHDR       = "Date:" ;
  608. Xchar *NEWSGROUPSHDR = "Newsgroups:" ;
  609. Xchar *REPLYHDR      = "Reply_to:" ;
  610. X
  611. X/* Header lines. */
  612. X
  613. Xchar *from            = NULL ;    /* From: */
  614. Xchar *from_           = NULL ;    /* From_ (UNIX from) */
  615. Xchar *apparently_from = NULL ;    /* Apparently_from: */
  616. Xchar *to[MAXCONT+1] ;             /* To: (can have multiple lines) */
  617. Xchar *apparently_to   = NULL ;    /* Apparently_to: */
  618. Xchar *cc[MAXCONT+1]   = NULL ;    /* Cc: (can have multiple lines) */
  619. Xchar *subject         = "" ;      /* Subject: (can be set from command line) */
  620. Xchar *date            = NULL ;    /* Date: */
  621. Xchar *newsgroups      = NULL ;    /* Newsgroups: (news articles only) */
  622. Xchar *reply_to        = NULL ;    /* Reply-to: */
  623. X
  624. X/* Strings used in page processing. */
  625. X
  626. Xchar curfname[MAXPATHLEN] ;       /* Current file being printed. */
  627. Xchar *message_for = "" ;          /* "[Mail,News,Listing] for " line */
  628. Xchar *nameptr ;                   /* Used to getenv the NAME variable. */
  629. Xchar *optarg ;                    /* Optional command line argument. */
  630. Xchar *owner       = NULL ;        /* Name of owner (usually equal to 'to') */
  631. Xchar *progname    = "" ;          /* Name of this program. */
  632. Xchar *prologue    = PROLOGUE ;    /* Name of PostScript prologue file. */
  633. Xchar proname[MAXPATHLEN] ;        /* Full pathname of the prologue file. */
  634. X
  635. X/* Other globals. */
  636. X
  637. Xdocument_type doc_type = DO_MAIL ;  /* Printing type - default mail */
  638. X
  639. Xint cmdfiles = 0 ;          /* Set if file to print given on command line. */
  640. Xint linect = 0 ;            /* Line count on current page. */
  641. Xint llen = LINELENGTH ;     /* Number of characters per line. */
  642. Xint optind ;                /* Optional command line argument indicator. */
  643. Xint pageno = 1 ;            /* Page number within message. */
  644. Xint plen = PAGELENGTH ;     /* Number of lines per page. */
  645. Xint tpn    = 0 ;            /* Total number of pages printed. */
  646. X
  647. X/* Read-ahead variables. */
  648. X
  649. Xchar nextline[MAXLINE] ;  /* Read-ahead of the mail message, minus nl */
  650. X
  651. Xbool end_of_file = FALSE ;     /* EOF indicator */
  652. Xbool end_of_line ;             /* Is a newline removed from this line */
  653. Xbool end_of_page = FALSE ;     /* end-of-page indicator - ^L on input */
  654. X
  655. XFILE *fp ;                     /* File pointer for current file. */
  656. X
  657. X
  658. Xmain(argc, argv)
  659. Xint argc ;
  660. Xchar **argv ;
  661. X{
  662. X  to[0] = cc[0] = NULL ;
  663. X
  664. X  progname = argv[0] ;        /* Save this program name. */
  665. X
  666. X/*  Try to get location of the mp prologue file from an environment variable.
  667. X *  If it's not found, then use the default value.
  668. X */
  669. X
  670. X  if ((prologue = getenv("MP_PROLOGUE")) == NULL)
  671. X    prologue = PROLOGUE ;
  672. X  SPRINTF(proname, "%s/mp.pro.ps", prologue) ;
  673. X
  674. X  get_options(argc, argv) ;   /* Read and process command line options. */
  675. X
  676. X  if (argc - optind != 0) cmdfiles = 1 ;
  677. X  if (!cmdfiles)
  678. X    {
  679. X      fp = stdin ;                 /* Get input from standard input. */
  680. X      STRCPY(curfname, "stdin") ;
  681. X      printfile() ;                /* Pretty print *just* standard input. */
  682. X    }
  683. X  else
  684. X    for (; optind < argc; ++optind)
  685. X      {
  686. X        STRCPY(curfname, argv[optind]) ;    /* Current file to print. */
  687. X        if ((fp = fopen(curfname, "r")) == NULL)
  688. X          {
  689. X            FPRINTF(stderr, "%s: cannot open %s\n", progname, curfname) ;
  690. X            continue ;
  691. X          }
  692. X        pageno = 1 ;       /* Initialise current page number. */
  693. X        end_of_file = 0 ;  /* Reset in case there's another file to print. */
  694. X        tpn = 0 ;          /* Zeroise printed page count. */
  695. X        printfile() ;      /* Pretty print current file. */
  696. X      }
  697. X
  698. X  exit(0) ;
  699. X}
  700. X
  701. X
  702. Xprintfile()    /* Create PostScript to pretty print the current file. */
  703. X{
  704. X  readline() ;
  705. X  if (end_of_file)
  706. X    {
  707. X      FPRINTF(stderr, "mp: empty input file, nothing printed\n") ;
  708. X      exit(1) ;
  709. X    }
  710. X  if (!text_doc)
  711. X    parse_headers(FALSE) ;    /* Parse headers of mail or news article */
  712. X  init_setup() ;              /* Set values for remaining globals. */
  713. X  show_prologue(proname) ;    /* Send prologue file to output */
  714. X  set_defs() ;                /* Output initial definitions. */
  715. X  fputs("%%EndProlog\n", stdout) ;
  716. X/* Print the document */
  717. X  startpage() ;
  718. X  if (doc_type != DO_TEXT) show_headers(FALSE) ;
  719. X  while (!end_of_file)
  720. X    {
  721. X      if (folder && EQUAL(FROM_HDR))
  722. X        {
  723. X          linect = plen ;
  724. X          reset_headers() ;
  725. X          parse_headers(FALSE) ;
  726. X          show_headers(FALSE) ;
  727. X        }
  728. X      if (digest && (EQUAL(FROMHDR) || EQUAL(DATEHDR) || EQUAL(SUBJECTHDR)))
  729. X        {
  730. X          linect = plen ;
  731. X          parse_headers(TRUE) ;
  732. X          show_headers(TRUE) ;
  733. X        }
  734. X      textshow(nextline) ;
  735. X      readline() ;
  736. X    }    
  737. X  if (filofax || timeman) endfile() ;
  738. X  else endpage() ;
  739. X  FCLOSE(fp) ;
  740. X  fputs("%%Trailer\n", stdout) ;
  741. X  PRINTF("%%%%Pages: %1d\n", tpn) ;
  742. X}
  743. SHAR_EOF
  744. chmod 0444 main.c || echo "restore of main.c fails"
  745. set `wc -c main.c`;Sum=$1
  746. if test "$Sum" != "7091"
  747. then echo original size 7091, current size $Sum;fi
  748. echo "x - extracting misc.c (Text)"
  749. sed 's/^X//' << 'SHAR_EOF' > misc.c &&
  750. X
  751. X/*  @(#)misc.c 1.2 89/10/16
  752. X *
  753. X *  Copyright (c) Steve Holden and Rich Burridge.
  754. X *                All rights reserved.
  755. X *
  756. X *  Permission is given to distribute these sources, as long as the
  757. X *  copyright messages are not removed, and no monies are exchanged.
  758. X *
  759. X *  No responsibility is taken for any errors inherent either
  760. X *  to the comments or the code of this program, but if reported
  761. X *  to me then an attempt will be made to fix them.
  762. X */
  763. X
  764. X#include "mp.h"
  765. X#include "patchlevel.h"
  766. X#include "extern.h"
  767. X
  768. X
  769. Xvoid
  770. Xdo_date()        /* Output Postscript definition for the date and time. */
  771. X{
  772. X  long clock ;           /* Used by the localtime function call. */
  773. X  struct tm *tm ;        /* Used by the localtime and asctime calls. */
  774. X
  775. X  if (date == NULL)
  776. X    {
  777. X      clock = time((time_t *) 0) ;
  778. X      tm = localtime(&clock) ;
  779. X      psdef("TimeNow", asctime(tm)) ;
  780. X    }
  781. X  else psdef("TimeNow", date) ;
  782. X}
  783. X
  784. X
  785. Xget_opt(argc, argv, options)
  786. Xint argc ;
  787. Xchar **argv, *options ;
  788. X{
  789. X  char opch, *str, *ptr ;
  790. X  static int flag = 0 ;
  791. X  static int cur_argc ;
  792. X  static char **cur_argv ;
  793. X
  794. X  if (flag == 0)
  795. X    {
  796. X      cur_argc = argc ;
  797. X      cur_argv = argv ;
  798. X      flag = 1 ;
  799. X      optind = 1 ;
  800. X    }
  801. X
  802. X  if (cur_argc <= 1) return -1 ;
  803. X
  804. X  if (--cur_argc >= 1)
  805. X    {
  806. X      str = *++cur_argv ;
  807. X      if (*str != '-') return -1 ;    /* Argument is not an option   */
  808. X      else
  809. X        {                             /* Argument is an option */
  810. X          if ((ptr = strchr(options, opch = *++str)) != (char *) 0)
  811. X            {
  812. X              ++optind ;
  813. X              optarg = ++str ;        /* Point to rest of argument if any  */
  814. X              if ((*++ptr == ':') && (*optarg == '\0'))
  815. X                {
  816. X                  if (--cur_argc <= 0) return '?' ;
  817. X                  optarg = *++cur_argv ;
  818. X                  ++optind ;
  819. X                }
  820. X              return opch ;
  821. X            }
  822. X          else if (opch == '-')
  823. X            {                         /* End of options */
  824. X              ++optind ;
  825. X              return -1 ;
  826. X            }
  827. X          else return '?' ;
  828. X        }
  829. X    } 
  830. X  return 0 ;                          /* Should never be reached. */
  831. X}
  832. X
  833. X
  834. Xget_options(argc, argv)      /* Read and process command line options. */
  835. Xint argc ;
  836. Xchar *argv[] ;
  837. X{
  838. X  int opch ;
  839. X
  840. X  while ((opch = get_opt(argc, argv, "adfmop:s:tv")) != -1)
  841. X    switch (opch)
  842. X      {
  843. X        case 'a' : article = TRUE ;      /* "Article from" format. */
  844. X                   break ;
  845. X        case 'd' : digest = TRUE ;       /* Print digest. */
  846. X                   break ;
  847. X        case 'f' : filofax = TRUE ;      /* Print filofax file. */
  848. X                   SPRINTF(proname, "%s/mp.pro.filofax.ps", prologue) ;
  849. X                   break ;
  850. X        case 'm' : folder = TRUE ;       /* Print mail folder. */
  851. X                   break ;
  852. X        case 'o' : text_doc = TRUE ;     /* Print ordinary text file */
  853. X                   break ;
  854. X        case 'p' : if (strlen(optarg))
  855. X                     STRCPY(proname, optarg) ;  /* New prologue file. */
  856. X                   break ;
  857. X        case 's' : if (strlen(optarg))
  858. X                     subject = optarg ;         /* New subject line. */
  859. X                   break ;
  860. X        case 't' : timeman = TRUE ;     /* Print Time Manager file. */
  861. X                   SPRINTF(proname, "%s/mp.pro.timeman.ps", prologue) ;
  862. X                   break ;
  863. X        case 'v' : FPRINTF(stderr,
  864. X                           "%s version 2.3.%1d\n", progname, PATCHLEVEL) ;                         exit(1) ;
  865. X        case '?' : usage() ;
  866. X      }
  867. X}
  868. X
  869. X
  870. Xvoid
  871. Xinit_setup()            /* Set default values for various options. */
  872. X{
  873. X  char *c, *ptr ;
  874. X  int amp_cnt = 0 ;     /* Number of ampersands in gecos field. */
  875. X  int i, j, n, spaces ;
  876. X  struct passwd *pp ;
  877. X
  878. X  c = getlogin() ;      /* Pointer to users login name. */
  879. X  if (c == NULL)        /* Get username from password file */
  880. X    {
  881. X      pp = getpwuid(geteuid()) ;
  882. X      if (pp == NULL) c = "printing" ;
  883. X      else c = pp->pw_name ;
  884. X    }
  885. X  owner = malloc((unsigned) (strlen(c) + 1)) ;
  886. X  STRCPY(owner, c) ;
  887. X/*  Have a look for the users gecos (normally real name), so that its a bit
  888. X *  more recognisable. If this field is too long, then we need to truncate
  889. X *  sensibly. We also need to check a few things. If we've extracted
  890. X *  two "words" or have found a comma, then exit. If an ampersand is
  891. X *  found, this is expanded to the users name in capitals.
  892. X */    
  893. X     
  894. X  pp = getpwnam(owner) ;
  895. X  if (pp != NULL && pp->pw_gecos && pp->pw_gecos[0] != '\0')
  896. X    {  
  897. X      for (i = 0; i < strlen(pp->pw_gecos); i++)
  898. X        if (pp->pw_gecos[i] == '&') amp_cnt++ ;
  899. X      owner = malloc((unsigned) (strlen(pp->pw_gecos) +
  900. X                                 amp_cnt * strlen(c) + 1)) ;
  901. X
  902. X      n = spaces = 0 ;
  903. X      ptr = pp->pw_gecos ;
  904. X      for (i = 0; i < strlen(pp->pw_gecos); i++)
  905. X        {
  906. X               if (*ptr == ',') break ;
  907. X          else if (*ptr == '&')
  908. X            {
  909. X              for (j = 0; j < strlen(c); j++)
  910. X                if (islower(c[j])) owner[n++] = toupper(c[j]) ;
  911. X                else owner[n++] = c[j] ;
  912. X              *ptr++ ;
  913. X            }
  914. X          else if (*ptr == ' ')
  915. X            {
  916. X              if (++spaces == 2) break ;
  917. X              else owner[n++] = *ptr++ ;
  918. X            }
  919. X          else owner[n++] = *ptr++ ;
  920. X          if (n >= NAMELENGTH) break ;
  921. X        }
  922. X      if (n > NAMELENGTH) n = NAMELENGTH ;
  923. X      owner[n] = '\0' ;
  924. X    }
  925. X  if ((nameptr = getenv("NAME")) != NULL)
  926. X    STRCPY(owner, nameptr) ;
  927. X
  928. X  if (text_doc) doc_type = DO_TEXT ;
  929. X  switch (doc_type)
  930. X    {
  931. X      case DO_TEXT : message_for = "Listing for ";
  932. X                     digest = FALSE ;
  933. X                     break ;
  934. X      case DO_MAIL : message_for = digest ? "Mail digest for " : "Mail for " ;
  935. X                     break ;
  936. X      case DO_NEWS : message_for = digest ? "News digest for " : "News for " ;
  937. X                     break ;
  938. X    }
  939. X}
  940. X
  941. X
  942. Xusage()     /* Print usage message and exit. */
  943. X{
  944. X  FPRINTF(stderr,"Usage: %s [-a] [-d] [-f] [-m] ", progname) ;
  945. X  FPRINTF(stderr, "[-o] [-p prologue] [-s subject] [-t] [-v] [-?]\n") ;
  946. X  exit(1) ;
  947. X}
  948. X
  949. SHAR_EOF
  950. chmod 0444 misc.c || echo "restore of misc.c fails"
  951. set `wc -c misc.c`;Sum=$1
  952. if test "$Sum" != "6066"
  953. then echo original size 6066, current size $Sum;fi
  954. echo "x - extracting print.c (Text)"
  955. sed 's/^X//' << 'SHAR_EOF' > print.c &&
  956. X
  957. X/*  @(#)print.c 1.2 89/10/16
  958. X *
  959. X *  Copyright (c) Steve Holden and Rich Burridge.
  960. X *                All rights reserved.
  961. X *
  962. X *  Permission is given to distribute these sources, as long as the
  963. X *  copyright messages are not removed, and no monies are exchanged.
  964. X *
  965. X *  No responsibility is taken for any errors inherent either
  966. X *  to the comments or the code of this program, but if reported
  967. X *  to me then an attempt will be made to fix them.
  968. X */
  969. X
  970. X#include "mp.h"
  971. X#include "extern.h"
  972. X
  973. X
  974. Xboldshow(hdr, str)      /* Display a header all in bold. */
  975. Xchar *hdr, *str ;
  976. X{
  977. X  useline() ;
  978. X  fputs("BoldFont ", stdout) ;
  979. X  startline() ;
  980. X  expand(hdr) ;
  981. X  expand(str) ;
  982. X  endline() ;
  983. X}
  984. X
  985. X
  986. Xendfile()
  987. X{
  988. X  linect = 0 ;
  989. X  PRINTF("(%1d) endfile\n", pageno) ;
  990. X}
  991. X
  992. X
  993. Xendline()
  994. X{
  995. X  PRINTF(") showline\n") ;
  996. X}
  997. X
  998. X
  999. Xendpage()
  1000. X{
  1001. X  linect = 0 ;
  1002. X  PRINTF("(%1d) endpage\n", pageno++) ;
  1003. X}
  1004. X
  1005. X
  1006. Xexpand(s)   /* Display a string with PostScript-sensitive characters escaped */
  1007. Xchar *s ;
  1008. X{
  1009. X  for (; *s; s++)
  1010. X    {
  1011. X      switch (*s)
  1012. X        {
  1013. X          case '\\' : fputs("\\\\", stdout) ;
  1014. X                      break ;
  1015. X          case '('  : fputs("\\(", stdout) ;
  1016. X                      break ;
  1017. X          case ')'  : fputs("\\)", stdout) ;
  1018. X                      break ;
  1019. X          case '\b' : PUTC(*s, stdout) ;
  1020. X                      break ;
  1021. X          default   : if (isprint(*s)) PUTC(*s, stdout) ;
  1022. X        }
  1023. X    }
  1024. X}
  1025. X
  1026. X
  1027. Xmixedshow(hdr, str)     /* Display a header in mixed bold/Roman. */
  1028. Xchar *hdr, *str ;
  1029. X{
  1030. X  useline() ;
  1031. X  fputs("BoldFont ", stdout) ;
  1032. X  startline() ;
  1033. X  expand(hdr) ;
  1034. X  fputs(") show PrimaryFont (", stdout) ;
  1035. X  expand(str) ;
  1036. X  endline() ;
  1037. X}
  1038. X
  1039. X
  1040. Xpsdef(name, def)        /* Do a PostScript define. */
  1041. Xchar *name, *def ;
  1042. X{
  1043. X  PRINTF("/%s (", name) ;
  1044. X  expand(def) ;
  1045. X  PRINTF(") def\n") ;
  1046. X}
  1047. X
  1048. X
  1049. Xromanshow(str)          /* Display a header all in Roman. */
  1050. Xchar *str ;
  1051. X{
  1052. X  useline() ;
  1053. X  fputs("PrimaryFont ", stdout) ;
  1054. X  startline() ;
  1055. X  expand(str) ;
  1056. X  endline() ;
  1057. X}
  1058. X
  1059. X
  1060. Xvoid
  1061. Xset_defs()               /* Setup PostScript definitions. */
  1062. X{
  1063. X  int i ;
  1064. X
  1065. X  if (article == TRUE)
  1066. X    STRCPY(message_for, "Article from") ;             /* MailFor. */
  1067. X  psdef("MailFor", message_for) ;
  1068. X
  1069. X  if (article == TRUE && newsgroups != NULL)          /* User. */
  1070. X    {
  1071. X      for (i = 0; i < strlen(newsgroups); i++)
  1072. X        if (newsgroups[i] == ',' ||
  1073. X            newsgroups[i] == '\0') break ;
  1074. X      STRNCPY(owner, newsgroups, i) ;
  1075. X      owner[i] = '\0' ;
  1076. X    }
  1077. X  psdef("User", owner) ;
  1078. X  do_date() ;                                         /* TimeNow. */
  1079. X  if (text_doc && cmdfiles) STRCPY(subject, curfname) ;
  1080. X  psdef("Subject", subject) ;                         /* Subject. */
  1081. X}
  1082. X
  1083. X
  1084. X/* Display the PostScript prologue file for mp */
  1085. X                   
  1086. Xshow_prologue(pro)
  1087. Xchar *pro ;              /* Prologue file name */
  1088. X{
  1089. X  FILE *pf ;
  1090. X  char buf[MAXLINE], tmpstr[MAXLINE] ;
  1091. X  int t2 ;               /* Possible extract page or line length. */
  1092. X
  1093. X  if ((pf = fopen(pro, "r")) == NULL)                                
  1094. X    {
  1095. X      FPRINTF(stderr,"%s: Prologue file %s not found.\n",progname, pro) ;
  1096. X      exit(1) ;
  1097. X    }
  1098. X  while (fgets(buf, MAXLINE, pf) != NULL)
  1099. X    {
  1100. X      fputs(buf, stdout) ;
  1101. X/* Check for new line or page length. */
  1102. X      SSCANF(buf, "%s %d", tmpstr, &t2) ;
  1103. X      if (strcmp(tmpstr, "%%PageLength") == 0)
  1104. X        plen = t2 ;               /* Change the page length. */
  1105. X      else if (strcmp(tmpstr, "%%LineLength") == 0)
  1106. X        llen = t2 ;               /* Change the line length. */
  1107. X    }
  1108. X  FCLOSE(pf) ;
  1109. X}
  1110. X
  1111. X
  1112. Xstartline()
  1113. X{
  1114. X  PRINTF("(") ;
  1115. X}
  1116. X
  1117. X
  1118. Xstartpage()
  1119. X{
  1120. X  PRINTF("%%%%Page: ? %1d\n", ++tpn) ;
  1121. X  psdef("MailFor", message_for) ;
  1122. X  psdef("User", owner) ;
  1123. X}
  1124. X
  1125. X
  1126. Xtextshow(s)
  1127. Xchar *s ;
  1128. X{
  1129. X  useline() ;
  1130. X  fputs("SecondaryFont ", stdout) ;
  1131. X  startline() ;
  1132. X  expand(s) ;
  1133. X  endline() ;
  1134. X}
  1135. X
  1136. X
  1137. Xuseline()   /* Called in order to ready a line for printing. */
  1138. X{
  1139. X  if (++linect > plen || end_of_page == TRUE)
  1140. X    {
  1141. X      endpage() ;
  1142. X      linect = 0 ;
  1143. X      startpage() ;
  1144. X      psdef("Subject", subject) ;
  1145. X      do_date() ;
  1146. X    }
  1147. X}
  1148. SHAR_EOF
  1149. chmod 0444 print.c || echo "restore of print.c fails"
  1150. set `wc -c print.c`;Sum=$1
  1151. if test "$Sum" != "3992"
  1152. then echo original size 3992, current size $Sum;fi
  1153. echo "x - extracting extern.h (Text)"
  1154. sed 's/^X//' << 'SHAR_EOF' > extern.h &&
  1155. X
  1156. X/*  @(#)extern.h 1.1 89/10/16
  1157. X *
  1158. X *  Contains all the external definitions used by mp.
  1159. X *
  1160. X *  Copyright (c) Steve Holden and Rich Burridge.
  1161. X *                All rights reserved.
  1162. X *
  1163. X *  Permission is given to distribute these sources, as long as the
  1164. X *  copyright messages are not removed, and no monies are exchanged.
  1165. X *
  1166. X *  No responsibility is taken for any errors or inaccuracies inherent
  1167. X *  either to the comments or the code of this program, but if
  1168. X *  reported to me then an attempt will be made to fix them.
  1169. X */
  1170. X
  1171. Xextern char *APP_FROMHDR ;
  1172. Xextern char *APP_TOHDR ;
  1173. Xextern char *CCHDR ;
  1174. Xextern char *DATEHDR ;
  1175. Xextern char *FROMHDR ;
  1176. Xextern char *FROM_HDR ;          /* UNIX From header */
  1177. Xextern char *NEWSGROUPSHDR ;
  1178. Xextern char *REPLYHDR ;
  1179. Xextern char *SUBJECTHDR ;
  1180. Xextern char *TOHDR ;
  1181. X
  1182. Xextern char *apparently_from ;   /* Apparently_from: */
  1183. Xextern char *apparently_to ;     /* Apparently_to: */
  1184. Xextern char *cc[] ;              /* Cc: (can have multiple lines) */
  1185. Xextern char *date ;              /* Date: */
  1186. Xextern char *from ;              /* From: */
  1187. Xextern char *from_ ;             /* From_ (UNIX from) */
  1188. Xextern char *newsgroups ;        /* Newsgroups: (news articles only) */
  1189. Xextern char *reply_to ;          /* Reply-to: */
  1190. Xextern char *subject ;           /* Subject: (can be set from command line) */
  1191. Xextern char *to[] ;              /* To: (can have multiple lines) */
  1192. X
  1193. Xextern char curfname[] ;     /* Current file being printed. */
  1194. Xextern char *message_for ;   /* "[Mail,News,Listing] for " line */
  1195. Xextern char *nameptr ;       /* Used to getenv the NAME variable. */
  1196. Xextern char nextline[] ;     /* Read-ahead of the mail message, minus nl */
  1197. Xextern char *optarg ;        /* Optional command line argument. */
  1198. Xextern char *owner ;         /* Name of owner (usually equal to 'to') */
  1199. Xextern char *progname ;      /* Name of this program. */
  1200. Xextern char *prologue ;      /* Name of PostScript prologue file. */
  1201. Xextern char proname[] ;      /* Full pathname of the prologue file. */
  1202. X
  1203. Xextern int cmdfiles ;        /* Set if file to print given on command line. */
  1204. Xextern int linect ;          /* Line count on current page. */
  1205. Xextern int llen ;            /* Number of characters per line. */
  1206. Xextern int optind ;          /* Optional command line argument indicator. */
  1207. Xextern int pageno ;          /* Page number within message. */
  1208. Xextern int plen ;            /* Number of lines per page. */
  1209. Xextern int tpn ;             /* Total number of pages printed. */
  1210. X
  1211. Xextern bool article ;        /* Set for news in "Article from " format. */
  1212. Xextern bool digest ;         /* Are we are printing a mail digest (-d) */
  1213. Xextern bool filofax ;        /* Set if we are printing a filofax file. */
  1214. Xextern bool folder ;         /* Set if we are printing a mail folder. */
  1215. Xextern bool text_doc ;       /* Printing normal text (-o) */
  1216. Xextern bool timeman ;        /* Set if we are printing a Time Manager file. */
  1217. X
  1218. Xextern bool end_of_file ;    /* EOF indicator */
  1219. Xextern bool end_of_line ;    /* Is a newline removed from this line */
  1220. Xextern bool end_of_page ;    /* end-of-page indicator - ^L on input */
  1221. X
  1222. Xextern document_type doc_type ;  /* Printing type - default mail */
  1223. X
  1224. Xextern FILE *fp ;            /* File pointer for current file. */
  1225. SHAR_EOF
  1226. chmod 0444 extern.h || echo "restore of extern.h fails"
  1227. set `wc -c extern.h`;Sum=$1
  1228. if test "$Sum" != "3248"
  1229. then echo original size 3248, current size $Sum;fi
  1230. echo "x - extracting mp.h (Text)"
  1231. sed 's/^X//' << 'SHAR_EOF' > mp.h &&
  1232. X
  1233. X/*  @(#)mp.h 1.1 89/10/16
  1234. X *
  1235. X *  Contains all the global definitions used by mp.
  1236. X *
  1237. X *  Copyright (c) Steve Holden and Rich Burridge.
  1238. X *                All rights reserved.
  1239. X *
  1240. X *  Permission is given to distribute these sources, as long as the
  1241. X *  copyright messages are not removed, and no monies are exchanged.
  1242. X *
  1243. X *  No responsibility is taken for any errors or inaccuracies inherent
  1244. X *  either to the comments or the code of this program, but if
  1245. X *  reported to me then an attempt will be made to fix them.
  1246. X */
  1247. X
  1248. X#include <stdio.h>
  1249. X#include <sys/types.h>
  1250. X#include <sys/file.h>
  1251. X#include <sys/param.h>
  1252. X#include <ctype.h>
  1253. X#include <time.h>
  1254. X#include <pwd.h>
  1255. X
  1256. X#define  FCLOSE       (void) fclose
  1257. X#define  FPRINTF      (void) fprintf
  1258. X#define  PRINTF       (void) printf
  1259. X#define  PUTC         (void) putc
  1260. X#define  SPRINTF      (void) sprintf
  1261. X#define  SSCANF       (void) sscanf
  1262. X#define  STRCPY       (void) strcpy
  1263. X#define  STRNCPY      (void) strncpy
  1264. X#define  UNGETC       (void) ungetc
  1265. X
  1266. X/* Configuration constants */
  1267. X
  1268. X#ifndef  PROLOGUE            /* PostScript prologue file */
  1269. X#define  PROLOGUE     "/usr/local/lib"
  1270. X#endif   PROLOGUE
  1271. X
  1272. X#define  EQUAL(val)   (!strncmp(val, nextline, strlen(val)))
  1273. X#define  INC          argc-- ; argv++ ;
  1274. X#define  LINELENGTH   80     /* Number of characters per line. */
  1275. X#define  NAMELENGTH   18     /* Maximum allowable real user name. */
  1276. X#define  PAGELENGTH   60     /* Number of lines per page. */
  1277. X#define  MAXCONT      10     /* Maximum no of continuation header lines */
  1278. X#define  MAXLINE      256    /* Maximum string length. */
  1279. X#ifndef TRUE
  1280. X#define TRUE          1
  1281. X#define FALSE         0
  1282. X#endif  /*TRUE*/
  1283. Xtypedef enum {DO_MAIL, DO_NEWS, DO_TEXT} document_type ;
  1284. Xtypedef char bool ;
  1285. X
  1286. Xtime_t time() ;
  1287. Xstruct tm *localtime() ;
  1288. Xbool emptyline() ;
  1289. XFILE *fopen() ;
  1290. Xchar *asctime(), *getenv(), *getlogin(), *gets(), *index(), *malloc() ;
  1291. Xchar *sprintf(), *strchr(), *strcpy(), *strncpy() ;
  1292. X
  1293. Xvoid do_date(), get_header(), get_mult_hdr(), init_setup() ;
  1294. Xvoid parse_headers(), readline(), reset_headers(), set_defs() ;
  1295. Xvoid show_headers(), show_mult_hdr() ;
  1296. SHAR_EOF
  1297. chmod 0444 mp.h || echo "restore of mp.h fails"
  1298. set `wc -c mp.h`;Sum=$1
  1299. if test "$Sum" != "2089"
  1300. then echo original size 2089, current size $Sum;fi
  1301. echo "x - extracting patchlevel.h (Text)"
  1302. sed 's/^X//' << 'SHAR_EOF' > patchlevel.h &&
  1303. X/*  @(#)patchlevel.h 1.2 89/10/18
  1304. X *
  1305. X *  This is the current patch level for this version of mp.
  1306. X *
  1307. X *  Copyright (c) Steve Holden and Rich Burridge.
  1308. X *                All rights reserved.
  1309. X *
  1310. X *  Permission is given to distribute these sources, as long as the
  1311. X *  copyright messages are not removed, and no monies are exchanged.
  1312. X *
  1313. X *  No responsibility is taken for any errors or inaccuracies inherent
  1314. X *  either to the comments or the code of this program, but if
  1315. X *  reported to me then an attempt will be made to fix them.
  1316. X */
  1317. X
  1318. X#define  PATCHLEVEL  1
  1319. SHAR_EOF
  1320. chmod 0444 patchlevel.h || echo "restore of patchlevel.h fails"
  1321. set `wc -c patchlevel.h`;Sum=$1
  1322. if test "$Sum" != "557"
  1323. then echo original size 557, current size $Sum;fi
  1324. echo "x - extracting mailp (Text)"
  1325. sed 's/^X//' << 'SHAR_EOF' > mailp &&
  1326. X#! /bin/sh
  1327. X#
  1328. X#  @(#)mailp 1.5 89/06/28
  1329. X#
  1330. X#  mailp, newsp, filep, digestp, filofaxp and timemanp
  1331. X#  shell script de lancement de mp
  1332. X#  (mail/news/file/digest/filofax/time-manager pretty printer)
  1333. X#
  1334. X#  Original: Bruno Pillard - October 1988.
  1335. X#  Modified: Rich Burridge - June 1989.
  1336. X
  1337. XBIN=/usr/local/bin
  1338. X
  1339. Xcase $0 in
  1340. X    *mailp)    PROG=mp       ;; 
  1341. X    *newsp)       PROG=mp       ;;
  1342. X    *digestp)  PROG="mp -d"     ;;
  1343. X    *filep)       PROG="mp -o"  ;;
  1344. X    *filofaxp) PROG="mp -f      ;;
  1345. X    *timemanp) PROG="mp -t      ;;
  1346. X    *)    echo Unknown pretty printer: $0
  1347. X        exit;;
  1348. Xesac
  1349. X
  1350. Xif    [ $# -eq 0 ]
  1351. Xthen
  1352. X    set - " - "
  1353. Xfi
  1354. Xwhile [ $# -gt 0 ]
  1355. Xdo
  1356. X    /bin/cat $1 | ${BIN}/${PROG} | lpr -h -Plw
  1357. X    shift
  1358. Xdone
  1359. SHAR_EOF
  1360. chmod 0444 mailp || echo "restore of mailp fails"
  1361. set `wc -c mailp`;Sum=$1
  1362. if test "$Sum" != "655"
  1363. then echo original size 655, current size $Sum;fi
  1364. echo "x - extracting mp.1 (Text)"
  1365. sed 's/^X//' << 'SHAR_EOF' > mp.1 &&
  1366. X.\" @(#)mp.1 1.11 89/10/18
  1367. X.TH MP 1L "17 October 1989"
  1368. X.SH NAME
  1369. Xmp \- Postscript pretty printer
  1370. X.SH SYNOPSIS
  1371. X.B mp
  1372. X[
  1373. X.B \-a
  1374. X]
  1375. X[
  1376. X.B \-d
  1377. X]
  1378. X[
  1379. X.B \-f
  1380. X]
  1381. X[
  1382. X.B \-m
  1383. X]
  1384. X[
  1385. X.B \-o
  1386. X]
  1387. X[
  1388. X.B \-p
  1389. X.I prologue
  1390. X]
  1391. X[
  1392. X.B \-s
  1393. X.I subject
  1394. X]
  1395. X[
  1396. X.B \-t
  1397. X]
  1398. X[
  1399. X.B \-v
  1400. X]
  1401. X[
  1402. X.B \-?
  1403. X]
  1404. X[
  1405. X.IR filename .\|.\|.
  1406. X]
  1407. X.SH DESCRIPTION
  1408. X.B mp
  1409. Xwill read each
  1410. X.I filename
  1411. Xin sequence and generate a Postscript file on standard output,
  1412. Xwhich is a pretty print of the original. If no filename argument is given
  1413. X.B mp
  1414. Xreads from the standard input. If the standard input is a terminal, input
  1415. Xis terminated by an
  1416. X.SM EOF
  1417. Xsignal, usually
  1418. X.SM CTRL-D\s0.
  1419. X.LP
  1420. XThe input files to
  1421. X.B mp
  1422. Xcan be mail items, news articles or ordinary ASCII files. It is also
  1423. Xpossible to print out complete mail folders and digests.
  1424. X.LP
  1425. XThe format adopted has textured areas containing banner information
  1426. Xat the top and bottom of every page.
  1427. X.LP
  1428. X.B mp
  1429. Xwas originally designed to be used in conjunction with the print
  1430. Xbutton in the
  1431. X.B "mailtool (1)"
  1432. Xprogram, or the
  1433. X.B pipe
  1434. Xcommand from within mail. Add (or alter) the following two line in your
  1435. X.B .mailrc
  1436. Xfile:
  1437. X.in +1.0i
  1438. X.nf
  1439. X\fCset printmail='mp | lpr'
  1440. Xset cmd="mp | lpr &"\fP
  1441. X.fi
  1442. X.in -1.0i
  1443. X.LP
  1444. XSource the
  1445. X.B .mailrc
  1446. Xfile again, and you are ready.
  1447. X.LP
  1448. XA useful alias to use used in conjunction with your
  1449. X.I .cshrc
  1450. Xfile for printing out ordinary text files is:
  1451. X.in +1.0i
  1452. X.nf
  1453. X\fCalias print 'mp -o -s "\\!*" <\\!* | lpr'\fP
  1454. X.fi
  1455. X.in -1.0i
  1456. X.SH OPTIONS
  1457. X.TP
  1458. X.B \-a
  1459. XThe file on standard input is a news article, and should be printed with
  1460. X"Article from
  1461. X.I newsgroup
  1462. X" in the top banner, where
  1463. X.I newsgroup
  1464. Xis the first news group found on the Newsgroups: line.
  1465. X.TP
  1466. X.B \-d
  1467. XThe file on standard input is a digest so print accordingly.
  1468. X.TP
  1469. X.B \-f
  1470. XThe file on standard input is printed specifically was use with Filofax,
  1471. Xa personal organiser.
  1472. X.TP
  1473. X.B \-m
  1474. XThe file on standard input is a mail folder, so print out multiple messages.
  1475. X.TP
  1476. X.B \-o
  1477. XThe file on standard input is an ASCII file so print accordingly.
  1478. X.TP
  1479. X.BI \-p " prologue filename"
  1480. XEmploy
  1481. X.I "prologue filename"
  1482. Xas the Postscript prologue file. This overrides any previously defined
  1483. Xprologue values.
  1484. XThe
  1485. X.I mp
  1486. Xprologue file is determined by first looking for the environment variable
  1487. X.IR MP_PROLOGUE .
  1488. XThis will be the directory where the mp prologue files are to be found.
  1489. XThree different prologue files are used. Normally the prologue file is
  1490. X.I mp.pro.ps
  1491. Xbut if the
  1492. X-I \-f
  1493. Xoption is used, then the prologue file is called
  1494. X-I mp.pro.filofax.ps
  1495. Xand if the
  1496. X-I \-t
  1497. Xoption is used, then the prologue file is
  1498. X-I mp.pro.timeman.ps
  1499. XIf
  1500. X.I MP_PROLOGUE
  1501. Xisn't found, then the default location is used. The default location is
  1502. X.IR /usr/local/lib/mp.pro.ps .
  1503. X.TP
  1504. X.BI \-s " subject"
  1505. XUse
  1506. X.I " subject"
  1507. Xas the new subject for the printout. If you are printing ordinary text
  1508. Xfiles which have been specified on the command line, the the subject will
  1509. Xdefault to the name of each of these files.
  1510. X.TP
  1511. X.B \-t
  1512. XThe file on standard input is printed specifically for use with Time Manager,
  1513. Xa personal organiser.
  1514. X.TP
  1515. X.B \-v
  1516. XPrint the version number of this release of the
  1517. X.B mp
  1518. Xprogram.
  1519. X.TP
  1520. X.B \-?
  1521. XPrint the usage line for this program. Note that the
  1522. X.B ?
  1523. Xcharacter should be escaped if running from
  1524. X.BR csh (1).
  1525. X.SH FILES
  1526. X.TP
  1527. X.B /usr/local/bin/mp
  1528. Xexecutable
  1529. X.TP
  1530. X.B /usr/local/lib/mp.pro.ps
  1531. XPostScript prologue to define required vocabulary for mail printing.
  1532. SHAR_EOF
  1533. echo "End of part 1"
  1534. echo "File mp.1 is continued in part 2"
  1535. echo "2" > s2_seq_.tmp
  1536. exit 0
  1537.  
  1538.