12264Sjacobs /* 22264Sjacobs * CDDL HEADER START 32264Sjacobs * 42264Sjacobs * The contents of this file are subject to the terms of the 52264Sjacobs * Common Development and Distribution License (the "License"). 62264Sjacobs * You may not use this file except in compliance with the License. 72264Sjacobs * 82264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 92264Sjacobs * or http://www.opensolaris.org/os/licensing. 102264Sjacobs * See the License for the specific language governing permissions 112264Sjacobs * and limitations under the License. 122264Sjacobs * 132264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 142264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 152264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 162264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 172264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 182264Sjacobs * 192264Sjacobs * CDDL HEADER END 202264Sjacobs */ 212264Sjacobs 222264Sjacobs /* 236817Sjacobs * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 242264Sjacobs * Use is subject to license terms. 252264Sjacobs * 262264Sjacobs */ 272264Sjacobs 282409Sjacobs /* Id: nss.c 180 2006-07-20 17:33:02Z njacobs $ */ 292264Sjacobs 302264Sjacobs #include <stdio.h> 312264Sjacobs #include <stdlib.h> 322264Sjacobs #include <unistd.h> 332264Sjacobs #include <string.h> 342264Sjacobs #include <ctype.h> 352264Sjacobs #include <sys/types.h> 362264Sjacobs #include <syslog.h> 372264Sjacobs #include <papi.h> 382264Sjacobs #include <uri.h> 392264Sjacobs #include <papi_impl.h> 402264Sjacobs #ifdef NSS_EMULATION 412264Sjacobs #include <nss-emulation.h> 422264Sjacobs #elif NSS_SOLARIS 432264Sjacobs #include <nss_dbdefs.h> 442264Sjacobs #endif 452264Sjacobs #include <config-site.h> 462264Sjacobs #if defined(__sun) && defined(__SVR4) 472264Sjacobs #include <sys/systeminfo.h> 482264Sjacobs #endif 492264Sjacobs 502264Sjacobs 512264Sjacobs static char * 522409Sjacobs bsdaddr_to_uri(papi_attribute_t **list, char *bsdaddr) 532264Sjacobs { 542264Sjacobs char *result = NULL; 552264Sjacobs 562264Sjacobs if (bsdaddr != NULL) { 572264Sjacobs char *bsd[3], *tmp, *iter = NULL; 582264Sjacobs char buf[512]; 592264Sjacobs 602264Sjacobs tmp = strdup(bsdaddr); 612264Sjacobs 622264Sjacobs bsd[0] = strtok_r(tmp, ":,", &iter); 632409Sjacobs if ((bsd[1] = strtok_r(NULL, ":,", &iter)) == NULL) 642409Sjacobs papiAttributeListGetString(list, NULL, 652409Sjacobs "printer-name", &bsd[1]); 662264Sjacobs bsd[2] = strtok_r(NULL, ":,", &iter); 672264Sjacobs 682409Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s%s%s", bsd[0], 692409Sjacobs (bsd[1] != NULL) ? bsd[1] : "", 702264Sjacobs (bsd[2] != NULL) ? "#" : "", 712264Sjacobs (bsd[2] != NULL) ? bsd[2] : ""); 722264Sjacobs 732264Sjacobs free(tmp); 742264Sjacobs 752264Sjacobs result = strdup(buf); 762264Sjacobs } 772264Sjacobs 782264Sjacobs return (result); 792264Sjacobs } 802264Sjacobs 812264Sjacobs #if defined(__sun) && defined(__SVR4) 822264Sjacobs /* 832264Sjacobs * This is an awful HACK to force the dynamic PAPI library to use the 842264Sjacobs * lpsched support when the destination apears to be a local lpsched 852264Sjacobs * queue on Solaris. 862264Sjacobs */ 872264Sjacobs static void 882264Sjacobs solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list) 892264Sjacobs { 902264Sjacobs papi_attribute_t *attribute; 912264Sjacobs uri_t *uri = NULL; 922264Sjacobs char *printer = NULL; 932264Sjacobs char buf[128], buf2[128]; 942264Sjacobs 952264Sjacobs /* setting this in the calling env can be useful for debugging */ 962264Sjacobs if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL) 972264Sjacobs return; 982264Sjacobs 992264Sjacobs papiAttributeListGetString(*list, NULL, 1002264Sjacobs "printer-uri-supported", &printer); 1017253Sjacobs /* if there is no printer-uri-supported, there is nothing to do */ 102*7322SWendy.Phillips@Sun.COM if (printer == NULL) { 1032264Sjacobs return; 104*7322SWendy.Phillips@Sun.COM } 1052264Sjacobs 1067253Sjacobs if (uri_from_string(printer, &uri) < 0) { 1077253Sjacobs papiAttributeListFree(*list); 1087253Sjacobs *list = NULL; 109*7322SWendy.Phillips@Sun.COM uri_free(uri); 1107253Sjacobs return; 1117253Sjacobs } 1127253Sjacobs 1132264Sjacobs /* already an lpsched URI ? */ 114*7322SWendy.Phillips@Sun.COM if (strcasecmp(uri->scheme, "lpsched") == 0) { 115*7322SWendy.Phillips@Sun.COM uri_free(uri); 1162264Sjacobs return; 117*7322SWendy.Phillips@Sun.COM } 1182264Sjacobs 1192264Sjacobs if ((printer = strrchr(uri->path, '/')) == NULL) 1202264Sjacobs printer = uri->path; 1212264Sjacobs else 1222264Sjacobs printer++; 1232264Sjacobs 1242264Sjacobs /* is there an lpsched queue (printer/class) */ 1252264Sjacobs snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer); 1262264Sjacobs snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer); 127*7322SWendy.Phillips@Sun.COM if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) { 128*7322SWendy.Phillips@Sun.COM uri_free(uri); 1292264Sjacobs return; 130*7322SWendy.Phillips@Sun.COM } 1312264Sjacobs 1322313Sjacobs /* is this the "local" host */ 133*7322SWendy.Phillips@Sun.COM if ((uri->host != NULL) && (is_localhost(uri->host) == 0)) { 134*7322SWendy.Phillips@Sun.COM uri_free(uri); 1352313Sjacobs return; 136*7322SWendy.Phillips@Sun.COM } 1372313Sjacobs 1382313Sjacobs snprintf(buf, sizeof (buf), "lpsched://%s/printers/%s", 1392313Sjacobs (uri->host ? uri->host : "localhost"), printer); 1402264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_REPLACE, 1412264Sjacobs "printer-uri-supported", buf); 142*7322SWendy.Phillips@Sun.COM uri_free(uri); 1432264Sjacobs } 1442264Sjacobs #endif 1452264Sjacobs 1462264Sjacobs static void 1472264Sjacobs fill_printer_uri_supported(papi_attribute_t ***list) 1482264Sjacobs { 1492264Sjacobs papi_attribute_t *attribute; 1502264Sjacobs char *string = NULL; 1512264Sjacobs 1522264Sjacobs /* do we have a printer-uri-supported */ 1532264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri-supported"); 1542264Sjacobs if (attribute != NULL) /* we have what we need, return */ 1552264Sjacobs return; 1562264Sjacobs 1576817Sjacobs /* do we have a printer-uri (in URI form) to rename */ 1582264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 1596817Sjacobs if ((attribute != NULL) && 1606817Sjacobs (attribute->type == PAPI_STRING) && 1616817Sjacobs (attribute->values != NULL) && 1626817Sjacobs (attribute->values[0]->string != NULL) && 1636817Sjacobs (strstr(attribute->values[0]->string, "://") != NULL)) { 1646817Sjacobs /* rename it in place and return */ 1652264Sjacobs free(attribute->name); 1662264Sjacobs attribute->name = strdup("printer-uri-supported"); 1672264Sjacobs return; 1682264Sjacobs } 1692264Sjacobs 1702264Sjacobs /* do we have a printers.conf(4) "bsdaddr" to convert */ 1712264Sjacobs papiAttributeListGetString(*list, NULL, "bsdaddr", &string); 1722264Sjacobs if (string != NULL) { /* parse it, convert it, add it */ 1732409Sjacobs char *uri = bsdaddr_to_uri(*list, string); 1742264Sjacobs 1752264Sjacobs if (uri != NULL) { 1762264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 1772264Sjacobs "printer-uri-supported", uri); 1782264Sjacobs papiAttributeListDelete(list, "bsdaddr"); 1792264Sjacobs free(uri); 1802264Sjacobs return; 1812264Sjacobs } 1822264Sjacobs } 1832264Sjacobs 1842264Sjacobs /* do we have a printers.conf(4) "rm" (and "rp") to convert */ 1852264Sjacobs papiAttributeListGetString(*list, NULL, "rm", &string); 1862264Sjacobs if (string != NULL) { 1872264Sjacobs char *rp = NULL; 1882264Sjacobs 1892264Sjacobs /* default to "printer-name", but use "rp" if we have it */ 1902264Sjacobs papiAttributeListGetString(*list, NULL, "printer-name", &rp); 1912264Sjacobs papiAttributeListGetString(*list, NULL, "rp", &rp); 1922264Sjacobs 1932264Sjacobs if (rp != NULL) { /* fill in the uri if we have the data */ 1942264Sjacobs char buf[BUFSIZ]; 1952264Sjacobs 1962264Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", 1972264Sjacobs string, rp); 1982264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 1992264Sjacobs "printer-uri-supported", strdup(buf)); 2002264Sjacobs return; 2012264Sjacobs } 2022264Sjacobs } 2032264Sjacobs 2042264Sjacobs /* if were are here, we don't have a printer-uri-supported */ 2052264Sjacobs } 2062264Sjacobs 2072264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 2082264Sjacobs static void 2092264Sjacobs fill_printer_uri(papi_attribute_t ***list) 2102264Sjacobs { 2112264Sjacobs papi_attribute_t *attribute; 2122264Sjacobs char *uri = NULL; 2132264Sjacobs 2142264Sjacobs if ((list == NULL) || (*list == NULL)) 2152264Sjacobs return; 2162264Sjacobs 2172313Sjacobs /* do we have a printer-uri */ 2182264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 2192264Sjacobs if (attribute != NULL) /* we have what we need, return */ 2202264Sjacobs return; 2212264Sjacobs 2222264Sjacobs /* 2232264Sjacobs * this is sufficient to fool libgnomeprintpapi, but not promote it's 2242264Sjacobs * use in the future. 2252264Sjacobs */ 2262264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", 2272264Sjacobs "broken printer-uri semantic"); 2282264Sjacobs } 2292264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 2302264Sjacobs 2312264Sjacobs static void 2322264Sjacobs cvt_all_to_member_names(papi_attribute_t ***list) 2332264Sjacobs { 2342264Sjacobs papi_status_t status; 2352264Sjacobs void *iter = NULL; 2362264Sjacobs char *string = NULL; 2372264Sjacobs 2382264Sjacobs papiAttributeListGetString(*list, NULL, "member-names", &string); 2392264Sjacobs if (string != NULL) /* already have a member-names */ 2402264Sjacobs return; 2412264Sjacobs 2422264Sjacobs for (status = papiAttributeListGetString(*list, &iter, "all", &string); 243*7322SWendy.Phillips@Sun.COM status == PAPI_OK; 244*7322SWendy.Phillips@Sun.COM status = papiAttributeListGetString(*list, &iter, NULL, &string)) { 2452264Sjacobs char *s_iter = NULL, *value, *tmp = strdup(string); 2462264Sjacobs 2472264Sjacobs for (value = strtok_r(tmp, ", \t", &s_iter); 248*7322SWendy.Phillips@Sun.COM value != NULL; 249*7322SWendy.Phillips@Sun.COM value = strtok_r(NULL, ", \t", &s_iter)) 2502264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 2512264Sjacobs "member-names", value); 2522264Sjacobs free(tmp); 2532264Sjacobs } 2542264Sjacobs } 2552264Sjacobs 2562264Sjacobs static papi_attribute_t ** 2572264Sjacobs _cvt_nss_entry_to_printer(char *entry) 2582264Sjacobs { 2592264Sjacobs char *key = NULL, 2602264Sjacobs *cp, 2612264Sjacobs buf[BUFSIZ]; 2622264Sjacobs int in_namelist = 1, buf_pos = 0; 2632264Sjacobs papi_attribute_t **list = NULL; 2642264Sjacobs 2652264Sjacobs if (entry == NULL) 2662264Sjacobs return (NULL); 2672264Sjacobs 2682264Sjacobs memset(buf, 0, sizeof (buf)); 2692264Sjacobs for (cp = entry; *cp != '\0'; cp++) { 2702264Sjacobs switch (*cp) { 2712264Sjacobs case ':': /* end of kvp */ 2722264Sjacobs if (in_namelist != 0) { 2732264Sjacobs papiAttributeListAddString(&list, 2742264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 2752264Sjacobs in_namelist = 0; 276*7322SWendy.Phillips@Sun.COM } else if (key != NULL) { 2772264Sjacobs papiAttributeListAddString(&list, 2782264Sjacobs PAPI_ATTR_APPEND, key, buf); 279*7322SWendy.Phillips@Sun.COM free(key); 280*7322SWendy.Phillips@Sun.COM } 2812264Sjacobs memset(buf, 0, sizeof (buf)); 2822264Sjacobs buf_pos = 0; 2832264Sjacobs key = NULL; 2842264Sjacobs break; 2852264Sjacobs case '=': /* kvp seperator */ 2862264Sjacobs if (key == NULL) { 2872264Sjacobs key = strdup(buf); 2882264Sjacobs memset(buf, 0, sizeof (buf)); 2892264Sjacobs buf_pos = 0; 2902264Sjacobs } else 2912264Sjacobs buf[buf_pos++] = *cp; 2922264Sjacobs break; 2932264Sjacobs case '|': /* namelist seperator */ 2942264Sjacobs if (in_namelist != 0) { 2952264Sjacobs papiAttributeListAddString(&list, 2962264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 2972264Sjacobs memset(buf, 0, sizeof (buf)); 2982264Sjacobs buf_pos = 0; 2992264Sjacobs } else /* add it to the buffer */ 3002264Sjacobs buf[buf_pos++] = *cp; 3012264Sjacobs break; 3022264Sjacobs case '\\': /* escape char */ 3032264Sjacobs buf[buf_pos++] = *(++cp); 3042264Sjacobs break; 3052264Sjacobs default: 3062264Sjacobs buf[buf_pos++] = *cp; 3072264Sjacobs } 3082264Sjacobs 3092264Sjacobs } 3102264Sjacobs 311*7322SWendy.Phillips@Sun.COM if (key != NULL) { 3122264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); 313*7322SWendy.Phillips@Sun.COM free(key); 314*7322SWendy.Phillips@Sun.COM } 3152264Sjacobs 3162264Sjacobs /* resolve any "use" references in the configuration DB */ 3172264Sjacobs key = NULL; 3182264Sjacobs papiAttributeListGetString(list, NULL, "use", &key); 3192264Sjacobs if (key != NULL) { 3202264Sjacobs papi_attribute_t **use_attrs = getprinterbyname(key, NULL); 3212264Sjacobs 3222264Sjacobs list_concatenate(&list, use_attrs); 3232264Sjacobs } 3242264Sjacobs 3252264Sjacobs fill_printer_uri_supported(&list); 3262264Sjacobs cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ 3272264Sjacobs 3282264Sjacobs return (list); 3292264Sjacobs } 3302264Sjacobs 3312264Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) 3322264Sjacobs 3332264Sjacobs #ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ 3342264Sjacobs #define NSS_DBNAM__PRINTERS "_printers" 3352264Sjacobs #endif 3362264Sjacobs 3372264Sjacobs static DEFINE_NSS_DB_ROOT(db_root); 3382264Sjacobs static DEFINE_NSS_GETENT(context); 3392264Sjacobs 3402264Sjacobs static char *private_ns = NULL; 3412264Sjacobs 3422264Sjacobs static void 3432264Sjacobs _nss_initf_printers(p) 3442264Sjacobs nss_db_params_t *p; 3452264Sjacobs { 3462264Sjacobs if (private_ns != NULL) { 3472264Sjacobs /* 3482264Sjacobs * because we need to support a legacy interface that allows 3492264Sjacobs * us to select a specific name service, we need to dummy up 3502264Sjacobs * the parameters to use a private nsswitch database and set 3512264Sjacobs * the * default_config entry to the name service we are 3522264Sjacobs * looking into. 3532264Sjacobs */ 3542264Sjacobs p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ 3552264Sjacobs p->default_config = private_ns; 3562847Sjacobs } else { 3572264Sjacobs /* regular behaviour */ 3582264Sjacobs p->name = NSS_DBNAM_PRINTERS; /* "printers" */ 3592264Sjacobs p->default_config = NSS_DEFCONF_PRINTERS; 3602264Sjacobs } 3612847Sjacobs syslog(LOG_DEBUG, "database: %s, default: %s", 3622264Sjacobs (p->name ? p->name : "NULL"), 3632264Sjacobs (p->default_config ? p->default_config : "NULL")); 3642264Sjacobs } 3652264Sjacobs 3662264Sjacobs /* 3672264Sjacobs * Return values: 0 = success, 1 = parse error, 2 = erange ... 3682264Sjacobs * The structure pointer passed in is a structure in the caller's space 3692264Sjacobs * wherein the field pointers would be set to areas in the buffer if 3702264Sjacobs * need be. instring and buffer should be separate areas. 3712264Sjacobs */ 3722264Sjacobs /* ARGSUSED */ 3732264Sjacobs static int 3742264Sjacobs str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 3752264Sjacobs { 3762264Sjacobs if (lenstr + 1 > buflen) 3772264Sjacobs return (NSS_STR_PARSE_ERANGE); 3782571Sjacobs 3792571Sjacobs /* skip entries that begin with '#' */ 3802571Sjacobs if (instr[0] == '#') 3812571Sjacobs return (NSS_STR_PARSE_PARSE); 3822571Sjacobs 3832264Sjacobs /* 3842264Sjacobs * We copy the input string into the output buffer 3852264Sjacobs */ 3862264Sjacobs (void) memcpy(buffer, instr, lenstr); 3872264Sjacobs buffer[lenstr] = '\0'; 3882264Sjacobs 3892264Sjacobs return (NSS_STR_PARSE_SUCCESS); 3902264Sjacobs } 3912264Sjacobs #endif /* NSS_SOLARIS */ 3922264Sjacobs 3932264Sjacobs int 3942264Sjacobs setprinterentry(int stayopen, char *ns) 3952264Sjacobs { 3962264Sjacobs #ifdef NSS_EMULATION 3972264Sjacobs emul_setprinterentry(stayopen); 3982264Sjacobs #elif NSS_SOLARIS 3992264Sjacobs private_ns = ns; 4002264Sjacobs nss_setent(&db_root, _nss_initf_printers, &context); 4012847Sjacobs private_ns = NULL; 4022264Sjacobs #endif 4032264Sjacobs return (0); 4042264Sjacobs } 4052264Sjacobs 4062264Sjacobs 4072264Sjacobs int 4082264Sjacobs endprinterentry(int i) 4092264Sjacobs { 4102264Sjacobs #ifdef NSS_EMULATION 4112264Sjacobs emul_endprinterentry(); 4122264Sjacobs #elif NSS_SOLARIS 4132264Sjacobs nss_endent(&db_root, _nss_initf_printers, &context); 4142264Sjacobs nss_delete(&db_root); 4152847Sjacobs private_ns = NULL; 4162264Sjacobs #endif 4172264Sjacobs return (0); 4182264Sjacobs } 4192264Sjacobs 4202264Sjacobs /* ARGSUSED2 */ 4212264Sjacobs papi_attribute_t ** 4222264Sjacobs getprinterentry(char *ns) 4232264Sjacobs { 4242264Sjacobs papi_attribute_t **result = NULL; 4252264Sjacobs 4262264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 4272264Sjacobs char buf[10240]; 4282264Sjacobs nss_status_t res = NSS_NOTFOUND; 4292264Sjacobs 4302264Sjacobs #ifdef NSS_EMULATION 4312264Sjacobs res = emul_getprinterentry_r(buf, sizeof (buf)); 4322264Sjacobs #elif NSS_SOLARIS 4332264Sjacobs nss_XbyY_args_t arg; 4342264Sjacobs 4352847Sjacobs private_ns = ns; 4362264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 4372264Sjacobs res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); 4382264Sjacobs (void) NSS_XbyY_FINI(&arg); 4392847Sjacobs private_ns = NULL; 4402264Sjacobs #endif 4412264Sjacobs 4422264Sjacobs if (res != NSS_SUCCESS) 4432264Sjacobs buf[0] = '\0'; 4442264Sjacobs 4452264Sjacobs result = _cvt_nss_entry_to_printer(buf); 4462313Sjacobs #if defined(__sun) && defined(__SVR4) 4472313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 4482313Sjacobs #endif 4492264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 4502264Sjacobs fill_printer_uri(&result); 4512264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 4522264Sjacobs #endif 4532264Sjacobs 4542264Sjacobs #ifdef DEBUG 4552264Sjacobs printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); 4562264Sjacobs if (result != NULL) { 4572264Sjacobs char buf[4096]; 4582264Sjacobs 4592264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 4602264Sjacobs printf("\t%s\n", buf); 4612264Sjacobs } 4622264Sjacobs #endif /* DEBUG */ 4632264Sjacobs 4642264Sjacobs return (result); 4652264Sjacobs } 4662264Sjacobs 4672264Sjacobs 4682264Sjacobs papi_attribute_t ** 4692264Sjacobs getprinterbyname(char *name, char *ns) 4702264Sjacobs { 4712264Sjacobs papi_attribute_t **result = NULL; 4722264Sjacobs 4732264Sjacobs if (strstr(name, "://") != NULL) { /* shortcut for URI form */ 4742264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 4752264Sjacobs "printer-name", name); 4762264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 4772264Sjacobs "printer-uri-supported", name); 4782264Sjacobs } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ 4792409Sjacobs char *uri = bsdaddr_to_uri(result, name); 4802264Sjacobs 4812264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 4822264Sjacobs "printer-name", name); 4832264Sjacobs if (uri != NULL) { 4842264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 4852264Sjacobs "printer-uri-supported", uri); 4862264Sjacobs free(uri); 4872264Sjacobs } 4882264Sjacobs } else { /* anything else */ 4892264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 4902264Sjacobs char buf[10240]; 4912264Sjacobs nss_status_t res = NSS_NOTFOUND; 4922264Sjacobs 4932264Sjacobs #ifdef NSS_EMULATION 4942264Sjacobs res = emul_getprinterbyname_r(name, buf, sizeof (buf)); 4952264Sjacobs #elif NSS_SOLARIS 4962264Sjacobs nss_XbyY_args_t arg; 4972264Sjacobs 4982264Sjacobs private_ns = ns; 4992264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 5002264Sjacobs arg.key.name = name; 5012264Sjacobs res = nss_search(&db_root, _nss_initf_printers, 5022264Sjacobs NSS_DBOP_PRINTERS_BYNAME, &arg); 5032264Sjacobs (void) NSS_XbyY_FINI(&arg); 5042847Sjacobs private_ns = NULL; 5052264Sjacobs 5062264Sjacobs if (res != NSS_SUCCESS) 5072264Sjacobs buf[0] = '\0'; 5082264Sjacobs #endif 5092264Sjacobs 5102264Sjacobs result = _cvt_nss_entry_to_printer(buf); 5112264Sjacobs #endif 5122264Sjacobs } 5132313Sjacobs #if defined(__sun) && defined(__SVR4) 5142313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 5152313Sjacobs #endif 5162264Sjacobs #ifdef DEBUG 5172264Sjacobs printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), 5182264Sjacobs name, result); 5192264Sjacobs if (result != NULL) { 5202264Sjacobs char buf[4096]; 5212264Sjacobs 5222264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 5232264Sjacobs printf("\t%s\n", buf); 5242264Sjacobs } 5252264Sjacobs #endif /* DEBUG */ 5262264Sjacobs 5272264Sjacobs return (result); 5282264Sjacobs } 529