2caa23e8ac0c828de8c46d53f74b908835c00932
* Copyright (c) 1983 Regents of the University of California.
* Redistribution and use in source and binary forms are permitted
* provided that the above copyright notice and this paragraph are
* duplicated in all such forms and that any documentation,
* advertising materials, and other materials related to such
* distribution and use acknowledge that the software was developed
* by the University of California, Berkeley. The name of the
* University may not be used to endorse or promote products derived
* from this software without specific prior written permission.
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
static char sccsid
[] = "@(#)recvjob.c 5.7 (Berkeley) %G%";
* Receive printer jobs from the network, queue them and
* start the printer daemon.
#define ack() (void) write(1, sp, 1);
char tfname
[40]; /* tmp copy of cf before linking */
char dfname
[40]; /* data files */
int minfree
; /* keep at least minfree blocks available */
char *ddev
; /* disk device (for checking free space) */
int dfd
; /* file system device descriptor */
* Perform lookup for printer name or abbreviation
if ((status
= pgetent(line
, printer
)) < 0)
frecverr("cannot open printer description file");
frecverr("unknown printer %s", printer
);
if ((LF
= pgetstr("lf", &bp
)) == NULL
)
if ((SD
= pgetstr("sd", &bp
)) == NULL
)
if ((LO
= pgetstr("lo", &bp
)) == NULL
)
(void) close(2); /* set up log file */
if (open(LF
, O_WRONLY
|O_APPEND
, 0664) < 0) {
syslog(LOG_ERR
, "%s: %m", LF
);
(void) open("/dev/null", 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
= read_number("minfree");
ddev
= find_dev(stb
.st_dev
, S_IFBLK
);
if ((dfd
= open(ddev
, O_RDONLY
)) < 0)
syslog(LOG_WARNING
, "%s: %s: %m", printer
, ddev
);
signal(SIGTERM
, rcleanup
);
signal(SIGPIPE
, rcleanup
);
register DIR *dfd
= opendir("/dev");
char devname
[MAXNAMLEN
+6];
strcpy(devname
, "/dev/");
while ((dir
= readdir(dfd
))) {
strcpy(devname
+ 5, dir
->d_name
);
if ((stb
.st_mode
& S_IFMT
) != type
)
if (dev
== stb
.st_rdev
) {
dp
= (char *)malloc(strlen(devname
)+1);
frecverr("cannot find device %d, %d", major(dev
), minor(dev
));
* 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) readfile(dfname
, size
);
frecverr("protocol screwup");
* Read files send by lpd and copy them to the spooling directory.
fd
= open(file
, O_WRONLY
|O_CREAT
, FILMOD
);
frecverr("%s: %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 (dfd
< 0 || lseek(dfd
, (long)(SBOFF
), 0) < 0)
if (read(dfd
, (char *)&fs
, sizeof fs
) != sizeof fs
)
spacefree
= freespace(&fs
, fs
.fs_minfree
) * fs
.fs_fsize
/ 1024;
size
= (size
+ 1023) / 1024;
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');
syslog(LOG_ERR
, msg
, a1
, a2
);
putchar('\1'); /* return error code */