source: trunk/third/transcript/src/ascomm.c @ 9090

Revision 9090, 20.4 KB checked in by ghudson, 28 years ago (diff)
This commit was generated by cvs2svn to compensate for changes in r9089, which included commits to RCS files with non-trunk default branches.
Line 
1#ifndef lint
2#define _NOTICE static char
3_NOTICE N1[] = "Copyright (c) 1993 Adobe Systems Incorporated";
4_NOTICE RCSID[] = "$Header: /afs/dev.mit.edu/source/repository/third/transcript/src/ascomm.c,v 1.1.1.1 1996-10-07 20:25:47 ghudson Exp $";
5#endif
6/*
7 * ascomm.c
8 *
9 * Copyright (C) 1993 Adobe Systems Incorporated.
10 * All rights reserved.
11 *
12 * lpr/lpd communications filter for Adobe network printer.
13 *
14 * ascomm gets called with:
15 *   stdin = the file to print
16 *   stdout = the printer device (ignored)
17 *   stderr = the printer log file
18 *   cwd = the spool directory
19 *   argv = set up by interface shell script:
20 *   filtername -P printer -p filtername -n username -h host [acctfile]
21 *
22 *
23 */
24/*
25  RCSLOG
26  $Log: not supported by cvs2svn $
27 * Revision 1.6  1994/04/08  23:27:38  snichols
28 * added sigignore for SIGPIPE, surrounded by ifdef SYSV since
29 * not all BSD systems have sigignore, and the problem doesn't
30 * happen there anyway.
31 *
32 * Revision 1.5  1994/04/08  23:15:14  snichols
33 * more fixes for Solaris.
34 *
35 * Revision 1.4  1994/04/08  21:03:25  snichols
36 * close fdinput as soon as we're done with it, to avoid SIGPIPE problems
37 * on Solaris.
38 *
39 * Revision 1.3  1994/03/09  18:15:32  snichols
40 * added support for not using the control protocol and not querying status.
41 *
42 * Revision 1.2  1994/02/16  22:41:54  snichols
43 * ported to Solaris, plus some typos corrected.
44 *
45*/
46
47#include <stdlib.h>
48#include <stdio.h>
49#include <unistd.h>
50#include <fcntl.h>
51#include <signal.h>
52#include <sys/time.h>
53#include <sys/wait.h>
54#include <netdb.h>
55#include <sys/types.h>
56#include <sys/socket.h>
57#include <netinet/in.h>
58#include <errno.h>
59#include <netinet/tcp.h>
60#include <string.h>
61
62#include "transcript.h"
63#include "config.h"
64
65#define TRUE 1
66#define FALSE 0
67
68
69static char *prog ="ascomm";
70static char *host = " ";
71static char *name = " ";
72static char *pname = " ";
73static char *accountingfile;
74
75static long startpagecount;
76static long endpagecount;
77
78static char *getpages = "(%%[ pagecount: )print statusdict/pagecount \
79get exec (                      ) cvs print ( ]%%)= flush";
80
81static int socklen;
82static struct sockaddr_in datasock;
83static struct sockaddr_in statussock;
84static struct sockaddr_in self;
85static struct hostent *hp;
86
87static char *hostname;
88static int ppid;
89
90static int fdsend;
91static int fdinput;
92static int fdcontrol;
93static int fdstatus;
94
95int control = 1;
96int status = 1;
97
98struct controlpacket {
99    unsigned char ctrlchar;
100    unsigned char dummy;
101    u_short port;
102} controldata;
103
104static fd_set readfds;
105static fd_set statfds;
106
107static int doactng;
108static int bannerfirst = 0;
109static int bannerlast = 0;
110
111
112/* job state variables */
113typedef enum {
114    init,                       /* initialization */
115    syncstart,                  /* first acc'ting job */
116    sending,                    /* sending main job to printer */
117    waiting,                    /* waiting for EOF from printer */
118    lastpart,                   /* sending banner after job */
119    synclast,                   /* last acc'ting job */
120    ending,                     /* cleaning up */
121    croaking,                   /* abnormal exit */
122    child,                      /* child */
123} states;
124
125static states currentstate;
126
127static int statusp;
128
129static void JobControl();
130
131#define PRINTER_PORT 9100
132#define STATUS_PORT 9101
133#define MYBUFSIZE 10240
134
135#ifdef BDEBUG
136#define debugp(x) {fprintf x ; (void) fflush(stderr);}
137extern int errno;
138#else
139#define debugp(x)
140#endif /* BDEBUG */
141
142static int dataport = PRINTER_PORT;
143static int statusport = STATUS_PORT;
144static int localport;
145
146static void cleanupandexit(code)
147    int code;
148{
149    /* we want to clean and and leave; closing any open file descriptors,
150       and possibly trying to send an end of session to the printer */
151
152    debugp((stderr, "cleanupanexit send %d status %d control %d\n", fdsend,
153            fdstatus, fdcontrol));
154    if (currentstate >= syncstart && currentstate < ending) {
155        /* send a ctrl-D to clean up */
156        controldata.ctrlchar = 0x04;
157        controldata.port = htons(0);
158        JobControl(controldata);
159       
160    }
161    if (fdsend) close(fdsend);
162    if (fdinput) close(fdinput);
163    if (fdstatus) close(fdstatus);
164    if (fdcontrol) close(fdcontrol);
165    exit(code);
166}
167
168#ifdef BDEBUG
169handler(sig)
170    int sig;
171{
172    char buf[20];
173    sprintf(buf, "terminated with signal %d\n", sig);
174    write(2,buf, strlen(buf));
175    _exit(2);
176}
177#endif
178
179static void giveup(sig)
180    int sig;
181{
182    /* child told us to die */
183    debugp((stderr, "Got EMT sig! Die!.\n"));
184    cleanupandexit(2);
185}
186
187static long ParseAnswer(p)
188    char *p;
189{
190    char *r;
191    char *q;
192
193    r = strchr(p, ':');
194    if (r == NULL)
195        return 0;
196    r++;
197    while (*r == ' ') r++;
198    /* now r should point to count */
199    q = strchr(r, ' ');
200    if (q == NULL)
201        return 0;
202    *q = '\0';
203    return atoi(r);
204}
205
206static void AccountingJob(pagecount)
207    long *pagecount;
208{
209    int cnt;
210    char buf[BUFSIZ];
211    int foo;
212    int r;
213    int percents = 0;
214    struct linger linger;
215    char *p;
216
217    /* NOTE: this closes the connection! */
218
219    foo = 1;
220    if (setsockopt(fdsend, IPPROTO_TCP, TCP_NODELAY, (char *)&foo,
221                   sizeof(foo)) < 0) {
222        perror("sockcomm: setsockopt (no delay)");
223        cleanupandexit(2);
224    }
225
226    debugp((stderr, "sending accounting job\n"));
227    cnt = write(fdsend, getpages, strlen(getpages));
228    linger.l_onoff = 0;
229    linger.l_linger = 0;
230    if (setsockopt(fdsend, SOL_SOCKET, SO_LINGER, (char *)&linger,
231                   sizeof(linger))
232        < 0) {
233        perror("sockcomm: setsockopt(linger)");
234        cleanupandexit(2);
235    }
236    shutdown(fdsend, 1);
237    debugp((stderr, "sent %d bytes\n", cnt));
238    p = buf;
239    while ((cnt = read(fdsend, p, BUFSIZ)) > 0) {
240        p += cnt;
241    }
242    *p = '\0';
243    debugp((stderr, "%s\n", buf));
244    *pagecount = ParseAnswer(buf);
245    close(fdsend);
246}
247
248static void AcctEntry(start, end)
249    long start, end;
250{
251    FILE *fp;
252
253    debugp((stderr, "startpagecount %d endpagecount %d\n", startpagecount,
254            endpagecount));
255    if (start > end || start < 0 || end < 0) {
256        fprintf(stderr, "%s: accounting error: start %d end %d\n", prog,
257                start, end);
258        fflush(stderr);
259    }
260    else if ((fp = fopen(accountingfile, "a")) != NULL) {
261        fprintf(fp, "%7.2f\t%s:%s\n", (float) (end - start), host, name);
262        fclose(fp);
263    }
264}
265
266
267
268static void ReopenConn()
269{
270    struct linger linger;
271    struct sockaddr_in sockname;
272    int namelen = sizeof(struct sockaddr_in);
273
274    if ((fdsend = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
275        fprintf(stderr, "%s: error creating data socket\n", prog);
276        cleanupandexit(2);
277    }
278    debugp((stderr, "after data socket call\n"));
279    debugp((stderr, "TCP file descriptor (data) %d\n", fdsend));
280
281    linger.l_onoff = 1;
282    linger.l_linger = 0;
283    if (setsockopt(fdsend, SOL_SOCKET, SO_LINGER, (char *)&linger,
284                   sizeof(linger))
285        < 0) {
286        perror("sockcomm: setsockopt(linger)");
287        cleanupandexit(2);
288    }
289
290    memset(&self, 0, sizeof(self));
291    self.sin_addr.s_addr = htonl(INADDR_ANY);
292    self.sin_family = AF_INET;
293    self.sin_port = htons(0);
294    if (bind(fdsend, (struct sockaddr *)&self, sizeof(self)) < 0) {
295        fprintf(stderr, "%s: bind of local address failed (data)\n", prog);
296        cleanupandexit(2);
297    }
298    getsockname(fdsend, (struct sockaddr *)&sockname, &namelen);
299    debugp((stderr, "local port is %d\n", sockname.sin_port));
300    localport = sockname.sin_port;
301    controldata.ctrlchar = 0x02;
302    controldata.port = localport;
303    JobControl(controldata);
304
305    while (1) {
306        if (connect(fdsend, (struct sockaddr *)&datasock, socklen) < 0) {
307            continue;
308        }
309        break;
310    }
311}
312
313static void SendBanner(done)
314    int done;
315{
316    int banner;
317    int cnt;
318    char buf[MYBUFSIZE];
319
320    debugp((stderr, "in SendBanner\n"));
321    if ((banner = open(".banner", O_RDONLY|O_NDELAY, 0)) < 0) {
322        fprintf(stderr, "%s: no banner file\n", prog);
323        return;
324    }
325    while ((cnt = read(banner, buf, sizeof(buf))) > 0) {
326        debugp((stderr, "read %d bytes for banner.\n", cnt));
327        write(fdsend, buf, cnt);
328    }
329    /* hang around until banner is done */
330    if (done) {
331        shutdown(fdsend, 1);
332        while ((cnt = read(fdsend, buf, sizeof(buf))) > 0);
333    }
334    close(banner);
335}
336
337   
338static int CheckStatus(who)
339    char *who;
340{
341    /* send a packet down a UDP port to the printer; expect
342       interpreter status in return */
343
344    char readbuf[MYBUFSIZE];
345    int nfound = 0;
346    int cnt;
347    int retries = 0;
348    struct sockaddr from;
349    int fromlen;
350    int answered = FALSE;
351    struct timeval timeout;
352
353    if (!status) {
354        return 1;
355    }
356    /* set up select */
357    FD_ZERO(&statfds);
358    FD_SET(fdstatus, &statfds);
359    timeout.tv_sec = 5;
360    timeout.tv_usec = 0;
361
362    cnt = sendto(fdstatus, " ", 1, 0, (struct sockaddr *)&statussock,
363                 sizeof(statussock));
364    debugp((stderr, "%s: sent status query\n", who));
365
366    while (1) {
367        nfound = select(fdstatus+1, &statfds, (fd_set *) 0, (fd_set *) 0,
368                        &timeout);
369        if (nfound > 0) {
370            cnt = recvfrom(fdstatus, readbuf, MYBUFSIZE, 0,
371                           (struct sockaddr *)&from, (int *) &fromlen);
372            if (cnt > 0) {
373                debugp((stderr, "%s: fdstatus read cnt %d\n", who, cnt));
374                readbuf[cnt] = '\0';
375                debugp((stderr, "stat: %s\n", readbuf));
376                answered = TRUE;
377            }
378            else if (cnt == 0) {
379                break;
380            }
381            else {
382                fprintf(stderr, "%s: fatal error reading status\n", prog);
383                perror("");
384                return -1;
385            }
386        }
387        else if (nfound == 0) {
388            if (answered) {
389                /* we received an answer, so this timeout probably means
390                   we're done receiving this answer */
391                break;
392            }
393            debugp((stderr,
394                    "checkstatus: no response from printer, retrying %d.\n",
395                    ++retries));
396            if (retries > 3) {
397                fprintf(stderr,
398                        "%s: no response from printer! giving up.\n", prog);
399                return 0;
400            }
401            cnt = sendto(fdstatus, "\024", 1, 0, (struct sockaddr *)&statussock,
402                         sizeof(statussock));
403            FD_ZERO(&statfds);
404            FD_SET(fdstatus, &statfds);
405            timeout.tv_sec = 5;
406            timeout.tv_usec = 0;
407        }
408    }
409    return 1;
410}
411
412static void Listener()
413{
414    /* child process; listens to the data port.  When
415       it receives EOF on the data port, it exits.  */
416
417    static char readbuf[MYBUFSIZE];
418    int cs, done = FALSE;
419    int nfound = 0;
420    int cnt;
421    struct timeval timeout;
422   
423    /* child */
424    debugp((stderr, "child started\n"));
425
426    while (!done) {
427        debugp((stderr, "child: calling select\n"));
428
429        /* set up select so we can listen on data sockets */
430       
431        FD_ZERO(&readfds);
432        FD_SET(fdsend, &readfds);
433
434        timeout.tv_sec = 15;
435        timeout.tv_usec = 0;
436        nfound = select(fdsend+1, &readfds, (fd_set *) 0,
437                        (fd_set *) 0, &timeout);
438        if (nfound < 0 || nfound > 2) {
439            /* select failed */
440            fprintf(stderr, "%s: select failed\n", prog);
441            perror("");
442            kill(ppid, SIGEMT);
443            cleanupandexit(2);
444        }
445        else {
446            if (nfound == 0) {
447                /* timeout! */
448                debugp((stderr,"child: timeout\n"));
449                cs = CheckStatus("child");
450                if (cs < 1) {
451                    fprintf(stderr, "Giving up!\n");
452                    kill(ppid, SIGEMT);
453                    cleanupandexit(2);
454                }
455            }
456            if (nfound > 0) {
457                debugp((stderr, "child: data ready! %d\n", nfound));
458                /* data ready! */
459                if (FD_ISSET(fdsend, &readfds)) {
460                    debugp((stderr, "child: data ready on fdsend\n"));
461                    cnt = read(fdsend, readbuf, MYBUFSIZE);
462                    debugp((stderr, "child: fdsend read cnt %d\n",
463                            cnt));
464                    if (cnt < 0) {
465                        fprintf(stderr,
466                                "%s: fatal error reading from data port!\n",
467                                prog);
468                        perror("");
469                        kill(ppid, SIGEMT);
470                        cleanupandexit(2);
471                    }
472                    readbuf[cnt] = '\0';
473                    if (cnt > 0) {
474                        fprintf(stderr, "%s", readbuf);
475                    }
476                    else {
477                        done = TRUE;
478                        break;
479                    }
480                }
481            }
482        }
483    }
484    cleanupandexit(2);
485}
486
487static void JobControl(msg)
488    struct controlpacket msg;
489{
490    /* sends msg as a TCP packet down the control port, listens for
491       response; this will change to TCP  */
492    int cnt;
493    int nfound = 0;
494    char readbuf[MYBUFSIZE];
495    int retries = 0;
496    struct sockaddr from;
497    int fromlen;
498    char *p;
499   
500    if (!control) {
501        /* if we're not doing job control, bail */
502        return;
503    }
504    /* send msg */
505    cnt = write(fdcontrol, &msg, sizeof(msg));
506    debugp((stderr, "%d: sent %x\n", currentstate, msg.ctrlchar));
507    cnt = read(fdcontrol, readbuf, sizeof(readbuf));
508    if (cnt > 0) {
509        debugp((stderr, "%d: received %x\n", currentstate, readbuf[0]));
510        if (readbuf[0] != msg.ctrlchar) {
511            fprintf(stderr, "%s: unexpected response from printer!\n", prog);
512            cleanupandexit(2);
513        }
514    }
515}
516
517
518static void abortjob(sig)
519    int sig;
520{
521    debugp((stderr, "%s: Got 'die' signal=%d, state=%d\n", prog, sig,
522            currentstate));
523    controldata.ctrlchar = 0x03;
524    controldata.port = htons(0);
525    switch (currentstate) {
526    case init:
527        cleanupandexit(2);
528        break;
529    case syncstart:
530        fprintf(stderr, "%s: abort (start communications)\n", prog);
531        fflush(stderr);
532        JobControl(controldata);
533        cleanupandexit(2);
534        break;
535    case sending:
536        fprintf(stderr, "%s: abort (sending job)\n", prog);
537        fflush(stderr);
538        JobControl(controldata);
539        cleanupandexit(2);
540        break;
541    case lastpart:
542    case synclast:
543        fprintf(stderr, "%s: abort (post-job processing)\n", prog);
544        fflush(stderr);
545        JobControl(controldata);
546        cleanupandexit(2);
547        break;
548    default:
549        break;
550    }
551}
552
553static void SendFile()
554{
555    int cnt, wc;
556    char *mbp;
557    char mybuf[MYBUFSIZE];
558    int pid, childpid;
559    char readbuf[MYBUFSIZE];
560    int foo = 1;
561    int retries = 0;
562    struct sockaddr_in sockname;
563    int namelen = sizeof(struct sockaddr_in);
564    struct linger linger;
565
566    /* create status, control, and data connectons */
567    if ((fdstatus = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
568        fprintf(stderr, "%s: error creating status socket.\n", prog);
569        perror("");
570        cleanupandexit(2);
571    }
572    debugp((stderr, "after status socket call\n"));
573    debugp((stderr, "status fd is %d\n", fdstatus));
574
575    memset(&self, 0, sizeof(self));
576    self.sin_addr.s_addr = htonl(INADDR_ANY);
577    self.sin_family = AF_INET;
578    self.sin_port = htons(9101);
579
580    if (bind(fdstatus, (struct sockaddr *)&self, sizeof(self)) < 0) {
581        fprintf(stderr, "%s: bind of local address failed (status)\n", prog);
582        cleanupandexit(2);
583    }
584
585    if ((fdcontrol = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
586        fprintf(stderr, "%s: error creating control socket\n", prog);
587        cleanupandexit(2);
588    }
589
590    if (setsockopt(fdcontrol, IPPROTO_TCP, TCP_NODELAY, (char *)&foo,
591                   sizeof(foo)) < 0) {
592        perror("sockcomm: setsockopt (no delay)");
593        cleanupandexit(2);
594    }
595    memset(&self, 0, sizeof(self));
596    self.sin_addr.s_addr = htonl(INADDR_ANY);
597    self.sin_family = AF_INET;
598    self.sin_port = htons(0);
599    if (bind(fdcontrol, (struct sockaddr *)&self, sizeof(self)) < 0) {
600        fprintf(stderr, "%s: bind of local address failed (control)\n", prog);
601        cleanupandexit(2);
602    }
603    socklen = sizeof(statussock);
604    if (control && status) {
605        if (connect(fdcontrol, (struct sockaddr *)&statussock, socklen) < 0 ) {
606            fprintf(stderr, "error connecting\n");
607            perror("");
608            cleanupandexit(1);
609        }
610        debugp((stderr, "after connect call (control)\n"));
611    }
612
613    currentstate = syncstart;
614
615    if ((fdsend = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
616        fprintf(stderr, "%s: error creating data socket\n", prog);
617        cleanupandexit(2);
618    }
619    debugp((stderr, "after data socket call\n"));
620    debugp((stderr, "TCP file descriptor (data) %d\n", fdsend));
621   
622    memset(&self, 0, sizeof(self));
623    self.sin_addr.s_addr = htonl(INADDR_ANY);
624    self.sin_family = AF_INET;
625    /* let system pick it, then we'll tell printer */
626    self.sin_port = htons(0);
627    if (bind(fdsend, (struct sockaddr *)&self, sizeof(self)) < 0) {
628        fprintf(stderr, "%s: bind of local address failed (data)\n", prog);
629        cleanupandexit(2);
630    }
631
632    getsockname(fdsend, (struct sockaddr *)&sockname, &namelen);
633    localport = sockname.sin_port;
634    debugp((stderr, "local port is %d\n", ntohs(localport)));
635    memset(&controldata, 0, sizeof(controldata));
636    controldata.ctrlchar = 0x01;
637    JobControl(controldata);
638
639    controldata.ctrlchar = 0x02;
640    controldata.port = localport;
641    JobControl(controldata);
642
643    debugp((stderr, "trying to connect to data socket...\n"));
644
645    socklen = sizeof(datasock);
646    if (connect(fdsend, (struct sockaddr *)&datasock, socklen) < 0 ) {
647        fprintf(stderr, "%s: error connecting (data)\n", prog);
648        perror("");
649        cleanupandexit(2);
650    }
651    debugp((stderr, "after connect call \n"));
652
653    /* do accounting, if necessary */
654
655    if (doactng) {
656        AccountingJob(&startpagecount);
657        ReopenConn();
658    }
659
660    /* fork a child for listening */
661    if ((pid = fork()) < 0) {
662        fprintf(stderr, "fork failed \n");
663        perror("");
664        cleanupandexit(2);
665    }
666    if (pid == 0) {
667        currentstate = child;
668        Listener();
669        /* should never get here */
670        exit(2);
671    }
672    /* parent */
673
674    /* send file */
675    currentstate = sending;
676    if (bannerfirst) {
677        SendBanner(0);
678        if (!bannerlast) unlink(".banner");
679    }
680    debugp((stderr, "sending file\n"));
681    while ((cnt = read(fdinput, mybuf, sizeof(mybuf))) > 0) {
682        mbp = mybuf;
683        debugp((stderr, "parent: read %d bytes\n", cnt));
684        while ((cnt > 0) && ((wc = write(fdsend, mbp, cnt)) != cnt)) {
685            if (wc < 0) {
686                fprintf(stderr, "%s: error writing to printer\n", prog);
687                perror("");
688                sleep(10);
689                kill(pid, SIGEMT);
690                cleanupandexit(1);
691            }
692            debugp((stderr, "parent: wrote %d bytes\n", wc));
693            mbp += wc;
694            cnt -= wc;
695        }
696        debugp((stderr, "parent: wrote it all, read some more\n"));
697    }
698    linger.l_onoff = 0;
699    linger.l_linger = 0;
700    if (setsockopt(fdsend, SOL_SOCKET, SO_LINGER, (char *)&linger,
701                   sizeof(linger))
702        < 0) {
703        perror("sockcomm: setsockopt(linger)");
704        cleanupandexit(2);
705    }
706    close(fdinput);
707    shutdown(fdsend, 1);
708    debugp((stderr, "after shutdown\n"));
709    if (cnt < 0) {
710        fprintf(stderr, "%s: error reading input file\n", prog);
711        perror("");
712        sleep(10);
713        kill(pid, SIGEMT);
714        cleanupandexit(1);
715    }
716    debugp((stderr, "sent file\n"));
717    currentstate = waiting;
718    while ((childpid=wait(&statusp)) > 0) {
719        debugp((stderr, "parent: wait returned pid %d status %d\n",
720                childpid, statusp));
721        if (childpid == pid)
722            break;
723    }
724    if (bannerlast) {
725        currentstate = lastpart;
726        ReopenConn();
727        SendBanner(1);
728        close(fdsend);
729        if (bannerlast > 1) unlink(".banner");
730    }
731    if (doactng) {
732        currentstate = synclast;
733        ReopenConn();
734        AccountingJob(&endpagecount);
735        AcctEntry(startpagecount, endpagecount);
736    }
737    currentstate = ending;
738    controldata.ctrlchar = 0x04;
739    controldata.port = htons(0);
740    JobControl(controldata);
741}
742   
743
744#define ARGS "P:n:h:p:"
745extern char *optarg;
746extern int optind;
747
748main(argc, argv)
749    int argc;
750    char **argv;
751{
752    int i;
753    int argp;
754    long starttime;
755    char *tmp;
756    long addr;
757   
758
759    currentstate = init;
760    while ((argp = getopt(argc, argv, ARGS)) != EOF) {
761        switch(argp) {
762        case 'P':
763            /* printer name */
764            pname = optarg;
765            break;
766        case 'n':
767            name = optarg;
768            break;
769        case 'h':
770            host = optarg;
771            break;
772        case 'p':
773            prog = optarg;
774            break;
775        }
776    }
777
778    if (argc > optind)
779        accountingfile = argv[optind];
780
781    doactng = name && accountingfile && (access(accountingfile, W_OK) == 0);
782
783    if (tmp = getenv("BANNERFIRST"))
784        bannerfirst = atoi(tmp);
785
786    if (tmp = getenv("BANNERLAST"))
787        bannerlast = atoi(tmp);
788
789    if (tmp = getenv("ASCONTROL"))
790        control = atoi(tmp);
791
792    if (tmp = getenv("ASSTATUS"))
793        status = atoi(tmp);
794
795    /* init signal processing */
796#ifdef BDEBUG
797    for (i=1; i<31; i++)
798        if (i != SIGCHLD)
799            signal(i, handler);
800#endif   
801    signal(SIGEMT, giveup);
802    signal(SIGINT, abortjob);
803    signal(SIGHUP, abortjob);
804    signal(SIGTERM, abortjob);
805#ifdef SYSV
806    sigignore(SIGPIPE);
807#endif /* SYSV */   
808
809#ifdef BSD
810    time(&starttime);
811    fprintf(stderr, "%s: %s:%s %s start - %s", prog, host, name, pname,
812            ctime(&starttime));
813    fflush(stderr);
814#endif /* BSD */   
815   
816    ppid = getpid();
817
818    fdinput = fileno(stdin);
819
820    memset(&statussock, 0, sizeof(statussock));
821    memset(&datasock, 0, sizeof(datasock));
822    datasock.sin_addr.s_addr = inet_addr(pname);
823    statussock.sin_addr.s_addr = inet_addr(pname);
824    if (datasock.sin_addr.s_addr == -1) {
825        if ((hp = gethostbyname(pname)) == NULL) {
826            fprintf(stderr, "%s: couldn't find host %s.\n", prog, pname);
827            cleanupandexit(2);
828        }
829        debugp((stderr, "after gethostbyname\n"));
830        debugp((stderr,
831                "printer hostent fields: name %s\n addr %s length 0x%x\n",
832                hp->h_name, inet_ntoa((struct in_addr *) (hp->h_addr)),
833                hp->h_length));
834        memcpy(&datasock.sin_addr, hp->h_addr, hp->h_length);
835        memcpy(&statussock.sin_addr, hp->h_addr, hp->h_length);
836    }
837
838    debugp((stderr, "port no. %d\n", dataport));
839
840    datasock.sin_family = AF_INET;
841    datasock.sin_port = htons(dataport);
842
843    statussock.sin_family = AF_INET;
844    statussock.sin_port = htons(statusport);
845
846    debugp((stderr, "status port no %d\n", statusport));
847
848    SendFile();
849
850#ifdef BSD
851    time(&starttime);
852    fprintf(stderr, "%s: end - %s", prog, ctime(&starttime));
853    fflush(stderr);
854#endif /* BSD */   
855    cleanupandexit(0);
856}
Note: See TracBrowser for help on using the repository browser.