xref: /csrg-svn/usr.sbin/lpr/lpd/recvjob.c (revision 13955)
1*13955Ssam #ifndef lint
2*13955Ssam static char sccsid[] = "@(#)recvjob.c	4.6 (Berkeley) 07/17/83";
3*13955Ssam #endif
4*13955Ssam 
512115Sralph /*
612115Sralph  * Receive printer jobs from the network, queue them and
712115Sralph  * start the printer daemon.
812115Sralph  */
912115Sralph 
1012115Sralph #include "lp.h"
1112115Sralph 
1212877Sralph static char    tfname[40];	/* tmp copy of cf before linking */
1312877Sralph static char    *dfname;		/* data files */
1412115Sralph 
1512115Sralph recvjob()
1612115Sralph {
1712464Sralph 	struct stat stb;
1812115Sralph 	char *bp = pbuf;
1912115Sralph 	int status;
2012115Sralph 
2112115Sralph 	/*
2212115Sralph 	 * Perform lookup for printer name or abbreviation
2312115Sralph 	 */
2412115Sralph 	if ((status = pgetent(line, printer)) < 0)
2512115Sralph 		fatal("cannot open printer description file");
2612115Sralph 	else if (status == 0)
2712115Sralph 		fatal("unknown printer");
2812115Sralph 	if ((LF = pgetstr("lf", &bp)) == NULL)
2912115Sralph 		LF = DEFLOGF;
3012115Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
3112115Sralph 		SD = DEFSPOOL;
3212464Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
3312464Sralph 		LO = DEFLOCK;
3412115Sralph 
3512115Sralph 	(void) close(2);
3613149Ssam 	(void) open(LF, O_WRONLY|O_APPEND);
3712115Sralph 	if (chdir(SD) < 0)
3812115Sralph 		fatal("cannot chdir to %s", SD);
3912464Sralph 	if (stat(LO, &stb) == 0 && (stb.st_mode & 010)) {
4012464Sralph 		/* queue is disabled */
4112464Sralph 		putchar('\1');		/* return error code */
4212464Sralph 		exit(1);
4312464Sralph 	}
4412115Sralph 
4512115Sralph 	if (readjob())
4612115Sralph 		printjob();
4712115Sralph }
4812115Sralph 
4912115Sralph char	*sp = "";
5012115Sralph #define ack()	(void) write(1, sp, 1);
5112115Sralph 
5212115Sralph /*
5312115Sralph  * Read printer jobs sent by lpd and copy them to the spooling directory.
5412115Sralph  * Return the number of jobs successfully transfered.
5512115Sralph  */
5612877Sralph static
5712115Sralph readjob(printer)
5812115Sralph 	char *printer;
5912115Sralph {
6012115Sralph 	register int size, nfiles;
6112115Sralph 	register char *cp;
6212115Sralph 
6312115Sralph 	ack();
6412115Sralph 	nfiles = 0;
6512115Sralph 	for (;;) {
6612115Sralph 		/*
6712115Sralph 		 * Read a command to tell us what to do
6812115Sralph 		 */
6912115Sralph 		cp = line;
7012115Sralph 		do {
7112115Sralph 			if ((size = read(1, cp, 1)) != 1) {
7212115Sralph 				if (size < 0)
7312115Sralph 					fatal("Lost connection");
7412115Sralph 				return(nfiles);
7512115Sralph 			}
7612115Sralph 		} while (*cp++ != '\n');
7712115Sralph 		*--cp = '\0';
7812115Sralph 		cp = line;
7912115Sralph 		switch (*cp++) {
8012115Sralph 		case '\1':	/* cleanup because data sent was bad */
8112115Sralph 			cleanup();
8212115Sralph 			continue;
8312115Sralph 
8412115Sralph 		case '\2':	/* read cf file */
8512115Sralph 			size = 0;
8612115Sralph 			while (*cp >= '0' && *cp <= '9')
8712115Sralph 				size = size * 10 + (*cp++ - '0');
8812115Sralph 			if (*cp++ != ' ')
8912115Sralph 				break;
9012115Sralph 			strcpy(tfname, cp);
9112115Sralph 			tfname[0] = 't';
9212115Sralph 			if (!readfile(tfname, size)) {
9312115Sralph 				cleanup();
9412115Sralph 				continue;
9512115Sralph 			}
9612115Sralph 			if (link(tfname, cp) < 0)
9712115Sralph 				fatal("cannot rename %s", tfname);
9812115Sralph 			(void) unlink(tfname);
9912115Sralph 			tfname[0] = '\0';
10012115Sralph 			nfiles++;
10112115Sralph 			continue;
10212115Sralph 
10312115Sralph 		case '\3':	/* read df file */
10412115Sralph 			size = 0;
10512115Sralph 			while (*cp >= '0' && *cp <= '9')
10612115Sralph 				size = size * 10 + (*cp++ - '0');
10712115Sralph 			if (*cp++ != ' ')
10812115Sralph 				break;
10912115Sralph 			(void) readfile(dfname = cp, size);
11012115Sralph 			continue;
11112115Sralph 		}
11212115Sralph 		fatal("protocol screwup");
11312115Sralph 	}
11412115Sralph }
11512115Sralph 
11612115Sralph /*
11712115Sralph  * Read files send by lpd and copy them to the spooling directory.
11812115Sralph  */
11912877Sralph static
12012115Sralph readfile(file, size)
12112115Sralph 	char *file;
12212115Sralph 	int size;
12312115Sralph {
12412115Sralph 	register char *cp;
12512115Sralph 	char buf[BUFSIZ];
12612115Sralph 	register int i, j, amt;
12712115Sralph 	int fd, err;
12812115Sralph 
12913149Ssam 	fd = open(file, O_WRONLY|O_CREAT, FILMOD);
13012115Sralph 	if (fd < 0)
13112115Sralph 		fatal("cannot create %s", file);
13212115Sralph 	ack();
13312115Sralph 	err = 0;
13412115Sralph 	for (i = 0; i < size; i += BUFSIZ) {
13512115Sralph 		amt = BUFSIZ;
13612115Sralph 		cp = buf;
13712115Sralph 		if (i + amt > size)
13812115Sralph 			amt = size - i;
13912115Sralph 		do {
14012115Sralph 			j = read(1, cp, amt);
14112115Sralph 			if (j <= 0)
14212115Sralph 				fatal("Lost connection");
14312115Sralph 			amt -= j;
14412115Sralph 			cp += j;
14512115Sralph 		} while (amt > 0);
14612115Sralph 		amt = BUFSIZ;
14712115Sralph 		if (i + amt > size)
14812115Sralph 			amt = size - i;
14913170Sralph 		if (write(fd, buf, amt) != amt) {
15012115Sralph 			err++;
15113170Sralph 			break;
15213170Sralph 		}
15312115Sralph 	}
15412115Sralph 	(void) close(fd);
15512115Sralph 	if (err)
15612115Sralph 		fatal("%s: write error", file);
15712115Sralph 	if (noresponse()) {		/* file sent had bad data in it */
15812115Sralph 		(void) unlink(file);
15912115Sralph 		return(0);
16012115Sralph 	}
16112115Sralph 	ack();
16212115Sralph 	return(1);
16312115Sralph }
16412115Sralph 
16512115Sralph static
16612115Sralph noresponse()
16712115Sralph {
16812115Sralph 	char resp;
16912115Sralph 
17012115Sralph 	if (read(1, &resp, 1) != 1)
17112115Sralph 		fatal("Lost connection");
17212115Sralph 	if (resp == '\0')
17312115Sralph 		return(0);
17412115Sralph 	return(1);
17512115Sralph }
17612115Sralph 
17712115Sralph /*
17812115Sralph  * Remove all the files associated with the current job being transfered.
17912115Sralph  */
18012115Sralph static
18112115Sralph cleanup()
18212115Sralph {
18312115Sralph 	register int i;
18412115Sralph 
18512115Sralph 	if (tfname[0])
18612115Sralph 		(void) unlink(tfname);
18712115Sralph 	if (dfname)
18812115Sralph 		do {
18912115Sralph 			do
19012115Sralph 				(void) unlink(dfname);
19112115Sralph 			while (dfname[i]-- != 'A');
19212115Sralph 			dfname[i] = 'z';
19312115Sralph 		} while (dfname[i-2]-- != 'd');
19412115Sralph }
19512115Sralph 
19612115Sralph static
19712115Sralph fatal(msg, a1)
19812115Sralph 	char *msg;
19912115Sralph {
20012115Sralph 	cleanup();
20112115Sralph 	log(msg, a1);
20212115Sralph 	putchar('\1');		/* return error code */
20312115Sralph 	exit(1);
20412115Sralph }
205