static void cups_read_client_conf( cups_file_t *fp, /* I - File to read */ _cups_client_conf_t *cc) /* I - client.conf values */ { int linenum; /* Current line number */ char line[1024], /* Line from file */ *value; /* Pointer into line */ /* * Read from the file... */ linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { if (!_cups_strcasecmp(line, "Encryption") && value) cups_set_encryption(cc, value); #ifndef __APPLE__ /* * The ServerName directive is not supported on macOS due to app * sandboxing restrictions, i.e. not all apps request network access. */ else if (!_cups_strcasecmp(line, "ServerName") && value) cups_set_server_name(cc, value); #endif /* !__APPLE__ */ else if (!_cups_strcasecmp(line, "User") && value) cups_set_user(cc, value); else if (!_cups_strcasecmp(line, "TrustOnFirstUse") && value) cc->trust_first = cups_boolean_value(value); else if (!_cups_strcasecmp(line, "AllowAnyRoot") && value) cc->any_root = cups_boolean_value(value); else if (!_cups_strcasecmp(line, "AllowExpiredCerts") && value) cc->expired_certs = cups_boolean_value(value); else if (!_cups_strcasecmp(line, "ValidateCerts") && value) cc->validate_certs = cups_boolean_value(value); #ifdef HAVE_GSSAPI else if (!_cups_strcasecmp(line, "GSSServiceName") && value) cups_set_gss_service_name(cc, value); #endif /* HAVE_GSSAPI */ #ifdef HAVE_SSL else if (!_cups_strcasecmp(line, "SSLOptions") && value) cups_set_ssl_options(cc, value); #endif /* HAVE_SSL */ } }
const char * /* O - Default community name */ _cupsSNMPDefaultCommunity(void) { cups_file_t *fp; /* snmp.conf file */ char line[1024], /* Line from file */ *value; /* Value from file */ int linenum; /* Line number in file */ _cups_globals_t *cg = _cupsGlobals(); /* Global data */ DEBUG_puts("4_cupsSNMPDefaultCommunity()"); if (!cg->snmp_community[0]) { strlcpy(cg->snmp_community, "public", sizeof(cg->snmp_community)); snprintf(line, sizeof(line), "%s/snmp.conf", cg->cups_serverroot); if ((fp = cupsFileOpen(line, "r")) != NULL) { linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) if (!_cups_strcasecmp(line, "Community") && value) { strlcpy(cg->snmp_community, value, sizeof(cg->snmp_community)); break; } cupsFileClose(fp); } } DEBUG_printf(("5_cupsSNMPDefaultCommunity: Returning \"%s\"", cg->snmp_community)); return (cg->snmp_community); }
static int /* O - Status */ read_write_tests(int compression) /* I - Use compression? */ { int i; /* Looping var */ cups_file_t *fp; /* File */ int status; /* Exit status */ char line[1024], /* Line from file */ *value; /* Directive value from line */ int linenum; /* Line number */ unsigned char readbuf[8192], /* Read buffer */ writebuf[8192]; /* Write buffer */ int byte; /* Byte from file */ off_t length; /* Length of file */ static const char *partial_line = "partial line"; /* Partial line */ /* * No errors so far... */ status = 0; /* * Initialize the write buffer with random data... */ CUPS_SRAND((unsigned)time(NULL)); for (i = 0; i < (int)sizeof(writebuf); i ++) writebuf[i] = CUPS_RAND(); /* * cupsFileOpen(write) */ printf("cupsFileOpen(write%s): ", compression ? " compressed" : ""); fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat", compression ? "w9" : "w"); if (fp) { puts("PASS"); /* * cupsFileCompression() */ fputs("cupsFileCompression(): ", stdout); if (cupsFileCompression(fp) == compression) puts("PASS"); else { printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp), compression); status ++; } /* * cupsFilePuts() */ fputs("cupsFilePuts(): ", stdout); if (cupsFilePuts(fp, "# Hello, World\n") > 0) puts("PASS"); else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFilePrintf() */ fputs("cupsFilePrintf(): ", stdout); for (i = 0; i < 1000; i ++) if (cupsFilePrintf(fp, "TestLine %03d\n", i) < 0) break; if (i >= 1000) puts("PASS"); else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFilePutChar() */ fputs("cupsFilePutChar(): ", stdout); for (i = 0; i < 256; i ++) if (cupsFilePutChar(fp, i) < 0) break; if (i >= 256) puts("PASS"); else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFileWrite() */ fputs("cupsFileWrite(): ", stdout); for (i = 0; i < 10000; i ++) if (cupsFileWrite(fp, (char *)writebuf, sizeof(writebuf)) < 0) break; if (i >= 10000) puts("PASS"); else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFilePuts() with partial line... */ fputs("cupsFilePuts(\"partial line\"): ", stdout); if (cupsFilePuts(fp, partial_line) > 0) puts("PASS"); else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFileTell() */ fputs("cupsFileTell(): ", stdout); if ((length = cupsFileTell(fp)) == 81933283) puts("PASS"); else { printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length); status ++; } /* * cupsFileClose() */ fputs("cupsFileClose(): ", stdout); if (!cupsFileClose(fp)) puts("PASS"); else { printf("FAIL (%s)\n", strerror(errno)); status ++; } } else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFileOpen(read) */ fputs("\ncupsFileOpen(read): ", stdout); fp = cupsFileOpen(compression ? "testfile.dat.gz" : "testfile.dat", "r"); if (fp) { puts("PASS"); /* * cupsFileGets() */ fputs("cupsFileGets(): ", stdout); if (cupsFileGets(fp, line, sizeof(line))) { if (line[0] == '#') puts("PASS"); else { printf("FAIL (Got line \"%s\", expected comment line)\n", line); status ++; } } else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFileCompression() */ fputs("cupsFileCompression(): ", stdout); if (cupsFileCompression(fp) == compression) puts("PASS"); else { printf("FAIL (Got %d, expected %d)\n", cupsFileCompression(fp), compression); status ++; } /* * cupsFileGetConf() */ linenum = 1; fputs("cupsFileGetConf(): ", stdout); for (i = 0; i < 1000; i ++) if (!cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) break; else if (_cups_strcasecmp(line, "TestLine") || !value || atoi(value) != i || linenum != (i + 2)) break; if (i >= 1000) puts("PASS"); else if (line[0]) { printf("FAIL (Line %d, directive \"%s\", value \"%s\")\n", linenum, line, value ? value : "(null)"); status ++; } else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFileGetChar() */ fputs("cupsFileGetChar(): ", stdout); for (i = 0; i < 256; i ++) if ((byte = cupsFileGetChar(fp)) != i) break; if (i >= 256) puts("PASS"); else if (byte >= 0) { printf("FAIL (Got %d, expected %d)\n", byte, i); status ++; } else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFileRead() */ fputs("cupsFileRead(): ", stdout); for (i = 0; i < 10000; i ++) if ((byte = cupsFileRead(fp, (char *)readbuf, sizeof(readbuf))) < 0) break; else if (memcmp(readbuf, writebuf, sizeof(readbuf))) break; if (i >= 10000) puts("PASS"); else if (byte > 0) { printf("FAIL (Pass %d, ", i); for (i = 0; i < (int)sizeof(readbuf); i ++) if (readbuf[i] != writebuf[i]) break; printf("match failed at offset %d - got %02X, expected %02X)\n", i, readbuf[i], writebuf[i]); } else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * cupsFileGetChar() with partial line... */ fputs("cupsFileGetChar(partial line): ", stdout); for (i = 0; i < (int)strlen(partial_line); i ++) if ((byte = cupsFileGetChar(fp)) < 0) break; else if (byte != partial_line[i]) break; if (!partial_line[i]) puts("PASS"); else { printf("FAIL (got '%c', expected '%c')\n", byte, partial_line[i]); status ++; } /* * cupsFileTell() */ fputs("cupsFileTell(): ", stdout); if ((length = cupsFileTell(fp)) == 81933283) puts("PASS"); else { printf("FAIL (" CUPS_LLFMT " instead of 81933283)\n", CUPS_LLCAST length); status ++; } /* * cupsFileClose() */ fputs("cupsFileClose(): ", stdout); if (!cupsFileClose(fp)) puts("PASS"); else { printf("FAIL (%s)\n", strerror(errno)); status ++; } } else { printf("FAIL (%s)\n", strerror(errno)); status ++; } /* * Remove the test file... */ unlink(compression ? "testfile.dat.gz" : "testfile.dat"); /* * Return the test status... */ return (status); }
static void read_snmp_conf(const char *address) /* I - Single address to probe */ { cups_file_t *fp; /* File pointer */ char filename[1024], /* Filename */ line[1024], /* Line from file */ *value; /* Value on line */ int linenum; /* Line number */ const char *cups_serverroot; /* CUPS_SERVERROOT env var */ const char *debug; /* CUPS_DEBUG_LEVEL env var */ const char *runtime; /* CUPS_MAX_RUN_TIME env var */ /* * Initialize the global address and community lists... */ Addresses = cupsArrayNew(NULL, NULL); Communities = cupsArrayNew(NULL, NULL); if (address) add_array(Addresses, address); if ((debug = getenv("CUPS_DEBUG_LEVEL")) != NULL) DebugLevel = atoi(debug); if ((runtime = getenv("CUPS_MAX_RUN_TIME")) != NULL) MaxRunTime = atoi(runtime); /* * Find the snmp.conf file... */ if ((cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL) cups_serverroot = CUPS_SERVERROOT; snprintf(filename, sizeof(filename), "%s/snmp.conf", cups_serverroot); if ((fp = cupsFileOpen(filename, "r")) != NULL) { /* * Read the snmp.conf file... */ linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { if (!value) fprintf(stderr, "ERROR: Missing value on line %d of %s!\n", linenum, filename); else if (!_cups_strcasecmp(line, "Address")) { if (!address) add_array(Addresses, value); } else if (!_cups_strcasecmp(line, "Community")) add_array(Communities, value); else if (!_cups_strcasecmp(line, "DebugLevel")) DebugLevel = atoi(value); else if (!_cups_strcasecmp(line, "DeviceURI")) { if (*value != '\"') fprintf(stderr, "ERROR: Missing double quote for regular expression on " "line %d of %s!\n", linenum, filename); else add_device_uri(value); } else if (!_cups_strcasecmp(line, "HostNameLookups")) HostNameLookups = !_cups_strcasecmp(value, "on") || !_cups_strcasecmp(value, "yes") || !_cups_strcasecmp(value, "true") || !_cups_strcasecmp(value, "double"); else if (!_cups_strcasecmp(line, "MaxRunTime")) MaxRunTime = atoi(value); else fprintf(stderr, "ERROR: Unknown directive %s on line %d of %s!\n", line, linenum, filename); } cupsFileClose(fp); } /* * Use defaults if parameters are undefined... */ if (cupsArrayCount(Addresses) == 0) { /* * If we have no addresses, exit immediately... */ fprintf(stderr, "DEBUG: No address specified and no Address line in %s...\n", filename); exit(0); } if (cupsArrayCount(Communities) == 0) { fputs("INFO: Using default SNMP Community public\n", stderr); add_array(Communities, "public"); } }
void cupsdLoadAllSubscriptions(void) { int i; /* Looping var */ cups_file_t *fp; /* subscriptions.conf file */ int linenum; /* Current line number */ char line[1024], /* Line from file */ *value, /* Pointer to value */ *valueptr; /* Pointer into value */ cupsd_subscription_t *sub; /* Current subscription */ int hex; /* Non-zero if reading hex data */ int delete_sub; /* Delete subscription? */ /* * Open the subscriptions.conf file... */ snprintf(line, sizeof(line), "%s/subscriptions.conf", ServerRoot); if ((fp = cupsdOpenConfFile(line)) == NULL) return; /* * Read all of the lines from the file... */ linenum = 0; sub = NULL; delete_sub = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { if (!_cups_strcasecmp(line, "NextSubscriptionId") && value) { /* * NextSubscriptionId NNN */ i = atoi(value); if (i >= NextSubscriptionId && i > 0) NextSubscriptionId = i; } else if (!_cups_strcasecmp(line, "<Subscription")) { /* * <Subscription #> */ if (!sub && value && isdigit(value[0] & 255)) { sub = cupsdAddSubscription(CUPSD_EVENT_NONE, NULL, NULL, NULL, atoi(value)); } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "</Subscription>")) { if (!sub) { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } if (delete_sub) cupsdDeleteSubscription(sub, 0); sub = NULL; delete_sub = 0; } else if (!sub) { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); } else if (!_cups_strcasecmp(line, "Events")) { /* * Events name * Events name name name ... */ if (!value) { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } while (*value) { /* * Separate event names... */ for (valueptr = value; !isspace(*valueptr) && *valueptr; valueptr ++); while (isspace(*valueptr & 255)) *valueptr++ = '\0'; /* * See if the name exists... */ if ((sub->mask |= cupsdEventValue(value)) == CUPSD_EVENT_NONE) { cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown event name \'%s\' on line %d of subscriptions.conf.", value, linenum); break; } value = valueptr; } } else if (!_cups_strcasecmp(line, "Owner")) { /* * Owner */ if (value) cupsdSetString(&sub->owner, value); else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "Recipient")) { /* * Recipient uri */ if (value) cupsdSetString(&sub->recipient, value); else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "JobId")) { /* * JobId # */ if (value && isdigit(*value & 255)) { if ((sub->job = cupsdFindJob(atoi(value))) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "Job %s not found on line %d of subscriptions.conf.", value, linenum); delete_sub = 1; } } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "PrinterName")) { /* * PrinterName name */ if (value) { if ((sub->dest = cupsdFindDest(value)) == NULL) { cupsdLogMessage(CUPSD_LOG_ERROR, "Printer \'%s\' not found on line %d of subscriptions.conf.", value, linenum); delete_sub = 1; } } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "UserData")) { /* * UserData encoded-string */ if (value) { for (i = 0, valueptr = value, hex = 0; i < 63 && *valueptr; i ++) { if (*valueptr == '<' && !hex) { hex = 1; valueptr ++; } if (hex) { if (isxdigit(valueptr[0]) && isxdigit(valueptr[1])) { if (isdigit(valueptr[0])) sub->user_data[i] = (unsigned char)((valueptr[0] - '0') << 4); else sub->user_data[i] = (unsigned char)((tolower(valueptr[0]) - 'a' + 10) << 4); if (isdigit(valueptr[1])) sub->user_data[i] |= valueptr[1] - '0'; else sub->user_data[i] |= tolower(valueptr[1]) - 'a' + 10; valueptr += 2; if (*valueptr == '>') { hex = 0; valueptr ++; } } else break; } else sub->user_data[i] = (unsigned char)*valueptr++; } if (*valueptr) { cupsdLogMessage(CUPSD_LOG_ERROR, "Bad UserData \'%s\' on line %d of subscriptions.conf.", value, linenum); } else sub->user_data_len = i; } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "LeaseDuration")) { /* * LeaseDuration # */ if (value && isdigit(*value & 255)) { sub->lease = atoi(value); sub->expire = sub->lease ? time(NULL) + sub->lease : 0; } else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "Interval")) { /* * Interval # */ if (value && isdigit(*value & 255)) sub->interval = atoi(value); else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "ExpirationTime")) { /* * ExpirationTime # */ if (value && isdigit(*value & 255)) sub->expire = atoi(value); else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else if (!_cups_strcasecmp(line, "NextEventId")) { /* * NextEventId # */ if (value && isdigit(*value & 255)) sub->next_event_id = sub->first_event_id = atoi(value); else { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of subscriptions.conf.", linenum); break; } } else { /* * Something else we don't understand... */ cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown configuration directive %s on line %d of subscriptions.conf.", line, linenum); } } cupsFileClose(fp); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { int status = 0; /* Exit status */ cups_file_t *fp; /* Command file */ char line[1024], /* Line from file */ *value; /* Value on line */ int linenum; /* Line number in file */ ppd_file_t *ppd; /* PPD file */ /* * Check for valid arguments... */ if (argc < 6 || argc > 7) { /* * We don't have the correct number of arguments; write an error message * and return. */ _cupsLangPrintf(stderr, _("Usage: %s job-id user title copies options [file]"), argv[0]); return (1); } /* * Open the PPD file... */ if ((ppd = ppdOpenFile(getenv("PPD"))) == NULL) { fputs("ERROR: Unable to open PPD file!\n", stderr); return (1); } /* * Open the command file as needed... */ if (argc == 7) { if ((fp = cupsFileOpen(argv[6], "r")) == NULL) { perror("ERROR: Unable to open command file - "); return (1); } } else fp = cupsFileStdin(); /* * Read the commands from the file and send the appropriate commands... */ linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { /* * Parse the command... */ if (!_cups_strcasecmp(line, "AutoConfigure")) status |= auto_configure(ppd, argv[2]); else if (!_cups_strcasecmp(line, "PrintSelfTestPage")) print_self_test_page(ppd, argv[2]); else if (!_cups_strcasecmp(line, "ReportLevels")) report_levels(ppd, argv[2]); else { _cupsLangPrintFilter(stderr, "ERROR", _("Invalid printer command \"%s\"."), line); status = 1; } } return (status); }
static int /* O - Number of options or -1 on error */ get_printer(http_t *http, /* I - HTTP connection */ const char *name, /* I - Printer name from request */ char *dest, /* I - Destination buffer */ size_t destsize, /* I - Size of destination buffer */ cups_option_t **options, /* O - Printer options */ int *accepting, /* O - printer-is-accepting-jobs value */ int *shared, /* O - printer-is-shared value */ ipp_pstate_t *state) /* O - printer-state value */ { int num_options; /* Number of options */ cups_file_t *fp; /* lpoptions file */ char line[1024], /* Line from lpoptions file */ *value, /* Pointer to value on line */ *optptr; /* Pointer to options on line */ int linenum; /* Line number in file */ const char *cups_serverroot; /* CUPS_SERVERROOT env var */ ipp_t *request; /* IPP request */ ipp_t *response; /* IPP response */ ipp_attribute_t *attr; /* IPP attribute */ char uri[HTTP_MAX_URI]; /* Printer URI */ static const char * const requested[] = { /* Requested attributes */ "printer-info", "printer-is-accepting-jobs", "printer-is-shared", "printer-name", "printer-state" }; /* * Initialize everything... */ if (accepting) *accepting = 0; if (shared) *shared = 0; if (state) *state = IPP_PRINTER_STOPPED; if (options) *options = NULL; /* * See if the name is a queue name optionally with an instance name. */ strlcpy(dest, name, destsize); if ((value = strchr(dest, '/')) != NULL) *value = '\0'; /* * Setup the Get-Printer-Attributes request... */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", dest); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request... */ response = cupsDoRequest(http, request, "/"); if (!response || cupsLastError() > IPP_OK_CONFLICT) { /* * If we can't find the printer by name, look up the printer-name * using the printer-info values... */ ipp_attribute_t *accepting_attr,/* printer-is-accepting-jobs */ *info_attr, /* printer-info */ *name_attr, /* printer-name */ *shared_attr, /* printer-is-shared */ *state_attr; /* printer-state */ ippDelete(response); /* * Setup the CUPS-Get-Printers request... */ request = ippNewRequest(CUPS_GET_PRINTERS); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (int)(sizeof(requested) / sizeof(requested[0])), NULL, requested); /* * Do the request... */ response = cupsDoRequest(http, request, "/"); if (!response || cupsLastError() > IPP_OK_CONFLICT) { syslog(LOG_ERR, "Unable to get list of printers - %s", cupsLastErrorString()); ippDelete(response); return (-1); } /* * Scan the response for printers... */ *dest = '\0'; attr = response->attrs; while (attr) { /* * Skip to the next printer... */ while (attr && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (!attr) break; /* * Get all of the attributes for the current printer... */ accepting_attr = NULL; info_attr = NULL; name_attr = NULL; shared_attr = NULL; state_attr = NULL; while (attr && attr->group_tag == IPP_TAG_PRINTER) { if (!strcmp(attr->name, "printer-is-accepting-jobs") && attr->value_tag == IPP_TAG_BOOLEAN) accepting_attr = attr; else if (!strcmp(attr->name, "printer-info") && attr->value_tag == IPP_TAG_TEXT) info_attr = attr; else if (!strcmp(attr->name, "printer-name") && attr->value_tag == IPP_TAG_NAME) name_attr = attr; else if (!strcmp(attr->name, "printer-is-shared") && attr->value_tag == IPP_TAG_BOOLEAN) shared_attr = attr; else if (!strcmp(attr->name, "printer-state") && attr->value_tag == IPP_TAG_ENUM) state_attr = attr; attr = attr->next; } if (info_attr && name_attr && !_cups_strcasecmp(name, info_attr->values[0].string.text)) { /* * Found a match, use this one! */ strlcpy(dest, name_attr->values[0].string.text, destsize); if (accepting && accepting_attr) *accepting = accepting_attr->values[0].boolean; if (shared && shared_attr) *shared = shared_attr->values[0].boolean; if (state && state_attr) *state = (ipp_pstate_t)state_attr->values[0].integer; break; } } ippDelete(response); if (!*dest) { syslog(LOG_ERR, "Unable to find \"%s\" in list of printers!", name); return (-1); } name = dest; } else { /* * Get values from the response... */ if (accepting) { if ((attr = ippFindAttribute(response, "printer-is-accepting-jobs", IPP_TAG_BOOLEAN)) == NULL) syslog(LOG_ERR, "No printer-is-accepting-jobs attribute found in " "response from server!"); else *accepting = attr->values[0].boolean; } if (shared) { if ((attr = ippFindAttribute(response, "printer-is-shared", IPP_TAG_BOOLEAN)) == NULL) { syslog(LOG_ERR, "No printer-is-shared attribute found in " "response from server!"); *shared = 1; } else *shared = attr->values[0].boolean; } if (state) { if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) == NULL) syslog(LOG_ERR, "No printer-state attribute found in " "response from server!"); else *state = (ipp_pstate_t)attr->values[0].integer; } ippDelete(response); } /* * Next look for the printer in the lpoptions file... */ num_options = 0; if (options && shared && accepting) { if ((cups_serverroot = getenv("CUPS_SERVERROOT")) == NULL) cups_serverroot = CUPS_SERVERROOT; snprintf(line, sizeof(line), "%s/lpoptions", cups_serverroot); if ((fp = cupsFileOpen(line, "r")) != NULL) { linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { /* * Make sure we have "Dest name options" or "Default name options"... */ if ((_cups_strcasecmp(line, "Dest") && _cups_strcasecmp(line, "Default")) || !value) continue; /* * Separate destination name from options... */ for (optptr = value; *optptr && !isspace(*optptr & 255); optptr ++); while (*optptr == ' ') *optptr++ = '\0'; /* * If this is our destination, parse the options and break out of * the loop - we're done! */ if (!_cups_strcasecmp(value, name)) { num_options = cupsParseOptions(optptr, num_options, options); break; } } cupsFileClose(fp); } } else if (options) *options = NULL; /* * Return the number of options for this destination... */ return (num_options); }
int /* O - 1 on success, 0 on failure */ cupsAdminSetServerSettings( http_t *http, /* I - Connection to server or @code CUPS_HTTP_DEFAULT@ */ int num_settings, /* I - Number of settings */ cups_option_t *settings) /* I - Settings */ { int i; /* Looping var */ http_status_t status; /* GET/PUT status */ const char *server_port_env; /* SERVER_PORT env var */ int server_port; /* IPP port for server */ cups_file_t *cupsd; /* cupsd.conf file */ char cupsdconf[1024]; /* cupsd.conf filename */ int remote; /* Remote cupsd.conf file? */ char tempfile[1024]; /* Temporary new cupsd.conf */ cups_file_t *temp; /* Temporary file */ char line[1024], /* Line from cupsd.conf file */ *value; /* Value on line */ int linenum, /* Line number in file */ in_location, /* In a location section? */ in_policy, /* In a policy section? */ in_default_policy, /* In the default policy section? */ in_cancel_job, /* In a cancel-job section? */ in_admin_location, /* In the /admin location? */ in_conf_location, /* In the /admin/conf location? */ in_log_location, /* In the /admin/log location? */ in_root_location; /* In the / location? */ const char *val; /* Setting value */ int share_printers, /* Share local printers */ remote_admin, /* Remote administration allowed? */ remote_any, /* Remote access from anywhere? */ user_cancel_any, /* Cancel-job policy set? */ debug_logging; /* LogLevel debug set? */ int wrote_port_listen, /* Wrote the port/listen lines? */ wrote_browsing, /* Wrote the browsing lines? */ wrote_policy, /* Wrote the policy? */ wrote_loglevel, /* Wrote the LogLevel line? */ wrote_admin_location, /* Wrote the /admin location? */ wrote_conf_location, /* Wrote the /admin/conf location? */ wrote_log_location, /* Wrote the /admin/log location? */ wrote_root_location; /* Wrote the / location? */ int indent; /* Indentation */ int cupsd_num_settings; /* New number of settings */ int old_share_printers, /* Share local printers */ old_remote_admin, /* Remote administration allowed? */ old_remote_any, /* Remote access from anywhere? */ old_user_cancel_any, /* Cancel-job policy set? */ old_debug_logging; /* LogLevel debug set? */ cups_option_t *cupsd_settings, /* New settings */ *setting; /* Current setting */ _cups_globals_t *cg = _cupsGlobals(); /* Global data */ /* * Range check input... */ if (!http) http = _cupsConnect(); if (!http || !num_settings || !settings) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, strerror(EINVAL), 0); return (0); } /* * Get the cupsd.conf file... */ if (get_cupsd_conf(http, cg, 0, cupsdconf, sizeof(cupsdconf), &remote) == HTTP_STATUS_OK) { if ((cupsd = cupsFileOpen(cupsdconf, "r")) == NULL) { _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0); return (0); } } else return (0); /* * Get current settings... */ if (!cupsAdminGetServerSettings(http, &cupsd_num_settings, &cupsd_settings)) return (0); if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, cupsd_num_settings, cupsd_settings)) != NULL) old_debug_logging = atoi(val); else old_debug_logging = 0; DEBUG_printf(("1cupsAdminSetServerSettings: old debug_logging=%d", old_debug_logging)); if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, cupsd_num_settings, cupsd_settings)) != NULL) old_remote_admin = atoi(val); else old_remote_admin = 0; DEBUG_printf(("1cupsAdminSetServerSettings: old remote_admin=%d", old_remote_admin)); if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, cupsd_num_settings, cupsd_settings)) != NULL) old_remote_any = atoi(val); else old_remote_any = 0; DEBUG_printf(("1cupsAdminSetServerSettings: old remote_any=%d", old_remote_any)); if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, cupsd_num_settings, cupsd_settings)) != NULL) old_share_printers = atoi(val); else old_share_printers = 0; DEBUG_printf(("1cupsAdminSetServerSettings: old share_printers=%d", old_share_printers)); if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, cupsd_num_settings, cupsd_settings)) != NULL) old_user_cancel_any = atoi(val); else old_user_cancel_any = 0; DEBUG_printf(("1cupsAdminSetServerSettings: old user_cancel_any=%d", old_user_cancel_any)); cupsFreeOptions(cupsd_num_settings, cupsd_settings); /* * Get basic settings... */ if ((val = cupsGetOption(CUPS_SERVER_DEBUG_LOGGING, num_settings, settings)) != NULL) { debug_logging = atoi(val); if (debug_logging == old_debug_logging) { /* * No change to this setting... */ debug_logging = -1; } } else debug_logging = -1; DEBUG_printf(("1cupsAdminSetServerSettings: debug_logging=%d", debug_logging)); if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ANY, num_settings, settings)) != NULL) { remote_any = atoi(val); if (remote_any == old_remote_any) { /* * No change to this setting... */ remote_any = -1; } } else remote_any = -1; DEBUG_printf(("1cupsAdminSetServerSettings: remote_any=%d", remote_any)); if ((val = cupsGetOption(CUPS_SERVER_REMOTE_ADMIN, num_settings, settings)) != NULL) { remote_admin = atoi(val); if (remote_admin == old_remote_admin) { /* * No change to this setting... */ remote_admin = -1; } } else remote_admin = -1; DEBUG_printf(("1cupsAdminSetServerSettings: remote_admin=%d", remote_admin)); if ((val = cupsGetOption(CUPS_SERVER_SHARE_PRINTERS, num_settings, settings)) != NULL) { share_printers = atoi(val); if (share_printers == old_share_printers) { /* * No change to this setting... */ share_printers = -1; } } else share_printers = -1; DEBUG_printf(("1cupsAdminSetServerSettings: share_printers=%d", share_printers)); if ((val = cupsGetOption(CUPS_SERVER_USER_CANCEL_ANY, num_settings, settings)) != NULL) { user_cancel_any = atoi(val); if (user_cancel_any == old_user_cancel_any) { /* * No change to this setting... */ user_cancel_any = -1; } } else user_cancel_any = -1; DEBUG_printf(("1cupsAdminSetServerSettings: user_cancel_any=%d", user_cancel_any)); /* * Create a temporary file for the new cupsd.conf file... */ if ((temp = cupsTempFile2(tempfile, sizeof(tempfile))) == NULL) { cupsFileClose(cupsd); if (remote) unlink(cupsdconf); _cupsSetError(IPP_STATUS_ERROR_INTERNAL, NULL, 0); return (0); } /* * Copy the old file to the new, making changes along the way... */ cupsd_num_settings = 0; in_admin_location = 0; in_cancel_job = 0; in_conf_location = 0; in_default_policy = 0; in_location = 0; in_log_location = 0; in_policy = 0; in_root_location = 0; linenum = 0; wrote_admin_location = 0; wrote_browsing = 0; wrote_conf_location = 0; wrote_log_location = 0; wrote_loglevel = 0; wrote_policy = 0; wrote_port_listen = 0; wrote_root_location = 0; indent = 0; if ((server_port_env = getenv("SERVER_PORT")) != NULL) { if ((server_port = atoi(server_port_env)) <= 0) server_port = ippPort(); } else server_port = ippPort(); if (server_port <= 0) server_port = IPP_PORT; while (cupsFileGetConf(cupsd, line, sizeof(line), &value, &linenum)) { if ((!_cups_strcasecmp(line, "Port") || !_cups_strcasecmp(line, "Listen")) && (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0)) { if (!wrote_port_listen) { wrote_port_listen = 1; if (remote_admin > 0 || remote_any > 0 || share_printers > 0) { cupsFilePuts(temp, "# Allow remote access\n"); cupsFilePrintf(temp, "Port %d\n", server_port); } else { cupsFilePuts(temp, "# Only listen for connections from the local " "machine.\n"); cupsFilePrintf(temp, "Listen localhost:%d\n", server_port); } #ifdef CUPS_DEFAULT_DOMAINSOCKET if ((!value || strcmp(CUPS_DEFAULT_DOMAINSOCKET, value)) && !access(CUPS_DEFAULT_DOMAINSOCKET, 0)) cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n"); #endif /* CUPS_DEFAULT_DOMAINSOCKET */ } else if (value && value[0] == '/' #ifdef CUPS_DEFAULT_DOMAINSOCKET && strcmp(CUPS_DEFAULT_DOMAINSOCKET, value) #endif /* CUPS_DEFAULT_DOMAINSOCKET */ ) cupsFilePrintf(temp, "Listen %s\n", value); } else if ((!_cups_strcasecmp(line, "Browsing") || !_cups_strcasecmp(line, "BrowseLocalProtocols")) && share_printers >= 0) { if (!wrote_browsing) { int new_share_printers = (share_printers > 0 || (share_printers == -1 && old_share_printers > 0)); wrote_browsing = 1; if (new_share_printers) { const char *localp = cupsGetOption("BrowseLocalProtocols", num_settings, settings); if (!localp || !localp[0]) localp = cupsGetOption("BrowseLocalProtocols", cupsd_num_settings, cupsd_settings); cupsFilePuts(temp, "# Share local printers on the local network.\n"); cupsFilePuts(temp, "Browsing On\n"); if (!localp) localp = CUPS_DEFAULT_BROWSE_LOCAL_PROTOCOLS; cupsFilePrintf(temp, "BrowseLocalProtocols %s\n", localp); cupsd_num_settings = cupsAddOption("BrowseLocalProtocols", localp, cupsd_num_settings, &cupsd_settings); } else { cupsFilePuts(temp, "# Disable printer sharing.\n"); cupsFilePuts(temp, "Browsing Off\n"); } } } else if (!_cups_strcasecmp(line, "LogLevel") && debug_logging >= 0) { wrote_loglevel = 1; if (debug_logging) { cupsFilePuts(temp, "# Show troubleshooting information in error_log.\n"); cupsFilePuts(temp, "LogLevel debug\n"); } else { cupsFilePuts(temp, "# Show general information in error_log.\n"); cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n"); } } else if (!_cups_strcasecmp(line, "<Policy")) { in_default_policy = !_cups_strcasecmp(value, "default"); in_policy = 1; cupsFilePrintf(temp, "%s %s>\n", line, value); indent += 2; } else if (!_cups_strcasecmp(line, "</Policy>")) { indent -= 2; if (!wrote_policy && in_default_policy) { wrote_policy = 1; if (!user_cancel_any) cupsFilePuts(temp, " # Only the owner or an administrator can " "cancel a job...\n" " <Limit Cancel-Job>\n" " Order deny,allow\n" " Require user @OWNER " CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n" " </Limit>\n"); } in_policy = 0; in_default_policy = 0; cupsFilePuts(temp, "</Policy>\n"); } else if (!_cups_strcasecmp(line, "<Location")) { in_location = 1; indent += 2; if (!strcmp(value, "/admin")) in_admin_location = 1; else if (!strcmp(value, "/admin/conf")) in_conf_location = 1; else if (!strcmp(value, "/admin/log")) in_log_location = 1; else if (!strcmp(value, "/")) in_root_location = 1; cupsFilePrintf(temp, "%s %s>\n", line, value); } else if (!_cups_strcasecmp(line, "</Location>")) { in_location = 0; indent -= 2; if (in_admin_location && remote_admin >= 0) { wrote_admin_location = 1; if (remote_admin) cupsFilePuts(temp, " # Allow remote administration...\n"); else if (remote_admin == 0) cupsFilePuts(temp, " # Restrict access to the admin pages...\n"); cupsFilePuts(temp, " Order allow,deny\n"); if (remote_admin) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); } else if (in_conf_location && remote_admin >= 0) { wrote_conf_location = 1; if (remote_admin) cupsFilePuts(temp, " # Allow remote access to the configuration " "files...\n"); else cupsFilePuts(temp, " # Restrict access to the configuration " "files...\n"); cupsFilePuts(temp, " Order allow,deny\n"); if (remote_admin) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); } else if (in_log_location && remote_admin >= 0) { wrote_log_location = 1; if (remote_admin) cupsFilePuts(temp, " # Allow remote access to the log " "files...\n"); else cupsFilePuts(temp, " # Restrict access to the log " "files...\n"); cupsFilePuts(temp, " Order allow,deny\n"); if (remote_admin) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); } else if (in_root_location && (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0)) { wrote_root_location = 1; if (remote_admin > 0 && share_printers > 0) cupsFilePuts(temp, " # Allow shared printing and remote " "administration...\n"); else if (remote_admin > 0) cupsFilePuts(temp, " # Allow remote administration...\n"); else if (share_printers > 0) cupsFilePuts(temp, " # Allow shared printing...\n"); else if (remote_any > 0) cupsFilePuts(temp, " # Allow remote access...\n"); else cupsFilePuts(temp, " # Restrict access to the server...\n"); cupsFilePuts(temp, " Order allow,deny\n"); if (remote_admin > 0 || remote_any > 0 || share_printers > 0) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); } in_admin_location = 0; in_conf_location = 0; in_log_location = 0; in_root_location = 0; cupsFilePuts(temp, "</Location>\n"); } else if (!_cups_strcasecmp(line, "<Limit")) { if (in_default_policy) { /* * See if the policy limit is for the Cancel-Job operation... */ char *valptr; /* Pointer into value */ if (!_cups_strcasecmp(value, "cancel-job") && user_cancel_any >= 0) { /* * Don't write anything for this limit section... */ in_cancel_job = 2; } else { cupsFilePrintf(temp, "%*s%s", indent, "", line); while (*value) { for (valptr = value; *valptr && !_cups_isspace(*valptr); valptr ++); if (*valptr) *valptr++ = '\0'; if (!_cups_strcasecmp(value, "cancel-job") && user_cancel_any >= 0) { /* * Write everything except for this definition... */ in_cancel_job = 1; } else cupsFilePrintf(temp, " %s", value); for (value = valptr; _cups_isspace(*value); value ++); } cupsFilePuts(temp, ">\n"); } } else cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value); indent += 2; } else if (!_cups_strcasecmp(line, "</Limit>") && in_cancel_job) { indent -= 2; if (in_cancel_job == 1) cupsFilePuts(temp, " </Limit>\n"); wrote_policy = 1; if (!user_cancel_any) cupsFilePuts(temp, " # Only the owner or an administrator can cancel " "a job...\n" " <Limit Cancel-Job>\n" " Order deny,allow\n" " Require user @OWNER " CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n" " </Limit>\n"); in_cancel_job = 0; } else if ((((in_admin_location || in_conf_location || in_root_location) && (remote_admin >= 0 || remote_any >= 0)) || (in_root_location && share_printers >= 0)) && (!_cups_strcasecmp(line, "Allow") || !_cups_strcasecmp(line, "Deny") || !_cups_strcasecmp(line, "Order"))) continue; else if (in_cancel_job == 2) continue; else if (line[0] == '<') { if (value) { cupsFilePrintf(temp, "%*s%s %s>\n", indent, "", line, value); indent += 2; } else { if (line[1] == '/') indent -= 2; cupsFilePrintf(temp, "%*s%s\n", indent, "", line); } } else if (!in_policy && !in_location && (val = cupsGetOption(line, num_settings, settings)) != NULL) { /* * Replace this directive's value with the new one... */ cupsd_num_settings = cupsAddOption(line, val, cupsd_num_settings, &cupsd_settings); /* * Write the new value in its place, without indentation since we * only support setting root directives, not in sections... */ cupsFilePrintf(temp, "%s %s\n", line, val); } else if (value) { if (!in_policy && !in_location) { /* * Record the non-policy, non-location directives that we find * in the server settings, since we cache this info and record it * in cupsAdminGetServerSettings()... */ cupsd_num_settings = cupsAddOption(line, value, cupsd_num_settings, &cupsd_settings); } cupsFilePrintf(temp, "%*s%s %s\n", indent, "", line, value); } else cupsFilePrintf(temp, "%*s%s\n", indent, "", line); } /* * Write any missing info... */ if (!wrote_browsing && share_printers >= 0) { if (share_printers > 0) { cupsFilePuts(temp, "# Share local printers on the local network.\n"); cupsFilePuts(temp, "Browsing On\n"); } else { cupsFilePuts(temp, "# Disable printer sharing and shared printers.\n"); cupsFilePuts(temp, "Browsing Off\n"); } } if (!wrote_loglevel && debug_logging >= 0) { if (debug_logging) { cupsFilePuts(temp, "# Show troubleshooting information in error_log.\n"); cupsFilePuts(temp, "LogLevel debug\n"); } else { cupsFilePuts(temp, "# Show general information in error_log.\n"); cupsFilePuts(temp, "LogLevel " CUPS_DEFAULT_LOG_LEVEL "\n"); } } if (!wrote_port_listen && (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0)) { if (remote_admin > 0 || remote_any > 0 || share_printers > 0) { cupsFilePuts(temp, "# Allow remote access\n"); cupsFilePrintf(temp, "Port %d\n", ippPort()); } else { cupsFilePuts(temp, "# Only listen for connections from the local machine.\n"); cupsFilePrintf(temp, "Listen localhost:%d\n", ippPort()); } #ifdef CUPS_DEFAULT_DOMAINSOCKET if (!access(CUPS_DEFAULT_DOMAINSOCKET, 0)) cupsFilePuts(temp, "Listen " CUPS_DEFAULT_DOMAINSOCKET "\n"); #endif /* CUPS_DEFAULT_DOMAINSOCKET */ } if (!wrote_root_location && (remote_admin >= 0 || remote_any >= 0 || share_printers >= 0)) { if (remote_admin > 0 && share_printers > 0) cupsFilePuts(temp, "# Allow shared printing and remote administration...\n"); else if (remote_admin > 0) cupsFilePuts(temp, "# Allow remote administration...\n"); else if (share_printers > 0) cupsFilePuts(temp, "# Allow shared printing...\n"); else if (remote_any > 0) cupsFilePuts(temp, "# Allow remote access...\n"); else cupsFilePuts(temp, "# Restrict access to the server...\n"); cupsFilePuts(temp, "<Location />\n" " Order allow,deny\n"); if (remote_admin > 0 || remote_any > 0 || share_printers > 0) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); cupsFilePuts(temp, "</Location>\n"); } if (!wrote_admin_location && remote_admin >= 0) { if (remote_admin) cupsFilePuts(temp, "# Allow remote administration...\n"); else cupsFilePuts(temp, "# Restrict access to the admin pages...\n"); cupsFilePuts(temp, "<Location /admin>\n" " Order allow,deny\n"); if (remote_admin) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); cupsFilePuts(temp, "</Location>\n"); } if (!wrote_conf_location && remote_admin >= 0) { if (remote_admin) cupsFilePuts(temp, "# Allow remote access to the configuration files...\n"); else cupsFilePuts(temp, "# Restrict access to the configuration files...\n"); cupsFilePuts(temp, "<Location /admin/conf>\n" " AuthType Default\n" " Require user @SYSTEM\n" " Order allow,deny\n"); if (remote_admin) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); cupsFilePuts(temp, "</Location>\n"); } if (!wrote_log_location && remote_admin >= 0) { if (remote_admin) cupsFilePuts(temp, "# Allow remote access to the log files...\n"); else cupsFilePuts(temp, "# Restrict access to the log files...\n"); cupsFilePuts(temp, "<Location /admin/log>\n" " AuthType Default\n" " Require user @SYSTEM\n" " Order allow,deny\n"); if (remote_admin) cupsFilePrintf(temp, " Allow %s\n", remote_any > 0 ? "all" : "@LOCAL"); cupsFilePuts(temp, "</Location>\n"); } if (!wrote_policy && user_cancel_any >= 0) { cupsFilePuts(temp, "<Policy default>\n" " # Job-related operations must be done by the owner " "or an administrator...\n" " <Limit Send-Document Send-URI Hold-Job Release-Job " "Restart-Job Purge-Jobs Set-Job-Attributes " "Create-Job-Subscription Renew-Subscription " "Cancel-Subscription Get-Notifications Reprocess-Job " "Cancel-Current-Job Suspend-Current-Job Resume-Job " "CUPS-Move-Job>\n" " Require user @OWNER @SYSTEM\n" " Order deny,allow\n" " </Limit>\n" " # All administration operations require an " "administrator to authenticate...\n" " <Limit Pause-Printer Resume-Printer " "Set-Printer-Attributes Enable-Printer " "Disable-Printer Pause-Printer-After-Current-Job " "Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer " "Activate-Printer Restart-Printer Shutdown-Printer " "Startup-Printer Promote-Job Schedule-Job-After " "CUPS-Add-Printer CUPS-Delete-Printer " "CUPS-Add-Class CUPS-Delete-Class " "CUPS-Accept-Jobs CUPS-Reject-Jobs " "CUPS-Set-Default CUPS-Add-Device CUPS-Delete-Device>\n" " AuthType Default\n" " Require user @SYSTEM\n" " Order deny,allow\n" "</Limit>\n"); if (!user_cancel_any) cupsFilePuts(temp, " # Only the owner or an administrator can cancel " "a job...\n" " <Limit Cancel-Job>\n" " Order deny,allow\n" " Require user @OWNER " CUPS_DEFAULT_PRINTOPERATOR_AUTH "\n" " </Limit>\n"); cupsFilePuts(temp, " <Limit All>\n" " Order deny,allow\n" " </Limit>\n" "</Policy>\n"); } for (i = num_settings, setting = settings; i > 0; i --, setting ++) if (setting->name[0] != '_' && _cups_strcasecmp(setting->name, "Listen") && _cups_strcasecmp(setting->name, "Port") && !cupsGetOption(setting->name, cupsd_num_settings, cupsd_settings)) { /* * Add this directive to the list of directives we have written... */ cupsd_num_settings = cupsAddOption(setting->name, setting->value, cupsd_num_settings, &cupsd_settings); /* * Write the new value, without indentation since we only support * setting root directives, not in sections... */ cupsFilePrintf(temp, "%s %s\n", setting->name, setting->value); } cupsFileClose(cupsd); cupsFileClose(temp); /* * Upload the configuration file to the server... */ status = cupsPutFile(http, "/admin/conf/cupsd.conf", tempfile); if (status == HTTP_STATUS_CREATED) { /* * Updated OK, add the basic settings... */ if (debug_logging >= 0) cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, debug_logging ? "1" : "0", cupsd_num_settings, &cupsd_settings); else cupsd_num_settings = cupsAddOption(CUPS_SERVER_DEBUG_LOGGING, old_debug_logging ? "1" : "0", cupsd_num_settings, &cupsd_settings); if (remote_admin >= 0) cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, remote_admin ? "1" : "0", cupsd_num_settings, &cupsd_settings); else cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ADMIN, old_remote_admin ? "1" : "0", cupsd_num_settings, &cupsd_settings); if (remote_any >= 0) cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, remote_any ? "1" : "0", cupsd_num_settings, &cupsd_settings); else cupsd_num_settings = cupsAddOption(CUPS_SERVER_REMOTE_ANY, old_remote_any ? "1" : "0", cupsd_num_settings, &cupsd_settings); if (share_printers >= 0) cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, share_printers ? "1" : "0", cupsd_num_settings, &cupsd_settings); else cupsd_num_settings = cupsAddOption(CUPS_SERVER_SHARE_PRINTERS, old_share_printers ? "1" : "0", cupsd_num_settings, &cupsd_settings); if (user_cancel_any >= 0) cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, user_cancel_any ? "1" : "0", cupsd_num_settings, &cupsd_settings); else cupsd_num_settings = cupsAddOption(CUPS_SERVER_USER_CANCEL_ANY, old_user_cancel_any ? "1" : "0", cupsd_num_settings, &cupsd_settings); /* * Save the new values... */ invalidate_cupsd_cache(cg); cg->cupsd_num_settings = cupsd_num_settings; cg->cupsd_settings = cupsd_settings; cg->cupsd_update = time(NULL); httpGetHostname(http, cg->cupsd_hostname, sizeof(cg->cupsd_hostname)); } else cupsFreeOptions(cupsd_num_settings, cupsd_settings); /* * Remote our temp files and return... */ if (remote) unlink(cupsdconf); unlink(tempfile); return (status == HTTP_STATUS_CREATED); }
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); }
static int /* O - 0 on success, 1 on error */ read_cups_files_conf( const char *filename) /* I - File to read */ { cups_file_t *fp; /* cups-files.conf file */ const char *temp; /* Temporary string */ char line[1024], /* Line from file */ *ptr; /* Pointer into line */ int linenum; /* Current line number */ if ((temp = getenv("CUPS_DATADIR")) != NULL) set_string(&DataDir, temp); else set_string(&DataDir, CUPS_DATADIR); if ((temp = getenv("CUPS_FONTPATH")) != NULL) set_string(&FontPath, temp); else set_string(&FontPath, CUPS_FONTPATH); set_string(&RIPCache, "128m"); if ((temp = getenv("CUPS_SERVERBIN")) != NULL) set_string(&ServerBin, temp); else set_string(&ServerBin, CUPS_SERVERBIN); strlcpy(line, filename, sizeof(line)); if ((ptr = strrchr(line, '/')) != NULL) *ptr = '\0'; else getcwd(line, sizeof(line)); set_string(&ServerRoot, line); if ((fp = cupsFileOpen(filename, "r")) != NULL) { linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &ptr, &linenum)) { if (!_cups_strcasecmp(line, "DataDir")) set_string(&DataDir, ptr); else if (!_cups_strcasecmp(line, "FontPath")) set_string(&FontPath, ptr); else if (!_cups_strcasecmp(line, "RIPCache")) set_string(&RIPCache, ptr); else if (!_cups_strcasecmp(line, "ServerBin")) set_string(&ServerBin, ptr); else if (!_cups_strcasecmp(line, "ServerRoot")) set_string(&ServerRoot, ptr); } cupsFileClose(fp); } snprintf(line, sizeof(line), "%s/filter:" CUPS_BINDIR ":" CUPS_SBINDIR ":/bin:/usr/bin", ServerBin); set_string(&Path, line); return (0); }
static int /* O - 1 on success, 0 on failure */ load_system(const char *conf) /* I - Configuration file */ { cups_file_t *fp; /* File pointer */ int status = 1, /* Return value */ linenum = 0; /* Current line number */ char line[1024], /* Line from file */ *value; /* Pointer to value on line */ if ((fp = cupsFileOpen(conf, "r")) == NULL) return (errno == ENOENT); while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { if (!value) { fprintf(stderr, "ippserver: Missing value on line %d of \"%s\".\n", linenum, conf); status = 0; break; } if (!_cups_strcasecmp(line, "DataDirectory")) { if (access(value, R_OK)) { fprintf(stderr, "ippserver: Unable to access DataDirectory \"%s\": %s\n", value, strerror(errno)); status = 0; break; } DataDirectory = strdup(value); } else if (!_cups_strcasecmp(line, "DefaultPrinter")) { if (DefaultPrinter) { fprintf(stderr, "ippserver: Extra DefaultPrinter seen on line %d of \"%s\".\n", linenum, conf); status = 0; break; } DefaultPrinter = strdup(value); } else if (!_cups_strcasecmp(line, "Encryption")) { if (!_cups_strcasecmp(value, "always")) Encryption = HTTP_ENCRYPTION_ALWAYS; else if (!_cups_strcasecmp(value, "ifrequested")) Encryption = HTTP_ENCRYPTION_IF_REQUESTED; else if (!_cups_strcasecmp(value, "never")) Encryption = HTTP_ENCRYPTION_NEVER; else if (!_cups_strcasecmp(value, "required")) Encryption = HTTP_ENCRYPTION_REQUIRED; else { fprintf(stderr, "ippserver: Bad Encryption value \"%s\" on line %d of \"%s\".\n", value, linenum, conf); status = 0; break; } } else if (!_cups_strcasecmp(line, "KeepFiles")) { KeepFiles = !strcasecmp(value, "yes") || !strcasecmp(value, "true") || !strcasecmp(value, "on"); } else if (!_cups_strcasecmp(line, "Listen")) { char *ptr; /* Pointer into host value */ int port; /* Port number */ if ((ptr = strrchr(value, ':')) != NULL && !isdigit(ptr[1] & 255)) { fprintf(stderr, "ippserver: Bad Listen value \"%s\" on line %d of \"%s\".\n", value, linenum, conf); status = 0; break; } if (ptr) { *ptr++ = '\0'; port = atoi(ptr); } else port = 8000 + ((int)getuid() % 1000); if (!serverCreateListeners(value, port)) { status = 0; break; } } else if (!_cups_strcasecmp(line, "LogFile")) { if (!_cups_strcasecmp(value, "stderr")) LogFile = NULL; else LogFile = strdup(value); } else if (!_cups_strcasecmp(line, "LogLevel")) { if (!_cups_strcasecmp(value, "error")) LogLevel = SERVER_LOGLEVEL_ERROR; else if (!_cups_strcasecmp(value, "info")) LogLevel = SERVER_LOGLEVEL_INFO; else if (!_cups_strcasecmp(value, "debug")) LogLevel = SERVER_LOGLEVEL_DEBUG; else { fprintf(stderr, "ippserver: Bad LogLevel value \"%s\" on line %d of \"%s\".\n", value, linenum, conf); status = 0; break; } } else if (!_cups_strcasecmp(line, "MaxJobs")) { if (!isdigit(*value & 255)) { fprintf(stderr, "ippserver: Bad MaxJobs value \"%s\" on line %d of \"%s\".\n", value, linenum, conf); status = 0; break; } MaxJobs = atoi(value); } else if (!_cups_strcasecmp(line, "SpoolDirectory")) { if (access(value, R_OK)) { fprintf(stderr, "ippserver: Unable to access SpoolDirectory \"%s\": %s\n", value, strerror(errno)); status = 0; break; } SpoolDirectory = strdup(value); } else { fprintf(stderr, "ippserver: Unknown directive \"%s\" on line %d.\n", line, linenum); } } cupsFileClose(fp); return (status); }
int /* I - 1 on success, 0 on failure */ load_configuration(void) { cups_file_t *fp; /* mailto.conf file */ const char *server_root, /* CUPS_SERVERROOT environment variable */ *server_admin; /* SERVER_ADMIN environment variable */ char line[1024], /* Line from file */ *value; /* Value for directive */ int linenum; /* Line number in file */ /* * Initialize defaults... */ mailtoCc[0] = '\0'; if ((server_admin = getenv("SERVER_ADMIN")) != NULL) strlcpy(mailtoFrom, server_admin, sizeof(mailtoFrom)); else snprintf(mailtoFrom, sizeof(mailtoFrom), "root@%s", httpGetHostname(NULL, line, sizeof(line))); strlcpy(mailtoSendmail, "/usr/sbin/sendmail", sizeof(mailtoSendmail)); mailtoSMTPServer[0] = '\0'; mailtoSubject[0] = '\0'; /* * Try loading the config file... */ if ((server_root = getenv("CUPS_SERVERROOT")) == NULL) server_root = CUPS_SERVERROOT; snprintf(line, sizeof(line), "%s/mailto.conf", server_root); if ((fp = cupsFileOpen(line, "r")) == NULL) { fprintf(stderr, "ERROR: Unable to open \"%s\" - %s\n", line, strerror(errno)); return (1); } linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { if (!value) { fprintf(stderr, "ERROR: No value found for %s directive on line %d!\n", line, linenum); cupsFileClose(fp); return (0); } if (!strcasecmp(line, "Cc")) strlcpy(mailtoCc, value, sizeof(mailtoCc)); else if (!strcasecmp(line, "From")) strlcpy(mailtoFrom, value, sizeof(mailtoFrom)); else if (!strcasecmp(line, "Sendmail")) { strlcpy(mailtoSendmail, value, sizeof(mailtoSendmail)); mailtoSMTPServer[0] = '\0'; } else if (!strcasecmp(line, "SMTPServer")) { mailtoSendmail[0] = '\0'; strlcpy(mailtoSMTPServer, value, sizeof(mailtoSMTPServer)); } else if (!strcasecmp(line, "Subject")) strlcpy(mailtoSubject, value, sizeof(mailtoSubject)); else { fprintf(stderr, "ERROR: Unknown configuration directive \"%s\" on line %d!\n", line, linenum); } } /* * Close file and return... */ cupsFileClose(fp); return (1); }
static void cups_read_client_conf( cups_file_t *fp, /* I - File to read */ _cups_globals_t *cg, /* I - Global data */ const char *cups_encryption, /* I - CUPS_ENCRYPTION env var */ const char *cups_server, /* I - CUPS_SERVER env var */ #ifdef HAVE_GSSAPI const char *cups_gssservicename, /* I - CUPS_GSSSERVICENAME env var */ #endif /* HAVE_GSSAPI */ const char *cups_anyroot, /* I - CUPS_ANYROOT env var */ const char *cups_expiredroot, /* I - CUPS_EXPIREDROOT env var */ const char *cups_expiredcerts) /* I - CUPS_EXPIREDCERTS env var */ { int linenum; /* Current line number */ char line[1024], /* Line from file */ *value, /* Pointer into line */ encryption[1024], /* Encryption value */ #ifndef __APPLE__ server_name[1024], /* ServerName value */ #endif /* !__APPLE__ */ any_root[1024], /* AllowAnyRoot value */ expired_root[1024], /* AllowExpiredRoot value */ expired_certs[1024]; /* AllowExpiredCerts value */ #ifdef HAVE_GSSAPI char gss_service_name[32]; /* GSSServiceName value */ #endif /* HAVE_GSSAPI */ /* * Read from the file... */ linenum = 0; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { if (!cups_encryption && cg->encryption == (http_encryption_t)-1 && !_cups_strcasecmp(line, "Encryption") && value) { strlcpy(encryption, value, sizeof(encryption)); cups_encryption = encryption; } #ifndef __APPLE__ /* * The Server directive is not supported on Mac OS X due to app sandboxing * restrictions, i.e. not all apps request network access. */ else if (!cups_server && (!cg->server[0] || !cg->ipp_port) && !_cups_strcasecmp(line, "ServerName") && value) { strlcpy(server_name, value, sizeof(server_name)); cups_server = server_name; } #endif /* !__APPLE__ */ else if (!cups_anyroot && !_cups_strcasecmp(line, "AllowAnyRoot") && value) { strlcpy(any_root, value, sizeof(any_root)); cups_anyroot = any_root; } else if (!cups_expiredroot && !_cups_strcasecmp(line, "AllowExpiredRoot") && value) { strlcpy(expired_root, value, sizeof(expired_root)); cups_expiredroot = expired_root; } else if (!cups_expiredcerts && !_cups_strcasecmp(line, "AllowExpiredCerts") && value) { strlcpy(expired_certs, value, sizeof(expired_certs)); cups_expiredcerts = expired_certs; } #ifdef HAVE_GSSAPI else if (!cups_gssservicename && !_cups_strcasecmp(line, "GSSServiceName") && value) { strlcpy(gss_service_name, value, sizeof(gss_service_name)); cups_gssservicename = gss_service_name; } #endif /* HAVE_GSSAPI */ } /* * Set values... */ if (cg->encryption == (http_encryption_t)-1 && cups_encryption) { if (!_cups_strcasecmp(cups_encryption, "never")) cg->encryption = HTTP_ENCRYPT_NEVER; else if (!_cups_strcasecmp(cups_encryption, "always")) cg->encryption = HTTP_ENCRYPT_ALWAYS; else if (!_cups_strcasecmp(cups_encryption, "required")) cg->encryption = HTTP_ENCRYPT_REQUIRED; else cg->encryption = HTTP_ENCRYPT_IF_REQUESTED; } if ((!cg->server[0] || !cg->ipp_port) && cups_server) { if (!cg->server[0]) { /* * Copy server name... */ strlcpy(cg->server, cups_server, sizeof(cg->server)); if (cg->server[0] != '/' && (value = strrchr(cg->server, ':')) != NULL && !strchr(value, ']') && isdigit(value[1] & 255)) *value++ = '\0'; else value = NULL; if (cg->server[0] == '/') strcpy(cg->servername, "localhost"); else strlcpy(cg->servername, cg->server, sizeof(cg->servername)); } else if (cups_server[0] != '/' && (value = strrchr(cups_server, ':')) != NULL && !strchr(value, ']') && isdigit(value[1] & 255)) value ++; else value = NULL; if (!cg->ipp_port && value) cg->ipp_port = atoi(value); } if (!cg->server[0]) { #ifdef CUPS_DEFAULT_DOMAINSOCKET /* * If we are compiled with domain socket support, only use the * domain socket if it exists and has the right permissions... */ struct stat sockinfo; /* Domain socket information */ if (!stat(CUPS_DEFAULT_DOMAINSOCKET, &sockinfo) && (sockinfo.st_mode & S_IRWXO) == S_IRWXO) cups_server = CUPS_DEFAULT_DOMAINSOCKET; else #endif /* CUPS_DEFAULT_DOMAINSOCKET */ cups_server = "localhost"; cupsSetServer(cups_server); } if (!cg->ipp_port) { const char *ipp_port; /* IPP_PORT environment variable */ if ((ipp_port = getenv("IPP_PORT")) != NULL) { if ((cg->ipp_port = atoi(ipp_port)) <= 0) cg->ipp_port = CUPS_DEFAULT_IPP_PORT; } else cg->ipp_port = CUPS_DEFAULT_IPP_PORT; } #ifdef HAVE_GSSAPI if (!cups_gssservicename) cups_gssservicename = CUPS_DEFAULT_GSSSERVICENAME; strlcpy(cg->gss_service_name, cups_gssservicename, sizeof(cg->gss_service_name)); #endif /* HAVE_GSSAPI */ if (cups_anyroot) cg->any_root = !_cups_strcasecmp(cups_anyroot, "yes") || !_cups_strcasecmp(cups_anyroot, "on") || !_cups_strcasecmp(cups_anyroot, "true"); if (cups_expiredroot) cg->expired_root = !_cups_strcasecmp(cups_expiredroot, "yes") || !_cups_strcasecmp(cups_expiredroot, "on") || !_cups_strcasecmp(cups_expiredroot, "true"); if (cups_expiredcerts) cg->expired_certs = !_cups_strcasecmp(cups_expiredcerts, "yes") || !_cups_strcasecmp(cups_expiredcerts, "on") || !_cups_strcasecmp(cups_expiredcerts, "true"); }
void cupsdLoadAllClasses(void) { int i; /* Looping var */ cups_file_t *fp; /* classes.conf file */ int linenum; /* Current line number */ char line[4096], /* Line from file */ *value, /* Pointer to value */ *valueptr; /* Pointer into value */ cupsd_printer_t *p, /* Current printer class */ *temp; /* Temporary pointer to printer */ /* * Open the classes.conf file... */ snprintf(line, sizeof(line), "%s/classes.conf", ServerRoot); if ((fp = cupsFileOpen(line, "r")) == NULL) { if (errno != ENOENT) cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to open %s - %s", line, strerror(errno)); return; } /* * Read class configurations until we hit EOF... */ linenum = 0; p = NULL; while (cupsFileGetConf(fp, line, sizeof(line), &value, &linenum)) { /* * Decode the directive... */ if (!strcasecmp(line, "<Class") || !strcasecmp(line, "<DefaultClass")) { /* * <Class name> or <DefaultClass name> */ if (p == NULL && value) { cupsdLogMessage(CUPSD_LOG_DEBUG, "Loading class %s...", value); /* * Since prior classes may have implicitly defined this class, * see if it already exists... */ if ((p = cupsdFindDest(value)) != NULL) { p->type = CUPS_PRINTER_CLASS; cupsdSetStringf(&p->uri, "ipp://%s:%d/classes/%s", ServerName, LocalPort, value); cupsdSetString(&p->error_policy, "retry-job"); } else p = cupsdAddClass(value); p->accepting = 1; p->state = IPP_PRINTER_IDLE; if (!strcasecmp(line, "<DefaultClass")) DefaultPrinter = p; } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "</Class>")) { if (p != NULL) { cupsdSetPrinterAttrs(p); p = NULL; } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!p) { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "AuthInfoRequired")) { if (!cupsdSetAuthInfoRequired(p, value, NULL)) cupsdLogMessage(CUPSD_LOG_ERROR, "Bad AuthInfoRequired on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "Info")) { if (value) cupsdSetString(&p->info, value); } else if (!strcasecmp(line, "Location")) { if (value) cupsdSetString(&p->location, value); } else if (!strcasecmp(line, "Option") && value) { /* * Option name value */ for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); if (!*valueptr) cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); else { for (; *valueptr && isspace(*valueptr & 255); *valueptr++ = '\0'); p->num_options = cupsAddOption(value, valueptr, p->num_options, &(p->options)); } } else if (!strcasecmp(line, "Printer")) { if (!value) { cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); continue; } else if ((temp = cupsdFindPrinter(value)) == NULL) { cupsdLogMessage(CUPSD_LOG_WARN, "Unknown printer %s on line %d of classes.conf.", value, linenum); /* * Add the missing remote printer... */ if ((temp = cupsdAddPrinter(value)) != NULL) { cupsdSetString(&temp->make_model, "Remote Printer on unknown"); temp->state = IPP_PRINTER_STOPPED; temp->type |= CUPS_PRINTER_REMOTE; temp->browse_time = 2147483647; cupsdSetString(&temp->location, "Location Unknown"); cupsdSetString(&temp->info, "No Information Available"); temp->hostname[0] = '\0'; cupsdSetPrinterAttrs(temp); } } if (temp) cupsdAddPrinterToClass(p, temp); } else if (!strcasecmp(line, "State")) { /* * Set the initial queue state... */ if (!strcasecmp(value, "idle")) p->state = IPP_PRINTER_IDLE; else if (!strcasecmp(value, "stopped")) { p->state = IPP_PRINTER_STOPPED; for (i = 0 ; i < p->num_reasons; i ++) if (!strcmp("paused", p->reasons[i])) break; if (i >= p->num_reasons && p->num_reasons < (int)(sizeof(p->reasons) / sizeof(p->reasons[0]))) { p->reasons[p->num_reasons] = _cupsStrAlloc("paused"); p->num_reasons ++; } } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "StateMessage")) { /* * Set the initial queue state message... */ if (value) strlcpy(p->state_message, value, sizeof(p->state_message)); } else if (!strcasecmp(line, "StateTime")) { /* * Set the state time... */ if (value) p->state_time = atoi(value); } else if (!strcasecmp(line, "Accepting")) { /* * Set the initial accepting state... */ if (value && (!strcasecmp(value, "yes") || !strcasecmp(value, "on") || !strcasecmp(value, "true"))) p->accepting = 1; else if (value && (!strcasecmp(value, "no") || !strcasecmp(value, "off") || !strcasecmp(value, "false"))) p->accepting = 0; else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "Shared")) { /* * Set the initial shared state... */ if (value && (!strcasecmp(value, "yes") || !strcasecmp(value, "on") || !strcasecmp(value, "true"))) p->shared = 1; else if (value && (!strcasecmp(value, "no") || !strcasecmp(value, "off") || !strcasecmp(value, "false"))) p->shared = 0; else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "JobSheets")) { /* * Set the initial job sheets... */ if (value) { for (valueptr = value; *valueptr && !isspace(*valueptr & 255); valueptr ++); if (*valueptr) *valueptr++ = '\0'; cupsdSetString(&p->job_sheets[0], value); while (isspace(*valueptr & 255)) valueptr ++; if (*valueptr) { for (value = valueptr; *valueptr && !isspace(*valueptr & 255); valueptr ++); if (*valueptr) *valueptr = '\0'; cupsdSetString(&p->job_sheets[1], value); } } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "AllowUser")) { if (value) { p->deny_users = 0; cupsdAddPrinterUser(p, value); } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "DenyUser")) { if (value) { p->deny_users = 1; cupsdAddPrinterUser(p, value); } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "QuotaPeriod")) { if (value) p->quota_period = atoi(value); else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "PageLimit")) { if (value) p->page_limit = atoi(value); else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "KLimit")) { if (value) p->k_limit = atoi(value); else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "OpPolicy")) { if (value) { cupsd_policy_t *pol; /* Policy */ if ((pol = cupsdFindPolicy(value)) != NULL) { cupsdSetString(&p->op_policy, value); p->op_policy_ptr = pol; } else cupsdLogMessage(CUPSD_LOG_ERROR, "Bad policy \"%s\" on line %d of classes.conf", value, linenum); } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else if (!strcasecmp(line, "ErrorPolicy")) { if (value) { if (strcmp(value, "retry-current-job") && strcmp(value, "retry-job")) cupsdLogMessage(CUPSD_LOG_WARN, "ErrorPolicy %s ignored on line %d of classes.conf", value, linenum); } else cupsdLogMessage(CUPSD_LOG_ERROR, "Syntax error on line %d of classes.conf.", linenum); } else { /* * Something else we don't understand... */ cupsdLogMessage(CUPSD_LOG_ERROR, "Unknown configuration directive %s on line %d of classes.conf.", line, linenum); } } cupsFileClose(fp); }