123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/param.h>
- #define REDIALTIMEOUT 15
- #ifdef PLAN9
- #include <Plan9libnet.h>
- #endif
- enum {
- TIMEOUT = 30*60,
- SBSIZE = 8192,
- };
- char tmpfilename[L_tmpnam+1];
- unsigned char sendbuf[SBSIZE];
- int alarmstate = 0;
- int debugflag = 0;
- int killflag = 0;
- int statflag = 0;
- void
- cleanup(void)
- {
- unlink(tmpfilename);
- }
- void
- debug(char *str)
- {
- if (debugflag)
- fprintf(stderr, "%s", str);
- }
- void
- alarmhandler(int sig)
- {
- fprintf(stderr, "timeout occurred, check printer.\n");
- exit(2);
- }
- /* send a message after each WARNPC percent of data sent */
- #define WARNPC 5
- int
- copyfile(int in, int out, long tosend)
- {
- int n;
- int sent = 0;
- int percent = 0;
- if (debugflag)
- fprintf(stderr, "lpdsend: copyfile(%d,%d,%ld)\n",
- in, out, tosend);
- while ((n=read(in, sendbuf, SBSIZE)) > 0) {
- if (debugflag)
- fprintf(stderr, "lpdsend: copyfile read %d bytes from %d\n",
- n, in);
- alarm(TIMEOUT);
- alarmstate = 1;
- if (write(out, sendbuf, n) != n) {
- alarm(0);
- fprintf(stderr, "write to fd %d failed\n", out);
- return(0);
- }
- alarm(0);
- if (debugflag)
- fprintf(stderr, "lpdsend: copyfile wrote %d bytes to %d\n",
- n, out);
- sent += n;
- if (tosend && sent*100/tosend >= percent+WARNPC) {
- percent += WARNPC;
- fprintf(stderr, ": %5.2f%% sent\n", sent*100.0/tosend);
- }
- }
- if (debugflag)
- fprintf(stderr, "lpdsend: copyfile read %d bytes from %d\n",
- n, in);
- return(!n);
- }
- char strbuf[120];
- char hostname[MAXHOSTNAMELEN], *username, *printername, *killarg;
- char *inputname;
- char filetype = 'o'; /* 'o' is for PostScript */
- int seqno = 0;
- char *seqfilename;
- void
- killjob(int printerfd)
- {
- int strlength;
- if (printername==0) {
- fprintf(stderr, "no printer name\n");
- exit(1);
- }
- if (username==0) {
- fprintf(stderr, "no user name given\n");
- exit(1);
- }
- if (killarg==0) {
- fprintf(stderr, "no job to kill\n");
- exit(1);
- }
- sprintf(strbuf, "%c%s %s %s\n", '\5', printername, username, killarg);
- strlength = strlen(strbuf);
- if (write(printerfd, strbuf, strlength) != strlength) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- copyfile(printerfd, 2, 0L);
- }
- void
- checkqueue(int printerfd)
- {
- int n, strlength;
- unsigned char sendbuf[1];
- sprintf(strbuf, "%c%s\n", '\4', printername);
- strlength = strlen(strbuf);
- if (write(printerfd, strbuf, strlength) != strlength) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- copyfile(printerfd, 2, 0L);
- /*
- while ((n=read(printerfd, sendbuf, 1)) > 0) {
- write(2, sendbuf, n);
- }
- */
- }
- void
- getack(int printerfd, int as)
- {
- char resp;
- int rv;
- alarm(TIMEOUT);
- alarmstate = as;
- if ((rv = read(printerfd, &resp, 1)) != 1 || resp != '\0') {
- fprintf(stderr, "getack failed: read returned %d, "
- "read value (if any) %d, alarmstate=%d\n",
- rv, resp, alarmstate);
- exit(1);
- }
- alarm(0);
- }
- /* send control file */
- void
- sendctrl(int printerfd)
- {
- char cntrlstrbuf[256];
- int strlength, cntrlen;
- sprintf(cntrlstrbuf, "H%s\nP%s\n%cdfA%3.3d%s\n", hostname, username, filetype, seqno, hostname);
- cntrlen = strlen(cntrlstrbuf);
- sprintf(strbuf, "%c%d cfA%3.3d%s\n", '\2', cntrlen, seqno, hostname);
- strlength = strlen(strbuf);
- if (write(printerfd, strbuf, strlength) != strlength) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- getack(printerfd, 3);
- if (write(printerfd, cntrlstrbuf, cntrlen) != cntrlen) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- if (write(printerfd, "\0", 1) != 1) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- getack(printerfd, 4);
- }
- /* send data file */
- void
- senddata(int inputfd, int printerfd, long size)
- {
- int strlength;
- sprintf(strbuf, "%c%d dfA%3.3d%s\n", '\3', size, seqno, hostname);
- strlength = strlen(strbuf);
- if (write(printerfd, strbuf, strlength) != strlength) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- getack(printerfd, 5);
- if (!copyfile(inputfd, printerfd, size)) {
- fprintf(stderr, "failed to send file to printer\n");
- exit(1);
- }
- if (write(printerfd, "\0", 1) != 1) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- fprintf(stderr, "%d bytes sent, status: waiting for end of job\n", size);
- getack(printerfd, 6);
- }
- void
- sendjob(int inputfd, int printerfd)
- {
- struct stat statbuf;
- int strlength;
- if (fstat(inputfd, &statbuf) < 0) {
- fprintf(stderr, "fstat(%s) failed\n", inputname);
- exit(1);
- }
- sprintf(strbuf, "%c%s\n", '\2', printername);
- strlength = strlen(strbuf);
- if (write(printerfd, strbuf, strlength) != strlength) {
- fprintf(stderr, "write(printer) error\n");
- exit(1);
- }
- getack(printerfd, 2);
- debug("send data\n");
- senddata(inputfd, printerfd, statbuf.st_size);
- debug("send control info\n");
- sendctrl(printerfd);
- fprintf(stderr, "%ld bytes sent, status: end of job\n", statbuf.st_size);
- }
- /*
- * make an address, add the defaults
- */
- char *
- netmkaddr(char *linear, char *defnet, char *defsrv)
- {
- static char addr[512];
- char *cp;
- /*
- * dump network name
- */
- cp = strchr(linear, '!');
- if(cp == 0){
- if(defnet==0){
- if(defsrv)
- snprintf(addr, sizeof addr, "net!%s!%s", linear, defsrv);
- else
- snprintf(addr, sizeof addr, "net!%s", linear);
- }
- else {
- if(defsrv)
- snprintf(addr, sizeof addr, "%s!%s!%s", defnet, linear, defsrv);
- else
- snprintf(addr, sizeof addr, "%s!%s", defnet, linear);
- }
- return addr;
- }
- /*
- * if there is already a service, use it
- */
- cp = strchr(cp+1, '!');
- if(cp)
- return linear;
- /*
- * add default service
- */
- if(defsrv == 0)
- return linear;
- sprintf(addr, "%s!%s", linear, defsrv);
- return addr;
- }
- void
- main(int argc, char *argv[])
- {
- int c, usgflg = 0, inputfd, printerfd, sendport;
- char *desthostname, *hnend;
- char portstr[4];
- if (signal(SIGALRM, alarmhandler) == SIG_ERR) {
- fprintf(stderr, "failed to set alarm handler\n");
- exit(1);
- }
- while ((c = getopt(argc, argv, "Dd:k:qs:t:H:P:")) != -1)
- switch (c) {
- case 'D':
- debugflag = 1;
- debug("debugging on\n");
- break;
- case 'd':
- printername = optarg;
- break;
- case 'k':
- if (statflag) {
- fprintf(stderr, "cannot have both -k and -q flags\n");
- exit(1);
- }
- killflag = 1;
- killarg = optarg;
- break;
- case 'q':
- if (killflag) {
- fprintf(stderr, "cannot have both -q and -k flags\n");
- exit(1);
- }
- statflag = 1;
- break;
- case 's':
- seqno = strtol(optarg, NULL, 10);
- if (seqno < 0 || seqno > 999)
- seqno = 0;
- break;
- case 't':
- switch (filetype) {
- case 'c':
- case 'd':
- case 'f':
- case 'g':
- case 'l':
- case 'n':
- case 'o':
- case 'p':
- case 'r':
- case 't':
- case 'v':
- case 'z':
- filetype = optarg[0];
- break;
- default:
- usgflg++;
- break;
- }
- break;
- case 'H':
- strncpy(hostname, optarg, MAXHOSTNAMELEN);
- break;
- case 'P':
- username = optarg;
- break;
- default:
- case '?':
- fprintf(stderr, "unknown option %c\n", c);
- usgflg++;
- }
- if (argc < 2) usgflg++;
- if (optind < argc) {
- desthostname = argv[optind++];
- } else
- usgflg++;
- if (usgflg) {
- fprintf(stderr, "usage: to send a job - %s -d printer -H hostname -P username [-s seqno] [-t[cdfgklnoprtvz]] desthost [filename]\n", argv[0]);
- fprintf(stderr, " to check status - %s -d printer -q desthost\n", argv[0]);
- fprintf(stderr, " to kill a job - %s -d printer -P username -k jobname desthost\n", argv[0]);
- exit(1);
- }
- /* make sure the file to send is here and ready
- * otherwise the TCP connection times out.
- */
- if (!statflag && !killflag) {
- if (optind < argc) {
- inputname = argv[optind++];
- debug("open("); debug(inputname); debug(")\n");
- inputfd = open(inputname, O_RDONLY);
- if (inputfd < 0) {
- fprintf(stderr, "open(%s) failed\n", inputname);
- exit(1);
- }
- } else {
- inputname = "stdin";
- tmpnam(tmpfilename);
- debug("using stdin\n");
- if ((inputfd = open(tmpfilename, O_RDWR|O_CREAT, 0600)) < 0) {
- fprintf(stderr, "open(%s) failed\n", tmpfilename);
- exit(1);
- }
- atexit(cleanup);
- debug("copy input to temp file ");
- debug(tmpfilename);
- debug("\n");
- if (!copyfile(0, inputfd, 0L)) {
- fprintf(stderr, "failed to copy file to temporary file\n");
- exit(1);
- }
- if (lseek(inputfd, 0L, 0) < 0) {
- fprintf(stderr, "failed to seek back to the beginning of the temporary file\n");
- exit(1);
- }
- }
- }
- sprintf(strbuf, "%s", netmkaddr(desthostname, "tcp", "printer"));
- fprintf(stderr, "connecting to %s\n", strbuf);
- for (sendport=721; sendport<=731; sendport++) {
- sprintf(portstr, "%3.3d", sendport);
- fprintf(stderr, " trying from port %s...", portstr);
- debug(" dial("); debug(strbuf); debug(", "); debug(portstr); debug(", 0, 0) ...");
- printerfd = dial(strbuf, portstr, 0, 0);
- if (printerfd >= 0) {
- fprintf(stderr, "connected\n");
- break;
- }
- fprintf(stderr, "failed\n");
- sleep(REDIALTIMEOUT);
- }
- if (printerfd < 0) {
- fprintf(stderr, "Cannot open a valid port!\n");
- fprintf(stderr, "- All source ports [721-731] may be busy.\n");
- fprintf(stderr, "- Is recipient ready and online?\n");
- fprintf(stderr, "- If all else fails, cycle the power!\n");
- exit(1);
- }
- /* hostname[8] = '\0'; */
- #ifndef PLAN9
- if (gethostname(hostname, sizeof(hostname)) < 0) {
- perror("gethostname");
- exit(1);
- }
- #endif
- /* if ((hnend = strchr(hostname, '.')) != NULL)
- *hnend = '\0';
- */
- if (statflag) {
- checkqueue(printerfd);
- } else if (killflag) {
- killjob(printerfd);
- } else {
- sendjob(inputfd, printerfd);
- }
- exit(0);
- }
|