2c6efda0ccb489a7378ee05f6ed831c7cff4c76b
* Copyright (c) 1983 The Regents of the University of California.
* %sccs.include.redist.c%
static char copyright
[] =
"@(#) Copyright (c) 1983 The Regents of the University of California.\n\
static char sccsid
[] = "@(#)recvjob.c 5.20 (Berkeley) %G%";
* Receive printer jobs from the network, queue them and
* start the printer daemon.
#define ack() (void) write(1, sp, 1);
static char dfname
[40]; /* data files */
static int minfree
; /* keep at least minfree blocks available */
static char tfname
[40]; /* tmp copy of cf before linking */
static int chksize
__P((int));
static void frecverr
__P((const char *, ...));
static int noresponse
__P((void));
static void rcleanup
__P((int));
static int read_number
__P((char *));
static int readfile
__P((char *, int));
static int readjob
__P((void));
* Perform lookup for printer name or abbreviation
if ((status
= cgetent(&bp
, printcapdb
, printer
)) == -2)
frecverr("cannot open printer description file");
frecverr("unknown printer %s", printer
);
fatal("potential reference loop detected in printcap file");
if (cgetstr(bp
, "lf", &LF
) == -1)
if (cgetstr(bp
, "sd", &SD
) == -1)
if (cgetstr(bp
, "lo", &LO
) == -1)
(void) close(2); /* set up log file */
if (open(LF
, O_WRONLY
|O_APPEND
, 0664) < 0) {
syslog(LOG_ERR
, "%s: %m", LF
);
(void) open(_PATH_DEVNULL
, O_WRONLY
);
frecverr("%s: %s: %m", printer
, SD
);
if (stat(LO
, &stb
) == 0) {
putchar('\1'); /* return error code */
} else if (stat(SD
, &stb
) < 0)
frecverr("%s: %s: %m", printer
, SD
);
minfree
= 2 * read_number("minfree"); /* scale KB to 512 blocks */
signal(SIGTERM
, rcleanup
);
signal(SIGPIPE
, rcleanup
);
* Read printer jobs sent by lpd and copy them to the spooling directory.
* Return the number of jobs successfully transfered.
register int size
, nfiles
;
* Read a command to tell us what to do
if ((size
= read(1, cp
, 1)) != 1) {
frecverr("%s: Lost connection",printer
);
case '\1': /* cleanup because data sent was bad */
case '\2': /* read cf file */
while (*cp
>= '0' && *cp
<= '9')
size
= size
* 10 + (*cp
++ - '0');
* host name has been authenticated, we use our
* view of the host name since we may be passed
* something different than what gethostbyaddr()
(void) write(1, "\2", 1);
if (!readfile(tfname
, size
)) {
if (link(tfname
, cp
) < 0)
frecverr("%s: %m", tfname
);
case '\3': /* read df file */
while (*cp
>= '0' && *cp
<= '9')
size
= size
* 10 + (*cp
++ - '0');
(void) write(1, "\2", 1);
(void) strcpy(dfname
, cp
);
frecverr("readjob: %s: illegal path name",
(void) readfile(dfname
, size
);
frecverr("protocol screwup");
* Read files send by lpd and copy them to the spooling directory.
fd
= open(file
, O_CREAT
|O_EXCL
|O_WRONLY
, FILMOD
);
frecverr("readfile: %s: illegal path name: %m", file
);
for (i
= 0; i
< size
; i
+= BUFSIZ
) {
frecverr("Lost connection");
if (write(fd
, buf
, amt
) != amt
) {
frecverr("%s: write error", file
);
if (noresponse()) { /* file sent had bad data in it */
if (read(1, &resp
, 1) != 1)
frecverr("Lost connection");
* Check to see if there is enough space on the disk for size bytes.
if (statfs(".", &sfb
) < 0) {
syslog(LOG_ERR
, "%s: %m", "statfs(\".\")");
spacefree
= sfb
.f_bavail
* (sfb
.f_bsize
/ 512);
size
= (size
+ 511) / 512;
if (minfree
+ size
> spacefree
)
if ((fp
= fopen(fn
, "r")) == NULL
)
if (fgets(lin
, 80, fp
) == NULL
) {
* Remove all the files associated with the current job being transfered.
while (dfname
[2]-- != 'A');
} while (dfname
[0]-- != 'd');
frecverr(const char *msg
, ...)
vsyslog(LOG_ERR
, msg
, ap
);
putchar('\1'); /* return error code */