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