xref: /csrg-svn/usr.sbin/lpr/lpd/recvjob.c (revision 12115)
1*12115Sralph /*	recvjob.c	4.1	83/04/29	*/
2*12115Sralph /*
3*12115Sralph  * Receive printer jobs from the network, queue them and
4*12115Sralph  * start the printer daemon.
5*12115Sralph  */
6*12115Sralph 
7*12115Sralph #include "lp.h"
8*12115Sralph 
9*12115Sralph char    tfname[40];		/* tmp copy of cf before linking */
10*12115Sralph char    *dfname;		/* data files */
11*12115Sralph 
12*12115Sralph recvjob()
13*12115Sralph {
14*12115Sralph 	char *bp = pbuf;
15*12115Sralph 	int status;
16*12115Sralph 
17*12115Sralph 	name = "recvjob";
18*12115Sralph 
19*12115Sralph 	/*
20*12115Sralph 	 * Perform lookup for printer name or abbreviation
21*12115Sralph 	 */
22*12115Sralph 	if ((status = pgetent(line, printer)) < 0)
23*12115Sralph 		fatal("cannot open printer description file");
24*12115Sralph 	else if (status == 0)
25*12115Sralph 		fatal("unknown printer");
26*12115Sralph 	if ((LF = pgetstr("lf", &bp)) == NULL)
27*12115Sralph 		LF = DEFLOGF;
28*12115Sralph 	if ((SD = pgetstr("sd", &bp)) == NULL)
29*12115Sralph 		SD = DEFSPOOL;
30*12115Sralph 
31*12115Sralph 	(void) close(2);
32*12115Sralph 	(void) open(LF, FWRONLY|FAPPEND, 0);
33*12115Sralph 	if (chdir(SD) < 0)
34*12115Sralph 		fatal("cannot chdir to %s", SD);
35*12115Sralph 
36*12115Sralph 	if (readjob())
37*12115Sralph 		printjob();
38*12115Sralph }
39*12115Sralph 
40*12115Sralph char	*sp = "";
41*12115Sralph #define ack()	(void) write(1, sp, 1);
42*12115Sralph 
43*12115Sralph /*
44*12115Sralph  * Read printer jobs sent by lpd and copy them to the spooling directory.
45*12115Sralph  * Return the number of jobs successfully transfered.
46*12115Sralph  */
47*12115Sralph readjob(printer)
48*12115Sralph 	char *printer;
49*12115Sralph {
50*12115Sralph 	register int size, nfiles;
51*12115Sralph 	register char *cp;
52*12115Sralph 
53*12115Sralph 	ack();
54*12115Sralph 	nfiles = 0;
55*12115Sralph 	for (;;) {
56*12115Sralph 		/*
57*12115Sralph 		 * Read a command to tell us what to do
58*12115Sralph 		 */
59*12115Sralph 		cp = line;
60*12115Sralph 		do {
61*12115Sralph 			if ((size = read(1, cp, 1)) != 1) {
62*12115Sralph 				if (size < 0)
63*12115Sralph 					fatal("Lost connection");
64*12115Sralph 				return(nfiles);
65*12115Sralph 			}
66*12115Sralph 		} while (*cp++ != '\n');
67*12115Sralph 		*--cp = '\0';
68*12115Sralph 		cp = line;
69*12115Sralph 		switch (*cp++) {
70*12115Sralph 		case '\1':	/* cleanup because data sent was bad */
71*12115Sralph 			cleanup();
72*12115Sralph 			continue;
73*12115Sralph 
74*12115Sralph 		case '\2':	/* read cf file */
75*12115Sralph 			size = 0;
76*12115Sralph 			while (*cp >= '0' && *cp <= '9')
77*12115Sralph 				size = size * 10 + (*cp++ - '0');
78*12115Sralph 			if (*cp++ != ' ')
79*12115Sralph 				break;
80*12115Sralph 			strcpy(tfname, cp);
81*12115Sralph 			tfname[0] = 't';
82*12115Sralph 			if (!readfile(tfname, size)) {
83*12115Sralph 				cleanup();
84*12115Sralph 				continue;
85*12115Sralph 			}
86*12115Sralph 			if (link(tfname, cp) < 0)
87*12115Sralph 				fatal("cannot rename %s", tfname);
88*12115Sralph 			(void) unlink(tfname);
89*12115Sralph 			tfname[0] = '\0';
90*12115Sralph 			nfiles++;
91*12115Sralph 			continue;
92*12115Sralph 
93*12115Sralph 		case '\3':	/* read df file */
94*12115Sralph 			size = 0;
95*12115Sralph 			while (*cp >= '0' && *cp <= '9')
96*12115Sralph 				size = size * 10 + (*cp++ - '0');
97*12115Sralph 			if (*cp++ != ' ')
98*12115Sralph 				break;
99*12115Sralph 			(void) readfile(dfname = cp, size);
100*12115Sralph 			continue;
101*12115Sralph 		}
102*12115Sralph 		fatal("protocol screwup");
103*12115Sralph 	}
104*12115Sralph }
105*12115Sralph 
106*12115Sralph /*
107*12115Sralph  * Read files send by lpd and copy them to the spooling directory.
108*12115Sralph  */
109*12115Sralph readfile(file, size)
110*12115Sralph 	char *file;
111*12115Sralph 	int size;
112*12115Sralph {
113*12115Sralph 	register char *cp;
114*12115Sralph 	char buf[BUFSIZ];
115*12115Sralph 	register int i, j, amt;
116*12115Sralph 	int fd, err;
117*12115Sralph 
118*12115Sralph 	fd = open(file, FWRONLY|FCREATE, FILMOD);
119*12115Sralph 	if (fd < 0)
120*12115Sralph 		fatal("cannot create %s", file);
121*12115Sralph 	ack();
122*12115Sralph 	err = 0;
123*12115Sralph 	for (i = 0; i < size; i += BUFSIZ) {
124*12115Sralph 		amt = BUFSIZ;
125*12115Sralph 		cp = buf;
126*12115Sralph 		if (i + amt > size)
127*12115Sralph 			amt = size - i;
128*12115Sralph 		do {
129*12115Sralph 			j = read(1, cp, amt);
130*12115Sralph 			if (j <= 0)
131*12115Sralph 				fatal("Lost connection");
132*12115Sralph 			amt -= j;
133*12115Sralph 			cp += j;
134*12115Sralph 		} while (amt > 0);
135*12115Sralph 		amt = BUFSIZ;
136*12115Sralph 		if (i + amt > size)
137*12115Sralph 			amt = size - i;
138*12115Sralph 		if (err == 0 && write(fd, buf, amt) != amt)
139*12115Sralph 			err++;
140*12115Sralph 	}
141*12115Sralph 	(void) close(fd);
142*12115Sralph 	if (err)
143*12115Sralph 		fatal("%s: write error", file);
144*12115Sralph 	if (noresponse()) {		/* file sent had bad data in it */
145*12115Sralph 		(void) unlink(file);
146*12115Sralph 		return(0);
147*12115Sralph 	}
148*12115Sralph 	ack();
149*12115Sralph 	return(1);
150*12115Sralph }
151*12115Sralph 
152*12115Sralph static
153*12115Sralph noresponse()
154*12115Sralph {
155*12115Sralph 	char resp;
156*12115Sralph 
157*12115Sralph 	if (read(1, &resp, 1) != 1)
158*12115Sralph 		fatal("Lost connection");
159*12115Sralph 	if (resp == '\0')
160*12115Sralph 		return(0);
161*12115Sralph 	return(1);
162*12115Sralph }
163*12115Sralph 
164*12115Sralph /*
165*12115Sralph  * Remove all the files associated with the current job being transfered.
166*12115Sralph  */
167*12115Sralph static
168*12115Sralph cleanup()
169*12115Sralph {
170*12115Sralph 	register int i;
171*12115Sralph 
172*12115Sralph 	if (tfname[0])
173*12115Sralph 		(void) unlink(tfname);
174*12115Sralph 	if (dfname)
175*12115Sralph 		do {
176*12115Sralph 			do
177*12115Sralph 				(void) unlink(dfname);
178*12115Sralph 			while (dfname[i]-- != 'A');
179*12115Sralph 			dfname[i] = 'z';
180*12115Sralph 		} while (dfname[i-2]-- != 'd');
181*12115Sralph }
182*12115Sralph 
183*12115Sralph static
184*12115Sralph fatal(msg, a1)
185*12115Sralph 	char *msg;
186*12115Sralph {
187*12115Sralph 	cleanup();
188*12115Sralph 	log(msg, a1);
189*12115Sralph 	putchar('\1');		/* return error code */
190*12115Sralph 	exit(1);
191*12115Sralph }
192