11 #define REDIALTIMEOUT 15
13 #include <Plan9libnet.h>
21 char tmpfilename[L_tmpnam+1];
22 unsigned char sendbuf[SBSIZE];
39 fprintf(stderr, "%s", str);
45 fprintf(stderr, "timeout occurred, check printer.\n");
49 /* send a message after each WARNPC percent of data sent */
53 copyfile(int in, int out, long tosend)
60 fprintf(stderr, "lpdsend: copyfile(%d,%d,%ld)\n",
62 while ((n=read(in, sendbuf, SBSIZE)) > 0) {
64 fprintf(stderr, "lpdsend: copyfile read %d bytes from %d\n",
68 if (write(out, sendbuf, n) != n) {
70 fprintf(stderr, "write to fd %d failed\n", out);
75 fprintf(stderr, "lpdsend: copyfile wrote %d bytes to %d\n",
78 if (tosend && sent*100/tosend >= percent+WARNPC) {
80 fprintf(stderr, ": %5.2f%% sent\n", sent*100.0/tosend);
84 fprintf(stderr, "lpdsend: copyfile read %d bytes from %d\n",
90 char hostname[MAXHOSTNAMELEN], *username, *printername, *killarg;
92 char filetype = 'o'; /* 'o' is for PostScript */
97 killjob(int printerfd)
101 if (printername==0) {
102 fprintf(stderr, "no printer name\n");
106 fprintf(stderr, "no user name given\n");
110 fprintf(stderr, "no job to kill\n");
113 sprintf(strbuf, "%c%s %s %s\n", '\5', printername, username, killarg);
114 strlength = strlen(strbuf);
115 if (write(printerfd, strbuf, strlength) != strlength) {
116 fprintf(stderr, "write(printer) error\n");
119 copyfile(printerfd, 2, 0L);
123 checkqueue(int printerfd)
126 unsigned char sendbuf[1];
128 sprintf(strbuf, "%c%s\n", '\4', printername);
129 strlength = strlen(strbuf);
130 if (write(printerfd, strbuf, strlength) != strlength) {
131 fprintf(stderr, "write(printer) error\n");
134 copyfile(printerfd, 2, 0L);
136 while ((n=read(printerfd, sendbuf, 1)) > 0) {
137 write(2, sendbuf, n);
143 getack(int printerfd, int as)
150 if ((rv = read(printerfd, &resp, 1)) != 1 || resp != '\0') {
151 fprintf(stderr, "getack failed: read returned %d, "
152 "read value (if any) %d, alarmstate=%d\n",
153 rv, resp, alarmstate);
159 /* send control file */
161 sendctrl(int printerfd)
163 char cntrlstrbuf[256];
164 int strlength, cntrlen;
166 sprintf(cntrlstrbuf, "H%s\nP%s\n%cdfA%3.3d%s\n", hostname, username, filetype, seqno, hostname);
167 cntrlen = strlen(cntrlstrbuf);
168 sprintf(strbuf, "%c%d cfA%3.3d%s\n", '\2', cntrlen, seqno, hostname);
169 strlength = strlen(strbuf);
170 if (write(printerfd, strbuf, strlength) != strlength) {
171 fprintf(stderr, "write(printer) error\n");
174 getack(printerfd, 3);
175 if (write(printerfd, cntrlstrbuf, cntrlen) != cntrlen) {
176 fprintf(stderr, "write(printer) error\n");
179 if (write(printerfd, "\0", 1) != 1) {
180 fprintf(stderr, "write(printer) error\n");
183 getack(printerfd, 4);
188 senddata(int inputfd, int printerfd, long size)
192 sprintf(strbuf, "%c%d dfA%3.3d%s\n", '\3', size, seqno, hostname);
193 strlength = strlen(strbuf);
194 if (write(printerfd, strbuf, strlength) != strlength) {
195 fprintf(stderr, "write(printer) error\n");
198 getack(printerfd, 5);
199 if (!copyfile(inputfd, printerfd, size)) {
200 fprintf(stderr, "failed to send file to printer\n");
203 if (write(printerfd, "\0", 1) != 1) {
204 fprintf(stderr, "write(printer) error\n");
207 fprintf(stderr, "%d bytes sent, status: waiting for end of job\n", size);
208 getack(printerfd, 6);
212 sendjob(int inputfd, int printerfd)
217 if (fstat(inputfd, &statbuf) < 0) {
218 fprintf(stderr, "fstat(%s) failed\n", inputname);
221 sprintf(strbuf, "%c%s\n", '\2', printername);
222 strlength = strlen(strbuf);
223 if (write(printerfd, strbuf, strlength) != strlength) {
224 fprintf(stderr, "write(printer) error\n");
227 getack(printerfd, 2);
228 debug("send data\n");
229 senddata(inputfd, printerfd, statbuf.st_size);
230 debug("send control info\n");
232 fprintf(stderr, "%ld bytes sent, status: end of job\n", statbuf.st_size);
236 * make an address, add the defaults
239 netmkaddr(char *linear, char *defnet, char *defsrv)
241 static char addr[512];
247 cp = strchr(linear, '!');
251 snprintf(addr, sizeof addr, "net!%s!%s", linear, defsrv);
253 snprintf(addr, sizeof addr, "net!%s", linear);
257 snprintf(addr, sizeof addr, "%s!%s!%s", defnet, linear, defsrv);
259 snprintf(addr, sizeof addr, "%s!%s", defnet, linear);
265 * if there is already a service, use it
267 cp = strchr(cp+1, '!');
272 * add default service
276 sprintf(addr, "%s!%s", linear, defsrv);
281 main(int argc, char *argv[])
283 int c, usgflg = 0, inputfd, printerfd, sendport;
284 char *desthostname, *hnend;
287 if (signal(SIGALRM, alarmhandler) == SIG_ERR) {
288 fprintf(stderr, "failed to set alarm handler\n");
291 while ((c = getopt(argc, argv, "Dd:k:qs:t:H:P:")) != -1)
295 debug("debugging on\n");
298 printername = optarg;
302 fprintf(stderr, "cannot have both -k and -q flags\n");
310 fprintf(stderr, "cannot have both -q and -k flags\n");
316 seqno = strtol(optarg, NULL, 10);
317 if (seqno < 0 || seqno > 999)
334 filetype = optarg[0];
342 strncpy(hostname, optarg, MAXHOSTNAMELEN);
349 fprintf(stderr, "unknown option %c\n", c);
352 if (argc < 2) usgflg++;
354 desthostname = argv[optind++];
358 fprintf(stderr, "usage: to send a job - %s -d printer -H hostname -P username [-s seqno] [-t[cdfgklnoprtvz]] desthost [filename]\n", argv[0]);
359 fprintf(stderr, " to check status - %s -d printer -q desthost\n", argv[0]);
360 fprintf(stderr, " to kill a job - %s -d printer -P username -k jobname desthost\n", argv[0]);
364 /* make sure the file to send is here and ready
365 * otherwise the TCP connection times out.
367 if (!statflag && !killflag) {
369 inputname = argv[optind++];
370 debug("open("); debug(inputname); debug(")\n");
371 inputfd = open(inputname, O_RDONLY);
373 fprintf(stderr, "open(%s) failed\n", inputname);
379 debug("using stdin\n");
380 if ((inputfd = open(tmpfilename, O_RDWR|O_CREAT, 0600)) < 0) {
381 fprintf(stderr, "open(%s) failed\n", tmpfilename);
385 debug("copy input to temp file ");
388 if (!copyfile(0, inputfd, 0L)) {
389 fprintf(stderr, "failed to copy file to temporary file\n");
392 if (lseek(inputfd, 0L, 0) < 0) {
393 fprintf(stderr, "failed to seek back to the beginning of the temporary file\n");
399 sprintf(strbuf, "%s", netmkaddr(desthostname, "tcp", "printer"));
400 fprintf(stderr, "connecting to %s\n", strbuf);
401 for (sendport=721; sendport<=731; sendport++) {
402 sprintf(portstr, "%3.3d", sendport);
403 fprintf(stderr, " trying from port %s...", portstr);
404 debug(" dial("); debug(strbuf); debug(", "); debug(portstr); debug(", 0, 0) ...");
405 printerfd = dial(strbuf, portstr, 0, 0);
406 if (printerfd >= 0) {
407 fprintf(stderr, "connected\n");
410 fprintf(stderr, "failed\n");
411 sleep(REDIALTIMEOUT);
414 fprintf(stderr, "Cannot open a valid port!\n");
415 fprintf(stderr, "- All source ports [721-731] may be busy.\n");
416 fprintf(stderr, "- Is recipient ready and online?\n");
417 fprintf(stderr, "- If all else fails, cycle the power!\n");
420 /* hostname[8] = '\0'; */
422 if (gethostname(hostname, sizeof(hostname)) < 0) {
423 perror("gethostname");
427 /* if ((hnend = strchr(hostname, '.')) != NULL)
431 checkqueue(printerfd);
432 } else if (killflag) {
435 sendjob(inputfd, printerfd);