char * /* O - Buffer */ _cupsStrDate(char *buf, /* I - Buffer */ size_t bufsize, /* I - Size of buffer */ time_t timeval) /* I - Time value */ { struct tm *dateval; /* Local date/time */ char temp[1024]; /* Temporary buffer */ _cups_globals_t *cg = _cupsGlobals(); /* Per-thread globals */ if (!cg->lang_default) cg->lang_default = cupsLangDefault(); dateval = localtime(&timeval); if (cg->lang_default->encoding != CUPS_UTF8) { strftime(temp, sizeof(temp), "%c", dateval); cupsCharsetToUTF8((cups_utf8_t *)buf, temp, (int)bufsize, cg->lang_default->encoding); } else strftime(buf, bufsize, "%c", dateval); return (buf); }
const char * cups_get_language (void) { cups_lang_t *language; language = cupsLangDefault(); /* needed for conversion */ return cupsLangEncoding(language); }
int /* O - 0 on success, non-zero on error */ export_dest(http_t *http, /* I - Connection to server */ const char *dest) /* I - Destination to export */ { int status; /* Status of export */ char ppdfile[1024], /* PPD file for printer drivers */ prompt[1024]; /* Password prompt */ int tries; /* Number of tries */ /* * Get the Windows PPD file for the printer... */ if (!cupsAdminCreateWindowsPPD(http, dest, ppdfile, sizeof(ppdfile))) { _cupsLangPrintf(stderr, _("cupsaddsmb: No PPD file for printer \"%s\" - %s"), dest, cupsLastErrorString()); return (1); } /* * Try to export it... */ for (status = 0, tries = 0; !status && tries < 3; tries ++) { /* * Get the password, as needed... */ if (!SAMBAPassword) { snprintf(prompt, sizeof(prompt), _cupsLangString(cupsLangDefault(), _("Password for %s required to access %s via " "SAMBA: ")), SAMBAUser, SAMBAServer); if ((SAMBAPassword = cupsGetPassword(prompt)) == NULL) break; } status = cupsAdminExportSamba(dest, ppdfile, SAMBAServer, SAMBAUser, SAMBAPassword, Verbosity ? stderr : NULL); if (!status && cupsLastError() == IPP_NOT_FOUND) break; } unlink(ppdfile); return (!status); }
int /* O - Number of bytes written */ _cupsLangPrintFilter( FILE *fp, /* I - File to write to */ const char *prefix, /* I - Non-localized message prefix */ const char *message, /* I - Message string to use */ ...) /* I - Additional arguments as needed */ { ssize_t bytes; /* Number of bytes formatted */ char temp[2048], /* Temporary format buffer */ buffer[2048], /* Message buffer */ output[8192]; /* Output buffer */ va_list ap; /* Pointer to additional arguments */ _cups_globals_t *cg; /* Global data */ /* * Range check... */ if (!fp || !message) return (-1); cg = _cupsGlobals(); if (!cg->lang_default) cg->lang_default = cupsLangDefault(); /* * Format the string... */ va_start(ap, message); snprintf(temp, sizeof(temp), "%s: %s\n", prefix, _cupsLangString(cg->lang_default, message)); vsnprintf(buffer, sizeof(buffer), temp, ap); va_end(ap); /* * Transcode to the destination charset... */ bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), cg->lang_default->encoding); /* * Write the string and return the number of bytes written... */ if (bytes > 0) return ((int)fwrite(output, 1, (size_t)bytes, fp)); else return ((int)bytes); }
////////////////////////////////////////////////////////////// // // CS : PRIVATE cups_lang_t * bjcupsLangDefault() // IN : none // OUT : LC_ALL(locale) // RETURN : pointer to cupa_lang_t structure // // This routine written for cups-1.1.19 Turbolinux10(Suzuka) // Replace to cupsLangDefault() // PRIVATE cups_lang_t * bjcupsLangDefault( ) { cups_lang_t *pLanguage; char *tLang; if( (tLang = getenv("LC_ALL"))==NULL) tLang = getenv("LANG"); pLanguage = cupsLangDefault(); setlocale(LC_ALL,tLang); return pLanguage; }
static cups_lang_t * /* O - Current language */ ppd_ll_CC(char *ll_CC, /* O - Country-specific locale name */ size_t ll_CC_size) /* I - Size of country-specific name */ { cups_lang_t *lang; /* Current language */ /* * Get the current locale... */ if ((lang = cupsLangDefault()) == NULL) { strlcpy(ll_CC, "en_US", ll_CC_size); return (NULL); } /* * Copy the locale name... */ strlcpy(ll_CC, lang->language, ll_CC_size); if (strlen(ll_CC) == 2) { /* * Map "ll" to primary/origin country locales to have the best * chance of finding a match... */ if (!strcmp(ll_CC, "cs")) strlcpy(ll_CC, "cs_CZ", ll_CC_size); else if (!strcmp(ll_CC, "en")) strlcpy(ll_CC, "en_US", ll_CC_size); else if (!strcmp(ll_CC, "ja")) strlcpy(ll_CC, "ja_JP", ll_CC_size); else if (!strcmp(ll_CC, "sv")) strlcpy(ll_CC, "sv_SE", ll_CC_size); else if (!strcmp(ll_CC, "zh")) /* Simplified Chinese */ strlcpy(ll_CC, "zh_CN", ll_CC_size); } DEBUG_printf(("8ppd_ll_CC: lang->language=\"%s\", ll_CC=\"%s\"...", lang->language, ll_CC)); return (lang); }
void _cupsSetError(ipp_status_t status, /* I - IPP status code */ const char *message, /* I - status-message value */ int localize) /* I - Localize the message? */ { _cups_globals_t *cg; /* Global data */ if (!message && errno) { message = strerror(errno); localize = 0; } cg = _cupsGlobals(); cg->last_error = status; if (cg->last_status_message) { _cupsStrFree(cg->last_status_message); cg->last_status_message = NULL; } if (message) { if (localize) { /* * Get the message catalog... */ if (!cg->lang_default) cg->lang_default = cupsLangDefault(); cg->last_status_message = _cupsStrAlloc(_cupsLangString(cg->lang_default, message)); } else cg->last_status_message = _cupsStrAlloc(message); } DEBUG_printf(("4_cupsSetError: last_error=%s, last_status_message=\"%s\"", ippErrorString(cg->last_error), cg->last_status_message)); }
int /* O - Number of bytes written */ _cupsLangPuts(FILE *fp, /* I - File to write to */ const char *message) /* I - Message string to use */ { int bytes; /* Number of bytes formatted */ char output[8192]; /* Message buffer */ _cups_globals_t *cg; /* Global data */ /* * Range check... */ if (!fp || !message) return (-1); cg = _cupsGlobals(); if (!cg->lang_default) cg->lang_default = cupsLangDefault(); /* * Transcode to the destination charset... */ bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)_cupsLangString(cg->lang_default, message), sizeof(output) - 4, cg->lang_default->encoding); bytes += cupsUTF8ToCharset(output + bytes, (cups_utf8_t *)"\n", sizeof(output) - bytes, cg->lang_default->encoding); /* * Write the string and return the number of bytes written... */ if (bytes > 0) return ((int)fwrite(output, 1, bytes, fp)); else return (bytes); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ char *opt; /* Option pointer */ const char *username; /* Pointer to username */ const char *groupname; /* Pointer to group name */ int op; /* Operation (add, change, delete) */ const char *passwd; /* Password string */ FILE *infile, /* Input file */ *outfile; /* Output file */ char line[256], /* Line from file */ userline[17], /* User from line */ groupline[17], /* Group from line */ md5line[33], /* MD5-sum from line */ md5new[33]; /* New MD5 sum */ char passwdmd5[1024], /* passwd.md5 file */ passwdold[1024], /* passwd.old file */ passwdnew[1024]; /* passwd.tmp file */ char *newpass, /* new password */ *oldpass; /* old password */ int flag; /* Password check flags... */ int fd; /* Password file descriptor */ int error; /* Write error */ _cups_globals_t *cg = _cupsGlobals(); /* Global data */ cups_lang_t *lang; /* Language info */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Signal action */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET*/ _cupsSetLocale(argv); lang = cupsLangDefault(); /* * Check to see if stdin, stdout, and stderr are still open... */ if (fcntl(0, F_GETFD, &i) || fcntl(1, F_GETFD, &i) || fcntl(2, F_GETFD, &i)) { /* * No, return exit status 2 and don't try to send any output since * someone is trying to bypass the security on the server. */ return (2); } /* * Find the server directory... */ snprintf(passwdmd5, sizeof(passwdmd5), "%s/passwd.md5", cg->cups_serverroot); snprintf(passwdold, sizeof(passwdold), "%s/passwd.old", cg->cups_serverroot); snprintf(passwdnew, sizeof(passwdnew), "%s/passwd.new", cg->cups_serverroot); /* * Find the default system group... */ if (getgrnam(CUPS_DEFAULT_GROUP)) groupname = CUPS_DEFAULT_GROUP; else groupname = "unknown"; endgrent(); username = NULL; op = CHANGE; /* * Parse command-line options... */ for (i = 1; i < argc; i ++) if (argv[i][0] == '-') for (opt = argv[i] + 1; *opt; opt ++) switch (*opt) { case 'a' : /* Add */ op = ADD; break; case 'x' : /* Delete */ op = DELETE; break; case 'g' : /* Group */ i ++; if (i >= argc) usage(stderr); groupname = argv[i]; break; case 'h' : /* Help */ usage(stdout); break; default : /* Bad option */ usage(stderr); break; } else if (!username) username = argv[i]; else usage(stderr); /* * See if we are trying to add or delete a password when we aren't logged in * as root... */ if (getuid() && getuid() != geteuid() && (op != CHANGE || username)) { _cupsLangPuts(stderr, _("lppasswd: Only root can add or delete passwords!\n")); return (1); } /* * Fill in missing info... */ if (!username) username = cupsUser(); oldpass = newpass = NULL; /* * Obtain old and new password _before_ locking the database * to keep users from locking the file indefinitely. */ if (op == CHANGE && getuid()) { if ((passwd = cupsGetPassword(_("Enter old password:"******"lppasswd: Unable to copy password string: %s\n"), strerror(errno)); return (1); } } /* * Now get the new password, if necessary... */ if (op != DELETE) { if ((passwd = cupsGetPassword( _cupsLangString(lang, _("Enter password:"******"lppasswd: Unable to copy password string: %s\n"), strerror(errno)); return (1); } if ((passwd = cupsGetPassword( _cupsLangString(lang, _("Enter password again:")))) == NULL) return (1); if (strcmp(passwd, newpass) != 0) { _cupsLangPuts(stderr, _("lppasswd: Sorry, passwords don't match!\n")); return (1); } /* * Check that the password contains at least one letter and number. */ flag = 0; for (passwd = newpass; *passwd; passwd ++) if (isdigit(*passwd & 255)) flag |= 1; else if (isalpha(*passwd & 255)) flag |= 2; /* * Only allow passwords that are at least 6 chars, have a letter and * a number, and don't contain the username. */ if (strlen(newpass) < 6 || strstr(newpass, username) != NULL || flag != 3) { _cupsLangPuts(stderr, _("lppasswd: Sorry, password rejected.\n" "Your password must be at least 6 characters long, " "cannot contain\n" "your username, and must contain at least one letter " "and number.\n")); return (1); } } /* * Ignore SIGHUP, SIGINT, SIGTERM, and SIGXFSZ (if defined) for the * remainder of the time so that we won't end up with bogus password * files... */ #ifndef WIN32 # if defined(HAVE_SIGSET) sigset(SIGHUP, SIG_IGN); sigset(SIGINT, SIG_IGN); sigset(SIGTERM, SIG_IGN); # ifdef SIGXFSZ sigset(SIGXFSZ, SIG_IGN); # endif /* SIGXFSZ */ # elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); action.sa_handler = SIG_IGN; sigaction(SIGHUP, &action, NULL); sigaction(SIGINT, &action, NULL); sigaction(SIGTERM, &action, NULL); # ifdef SIGXFSZ sigaction(SIGXFSZ, &action, NULL); # endif /* SIGXFSZ */ # else signal(SIGHUP, SIG_IGN); signal(SIGINT, SIG_IGN); signal(SIGTERM, SIG_IGN); # ifdef SIGXFSZ signal(SIGXFSZ, SIG_IGN); # endif /* SIGXFSZ */ # endif #endif /* !WIN32 */ /* * Open the output file. */ if ((fd = open(passwdnew, O_WRONLY | O_CREAT | O_EXCL, 0400)) < 0) { if (errno == EEXIST) _cupsLangPuts(stderr, _("lppasswd: Password file busy!\n")); else _cupsLangPrintf(stderr, _("lppasswd: Unable to open password file: %s\n"), strerror(errno)); return (1); } if ((outfile = fdopen(fd, "w")) == NULL) { _cupsLangPrintf(stderr, _("lppasswd: Unable to open password file: %s\n"), strerror(errno)); unlink(passwdnew); return (1); } setbuf(outfile, NULL); /* * Open the existing password file and create a new one... */ infile = fopen(passwdmd5, "r"); if (infile == NULL && errno != ENOENT && op != ADD) { _cupsLangPrintf(stderr, _("lppasswd: Unable to open password file: %s\n"), strerror(errno)); fclose(outfile); unlink(passwdnew); return (1); } /* * Read lines from the password file; the format is: * * username:group:MD5-sum */ error = 0; userline[0] = '\0'; groupline[0] = '\0'; md5line[0] = '\0'; if (infile) { while (fgets(line, sizeof(line), infile) != NULL) { if (sscanf(line, "%16[^:]:%16[^:]:%32s", userline, groupline, md5line) != 3) continue; if (strcmp(username, userline) == 0 && strcmp(groupname, groupline) == 0) break; if (fputs(line, outfile) == EOF) { _cupsLangPrintf(stderr, _("lppasswd: Unable to write to password file: %s\n"), strerror(errno)); error = 1; break; } } if (!error) { while (fgets(line, sizeof(line), infile) != NULL) if (fputs(line, outfile) == EOF) { _cupsLangPrintf(stderr, _("lppasswd: Unable to write to password file: %s\n"), strerror(errno)); error = 1; break; } } } if (op == CHANGE && (strcmp(username, userline) || strcmp(groupname, groupline))) { _cupsLangPrintf(stderr, _("lppasswd: user \"%s\" and group \"%s\" do not exist.\n"), username, groupname); error = 1; } else if (op != DELETE) { if (oldpass && strcmp(httpMD5(username, "CUPS", oldpass, md5new), md5line) != 0) { _cupsLangPuts(stderr, _("lppasswd: Sorry, password doesn't match!\n")); error = 1; } else { snprintf(line, sizeof(line), "%s:%s:%s\n", username, groupname, httpMD5(username, "CUPS", newpass, md5new)); if (fputs(line, outfile) == EOF) { _cupsLangPrintf(stderr, _("lppasswd: Unable to write to password file: %s\n"), strerror(errno)); error = 1; } } } /* * Close the files... */ if (infile) fclose(infile); if (fclose(outfile) == EOF) error = 1; /* * Error out gracefully as needed... */ if (error) { _cupsLangPuts(stderr, _("lppasswd: Password file not updated!\n")); unlink(passwdnew); return (1); } /* * Save old passwd file */ unlink(passwdold); if (link(passwdmd5, passwdold) && errno != ENOENT) { _cupsLangPrintf(stderr, _("lppasswd: failed to backup old password file: %s\n"), strerror(errno)); unlink(passwdnew); return (1); } /* * Install new password file */ if (rename(passwdnew, passwdmd5) < 0) { _cupsLangPrintf(stderr, _("lppasswd: failed to rename password file: %s\n"), strerror(errno)); unlink(passwdnew); return (1); } return (0); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments (6 or 7) */ char *argv[]) /* I - Command-line arguments */ { const char *device_uri; /* Device URI */ char scheme[255], /* Scheme in URI */ hostname[1024], /* Hostname */ username[255], /* Username info */ resource[1024], /* Resource info (printer name) */ *options, /* Pointer to options */ *name, /* Name of option */ *value, /* Value of option */ sep, /* Separator character */ *filename, /* File to print */ title[256]; /* Title string */ int port; /* Port number */ char portname[256]; /* Port name (string) */ http_addrlist_t *addrlist; /* List of addresses for printer */ int snmp_enabled = 1; /* Is SNMP enabled? */ int snmp_fd; /* SNMP socket */ int fd; /* Print file */ int status; /* Status of LPD job */ int mode; /* Print mode */ int banner; /* Print banner page? */ int format; /* Print format */ int order; /* Order of control/data files */ int reserve; /* Reserve priviledged port? */ int sanitize_title; /* Sanitize title string? */ int manual_copies, /* Do manual copies? */ timeout, /* Timeout */ contimeout, /* Connection timeout */ copies; /* Number of copies */ ssize_t bytes = 0; /* Initial bytes read */ char buffer[16384]; /* Initial print buffer */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ int num_jobopts; /* Number of job options */ cups_option_t *jobopts = NULL; /* Job options */ /* * Make sure status messages are not buffered... */ setbuf(stderr, NULL); /* * Ignore SIGPIPE and catch SIGTERM signals... */ #ifdef HAVE_SIGSET sigset(SIGPIPE, SIG_IGN); sigset(SIGTERM, sigterm_handler); #elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); sigemptyset(&action.sa_mask); sigaddset(&action.sa_mask, SIGTERM); action.sa_handler = sigterm_handler; sigaction(SIGTERM, &action, NULL); #else signal(SIGPIPE, SIG_IGN); signal(SIGTERM, sigterm_handler); #endif /* HAVE_SIGSET */ /* * Check command-line... */ if (argc == 1) { printf("network lpd \"Unknown\" \"%s\"\n", _cupsLangString(cupsLangDefault(), _("LPD/LPR Host or Printer"))); return (CUPS_BACKEND_OK); } else if (argc < 6 || argc > 7) { _cupsLangPrintf(stderr, _("Usage: %s job-id user title copies options [file]"), argv[0]); return (CUPS_BACKEND_FAILED); } num_jobopts = cupsParseOptions(argv[5], 0, &jobopts); /* * Extract the hostname and printer name from the URI... */ while ((device_uri = cupsBackendDeviceURI(argv)) == NULL) { _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer.")); sleep(10); if (getenv("CLASS") != NULL) return (CUPS_BACKEND_FAILED); } httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, resource, sizeof(resource)); if (!port) port = 515; /* Default to port 515 */ if (!username[0]) { /* * If no username is in the device URI, then use the print job user... */ strlcpy(username, argv[2], sizeof(username)); } /* * See if there are any options... */ mode = MODE_STANDARD; banner = 0; format = 'l'; order = ORDER_CONTROL_DATA; reserve = RESERVE_ANY; manual_copies = 1; timeout = 300; contimeout = 7 * 24 * 60 * 60; #ifdef __APPLE__ /* * We want to pass UTF-8 characters by default, not re-map them (3071945) */ sanitize_title = 0; #else /* * Otherwise we want to re-map UTF-8 to "safe" characters by default... */ sanitize_title = 1; #endif /* __APPLE__ */ if ((options = strchr(resource, '?')) != NULL) { /* * Yup, terminate the device name string and move to the first * character of the options... */ *options++ = '\0'; /* * Parse options... */ while (*options) { /* * Get the name... */ name = options; while (*options && *options != '=' && *options != '+' && *options != '&') options ++; if ((sep = *options) != '\0') *options++ = '\0'; if (sep == '=') { /* * Get the value... */ value = options; while (*options && *options != '+' && *options != '&') options ++; if (*options) *options++ = '\0'; } else value = (char *)""; /* * Process the option... */ if (!_cups_strcasecmp(name, "banner")) { /* * Set the banner... */ banner = !value[0] || !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true"); } else if (!_cups_strcasecmp(name, "format") && value[0]) { /* * Set output format... */ if (strchr("cdfglnoprtv", value[0])) format = value[0]; else _cupsLangPrintFilter(stderr, "ERROR", _("Unknown format character: \"%c\"."), value[0]); } else if (!_cups_strcasecmp(name, "mode") && value[0]) { /* * Set control/data order... */ if (!_cups_strcasecmp(value, "standard")) mode = MODE_STANDARD; else if (!_cups_strcasecmp(value, "stream")) mode = MODE_STREAM; else _cupsLangPrintFilter(stderr, "ERROR", _("Unknown print mode: \"%s\"."), value); } else if (!_cups_strcasecmp(name, "order") && value[0]) { /* * Set control/data order... */ if (!_cups_strcasecmp(value, "control,data")) order = ORDER_CONTROL_DATA; else if (!_cups_strcasecmp(value, "data,control")) order = ORDER_DATA_CONTROL; else _cupsLangPrintFilter(stderr, "ERROR", _("Unknown file order: \"%s\"."), value); } else if (!_cups_strcasecmp(name, "reserve")) { /* * Set port reservation mode... */ if (!value[0] || !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true") || !_cups_strcasecmp(value, "rfc1179")) reserve = RESERVE_RFC1179; else if (!_cups_strcasecmp(value, "any")) reserve = RESERVE_ANY; else reserve = RESERVE_NONE; } else if (!_cups_strcasecmp(name, "manual_copies")) { /* * Set manual copies... */ manual_copies = !value[0] || !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true"); } else if (!_cups_strcasecmp(name, "sanitize_title")) { /* * Set sanitize title... */ sanitize_title = !value[0] || !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true"); } else if (!_cups_strcasecmp(name, "snmp")) { /* * Enable/disable SNMP stuff... */ snmp_enabled = !value[0] || !_cups_strcasecmp(value, "on") || _cups_strcasecmp(value, "yes") || _cups_strcasecmp(value, "true"); } else if (!_cups_strcasecmp(name, "timeout")) { /* * Set the timeout... */ if (atoi(value) > 0) timeout = atoi(value); } else if (!_cups_strcasecmp(name, "contimeout")) { /* * Set the connection timeout... */ if (atoi(value) > 0) contimeout = atoi(value); } } } if (mode == MODE_STREAM) order = ORDER_CONTROL_DATA; /* * Find the printer... */ snprintf(portname, sizeof(portname), "%d", port); fputs("STATE: +connecting-to-device\n", stderr); fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) { _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer \"%s\"."), hostname); sleep(10); if (getenv("CLASS") != NULL) { fputs("STATE: -connecting-to-device\n", stderr); exit(CUPS_BACKEND_FAILED); } } if (snmp_enabled) snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family); else snmp_fd = -1; /* * Wait for data from the filter... */ if (argc == 6) { if (!backendWaitLoop(snmp_fd, &(addrlist->addr), 0, backendNetworkSideCB)) return (CUPS_BACKEND_OK); else if (mode == MODE_STANDARD && (bytes = read(0, buffer, sizeof(buffer))) <= 0) return (CUPS_BACKEND_OK); } /* * If we have 7 arguments, print the file named on the command-line. * Otherwise, copy stdin to a temporary file and print the temporary * file. */ if (argc == 6 && mode == MODE_STANDARD) { /* * Copy stdin to a temporary file... */ if ((fd = cupsTempFd(tmpfilename, sizeof(tmpfilename))) < 0) { perror("DEBUG: Unable to create temporary file"); return (CUPS_BACKEND_FAILED); } _cupsLangPrintFilter(stderr, "INFO", _("Copying print data.")); if (bytes > 0) write(fd, buffer, bytes); backendRunLoop(-1, fd, snmp_fd, &(addrlist->addr), 0, 0, backendNetworkSideCB); } else if (argc == 6) { /* * Stream from stdin... */ filename = NULL; fd = 0; } else { filename = argv[6]; fd = open(filename, O_RDONLY); if (fd == -1) { _cupsLangPrintError("ERROR", _("Unable to open print file")); return (CUPS_BACKEND_FAILED); } } /* * Sanitize the document title... */ strlcpy(title, argv[3], sizeof(title)); if (sanitize_title) { /* * Sanitize the title string so that we don't cause problems on * the remote end... */ char *ptr; for (ptr = title; *ptr; ptr ++) if (!isalnum(*ptr & 255) && !isspace(*ptr & 255)) *ptr = '_'; } /* * Queue the job... */ if (argc > 6) { if (manual_copies) { manual_copies = atoi(argv[4]); copies = 1; } else { manual_copies = 1; copies = atoi(argv[4]); } status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, username, title, copies, banner, format, order, reserve, manual_copies, timeout, contimeout, cupsGetOption("job-originating-host-name", num_jobopts, jobopts)); if (!status) fprintf(stderr, "PAGE: 1 %d\n", atoi(argv[4])); } else status = lpd_queue(hostname, addrlist, resource + 1, fd, snmp_fd, mode, username, title, 1, banner, format, order, reserve, 1, timeout, contimeout, cupsGetOption("job-originating-host-name", num_jobopts, jobopts)); /* * Remove the temporary file if necessary... */ if (tmpfilename[0]) unlink(tmpfilename); if (fd) close(fd); if (snmp_fd >= 0) _cupsSNMPClose(snmp_fd); /* * Return the queue status... */ return (status); }
static bool cups_cache_reload_async(int fd) { TALLOC_CTX *frame = talloc_stackframe(); struct pcap_cache *tmp_pcap_cache = NULL; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *name, /* printer-name attribute */ *info; /* printer-info attribute */ static const char *requested[] =/* Requested attributes */ { "printer-name", "printer-info" }; bool ret = False; size_t size; DEBUG(5, ("reloading cups printcap cache\n")); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(cups_passwd_cb); /* * Try to connect to the server... */ if ((http = cups_connect(frame)) == NULL) { goto out; } /* * Build a CUPS_GET_PRINTERS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes */ request = ippNew(); request->request.op.operation_id = CUPS_GET_PRINTERS; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requested-attributes", (sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && attr->value_tag == IPP_TAG_NAME) { if (!pull_utf8_talloc(frame, &name, attr->values[0].string.text, &size)) { goto out; } } if (strcmp(attr->name, "printer-info") == 0 && attr->value_tag == IPP_TAG_TEXT) { if (!pull_utf8_talloc(frame, &info, attr->values[0].string.text, &size)) { goto out; } } attr = attr->next; } /* * See if we have everything needed... */ if (name == NULL) break; if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) { goto out; } } ippDelete(response); response = NULL; /* * Build a CUPS_GET_CLASSES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes */ request = ippNew(); request->request.op.operation_id = CUPS_GET_CLASSES; request->request.op.request_id = 1; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requested-attributes", (sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && attr->value_tag == IPP_TAG_NAME) { if (!pull_utf8_talloc(frame, &name, attr->values[0].string.text, &size)) { goto out; } } if (strcmp(attr->name, "printer-info") == 0 && attr->value_tag == IPP_TAG_TEXT) { if (!pull_utf8_talloc(frame, &info, attr->values[0].string.text, &size)) { goto out; } } attr = attr->next; } /* * See if we have everything needed... */ if (name == NULL) break; if (!pcap_cache_add_specific(&tmp_pcap_cache, name, info)) { goto out; } } ret = True; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); /* Send all the entries up the pipe. */ if (tmp_pcap_cache) { pcap_printer_fn_specific(tmp_pcap_cache, send_pcap_info, (void *)&fd); pcap_cache_destroy_specific(&tmp_pcap_cache); } TALLOC_FREE(frame); return ret; }
static int iprint_queue_get(const char *sharename, enum printing_types printing_type, char *lpq_command, print_queue_struct **q, print_status_struct *status) { fstring printername; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr = NULL; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char serviceUri[HTTP_MAX_URI]; /* service-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the uri */ int jobUseUnixTime = 0; /* Whether job times should * be assumed to be Unix time */ int qcount = 0, /* Number of active queue entries */ qalloc = 0; /* Number of queue entries allocated */ print_queue_struct *queue = NULL, /* Queue entries */ *temp; /* Temporary pointer for queue */ const char *user_name, /* job-originating-user-name attribute */ *job_name; /* job-name attribute */ int job_id; /* job-id attribute */ int job_k_octets; /* job-k-octets attribute */ time_t job_time; /* time-at-creation attribute */ time_t printer_up_time = 0; /* printer's uptime */ ipp_jstate_t job_status; /* job-status attribute */ int job_priority; /* job-priority attribute */ static const char *jattrs[] = /* Requested job attributes */ { "job-id", "job-k-octets", "job-name", "job-originating-user-name", "job-priority", "job-state", "time-at-creation", }; static const char *pattrs[] = /* Requested printer attributes */ { "printer-state", "printer-state-message", "printer-current-time", "printer-up-time" }; *q = NULL; /* HACK ALERT!!! The porblem with support the 'printer name' option is that we key the tdb off the sharename. So we will overload the lpq_command string to pass in the printername (which is basically what we do for non-cups printers ... using the lpq_command to get the queue listing). */ fstrcpy( printername, lpq_command ); DEBUG(5,("iprint_queue_get(%s, %p, %p)\n", printername, q, status)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Generate the printer URI and the service URI that goes with it... */ slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), printername); slprintf(serviceUri, sizeof(serviceUri) - 1, "ipp://%s/ipp/", iprint_server()); /* * For Linux iPrint servers from OES SP1 on, the iPrint server * uses Unix time for job start times unless it detects the iPrint * client in an http User-Agent header. (This was done to accomodate * CUPS broken behavior. According to RFC 2911, section 4.3.14, job * start times are supposed to be relative to how long the printer has * been up.) Since libcups doesn't allow us to set that header before * the request is sent, this ugly hack allows us to detect the server * version and decide how to interpret the job time. */ if (iprint_get_server_version(http, serviceUri) >= NOVELL_SERVER_VERSION_OES_SP1) jobUseUnixTime = 1; request = ippNew(); ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES); ippSetRequestId(request, 2); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(cupsLastError()))); *q = queue; goto out; } if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get printer status for %s - %s\n", printername, ippErrorString(ippGetStatusCode(response)))); *q = queue; goto out; } /* * Get the current printer status and convert it to the SAMBA values. */ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL) { if (ippGetInteger(attr, 0) == IPP_PRINTER_STOPPED) status->status = LPSTAT_STOPPED; else status->status = LPSTAT_OK; } if ((attr = ippFindAttribute(response, "printer-state-message", IPP_TAG_TEXT)) != NULL) fstrcpy(status->message, ippGetString(attr, 0, NULL)); if ((attr = ippFindAttribute(response, "printer-up-time", IPP_TAG_INTEGER)) != NULL) printer_up_time = ippGetInteger(attr, 0); ippDelete(response); response = NULL; /* * Build an IPP_GET_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * requested-attributes * printer-uri */ request = ippNew(); ippSetOperation(request, IPP_GET_JOBS); ippSetRequestId(request, 3); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(jattrs) / sizeof(jattrs[0])), NULL, jattrs); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", printername); if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(cupsLastError()))); goto out; } if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to get jobs for %s - %s\n", uri, ippErrorString(ippGetStatusCode(response)))); goto out; } /* * Process the jobs... */ qcount = 0; qalloc = 0; queue = NULL; for (attr = ippFirstAttribute(response); attr != NULL; attr = ippNextAttribute(response)) { /* * Skip leading attributes until we hit a job... */ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_JOB) attr = ippNextAttribute(response); if (attr == NULL) break; /* * Allocate memory as needed... */ if (qcount >= qalloc) { qalloc += 16; queue = SMB_REALLOC_ARRAY(queue, print_queue_struct, qalloc); if (queue == NULL) { DEBUG(0,("iprint_queue_get: Not enough memory!")); qcount = 0; goto out; } } temp = queue + qcount; memset(temp, 0, sizeof(print_queue_struct)); /* * Pull the needed attributes from this job... */ job_id = 0; job_priority = 50; job_status = IPP_JOB_PENDING; job_time = 0; job_k_octets = 0; user_name = NULL; job_name = NULL; while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) { if (ippGetName(attr) == NULL) { attr = ippNextAttribute(response); break; } if (strcmp(ippGetName(attr), "job-id") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) job_id = ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "job-k-octets") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) job_k_octets = ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "job-priority") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) job_priority = ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "job-state") == 0 && ippGetValueTag(attr) == IPP_TAG_ENUM) job_status = (ipp_jstate_t)ippGetInteger(attr, 0); if (strcmp(ippGetName(attr), "time-at-creation") == 0 && ippGetValueTag(attr) == IPP_TAG_INTEGER) { /* * If jobs times are in Unix time, the accuracy of the job * start time depends upon the iPrint server's time being * set correctly. Otherwise, the accuracy depends upon * the Samba server's time being set correctly */ if (jobUseUnixTime) job_time = ippGetInteger(attr, 0); else job_time = time(NULL) - printer_up_time + ippGetInteger(attr, 0); } if (strcmp(ippGetName(attr), "job-name") == 0 && (ippGetValueTag(attr) == IPP_TAG_NAMELANG || ippGetValueTag(attr) == IPP_TAG_NAME)) job_name = ippGetString(attr, 0, NULL); if (strcmp(ippGetName(attr), "job-originating-user-name") == 0 && (ippGetValueTag(attr) == IPP_TAG_NAMELANG || ippGetValueTag(attr) == IPP_TAG_NAME)) user_name = ippGetString(attr, 0, NULL); attr = ippNextAttribute(response); } /* * See if we have everything needed... */ if (user_name == NULL || job_name == NULL || job_id == 0) { if (attr == NULL) break; else continue; } temp->sysjob = job_id; temp->size = job_k_octets * 1024; temp->status = job_status == IPP_JOB_PENDING ? LPQ_QUEUED : job_status == IPP_JOB_STOPPED ? LPQ_PAUSED : job_status == IPP_JOB_HELD ? LPQ_PAUSED : LPQ_PRINTING; temp->priority = job_priority; temp->time = job_time; strncpy(temp->fs_user, user_name, sizeof(temp->fs_user) - 1); strncpy(temp->fs_file, job_name, sizeof(temp->fs_file) - 1); qcount ++; if (attr == NULL) break; } /* * Return the job queue... */ *q = queue; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return qcount; }
bool CupsdConf::loadAvailableResources() { KConfig conf("kdeprintrc"); conf.setGroup("CUPS"); QString host = conf.readEntry("Host", cupsServer()); int port = conf.readNumEntry("Port", ippPort()); http_t *http_ = httpConnect(host.local8Bit(), port); resources_.clear(); // standard resources resources_.append(new CupsResource("/")); resources_.append(new CupsResource("/admin")); resources_.append(new CupsResource("/printers")); resources_.append(new CupsResource("/classes")); resources_.append(new CupsResource("/jobs")); if(!http_) return false; // printer resources ipp_t *request_ = ippNew(); cups_lang_t *lang = cupsLangDefault(); ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(lang)); ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, lang->language); request_->request.op.operation_id = CUPS_GET_PRINTERS; request_ = cupsDoRequest(http_, request_, "/printers/"); if(request_) { QString name; int type(0); ipp_attribute_t *attr = request_->attrs; while(attr) { // check new printer (keep only local non-implicit printers) if(!attr->name) { if(!(type & CUPS_PRINTER_REMOTE) && !(type & CUPS_PRINTER_IMPLICIT) && !name.isEmpty()) resources_.append(new CupsResource("/printers/" + name)); name = ""; type = 0; } else if(strcmp(attr->name, "printer-name") == 0) name = attr->values[0].string.text; else if(strcmp(attr->name, "printer-type") == 0) type = attr->values[0].integer; attr = attr->next; } if(!(type & CUPS_PRINTER_REMOTE) && !(type & CUPS_PRINTER_IMPLICIT) && !name.isEmpty()) resources_.append(new CupsResource("/printers/" + name)); ippDelete(request_); } // class resources request_ = ippNew(); ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(lang)); ippAddString(request_, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, lang->language); request_->request.op.operation_id = CUPS_GET_CLASSES; request_ = cupsDoRequest(http_, request_, "/classes/"); if(request_) { QString name; int type(0); ipp_attribute_t *attr = request_->attrs; while(attr) { // check new class (keep only local classes) if(!attr->name) { if(!(type & CUPS_PRINTER_REMOTE) && !name.isEmpty()) resources_.append(new CupsResource("/classes/" + name)); name = ""; type = 0; } else if(strcmp(attr->name, "printer-name") == 0) name = attr->values[0].string.text; else if(strcmp(attr->name, "printer-type") == 0) type = attr->values[0].integer; attr = attr->next; } if(!(type & CUPS_PRINTER_REMOTE) && !name.isEmpty()) resources_.append(new CupsResource("/classes/" + name)); ippDelete(request_); } httpClose(http_); return true; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ int errors = 0; /* Number of errors */ cups_lang_t *language; /* Message catalog */ cups_lang_t *language2; /* Message catalog */ struct lconv *loc; /* Locale data */ char buffer[1024]; /* String buffer */ double number; /* Number */ static const char * const tests[] = /* Test strings */ { "1", "-1", "3", "5.125" }; _cupsSetLocale(argv); if (argc == 1) { language = cupsLangDefault(); language2 = cupsLangDefault(); } else { language = cupsLangGet(argv[1]); language2 = cupsLangGet(argv[1]); } if (language != language2) { errors ++; puts("**** ERROR: Language cache did not work! ****"); puts("First result from cupsLangGet:"); } printf("Language = \"%s\"\n", language->language); printf("Encoding = \"%s\"\n", _cupsEncodingName(language->encoding)); printf("No = \"%s\"\n", _cupsLangString(language, "No")); printf("Yes = \"%s\"\n", _cupsLangString(language, "Yes")); if (language != language2) { puts("Second result from cupsLangGet:"); printf("Language = \"%s\"\n", language2->language); printf("Encoding = \"%s\"\n", _cupsEncodingName(language2->encoding)); printf("No = \"%s\"\n", _cupsLangString(language2, "No")); printf("Yes = \"%s\"\n", _cupsLangString(language2, "Yes")); } loc = localeconv(); for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i ++) { number = _cupsStrScand(tests[i], NULL, loc); printf("_cupsStrScand(\"%s\") number=%f\n", tests[i], number); _cupsStrFormatd(buffer, buffer + sizeof(buffer), number, loc); printf("_cupsStrFormatd(%f) buffer=\"%s\"\n", number, buffer); if (strcmp(buffer, tests[i])) { errors ++; puts("**** ERROR: Bad formatted number! ****"); } } return (errors > 0); }
static int iprint_job_submit(int snum, struct printjob *pjob, enum printing_types printing_type, char *lpq_cmd) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ DEBUG(5,("iprint_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build an IPP_PRINT_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requesting-user-name * [document-data] */ request = ippNew(); ippSetOperation(request, IPP_PRINT_JOB); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), lp_printername(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-originating-host-name", NULL, pjob->clientmachine); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "job-name", NULL, pjob->jobname); /* * Do the request and get back a response... */ slprintf(uri, sizeof(uri) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to print file to %s - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to print file to `%s' - %s\n", lp_printername(snum), ippErrorString(cupsLastError()))); } if ( ret == 0 ) unlink(pjob->filename); /* else print_job_end will do it for us */ if ( ret == 0 ) { attr = ippFindAttribute(response, "job-id", IPP_TAG_INTEGER); if (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_JOB) { pjob->sysjob = ippGetInteger(attr, 0); } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
static int /* O - 0 on success, 1 on error */ exec_filters(mime_type_t *srctype, /* I - Source type */ cups_array_t *filters, /* I - Array of filters to run */ const char *infile, /* I - File to filter */ const char *outfile, /* I - File to create */ const char *ppdfile, /* I - PPD file, if any */ const char *printer, /* I - Printer name */ const char *user, /* I - Username */ const char *title, /* I - Job title */ int num_options, /* I - Number of filter options */ cups_option_t *options) /* I - Filter options */ { int i; /* Looping var */ const char *argv[8], /* Command-line arguments */ *envp[17], /* Environment variables */ *temp; /* Temporary string */ char *optstr, /* Filter options */ content_type[1024], /* CONTENT_TYPE */ cups_datadir[1024], /* CUPS_DATADIR */ cups_fontpath[1024], /* CUPS_FONTPATH */ cups_serverbin[1024], /* CUPS_SERVERBIN */ cups_serverroot[1024], /* CUPS_SERVERROOT */ final_content_type[1024] = "", /* FINAL_CONTENT_TYPE */ lang[1024], /* LANG */ path[1024], /* PATH */ ppd[1024], /* PPD */ printer_info[255], /* PRINTER_INFO env variable */ printer_location[255], /* PRINTER_LOCATION env variable */ printer_name[255], /* PRINTER env variable */ rip_max_cache[1024], /* RIP_MAX_CACHE */ userenv[1024], /* USER */ program[1024]; /* Program to run */ mime_filter_t *filter, /* Current filter */ *next; /* Next filter */ int current, /* Current filter */ filterfds[2][2], /* Pipes for filters */ pid, /* Process ID of filter */ status, /* Exit status */ retval; /* Return value */ cups_array_t *pids; /* Executed filters array */ mime_filter_t key; /* Search key for filters */ cups_lang_t *language; /* Current language */ cups_dest_t *dest; /* Destination information */ /* * Figure out the final content type... */ for (filter = (mime_filter_t *)cupsArrayLast(filters); filter && filter->dst; filter = (mime_filter_t *)cupsArrayPrev(filters)) if (strcmp(filter->dst->super, "printer")) break; if (filter && filter->dst) { const char *ptr; /* Pointer in type name */ if ((ptr = strchr(filter->dst->type, '/')) != NULL) snprintf(final_content_type, sizeof(final_content_type), "FINAL_CONTENT_TYPE=%s", ptr + 1); else snprintf(final_content_type, sizeof(final_content_type), "FINAL_CONTENT_TYPE=%s/%s", filter->dst->super, filter->dst->type); } /* * Remove NULL ("-") filters... */ for (filter = (mime_filter_t *)cupsArrayFirst(filters); filter; filter = (mime_filter_t *)cupsArrayNext(filters)) if (!strcmp(filter->filter, "-")) cupsArrayRemove(filters, filter); /* * Setup the filter environment and command-line... */ optstr = escape_options(num_options, options); snprintf(content_type, sizeof(content_type), "CONTENT_TYPE=%s/%s", srctype->super, srctype->type); snprintf(cups_datadir, sizeof(cups_datadir), "CUPS_DATADIR=%s", DataDir); snprintf(cups_fontpath, sizeof(cups_fontpath), "CUPS_FONTPATH=%s", FontPath); snprintf(cups_serverbin, sizeof(cups_serverbin), "CUPS_SERVERBIN=%s", ServerBin); snprintf(cups_serverroot, sizeof(cups_serverroot), "CUPS_SERVERROOT=%s", ServerRoot); language = cupsLangDefault(); snprintf(lang, sizeof(lang), "LANG=%s.UTF8", language->language); snprintf(path, sizeof(path), "PATH=%s", Path); if (ppdfile) snprintf(ppd, sizeof(ppd), "PPD=%s", ppdfile); else if ((temp = getenv("PPD")) != NULL) snprintf(ppd, sizeof(ppd), "PPD=%s", temp); else #ifdef __APPLE__ if (!access("/System/Library/Frameworks/ApplicationServices.framework/" "Versions/A/Frameworks/PrintCore.framework/Versions/A/" "Resources/English.lproj/Generic.ppd", 0)) strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/" "Versions/A/Frameworks/PrintCore.framework/Versions/A/" "Resources/English.lproj/Generic.ppd", sizeof(ppd)); else strlcpy(ppd, "PPD=/System/Library/Frameworks/ApplicationServices.framework/" "Versions/A/Frameworks/PrintCore.framework/Versions/A/" "Resources/Generic.ppd", sizeof(ppd)); #else snprintf(ppd, sizeof(ppd), "PPD=%s/model/laserjet.ppd", DataDir); #endif /* __APPLE__ */ snprintf(rip_max_cache, sizeof(rip_max_cache), "RIP_MAX_CACHE=%s", RIPCache); snprintf(userenv, sizeof(userenv), "USER=%s", user); if (printer && (dest = cupsGetNamedDest(CUPS_HTTP_DEFAULT, printer, NULL)) != NULL) { if ((temp = cupsGetOption("printer-info", dest->num_options, dest->options)) != NULL) snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s", temp); else snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s", printer); if ((temp = cupsGetOption("printer-location", dest->num_options, dest->options)) != NULL) snprintf(printer_location, sizeof(printer_location), "PRINTER_LOCATION=%s", temp); else strlcpy(printer_location, "PRINTER_LOCATION=Unknown", sizeof(printer_location)); } else { snprintf(printer_info, sizeof(printer_info), "PRINTER_INFO=%s", printer ? printer : "Unknown"); strlcpy(printer_location, "PRINTER_LOCATION=Unknown", sizeof(printer_location)); } snprintf(printer_name, sizeof(printer_name), "PRINTER=%s", printer ? printer : "Unknown"); argv[0] = (char *)printer; argv[1] = "1"; argv[2] = user; argv[3] = title; argv[4] = cupsGetOption("copies", num_options, options); argv[5] = optstr; argv[6] = infile; argv[7] = NULL; if (!argv[4]) argv[4] = "1"; envp[0] = "<CFProcessPath>"; envp[1] = content_type; envp[2] = cups_datadir; envp[3] = cups_fontpath; envp[4] = cups_serverbin; envp[5] = cups_serverroot; envp[6] = lang; envp[7] = path; envp[8] = ppd; envp[9] = printer_info; envp[10] = printer_location; envp[11] = printer_name; envp[12] = rip_max_cache; envp[13] = userenv; envp[14] = "CHARSET=utf-8"; if (final_content_type[0]) { envp[15] = final_content_type; envp[16] = NULL; } else envp[15] = NULL; for (i = 0; argv[i]; i ++) fprintf(stderr, "DEBUG: argv[%d]=\"%s\"\n", i, argv[i]); for (i = 0; envp[i]; i ++) fprintf(stderr, "DEBUG: envp[%d]=\"%s\"\n", i, envp[i]); /* * Execute all of the filters... */ pids = cupsArrayNew((cups_array_func_t)compare_pids, NULL); current = 0; filterfds[0][0] = -1; filterfds[0][1] = -1; filterfds[1][0] = -1; filterfds[1][1] = -1; if (!infile) filterfds[0][0] = 0; for (filter = (mime_filter_t *)cupsArrayFirst(filters); filter; filter = next, current = 1 - current) { next = (mime_filter_t *)cupsArrayNext(filters); if (filter->filter[0] == '/') strlcpy(program, filter->filter, sizeof(program)); else snprintf(program, sizeof(program), "%s/filter/%s", ServerBin, filter->filter); if (filterfds[!current][1] > 1) { close(filterfds[1 - current][0]); close(filterfds[1 - current][1]); filterfds[1 - current][0] = -1; filterfds[1 - current][0] = -1; } if (next) open_pipe(filterfds[1 - current]); else if (outfile) { filterfds[1 - current][1] = open(outfile, O_CREAT | O_TRUNC | O_WRONLY, 0666); if (filterfds[1 - current][1] < 0) fprintf(stderr, "ERROR: Unable to create \"%s\" - %s\n", outfile, strerror(errno)); } else filterfds[1 - current][1] = 1; pid = exec_filter(program, (char **)argv, (char **)envp, filterfds[current][0], filterfds[1 - current][1]); if (pid > 0) { fprintf(stderr, "INFO: %s (PID %d) started.\n", filter->filter, pid); filter->cost = pid; cupsArrayAdd(pids, filter); } else break; argv[6] = NULL; } /* * Close remaining pipes... */ if (filterfds[0][1] > 1) { close(filterfds[0][0]); close(filterfds[0][1]); } if (filterfds[1][1] > 1) { close(filterfds[1][0]); close(filterfds[1][1]); } /* * Wait for the children to exit... */ retval = 0; while (cupsArrayCount(pids) > 0) { if ((pid = wait(&status)) < 0) continue; key.cost = pid; if ((filter = (mime_filter_t *)cupsArrayFind(pids, &key)) != NULL) { cupsArrayRemove(pids, filter); if (status) { if (WIFEXITED(status)) fprintf(stderr, "ERROR: %s (PID %d) stopped with status %d\n", filter->filter, pid, WEXITSTATUS(status)); else fprintf(stderr, "ERROR: %s (PID %d) crashed on signal %d\n", filter->filter, pid, WTERMSIG(status)); retval = 1; } else fprintf(stderr, "INFO: %s (PID %d) exited with no errors.\n", filter->filter, pid); } } cupsArrayDelete(pids); return (retval); }
bool iprint_cache_reload(void) { http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ int i; bool ret = False; DEBUG(5, ("reloading iprint printcap cache\n")); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes: * * attributes-charset * attributes-natural-language */ request = ippNew(); ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_LIST_PRINTERS); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "ipp-server", NULL, "ippSrvr"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = ippFirstAttribute(response); attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) attr = ippNextAttribute(response); if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { if (strcmp(ippGetName(attr), "printer-name") == 0 && (ippGetValueTag(attr) == IPP_TAG_URI || ippGetValueTag(attr) == IPP_TAG_NAME || ippGetValueTag(attr) == IPP_TAG_TEXT || ippGetValueTag(attr) == IPP_TAG_NAMELANG || ippGetValueTag(attr) == IPP_TAG_TEXTLANG)) { for (i = 0; i<ippGetCount(attr); i++) { char *url = ippGetString(attr, i, NULL); if (!url || !strlen(url)) continue; iprint_cache_add_printer(http, i+2, url); } } attr = ippNextAttribute(response); } } ret = True; out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
GtkCupsRequest * gtk_cups_request_new_with_username (http_t *connection, GtkCupsRequestType req_type, gint operation_id, GIOChannel *data_io, const char *server, const char *resource, const char *username) { GtkCupsRequest *request; cups_lang_t *language; request = g_new0 (GtkCupsRequest, 1); request->result = g_new0 (GtkCupsResult, 1); request->result->error_msg = NULL; request->result->ipp_response = NULL; request->result->is_error = FALSE; request->result->is_ipp_response = FALSE; request->type = req_type; request->state = GTK_CUPS_REQUEST_START; request->password_state = GTK_CUPS_PASSWORD_NONE; if (server) request->server = g_strdup (server); else request->server = g_strdup (cupsServer ()); if (resource) request->resource = g_strdup (resource); else request->resource = g_strdup ("/"); if (connection != NULL) { request->http = connection; request->own_http = FALSE; } else { request->http = NULL; request->http = httpConnectEncrypt (request->server, ippPort (), cupsEncryption ()); if (request->http) httpBlocking (request->http, 0); request->own_http = TRUE; } request->last_status = HTTP_CONTINUE; request->attempts = 0; request->data_io = data_io; request->ipp_request = ippNew (); ippSetOperation (request->ipp_request, operation_id); ippSetRequestId (request->ipp_request, 1); language = cupsLangDefault (); gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); if (username != NULL) gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, username); else gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, cupsUser ()); request->auth_info_required = NULL; request->auth_info = NULL; request->need_auth_info = FALSE; cupsLangFree (language); return request; }
static http_status_t /* O - Status of request */ get_cupsd_conf( http_t *http, /* I - Connection to server */ _cups_globals_t *cg, /* I - Global data */ time_t last_update, /* I - Last update time for file */ char *name, /* I - Filename buffer */ size_t namesize, /* I - Size of filename buffer */ int *remote) /* O - Remote file? */ { int fd; /* Temporary file descriptor */ #ifndef _WIN32 struct stat info; /* cupsd.conf file information */ #endif /* _WIN32 */ http_status_t status; /* Status of getting cupsd.conf */ char host[HTTP_MAX_HOST]; /* Hostname for connection */ /* * See if we already have the data we need... */ httpGetHostname(http, host, sizeof(host)); if (_cups_strcasecmp(cg->cupsd_hostname, host)) invalidate_cupsd_cache(cg); snprintf(name, namesize, "%s/cupsd.conf", cg->cups_serverroot); *remote = 0; #ifndef _WIN32 if (!_cups_strcasecmp(host, "localhost") && !access(name, R_OK)) { /* * Read the local file rather than using HTTP... */ if (stat(name, &info)) { char message[1024]; /* Message string */ snprintf(message, sizeof(message), _cupsLangString(cupsLangDefault(), _("stat of %s failed: %s")), name, strerror(errno)); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); *name = '\0'; return (HTTP_STATUS_SERVER_ERROR); } else if (last_update && info.st_mtime <= last_update) status = HTTP_STATUS_NOT_MODIFIED; else status = HTTP_STATUS_OK; } else #endif /* !_WIN32 */ { /* * Read cupsd.conf via a HTTP GET request... */ if ((fd = cupsTempFd(name, (int)namesize)) < 0) { *name = '\0'; _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0); invalidate_cupsd_cache(cg); return (HTTP_STATUS_SERVER_ERROR); } *remote = 1; httpClearFields(http); if (last_update) httpSetField(http, HTTP_FIELD_IF_MODIFIED_SINCE, httpGetDateString(last_update)); status = cupsGetFd(http, "/admin/conf/cupsd.conf", fd); close(fd); if (status != HTTP_STATUS_OK) { unlink(name); *name = '\0'; } } return (status); }
int /* O - 1 on success, 0 on failure */ cupsAdminGetServerSettings( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ int *num_settings, /* O - Number of settings */ cups_option_t **settings) /* O - Settings */ { int i; /* Looping var */ cups_file_t *cupsd; /* cupsd.conf file */ char cupsdconf[1024]; /* cupsd.conf filename */ int remote; /* Remote cupsd.conf file? */ http_status_t status; /* Status of getting cupsd.conf */ char line[1024], /* Line from cupsd.conf file */ *value; /* Value on line */ cups_option_t *setting; /* Current setting */ _cups_globals_t *cg = _cupsGlobals(); /* Global data */ /* * Range check input... */ if (!http) { /* * See if we are connected to the same server... */ if (cg->http) { /* * Compare the connection hostname, port, and encryption settings to * the cached defaults; these were initialized the first time we * connected... */ if (strcmp(cg->http->hostname, cg->server) || cg->ipp_port != httpAddrPort(cg->http->hostaddr) || (cg->http->encryption != cg->encryption && cg->http->encryption == HTTP_ENCRYPTION_NEVER)) { /* * Need to close the current connection because something has changed... */ httpClose(cg->http); cg->http = NULL; } } /* * (Re)connect as needed... */ if (!cg->http) { if ((cg->http = httpConnect2(cupsServer(), ippPort(), NULL, AF_UNSPEC, cupsEncryption(), 1, 0, NULL)) == NULL) { if (errno) _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, NULL, 0); else _cupsSetError(IPP_STATUS_ERROR_SERVICE_UNAVAILABLE, _("Unable to connect to host."), 1); if (num_settings) *num_settings = 0; if (settings) *settings = NULL; return (0); } } http = cg->http; } if (!http || !num_settings || !settings) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); if (num_settings) *num_settings = 0; if (settings) *settings = NULL; return (0); } *num_settings = 0; *settings = NULL; /* * Get the cupsd.conf file... */ if ((status = get_cupsd_conf(http, cg, cg->cupsd_update, cupsdconf, sizeof(cupsdconf), &remote)) == HTTP_STATUS_OK) { if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL) { char message[1024]; /* Message string */ snprintf(message, sizeof(message), _cupsLangString(cupsLangDefault(), _("Open of %s failed: %s")), cupsdconf, strerror(errno)); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, message, 0); } } else cupsd = NULL; if (cupsd) { /* * Read the file, keeping track of what settings are enabled... */ int remote_access = 0, /* Remote access allowed? */ remote_admin = 0, /* Remote administration allowed? */ remote_any = 0, /* Remote access from anywhere allowed? */ browsing = 1, /* Browsing enabled? */ cancel_policy = 1, /* Cancel-job policy set? */ debug_logging = 0; /* LogLevel debug set? */ int linenum = 0, /* Line number in file */ in_location = 0, /* In a location section? */ in_policy = 0, /* In a policy section? */ in_cancel_job = 0, /* In a cancel-job section? */ in_admin_location = 0; /* In the /admin location? */ invalidate_cupsd_cache(cg); cg->cupsd_update = time(NULL); httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname)); while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum)) { if (!value && strncmp(line, "</", 2)) value = line + strlen(line); if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")) && value) { char *port; /* Pointer to port number, if any */ if ((port = strrchr(value, ':')) != NULL) *port = '\0'; else if (isdigit(*value & 255)) { /* * Listen on a port number implies remote access... */ remote_access = 1; continue; } if (_cups_strcasecmp(value, "localhost") && strcmp(value, "127.0.0.1") #ifdef AF_LOCAL && *value != '/' #endif /* AF_LOCAL */ #ifdef AF_INET6 && strcmp(value, "[::1]") #endif /* AF_INET6 */ ) remote_access = 1; } else if (!_cups_strcasecmp(line, "Browsing")) { browsing = !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "true"); } else if (!_cups_strcasecmp(line, "LogLevel")) { debug_logging = !_cups_strncasecmp(value, "debug", 5); } else if (!_cups_strcasecmp(line, "<Policy") && !_cups_strcasecmp(value, "default")) { in_policy = 1; } else if (!_cups_strcasecmp(line, "</Policy>")) { in_policy = 0; } else if (!_cups_strcasecmp(line, "<Limit") && in_policy && value) { /* * See if the policy limit is for the Cancel-Job operation... */ char *valptr; /* Pointer into value */ while (*value) { for (valptr = value; *valptr && !_cups_isspace(*valptr); valptr ++); if (*valptr) *valptr++ = '\0'; if (!_cups_strcasecmp(value, "cancel-job") || !_cups_strcasecmp(value, "all")) { in_cancel_job = 1; break; } for (value = valptr; _cups_isspace(*value); value ++); } } else if (!_cups_strcasecmp(line, "</Limit>")) { in_cancel_job = 0; } else if (!_cups_strcasecmp(line, "Require") && in_cancel_job) { cancel_policy = 0; } else if (!_cups_strcasecmp(line, "<Location") && value) { in_admin_location = !_cups_strcasecmp(value, "/admin"); in_location = 1; } else if (!_cups_strcasecmp(line, "</Location>")) { in_admin_location = 0; in_location = 0; } else if (!_cups_strcasecmp(line, "Allow") && value && _cups_strcasecmp(value, "localhost") && _cups_strcasecmp(value, "127.0.0.1") #ifdef AF_LOCAL && *value != '/' #endif /* AF_LOCAL */ #ifdef AF_INET6 && strcmp(value, "::1") #endif /* AF_INET6 */ ) { if (in_admin_location) remote_admin = 1; else if (!_cups_strcasecmp(value, "all")) remote_any = 1; } else if (line[0] != '<' && !in_location && !in_policy && _cups_strcasecmp(line, "Allow") && _cups_strcasecmp(line, "AuthType") && _cups_strcasecmp(line, "Deny") && _cups_strcasecmp(line, "Order") && _cups_strcasecmp(line, "Require") && _cups_strcasecmp(line, "Satisfy")) cg->cupsd_num_settings = cupsAddOption(line, value, cg->cupsd_num_settings, &(cg->cupsd_settings)); } cupsFileClose(cupsd); cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, debug_logging ? "1" : "0", cg->cupsd_num_settings, &(cg->cupsd_settings)); cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, (remote_access && remote_admin) ? "1" : "0", cg->cupsd_num_settings, &(cg->cupsd_settings)); cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, remote_any ? "1" : "0", cg->cupsd_num_settings, &(cg->cupsd_settings)); cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, (remote_access && browsing) ? "1" : "0", cg->cupsd_num_settings, &(cg->cupsd_settings)); cg->cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, cancel_policy ? "1" : "0", cg->cupsd_num_settings, &(cg->cupsd_settings)); } else if (status != HTTP_STATUS_NOT_MODIFIED) invalidate_cupsd_cache(cg); /* * Remove any temporary files and copy the settings array... */ if (remote) unlink(cupsdconf); for (i = cg->cupsd_num_settings, setting = cg->cupsd_settings; i > 0; i --, setting ++) *num_settings = cupsAddOption(setting->name, setting->value, *num_settings, settings); return (cg->cupsd_num_settings > 0); }
void _cupsLangPrintError(const char *prefix, /* I - Non-localized message prefix */ const char *message)/* I - Message */ { ssize_t bytes; /* Number of bytes formatted */ int last_errno; /* Last error */ char buffer[2048], /* Message buffer */ *bufptr, /* Pointer into buffer */ output[8192]; /* Output buffer */ _cups_globals_t *cg; /* Global data */ /* * Range check... */ if (!message) return; /* * Save the errno value... */ last_errno = errno; /* * Get the message catalog... */ cg = _cupsGlobals(); if (!cg->lang_default) cg->lang_default = cupsLangDefault(); /* * Format the message... */ if (prefix) { snprintf(buffer, sizeof(buffer), "%s:", prefix); bufptr = buffer + strlen(buffer); } else bufptr = buffer; snprintf(bufptr, sizeof(buffer) - (size_t)(bufptr - buffer), /* TRANSLATORS: Message is "subject: error" */ _cupsLangString(cg->lang_default, _("%s: %s")), _cupsLangString(cg->lang_default, message), strerror(last_errno)); strlcat(buffer, "\n", sizeof(buffer)); /* * Convert and write to stderr... */ bytes = cupsUTF8ToCharset(output, (cups_utf8_t *)buffer, sizeof(output), cg->lang_default->encoding); if (bytes > 0) fwrite(output, 1, (size_t)bytes, stderr); }
void _cupsSetLocale(char *argv[]) /* IO - Command-line arguments */ { int i; /* Looping var */ char buffer[8192]; /* Command-line argument buffer */ _cups_globals_t *cg; /* Global data */ #ifdef LC_TIME const char *lc_time; /* Current LC_TIME value */ char new_lc_time[255], /* New LC_TIME value */ *charset; /* Pointer to character set */ #endif /* LC_TIME */ /* * Set the locale so that times, etc. are displayed properly. * * Unfortunately, while we need the localized time value, we *don't* * want to use the localized charset for the time value, so we need * to set LC_TIME to the locale name with .UTF-8 on the end (if * the locale includes a character set specifier...) */ setlocale(LC_ALL, ""); #ifdef LC_TIME if ((lc_time = setlocale(LC_TIME, NULL)) == NULL) lc_time = setlocale(LC_ALL, NULL); if (lc_time) { strlcpy(new_lc_time, lc_time, sizeof(new_lc_time)); if ((charset = strchr(new_lc_time, '.')) == NULL) charset = new_lc_time + strlen(new_lc_time); strlcpy(charset, ".UTF-8", sizeof(new_lc_time) - (size_t)(charset - new_lc_time)); } else strlcpy(new_lc_time, "C", sizeof(new_lc_time)); setlocale(LC_TIME, new_lc_time); #endif /* LC_TIME */ /* * Initialize the default language info... */ cg = _cupsGlobals(); if (!cg->lang_default) cg->lang_default = cupsLangDefault(); /* * Transcode the command-line arguments from the locale charset to * UTF-8... */ if (cg->lang_default->encoding != CUPS_US_ASCII && cg->lang_default->encoding != CUPS_UTF8) { for (i = 1; argv[i]; i ++) { /* * Try converting from the locale charset to UTF-8... */ if (cupsCharsetToUTF8((cups_utf8_t *)buffer, argv[i], sizeof(buffer), cg->lang_default->encoding) < 0) continue; /* * Save the new string if it differs from the original... */ if (strcmp(buffer, argv[i])) argv[i] = strdup(buffer); } } }
int /* O - 0 on success, -1 on error */ cupsDoAuthentication( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ const char *method, /* I - Request method ("GET", "POST", "PUT") */ const char *resource) /* I - Resource path */ { const char *password, /* Password string */ *www_auth; /* WWW-Authenticate header */ char prompt[1024], /* Prompt for user */ realm[HTTP_MAX_VALUE], /* realm="xyz" string */ nonce[HTTP_MAX_VALUE]; /* nonce="xyz" string */ int localauth; /* Local authentication result */ _cups_globals_t *cg; /* Global data */ DEBUG_printf(("cupsDoAuthentication(http=%p, method=\"%s\", resource=\"%s\")", http, method, resource)); if (!http) http = _cupsConnect(); if (!http || !method || !resource) return (-1); DEBUG_printf(("2cupsDoAuthentication: digest_tries=%d, userpass=\"%s\"", http->digest_tries, http->userpass)); DEBUG_printf(("2cupsDoAuthentication: WWW-Authenticate=\"%s\"", httpGetField(http, HTTP_FIELD_WWW_AUTHENTICATE))); /* * Clear the current authentication string... */ httpSetAuthString(http, NULL, NULL); /* * See if we can do local authentication... */ if (http->digest_tries < 3) { if ((localauth = cups_local_auth(http)) == 0) { DEBUG_printf(("2cupsDoAuthentication: authstring=\"%s\"", http->authstring)); if (http->status == HTTP_STATUS_UNAUTHORIZED) http->digest_tries ++; return (0); } else if (localauth == -1) { http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); /* Error or canceled */ } } /* * Nope, see if we should retry the current username:password... */ www_auth = http->fields[HTTP_FIELD_WWW_AUTHENTICATE]; if ((http->digest_tries > 1 || !http->userpass[0]) && (!_cups_strncasecmp(www_auth, "Basic", 5) || !_cups_strncasecmp(www_auth, "Digest", 6))) { /* * Nope - get a new password from the user... */ char default_username[HTTP_MAX_VALUE]; /* Default username */ cg = _cupsGlobals(); if (!cg->lang_default) cg->lang_default = cupsLangDefault(); if (httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "username", default_username)) cupsSetUser(default_username); snprintf(prompt, sizeof(prompt), _cupsLangString(cg->lang_default, _("Password for %s on %s? ")), cupsUser(), http->hostname[0] == '/' ? "localhost" : http->hostname); http->digest_tries = _cups_strncasecmp(www_auth, "Digest", 6) != 0; http->userpass[0] = '\0'; if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) { http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); } snprintf(http->userpass, sizeof(http->userpass), "%s:%s", cupsUser(), password); } else if (http->status == HTTP_STATUS_UNAUTHORIZED) http->digest_tries ++; if (http->status == HTTP_STATUS_UNAUTHORIZED && http->digest_tries >= 3) { DEBUG_printf(("1cupsDoAuthentication: Too many authentication tries (%d)", http->digest_tries)); http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); } /* * Got a password; encode it for the server... */ #ifdef HAVE_GSSAPI if (!_cups_strncasecmp(www_auth, "Negotiate", 9)) { /* * Kerberos authentication... */ if (_cupsSetNegotiateAuthString(http, method, resource)) { http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); } } else #endif /* HAVE_GSSAPI */ if (!_cups_strncasecmp(www_auth, "Basic", 5)) { /* * Basic authentication... */ char encode[256]; /* Base64 buffer */ httpEncode64_2(encode, sizeof(encode), http->userpass, (int)strlen(http->userpass)); httpSetAuthString(http, "Basic", encode); } else if (!_cups_strncasecmp(www_auth, "Digest", 6)) { /* * Digest authentication... */ char encode[33], /* MD5 buffer */ digest[1024]; /* Digest auth data */ httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "realm", realm); httpGetSubField(http, HTTP_FIELD_WWW_AUTHENTICATE, "nonce", nonce); httpMD5(cupsUser(), realm, strchr(http->userpass, ':') + 1, encode); httpMD5Final(nonce, method, resource, encode); snprintf(digest, sizeof(digest), "username=\"%s\", realm=\"%s\", nonce=\"%s\", uri=\"%s\", " "response=\"%s\"", cupsUser(), realm, nonce, resource, encode); httpSetAuthString(http, "Digest", digest); } else { DEBUG_printf(("1cupsDoAuthentication: Unknown auth type: \"%s\"", www_auth)); http->status = HTTP_STATUS_CUPS_AUTHORIZATION_CANCELED; return (-1); } DEBUG_printf(("1cupsDoAuthentication: authstring=\"%s\"", http->authstring)); return (0); }
static int iprint_job_resume(int snum, struct printjob *pjob) { int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ char uri[HTTP_MAX_URI]; /* printer-uri attribute */ char httpPath[HTTP_MAX_URI]; /* path portion of the printer-uri */ DEBUG(5,("iprint_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build an IPP_RELEASE_JOB request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * job-id * requesting-user-name */ request = ippNew(); ippSetOperation(request, IPP_RELEASE_JOB); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); slprintf(uri, sizeof(uri) - 1, "ipp://%s/ipp/%s", iprint_server(), lp_printername(snum)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id", pjob->sysjob); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", NULL, pjob->user); /* * Do the request and get back a response... */ slprintf(httpPath, sizeof(httpPath) - 1, "/ipp/%s", lp_printername(snum)); if ((response = cupsDoRequest(http, request, httpPath)) != NULL) { if (ippGetStatusCode(response) >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } else { ret = 0; } } else { DEBUG(0,("Unable to release job %d - %s\n", pjob->sysjob, ippErrorString(cupsLastError()))); } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (http) httpClose(http); return ret; }
int /* O - 0 on success, -1 on error */ _cupsSetNegotiateAuthString( http_t *http, /* I - Connection to server */ const char *method, /* I - Request method ("GET", "POST", "PUT") */ const char *resource) /* I - Resource path */ { OM_uint32 minor_status, /* Minor status code */ major_status; /* Major status code */ gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER; /* Output token */ (void)method; (void)resource; # ifdef __APPLE__ /* * If the weak-linked GSSAPI/Kerberos library is not present, don't try * to use it... */ if (&gss_init_sec_context == NULL) { DEBUG_puts("1_cupsSetNegotiateAuthString: Weak-linked GSSAPI/Kerberos " "framework is not present"); return (-1); } # endif /* __APPLE__ */ if (http->gssname == GSS_C_NO_NAME) { http->gssname = cups_gss_getname(http, _cupsGSSServiceName()); } if (http->gssctx != GSS_C_NO_CONTEXT) { gss_delete_sec_context(&minor_status, &http->gssctx, GSS_C_NO_BUFFER); http->gssctx = GSS_C_NO_CONTEXT; } major_status = gss_init_sec_context(&minor_status, GSS_C_NO_CREDENTIAL, &http->gssctx, http->gssname, http->gssmech, GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, &http->gssmech, &output_token, NULL, NULL); #ifdef HAVE_GSS_ACQUIRE_CRED_EX_F if (major_status == GSS_S_NO_CRED) { /* * Ask the user for credentials... */ char prompt[1024], /* Prompt for user */ userbuf[256]; /* Kerberos username */ const char *username, /* Username string */ *password; /* Password string */ _cups_gss_acquire_t data; /* Callback data */ gss_auth_identity_desc identity; /* Kerberos user identity */ _cups_globals_t *cg = _cupsGlobals(); /* Per-thread global data */ if (!cg->lang_default) cg->lang_default = cupsLangDefault(); snprintf(prompt, sizeof(prompt), _cupsLangString(cg->lang_default, _("Password for %s on %s? ")), cupsUser(), http->gsshost); if ((password = cupsGetPassword2(prompt, http, method, resource)) == NULL) return (-1); /* * Try to acquire credentials... */ username = cupsUser(); if (!strchr(username, '@')) { snprintf(userbuf, sizeof(userbuf), "%s@%s", username, http->gsshost); username = userbuf; } identity.type = GSS_AUTH_IDENTITY_TYPE_1; identity.flags = 0; identity.username = (char *)username; identity.realm = (char *)""; identity.password = (char *)password; identity.credentialsRef = NULL; data.sem = dispatch_semaphore_create(0); data.major = 0; data.creds = NULL; if (data.sem) { major_status = gss_acquire_cred_ex_f(NULL, GSS_C_NO_NAME, 0, GSS_C_INDEFINITE, GSS_KRB5_MECHANISM, GSS_C_INITIATE, &identity, &data, cups_gss_acquire); if (major_status == GSS_S_COMPLETE) { dispatch_semaphore_wait(data.sem, DISPATCH_TIME_FOREVER); major_status = data.major; } dispatch_release(data.sem); if (major_status == GSS_S_COMPLETE) { OM_uint32 release_minor; /* Minor status from releasing creds */ major_status = gss_init_sec_context(&minor_status, data.creds, &http->gssctx, http->gssname, http->gssmech, GSS_C_MUTUAL_FLAG | GSS_C_INTEG_FLAG, GSS_C_INDEFINITE, GSS_C_NO_CHANNEL_BINDINGS, GSS_C_NO_BUFFER, &http->gssmech, &output_token, NULL, NULL); gss_release_cred(&release_minor, &data.creds); } } } #endif /* HAVE_GSS_ACQUIRED_CRED_EX_F */ if (GSS_ERROR(major_status)) { cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Unable to initialize " "security context"); return (-1); } #ifdef DEBUG else if (major_status == GSS_S_CONTINUE_NEEDED) cups_gss_printf(major_status, minor_status, "_cupsSetNegotiateAuthString: Continuation needed!"); #endif /* DEBUG */ if (output_token.length > 0 && output_token.length <= 65536) { /* * Allocate the authorization string since Windows KDCs can have * arbitrarily large credentials... */ int authsize = 10 + /* "Negotiate " */ (int)output_token.length * 4 / 3 + 1 + 1; /* Base64 + nul */ httpSetAuthString(http, NULL, NULL); if ((http->authstring = malloc((size_t)authsize)) == NULL) { http->authstring = http->_authstring; authsize = sizeof(http->_authstring); } strlcpy(http->authstring, "Negotiate ", (size_t)authsize); httpEncode64_2(http->authstring + 10, authsize - 10, output_token.value, (int)output_token.length); gss_release_buffer(&minor_status, &output_token); } else { DEBUG_printf(("1_cupsSetNegotiateAuthString: Kerberos credentials too " "large - %d bytes!", (int)output_token.length)); gss_release_buffer(&minor_status, &output_token); return (-1); } return (0); }
static int /* O - 1 on success, 0 on failure */ make_certificate(cupsd_client_t *con) /* I - Client connection */ { gnutls_x509_crt crt; /* Self-signed certificate */ gnutls_x509_privkey key; /* Encryption key */ cups_lang_t *language; /* Default language info */ cups_file_t *fp; /* Key/cert file */ unsigned char buffer[8192]; /* Buffer for x509 data */ size_t bytes; /* Number of bytes of data */ unsigned char serial[4]; /* Serial number buffer */ time_t curtime; /* Current time */ int result; /* Result of GNU TLS calls */ /* * Create the encryption key... */ cupsdLogMessage(CUPSD_LOG_INFO, "Generating SSL server key..."); gnutls_x509_privkey_init(&key); gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, 2048, 0); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server key - %s", gnutls_strerror(result)); gnutls_x509_privkey_deinit(key); return (0); } else if ((fp = cupsFileOpen(ServerKey, "w")) != NULL) { cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server key file \"%s\"...", ServerKey); } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server key file \"%s\" - %s", ServerKey, strerror(errno)); gnutls_x509_privkey_deinit(key); return (0); } /* * Create the self-signed certificate... */ cupsdLogMessage(CUPSD_LOG_INFO, "Generating self-signed SSL certificate..."); language = cupsLangDefault(); curtime = time(NULL); serial[0] = curtime >> 24; serial[1] = curtime >> 16; serial[2] = curtime >> 8; serial[3] = curtime; gnutls_x509_crt_init(&crt); if (strlen(language->language) == 5) gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, language->language + 3, 2); else gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COUNTRY_NAME, 0, "US", 2); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_COMMON_NAME, 0, ServerName, strlen(ServerName)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATION_NAME, 0, ServerName, strlen(ServerName)); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_STATE_OR_PROVINCE_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_X520_LOCALITY_NAME, 0, "Unknown", 7); gnutls_x509_crt_set_dn_by_oid(crt, GNUTLS_OID_PKCS9_EMAIL, 0, ServerAdmin, strlen(ServerAdmin)); gnutls_x509_crt_set_key(crt, key); gnutls_x509_crt_set_serial(crt, serial, sizeof(serial)); gnutls_x509_crt_set_activation_time(crt, curtime); gnutls_x509_crt_set_expiration_time(crt, curtime + 10 * 365 * 86400); gnutls_x509_crt_set_ca_status(crt, 0); gnutls_x509_crt_set_subject_alternative_name(crt, GNUTLS_SAN_DNSNAME, ServerName); gnutls_x509_crt_set_key_purpose_oid(crt, GNUTLS_KP_TLS_WWW_SERVER, 0); gnutls_x509_crt_set_key_usage(crt, GNUTLS_KEY_KEY_ENCIPHERMENT); gnutls_x509_crt_set_version(crt, 3); bytes = sizeof(buffer); if (gnutls_x509_crt_get_key_id(crt, 0, buffer, &bytes) >= 0) gnutls_x509_crt_set_subject_key_id(crt, buffer, bytes); gnutls_x509_crt_sign(crt, crt, key); /* * Save it... */ bytes = sizeof(buffer); if ((result = gnutls_x509_crt_export(crt, GNUTLS_X509_FMT_PEM, buffer, &bytes)) < 0) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to export SSL server certificate - %s", gnutls_strerror(result)); else if ((fp = cupsFileOpen(ServerCertificate, "w")) != NULL) { cupsFileWrite(fp, (char *)buffer, bytes); cupsFileClose(fp); cupsdLogMessage(CUPSD_LOG_INFO, "Created SSL server certificate file \"%s\"...", ServerCertificate); } else cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create SSL server certificate file \"%s\" - %s", ServerCertificate, strerror(errno)); /* * Cleanup... */ gnutls_x509_crt_deinit(crt); gnutls_x509_privkey_deinit(key); return (1); }
static int /* O - Exit status */ do_test(const char *server, /* I - Server to use */ http_encryption_t encryption, /* I - Encryption to use */ int requests, /* I - Number of requests to send */ int verbose) /* I - Verbose output? */ { int i; /* Looping var */ http_t *http; /* Connection to server */ ipp_t *request, /* IPP Request */ *response; /* IPP Response */ cups_lang_t *language; /* Default language */ struct timeval start, /* Start time */ end; /* End time */ double elapsed; /* Elapsed time */ static ipp_op_t ops[4] = /* Operations to test... */ { IPP_PRINT_JOB, CUPS_GET_PRINTERS, CUPS_GET_CLASSES, IPP_GET_JOBS }; /* * Connect to the server... */ http = httpConnectEncrypt(server, ippPort(), encryption); if (http == NULL) { perror("testspeed: unable to connect to server"); return (1); } language = cupsLangDefault(); /* * Do multiple requests... */ for (elapsed = 0.0, i = 0; i < requests; i ++) { if (verbose && (i % 10) == 0) printf("testspeed(%d): %d%% complete...\n", (int)getpid(), i * 100 / requests); /* * Build a request which requires the following attributes: * * attributes-charset * attributes-natural-language * * In addition, IPP_GET_JOBS needs a printer-uri attribute. */ request = ippNew(); request->request.op.operation_id = ops[i & 3]; request->request.op.request_id = 1; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(language)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); gettimeofday(&start, NULL); switch (request->request.op.operation_id) { case IPP_GET_JOBS : ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/printers/"); default : response = cupsDoRequest(http, request, "/"); break; case IPP_PRINT_JOB : ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, "ipp://localhost/printers/test"); response = cupsDoFileRequest(http, request, "/printers/test", "../data/testprint.ps"); break; } gettimeofday(&end, NULL); if (response != NULL) ippDelete(response); elapsed += (end.tv_sec - start.tv_sec) + 0.000001 * (end.tv_usec - start.tv_usec); } cupsLangFree(language); httpClose(http); printf("testspeed(%d): %d requests in %.1fs (%.3fs/r, %.1fr/s)\n", (int)getpid(), i, elapsed, elapsed / i, i / elapsed); return (0); }
static int iprint_get_server_version(http_t *http, char* serviceUri) { ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *ver; /* server version pointer */ char *vertmp; /* server version tmp pointer */ int serverVersion = 0; /* server version */ char *os; /* server os */ int osFlag = 0; /* 0 for NetWare, 1 for anything else */ char *temp; /* pointer for string manipulation */ /* * Build an OPERATION_NOVELL_MGMT("get-server-version") request, * which requires the following attributes: * * attributes-charset * attributes-natural-language * operation-name * service-uri */ request = ippNew(); ippSetOperation(request, (ipp_op_t)OPERATION_NOVELL_MGMT); ippSetRequestId(request, 1); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "service-uri", NULL, serviceUri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "operation-name", NULL, "get-server-version"); /* * Do the request and get back a response... */ if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) || (ippGetStatusCode(response) >= IPP_OK_CONFLICT)) goto out; if (((attr = ippFindAttribute(response, "server-version", IPP_TAG_STRING)) != NULL)) { if ((ver = strstr(ippGetString(attr, 0, NULL), NOVELL_SERVER_VERSION_STRING)) != NULL) { ver += strlen(NOVELL_SERVER_VERSION_STRING); /* * Strangely, libcups stores a IPP_TAG_STRING (octet * string) as a null-terminated string with no length * even though it could be binary data with nulls in * it. Luckily, in this case the value is not binary. */ serverVersion = strtol(ver, &vertmp, 10); /* Check for not found, overflow or negative version */ if ((ver == vertmp) || (serverVersion < 0)) serverVersion = 0; } if ((os = strstr(ippGetString(attr, 0, NULL), NOVELL_SERVER_SYSNAME)) != NULL) { os += strlen(NOVELL_SERVER_SYSNAME); if ((temp = strchr(os,'<')) != NULL) *temp = '\0'; if (strcmp(os,NOVELL_SERVER_SYSNAME_NETWARE)) osFlag = 1; /* 1 for non-NetWare systems */ } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (osFlag == 0) serverVersion *= -1; return serverVersion; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments (6 or 7) */ char *argv[]) /* I - Command-line arguments */ { const char *device_uri; /* Device URI */ char scheme[255], /* Scheme in URI */ hostname[1024], /* Hostname */ username[255], /* Username info (not used) */ resource[1024], /* Resource info (not used) */ *options, /* Pointer to options */ *name, /* Name of option */ *value, /* Value of option */ sep; /* Option separator */ int print_fd; /* Print file */ int copies; /* Number of copies to print */ time_t start_time; /* Time of first connect */ #ifdef __APPLE__ time_t current_time, /* Current time */ wait_time; /* Time to wait before shutting down socket */ #endif /* __APPLE__ */ int contimeout; /* Connection timeout */ int waiteof; /* Wait for end-of-file? */ int port; /* Port number */ char portname[255]; /* Port name */ int delay; /* Delay for retries... */ int device_fd; /* AppSocket */ int error; /* Error code (if any) */ http_addrlist_t *addrlist, /* Address list */ *addr; /* Connected address */ char addrname[256]; /* Address name */ int snmp_fd, /* SNMP socket */ start_count, /* Page count via SNMP at start */ page_count, /* Page count via SNMP */ have_supplies; /* Printer supports supply levels? */ ssize_t bytes = 0, /* Initial bytes read */ tbytes; /* Total number of bytes written */ char buffer[1024]; /* Initial print buffer */ #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET) struct sigaction action; /* Actions for POSIX signals */ #endif /* HAVE_SIGACTION && !HAVE_SIGSET */ /* * Make sure status messages are not buffered... */ setbuf(stderr, NULL); /* * Ignore SIGPIPE signals... */ #ifdef HAVE_SIGSET sigset(SIGPIPE, SIG_IGN); #elif defined(HAVE_SIGACTION) memset(&action, 0, sizeof(action)); action.sa_handler = SIG_IGN; sigaction(SIGPIPE, &action, NULL); #else signal(SIGPIPE, SIG_IGN); #endif /* HAVE_SIGSET */ /* * Check command-line... */ if (argc == 1) { printf("network socket \"Unknown\" \"%s\"\n", _cupsLangString(cupsLangDefault(), _("AppSocket/HP JetDirect"))); return (CUPS_BACKEND_OK); } else if (argc < 6 || argc > 7) { _cupsLangPrintf(stderr, _("Usage: %s job-id user title copies options [file]"), argv[0]); return (CUPS_BACKEND_FAILED); } /* * If we have 7 arguments, print the file named on the command-line. * Otherwise, send stdin instead... */ if (argc == 6) { print_fd = 0; copies = 1; } else { /* * Try to open the print file... */ if ((print_fd = open(argv[6], O_RDONLY)) < 0) { _cupsLangPrintError("ERROR", _("Unable to open print file")); return (CUPS_BACKEND_FAILED); } copies = atoi(argv[4]); } /* * Extract the hostname and port number from the URI... */ while ((device_uri = cupsBackendDeviceURI(argv)) == NULL) { _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer.")); sleep(10); if (getenv("CLASS") != NULL) return (CUPS_BACKEND_FAILED); } httpSeparateURI(HTTP_URI_CODING_ALL, device_uri, scheme, sizeof(scheme), username, sizeof(username), hostname, sizeof(hostname), &port, resource, sizeof(resource)); if (port == 0) port = 9100; /* Default to HP JetDirect/Tektronix PhaserShare */ /* * Get options, if any... */ waiteof = 1; contimeout = 7 * 24 * 60 * 60; if ((options = strchr(resource, '?')) != NULL) { /* * Yup, terminate the device name string and move to the first * character of the options... */ *options++ = '\0'; /* * Parse options... */ while (*options) { /* * Get the name... */ name = options; while (*options && *options != '=' && *options != '+' && *options != '&') options ++; if ((sep = *options) != '\0') *options++ = '\0'; if (sep == '=') { /* * Get the value... */ value = options; while (*options && *options != '+' && *options != '&') options ++; if (*options) *options++ = '\0'; } else value = (char *)""; /* * Process the option... */ if (!_cups_strcasecmp(name, "waiteof")) { /* * Set the wait-for-eof value... */ waiteof = !value[0] || !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true"); } else if (!_cups_strcasecmp(name, "contimeout")) { /* * Set the connection timeout... */ if (atoi(value) > 0) contimeout = atoi(value); } } } /* * Then try finding the remote host... */ start_time = time(NULL); sprintf(portname, "%d", port); fputs("STATE: +connecting-to-device\n", stderr); fprintf(stderr, "DEBUG: Looking up \"%s\"...\n", hostname); while ((addrlist = httpAddrGetList(hostname, AF_UNSPEC, portname)) == NULL) { _cupsLangPrintFilter(stderr, "INFO", _("Unable to locate printer \"%s\"."), hostname); sleep(10); if (getenv("CLASS") != NULL) { fputs("STATE: -connecting-to-device\n", stderr); return (CUPS_BACKEND_STOP); } } /* * See if the printer supports SNMP... */ if ((snmp_fd = _cupsSNMPOpen(addrlist->addr.addr.sa_family)) >= 0) { have_supplies = !backendSNMPSupplies(snmp_fd, &(addrlist->addr), &start_count, NULL); } else have_supplies = start_count = 0; /* * Wait for data from the filter... */ if (print_fd == 0) { if (!backendWaitLoop(snmp_fd, &(addrlist->addr), 1, backendNetworkSideCB)) return (CUPS_BACKEND_OK); else if ((bytes = read(0, buffer, sizeof(buffer))) <= 0) return (CUPS_BACKEND_OK); } /* * Connect to the printer... */ fprintf(stderr, "DEBUG: Connecting to %s:%d\n", hostname, port); _cupsLangPrintFilter(stderr, "INFO", _("Connecting to printer.")); for (delay = 5;;) { if ((addr = httpAddrConnect(addrlist, &device_fd)) == NULL) { error = errno; device_fd = -1; if (getenv("CLASS") != NULL) { /* * If the CLASS environment variable is set, the job was submitted * to a class and not to a specific queue. In this case, we want * to abort immediately so that the job can be requeued on the next * available printer in the class. */ _cupsLangPrintFilter(stderr, "INFO", _("Unable to contact printer, queuing on next " "printer in class.")); /* * Sleep 5 seconds to keep the job from requeuing too rapidly... */ sleep(5); return (CUPS_BACKEND_FAILED); } fprintf(stderr, "DEBUG: Connection error: %s\n", strerror(error)); if (error == ECONNREFUSED || error == EHOSTDOWN || error == EHOSTUNREACH) { if (contimeout && (time(NULL) - start_time) > contimeout) { _cupsLangPrintFilter(stderr, "ERROR", _("The printer is not responding.")); return (CUPS_BACKEND_FAILED); } switch (error) { case EHOSTDOWN : _cupsLangPrintFilter(stderr, "WARNING", _("The printer may not exist or " "is unavailable at this time.")); break; case EHOSTUNREACH : _cupsLangPrintFilter(stderr, "WARNING", _("The printer is unreachable at this " "time.")); break; case ECONNREFUSED : default : _cupsLangPrintFilter(stderr, "WARNING", _("The printer is in use.")); break; } sleep(delay); if (delay < 30) delay += 5; } else { _cupsLangPrintFilter(stderr, "ERROR", _("The printer is not responding.")); sleep(30); } } else break; } fputs("STATE: -connecting-to-device\n", stderr); _cupsLangPrintFilter(stderr, "INFO", _("Connected to printer.")); fprintf(stderr, "DEBUG: Connected to %s:%d...\n", httpAddrString(&(addr->addr), addrname, sizeof(addrname)), _httpAddrPort(&(addr->addr))); /* * Print everything... */ tbytes = 0; if (bytes > 0) tbytes += write(device_fd, buffer, bytes); while (copies > 0 && tbytes >= 0) { copies --; if (print_fd != 0) { fputs("PAGE: 1 1\n", stderr); lseek(print_fd, 0, SEEK_SET); } tbytes = backendRunLoop(print_fd, device_fd, snmp_fd, &(addrlist->addr), 1, 0, backendNetworkSideCB); if (print_fd != 0 && tbytes >= 0) _cupsLangPrintFilter(stderr, "INFO", _("Print file sent.")); } #ifdef __APPLE__ /* * Wait up to 5 seconds to get any pending back-channel data... */ wait_time = time(NULL) + 5; while (wait_time >= time(¤t_time)) if (wait_bc(device_fd, wait_time - current_time) <= 0) break; #endif /* __APPLE__ */ if (waiteof) { /* * Shutdown the socket and wait for the other end to finish... */ _cupsLangPrintFilter(stderr, "INFO", _("Waiting for printer to finish.")); shutdown(device_fd, 1); while (wait_bc(device_fd, 90) > 0); } /* * Collect the final page count as needed... */ if (have_supplies && !backendSNMPSupplies(snmp_fd, &(addrlist->addr), &page_count, NULL) && page_count > start_count) fprintf(stderr, "PAGE: total %d\n", page_count - start_count); /* * Close the socket connection... */ close(device_fd); httpAddrFreeList(addrlist); /* * Close the input file and return... */ if (print_fd != 0) close(print_fd); return (CUPS_BACKEND_OK); }
static int iprint_cache_add_printer(http_t *http, int reqId, char* url) { ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *name, /* printer-name attribute */ *info, /* printer-info attribute */ smb_enabled, /* smb-enabled attribute */ secure; /* security-enabled attrib. */ char *httpPath; /* path portion of the printer-uri */ static const char *pattrs[] = /* Requested printer attributes */ { "printer-name", "security-enabled", "printer-info", "smb-enabled" }; request = ippNew(); ippSetOperation(request, IPP_GET_PRINTER_ATTRIBUTES); ippSetRequestId(request, reqId); language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, url); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); /* * Do the request and get back a response... */ if ((httpPath = strstr(url,"://")) == NULL || (httpPath = strchr(httpPath+3,'/')) == NULL) { ippDelete(request); request = NULL; goto out; } if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { ipp_status_t lastErr = cupsLastError(); /* * Ignore printers that cannot be queried without credentials */ if (lastErr == IPP_FORBIDDEN || lastErr == IPP_NOT_AUTHENTICATED || lastErr == IPP_NOT_AUTHORIZED) goto out; DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(lastErr))); goto out; } for (attr = ippFirstAttribute(response); attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && ippGetGroupTag(attr) != IPP_TAG_PRINTER) attr = ippNextAttribute(response); if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; smb_enabled= 1; secure = 0; while (attr != NULL && ippGetGroupTag(attr) == IPP_TAG_PRINTER) { if (strcmp(ippGetName(attr), "printer-name") == 0 && ippGetValueTag(attr) == IPP_TAG_NAME) name = ippGetString(attr, 0, NULL); if (strcmp(ippGetName(attr), "printer-info") == 0 && (ippGetValueTag(attr) == IPP_TAG_TEXT || ippGetValueTag(attr) == IPP_TAG_TEXTLANG)) info = ippGetString(attr, 0, NULL); /* * If the smb-enabled attribute is present and the * value is set to 0, don't show the printer. * If the attribute is not present, assume that the * printer should show up */ if (!strcmp(ippGetName(attr), "smb-enabled") && ((ippGetValueTag(attr) == IPP_TAG_INTEGER && !ippGetInteger(attr, 0)) || (ippGetValueTag(attr) == IPP_TAG_BOOLEAN && !ippGetBoolean(attr, 0)))) smb_enabled = 0; /* * If the security-enabled attribute is present and the * value is set to 1, don't show the printer. * If the attribute is not present, assume that the * printer should show up */ if (!strcmp(ippGetName(attr), "security-enabled") && ((ippGetValueTag(attr) == IPP_TAG_INTEGER && ippGetInteger(attr, 0)) || (ippGetValueTag(attr) == IPP_TAG_BOOLEAN && ippGetBoolean(attr, 0)))) secure = 1; attr = ippNextAttribute(response); } /* * See if we have everything needed... * Make sure the printer is not a secure printer * and make sure smb printing hasn't been explicitly * disabled for the printer */ if (name != NULL && !secure && smb_enabled) pcap_cache_add(name, info, NULL); } out: if (response) ippDelete(response); return(0); }