home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume16 / plp / part14 < prev    next >
Text File  |  1988-09-14  |  44KB  |  2,059 lines

  1. Subject:  v16i027:  Public lineprinter spooler package, Part14/16
  2. Newsgroups: comp.sources.unix
  3. Sender: sources
  4. Approved: rsalz@uunet.UU.NET
  5.  
  6. Submitted-by: papowell@julius.cs.umn.edu
  7. Posting-number: Volume 16, Issue 27
  8. Archive-name: plp/part14
  9.  
  10. #! /bin/sh
  11. # This is a shell archive.  Remove anything before this line, then unpack
  12. # it by saving it into a file and typing "sh file".  To overwrite existing
  13. # files, type "sh file -c".  You can also feed this as standard input via
  14. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  15. # will see the following message at the end:
  16. #        "End of archive 14 (of 16)."
  17. # Contents:  doc/PLP/02.t src/banner.c
  18. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  19. if test -f 'doc/PLP/02.t' -a "${1}" != "-c" ; then 
  20.   echo shar: Will not clobber existing file \"'doc/PLP/02.t'\"
  21. else
  22. echo shar: Extracting \"'doc/PLP/02.t'\" \(19343 characters\)
  23. sed "s/^X//" >'doc/PLP/02.t' <<'END_OF_FILE'
  24. X.ig
  25. X$Header: 02.t,v 1.1 88/05/21 18:39:32 papowell Locked $
  26. X$log$
  27. X..
  28. X.NH 1
  29. PLP Programs
  30. X.PP
  31. The following section outlines the operation of the
  32. X.IR lpd \|(8)
  33. line printer
  34. X.IR daemon ,
  35. and the
  36. X.IR lpr \|(1),
  37. X.IR lpq \|(1),
  38. X.IR lprm \|(1),
  39. and
  40. X.IR lpc \|(1)
  41. utility programs.
  42. X.NH 2
  43. lpd \- Line Printer Dameon Program
  44. X.PP
  45. The 
  46. X.IR lpd \|(8)
  47. program is usually invoked at boot time from the
  48. X.L /etc/rc
  49. or
  50. X.L /etc/rc.local
  51. startup file,
  52. and acts as a server or
  53. X.I daemon
  54. for coordinating and controlling
  55. the spooling queues configured in the printcap file.
  56. XFigure 2.1 is a typically  used to start the
  57. X.I lpd
  58. daemon.
  59. X.KF
  60. X.in +1i
  61. X.L
  62. X.SM
  63. X.nf
  64. X.ta 4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n +4n 8i
  65. X# Start up the lpd daemon
  66. if [ -f /usr/lib/lpd ]; then
  67. X    /usr/lib/lpd & (echo -n ' printer')  >/dev/console
  68. X.LG
  69. X.in -1i
  70. X.R
  71. X.ce
  72. XFigure 2.1  Startup File Command for LPD
  73. X.KE
  74. X.PP
  75. When
  76. X.I lpd
  77. is started,
  78. it checks to see if there is an active
  79. X.I lpd
  80. daemon already running by trying to lock the
  81. X.L /usr/spool/lpd.lock
  82. file using the
  83. X.IR flock \|(2)
  84. or
  85. X.IR lockf \|(3)
  86. facilities.
  87. If no daemon is present,
  88. X.I lpd
  89. forks a server process for each non-empty spool queue in the
  90. X.IR printcap \|(5)
  91. data base,
  92. and then listens for service requests on specific
  93. Internet domain port.
  94. The Internet port name is found using the
  95. X.IR getservbyname \|(3)
  96. facility to get the
  97. X.I printer
  98. service information.
  99. The
  100. X.I "Advanced Tuturial on Interprocess Communications"
  101. distributed with the Berkeley UNIX 4.3 BSD 
  102. X(and reprinted by SUN Microsystems) provides an excellent
  103. tutorial on interprocess communications.
  104. See  the manual pages for
  105. X.IR socket \|(2)
  106. and 
  107. X.IR services \|(5)
  108. for more information on sockets and service specifications.
  109. X.PP
  110. When a connection is made to the 
  111. X.I lpd
  112. port by a requesting process (usually called a client),
  113. X.I lpd
  114. forks a server process to carry out the request and
  115. continues to listen for new requests.
  116. The Table 2.1 shows the requests
  117. understood by
  118. X.IR lpd .
  119. The first byte of a request is a binary number
  120. specifying the request type,
  121. and the following characters up to a terminating a new line ('\en') character
  122. are the request.
  123. X.KF
  124. X.TS
  125. box center;
  126. l | l.
  127. Request    Interpretation
  128. X_
  129. X^Aprinter\en    start a server for the queue
  130. X^Bprinter\en    receive and queue a job from another host
  131. X^Cprinter [users ...] [jobs ...]\en    return short form of printer queue status
  132. X^Dprinter [users ...] [jobs ...]\en    return long form of printer queue status
  133. X^Eprinter person [users ...] [jobs ...]\en    remove jobs from a queue
  134. X^Fperson command [printers]\en    perform lpc control function
  135. X.TE
  136. X.R
  137. X.ce 1
  138. Table 2.1 LPD Request Message Format
  139. X.KE
  140. X.PP
  141. After reading the request,
  142. the server process will the printer permissions file to
  143. determine if the originating host
  144. has permissions to access the specified printer.
  145. Next,
  146. the
  147. X.I printcap
  148. data base is scanned
  149. determine the set of options and restrictions that apply to the
  150. spool queue or printer.
  151. XFinally,
  152. the server will use this information to perform the requested action.
  153. X.PP
  154. In response to a
  155. start printer message,
  156. the server process will check to see if a server is present,
  157. and if not,
  158. will undertake to start unspooling activities.
  159. The two forms of status requests will cause the server to check the
  160. spool queue and report on the current activities.
  161. X.PP
  162. The file transfer request will cause the server and client process to start
  163. transferring control and data files that make up a print job.
  164. This activity is described in detail in Section 5.
  165. The remove job request will cause the server to check that the user has
  166. suitable permissions for the particular queue,
  167. and will then remove the specified jobs.
  168. X.PP
  169. The control request will cause the server to perform control functions
  170. similar to the
  171. X.I lpd
  172. program.
  173. This function allows control over spooling operations to be done using the
  174. X.I lpc
  175. program on a remote host.
  176. X.NH 3
  177. Security Issues In a Networked Environment
  178. X.PP
  179. The permissions and restriction checks
  180. performed by
  181. X.I lpd
  182. are based on the assumption that the client host machine is
  183. well known by the network support software,
  184. and that the process originating a request authenticates
  185. the user requesting the service.
  186. The port from which the client request can be originated
  187. is restricted to a value which is reserved for users with system or
  188. X.I "superuser"
  189. permissions.
  190. In a UNIX environment,
  191. this means that the originating program must be running
  192. X.I setuid
  193. X(SUID)
  194. X.I root
  195. or the originating user is
  196. X.IR root .
  197. X.PP
  198. In an environment where users can implement their own support for
  199. TCP/IP facilities,
  200. these security checks may not be sufficient.
  201. In fact,
  202. given access to the network communications hardware,
  203. it is possible to forge messages that appear to be originating
  204. from any valid site.
  205. The problem of authentication of request is currently open;
  206. as part of the PLP development a facility for
  207. network wide authentication is under development.
  208. X.NH 3
  209. Spool Queue Access and Permissions
  210. X.PP
  211. As discussed in the previous section,
  212. there are problems in controlling access to the PLP software by
  213. clients on remote hosts.
  214. As a preliminary step towards a more general authentication
  215. procedure,
  216. PLP uses a
  217. X.I printer_perms
  218. or printer permissions file contains a list of machines,
  219. users,
  220. spool queues and associated privileges.
  221. Authentication of remote hosts is based on the network connection information
  222. provided by the
  223. X.IR gethostent \|(3N)
  224. networking function.
  225. In the future,
  226. authentication of this information will be done
  227. before using it to determine associated PLP capabilities.
  228. X.KF
  229. X.L
  230. X.SM
  231. X.TS
  232. tab(:) center box;
  233. l s s s s s s s
  234. l l l l l l l l.
  235. X# -- Line printer permissions
  236. X# host:name:queue:Ops:Pr:Max:Done:#Comment
  237. X~*.umn.edu:*:*:C:A:0:0:# filter out non-local sites
  238. central.*.umn.edu:root:*:C:A:0:0:# root@central can do anything
  239. X*.umn.edu:root:lp:C:A:0:100:# root@* can access lp, priority A
  240. server.adm.umn.edu:admin:lp:R:C:1000:200:# admin@server, lp priority C
  241. X!*:CS*:laser*:R:Z:*:*:# CS accounts, no laser queues
  242. X*.umn.edu:*:lp:R:Z:*:*:# the great unwashed have priority Z
  243. X.TE
  244. X.LG
  245. X.R
  246. X.ce
  247. Table 2.2 Example Printer Permissions File
  248. X.KE
  249. X.PP
  250. XEach entry in the printer permissions file specifies a host machine,
  251. a userid,
  252. a printer or spool queue name,
  253. a set of operations (R or C),
  254. a maximum priority (A-Z),
  255. and a maximum and current page counts associated with use of a spool queue.
  256. Blank lines and lines that start with
  257. X.L #
  258. X(comment) are ignored.
  259. XFields are separated with one or more spaces or tabs.
  260. There is a simple wildcard match facility similar to the UNIX
  261. shell metacharacter match.
  262. The
  263. X.L *
  264. character will match 0 or more characters in the string,
  265. and the
  266. X.L ?
  267. will match exactly one character.
  268. Lines that start with a ! (not) indicate that permissions are
  269. denied for queries that would otherwise match.
  270. X.PP
  271. Given a host,
  272. user,
  273. and spool queue,
  274. the printer permissions file is searched for a matching entry in
  275. first line to last line,
  276. left to right order.
  277. The host,
  278. user,
  279. and spool queue fields are checked for a match;
  280. the first line found which matches these will terminate the search.
  281. If an tilde
  282. X.B (~)
  283. is first character on the line,
  284. the fields are checked for a match.
  285. If the match fails,
  286. then permissions are refused.
  287. If the match succeeds,
  288. then further searching will be done.
  289. This facility allows only sites with suitable path names,
  290. etc.,
  291. to have access to a spool queue.
  292. If an exclamation mark
  293. X.B (!)
  294. is first character on the line,
  295. all permissions are refused;
  296. this allows
  297. X.I filtering
  298. out request that are to be rejected in a simple manner.
  299. If this facility is used,
  300. entries should be ordered so that refusals
  301. X(starting with !) precede any matching entries.
  302. X.PP
  303. XFor example,
  304. the printer permissions file in Table 2.1 allows
  305. X.L root
  306. on host
  307. X.L central
  308. X(i.e.-
  309. X.L root@central )
  310. to access all queues,
  311. X.L root
  312. on any machine to access the lp queue,
  313. and
  314. X.L admin
  315. on 
  316. X.L server
  317. to access the lp queue.
  318. Userids starting with CS are denied permission to use
  319. spool queues whose names start with laser.
  320. Note that the host name used for checking is the full name returned by the
  321. X.I gethostent (3N)
  322. function.
  323. X.PP
  324. Spool queue operations,
  325. spooling priorities,
  326. and other information are set by the matching line.
  327. The 
  328. X.I Ops
  329. field controls the allowed operations;
  330. a
  331. X.L C
  332. value stands for Control,
  333. and means that the user has permissions to use the LPC and LPRM
  334. programs to manage a queue as well as spool jobs to the queue.
  335. An
  336. X.L R
  337. value stands for LPR,
  338. and means that the user can only spool to the queue and remove his own jobs.
  339. Control functions can be exercised from remote hosts
  340. using the
  341. X.I remote
  342. command of the
  343. X.I lpc
  344. program.
  345. X.PP
  346. The Priority field determines the maximum priority available to a user.
  347. Users can prioritize jobs;
  348. the default is
  349. X.B Z ,
  350. or lowest priority,
  351. and the highest is
  352. X.B A .
  353. X.PP
  354. The maximum and current page count fields are used for accounting
  355. and other purposes.
  356. They are checked when a job is queued by
  357. X.I lpr
  358. and when the job is unqueued for printing.
  359. If the current maximum page count is exceeded by the user,
  360. the job will be refused.
  361. X.PP
  362. The
  363. server process checks the printer permissions file to determine if a
  364. requesting host is allowed access to a particular queue;
  365. if so,
  366. it will perform the requested actions as detailed in the following sections.
  367. X.NH 3
  368. Unspooler Servers
  369. X.PP
  370. During initialization and in response to
  371. X.I "start printer"
  372. requests,
  373. X.I lpd
  374. forks an
  375. unspooler or server process that processes jobs in the spool queue.
  376. Jobs are placed in the spool queue by
  377. X.I lpr
  378. or are transferred from a remote site and removed by the server process.
  379. XEach spool queue has a
  380. X.I lock
  381. file which is used to control spooling and unspooling activities.
  382. The lock file
  383. X.I owner ,
  384. X.I group
  385. and
  386. X.I execute
  387. permissions are used to control spooling and unspooling actions;
  388. if the owner execute permission is set then unspooling is disabled
  389. and if the group execute permission is set then spooling is disabled.
  390. If unspooling is enabled,
  391. the server tries to lock the
  392. X.I lock
  393. file;
  394. if it cannot  be locked,
  395. then another server is active and the process will exit.
  396. X.PP
  397. Once the server has gained control of the queue,
  398. it finds the entries in the queue,
  399. sort them in order of priority and time,
  400. and then unspools them according to specifications in the
  401. X.I printcap
  402. file.
  403. When a job unspooled,
  404. the server will lock the job's control file
  405. in order to prevent other processes from manipulating the job.
  406. If it cannot lock the control file,
  407. then the job is currently being manipulated by another PLP
  408. program and the server will process another job in the queue.
  409. X.NH 3
  410. Local Printer Queues
  411. X.PP
  412. If the spool queue is for a local printer
  413. X(a printer attached to the host processor),
  414. then the server process will print the job
  415. according to specifications in the
  416. X.I printcap
  417. file.
  418. The printcap file specify
  419. the physcial printer device,
  420. any serial line characteristics which need to be set,
  421. and any
  422. X.I filter
  423. programs  used to print the job.
  424. X.NH 3
  425. Remote Printer Queues
  426. X.PP
  427. If the spool queue is for a printer attached to another host,
  428. the server attempts to connect to the remote host and transfer the
  429. jobs in the spool queue to the remote host.
  430. If the file system used to
  431. store the job is flagged as being shared by the local host and the
  432. remote host,
  433. then it is not neccessary to transfer files
  434. but only to inform the remote host that there are jobs in the spool queue.
  435. X.NH 3
  436. Multiple Printers For a Spool Queue
  437. X.PP
  438. If there are multiple unspooling devices or printers for a local queue,
  439. the server process checks to see if unspooling is enabled,
  440. and then forks individual unspooler process for each printer.
  441. The printer processes will read the printcap entry controlling
  442. the individual actions of each printer,
  443. and then check the status of a printer lock file which controls the
  444. action of the printer.
  445. Thus,
  446. individual printers can be enabled or disabled
  447. as well as the entire spool queue.
  448. X.NH 2
  449. lpr \- Job Submission Program
  450. X.PP
  451. The
  452. X.I lpr (1)
  453. program is used to place a print job in a spool queue
  454. and to then send a
  455. X.I "start printer"
  456. message to the 
  457. X.I lpd
  458. process.
  459. The
  460. X.I lpd
  461. process is then responsible for printing the job or forwarding it to
  462. the correct destination.
  463. X.PP
  464. The
  465. X.I lpr
  466. program uses the
  467. printcap database to determine the actions required for spooling a job.
  468. Spooling is enabled by the state of the spool queue lock file
  469. permissions;
  470. if the owner permission is set,
  471. then spooling is disabled.
  472. X.PP
  473. Permission to use a spool queue is determined by using the
  474. printer permissions file.
  475. X.I Lpr
  476. will determine the user name
  477. X(by using the
  478. X.I getuid (2)
  479. and
  480. X.I getpwent(3)
  481. functions),
  482. and then searches the
  483. printer permission file to see if the user
  484. can submit jobs to the spool queue (has R or C privileges).
  485. If the user can use the spool queue,
  486. X.I lpr
  487. will then copy the users files to the spool queue.
  488. On systems that support symbolic links,
  489. X.I lpr
  490. can make symbolic links to the original files
  491. rather than copying them.
  492. After copying a file,
  493. X.I lpr
  494. can be requested to remove the file.
  495. Note that there are security loopholes in the use of the last two
  496. facilities that restrict their use only to trusted users.
  497. X.PP
  498. Before a job is placed in the spool queue,
  499. it may be desirable to do some local processing or prefiltering of the files.
  500. XFor example,
  501. running a formatter such as
  502. X.IR pr ,
  503. translating a typesetter format file into a different form,
  504. etc,
  505. can be done by lpr.
  506. These actions are controlled by
  507. X.I prefilter
  508. information specified in the printcap entry for the spool queue.
  509. X.PP
  510. Associated with each job is a format
  511. that specifies how the job is to be processed.
  512. XFor example,
  513. the
  514. X.B f
  515. format is the default format,
  516. and is used when files contain printable information.
  517. XEach format can have a
  518. prefilter that is to be applied to the job before it is placed in the
  519. spool queue.
  520. The prefilter facility is 
  521. usually used when files must have some further form of processing carried out,
  522. but the remote site where they are to be printed cannot perform
  523. the processing.
  524. X.PP
  525. Once the job has been placed in a queue,
  526. lpr will request the lpd daemon to start a spool queue server.
  527. X.NH 2
  528. lpq \- Spool Queue Status Display
  529. X.PP
  530. The
  531. X.IR lpq \|(1)
  532. program displays the status and contents of selected spool queues.
  533. X.I Lpq
  534. has two forms of output:
  535. the (default) long format which displays a complete summary of
  536. the current spool queue activities,
  537. and a short format which simply lists the jobs that are outstanding,
  538. The output format of
  539. X.I lpq
  540. is extraordinarily verbose,
  541. and attempts to give a full picture of the total state of the line printer
  542. and its associated queues,
  543. servers,
  544. and other information.
  545. The following is an example of the output produced by
  546. X.I lpq
  547. when displaying the status of a remote spool queue.
  548. X.DS
  549. X.L
  550. X.SM
  551. X.nf
  552. Printer 'diablo' (julius.cs.umn.edu):
  553. X  processing, active job started Wed May 11 15:20:54 1988, attempt 1
  554. X  Rank Owner       Pr Job Host        Files                Size
  555. active root        A  15  julius      /tmp/test5           132
  556. X   2nd root        Z  14  julius      /tmp/test2           15
  557. Remote printer 'lp2' (umn-cs.cs.umn.edu):
  558. Warning: no server present
  559. X  work done at Wed May 11 15:16:43 1988
  560. X  Rank Owner       Pr Job Host        Files                Size
  561. X   1st root        Z  13  julius      /tmp/test3           30
  562. X   2nd root        Z  14  julius      /tmp/test4           9
  563. X.LG
  564. X.DE
  565. X.PP
  566. The first line identifies the name of the local printer,
  567. and the host.
  568. It is followed by an informative message generated by the currently active
  569. server process,
  570. which is transferring a file to the remote site.
  571. Next is a list of the files in the local queue,
  572. ranked according to their processing order.
  573. The next line identifies the remote printer and site.
  574. The warning message indicates that no server process is present,
  575. even though there are jobs in the spool queue.
  576. This is a transitory condition,
  577. because the server process will be started as soon as the file transfers
  578. are completed.
  579. X.DS
  580. X.L
  581. X.SM
  582. X.nf
  583. imagen_lind27: 0 jobs
  584. imagen_ld27: 3 jobs
  585. X1 cfZ022julius: root
  586. X2 cfZ023julius: root
  587. X3 cfZ024julius: root
  588. X.LG
  589. X.DE
  590. The short form of status display 
  591. illustrated above merely gives a summary of the numbers of jobs
  592. and their order in the queue.
  593. X.NH 2
  594. lprm \- remove jobs from a queue
  595. X.PP
  596. The
  597. X.IR lprm \|(1)
  598. command deletes jobs from a spooling queue.
  599. If necessary,
  600. X.I lprm
  601. will kill off a server process which is working on the job.
  602. After removing any files,
  603. it will then restart the queue by sending a request to the lpd daemon.
  604. X.I Lprm
  605. will lock a job control file before removing the job,
  606. preventing a server from trying to unspool the job while it is being removed.
  607. X.PP
  608. If a user can submit jobs to a queue,
  609. he can remove jobs that he has submitted.
  610. The root or superuser for a host can remove any job submitted from
  611. a particular host.
  612. XFinally,
  613. the printer permission file will allow any use with control permissions for
  614. a spool queue to remove any job from the spool queue.
  615. X.NH 2
  616. lpc \- line printer control program
  617. X.PP
  618. The
  619. X.IR lpc \|(1)
  620. program is used to monitor and control the
  621. operation of the Line Printer Software
  622. by manipulating the status of  spool queue lock files,
  623. and killing active servers.
  624. It can send messages to PLP daemons requesting that
  625. they carry out similar actions,
  626. controlling both local and remote PLP daemons.
  627. It is not necessary to log onto a remote machine to perform control
  628. actions,
  629. as long as the printer permissions file has the appropriate entries.
  630. The
  631. X.I lpc
  632. program has the following commands.
  633. Unless specified as unpriviledged,
  634. they can only be used by a user with control permissions for the specified
  635. spool queue,
  636. and on the current or local host machine.
  637. X.I All
  638. or individual queues can be operated on.
  639. X.IP "disable/enable [queue* | all]" 3
  640. Disable or enable spooling to list of queues or  all queues.
  641. X.IP "start/restart/stop [queue* | all]" 3
  642. The start command enables  unspooling from a queue,
  643. and starts a server;
  644. restart is unprivileged and simply request the
  645. X.I lpd
  646. process to start a server.
  647. The stop command disables any further unspooling.
  648. X.IP "abort/kill [queue* | all]" 3
  649. The abort command does a stop,
  650. and then kills off any server process that is active for the queue.
  651. The kill command does an abort followed by a start;
  652. this last command is handy for restarting a queue whose server process
  653. is hung due to problems with a job or hardware.
  654. X.IP "status [queue*]" 3
  655. Display a short form of status information about the spool queues.
  656. The following is a typical status report.
  657. X.DS
  658. X.SM
  659. X.L
  660. X.nf
  661. Queue          Jobs    Queueing     Printing
  662. imagen_lind27     1    enabled      enabled (server 15817, job cfZ025julius)
  663. X  checking queue at Thu May 12 11:19:22 1988
  664. diablo_lind136    0    enabled      enabled 
  665. X  work done at Wed May 11 15:21:04 1988
  666. X.LG
  667. X.DE
  668. X.IP "topq queue [job*]" 3
  669. Rearrange the order of jobs in a spool queue,
  670. placing specified jobs at the head of the queue.
  671. X.IP "lprm queue [job*]" 3
  672. Use lprm to remove a job from the specified queue.
  673. X.IP "lpq [parms*]" 3
  674. Use lpq to display queue status.
  675. X.IP "lpd\ \ \ " 3
  676. Report the status of the lpd daemon.
  677. This is useful when you wish to monitor the status of the daemon process.
  678. X.IP "remote {command}" 3
  679. Perform the command for the specified spool queue at the remote host.
  680. The start,
  681. stop,
  682. abort,
  683. etc.,
  684. commands will be executed by the remote
  685. X.I lpd
  686. daemon.
  687. This command is useful for network wide management of the PLP spooler.
  688. END_OF_FILE
  689. if test 19343 -ne `wc -c <'doc/PLP/02.t'`; then
  690.     echo shar: \"'doc/PLP/02.t'\" unpacked with wrong size!
  691. fi
  692. # end of 'doc/PLP/02.t'
  693. fi
  694. if test -f 'src/banner.c' -a "${1}" != "-c" ; then 
  695.   echo shar: Will not clobber existing file \"'src/banner.c'\"
  696. else
  697. echo shar: Extracting \"'src/banner.c'\" \(21457 characters\)
  698. sed "s/^X//" >'src/banner.c' <<'END_OF_FILE'
  699. X/***************************************************************************
  700. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  701. X ***************************************************************************
  702. X * MODULE: banner.c
  703. X ***************************************************************************
  704. X * Revision History: Fri Jan 15 12:13:50 CST 1988
  705. X * $Log:    banner.c,v $
  706. X * Revision 3.1  88/06/18  09:36:50  papowell
  707. X * Version 3.0- Distributed Sat Jun 18 1988
  708. X * 
  709. X * Revision 3.1  88/06/18  09:30:10  papowell
  710. X * Version 3.0- Distributed Sat Jun 18 1988
  711. X * 
  712. X * Revision 2.1  88/05/09  10:07:30  papowell
  713. X * PLP: Released Version
  714. X * 
  715. X * Revision 1.5  88/05/05  20:09:07  papowell
  716. X * Modified short banner format
  717. X * 
  718. X * Revision 1.4  88/04/21  21:51:21  papowell
  719. X * Removed spurious line feeds
  720. X * 
  721. X * Revision 1.3  88/03/25  14:58:55  papowell
  722. X * Debugged Version:
  723. X * 1. Added the PLP control file first transfer
  724. X * 2. Checks for MX during file transfers
  725. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  726. X *     apparently they open files and then assume that they will stay
  727. X *     open.
  728. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  729. X * 
  730. X * Revision 1.2  88/03/05  15:01:32  papowell
  731. X * Minor Corrections,  Lint Problems
  732. X * 
  733. X * Revision 1.1  88/03/01  11:08:11  papowell
  734. X * Initial revision
  735. X * 
  736. X * banner printing routine.
  737. X * some of the code (the tables for the banner headers) was stolen from the
  738. X * old LPD program.  But this in turn was snarfed from a banner
  739. X * printing games program.  Which snarfed it from an old card deck... etc.
  740. X *
  741. X ***************************************************************************/
  742. X#ifndef lint
  743. static char id_str1[] =
  744. X    "$Header: banner.c,v 3.1 88/06/18 09:36:50 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  745. X#endif lint
  746. X
  747. X#include "lp.h"
  748. X
  749. X/*
  750. X * Print a banner
  751. X * The large character fonts have been stolen from the
  752. X * BANNER program, which stole them from an old card deck...
  753. X * 
  754. X * banner( fd )
  755. X * will print the banner
  756. X * 1. form feed if needed
  757. X * 2. print banner
  758. X * 3. another form feed
  759. X */
  760. X#define HEIGHT  9       /* height of representation of characters */
  761. X#define WIDTH   8       /* width of characters */
  762. X#define DROP    3       /* offset to drop characters with descenders */
  763. X#define BLAST   10      /* 10 lines to separate things */
  764. X#define SEP     3       /* 3 lines to separate BLAST from printing */
  765. X
  766. static int linecnt;
  767. static int fail;
  768. extern char chartable[][HEIGHT];
  769. static char *bline;
  770. static unsigned blen;
  771. static int fd;
  772. X
  773. int
  774. banner( pr )
  775. X    int pr;
  776. X{
  777. X    linecnt = 0;
  778. X    /*
  779. X     * print the banner
  780. X     */
  781. X
  782. X    fd = pr;
  783. X    fail = 0;
  784. X    if( bline == 0 ){
  785. X        blen = BUFSIZ;
  786. X        if( (bline = malloc( blen )) == 0 ){
  787. X            logerr_die( XLOG_INFO, "banner: malloc failed" );
  788. X        }
  789. X    }
  790. X    if( blen < PW+1 ){
  791. X        blen = PW+2;
  792. X        if( (bline = realloc( bline, blen )) == 0 ){
  793. X            logerr_die( XLOG_INFO, "banner: realloc failed" );
  794. X        }
  795. X    }
  796. X    if( SB ) {
  797. X        shortbanner();
  798. X    } else {
  799. X        longbanner();
  800. X    }
  801. X    if(Debug>4)log( XLOG_DEBUG, "banner: printed, fail %d", fail);
  802. X    if( fail ){
  803. X        return( JFAIL );
  804. X    } else {
  805. X        return( JSUCC );
  806. X    }
  807. X}
  808. X
  809. X/*
  810. X * shortbanner
  811. X * single line, has format:
  812. X * adobe:shore  Job: test.data  Date: Tue Sep 18 16:22:33 1984
  813. X */
  814. shortbanner()
  815. X{
  816. X    (void)sprintf(bline, "%s:%s Job: %s Date: %s", LOGNAME, FROMHOST, JOBNAME, Time_str());
  817. X    Out_line();
  818. X}
  819. X/*
  820. X * userinfo
  821. X * just print the information
  822. X */
  823. userinfo()
  824. X{
  825. X    (void)sprintf(bline, "User: %s@%s", LOGNAME, FROMHOST);
  826. X    Out_line();
  827. X    (void)sprintf(bline, "Name: %s", BNRNAME);
  828. X    Out_line();
  829. X    (void)sprintf(bline, "Date: %s", Time_str());
  830. X    Out_line();
  831. X    (void)sprintf(bline, "Job: %s", JOBNAME );
  832. X    Out_line();
  833. X    (void)sprintf(bline, "Class: %s", CLASSNAME );
  834. X    Out_line();
  835. X}
  836. X/*
  837. X * long banner
  838. X * get fancy and print separators, etc.
  839. X */
  840. longbanner()
  841. X{
  842. X    int i;            /* ACME integers, INC */
  843. X
  844. X    for( i = 0; i < BLAST; ++i ){
  845. X        breakline( '*');
  846. X    }
  847. X    for( i = 0; i < SEP; ++i ){
  848. X        breakline( 0 );
  849. X    }
  850. X    /*
  851. X     * print the Name and Host in BIG letters
  852. X     */
  853. X    bigprint( LOGNAME);
  854. X    bigprint( FROMHOST);
  855. X    userinfo();
  856. X    for( i = 0; i < SEP; ++i ){
  857. X        breakline( 0);
  858. X    }
  859. X    if( PL > 0 ){
  860. X        /* separator from banner */
  861. X        while( (linecnt + BLAST) % PL ){
  862. X            breakline( 0 );
  863. X        }
  864. X        /* page bottom marker */
  865. X        while(  linecnt % PL ){
  866. X            breakline( '*' );
  867. X        }
  868. X    }
  869. X}
  870. X
  871. breakline( c )
  872. X    int c;
  873. X{
  874. X    int    i;    /* ACME Integers, Inc. */
  875. X
  876. X    i = 0;
  877. X    if( c ){
  878. X        for( i = 0; i < PW; ++i ){
  879. X            bline[i] = c;
  880. X        }
  881. X    }
  882. X    bline[i] = 0;
  883. X    Out_line();
  884. X}
  885. X
  886. X/***************************************************************************
  887. X * bigprint( char * line )
  888. X * print the line in big characters 
  889. X * for i = topline to bottomline do
  890. X *  for each character in the line do
  891. X *    get the scan line representation for the character
  892. X *    foreach bit in the string do
  893. X *       if the bit is set, print X, else print ' ';
  894. X *      endfor
  895. X *  endfor
  896. X * endfor
  897. X ***************************************************************************/
  898. X
  899. bigprint( line )
  900. X    char *line;
  901. X{
  902. X    int i, j;        /* ACME Integers, Inc. */
  903. X    int cnt;        /* number of characters */
  904. X
  905. X    if(Debug>5)log(XLOG_DEBUG,"bigprint: '%s'", line );
  906. X    cnt = strlen(line);
  907. X    i = PW/WIDTH;
  908. X    if( cnt > i ){
  909. X        cnt = i;
  910. X    }
  911. X    for( i = 0;  i < HEIGHT+DROP; ++i ){
  912. X        for( j = 0; j < cnt; ++j ){
  913. X            do_char( line[j], i, bline+(j*WIDTH) );
  914. X        }
  915. X        bline[j*WIDTH] = 0;
  916. X        Out_line();
  917. X    }
  918. X}
  919. X
  920. X/***************************************************************************
  921. X * do_char( c, line, buf )
  922. X *  print out the raster line corresponding to character c, line l
  923. X *  If a character is not a descender, you can use the direct mapping.
  924. X *  If it is a descender,  you have to shift down by the descender amount.
  925. X *  1.  for lines above the "top" of a descender line
  926. X *      if the character is a descender, print a space
  927. X *      otherwise print normally
  928. X *  2.  for lines at and below the top of a descender
  929. X *      if the character is a descender, print line
  930. X *      otherwise print normally
  931. X *  3.  for lines below the baseline
  932. X *      if a descender, print line
  933. X *      otherwise print blank
  934. X ***************************************************************************/
  935. static int
  936. is_descender(c)
  937. X    char c;
  938. X{
  939. X    switch(c) {
  940. X    case '_': case ';': case ',': case 'g': case 'j': case 'p':
  941. X    case 'q': case 'y':
  942. X        return(1);
  943. X    default:
  944. X        break;
  945. X    }
  946. X    return (0);
  947. X}
  948. X
  949. do_char( c, line, buf )
  950. X    int c;        /* character */
  951. X    int line;
  952. X    char *buf;
  953. X{
  954. X    int i;                    /* ACME Integer, Inc. */
  955. X    int position;            /* index into chartable */
  956. X    int rep;                /* representation of character scan line */
  957. X
  958. X    if( !isprint( c ) ){
  959. X        c = ' ';
  960. X    }
  961. X    if(Debug>5)log(XLOG_DEBUG,"do_char: %c, line %d", c, line );
  962. X    position = c - ' ';
  963. X    if( is_descender(c) ){
  964. X        if( line >= DROP ){
  965. X            line = line - DROP;
  966. X        } else {
  967. X            position = 0;
  968. X            line = 0;
  969. X        }
  970. X    }
  971. X    if( line >= HEIGHT ){
  972. X        position = 0;
  973. X        line = 0;
  974. X    }
  975. X
  976. X    rep = chartable[position][line];
  977. X    if(Debug>5)log(XLOG_DEBUG,"do_char: position %d, line %d, rep 0x%x",
  978. X        position, line, rep );
  979. X    for( i = 6; i >= 0; --i ){
  980. X        if( rep & (1 << i)){
  981. X            buf[6-i] = 'o';
  982. X        } else {
  983. X            buf[6-i] = ' ';
  984. X        }
  985. X    }
  986. X    for( i = 7; i < WIDTH; ++i ){
  987. X        buf[i] = ' ';
  988. X    }
  989. X}
  990. X
  991. X
  992. X/***************************************************************************
  993. X * Out_line( char* buf )
  994. X * write the buffer out to the file descriptor.
  995. X * don;t do if fail is invalid.
  996. X ***************************************************************************/
  997. Out_line()
  998. X{
  999. X    int i;
  1000. X    i = strlen(bline);
  1001. X
  1002. X    if( fail == 0 ){
  1003. X        if( (i > 0 && write( fd, bline, i) != i) || write( fd, "\n", 1) != 1){
  1004. X            logerr( XLOG_INFO, "Out_line: write failed" );
  1005. X            fail = 1;
  1006. X        }
  1007. X    }
  1008. X    ++linecnt;
  1009. X}
  1010. X
  1011. X#define c_______ 0
  1012. X#define c______1 01
  1013. X#define c_____1_ 02
  1014. X#define c____1__ 04
  1015. X#define c____11_ 06
  1016. X#define c___1___ 010
  1017. X#define c___1__1 011
  1018. X#define c___1_1_ 012
  1019. X#define c___11__ 014
  1020. X#define c__1____ 020
  1021. X#define c__1__1_ 022
  1022. X#define c__1_1__ 024
  1023. X#define c__11___ 030
  1024. X#define c__111__ 034
  1025. X#define c__111_1 035
  1026. X#define c__1111_ 036
  1027. X#define c__11111 037
  1028. X#define c_1_____ 040
  1029. X#define c_1____1 041
  1030. X#define c_1___1_ 042
  1031. X#define c_1__1__ 044
  1032. X#define c_1_1___ 050
  1033. X#define c_1_1__1 051
  1034. X#define c_1_1_1_ 052
  1035. X#define c_11____ 060
  1036. X#define c_11_11_ 066
  1037. X#define c_111___ 070
  1038. X#define c_111__1 071
  1039. X#define c_111_1_ 072
  1040. X#define c_1111__ 074
  1041. X#define c_1111_1 075
  1042. X#define c_11111_ 076
  1043. X#define c_111111 077
  1044. X#define c1______ 0100
  1045. X#define c1_____1 0101
  1046. X#define c1____1_ 0102
  1047. X#define c1____11 0103
  1048. X#define c1___1__ 0104
  1049. X#define c1___1_1 0105
  1050. X#define c1___11_ 0106
  1051. X#define c1__1___ 0110
  1052. X#define c1__1__1 0111
  1053. X#define c1__11_1 0115
  1054. X#define c1__1111 0117
  1055. X#define c1_1____ 0120
  1056. X#define c1_1___1 0121
  1057. X#define c1_1_1_1 0125
  1058. X#define c1_1_11_ 0126
  1059. X#define c1_111__ 0134
  1060. X#define c1_1111_ 0136
  1061. X#define c11____1 0141
  1062. X#define c11___1_ 0142
  1063. X#define c11___11 0143
  1064. X#define c11_1___ 0150
  1065. X#define c11_1__1 0151
  1066. X#define c111_11_ 0166
  1067. X#define c1111___ 0170
  1068. X#define c11111__ 0174
  1069. X#define c111111_ 0176
  1070. X#define c1111111 0177
  1071. X
  1072. char chartable[][HEIGHT] =    /* this is relatively easy to modify */
  1073. X            /* just look: */
  1074. X{
  1075. X    { c_______,
  1076. X      c_______,
  1077. X      c_______,
  1078. X      c_______,
  1079. X      c_______,
  1080. X      c_______,
  1081. X      c_______,
  1082. X      c_______,
  1083. X      c_______ },            /*   */
  1084. X
  1085. X    { c__11___,
  1086. X      c__11___,
  1087. X      c__11___,
  1088. X      c__11___,
  1089. X      c__11___,
  1090. X      c_______,
  1091. X      c_______,
  1092. X      c__11___,
  1093. X      c__11___ },            /* ! */
  1094. X
  1095. X    { c_1__1__,
  1096. X      c_1__1__,
  1097. X      c_______,
  1098. X      c_______,
  1099. X      c_______,
  1100. X      c_______,
  1101. X      c_______,
  1102. X      c_______,
  1103. X      c_______ },            /* " */
  1104. X
  1105. X    { c_______,
  1106. X      c__1_1__,
  1107. X      c__1_1__,
  1108. X      c1111111,
  1109. X      c__1_1__,
  1110. X      c1111111,
  1111. X      c__1_1__,
  1112. X      c__1_1__,
  1113. X      c_______ },            /* # */
  1114. X
  1115. X    { c___1___,
  1116. X      c_11111_,
  1117. X      c1__1__1,
  1118. X      c1__1___,
  1119. X      c_11111_,
  1120. X      c___1__1,
  1121. X      c1__1__1,
  1122. X      c_11111_,
  1123. X      c___1___ },            /* $ */
  1124. X
  1125. X     { c_1_____,
  1126. X       c1_1___1,
  1127. X       c_1___1_,
  1128. X       c____1__,
  1129. X       c___1___,
  1130. X       c__1____,
  1131. X       c_1___1_,
  1132. X       c1___1_1,
  1133. X       c_____1_ },            /* % */
  1134. X     { c_11____,
  1135. X       c1__1___,
  1136. X       c1___1__,
  1137. X       c_1_1___,
  1138. X       c__1____,
  1139. X       c_1_1__1,
  1140. X       c1___11_,
  1141. X       c1___11_,
  1142. X       c_111__1 },            /* & */
  1143. X     { c___11__,
  1144. X       c___11__,
  1145. X       c___1___,
  1146. X       c__1____,
  1147. X       c_______,
  1148. X       c_______,
  1149. X       c_______,
  1150. X       c_______,
  1151. X       c_______ },            /* ' */
  1152. X     { c____1__,
  1153. X       c___1___,
  1154. X       c__1____,
  1155. X       c__1____,
  1156. X       c__1____,
  1157. X       c__1____,
  1158. X       c__1____,
  1159. X       c___1___,
  1160. X       c____1__ },            /* ( */
  1161. X     { c__1____,
  1162. X       c___1___,
  1163. X       c____1__,
  1164. X       c____1__,
  1165. X       c____1__,
  1166. X       c____1__,
  1167. X       c____1__,
  1168. X       c___1___,
  1169. X       c__1____ },            /* ) */
  1170. X     { c_______,
  1171. X       c___1___,
  1172. X       c1__1__1,
  1173. X       c_1_1_1_,
  1174. X       c__111__,
  1175. X       c_1_1_1_,
  1176. X       c1__1__1,
  1177. X       c___1___,
  1178. X       c_______ },            /* * */
  1179. X     { c_______,
  1180. X       c___1___,
  1181. X       c___1___,
  1182. X       c___1___,
  1183. X       c1111111,
  1184. X       c___1___,
  1185. X       c___1___,
  1186. X       c___1___,
  1187. X       c_______ },            /* + */
  1188. X     { c_______,
  1189. X       c_______,
  1190. X       c_______,
  1191. X       c_______,
  1192. X       c__11___,
  1193. X       c__11___,
  1194. X       c__1____,
  1195. X       c_1_____,
  1196. X       c_______ },            /* , */
  1197. X     { c_______,
  1198. X       c_______,
  1199. X       c_______,
  1200. X       c_______,
  1201. X       c1111111,
  1202. X       c_______,
  1203. X       c_______,
  1204. X       c_______,
  1205. X       c_______ },            /* - */
  1206. X     { c_______,
  1207. X      c_______,
  1208. X      c_______,
  1209. X      c_______,
  1210. X      c_______,
  1211. X      c_______,
  1212. X      c_______,
  1213. X      c__11___,
  1214. X      c__11___ },            /* . */
  1215. X
  1216. X    { c_______,
  1217. X      c______1,
  1218. X      c_____1_,
  1219. X      c____1__,
  1220. X      c___1___,
  1221. X      c__1____,
  1222. X      c_1_____,
  1223. X      c1______,
  1224. X      c_______ },            /* / */
  1225. X
  1226. X    { c_11111_,
  1227. X      c1_____1,
  1228. X      c1____11,
  1229. X      c1___1_1,
  1230. X      c1__1__1,
  1231. X      c1_1___1,
  1232. X      c11____1,
  1233. X      c1_____1,
  1234. X      c_11111_ },            /* 0 */
  1235. X
  1236. X    { c___1___,
  1237. X      c__11___,
  1238. X      c_1_1___,
  1239. X      c___1___,
  1240. X      c___1___,
  1241. X      c___1___,
  1242. X      c___1___,
  1243. X      c___1___,
  1244. X      c_11111_ },            /* 1 */
  1245. X
  1246. X    { c_11111_,
  1247. X      c1_____1,
  1248. X      c______1,
  1249. X      c_____1_,
  1250. X      c__111__,
  1251. X      c_1_____,
  1252. X      c1______,
  1253. X      c1______,
  1254. X      c1111111 },            /* 2 */
  1255. X
  1256. X    { c_11111_,
  1257. X      c1_____1,
  1258. X      c______1,
  1259. X      c______1,
  1260. X      c__1111_,
  1261. X      c______1,
  1262. X      c______1,
  1263. X      c1_____1,
  1264. X      c_11111_ },            /* 3 */
  1265. X
  1266. X    { c_____1_,
  1267. X      c____11_,
  1268. X      c___1_1_,
  1269. X      c__1__1_,
  1270. X      c_1___1_,
  1271. X      c1____1_,
  1272. X      c1111111,
  1273. X      c_____1_,
  1274. X      c_____1_ },            /* 4 */
  1275. X
  1276. X    { c1111111,
  1277. X      c1______,
  1278. X      c1______,
  1279. X      c11111__,
  1280. X      c_____1_,
  1281. X      c______1,
  1282. X      c______1,
  1283. X      c1____1_,
  1284. X      c_1111__ },            /* 5 */
  1285. X
  1286. X    { c__1111_,
  1287. X      c_1_____,
  1288. X      c1______,
  1289. X      c1______,
  1290. X      c1_1111_,
  1291. X      c11____1,
  1292. X      c1_____1,
  1293. X      c1_____1,
  1294. X      c_11111_ },            /* 6 */
  1295. X
  1296. X    { c1111111,
  1297. X      c1_____1,
  1298. X      c_____1_,
  1299. X      c____1__,
  1300. X      c___1___,
  1301. X      c__1____,
  1302. X      c__1____,
  1303. X      c__1____,
  1304. X      c__1____ },            /* 7 */
  1305. X
  1306. X    { c_11111_,
  1307. X      c1_____1,
  1308. X      c1_____1,
  1309. X      c1_____1,
  1310. X      c_11111_,
  1311. X      c1_____1,
  1312. X      c1_____1,
  1313. X      c1_____1,
  1314. X      c_11111_ },            /* 8 */
  1315. X
  1316. X    { c_11111_,
  1317. X      c1_____1,
  1318. X      c1_____1,
  1319. X      c1_____1,
  1320. X      c_111111,
  1321. X      c______1,
  1322. X      c______1,
  1323. X      c1_____1,
  1324. X      c_1111__ },            /* 9 */
  1325. X
  1326. X    { c_______,
  1327. X      c_______,
  1328. X      c_______,
  1329. X      c__11___,
  1330. X      c__11___,
  1331. X      c_______,
  1332. X      c_______,
  1333. X      c__11___,
  1334. X      c__11___ },            /* : */
  1335. X
  1336. X
  1337. X    { c__11___,
  1338. X      c__11___,
  1339. X      c_______,
  1340. X      c_______,
  1341. X      c__11___,
  1342. X      c__11___,
  1343. X      c__1____,
  1344. X      c_1_____,
  1345. X      c_______ },            /* ; */
  1346. X
  1347. X    { c____1__,
  1348. X      c___1___,
  1349. X      c__1____,
  1350. X      c_1_____,
  1351. X      c1______,
  1352. X      c_1_____,
  1353. X      c__1____,
  1354. X      c___1___,
  1355. X      c____1__ },            /* < */
  1356. X
  1357. X    { c_______,
  1358. X      c_______,
  1359. X      c_______,
  1360. X      c1111111,
  1361. X      c_______,
  1362. X      c1111111,
  1363. X      c_______,
  1364. X      c_______,
  1365. X      c_______ },            /* = */
  1366. X
  1367. X    { c__1____,
  1368. X      c___1___,
  1369. X      c____1__,
  1370. X      c_____1_,
  1371. X      c______1,
  1372. X      c_____1_,
  1373. X      c____1__,
  1374. X      c___1___,
  1375. X      c__1____ },            /* > */
  1376. X
  1377. X    { c__1111_,
  1378. X      c_1____1,
  1379. X      c_1____1,
  1380. X      c______1,
  1381. X      c____11_,
  1382. X      c___1___,
  1383. X      c___1___,
  1384. X      c_______,
  1385. X      c___1___ },            /* ? */
  1386. X
  1387. X    { c__1111_,
  1388. X      c_1____1,
  1389. X      c1__11_1,
  1390. X      c1_1_1_1,
  1391. X      c1_1_1_1,
  1392. X      c1_1111_,
  1393. X      c1______,
  1394. X      c_1____1,
  1395. X      c__1111_ },            /* @ */
  1396. X
  1397. X    { c__111__,
  1398. X      c_1___1_,
  1399. X      c1_____1,
  1400. X      c1_____1,
  1401. X      c1111111,
  1402. X      c1_____1,
  1403. X      c1_____1,
  1404. X      c1_____1,
  1405. X      c1_____1 },            /* A */
  1406. X
  1407. X    { c111111_,
  1408. X      c_1____1,
  1409. X      c_1____1,
  1410. X      c_1____1,
  1411. X      c_11111_,
  1412. X      c_1____1,
  1413. X      c_1____1,
  1414. X      c_1____1,
  1415. X      c111111_ },            /* B */
  1416. X
  1417. X    { c__1111_,
  1418. X      c_1____1,
  1419. X      c1______,
  1420. X      c1______,
  1421. X      c1______,
  1422. X      c1______,
  1423. X      c1______,
  1424. X      c_1____1,
  1425. X      c__1111_ },            /* C */
  1426. X
  1427. X    { c11111__,
  1428. X      c_1___1_,
  1429. X      c_1____1,
  1430. X      c_1____1,
  1431. X      c_1____1,
  1432. X      c_1____1,
  1433. X      c_1____1,
  1434. X      c_1___1_,
  1435. X      c11111__ },            /* D */
  1436. X
  1437. X    { c1111111,
  1438. X      c1______,
  1439. X      c1______,
  1440. X      c1______,
  1441. X      c111111_,
  1442. X      c1______,
  1443. X      c1______,
  1444. X      c1______,
  1445. X      c1111111 },            /* E */
  1446. X
  1447. X    { c1111111,
  1448. X      c1______,
  1449. X      c1______,
  1450. X      c1______,
  1451. X      c111111_,
  1452. X      c1______,
  1453. X      c1______,
  1454. X      c1______,
  1455. X      c1______ },            /* F */
  1456. X
  1457. X    { c__1111_,
  1458. X      c_1____1,
  1459. X      c1______,
  1460. X      c1______,
  1461. X      c1______,
  1462. X      c1__1111,
  1463. X      c1_____1,
  1464. X      c_1____1,
  1465. X      c__1111_ },            /* G */
  1466. X
  1467. X    { c1_____1,
  1468. X      c1_____1,
  1469. X      c1_____1,
  1470. X      c1_____1,
  1471. X      c1111111,
  1472. X      c1_____1,
  1473. X      c1_____1,
  1474. X      c1_____1,
  1475. X      c1_____1 },            /* H */
  1476. X
  1477. X    { c_11111_,
  1478. X      c___1___,
  1479. X      c___1___,
  1480. X      c___1___,
  1481. X      c___1___,
  1482. X      c___1___,
  1483. X      c___1___,
  1484. X      c___1___,
  1485. X      c_11111_ },            /* I */
  1486. X
  1487. X    { c__11111,
  1488. X      c____1__,
  1489. X      c____1__,
  1490. X      c____1__,
  1491. X      c____1__,
  1492. X      c____1__,
  1493. X      c____1__,
  1494. X      c1___1__,
  1495. X      c_111___ },            /* J */
  1496. X
  1497. X    { c1_____1,
  1498. X      c1____1_,
  1499. X      c1___1__,
  1500. X      c1__1___,
  1501. X      c1_1____,
  1502. X      c11_1___,
  1503. X      c1___1__,
  1504. X      c1____1_,
  1505. X      c1_____1 },            /* K */
  1506. X
  1507. X    { c1______,
  1508. X      c1______,
  1509. X      c1______,
  1510. X      c1______,
  1511. X      c1______,
  1512. X      c1______,
  1513. X      c1______,
  1514. X      c1______,
  1515. X      c1111111 },            /* L */
  1516. X
  1517. X    { c1_____1,
  1518. X      c11___11,
  1519. X      c1_1_1_1,
  1520. X      c1__1__1,
  1521. X      c1_____1,
  1522. X      c1_____1,
  1523. X      c1_____1,
  1524. X      c1_____1,
  1525. X      c1_____1 },            /* M */
  1526. X
  1527. X    { c1_____1,
  1528. X      c11____1,
  1529. X      c1_1___1,
  1530. X      c1__1__1,
  1531. X      c1___1_1,
  1532. X      c1____11,
  1533. X      c1_____1,
  1534. X      c1_____1,
  1535. X      c1_____1 },            /* N */
  1536. X
  1537. X    { c__111__,
  1538. X      c_1___1_,
  1539. X      c1_____1,
  1540. X      c1_____1,
  1541. X      c1_____1,
  1542. X      c1_____1,
  1543. X      c1_____1,
  1544. X      c_1___1_,
  1545. X      c__111__ },            /* O */
  1546. X
  1547. X    { c111111_,
  1548. X      c1_____1,
  1549. X      c1_____1,
  1550. X      c1_____1,
  1551. X      c111111_,
  1552. X      c1______,
  1553. X      c1______,
  1554. X      c1______,
  1555. X      c1______ },            /* P */
  1556. X
  1557. X    { c__111__,
  1558. X      c_1___1_,
  1559. X      c1_____1,
  1560. X      c1_____1,
  1561. X      c1_____1,
  1562. X      c1__1__1,
  1563. X      c1___1_1,
  1564. X      c_1___1_,
  1565. X      c__111_1 },            /* Q */
  1566. X
  1567. X    { c111111_,
  1568. X      c1_____1,
  1569. X      c1_____1,
  1570. X      c1_____1,
  1571. X      c111111_,
  1572. X      c1__1___,
  1573. X      c1___1__,
  1574. X      c1____1_,
  1575. X      c1_____1 },            /* R */
  1576. X
  1577. X    { c_11111_,
  1578. X      c1_____1,
  1579. X      c1______,
  1580. X      c1______,
  1581. X      c_11111_,
  1582. X      c______1,
  1583. X      c______1,
  1584. X      c1_____1,
  1585. X      c_11111_ },            /* S */
  1586. X
  1587. X    { c1111111,
  1588. X      c___1___,
  1589. X      c___1___,
  1590. X      c___1___,
  1591. X      c___1___,
  1592. X      c___1___,
  1593. X      c___1___,
  1594. X      c___1___,
  1595. X      c___1___ },            /* T */
  1596. X
  1597. X    { c1_____1,
  1598. X      c1_____1,
  1599. X      c1_____1,
  1600. X      c1_____1,
  1601. X      c1_____1,
  1602. X      c1_____1,
  1603. X      c1_____1,
  1604. X      c1_____1,
  1605. X      c_11111_ },            /* U */
  1606. X
  1607. X    { c1_____1,
  1608. X      c1_____1,
  1609. X      c1_____1,
  1610. X      c_1___1_,
  1611. X      c_1___1_,
  1612. X      c__1_1__,
  1613. X      c__1_1__,
  1614. X      c___1___,
  1615. X      c___1___ },            /* V */
  1616. X
  1617. X    { c1_____1,
  1618. X      c1_____1,
  1619. X      c1_____1,
  1620. X      c1_____1,
  1621. X      c1__1__1,
  1622. X      c1__1__1,
  1623. X      c1_1_1_1,
  1624. X      c11___11,
  1625. X      c1_____1 },            /* W */
  1626. X
  1627. X    { c1_____1,
  1628. X      c1_____1,
  1629. X      c_1___1_,
  1630. X      c__1_1__,
  1631. X      c___1___,
  1632. X      c__1_1__,
  1633. X      c_1___1_,
  1634. X      c1_____1,
  1635. X      c1_____1 },            /* X */
  1636. X
  1637. X    { c1_____1,
  1638. X      c1_____1,
  1639. X      c_1___1_,
  1640. X      c__1_1__,
  1641. X      c___1___,
  1642. X      c___1___,
  1643. X      c___1___,
  1644. X      c___1___,
  1645. X      c___1___ },            /* Y */
  1646. X
  1647. X    { c1111111,
  1648. X      c______1,
  1649. X      c_____1_,
  1650. X      c____1__,
  1651. X      c___1___,
  1652. X      c__1____,
  1653. X      c_1_____,
  1654. X      c1______,
  1655. X      c1111111 },            /* Z */
  1656. X
  1657. X    { c_1111__,
  1658. X      c_1_____,
  1659. X      c_1_____,
  1660. X      c_1_____,
  1661. X      c_1_____,
  1662. X      c_1_____,
  1663. X      c_1_____,
  1664. X      c_1_____,
  1665. X      c_1111__ },            /* [ */
  1666. X
  1667. X    { c_______,
  1668. X      c1______,
  1669. X      c_1_____,
  1670. X      c__1____,
  1671. X      c___1___,
  1672. X      c____1__,
  1673. X      c_____1_,
  1674. X      c______1,
  1675. X      c_______ },            /* \ */
  1676. X
  1677. X    { c__1111_,
  1678. X      c_____1_,
  1679. X      c_____1_,
  1680. X      c_____1_,
  1681. X      c_____1_,
  1682. X      c_____1_,
  1683. X      c_____1_,
  1684. X      c_____1_,
  1685. X      c__1111_ },            /* ] */
  1686. X
  1687. X    { c___1___,
  1688. X      c__1_1__,
  1689. X      c_1___1_,
  1690. X      c1_____1,
  1691. X      c_______,
  1692. X      c_______,
  1693. X      c_______,
  1694. X      c_______ },            /* ^ */
  1695. X
  1696. X    { c_______,
  1697. X      c_______,
  1698. X      c_______,
  1699. X      c_______,
  1700. X      c_______,
  1701. X      c_______,
  1702. X      c_______,
  1703. X      c1111111,
  1704. X      c_______ },            /* _ */
  1705. X
  1706. X    { c__11___,
  1707. X      c__11___,
  1708. X      c___1___,
  1709. X      c____1__,
  1710. X      c_______,
  1711. X      c_______,
  1712. X      c_______,
  1713. X      c_______,
  1714. X      c_______ },            /* ` */
  1715. X
  1716. X    { c_______,
  1717. X      c_______,
  1718. X      c_______,
  1719. X      c_1111__,
  1720. X      c_____1_,
  1721. X      c_11111_,
  1722. X      c1_____1,
  1723. X      c1____11,
  1724. X      c_1111_1 },            /* a */
  1725. X
  1726. X    { c1______,
  1727. X      c1______,
  1728. X      c1______,
  1729. X      c1_111__,
  1730. X      c11___1_,
  1731. X      c1_____1,
  1732. X      c1_____1,
  1733. X      c11___1_,
  1734. X      c1_111__ },            /* b */
  1735. X
  1736. X    { c_______,
  1737. X      c_______,
  1738. X      c_______,
  1739. X      c_1111__,
  1740. X      c1____1_,
  1741. X      c1______,
  1742. X      c1______,
  1743. X      c1____1_,
  1744. X      c_1111__ },            /* c */
  1745. X
  1746. X    { c_____1_,
  1747. X      c_____1_,
  1748. X      c_____1_,
  1749. X      c_111_1_,
  1750. X      c1___11_,
  1751. X      c1____1_,
  1752. X      c1____1_,
  1753. X      c1___11_,
  1754. X      c_111_1_ },            /* d */
  1755. X
  1756. X    { c_______,
  1757. X      c_______,
  1758. X      c_______,
  1759. X      c_1111__,
  1760. X      c1____1_,
  1761. X      c111111_,
  1762. X      c1______,
  1763. X      c1____1_,
  1764. X      c_1111__ },            /* e */
  1765. X
  1766. X    { c___11__,
  1767. X      c__1__1_,
  1768. X      c__1____,
  1769. X      c__1____,
  1770. X      c11111__,
  1771. X      c__1____,
  1772. X      c__1____,
  1773. X      c__1____,
  1774. X      c__1____ },            /* f */
  1775. X
  1776. X    { c_111_1_,
  1777. X      c1___11_,
  1778. X      c1____1_,
  1779. X      c1____1_,
  1780. X      c1___11_,
  1781. X      c_111_1_,
  1782. X      c_____1_,
  1783. X      c1____1_,
  1784. X      c_1111__ },            /* g */
  1785. X
  1786. X    { c1______,
  1787. X      c1______,
  1788. X      c1______,
  1789. X      c1_111__,
  1790. X      c11___1_,
  1791. X      c1____1_,
  1792. X      c1____1_,
  1793. X      c1____1_,
  1794. X      c1____1_ },            /* h */
  1795. X
  1796. X    { c_______,
  1797. X      c___1___,
  1798. X      c_______,
  1799. X      c__11___,
  1800. X      c___1___,
  1801. X      c___1___,
  1802. X      c___1___,
  1803. X      c___1___,
  1804. X      c__111__ },            /* i */
  1805. X
  1806. X    { c____11_,
  1807. X      c_____1_,
  1808. X      c_____1_,
  1809. X      c_____1_,
  1810. X      c_____1_,
  1811. X      c_____1_,
  1812. X      c_____1_,
  1813. X      c_1___1_,
  1814. X      c__111__ },            /* j */
  1815. X
  1816. X    { c1______,
  1817. X      c1______,
  1818. X      c1______,
  1819. X      c1___1__,
  1820. X      c1__1___,
  1821. X      c1_1____,
  1822. X      c11_1___,
  1823. X      c1___1__,
  1824. X      c1____1_ },            /* k */
  1825. X
  1826. X    { c__11___,
  1827. X      c___1___,
  1828. X      c___1___,
  1829. X      c___1___,
  1830. X      c___1___,
  1831. X      c___1___,
  1832. X      c___1___,
  1833. X      c___1___,
  1834. X      c__111__ },            /* l */
  1835. X
  1836. X    { c_______,
  1837. X      c_______,
  1838. X      c_______,
  1839. X      c1_1_11_,
  1840. X      c11_1__1,
  1841. X      c1__1__1,
  1842. X      c1__1__1,
  1843. X      c1__1__1,
  1844. X      c1__1__1 },            /* m */
  1845. X
  1846. X    { c_______,
  1847. X      c_______,
  1848. X      c_______,
  1849. X      c1_111__,
  1850. X      c11___1_,
  1851. X      c1____1_,
  1852. X      c1____1_,
  1853. X      c1____1_,
  1854. X      c1____1_ },            /* n */
  1855. X
  1856. X    { c_______,
  1857. X      c_______,
  1858. X      c_______,
  1859. X      c_1111__,
  1860. X      c1____1_,
  1861. X      c1____1_,
  1862. X      c1____1_,
  1863. X      c1____1_,
  1864. X      c_1111__ },            /* o */
  1865. X
  1866. X    { c1_111__,
  1867. X      c11___1_,
  1868. X      c1____1_,
  1869. X      c1____1_,
  1870. X      c11___1_,
  1871. X      c1_111__,
  1872. X      c1______,
  1873. X      c1______,
  1874. X      c1______ },            /* p */
  1875. X
  1876. X    { c_111_1_,
  1877. X      c1___11_,
  1878. X      c1____1_,
  1879. X      c1____1_,
  1880. X      c1___11_,
  1881. X      c_111_1_,
  1882. X      c_____1_,
  1883. X      c_____1_,
  1884. X      c_____1_ },            /* q */
  1885. X
  1886. X    { c_______,
  1887. X      c_______,
  1888. X      c_______,
  1889. X      c1_111__,
  1890. X      c11___1_,
  1891. X      c1______,
  1892. X      c1______,
  1893. X      c1______,
  1894. X      c1______ },            /* r */
  1895. X
  1896. X    { c_______,
  1897. X      c_______,
  1898. X      c_______,
  1899. X      c_1111__,
  1900. X      c1____1_,
  1901. X      c_11____,
  1902. X      c___11__,
  1903. X      c1____1_,
  1904. X      c_1111__ },            /* s */
  1905. X
  1906. X    { c_______,
  1907. X      c__1____,
  1908. X      c__1____,
  1909. X      c11111__,
  1910. X      c__1____,
  1911. X      c__1____,
  1912. X      c__1____,
  1913. X      c__1__1_,
  1914. X      c___11__ },            /* t */
  1915. X
  1916. X    { c_______,
  1917. X      c_______,
  1918. X      c_______,
  1919. X      c1____1_,
  1920. X      c1____1_,
  1921. X      c1____1_,
  1922. X      c1____1_,
  1923. X      c1___11_,
  1924. X      c_111_1_ },            /* u */
  1925. X
  1926. X    { c_______,
  1927. X      c_______,
  1928. X      c_______,
  1929. X      c1_____1,
  1930. X      c1_____1,
  1931. X      c1_____1,
  1932. X      c_1___1_,
  1933. X      c__1_1__,
  1934. X      c___1___ },            /* v */
  1935. X
  1936. X    { c_______,
  1937. X      c_______,
  1938. X      c_______,
  1939. X      c1_____1,
  1940. X      c1__1__1,
  1941. X      c1__1__1,
  1942. X      c1__1__1,
  1943. X      c1__1__1,
  1944. X      c_11_11_ },            /* w */
  1945. X
  1946. X    { c_______,
  1947. X      c_______,
  1948. X      c_______,
  1949. X      c1____1_,
  1950. X      c_1__1__,
  1951. X      c__11___,
  1952. X      c__11___,
  1953. X      c_1__1__,
  1954. X      c1____1_ },            /* x */
  1955. X
  1956. X    { c1____1_,
  1957. X      c1____1_,
  1958. X      c1____1_,
  1959. X      c1____1_,
  1960. X      c1___11_,
  1961. X      c_111_1_,
  1962. X      c_____1_,
  1963. X      c1____1_,
  1964. X      c_1111__ },            /* y */
  1965. X
  1966. X    { c_______,
  1967. X      c_______,
  1968. X      c_______,
  1969. X      c111111_,
  1970. X      c____1__,
  1971. X      c___1___,
  1972. X      c__1____,
  1973. X      c_1_____,
  1974. X      c111111_ },            /* z */
  1975. X
  1976. X    { c___11__,
  1977. X      c__1____,
  1978. X      c__1____,
  1979. X      c__1____,
  1980. X      c_1_____,
  1981. X      c__1____,
  1982. X      c__1____,
  1983. X      c__1____,
  1984. X      c___11__ },            /* } */
  1985. X
  1986. X    { c___1___,
  1987. X      c___1___,
  1988. X      c___1___,
  1989. X      c___1___,
  1990. X      c___1___,
  1991. X      c___1___,
  1992. X      c___1___,
  1993. X      c___1___,
  1994. X      c___1___ },            /* | */
  1995. X
  1996. X    { c__11___,
  1997. X      c____1__,
  1998. X      c____1__,
  1999. X      c____1__,
  2000. X      c_____1_,
  2001. X      c____1__,
  2002. X      c____1__,
  2003. X      c____1__,
  2004. X      c__11___ },            /* } */
  2005. X
  2006. X    { c_11____,
  2007. X      c1__1__1,
  2008. X      c____11_,
  2009. X      c_______,
  2010. X      c_______,
  2011. X      c_______,
  2012. X      c_______,
  2013. X      c_______,
  2014. X      c_______ },            /* ~ */
  2015. X
  2016. X    { c_1__1__,
  2017. X      c1__1__1,
  2018. X      c__1__1_,
  2019. X      c_1__1__,
  2020. X      c1__1__1,
  2021. X      c__1__1_,
  2022. X      c_1__1__,
  2023. X      c1__1__1,
  2024. X      c__1__1_ }            /* rub-out */
  2025. X};
  2026. END_OF_FILE
  2027. if test 21457 -ne `wc -c <'src/banner.c'`; then
  2028.     echo shar: \"'src/banner.c'\" unpacked with wrong size!
  2029. fi
  2030. # end of 'src/banner.c'
  2031. fi
  2032. echo shar: End of archive 14 \(of 16\).
  2033. cp /dev/null ark14isdone
  2034. MISSING=""
  2035. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  2036.     if test ! -f ark${I}isdone ; then
  2037.     MISSING="${MISSING} ${I}"
  2038.     fi
  2039. done
  2040. if test "${MISSING}" = "" ; then
  2041.     echo You have unpacked all 16 archives.
  2042.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  2043. else
  2044.     echo You still need to unpack the following archives:
  2045.     echo "        " ${MISSING}
  2046. fi
  2047. ##  End of shell archive.
  2048. exit 0
  2049.  
  2050.