Annotation of 43BSD/contrib/xns/examples/print/xnsprint.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * $Header: xnsprint.c,v 2.0 85/11/21 07:23:11 jqj Exp $
                      3:  *
                      4:  * a program to print InterPress masters on an InterPress printer via
                      5:  * Ethernet.   Uses xns Courier.
                      6:  * This version runs on 4.3BSD only!
                      7:  */
                      8: 
                      9: /*
                     10:  * $Log:       xnsprint.c,v $
                     11:  * Revision 2.0  85/11/21  07:23:11  jqj
                     12:  * 4.3BSD standard release
                     13:  * 
                     14:  * Revision 1.1  85/11/20  13:56:53  jqj
                     15:  * Initial revision
                     16:  * 
                     17:  * modified 8-6-85 by jqj.
                     18:  *  Eliminated any hardwired addresses.  Instead, use CH_Enumerate to
                     19:  *  find a printer if none is specified.  Also, you can now print multiple
                     20:  *  files in a single call to xnsprint, and getopt() is used to parse
                     21:  *  arguments.
                     22:  */
                     23: #include <stdio.h>
                     24: #include <sys/types.h>
                     25: #include <netns/ns.h>
                     26: #include <netns/sp.h>
                     27: #include "Printing3_defs.h"
                     28: #include <xnscourier/Clearinghouse2.h>
                     29: #include <xnscourier/except.h>
                     30: #include <pwd.h>
                     31: #include <sys/file.h>
                     32: #include <strings.h>
                     33: 
                     34: static FILE *ipfile = NULL;
                     35: static int ExitStatus = 0;             /* modified lpd conventions: */
                     36:        /* 0 => Job printed.  (successfully sent to print-server) */
                     37: #define X_GOOD 0
                     38:        /* 1 => Couldn't send job.  Retry forever, should go eventually. */
                     39: #define X_RETRY 1
                     40:        /* 2 => Couldn't send job,  Strange error, Retry a limited number*/
                     41:        /*              of times.  If it still hasn't worked, give up.   */
                     42: #define X_LIMRETRY 2
                     43:        /* 3 => Couldn't send job:  Hard error, don't bother retrying,   */
                     44:        /*              get rid of the job.                              */
                     45: #define X_NORETRY 3
                     46: 
                     47: SendSource(bdtconnection)
                     48: CourierConnection *bdtconnection;
                     49: {
                     50:        int count;
                     51:        char buffer[SPPMAXDATA];
                     52: 
                     53:        while ( (count = fread(buffer,1,SPPMAXDATA,ipfile)) > 0 &&
                     54:                BDTwrite(bdtconnection,buffer,count) >= 0 )
                     55:                ;
                     56:        if (count <= 0)
                     57:                BDTclosewrite(bdtconnection);   /* last packet with EOM set */
                     58:        else
                     59:                BDTabort(bdtconnection);
                     60: }
                     61: /* 
                     62:  * misc externals
                     63:  */
                     64: int remove = 0;
                     65: int quiet = 0;
                     66: int attn = 0;          /* Write lpr system STATUS file?        LCP 850415*/
                     67: char *attnfile;                /* Status file name.            LCP 850415 */
                     68: char *FileName = NULL;
                     69: char *UserName = NULL;
                     70: char *Banner = NULL;
                     71: int copies = 1;
                     72: Clearinghouse2_Name hostname;
                     73: char *xnshost = NULL;
                     74: 
                     75: setxnshost(name)
                     76:        Clearinghouse2_ObjectName name;
                     77: {
                     78:        extern char *malloc(), *strcpy();
                     79: 
                     80:        if (xnshost == NULL)
                     81:          xnshost = strcpy(malloc(strlen(name.object)+1),name.object);
                     82: }
                     83: 
                     84: main(argc, argv)
                     85:        int argc;
                     86:        char **argv;
                     87: {
                     88:        struct ns_addr *destaddr;
                     89:        CourierConnection *conn;
                     90:        extern struct ns_addr *getXNSaddr();
                     91:        extern struct ns_addr *CH_LookupAddr();
                     92:        Clearinghouse2_Name hostname, defaultname;
                     93:        extern Clearinghouse2_Name CH_StringToName();
                     94:        int opt;
                     95:        extern int optind;
                     96:        extern char *optarg;
                     97:        int errflg = 0;
                     98: 
                     99:        while ((opt = getopt(argc,argv,"c:n:b:P:h:rqa:")) != EOF)
                    100:            switch (opt) {
                    101:            case 'c':   /* copies */
                    102:                copies = atoi(optarg);
                    103:                break;
                    104:            case 'n':   /* user name */
                    105:                UserName = optarg;
                    106:                break;
                    107:            case 'b':   /* file name */
                    108:                Banner = optarg;
                    109:                break;
                    110:            case 'P':   /* printer */
                    111:            case 'h':   /* host */
                    112:                xnshost = optarg;
                    113:                break;
                    114:            case 'r':   /* remove input file when done */
                    115:                remove++;
                    116:                break;
                    117:            case 'q':   /* don't print status messages */
                    118:                quiet++;
                    119:                break;
                    120:            case 'a':   /* Write lpr STATUS file.  Name follows.  LCP 850415 */
                    121:                quiet++;
                    122:                attn++;
                    123:                attnfile = optarg;
                    124:                break;
                    125:            default:
                    126:                errflg = 1;
                    127:            }
                    128:        if (errflg) {
                    129:                attnmsg("Usage: %s [-r] [-P host] [-c #] [-n name] [-b banner] file...\n",
                    130:                        argv[0]);
                    131:                exit(X_NORETRY);
                    132:        }
                    133: 
                    134:        /* set User Name for banner if necessary */
                    135:        if (UserName == NULL) {
                    136:            struct passwd *pwd, *getpwuid();
                    137:            char *p;
                    138:            extern char *getenv(), *index();
                    139: 
                    140:            UserName = getenv("USER");
                    141:            if ((pwd = getpwuid(getuid())) != NULL) {
                    142:                UserName = pwd->pw_gecos;
                    143:                if (p = index(UserName,','))
                    144:                        *p = '\000';
                    145:            }
                    146:        }
                    147: 
                    148:        /* figure out what address we're sending to */
                    149:        CH_NameDefault(&defaultname);/* default from clearinghouse.addresses */
                    150:        if (xnshost == NULL) {
                    151:                /* find the first object in the local domain of the CH 
                    152:                 * with a printService property.  setxnshost sets xnshost
                    153:                 * to the name part of the object
                    154:                 */
                    155:                hostname = defaultname;
                    156:                hostname.object = "*";
                    157:                CH_Enumerate(hostname,10001,setxnshost);
                    158:                hostname.object = xnshost;
                    159:        }
                    160:        else hostname = CH_StringToName(xnshost,&defaultname);
                    161:        if ((destaddr = CH_LookupAddr(hostname,4)) == NULL) {
                    162:                attnmsg("Invalid address, %s:%s:%s\n",
                    163:                        hostname.object,hostname.domain,hostname.organization);
                    164:                exit(X_NORETRY);
                    165:        }
                    166: 
                    167:        /* make sure the printer is available */
                    168:        checkIPstatus(destaddr);
                    169: 
                    170:        for ( ; optind < argc; optind++) {
                    171:            FileName = argv[optind];
                    172:            if (strcmp(FileName,"-") == 0) {
                    173:                ipfile = stdin;
                    174:                FileName = "standard input";
                    175:            }
                    176:            else if ((ipfile = fopen(FileName,"r")) == NULL) {
                    177:                fprintf(stderr, "%s: Can't open %s\n", argv[0], FileName);
                    178:                exit(X_NORETRY);
                    179:            }
                    180:            if(Banner == NULL)
                    181:                Banner = FileName;
                    182: 
                    183:            if (!quiet)
                    184:                printf("Sending to %s...", xnshost);
                    185:            fflush(stdout);
                    186: 
                    187:            sendIPfile(ipfile,destaddr);
                    188:            if (ipfile != stdin)
                    189:                fclose(ipfile);
                    190:        }
                    191: 
                    192:        if (!quiet)
                    193:                printf("Done.\n");
                    194:        exit(X_GOOD);
                    195: }
                    196: 
                    197: /*
                    198:  * Check printer status first so we won't dump big interpress
                    199:  * files accross the net unless we're fairly confidant that they'll
                    200:  * be accepted.
                    201:  */
                    202: checkIPstatus(destaddr)
                    203:        struct ns_addr *destaddr;
                    204: {
                    205:        CourierConnection *conn;
                    206:        GetPrinterStatusResults StatusResult;
                    207: 
                    208:        do {
                    209:            if (!quiet)
                    210:                printf("Opening connection to %s. ",xnshost);
                    211:            if (attn)
                    212:                attnmsg("Opening connection to %s.\n",xnshost);
                    213:            if ((conn = CourierOpen(destaddr)) == NULL) {
                    214:                attnmsg(stderr,"Can't open connection to %s\n",xnshost);
                    215:                if(remove && !attn)
                    216:                    attnmsg(stderr,"Output left in %s\n", FileName);
                    217:                exit(X_LIMRETRY);
                    218:            }
                    219:            if (!quiet)
                    220:                printf("Connected.\n");
                    221:            if (attn)
                    222:                attnmsg("Requesting status.\n");
                    223:            DURING
                    224:                StatusResult = GetPrinterStatus(conn,NULL);
                    225:            HANDLER {
                    226:                ExitStatus = X_LIMRETRY;
                    227:                switch (Exception.Code) {
                    228:                case ServiceUnavailable:
                    229:                        attnmsg(stderr,"GetStat: Service unavailable\n");
                    230:                        ExitStatus = X_NORETRY;
                    231:                        break;
                    232:                case SystemError:
                    233:                        attnmsg(stderr,"GetStat: System Error\n");
                    234:                        break;
                    235:                case Undefined:
                    236:                        attnmsg(stderr,"GetStat: Undefined error, number %d\n",
                    237:                                CourierErrArgs(UndefinedArgs,problem));
                    238:                        break;
                    239:                case REJECT_ERROR:
                    240:                        attnmsg(stderr,"GetStat: REJECT:  type = %d\n",
                    241:                                CourierErrArgs(rejectionDetails, designator));
                    242:                        break;
                    243:                default:
                    244:                        attnmsg(stderr,"GetStat: Some random error, code %d\n",
                    245:                                Exception.Code);
                    246:                        break;
                    247:                }
                    248:            if (remove && !attn) 
                    249:                attnmsg(stderr,"Output left in %s\n", FileName);
                    250:            exit(ExitStatus);
                    251:            } END_HANDLER;
                    252: 
                    253:            CourierClose(conn);
                    254:        } while (printresults(StatusResult.status) != 0);
                    255: }
                    256: 
                    257: /* 
                    258:  * display printer status, return 0 IFF spooler is available 
                    259:  */
                    260: int
                    261: printresults(status)
                    262:        PrinterStatus status;
                    263: {
                    264:        int i, typ;
                    265:        static char *spoollist[] = {"available","busy","disabled","full"};
                    266:        static char *formatlist[] = {"available","busy","disabled"};
                    267:        static char *printlist[] = {"available","busy","disabled",
                    268:                        "needs attention","needs key operator"};
                    269:        int error = 1;
                    270:        char bufr[256];
                    271: 
                    272:        bufr[0] = '\0';
                    273:        for (i = 0; i < status.length; i++) {
                    274:                switch (status.sequence[i].designator) {
                    275:                case spooler:
                    276:                        typ = (int) status.sequence[i].spooler_case;
                    277:                        if (!quiet || typ > 1)
                    278:                            sprintf(bufr+strlen(bufr),
                    279:                                "Spooler: %s; ", spoollist[typ]);
                    280:                        error = typ;
                    281:                        break;
                    282:                case formatter:
                    283:                        typ = (int) status.sequence[i].formatter_case;
                    284:                        if (!quiet || typ > 1)
                    285:                            sprintf(bufr+strlen(bufr),
                    286:                                "Formatter: %s; ", formatlist[typ]);
                    287:                        break;
                    288:                case printer:
                    289:                        typ = (int) status.sequence[i].printer_case;
                    290:                        if (!quiet || typ > 1)
                    291:                            sprintf(bufr+strlen(bufr),
                    292:                                "Printer: %s. ", printlist[typ]);
                    293:                        break;
                    294:                case media:
                    295:                        /* printmedia(status.sequence[i].media_case); */
                    296:                        break;
                    297:                }
                    298:        }
                    299:        if (bufr[0] != '\0')
                    300:        {
                    301:            if (attn)
                    302:                attnmsg("%s\n",bufr);
                    303:            else
                    304:                printf("%s\n",bufr);
                    305:        }
                    306: 
                    307:        switch(error) {
                    308:                case 0:
                    309:                        break;
                    310:                case 1:
                    311:                        if (!quiet)
                    312:                            printf("Retrying... ");
                    313:                        if (bufr[0] != '\0' && attn)
                    314:                            attnmsg("Status: Busy.  Retrying...\n");
                    315:                        fflush(stdout);
                    316:                        sleep(15);
                    317:                        break;
                    318:                default:
                    319:                        if(remove && !attn)
                    320:                            attnmsg(stderr, "Output left in %s\n", FileName);
                    321:                        exit(1);
                    322:        }
                    323:        return(error);
                    324: }
                    325: 
                    326: 
                    327: attnmsg(fmt,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9)
                    328:        char *fmt;
                    329: {
                    330:        char bufr[256];
                    331:        int af;
                    332: 
                    333:        if (attn)
                    334:        {
                    335:            if ((af = open(attnfile,O_TRUNC|O_WRONLY|O_CREAT,0666)) < 0)
                    336:                    return; /* Oh Well. */
                    337: 
                    338:            sprintf(bufr,fmt,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9);
                    339: 
                    340:            (void) write(af,bufr,strlen(bufr)); /* In case of error??? */
                    341:            close(af);
                    342:        }
                    343:        else
                    344:            fprintf(stderr,fmt,a0,a1,a2,a3,a4,a5,a6,a7,a8,a9);
                    345: }
                    346: 
                    347: sendIPfile(ipfile,destaddr)
                    348:        FILE *ipfile;
                    349:        struct ns_addr *destaddr;
                    350: {
                    351:        PrintResults result;
                    352:        CourierConnection *conn;
                    353:        PrintAttributes attributes;
                    354:        PrintOptions options;
                    355:        char *malloc();
                    356: 
                    357:        /* only use sender name and file name, no date */
                    358:        attributes.length = 2;
                    359:        attributes.sequence = malloc( 2 * sizeof(*attributes.sequence));
                    360:        attributes.sequence[0].designator = printObjectName;
                    361:        attributes.sequence[0].printObjectName_case = Banner;
                    362:        attributes.sequence[1].designator = senderName;
                    363:        attributes.sequence[1].senderName_case = UserName;
                    364: 
                    365:        options.length = 1;
                    366:        options.sequence = malloc( sizeof(*options.sequence));
                    367:        options.sequence[0].designator = copyCount;
                    368:        options.sequence[0].copyCount_case = copies;
                    369: 
                    370: again:
                    371:        if (!quiet)
                    372:                printf("Opening connection to %s. ",xnshost);
                    373:        if (attn)
                    374:                attnmsg("Opening connection to %s.\n",xnshost);
                    375: 
                    376:        if ((conn = CourierOpen(destaddr)) == NULL) {
                    377:                attnmsg(stderr,"Can't open connection to %s\n",xnshost);
                    378:                if(remove && !attn)
                    379:                    attnmsg(stderr,"Output left in %s\n", FileName);
                    380:                exit(X_LIMRETRY);
                    381:        }
                    382: 
                    383:        if (!quiet)
                    384:                printf("Connected.\n");
                    385:        if (attn)
                    386:                attnmsg("Sending to %s\n",xnshost);
                    387: 
                    388:        DURING
                    389:                result = Print(conn, SendSource, BulkData1_immediateSource,
                    390:                                        attributes, options);
                    391:        HANDLER {
                    392:                ExitStatus = X_RETRY;
                    393:                switch (Exception.Code) {
                    394:                case Busy:
                    395:                        if (!quiet)
                    396:                            printf("Busy, retrying...\n");
                    397:                        if (attn)
                    398:                            attnmsg("Busy, retrying...\n");
                    399:                        CourierClose(conn);
                    400:                        sleep(15);
                    401:                        if (rewind(ipfile) < 0) {
                    402:                                ExitStatus = X_LIMRETRY;
                    403:                                attnmsg(stderr,"Can't rewind file\n");
                    404:                        }
                    405:                        goto again;
                    406:                case ConnectionError:
                    407:                        ExitStatus = X_LIMRETRY;
                    408:                        attnmsg(stderr,"Connection error, %d\n",
                    409:                                CourierErrArgs(ConnectionErrorArgs,problem));
                    410:                        break;
                    411:                case InsufficientSpoolSpace:
                    412:                        attnmsg(stderr,"Insufficient Spool Space error\n");
                    413:                        break;
                    414:                case InvalidPrintParameters:
                    415:                        ExitStatus = X_LIMRETRY;
                    416:                        attnmsg(stderr,"InvalidPrintParameters error\n");
                    417:                        break;
                    418:                case MasterTooLarge:
                    419:                        ExitStatus=X_NORETRY;
                    420:                        attnmsg(stderr,"MasterTooLarge error\n");
                    421:                        break;
                    422:                case MediumUnavailable:
                    423:                        ExitStatus=X_NORETRY;
                    424:                        attnmsg(stderr,"MediumUnavailable error\n");
                    425:                        break;
                    426:                case ServiceUnavailable:
                    427:                        ExitStatus=X_NORETRY;
                    428:                        attnmsg(stderr,"ServiceUnavailable error\n");
                    429:                        break;
                    430:                case SpoolingDisabled:
                    431:                        attnmsg(stderr,"SpoolingDisabled\n");
                    432:                        break;
                    433:                case SpoolingQueueFull:
                    434:                        attnmsg(stderr,"SpoolingQueueFull error\n");
                    435:                        break;
                    436:                case SystemError:
                    437:                        ExitStatus = X_LIMRETRY;
                    438:                        attnmsg(stderr,"System Error\n");
                    439:                        break;
                    440:                case TooManyClients:
                    441:                        attnmsg(stderr,"TooManyClients error\n");
                    442:                        break;
                    443:                case TransferError:
                    444:                        ExitStatus = X_LIMRETRY;
                    445:                        attnmsg(stderr,"TransferError error\n");
                    446:                        break;
                    447:                case Undefined:
                    448:                        attnmsg(stderr,"Undefined error, number %d\n",
                    449:                                CourierErrArgs(UndefinedArgs,problem));
                    450:                        break;
                    451:                case REJECT_ERROR:
                    452:                        ExitStatus = X_LIMRETRY;
                    453:                        attnmsg(stderr,"REJECT:  type = %d\n",
                    454:                                CourierErrArgs(rejectionDetails, designator));
                    455:                        break;
                    456:                default:
                    457:                        ExitStatus = X_LIMRETRY;
                    458:                        attnmsg(stderr,"Some random error, code %d\n",
                    459:                                Exception.Code);
                    460:                        break;
                    461:                }
                    462:                if(remove && !attn)
                    463:                    attnmsg(stderr,"Output left in %s\n", FileName);
                    464:                exit(ExitStatus);
                    465:        } END_HANDLER;
                    466: 
                    467:        CourierClose(conn);
                    468: 
                    469:        /* RETURNS [printRequestID: RequestID] */
                    470:        if(remove) unlink(FileName);
                    471: }      

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.