4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
27 /* Id: nss.c 180 2006-07-20 17:33:02Z njacobs $ */
34 #include <sys/types.h>
38 #include <papi_impl.h>
40 #include <nss-emulation.h>
42 #include <nss_dbdefs.h>
44 #include <config-site.h>
45 #if defined(__sun) && defined(__SVR4)
46 #include <sys/systeminfo.h>
51 bsdaddr_to_uri(papi_attribute_t
**list
, char *bsdaddr
)
55 if (bsdaddr
!= NULL
) {
56 char *bsd
[3], *tmp
, *iter
= NULL
;
59 tmp
= strdup(bsdaddr
);
61 bsd
[0] = strtok_r(tmp
, ":,", &iter
);
62 if ((bsd
[1] = strtok_r(NULL
, ":,", &iter
)) == NULL
)
63 papiAttributeListGetString(list
, NULL
,
64 "printer-name", &bsd
[1]);
65 bsd
[2] = strtok_r(NULL
, ":,", &iter
);
67 snprintf(buf
, sizeof (buf
), "lpd://%s/printers/%s%s%s", bsd
[0],
68 (bsd
[1] != NULL
) ? bsd
[1] : "",
69 (bsd
[2] != NULL
) ? "#" : "",
70 (bsd
[2] != NULL
) ? bsd
[2] : "");
80 #if defined(__sun) && defined(__SVR4)
82 * This is an awful HACK to force the dynamic PAPI library to use the
83 * lpsched support when the destination apears to be a local lpsched
87 solaris_lpsched_shortcircuit_hack(papi_attribute_t
***list
)
89 papi_attribute_t
*attribute
;
92 char buf
[128], buf2
[128];
94 /* setting this in the calling env can be useful for debugging */
95 if (getenv("DISABLE_LPSCHED_SHORTCIRCUIT") != NULL
)
98 papiAttributeListGetString(*list
, NULL
,
99 "printer-uri-supported", &printer
);
100 /* if there is no printer-uri-supported, there is nothing to do */
101 if (printer
== NULL
) {
105 if (uri_from_string(printer
, &uri
) < 0) {
106 papiAttributeListFree(*list
);
112 /* already an lpsched URI ? */
113 if (strcasecmp(uri
->scheme
, "lpsched") == 0) {
118 if (uri
->path
== NULL
) {
121 if ((printer
= strrchr(uri
->path
, '/')) == NULL
)
127 /* is there an lpsched queue (printer/class) */
128 snprintf(buf
, sizeof (buf
), "/etc/lp/interfaces/%s", printer
);
129 snprintf(buf2
, sizeof (buf2
), "/etc/lp/classes/%s", printer
);
130 if ((access(buf
, F_OK
) < 0) && (access(buf2
, F_OK
) < 0)) {
135 /* is this the "local" host */
136 if ((uri
->host
!= NULL
) && (is_localhost(uri
->host
) == 0)) {
141 snprintf(buf
, sizeof (buf
), "lpsched://%s/printers/%s",
142 (uri
->host
? uri
->host
: "localhost"), printer
);
143 papiAttributeListAddString(list
, PAPI_ATTR_REPLACE
,
144 "printer-uri-supported", buf
);
150 fill_printer_uri_supported(papi_attribute_t
***list
)
152 papi_attribute_t
*attribute
;
155 /* do we have a printer-uri-supported */
156 attribute
= papiAttributeListFind(*list
, "printer-uri-supported");
157 if (attribute
!= NULL
) /* we have what we need, return */
160 /* do we have a printer-uri (in URI form) to rename */
161 attribute
= papiAttributeListFind(*list
, "printer-uri");
162 if ((attribute
!= NULL
) &&
163 (attribute
->type
== PAPI_STRING
) &&
164 (attribute
->values
!= NULL
) &&
165 (attribute
->values
[0]->string
!= NULL
) &&
166 (strstr(attribute
->values
[0]->string
, "://") != NULL
)) {
167 /* rename it in place and return */
168 free(attribute
->name
);
169 attribute
->name
= strdup("printer-uri-supported");
173 /* do we have a printers.conf(4) "bsdaddr" to convert */
174 papiAttributeListGetString(*list
, NULL
, "bsdaddr", &string
);
175 if (string
!= NULL
) { /* parse it, convert it, add it */
176 char *uri
= bsdaddr_to_uri(*list
, string
);
179 papiAttributeListAddString(list
, PAPI_ATTR_APPEND
,
180 "printer-uri-supported", uri
);
181 papiAttributeListDelete(list
, "bsdaddr");
187 /* do we have a printers.conf(4) "rm" (and "rp") to convert */
188 papiAttributeListGetString(*list
, NULL
, "rm", &string
);
189 if (string
!= NULL
) {
192 /* default to "printer-name", but use "rp" if we have it */
193 papiAttributeListGetString(*list
, NULL
, "printer-name", &rp
);
194 papiAttributeListGetString(*list
, NULL
, "rp", &rp
);
196 if (rp
!= NULL
) { /* fill in the uri if we have the data */
199 snprintf(buf
, sizeof (buf
), "lpd://%s/printers/%s",
201 papiAttributeListAddString(list
, PAPI_ATTR_APPEND
,
202 "printer-uri-supported", strdup(buf
));
207 /* if were are here, we don't have a printer-uri-supported */
210 #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
212 fill_printer_uri(papi_attribute_t
***list
)
214 papi_attribute_t
*attribute
;
217 if ((list
== NULL
) || (*list
== NULL
))
220 /* do we have a printer-uri */
221 attribute
= papiAttributeListFind(*list
, "printer-uri");
222 if (attribute
!= NULL
) /* we have what we need, return */
226 * this is sufficient to fool libgnomeprintpapi, but not promote it's
229 papiAttributeListAddString(list
, PAPI_ATTR_EXCL
, "printer-uri",
230 "broken printer-uri semantic");
232 #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
235 cvt_all_to_member_names(papi_attribute_t
***list
)
237 papi_status_t status
;
241 papiAttributeListGetString(*list
, NULL
, "member-names", &string
);
242 if (string
!= NULL
) /* already have a member-names */
245 for (status
= papiAttributeListGetString(*list
, &iter
, "all", &string
);
247 status
= papiAttributeListGetString(*list
, &iter
, NULL
, &string
)) {
248 char *s_iter
= NULL
, *value
, *tmp
= strdup(string
);
250 for (value
= strtok_r(tmp
, ", \t", &s_iter
);
252 value
= strtok_r(NULL
, ", \t", &s_iter
))
253 papiAttributeListAddString(list
, PAPI_ATTR_APPEND
,
254 "member-names", value
);
259 static papi_attribute_t
**
260 _cvt_nss_entry_to_printer(char *entry
)
265 int in_namelist
= 1, buf_pos
= 0;
266 papi_attribute_t
**list
= NULL
;
271 memset(buf
, 0, sizeof (buf
));
272 for (cp
= entry
; *cp
!= '\0'; cp
++) {
274 case ':': /* end of kvp */
275 if (in_namelist
!= 0) {
276 papiAttributeListAddString(&list
,
277 PAPI_ATTR_APPEND
, "printer-name", buf
);
279 } else if (key
!= NULL
) {
280 papiAttributeListAddString(&list
,
281 PAPI_ATTR_APPEND
, key
, buf
);
284 memset(buf
, 0, sizeof (buf
));
288 case '=': /* kvp seperator */
291 memset(buf
, 0, sizeof (buf
));
294 buf
[buf_pos
++] = *cp
;
296 case '|': /* namelist seperator */
297 if (in_namelist
!= 0) {
298 papiAttributeListAddString(&list
,
299 PAPI_ATTR_APPEND
, "printer-name", buf
);
300 memset(buf
, 0, sizeof (buf
));
302 } else /* add it to the buffer */
303 buf
[buf_pos
++] = *cp
;
305 case '\\': /* escape char */
306 buf
[buf_pos
++] = *(++cp
);
309 buf
[buf_pos
++] = *cp
;
315 papiAttributeListAddString(&list
, PAPI_ATTR_APPEND
, key
, buf
);
319 /* resolve any "use" references in the configuration DB */
321 papiAttributeListGetString(list
, NULL
, "use", &key
);
323 papi_attribute_t
**use_attrs
= getprinterbyname(key
, NULL
);
325 list_concatenate(&list
, use_attrs
);
328 fill_printer_uri_supported(&list
);
329 cvt_all_to_member_names(&list
); /* convert "all" to "member-names" */
334 #if defined(NSS_SOLARIS) && !defined(NSS_EMULATION)
336 #ifndef NSS_DBNAM__PRINTERS /* not in nss_dbdefs.h because it's private */
337 #define NSS_DBNAM__PRINTERS "_printers"
340 static DEFINE_NSS_DB_ROOT(db_root
);
341 static DEFINE_NSS_GETENT(context
);
343 static char *private_ns
= NULL
;
346 _nss_initf_printers(p
)
349 if (private_ns
!= NULL
) {
351 * because we need to support a legacy interface that allows
352 * us to select a specific name service, we need to dummy up
353 * the parameters to use a private nsswitch database and set
354 * the * default_config entry to the name service we are
357 p
->name
= NSS_DBNAM__PRINTERS
; /* "_printers" */
358 p
->default_config
= private_ns
;
360 /* regular behaviour */
361 p
->name
= NSS_DBNAM_PRINTERS
; /* "printers" */
362 p
->default_config
= NSS_DEFCONF_PRINTERS
;
364 syslog(LOG_DEBUG
, "database: %s, default: %s",
365 (p
->name
? p
->name
: "NULL"),
366 (p
->default_config
? p
->default_config
: "NULL"));
370 * Return values: 0 = success, 1 = parse error, 2 = erange ...
371 * The structure pointer passed in is a structure in the caller's space
372 * wherein the field pointers would be set to areas in the buffer if
373 * need be. instring and buffer should be separate areas.
377 str2printer(const char *instr
, int lenstr
, void *ent
, char *buffer
, int buflen
)
379 if (lenstr
+ 1 > buflen
)
380 return (NSS_STR_PARSE_ERANGE
);
382 /* skip entries that begin with '#' */
384 return (NSS_STR_PARSE_PARSE
);
387 * We copy the input string into the output buffer
389 (void) memcpy(buffer
, instr
, lenstr
);
390 buffer
[lenstr
] = '\0';
392 return (NSS_STR_PARSE_SUCCESS
);
394 #endif /* NSS_SOLARIS */
397 setprinterentry(int stayopen
, char *ns
)
400 emul_setprinterentry(stayopen
);
403 nss_setent(&db_root
, _nss_initf_printers
, &context
);
411 endprinterentry(int i
)
414 emul_endprinterentry();
416 nss_endent(&db_root
, _nss_initf_printers
, &context
);
417 nss_delete(&db_root
);
425 getprinterentry(char *ns
)
427 papi_attribute_t
**result
= NULL
;
429 #if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
431 nss_status_t res
= NSS_NOTFOUND
;
434 res
= emul_getprinterentry_r(buf
, sizeof (buf
));
440 NSS_XbyY_INIT(&arg
, buf
, buf
, sizeof (buf
), str2printer
);
441 res
= nss_getent(&db_root
, _nss_initf_printers
, &context
, &arg
);
442 (void) NSS_XbyY_FINI(&arg
);
446 if (res
!= NSS_SUCCESS
)
449 result
= _cvt_nss_entry_to_printer(buf
);
450 #if defined(__sun) && defined(__SVR4)
451 solaris_lpsched_shortcircuit_hack(&result
);
453 #ifdef NEED_BROKEN_PRINTER_URI_SEMANTIC
454 fill_printer_uri(&result
);
455 #endif /* NEED_BROKEN_PRINTER_URI_SEMANTIC */
459 printf("getprinterentry(%s): 0x%8.8x\n", (ns
? ns
: "NULL"), result
);
460 if (result
!= NULL
) {
463 papiAttributeListToString(result
, "\n\t", buf
, sizeof (buf
));
464 printf("\t%s\n", buf
);
473 getprinterbyname(char *name
, char *ns
)
475 papi_attribute_t
**result
= NULL
;
477 if (strstr(name
, "://") != NULL
) { /* shortcut for URI form */
478 papiAttributeListAddString(&result
, PAPI_ATTR_APPEND
,
479 "printer-name", name
);
480 papiAttributeListAddString(&result
, PAPI_ATTR_APPEND
,
481 "printer-uri-supported", name
);
482 } else if (strchr(name
, ':') != NULL
) { /* shortcut for POSIX form */
483 char *uri
= bsdaddr_to_uri(result
, name
);
485 papiAttributeListAddString(&result
, PAPI_ATTR_APPEND
,
486 "printer-name", name
);
488 papiAttributeListAddString(&result
, PAPI_ATTR_APPEND
,
489 "printer-uri-supported", uri
);
492 } else { /* anything else */
493 #if defined(NSS_EMULATION) || defined(NSS_SOLARIS)
495 nss_status_t res
= NSS_NOTFOUND
;
498 res
= emul_getprinterbyname_r(name
, buf
, sizeof (buf
));
503 NSS_XbyY_INIT(&arg
, buf
, buf
, sizeof (buf
), str2printer
);
505 res
= nss_search(&db_root
, _nss_initf_printers
,
506 NSS_DBOP_PRINTERS_BYNAME
, &arg
);
507 (void) NSS_XbyY_FINI(&arg
);
510 if (res
!= NSS_SUCCESS
)
514 result
= _cvt_nss_entry_to_printer(buf
);
517 #if defined(__sun) && defined(__SVR4)
518 solaris_lpsched_shortcircuit_hack(&result
);
521 printf("getprinterbyname(%s): %s = 0x%8.8x\n", (ns
? ns
: "NULL"),
523 if (result
!= NULL
) {
526 papiAttributeListToString(result
, "\n\t", buf
, sizeof (buf
));
527 printf("\t%s\n", buf
);