// 404 void respErrorPage( headerOut *header_out , int status_code ) { if (status_code >= 400 && status_code <= 507) { int ret = respDefinedErrorPage( header_out , status_code ); if (ret == AE_TRUE) { return; } } // get header info headerStatus error_page = getHttpStatus( status_code ); int datalen = strlen( error_page.data ); // header append createCommonHeader( header_out , status_code ); headerAppendLength( header_out , datalen ); appendRespHeader( header_out , HEADER_END_LINE ); // send httpResponseWrite( header_out->req->connfd , header_out->data , header_out->length ); if (header_out->req->nobody != AE_TRUE) { httpResponseWrite( header_out->req->connfd , error_page.data , datalen ); } // nobody强制关闭 httpClose( header_out->req , header_out->req->nobody ); }
int getPrinterSharingStatus() { http_t* cups = nullptr; int num_settings = 0; cups_option_t* settings = nullptr; const char* value = nullptr; cups = httpConnect2(cupsServer(), ippPort(), nullptr, AF_INET, cupsEncryption(), 1, 30000, nullptr); if (cups == nullptr) { return 0; } int ret = cupsAdminGetServerSettings(cups, &num_settings, &settings); if (ret != 0) { value = cupsGetOption("_share_printers", num_settings, settings); cupsFreeOptions(num_settings, settings); } else { VLOG(1) << "Unable to get CUPS server settings: " << cupsLastErrorString(); } httpClose(cups); if (value != nullptr) { return *value == '1' ? 1 : 0; } return 0; }
void cupsSetServer(const char *server) /* I - Server name */ { char *options, /* Options */ *port; /* Pointer to port */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ if (server) { strlcpy(cg->server, server, sizeof(cg->server)); if (cg->server[0] != '/' && (options = strrchr(cg->server, '/')) != NULL) { *options++ = '\0'; if (!strcmp(options, "version=1.0")) cg->server_version = 10; else if (!strcmp(options, "version=1.1")) cg->server_version = 11; else if (!strcmp(options, "version=2.0")) cg->server_version = 20; else if (!strcmp(options, "version=2.1")) cg->server_version = 21; else if (!strcmp(options, "version=2.2")) cg->server_version = 22; } else cg->server_version = 20; if (cg->server[0] != '/' && (port = strrchr(cg->server, ':')) != NULL && !strchr(port, ']') && isdigit(port[1] & 255)) { *port++ = '\0'; cg->ipp_port = atoi(port); } if (!cg->ipp_port) cups_set_default_ipp_port(cg); if (cg->server[0] == '/') strlcpy(cg->servername, "localhost", sizeof(cg->servername)); else strlcpy(cg->servername, cg->server, sizeof(cg->servername)); } else { cg->server[0] = '\0'; cg->servername[0] = '\0'; cg->server_version = 20; cg->ipp_port = 0; } if (cg->http) { httpClose(cg->http); cg->http = NULL; } }
void gtk_cups_request_free (GtkCupsRequest *request) { if (request->own_http) { if (request->http) httpClose (request->http); } if (request->ipp_request) ippDelete (request->ipp_request); g_free (request->server); g_free (request->resource); if (request->password != NULL) { memset (request->password, 0, strlen (request->password)); g_free (request->password); } g_free (request->username); g_strfreev (request->auth_info_required); gtk_cups_result_free (request->result); g_free (request); }
bool KMWIpp::isValid(QString& msg) { // check informations if (text(0).isEmpty()) { msg = i18n("Empty server name."); return false; } bool ok(false); int p = text(1).toInt(&ok); if (!ok) { msg = i18n("Incorrect port number."); return false; } // check server http_t *HTTP = httpConnect(text(0).latin1(),p); if (HTTP) { httpClose(HTTP); return true; } else { msg = i18n("<nobr>Unable to connect to <b>%1</b> on port <b>%2</b> .</nobr>").arg(text(0)).arg(p); return false; } }
static void printer_cups_close_printjob(rdpPrintJob* printjob) { rdpCupsPrintJob* cups_printjob = (rdpCupsPrintJob*)printjob; #ifndef _CUPS_API_1_4 { char buf[100]; printer_cups_get_printjob_name(buf, sizeof(buf)); if (cupsPrintFile(printjob->printer->name, (const char *)cups_printjob->printjob_object, buf, 0, NULL) == 0) { DEBUG_WARN("cupsPrintFile: %s", cupsLastErrorString()); } unlink(cups_printjob->printjob_object); xfree(cups_printjob->printjob_object); } #else cupsFinishDocument((http_t*)cups_printjob->printjob_object, printjob->printer->name); cups_printjob->printjob_id = 0; httpClose((http_t*)cups_printjob->printjob_object); #endif xfree(cups_printjob); ((rdpCupsPrinter*)printjob->printer)->printjob = NULL; }
static void cups_globals_free(_cups_globals_t *cg) /* I - Pointer to global data */ { _cups_buffer_t *buffer, /* Current read/write buffer */ *next; /* Next buffer */ if (cg->last_status_message) _cupsStrFree(cg->last_status_message); for (buffer = cg->cups_buffers; buffer; buffer = next) { next = buffer->next; free(buffer); } cupsArrayDelete(cg->leg_size_lut); cupsArrayDelete(cg->ppd_size_lut); cupsArrayDelete(cg->pwg_size_lut); httpClose(cg->http); _httpFreeCredentials(cg->tls_credentials); cupsFileClose(cg->stdio_files[0]); cupsFileClose(cg->stdio_files[1]); cupsFileClose(cg->stdio_files[2]); cupsFreeOptions(cg->cupsd_num_settings, cg->cupsd_settings); free(cg); }
/////////////////////////////////////////////////////////////////////////////////////////// // // CS : PUBLIC gint getPrinterStatus(gchar *pDestName, gchar *pStatus, gint bufSize) // IN : gchar *pDestName : Printer name. // gint bufSize : Size of output buffer. // OUT : gchar *pStatus : Printer status string. // RETURN : ID_ERR_NO_ERROR : No error. // ID_ERR_CUPS_API_FAILED : Error occured in CUPS API. // PUBLIC gint getPrinterStatus(gchar *pDestName, gchar *pStatus, gint bufSize) { /*** Parameters start ***/ http_t *pHTTP; // Pointer to HTTP connection. ipp_t *pRequest, // Pointer to CUPS IPP request. *pResponse; // Pointer to CUPS IPP response. ipp_attribute_t *pAttribute; // Pointer to CUPS attributes. cups_lang_t *pLanguage; // Pointer to language. gchar printerURI[HTTP_MAX_URI]; // Printer URI. gchar serverName[HTTP_MAX_URI]; // CUPS server name. gint retVal = ID_ERR_NO_ERROR; // Return value. /*** Parameters end ***/ // Initialize buffer. memset(printerURI, 0, sizeof(printerURI)); memset(serverName, 0, sizeof(serverName)); // Get printer URI and CUPS server name. retVal = getPrinterURI(pDestName, printerURI, serverName, HTTP_MAX_URI); if (retVal == ID_ERR_NO_ERROR) { // CUPS http connect. if ((pHTTP = httpConnectEncrypt(serverName, ippPort(), cupsEncryption())) == NULL) { retVal = ID_ERR_CUPS_API_FAILED; } else { pRequest = ippNew(); ippSetOperation(pRequest, IPP_GET_PRINTER_ATTRIBUTES); ippSetRequestId(pRequest, 1); pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19 ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage)); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printerURI); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) { if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } else { pAttribute = ippFindAttribute(pResponse, "printer-state-message", IPP_TAG_TEXT); if (pAttribute != NULL) { strncpy(pStatus, ippGetString(pAttribute, 0, NULL), bufSize); } } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } } return(retVal); }// End getPrinterStatus
static void list_options(cups_dest_t *dest) /* I - Destination to list */ { http_t *http; /* Connection to destination */ char resource[1024]; /* Resource path */ int i; /* Looping var */ const char *filename; /* PPD filename */ ppd_file_t *ppd; /* PPD data */ ppd_group_t *group; /* Current group */ if ((http = cupsConnectDest(dest, CUPS_DEST_FLAGS_NONE, 30000, NULL, resource, sizeof(resource), NULL, NULL)) == NULL) { _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"), dest->name, cupsLastErrorString()); return; } if ((filename = cupsGetPPD2(http, dest->name)) == NULL) { httpClose(http); _cupsLangPrintf(stderr, _("lpoptions: Unable to get PPD file for %s: %s"), dest->name, cupsLastErrorString()); return; } httpClose(http); if ((ppd = ppdOpenFile(filename)) == NULL) { unlink(filename); _cupsLangPrintf(stderr, _("lpoptions: Unable to open PPD file for %s."), dest->name); return; } ppdMarkDefaults(ppd); cupsMarkOptions(ppd, dest->num_options, dest->options); for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++) list_group(ppd, group); ppdClose(ppd); unlink(filename); }
void uploadctr(char *filename, char *ip) { int ret, size, p, n, k, i, j; FILE *fd; SOCKET sd; unsigned char *buf; fd = fopen(filename, "rb"); if ( fd == NULL ) { printf("file %s not found\n", filename); return; } #ifndef __WIN32__ if (!is_regular_file(filename)) { printf("file %s is not a regular file\n", filename); fclose(fd); return; } #endif fseek(fd, 0, SEEK_END); size = ftell(fd); fseek(fd, 0, SEEK_SET); buf = malloc(size); if ( buf == NULL ) { printf("Not enough memory!\n"); fclose(fd); return; } fread(buf, size, 1, fd); // gah no validation, M4 will verify some... fclose(fd); ret = httpConnect(ip); if ( ret >= 0 ) { sd = ret; // connect socket if ( httpSend(sd, "/CARTIMG.BIN", buf, size, "upfile", "/upload.html", ip) >= 0 ) ret = httpResponse(sd); httpClose(sd); if ( ret == 200 ) printf("Upload OK!\r\n"); else printf("Upload error code. %i\r\n", ret); } else printf("Connect to %s failed\n", ip); free(buf); }
static rdpPrintJob* printer_cups_create_printjob(rdpPrinter* printer, UINT32 id) { rdpCupsPrinter* cups_printer = (rdpCupsPrinter*) printer; rdpCupsPrintJob* cups_printjob; if (cups_printer->printjob != NULL) return NULL; cups_printjob = (rdpCupsPrintJob*) malloc(sizeof(rdpCupsPrintJob)); ZeroMemory(cups_printjob, sizeof(rdpCupsPrintJob)); cups_printjob->printjob.id = id; cups_printjob->printjob.printer = printer; cups_printjob->printjob.Write = printer_cups_write_printjob; cups_printjob->printjob.Close = printer_cups_close_printjob; #ifndef _CUPS_API_1_4 cups_printjob->printjob_object = _strdup(tmpnam(NULL)); #else { char buf[100]; cups_printjob->printjob_object = httpConnectEncrypt(cupsServer(), ippPort(), HTTP_ENCRYPT_IF_REQUESTED); if (cups_printjob->printjob_object == NULL) { DEBUG_WARN("httpConnectEncrypt: %s", cupsLastErrorString()); free(cups_printjob); return NULL; } printer_cups_get_printjob_name(buf, sizeof(buf)); cups_printjob->printjob_id = cupsCreateJob((http_t*) cups_printjob->printjob_object, printer->name, buf, 0, NULL); if (cups_printjob->printjob_id == 0) { DEBUG_WARN("cupsCreateJob: %s", cupsLastErrorString()); httpClose((http_t*) cups_printjob->printjob_object); free(cups_printjob); return NULL; } cupsStartDocument((http_t*) cups_printjob->printjob_object, printer->name, cups_printjob->printjob_id, buf, CUPS_FORMAT_AUTO, 1); } #endif cups_printer->printjob = cups_printjob; return (rdpPrintJob*)cups_printjob; }
uint32 printer_hw_create(IRP * irp, const char * path) { PRINTER_DEVICE_INFO * info; info = (PRINTER_DEVICE_INFO *) irp->dev->info; /* Server's print queue will ensure no two print jobs will be sent to the same printer. However, we still want to do a simple locking just to ensure we are safe. */ if (info->printjob_object) { return RD_STATUS_DEVICE_BUSY; } #ifndef _CUPS_API_1_4 info->printjob_id++; info->printjob_object = strdup(tmpnam(NULL)); #else { char buf[100]; info->printjob_object = httpConnectEncrypt(cupsServer(), ippPort(), HTTP_ENCRYPT_IF_REQUESTED); if (info->printjob_object == NULL) { LLOGLN(0, ("printer_hw_create: httpConnectEncrypt: %s", cupsLastErrorString())); return RD_STATUS_DEVICE_BUSY; } printer_hw_get_printjob_name(buf, sizeof(buf)); info->printjob_id = cupsCreateJob((http_t *) info->printjob_object, info->printer_name, buf, 0, NULL); if (info->printjob_id == 0) { LLOGLN(0, ("printer_hw_create: cupsCreateJob: %s", cupsLastErrorString())); httpClose((http_t *) info->printjob_object); info->printjob_object = NULL; /* Should get the right return code based on printer status */ return RD_STATUS_DEVICE_BUSY; } cupsStartDocument((http_t *) info->printjob_object, info->printer_name, info->printjob_id, buf, CUPS_FORMAT_POSTSCRIPT, 1); } #endif LLOGLN(10, ("printe_hw_create: %s id=%d", info->printer_name, info->printjob_id)); irp->fileID = info->printjob_id; return RD_STATUS_SUCCESS; }
/////////////////////////////////////////////////////////////////////////////////////////// // // CS : PRIVATE gint checkPrinterState(gchar *pDestName, gchar *pURI, gchar *pServerName) // IN : gchar *pDestName : Printer name. // gchar *pURI : Printer URI. // gchar *pServerName : CUPS server name. // OUT : None. // RETURN : ID_ERR_NO_ERROR : No error. // ID_ERR_UNKNOWN_PRINTER : No printer registerd in CUPS. // ID_ERR_CUPS_API_FAILED : Error occured in CUPS API. // PRIVATE gint checkPrinterState(gchar *pDestName, gchar *pURI, gchar *pServerName) { /*** Parameters start ***/ http_t *pHTTP; // Pointer to HTTP connection. ipp_t *pRequest, // Pointer to CUPS IPP request. *pResponse; // Pointer to CUPS IPP response. ipp_attribute_t *pAttribute; // Pointer to CUPS attributes. cups_lang_t *pLanguage; // Pointer to language. ipp_pstate_t printerState = IPP_PRINTER_STOPPED; // Pointer to printer state. gint retVal = ID_ERR_UNKNOWN_PRINTER; // Return value. /*** Parameters end ***/ // CUPS http connect. if ((pHTTP = httpConnectEncrypt(pServerName, ippPort(), cupsEncryption())) == NULL) { retVal = ID_ERR_CUPS_API_FAILED; } else { pRequest = ippNew(); ippSetOperation(pRequest, IPP_GET_PRINTER_ATTRIBUTES); ippSetRequestId(pRequest, 1); pLanguage = bjcupsLangDefault(); // cupsLangDefault() -> bjcupsLangDefault() for cups-1.1.19 ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(pLanguage)); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, pLanguage->language); ippAddString(pRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, pURI); if ((pResponse = cupsDoRequest(pHTTP, pRequest, "/")) != NULL) { if (ippGetStatusCode(pResponse) > IPP_OK_CONFLICT) { retVal = ID_ERR_CUPS_API_FAILED; } else { if ((pAttribute = ippFindAttribute(pResponse, "printer-state", IPP_TAG_ENUM)) != NULL) { printerState = (ipp_state_t) ippGetInteger(pAttribute, 0); } } ippDelete(pResponse); } else { retVal = ID_ERR_CUPS_API_FAILED; } cupsLangFree(pLanguage); httpClose(pHTTP); } if (printerState == IPP_PRINTER_IDLE || printerState == IPP_PRINTER_PROCESSING) { retVal = ID_ERR_NO_ERROR; } return(retVal); }// End checkPrinterState
static void _pp_host_get_remote_cups_devices_thread (GSimpleAsyncResult *res, GObject *object, GCancellable *cancellable) { cups_dest_t *dests = NULL; GSDData *data; PpHost *host = (PpHost *) object; PpHostPrivate *priv = host->priv; PpPrintDevice *device; http_t *http; gint num_of_devices = 0; gint port; gint i; data = g_simple_async_result_get_op_res_gpointer (res); data->devices = g_new0 (PpDevicesList, 1); data->devices->devices = NULL; if (priv->port == PP_HOST_UNSET_PORT) port = PP_HOST_DEFAULT_IPP_PORT; else port = priv->port; /* Connect to remote CUPS server and get its devices */ http = httpConnect (priv->hostname, port); if (http) { num_of_devices = cupsGetDests2 (http, &dests); if (num_of_devices > 0) { for (i = 0; i < num_of_devices; i++) { device = g_new0 (PpPrintDevice, 1); device->device_class = g_strdup ("network"); device->device_uri = g_strdup_printf ("ipp://%s:%d/printers/%s", priv->hostname, port, dests[i].name); device->device_name = g_strdup (dests[i].name); device->device_location = g_strdup (cupsGetOption ("printer-location", dests[i].num_options, dests[i].options)); device->host_name = g_strdup (priv->hostname); device->host_port = port; device->acquisition_method = ACQUISITION_METHOD_REMOTE_CUPS_SERVER; data->devices->devices = g_list_append (data->devices->devices, device); } } httpClose (http); } }
static void connection_test_thread (GTask *task, gpointer source_object, gpointer task_data, GCancellable *cancellable) { http_t *http; http = httpConnectEncrypt (cupsServer (), ippPort (), cupsEncryption ()); g_task_return_boolean (task, http != NULL); httpClose (http); }
void uploadRom(char *filename, char *ip, int slot, char *slotname) { int ret, size, p, n, k, i, j; char fullpath[256]; // don't exceed this, the cpc wouldn't be able |cd it anyway FILE *fd; SOCKET sd; unsigned char *buf; fd = fopen(filename, "rb"); if ( fd == NULL ) { printf("file %s not found\n", filename); return; } fseek(fd, 0, SEEK_END); size = ftell(fd); fseek(fd, 0, SEEK_SET); buf = malloc(size); if ( buf == NULL ) { printf("Not enough memory!\n"); fclose(fd); return; } fread(buf, size, 1, fd); fclose(fd); ret = httpConnect(ip); if ( ret >= 0 ) { sd = ret; // connect socket if ( httpSendRom(sd, "rom.bin", buf, size, slot, "/roms.shtml", ip, slotname) >= 0 ) ret = httpResponse(sd); httpClose(sd); if ( ret == 200 ) printf("Upload OK!\r\n"); else printf("Upload error code. %i\r\n", ret); } else printf("Connect to %s failed\n", ip); free(buf); }
void file_cleanup(void) { char filename[1024]; /* Temporary file */ #ifdef WIN32 char tmpdir[1024]; /* Temporary directory */ #else const char *tmpdir; /* Temporary directory */ #endif /* WIN32 */ if (http) { httpClose(http); http = NULL; } #ifdef WIN32 GetTempPath(sizeof(tmpdir), tmpdir); #else if ((tmpdir = getenv("TMPDIR")) == NULL) tmpdir = "/var/tmp"; #endif /* WIN32 */ while (web_files > 0) { snprintf(filename, sizeof(filename), TEMPLATE, tmpdir, getpid(), web_files); if (unlink(filename)) progress_error(HD_ERROR_DELETE_ERROR, "Unable to delete temporary file \"%s\": %s", filename, strerror(errno)); web_files --; if (web_cache[web_files].name) free(web_cache[web_files].name); if (web_cache[web_files].url) free(web_cache[web_files].url); } if (web_alloc) { free(web_cache); web_alloc = 0; web_cache = NULL; } }
void httpRedirect( httpHeader *req_header , char *uri ) { headerOut header_out; memset( &header_out , 0 , sizeof( header_out ) ); header_out.req = req_header; headerStatus error_page = getHttpStatus( 301 ); // header append createCommonHeader( &header_out , 301 ); appendRespHeader( &header_out , HEADER_LOCATION , uri ); appendRespHeader( &header_out , HEADER_CONTENT_LENGTH , 0 ); appendRespHeader( &header_out , HEADER_END_LINE ); httpResponseWrite( req_header->connfd , header_out.data , header_out.length ); httpClose( req_header , 0 ); }
/* * Checks if connection can be made to the server. * */ JNIEXPORT jboolean JNICALL Java_sun_print_CUPSPrinter_canConnect(JNIEnv *env, jobject printObj, jstring server, jint port) { const char *serverName; serverName = (*env)->GetStringUTFChars(env, server, NULL); if (serverName != NULL) { http_t *http = httpConnect(serverName, (int)port); (*env)->ReleaseStringUTFChars(env, server, serverName); if (http != NULL) { httpClose(http); return JNI_TRUE; } } return JNI_FALSE; }
uint32 printer_hw_close(IRP * irp) { PRINTER_DEVICE_INFO * info; info = (PRINTER_DEVICE_INFO *) irp->dev->info; LLOGLN(10, ("printe_hw_close: %s id=%d", info->printer_name, irp->fileID)); if (irp->fileID != info->printjob_id) { LLOGLN(0, ("printer_hw_close: invalid file id")); return RD_STATUS_INVALID_HANDLE; } #ifndef _CUPS_API_1_4 { char buf[100]; printer_hw_get_printjob_name(buf, sizeof(buf)); if (cupsPrintFile(info->printer_name, (const char *) info->printjob_object, buf, 0, NULL) == 0) { LLOGLN(0, ("printer_hw_close: cupsPrintFile: %s", cupsLastErrorString())); } unlink(info->printjob_object); free(info->printjob_object); } #else cupsFinishDocument((http_t *) info->printjob_object, info->printer_name); info->printjob_id = 0; httpClose((http_t *) info->printjob_object); #endif info->printjob_object = NULL; return RD_STATUS_SUCCESS; }
void printer_hw_free(void * info) { PRINTER_DEVICE_INFO * pinfo; LLOGLN(10, ("printer_free")); pinfo = (PRINTER_DEVICE_INFO *) info; if (pinfo->printer_name) { free(pinfo->printer_name); pinfo->printer_name = NULL; } if (pinfo->printjob_object) { #ifndef _CUPS_API_1_4 free(pinfo->printjob_object); #else httpClose((http_t *) pinfo->printjob_object); #endif pinfo->printjob_object = NULL; } free(pinfo); }
void papiServiceDestroy(papi_service_t handle) { if (handle != NULL) { service_t *svc = handle; if (svc->attributes != NULL) papiAttributeListFree(svc->attributes); if (svc->name != NULL) free(svc->name); if (svc->user != NULL) free(svc->user); if (svc->password != NULL) free(svc->password); if (svc->uri != NULL) uri_free(svc->uri); if (svc->post != NULL) free(svc->post); if (svc->connection != NULL) httpClose(svc->connection); free(handle); } }
void cupsSetServer(const char *server) /* I - Server name */ { char *port; /* Pointer to port */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ if (server) { strlcpy(cg->server, server, sizeof(cg->server)); if (cg->server[0] != '/' && (port = strrchr(cg->server, ':')) != NULL && !strchr(port, ']') && isdigit(port[1] & 255)) { *port++ = '\0'; cg->ipp_port = atoi(port); } if (cg->server[0] == '/') strcpy(cg->servername, "localhost"); else strlcpy(cg->servername, cg->server, sizeof(cg->servername)); } else { cg->server[0] = '\0'; cg->servername[0] = '\0'; } if (cg->http) { httpClose(cg->http); cg->http = NULL; } }
GList *dt_get_papers(const dt_printer_info_t *printer) { const char *printer_name = printer->name; GList *result = NULL; #if ((CUPS_VERSION_MAJOR == 1) && (CUPS_VERSION_MINOR >= 7)) || CUPS_VERSION_MAJOR > 1 #if defined(__APPLE__) && MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_9 if (cupsConnectDest != NULL && cupsCopyDestInfo != NULL && cupsGetDestMediaCount != NULL && cupsGetDestMediaByIndex != NULL && cupsFreeDestInfo != NULL) #endif { cups_dest_t *dests; int num_dests = cupsGetDests(&dests); cups_dest_t *dest = cupsGetDest(printer_name, NULL, num_dests, dests); int cancel = 0; // important char resource[1024]; if (dest) { http_t *hcon = cupsConnectDest(dest, 0, 2000, &cancel, resource, sizeof(resource), NULL, (void *)NULL); if (hcon) { cups_size_t size; cups_dinfo_t *info = cupsCopyDestInfo (hcon, dest); const int count = cupsGetDestMediaCount(hcon, dest, info, CUPS_MEDIA_FLAGS_DEFAULT); for (int k=0; k<count; k++) { if (cupsGetDestMediaByIndex(hcon, dest, info, k, CUPS_MEDIA_FLAGS_DEFAULT, &size)) { if (size.width!=0 && size.length!=0 && !paper_exists(result, size.media)) { pwg_media_t *med = pwgMediaForPWG (size.media); char common_name[MAX_NAME] = { 0 }; if (med->ppd) g_strlcpy(common_name, med->ppd, sizeof(common_name)); else g_strlcpy(common_name, size.media, sizeof(common_name)); dt_paper_info_t *paper = (dt_paper_info_t*)malloc(sizeof(dt_paper_info_t)); g_strlcpy(paper->name, size.media, sizeof(paper->name)); g_strlcpy(paper->common_name, common_name, sizeof(paper->common_name)); paper->width = (double)size.width / 100.0; paper->height = (double)size.length / 100.0; result = g_list_append (result, paper); dt_print(DT_DEBUG_PRINT, "[print] new media paper %4d %6.2f x %6.2f (%s) (%s)\n", k, paper->width, paper->height, paper->name, paper->common_name); } } } cupsFreeDestInfo(info); httpClose(hcon); } else dt_print(DT_DEBUG_PRINT, "[print] cannot connect to printer %s (cancel=%d)\n", printer_name, cancel); } cupsFreeDests(num_dests, dests); } #endif // check now PPD page sizes const char *PPDFile = cupsGetPPD(printer_name); ppd_file_t *ppd = ppdOpenFile(PPDFile); if (ppd) { ppd_size_t *size = ppd->sizes; for (int k=0; k<ppd->num_sizes; k++) { if (size->width!=0 && size->length!=0 && !paper_exists(result, size->name)) { dt_paper_info_t *paper = (dt_paper_info_t*)malloc(sizeof(dt_paper_info_t)); g_strlcpy(paper->name, size->name, MAX_NAME); g_strlcpy(paper->common_name, size->name, MAX_NAME); paper->width = (double)dt_pdf_point_to_mm(size->width); paper->height = (double)dt_pdf_point_to_mm(size->length); result = g_list_append (result, paper); dt_print(DT_DEBUG_PRINT, "[print] new ppd paper %4d %6.2f x %6.2f (%s) (%s)\n", k, paper->width, paper->height, paper->name, paper->common_name); } size++; } ppdClose(ppd); g_unlink(PPDFile); } result = g_list_sort_with_data (result, (GCompareDataFunc)sort_papers, NULL); return result; }
int /* O - Exit status */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ const char *opt, /* Current option character */ *name = NULL, /* Service name */ *type = "_ipp._tcp", /* Service type */ *domain = "local."; /* Service domain */ #ifdef HAVE_DNSSD DNSServiceRef ref; /* Browsing service reference */ #endif /* HAVE_DNSSD */ #ifdef HAVE_AVAHI AvahiClient *client; /* Client information */ int error; /* Error code, if any */ #endif /* HAVE_AVAHI */ for (i = 1; i < argc; i ++) if (!strcmp(argv[i], "snmp")) snmponly = 1; else if (!strcmp(argv[i], "ipp")) ipponly = 1; else { puts("Usage: ./ipp-printers [{ipp | snmp}]"); return (1); } /* * Create an array to track devices... */ devices = cupsArrayNew((cups_array_func_t)compare_devices, NULL); /* * Browse for different kinds of printers... */ if (DNSServiceCreateConnection(&main_ref) != kDNSServiceErr_NoError) { perror("ERROR: Unable to create service connection"); return (1); } fd = DNSServiceRefSockFD(main_ref); ipp_ref = main_ref; DNSServiceBrowse(&ipp_ref, kDNSServiceFlagsShareConnection, 0, "_ipp._tcp", NULL, browse_callback, devices); /* * Loop until we are killed... */ progress(); for (;;) { FD_ZERO(&input); FD_SET(fd, &input); timeout.tv_sec = 2; timeout.tv_usec = 500000; if (select(fd + 1, &input, NULL, NULL, &timeout) <= 0) { time_t curtime = time(NULL); for (device = (cups_device_t *)cupsArrayFirst(devices); device; device = (cups_device_t *)cupsArrayNext(devices)) if (!device->got_resolve) { if (!device->ref) break; if ((curtime - device->resolve_time) > 10) { device->got_resolve = -1; fprintf(stderr, "\rUnable to resolve \"%s\": timeout\n", device->name); progress(); } else break; } if (!device) break; } if (FD_ISSET(fd, &input)) { /* * Process results of our browsing... */ progress(); DNSServiceProcessResult(main_ref); } else { /* * Query any devices we've found... */ DNSServiceErrorType status; /* DNS query status */ int count; /* Number of queries */ for (device = (cups_device_t *)cupsArrayFirst(devices), count = 0; device; device = (cups_device_t *)cupsArrayNext(devices)) { if (!device->ref && !device->sent) { /* * Found the device, now get the TXT record(s) for it... */ if (count < 50) { device->resolve_time = time(NULL); device->ref = main_ref; status = DNSServiceResolve(&(device->ref), kDNSServiceFlagsShareConnection, 0, device->name, device->regtype, device->domain, resolve_callback, device); if (status != kDNSServiceErr_NoError) { fprintf(stderr, "\rUnable to resolve \"%s\": %d\n", device->name, status); progress(); } else count ++; } } else if (!device->sent && device->got_resolve) { /* * Got the TXT records, now report the device... */ DNSServiceRefDeallocate(device->ref); device->ref = 0; device->sent = 1; } } } } #ifndef DEBUG fprintf(stderr, "\rFound %d printers. Now querying for capabilities...\n", cupsArrayCount(devices)); #endif /* !DEBUG */ puts("#!/bin/sh -x"); puts("test -d results && rm -rf results"); puts("mkdir results"); puts("CUPS_DEBUG_LEVEL=6; export CUPS_DEBUG_LEVEL"); puts("CUPS_DEBUG_FILTER='^(ipp|http|_ipp|_http|cupsGetResponse|cupsSend|" "cupsWrite|cupsDo).*'; export CUPS_DEBUG_FILTER"); for (device = (cups_device_t *)cupsArrayFirst(devices); device; device = (cups_device_t *)cupsArrayNext(devices)) { if (device->got_resolve <= 0 || device->cups_shared) continue; #ifdef DEBUG fprintf(stderr, "Checking \"%s\" (got_resolve=%d, cups_shared=%d, uri=%s)\n", device->name, device->got_resolve, device->cups_shared, device->uri); #else fprintf(stderr, "Checking \"%s\"...\n", device->name); #endif /* DEBUG */ if ((http = httpConnect(device->host, device->port)) == NULL) { fprintf(stderr, "Failed to connect to \"%s\": %s\n", device->name, cupsLastErrorString()); continue; } request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, device->uri); response = cupsDoRequest(http, request, device->rp); if (cupsLastError() > IPP_OK_SUBST) fprintf(stderr, "Failed to query \"%s\": %s\n", device->name, cupsLastErrorString()); else { if ((attr = ippFindAttribute(response, "ipp-versions-supported", IPP_TAG_KEYWORD)) != NULL) { version = attr->values[0].string.text; for (i = 1; i < attr->num_values; i ++) if (strcmp(attr->values[i].string.text, version) > 0) version = attr->values[i].string.text; } else version = "1.0"; testfile = NULL; if ((attr = ippFindAttribute(response, "document-format-supported", IPP_TAG_MIMETYPE)) != NULL) { /* * Figure out the test file for printing, preferring PDF and PostScript * over JPEG and plain text... */ for (i = 0; i < attr->num_values; i ++) { if (!strcasecmp(attr->values[i].string.text, "application/pdf")) { testfile = "testfile.pdf"; break; } else if (!strcasecmp(attr->values[i].string.text, "application/postscript")) testfile = "testfile.ps"; else if (!strcasecmp(attr->values[i].string.text, "image/jpeg") && !testfile) testfile = "testfile.jpg"; else if (!strcasecmp(attr->values[i].string.text, "text/plain") && !testfile) testfile = "testfile.txt"; else if (!strcasecmp(attr->values[i].string.text, "application/vnd.hp-PCL") && !testfile) testfile = "testfile.pcl"; } if (!testfile) { fprintf(stderr, "Printer \"%s\" reports the following IPP file formats:\n", device->name); for (i = 0; i < attr->num_values; i ++) fprintf(stderr, " \"%s\"\n", attr->values[i].string.text); } } if (!testfile && device->pdl) { char *pdl, /* Copy of pdl string */ *start, *end; /* Pointers into pdl string */ pdl = strdup(device->pdl); for (start = device->pdl; start && *start; start = end) { if ((end = strchr(start, ',')) != NULL) *end++ = '\0'; if (!strcasecmp(start, "application/pdf")) { testfile = "testfile.pdf"; break; } else if (!strcasecmp(start, "application/postscript")) testfile = "testfile.ps"; else if (!strcasecmp(start, "image/jpeg") && !testfile) testfile = "testfile.jpg"; else if (!strcasecmp(start, "text/plain") && !testfile) testfile = "testfile.txt"; else if (!strcasecmp(start, "application/vnd.hp-PCL") && !testfile) testfile = "testfile.pcl"; } free(pdl); if (testfile) { fprintf(stderr, "Using \"%s\" for printer \"%s\" based on TXT record pdl " "info.\n", testfile, device->name); } else { fprintf(stderr, "Printer \"%s\" reports the following TXT file formats:\n", device->name); fprintf(stderr, " \"%s\"\n", device->pdl); } } if (!device->ty && (attr = ippFindAttribute(response, "printer-make-and-model", IPP_TAG_TEXT)) != NULL) device->ty = strdup(attr->values[0].string.text); if (strcmp(version, "1.0") && testfile && device->ty) { char filename[1024], /* Filename */ *fileptr; /* Pointer into filename */ const char *typtr; /* Pointer into ty */ if (!strncasecmp(device->ty, "DeskJet", 7) || !strncasecmp(device->ty, "DesignJet", 9) || !strncasecmp(device->ty, "OfficeJet", 9) || !strncasecmp(device->ty, "Photosmart", 10)) strlcpy(filename, "HP_", sizeof(filename)); else filename[0] = '\0'; fileptr = filename + strlen(filename); if (!strncasecmp(device->ty, "Lexmark International Lexmark", 29)) typtr = device->ty + 22; else typtr = device->ty; while (*typtr && fileptr < (filename + sizeof(filename) - 1)) { if (isalnum(*typtr & 255) || *typtr == '-') *fileptr++ = *typtr++; else { *fileptr++ = '_'; typtr++; } } *fileptr = '\0'; printf("# %s\n", device->name); printf("echo \"Testing %s...\"\n", device->name); if (!ipponly) { printf("echo \"snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 " "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1\" > results/%s.snmpwalk\n", device->host, filename); printf("snmpwalk -c public -v 1 -Cc %s 1.3.6.1.2.1.25 " "1.3.6.1.2.1.43 1.3.6.1.4.1.2699.1 | " "tee -a results/%s.snmpwalk\n", device->host, filename); } if (!snmponly) { printf("echo \"./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s " "ipp-%s.test\" > results/%s.log\n", testfile, version, device->uri, version, filename); printf("CUPS_DEBUG_LOG=results/%s.debug_log " "./ipptool-static -tIf %s -T 30 -d NOPRINT=1 -V %s %s " "ipp-%s.test | tee -a results/%s.log\n", filename, testfile, version, device->uri, version, filename); } puts(""); } else if (!device->ty) fprintf(stderr, "Ignoring \"%s\" since it doesn't provide a make and model.\n", device->name); else if (!testfile) fprintf(stderr, "Ignoring \"%s\" since it does not support a common format.\n", device->name); else fprintf(stderr, "Ignoring \"%s\" since it only supports IPP/1.0.\n", device->name); } ippDelete(response); httpClose(http); } return (0); }
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 void _post_check (GtkCupsRequest *request) { http_status_t http_status; http_status = request->last_status; GTK_NOTE (PRINTING, g_print ("CUPS Backend: %s - status %i\n", G_STRFUNC, http_status)); request->poll_state = GTK_CUPS_HTTP_READ; if (http_status == HTTP_CONTINUE) { goto again; } else if (http_status == HTTP_UNAUTHORIZED) { int auth_result = -1; httpFlush (request->http); if (request->password_state == GTK_CUPS_PASSWORD_APPLIED) { request->poll_state = GTK_CUPS_HTTP_IDLE; request->password_state = GTK_CUPS_PASSWORD_NOT_VALID; request->state = GTK_CUPS_POST_AUTH; request->need_password = TRUE; return; } /* Negotiate */ if (strncmp (httpGetField (request->http, HTTP_FIELD_WWW_AUTHENTICATE), "Negotiate", 9) == 0) { auth_result = cupsDoAuthentication (request->http, "POST", request->resource); } /* Basic, BasicDigest, Digest and PeerCred */ else { if (request->password_state == GTK_CUPS_PASSWORD_NONE) { cups_username = request->username; cupsSetPasswordCB (passwordCB); /* This call success for PeerCred authentication */ auth_result = cupsDoAuthentication (request->http, "POST", request->resource); if (auth_result != 0) { /* move to AUTH state to let the backend * ask for a password */ request->poll_state = GTK_CUPS_HTTP_IDLE; request->state = GTK_CUPS_POST_AUTH; request->need_password = TRUE; return; } } else { cups_password = request->password; cups_username = request->username; auth_result = cupsDoAuthentication (request->http, "POST", request->resource); if (cups_password != NULL) return; if (request->password != NULL) { memset (request->password, 0, strlen (request->password)); g_free (request->password); request->password = NULL; } request->password_state = GTK_CUPS_PASSWORD_APPLIED; } } if (auth_result || httpReconnect (request->http)) { /* if the password has been used, reset password_state * so that we ask for a new one next time around */ if (cups_password == NULL) request->password_state = GTK_CUPS_PASSWORD_NONE; request->state = GTK_CUPS_POST_DONE; request->poll_state = GTK_CUPS_HTTP_IDLE; gtk_cups_result_set_error (request->result, GTK_CUPS_ERROR_AUTH, 0, 0, "Not authorized"); return; } if (request->data_io != NULL) g_io_channel_seek_position (request->data_io, 0, G_SEEK_SET, NULL); request->state = GTK_CUPS_POST_CONNECT; request->poll_state = GTK_CUPS_HTTP_WRITE; } else if (http_status == HTTP_ERROR) { int error = httpError (request->http); #ifdef G_OS_WIN32 if (error != WSAENETDOWN && error != WSAENETUNREACH) #else if (error != ENETDOWN && error != ENETUNREACH) #endif /* G_OS_WIN32 */ { request->attempts++; goto again; } else { request->state = GTK_CUPS_POST_DONE; request->poll_state = GTK_CUPS_HTTP_IDLE; gtk_cups_result_set_error (request->result, GTK_CUPS_ERROR_HTTP, http_status, error, "Unknown HTTP error"); return; } } else if (http_status == HTTP_UPGRADE_REQUIRED) { /* Flush any error message... */ httpFlush (request->http); cupsSetEncryption (HTTP_ENCRYPT_REQUIRED); request->state = GTK_CUPS_POST_CONNECT; /* Reconnect... */ httpReconnect (request->http); /* Upgrade with encryption... */ httpEncryption (request->http, HTTP_ENCRYPT_REQUIRED); request->attempts++; goto again; } else if (http_status != HTTP_OK) { int http_errno; http_errno = httpError (request->http); if (http_errno == EPIPE) request->state = GTK_CUPS_POST_CONNECT; else { request->state = GTK_CUPS_POST_DONE; gtk_cups_result_set_error (request->result, GTK_CUPS_ERROR_HTTP, http_status, http_errno, "HTTP Error in POST %s", g_strerror (http_errno)); request->poll_state = GTK_CUPS_HTTP_IDLE; httpFlush (request->http); return; } request->poll_state = GTK_CUPS_HTTP_IDLE; request->last_status = HTTP_CONTINUE; httpFlush (request->http); if (request->own_http) httpClose (request->http); request->http = NULL; return; } else { request->state = GTK_CUPS_POST_READ_RESPONSE; return; } again: http_status = HTTP_CONTINUE; if (httpCheck (request->http)) http_status = httpUpdate (request->http); request->last_status = http_status; }
const char * /* O - Filename for PPD file */ cupsGetPPD2(http_t *http, /* I - HTTP connection */ const char *name) /* I - Printer name */ { int http_port; /* Port number */ char http_hostname[HTTP_MAX_HOST]; /* Hostname associated with connection */ http_t *http2; /* Alternate HTTP connection */ int fd; /* PPD file */ char localhost[HTTP_MAX_URI],/* Local hostname */ hostname[HTTP_MAX_URI], /* Hostname */ resource[HTTP_MAX_URI]; /* Resource name */ int port; /* Port number */ http_status_t status; /* HTTP status from server */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ /* * Range check input... */ DEBUG_printf(("cupsGetPPD2(http=%p, name=\"%s\")\n", http, name ? name : "(null)")); if (!http || !name) { if (!http) _cupsSetError(IPP_INTERNAL_ERROR, "No HTTP connection!"); else _cupsSetError(IPP_INTERNAL_ERROR, "No printer name!"); return (NULL); } /* * Try finding a printer URI for this printer... */ if (!cups_get_printer_uri(http, name, hostname, sizeof(hostname), &port, resource, sizeof(resource), 0)) return (NULL); DEBUG_printf(("cupsGetPPD3: Printer hostname=\"%s\", port=%d\n", hostname, port)); /* * Remap local hostname to localhost... */ httpGetHostname(NULL, localhost, sizeof(localhost)); DEBUG_printf(("Local hostname=\"%s\"\n", localhost)); if (!strcasecmp(localhost, hostname)) strcpy(hostname, "localhost"); /* * Get the hostname and port number we are connected to... */ httpGetHostname(http, http_hostname, sizeof(http_hostname)); #ifdef AF_INET6 if (http->hostaddr->addr.sa_family == AF_INET6) http_port = ntohs(http->hostaddr->ipv6.sin6_port); else #endif /* AF_INET6 */ if (http->hostaddr->addr.sa_family == AF_INET) http_port = ntohs(http->hostaddr->ipv4.sin_port); else http_port = ippPort(); DEBUG_printf(("Connection hostname=\"%s\", port=%d\n", http_hostname, http_port)); /* * Reconnect to the correct server as needed... */ if (!strcasecmp(http_hostname, hostname) && port == http_port) http2 = http; else if ((http2 = httpConnectEncrypt(hostname, port, cupsEncryption())) == NULL) { DEBUG_puts("Unable to connect to server!"); return (NULL); } /* * Get a temp file... */ if ((fd = cupsTempFd(cg->ppd_filename, sizeof(cg->ppd_filename))) < 0) { /* * Can't open file; close the server connection and return NULL... */ _cupsSetError(IPP_INTERNAL_ERROR, strerror(errno)); if (http2 != http) httpClose(http2); return (NULL); } /* * And send a request to the HTTP server... */ strlcat(resource, ".ppd", sizeof(resource)); status = cupsGetFd(http2, resource, fd); close(fd); /* * See if we actually got the file or an error... */ if (status != HTTP_OK) { switch (status) { case HTTP_NOT_FOUND : _cupsSetError(IPP_NOT_FOUND, httpStatus(status)); break; case HTTP_UNAUTHORIZED : _cupsSetError(IPP_NOT_AUTHORIZED, httpStatus(status)); break; default : DEBUG_printf(("HTTP error %d mapped to IPP_SERVICE_UNAVAILABLE!\n", status)); _cupsSetError(IPP_SERVICE_UNAVAILABLE, httpStatus(status)); break; } unlink(cg->ppd_filename); return (NULL); } if (http2 != http) httpClose(http2); /* * Return the PPD file... */ return (cg->ppd_filename); }
static int /* O - 1 on success, 0 on failure */ cups_get_printer_uri( http_t *http, /* I - HTTP connection */ const char *name, /* I - Name of printer or class */ char *host, /* I - Hostname buffer */ int hostsize, /* I - Size of hostname buffer */ int *port, /* O - Port number */ char *resource, /* I - Resource buffer */ int resourcesize, /* I - Size of resource buffer */ int depth) /* I - Depth of query */ { int i; /* Looping var */ int http_port; /* Port number */ http_t *http2; /* Alternate HTTP connection */ ipp_t *request, /* IPP request */ *response; /* IPP response */ ipp_attribute_t *attr; /* Current attribute */ char uri[HTTP_MAX_URI], /* printer-uri attribute */ scheme[HTTP_MAX_URI], /* Scheme name */ username[HTTP_MAX_URI], /* Username:password */ classname[255], /* Temporary class name */ http_hostname[HTTP_MAX_HOST]; /* Hostname associated with connection */ static const char * const requested_attrs[] = { /* Requested attributes */ "printer-uri-supported", "printer-type", "member-uris" }; DEBUG_printf(("cups_get_printer_uri(http=%p, name=\"%s\", host=%p, " "hostsize=%d, resource=%p, resourcesize=%d, depth=%d)\n", http, name ? name : "(null)", host, hostsize, resource, resourcesize, depth)); /* * Setup the printer URI... */ if (httpAssembleURIf(HTTP_URI_CODING_ALL, uri, sizeof(uri), "ipp", NULL, "localhost", 0, "/printers/%s", name) != HTTP_URI_OK) { _cupsSetError(IPP_INTERNAL_ERROR, "Unable to create printer-uri!"); *host = '\0'; *resource = '\0'; return (0); } DEBUG_printf(("cups_get_printer_uri: printer-uri=\"%s\"\n", uri)); /* * Get the hostname and port number we are connected to... */ httpGetHostname(http, http_hostname, sizeof(http_hostname)); #ifdef AF_INET6 if (http->hostaddr->addr.sa_family == AF_INET6) http_port = ntohs(http->hostaddr->ipv6.sin6_port); else #endif /* AF_INET6 */ if (http->hostaddr->addr.sa_family == AF_INET) http_port = ntohs(http->hostaddr->ipv4.sin_port); else http_port = ippPort(); /* * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * requested-attributes */ request = ippNewRequest(IPP_GET_PRINTER_ATTRIBUTES); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requested-attributes", sizeof(requested_attrs) / sizeof(requested_attrs[0]), NULL, requested_attrs); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { if ((attr = ippFindAttribute(response, "member-uris", IPP_TAG_URI)) != NULL) { /* * Get the first actual printer name in the class... */ for (i = 0; i < attr->num_values; i ++) { httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize); if (!strncmp(resource, "/printers/", 10)) { /* * Found a printer! */ ippDelete(response); return (1); } } /* * No printers in this class - try recursively looking for a printer, * but not more than 3 levels deep... */ if (depth < 3) { for (i = 0; i < attr->num_values; i ++) { httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[i].string.text, scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize); if (!strncmp(resource, "/classes/", 9)) { /* * Found a class! Connect to the right server... */ if (!strcasecmp(http_hostname, host) && *port == http_port) http2 = http; else if ((http2 = httpConnectEncrypt(host, *port, cupsEncryption())) == NULL) { DEBUG_puts("Unable to connect to server!"); continue; } /* * Look up printers on that server... */ strlcpy(classname, resource + 9, sizeof(classname)); cups_get_printer_uri(http2, classname, host, hostsize, port, resource, resourcesize, depth + 1); /* * Close the connection as needed... */ if (http2 != http) httpClose(http2); if (*host) return (1); } } } } else if ((attr = ippFindAttribute(response, "printer-uri-supported", IPP_TAG_URI)) != NULL) { httpSeparateURI(HTTP_URI_CODING_ALL, attr->values[0].string.text, scheme, sizeof(scheme), username, sizeof(username), host, hostsize, port, resource, resourcesize); ippDelete(response); if (!strncmp(resource, "/classes/", 9)) { _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found for class!")); *host = '\0'; *resource = '\0'; return (0); } return (1); } ippDelete(response); } if (cupsLastError() != IPP_NOT_FOUND) _cupsSetError(IPP_INTERNAL_ERROR, _("No printer-uri found!")); *host = '\0'; *resource = '\0'; return (0); }
static char * /* I - Printer name or NULL */ cups_connect(const char *name, /* I - Destination (printer[@host]) */ char *printer, /* O - Printer name [HTTP_MAX_URI] */ char *hostname) /* O - Hostname [HTTP_MAX_URI] */ { char hostbuf[HTTP_MAX_URI], /* Name of host */ http_hostname[HTTP_MAX_HOST]; /* Hostname associated with connection */ _cups_globals_t *cg = _cupsGlobals();/* Pointer to library globals */ DEBUG_printf(("cups_connect(\"%s\", %p, %p)\n", name, printer, hostname)); if (name == NULL) { _cupsSetError(IPP_BAD_REQUEST, NULL); return (NULL); } /* * All jobs are now queued to cupsServer() to avoid hostname * resolution problems and to ensure that the user sees all * locally queued jobs locally. */ strlcpy(hostbuf, cupsServer(), sizeof(hostbuf)); httpGetHostname(cg->http, http_hostname, sizeof(http_hostname)); if (hostname != NULL) strlcpy(hostname, hostbuf, HTTP_MAX_URI); else hostname = hostbuf; if (printer != NULL) strlcpy(printer, name, HTTP_MAX_URI); else printer = (char *)name; if (cg->http != NULL) { if (!strcasecmp(http_hostname, hostname)) return (printer); httpClose(cg->http); } DEBUG_printf(("connecting to %s on port %d...\n", hostname, ippPort())); if ((cg->http = httpConnectEncrypt(hostname, ippPort(), cupsEncryption())) == NULL) { DEBUG_puts("Unable to connect to server!"); _cupsSetError(IPP_SERVICE_UNAVAILABLE, strerror(errno)); return (NULL); } else return (printer); }