xref: /csrg-svn/usr.sbin/lpr/lpd/recvjob.c (revision 12464)
1*12464Sralph /*	recvjob.c	4.2	83/05/16	*/
212115Sralph /*
312115Sralph  * Receive printer jobs from the network, queue them and
412115Sralph  * start the printer daemon.
512115Sralph  */
612115Sralph 
712115Sralph #include "lp.h"
812115Sralph 
912115Sralph char    tfname[40];		/* tmp copy of cf before linking */
1012115Sralph char    *dfname;		/* data files */
1112115Sralph 
1212115Sralph recvjob()
1312115Sralph {
14*12464Sralph 	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;
29*12464Sralph 	if ((LO = pgetstr("lo", &bp)) == NULL)
30*12464Sralph 		LO = DEFLOCK;
3112115Sralph 
3212115Sralph 	(void) close(2);
3312115Sralph 	(void) open(LF, FWRONLY|FAPPEND, 0);
3412115Sralph 	if (chdir(SD) < 0)
3512115Sralph 		fatal("cannot chdir to %s", SD);
36*12464Sralph 	if (stat(LO, &stb) == 0 && (stb.st_mode & 010)) {
37*12464Sralph 		/* queue is disabled */
38*12464Sralph 		putchar('\1');		/* return error code */
39*12464Sralph 		exit(1);
40*12464Sralph 	}
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  */
5312115Sralph readjob(printer)
5412115Sralph 	char *printer;
5512115Sralph {
5612115Sralph 	register int size, nfiles;
5712115Sralph 	register char *cp;
5812115Sralph 
5912115Sralph 	ack();
6012115Sralph 	nfiles = 0;
6112115Sralph 	for (;;) {
6212115Sralph 		/*
6312115Sralph 		 * Read a command to tell us what to do
6412115Sralph 		 */
6512115Sralph 		cp = line;
6612115Sralph 		do {
6712115Sralph 			if ((size = read(1, cp, 1)) != 1) {
6812115Sralph 				if (size < 0)
6912115Sralph 					fatal("Lost connection");
7012115Sralph 				return(nfiles);
7112115Sralph 			}
7212115Sralph 		} while (*cp++ != '\n');
7312115Sralph 		*--cp = '\0';
7412115Sralph 		cp = line;
7512115Sralph 		switch (*cp++) {
7612115Sralph 		case '\1':	/* cleanup because data sent was bad */
7712115Sralph 			cleanup();
7812115Sralph 			continue;
7912115Sralph 
8012115Sralph 		case '\2':	/* read cf file */
8112115Sralph 			size = 0;
8212115Sralph 			while (*cp >= '0' && *cp <= '9')
8312115Sralph 				size = size * 10 + (*cp++ - '0');
8412115Sralph 			if (*cp++ != ' ')
8512115Sralph 				break;
8612115Sralph 			strcpy(tfname, cp);
8712115Sralph 			tfname[0] = 't';
8812115Sralph 			if (!readfile(tfname, size)) {
8912115Sralph 				cleanup();
9012115Sralph 				continue;
9112115Sralph 			}
9212115Sralph 			if (link(tfname, cp) < 0)
9312115Sralph 				fatal("cannot rename %s", tfname);
9412115Sralph 			(void) unlink(tfname);
9512115Sralph 			tfname[0] = '\0';
9612115Sralph 			nfiles++;
9712115Sralph 			continue;
9812115Sralph 
9912115Sralph 		case '\3':	/* read df file */
10012115Sralph 			size = 0;
10112115Sralph 			while (*cp >= '0' && *cp <= '9')
10212115Sralph 				size = size * 10 + (*cp++ - '0');
10312115Sralph 			if (*cp++ != ' ')
10412115Sralph 				break;
10512115Sralph 			(void) readfile(dfname = cp, size);
10612115Sralph 			continue;
10712115Sralph 		}
10812115Sralph 		fatal("protocol screwup");
10912115Sralph 	}
11012115Sralph }
11112115Sralph 
11212115Sralph /*
11312115Sralph  * Read files send by lpd and copy them to the spooling directory.
11412115Sralph  */
11512115Sralph readfile(file, size)
11612115Sralph 	char *file;
11712115Sralph 	int size;
11812115Sralph {
11912115Sralph 	register char *cp;
12012115Sralph 	char buf[BUFSIZ];
12112115Sralph 	register int i, j, amt;
12212115Sralph 	int fd, err;
12312115Sralph 
12412115Sralph 	fd = open(file, FWRONLY|FCREATE, FILMOD);
12512115Sralph 	if (fd < 0)
12612115Sralph 		fatal("cannot create %s", file);
12712115Sralph 	ack();
12812115Sralph 	err = 0;
12912115Sralph 	for (i = 0; i < size; i += BUFSIZ) {
13012115Sralph 		amt = BUFSIZ;
13112115Sralph 		cp = buf;
13212115Sralph 		if (i + amt > size)
13312115Sralph 			amt = size - i;
13412115Sralph 		do {
13512115Sralph 			j = read(1, cp, amt);
13612115Sralph 			if (j <= 0)
13712115Sralph 				fatal("Lost connection");
13812115Sralph 			amt -= j;
13912115Sralph 			cp += j;
14012115Sralph 		} while (amt > 0);
14112115Sralph 		amt = BUFSIZ;
14212115Sralph 		if (i + amt > size)
14312115Sralph 			amt = size - i;
14412115Sralph 		if (err == 0 && write(fd, buf, amt) != amt)
14512115Sralph 			err++;
14612115Sralph 	}
14712115Sralph 	(void) close(fd);
14812115Sralph 	if (err)
14912115Sralph 		fatal("%s: write error", file);
15012115Sralph 	if (noresponse()) {		/* file sent had bad data in it */
15112115Sralph 		(void) unlink(file);
15212115Sralph 		return(0);
15312115Sralph 	}
15412115Sralph 	ack();
15512115Sralph 	return(1);
15612115Sralph }
15712115Sralph 
15812115Sralph static
15912115Sralph noresponse()
16012115Sralph {
16112115Sralph 	char resp;
16212115Sralph 
16312115Sralph 	if (read(1, &resp, 1) != 1)
16412115Sralph 		fatal("Lost connection");
16512115Sralph 	if (resp == '\0')
16612115Sralph 		return(0);
16712115Sralph 	return(1);
16812115Sralph }
16912115Sralph 
17012115Sralph /*
17112115Sralph  * Remove all the files associated with the current job being transfered.
17212115Sralph  */
17312115Sralph static
17412115Sralph cleanup()
17512115Sralph {
17612115Sralph 	register int i;
17712115Sralph 
17812115Sralph 	if (tfname[0])
17912115Sralph 		(void) unlink(tfname);
18012115Sralph 	if (dfname)
18112115Sralph 		do {
18212115Sralph 			do
18312115Sralph 				(void) unlink(dfname);
18412115Sralph 			while (dfname[i]-- != 'A');
18512115Sralph 			dfname[i] = 'z';
18612115Sralph 		} while (dfname[i-2]-- != 'd');
18712115Sralph }
18812115Sralph 
18912115Sralph static
19012115Sralph fatal(msg, a1)
19112115Sralph 	char *msg;
19212115Sralph {
19312115Sralph 	cleanup();
19412115Sralph 	log(msg, a1);
19512115Sralph 	putchar('\1');		/* return error code */
19612115Sralph 	exit(1);
19712115Sralph }
198