📄 print_iprint.c
字号:
/* * Support code for Novell iPrint using the Common UNIX Printing * System ("CUPS") libraries * * Copyright 1999-2003 by Michael R Sweet. * Portions Copyright 2005 by Joel J. Smith. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */#include "includes.h"#include "printing.h"#ifdef HAVE_IPRINT#include <cups/cups.h>#include <cups/language.h>#define OPERATION_NOVELL_LIST_PRINTERS 0x401A#define OPERATION_NOVELL_MGMT 0x401C#define NOVELL_SERVER_SYSNAME "sysname="#define NOVELL_SERVER_SYSNAME_NETWARE "NetWare IA32"#define NOVELL_SERVER_VERSION_STRING "iprintserverversion="#define NOVELL_SERVER_VERSION_OES_SP1 33554432/* * 'iprint_passwd_cb()' - The iPrint password callback... */static const char * /* O - Password or NULL */iprint_passwd_cb(const char *prompt) /* I - Prompt */{ /* * Always return NULL to indicate that no password is available... */ return (NULL);}static const char *iprint_server(void){ if ((lp_iprint_server() != NULL) && (strlen(lp_iprint_server()) > 0)) { DEBUG(10, ("iprint server explicitly set to %s\n", lp_iprint_server())); return lp_iprint_server(); } DEBUG(10, ("iprint server left to default %s\n", cupsServer())); return cupsServer();}/* * Pass in an already connected http_t* * Returns the server version if one can be found, multiplied by * -1 for all NetWare versions. Returns 0 if a server version * cannot be determined */static int iprint_get_server_version(http_t *http, char* serviceUri){ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *ver; /* server version pointer */ char *vertmp; /* server version tmp pointer */ int serverVersion = 0; /* server version */ char *os; /* server os */ int osFlag = 0; /* 0 for NetWare, 1 for anything else */ char *temp; /* pointer for string manipulation */ /* * Build an OPERATION_NOVELL_MGMT("get-server-version") request, * which requires the following attributes: * * attributes-charset * attributes-natural-language * operation-name * service-uri */ request = ippNew(); request->request.op.operation_id = OPERATION_NOVELL_MGMT; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "service-uri", NULL, serviceUri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "operation-name", NULL, "get-server-version"); /* * Do the request and get back a response... */ if (((response = cupsDoRequest(http, request, "/ipp/")) == NULL) || (response->request.status.status_code >= IPP_OK_CONFLICT)) goto out; if (((attr = ippFindAttribute(response, "server-version", IPP_TAG_STRING)) != NULL)) { if ((ver = strstr(attr->values[0].string.text, NOVELL_SERVER_VERSION_STRING)) != NULL) { ver += strlen(NOVELL_SERVER_VERSION_STRING); /* * Strangely, libcups stores a IPP_TAG_STRING (octet * string) as a null-terminated string with no length * even though it could be binary data with nulls in * it. Luckily, in this case the value is not binary. */ serverVersion = strtol(ver, &vertmp, 10); /* Check for not found, overflow or negative version */ if ((ver == vertmp) || (serverVersion < 0)) serverVersion = 0; } if ((os = strstr(attr->values[0].string.text, NOVELL_SERVER_SYSNAME)) != NULL) { os += strlen(NOVELL_SERVER_SYSNAME); if ((temp = strchr(os,'<')) != NULL) *temp = '\0'; if (strcmp(os,NOVELL_SERVER_SYSNAME_NETWARE)) osFlag = 1; /* 1 for non-NetWare systems */ } } out: if (response) ippDelete(response); if (language) cupsLangFree(language); if (osFlag == 0) serverVersion *= -1; return serverVersion;}static int iprint_cache_add_printer(http_t *http, int reqId, char* url){ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ char *name, /* printer-name attribute */ *info, /* printer-info attribute */ smb_enabled, /* smb-enabled attribute */ secure; /* security-enabled attrib. */ char *httpPath; /* path portion of the printer-uri */ static const char *pattrs[] = /* Requested printer attributes */ { "printer-name", "security-enabled", "printer-info", "smb-enabled" }; request = ippNew(); request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES; request->request.op.request_id = reqId; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, url); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", (sizeof(pattrs) / sizeof(pattrs[0])), NULL, pattrs); /* * Do the request and get back a response... */ if ((httpPath = strstr(url,"://")) == NULL || (httpPath = strchr(httpPath+3,'/')) == NULL) { ippDelete(request); request = NULL; goto out; } if ((response = cupsDoRequest(http, request, httpPath)) == NULL) { ipp_status_t lastErr = cupsLastError(); /* * Ignore printers that cannot be queried without credentials */ if (lastErr == IPP_FORBIDDEN || lastErr == IPP_NOT_AUTHENTICATED || lastErr == IPP_NOT_AUTHORIZED) goto out; DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(lastErr))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ name = NULL; info = NULL; smb_enabled= 1; secure = 0; while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && attr->value_tag == IPP_TAG_NAME) name = attr->values[0].string.text; if (strcmp(attr->name, "printer-info") == 0 && (attr->value_tag == IPP_TAG_TEXT || attr->value_tag == IPP_TAG_TEXTLANG)) info = attr->values[0].string.text; /* * If the smb-enabled attribute is present and the * value is set to 0, don't show the printer. * If the attribute is not present, assume that the * printer should show up */ if (!strcmp(attr->name, "smb-enabled") && ((attr->value_tag == IPP_TAG_INTEGER && !attr->values[0].integer) || (attr->value_tag == IPP_TAG_BOOLEAN && !attr->values[0].boolean))) smb_enabled = 0; /* * If the security-enabled attribute is present and the * value is set to 1, don't show the printer. * If the attribute is not present, assume that the * printer should show up */ if (!strcmp(attr->name, "security-enabled") && ((attr->value_tag == IPP_TAG_INTEGER && attr->values[0].integer) || (attr->value_tag == IPP_TAG_BOOLEAN && attr->values[0].boolean))) secure = 1; attr = attr->next; } /* * See if we have everything needed... * Make sure the printer is not a secure printer * and make sure smb printing hasn't been explicitly * disabled for the printer */ if (name != NULL && !secure && smb_enabled) pcap_cache_add(name, info); } out: if (response) ippDelete(response); return(0);}BOOL iprint_cache_reload(void){ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ ipp_attribute_t *attr; /* Current attribute */ cups_lang_t *language = NULL; /* Default language */ int i; BOOL ret = False; DEBUG(5, ("reloading iprint printcap cache\n")); /* * Make sure we don't ask for passwords... */ cupsSetPasswordCB(iprint_passwd_cb); /* * Try to connect to the server... */ if ((http = httpConnect(iprint_server(), ippPort())) == NULL) { DEBUG(0,("Unable to connect to iPrint server %s - %s\n", iprint_server(), strerror(errno))); goto out; } /* * Build a OPERATION_NOVELL_LIST_PRINTERS request, which requires the following attributes: * * attributes-charset * attributes-natural-language */ request = ippNew(); request->request.op.operation_id = OPERATION_NOVELL_LIST_PRINTERS; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "ipp-server", NULL, "ippSrvr"); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/ipp")) == NULL) { DEBUG(0,("Unable to get printer list - %s\n", ippErrorString(cupsLastError()))); goto out; } for (attr = response->attrs; attr != NULL;) { /* * Skip leading attributes until we hit a printer... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this printer... */ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && (attr->value_tag == IPP_TAG_URI || attr->value_tag == IPP_TAG_NAME || attr->value_tag == IPP_TAG_TEXT || attr->value_tag == IPP_TAG_NAMELANG || attr->value_tag == IPP_TAG_TEXTLANG)) { for (i = 0; i<attr->num_values; i++) { char *url = attr->values[i].string.text; if (!url || !strlen(url)) continue; iprint_cache_add_printer(http, i+2, url); } } attr = attr->next; } } ret = True; out: if (response) ippDelete(response); if (language) cupsLangFree(language);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -