static cups_ptype_t /* O - printer-type value */ get_printer_type(http_t *http, /* I - Server connection */ char *printer, /* I - Printer name */ char *uri, /* I - URI buffer */ size_t urisize) /* I - Size of URI buffer */ { ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* printer-type attribute */ cups_ptype_t type; /* printer-type value */ /* * Build a GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requested-attributes * requesting-user-name */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, urisize, "ipp", NULL, "localhost", ippPort(), "/printers/%s", printer); request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-type"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); /* * Do the request... */ response = cupsDoRequest(http, request, "/"); if ((attr = ippFindAttribute(response, "printer-type", IPP_TAG_ENUM)) != NULL) { type = (cups_ptype_t)attr->values[0].integer; if (type & CUPS_PRINTER_CLASS) httpAssembleURIf(HTTP_URI_CODING_ALL, uri, urisize, "ipp", NULL, "localhost", ippPort(), "/classes/%s", printer); } else type = CUPS_PRINTER_LOCAL; ippDelete(response); return (type); }
http_status_t /* O - HTTP status of request */ cupsStartDocument( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ const char *name, /* I - Destination name */ int job_id, /* I - Job ID from @link cupsCreateJob@ */ const char *docname, /* I - Name of document */ const char *format, /* I - MIME type or @code CUPS_FORMAT_foo@ */ int last_document) /* I - 1 for last document in job, 0 otherwise */ { char resource[1024], /* Resource for destinatio */ printer_uri[1024]; /* Printer URI */ ipp_t *request; /* Send-Document request */ http_status_t status; /* HTTP status */ /* * Create a Send-Document request... */ if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL) { _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); return (HTTP_ERROR); } httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", NULL, "localhost", ippPort(), "/printers/%s", name); snprintf(resource, sizeof(resource), "/printers/%s", name); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_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 (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", last_document); /* * Send and delete the request, then return the status... */ status = cupsSendRequest(http, request, resource, CUPS_LENGTH_VARIABLE); ippDelete(request); return (status); }
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); }
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 */ const char *dest; /* Destination printer */ char *instance; /* Pointer to instance name */ char uri[1024]; /* Printer or job URI */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_op_t op; /* Operation */ int num_dests; /* Number of destinations */ cups_dest_t *dests, /* Destinations */ *defdest; /* Default destination */ http_encryption_t encryption; /* Encryption? */ _cupsSetLocale(argv); /* * Setup to cancel individual print jobs... */ op = IPP_CANCEL_JOB; job_id = 0; dest = NULL; response = NULL; http = NULL; encryption = cupsEncryption(); /* * Open a connection to the server... */ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), encryption)) == NULL) { _cupsLangPuts(stderr, _("lprm: Unable to contact server!\n")); return (1); } num_dests = cupsGetDests2(http, &dests); defdest = cupsGetDest(NULL, NULL, num_dests, dests); dest = defdest ? defdest->name : NULL; /* * Process command-line arguments... */ for (i = 1; i < argc; i ++) if (argv[i][0] == '-' && argv[i][1] != '\0') switch (argv[i][1]) { case 'E' : /* Encrypt */ #ifdef HAVE_SSL encryption = HTTP_ENCRYPT_REQUIRED; httpEncryption(http, encryption); cupsSetEncryption(encryption); #else _cupsLangPrintf(stderr, _("%s: Sorry, no encryption support compiled in!\n"), argv[0]); #endif /* HAVE_SSL */ break; case 'P' : /* Cancel jobs on a printer */ if (argv[i][2]) dest = argv[i] + 2; else { i ++; dest = argv[i]; } if ((instance = strchr(dest, '/')) != NULL) *instance = '\0'; if (cupsGetDest(dest, NULL, num_dests, dests) == NULL) { _cupsLangPrintf(stderr, _("%s: Error - unknown destination \"%s\"!\n"), argv[0], dest); cupsFreeDests(num_dests, dests); httpClose(http); return(1); } 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 'h' : /* Connect to host */ 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]); } httpClose(http); cupsFreeDests(num_dests, dests); if ((http = httpConnectEncrypt(cupsServer(), ippPort(), encryption)) == NULL) { _cupsLangPuts(stderr, _("lprm: Unable to contact server!\n")); return (1); } num_dests = cupsGetDests2(http, &dests); defdest = cupsGetDest(NULL, NULL, num_dests, dests); dest = defdest ? defdest->name : NULL; break; default : _cupsLangPrintf(stderr, _("%s: Error - unknown option \'%c\'!\n"), argv[0], argv[i][1]); cupsFreeDests(num_dests, dests); httpClose(http); return (1); } else { /* * Cancel a job or printer... */ if (isdigit(argv[i][0] & 255) && cupsGetDest(argv[i], NULL, num_dests, dests) == NULL) { dest = NULL; op = IPP_CANCEL_JOB; job_id = atoi(argv[i]); } else if (!strcmp(argv[i], "-")) { /* * Cancel all jobs */ op = IPP_PURGE_JOBS; } else { dest = argv[i]; job_id = 0; } /* * 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); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); /* * Do the request and get back a response... */ if (op == IPP_PURGE_JOBS) response = cupsDoRequest(http, request, "/admin/"); else response = cupsDoRequest(http, request, "/jobs/"); ippDelete(response); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); cupsFreeDests(num_dests, dests); httpClose(http); return (1); } } /* * If nothing has been canceled yet, cancel the current job on the specified * (or default) printer... */ if (response == NULL) if (!cupsCancelJob(dest, 0)) { _cupsLangPrintf(stderr, "%s: %s\n", argv[0], cupsLastErrorString()); cupsFreeDests(num_dests, dests); httpClose(http); return (1); } cupsFreeDests(num_dests, dests); httpClose(http); return (0); }
static cupsd_txt_t /* O - TXT record */ dnssdBuildTxtRecord( cupsd_printer_t *p, /* I - Printer information */ int for_lpd) /* I - 1 = LPD, 0 = IPP */ { int i, /* Looping var */ count; /* Count of key/value pairs */ char admin_hostname[256], /* .local hostname for admin page */ adminurl_str[256], /* URL for the admin page */ type_str[32], /* Type to string buffer */ state_str[32], /* State to string buffer */ rp_str[1024], /* Queue name string buffer */ air_str[1024], /* auth-info-required string buffer */ *keyvalue[32][2]; /* Table of key/value pairs */ cupsd_txt_t txt; /* TXT record */ /* * Load up the key value pairs... */ count = 0; if (!for_lpd || (BrowseLocalProtocols & BROWSE_LPD)) { keyvalue[count ][0] = "txtvers"; keyvalue[count++][1] = "1"; keyvalue[count ][0] = "qtotal"; keyvalue[count++][1] = "1"; keyvalue[count ][0] = "rp"; keyvalue[count++][1] = rp_str; if (for_lpd) strlcpy(rp_str, p->name, sizeof(rp_str)); else snprintf(rp_str, sizeof(rp_str), "%s/%s", (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name); keyvalue[count ][0] = "ty"; keyvalue[count++][1] = p->make_model ? p->make_model : "Unknown"; if (strstr(DNSSDHostName, ".local")) strlcpy(admin_hostname, DNSSDHostName, sizeof(admin_hostname)); else snprintf(admin_hostname, sizeof(admin_hostname), "%s.local.", DNSSDHostName); httpAssembleURIf(HTTP_URI_CODING_ALL, adminurl_str, sizeof(adminurl_str), # ifdef HAVE_SSL "https", # else "http", # endif /* HAVE_SSL */ NULL, admin_hostname, DNSSDPort, "/%s/%s", (p->type & CUPS_PRINTER_CLASS) ? "classes" : "printers", p->name); keyvalue[count ][0] = "adminurl"; keyvalue[count++][1] = adminurl_str; if (p->location) { keyvalue[count ][0] = "note"; keyvalue[count++][1] = p->location; } keyvalue[count ][0] = "priority"; keyvalue[count++][1] = for_lpd ? "100" : "0"; keyvalue[count ][0] = "product"; keyvalue[count++][1] = p->pc && p->pc->product ? p->pc->product : "Unknown"; keyvalue[count ][0] = "pdl"; keyvalue[count++][1] = p->pdl ? p->pdl : "application/postscript"; if (get_auth_info_required(p, air_str, sizeof(air_str))) { keyvalue[count ][0] = "air"; keyvalue[count++][1] = air_str; } keyvalue[count ][0] = "UUID"; keyvalue[count++][1] = p->uuid + 9; #ifdef HAVE_SSL keyvalue[count ][0] = "TLS"; keyvalue[count++][1] = "1.2"; #endif /* HAVE_SSL */ if (p->type & CUPS_PRINTER_FAX) { keyvalue[count ][0] = "Fax"; keyvalue[count++][1] = "T"; keyvalue[count ][0] = "rfo"; keyvalue[count++][1] = rp_str; } if (p->type & CUPS_PRINTER_COLOR) { keyvalue[count ][0] = "Color"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLOR) ? "T" : "F"; } if (p->type & CUPS_PRINTER_DUPLEX) { keyvalue[count ][0] = "Duplex"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_DUPLEX) ? "T" : "F"; } if (p->type & CUPS_PRINTER_STAPLE) { keyvalue[count ][0] = "Staple"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_STAPLE) ? "T" : "F"; } if (p->type & CUPS_PRINTER_COPIES) { keyvalue[count ][0] = "Copies"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_COPIES) ? "T" : "F"; } if (p->type & CUPS_PRINTER_COLLATE) { keyvalue[count ][0] = "Collate"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_COLLATE) ? "T" : "F"; } if (p->type & CUPS_PRINTER_PUNCH) { keyvalue[count ][0] = "Punch"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_PUNCH) ? "T" : "F"; } if (p->type & CUPS_PRINTER_BIND) { keyvalue[count ][0] = "Bind"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_BIND) ? "T" : "F"; } if (p->type & CUPS_PRINTER_SORT) { keyvalue[count ][0] = "Sort"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_SORT) ? "T" : "F"; } if (p->type & CUPS_PRINTER_MFP) { keyvalue[count ][0] = "Scan"; keyvalue[count++][1] = (p->type & CUPS_PRINTER_MFP) ? "T" : "F"; } snprintf(type_str, sizeof(type_str), "0x%X", p->type | CUPS_PRINTER_REMOTE); snprintf(state_str, sizeof(state_str), "%d", p->state); keyvalue[count ][0] = "printer-state"; keyvalue[count++][1] = state_str; keyvalue[count ][0] = "printer-type"; keyvalue[count++][1] = type_str; } /* * Then pack them into a proper txt record... */ # ifdef HAVE_DNSSD TXTRecordCreate(&txt, 0, NULL); for (i = 0; i < count; i ++) { size_t len = strlen(keyvalue[i][1]); if (len < 256) TXTRecordSetValue(&txt, keyvalue[i][0], (uint8_t)len, keyvalue[i][1]); } # else for (i = 0, txt = NULL; i < count; i ++) txt = avahi_string_list_add_printf(txt, "%s=%s", keyvalue[i][0], keyvalue[i][1]); # endif /* HAVE_DNSSD */ return (txt); }
int /* O - Number of jobs */ cupsGetJobs2(http_t *http, /* I - HTTP connection */ cups_job_t **jobs, /* O - Job data */ const char *mydest, /* I - NULL = all destinations, * * otherwise show jobs for mydest */ int myjobs, /* I - 0 = all users, 1 = mine */ int completed) /* I - -1 = show all, 0 = active, * * 1 = completed jobs */ { int n; /* Number of jobs */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_job_t *temp; /* Temporary pointer */ int id, /* job-id */ priority, /* job-priority */ size; /* job-k-octets */ ipp_jstate_t state; /* job-state */ time_t completed_time, /* time-at-completed */ creation_time, /* time-at-creation */ processing_time; /* time-at-processing */ const char *dest, /* job-printer-uri */ *format, /* document-format */ *title, /* job-name */ *user; /* job-originating-user-name */ char uri[HTTP_MAX_URI]; /* URI for jobs */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ static const char * const attrs[] = /* Requested attributes */ { "job-id", "job-priority", "job-k-octets", "job-state", "time-at-completed", "time-at-creation", "time-at-processing", "job-printer-uri", "document-format", "job-name", "job-originating-user-name" }; /* * Range check input... */ if (!http || !jobs) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (-1); } /* * Get the right URI... */ if (mydest) { if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", mydest) != HTTP_URI_OK) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (-1); } } else strcpy(uri, "ipp://localhost/jobs"); /* * Build an IPP_GET_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * which-jobs * my-jobs * requested-attributes */ request = ippNewRequest(IPP_GET_JOBS); 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 (myjobs) ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1); if (completed > 0) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", NULL, "completed"); else if (completed < 0) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "which-jobs", NULL, "all"); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(attrs) / sizeof(attrs[0]), NULL, attrs); /* * Do the request and get back a response... */ n = 0; *jobs = NULL; if ((response = cupsDoRequest(http, request, "/")) != NULL) { 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... */ id = 0; size = 0; priority = 50; state = IPP_JOB_PENDING; user = "******"; dest = NULL; format = "application/octet-stream"; title = "untitled"; creation_time = 0; completed_time = 0; processing_time = 0; while (attr != NULL && attr->group_tag == IPP_TAG_JOB) { if (strcmp(attr->name, "job-id") == 0 && attr->value_tag == IPP_TAG_INTEGER) id = attr->values[0].integer; else if (strcmp(attr->name, "job-state") == 0 && attr->value_tag == IPP_TAG_ENUM) state = (ipp_jstate_t)attr->values[0].integer; else if (strcmp(attr->name, "job-priority") == 0 && attr->value_tag == IPP_TAG_INTEGER) priority = attr->values[0].integer; else if (strcmp(attr->name, "job-k-octets") == 0 && attr->value_tag == IPP_TAG_INTEGER) size = attr->values[0].integer; else if (strcmp(attr->name, "time-at-completed") == 0 && attr->value_tag == IPP_TAG_INTEGER) completed_time = attr->values[0].integer; else if (strcmp(attr->name, "time-at-creation") == 0 && attr->value_tag == IPP_TAG_INTEGER) creation_time = attr->values[0].integer; else if (strcmp(attr->name, "time-at-processing") == 0 && attr->value_tag == IPP_TAG_INTEGER) processing_time = attr->values[0].integer; else if (strcmp(attr->name, "job-printer-uri") == 0 && attr->value_tag == IPP_TAG_URI) { if ((dest = strrchr(attr->values[0].string.text, '/')) != NULL) dest ++; } else if (strcmp(attr->name, "job-originating-user-name") == 0 && attr->value_tag == IPP_TAG_NAME) user = attr->values[0].string.text; else if (strcmp(attr->name, "document-format") == 0 && attr->value_tag == IPP_TAG_MIMETYPE) format = attr->values[0].string.text; else if (strcmp(attr->name, "job-name") == 0 && (attr->value_tag == IPP_TAG_TEXT || attr->value_tag == IPP_TAG_NAME)) title = attr->values[0].string.text; attr = attr->next; } /* * See if we have everything needed... */ if (dest == NULL || id == 0) { if (attr == NULL) break; else continue; } /* * Allocate memory for the job... */ if (n == 0) temp = malloc(sizeof(cups_job_t)); else temp = realloc(*jobs, sizeof(cups_job_t) * (n + 1)); if (temp == NULL) { /* * Ran out of memory! */ cupsFreeJobs(n, *jobs); *jobs = NULL; ippDelete(response); return (0); } *jobs = temp; temp += n; n ++; /* * Copy the data over... */ temp->dest = strdup(dest); temp->user = strdup(user); temp->format = strdup(format); temp->title = strdup(title); temp->id = id; temp->priority = priority; temp->state = state; temp->size = size; temp->completed_time = completed_time; temp->creation_time = creation_time; temp->processing_time = processing_time; if (attr == NULL) break; } ippDelete(response); } if (n == 0 && cg->last_error >= IPP_BAD_REQUEST) return (-1); else return (n); }
int /* O - Job ID */ cupsPrintFiles2(http_t *http, /* I - HTTP connection */ const char *name, /* I - Printer or class name */ int num_files,/* I - Number of files */ const char **files, /* I - File(s) to print */ const char *title, /* I - Title of job */ int num_options, /* I - Number of options */ cups_option_t *options) /* I - Options */ { int i; /* Looping var */ const char *val; /* Pointer to option value */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_attribute_t *attr; /* IPP job-id attribute */ char uri[HTTP_MAX_URI]; /* Printer URI */ int jobid; /* New job ID */ const char *base; /* Basename of current filename */ DEBUG_printf(("cupsPrintFiles(http=%p, name=\"%s\", num_files=%d, " "files=%p, title=\"%s\", num_options=%d, options=%p)\n", http, name, num_files, files, title, num_options, options)); /* * Range check input... */ if (!http || !name || num_files < 1 || files == NULL) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (0); } /* * Setup the printer URI... */ if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (0); } /* * Build a standard CUPS URI for the printer and fill the standard IPP * attributes... */ if ((request = ippNewRequest(num_files == 1 ? IPP_PRINT_JOB : IPP_CREATE_JOB)) == NULL) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (0); } 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 (title) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, title); /* * Then add all options... */ cupsEncodeOptions(request, num_options, options); /* * Do the request... */ snprintf(uri, sizeof(uri), "/printers/%s", name); if (num_files == 1) response = cupsDoFileRequest(http, request, uri, *files); else response = cupsDoRequest(http, request, uri); if (response == NULL) jobid = 0; else if (response->request.status.status_code > IPP_OK_CONFLICT) { DEBUG_printf(("IPP response code was 0x%x!\n", response->request.status.status_code)); jobid = 0; } else if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) == NULL) { DEBUG_puts("No job ID!"); _cupsSetError(IPP_INTERNAL_ERROR, NULL); jobid = 0; } else jobid = attr->values[0].integer; if (response != NULL) ippDelete(response); /* * Handle multiple file jobs if the create-job operation worked... */ if (jobid > 0 && num_files > 1) for (i = 0; i < num_files; i ++) { /* * Build a standard CUPS URI for the job and fill the standard IPP * attributes... */ if ((request = ippNewRequest(IPP_SEND_DOCUMENT)) == NULL) return (0); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", jobid); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); /* * Handle raw print files... */ if (cupsGetOption("raw", num_options, options)) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, "application/vnd.cups-raw"); else if ((val = cupsGetOption("document-format", num_options, options)) != NULL) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, val); else ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE, "document-format", NULL, "application/octet-stream"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); /* * Add the original document filename... */ if ((base = strrchr(files[i], '/')) != NULL) base ++; else base = files[i]; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "document-name", NULL, base); /* * Is this the last document? */ if (i == (num_files - 1)) ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1); /* * Send the file... */ snprintf(uri, sizeof(uri), "/printers/%s", name); if ((response = cupsDoFileRequest(http, request, uri, files[i])) != NULL) ippDelete(response); } return (jobid); }
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); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { const char *printer; /* Printer name */ const char *user; /* Username */ http_t *http; /* Connection to the server */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* IPP attribute */ const char *op; /* Operation to perform, if any */ static const char *def_attrs[] = /* Attributes for default printer */ { "printer-name", "printer-uri-supported" }; /* * Get any form variables... */ cgiInitialize(); op = cgiGetVariable("OP"); /* * Set the web interface section... */ cgiSetVariable("SECTION", "printers"); cgiSetVariable("REFRESH_PAGE", ""); /* * See if we are displaying a printer or all printers... */ if ((printer = getenv("PATH_INFO")) != NULL) { printer ++; if (!*printer) printer = NULL; if (printer) cgiSetVariable("PRINTER_NAME", printer); } /* * See who is logged in... */ user = getenv("REMOTE_USER"); /* * Connect to the HTTP server... */ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); /* * Get the default printer... */ if (!op || !cgiIsPOST()) { /* * Get the default destination... */ request = ippNewRequest(CUPS_GET_DEFAULT); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(def_attrs) / sizeof(def_attrs[0]), NULL, def_attrs); if ((response = cupsDoRequest(http, request, "/")) != NULL) { if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL) cgiSetVariable("DEFAULT_NAME", attr->values[0].string.text); if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL) { char url[HTTP_MAX_URI]; /* New URL */ cgiSetVariable("DEFAULT_URI", cgiRewriteURL(attr->values[0].string.text, url, sizeof(url), NULL)); } ippDelete(response); } /* * See if we need to show a list of printers or the status of a * single printer... */ if (!printer) show_all_printers(http, user); else show_printer(http, printer); } else if (printer) { if (!*op) { const char *server_port = getenv("SERVER_PORT"); /* Port number string */ int port = atoi(server_port ? server_port : "0"); /* Port number */ char uri[1024]; /* URL */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), getenv("HTTPS") ? "https" : "http", NULL, getenv("SERVER_NAME"), port, "/printers/%s", printer); printf("Location: %s\n\n", uri); } else if (!strcmp(op, "start-printer")) do_printer_op(http, printer, IPP_RESUME_PRINTER, cgiText(_("Resume Printer"))); else if (!strcmp(op, "stop-printer")) do_printer_op(http, printer, IPP_PAUSE_PRINTER, cgiText(_("Pause Printer"))); else if (!strcmp(op, "accept-jobs")) do_printer_op(http, printer, CUPS_ACCEPT_JOBS, cgiText(_("Accept Jobs"))); else if (!strcmp(op, "reject-jobs")) do_printer_op(http, printer, CUPS_REJECT_JOBS, cgiText(_("Reject Jobs"))); else if (!strcmp(op, "purge-jobs")) do_printer_op(http, printer, IPP_PURGE_JOBS, cgiText(_("Purge Jobs"))); else if (!_cups_strcasecmp(op, "print-self-test-page")) cgiPrintCommand(http, printer, "PrintSelfTestPage", cgiText(_("Print Self-Test Page"))); else if (!_cups_strcasecmp(op, "clean-print-heads")) cgiPrintCommand(http, printer, "Clean all", cgiText(_("Clean Print Heads"))); else if (!_cups_strcasecmp(op, "print-test-page")) cgiPrintTestPage(http, printer); else if (!_cups_strcasecmp(op, "move-jobs")) cgiMoveJobs(http, printer, 0); else { /* * Unknown/bad operation... */ cgiStartHTML(printer); cgiCopyTemplateLang("error-op.tmpl"); cgiEndHTML(); } } else { /* * Unknown/bad operation... */ cgiStartHTML(cgiText(_("Printers"))); cgiCopyTemplateLang("error-op.tmpl"); cgiEndHTML(); } /* * Close the HTTP server connection... */ httpClose(http); /* * Return with no errors... */ 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); }
int /* O - 0 on success, -1 on failure */ backendGetDeviceID( int fd, /* I - File descriptor */ char *device_id, /* O - 1284 device ID */ int device_id_size, /* I - Size of buffer */ char *make_model, /* O - Make/model */ int make_model_size, /* I - Size of buffer */ const char *scheme, /* I - URI scheme */ char *uri, /* O - Device URI */ int uri_size) /* I - Size of buffer */ { #ifdef __APPLE__ /* This function is a no-op */ (void)fd; (void)device_id; (void)device_id_size; (void)make_model; (void)make_model_size; (void)scheme; (void)uri; (void)uri_size; return (-1); #else /* Get the device ID from the specified file descriptor... */ # ifdef __linux int length; /* Length of device ID info */ int got_id = 0; # endif /* __linux */ # if defined(__sun) && defined(ECPPIOC_GETDEVID) struct ecpp_device_id did; /* Device ID buffer */ # endif /* __sun && ECPPIOC_GETDEVID */ char *ptr; /* Pointer into device ID */ DEBUG_printf(("backendGetDeviceID(fd=%d, device_id=%p, device_id_size=%d, " "make_model=%p, make_model_size=%d, scheme=\"%s\", " "uri=%p, uri_size=%d)\n", fd, device_id, device_id_size, make_model, make_model_size, scheme ? scheme : "(null)", uri, uri_size)); /* * Range check input... */ if (!device_id || device_id_size < 32) { DEBUG_puts("backendGetDeviceID: Bad args!"); return (-1); } if (make_model) *make_model = '\0'; if (fd >= 0) { /* * Get the device ID string... */ *device_id = '\0'; # ifdef __linux if (ioctl(fd, LPIOC_GET_DEVICE_ID(device_id_size), device_id)) { /* * Linux has to implement things differently for every device it seems. * Since the standard parallel port driver does not provide a simple * ioctl() to get the 1284 device ID, we have to open the "raw" parallel * device corresponding to this port and do some negotiation trickery * to get the current device ID. */ if (uri && !strncmp(uri, "parallel:/dev/", 14)) { char devparport[16]; /* /dev/parportN */ int devparportfd, /* File descriptor for raw device */ mode; /* Port mode */ /* * Since the Linux parallel backend only supports 4 parallel port * devices, just grab the trailing digit and use it to construct a * /dev/parportN filename... */ snprintf(devparport, sizeof(devparport), "/dev/parport%s", uri + strlen(uri) - 1); if ((devparportfd = open(devparport, O_RDWR | O_NOCTTY)) != -1) { /* * Claim the device... */ if (!ioctl(devparportfd, PPCLAIM)) { fcntl(devparportfd, F_SETFL, fcntl(devparportfd, F_GETFL) | O_NONBLOCK); mode = IEEE1284_MODE_COMPAT; if (!ioctl(devparportfd, PPNEGOT, &mode)) { /* * Put the device into Device ID mode... */ mode = IEEE1284_MODE_NIBBLE | IEEE1284_DEVICEID; if (!ioctl(devparportfd, PPNEGOT, &mode)) { /* * Read the 1284 device ID... */ if ((length = read(devparportfd, device_id, (size_t)device_id_size - 1)) >= 2) { device_id[length] = '\0'; got_id = 1; } } } /* * Release the device... */ ioctl(devparportfd, PPRELEASE); } close(devparportfd); } } } else got_id = 1; if (got_id) { /* * Extract the length of the device ID string from the first two * bytes. The 1284 spec says the length is stored MSB first... */ length = (int)((((unsigned)device_id[0] & 255) << 8) + ((unsigned)device_id[1] & 255)); /* * Check to see if the length is larger than our buffer; first * assume that the vendor incorrectly implemented the 1284 spec, * and then limit the length to the size of our buffer... */ if (length > device_id_size || length < 14) length = (int)((((unsigned)device_id[1] & 255) << 8) + ((unsigned)device_id[0] & 255)); if (length > device_id_size) length = device_id_size; /* * The length field counts the number of bytes in the string * including the length field itself (2 bytes). The minimum * length for a valid/usable device ID is 14 bytes: * * <LENGTH> MFG: <MFG> ;MDL: <MDL> ; * 2 + 4 + 1 + 5 + 1 + 1 */ if (length < 14) { /* * Can't use this device ID, so don't try to copy it... */ device_id[0] = '\0'; got_id = 0; } else { /* * Copy the device ID text to the beginning of the buffer and * nul-terminate. */ length -= 2; memmove(device_id, device_id + 2, (size_t)length); device_id[length] = '\0'; } } else { DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n", strerror(errno))); *device_id = '\0'; } # endif /* __linux */ # if defined(__sun) && defined(ECPPIOC_GETDEVID) did.mode = ECPP_CENTRONICS; did.len = device_id_size - 1; did.rlen = 0; did.addr = device_id; if (!ioctl(fd, ECPPIOC_GETDEVID, &did)) { /* * Nul-terminate the device ID text. */ if (did.rlen < (device_id_size - 1)) device_id[did.rlen] = '\0'; else device_id[device_id_size - 1] = '\0'; } # ifdef DEBUG else DEBUG_printf(("backendGetDeviceID: ioctl failed - %s\n", strerror(errno))); # endif /* DEBUG */ # endif /* __sun && ECPPIOC_GETDEVID */ } /* * Check whether device ID is valid. Turn line breaks and tabs to spaces and * reject device IDs with non-printable characters. */ for (ptr = device_id; *ptr; ptr ++) if (_cups_isspace(*ptr)) *ptr = ' '; else if ((*ptr & 255) < ' ' || *ptr == 127) { DEBUG_printf(("backendGetDeviceID: Bad device_id character %d.", *ptr & 255)); *device_id = '\0'; break; } DEBUG_printf(("backendGetDeviceID: device_id=\"%s\"\n", device_id)); if (scheme && uri) *uri = '\0'; if (!*device_id) return (-1); /* * Get the make and model... */ if (make_model) backendGetMakeModel(device_id, make_model, (size_t)make_model_size); /* * Then generate a device URI... */ if (scheme && uri && uri_size > 32) { int num_values; /* Number of keys and values */ cups_option_t *values; /* Keys and values in device ID */ const char *mfg, /* Manufacturer */ *mdl, /* Model */ *sern; /* Serial number */ char temp[256], /* Temporary manufacturer string */ *tempptr; /* Pointer into temp string */ /* * Get the make, model, and serial numbers... */ num_values = _cupsGet1284Values(device_id, &values); if ((sern = cupsGetOption("SERIALNUMBER", num_values, values)) == NULL) if ((sern = cupsGetOption("SERN", num_values, values)) == NULL) sern = cupsGetOption("SN", num_values, values); if ((mfg = cupsGetOption("MANUFACTURER", num_values, values)) == NULL) mfg = cupsGetOption("MFG", num_values, values); if ((mdl = cupsGetOption("MODEL", num_values, values)) == NULL) mdl = cupsGetOption("MDL", num_values, values); if (mfg) { if (!_cups_strcasecmp(mfg, "Hewlett-Packard")) mfg = "HP"; else if (!_cups_strcasecmp(mfg, "Lexmark International")) mfg = "Lexmark"; } else { strlcpy(temp, make_model, sizeof(temp)); if ((tempptr = strchr(temp, ' ')) != NULL) *tempptr = '\0'; mfg = temp; } if (!mdl) mdl = ""; if (!_cups_strncasecmp(mdl, mfg, strlen(mfg))) { mdl += strlen(mfg); while (isspace(*mdl & 255)) mdl ++; } /* * Generate the device URI from the manufacturer, make_model, and * serial number strings. */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, uri_size, scheme, NULL, mfg, 0, "/%s%s%s", mdl, sern ? "?serial=" : "", sern ? sern : ""); cupsFreeOptions(num_values, values); } return (0); #endif /* __APPLE__ */ }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ ipp_t *event; /* Event from scheduler */ ipp_state_t state; /* IPP event state */ char scheme[32], /* URI scheme ("rss") */ username[256], /* Username for remote RSS */ host[1024], /* Hostname for remote RSS */ resource[1024], /* RSS file */ *options; /* Options */ int port, /* Port number for remote RSS */ max_events; /* Maximum number of events */ http_t *http; /* Connection to remote server */ http_status_t status; /* HTTP GET/PUT status code */ char filename[1024], /* Local filename */ newname[1024]; /* filename.N */ cups_lang_t *language; /* Language information */ ipp_attribute_t *printer_up_time, /* Timestamp on event */ *notify_sequence_number,/* Sequence number */ *notify_printer_uri; /* Printer URI */ char *subject, /* Subject for notification message */ *text, /* Text for notification message */ link_url[1024], /* Link to printer */ link_scheme[32], /* Scheme for link */ link_username[256], /* Username for link */ link_host[1024], /* Host for link */ link_resource[1024]; /* Resource for link */ int link_port; /* Link port */ cups_array_t *rss; /* RSS message array */ _cups_rss_t *msg; /* RSS message */ char baseurl[1024]; /* Base URL */ fd_set input; /* Input set for select() */ struct timeval timeout; /* Timeout for select() */ int changed; /* Has the RSS data changed? */ int exit_status; /* Exit status */ fprintf(stderr, "DEBUG: argc=%d\n", argc); for (i = 0; i < argc; i ++) fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); /* * See whether we are publishing this RSS feed locally or remotely... */ if (httpSeparateURI(HTTP_URI_CODING_ALL, argv[1], scheme, sizeof(scheme), username, sizeof(username), host, sizeof(host), &port, resource, sizeof(resource)) < HTTP_URI_OK) { fprintf(stderr, "ERROR: Bad RSS URI \"%s\"!\n", argv[1]); return (1); } max_events = 20; if ((options = strchr(resource, '?')) != NULL) { *options++ = '\0'; if (!strncmp(options, "max_events=", 11)) { max_events = atoi(options + 11); if (max_events <= 0) max_events = 20; } } rss = cupsArrayNew((cups_array_func_t)compare_rss, NULL); if (host[0]) { /* * Remote feed, see if we can get the current file... */ int fd; /* Temporary file */ if ((rss_password = strchr(username, ':')) != NULL) *rss_password++ = '\0'; cupsSetPasswordCB(password_cb); cupsSetUser(username); if ((fd = cupsTempFd(filename, sizeof(filename))) < 0) { fprintf(stderr, "ERROR: Unable to create temporary file: %s\n", strerror(errno)); return (1); } if ((http = httpConnect(host, port)) == NULL) { fprintf(stderr, "ERROR: Unable to connect to %s on port %d: %s\n", host, port, strerror(errno)); close(fd); unlink(filename); return (1); } status = cupsGetFd(http, resource, fd); close(fd); if (status != HTTP_OK && status != HTTP_NOT_FOUND) { fprintf(stderr, "ERROR: Unable to GET %s from %s on port %d: %d %s\n", resource, host, port, status, httpStatus(status)); httpClose(http); unlink(filename); return (1); } strlcpy(newname, filename, sizeof(newname)); httpAssembleURI(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http", NULL, host, port, resource); } else { const char *cachedir, /* CUPS_CACHEDIR */ *server_name, /* SERVER_NAME */ *server_port; /* SERVER_PORT */ http = NULL; if ((cachedir = getenv("CUPS_CACHEDIR")) == NULL) cachedir = CUPS_CACHEDIR; if ((server_name = getenv("SERVER_NAME")) == NULL) server_name = "localhost"; if ((server_port = getenv("SERVER_PORT")) == NULL) server_port = "631"; snprintf(filename, sizeof(filename), "%s/rss%s", cachedir, resource); snprintf(newname, sizeof(newname), "%s.N", filename); httpAssembleURIf(HTTP_URI_CODING_ALL, baseurl, sizeof(baseurl), "http", NULL, server_name, atoi(server_port), "/rss%s", resource); } /* * Load the previous RSS file, if any... */ load_rss(rss, filename); changed = cupsArrayCount(rss) == 0; /* * Localize for the user's chosen language... */ language = cupsLangDefault(); /* * Read events and update the RSS file until we are out of events. */ for (exit_status = 0, event = NULL;;) { if (changed) { /* * Save the messages to the file again, uploading as needed... */ if (save_rss(rss, newname, baseurl)) { if (http) { /* * Upload the RSS file... */ if ((status = cupsPutFile(http, resource, filename)) != HTTP_CREATED) fprintf(stderr, "ERROR: Unable to PUT %s from %s on port %d: %d %s\n", resource, host, port, status, httpStatus(status)); } else { /* * Move the new RSS file over top the old one... */ if (rename(newname, filename)) fprintf(stderr, "ERROR: Unable to rename %s to %s: %s\n", newname, filename, strerror(errno)); } changed = 0; } } /* * Wait up to 30 seconds for an event... */ timeout.tv_sec = 30; timeout.tv_usec = 0; FD_ZERO(&input); FD_SET(0, &input); if (select(1, &input, NULL, NULL, &timeout) < 0) continue; else if (!FD_ISSET(0, &input)) { fprintf(stderr, "DEBUG: %s is bored, exiting...\n", argv[1]); break; } /* * Read the next event... */ event = ippNew(); while ((state = ippReadFile(0, event)) != IPP_DATA) { if (state <= IPP_IDLE) break; } if (state == IPP_ERROR) fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr); if (state <= IPP_IDLE) break; /* * Collect the info from the event... */ printer_up_time = ippFindAttribute(event, "printer-up-time", IPP_TAG_INTEGER); notify_sequence_number = ippFindAttribute(event, "notify-sequence-number", IPP_TAG_INTEGER); notify_printer_uri = ippFindAttribute(event, "notify-printer-uri", IPP_TAG_URI); subject = cupsNotifySubject(language, event); text = cupsNotifyText(language, event); if (printer_up_time && notify_sequence_number && subject && text) { /* * Create a new RSS message... */ if (notify_printer_uri) { httpSeparateURI(HTTP_URI_CODING_ALL, notify_printer_uri->values[0].string.text, link_scheme, sizeof(link_scheme), link_username, sizeof(link_username), link_host, sizeof(link_host), &link_port, link_resource, sizeof(link_resource)); httpAssembleURI(HTTP_URI_CODING_ALL, link_url, sizeof(link_url), "http", link_username, link_host, link_port, link_resource); } msg = new_message(notify_sequence_number->values[0].integer, xml_escape(subject), xml_escape(text), notify_printer_uri ? xml_escape(link_url) : NULL, printer_up_time->values[0].integer); if (!msg) { fprintf(stderr, "ERROR: Unable to create message: %s\n", strerror(errno)); exit_status = 1; break; } /* * Add it to the array... */ cupsArrayAdd(rss, msg); changed = 1; /* * Trim the array as needed... */ while (cupsArrayCount(rss) > max_events) { msg = cupsArrayFirst(rss); cupsArrayRemove(rss, msg); delete_message(msg); } } if (subject) free(subject); if (text) free(text); ippDelete(event); event = NULL; } /* * We only get here when idle or error... */ ippDelete(event); if (http) { unlink(filename); httpClose(http); } return (exit_status); }
int /* O - Job ID or 0 on error */ cupsCreateJob( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ const char *name, /* I - Destination name */ const char *title, /* I - Title of job */ int num_options, /* I - Number of options */ cups_option_t *options) /* I - Options */ { char printer_uri[1024], /* Printer URI */ resource[1024]; /* Printer resource */ ipp_t *request, /* Create-Job request */ *response; /* Create-Job response */ ipp_attribute_t *attr; /* job-id attribute */ int job_id = 0; /* job-id value */ DEBUG_printf(("cupsCreateJob(http=%p, name=\"%s\", title=\"%s\", " "num_options=%d, options=%p)", http, name, title, num_options, options)); /* * Range check input... */ if (!name) { _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); return (0); } /* * Build a Create-Job request... */ if ((request = ippNewRequest(IPP_CREATE_JOB)) == NULL) { _cupsSetError(IPP_INTERNAL_ERROR, strerror(ENOMEM), 0); return (0); } httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", NULL, "localhost", ippPort(), "/printers/%s", name); snprintf(resource, sizeof(resource), "/printers/%s", name); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_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_JOB); cupsEncodeOptions2(request, num_options, options, IPP_TAG_SUBSCRIPTION); /* * Send the request and get the job-id... */ response = cupsDoRequest(http, request, resource); if ((attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER)) != NULL) job_id = attr->values[0].integer; ippDelete(response); /* * Return it... */ return (job_id); }
ipp_status_t /* O - IPP status */ cupsCancelJob2(http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ const char *name, /* I - Name of printer or class */ int job_id, /* I - Job ID, @code CUPS_JOBID_CURRENT@ for the current job, or @code CUPS_JOBID_ALL@ for all jobs */ int purge) /* I - 1 to purge, 0 to cancel */ { char uri[HTTP_MAX_URI]; /* Job/printer URI */ ipp_t *request; /* IPP request */ /* * Range check input... */ if (job_id < -1 || (!name && job_id == 0)) { _cupsSetError(IPP_INTERNAL_ERROR, strerror(EINVAL), 0); return (0); } /* * Connect to the default server as needed... */ if (!http) if ((http = _cupsConnect()) == NULL) return (IPP_SERVICE_UNAVAILABLE); /* * Build an IPP_CANCEL_JOB or IPP_PURGE_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * job-uri or printer-uri + job-id * requesting-user-name * [purge-job] or [purge-jobs] */ request = ippNewRequest(job_id < 0 ? IPP_PURGE_JOBS : IPP_CANCEL_JOB); if (name) { httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", ippPort(), "/printers/%s", name); 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 if (job_id > 0) { snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_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, cupsUser()); if (purge && job_id >= 0) ippAddBoolean(request, IPP_TAG_OPERATION, "purge-job", 1); else if (!purge && job_id < 0) ippAddBoolean(request, IPP_TAG_OPERATION, "purge-jobs", 0); /* * Do the request... */ ippDelete(cupsDoRequest(http, request, "/jobs/")); return (cupsLastError()); }
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); }
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 int /* O - 0 on success, 1 on fail */ add_printer_to_class(http_t *http, /* I - Server connection */ char *printer, /* I - Printer to add */ char *pclass) /* I - Class to add to */ { int i; /* Looping var */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr, /* Current attribute */ *members; /* Members in class */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ DEBUG_printf(("add_printer_to_class(%p, \"%s\", \"%s\")\n", http, printer, pclass)); /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/classes/%s", pclass); 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... */ response = cupsDoRequest(http, request, "/"); /* * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * member-uris */ request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); 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()); /* * See if the printer is already in the class... */ if (response != NULL && (members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) != NULL) for (i = 0; i < members->num_values; i ++) if (_cups_strcasecmp(printer, members->values[i].string.text) == 0) { _cupsLangPrintf(stderr, _("lpadmin: Printer %s is already a member of class " "%s."), printer, pclass); ippDelete(request); ippDelete(response); return (0); } /* * OK, the printer isn't part of the class, so add it... */ httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer); if (response != NULL && (members = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) { /* * Add the printer to the existing list... */ attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", members->num_values + 1, NULL, NULL); for (i = 0; i < members->num_values; i ++) attr->values[i].string.text = _cupsStrAlloc(members->values[i].string.text); attr->values[i].string.text = _cupsStrAlloc(uri); } else ippAddString(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", NULL, uri); /* * Then send the request... */ ippDelete(response); ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
static void do_printer_op(http_t *http, /* I - HTTP connection */ const char *printer, /* I - Printer name */ ipp_op_t op, /* I - Operation to perform */ const char *title) /* I - Title of page */ { ipp_t *request; /* IPP request */ char uri[HTTP_MAX_URI], /* Printer URI */ resource[HTTP_MAX_URI]; /* Path for request */ /* * Build a printer request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri */ request = ippNewRequest(op); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); /* * Do the request and get back a response... */ snprintf(resource, sizeof(resource), "/printers/%s", printer); ippDelete(cupsDoRequest(http, request, resource)); if (cupsLastError() == IPP_NOT_AUTHORIZED) { puts("Status: 401\n"); exit(0); } else if (cupsLastError() > IPP_OK_CONFLICT) { cgiStartHTML(title); cgiShowIPPError(_("Unable to do maintenance command")); } else { /* * Redirect successful updates back to the printer page... */ char url[1024], /* Printer/class URL */ refresh[1024]; /* Refresh URL */ cgiRewriteURL(uri, url, sizeof(url), NULL); cgiFormEncode(uri, url, sizeof(uri)); snprintf(refresh, sizeof(refresh), "5;URL=%s", uri); cgiSetVariable("refresh_page", refresh); cgiStartHTML(title); if (op == IPP_PAUSE_PRINTER) cgiCopyTemplateLang("printer-stop.tmpl"); else if (op == IPP_RESUME_PRINTER) cgiCopyTemplateLang("printer-start.tmpl"); else if (op == CUPS_ACCEPT_JOBS) cgiCopyTemplateLang("printer-accept.tmpl"); else if (op == CUPS_REJECT_JOBS) cgiCopyTemplateLang("printer-reject.tmpl"); else if (op == IPP_PURGE_JOBS) cgiCopyTemplateLang("printer-purge.tmpl"); } cgiEndHTML(); }
static int /* O - 0 on success, 1 on fail */ delete_printer_from_class( http_t *http, /* I - Server connection */ char *printer, /* I - Printer to remove */ char *pclass) /* I - Class to remove from */ { int i, j, k; /* Looping vars */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ ipp_attribute_t *attr, /* Current attribute */ *members; /* Members in class */ char uri[HTTP_MAX_URI]; /* URI for printer/class */ DEBUG_printf(("delete_printer_from_class(%p, \"%s\", \"%s\")\n", http, printer, pclass)); /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/classes/%s", pclass); 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... */ if ((response = cupsDoRequest(http, request, "/classes/")) == NULL || response->request.status.status_code == IPP_NOT_FOUND) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); ippDelete(response); return (1); } /* * See if the printer is already in the class... */ if ((members = ippFindAttribute(response, "member-names", IPP_TAG_NAME)) == NULL) { _cupsLangPuts(stderr, _("lpadmin: No member names were seen.")); ippDelete(response); return (1); } for (i = 0; i < members->num_values; i ++) if (!_cups_strcasecmp(printer, members->values[i].string.text)) break; if (i >= members->num_values) { _cupsLangPrintf(stderr, _("lpadmin: Printer %s is not a member of class %s."), printer, pclass); ippDelete(response); return (1); } if (members->num_values == 1) { /* * Build a CUPS_DELETE_CLASS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name */ request = ippNewRequest(CUPS_DELETE_CLASS); 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()); } else { /* * Build a CUPS_ADD_MODIFY_CLASS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * member-uris */ request = ippNewRequest(CUPS_ADD_MODIFY_CLASS); 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()); /* * Delete the printer from the class... */ members = ippFindAttribute(response, "member-uris", IPP_TAG_URI); attr = ippAddStrings(request, IPP_TAG_PRINTER, IPP_TAG_URI, "member-uris", members->num_values - 1, NULL, NULL); for (j = 0, k = 0; j < members->num_values; j ++) if (j != i) attr->values[k ++].string.text = _cupsStrAlloc(members->values[j].string.text); } /* * Then send the request... */ ippDelete(response); ippDelete(cupsDoRequest(http, request, "/admin/")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, _("%s: %s"), "lpadmin", cupsLastErrorString()); return (1); } else return (0); }
static void show_printer(http_t *http, /* I - Connection to server */ const char *printer) /* I - Name of printer */ { ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* IPP attribute */ char uri[HTTP_MAX_URI]; /* Printer URI */ char refresh[1024]; /* Refresh URL */ fprintf(stderr, "DEBUG: show_printer(http=%p, printer=\"%s\")\n", http, printer ? printer : "(null)"); /* * 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", printer); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); cgiGetAttributes(request, "printer.tmpl"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { /* * Got the result; set the CGI variables and check the status of a * single-queue request... */ cgiSetIPPVars(response, NULL, NULL, NULL, 0); if (printer && (attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL && attr->values[0].integer == IPP_PRINTER_PROCESSING) { /* * Printer is processing - automatically refresh the page until we * are done printing... */ cgiFormEncode(uri, printer, sizeof(uri)); snprintf(refresh, sizeof(refresh), "10;URL=/printers/%s", uri); cgiSetVariable("refresh_page", refresh); } /* * Delete the response... */ ippDelete(response); /* * Show the standard header... */ cgiStartHTML(printer); /* * Show the printer status... */ cgiCopyTemplateLang("printer.tmpl"); /* * Show jobs for the specified printer... */ cgiCopyTemplateLang("printer-jobs-header.tmpl"); cgiShowJobs(http, printer); } else { /* * Show the IPP error... */ cgiStartHTML(printer); cgiShowIPPError(_("Unable to get printer status")); } cgiEndHTML(); }
void cgiMoveJobs(http_t *http, /* I - Connection to server */ const char *dest, /* I - Destination or NULL */ int job_id) /* I - Job ID or 0 for all */ { int i; /* Looping var */ const char *user; /* Username */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* Current attribute */ const char *name; /* Destination name */ const char *job_printer_uri; /* JOB_PRINTER_URI form variable */ char current_dest[1024]; /* Current destination */ /* * See who is logged in... */ if ((user = getenv("REMOTE_USER")) == NULL) user = "******"; /* * See if the user has already selected a new destination... */ if ((job_printer_uri = cgiGetVariable("JOB_PRINTER_URI")) == NULL) { /* * Make sure necessary form variables are set... */ if (job_id) { char temp[255]; /* Temporary string */ sprintf(temp, "%d", job_id); cgiSetVariable("JOB_ID", temp); } if (dest) cgiSetVariable("PRINTER_NAME", dest); /* * No new destination specified, show the user what the available * printers/classes are... */ if (!dest) { /* * Get the current destination for job N... */ char job_uri[1024]; /* Job URI */ request = ippNewRequest(IPP_GET_JOB_ATTRIBUTES); snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, job_uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "job-printer-uri"); if ((response = cupsDoRequest(http, request, "/")) != NULL) { if ((attr = ippFindAttribute(response, "job-printer-uri", IPP_TAG_URI)) != NULL) { /* * Pull the name from the URI... */ strlcpy(current_dest, strrchr(attr->values[0].string.text, '/') + 1, sizeof(current_dest)); dest = current_dest; } ippDelete(response); } if (!dest) { /* * Couldn't get the current destination... */ cgiStartHTML(cgiText(_("Move Job"))); cgiShowIPPError(_("Unable to find destination for job!")); cgiEndHTML(); return; } } /* * Get the list of available destinations... */ request = ippNewRequest(CUPS_GET_PRINTERS); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "printer-uri-supported"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); if ((response = cupsDoRequest(http, request, "/")) != NULL) { for (i = 0, attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI); attr; attr = ippFindNextAttribute(response, "printer-uri-supported", IPP_TAG_URI)) { /* * Pull the name from the URI... */ name = strrchr(attr->values[0].string.text, '/') + 1; /* * If the name is not the same as the current destination, add it! */ if (strcasecmp(name, dest)) { cgiSetArray("JOB_PRINTER_URI", i, attr->values[0].string.text); cgiSetArray("JOB_PRINTER_NAME", i, name); i ++; } } ippDelete(response); } /* * Show the form... */ if (job_id) cgiStartHTML(cgiText(_("Move Job"))); else cgiStartHTML(cgiText(_("Move All Jobs"))); cgiCopyTemplateLang("job-move.tmpl"); } else { /* * Try moving the job or jobs... */ char uri[1024], /* Job/printer URI */ resource[1024], /* Post resource */ refresh[1024]; /* Refresh URL */ const char *job_printer_name; /* New printer name */ request = ippNewRequest(CUPS_MOVE_JOB); if (job_id) { /* * Move 1 job... */ snprintf(resource, sizeof(resource), "/jobs/%d", job_id); snprintf(uri, sizeof(uri), "ipp://localhost/jobs/%d", job_id); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); } else { /* * Move all active jobs on a destination... */ snprintf(resource, sizeof(resource), "/%s/%s", cgiGetVariable("SECTION"), dest); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"), dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-printer-uri", NULL, job_printer_uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippDelete(cupsDoRequest(http, request, resource)); /* * Show the results... */ job_printer_name = strrchr(job_printer_uri, '/') + 1; if (cupsLastError() <= IPP_OK_CONFLICT) { const char *path = strstr(job_printer_uri, "/printers/"); if (!path) path = strstr(job_printer_uri, "/classes/"); if (path) { cgiFormEncode(uri, path, sizeof(uri)); snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); cgiSetVariable("refresh_page", refresh); } } if (job_id) cgiStartHTML(cgiText(_("Move Job"))); else cgiStartHTML(cgiText(_("Move All Jobs"))); if (cupsLastError() > IPP_OK_CONFLICT) { if (job_id) cgiShowIPPError(_("Unable to move job")); else cgiShowIPPError(_("Unable to move jobs")); } else { cgiSetVariable("JOB_PRINTER_NAME", job_printer_name); cgiCopyTemplateLang("job-moved.tmpl"); } } cgiEndHTML(); }
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); }
void cgiPrintTestPage(http_t *http, /* I - Connection to server */ const char *dest) /* I - Destination printer/class */ { ipp_t *request, /* IPP request */ *response; /* IPP response */ char uri[HTTP_MAX_URI], /* Printer URI */ resource[1024], /* POST resource path */ refresh[1024], /* Refresh URL */ filename[1024]; /* Test page filename */ const char *datadir; /* CUPS_DATADIR env var */ const char *user; /* Username */ /* * See who is logged in... */ user = getenv("REMOTE_USER"); /* * Locate the test page file... */ if ((datadir = getenv("CUPS_DATADIR")) == NULL) datadir = CUPS_DATADIR; snprintf(filename, sizeof(filename), "%s/data/testprint.ps", datadir); /* * Point to the printer/class... */ snprintf(resource, sizeof(resource), "/%s/%s", cgiGetVariable("SECTION"), dest); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", ippPort(), "/%s/%s", cgiGetVariable("SECTION"), dest); /* * Build an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * document-format */ request = ippNewRequest(IPP_PRINT_JOB); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); if (user) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, user); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, "Test Page"); ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format", NULL, "application/postscript"); /* * Do the request and get back a response... */ if ((response = cupsDoFileRequest(http, request, resource, filename)) != NULL) { cgiSetIPPVars(response, NULL, NULL, NULL, 0); ippDelete(response); } if (cupsLastError() <= IPP_OK_CONFLICT) { /* * Automatically reload the printer status page... */ cgiFormEncode(uri, resource, sizeof(uri)); snprintf(refresh, sizeof(refresh), "2;URL=%s", uri); cgiSetVariable("refresh_page", refresh); } else if (cupsLastError() == IPP_NOT_AUTHORIZED) { puts("Status: 401\n"); exit(0); } cgiStartHTML(cgiText(_("Print Test Page"))); if (cupsLastError() > IPP_OK_CONFLICT) cgiShowIPPError(_("Unable to print test page:")); else { cgiSetVariable("PRINTER_NAME", dest); cgiCopyTemplateLang("test-page.tmpl"); } cgiEndHTML(); }
static int /* O - 1 on success, 0 on failure */ cups_get_printer_uri( http_t *http, /* I - HTTP connection */ const char *name, /* I - Name of printer or class */ char *host, /* I - Hostname buffer */ int hostsize, /* I - Size of hostname buffer */ int *port, /* O - Port number */ char *resource, /* I - Resource buffer */ int resourcesize, /* I - Size of resource buffer */ int depth) /* I - Depth of query */ { int i; /* Looping var */ int http_port; /* Port number */ http_t *http2; /* Alternate HTTP connection */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* Current attribute */ char uri[HTTP_MAX_URI], /* printer-uri attribute */ scheme[HTTP_MAX_URI], /* Scheme name */ username[HTTP_MAX_URI], /* Username:password */ classname[255], /* Temporary class name */ http_hostname[HTTP_MAX_HOST]; /* Hostname associated with connection */ static const char * const requested_attrs[] = { /* Requested attributes */ "printer-uri-supported", "printer-type", "member-uris" }; DEBUG_printf(("cups_get_printer_uri(http=%p, name=\"%s\", host=%p, " "hostsize=%d, resource=%p, resourcesize=%d, depth=%d)\n", http, name ? name : "(null)", host, hostsize, resource, resourcesize, depth)); /* * Setup the printer URI... */ if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) { _cupsSetError(IPP_INTERNAL_ERROR, "Unable to create printer-uri!"); *host = '\0'; *resource = '\0'; return (0); } DEBUG_printf(("cups_get_printer_uri: printer-uri=\"%s\"\n", uri)); /* * Get the hostname and port number we are connected to... */ httpGetHostname(http, http_hostname, sizeof(http_hostname)); #ifdef AF_INET6 if (http->hostaddr->addr.sa_family == AF_INET6) http_port = ntohs(http->hostaddr->ipv6.sin6_port); else #endif /* AF_INET6 */ if (http->hostaddr->addr.sa_family == AF_INET) http_port = ntohs(http->hostaddr->ipv4.sin_port); else http_port = ippPort(); /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requested-attributes */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requested-attributes", sizeof(requested_attrs) / sizeof(requested_attrs[0]), NULL, requested_attrs); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) { /* * Get the first actual printer name in the class... */ for (i = 0; i < attr->num_values; i ++) { httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize); if (!strncmp(resource, "/printers/", 10)) { /* * Found a printer! */ ippDelete(response); return (1); } } /* * No printers in this class - try recursively looking for a printer, * but not more than 3 levels deep... */ if (depth < 3) { for (i = 0; i < attr->num_values; i ++) { httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize); if (!strncmp(resource, "/classes/", 9)) { /* * Found a class! Connect to the right server... */ if (!strcasecmp(http_hostname, host) && *port == http_port) http2 = http; else if ((http2 = httpConnectEncrypt(host, *port, cupsEncryption())) == NULL) { DEBUG_puts("Unable to connect to server!"); continue; } /* * Look up printers on that server... */ strlcpy(classname, resource + 9, sizeof(classname)); cups_get_printer_uri(http2, classname, host, hostsize, port, resource, resourcesize, depth + 1); /* * Close the connection as needed... */ if (http2 != http) httpClose(http2); if (*host) return (1); } } } } else if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL) { httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize); ippDelete(response); if (!strncmp(resource, "/classes/", 9)) { _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found for class!")); *host = '\0'; *resource = '\0'; return (0); } return (1); } ippDelete(response); } if (cupsLastError() != IPP_NOT_FOUND) _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found!")); *host = '\0'; *resource = '\0'; return (0); }
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); }
int /* O - 1 on success, 0 on failure */ cupsCancelJob(const char *name, /* I - Name of printer or class */ int job) /* I - Job ID */ { char printer[HTTP_MAX_URI], /* Printer name */ hostname[HTTP_MAX_URI], /* Hostname */ uri[HTTP_MAX_URI]; /* Printer URI */ ipp_t *request, /* IPP request */ *response; /* IPP response */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ /* * See if we can connect to the server... */ if (!cups_connect(name, printer, hostname)) { DEBUG_puts("Unable to connect to server!"); return (0); } /* * Create a printer URI... */ if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", printer) != HTTP_URI_OK) { _cupsSetError(IPP_INTERNAL_ERROR, NULL); return (0); } /* * Build an IPP_CANCEL_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * job-id * [requesting-user-name] */ request = ippNewRequest(IPP_CANCEL_JOB); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", job); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); /* * Do the request... */ if ((response = cupsDoRequest(cg->http, request, "/jobs/")) != NULL) ippDelete(response); return (cg->last_error < IPP_REDIRECTION_OTHER_SITE); }
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()); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { const char *name; /* Backend name */ cups_array_t *devices; /* Device array */ cups_device_t *device; /* Current device */ char uriName[1024]; /* Unquoted fullName for URI */ #ifdef HAVE_DNSSD int fd; /* Main file descriptor */ fd_set input; /* Input set for select() */ struct timeval timeout; /* Timeout for select() */ DNSServiceRef main_ref, /* Main service reference */ fax_ipp_ref, /* IPP fax service reference */ ipp_ref, /* IPP service reference */ ipp_tls_ref, /* IPP w/TLS service reference */ ipps_ref, /* IPP service reference */ local_fax_ipp_ref, /* Local IPP fax service reference */ local_ipp_ref, /* Local IPP service reference */ local_ipp_tls_ref, /* Local IPP w/TLS service reference */ local_ipps_ref, /* Local IPP service reference */ local_printer_ref, /* Local LPD service reference */ pdl_datastream_ref, /* AppSocket service reference */ printer_ref, /* LPD service reference */ riousbprint_ref; /* Remote IO service reference */ #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI AvahiClient *client; /* Client information */ int error; /* Error code, if any */ #endif /* HAVE_AVAHI */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ /* * Don't buffer stderr, and catch SIGTERM... */ setbuf(stderr, NULL); #ifdef HAVE_SIGSET /* Use System V signals over POSIX to avoid bugs */ sigset(SIGTERM, sigterm_handler); #elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); sigemptyset(&action.sa_mask); action.sa_handler = sigterm_handler; sigaction(SIGTERM, &action, NULL); #else signal(SIGTERM, sigterm_handler); #endif /* HAVE_SIGSET */ /* * Check command-line... */ if (argc >= 6) exec_backend(argv); else if (argc != 1) { _cupsLangPrintf(stderr, _("Usage: %s job-id user title copies options [file]"), argv[0]); return (1); } /* * Only do discovery when run as "dnssd"... */ if ((name = strrchr(argv[0], '/')) != NULL) name ++; else name = argv[0]; if (strcmp(name, "dnssd")) return (0); /* * Create an array to track devices... */ devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); /* * Browse for different kinds of printers... */ #ifdef HAVE_DNSSD if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) { perror("ERROR: Unable to create service connection"); return (1); } fd = DNSServiceRefSockFD(main_ref); fax_ipp_ref = main_ref; DNSServiceBrowse(&fax_ipp_ref, kDNSServiceFlagsShareConnection, 0, "_fax-ipp._tcp", NULL, browse_callback, devices); ipp_ref = main_ref; DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, browse_callback, devices); ipp_tls_ref = main_ref; DNSServiceBrowse(&ipp_tls_ref, kDNSServiceFlagsShareConnection, 0, "_ipp-tls._tcp", NULL, browse_callback, devices); ipps_ref = main_ref; DNSServiceBrowse(&ipps_ref, kDNSServiceFlagsShareConnection, 0, "_ipps._tcp", NULL, browse_callback, devices); local_fax_ipp_ref = main_ref; DNSServiceBrowse(&local_fax_ipp_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_fax-ipp._tcp", NULL, browse_local_callback, devices); local_ipp_ref = main_ref; DNSServiceBrowse(&local_ipp_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipp._tcp", NULL, browse_local_callback, devices); local_ipp_tls_ref = main_ref; DNSServiceBrowse(&local_ipp_tls_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipp-tls._tcp", NULL, browse_local_callback, devices); local_ipps_ref = main_ref; DNSServiceBrowse(&local_ipps_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_ipps._tcp", NULL, browse_local_callback, devices); local_printer_ref = main_ref; DNSServiceBrowse(&local_printer_ref, kDNSServiceFlagsShareConnection, kDNSServiceInterfaceIndexLocalOnly, "_printer._tcp", NULL, browse_local_callback, devices); pdl_datastream_ref = main_ref; DNSServiceBrowse(&pdl_datastream_ref, kDNSServiceFlagsShareConnection, 0, "_pdl-datastream._tcp", NULL, browse_callback, devices); printer_ref = main_ref; DNSServiceBrowse(&printer_ref, kDNSServiceFlagsShareConnection, 0, "_printer._tcp", NULL, browse_callback, devices); riousbprint_ref = main_ref; DNSServiceBrowse(&riousbprint_ref, kDNSServiceFlagsShareConnection, 0, "_riousbprint._tcp", NULL, browse_callback, devices); #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI if ((simple_poll = avahi_simple_poll_new()) == NULL) { fputs("DEBUG: Unable to create Avahi simple poll object.\n", stderr); return (0); } avahi_simple_poll_set_func(simple_poll, poll_callback, NULL); client = avahi_client_new(avahi_simple_poll_get(simple_poll), 0, client_callback, simple_poll, &error); if (!client) { fputs("DEBUG: Unable to create Avahi client.\n", stderr); return (0); } browsers = 6; avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_fax-ipp._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipp-tls._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_ipps._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_pdl-datastream._tcp", NULL, 0, browse_callback, devices); avahi_service_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, "_printer._tcp", NULL, 0, browse_callback, devices); #endif /* HAVE_AVAHI */ /* * Loop until we are killed... */ while (!job_canceled) { int announce = 0; /* Announce printers? */ #ifdef HAVE_DNSSD FD_ZERO(&input); FD_SET(fd, &input); timeout.tv_sec = 0; timeout.tv_usec = 500000; if (select(fd + 1, &input, NULL, NULL, &timeout) < 0) continue; if (FD_ISSET(fd, &input)) { /* * Process results of our browsing... */ DNSServiceProcessResult(main_ref); } else announce = 1; #elif defined(HAVE_AVAHI) got_data = 0; if ((error = avahi_simple_poll_iterate(simple_poll, 500)) > 0) { /* * We've been told to exit the loop. Perhaps the connection to * Avahi failed. */ break; } if (!got_data) announce = 1; #endif /* HAVE_DNSSD */ /* fprintf(stderr, "DEBUG: announce=%d\n", announce);*/ if (announce) { /* * Announce any devices we've found... */ #ifdef HAVE_DNSSD DNSServiceErrorType status; /* DNS query status */ #endif /* HAVE_DNSSD */ cups_device_t *best; /* Best matching device */ char device_uri[1024]; /* Device URI */ int count; /* Number of queries */ int sent; /* Number of sent */ for (device = (cups_device_t *)cupsArrayFirst(devices), best = NULL, count = 0, sent = 0; device; device = (cups_device_t *)cupsArrayNext(devices)) { if (device->sent) sent ++; if (device->ref) count ++; if (!device->ref && !device->sent) { /* * Found the device, now get the TXT record(s) for it... */ if (count < 50) { fprintf(stderr, "DEBUG: Querying \"%s\"...\n", device->fullName); #ifdef HAVE_DNSSD device->ref = main_ref; status = DNSServiceQueryRecord(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->fullName, kDNSServiceType_TXT, kDNSServiceClass_IN, query_callback, device); if (status != kDNSServiceErr_NoError) fprintf(stderr, "ERROR: Unable to query \"%s\" for TXT records: %d\n", device->fullName, status); /* Users never see this */ else count ++; #else if ((device->ref = avahi_record_browser_new(client, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, device->fullName, AVAHI_DNS_CLASS_IN, AVAHI_DNS_TYPE_TXT, 0, query_callback, device)) == NULL) fprintf(stderr, "ERROR: Unable to query \"%s\" for TXT records: %s\n", device->fullName, avahi_strerror(avahi_client_errno(client))); /* Users never see this */ else count ++; #endif /* HAVE_AVAHI */ } } else if (!device->sent) { #ifdef HAVE_DNSSD /* * Got the TXT records, now report the device... */ DNSServiceRefDeallocate(device->ref); #else avahi_record_browser_free(device->ref); #endif /* HAVE_DNSSD */ device->ref = NULL; if (!best) best = device; else if (_cups_strcasecmp(best->name, device->name) || _cups_strcasecmp(best->domain, device->domain)) { unquote(uriName, best->fullName, sizeof(uriName)); if (best->uuid) httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s", best->uuid); else httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups" : "/"); cupsBackendReport("network", device_uri, best->make_and_model, best->name, best->device_id, NULL); best->sent = 1; best = device; sent ++; } else if (best->priority > device->priority || (best->priority == device->priority && best->type < device->type)) { best->sent = 1; best = device; sent ++; } else { device->sent = 1; sent ++; } } } if (best) { unquote(uriName, best->fullName, sizeof(uriName)); if (best->uuid) httpAssembleURIf(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups?uuid=%s" : "/?uuid=%s", best->uuid); else httpAssembleURI(HTTP_URI_CODING_ALL, device_uri, sizeof(device_uri), "dnssd", NULL, uriName, 0, best->cups_shared ? "/cups" : "/"); cupsBackendReport("network", device_uri, best->make_and_model, best->name, best->device_id, NULL); best->sent = 1; sent ++; } fprintf(stderr, "DEBUG: sent=%d, count=%d\n", sent, count); #ifdef HAVE_AVAHI if (sent == cupsArrayCount(devices) && browsers == 0) #else if (sent == cupsArrayCount(devices)) #endif /* HAVE_AVAHI */ break; } } return (CUPS_BACKEND_OK); }
static int /* O - 0 on success, 1 on error */ move_job(http_t *http, /* I - HTTP connection to server */ const char *src, /* I - Source queue */ int jobid, /* I - Job ID */ const char *dest) /* I - Destination queue */ { ipp_t *request; /* IPP Request */ char job_uri[HTTP_MAX_URI], /* job-uri */ printer_uri[HTTP_MAX_URI]; /* job-printer-uri */ if (!http) return (1); /* * Build a CUPS_MOVE_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * job-uri/printer-uri * job-printer-uri * requesting-user-name */ request = ippNewRequest(CUPS_MOVE_JOB); if (jobid) { snprintf(job_uri, sizeof(job_uri), "ipp://localhost/jobs/%d", jobid); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, job_uri); } else { httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL, "localhost", 0, "/printers/%s", src); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, job_uri); } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser()); httpAssembleURIf(HTTP_URI_CODING_ALL, printer_uri, sizeof(printer_uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_JOB, IPP_TAG_URI, "job-printer-uri", NULL, printer_uri); /* * Do the request and get back a response... */ ippDelete(cupsDoRequest(http, request, "/jobs")); if (cupsLastError() > IPP_OK_CONFLICT) { _cupsLangPrintf(stderr, "lpmove: %s", cupsLastErrorString()); return (1); } else return (0); }