static rdpPrintJob* printer_cups_create_printjob(rdpPrinter* printer, UINT32 id) { rdpCupsPrinter* cups_printer = (rdpCupsPrinter*) printer; rdpCupsPrintJob* cups_printjob; if (cups_printer->printjob != NULL) return NULL; cups_printjob = (rdpCupsPrintJob*) malloc(sizeof(rdpCupsPrintJob)); ZeroMemory(cups_printjob, sizeof(rdpCupsPrintJob)); cups_printjob->printjob.id = id; cups_printjob->printjob.printer = printer; cups_printjob->printjob.Write = printer_cups_write_printjob; cups_printjob->printjob.Close = printer_cups_close_printjob; #ifndef _CUPS_API_1_4 cups_printjob->printjob_object = _strdup(tmpnam(NULL)); #else { char buf[100]; cups_printjob->printjob_object = httpConnectEncrypt(cupsServer(), ippPort(), HTTP_ENCRYPT_IF_REQUESTED); if (cups_printjob->printjob_object == NULL) { DEBUG_WARN("httpConnectEncrypt: %s", cupsLastErrorString()); free(cups_printjob); return NULL; } printer_cups_get_printjob_name(buf, sizeof(buf)); cups_printjob->printjob_id = cupsCreateJob((http_t*) cups_printjob->printjob_object, printer->name, buf, 0, NULL); if (cups_printjob->printjob_id == 0) { DEBUG_WARN("cupsCreateJob: %s", cupsLastErrorString()); httpClose((http_t*) cups_printjob->printjob_object); free(cups_printjob); return NULL; } cupsStartDocument((http_t*) cups_printjob->printjob_object, printer->name, cups_printjob->printjob_id, buf, CUPS_FORMAT_AUTO, 1); } #endif cups_printer->printjob = cups_printjob; return (rdpPrintJob*)cups_printjob; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int i, /* Looping var */ num_settings; /* Number of settings */ cups_option_t *settings; /* Settings */ http_t *http; /* Connection to server */ /* * Connect to the server using the defaults... */ http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 30000, NULL); /* * Set the current configuration if we have anything on the command-line... */ if (argc > 1) { for (i = 1, num_settings = 0, settings = NULL; i < argc; i ++) num_settings = cupsParseOptions(argv[i], num_settings, &settings); if (cupsAdminSetServerSettings(http, num_settings, settings)) { puts("New server settings:"); cupsFreeOptions(num_settings, settings); } else { printf("Server settings not changed: %s\n", cupsLastErrorString()); return (1); } } else puts("Current server settings:"); /* * Get the current configuration... */ if (cupsAdminGetServerSettings(http, &num_settings, &settings)) { show_settings(num_settings, settings); cupsFreeOptions(num_settings, settings); return (0); } else { printf(" %s\n", cupsLastErrorString()); return (1); } }
uint32 printer_hw_create(IRP * irp, const char * path) { PRINTER_DEVICE_INFO * info; info = (PRINTER_DEVICE_INFO *) irp->dev->info; /* Server's print queue will ensure no two print jobs will be sent to the same printer. However, we still want to do a simple locking just to ensure we are safe. */ if (info->printjob_object) { return RD_STATUS_DEVICE_BUSY; } #ifndef _CUPS_API_1_4 info->printjob_id++; info->printjob_object = strdup(tmpnam(NULL)); #else { char buf[100]; info->printjob_object = httpConnectEncrypt(cupsServer(), ippPort(), HTTP_ENCRYPT_IF_REQUESTED); if (info->printjob_object == NULL) { LLOGLN(0, ("printer_hw_create: httpConnectEncrypt: %s", cupsLastErrorString())); return RD_STATUS_DEVICE_BUSY; } printer_hw_get_printjob_name(buf, sizeof(buf)); info->printjob_id = cupsCreateJob((http_t *) info->printjob_object, info->printer_name, buf, 0, NULL); if (info->printjob_id == 0) { LLOGLN(0, ("printer_hw_create: cupsCreateJob: %s", cupsLastErrorString())); httpClose((http_t *) info->printjob_object); info->printjob_object = NULL; /* Should get the right return code based on printer status */ return RD_STATUS_DEVICE_BUSY; } cupsStartDocument((http_t *) info->printjob_object, info->printer_name, info->printjob_id, buf, CUPS_FORMAT_POSTSCRIPT, 1); } #endif LLOGLN(10, ("printe_hw_create: %s id=%d", info->printer_name, info->printjob_id)); irp->fileID = info->printjob_id; return RD_STATUS_SUCCESS; }
int getPrinterSharingStatus() { http_t* cups = nullptr; int num_settings = 0; cups_option_t* settings = nullptr; const char* value = nullptr; cups = httpConnect2(cupsServer(), ippPort(), nullptr, AF_INET, cupsEncryption(), 1, 30000, nullptr); if (cups == nullptr) { return 0; } int ret = cupsAdminGetServerSettings(cups, &num_settings, &settings); if (ret != 0) { value = cupsGetOption("_share_printers", num_settings, settings); cupsFreeOptions(num_settings, settings); } else { VLOG(1) << "Unable to get CUPS server settings: " << cupsLastErrorString(); } httpClose(cups); if (value != nullptr) { return *value == '1' ? 1 : 0; } return 0; }
void ofxCUPS::printImage(string filename) { int num_options = 0; cups_option_t *options = NULL; string path = ofFilePath::getAbsolutePath(""); string currentFile = filename; string printFile = path + currentFile; //optionen = "media=DS_PC_size"; //ds40 //num_options = cupsParseOptions(optionen.c_str(), num_options, &options); int last_job_id = cupsPrintFile( printerName.c_str(), printFile.c_str(), jobTitle.c_str() ? jobTitle.c_str() : "print from ofxCUPS", num_options, options); cout << "the job id is: " << last_job_id << endl; if (last_job_id == 0) { cout << "print Error: " << cupsLastErrorString() << endl; } cupsFreeOptions(num_options,options); }
static void list_options(cups_dest_t *dest) /* I - Destination to list */ { int i; /* Looping var */ const char *filename; /* PPD filename */ ppd_file_t *ppd; /* PPD data */ ppd_group_t *group; /* Current group */ if ((filename = cupsGetPPD(dest->name)) == NULL) { _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"), dest->name, cupsLastErrorString()); return; } if ((ppd = ppdOpenFile(filename)) == NULL) { unlink(filename); _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."), dest->name); return; } ppdMarkDefaults(ppd); cupsMarkOptions(ppd, dest->num_options, dest->options); for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) list_group(ppd, group); ppdClose(ppd); unlink(filename); }
static void printer_cups_close_printjob(rdpPrintJob* printjob) { rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*)printjob; #ifndef _CUPS_API_1_4 { char buf[100]; printer_cups_get_printjob_name(buf, sizeof(buf)); if (cupsPrintFile(printjob->printer->name, (const char *)cups_printjob->printjob_object, buf, 0, NULL) == 0) { DEBUG_WARN("cupsPrintFile: %s", cupsLastErrorString()); } unlink(cups_printjob->printjob_object); xfree(cups_printjob->printjob_object); } #else cupsFinishDocument((http_t*)cups_printjob->printjob_object, printjob->printer->name); cups_printjob->printjob_id = 0; httpClose((http_t*)cups_printjob->printjob_object); #endif xfree(cups_printjob); ((rdpCupsPrinter*)printjob->printer)->printjob = NULL; }
void ofxCUPS::printImage(string filename, bool isAbsolutePath) { int num_options = 0; cups_option_t *options = NULL; string printFile; if(isAbsolutePath) { printFile = filename; } else { printFile = ofToDataPath("./",true) + filename; } //optionen = "media=DS_PC_size"; //ds40 //num_options = cupsParseOptions(optionen.c_str(), num_options, &options); int last_job_id = cupsPrintFile( printerName.c_str(), printFile.c_str(), jobTitle.c_str() ? jobTitle.c_str() : "print from ofxCUPS", num_options, options); cout << "the job id is: " << last_job_id << endl; if (last_job_id == 0) { cout << "print Error: " << cupsLastErrorString() << endl; } cupsFreeOptions(num_options,options); }
ipp_status_t /* O - Status of document submission */ cupsFinishDestDocument( http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ cups_dinfo_t *info) /* I - Destination information */ { DEBUG_printf(("cupsFinishDestDocument(http=%p, dest=%p(%s/%s), info=%p)", http, dest, dest ? dest->name : NULL, dest ? dest->instance : NULL, info)); /* * Range check input... */ if (!http || !dest || !info) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); DEBUG_puts("1cupsFinishDestDocument: Bad arguments."); return (IPP_STATUS_ERROR_INTERNAL); } /* * Get the response at the end of the document and return it... */ ippDelete(cupsGetResponse(http, info->resource)); DEBUG_printf(("1cupsFinishDestDocument: %s (%s)", ippErrorString(cupsLastError()), cupsLastErrorString())); return (cupsLastError()); }
static void list_options(cups_dest_t *dest) /* I - Destination to list */ { http_t *http; /* Connection to destination */ char resource[1024]; /* Resource path */ int i; /* Looping var */ const char *filename; /* PPD filename */ ppd_file_t *ppd; /* PPD data */ ppd_group_t *group; /* Current group */ if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, resource, sizeof(resource), NULL, NULL)) == NULL) { _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"), dest->name, cupsLastErrorString()); return; } if ((filename = cupsGetPPD2(http, dest->name)) == NULL) { httpClose(http); _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"), dest->name, cupsLastErrorString()); return; } httpClose(http); if ((ppd = ppdOpenFile(filename)) == NULL) { unlink(filename); _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."), dest->name); return; } ppdMarkDefaults(ppd); cupsMarkOptions(ppd, dest->num_options, dest->options); for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) list_group(ppd, group); ppdClose(ppd); unlink(filename); }
int /* O - 0 on success, non-zero on error */ export_dest(http_t *http, /* I - Connection to server */ const char *dest) /* I - Destination to export */ { int status; /* Status of export */ char ppdfile[1024], /* PPD file for printer drivers */ prompt[1024]; /* Password prompt */ int tries; /* Number of tries */ /* * Get the Windows PPD file for the printer... */ if (!cupsAdminCreateWindowsPPD(http, dest, ppdfile, sizeof(ppdfile))) { _cupsLangPrintf(stderr, _("cupsaddsmb: No PPD file for printer \"%s\" - %s"), dest, cupsLastErrorString()); return (1); } /* * Try to export it... */ for (status = 0, tries = 0; !status && tries < 3; tries ++) { /* * Get the password, as needed... */ if (!SAMBAPassword) { snprintf(prompt, sizeof(prompt), _cupsLangString(cupsLangDefault(), _("Password for %s required to access %s via " "SAMBA: ")), SAMBAUser, SAMBAServer); if ((SAMBAPassword = cupsGetPassword(prompt)) == NULL) break; } status = cupsAdminExportSamba(dest, ppdfile, SAMBAServer, SAMBAUser, SAMBAPassword, Verbosity ? stderr : NULL); if (!status && cupsLastError() == IPP_NOT_FOUND) break; } unlink(ppdfile); return (!status); }
/* * call-seq: * print_job.error_reason -> String * * Get the last human-readable error string */ static VALUE cups_get_error_reason(VALUE self) { VALUE job_id = rb_iv_get(self, "@job_id"); if (NIL_P(job_id) || !NUM2INT(job_id) == 0) { return Qnil; } else { VALUE error_exp = rb_str_new2(cupsLastErrorString()); return error_exp; } }
static int /* O - 0 on success, -1 on failure */ print_file(http_t *http, /* I - HTTP connection */ int id, /* I - Job ID */ const char *filename, /* I - File to print */ const char *docname, /* I - document-name */ const char *user, /* I - requesting-user-name */ const char *format, /* I - document-format */ int last) /* I - 1 = last file in job */ { ipp_t *request; /* IPP request */ char uri[HTTP_MAX_URI]; /* Printer URI */ /* * Setup the Send-Document request... */ request = ippNewRequest(IPP_SEND_DOCUMENT); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); if (docname) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", NULL, docname); if (format) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, format); ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", (char)last); /* * Do the request... */ snprintf(uri, sizeof(uri), "/jobs/%d", id); ippDelete(cupsDoFileRequest(http, request, uri, filename)); if (cupsLastError() > IPP_OK_CONFLICT) { syslog(LOG_ERR, "Unable to send document - %s", cupsLastErrorString()); return (-1); } return (0); }
static int /* O - 0 on success, 1 on fail */ enable_printer(http_t *http, /* I - Server connection */ char *printer) /* I - Printer to enable */ { ipp_t *request; /* IPP Request */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ DEBUG_printf(("enable_printer(%p, \"%s\")\n", http, printer)); /* * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which * require the following attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * printer-state * printer-is-accepting-jobs */ if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS) request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); else request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state", IPP_PRINTER_IDLE); ippAddBoolean(request, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
static int /* O - 0 on success, 1 on fail */ delete_printer_option(http_t *http, /* I - Server connection */ char *printer, /* I - Printer */ char *option) /* I - Option to delete */ { ipp_t *request; /* IPP request */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ /* * Build a CUPS_ADD_MODIFY_PRINTER or CUPS_ADD_MODIFY_CLASS request, which * requires the following attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * option with deleteAttr tag */ if (get_printer_type(http, printer, uri, sizeof(uri)) & CUPS_PRINTER_CLASS) request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); else request = ippNewRequest(CUPS_ADD_MODIFY_PRINTER); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddInteger(request, IPP_TAG_PRINTER, IPP_TAG_DELETEATTR, option, 0); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
static int /* O - 0 on success, 1 on fail */ default_printer(http_t *http, /* I - Server connection */ char *printer) /* I - Printer name */ { ipp_t *request; /* IPP Request */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ DEBUG_printf(("default_printer(%p, \"%s\")\n", http, printer)); /* * Build a CUPS_SET_DEFAULT request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer); request = ippNewRequest(CUPS_SET_DEFAULT); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
uint32 printer_hw_close(IRP * irp) { PRINTER_DEVICE_INFO * info; info = (PRINTER_DEVICE_INFO *) irp->dev->info; LLOGLN(10, ("printe_hw_close: %s id=%d", info->printer_name, irp->fileID)); if (irp->fileID != info->printjob_id) { LLOGLN(0, ("printer_hw_close: invalid file id")); return RD_STATUS_INVALID_HANDLE; } #ifndef _CUPS_API_1_4 { char buf[100]; printer_hw_get_printjob_name(buf, sizeof(buf)); if (cupsPrintFile(info->printer_name, (const char *) info->printjob_object, buf, 0, NULL) == 0) { LLOGLN(0, ("printer_hw_close: cupsPrintFile: %s", cupsLastErrorString())); } unlink(info->printjob_object); free(info->printjob_object); } #else cupsFinishDocument((http_t *) info->printjob_object, info->printer_name); info->printjob_id = 0; httpClose((http_t *) info->printjob_object); #endif info->printjob_object = NULL; return RD_STATUS_SUCCESS; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ const char *opt, /* Current option character */ *name = NULL, /* Service name */ *type = "_ipp._tcp", /* Service type */ *domain = "local."; /* Service domain */ #ifdef HAVE_DNSSD DNSServiceRef ref; /* Browsing service reference */ #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI AvahiClient *client; /* Client information */ int error; /* Error code, if any */ #endif /* HAVE_AVAHI */ for (i = 1; i < argc; i ++) if (!strcmp(argv[i], "snmp")) snmponly = 1; else if (!strcmp(argv[i], "ipp")) ipponly = 1; else { puts("Usage: ./ipp-printers [{ipp | snmp}]"); return (1); } /* * Create an array to track devices... */ devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); /* * Browse for different kinds of printers... */ if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) { perror("ERROR: Unable to create service connection"); return (1); } fd = DNSServiceRefSockFD(main_ref); ipp_ref = main_ref; DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, browse_callback, devices); /* * Loop until we are killed... */ progress(); for (;;) { FD_ZERO(&input); FD_SET(fd, &input); timeout.tv_sec = 2; timeout.tv_usec = 500000; if (select(fd + 1, &input, NULL, NULL, &timeout) <= 0) { time_t curtime = time(NULL); for (device = (cups_device_t *)cupsArrayFirst(devices); device; device = (cups_device_t *)cupsArrayNext(devices)) if (!device->got_resolve) { if (!device->ref) break; if ((curtime - device->resolve_time) > 10) { device->got_resolve = -1; fprintf(stderr, "\rUnable to resolve \"%s\": timeout\n", device->name); progress(); } else break; } if (!device) break; } if (FD_ISSET(fd, &input)) { /* * Process results of our browsing... */ progress(); DNSServiceProcessResult(main_ref); } else { /* * Query any devices we've found... */ DNSServiceErrorType status; /* DNS query status */ int count; /* Number of queries */ for (device = (cups_device_t *)cupsArrayFirst(devices), count = 0; device; device = (cups_device_t *)cupsArrayNext(devices)) { if (!device->ref && !device->sent) { /* * Found the device, now get the TXT record(s) for it... */ if (count < 50) { device->resolve_time = time(NULL); device->ref = main_ref; status = DNSServiceResolve(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->name, device->regtype, device->domain, resolve_callback, device); if (status != kDNSServiceErr_NoError) { fprintf(stderr, "\rUnable to resolve \"%s\": %d\n", device->name, status); progress(); } else count ++; } } else if (!device->sent && device->got_resolve) { /* * Got the TXT records, now report the device... */ DNSServiceRefDeallocate(device->ref); device->ref = 0; device->sent = 1; } } } } #ifndef DEBUG fprintf(stderr, "\rFound %d printers. Now querying for capabilities...\n", cupsArrayCount(devices)); #endif /* !DEBUG */ puts("#!/bin/sh -x"); puts("test -d results && rm -rf results"); puts("mkdir results"); puts("CUPS_DEBUG_LEVEL=6; export CUPS_DEBUG_LEVEL"); puts("CUPS_DEBUG_FILTER='^(ipp|http|_ipp|_http|cupsGetResponse|cupsSend|" "cupsWrite|cupsDo).*'; export CUPS_DEBUG_FILTER"); for (device = (cups_device_t *)cupsArrayFirst(devices); device; device = (cups_device_t *)cupsArrayNext(devices)) { if (device->got_resolve <= 0 || device->cups_shared) continue; #ifdef DEBUG fprintf(stderr, "Checking \"%s\" (got_resolve=%d, cups_shared=%d, uri=%s)\n", device->name, device->got_resolve, device->cups_shared, device->uri); #else fprintf(stderr, "Checking \"%s\"...\n", device->name); #endif /* DEBUG */ if ((http = httpConnect(device->host, device->port)) == NULL) { fprintf(stderr, "Failed to connect to \"%s\": %s\n", device->name, cupsLastErrorString()); continue; } request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, device->uri); response = cupsDoRequest(http, request, device->rp); if (cupsLastError() > IPP_OK_SUBST) fprintf(stderr, "Failed to query \"%s\": %s\n", device->name, cupsLastErrorString()); else { if ((attr = ippFindAttribute(response, "ipp-versions-supported", IPP_TAG_KEYWORD)) != NULL) { version = attr->values[0].string.text; for (i = 1; i < attr->num_values; i ++) if (strcmp(attr->values[i].string.text, version) > 0) version = attr->values[i].string.text; } else version = "1.0"; testfile = NULL; if ((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL) { /* * Figure out the test file for printing, preferring PDF and PostScript * over JPEG and plain text... */ for (i = 0; i < attr->num_values; i ++) { if (!strcasecmp(attr->values[i].string.text, "application/pdf")) { testfile = "testfile.pdf"; break; } else if (!strcasecmp(attr->values[i].string.text, "application/postscript")) testfile = "testfile.ps"; else if (!strcasecmp(attr->values[i].string.text, "image/jpeg") && !testfile) testfile = "testfile.jpg"; else if (!strcasecmp(attr->values[i].string.text, "text/plain") && !testfile) testfile = "testfile.txt"; else if (!strcasecmp(attr->values[i].string.text, "application/vnd.hp-PCL") && !testfile) testfile = "testfile.pcl"; } if (!testfile) { fprintf(stderr, "Printer \"%s\" reports the following IPP file formats:\n", device->name); for (i = 0; i < attr->num_values; i ++) fprintf(stderr, " \"%s\"\n", attr->values[i].string.text); } } if (!testfile && device->pdl) { char *pdl, /* Copy of pdl string */ *start, *end; /* Pointers into pdl string */ pdl = strdup(device->pdl); for (start = device->pdl; start && *start; start = end) { if ((end = strchr(start, ',')) != NULL) *end++ = '\0'; if (!strcasecmp(start, "application/pdf")) { testfile = "testfile.pdf"; break; } else if (!strcasecmp(start, "application/postscript")) testfile = "testfile.ps"; else if (!strcasecmp(start, "image/jpeg") && !testfile) testfile = "testfile.jpg"; else if (!strcasecmp(start, "text/plain") && !testfile) testfile = "testfile.txt"; else if (!strcasecmp(start, "application/vnd.hp-PCL") && !testfile) testfile = "testfile.pcl"; } free(pdl); if (testfile) { fprintf(stderr, "Using \"%s\" for printer \"%s\" based on TXT record pdl " "info.\n", testfile, device->name); } else { fprintf(stderr, "Printer \"%s\" reports the following TXT file formats:\n", device->name); fprintf(stderr, " \"%s\"\n", device->pdl); } } if (!device->ty && (attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL) device->ty = strdup(attr->values[0].string.text); if (strcmp(version, "1.0") && testfile && device->ty) { char filename[1024], /* Filename */ *fileptr; /* Pointer into filename */ const char *typtr; /* Pointer into ty */ if (!strncasecmp(device->ty, "DeskJet", 7) || !strncasecmp(device->ty, "DesignJet", 9) || !strncasecmp(device->ty, "OfficeJet", 9) || !strncasecmp(device->ty, "Photosmart", 10)) strlcpy(filename, "HP_", sizeof(filename)); else filename[0] = '\0'; fileptr = filename + strlen(filename); if (!strncasecmp(device->ty, "Lexmark International Lexmark", 29)) typtr = device->ty + 22; else typtr = device->ty; while (*typtr && fileptr < (filename + sizeof(filename) - 1)) { if (isalnum(*typtr & 255) || *typtr == '-') *fileptr++ = *typtr++; else { *fileptr++ = '_'; typtr++; } } *fileptr = '\0'; printf("# %s\n", device->name); printf("echo \"Testing %s...\"\n", device->name); if (!ipponly) { printf("echo \"snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 " "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1\" > results/%s.snmpwalk\n", device->host, filename); printf("snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 " "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1 | " "tee -a results/%s.snmpwalk\n", device->host, filename); } if (!snmponly) { printf("echo \"./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s " "ipp-%s.test\" > results/%s.log\n", testfile, version, device->uri, version, filename); printf("CUPS_DEBUG_LOG=results/%s.debug_log " "./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s " "ipp-%s.test | tee -a results/%s.log\n", filename, testfile, version, device->uri, version, filename); } puts(""); } else if (!device->ty) fprintf(stderr, "Ignoring \"%s\" since it doesn't provide a make and model.\n", device->name); else if (!testfile) fprintf(stderr, "Ignoring \"%s\" since it does not support a common format.\n", device->name); else fprintf(stderr, "Ignoring \"%s\" since it only supports IPP/1.0.\n", device->name); } ippDelete(response); httpClose(http); } return (0); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int status = 0, /* Exit status */ i, /* Looping var */ num_dests; /* Number of destinations */ cups_dest_t *dests, /* Destinations */ *dest, /* Current destination */ *named_dest; /* Current named destination */ const char *ppdfile; /* PPD file */ ppd_file_t *ppd; /* PPD file data */ int num_jobs; /* Number of jobs for queue */ cups_job_t *jobs; /* Jobs for queue */ if (argc > 1) { if (!strcmp(argv[1], "enum")) { cups_ptype_t mask = CUPS_PRINTER_LOCAL, /* Printer type mask */ type = CUPS_PRINTER_LOCAL; /* Printer type */ int msec = 0; /* Timeout in milliseconds */ for (i = 2; i < argc; i ++) if (isdigit(argv[i][0] & 255) || argv[i][0] == '.') msec = (int)(atof(argv[i]) * 1000); else if (!_cups_strcasecmp(argv[i], "bw")) { mask |= CUPS_PRINTER_BW; type |= CUPS_PRINTER_BW; } else if (!_cups_strcasecmp(argv[i], "color")) { mask |= CUPS_PRINTER_COLOR; type |= CUPS_PRINTER_COLOR; } else if (!_cups_strcasecmp(argv[i], "mono")) { mask |= CUPS_PRINTER_COLOR; } else if (!_cups_strcasecmp(argv[i], "duplex")) { mask |= CUPS_PRINTER_DUPLEX; type |= CUPS_PRINTER_DUPLEX; } else if (!_cups_strcasecmp(argv[i], "simplex")) { mask |= CUPS_PRINTER_DUPLEX; } else if (!_cups_strcasecmp(argv[i], "staple")) { mask |= CUPS_PRINTER_STAPLE; type |= CUPS_PRINTER_STAPLE; } else if (!_cups_strcasecmp(argv[i], "copies")) { mask |= CUPS_PRINTER_COPIES; type |= CUPS_PRINTER_COPIES; } else if (!_cups_strcasecmp(argv[i], "collate")) { mask |= CUPS_PRINTER_COLLATE; type |= CUPS_PRINTER_COLLATE; } else if (!_cups_strcasecmp(argv[i], "punch")) { mask |= CUPS_PRINTER_PUNCH; type |= CUPS_PRINTER_PUNCH; } else if (!_cups_strcasecmp(argv[i], "cover")) { mask |= CUPS_PRINTER_COVER; type |= CUPS_PRINTER_COVER; } else if (!_cups_strcasecmp(argv[i], "bind")) { mask |= CUPS_PRINTER_BIND; type |= CUPS_PRINTER_BIND; } else if (!_cups_strcasecmp(argv[i], "sort")) { mask |= CUPS_PRINTER_SORT; type |= CUPS_PRINTER_SORT; } else if (!_cups_strcasecmp(argv[i], "mfp")) { mask |= CUPS_PRINTER_MFP; type |= CUPS_PRINTER_MFP; } else if (!_cups_strcasecmp(argv[i], "printer")) { mask |= CUPS_PRINTER_MFP; } else if (!_cups_strcasecmp(argv[i], "large")) { mask |= CUPS_PRINTER_LARGE; type |= CUPS_PRINTER_LARGE; } else if (!_cups_strcasecmp(argv[i], "medium")) { mask |= CUPS_PRINTER_MEDIUM; type |= CUPS_PRINTER_MEDIUM; } else if (!_cups_strcasecmp(argv[i], "small")) { mask |= CUPS_PRINTER_SMALL; type |= CUPS_PRINTER_SMALL; } else fprintf(stderr, "Unknown argument \"%s\" ignored...\n", argv[i]); cupsEnumDests(CUPS_DEST_FLAGS_NONE, msec, NULL, type, mask, enum_cb, NULL); } else if (!strcmp(argv[1], "password")) { const char *pass = cupsGetPassword("Password:"******"Password entered: %s\n", pass); else puts("No password entered."); } else if (!strcmp(argv[1], "ppd") && argc == 3) { /* * ./testcups ppd printer */ http_status_t http_status; /* Status */ char buffer[1024]; /* PPD filename */ time_t modtime = 0; /* Last modified */ if ((http_status = cupsGetPPD3(CUPS_HTTP_DEFAULT, argv[2], &modtime, buffer, sizeof(buffer))) != HTTP_STATUS_OK) printf("Unable to get PPD: %d (%s)\n", (int)http_status, cupsLastErrorString()); else puts(buffer); } else if (!strcmp(argv[1], "print") && argc == 5) { /* * ./testcups print printer file interval */ int interval, /* Interval between writes */ job_id; /* Job ID */ cups_file_t *fp; /* Print file */ char buffer[16384]; /* Read/write buffer */ ssize_t bytes; /* Bytes read/written */ if ((fp = cupsFileOpen(argv[3], "r")) == NULL) { printf("Unable to open \"%s\": %s\n", argv[2], strerror(errno)); return (1); } if ((job_id = cupsCreateJob(CUPS_HTTP_DEFAULT, argv[2], "testcups", 0, NULL)) <= 0) { printf("Unable to create print job on %s: %s\n", argv[1], cupsLastErrorString()); return (1); } interval = atoi(argv[4]); if (cupsStartDocument(CUPS_HTTP_DEFAULT, argv[1], job_id, argv[2], CUPS_FORMAT_AUTO, 1) != HTTP_STATUS_CONTINUE) { puts("Unable to start document!"); return (1); } while ((bytes = cupsFileRead(fp, buffer, sizeof(buffer))) > 0) { printf("Writing %d bytes...\n", (int)bytes); if (cupsWriteRequestData(CUPS_HTTP_DEFAULT, buffer, bytes) != HTTP_STATUS_CONTINUE) { puts("Unable to write bytes!"); return (1); } if (interval > 0) sleep(interval); } cupsFileClose(fp); if (cupsFinishDocument(CUPS_HTTP_DEFAULT, argv[1]) > IPP_STATUS_OK_IGNORED_OR_SUBSTITUTED) { puts("Unable to finish document!"); return (1); } } else { puts("Usage:"); puts(""); puts("Run basic unit tests:"); puts(""); puts(" ./testcups"); puts(""); puts("Enumerate printers (for N seconds, -1 for indefinitely):"); puts(""); puts(" ./testcups enum [seconds]"); puts(""); puts("Ask for a password:"******""); puts(" ./testcups password"); puts(""); puts("Get the PPD file:"); puts(""); puts(" ./testcups ppd printer"); puts(""); puts("Print a file (interval controls delay between buffers in seconds):"); puts(""); puts(" ./testcups print printer file interval"); return (1); } return (0); } /* * cupsGetDests() */ fputs("cupsGetDests: ", stdout); fflush(stdout); num_dests = cupsGetDests(&dests); if (num_dests == 0) { puts("FAIL"); return (1); } else { printf("PASS (%d dests)\n", num_dests); for (i = num_dests, dest = dests; i > 0; i --, dest ++) { printf(" %s", dest->name); if (dest->instance) printf(" /%s", dest->instance); if (dest->is_default) puts(" ***DEFAULT***"); else putchar('\n'); } } /* * cupsGetDest(NULL) */ fputs("cupsGetDest(NULL): ", stdout); fflush(stdout); if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) == NULL) { for (i = num_dests, dest = dests; i > 0; i --, dest ++) if (dest->is_default) break; if (i) { status = 1; puts("FAIL"); } else puts("PASS (no default)"); dest = NULL; } else printf("PASS (%s)\n", dest->name); /* * cupsGetNamedDest(NULL, NULL, NULL) */ fputs("cupsGetNamedDest(NULL, NULL, NULL): ", stdout); fflush(stdout); if ((named_dest = cupsGetNamedDest(NULL, NULL, NULL)) == NULL || !dests_equal(dest, named_dest)) { if (!dest) puts("PASS (no default)"); else if (named_dest) { puts("FAIL (different values)"); show_diffs(dest, named_dest); status = 1; } else { puts("FAIL (no default)"); status = 1; } } else printf("PASS (%s)\n", named_dest->name); if (named_dest) cupsFreeDests(1, named_dest); /* * cupsGetDest(printer) */ printf("cupsGetDest(\"%s\"): ", dests[num_dests / 2].name); fflush(stdout); if ((dest = cupsGetDest(dests[num_dests / 2].name, NULL, num_dests, dests)) == NULL) { puts("FAIL"); return (1); } else puts("PASS"); /* * cupsGetNamedDest(NULL, printer, instance) */ printf("cupsGetNamedDest(NULL, \"%s\", \"%s\"): ", dest->name, dest->instance ? dest->instance : "(null)"); fflush(stdout); if ((named_dest = cupsGetNamedDest(NULL, dest->name, dest->instance)) == NULL || !dests_equal(dest, named_dest)) { if (named_dest) { puts("FAIL (different values)"); show_diffs(dest, named_dest); } else puts("FAIL (no destination)"); status = 1; } else puts("PASS"); if (named_dest) cupsFreeDests(1, named_dest); /* * cupsPrintFile() */ fputs("cupsPrintFile: ", stdout); fflush(stdout); if (cupsPrintFile(dest->name, "../data/testprint", "Test Page", dest->num_options, dest->options) <= 0) { printf("FAIL (%s)\n", cupsLastErrorString()); return (1); } else puts("PASS"); /* * cupsGetPPD(printer) */ fputs("cupsGetPPD(): ", stdout); fflush(stdout); if ((ppdfile = cupsGetPPD(dest->name)) == NULL) { puts("FAIL"); } else { puts("PASS"); /* * ppdOpenFile() */ fputs("ppdOpenFile(): ", stdout); fflush(stdout); if ((ppd = ppdOpenFile(ppdfile)) == NULL) { puts("FAIL"); return (1); } else puts("PASS"); ppdClose(ppd); unlink(ppdfile); } /* * cupsGetJobs() */ fputs("cupsGetJobs: ", stdout); fflush(stdout); num_jobs = cupsGetJobs(&jobs, NULL, 0, -1); if (num_jobs == 0) { puts("FAIL"); return (1); } else puts("PASS"); cupsFreeJobs(num_jobs, jobs); cupsFreeDests(num_dests, dests); return (status); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ char *command, /* Command to do */ *opt, /* Option pointer */ uri[1024], /* Printer URI */ *reason; /* Reason for reject/disable */ ipp_t *request; /* IPP request */ ipp_op_t op; /* Operation */ int cancel; /* Cancel jobs? */ _cupsSetLocale(argv); /* * See what operation we're supposed to do... */ if ((command = strrchr(argv[0], '/')) != NULL) command ++; else command = argv[0]; cancel = 0; if (!strcmp(command, "cupsaccept")) op = CUPS_ACCEPT_JOBS; else if (!strcmp(command, "cupsreject")) op = CUPS_REJECT_JOBS; else if (!strcmp(command, "cupsdisable")) op = IPP_PAUSE_PRINTER; else if (!strcmp(command, "cupsenable")) op = IPP_RESUME_PRINTER; else { _cupsLangPrintf(stderr, _("%s: Don't know what to do."), command); return (1); } reason = NULL; /* * Process command-line arguments... */ for (i = 1; i < argc; i ++) { if (!strcmp(argv[i], "--help")) usage(command); else if (!strcmp(argv[i], "--hold")) op = IPP_HOLD_NEW_JOBS; else if (!strcmp(argv[i], "--release")) op = IPP_RELEASE_HELD_NEW_JOBS; else if (argv[i][0] == '-') { for (opt = argv[i] + 1; *opt; opt ++) { switch (*opt) { case 'E' : /* Encrypt */ #ifdef HAVE_SSL cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); #else _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support."), command); #endif /* HAVE_SSL */ break; case 'U' : /* Username */ if (opt[1] != '\0') { cupsSetUser(opt + 1); opt += strlen(opt) - 1; } else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after \"-U\" option."), command); usage(command); } cupsSetUser(argv[i]); } break; case 'c' : /* Cancel jobs */ cancel = 1; break; case 'h' : /* Connect to host */ if (opt[1] != '\0') { cupsSetServer(opt + 1); opt += strlen(opt) - 1; } else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected hostname after \"-h\" option."), command); usage(command); } cupsSetServer(argv[i]); } break; case 'r' : /* Reason for cancellation */ if (opt[1] != '\0') { reason = opt + 1; opt += strlen(opt) - 1; } else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected reason text after \"-r\" option."), command); usage(command); } reason = argv[i]; } break; default : _cupsLangPrintf(stderr, _("%s: Error - unknown option \"%c\"."), command, *opt); usage(command); } } } else { /* * Accept/disable/enable/reject a destination... */ request = ippNewRequest(op); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", argv[i]); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (reason != NULL) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_TEXT, "printer-state-message", NULL, reason); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: Operation failed: %s"), command, ippErrorString(cupsLastError())); return (1); } /* * Cancel all jobs if requested... */ if (cancel) { /* * Build an IPP_PURGE_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri */ request = ippNewRequest(IPP_PURGE_JOBS); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippDelete(cupsDoRequest(CUPS_HTTP_DEFAULT, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString()); return (1); } } } } return (0); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { http_t *http; /* HTTP connection to server */ int i; /* Looping var */ int job_id; /* Job ID */ int num_dests; /* Number of destinations */ cups_dest_t *dests; /* Destinations */ char *dest, /* Destination printer */ *job, /* Job ID pointer */ *user; /* Cancel jobs for a user */ int purge; /* Purge or cancel jobs? */ char uri[1024]; /* Printer or job URI */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_op_t op; /* Operation */ _cupsSetLocale(argv); /* * Setup to cancel individual print jobs... */ op = IPP_CANCEL_JOB; purge = 0; dest = NULL; user = NULL; http = NULL; num_dests = 0; dests = NULL; /* * Process command-line arguments... */ for (i = 1; i < argc; i ++) if (argv[i][0] == '-' && argv[i][1]) switch (argv[i][1]) { case 'E' : /* Encrypt */ #ifdef HAVE_SSL cupsSetEncryption(HTTP_ENCRYPT_REQUIRED); if (http) httpEncryption(http, HTTP_ENCRYPT_REQUIRED); #else _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support compiled in!\n"), argv[0]); #endif /* HAVE_SSL */ break; case 'U' : /* Username */ if (argv[i][2] != '\0') cupsSetUser(argv[i] + 2); else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after " "\'-U\' option!\n"), argv[0]); return (1); } cupsSetUser(argv[i]); } break; case 'a' : /* Cancel all jobs */ purge = 1; op = IPP_PURGE_JOBS; break; case 'h' : /* Connect to host */ if (http != NULL) { httpClose(http); http = NULL; } if (argv[i][2] != '\0') cupsSetServer(argv[i] + 2); else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected hostname after " "\'-h\' option!\n"), argv[0]); return (1); } else cupsSetServer(argv[i]); } break; case 'u' : /* Username */ op = IPP_PURGE_JOBS; if (argv[i][2] != '\0') user = argv[i] + 2; else { i ++; if (i >= argc) { _cupsLangPrintf(stderr, _("%s: Error - expected username after " "\'-u\' option!\n"), argv[0]); return (1); } else user = argv[i]; } break; default : _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%c\'!\n"), argv[0], argv[i][1]); return (1); } else { /* * Cancel a job or printer... */ if (num_dests == 0) num_dests = cupsGetDests(&dests); if (!strcmp(argv[i], "-")) { /* * Delete the current job... */ dest = ""; job_id = 0; } else if (cupsGetDest(argv[i], NULL, num_dests, dests) != NULL) { /* * Delete the current job on the named destination... */ dest = argv[i]; job_id = 0; } else if ((job = strrchr(argv[i], '-')) != NULL && isdigit(job[1] & 255)) { /* * Delete the specified job ID. */ dest = NULL; op = IPP_CANCEL_JOB; job_id = atoi(job + 1); } else if (isdigit(argv[i][0] & 255)) { /* * Delete the specified job ID. */ dest = NULL; op = IPP_CANCEL_JOB; job_id = atoi(argv[i]); } else { /* * Bad printer name! */ _cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s\"!\n"), argv[0], argv[i]); return (1); } /* * For Solaris LP compatibility, ignore a destination name after * cancelling a specific job ID... */ if (job_id && (i + 1) < argc && cupsGetDest(argv[i + 1], NULL, num_dests, dests) != NULL) i ++; /* * Open a connection to the server... */ if (http == NULL) if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { _cupsLangPrintf(stderr, _("%s: Unable to contact server!\n"), argv[0]); return (1); } /* * Build an IPP request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri + job-id *or* job-uri * [requesting-user-name] */ request = ippNewRequest(op); if (dest) { httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); } else { sprintf(uri, "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } if (user) { ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); } else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (op == IPP_PURGE_JOBS) ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", purge); /* * Do the request and get back a response... */ if (op == IPP_PURGE_JOBS && (!user || strcasecmp(user, cupsUser()))) response = cupsDoRequest(http, request, "/admin/"); else response = cupsDoRequest(http, request, "/jobs/"); if (response == NULL || response->request.status.status_code > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s failed: %s\n"), argv[0], op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job", cupsLastErrorString()); if (response) ippDelete(response); return (1); } ippDelete(response); } if (num_dests == 0 && op == IPP_PURGE_JOBS) { /* * Open a connection to the server... */ if (http == NULL) if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { _cupsLangPrintf(stderr, _("%s: Unable to contact server!\n"), argv[0]); return (1); } /* * Build an IPP request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri + job-id *or* job-uri * [requesting-user-name] */ request = ippNewRequest(op); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/printers/"); if (user) { ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); } else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", purge); /* * Do the request and get back a response... */ response = cupsDoRequest(http, request, "/admin/"); if (response == NULL || response->request.status.status_code > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s failed: %s\n"), argv[0], op == IPP_PURGE_JOBS ? "purge-jobs" : "cancel-job", cupsLastErrorString()); if (response) ippDelete(response); return (1); } ippDelete(response); } return (0); }
static int /* O - Number of options or -1 on error */ get_printer(http_t *http, /* I - HTTP connection */ const char *name, /* I - Printer name from request */ char *dest, /* I - Destination buffer */ size_t destsize, /* I - Size of destination buffer */ cups_option_t **options, /* O - Printer options */ int *accepting, /* O - printer-is-accepting-jobs value */ int *shared, /* O - printer-is-shared value */ ipp_pstate_t *state) /* O - printer-state value */ { int num_options; /* Number of options */ cups_file_t *fp; /* lpoptions file */ char line[1024], /* Line from lpoptions file */ *value, /* Pointer to value on line */ *optptr; /* Pointer to options on line */ int linenum; /* Line number in file */ const char *cups_serverroot; /* CUPS_SERVERROOT env var */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_attribute_t *attr; /* IPP attribute */ char uri[HTTP_MAX_URI]; /* Printer URI */ static const char * const requested[] = { /* Requested attributes */ "printer-info", "printer-is-accepting-jobs", "printer-is-shared", "printer-name", "printer-state" }; /* * Initialize everything... */ if (accepting) *accepting = 0; if (shared) *shared = 0; if (state) *state = IPP_PRINTER_STOPPED; if (options) *options = NULL; /* * See if the name is a queue name optionally with an instance name. */ strlcpy(dest, name, destsize); if ((value = strchr(dest, '/')) != NULL) *value = '\0'; /* * Setup the Get-Printer-Attributes request... */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request... */ response = cupsDoRequest(http, request, "/"); if (!response || cupsLastError() > IPP_OK_CONFLICT) { /* * If we can't find the printer by name, look up the printer-name * using the printer-info values... */ ipp_attribute_t *accepting_attr,/* printer-is-accepting-jobs */ *info_attr, /* printer-info */ *name_attr, /* printer-name */ *shared_attr, /* printer-is-shared */ *state_attr; /* printer-state */ ippDelete(response); /* * Setup the CUPS-Get-Printers request... */ request = ippNewRequest(CUPS_GET_PRINTERS); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request... */ response = cupsDoRequest(http, request, "/"); if (!response || cupsLastError() > IPP_OK_CONFLICT) { syslog(LOG_ERR, "Unable to get list of printers - %s", cupsLastErrorString()); ippDelete(response); return (-1); } /* * Scan the response for printers... */ *dest = '\0'; attr = response->attrs; while (attr) { /* * Skip to the next printer... */ while (attr && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (!attr) break; /* * Get all of the attributes for the current printer... */ accepting_attr = NULL; info_attr = NULL; name_attr = NULL; shared_attr = NULL; state_attr = NULL; while (attr && attr->group_tag == IPP_TAG_PRINTER) { if (!strcmp(attr->name, "printer-is-accepting-jobs") && attr->value_tag == IPP_TAG_BOOLEAN) accepting_attr = attr; else if (!strcmp(attr->name, "printer-info") && attr->value_tag == IPP_TAG_TEXT) info_attr = attr; else if (!strcmp(attr->name, "printer-name") && attr->value_tag == IPP_TAG_NAME) name_attr = attr; else if (!strcmp(attr->name, "printer-is-shared") && attr->value_tag == IPP_TAG_BOOLEAN) shared_attr = attr; else if (!strcmp(attr->name, "printer-state") && attr->value_tag == IPP_TAG_ENUM) state_attr = attr; attr = attr->next; } if (info_attr && name_attr && !_cups_strcasecmp(name, info_attr->values[0].string.text)) { /* * Found a match, use this one! */ strlcpy(dest, name_attr->values[0].string.text, destsize); if (accepting && accepting_attr) *accepting = accepting_attr->values[0].boolean; if (shared && shared_attr) *shared = shared_attr->values[0].boolean; if (state && state_attr) *state = (ipp_pstate_t)state_attr->values[0].integer; break; } } ippDelete(response); if (!*dest) { syslog(LOG_ERR, "Unable to find \"%s\" in list of printers!", name); return (-1); } name = dest; } else { /* * Get values from the response... */ if (accepting) { if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN)) == NULL) syslog(LOG_ERR, "No printer-is-accepting-jobs attribute found in " "response from server!"); else *accepting = attr->values[0].boolean; } if (shared) { if ((attr = ippFindAttribute(response, "printer-is-shared", IPP_TAG_BOOLEAN)) == NULL) { syslog(LOG_ERR, "No printer-is-shared attribute found in " "response from server!"); *shared = 1; } else *shared = attr->values[0].boolean; } if (state) { if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) == NULL) syslog(LOG_ERR, "No printer-state attribute found in " "response from server!"); else *state = (ipp_pstate_t)attr->values[0].integer; } ippDelete(response); } /* * Next look for the printer in the lpoptions file... */ num_options = 0; if (options && shared && accepting) { if ((cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL) cups_serverroot = CUPS_SERVERROOT; snprintf(line, sizeof(line), "%s/lpoptions", cups_serverroot); if ((fp = cupsFileOpen(line, "r")) != NULL) { linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { /* * Make sure we have "Dest name options" or "Default name options"... */ if ((_cups_strcasecmp(line, "Dest") && _cups_strcasecmp(line, "Default")) || !value) continue; /* * Separate destination name from options... */ for (optptr = value; *optptr && !isspace(*optptr & 255); optptr ++); while (*optptr == ' ') *optptr++ = '\0'; /* * If this is our destination, parse the options and break out of * the loop - we're done! */ if (!_cups_strcasecmp(value, name)) { num_options = cupsParseOptions(optptr, num_options, options); break; } } cupsFileClose(fp); } } else if (options) *options = NULL; /* * Return the number of options for this destination... */ return (num_options); }
static int /* O - Command status */ send_state(const char *queue, /* I - Destination */ const char *list, /* I - Job or user */ int longstatus) /* I - List of jobs or users */ { int id; /* Job ID from list */ http_t *http; /* HTTP server connection */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ ipp_pstate_t state; /* Printer state */ const char *jobdest, /* Pointer into job-printer-uri */ *jobuser, /* Pointer to job-originating-user-name */ *jobname; /* Pointer to job-name */ ipp_jstate_t jobstate; /* job-state */ int jobid, /* job-id */ jobsize, /* job-k-octets */ jobcount, /* Number of jobs */ jobcopies, /* Number of copies */ rank; /* Rank of job */ char rankstr[255]; /* Rank string */ char namestr[1024]; /* Job name string */ char uri[HTTP_MAX_URI]; /* Printer URI */ char dest[256]; /* Printer/class queue */ static const char * const ranks[10] = /* Ranking strings */ { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" }; static const char * const requested[] = { /* Requested attributes */ "job-id", "job-k-octets", "job-state", "job-printer-uri", "job-originating-user-name", "job-name", "copies" }; /* * Try connecting to the local server... */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(), strerror(errno)); printf("Unable to connect to server %s: %s", cupsServer(), strerror(errno)); return (1); } /* * Get the actual destination name and printer state... */ if (get_printer(http, queue, dest, sizeof(dest), NULL, NULL, NULL, &state)) { syslog(LOG_ERR, "Unable to get printer %s: %s", queue, cupsLastErrorString()); printf("Unable to get printer %s: %s", queue, cupsLastErrorString()); return (1); } /* * Show the queue state... */ switch (state) { case IPP_PRINTER_IDLE : printf("%s is ready\n", dest); break; case IPP_PRINTER_PROCESSING : printf("%s is ready and printing\n", dest); break; case IPP_PRINTER_STOPPED : printf("%s is not ready\n", dest); break; } /* * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires * the following attributes: * * attributes-charset * attributes-natural-language * job-uri or printer-uri */ id = atoi(list); request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); if (id) ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", id); else { ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, list); ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); } ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(requested) / sizeof(requested[0]), NULL, requested); /* * Do the request and get back a response... */ jobcount = 0; response = cupsDoRequest(http, request, "/"); if (cupsLastError() > IPP_OK_CONFLICT) { printf("get-jobs failed: %s\n", cupsLastErrorString()); ippDelete(response); return (1); } /* * Loop through the job list and display them... */ for (attr = response->attrs, rank = 1; attr; attr = attr->next) { /* * Skip leading attributes until we hit a job... */ while (attr && (attr->group_tag != IPP_TAG_JOB || !attr->name)) attr = attr->next; if (!attr) break; /* * Pull the needed attributes from this job... */ jobid = 0; jobsize = 0; jobstate = IPP_JOB_PENDING; jobname = "untitled"; jobuser = NULL; jobdest = NULL; jobcopies = 1; while (attr && attr->group_tag == IPP_TAG_JOB) { if (!strcmp(attr->name, "job-id") && attr->value_tag == IPP_TAG_INTEGER) jobid = attr->values[0].integer; if (!strcmp(attr->name, "job-k-octets") && attr->value_tag == IPP_TAG_INTEGER) jobsize = attr->values[0].integer; if (!strcmp(attr->name, "job-state") && attr->value_tag == IPP_TAG_ENUM) jobstate = (ipp_jstate_t)attr->values[0].integer; if (!strcmp(attr->name, "job-printer-uri") && attr->value_tag == IPP_TAG_URI) if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) jobdest ++; if (!strcmp(attr->name, "job-originating-user-name") && attr->value_tag == IPP_TAG_NAME) jobuser = attr->values[0].string.text; if (!strcmp(attr->name, "job-name") && attr->value_tag == IPP_TAG_NAME) jobname = attr->values[0].string.text; if (!strcmp(attr->name, "copies") && attr->value_tag == IPP_TAG_INTEGER) jobcopies = attr->values[0].integer; attr = attr->next; } /* * See if we have everything needed... */ if (!jobdest || !jobid) { if (!attr) break; else continue; } if (!longstatus && jobcount == 0) puts("Rank Owner Job File(s) Total Size"); jobcount ++; /* * Display the job... */ if (jobstate == IPP_JOB_PROCESSING) strlcpy(rankstr, "active", sizeof(rankstr)); else { snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]); rank ++; } if (longstatus) { puts(""); if (jobcopies > 1) snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies, jobname); else strlcpy(namestr, jobname, sizeof(namestr)); printf("%s: %-33.33s [job %d localhost]\n", jobuser, rankstr, jobid); printf(" %-39.39s %.0f bytes\n", namestr, 1024.0 * jobsize); } else printf("%-7s %-7.7s %-7d %-31.31s %.0f bytes\n", rankstr, jobuser, jobid, jobname, 1024.0 * jobsize); if (!attr) break; } ippDelete(response); if (jobcount == 0) puts("no entries"); httpClose(http); return (0); }
ipp_status_t /* O - IPP status code */ cupsCloseDestJob( http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ cups_dinfo_t *info, /* I - Destination information */ int job_id) /* I - Job ID */ { int i; /* Looping var */ ipp_t *request = NULL;/* Close-Job/Send-Document request */ ipp_attribute_t *attr; /* operations-supported attribute */ DEBUG_printf(("cupsCloseDestJob(http=%p, dest=%p(%s/%s), info=%p, job_id=%d)", http, dest, dest ? dest->name : NULL, dest ? dest->instance : NULL, info, job_id)); /* * Range check input... */ if (!http || !dest || !info || job_id <= 0) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); DEBUG_puts("1cupsCloseDestJob: Bad arguments."); return (IPP_STATUS_ERROR_INTERNAL); } /* * Build a Close-Job or empty Send-Document request... */ if ((attr = ippFindAttribute(info->attrs, "operations-supported", IPP_TAG_ENUM)) != NULL) { for (i = 0; i < attr->num_values; i ++) if (attr->values[i].integer == IPP_OP_CLOSE_JOB) { request = ippNewRequest(IPP_OP_CLOSE_JOB); break; } } if (!request) request = ippNewRequest(IPP_OP_SEND_DOCUMENT); if (!request) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); DEBUG_puts("1cupsCloseDestJob: Unable to create Close-Job/Send-Document " "request."); return (IPP_STATUS_ERROR_INTERNAL); } ippSetVersion(request, info->version / 10, info->version % 10); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, info->uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (ippGetOperation(request) == IPP_OP_SEND_DOCUMENT) ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); /* * Send the request and return the status... */ ippDelete(cupsDoRequest(http, request, info->resource)); DEBUG_printf(("1cupsCloseDestJob: %s (%s)", ippErrorString(cupsLastError()), cupsLastErrorString())); return (cupsLastError()); }
static int /* O - Number of jobs in queue */ show_jobs(const char *command, /* I - Command name */ http_t *http, /* I - HTTP connection to server */ const char *dest, /* I - Destination */ const char *user, /* I - User */ const int id, /* I - Job ID */ const int longstatus) /* I - 1 if long report desired */ { ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ const char *jobdest, /* Pointer into job-printer-uri */ *jobuser, /* Pointer to job-originating-user-name */ *jobname; /* Pointer to job-name */ ipp_jstate_t jobstate; /* job-state */ int jobid, /* job-id */ jobsize, /* job-k-octets */ #ifdef __osf__ jobpriority, /* job-priority */ #endif /* __osf__ */ jobcount, /* Number of jobs */ jobcopies, /* Number of copies */ rank; /* Rank of job */ char resource[1024]; /* Resource string */ char rankstr[255]; /* Rank string */ char namestr[1024]; /* Job name string */ static const char * const jobattrs[] =/* Job attributes we want to see */ { "copies", "job-id", "job-k-octets", "job-name", "job-originating-user-name", "job-printer-uri", "job-priority", "job-state" }; static const char * const ranks[10] = /* Ranking strings */ { "th", "st", "nd", "rd", "th", "th", "th", "th", "th", "th" }; DEBUG_printf(("show_jobs(http=%p, dest=%p, user=%p, id=%d, longstatus%d)\n", http, dest, user, id, longstatus)); if (http == NULL) return (0); /* * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires * the following attributes: * * attributes-charset * attributes-natural-language * job-uri or printer-uri * requested-attributes * requesting-user-name */ request = ippNewRequest(id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS); if (id) { snprintf(resource, sizeof(resource), "ipp://localhost/jobs/%d", id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, resource); } else if (dest) { httpAssembleURIf(HTTP_URI_CODING_ALL, resource, sizeof(resource), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, resource); } else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/"); if (user) { ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); } else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(jobattrs) / sizeof(jobattrs[0])), NULL, jobattrs); /* * Do the request and get back a response... */ jobcount = 0; if ((response = cupsDoRequest(http, request, "/")) != NULL) { if (response->request.status.status_code > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString()); ippDelete(response); return (0); } rank = 1; /* * Loop through the job list and display them... */ for (attr = response->attrs; attr != NULL; attr = attr->next) { /* * Skip leading attributes until we hit a job... */ while (attr != NULL && attr->group_tag != IPP_TAG_JOB) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this job... */ jobid = 0; jobsize = 0; #ifdef __osf__ jobpriority = 50; #endif /* __osf__ */ jobstate = IPP_JOB_PENDING; jobname = "unknown"; jobuser = "******"; jobdest = NULL; jobcopies = 1; while (attr != NULL && attr->group_tag == IPP_TAG_JOB) { if (!strcmp(attr->name, "job-id") && attr->value_tag == IPP_TAG_INTEGER) jobid = attr->values[0].integer; if (!strcmp(attr->name, "job-k-octets") && attr->value_tag == IPP_TAG_INTEGER) jobsize = attr->values[0].integer; #ifdef __osf__ if (!strcmp(attr->name, "job-priority") && attr->value_tag == IPP_TAG_INTEGER) jobpriority = attr->values[0].integer; #endif /* __osf__ */ if (!strcmp(attr->name, "job-state") && attr->value_tag == IPP_TAG_ENUM) jobstate = (ipp_jstate_t)attr->values[0].integer; if (!strcmp(attr->name, "job-printer-uri") && attr->value_tag == IPP_TAG_URI) if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL) jobdest ++; if (!strcmp(attr->name, "job-originating-user-name") && attr->value_tag == IPP_TAG_NAME) jobuser = attr->values[0].string.text; if (!strcmp(attr->name, "job-name") && attr->value_tag == IPP_TAG_NAME) jobname = attr->values[0].string.text; if (!strcmp(attr->name, "copies") && attr->value_tag == IPP_TAG_INTEGER) jobcopies = attr->values[0].integer; attr = attr->next; } /* * See if we have everything needed... */ if (jobdest == NULL || jobid == 0) { if (attr == NULL) break; else continue; } if (!longstatus && jobcount == 0) #ifdef __osf__ _cupsLangPuts(stdout, /* TRANSLATORS: Pri is job priority. */ _("Rank Owner Pri Job Files" " Total Size")); #else _cupsLangPuts(stdout, _("Rank Owner Job File(s)" " Total Size")); #endif /* __osf__ */ jobcount ++; /* * Display the job... */ if (jobstate == IPP_JOB_PROCESSING) strlcpy(rankstr, "active", sizeof(rankstr)); else { /* * Make the rank show the "correct" suffix for each number * (11-13 are the only special cases, for English anyways...) */ if ((rank % 100) >= 11 && (rank % 100) <= 13) snprintf(rankstr, sizeof(rankstr), "%dth", rank); else snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]); rank ++; } if (longstatus) { _cupsLangPuts(stdout, "\n"); if (jobcopies > 1) snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies, jobname); else strlcpy(namestr, jobname, sizeof(namestr)); _cupsLangPrintf(stdout, _("%s: %-33.33s [job %d localhost]"), jobuser, rankstr, jobid); _cupsLangPrintf(stdout, _(" %-39.39s %.0f bytes"), namestr, 1024.0 * jobsize); } else #ifdef __osf__ _cupsLangPrintf(stdout, _("%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes"), rankstr, jobuser, jobpriority, jobid, jobname, 1024.0 * jobsize); #else _cupsLangPrintf(stdout, _("%-7s %-7.7s %-7d %-31.31s %.0f bytes"), rankstr, jobuser, jobid, jobname, 1024.0 * jobsize); #endif /* __osf */ if (attr == NULL) break; } ippDelete(response); } else { _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString()); return (0); } if (jobcount == 0) _cupsLangPuts(stdout, _("no entries")); return (jobcount); }
ipp_status_t /* O - IPP status code */ cupsCreateDestJob( http_t *http, /* I - Connection to destination */ cups_dest_t *dest, /* I - Destination */ cups_dinfo_t *info, /* I - Destination information */ int *job_id, /* O - Job ID or 0 on error */ const char *title, /* I - Job name */ int num_options, /* I - Number of job options */ cups_option_t *options) /* I - Job options */ { ipp_t *request, /* Create-Job request */ *response; /* Create-Job response */ ipp_attribute_t *attr; /* job-id attribute */ DEBUG_printf(("cupsCreateDestJob(http=%p, dest=%p(%s/%s), info=%p, " "job_id=%p, title=\"%s\", num_options=%d, options=%p)", http, dest, dest ? dest->name : NULL, dest ? dest->instance : NULL, info, job_id, title, num_options, options)); /* * Range check input... */ if (job_id) *job_id = 0; if (!http || !dest || !info || !job_id) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); DEBUG_puts("1cupsCreateDestJob: Bad arguments."); return (IPP_STATUS_ERROR_INTERNAL); } /* * Build a Create-Job request... */ if ((request = ippNewRequest(IPP_OP_CREATE_JOB)) == NULL) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(ENOMEM), 0); DEBUG_puts("1cupsCreateDestJob: Unable to create Create-Job request."); return (IPP_STATUS_ERROR_INTERNAL); } ippSetVersion(request, info->version / 10, info->version % 10); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, info->uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); if (title) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); cupsEncodeOptions2(request, num_options, options, IPP_TAG_OPERATION); cupsEncodeOptions2(request, num_options, options, IPP_TAG_JOB); cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION); /* * Send the request and get the job-id... */ response = cupsDoRequest(http, request, info->resource); if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) { *job_id = attr->values[0].integer; DEBUG_printf(("1cupsCreateDestJob: job-id=%d", *job_id)); } ippDelete(response); /* * Return the status code from the Create-Job request... */ DEBUG_printf(("1cupsCreateDestJob: %s (%s)", ippErrorString(cupsLastError()), cupsLastErrorString())); return (cupsLastError()); }
static void cups_create_localizations( http_t *http, /* I - Connection to destination */ cups_dinfo_t *dinfo) /* I - Destination informations */ { http_t *http2; /* Connection for strings file */ http_status_t status; /* Request status */ ipp_attribute_t *attr; /* "printer-strings-uri" attribute */ char scheme[32], /* URI scheme */ userpass[256], /* Username/password info */ hostname[256], /* Hostname */ resource[1024], /* Resource */ http_hostname[256], /* Hostname of connection */ tempfile[1024]; /* Temporary filename */ int port; /* Port number */ http_encryption_t encryption; /* Encryption to use */ cups_file_t *temp; /* Temporary file */ /* * Create an empty message catalog... */ dinfo->localizations = _cupsMessageNew(NULL); /* * See if there are any localizations... */ if ((attr = ippFindAttribute(dinfo->attrs, "printer-strings-uri", IPP_TAG_URI)) == NULL) { /* * Nope... */ DEBUG_puts("4cups_create_localizations: No printer-strings-uri (uri) " "value."); return; /* Nope */ } /* * Pull apart the URI and determine whether we need to try a different * server... */ if (httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, scheme, sizeof(scheme), userpass, sizeof(userpass), hostname, sizeof(hostname), &port, resource, sizeof(resource)) < HTTP_URI_OK) { DEBUG_printf(("4cups_create_localizations: Bad printer-strings-uri value " "\"%s\".", attr->values[0].string.text)); return; } httpGetHostname(http, http_hostname, sizeof(http_hostname)); if (!_cups_strcasecmp(http_hostname, hostname) && port == _httpAddrPort(http->hostaddr)) { /* * Use the same connection... */ http2 = http; } else { /* * Connect to the alternate host... */ if (!strcmp(scheme, "https")) encryption = HTTP_ENCRYPT_ALWAYS; else encryption = HTTP_ENCRYPT_IF_REQUESTED; if ((http2 = httpConnectEncrypt(hostname, port, encryption)) == NULL) { DEBUG_printf(("4cups_create_localizations: Unable to connect to " "%s:%d: %s", hostname, port, cupsLastErrorString())); return; } } /* * Get a temporary file... */ if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL) { DEBUG_printf(("4cups_create_localizations: Unable to create temporary " "file: %s", cupsLastErrorString())); if (http2 != http) httpClose(http2); return; } status = cupsGetFd(http2, resource, cupsFileNumber(temp)); DEBUG_printf(("4cups_create_localizations: GET %s = %s", resource, httpStatus(status))); if (status == HTTP_OK) { /* * Got the file, read it... */ char buffer[8192], /* Message buffer */ *id, /* ID string */ *str; /* Translated message */ _cups_message_t *m; /* Current message */ lseek(cupsFileNumber(temp), 0, SEEK_SET); while (cups_read_strings(temp, buffer, sizeof(buffer), &id, &str)) { if ((m = malloc(sizeof(_cups_message_t))) == NULL) break; m->id = strdup(id); m->str = strdup(str); if (m->id && m->str) cupsArrayAdd(dinfo->localizations, m); else { if (m->id) free(m->id); if (m->str) free(m->str); free(m); break; } } } DEBUG_printf(("4cups_create_localizations: %d messages loaded.", cupsArrayCount(dinfo->localizations))); /* * Cleanup... */ unlink(tempfile); cupsFileClose(temp); if (http2 != http) httpClose(http2); }
static int /* O - Job ID or -1 on error */ create_job(http_t *http, /* I - HTTP connection */ const char *dest, /* I - Destination name */ const char *title, /* I - job-name */ const char *docname, /* I - Name of job file */ const char *user, /* I - requesting-user-name */ int num_options, /* I - Number of options for job */ cups_option_t *options) /* I - Options for job */ { ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_attribute_t *attr; /* IPP attribute */ char uri[HTTP_MAX_URI]; /* Printer URI */ int id; /* Job ID */ /* * Setup the Create-Job request... */ request = ippNewRequest(IPP_CREATE_JOB); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); if (title[0]) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); if (docname[0]) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", NULL, docname); cupsEncodeOptions(request, num_options, options); /* * Do the request... */ snprintf(uri, sizeof(uri), "/printers/%s", dest); response = cupsDoRequest(http, request, uri); if (!response || cupsLastError() > IPP_OK_CONFLICT) { syslog(LOG_ERR, "Unable to create job - %s", cupsLastErrorString()); ippDelete(response); return (-1); } /* * Get the job-id value from the response and return it... */ if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) { id = -1; syslog(LOG_ERR, "No job-id attribute found in response from server!"); } else { id = attr->values[0].integer; syslog(LOG_INFO, "Print file - job ID = %d", id); } ippDelete(response); return (id); }
static void show_printer(const char *command, /* I - Command name */ http_t *http, /* I - HTTP connection to server */ const char *dest) /* I - Destination */ { ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ ipp_pstate_t state; /* Printer state */ char uri[HTTP_MAX_URI]; /* Printer URI */ if (http == NULL) return; /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { if (response->request.status.status_code > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString()); ippDelete(response); return; } if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) state = (ipp_pstate_t)attr->values[0].integer; else state = IPP_PRINTER_STOPPED; switch (state) { case IPP_PRINTER_IDLE : _cupsLangPrintf(stdout, _("%s is ready"), dest); break; case IPP_PRINTER_PROCESSING : _cupsLangPrintf(stdout, _("%s is ready and printing"), dest); break; case IPP_PRINTER_STOPPED : _cupsLangPrintf(stdout, _("%s is not ready"), dest); break; } ippDelete(response); } else _cupsLangPrintf(stderr, "%s: %s", command, cupsLastErrorString()); }
static int /* O - Command status */ remove_jobs(const char *dest, /* I - Destination */ const char *agent, /* I - User agent */ const char *list) /* I - List of jobs or users */ { int id; /* Job ID */ http_t *http; /* HTTP server connection */ ipp_t *request; /* IPP Request */ char uri[HTTP_MAX_URI]; /* Job URI */ (void)dest; /* Suppress compiler warnings... */ /* * Try connecting to the local server... */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption())) == NULL) { syslog(LOG_ERR, "Unable to connect to server %s: %s", cupsServer(), strerror(errno)); return (1); } /* * Loop for each job... */ while ((id = atoi(list)) > 0) { /* * Skip job ID in list... */ while (isdigit(*list & 255)) list ++; while (isspace(*list & 255)) list ++; /* * Build an IPP_CANCEL_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * job-uri * requesting-user-name */ request = ippNewRequest(IPP_CANCEL_JOB); sprintf(uri, "ipp://localhost/jobs/%d", id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, agent); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/jobs")); if (cupsLastError() > IPP_OK_CONFLICT) { syslog(LOG_WARNING, "Cancel of job ID %d failed: %s\n", id, cupsLastErrorString()); httpClose(http); return (1); } else syslog(LOG_INFO, "Job ID %d canceled", id); } httpClose(http); return (0); }