/* a simple line printer daemon */ #include #ifdef __GNUC__ #include #endif #include "mintbind.h" #define PRINTERFILE "U:\\DEV\\PRN" #define MSGQUEUE "U:\\PIPE\\LPD.MSG" #define MSGSIZ 128 char msgbuf[MSGSIZ]; #define BUFSIZ 2048 int msgfd; /* requests to print files come here */ int printerfd; /* make a copy of a file. the name of the copy is kept in local storage, and must be of the form XXXXXXXX.LPR. Moreover, it had better be unique. The string "from" is overwritten with an error message if an error occurs, otherwise from[0] is set to 0. */ void copy_file(from) char *from; { static char buf[BUFSIZ]; static char topat[] = "AAAAAAA.LPR"; char *to; int infd, outfd; long r; if ((infd = Fopen(from, 0)) < 0) { strcpy(from, "File couldn't be opened for input."); return; } for(;;) { to = topat; while (*to == 'Z') *to++ = 'A'; if (*to != '.') *to += 1; outfd = Fopen(topat, 1); if (outfd < 0) break; Fclose(outfd); } outfd = Fcreate(topat, 0); if (outfd < 0) { Fclose(infd); strcpy(from, "Error creating spool file."); return; } while ((r = Fread(infd, (long)BUFSIZ, buf)) > 0) { if (r != Fwrite(outfd, r, buf)) { strcpy(from, "Write error on spool file (disk full?)"); break; } } Fclose(infd); Fclose(outfd); if (r == 0) from[0] = 0; } /* * get a file name to be printed, and queue it. The queueing is done * simply by making a copy of the file (see copyfile(), above) in the * current directory. */ void get_request() { Fread(msgfd, (long)MSGSIZ, msgbuf); /* read the request */ copy_file(msgbuf); /* on error, copy_file puts an error message in msgbuf */ Fwrite(msgfd, (long)MSGSIZ, msgbuf); /* reply to the request */ } /* * print a file. periodically checks for incoming requests to print, * and calls get_request if there are any. */ void print_file(name) char *name; { int fd; long r; static char inbuf[80]; fd = Fopen(name, 0); if (fd < 0) { Cconws("lpd: couldn't open a file???\r\n"); return; } for(;;) { r = Fread(fd, 80L, inbuf); if (r <= 0) break; Fwrite(printerfd, r, inbuf); /* check for incoming messages */ if (Finstat(msgfd)) get_request(); } Fclose(fd); Fdelete(name); } int main(argc, argv) int argc; char **argv; { extern char *getenv(); char *tmpdir; long r; struct _dta p; char printfile[80]; if ((tmpdir = getenv("TEMP"))) Dsetpath(tmpdir); msgfd = Fcreate(MSGQUEUE, 0); if (msgfd == -36) { /* access denied */ Cconws("lpd: a printer daemon already exists\r\n"); Pterm0(); } else if (msgfd < 0) { Cconws("lpd: unable to create message queue\r\n"); Pterm(1); } if (argv[1]) strcpy(printfile, argv[1]); else strcpy(printfile, PRINTERFILE); printerfd = Fcreate(printfile, 0); if (printerfd < 0) { Cconws("lpd: unable to open printer\r\n"); Pterm(1); } Fsetdta(&p); for(;;) { r = Fsfirst("*.LPR", 0); while (r >= 0) { print_file(p.dta_name); r = Fsnext(); } get_request(); /* get outstanding requests */ } }