|
|
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.