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 282264Sjacobs /* $Id: nss.c 166 2006-05-20 05:48:55Z 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 * 542264Sjacobs bsdaddr_to_uri(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); 652264Sjacobs bsd[1] = strtok_r(NULL, ":,", &iter); 662264Sjacobs bsd[2] = strtok_r(NULL, ":,", &iter); 672264Sjacobs 682264Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/%s%s%s", bsd[0], bsd[1], 692264Sjacobs (bsd[2] != NULL) ? "#" : "", 702264Sjacobs (bsd[2] != NULL) ? bsd[2] : ""); 712264Sjacobs 722264Sjacobs free(tmp); 732264Sjacobs 742264Sjacobs result = strdup(buf); 752264Sjacobs } 762264Sjacobs 772264Sjacobs return (result); 782264Sjacobs } 792264Sjacobs 802264Sjacobs #if defined(__sun) && defined(__SVR4) 81*2313Sjacobs #include <sys/socket.h> 82*2313Sjacobs #include <sys/ioctl.h> 83*2313Sjacobs #include <sys/sockio.h> 84*2313Sjacobs #include <net/if.h> 85*2313Sjacobs #include <netinet/in.h> 86*2313Sjacobs #include <arpa/inet.h> 87*2313Sjacobs #include <netdb.h> 88*2313Sjacobs 89*2313Sjacobs static struct in6_addr ** 90*2313Sjacobs local_interfaces() 91*2313Sjacobs { 92*2313Sjacobs struct in6_addr **result = NULL; 93*2313Sjacobs int s; 94*2313Sjacobs struct lifnum n; 95*2313Sjacobs struct lifconf c; 96*2313Sjacobs struct lifreq *r; 97*2313Sjacobs int count; 98*2313Sjacobs 99*2313Sjacobs /* we need a socket to get the interfaces */ 100*2313Sjacobs if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 101*2313Sjacobs return (0); 102*2313Sjacobs 103*2313Sjacobs /* get the number of interfaces */ 104*2313Sjacobs memset(&n, 0, sizeof (n)); 105*2313Sjacobs n.lifn_family = AF_UNSPEC; 106*2313Sjacobs if (ioctl(s, SIOCGLIFNUM, (char *)&n) < 0) { 107*2313Sjacobs close(s); 108*2313Sjacobs return (0); /* no interfaces */ 109*2313Sjacobs } 110*2313Sjacobs 111*2313Sjacobs /* get the interface(s) configuration */ 112*2313Sjacobs memset(&c, 0, sizeof (c)); 113*2313Sjacobs c.lifc_family = AF_UNSPEC; 114*2313Sjacobs c.lifc_buf = calloc(n.lifn_count, sizeof (struct lifreq)); 115*2313Sjacobs c.lifc_len = (n.lifn_count * sizeof (struct lifreq)); 116*2313Sjacobs if (ioctl(s, SIOCGLIFCONF, (char *)&c) < 0) { 117*2313Sjacobs free(c.lifc_buf); 118*2313Sjacobs close(s); 119*2313Sjacobs return (0); /* can't get interface(s) configuration */ 120*2313Sjacobs } 121*2313Sjacobs close(s); 122*2313Sjacobs 123*2313Sjacobs r = c.lifc_req; 124*2313Sjacobs for (count = c.lifc_len / sizeof (struct lifreq); 125*2313Sjacobs count > 0; count--, r++) { 126*2313Sjacobs struct in6_addr v6[1], *addr = NULL; 127*2313Sjacobs 128*2313Sjacobs switch (r->lifr_addr.ss_family) { 129*2313Sjacobs case AF_INET: { 130*2313Sjacobs struct sockaddr_in *s = 131*2313Sjacobs (struct sockaddr_in *)&r->lifr_addr; 132*2313Sjacobs IN6_INADDR_TO_V4MAPPED(&s->sin_addr, v6); 133*2313Sjacobs addr = v6; 134*2313Sjacobs } 135*2313Sjacobs break; 136*2313Sjacobs case AF_INET6: { 137*2313Sjacobs struct sockaddr_in6 *s = 138*2313Sjacobs (struct sockaddr_in6 *)&r->lifr_addr; 139*2313Sjacobs addr = &s->sin6_addr; 140*2313Sjacobs } 141*2313Sjacobs break; 142*2313Sjacobs } 143*2313Sjacobs 144*2313Sjacobs if (addr != NULL) { 145*2313Sjacobs struct in6_addr *a = malloc(sizeof (*a)); 146*2313Sjacobs 147*2313Sjacobs memcpy(a, addr, sizeof (*a)); 148*2313Sjacobs list_append(&result, a); 149*2313Sjacobs } 150*2313Sjacobs } 151*2313Sjacobs free(c.lifc_buf); 152*2313Sjacobs 153*2313Sjacobs return (result); 154*2313Sjacobs } 155*2313Sjacobs 156*2313Sjacobs static int 157*2313Sjacobs match_interfaces(char *host) 158*2313Sjacobs { 159*2313Sjacobs struct in6_addr **lif = local_interfaces(); 160*2313Sjacobs struct hostent *hp; 161*2313Sjacobs int rc = 0; 162*2313Sjacobs int errnum; 163*2313Sjacobs 164*2313Sjacobs /* are there any local interfaces */ 165*2313Sjacobs if (lif == NULL) 166*2313Sjacobs return (0); 167*2313Sjacobs 168*2313Sjacobs /* cycle through the host db addresses */ 169*2313Sjacobs hp = getipnodebyname(host, AF_INET6, AI_ALL|AI_V4MAPPED, &errnum); 170*2313Sjacobs if (hp != NULL) { 171*2313Sjacobs struct in6_addr **tmp = (struct in6_addr **)hp->h_addr_list; 172*2313Sjacobs int i; 173*2313Sjacobs 174*2313Sjacobs for (i = 0; ((rc == 0) && (tmp[i] != NULL)); i++) { 175*2313Sjacobs int j; 176*2313Sjacobs 177*2313Sjacobs for (j = 0; ((rc == 0) && (lif[j] != NULL)); j++) 178*2313Sjacobs if (memcmp(tmp[i], lif[j], 179*2313Sjacobs sizeof (struct in6_addr)) == 0) 180*2313Sjacobs rc = 1; 181*2313Sjacobs } 182*2313Sjacobs } 183*2313Sjacobs free(lif); 184*2313Sjacobs 185*2313Sjacobs return (rc); 186*2313Sjacobs } 187*2313Sjacobs 188*2313Sjacobs static int 189*2313Sjacobs is_localhost(char *host) 190*2313Sjacobs { 191*2313Sjacobs char hostname[BUFSIZ]; 192*2313Sjacobs 193*2313Sjacobs /* is it "localhost" */ 194*2313Sjacobs if (strncasecmp(host, "localhost", 10) == 0) 195*2313Sjacobs return (1); 196*2313Sjacobs 197*2313Sjacobs /* is it the {nodename} */ 198*2313Sjacobs sysinfo(SI_HOSTNAME, hostname, sizeof (hostname)); 199*2313Sjacobs if (strncasecmp(host, hostname, strlen(hostname)) == 0) 200*2313Sjacobs return (1); 201*2313Sjacobs 202*2313Sjacobs /* does it match one of the host's configured interfaces */ 203*2313Sjacobs if (match_interfaces(host) != 0) 204*2313Sjacobs return (1); 205*2313Sjacobs 206*2313Sjacobs return (0); 207*2313Sjacobs } 208*2313Sjacobs 2092264Sjacobs /* 2102264Sjacobs * This is an awful HACK to force the dynamic PAPI library to use the 2112264Sjacobs * lpsched support when the destination apears to be a local lpsched 2122264Sjacobs * queue on Solaris. 2132264Sjacobs */ 2142264Sjacobs static void 2152264Sjacobs solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list) 2162264Sjacobs { 2172264Sjacobs papi_attribute_t *attribute; 2182264Sjacobs uri_t *uri = NULL; 2192264Sjacobs char *printer = NULL; 2202264Sjacobs char buf[128], buf2[128]; 2212264Sjacobs 2222264Sjacobs /* setting this in the calling env can be useful for debugging */ 2232264Sjacobs if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL) 2242264Sjacobs return; 2252264Sjacobs 2262264Sjacobs papiAttributeListGetString(*list, NULL, 2272264Sjacobs "printer-uri-supported", &printer); 2282264Sjacobs if (uri_from_string(printer, &uri) < 0) 2292264Sjacobs return; 2302264Sjacobs 2312264Sjacobs /* already an lpsched URI ? */ 2322264Sjacobs if (strcasecmp(uri->scheme, "lpsched") == 0) 2332264Sjacobs return; 2342264Sjacobs 2352264Sjacobs if ((printer = strrchr(uri->path, '/')) == NULL) 2362264Sjacobs printer = uri->path; 2372264Sjacobs else 2382264Sjacobs printer++; 2392264Sjacobs 2402264Sjacobs /* is there an lpsched queue (printer/class) */ 2412264Sjacobs snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer); 2422264Sjacobs snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer); 2432264Sjacobs if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) 2442264Sjacobs return; 2452264Sjacobs 246*2313Sjacobs /* is this the "local" host */ 247*2313Sjacobs if ((uri->host != NULL) && (is_localhost(uri->host) == 0)) 248*2313Sjacobs return; 249*2313Sjacobs 250*2313Sjacobs snprintf(buf, sizeof (buf), "lpsched://%s/printers/%s", 251*2313Sjacobs (uri->host ? uri->host : "localhost"), printer); 2522264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_REPLACE, 2532264Sjacobs "printer-uri-supported", buf); 2542264Sjacobs } 2552264Sjacobs #endif 2562264Sjacobs 2572264Sjacobs static void 2582264Sjacobs fill_printer_uri_supported(papi_attribute_t ***list) 2592264Sjacobs { 2602264Sjacobs papi_attribute_t *attribute; 2612264Sjacobs char *string = NULL; 2622264Sjacobs 2632264Sjacobs /* do we have a printer-uri-supported */ 2642264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri-supported"); 2652264Sjacobs if (attribute != NULL) /* we have what we need, return */ 2662264Sjacobs return; 2672264Sjacobs 2682264Sjacobs /* do we have a printer-uri to rename */ 2692264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 2702264Sjacobs if (attribute != NULL) { /* rename it in place and return */ 2712264Sjacobs free(attribute->name); 2722264Sjacobs attribute->name = strdup("printer-uri-supported"); 2732264Sjacobs return; 2742264Sjacobs } 2752264Sjacobs 2762264Sjacobs /* do we have a printers.conf(4) "bsdaddr" to convert */ 2772264Sjacobs papiAttributeListGetString(*list, NULL, "bsdaddr", &string); 2782264Sjacobs if (string != NULL) { /* parse it, convert it, add it */ 2792264Sjacobs char *uri = bsdaddr_to_uri(string); 2802264Sjacobs 2812264Sjacobs if (uri != NULL) { 2822264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 2832264Sjacobs "printer-uri-supported", uri); 2842264Sjacobs papiAttributeListDelete(list, "bsdaddr"); 2852264Sjacobs free(uri); 2862264Sjacobs return; 2872264Sjacobs } 2882264Sjacobs } 2892264Sjacobs 2902264Sjacobs /* do we have a printers.conf(4) "rm" (and "rp") to convert */ 2912264Sjacobs papiAttributeListGetString(*list, NULL, "rm", &string); 2922264Sjacobs if (string != NULL) { 2932264Sjacobs char *rp = NULL; 2942264Sjacobs 2952264Sjacobs /* default to "printer-name", but use "rp" if we have it */ 2962264Sjacobs papiAttributeListGetString(*list, NULL, "printer-name", &rp); 2972264Sjacobs papiAttributeListGetString(*list, NULL, "rp", &rp); 2982264Sjacobs 2992264Sjacobs if (rp != NULL) { /* fill in the uri if we have the data */ 3002264Sjacobs char buf[BUFSIZ]; 3012264Sjacobs 3022264Sjacobs snprintf(buf, sizeof (buf), "lpd://%s/printers/%s", 3032264Sjacobs string, rp); 3042264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 3052264Sjacobs "printer-uri-supported", strdup(buf)); 3062264Sjacobs return; 3072264Sjacobs } 3082264Sjacobs } 3092264Sjacobs 3102264Sjacobs /* if were are here, we don't have a printer-uri-supported */ 3112264Sjacobs } 3122264Sjacobs 3132264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 3142264Sjacobs static void 3152264Sjacobs fill_printer_uri(papi_attribute_t ***list) 3162264Sjacobs { 3172264Sjacobs papi_attribute_t *attribute; 3182264Sjacobs char *uri = NULL; 3192264Sjacobs 3202264Sjacobs if ((list == NULL) || (*list == NULL)) 3212264Sjacobs return; 3222264Sjacobs 323*2313Sjacobs /* do we have a printer-uri */ 3242264Sjacobs attribute = papiAttributeListFind(*list, "printer-uri"); 3252264Sjacobs if (attribute != NULL) /* we have what we need, return */ 3262264Sjacobs return; 3272264Sjacobs 3282264Sjacobs /* 3292264Sjacobs * this is sufficient to fool libgnomeprintpapi, but not promote it's 3302264Sjacobs * use in the future. 3312264Sjacobs */ 3322264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri", 3332264Sjacobs "broken printer-uri semantic"); 3342264Sjacobs } 3352264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 3362264Sjacobs 3372264Sjacobs static void 3382264Sjacobs cvt_all_to_member_names(papi_attribute_t ***list) 3392264Sjacobs { 3402264Sjacobs papi_status_t status; 3412264Sjacobs void *iter = NULL; 3422264Sjacobs char *string = NULL; 3432264Sjacobs 3442264Sjacobs papiAttributeListGetString(*list, NULL, "member-names", &string); 3452264Sjacobs if (string != NULL) /* already have a member-names */ 3462264Sjacobs return; 3472264Sjacobs 3482264Sjacobs for (status = papiAttributeListGetString(*list, &iter, "all", &string); 3492264Sjacobs status == PAPI_OK; 3502264Sjacobs status = papiAttributeListGetString(*list, &iter, NULL, &string)) { 3512264Sjacobs char *s_iter = NULL, *value, *tmp = strdup(string); 3522264Sjacobs 3532264Sjacobs for (value = strtok_r(tmp, ", \t", &s_iter); 3542264Sjacobs value != NULL; 3552264Sjacobs value = strtok_r(NULL, ", \t", &s_iter)) 3562264Sjacobs papiAttributeListAddString(list, PAPI_ATTR_APPEND, 3572264Sjacobs "member-names", value); 3582264Sjacobs free(tmp); 3592264Sjacobs } 3602264Sjacobs } 3612264Sjacobs 3622264Sjacobs static papi_attribute_t ** 3632264Sjacobs _cvt_nss_entry_to_printer(char *entry) 3642264Sjacobs { 3652264Sjacobs char *key = NULL, 3662264Sjacobs *cp, 3672264Sjacobs buf[BUFSIZ]; 3682264Sjacobs int in_namelist = 1, buf_pos = 0; 3692264Sjacobs papi_attribute_t **list = NULL; 3702264Sjacobs 3712264Sjacobs if (entry == NULL) 3722264Sjacobs return (NULL); 3732264Sjacobs 3742264Sjacobs memset(buf, 0, sizeof (buf)); 3752264Sjacobs for (cp = entry; *cp != '\0'; cp++) { 3762264Sjacobs switch (*cp) { 3772264Sjacobs case ':': /* end of kvp */ 3782264Sjacobs if (in_namelist != 0) { 3792264Sjacobs papiAttributeListAddString(&list, 3802264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 3812264Sjacobs in_namelist = 0; 3822264Sjacobs } else if (key != NULL) 3832264Sjacobs papiAttributeListAddString(&list, 3842264Sjacobs PAPI_ATTR_APPEND, key, buf); 3852264Sjacobs memset(buf, 0, sizeof (buf)); 3862264Sjacobs buf_pos = 0; 3872264Sjacobs key = NULL; 3882264Sjacobs break; 3892264Sjacobs case '=': /* kvp seperator */ 3902264Sjacobs if (key == NULL) { 3912264Sjacobs key = strdup(buf); 3922264Sjacobs memset(buf, 0, sizeof (buf)); 3932264Sjacobs buf_pos = 0; 3942264Sjacobs } else 3952264Sjacobs buf[buf_pos++] = *cp; 3962264Sjacobs break; 3972264Sjacobs case '|': /* namelist seperator */ 3982264Sjacobs if (in_namelist != 0) { 3992264Sjacobs papiAttributeListAddString(&list, 4002264Sjacobs PAPI_ATTR_APPEND, "printer-name", buf); 4012264Sjacobs memset(buf, 0, sizeof (buf)); 4022264Sjacobs buf_pos = 0; 4032264Sjacobs } else /* add it to the buffer */ 4042264Sjacobs buf[buf_pos++] = *cp; 4052264Sjacobs break; 4062264Sjacobs case '\\': /* escape char */ 4072264Sjacobs buf[buf_pos++] = *(++cp); 4082264Sjacobs break; 4092264Sjacobs default: 4102264Sjacobs buf[buf_pos++] = *cp; 4112264Sjacobs } 4122264Sjacobs 4132264Sjacobs } 4142264Sjacobs 4152264Sjacobs if (key != NULL) 4162264Sjacobs papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf); 4172264Sjacobs 4182264Sjacobs /* resolve any "use" references in the configuration DB */ 4192264Sjacobs key = NULL; 4202264Sjacobs papiAttributeListGetString(list, NULL, "use", &key); 4212264Sjacobs if (key != NULL) { 4222264Sjacobs papi_attribute_t **use_attrs = getprinterbyname(key, NULL); 4232264Sjacobs 4242264Sjacobs list_concatenate(&list, use_attrs); 4252264Sjacobs } 4262264Sjacobs 4272264Sjacobs fill_printer_uri_supported(&list); 4282264Sjacobs cvt_all_to_member_names(&list); /* convert "all" to "member-names" */ 4292264Sjacobs 4302264Sjacobs return (list); 4312264Sjacobs } 4322264Sjacobs 4332264Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION) 4342264Sjacobs 4352264Sjacobs #ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */ 4362264Sjacobs #define NSS_DBNAM__PRINTERS "_printers" 4372264Sjacobs #endif 4382264Sjacobs 4392264Sjacobs static DEFINE_NSS_DB_ROOT(db_root); 4402264Sjacobs static DEFINE_NSS_GETENT(context); 4412264Sjacobs 4422264Sjacobs static char *private_ns = NULL; 4432264Sjacobs static char initialized = 0; 4442264Sjacobs 4452264Sjacobs static void 4462264Sjacobs _nss_initf_printers(p) 4472264Sjacobs nss_db_params_t *p; 4482264Sjacobs { 4492264Sjacobs if (private_ns != NULL) { 4502264Sjacobs /* 4512264Sjacobs * because we need to support a legacy interface that allows 4522264Sjacobs * us to select a specific name service, we need to dummy up 4532264Sjacobs * the parameters to use a private nsswitch database and set 4542264Sjacobs * the * default_config entry to the name service we are 4552264Sjacobs * looking into. 4562264Sjacobs */ 4572264Sjacobs p->name = NSS_DBNAM__PRINTERS; /* "_printers" */ 4582264Sjacobs p->default_config = private_ns; 4592264Sjacobs private_ns = NULL; 4602264Sjacobs } else if (initialized == 0) { 4612264Sjacobs /* regular behaviour */ 4622264Sjacobs p->name = NSS_DBNAM_PRINTERS; /* "printers" */ 4632264Sjacobs p->default_config = NSS_DEFCONF_PRINTERS; 4642264Sjacobs initialized = 1; 4652264Sjacobs } 4662264Sjacobs syslog(LOG_DEBUG, "database: %s, services: %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); 4832264Sjacobs /* 4842264Sjacobs * We copy the input string into the output buffer 4852264Sjacobs */ 4862264Sjacobs (void) memcpy(buffer, instr, lenstr); 4872264Sjacobs buffer[lenstr] = '\0'; 4882264Sjacobs 4892264Sjacobs return (NSS_STR_PARSE_SUCCESS); 4902264Sjacobs } 4912264Sjacobs #endif /* NSS_SOLARIS */ 4922264Sjacobs 4932264Sjacobs int 4942264Sjacobs setprinterentry(int stayopen, char *ns) 4952264Sjacobs { 4962264Sjacobs #ifdef NSS_EMULATION 4972264Sjacobs emul_setprinterentry(stayopen); 4982264Sjacobs #elif NSS_SOLARIS 4992264Sjacobs initialized = 0; 5002264Sjacobs private_ns = ns; 5012264Sjacobs nss_setent(&db_root, _nss_initf_printers, &context); 5022264Sjacobs #endif 5032264Sjacobs return (0); 5042264Sjacobs } 5052264Sjacobs 5062264Sjacobs 5072264Sjacobs int 5082264Sjacobs endprinterentry(int i) 5092264Sjacobs { 5102264Sjacobs #ifdef NSS_EMULATION 5112264Sjacobs emul_endprinterentry(); 5122264Sjacobs #elif NSS_SOLARIS 5132264Sjacobs initialized = 0; 5142264Sjacobs nss_endent(&db_root, _nss_initf_printers, &context); 5152264Sjacobs nss_delete(&db_root); 5162264Sjacobs #endif 5172264Sjacobs return (0); 5182264Sjacobs } 5192264Sjacobs 5202264Sjacobs /* ARGSUSED2 */ 5212264Sjacobs papi_attribute_t ** 5222264Sjacobs getprinterentry(char *ns) 5232264Sjacobs { 5242264Sjacobs papi_attribute_t **result = NULL; 5252264Sjacobs 5262264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 5272264Sjacobs char buf[10240]; 5282264Sjacobs nss_status_t res = NSS_NOTFOUND; 5292264Sjacobs 5302264Sjacobs #ifdef NSS_EMULATION 5312264Sjacobs res = emul_getprinterentry_r(buf, sizeof (buf)); 5322264Sjacobs #elif NSS_SOLARIS 5332264Sjacobs nss_XbyY_args_t arg; 5342264Sjacobs 5352264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 5362264Sjacobs res = nss_getent(&db_root, _nss_initf_printers, &context, &arg); 5372264Sjacobs (void) NSS_XbyY_FINI(&arg); 5382264Sjacobs #endif 5392264Sjacobs 5402264Sjacobs if (res != NSS_SUCCESS) 5412264Sjacobs buf[0] = '\0'; 5422264Sjacobs 5432264Sjacobs result = _cvt_nss_entry_to_printer(buf); 544*2313Sjacobs #if defined(__sun) && defined(__SVR4) 545*2313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 546*2313Sjacobs #endif 5472264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC 5482264Sjacobs fill_printer_uri(&result); 5492264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */ 5502264Sjacobs #endif 5512264Sjacobs 5522264Sjacobs #ifdef DEBUG 5532264Sjacobs printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result); 5542264Sjacobs if (result != NULL) { 5552264Sjacobs char buf[4096]; 5562264Sjacobs 5572264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 5582264Sjacobs printf("\t%s\n", buf); 5592264Sjacobs } 5602264Sjacobs #endif /* DEBUG */ 5612264Sjacobs 5622264Sjacobs return (result); 5632264Sjacobs } 5642264Sjacobs 5652264Sjacobs 5662264Sjacobs papi_attribute_t ** 5672264Sjacobs getprinterbyname(char *name, char *ns) 5682264Sjacobs { 5692264Sjacobs papi_attribute_t **result = NULL; 5702264Sjacobs 5712264Sjacobs if (strstr(name, "://") != NULL) { /* shortcut for URI form */ 5722264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5732264Sjacobs "printer-name", name); 5742264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5752264Sjacobs "printer-uri-supported", name); 5762264Sjacobs } else if (strchr(name, ':') != NULL) { /* shortcut for POSIX form */ 5772264Sjacobs char *uri = bsdaddr_to_uri(name); 5782264Sjacobs 5792264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5802264Sjacobs "printer-name", name); 5812264Sjacobs if (uri != NULL) { 5822264Sjacobs papiAttributeListAddString(&result, PAPI_ATTR_APPEND, 5832264Sjacobs "printer-uri-supported", uri); 5842264Sjacobs free(uri); 5852264Sjacobs } 5862264Sjacobs } else { /* anything else */ 5872264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS) 5882264Sjacobs char buf[10240]; 5892264Sjacobs nss_status_t res = NSS_NOTFOUND; 5902264Sjacobs 5912264Sjacobs #ifdef NSS_EMULATION 5922264Sjacobs res = emul_getprinterbyname_r(name, buf, sizeof (buf)); 5932264Sjacobs #elif NSS_SOLARIS 5942264Sjacobs nss_XbyY_args_t arg; 5952264Sjacobs 5962264Sjacobs private_ns = ns; 5972264Sjacobs NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer); 5982264Sjacobs arg.key.name = name; 5992264Sjacobs res = nss_search(&db_root, _nss_initf_printers, 6002264Sjacobs NSS_DBOP_PRINTERS_BYNAME, &arg); 6012264Sjacobs (void) NSS_XbyY_FINI(&arg); 6022264Sjacobs 6032264Sjacobs if (res != NSS_SUCCESS) 6042264Sjacobs buf[0] = '\0'; 6052264Sjacobs #endif 6062264Sjacobs 6072264Sjacobs result = _cvt_nss_entry_to_printer(buf); 6082264Sjacobs #endif 6092264Sjacobs } 610*2313Sjacobs #if defined(__sun) && defined(__SVR4) 611*2313Sjacobs solaris_lpsched_shortcircuit_hack(&result); 612*2313Sjacobs #endif 6132264Sjacobs #ifdef DEBUG 6142264Sjacobs printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"), 6152264Sjacobs name, result); 6162264Sjacobs if (result != NULL) { 6172264Sjacobs char buf[4096]; 6182264Sjacobs 6192264Sjacobs papiAttributeListToString(result, "\n\t", buf, sizeof (buf)); 6202264Sjacobs printf("\t%s\n", buf); 6212264Sjacobs } 6222264Sjacobs #endif /* DEBUG */ 6232264Sjacobs 6242264Sjacobs return (result); 6252264Sjacobs } 626