1*2264Sjacobs /* 2*2264Sjacobs * CDDL HEADER START 3*2264Sjacobs * 4*2264Sjacobs * The contents of this file are subject to the terms of the 5*2264Sjacobs * Common Development and Distribution License (the "License"). 6*2264Sjacobs * You may not use this file except in compliance with the License. 7*2264Sjacobs * 8*2264Sjacobs * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9*2264Sjacobs * or http://www.opensolaris.org/os/licensing. 10*2264Sjacobs * See the License for the specific language governing permissions 11*2264Sjacobs * and limitations under the License. 12*2264Sjacobs * 13*2264Sjacobs * When distributing Covered Code, include this CDDL HEADER in each 14*2264Sjacobs * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15*2264Sjacobs * If applicable, add the following below this CDDL HEADER, with the 16*2264Sjacobs * fields enclosed by brackets "[]" replaced with your own identifying 17*2264Sjacobs * information: Portions Copyright [yyyy] [name of copyright owner] 18*2264Sjacobs * 19*2264Sjacobs * CDDL HEADER END 20*2264Sjacobs */ 21*2264Sjacobs 22*2264Sjacobs /* 23*2264Sjacobs * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24*2264Sjacobs * Use is subject to license terms. 25*2264Sjacobs * 26*2264Sjacobs */ 27*2264Sjacobs 28*2264Sjacobs /* $Id: nss.c 166 2006-05-20 05:48:55Z njacobs $ */ 29*2264Sjacobs 30*2264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 31*2264Sjacobs 32*2264Sjacobs #include <stdio.h> 33*2264Sjacobs #include <stdlib.h> 34*2264Sjacobs #include <unistd.h> 35*2264Sjacobs #include <string.h> 36*2264Sjacobs #include <ctype.h> 37*2264Sjacobs #include <sys/types.h> 38*2264Sjacobs #include <syslog.h> 39*2264Sjacobs #include <papi.h> 40*2264Sjacobs #include <uri.h> 41*2264Sjacobs #include <papi_impl.h> 42*2264Sjacobs #ifdef NSS_EMULATION 43*2264Sjacobs #include <nss-emulation.h> 44*2264Sjacobs #elif NSS_SOLARIS 45*2264Sjacobs #include <nss_dbdefs.h> 46*2264Sjacobs #endif 47*2264Sjacobs #include <config-site.h> 48*2264Sjacobs #if defined(__sun) && defined(__SVR4) 49*2264Sjacobs #include <sys/systeminfo.h> 50*2264Sjacobs #endif 51*2264Sjacobs 52*2264Sjacobs 53*2264Sjacobs static char * 54*2264Sjacobs bsdaddr_to_uri(char *bsdaddr) 55*2264Sjacobs { 56*2264Sjacobs char *result = NULL; 57*2264Sjacobs 58*2264Sjacobs if (bsdaddr != NULL) { 59*2264Sjacobs char *bsd[3], *tmp, *iter = NULL; 60*2264Sjacobs char buf[512]; 61*2264Sjacobs 62*2264Sjacobs tmp = strdup(bsdaddr); 63*2264Sjacobs 64*2264Sjacobs bsd[0] = strtok_r(tmp, ":,", &iter); 65*2264Sjacobs bsd[1] = strtok_r(NULL, ":,", &iter); 66*2264Sjacobs bsd[2] = strtok_r(NULL, ":,", &iter); 67*2264Sjacobs 68*2264Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/%s%s%s", bsd[0], bsd[1], 69*2264Sjacobs (bsd[2] != NULL) ? "#" : "", 70*2264Sjacobs (bsd[2] != NULL) ? bsd[2] : ""); 71*2264Sjacobs 72*2264Sjacobs free(tmp); 73*2264Sjacobs 74*2264Sjacobs result = strdup(buf); 75*2264Sjacobs } 76*2264Sjacobs 77*2264Sjacobs return (result); 78*2264Sjacobs } 79*2264Sjacobs 80*2264Sjacobs #if defined(__sun) && defined(__SVR4) 81*2264Sjacobs /* 82*2264Sjacobs * This is an awful HACK to force the dynamic PAPI library to use the 83*2264Sjacobs * lpsched support when the destination apears to be a local lpsched 84*2264Sjacobs * queue on Solaris. 85*2264Sjacobs */ 86*2264Sjacobs static void 87*2264Sjacobs solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list) 88*2264Sjacobs { 89*2264Sjacobs papi_attribute_t *attribute; 90*2264Sjacobs uri_t *uri = NULL; 91*2264Sjacobs char *printer = NULL; 92*2264Sjacobs char hostname[BUFSIZ]; 93*2264Sjacobs char buf[128], buf2[128]; 94*2264Sjacobs 95*2264Sjacobs /* setting this in the calling env can be useful for debugging */ 96*2264Sjacobs if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL) 97*2264Sjacobs return; 98*2264Sjacobs 99*2264Sjacobs papiAttributeListGetString(*list, NULL, 100*2264Sjacobs "printer-uri-supported", &printer); 101*2264Sjacobs if (uri_from_string(printer, &uri) < 0) 102*2264Sjacobs return; 103*2264Sjacobs 104*2264Sjacobs /* already an lpsched URI ? */ 105*2264Sjacobs if (strcasecmp(uri->scheme, "lpsched") == 0) 106*2264Sjacobs return; 107*2264Sjacobs 108*2264Sjacobs sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); 109*2264Sjacobs if ((uri->host != NULL) && 110*2264Sjacobs (strncasecmp(uri->host, hostname, strlen(hostname)) != 0) && 111*2264Sjacobs (strncasecmp(uri->host, "localhost", 10) != 0)) 112*2264Sjacobs return; 113*2264Sjacobs 114*2264Sjacobs if ((printer = strrchr(uri->path, '/')) == NULL) 115*2264Sjacobs printer = uri->path; 116*2264Sjacobs else 117*2264Sjacobs printer++; 118*2264Sjacobs 119*2264Sjacobs /* is there an lpsched queue (printer/class) */ 120*2264Sjacobs snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer); 121*2264Sjacobs snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer); 122*2264Sjacobs if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) 123*2264Sjacobs return; 124*2264Sjacobs 125*2264Sjacobs snprintf(buf, sizeof (buf), "lpsched://localhost/printers/%s", printer); 126*2264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_REPLACE, 127*2264Sjacobs "printer-uri-supported", buf); 128*2264Sjacobs } 129*2264Sjacobs #endif 130*2264Sjacobs 131*2264Sjacobs static void 132*2264Sjacobs fill_printer_uri_supported(papi_attribute_t ***list) 133*2264Sjacobs { 134*2264Sjacobs papi_attribute_t *attribute; 135*2264Sjacobs char *string = NULL; 136*2264Sjacobs 137*2264Sjacobs /* do we have a printer-uri-supported */ 138*2264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri-supported"); 139*2264Sjacobs if (attribute != NULL) /* we have what we need, return */ 140*2264Sjacobs return; 141*2264Sjacobs 142*2264Sjacobs /* do we have a printer-uri to rename */ 143*2264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 144*2264Sjacobs if (attribute != NULL) { /* rename it in place and return */ 145*2264Sjacobs free(attribute->name); 146*2264Sjacobs attribute->name = strdup("printer-uri-supported"); 147*2264Sjacobs return; 148*2264Sjacobs } 149*2264Sjacobs 150*2264Sjacobs /* do we have a printers.conf(4) "bsdaddr" to convert */ 151*2264Sjacobs papiAttributeListGetString(*list, NULL, "bsdaddr", &string); 152*2264Sjacobs if (string != NULL) { /* parse it, convert it, add it */ 153*2264Sjacobs char *uri = bsdaddr_to_uri(string); 154*2264Sjacobs 155*2264Sjacobs if (uri != NULL) { 156*2264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 157*2264Sjacobs "printer-uri-supported", uri); 158*2264Sjacobs papiAttributeListDelete(list, "bsdaddr"); 159*2264Sjacobs free(uri); 160*2264Sjacobs return; 161*2264Sjacobs } 162*2264Sjacobs } 163*2264Sjacobs 164*2264Sjacobs /* do we have a printers.conf(4) "rm" (and "rp") to convert */ 165*2264Sjacobs papiAttributeListGetString(*list, NULL, "rm", &string); 166*2264Sjacobs if (string != NULL) { 167*2264Sjacobs char *rp = NULL; 168*2264Sjacobs 169*2264Sjacobs /* default to "printer-name", but use "rp" if we have it */ 170*2264Sjacobs papiAttributeListGetString(*list, NULL, "printer-name", &rp); 171*2264Sjacobs papiAttributeListGetString(*list, NULL, "rp", &rp); 172*2264Sjacobs 173*2264Sjacobs if (rp != NULL) { /* fill in the uri if we have the data */ 174*2264Sjacobs char buf[BUFSIZ]; 175*2264Sjacobs 176*2264Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", 177*2264Sjacobs string, rp); 178*2264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 179*2264Sjacobs "printer-uri-supported", strdup(buf)); 180*2264Sjacobs return; 181*2264Sjacobs } 182*2264Sjacobs } 183*2264Sjacobs 184*2264Sjacobs /* if were are here, we don't have a printer-uri-supported */ 185*2264Sjacobs } 186*2264Sjacobs 187*2264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 188*2264Sjacobs static void 189*2264Sjacobs fill_printer_uri(papi_attribute_t ***list) 190*2264Sjacobs { 191*2264Sjacobs papi_attribute_t *attribute; 192*2264Sjacobs char *uri = NULL; 193*2264Sjacobs 194*2264Sjacobs if ((list == NULL) || (*list == NULL)) 195*2264Sjacobs return; 196*2264Sjacobs 197*2264Sjacobs /* do we have a printer-uri-supported */ 198*2264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 199*2264Sjacobs if (attribute != NULL) /* we have what we need, return */ 200*2264Sjacobs return; 201*2264Sjacobs 202*2264Sjacobs /* 203*2264Sjacobs * this is sufficient to fool libgnomeprintpapi, but not promote it's 204*2264Sjacobs * use in the future. 205*2264Sjacobs */ 206*2264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", 207*2264Sjacobs "broken printer-uri semantic"); 208*2264Sjacobs } 209*2264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 210*2264Sjacobs 211*2264Sjacobs static void 212*2264Sjacobs cvt_all_to_member_names(papi_attribute_t ***list) 213*2264Sjacobs { 214*2264Sjacobs papi_status_t status; 215*2264Sjacobs void *iter = NULL; 216*2264Sjacobs char *string = NULL; 217*2264Sjacobs 218*2264Sjacobs papiAttributeListGetString(*list, NULL, "member-names", &string); 219*2264Sjacobs if (string != NULL) /* already have a member-names */ 220*2264Sjacobs return; 221*2264Sjacobs 222*2264Sjacobs for (status = papiAttributeListGetString(*list, &iter, "all", &string); 223*2264Sjacobs status == PAPI_OK; 224*2264Sjacobs status = papiAttributeListGetString(*list, &iter, NULL, &string)) { 225*2264Sjacobs char *s_iter = NULL, *value, *tmp = strdup(string); 226*2264Sjacobs 227*2264Sjacobs for (value = strtok_r(tmp, ", \t", &s_iter); 228*2264Sjacobs value != NULL; 229*2264Sjacobs value = strtok_r(NULL, ", \t", &s_iter)) 230*2264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 231*2264Sjacobs "member-names", value); 232*2264Sjacobs free(tmp); 233*2264Sjacobs } 234*2264Sjacobs } 235*2264Sjacobs 236*2264Sjacobs static papi_attribute_t ** 237*2264Sjacobs _cvt_nss_entry_to_printer(char *entry) 238*2264Sjacobs { 239*2264Sjacobs char *key = NULL, 240*2264Sjacobs *cp, 241*2264Sjacobs buf[BUFSIZ]; 242*2264Sjacobs int in_namelist = 1, buf_pos = 0; 243*2264Sjacobs papi_attribute_t **list = NULL; 244*2264Sjacobs 245*2264Sjacobs if (entry == NULL) 246*2264Sjacobs return (NULL); 247*2264Sjacobs 248*2264Sjacobs memset(buf, 0, sizeof (buf)); 249*2264Sjacobs for (cp = entry; *cp != '\0'; cp++) { 250*2264Sjacobs switch (*cp) { 251*2264Sjacobs case ':': /* end of kvp */ 252*2264Sjacobs if (in_namelist != 0) { 253*2264Sjacobs papiAttributeListAddString(&list, 254*2264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 255*2264Sjacobs in_namelist = 0; 256*2264Sjacobs } else if (key != NULL) 257*2264Sjacobs papiAttributeListAddString(&list, 258*2264Sjacobs PAPI_ATTR_APPEND, key, buf); 259*2264Sjacobs memset(buf, 0, sizeof (buf)); 260*2264Sjacobs buf_pos = 0; 261*2264Sjacobs key = NULL; 262*2264Sjacobs break; 263*2264Sjacobs case '=': /* kvp seperator */ 264*2264Sjacobs if (key == NULL) { 265*2264Sjacobs key = strdup(buf); 266*2264Sjacobs memset(buf, 0, sizeof (buf)); 267*2264Sjacobs buf_pos = 0; 268*2264Sjacobs } else 269*2264Sjacobs buf[buf_pos++] = *cp; 270*2264Sjacobs break; 271*2264Sjacobs case '|': /* namelist seperator */ 272*2264Sjacobs if (in_namelist != 0) { 273*2264Sjacobs papiAttributeListAddString(&list, 274*2264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 275*2264Sjacobs memset(buf, 0, sizeof (buf)); 276*2264Sjacobs buf_pos = 0; 277*2264Sjacobs } else /* add it to the buffer */ 278*2264Sjacobs buf[buf_pos++] = *cp; 279*2264Sjacobs break; 280*2264Sjacobs case '\\': /* escape char */ 281*2264Sjacobs buf[buf_pos++] = *(++cp); 282*2264Sjacobs break; 283*2264Sjacobs default: 284*2264Sjacobs buf[buf_pos++] = *cp; 285*2264Sjacobs } 286*2264Sjacobs 287*2264Sjacobs } 288*2264Sjacobs 289*2264Sjacobs if (key != NULL) 290*2264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); 291*2264Sjacobs 292*2264Sjacobs /* resolve any "use" references in the configuration DB */ 293*2264Sjacobs key = NULL; 294*2264Sjacobs papiAttributeListGetString(list, NULL, "use", &key); 295*2264Sjacobs if (key != NULL) { 296*2264Sjacobs papi_attribute_t **use_attrs = getprinterbyname(key, NULL); 297*2264Sjacobs 298*2264Sjacobs list_concatenate(&list, use_attrs); 299*2264Sjacobs } 300*2264Sjacobs 301*2264Sjacobs fill_printer_uri_supported(&list); 302*2264Sjacobs #if defined(__sun) && defined(__SVR4) 303*2264Sjacobs solaris_lpsched_shortcircuit_hack(&list); 304*2264Sjacobs #endif 305*2264Sjacobs cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ 306*2264Sjacobs 307*2264Sjacobs return (list); 308*2264Sjacobs } 309*2264Sjacobs 310*2264Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) 311*2264Sjacobs 312*2264Sjacobs #ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ 313*2264Sjacobs #define NSS_DBNAM__PRINTERS "_printers" 314*2264Sjacobs #endif 315*2264Sjacobs 316*2264Sjacobs static DEFINE_NSS_DB_ROOT(db_root); 317*2264Sjacobs static DEFINE_NSS_GETENT(context); 318*2264Sjacobs 319*2264Sjacobs static char *private_ns = NULL; 320*2264Sjacobs static char initialized = 0; 321*2264Sjacobs 322*2264Sjacobs static void 323*2264Sjacobs _nss_initf_printers(p) 324*2264Sjacobs nss_db_params_t *p; 325*2264Sjacobs { 326*2264Sjacobs if (private_ns != NULL) { 327*2264Sjacobs /* 328*2264Sjacobs * because we need to support a legacy interface that allows 329*2264Sjacobs * us to select a specific name service, we need to dummy up 330*2264Sjacobs * the parameters to use a private nsswitch database and set 331*2264Sjacobs * the * default_config entry to the name service we are 332*2264Sjacobs * looking into. 333*2264Sjacobs */ 334*2264Sjacobs p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ 335*2264Sjacobs p->default_config = private_ns; 336*2264Sjacobs private_ns = NULL; 337*2264Sjacobs } else if (initialized == 0) { 338*2264Sjacobs /* regular behaviour */ 339*2264Sjacobs p->name = NSS_DBNAM_PRINTERS; /* "printers" */ 340*2264Sjacobs p->default_config = NSS_DEFCONF_PRINTERS; 341*2264Sjacobs initialized = 1; 342*2264Sjacobs } 343*2264Sjacobs syslog(LOG_DEBUG, "database: %s, services: %s", 344*2264Sjacobs (p->name ? p->name : "NULL"), 345*2264Sjacobs (p->default_config ? p->default_config : "NULL")); 346*2264Sjacobs } 347*2264Sjacobs 348*2264Sjacobs /* 349*2264Sjacobs * Return values: 0 = success, 1 = parse error, 2 = erange ... 350*2264Sjacobs * The structure pointer passed in is a structure in the caller's space 351*2264Sjacobs * wherein the field pointers would be set to areas in the buffer if 352*2264Sjacobs * need be. instring and buffer should be separate areas. 353*2264Sjacobs */ 354*2264Sjacobs /* ARGSUSED */ 355*2264Sjacobs static int 356*2264Sjacobs str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 357*2264Sjacobs { 358*2264Sjacobs if (lenstr + 1 > buflen) 359*2264Sjacobs return (NSS_STR_PARSE_ERANGE); 360*2264Sjacobs /* 361*2264Sjacobs * We copy the input string into the output buffer 362*2264Sjacobs */ 363*2264Sjacobs (void) memcpy(buffer, instr, lenstr); 364*2264Sjacobs buffer[lenstr] = '\0'; 365*2264Sjacobs 366*2264Sjacobs return (NSS_STR_PARSE_SUCCESS); 367*2264Sjacobs } 368*2264Sjacobs #endif /* NSS_SOLARIS */ 369*2264Sjacobs 370*2264Sjacobs int 371*2264Sjacobs setprinterentry(int stayopen, char *ns) 372*2264Sjacobs { 373*2264Sjacobs #ifdef NSS_EMULATION 374*2264Sjacobs emul_setprinterentry(stayopen); 375*2264Sjacobs #elif NSS_SOLARIS 376*2264Sjacobs initialized = 0; 377*2264Sjacobs private_ns = ns; 378*2264Sjacobs nss_setent(&db_root, _nss_initf_printers, &context); 379*2264Sjacobs #endif 380*2264Sjacobs return (0); 381*2264Sjacobs } 382*2264Sjacobs 383*2264Sjacobs 384*2264Sjacobs int 385*2264Sjacobs endprinterentry(int i) 386*2264Sjacobs { 387*2264Sjacobs #ifdef NSS_EMULATION 388*2264Sjacobs emul_endprinterentry(); 389*2264Sjacobs #elif NSS_SOLARIS 390*2264Sjacobs initialized = 0; 391*2264Sjacobs nss_endent(&db_root, _nss_initf_printers, &context); 392*2264Sjacobs nss_delete(&db_root); 393*2264Sjacobs #endif 394*2264Sjacobs return (0); 395*2264Sjacobs } 396*2264Sjacobs 397*2264Sjacobs /* ARGSUSED2 */ 398*2264Sjacobs papi_attribute_t ** 399*2264Sjacobs getprinterentry(char *ns) 400*2264Sjacobs { 401*2264Sjacobs papi_attribute_t **result = NULL; 402*2264Sjacobs 403*2264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 404*2264Sjacobs char buf[10240]; 405*2264Sjacobs nss_status_t res = NSS_NOTFOUND; 406*2264Sjacobs 407*2264Sjacobs #ifdef NSS_EMULATION 408*2264Sjacobs res = emul_getprinterentry_r(buf, sizeof (buf)); 409*2264Sjacobs #elif NSS_SOLARIS 410*2264Sjacobs nss_XbyY_args_t arg; 411*2264Sjacobs 412*2264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 413*2264Sjacobs res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); 414*2264Sjacobs (void) NSS_XbyY_FINI(&arg); 415*2264Sjacobs #endif 416*2264Sjacobs 417*2264Sjacobs if (res != NSS_SUCCESS) 418*2264Sjacobs buf[0] = '\0'; 419*2264Sjacobs 420*2264Sjacobs result = _cvt_nss_entry_to_printer(buf); 421*2264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 422*2264Sjacobs fill_printer_uri(&result); 423*2264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 424*2264Sjacobs #endif 425*2264Sjacobs 426*2264Sjacobs #ifdef DEBUG 427*2264Sjacobs printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); 428*2264Sjacobs if (result != NULL) { 429*2264Sjacobs char buf[4096]; 430*2264Sjacobs 431*2264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 432*2264Sjacobs printf("\t%s\n", buf); 433*2264Sjacobs } 434*2264Sjacobs #endif /* DEBUG */ 435*2264Sjacobs 436*2264Sjacobs return (result); 437*2264Sjacobs } 438*2264Sjacobs 439*2264Sjacobs 440*2264Sjacobs papi_attribute_t ** 441*2264Sjacobs getprinterbyname(char *name, char *ns) 442*2264Sjacobs { 443*2264Sjacobs papi_attribute_t **result = NULL; 444*2264Sjacobs 445*2264Sjacobs if (strstr(name, "://") != NULL) { /* shortcut for URI form */ 446*2264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 447*2264Sjacobs "printer-name", name); 448*2264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 449*2264Sjacobs "printer-uri-supported", name); 450*2264Sjacobs } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ 451*2264Sjacobs char *uri = bsdaddr_to_uri(name); 452*2264Sjacobs 453*2264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 454*2264Sjacobs "printer-name", name); 455*2264Sjacobs if (uri != NULL) { 456*2264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 457*2264Sjacobs "printer-uri-supported", uri); 458*2264Sjacobs free(uri); 459*2264Sjacobs } 460*2264Sjacobs } else { /* anything else */ 461*2264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 462*2264Sjacobs char buf[10240]; 463*2264Sjacobs nss_status_t res = NSS_NOTFOUND; 464*2264Sjacobs 465*2264Sjacobs #ifdef NSS_EMULATION 466*2264Sjacobs res = emul_getprinterbyname_r(name, buf, sizeof (buf)); 467*2264Sjacobs #elif NSS_SOLARIS 468*2264Sjacobs nss_XbyY_args_t arg; 469*2264Sjacobs 470*2264Sjacobs private_ns = ns; 471*2264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 472*2264Sjacobs arg.key.name = name; 473*2264Sjacobs res = nss_search(&db_root, _nss_initf_printers, 474*2264Sjacobs NSS_DBOP_PRINTERS_BYNAME, &arg); 475*2264Sjacobs (void) NSS_XbyY_FINI(&arg); 476*2264Sjacobs 477*2264Sjacobs if (res != NSS_SUCCESS) 478*2264Sjacobs buf[0] = '\0'; 479*2264Sjacobs #endif 480*2264Sjacobs 481*2264Sjacobs result = _cvt_nss_entry_to_printer(buf); 482*2264Sjacobs #endif 483*2264Sjacobs } 484*2264Sjacobs 485*2264Sjacobs #ifdef DEBUG 486*2264Sjacobs printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), 487*2264Sjacobs name, result); 488*2264Sjacobs if (result != NULL) { 489*2264Sjacobs char buf[4096]; 490*2264Sjacobs 491*2264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 492*2264Sjacobs printf("\t%s\n", buf); 493*2264Sjacobs } 494*2264Sjacobs #endif /* DEBUG */ 495*2264Sjacobs 496*2264Sjacobs return (result); 497*2264Sjacobs } 498