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 /* 23*6817Sjacobs * 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 #pragma ident "%Z%%M% %I% %E% SMI" 312264Sjacobs 322264Sjacobs #include <stdio.h> 332264Sjacobs #include <stdlib.h> 342264Sjacobs #include <unistd.h> 352264Sjacobs #include <string.h> 362264Sjacobs #include <ctype.h> 372264Sjacobs #include <sys/types.h> 382264Sjacobs #include <syslog.h> 392264Sjacobs #include <papi.h> 402264Sjacobs #include <uri.h> 412264Sjacobs #include <papi_impl.h> 422264Sjacobs #ifdef NSS_EMULATION 432264Sjacobs #include <nss-emulation.h> 442264Sjacobs #elif NSS_SOLARIS 452264Sjacobs #include <nss_dbdefs.h> 462264Sjacobs #endif 472264Sjacobs #include <config-site.h> 482264Sjacobs #if defined(__sun) && defined(__SVR4) 492264Sjacobs #include <sys/systeminfo.h> 502264Sjacobs #endif 512264Sjacobs 522264Sjacobs 532264Sjacobs static char * 542409Sjacobs bsdaddr_to_uri(papi_attribute_t **list, char *bsdaddr) 552264Sjacobs { 562264Sjacobs char *result = NULL; 572264Sjacobs 582264Sjacobs if (bsdaddr != NULL) { 592264Sjacobs char *bsd[3], *tmp, *iter = NULL; 602264Sjacobs char buf[512]; 612264Sjacobs 622264Sjacobs tmp = strdup(bsdaddr); 632264Sjacobs 642264Sjacobs bsd[0] = strtok_r(tmp, ":,", &iter); 652409Sjacobs if ((bsd[1] = strtok_r(NULL, ":,", &iter)) == NULL) 662409Sjacobs papiAttributeListGetString(list, NULL, 672409Sjacobs "printer-name", &bsd[1]); 682264Sjacobs bsd[2] = strtok_r(NULL, ":,", &iter); 692264Sjacobs 702409Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s%s%s", bsd[0], 712409Sjacobs (bsd[1] != NULL) ? bsd[1] : "", 722264Sjacobs (bsd[2] != NULL) ? "#" : "", 732264Sjacobs (bsd[2] != NULL) ? bsd[2] : ""); 742264Sjacobs 752264Sjacobs free(tmp); 762264Sjacobs 772264Sjacobs result = strdup(buf); 782264Sjacobs } 792264Sjacobs 802264Sjacobs return (result); 812264Sjacobs } 822264Sjacobs 832264Sjacobs #if defined(__sun) && defined(__SVR4) 842313Sjacobs #include <sys/socket.h> 852313Sjacobs #include <sys/ioctl.h> 862313Sjacobs #include <sys/sockio.h> 872313Sjacobs #include <net/if.h> 882313Sjacobs #include <netinet/in.h> 892313Sjacobs #include <arpa/inet.h> 902313Sjacobs #include <netdb.h> 912313Sjacobs 922313Sjacobs static struct in6_addr ** 932313Sjacobs local_interfaces() 942313Sjacobs { 952313Sjacobs struct in6_addr **result = NULL; 962313Sjacobs int s; 972313Sjacobs struct lifnum n; 982313Sjacobs struct lifconf c; 992313Sjacobs struct lifreq *r; 1002313Sjacobs int count; 1012313Sjacobs 1022313Sjacobs /* we need a socket to get the interfaces */ 1032313Sjacobs if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 1042313Sjacobs return (0); 1052313Sjacobs 1062313Sjacobs /* get the number of interfaces */ 1072313Sjacobs memset(&n, 0, sizeof (n)); 1082313Sjacobs n.lifn_family = AF_UNSPEC; 1092313Sjacobs if (ioctl(s, SIOCGLIFNUM, (char *)&n) < 0) { 1102313Sjacobs close(s); 1112313Sjacobs return (0); /* no interfaces */ 1122313Sjacobs } 1132313Sjacobs 1142313Sjacobs /* get the interface(s) configuration */ 1152313Sjacobs memset(&c, 0, sizeof (c)); 1162313Sjacobs c.lifc_family = AF_UNSPEC; 1172313Sjacobs c.lifc_buf = calloc(n.lifn_count, sizeof (struct lifreq)); 1182313Sjacobs c.lifc_len = (n.lifn_count * sizeof (struct lifreq)); 1192313Sjacobs if (ioctl(s, SIOCGLIFCONF, (char *)&c) < 0) { 1202313Sjacobs free(c.lifc_buf); 1212313Sjacobs close(s); 1222313Sjacobs return (0); /* can't get interface(s) configuration */ 1232313Sjacobs } 1242313Sjacobs close(s); 1252313Sjacobs 1262313Sjacobs r = c.lifc_req; 1272313Sjacobs for (count = c.lifc_len / sizeof (struct lifreq); 1282313Sjacobs count > 0; count--, r++) { 1292313Sjacobs struct in6_addr v6[1], *addr = NULL; 1302313Sjacobs 1312313Sjacobs switch (r->lifr_addr.ss_family) { 1322313Sjacobs case AF_INET: { 1332313Sjacobs struct sockaddr_in *s = 1342313Sjacobs (struct sockaddr_in *)&r->lifr_addr; 1352313Sjacobs IN6_INADDR_TO_V4MAPPED(&s->sin_addr, v6); 1362313Sjacobs addr = v6; 1372313Sjacobs } 1382313Sjacobs break; 1392313Sjacobs case AF_INET6: { 1402313Sjacobs struct sockaddr_in6 *s = 1412313Sjacobs (struct sockaddr_in6 *)&r->lifr_addr; 1422313Sjacobs addr = &s->sin6_addr; 1432313Sjacobs } 1442313Sjacobs break; 1452313Sjacobs } 1462313Sjacobs 1472313Sjacobs if (addr != NULL) { 1482313Sjacobs struct in6_addr *a = malloc(sizeof (*a)); 1492313Sjacobs 1502313Sjacobs memcpy(a, addr, sizeof (*a)); 1512313Sjacobs list_append(&result, a); 1522313Sjacobs } 1532313Sjacobs } 1542313Sjacobs free(c.lifc_buf); 1552313Sjacobs 1562313Sjacobs return (result); 1572313Sjacobs } 1582313Sjacobs 1592313Sjacobs static int 1602313Sjacobs match_interfaces(char *host) 1612313Sjacobs { 1622313Sjacobs struct in6_addr **lif = local_interfaces(); 1632313Sjacobs struct hostent *hp; 1642313Sjacobs int rc = 0; 1652313Sjacobs int errnum; 1662313Sjacobs 1672313Sjacobs /* are there any local interfaces */ 1682313Sjacobs if (lif == NULL) 1692313Sjacobs return (0); 1702313Sjacobs 1712313Sjacobs /* cycle through the host db addresses */ 1722313Sjacobs hp = getipnodebyname(host, AF_INET6, AI_ALL|AI_V4MAPPED, &errnum); 1732313Sjacobs if (hp != NULL) { 1742313Sjacobs struct in6_addr **tmp = (struct in6_addr **)hp->h_addr_list; 1752313Sjacobs int i; 1762313Sjacobs 1772313Sjacobs for (i = 0; ((rc == 0) && (tmp[i] != NULL)); i++) { 1782313Sjacobs int j; 1792313Sjacobs 1802313Sjacobs for (j = 0; ((rc == 0) && (lif[j] != NULL)); j++) 1812313Sjacobs if (memcmp(tmp[i], lif[j], 1822313Sjacobs sizeof (struct in6_addr)) == 0) 1832313Sjacobs rc = 1; 1842313Sjacobs } 1852313Sjacobs } 1862313Sjacobs free(lif); 1872313Sjacobs 1882313Sjacobs return (rc); 1892313Sjacobs } 1902313Sjacobs 1912313Sjacobs static int 1922313Sjacobs is_localhost(char *host) 1932313Sjacobs { 1942313Sjacobs char hostname[BUFSIZ]; 1952313Sjacobs 1962313Sjacobs /* is it "localhost" */ 1972313Sjacobs if (strncasecmp(host, "localhost", 10) == 0) 1982313Sjacobs return (1); 1992313Sjacobs 2002313Sjacobs /* is it the {nodename} */ 2012313Sjacobs sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); 2022313Sjacobs if (strncasecmp(host, hostname, strlen(hostname)) == 0) 2032313Sjacobs return (1); 2042313Sjacobs 2052313Sjacobs /* does it match one of the host's configured interfaces */ 2062313Sjacobs if (match_interfaces(host) != 0) 2072313Sjacobs return (1); 2082313Sjacobs 2092313Sjacobs return (0); 2102313Sjacobs } 2112313Sjacobs 2122264Sjacobs /* 2132264Sjacobs * This is an awful HACK to force the dynamic PAPI library to use the 2142264Sjacobs * lpsched support when the destination apears to be a local lpsched 2152264Sjacobs * queue on Solaris. 2162264Sjacobs */ 2172264Sjacobs static void 2182264Sjacobs solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list) 2192264Sjacobs { 2202264Sjacobs papi_attribute_t *attribute; 2212264Sjacobs uri_t *uri = NULL; 2222264Sjacobs char *printer = NULL; 2232264Sjacobs char buf[128], buf2[128]; 2242264Sjacobs 2252264Sjacobs /* setting this in the calling env can be useful for debugging */ 2262264Sjacobs if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL) 2272264Sjacobs return; 2282264Sjacobs 2292264Sjacobs papiAttributeListGetString(*list, NULL, 2302264Sjacobs "printer-uri-supported", &printer); 2312264Sjacobs if (uri_from_string(printer, &uri) < 0) 2322264Sjacobs return; 2332264Sjacobs 2342264Sjacobs /* already an lpsched URI ? */ 2352264Sjacobs if (strcasecmp(uri->scheme, "lpsched") == 0) 2362264Sjacobs return; 2372264Sjacobs 2382264Sjacobs if ((printer = strrchr(uri->path, '/')) == NULL) 2392264Sjacobs printer = uri->path; 2402264Sjacobs else 2412264Sjacobs printer++; 2422264Sjacobs 2432264Sjacobs /* is there an lpsched queue (printer/class) */ 2442264Sjacobs snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer); 2452264Sjacobs snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer); 2462264Sjacobs if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) 2472264Sjacobs return; 2482264Sjacobs 2492313Sjacobs /* is this the "local" host */ 2502313Sjacobs if ((uri->host != NULL) && (is_localhost(uri->host) == 0)) 2512313Sjacobs return; 2522313Sjacobs 2532313Sjacobs snprintf(buf, sizeof (buf), "lpsched://%s/printers/%s", 2542313Sjacobs (uri->host ? uri->host : "localhost"), printer); 2552264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_REPLACE, 2562264Sjacobs "printer-uri-supported", buf); 2572264Sjacobs } 2582264Sjacobs #endif 2592264Sjacobs 2602264Sjacobs static void 2612264Sjacobs fill_printer_uri_supported(papi_attribute_t ***list) 2622264Sjacobs { 2632264Sjacobs papi_attribute_t *attribute; 2642264Sjacobs char *string = NULL; 2652264Sjacobs 2662264Sjacobs /* do we have a printer-uri-supported */ 2672264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri-supported"); 2682264Sjacobs if (attribute != NULL) /* we have what we need, return */ 2692264Sjacobs return; 2702264Sjacobs 271*6817Sjacobs /* do we have a printer-uri (in URI form) to rename */ 2722264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 273*6817Sjacobs if ((attribute != NULL) && 274*6817Sjacobs (attribute->type == PAPI_STRING) && 275*6817Sjacobs (attribute->values != NULL) && 276*6817Sjacobs (attribute->values[0]->string != NULL) && 277*6817Sjacobs (strstr(attribute->values[0]->string, "://") != NULL)) { 278*6817Sjacobs /* rename it in place and return */ 2792264Sjacobs free(attribute->name); 2802264Sjacobs attribute->name = strdup("printer-uri-supported"); 2812264Sjacobs return; 2822264Sjacobs } 2832264Sjacobs 2842264Sjacobs /* do we have a printers.conf(4) "bsdaddr" to convert */ 2852264Sjacobs papiAttributeListGetString(*list, NULL, "bsdaddr", &string); 2862264Sjacobs if (string != NULL) { /* parse it, convert it, add it */ 2872409Sjacobs char *uri = bsdaddr_to_uri(*list, string); 2882264Sjacobs 2892264Sjacobs if (uri != NULL) { 2902264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 2912264Sjacobs "printer-uri-supported", uri); 2922264Sjacobs papiAttributeListDelete(list, "bsdaddr"); 2932264Sjacobs free(uri); 2942264Sjacobs return; 2952264Sjacobs } 2962264Sjacobs } 2972264Sjacobs 2982264Sjacobs /* do we have a printers.conf(4) "rm" (and "rp") to convert */ 2992264Sjacobs papiAttributeListGetString(*list, NULL, "rm", &string); 3002264Sjacobs if (string != NULL) { 3012264Sjacobs char *rp = NULL; 3022264Sjacobs 3032264Sjacobs /* default to "printer-name", but use "rp" if we have it */ 3042264Sjacobs papiAttributeListGetString(*list, NULL, "printer-name", &rp); 3052264Sjacobs papiAttributeListGetString(*list, NULL, "rp", &rp); 3062264Sjacobs 3072264Sjacobs if (rp != NULL) { /* fill in the uri if we have the data */ 3082264Sjacobs char buf[BUFSIZ]; 3092264Sjacobs 3102264Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", 3112264Sjacobs string, rp); 3122264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 3132264Sjacobs "printer-uri-supported", strdup(buf)); 3142264Sjacobs return; 3152264Sjacobs } 3162264Sjacobs } 3172264Sjacobs 3182264Sjacobs /* if were are here, we don't have a printer-uri-supported */ 3192264Sjacobs } 3202264Sjacobs 3212264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 3222264Sjacobs static void 3232264Sjacobs fill_printer_uri(papi_attribute_t ***list) 3242264Sjacobs { 3252264Sjacobs papi_attribute_t *attribute; 3262264Sjacobs char *uri = NULL; 3272264Sjacobs 3282264Sjacobs if ((list == NULL) || (*list == NULL)) 3292264Sjacobs return; 3302264Sjacobs 3312313Sjacobs /* do we have a printer-uri */ 3322264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 3332264Sjacobs if (attribute != NULL) /* we have what we need, return */ 3342264Sjacobs return; 3352264Sjacobs 3362264Sjacobs /* 3372264Sjacobs * this is sufficient to fool libgnomeprintpapi, but not promote it's 3382264Sjacobs * use in the future. 3392264Sjacobs */ 3402264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", 3412264Sjacobs "broken printer-uri semantic"); 3422264Sjacobs } 3432264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 3442264Sjacobs 3452264Sjacobs static void 3462264Sjacobs cvt_all_to_member_names(papi_attribute_t ***list) 3472264Sjacobs { 3482264Sjacobs papi_status_t status; 3492264Sjacobs void *iter = NULL; 3502264Sjacobs char *string = NULL; 3512264Sjacobs 3522264Sjacobs papiAttributeListGetString(*list, NULL, "member-names", &string); 3532264Sjacobs if (string != NULL) /* already have a member-names */ 3542264Sjacobs return; 3552264Sjacobs 3562264Sjacobs for (status = papiAttributeListGetString(*list, &iter, "all", &string); 3572264Sjacobs status == PAPI_OK; 3582264Sjacobs status = papiAttributeListGetString(*list, &iter, NULL, &string)) { 3592264Sjacobs char *s_iter = NULL, *value, *tmp = strdup(string); 3602264Sjacobs 3612264Sjacobs for (value = strtok_r(tmp, ", \t", &s_iter); 3622264Sjacobs value != NULL; 3632264Sjacobs value = strtok_r(NULL, ", \t", &s_iter)) 3642264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 3652264Sjacobs "member-names", value); 3662264Sjacobs free(tmp); 3672264Sjacobs } 3682264Sjacobs } 3692264Sjacobs 3702264Sjacobs static papi_attribute_t ** 3712264Sjacobs _cvt_nss_entry_to_printer(char *entry) 3722264Sjacobs { 3732264Sjacobs char *key = NULL, 3742264Sjacobs *cp, 3752264Sjacobs buf[BUFSIZ]; 3762264Sjacobs int in_namelist = 1, buf_pos = 0; 3772264Sjacobs papi_attribute_t **list = NULL; 3782264Sjacobs 3792264Sjacobs if (entry == NULL) 3802264Sjacobs return (NULL); 3812264Sjacobs 3822264Sjacobs memset(buf, 0, sizeof (buf)); 3832264Sjacobs for (cp = entry; *cp != '\0'; cp++) { 3842264Sjacobs switch (*cp) { 3852264Sjacobs case ':': /* end of kvp */ 3862264Sjacobs if (in_namelist != 0) { 3872264Sjacobs papiAttributeListAddString(&list, 3882264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 3892264Sjacobs in_namelist = 0; 3902264Sjacobs } else if (key != NULL) 3912264Sjacobs papiAttributeListAddString(&list, 3922264Sjacobs PAPI_ATTR_APPEND, key, buf); 3932264Sjacobs memset(buf, 0, sizeof (buf)); 3942264Sjacobs buf_pos = 0; 3952264Sjacobs key = NULL; 3962264Sjacobs break; 3972264Sjacobs case '=': /* kvp seperator */ 3982264Sjacobs if (key == NULL) { 3992264Sjacobs key = strdup(buf); 4002264Sjacobs memset(buf, 0, sizeof (buf)); 4012264Sjacobs buf_pos = 0; 4022264Sjacobs } else 4032264Sjacobs buf[buf_pos++] = *cp; 4042264Sjacobs break; 4052264Sjacobs case '|': /* namelist seperator */ 4062264Sjacobs if (in_namelist != 0) { 4072264Sjacobs papiAttributeListAddString(&list, 4082264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 4092264Sjacobs memset(buf, 0, sizeof (buf)); 4102264Sjacobs buf_pos = 0; 4112264Sjacobs } else /* add it to the buffer */ 4122264Sjacobs buf[buf_pos++] = *cp; 4132264Sjacobs break; 4142264Sjacobs case '\\': /* escape char */ 4152264Sjacobs buf[buf_pos++] = *(++cp); 4162264Sjacobs break; 4172264Sjacobs default: 4182264Sjacobs buf[buf_pos++] = *cp; 4192264Sjacobs } 4202264Sjacobs 4212264Sjacobs } 4222264Sjacobs 4232264Sjacobs if (key != NULL) 4242264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); 4252264Sjacobs 4262264Sjacobs /* resolve any "use" references in the configuration DB */ 4272264Sjacobs key = NULL; 4282264Sjacobs papiAttributeListGetString(list, NULL, "use", &key); 4292264Sjacobs if (key != NULL) { 4302264Sjacobs papi_attribute_t **use_attrs = getprinterbyname(key, NULL); 4312264Sjacobs 4322264Sjacobs list_concatenate(&list, use_attrs); 4332264Sjacobs } 4342264Sjacobs 4352264Sjacobs fill_printer_uri_supported(&list); 4362264Sjacobs cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ 4372264Sjacobs 4382264Sjacobs return (list); 4392264Sjacobs } 4402264Sjacobs 4412264Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) 4422264Sjacobs 4432264Sjacobs #ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ 4442264Sjacobs #define NSS_DBNAM__PRINTERS "_printers" 4452264Sjacobs #endif 4462264Sjacobs 4472264Sjacobs static DEFINE_NSS_DB_ROOT(db_root); 4482264Sjacobs static DEFINE_NSS_GETENT(context); 4492264Sjacobs 4502264Sjacobs static char *private_ns = NULL; 4512264Sjacobs 4522264Sjacobs static void 4532264Sjacobs _nss_initf_printers(p) 4542264Sjacobs nss_db_params_t *p; 4552264Sjacobs { 4562264Sjacobs if (private_ns != NULL) { 4572264Sjacobs /* 4582264Sjacobs * because we need to support a legacy interface that allows 4592264Sjacobs * us to select a specific name service, we need to dummy up 4602264Sjacobs * the parameters to use a private nsswitch database and set 4612264Sjacobs * the * default_config entry to the name service we are 4622264Sjacobs * looking into. 4632264Sjacobs */ 4642264Sjacobs p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ 4652264Sjacobs p->default_config = private_ns; 4662847Sjacobs } else { 4672264Sjacobs /* regular behaviour */ 4682264Sjacobs p->name = NSS_DBNAM_PRINTERS; /* "printers" */ 4692264Sjacobs p->default_config = NSS_DEFCONF_PRINTERS; 4702264Sjacobs } 4712847Sjacobs syslog(LOG_DEBUG, "database: %s, default: %s", 4722264Sjacobs (p->name ? p->name : "NULL"), 4732264Sjacobs (p->default_config ? p->default_config : "NULL")); 4742264Sjacobs } 4752264Sjacobs 4762264Sjacobs /* 4772264Sjacobs * Return values: 0 = success, 1 = parse error, 2 = erange ... 4782264Sjacobs * The structure pointer passed in is a structure in the caller's space 4792264Sjacobs * wherein the field pointers would be set to areas in the buffer if 4802264Sjacobs * need be. instring and buffer should be separate areas. 4812264Sjacobs */ 4822264Sjacobs /* ARGSUSED */ 4832264Sjacobs static int 4842264Sjacobs str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 4852264Sjacobs { 4862264Sjacobs if (lenstr + 1 > buflen) 4872264Sjacobs return (NSS_STR_PARSE_ERANGE); 4882571Sjacobs 4892571Sjacobs /* skip entries that begin with '#' */ 4902571Sjacobs if (instr[0] == '#') 4912571Sjacobs return (NSS_STR_PARSE_PARSE); 4922571Sjacobs 4932264Sjacobs /* 4942264Sjacobs * We copy the input string into the output buffer 4952264Sjacobs */ 4962264Sjacobs (void) memcpy(buffer, instr, lenstr); 4972264Sjacobs buffer[lenstr] = '\0'; 4982264Sjacobs 4992264Sjacobs return (NSS_STR_PARSE_SUCCESS); 5002264Sjacobs } 5012264Sjacobs #endif /* NSS_SOLARIS */ 5022264Sjacobs 5032264Sjacobs int 5042264Sjacobs setprinterentry(int stayopen, char *ns) 5052264Sjacobs { 5062264Sjacobs #ifdef NSS_EMULATION 5072264Sjacobs emul_setprinterentry(stayopen); 5082264Sjacobs #elif NSS_SOLARIS 5092264Sjacobs private_ns = ns; 5102264Sjacobs nss_setent(&db_root, _nss_initf_printers, &context); 5112847Sjacobs private_ns = NULL; 5122264Sjacobs #endif 5132264Sjacobs return (0); 5142264Sjacobs } 5152264Sjacobs 5162264Sjacobs 5172264Sjacobs int 5182264Sjacobs endprinterentry(int i) 5192264Sjacobs { 5202264Sjacobs #ifdef NSS_EMULATION 5212264Sjacobs emul_endprinterentry(); 5222264Sjacobs #elif NSS_SOLARIS 5232264Sjacobs nss_endent(&db_root, _nss_initf_printers, &context); 5242264Sjacobs nss_delete(&db_root); 5252847Sjacobs private_ns = NULL; 5262264Sjacobs #endif 5272264Sjacobs return (0); 5282264Sjacobs } 5292264Sjacobs 5302264Sjacobs /* ARGSUSED2 */ 5312264Sjacobs papi_attribute_t ** 5322264Sjacobs getprinterentry(char *ns) 5332264Sjacobs { 5342264Sjacobs papi_attribute_t **result = NULL; 5352264Sjacobs 5362264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 5372264Sjacobs char buf[10240]; 5382264Sjacobs nss_status_t res = NSS_NOTFOUND; 5392264Sjacobs 5402264Sjacobs #ifdef NSS_EMULATION 5412264Sjacobs res = emul_getprinterentry_r(buf, sizeof (buf)); 5422264Sjacobs #elif NSS_SOLARIS 5432264Sjacobs nss_XbyY_args_t arg; 5442264Sjacobs 5452847Sjacobs private_ns = ns; 5462264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 5472264Sjacobs res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); 5482264Sjacobs (void) NSS_XbyY_FINI(&arg); 5492847Sjacobs private_ns = NULL; 5502264Sjacobs #endif 5512264Sjacobs 5522264Sjacobs if (res != NSS_SUCCESS) 5532264Sjacobs buf[0] = '\0'; 5542264Sjacobs 5552264Sjacobs result = _cvt_nss_entry_to_printer(buf); 5562313Sjacobs #if defined(__sun) && defined(__SVR4) 5572313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 5582313Sjacobs #endif 5592264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 5602264Sjacobs fill_printer_uri(&result); 5612264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 5622264Sjacobs #endif 5632264Sjacobs 5642264Sjacobs #ifdef DEBUG 5652264Sjacobs printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); 5662264Sjacobs if (result != NULL) { 5672264Sjacobs char buf[4096]; 5682264Sjacobs 5692264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 5702264Sjacobs printf("\t%s\n", buf); 5712264Sjacobs } 5722264Sjacobs #endif /* DEBUG */ 5732264Sjacobs 5742264Sjacobs return (result); 5752264Sjacobs } 5762264Sjacobs 5772264Sjacobs 5782264Sjacobs papi_attribute_t ** 5792264Sjacobs getprinterbyname(char *name, char *ns) 5802264Sjacobs { 5812264Sjacobs papi_attribute_t **result = NULL; 5822264Sjacobs 5832264Sjacobs if (strstr(name, "://") != NULL) { /* shortcut for URI form */ 5842264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5852264Sjacobs "printer-name", name); 5862264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5872264Sjacobs "printer-uri-supported", name); 5882264Sjacobs } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ 5892409Sjacobs char *uri = bsdaddr_to_uri(result, name); 5902264Sjacobs 5912264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5922264Sjacobs "printer-name", name); 5932264Sjacobs if (uri != NULL) { 5942264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5952264Sjacobs "printer-uri-supported", uri); 5962264Sjacobs free(uri); 5972264Sjacobs } 5982264Sjacobs } else { /* anything else */ 5992264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 6002264Sjacobs char buf[10240]; 6012264Sjacobs nss_status_t res = NSS_NOTFOUND; 6022264Sjacobs 6032264Sjacobs #ifdef NSS_EMULATION 6042264Sjacobs res = emul_getprinterbyname_r(name, buf, sizeof (buf)); 6052264Sjacobs #elif NSS_SOLARIS 6062264Sjacobs nss_XbyY_args_t arg; 6072264Sjacobs 6082264Sjacobs private_ns = ns; 6092264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 6102264Sjacobs arg.key.name = name; 6112264Sjacobs res = nss_search(&db_root, _nss_initf_printers, 6122264Sjacobs NSS_DBOP_PRINTERS_BYNAME, &arg); 6132264Sjacobs (void) NSS_XbyY_FINI(&arg); 6142847Sjacobs private_ns = NULL; 6152264Sjacobs 6162264Sjacobs if (res != NSS_SUCCESS) 6172264Sjacobs buf[0] = '\0'; 6182264Sjacobs #endif 6192264Sjacobs 6202264Sjacobs result = _cvt_nss_entry_to_printer(buf); 6212264Sjacobs #endif 6222264Sjacobs } 6232313Sjacobs #if defined(__sun) && defined(__SVR4) 6242313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 6252313Sjacobs #endif 6262264Sjacobs #ifdef DEBUG 6272264Sjacobs printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), 6282264Sjacobs name, result); 6292264Sjacobs if (result != NULL) { 6302264Sjacobs char buf[4096]; 6312264Sjacobs 6322264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 6332264Sjacobs printf("\t%s\n", buf); 6342264Sjacobs } 6352264Sjacobs #endif /* DEBUG */ 6362264Sjacobs 6372264Sjacobs return (result); 6382264Sjacobs } 639