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