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