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