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*9411SKeerthi.Kondaka@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
242264Sjacobs  * Use is subject to license terms.
252264Sjacobs  *
262264Sjacobs  */
272264Sjacobs 
282409Sjacobs /* Id: nss.c 180 2006-07-20 17:33:02Z njacobs $ */
292264Sjacobs 
302264Sjacobs #include <stdio.h>
312264Sjacobs #include <stdlib.h>
322264Sjacobs #include <unistd.h>
332264Sjacobs #include <string.h>
342264Sjacobs #include <ctype.h>
352264Sjacobs #include <sys/types.h>
362264Sjacobs #include <syslog.h>
372264Sjacobs #include <papi.h>
382264Sjacobs #include <uri.h>
392264Sjacobs #include <papi_impl.h>
402264Sjacobs #ifdef NSS_EMULATION
412264Sjacobs #include <nss-emulation.h>
422264Sjacobs #elif NSS_SOLARIS
432264Sjacobs #include <nss_dbdefs.h>
442264Sjacobs #endif
452264Sjacobs #include <config-site.h>
462264Sjacobs #if defined(__sun) && defined(__SVR4)
472264Sjacobs #include <sys/systeminfo.h>
482264Sjacobs #endif
492264Sjacobs 
502264Sjacobs 
512264Sjacobs static char *
522409Sjacobs bsdaddr_to_uri(papi_attribute_t **list, char *bsdaddr)
532264Sjacobs {
542264Sjacobs 	char *result = NULL;
552264Sjacobs 
562264Sjacobs 	if (bsdaddr != NULL) {
572264Sjacobs 		char *bsd[3], *tmp, *iter = NULL;
582264Sjacobs 		char buf[512];
592264Sjacobs 
602264Sjacobs 		tmp = strdup(bsdaddr);
612264Sjacobs 
622264Sjacobs 		bsd[0] = strtok_r(tmp, ":,", &iter);
632409Sjacobs 		if ((bsd[1] = strtok_r(NULL, ":,", &iter)) == NULL)
642409Sjacobs 			papiAttributeListGetString(list, NULL,
652409Sjacobs 					"printer-name", &bsd[1]);
662264Sjacobs 		bsd[2] = strtok_r(NULL, ":,", &iter);
672264Sjacobs 
682409Sjacobs 		snprintf(buf, sizeof (buf), "lpd://%s/printers/%s%s%s", bsd[0],
692409Sjacobs 			(bsd[1] != NULL) ? bsd[1] : "",
702264Sjacobs 			(bsd[2] != NULL) ? "#" : "",
712264Sjacobs 			(bsd[2] != NULL) ? bsd[2] : "");
722264Sjacobs 
732264Sjacobs 		free(tmp);
742264Sjacobs 
752264Sjacobs 		result = strdup(buf);
762264Sjacobs 	}
772264Sjacobs 
782264Sjacobs 	return (result);
792264Sjacobs }
802264Sjacobs 
812264Sjacobs #if defined(__sun) && defined(__SVR4)
822264Sjacobs /*
832264Sjacobs  * This is an awful HACK to force the dynamic PAPI library to use the
842264Sjacobs  * lpsched support when the destination apears to be a local lpsched
852264Sjacobs  * queue on Solaris.
862264Sjacobs  */
872264Sjacobs static void
882264Sjacobs solaris_lpsched_shortcircuit_hack(papi_attribute_t ***list)
892264Sjacobs {
902264Sjacobs 	papi_attribute_t *attribute;
912264Sjacobs 	uri_t *uri = NULL;
922264Sjacobs 	char *printer = NULL;
932264Sjacobs 	char buf[128], buf2[128];
942264Sjacobs 
952264Sjacobs 	/* setting this in the calling env can be useful for debugging */
962264Sjacobs 	if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL)
972264Sjacobs 		return;
982264Sjacobs 
992264Sjacobs 	papiAttributeListGetString(*list, NULL,
1002264Sjacobs 				"printer-uri-supported", &printer);
1017253Sjacobs 	/* if there is no printer-uri-supported, there is nothing to do */
1027322SWendy.Phillips@Sun.COM 	if (printer == NULL) {
1032264Sjacobs 		return;
1047322SWendy.Phillips@Sun.COM 	}
1052264Sjacobs 
1067253Sjacobs 	if (uri_from_string(printer, &uri) < 0) {
1077253Sjacobs 		papiAttributeListFree(*list);
1087253Sjacobs 		*list = NULL;
1097322SWendy.Phillips@Sun.COM 		uri_free(uri);
1107253Sjacobs 		return;
1117253Sjacobs 	}
1127253Sjacobs 
1132264Sjacobs 	/* already an lpsched URI ? */
1147322SWendy.Phillips@Sun.COM 	if (strcasecmp(uri->scheme, "lpsched") == 0) {
1157322SWendy.Phillips@Sun.COM 		uri_free(uri);
1162264Sjacobs 		return;
1177322SWendy.Phillips@Sun.COM 	}
1182264Sjacobs 
119*9411SKeerthi.Kondaka@Sun.COM 	if (uri->path == NULL) {
120*9411SKeerthi.Kondaka@Sun.COM 		printer = "";
121*9411SKeerthi.Kondaka@Sun.COM 	} else {
122*9411SKeerthi.Kondaka@Sun.COM 		if ((printer = strrchr(uri->path, '/')) == NULL)
123*9411SKeerthi.Kondaka@Sun.COM 			printer = uri->path;
124*9411SKeerthi.Kondaka@Sun.COM 		else
125*9411SKeerthi.Kondaka@Sun.COM 			printer++;
126*9411SKeerthi.Kondaka@Sun.COM 	}
1272264Sjacobs 
1282264Sjacobs 	/* is there an lpsched queue (printer/class) */
1292264Sjacobs 	snprintf(buf, sizeof (buf), "/etc/lp/interfaces/%s", printer);
1302264Sjacobs 	snprintf(buf2, sizeof (buf2), "/etc/lp/classes/%s", printer);
1317322SWendy.Phillips@Sun.COM 	if ((access(buf, F_OK) < 0) && (access(buf2, F_OK) < 0)) {
1327322SWendy.Phillips@Sun.COM 		uri_free(uri);
1332264Sjacobs 		return;
1347322SWendy.Phillips@Sun.COM 	}
1352264Sjacobs 
1362313Sjacobs 	/* is this the "local" host */
1377322SWendy.Phillips@Sun.COM 	if ((uri->host != NULL) && (is_localhost(uri->host) == 0)) {
1387322SWendy.Phillips@Sun.COM 		uri_free(uri);
1392313Sjacobs 		return;
1407322SWendy.Phillips@Sun.COM 	}
1412313Sjacobs 
1422313Sjacobs 	snprintf(buf, sizeof (buf), "lpsched://%s/printers/%s",
1432313Sjacobs 			(uri->host ? uri->host : "localhost"), printer);
1442264Sjacobs 	papiAttributeListAddString(list, PAPI_ATTR_REPLACE,
1452264Sjacobs 			"printer-uri-supported", buf);
1467322SWendy.Phillips@Sun.COM 	uri_free(uri);
1472264Sjacobs }
1482264Sjacobs #endif
1492264Sjacobs 
1502264Sjacobs static void
1512264Sjacobs fill_printer_uri_supported(papi_attribute_t ***list)
1522264Sjacobs {
1532264Sjacobs 	papi_attribute_t *attribute;
1542264Sjacobs 	char *string = NULL;
1552264Sjacobs 
1562264Sjacobs 	/* do we have a printer-uri-supported */
1572264Sjacobs 	attribute = papiAttributeListFind(*list, "printer-uri-supported");
1582264Sjacobs 	if (attribute != NULL) /* we have what we need, return */
1592264Sjacobs 		return;
1602264Sjacobs 
1616817Sjacobs 	/* do we have a printer-uri (in URI form) to rename */
1622264Sjacobs 	attribute = papiAttributeListFind(*list, "printer-uri");
1636817Sjacobs 	if ((attribute != NULL) &&
1646817Sjacobs 	    (attribute->type == PAPI_STRING) &&
1656817Sjacobs 	    (attribute->values != NULL) &&
1666817Sjacobs 	    (attribute->values[0]->string != NULL) &&
1676817Sjacobs 	    (strstr(attribute->values[0]->string, "://") != NULL)) {
1686817Sjacobs 			/* rename it in place and return */
1692264Sjacobs 		free(attribute->name);
1702264Sjacobs 		attribute->name = strdup("printer-uri-supported");
1712264Sjacobs 		return;
1722264Sjacobs 	}
1732264Sjacobs 
1742264Sjacobs 	/* do we have a printers.conf(4) "bsdaddr" to convert */
1752264Sjacobs 	papiAttributeListGetString(*list, NULL, "bsdaddr", &string);
1762264Sjacobs 	if (string != NULL) { /* parse it, convert it, add it */
1772409Sjacobs 		char *uri = bsdaddr_to_uri(*list, string);
1782264Sjacobs 
1792264Sjacobs 		if (uri != NULL) {
1802264Sjacobs 			papiAttributeListAddString(list, PAPI_ATTR_APPEND,
1812264Sjacobs 					"printer-uri-supported", uri);
1822264Sjacobs 			papiAttributeListDelete(list, "bsdaddr");
1832264Sjacobs 			free(uri);
1842264Sjacobs 			return;
1852264Sjacobs 		}
1862264Sjacobs 	}
1872264Sjacobs 
1882264Sjacobs 	/* do we have a printers.conf(4) "rm" (and "rp") to convert */
1892264Sjacobs 	papiAttributeListGetString(*list, NULL, "rm", &string);
1902264Sjacobs 	if (string != NULL) {
1912264Sjacobs 		char *rp = NULL;
1922264Sjacobs 
1932264Sjacobs 		/* default to "printer-name", but use "rp" if we have it */
1942264Sjacobs 		papiAttributeListGetString(*list, NULL, "printer-name", &rp);
1952264Sjacobs 		papiAttributeListGetString(*list, NULL, "rp", &rp);
1962264Sjacobs 
1972264Sjacobs 		if (rp != NULL) { /* fill in the uri if we have the data */
1982264Sjacobs 			char buf[BUFSIZ];
1992264Sjacobs 
2002264Sjacobs 			snprintf(buf, sizeof (buf), "lpd://%s/printers/%s",
2012264Sjacobs 				string, rp);
2022264Sjacobs 			papiAttributeListAddString(list, PAPI_ATTR_APPEND,
2032264Sjacobs 					"printer-uri-supported", strdup(buf));
2042264Sjacobs 			return;
2052264Sjacobs 		}
2062264Sjacobs 	}
2072264Sjacobs 
2082264Sjacobs 	/* if were are here, we don't have a printer-uri-supported */
2092264Sjacobs }
2102264Sjacobs 
2112264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
2122264Sjacobs static void
2132264Sjacobs fill_printer_uri(papi_attribute_t ***list)
2142264Sjacobs {
2152264Sjacobs 	papi_attribute_t *attribute;
2162264Sjacobs 	char *uri = NULL;
2172264Sjacobs 
2182264Sjacobs 	if ((list == NULL) || (*list == NULL))
2192264Sjacobs 		return;
2202264Sjacobs 
2212313Sjacobs 	/* do we have a printer-uri */
2222264Sjacobs 	attribute = papiAttributeListFind(*list, "printer-uri");
2232264Sjacobs 	if (attribute != NULL) /* we have what we need, return */
2242264Sjacobs 		return;
2252264Sjacobs 
2262264Sjacobs 	/*
2272264Sjacobs 	 * this is sufficient to fool libgnomeprintpapi, but not promote it's
2282264Sjacobs 	 * use in the future.
2292264Sjacobs 	 */
2302264Sjacobs 	papiAttributeListAddString(list, PAPI_ATTR_EXCL, "printer-uri",
2312264Sjacobs 			"broken printer-uri semantic");
2322264Sjacobs }
2332264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
2342264Sjacobs 
2352264Sjacobs static void
2362264Sjacobs cvt_all_to_member_names(papi_attribute_t ***list)
2372264Sjacobs {
2382264Sjacobs 	papi_status_t status;
2392264Sjacobs 	void *iter = NULL;
2402264Sjacobs 	char *string = NULL;
2412264Sjacobs 
2422264Sjacobs 	papiAttributeListGetString(*list, NULL, "member-names", &string);
2432264Sjacobs 	if (string != NULL) /* already have a member-names */
2442264Sjacobs 		return;
2452264Sjacobs 
2462264Sjacobs 	for (status = papiAttributeListGetString(*list, &iter, "all", &string);
2477322SWendy.Phillips@Sun.COM 	    status == PAPI_OK;
2487322SWendy.Phillips@Sun.COM 	    status = papiAttributeListGetString(*list, &iter, NULL, &string)) {
2492264Sjacobs 		char *s_iter = NULL, *value, *tmp = strdup(string);
2502264Sjacobs 
2512264Sjacobs 		for (value = strtok_r(tmp, ", \t", &s_iter);
2527322SWendy.Phillips@Sun.COM 		    value != NULL;
2537322SWendy.Phillips@Sun.COM 		    value = strtok_r(NULL, ", \t", &s_iter))
2542264Sjacobs 			papiAttributeListAddString(list, PAPI_ATTR_APPEND,
2552264Sjacobs 					"member-names", value);
2562264Sjacobs 		free(tmp);
2572264Sjacobs 	}
2582264Sjacobs }
2592264Sjacobs 
2602264Sjacobs static papi_attribute_t **
2612264Sjacobs _cvt_nss_entry_to_printer(char *entry)
2622264Sjacobs {
2632264Sjacobs 	char    *key = NULL,
2642264Sjacobs 		*cp,
2652264Sjacobs 		buf[BUFSIZ];
2662264Sjacobs 	int in_namelist = 1, buf_pos = 0;
2672264Sjacobs 	papi_attribute_t **list = NULL;
2682264Sjacobs 
2692264Sjacobs 	if (entry == NULL)
2702264Sjacobs 		return (NULL);
2712264Sjacobs 
2722264Sjacobs 	memset(buf, 0, sizeof (buf));
2732264Sjacobs 	for (cp = entry; *cp != '\0'; cp++) {
2742264Sjacobs 		switch (*cp) {
2752264Sjacobs 		case ':':	/* end of kvp */
2762264Sjacobs 			if (in_namelist != 0) {
2772264Sjacobs 				papiAttributeListAddString(&list,
2782264Sjacobs 					PAPI_ATTR_APPEND, "printer-name", buf);
2792264Sjacobs 				in_namelist = 0;
2807322SWendy.Phillips@Sun.COM 			} else if (key != NULL) {
2812264Sjacobs 				papiAttributeListAddString(&list,
2822264Sjacobs 					PAPI_ATTR_APPEND, key, buf);
2837322SWendy.Phillips@Sun.COM 				free(key);
2847322SWendy.Phillips@Sun.COM 			}
2852264Sjacobs 			memset(buf, 0, sizeof (buf));
2862264Sjacobs 			buf_pos = 0;
2872264Sjacobs 			key = NULL;
2882264Sjacobs 			break;
2892264Sjacobs 		case '=':	/* kvp seperator */
2902264Sjacobs 			if (key == NULL) {
2912264Sjacobs 				key = strdup(buf);
2922264Sjacobs 				memset(buf, 0, sizeof (buf));
2932264Sjacobs 				buf_pos = 0;
2942264Sjacobs 			} else
2952264Sjacobs 				buf[buf_pos++] = *cp;
2962264Sjacobs 			break;
2972264Sjacobs 		case '|':	/* namelist seperator */
2982264Sjacobs 			if (in_namelist != 0) {
2992264Sjacobs 				papiAttributeListAddString(&list,
3002264Sjacobs 					PAPI_ATTR_APPEND, "printer-name", buf);
3012264Sjacobs 				memset(buf, 0, sizeof (buf));
3022264Sjacobs 				buf_pos = 0;
3032264Sjacobs 			} else	/* add it to the buffer */
3042264Sjacobs 				buf[buf_pos++] = *cp;
3052264Sjacobs 			break;
3062264Sjacobs 		case '\\':	/* escape char */
3072264Sjacobs 			buf[buf_pos++] = *(++cp);
3082264Sjacobs 			break;
3092264Sjacobs 		default:
3102264Sjacobs 			buf[buf_pos++] = *cp;
3112264Sjacobs 		}
3122264Sjacobs 
3132264Sjacobs 	}
3142264Sjacobs 
3157322SWendy.Phillips@Sun.COM 	if (key != NULL) {
3162264Sjacobs 		papiAttributeListAddString(&list, PAPI_ATTR_APPEND, key, buf);
3177322SWendy.Phillips@Sun.COM 		free(key);
3187322SWendy.Phillips@Sun.COM 	}
3192264Sjacobs 
3202264Sjacobs 	/* resolve any "use" references in the configuration DB */
3212264Sjacobs 	key = NULL;
3222264Sjacobs 	papiAttributeListGetString(list, NULL, "use", &key);
3232264Sjacobs 	if (key != NULL) {
3242264Sjacobs 		papi_attribute_t **use_attrs = getprinterbyname(key, NULL);
3252264Sjacobs 
3262264Sjacobs 		list_concatenate(&list, use_attrs);
3272264Sjacobs 	}
3282264Sjacobs 
3292264Sjacobs 	fill_printer_uri_supported(&list);
3302264Sjacobs 	cvt_all_to_member_names(&list); /* convert "all" to "member-names" */
3312264Sjacobs 
3322264Sjacobs 	return (list);
3332264Sjacobs }
3342264Sjacobs 
3352264Sjacobs #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION)
3362264Sjacobs 
3372264Sjacobs #ifndef	NSS_DBNAM__PRINTERS	/* not in nss_dbdefs.h because it's private */
3382264Sjacobs #define	NSS_DBNAM__PRINTERS	"_printers"
3392264Sjacobs #endif
3402264Sjacobs 
3412264Sjacobs static DEFINE_NSS_DB_ROOT(db_root);
3422264Sjacobs static DEFINE_NSS_GETENT(context);
3432264Sjacobs 
3442264Sjacobs static char *private_ns = NULL;
3452264Sjacobs 
3462264Sjacobs static void
3472264Sjacobs _nss_initf_printers(p)
3482264Sjacobs     nss_db_params_t *p;
3492264Sjacobs {
3502264Sjacobs 	if (private_ns != NULL) {
3512264Sjacobs 		/*
3522264Sjacobs 		 * because we need to support a legacy interface that allows
3532264Sjacobs 		 * us to select a specific name service, we need to dummy up
3542264Sjacobs 		 * the parameters to use a private nsswitch database and set
3552264Sjacobs 		 * the * default_config entry to the name service we are
3562264Sjacobs 		 * looking into.
3572264Sjacobs 		 */
3582264Sjacobs 		p->name = NSS_DBNAM__PRINTERS;		/* "_printers" */
3592264Sjacobs 		p->default_config = private_ns;
3602847Sjacobs 	} else {
3612264Sjacobs 		/* regular behaviour */
3622264Sjacobs 		p->name = NSS_DBNAM_PRINTERS;	 /* "printers" */
3632264Sjacobs 		p->default_config = NSS_DEFCONF_PRINTERS;
3642264Sjacobs 	}
3652847Sjacobs 	syslog(LOG_DEBUG, "database: %s, default: %s",
3662264Sjacobs 		(p->name ? p->name : "NULL"),
3672264Sjacobs 		(p->default_config ? p->default_config : "NULL"));
3682264Sjacobs }
3692264Sjacobs 
3702264Sjacobs /*
3712264Sjacobs  * Return values: 0 = success, 1 = parse error, 2 = erange ...
3722264Sjacobs  * The structure pointer passed in is a structure in the caller's space
3732264Sjacobs  * wherein the field pointers would be set to areas in the buffer if
3742264Sjacobs  * need be. instring and buffer should be separate areas.
3752264Sjacobs  */
3762264Sjacobs /* ARGSUSED */
3772264Sjacobs static int
3782264Sjacobs str2printer(const char *instr, int lenstr, void *ent, char *buffer, int buflen)
3792264Sjacobs {
3802264Sjacobs 	if (lenstr + 1 > buflen)
3812264Sjacobs 		return (NSS_STR_PARSE_ERANGE);
3822571Sjacobs 
3832571Sjacobs 	/* skip entries that begin with '#' */
3842571Sjacobs 	if (instr[0] == '#')
3852571Sjacobs 		return (NSS_STR_PARSE_PARSE);
3862571Sjacobs 
3872264Sjacobs 	/*
3882264Sjacobs 	 * We copy the input string into the output buffer
3892264Sjacobs 	 */
3902264Sjacobs 	(void) memcpy(buffer, instr, lenstr);
3912264Sjacobs 	buffer[lenstr] = '\0';
3922264Sjacobs 
3932264Sjacobs 	return (NSS_STR_PARSE_SUCCESS);
3942264Sjacobs }
3952264Sjacobs #endif /* NSS_SOLARIS */
3962264Sjacobs 
3972264Sjacobs int
3982264Sjacobs setprinterentry(int stayopen, char *ns)
3992264Sjacobs {
4002264Sjacobs #ifdef NSS_EMULATION
4012264Sjacobs 	emul_setprinterentry(stayopen);
4022264Sjacobs #elif NSS_SOLARIS
4032264Sjacobs 	private_ns = ns;
4042264Sjacobs 	nss_setent(&db_root, _nss_initf_printers, &context);
4052847Sjacobs 	private_ns = NULL;
4062264Sjacobs #endif
4072264Sjacobs 	return (0);
4082264Sjacobs }
4092264Sjacobs 
4102264Sjacobs 
4112264Sjacobs int
4122264Sjacobs endprinterentry(int i)
4132264Sjacobs {
4142264Sjacobs #ifdef NSS_EMULATION
4152264Sjacobs 	emul_endprinterentry();
4162264Sjacobs #elif NSS_SOLARIS
4172264Sjacobs 	nss_endent(&db_root, _nss_initf_printers, &context);
4182264Sjacobs 	nss_delete(&db_root);
4192847Sjacobs 	private_ns = NULL;
4202264Sjacobs #endif
4212264Sjacobs 	return (0);
4222264Sjacobs }
4232264Sjacobs 
4242264Sjacobs /* ARGSUSED2 */
4252264Sjacobs papi_attribute_t **
4262264Sjacobs getprinterentry(char *ns)
4272264Sjacobs {
4282264Sjacobs 	papi_attribute_t **result = NULL;
4292264Sjacobs 
4302264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
4312264Sjacobs 	char buf[10240];
4322264Sjacobs 	nss_status_t	res = NSS_NOTFOUND;
4332264Sjacobs 
4342264Sjacobs #ifdef NSS_EMULATION
4352264Sjacobs 	res = emul_getprinterentry_r(buf, sizeof (buf));
4362264Sjacobs #elif NSS_SOLARIS
4372264Sjacobs 	nss_XbyY_args_t arg;
4382264Sjacobs 
4392847Sjacobs 	private_ns = ns;
4402264Sjacobs 	NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer);
4412264Sjacobs 	res = nss_getent(&db_root, _nss_initf_printers, &context, &arg);
4422264Sjacobs 	(void) NSS_XbyY_FINI(&arg);
4432847Sjacobs 	private_ns = NULL;
4442264Sjacobs #endif
4452264Sjacobs 
4462264Sjacobs 	if (res != NSS_SUCCESS)
4472264Sjacobs 		buf[0] = '\0';
4482264Sjacobs 
4492264Sjacobs 	result = _cvt_nss_entry_to_printer(buf);
4502313Sjacobs #if defined(__sun) && defined(__SVR4)
4512313Sjacobs 	solaris_lpsched_shortcircuit_hack(&result);
4522313Sjacobs #endif
4532264Sjacobs #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
4542264Sjacobs 	fill_printer_uri(&result);
4552264Sjacobs #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
4562264Sjacobs #endif
4572264Sjacobs 
4582264Sjacobs #ifdef DEBUG
4592264Sjacobs 	printf("getprinterentry(%s): 0x%8.8x\n", (ns ? ns : "NULL"), result);
4602264Sjacobs 	if (result != NULL) {
4612264Sjacobs 		char buf[4096];
4622264Sjacobs 
4632264Sjacobs 		papiAttributeListToString(result, "\n\t", buf, sizeof (buf));
4642264Sjacobs 		printf("\t%s\n", buf);
4652264Sjacobs 	}
4662264Sjacobs #endif /* DEBUG */
4672264Sjacobs 
4682264Sjacobs 	return (result);
4692264Sjacobs }
4702264Sjacobs 
4712264Sjacobs 
4722264Sjacobs papi_attribute_t **
4732264Sjacobs getprinterbyname(char *name, char *ns)
4742264Sjacobs {
4752264Sjacobs 	papi_attribute_t **result = NULL;
4762264Sjacobs 
4772264Sjacobs 	if (strstr(name, "://") != NULL) {	/* shortcut for URI form */
4782264Sjacobs 		papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
4792264Sjacobs 				"printer-name", name);
4802264Sjacobs 		papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
4812264Sjacobs 				"printer-uri-supported", name);
4822264Sjacobs 	} else if (strchr(name, ':') != NULL) {	/* shortcut for POSIX form */
4832409Sjacobs 		char *uri = bsdaddr_to_uri(result, name);
4842264Sjacobs 
4852264Sjacobs 		papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
4862264Sjacobs 				"printer-name", name);
4872264Sjacobs 		if (uri != NULL) {
4882264Sjacobs 			papiAttributeListAddString(&result, PAPI_ATTR_APPEND,
4892264Sjacobs 					"printer-uri-supported", uri);
4902264Sjacobs 			free(uri);
4912264Sjacobs 		}
4922264Sjacobs 	} else {				/* anything else */
4932264Sjacobs #if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
4942264Sjacobs 		char buf[10240];
4952264Sjacobs 		nss_status_t	res = NSS_NOTFOUND;
4962264Sjacobs 
4972264Sjacobs #ifdef NSS_EMULATION
4982264Sjacobs 		res = emul_getprinterbyname_r(name, buf, sizeof (buf));
4992264Sjacobs #elif NSS_SOLARIS
5002264Sjacobs 		nss_XbyY_args_t arg;
5012264Sjacobs 
5022264Sjacobs 		private_ns = ns;
5032264Sjacobs 		NSS_XbyY_INIT(&arg, buf, buf, sizeof (buf), str2printer);
5042264Sjacobs 		arg.key.name = name;
5052264Sjacobs 		res = nss_search(&db_root, _nss_initf_printers,
5062264Sjacobs 				NSS_DBOP_PRINTERS_BYNAME, &arg);
5072264Sjacobs 		(void) NSS_XbyY_FINI(&arg);
5082847Sjacobs 		private_ns = NULL;
5092264Sjacobs 
5102264Sjacobs 		if (res != NSS_SUCCESS)
5112264Sjacobs 			buf[0] = '\0';
5122264Sjacobs #endif
5132264Sjacobs 
5142264Sjacobs 		result = _cvt_nss_entry_to_printer(buf);
5152264Sjacobs #endif
5162264Sjacobs 	}
5172313Sjacobs #if defined(__sun) && defined(__SVR4)
5182313Sjacobs 	solaris_lpsched_shortcircuit_hack(&result);
5192313Sjacobs #endif
5202264Sjacobs #ifdef DEBUG
5212264Sjacobs 	printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns ? ns : "NULL"),
5222264Sjacobs 		name, result);
5232264Sjacobs 	if (result != NULL) {
5242264Sjacobs 		char buf[4096];
5252264Sjacobs 
5262264Sjacobs 		papiAttributeListToString(result, "\n\t", buf, sizeof (buf));
5272264Sjacobs 		printf("\t%s\n", buf);
5282264Sjacobs 	}
5292264Sjacobs #endif /* DEBUG */
5302264Sjacobs 
5312264Sjacobs 	return (result);
5322264Sjacobs }
533