home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume16 / plp / part04 < prev    next >
Text File  |  1989-01-22  |  53KB  |  1,793 lines

  1. Article 196 of comp.sources.unix:
  2. Path: mace.cc.purdue.edu!j.cc.purdue.edu!pur-ee!iuvax!mailrus!uflorida!gatech!bbn!bbn.com!rsalz
  3. From: rsalz@uunet.uu.net (Rich Salz)
  4. Newsgroups: comp.sources.unix
  5. Subject: v16i017:  Public lineprinter spooler package, Part04/16
  6. Message-ID: <1070@fig.bbn.com>
  7. Date: 14 Sep 88 20:15:44 GMT
  8. Lines: 1780
  9. Approved: rsalz@uunet.UU.NET
  10.  
  11. Submitted-by: papowell@julius.cs.umn.edu
  12. Posting-number: Volume 16, Issue 17
  13. Archive-name: plp/part04
  14.  
  15. #! /bin/sh
  16. # This is a shell archive.  Remove anything before this line, then unpack
  17. # it by saving it into a file and typing "sh file".  To overwrite existing
  18. # files, type "sh file -c".  You can also feed this as standard input via
  19. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  20. # will see the following message at the end:
  21. #        "End of archive 4 (of 16)."
  22. # Contents:  doc/PLP/01.t filters/pref_main.c man/lpc.1 man/printcap.5
  23. #   src/getopt.c src/lpr_canprint.c src/lpr_temp.c src/servicereq.c
  24. # Wrapped by papowell@attila on Wed Aug 10 10:44:51 1988
  25. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  26. if test -f 'doc/PLP/01.t' -a "${1}" != "-c" ; then 
  27.   echo shar: Will not clobber existing file \"'doc/PLP/01.t'\"
  28. else
  29. echo shar: Extracting \"'doc/PLP/01.t'\" \(5586 characters\)
  30. sed "s/^X//" >'doc/PLP/01.t' <<'END_OF_FILE'
  31. X.ig
  32. X$Header: 01.t,v 1.1 88/05/21 18:39:31 papowell Locked $
  33. X$log$
  34. X..
  35. X.NH 1
  36. Overview
  37. X.PP
  38. The Public Line Printer Spooler (PLP) software is a
  39. reverse engineered version of the Berkeley Line Printer Spooler (LPD).
  40. During the implementation,
  41. there was no resort to any of the Berkeley LPD source,
  42. other than for tables that are used to print big letter banners\**.
  43. X.FS
  44. The author has seen these appear in several public domain games programs,
  45. and has recollections of running card decks which produced
  46. suspiciously similar output.
  47. X.FE
  48. Due to experience with the Berkeley software,
  49. some LPD routines and functionality may be duplicated,
  50. but in general the implementation and structure of the PLP software is
  51. radically different.
  52. X.PP
  53. The Public Line Printer Spooler supports:
  54. X.IP 1). 3
  55. Multiple printers,
  56. one or more per spooling queue.
  57. X.IP 2). 3
  58. Multiple prioritized spooling queues.
  59. X.IP 3). 3
  60. Both local and remote printers.
  61. X.IP 4). 3
  62. Printers attached via serial lines,
  63. which can have line characteristics such as baud rate,
  64. parity,
  65. etc., specified.
  66. X.IP 5). 3
  67. Devices such as an Imagen laser printer which may
  68. require a special communications protocol for printing.
  69. X.IP 6). 3
  70. Operation in a shared file system environment (such as NFS).
  71. X.IP 7). 3
  72. Restriction of use by a printer permissions data base.
  73. In addition to a per-host database,
  74. each individual spool queue may have a supplementary database.
  75. X.PP
  76. The major components of line printer system are the
  77. following files and commands in Table 1.1.
  78. X.TS
  79. center box;
  80. l | l | l.
  81. Name    Type    Purpose
  82. X_
  83. X/??/printcap.<host>    file    printer configuration and capability data base
  84. X/??/printer_perms.<host>    file    printer permissions data base
  85. X/??/log.<host>    file    daemon log file
  86. X/??/lock.<host>    file    daemon lock
  87. X/usr/lib/lpd    daemon    line printer daemon
  88. X/usr/local/bin/lpr    command    enter a job in a printer queue
  89. X/usr/local/bin/lpq    command    examine queues
  90. X/usr/local/bin/lprm    command    delete jobs from a queue
  91. X/usr/local/bin/lpc    command    administer printers and spooling queues
  92. printer,tcp    port    inet service port on which lpd listens
  93. X.TE
  94. X.ce
  95. Table 1.1 Major PLP Components
  96. X.PP
  97. The
  98. X.L /??/printcap.<host>
  99. file
  100. is a master data base describing
  101. characteristics of line printers either directly attached to the host
  102. or accessible across a network.
  103. In the Berkeley LPD software,
  104. the printcap file was
  105. X.L /etc/printcap .
  106. While this convention is easy to use in a single host or loosely
  107. coupled multiple processor environment,
  108. it has proven to be difficult to manage and apply in a networked based
  109. file system such as NFS.
  110. In order to provide an easier management of the PLP software,
  111. the
  112. X.L printcap ,
  113. X.L printer_perms ,
  114. X.L log ,
  115. and
  116. X.L lock
  117. files have the form:
  118. X.L /usr/spool/lpd/<file>.<host> ,
  119. where
  120. X.L <host>
  121. is the network level form of the host name.
  122. Note that this allows a single  spool directory to be made available to
  123. all the systems using an NFS file system.
  124. Note that all files in the spool directory are created using the
  125. X.L daemon
  126. user ID and group ID,
  127. avoiding problems with NFS systems and root userids.
  128. X.PP
  129. The format of the printcap database is based on the
  130. X.IR termcap (5)
  131. format.
  132. X.PP
  133. The
  134. X.L printer_perms
  135. or printer permissions file is used by PLP software to
  136. determine what operations,
  137. queues,
  138. and services can be accesssed by users.
  139. It also determines the spool queues accessible by users from remote hosts,
  140. as well as determining.
  141. The printer permissions file is similar in purpose to the
  142. X.I host.equiv
  143. file that is used by
  144. X.I rshd .
  145. X.PP
  146. The
  147. X.L lpd
  148. program is a
  149. X.I daemon
  150. or server program that carries out actions as requested by other programs.
  151. The
  152. X.L lpr
  153. program creates print jobs in the appropriate spool queue,
  154. and then requests the
  155. X.L lpd
  156. daemon to perform unspooling actions.
  157. The
  158. X.L lpq
  159. program is used to print the status of local and remote spool queues.
  160. The
  161. X.L lprm
  162. program is used to remove jobs from spool queues,
  163. and the
  164. X.L lpc
  165. program is used to control spooling and unspooling activities.
  166. X.PP
  167. Communication between the
  168. X.L lpd
  169. daemon and the utility programs is done using the Internet TCP/IP
  170. communications support provided by most UNIX systems.
  171. XEach host has an
  172. X.L lpd
  173. daemon which listens on a well known port of the host,
  174. and carries out requested activities.
  175. X.PP
  176. The remainder of this document provides details of the structure and
  177. implementation of the above facilities and programs.
  178. Section 2 describes the functionality of the
  179. X.L lpd
  180. daemon and  the 
  181. X.L "lpr" ,
  182. X.L "lpq" ,
  183. X.L "lprm" ,
  184. and
  185. X.L "lpc"
  186. programs.
  187. Section 3 describes the structure of the spool directory associated
  188. with each spool queue,
  189. and the security precautions taken to ensure the integrity of the
  190. the spool directory and print jobs.
  191. Section 4 is a description of the
  192. X.I printcap
  193. data base,
  194. and how the information in the database
  195. is used by the PLP software to perform spooling operations.
  196. Section 5 is a description of the inter-host file transfer protocol used
  197. by PLP.
  198. Section 6 is a description of the unspooling operations carried out by the
  199. X.I lpd
  200. program,
  201. and how they are controlled by the printcap information.
  202. Section 7 details how filter programs are invoked by the spool server
  203. processes and how they are specified in the printcap.
  204. Section 8 describes how PLP can be used in a networked file system
  205. environment.
  206. Section 9 outlines how the
  207. X.I lpc
  208. program is used to control spooling operations.
  209. Section 10 is a discussion of some diagnositic information supplied by
  210. the PLP programs.
  211. Section 11 is an outline of the installation and test procedures for
  212. PLP.
  213. Section 12 is a summary of differences between the Berkeley LPR
  214. software and PLP.
  215. END_OF_FILE
  216. if test 5586 -ne `wc -c <'doc/PLP/01.t'`; then
  217.     echo shar: \"'doc/PLP/01.t'\" unpacked with wrong size!
  218. fi
  219. # end of 'doc/PLP/01.t'
  220. fi
  221. if test -f 'filters/pref_main.c' -a "${1}" != "-c" ; then 
  222.   echo shar: Will not clobber existing file \"'filters/pref_main.c'\"
  223. else
  224. echo shar: Extracting \"'filters/pref_main.c'\" \(5906 characters\)
  225. sed "s/^X//" >'filters/pref_main.c' <<'END_OF_FILE'
  226. X#ifndef    lint
  227. X/*
  228. X * Updated LPR software;
  229. X * Original Version (Copyright) 1983 Regents of the Univeristy of California
  230. X * This is a derivative work,
  231. X * and the original copyright is still valid.  Covered by the
  232. X * 4BSD Licensing Agreement;  this is NOT public domain software.
  233. X * Mon Nov 23 09:23:23 CST 1987 Patrick Powell, U. Minnesota
  234. X */
  235. X#ifndef __INDENT_INCL
  236. static char id_str1[] =
  237. X    "Revised LPR, Patrick Powell, U. Waterloo, April 10, 1984";
  238. static char id_str2[] =
  239. X    "Re-revised LPR, Patrick Powell, U. Minnesota, 23 Nov 1987";
  240. X#define __INDENT_INCL 1
  241. X#endif __INDENT_INCL
  242. X#endif lint
  243. X/*
  244. X * Prefilter main and setup.
  245. X *    A prefilter is invoked with the following parameters:
  246. X *
  247. X *
  248. X * filter -wwidth -llength -xwidth -ylength [-c]  [-iindent]
  249. X *        -Zoptions -Cclass -Jjob -nlogin -hhost -Fx [files]
  250. X * 
  251. X *    if the [files] are missing, input is from stdin
  252. X *
  253. X *    The following variables are set up
  254. X *
  255. X * name        - name of filter            PRINTCAP ENTRY
  256. X * width    - default 132                pl
  257. X * length    - default 66                pw
  258. X * xwidth    - default 0                px
  259. X * ylength    - default 0                py
  260. X * literal    - default 0 [-c flag]
  261. X * indent    - default 0
  262. X * zopts    - NULL    [lpr]
  263. X * class    - NULL [lpr]
  264. X * job        - NULL [lpr]
  265. X * login    - NULL [lpr]
  266. X * host        - NULL [lpr]
  267. X * format    - set from -F
  268. X * last        - set for last file
  269. X * file        - current file (NULL if stdin)
  270. X *
  271. X *    The list of files is opened, and the file descriptor is set to 0
  272. X *    with a dup2.  The "last" flag is set when the last file is opened.
  273. X *    The name of the current file is available in "file".
  274. X *    Then the "prefilter" function is called.
  275. X *    The program exits with a 0 (successful), 1 (unsuccessful, retry)
  276. X *    and anything else indicates unsuccessful, no retry.
  277. X *    The prefilter() function should return a similar status.
  278. X *    The functions fatal(), logerr(), and logerr_die() can be used to report
  279. X *    status. The variable errorcode can be set by the user before calling
  280. X *    these functions, and will be the exit value of the program. Its default
  281. X *    value will be 2.
  282. X *    The fatal function reports a fatal message, and terminates
  283. X *    logerr() will report a message, append information indicated by errno
  284. X *    (see perror(2) for details), and then returns.
  285. X *    logerr_die() will call logerr(), and then will exit with errorcode
  286. X *    status.
  287. X *    In case of an error, the "cleanup()" function will be called.
  288. X *    This can be used to do any error functions.
  289. X *
  290. X */
  291. X
  292. X#include <stdio.h>
  293. X#include <sys/file.h>
  294. X
  295. int errorcode = 2;
  296. X
  297. char *name;        /* name of filter */
  298. int width = 132;    /* default 132    */
  299. int length;    /* default 66    */
  300. int xwidth;    /* default 0    */
  301. int ylength;    /* default 0    */
  302. int literal;    /* default 0 [-c flag]*/
  303. int indent;    /* default 0 */
  304. char *zopts;    /* NULL    [lpr]*/
  305. char *class;    /* NULL [lpr]*/
  306. char *job;    /* NULL [lpr]*/
  307. char *login;    /* NULL [lpr]*/
  308. char *host;    /* NULL [lpr]*/
  309. int format;    /* set from -F*/
  310. int last;    /* set for last file*/
  311. char *file;    /* current file (NULL if stdin)*/
  312. X
  313. main( argc, argv )
  314. X    int argc;
  315. X    char **argv;
  316. X    {
  317. X    char * arg;
  318. X    int i;
  319. X
  320. X    name = argv[0];
  321. X    ++argv;
  322. X
  323. X    /*
  324. X     * process the flagged arguments
  325. X     */
  326. X    while( --argc > 0 ){
  327. X        if( **argv != '-' )
  328. X            break;
  329. X        arg = 1 + *argv++;    /* arg ^s to the option letter */
  330. X        switch( *arg++ ){    /* arg now ^s to the option value */
  331. X        case 'w':
  332. X            if( (i = atoi(arg))< 0 ){
  333. X            fatal("argument for %c out of range",arg[-1]);
  334. X            } else if( i > 0 ){
  335. X                width = i;
  336. X            }
  337. X            break;
  338. X        case 'l':
  339. X            if( (i = atoi(arg))< 0 ){
  340. X            fatal("argument for %c out of range",arg[-1]);
  341. X            } else if( i > 0 ){
  342. X                length = i;
  343. X            }
  344. X            break;
  345. X        case 'x':
  346. X            if( (i = atoi(arg))< 0 ){
  347. X            fatal("argument for %c out of range",arg[-1]);
  348. X            } else if( i > 0 ){
  349. X                xwidth = i;
  350. X            }
  351. X            break;
  352. X        case 'y':
  353. X            if( (i = atoi(arg))< 0 ){
  354. X            fatal("argument for %c out of range",arg[-1]);
  355. X            } else if( i > 0 ){
  356. X                ylength = i;
  357. X            }
  358. X            break;
  359. X        case 'c':
  360. X            literal = 1;
  361. X            break;
  362. X        case 'i':
  363. X            if( (i = atoi(arg))< 0 ){
  364. X            fatal("argument for %c out of range",arg[-1]);
  365. X            } else if( i > 0 ){
  366. X                indent = i;
  367. X            }
  368. X            break;
  369. X        case 'Z':
  370. X            zopts = arg;
  371. X            break;
  372. X        case 'C':
  373. X            class = arg;
  374. X            break;
  375. X        case 'J':
  376. X            job = arg;
  377. X            break;
  378. X        case 'n':
  379. X            login = arg;
  380. X            break;
  381. X        case 'h':
  382. X            host = arg;
  383. X            break;
  384. X        case 'F':
  385. X            format = *arg;
  386. X            break;
  387. X        }
  388. X    }
  389. X    /*
  390. X     * now assume the rest of the arguments are filenames
  391. X     */
  392. X    dofiles( argc, argv );
  393. X    }
  394. X
  395. X
  396. X/*
  397. X * Now do the files.  Open each as fd 0 (stdin), and read each one.
  398. X */
  399. dofiles( argc, argv )
  400. X    int argc;    /* # of items in 'argv' */
  401. X    char **argv;
  402. X    {
  403. X    int fd;
  404. X
  405. X    if( argc > 0 ){
  406. X        while( --argc >= 0 ){
  407. X            file = *argv++;
  408. X            if( argc == 0 ){
  409. X                last = 1;
  410. X            }
  411. X            if( (fd = open(file,O_RDONLY,0)) < 0 ) {
  412. X                logerr_die( "cannot open %s ", file );
  413. X            }
  414. X            if( fd != 0 ){
  415. X                if(dup2( fd, 0 ) < 0){
  416. X                errorcode = 1;
  417. X                logerr_die( "dup2 failed" );
  418. X                }
  419. X                (void)close( fd );
  420. X            }
  421. X            prefilter();
  422. X            (void)clearerr( stdin );
  423. X            (void)close(0);
  424. X            }
  425. X    } else {
  426. X        last = 1;
  427. X        prefilter();
  428. X    }
  429. X    exit(0);
  430. X    }
  431. X
  432. X/*VARARGS1*/
  433. log(msg, a1, a2, a3)
  434. X    char *msg;
  435. X{
  436. X    (void)fprintf(stderr, "%s: ", name);
  437. X    (void)fprintf(stderr, msg, a1, a2, a3);
  438. X    (void)putc('\n', stderr);
  439. X    (void)fflush(stderr);
  440. X}
  441. X
  442. X
  443. X/*VARARGS1*/
  444. fatal(msg, a1, a2, a3)
  445. X    char *msg;
  446. X{
  447. X    log(msg, a1, a2, a3);
  448. X    cleanup();
  449. X    exit(errorcode);
  450. X}
  451. X
  452. X
  453. X/*VARARGS1*/
  454. logerr(msg, a1, a2, a3)
  455. X    char *msg;
  456. X{
  457. X    extern int errno, sys_nerr;
  458. X    extern char *sys_errlist[];
  459. X    register int err = errno;
  460. X
  461. X    (void)fprintf(stderr, "%s: ", name);
  462. X    if (msg){
  463. X        (void)fprintf(stderr, msg, a1, a2, a3);
  464. X        (void)fputs( "- ", stderr);
  465. X    }
  466. X    (void)fputs(err<sys_nerr ?sys_errlist[err] :"Unknown error", stderr);
  467. X    (void)putc('\n', stderr);
  468. X    (void)fflush();
  469. X}
  470. X
  471. X/*VARARGS1*/
  472. logerr_die(msg, a1, a2, a3)
  473. X    char *msg;
  474. X{
  475. X    logerr(msg, a1, a2, a3);
  476. X    cleanup();
  477. X    exit(errorcode);
  478. X}
  479. X
  480. X#ifdef DEBUG
  481. cleanup() {}
  482. X
  483. prefilter()
  484. X    {
  485. X    int c;
  486. X
  487. X    if( file ){
  488. X        log( "file %s", file );
  489. X    } else {
  490. X        log( "file %s", "(stdin)" );
  491. X    }
  492. X    while( (c = getchar()) != EOF ){
  493. X        putchar(c);
  494. X    }
  495. X    }
  496. X#endif DEBUG
  497. END_OF_FILE
  498. if test 5906 -ne `wc -c <'filters/pref_main.c'`; then
  499.     echo shar: \"'filters/pref_main.c'\" unpacked with wrong size!
  500. fi
  501. # end of 'filters/pref_main.c'
  502. fi
  503. if test -f 'man/lpc.1' -a "${1}" != "-c" ; then 
  504.   echo shar: Will not clobber existing file \"'man/lpc.1'\"
  505. else
  506. echo shar: Extracting \"'man/lpc.1'\" \(5371 characters\)
  507. sed "s/^X//" >'man/lpc.1' <<'END_OF_FILE'
  508. X.TH LPC 1 "19 Mar 1988" "U-MN PLP"
  509. X.ig
  510. X$Header: lpc.1,v 2.1 88/05/09 10:08:27 papowell Exp $
  511. X$Log:    lpc.1,v $
  512. Revision 2.1  88/05/09  10:08:27  papowell
  513. PLP: Released Version
  514. X
  515. Revision 1.1  88/04/28  10:58:49  papowell
  516. Initial revision
  517. X
  518. X..
  519. X.SH NAME
  520. lpc \- line printer control program
  521. X.SH SYNOPSIS
  522. X.B lpc
  523. X[
  524. X.BI \-D n
  525. X] [
  526. X.B \-X
  527. X[ command [ argument ... ] ]
  528. X.SH DESCRIPTION
  529. X.I Lpc
  530. is used by the system administrator to control the
  531. operation of the line printer system.  
  532. XFor each line printer configured in /etc/printcap,
  533. X.I lpc
  534. may be used to:
  535. X.IP \(bu 3
  536. disable or enable a printer,
  537. X.IP \(bu 3
  538. disable or enable a printer's spooling queue,
  539. X.IP \(bu 3
  540. rearrange the order of jobs in a spooling queue,
  541. X.IP \(bu 3
  542. find the status of printers, and their associated
  543. spooling queues and printer dameons.
  544. X.IP \(bu 3
  545. start and stop printer servers for a queue with multiple print servers
  546. X.IP \(bu 3
  547. perform remote control of a spool queue
  548. X.PP
  549. Without any arguments,
  550. X.I lpc
  551. will prompt for commands from the standard input.
  552. If arguments are supplied,
  553. X.IR lpc
  554. interprets the first argument as a command and the remaining
  555. arguments as parameters to the command.
  556. The standard input
  557. may be redirected causing
  558. X.I lpc
  559. to read commands from file.
  560. Permission to use spool queue control commands is determined by the
  561. printer permissions file
  562. X.I /etc/printer_perms.
  563. Priviledged commands can only be used by users with
  564. C or control permissions.
  565. Commands may be abreviated;
  566. the following is the list of recognized commands.
  567. X.TP
  568. X? [ command ... ]
  569. X.TP
  570. h[elp] [ command ... ]
  571. X.br
  572. Print a short description of each command specified in the argument list,
  573. or, if no arguments are given, a list of the recognized commands.
  574. X.TP
  575. e[xit]
  576. X.TP
  577. q[uit]
  578. X.br
  579. XEx[it] from lpc.
  580. X.TP
  581. en[able] { all | printer ... }
  582. X.br
  583. XEnable spooling on the local queue for the listed printers. 
  584. This will allow
  585. X.I lpr
  586. to put new jobs in the spool queue.
  587. Priviledged.
  588. X.TP
  589. d[isable] { all | printer ... }
  590. X.br
  591. Disable spooling to the specified spool queues.
  592. This will suppress spooling by
  593. X.IR lpr .
  594. Priviledged.
  595. X.TP
  596. star[t] { all | printer ... }
  597. X.br
  598. XEnable unspooling and start a server for the listed printers.
  599. Priviledged.
  600. X.TP
  601. sto[p] { all | printer ... }
  602. X.br
  603. Disable any further unspooling.
  604. Stop the unspooler after the current job completes.
  605. Priviledged.
  606. X.TP
  607. a[bort] { all | printer ... }
  608. X.br
  609. Disable any further unspooling.
  610. Kill the currently active unspooling server.
  611. Note that the currently active job will not be deleted from the queue.
  612. Priviledged.
  613. X.TP
  614. k[ill] { all | printer ... }
  615. X.br
  616. Do an abort followed by a start.
  617. This is a quick way to kill off a server that has problems.
  618. Priviledged.
  619. X.TP
  620. res[tart] { all | printer ... }
  621. X.br
  622. Attempt to start a new printer daemon. 
  623. This is useful when some abnormal condition causes the daemon to
  624. die unexpectedly leaving jobs in the queue.
  625. X.I Lpq
  626. will report that there is no daemon present when this condition occurs. 
  627. X.TP
  628. stat[us] [ terse ] [ all ] [ printer ... ]
  629. Display the status of daemons and queues on the local machine.
  630. If 'terse' is given, then any printers with printing and queueing both
  631. enabled with no entries in the spool queue, will not be displayed.
  632. X.TP
  633. t[opq] printer [ jobnum ... ] [ user ... ]
  634. X.br
  635. Place the jobs in the order listed at the top of the printer queue.
  636. It does this by boosting them to priority A,
  637. and then reordering the priority A jobs.
  638. Priviledged.
  639. X.TP
  640. rem[ote] lpc command
  641. X.br
  642. XExecute the lpc command on the remote host for the printer.
  643. XFor example,
  644. to restart all queues that have remote entries on the current host,
  645. X.I "remote start all"
  646. can be used;
  647. to disable them
  648. X.I "remote disable all"
  649. can be used.
  650. X.TP
  651. lpq { lpq options }
  652. X.br
  653. Run
  654. X.I lpq
  655. from inside the 
  656. X.I lpc
  657. program.
  658. X.TP
  659. lprm { lprm options }
  660. X.br
  661. Run
  662. X.I lprm
  663. from inside the 
  664. X.I lpc
  665. program.
  666. X.TP
  667. lpd
  668. X.br
  669. determines the if the LPD daemon process is running,
  670. and if the UNIX /dev/printer socket is active.
  671. This is handy to determine if the LPD daemon was killed or
  672. committed suicide due to abnormal conditions.
  673. X.TP
  674. clean { all | printer ... }
  675. X.br
  676. Remove all files beginning with ``cf'', ``tf'', or ``df''
  677. from the specified printer queue(s) on the local machine.
  678. X.IP "\fB\-D\fR[\fIn\fR]"
  679. XEnables display of debugging information.
  680. The 
  681. X.B \-D\fIn\fR
  682. X\fRsets debugging information to level
  683. X.I n
  684. X(n is a single digit).
  685. X.IP "\fB\-X"
  686. Use an Xperimental version of LPD if the software has been compiled
  687. with the appropriate support;
  688. ignored otherwise.
  689. X.SH FILES
  690. X.nf
  691. X.ta \w'/etc/printcap           'u
  692. X/etc/printcap    printer description file
  693. X/etc/printer_perms    printer permissions
  694. X/usr/spool/*    spool directories
  695. X/usr/spool/*/lock    lock file for queue control
  696. X.fi
  697. X.SH "SEE ALSO"
  698. lpd(8),
  699. lpr(1),
  700. lpq(1),
  701. lprm(1),
  702. printcap(5),
  703. printers(1),
  704. printer(1)
  705. X.br
  706. X.I "PLP- The Public Line Printer Spooler" ,
  707. Patrick Powell,
  708. U. Minnesota.
  709. X.SH DIAGNOSTICS
  710. X.nf
  711. Most of the diagnostics are self explanatory.
  712. If you are puzzled over the exact cause of failure,
  713. set the debugging level high and run again.
  714. The debugging information will 
  715. attempt to pinpoint the exact cause of failure.
  716. X.fi
  717. X.SH "HISTORY"
  718. X.PP
  719. The PLP is a reverse engineered version of the Berkeley 4.3BSD Line Printer
  720. Spooler,
  721. done in 1988 at the University of Minnesota.
  722. It has many advanced features which are described in
  723. X.I "PLP - The Public Line Printer Spooler"
  724. by
  725. Patrick Powell,
  726. Department of Computer Science,
  727. University of Minnesota.
  728. END_OF_FILE
  729. if test 5371 -ne `wc -c <'man/lpc.1'`; then
  730.     echo shar: \"'man/lpc.1'\" unpacked with wrong size!
  731. fi
  732. # end of 'man/lpc.1'
  733. fi
  734. if test -f 'man/printcap.5' -a "${1}" != "-c" ; then 
  735.   echo shar: Will not clobber existing file \"'man/printcap.5'\"
  736. else
  737. echo shar: Extracting \"'man/printcap.5'\" \(6334 characters\)
  738. sed "s/^X//" >'man/printcap.5' <<'END_OF_FILE'
  739. X.TH PRINTCAP 5 "19 Mar 1988" "U-MN PLP"
  740. X.ig
  741. X$Header: printcap.5,v 2.2 88/05/19 07:42:43 papowell Locked $
  742. X$Log:    printcap.5,v $
  743. Revision 2.2  88/05/19  07:42:43  papowell
  744. Added several more flags
  745. X
  746. Revision 2.1  88/05/09  10:08:53  papowell
  747. PLP: Released Version
  748. X
  749. Revision 1.2  88/05/09  10:02:04  papowell
  750. added :ab: flag, controls effect of -h option
  751. X
  752. Revision 1.1  88/04/28  10:58:58  papowell
  753. Initial revision
  754. X
  755. X..
  756. X.SH NAME
  757. printcap \- printer capability data base
  758. X.SH SYNOPSIS
  759. X/etc/printcap
  760. X.SH DESCRIPTION
  761. X.I Printcap
  762. is a simplified version of the
  763. X.IR termcap (5)
  764. data base
  765. used to describe line printers.  The spooling system accesses the
  766. X.I printcap
  767. file every time it is used, allowing dynamic
  768. addition and deletion of printers.  Each entry in the data base
  769. is used to describe one printer.  This data base may not be
  770. substituted for, as is possible for 
  771. X.IR termcap ,
  772. because it may allow accounting to be bypassed.
  773. X.PP
  774. The default printer is normally 
  775. X.IR lp ,
  776. though the environment variable PRINTER
  777. may be used to override this.  Each spooling utility supports an option,
  778. X.BI \-P printer,
  779. to allow explicit naming of a destination printer.
  780. X.PP
  781. Refer to the
  782. X.ul
  783. X4.2BSD Line Printer Spooler Manual
  784. for a complete discussion on how setup the database for a given printer.
  785. X.SH CAPABILITIES
  786. The database is a simplified form of the
  787. X.I termcap (5)
  788. database.
  789. The entries can be strings
  790. X(:st=string:),
  791. positive integer values
  792. X(:nu#12:),
  793. or flags
  794. X(:fl: to set,
  795. X:fl@: to clear).
  796. The following list the entries and the main users of them.
  797. Use
  798. X.B A
  799. stands for
  800. all programs,
  801. and is commonly used by several programs.
  802. XFor example,
  803. the
  804. X.B lf
  805. X(lock file) entry is used by most programs to determine the state of the
  806. spool queue.
  807. X.B R
  808. stands for
  809. X.IR lpr ,
  810. and is used by lpr for spooling purposes;
  811. X.B D
  812. stands for
  813. X.IR lpd ,
  814. and is used by lpd for controlling unspooling;
  815. X.B P
  816. stands for accounting information and is used by
  817. X.I pac
  818. or other programs.
  819. Note that when the a filter is invoked by lpd or lpr,
  820. the printcap entry will be available as the
  821. X.B PRINTCAP
  822. environment variable.
  823. X.nf
  824. X
  825. X.ta \w'\0\0\0\0'u +\w'\0\0\0\0'u +\w'Type 'u +\w'Default 'u +4n +4n +4n 8i
  826. X\fBFL    Use    Type    Default    Description\fR
  827. XXf    D    str    NULL    output filter for format X used by lpd
  828. XXe    R    str    NULL    prefilter for format X  used by lpr
  829. ab    D    bool    false    always print banner, ignore lpr -h option
  830. af    D    str    NULL    name of accounting file
  831. bp    D    str    NULL    banner printing program (see ep)
  832. br    D    num    none    if lp is a tty, set the baud rate (see ty)
  833. cf    D    str    NULL    cifplot data filter
  834. co    P    num    20    cost in dollars per thousand pages
  835. df    D    str    NULL    tex data filter (DVI format)
  836. ep    D    str    NULL    end of job banner printer
  837. fc    D    num    0    if lp is a tty, clear flag bits (see ty)
  838. fd    D    bool    false    no forwarded jobs accepted
  839. ff    D    str    ``\ef''    string to send for a form feed
  840. fj    D    bool    false    send control file first to remote site
  841. fo    D    bool    false    print a form feed when device is opened
  842. fs    D    num    0    like `fc' but set bits (see ty)
  843. fx    R    str    ``flp''    valid output filter formats
  844. gf    D    str    NULL    graph data filter (plot (3X) format)
  845. if    D    str    NULL    name of text filter which does accounting
  846. ld    D    str    NULL    leader string printed on printer open
  847. lf    A    str    ``log''    error log file (servers, filters and prefilters)
  848. lh    D    bool    false    long hostname control file format
  849. ln    R    str    NULL    groups allowed to use LPR -s (link), -r (remove)
  850. lo    A    str    ``lock''    name of lock file
  851. lp    D    str    NULL    device name to open for output
  852. mx    R    num    1000    maximum job size (1KB blocks, 0 = unlimited)
  853. nf    D    str    NULL    DITROFF data filter
  854. nw    A    bool    false    networked or distributed file system    
  855. of    D    str    NULL    name of OF filter program
  856. pl    D    num    66    page length (in lines)
  857. pr    RD    str    ``/bin/pr''    pr program for p format
  858. pw    D    num    132    page width (in characters)
  859. ps    A    str    NULL    printer status file name
  860. px    D    num    0    page width in pixels (horizontal)
  861. py    D    num    0    page length in pixels (vertical)
  862. qh    D    str    NULL    unspooler program, instead of normal unspooler
  863. rf    D    str    NULL    filter for printing FORTRAN style text files
  864. rm    A    str    NULL    machine name for remote printer
  865. rp    A    str    NULL    remote printer name argument
  866. rw    D    bool    false    open the printer for reading and writing
  867. sb    D    bool    false    short banner (one line only)
  868. sc    R    bool    false    suppress multiple copies
  869. sd    A    str    NULL    spool directory
  870. sf    D    bool    false    suppress form feeds separating multiple jobs
  871. sh    D    bool    false    suppress headers and/or banner page
  872. st    A    str    ``status''    queue server status file name
  873. tf    D    str    NULL    troff data filter (C/A/T phototypesetter)
  874. tr    D    str    NULL    trailer string to print when queue empties
  875. ty    D    str    NULL    stty form to set printer line
  876. vf    D    str    NULL    (Versatek) raster image filter
  877. xc    D    num    0    if lp is a tty, clear local mode bits (see ty)
  878. xs    D    num    0    like `xc' but set bits (see ty)
  879. xt    R    str    NULL    formats to check for printable files
  880. xu    A    str    NULL    additional printer_perms file for this queue
  881. X.fi
  882. X.PP
  883. By convention,
  884. all output filter names have for form
  885. X.B Xf,
  886. where
  887. X.B X
  888. is the lower case letter corresponding to the lpr formatting option.
  889. The
  890. X.B if
  891. and
  892. X.B of
  893. filters are the standard output filters.
  894. The filter capabilities have been extended by providing a
  895. X.I prefilter
  896. capability.
  897. The names of prefilters have the form
  898. X.B Xe,
  899. and are specified in the same manner as the other filters.
  900. If a prefilter is specified,
  901. X.I lpr
  902. will run the input files through the prefilter,
  903. and spool the output of the prefilter for
  904. disposition.
  905. X.SH "TY (STTY) OPTIONS"
  906. X.PP
  907. The following
  908. X.IR stty (1)
  909. options are recognized by the
  910. X.B ty
  911. X(stty) printcap entry,
  912. and can be used to set serial line characteristics for the printer.
  913. X.nf
  914. X.ta 16n +16n +16n +16n +16n +16n +16n +16n +16n
  915. bs0    bs1    [-]cbreak    cooked    cr0    
  916. cr1    cr2    cr3    [-]decctlq    [-]echo    
  917. X[-]even    ff0    ff1    [-]lcase    [-]litout    
  918. nl0    nl1    nl2    nl3    [-]nl    
  919. X[-]noflsh    new    [-]nohang    old    [-]odd    
  920. X[-]raw    start    stop    tab0    tab1    
  921. tab2    [-]tabs    [-]tandem    tek    ti700    
  922. X[-]tilde    tn300    tty33    tty37    vt05    
  923. X.fi
  924. X.SH "SEE ALSO"
  925. termcap(5),
  926. lpc(8),
  927. lpd(8),
  928. pac(8),
  929. lpr(1),
  930. lpq(1),
  931. lprm(1)
  932. X.br
  933. X.I "PLP - The Public Line Printer Spooler",
  934. by
  935. Patrick Powell,
  936. University of Minnesota.
  937. X.fi
  938. X.SH "HISTORY"
  939. X.PP
  940. The PLP is a reverse engineered version of the Berkeley 4.3BSD Line Printer
  941. Spooler,
  942. done in 1988 at the University of Minnesota.
  943. It has many advanced features which are described in
  944. X.I "PLP - The Public Line Printer Spooler"
  945. by
  946. Patrick Powell,
  947. Department of Computer Science,
  948. University of Minnesota.
  949. END_OF_FILE
  950. if test 6334 -ne `wc -c <'man/printcap.5'`; then
  951.     echo shar: \"'man/printcap.5'\" unpacked with wrong size!
  952. fi
  953. # end of 'man/printcap.5'
  954. fi
  955. if test -f 'src/getopt.c' -a "${1}" != "-c" ; then 
  956.   echo shar: Will not clobber existing file \"'src/getopt.c'\"
  957. else
  958. echo shar: Extracting \"'src/getopt.c'\" \(6106 characters\)
  959. sed "s/^X//" >'src/getopt.c' <<'END_OF_FILE'
  960. X/***************************************************************************
  961. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  962. X ***************************************************************************
  963. X * MODULE: Getopt.c
  964. X * Getopt(3) implementation; modified so that the first time it is
  965. X * called it sets "Name" to argv[0];
  966. X ***************************************************************************
  967. X * Revision History: Created Fri Jan  1 15:36:11 CST 1988
  968. X * $Log:    getopt.c,v $
  969. X * Revision 3.1  88/06/18  09:34:13  papowell
  970. X * Version 3.0- Distributed Sat Jun 18 1988
  971. X * 
  972. X * Revision 2.1  88/05/09  10:08:08  papowell
  973. X * PLP: Released Version
  974. X * 
  975. X * Revision 1.4  88/04/15  10:45:19  papowell
  976. X * When checking for alternate flag chars, got a && mixed up with || test
  977. X * 
  978. X * Revision 1.3  88/04/07  12:27:20  papowell
  979. X * Added ability to detect '+' options
  980. X * 
  981. X * Revision 1.2  88/04/06  12:13:51  papowell
  982. X * Minor updates, changes in error message formats.
  983. X * Elimination of the AF_UNIX connections, use AF_INET only.
  984. X * Better error messages.
  985. X * 
  986. X * Revision 1.1  88/03/01  11:08:25  papowell
  987. X * Initial revision
  988. X * 
  989. X ***************************************************************************/
  990. X#ifndef lint
  991. static char id_str1[] =
  992. X    "$Header: getopt.c,v 3.1 88/06/18 09:34:13 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  993. X#endif lint
  994. X/***************************************************************************
  995. X * int Getopt ( argc, argv, optstring)
  996. X *     int argc;
  997. X *        char **argv, *opstring;
  998. X * int Optind, Opterr;
  999. X * char *Optarg;
  1000. X * extern char *Name; 
  1001. X * Returns: EOF if no more options left;
  1002. X *    '?' if option not in optstring;
  1003. X *    option character if in optstr.
  1004. X *      if option char is followed by : in opstring, an argument is required,
  1005. X *        and Optarg will point to the option argument
  1006. X *      if option char is followed by ? in opstring, an argument is optional
  1007. X *        and Optarg will point to the argument if it immediately follows
  1008. X *        the option character
  1009. X *    If there are a special set of characters (such as "+" ) that should also
  1010. X *    be allowed to indicate flags, these are specified in the Opt_flag,
  1011. X *  which indicates that the character is allowed to act as an option flag
  1012. X * 
  1013. X * 
  1014. X * Getopt places the argv index of the next argument to be processed in
  1015. X * Optind. Because Optind is external, it is automatically set to zero
  1016. X * before the first call to Getopt.  When all the options have been
  1017. X * processed (i.e., up to the first non-option argument), Getopt returns
  1018. X * EOF.  The special option -- may be used to delimit the end of the
  1019. X * options; EOF will be returned, and -- will be skipped.
  1020. X * 
  1021. X * Getopt prints an error message on stderr and returns the offending
  1022. X * character when it encounters an option letter that is not included in
  1023. X * optstring.  This error message may be disabled by setting Opterr to a
  1024. X * non-zero value.
  1025. X * 
  1026. X * Side Effect:  when Getopt is called and Optind is 0, Name is set to
  1027. X * argv[0].  This allows pulling the program Name from the file.
  1028. X * Errors: if an argument is specified and none is there, then Optarg is
  1029. X * set to NULL
  1030. X * 
  1031. X ***************************************************************************/
  1032. X
  1033. X#include <stdio.h>
  1034. X
  1035. int    Optind = 0;            /* next argv to process */
  1036. int    Opterr = 0;            /* Non-zero disables errors msgs */
  1037. char    *Optarg = NULL;            /* Pointer to option argument */
  1038. static    char *next_opt = NULL;    /* pointer to next option char */
  1039. extern  char *Name;                /* the program Name */
  1040. extern  char *index();            /* find character in string */
  1041. char *Opt_flag;            /* first character is a flag */
  1042. X
  1043. int
  1044. Getopt(argc, argv, optstring)
  1045. X    int argc;                    /* number of arguments */
  1046. X    char **argv;                /* array or arguments */
  1047. X    char *optstring;            /* option string */
  1048. X{
  1049. X    int option;                /* current option found */
  1050. X    char *match;            /* matched option in optstring */
  1051. X
  1052. X    if( Optind == 0 ){
  1053. X        /* set up the Name variable for error messages */
  1054. X        Name = argv[0];
  1055. X        Optind = 1;
  1056. X    }
  1057. X    if ( next_opt == NULL || *next_opt == '\0' ) {
  1058. X        /* No more arguments left in current or initial string */
  1059. X        if ( Optind >= argc ){
  1060. X            return( EOF );
  1061. X        }
  1062. X        next_opt = argv[Optind];
  1063. X        if( next_opt[0] != '-'
  1064. X            && (Opt_flag == 0 || index( Opt_flag, next_opt[0] ) == 0) ){
  1065. X            /* we hit the last argument */
  1066. X            return( EOF );
  1067. X        }
  1068. X        /*
  1069. X         * we have a '-' or a flag as first character
  1070. X         */
  1071. X        if( next_opt[0] == '-' ){
  1072. X            ++next_opt;
  1073. X        }
  1074. X        /* Single '-', end of opts */
  1075. X        if ( *next_opt == '\0' ){
  1076. X            return( EOF );
  1077. X        }
  1078. X        Optind++;
  1079. X    }
  1080. X    option = *next_opt++;
  1081. X    /*
  1082. X     * Case of '--',  Force end of options
  1083. X     */
  1084. X    if ( option == '-' ){
  1085. X        return( EOF );
  1086. X    }
  1087. X    /*
  1088. X     * See if option is in optstring
  1089. X     */
  1090. X    if ( (match = index(optstring, option)) == NULL ) {
  1091. X        if ( Opterr == 0 ){
  1092. X            (void)fprintf(stderr, "%s: Illegal option '%c'\n", Name, option);
  1093. X        }
  1094. X        return( '?' );
  1095. X    }
  1096. X    /*
  1097. X     * Argument always follows this option
  1098. X     */
  1099. X    if ( match[1] == ':' ) {
  1100. X        /*
  1101. X         * Set Optarg to proper value
  1102. X         */
  1103. X        if ( *next_opt != '\0' ){
  1104. X            Optarg = next_opt;
  1105. X        } else if ( Optind < argc ) {
  1106. X            Optarg = argv[Optind++];
  1107. X        } else {
  1108. X            if ( Opterr == 0 ){
  1109. X                (void)fprintf(stderr,
  1110. X                    "%s: missing argument for '%c'\n",Name,option);
  1111. X                Optarg = NULL;
  1112. X            }
  1113. X        }
  1114. X        if( Optarg != NULL && Optarg[0] == '-' ){
  1115. X            if ( Opterr == 0 ){
  1116. X                (void)fprintf(stderr,
  1117. X                    "%s: missing argument for '%c'\n",Name,option);
  1118. X                Optarg = NULL;
  1119. X            }
  1120. X        }
  1121. X        next_opt = NULL;
  1122. X    }
  1123. X    /*
  1124. X     * Argument sometimes follows this option
  1125. X     */
  1126. X    if ( match[1] == '?' ) {
  1127. X        /*
  1128. X         * Set Optarg to proper value
  1129. X         */
  1130. X        if ( *next_opt != '\0' ){
  1131. X            Optarg = next_opt;
  1132. X        } else {
  1133. X            Optarg = NULL;
  1134. X        }
  1135. X        next_opt = NULL;
  1136. X    }
  1137. X    return( option );
  1138. X}
  1139. X
  1140. X/***************************************************************************
  1141. X * Push_opt()
  1142. X * Some flags may have an optional argument.  The Push_opt is used to
  1143. X * push the argument that would normally be supplied back.  The assumption
  1144. X * is that the argument will start with a - sign, i.e.- be a flag,
  1145. X * and be the current value of Optind
  1146. X ***************************************************************************/
  1147. Push_opt()
  1148. X{
  1149. X    next_opt = 0;
  1150. X    Optind = Optind - 1;
  1151. X}
  1152. END_OF_FILE
  1153. if test 6106 -ne `wc -c <'src/getopt.c'`; then
  1154.     echo shar: \"'src/getopt.c'\" unpacked with wrong size!
  1155. fi
  1156. # end of 'src/getopt.c'
  1157. fi
  1158. if test -f 'src/lpr_canprint.c' -a "${1}" != "-c" ; then 
  1159.   echo shar: Will not clobber existing file \"'src/lpr_canprint.c'\"
  1160. else
  1161. echo shar: Extracting \"'src/lpr_canprint.c'\" \(6092 characters\)
  1162. sed "s/^X//" >'src/lpr_canprint.c' <<'END_OF_FILE'
  1163. X/***************************************************************************
  1164. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  1165. X ***************************************************************************
  1166. X * MODULE: lpr_canprint.c
  1167. X * Checks to see if a file is printable
  1168. X * This will be a system dependent function.  If you have setreuid(),
  1169. X * you can implement this in a fairly effective manner, as the file
  1170. X * open and stat() is done as the user, not as root.
  1171. X * The "is_exec" and "is_arch" functions are very system dependent.
  1172. X * If you have file(1) available,  check to see how it determines the file
  1173. X * types.  This may be more bizzare than you expect.
  1174. X ***************************************************************************
  1175. X * Revision History: Created Sat Jan 30 15:17:59 CST 1988
  1176. X * $Log:    lpr_canprint.c,v $
  1177. X * Revision 3.2  88/06/24  17:55:54  papowell
  1178. X * MODS for VAX 4.3BSD UNIX
  1179. X * 
  1180. X * Revision 3.1  88/06/18  09:34:51  papowell
  1181. X * Version 3.0- Distributed Sat Jun 18 1988
  1182. X * 
  1183. X * Revision 2.2  88/05/19  10:34:15  papowell
  1184. X * Fixed open() calls to have a 0 parameter, ie: open(f, perms, 0), where needed
  1185. X * 
  1186. X * Revision 2.1  88/05/09  10:09:06  papowell
  1187. X * PLP: Released Version
  1188. X * 
  1189. X * Revision 1.9  88/05/06  07:08:54  papowell
  1190. X * Modified getwd() call so that a setreuid() is done first.  This way there
  1191. X * are no problems with root perms on different systems.
  1192. X * 
  1193. X * Revision 1.8  88/04/28  17:31:59  papowell
  1194. X * fixed the setreuid() calls so that they will work on several systems
  1195. X * very odd behaviour.  Also modified the access() calls.
  1196. X * 
  1197. X * Revision 1.7  88/04/28  11:03:30  papowell
  1198. X * Modified the "printability" check to only do known text formats.
  1199. X * The XT flag is now used to force a check, rather than not forced a check
  1200. X * 
  1201. X * Revision 1.5  88/04/07  09:10:09  papowell
  1202. X * Apollo Workstation Modifications
  1203. X * 
  1204. X * Revision 1.4  88/04/06  12:13:14  papowell
  1205. X * Minor updates, changes in error message formats.
  1206. X * Elimination of the AF_UNIX connections, use AF_INET only.
  1207. X * Better error messages.
  1208. X * 
  1209. X * Revision 1.3  88/03/25  15:00:23  papowell
  1210. X * Debugged Version:
  1211. X * 1. Added the PLP control file first transfer
  1212. X * 2. Checks for MX during file transfers
  1213. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  1214. X *     apparently they open files and then assume that they will stay
  1215. X *     open.
  1216. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  1217. X * 
  1218. X * Revision 1.2  88/03/11  19:27:52  papowell
  1219. X * Minor Changes, Updates
  1220. X * 
  1221. X * Revision 1.1  88/03/01  11:08:43  papowell
  1222. X * Initial revision
  1223. X * 
  1224. X ***************************************************************************/
  1225. X#ifndef lint
  1226. static char id_str1[] =
  1227. X    "$Header: lpr_canprint.c,v 3.2 88/06/24 17:55:54 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  1228. X#endif lint
  1229. X
  1230. X#include "lpr.h"
  1231. extern long lseek();
  1232. X
  1233. X/***************************************************************************
  1234. X * Is_printable(  char *f )
  1235. X * Test to see if this is a printable file.
  1236. X * Return: 0 if unprintable; 1 otherwise
  1237. X ***************************************************************************/
  1238. static char errmsg[] = "File '%s' not printed: %s";
  1239. X
  1240. int
  1241. Is_printable( file, statb )
  1242. X    char *file;
  1243. X    struct stat *statb;    /* file status */
  1244. X{
  1245. X    char buf[BUFSIZ];
  1246. X    int fd = -1;        /* file descriptor */
  1247. X    int n, i, c;        /* Acme Integers, Inc. */
  1248. X    int succ = 0;
  1249. X    int euid = geteuid();    /* euid of process */
  1250. X
  1251. X    /*
  1252. X     * If you have setreuid, you are very lucky; do all this as the user
  1253. X     */
  1254. X    if( access(file, F_OK | R_OK) < 0){
  1255. X        Warnmsg(errmsg, file, "cannot access it");
  1256. X    } else if(Remove && access(file, F_OK | R_OK | W_OK ) < 0){
  1257. X        Warnmsg(errmsg, file, "cannot remove it");
  1258. X     } else {
  1259. X        /*
  1260. X         * do the rest of tests as USER
  1261. X         */
  1262. X        if( euid == 0 ){
  1263. X            Set_uid( getuid() );
  1264. X        }
  1265. X        if ((fd = open(file, O_RDONLY, 0)) < 0) {
  1266. X            Warnmsg(errmsg, file, "cannot open it");
  1267. X        } else if (fstat(fd, statb) < 0) {
  1268. X            Warnmsg(errmsg, file, "cannot stat it");
  1269. X        } else if ((statb->st_mode & S_IFMT) == S_IFDIR) {
  1270. X            Warnmsg(errmsg, file, "it is a directory");
  1271. X        } else if (statb->st_size == 0) {
  1272. X            Warnmsg(errmsg, file, "it is an empty file");
  1273. X        } else if( (n = read(fd, buf, sizeof(buf))) <= 0 ){
  1274. X            Warnmsg(errmsg, file, "cannot read it");
  1275. X        } else if( Binary || Format == 'l' ){
  1276. X            succ = 1;
  1277. X        } else if( !(index( "fpr", Format) || (XT && index( XT, Format)) )){
  1278. X            /*
  1279. X             * We don't have to do the following checks, applicable to
  1280. X             * text files.
  1281. X             */
  1282. X                succ = 1;
  1283. X        } else if( is_exec(fd, buf, n) ){
  1284. X            Warnmsg(errmsg, file, "executable program");
  1285. X        } else if( is_arch(fd, buf, n)){
  1286. X            Warnmsg(errmsg, file, "archive file");
  1287. X        } else {
  1288. X            succ = 1;
  1289. X            /*
  1290. X             * check for clean and lovely files, up to the first block
  1291. X             */
  1292. X            for( i = 0; i < n; ++i ){
  1293. X                c = buf[i];
  1294. X                if(!isascii(c) || !( c == '\b' || isprint(c) || isspace(c))){
  1295. X                    Warnmsg(errmsg, file, "it is a garbage file");
  1296. X                    succ = 0;
  1297. X                        break;
  1298. X                }
  1299. X            }
  1300. X        }
  1301. X        if( succ == 0 ){
  1302. X            (void)close(fd);
  1303. X            fd = -1;
  1304. X        } else if( lseek( fd, 0L, 0 ) < 0 ){
  1305. X            logerr( XLOG_INFO, "Is_printable: lseek failed %s", file );
  1306. X            (void)close(fd);
  1307. X            fd = -1;
  1308. X        }
  1309. X        if( euid == 0 ){
  1310. X            Clear_uid();
  1311. X        }
  1312. X    }
  1313. X    return(fd);
  1314. X}
  1315. X/*
  1316. X * The is_exec and is_arch are system dependent functions
  1317. X * which check if a file is an executable or archive file,
  1318. X * based on the information in the header.
  1319. X */
  1320. X
  1321. X#ifndef    NO_A_OUT_H
  1322. X#include <a.out.h>
  1323. X#endif    NO_A_OUT_H
  1324. X#include <ar.h>
  1325. X
  1326. static int
  1327. is_exec( fd, buf, n )
  1328. X    int fd;
  1329. X    char *buf;
  1330. X    int n;
  1331. X{
  1332. X    int i;
  1333. X#ifdef IS_DATAGEN
  1334. X#    include <sgs.h>
  1335. X    struct header header;
  1336. X
  1337. X    i = 0;
  1338. X    if( lseek(fd, (long)0, 0 ) < 0 ){
  1339. X        logerr(XLOG_INFO,"is_exec: cannot lseek");
  1340. X    }
  1341. X    if( read(fd, (char *)&header, sizeof(header) ) == sizeof(header)  ){
  1342. X        i =  ISMAGIC(header.magic_number);
  1343. X    }
  1344. X#endif IS_DATAGEN
  1345. X#if defined(IS_VAX) || defined(IS_SUN)
  1346. X
  1347. X    i = 0;
  1348. X    if( n >= sizeof( struct exec ) ){
  1349. X        i = !(N_BADMAG( (*(struct exec *)buf) ));
  1350. X    }
  1351. X#endif
  1352. X#if defined( IS_UMAX ) || defined( NO_A_OUT_H )
  1353. X    i = 0;
  1354. X#endif
  1355. X    return( i );
  1356. X}
  1357. X
  1358. static int
  1359. is_arch( fd, buf, n )
  1360. X    int fd;
  1361. X    char *buf;
  1362. X{
  1363. X    return( !strncmp( buf, ARMAG, strlen( ARMAG )) );
  1364. X}
  1365. END_OF_FILE
  1366. if test 6092 -ne `wc -c <'src/lpr_canprint.c'`; then
  1367.     echo shar: \"'src/lpr_canprint.c'\" unpacked with wrong size!
  1368. fi
  1369. # end of 'src/lpr_canprint.c'
  1370. fi
  1371. if test -f 'src/lpr_temp.c' -a "${1}" != "-c" ; then 
  1372.   echo shar: Will not clobber existing file \"'src/lpr_temp.c'\"
  1373. else
  1374. echo shar: Extracting \"'src/lpr_temp.c'\" \(5731 characters\)
  1375. sed "s/^X//" >'src/lpr_temp.c' <<'END_OF_FILE'
  1376. X/***************************************************************************
  1377. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  1378. X ***************************************************************************
  1379. X * MODULE: lpr_temp.c
  1380. X * Routines to manage the Temp_file array
  1381. X ***************************************************************************
  1382. X * Revision History: Created Sat Jan 30 12:31:45 CST 1988
  1383. X * $Log:    lpr_temp.c,v $
  1384. X * Revision 3.1  88/06/18  09:35:03  papowell
  1385. X * Version 3.0- Distributed Sat Jun 18 1988
  1386. X * 
  1387. X * Revision 2.2  88/05/14  10:18:36  papowell
  1388. X * Use long format for job file names;
  1389. X * Added 'fd', no forward flag;
  1390. X * Control file has to have hostname and origination agree.
  1391. X * 
  1392. X * Revision 2.1  88/05/09  10:09:28  papowell
  1393. X * PLP: Released Version
  1394. X * 
  1395. X * Revision 1.4  88/05/06  07:07:58  papowell
  1396. X * Fixed up error messages.
  1397. X * 
  1398. X * Revision 1.3  88/03/25  15:00:45  papowell
  1399. X * Debugged Version:
  1400. X * 1. Added the PLP control file first transfer
  1401. X * 2. Checks for MX during file transfers
  1402. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  1403. X *     apparently they open files and then assume that they will stay
  1404. X *     open.
  1405. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  1406. X * 
  1407. X * Revision 1.2  88/03/11  19:29:54  papowell
  1408. X * Minor Changes, Updates
  1409. X * 
  1410. X * Revision 1.1  88/03/01  11:08:52  papowell
  1411. X * Initial revision
  1412. X * 
  1413. X ***************************************************************************/
  1414. X#ifndef lint
  1415. static char id_str1[] =
  1416. X    "$Header: lpr_temp.c,v 3.1 88/06/18 09:35:03 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  1417. X#endif lint
  1418. X
  1419. X#include "lpr.h"
  1420. X
  1421. X/***************************************************************************
  1422. X * Get_tmp_data()
  1423. X *   Generate the name of a data file
  1424. X * Get_cf()
  1425. X *   return the name of the control file.
  1426. X * Add_temp( char *s )
  1427. X *   Add the name of a file to the temporary file list
  1428. X * Remove_temp()
  1429. X *   Unlink all the files in the Temp_file[] list
  1430. X ***************************************************************************/
  1431. X
  1432. X/***************************************************************************
  1433. X * Get_tmp_data()
  1434. X * Generate the name of a data file
  1435. X * The name has the form: df<seq><job><host>
  1436. X ***************************************************************************/
  1437. static int seq;
  1438. X
  1439. char *
  1440. Get_tmp_data()
  1441. X{
  1442. X    char buf[BUFSIZ];    /* Big Buffers, Inc. */
  1443. X    int c;                /* ACME Integers, Inc. */
  1444. X    char *sp;            /* ACME Pointers, Inc. */
  1445. X    char *st = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
  1446. X
  1447. X    /*
  1448. X     * convert sequence number to A-Z, a-z
  1449. X     */
  1450. X    if( seq >= strlen(st) ){
  1451. X        Diemsg( "too many input files, split job up" );
  1452. X    }
  1453. X    c = st[seq];
  1454. X    ++seq;
  1455. X    /*
  1456. X     * generate name
  1457. X     */
  1458. X    (void)sprintf(buf, "df%c%03d%s", c, Job_number, Host );
  1459. X    if(Debug>3)log(XLOG_DEBUG,"Get_tmp_data: %s",buf);
  1460. X
  1461. X    /*
  1462. X     * Add to list of temporary files to be removed in case of error
  1463. X     */
  1464. X    sp = Add_temp( buf );
  1465. X    return( sp );
  1466. X}
  1467. X
  1468. X
  1469. X/***************************************************************************
  1470. X * Get_cf()
  1471. X * return the name of the control file.  This has the form
  1472. X * tf<Priority><Sequence><Host>
  1473. X ***************************************************************************/
  1474. char *
  1475. Get_cf()
  1476. X{
  1477. X    char buf[BUFSIZ];    /* Big Buffers, Inc. */
  1478. X    char *sp;            /* ACME Pointers and Buggy Whips */
  1479. X
  1480. X    (void)sprintf(buf, "tf%c%03d%s", Priority, Job_number, Host );
  1481. X    /*
  1482. X     * check to see that the job file name fits in the limits
  1483. X     */
  1484. X    if( strlen( buf ) >= CFNAMELEN ){
  1485. X        fatal( XLOG_INFO, "Get_cf: control file name too long '%s'",
  1486. X            buf);
  1487. X    }
  1488. X    if(Debug>3)log(XLOG_DEBUG,"Get_cf: control file %s",buf);
  1489. X    sp = Add_temp( buf );
  1490. X    return( sp );
  1491. X}
  1492. X
  1493. X/***************************************************************************
  1494. X * Add_temp( char *s )
  1495. X * Add the name of a file to the temporary file list
  1496. X * Note: these will be deleted on abnormal exit
  1497. X ***************************************************************************/
  1498. static char *Temp_space;
  1499. static int Temp_size;
  1500. X
  1501. char *
  1502. Add_temp( s )
  1503. X    char *s;
  1504. X{
  1505. X    int i;
  1506. X    char *sp;        /* ACME Pointers and Integers */
  1507. X
  1508. X    if( Temp_max == 0 ){
  1509. X        Temp_max = 10;
  1510. X        Temp_file = (char **)malloc( (unsigned)sizeof(char *) * Temp_max);
  1511. X        if( Temp_file == 0 ){
  1512. X            fatal( XLOG_INFO, "Add_temp: malloc Temp_file failed" );
  1513. X        }
  1514. X    }
  1515. X    if( Temp_max <= Temp_count ){
  1516. X        Temp_max += 10;
  1517. X        Temp_file = (char **)realloc((char *)Temp_file,
  1518. X            (unsigned)(sizeof(char *)*Temp_max));
  1519. X        if( Temp_file == 0 ){
  1520. X            fatal( XLOG_INFO, "Add_temp: realloc Temp_file failed" );
  1521. X        }
  1522. X    }
  1523. X    i = strlen( s ) + 1;
  1524. X    if( i > Temp_size ){
  1525. X        Temp_size = BUFSIZ;
  1526. X        Temp_space = malloc( BUFSIZ );
  1527. X        if( Temp_space == 0 ){
  1528. X            fatal( XLOG_INFO, "Add_temp: malloc Temp_space failed" );
  1529. X        }
  1530. X    }
  1531. X    sp = Temp_space;
  1532. X    (void)strcpy(Temp_space, s );
  1533. X    Temp_file[Temp_count] = sp;
  1534. X    ++Temp_count;
  1535. X    Temp_space += i;
  1536. X    Temp_size -= i;
  1537. X    if(Debug>5){
  1538. X        for(i=0;i<Temp_count;++i)log(XLOG_DEBUG,"temp %d %s",i,Temp_file[i]);
  1539. X    }
  1540. X    return( sp );
  1541. X}
  1542. X
  1543. X
  1544. X/***************************************************************************
  1545. X * Remove_temp()
  1546. X * Unlink all the files in the Temp_file[] list
  1547. X ***************************************************************************/
  1548. X
  1549. Remove_temp()
  1550. X{
  1551. X    char buf[BUFSIZ];    /* hold the full pathname */
  1552. X    int i;                /* ACME Integers, Inc. */
  1553. X    char *sd_end;        /* end of the SD name in buf */
  1554. X
  1555. X    if( Temp_count <= 0 || SD == 0 || *SD == 0
  1556. X        || (strlen(SD)+CFNAMELEN)> sizeof(buf) ){
  1557. X        return;
  1558. X    }
  1559. X    (void)strcpy(buf, SD );
  1560. X    (void)strcat(buf, "/" );
  1561. X    sd_end = &buf[strlen(buf)];
  1562. X    for(i = 0; i < Temp_count; ++i ){
  1563. X        (void)strcpy( sd_end, Temp_file[i] );
  1564. X        if(Debug>3)log(XLOG_DEBUG,"Remove_temp: removing temp file %s", buf );
  1565. X        if( unlink( buf ) < 0 ){
  1566. X            logerr(XLOG_INFO,"Remove_temp: cannot remove temp file %s", buf );
  1567. X        }
  1568. X    }
  1569. X}
  1570. END_OF_FILE
  1571. if test 5731 -ne `wc -c <'src/lpr_temp.c'`; then
  1572.     echo shar: \"'src/lpr_temp.c'\" unpacked with wrong size!
  1573. fi
  1574. # end of 'src/lpr_temp.c'
  1575. fi
  1576. if test -f 'src/servicereq.c' -a "${1}" != "-c" ; then 
  1577.   echo shar: Will not clobber existing file \"'src/servicereq.c'\"
  1578. else
  1579. echo shar: Extracting \"'src/servicereq.c'\" \(5963 characters\)
  1580. sed "s/^X//" >'src/servicereq.c' <<'END_OF_FILE'
  1581. X/***************************************************************************
  1582. X * U. Minnesota LPD Software * Copyright 1987, 1988, Patrick Powell
  1583. X ***************************************************************************
  1584. X * MODULE: servicereq.c
  1585. X * service requests to lpd
  1586. X ***************************************************************************
  1587. X * Revision History: Created Sat Jan  2 08:54:52 CST 1988
  1588. X * $Log:    servicereq.c,v $
  1589. X * Revision 3.1  88/06/18  09:35:39  papowell
  1590. X * Version 3.0- Distributed Sat Jun 18 1988
  1591. X * 
  1592. X * Revision 2.1  88/05/09  10:10:17  papowell
  1593. X * PLP: Released Version
  1594. X * 
  1595. X * Revision 1.3  88/04/06  12:12:48  papowell
  1596. X * Minor updates, changes in error message formats.
  1597. X * Elimination of the AF_UNIX connections, use AF_INET only.
  1598. X * Better error messages.
  1599. X * 
  1600. X * Revision 1.2  88/03/25  15:01:39  papowell
  1601. X * Debugged Version:
  1602. X * 1. Added the PLP control file first transfer
  1603. X * 2. Checks for MX during file transfers
  1604. X * 3. Found and fixed a mysterious bug involving the SYSLOG facilities;
  1605. X *     apparently they open files and then assume that they will stay
  1606. X *     open.
  1607. X * 4. Made sure that stdin, stdout, stderr was available at all times.
  1608. X * 
  1609. X * Revision 1.1  88/03/01  11:09:16  papowell
  1610. X * Initial revision
  1611. X * 
  1612. X ***************************************************************************
  1613. X * Description:
  1614. X * The LPD daemon waits for a request from an associated process using a socket.
  1615. X * The main lpd daemon forks a server process,  which connects to the
  1616. X * requesting process.  The two processes communicate over the socket. 
  1617. X * A message packet containing a request is the first information transferred.
  1618. X * Some requests will need to have error messages and diagnostics generated
  1619. X * by LPD sent to the user;  the "Echo_on_stdout" flag causes errors to be
  1620. X * echoed there as well.
  1621. X * The following operations are supported:
  1622. X *        \1Printer\n
  1623. X *             check the queue for jobs and print any found.
  1624. X *          -- acknowlege request and close socket
  1625. X *          -- start up the Printer
  1626. X *        \2Printer\n
  1627. X *            receive a job from another machine and queue it.
  1628. X *          -- a complex file transfer protocol is used to transfer files.
  1629. X *        \3Printer [users ...] [jobs ...]\n
  1630. X *            return the current state of the queue (short form).
  1631. X *          -- errors and diagnostics returned as well
  1632. X *        \4Printer [users ...] [jobs ...]\n
  1633. X *            return the current state of the queue (long form).
  1634. X *          -- errors and diagnostics returned as well
  1635. X *        \5Printer Person [users ...] [jobs ...]\n
  1636. X *            remove jobs from the queue.
  1637. X *          -- errors and diagnostics returned as well
  1638. X *        \6Printer Person operation
  1639. X *            enable/disable queueing, etc.
  1640. X *          -- errors and diagnostics returned as well
  1641. X ***************************************************************************/
  1642. X#ifndef lint
  1643. static char id_str1[] =
  1644. X    "$Header: servicereq.c,v 3.1 88/06/18 09:35:39 papowell Exp $ PLP Copyright 1988 Patrick Powell";
  1645. X#endif lint
  1646. X
  1647. X#include "lp.h"
  1648. X
  1649. static char    command[BUFSIZ];    /* command line buffer */
  1650. static char    *cmd_names[] = {
  1651. X    "ERROR",            /* 0 */
  1652. X    "Startprinter",        /* 1 */
  1653. X    "receive files",    /* 2 */
  1654. X    "display [short]",    /* 3 */
  1655. X    "display [long]",    /* 4 */
  1656. X    "remove job",        /* 5 */
  1657. X    "control operation"            /* 6 */
  1658. X};
  1659. X
  1660. X/****************************************************************
  1661. X * servicereq()
  1662. X *   1. Reads the first line from the socket
  1663. X *   2. Determine service request
  1664. X *   3. Call suitable dispatch function
  1665. X ****************************************************************/
  1666. servicereq()
  1667. X{
  1668. X    int n;            /* ACME Integer, Inc. */
  1669. X
  1670. X    /*
  1671. X     * use almost bombproof way to read command line from socket
  1672. X     */
  1673. X    n = bpread( 1, command, sizeof(command));
  1674. X    if(n < 2 ){
  1675. X        fatal(XLOG_INFO,"servicereq: bad command line");
  1676. X    }
  1677. X    Request = command[0];
  1678. X    if (Request < 1 || Request > 6 ){
  1679. X        fatal(XLOG_INFO,"servicereq: bad request (%d) %s",Request, &command[1]);
  1680. X    }
  1681. X    if (Debug>1)log( XLOG_DEBUG,"%s requests %d (%s) %s",From,Request,
  1682. X        cmd_names[Request],&command[1]);
  1683. X    splitline( &command[1] );
  1684. X    if( Request != REQ_CONTROL ){
  1685. X        /*
  1686. X         * extract Printer Name from command
  1687. X         */
  1688. X        Printer = Parms[0].str;
  1689. X        /*
  1690. X         * check to see if you can do the job
  1691. X         */
  1692. X        if(chkhost() == 0){
  1693. X            fatal(XLOG_INFO,"Host %s cannot access %s", From, Printer);
  1694. X        }
  1695. X    }
  1696. X    switch (Request) {
  1697. X    /*
  1698. X     * start Printer
  1699. X     */
  1700. X    case REQ_START:
  1701. X        /* signal the other end that you are doing the request */
  1702. X        putchar( 0 );        /* fd 1 is the socket */
  1703. X        (void)fflush(stdout);    /* send it */
  1704. X        (void)close(1);            /* disconnect */
  1705. X        if( dup2(0,1) < 0 ){
  1706. X            logerr_die(XLOG_INFO,"dup2 failed");
  1707. X        }
  1708. X        Startprinter();        /* start Printer */
  1709. X        break;
  1710. X    /*
  1711. X     * get remote jobs
  1712. X     */
  1713. X    case REQ_RECV:    /* get files from remote site */
  1714. X        recvfiles();
  1715. X        Startprinter();        /* start Printer */
  1716. X        break;
  1717. X    /*
  1718. X     * display current queue
  1719. X     */
  1720. X    case REQ_DSHORT:    /* display the queue (short form) */
  1721. X    case REQ_DLONG:        /* display the queue (long form) */
  1722. X        /*    echo errors on stdout as well as stderr */
  1723. X        Echo_on_stdout = 1;
  1724. X        Short_format = (REQ_DSHORT==Request);
  1725. X        Shift_parms(1);
  1726. X        (void)Displayq();
  1727. X        break;
  1728. X    /*
  1729. X     * remove job from queue
  1730. X     */
  1731. X    case REQ_REMOVE:    /* remove a job from the queue */
  1732. X        /*    echo errors on stdout as well as stderr */
  1733. X        Echo_on_stdout = 1;
  1734. X        Person = Parms[1].str;
  1735. X        Shift_parms(2);
  1736. X        rmjob();
  1737. X        break;
  1738. X    /*
  1739. X     * perform control function
  1740. X     */
  1741. X    case REQ_CONTROL:    /* remove a job from the queue */
  1742. X        Echo_on_stdout = 1;
  1743. X        Person = Parms[0].str;
  1744. X        Shift_parms(1);
  1745. X        (void)Control_ops();
  1746. X        break;
  1747. X    }
  1748. X}
  1749. X
  1750. X/**********************************************************************
  1751. X * chkhost()
  1752. X * check permissions to see if Host has access to the Printer
  1753. X * Return: 1 if permissions to use Printer, 0 otherwise
  1754. X **********************************************************************/
  1755. static int
  1756. chkhost()
  1757. X{
  1758. X    if( strcmp(From, Host) == 0    /* this Host */
  1759. X        ||( Permfile && *Permfile
  1760. X            && Checkperm(Permfile,From,(char*)0,Printer,(int*)0,(int*)0,0)) ){
  1761. X        return(1);
  1762. X    }
  1763. X    return(0);
  1764. X}
  1765. END_OF_FILE
  1766. if test 5963 -ne `wc -c <'src/servicereq.c'`; then
  1767.     echo shar: \"'src/servicereq.c'\" unpacked with wrong size!
  1768. fi
  1769. # end of 'src/servicereq.c'
  1770. fi
  1771. echo shar: End of archive 4 \(of 16\).
  1772. cp /dev/null ark4isdone
  1773. MISSING=""
  1774. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
  1775.     if test ! -f ark${I}isdone ; then
  1776.     MISSING="${MISSING} ${I}"
  1777.     fi
  1778. done
  1779. if test "${MISSING}" = "" ; then
  1780.     echo You have unpacked all 16 archives.
  1781.     rm -f ark[1-9]isdone ark[1-9][0-9]isdone
  1782. else
  1783.     echo You still need to unpack the following archives:
  1784.     echo "        " ${MISSING}
  1785. fi
  1786. ##  End of shell archive.
  1787. exit 0
  1788.  
  1789. -- 
  1790. Please send comp.sources.unix-related mail to rsalz@uunet.uu.net.
  1791.  
  1792.  
  1793.