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 /* 232264Sjacobs * Copyright 2006 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 2712264Sjacobs /* do we have a printer-uri to rename */ 2722264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 2732264Sjacobs if (attribute != NULL) { /* rename it in place and return */ 2742264Sjacobs free(attribute->name); 2752264Sjacobs attribute->name = strdup("printer-uri-supported"); 2762264Sjacobs return; 2772264Sjacobs } 2782264Sjacobs 2792264Sjacobs /* do we have a printers.conf(4) "bsdaddr" to convert */ 2802264Sjacobs papiAttributeListGetString(*list, NULL, "bsdaddr", &string); 2812264Sjacobs if (string != NULL) { /* parse it, convert it, add it */ 2822409Sjacobs char *uri = bsdaddr_to_uri(*list, string); 2832264Sjacobs 2842264Sjacobs if (uri != NULL) { 2852264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 2862264Sjacobs "printer-uri-supported", uri); 2872264Sjacobs papiAttributeListDelete(list, "bsdaddr"); 2882264Sjacobs free(uri); 2892264Sjacobs return; 2902264Sjacobs } 2912264Sjacobs } 2922264Sjacobs 2932264Sjacobs /* do we have a printers.conf(4) "rm" (and "rp") to convert */ 2942264Sjacobs papiAttributeListGetString(*list, NULL, "rm", &string); 2952264Sjacobs if (string != NULL) { 2962264Sjacobs char *rp = NULL; 2972264Sjacobs 2982264Sjacobs /* default to "printer-name", but use "rp" if we have it */ 2992264Sjacobs papiAttributeListGetString(*list, NULL, "printer-name", &rp); 3002264Sjacobs papiAttributeListGetString(*list, NULL, "rp", &rp); 3012264Sjacobs 3022264Sjacobs if (rp != NULL) { /* fill in the uri if we have the data */ 3032264Sjacobs char buf[BUFSIZ]; 3042264Sjacobs 3052264Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", 3062264Sjacobs string, rp); 3072264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 3082264Sjacobs "printer-uri-supported", strdup(buf)); 3092264Sjacobs return; 3102264Sjacobs } 3112264Sjacobs } 3122264Sjacobs 3132264Sjacobs /* if were are here, we don't have a printer-uri-supported */ 3142264Sjacobs } 3152264Sjacobs 3162264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 3172264Sjacobs static void 3182264Sjacobs fill_printer_uri(papi_attribute_t ***list) 3192264Sjacobs { 3202264Sjacobs papi_attribute_t *attribute; 3212264Sjacobs char *uri = NULL; 3222264Sjacobs 3232264Sjacobs if ((list == NULL) || (*list == NULL)) 3242264Sjacobs return; 3252264Sjacobs 3262313Sjacobs /* do we have a printer-uri */ 3272264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 3282264Sjacobs if (attribute != NULL) /* we have what we need, return */ 3292264Sjacobs return; 3302264Sjacobs 3312264Sjacobs /* 3322264Sjacobs * this is sufficient to fool libgnomeprintpapi, but not promote it's 3332264Sjacobs * use in the future. 3342264Sjacobs */ 3352264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", 3362264Sjacobs "broken printer-uri semantic"); 3372264Sjacobs } 3382264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 3392264Sjacobs 3402264Sjacobs static void 3412264Sjacobs cvt_all_to_member_names(papi_attribute_t ***list) 3422264Sjacobs { 3432264Sjacobs papi_status_t status; 3442264Sjacobs void *iter = NULL; 3452264Sjacobs char *string = NULL; 3462264Sjacobs 3472264Sjacobs papiAttributeListGetString(*list, NULL, "member-names", &string); 3482264Sjacobs if (string != NULL) /* already have a member-names */ 3492264Sjacobs return; 3502264Sjacobs 3512264Sjacobs for (status = papiAttributeListGetString(*list, &iter, "all", &string); 3522264Sjacobs status == PAPI_OK; 3532264Sjacobs status = papiAttributeListGetString(*list, &iter, NULL, &string)) { 3542264Sjacobs char *s_iter = NULL, *value, *tmp = strdup(string); 3552264Sjacobs 3562264Sjacobs for (value = strtok_r(tmp, ", \t", &s_iter); 3572264Sjacobs value != NULL; 3582264Sjacobs value = strtok_r(NULL, ", \t", &s_iter)) 3592264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 3602264Sjacobs "member-names", value); 3612264Sjacobs free(tmp); 3622264Sjacobs } 3632264Sjacobs } 3642264Sjacobs 3652264Sjacobs static papi_attribute_t ** 3662264Sjacobs _cvt_nss_entry_to_printer(char *entry) 3672264Sjacobs { 3682264Sjacobs char *key = NULL, 3692264Sjacobs *cp, 3702264Sjacobs buf[BUFSIZ]; 3712264Sjacobs int in_namelist = 1, buf_pos = 0; 3722264Sjacobs papi_attribute_t **list = NULL; 3732264Sjacobs 3742264Sjacobs if (entry == NULL) 3752264Sjacobs return (NULL); 3762264Sjacobs 3772264Sjacobs memset(buf, 0, sizeof (buf)); 3782264Sjacobs for (cp = entry; *cp != '\0'; cp++) { 3792264Sjacobs switch (*cp) { 3802264Sjacobs case ':': /* end of kvp */ 3812264Sjacobs if (in_namelist != 0) { 3822264Sjacobs papiAttributeListAddString(&list, 3832264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 3842264Sjacobs in_namelist = 0; 3852264Sjacobs } else if (key != NULL) 3862264Sjacobs papiAttributeListAddString(&list, 3872264Sjacobs PAPI_ATTR_APPEND, key, buf); 3882264Sjacobs memset(buf, 0, sizeof (buf)); 3892264Sjacobs buf_pos = 0; 3902264Sjacobs key = NULL; 3912264Sjacobs break; 3922264Sjacobs case '=': /* kvp seperator */ 3932264Sjacobs if (key == NULL) { 3942264Sjacobs key = strdup(buf); 3952264Sjacobs memset(buf, 0, sizeof (buf)); 3962264Sjacobs buf_pos = 0; 3972264Sjacobs } else 3982264Sjacobs buf[buf_pos++] = *cp; 3992264Sjacobs break; 4002264Sjacobs case '|': /* namelist seperator */ 4012264Sjacobs if (in_namelist != 0) { 4022264Sjacobs papiAttributeListAddString(&list, 4032264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 4042264Sjacobs memset(buf, 0, sizeof (buf)); 4052264Sjacobs buf_pos = 0; 4062264Sjacobs } else /* add it to the buffer */ 4072264Sjacobs buf[buf_pos++] = *cp; 4082264Sjacobs break; 4092264Sjacobs case '\\': /* escape char */ 4102264Sjacobs buf[buf_pos++] = *(++cp); 4112264Sjacobs break; 4122264Sjacobs default: 4132264Sjacobs buf[buf_pos++] = *cp; 4142264Sjacobs } 4152264Sjacobs 4162264Sjacobs } 4172264Sjacobs 4182264Sjacobs if (key != NULL) 4192264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); 4202264Sjacobs 4212264Sjacobs /* resolve any "use" references in the configuration DB */ 4222264Sjacobs key = NULL; 4232264Sjacobs papiAttributeListGetString(list, NULL, "use", &key); 4242264Sjacobs if (key != NULL) { 4252264Sjacobs papi_attribute_t **use_attrs = getprinterbyname(key, NULL); 4262264Sjacobs 4272264Sjacobs list_concatenate(&list, use_attrs); 4282264Sjacobs } 4292264Sjacobs 4302264Sjacobs fill_printer_uri_supported(&list); 4312264Sjacobs cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ 4322264Sjacobs 4332264Sjacobs return (list); 4342264Sjacobs } 4352264Sjacobs 4362264Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) 4372264Sjacobs 4382264Sjacobs #ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ 4392264Sjacobs #define NSS_DBNAM__PRINTERS "_printers" 4402264Sjacobs #endif 4412264Sjacobs 4422264Sjacobs static DEFINE_NSS_DB_ROOT(db_root); 4432264Sjacobs static DEFINE_NSS_GETENT(context); 4442264Sjacobs 4452264Sjacobs static char *private_ns = NULL; 4462264Sjacobs 4472264Sjacobs static void 4482264Sjacobs _nss_initf_printers(p) 4492264Sjacobs nss_db_params_t *p; 4502264Sjacobs { 4512264Sjacobs if (private_ns != NULL) { 4522264Sjacobs /* 4532264Sjacobs * because we need to support a legacy interface that allows 4542264Sjacobs * us to select a specific name service, we need to dummy up 4552264Sjacobs * the parameters to use a private nsswitch database and set 4562264Sjacobs * the * default_config entry to the name service we are 4572264Sjacobs * looking into. 4582264Sjacobs */ 4592264Sjacobs p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ 4602264Sjacobs p->default_config = private_ns; 461*2847Sjacobs } else { 4622264Sjacobs /* regular behaviour */ 4632264Sjacobs p->name = NSS_DBNAM_PRINTERS; /* "printers" */ 4642264Sjacobs p->default_config = NSS_DEFCONF_PRINTERS; 4652264Sjacobs } 466*2847Sjacobs syslog(LOG_DEBUG, "database: %s, default: %s", 4672264Sjacobs (p->name ? p->name : "NULL"), 4682264Sjacobs (p->default_config ? p->default_config : "NULL")); 4692264Sjacobs } 4702264Sjacobs 4712264Sjacobs /* 4722264Sjacobs * Return values: 0 = success, 1 = parse error, 2 = erange ... 4732264Sjacobs * The structure pointer passed in is a structure in the caller's space 4742264Sjacobs * wherein the field pointers would be set to areas in the buffer if 4752264Sjacobs * need be. instring and buffer should be separate areas. 4762264Sjacobs */ 4772264Sjacobs /* ARGSUSED */ 4782264Sjacobs static int 4792264Sjacobs str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen) 4802264Sjacobs { 4812264Sjacobs if (lenstr + 1 > buflen) 4822264Sjacobs return (NSS_STR_PARSE_ERANGE); 4832571Sjacobs 4842571Sjacobs /* skip entries that begin with '#' */ 4852571Sjacobs if (instr[0] == '#') 4862571Sjacobs return (NSS_STR_PARSE_PARSE); 4872571Sjacobs 4882264Sjacobs /* 4892264Sjacobs * We copy the input string into the output buffer 4902264Sjacobs */ 4912264Sjacobs (void) memcpy(buffer, instr, lenstr); 4922264Sjacobs buffer[lenstr] = '\0'; 4932264Sjacobs 4942264Sjacobs return (NSS_STR_PARSE_SUCCESS); 4952264Sjacobs } 4962264Sjacobs #endif /* NSS_SOLARIS */ 4972264Sjacobs 4982264Sjacobs int 4992264Sjacobs setprinterentry(int stayopen, char *ns) 5002264Sjacobs { 5012264Sjacobs #ifdef NSS_EMULATION 5022264Sjacobs emul_setprinterentry(stayopen); 5032264Sjacobs #elif NSS_SOLARIS 5042264Sjacobs private_ns = ns; 5052264Sjacobs nss_setent(&db_root, _nss_initf_printers, &context); 506*2847Sjacobs private_ns = NULL; 5072264Sjacobs #endif 5082264Sjacobs return (0); 5092264Sjacobs } 5102264Sjacobs 5112264Sjacobs 5122264Sjacobs int 5132264Sjacobs endprinterentry(int i) 5142264Sjacobs { 5152264Sjacobs #ifdef NSS_EMULATION 5162264Sjacobs emul_endprinterentry(); 5172264Sjacobs #elif NSS_SOLARIS 5182264Sjacobs nss_endent(&db_root, _nss_initf_printers, &context); 5192264Sjacobs nss_delete(&db_root); 520*2847Sjacobs private_ns = NULL; 5212264Sjacobs #endif 5222264Sjacobs return (0); 5232264Sjacobs } 5242264Sjacobs 5252264Sjacobs /* ARGSUSED2 */ 5262264Sjacobs papi_attribute_t ** 5272264Sjacobs getprinterentry(char *ns) 5282264Sjacobs { 5292264Sjacobs papi_attribute_t **result = NULL; 5302264Sjacobs 5312264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 5322264Sjacobs char buf[10240]; 5332264Sjacobs nss_status_t res = NSS_NOTFOUND; 5342264Sjacobs 5352264Sjacobs #ifdef NSS_EMULATION 5362264Sjacobs res = emul_getprinterentry_r(buf, sizeof (buf)); 5372264Sjacobs #elif NSS_SOLARIS 5382264Sjacobs nss_XbyY_args_t arg; 5392264Sjacobs 540*2847Sjacobs private_ns = ns; 5412264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 5422264Sjacobs res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); 5432264Sjacobs (void) NSS_XbyY_FINI(&arg); 544*2847Sjacobs private_ns = NULL; 5452264Sjacobs #endif 5462264Sjacobs 5472264Sjacobs if (res != NSS_SUCCESS) 5482264Sjacobs buf[0] = '\0'; 5492264Sjacobs 5502264Sjacobs result = _cvt_nss_entry_to_printer(buf); 5512313Sjacobs #if defined(__sun) && defined(__SVR4) 5522313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 5532313Sjacobs #endif 5542264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 5552264Sjacobs fill_printer_uri(&result); 5562264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 5572264Sjacobs #endif 5582264Sjacobs 5592264Sjacobs #ifdef DEBUG 5602264Sjacobs printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); 5612264Sjacobs if (result != NULL) { 5622264Sjacobs char buf[4096]; 5632264Sjacobs 5642264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 5652264Sjacobs printf("\t%s\n", buf); 5662264Sjacobs } 5672264Sjacobs #endif /* DEBUG */ 5682264Sjacobs 5692264Sjacobs return (result); 5702264Sjacobs } 5712264Sjacobs 5722264Sjacobs 5732264Sjacobs papi_attribute_t ** 5742264Sjacobs getprinterbyname(char *name, char *ns) 5752264Sjacobs { 5762264Sjacobs papi_attribute_t **result = NULL; 5772264Sjacobs 5782264Sjacobs if (strstr(name, "://") != NULL) { /* shortcut for URI form */ 5792264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5802264Sjacobs "printer-name", name); 5812264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5822264Sjacobs "printer-uri-supported", name); 5832264Sjacobs } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ 5842409Sjacobs char *uri = bsdaddr_to_uri(result, name); 5852264Sjacobs 5862264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5872264Sjacobs "printer-name", name); 5882264Sjacobs if (uri != NULL) { 5892264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5902264Sjacobs "printer-uri-supported", uri); 5912264Sjacobs free(uri); 5922264Sjacobs } 5932264Sjacobs } else { /* anything else */ 5942264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 5952264Sjacobs char buf[10240]; 5962264Sjacobs nss_status_t res = NSS_NOTFOUND; 5972264Sjacobs 5982264Sjacobs #ifdef NSS_EMULATION 5992264Sjacobs res = emul_getprinterbyname_r(name, buf, sizeof (buf)); 6002264Sjacobs #elif NSS_SOLARIS 6012264Sjacobs nss_XbyY_args_t arg; 6022264Sjacobs 6032264Sjacobs private_ns = ns; 6042264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 6052264Sjacobs arg.key.name = name; 6062264Sjacobs res = nss_search(&db_root, _nss_initf_printers, 6072264Sjacobs NSS_DBOP_PRINTERS_BYNAME, &arg); 6082264Sjacobs (void) NSS_XbyY_FINI(&arg); 609*2847Sjacobs private_ns = NULL; 6102264Sjacobs 6112264Sjacobs if (res != NSS_SUCCESS) 6122264Sjacobs buf[0] = '\0'; 6132264Sjacobs #endif 6142264Sjacobs 6152264Sjacobs result = _cvt_nss_entry_to_printer(buf); 6162264Sjacobs #endif 6172264Sjacobs } 6182313Sjacobs #if defined(__sun) && defined(__SVR4) 6192313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 6202313Sjacobs #endif 6212264Sjacobs #ifdef DEBUG 6222264Sjacobs printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), 6232264Sjacobs name, result); 6242264Sjacobs if (result != NULL) { 6252264Sjacobs char buf[4096]; 6262264Sjacobs 6272264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 6282264Sjacobs printf("\t%s\n", buf); 6292264Sjacobs } 6302264Sjacobs #endif /* DEBUG */ 6312264Sjacobs 6322264Sjacobs return (result); 6332264Sjacobs } 634