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: printer.c 151 2006-04-25 16:55:34Z njacobs $ */ 292264Sjacobs 302264Sjacobs #pragma ident "%Z%%M% %I% %E% SMI" 312264Sjacobs 322264Sjacobs /*LINTLIBRARY*/ 332264Sjacobs 342264Sjacobs #include <stdlib.h> 352264Sjacobs #include <papi_impl.h> 362264Sjacobs 372264Sjacobs void 382264Sjacobs papiPrinterFree(papi_printer_t printer) 392264Sjacobs { 402264Sjacobs printer_t *tmp = printer; 412264Sjacobs 422264Sjacobs if (tmp != NULL) { 432264Sjacobs void (*f)(); 442264Sjacobs 452264Sjacobs f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree"); 462264Sjacobs if (f != NULL) 472264Sjacobs f(tmp->printer); 482264Sjacobs if (tmp->attributes != NULL) 492264Sjacobs papiAttributeListFree(tmp->attributes); 502264Sjacobs if (tmp->svc_is_internal != 0) 512264Sjacobs papiServiceDestroy(tmp->svc); 522264Sjacobs free(tmp); 532264Sjacobs } 542264Sjacobs } 552264Sjacobs 562264Sjacobs void 572264Sjacobs papiPrinterListFree(papi_printer_t *printers) 582264Sjacobs { 592264Sjacobs if (printers != NULL) { 602264Sjacobs int i; 612264Sjacobs 622264Sjacobs for (i = 0; printers[i] != NULL; i++) 632264Sjacobs papiPrinterFree(printers[i]); 642264Sjacobs free(printers); 652264Sjacobs } 662264Sjacobs } 672264Sjacobs 682264Sjacobs /* Enumerate a list of printers from the loaded print service. */ 692264Sjacobs static papi_status_t 702264Sjacobs printers_from_service(service_t *svc, char **requested_attrs, 712264Sjacobs papi_filter_t *filter, papi_printer_t **printers) 722264Sjacobs { 732264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 742264Sjacobs papi_printer_t *svc_printers = NULL; 752264Sjacobs papi_status_t (*f)(); 762264Sjacobs 772264Sjacobs if ((svc == NULL) || (printers == NULL)) 782264Sjacobs return (PAPI_BAD_ARGUMENT); 792264Sjacobs 802264Sjacobs /* connect to the service if we are not connected */ 812264Sjacobs if ((result = service_connect(svc, svc->name)) != PAPI_OK) 822264Sjacobs return (result); 832264Sjacobs 842264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList"); 852264Sjacobs if (f != NULL) 862264Sjacobs result = f(svc->svc_handle, requested_attrs, filter, 872264Sjacobs &svc_printers); 882264Sjacobs 892264Sjacobs /* 902264Sjacobs * copy the resulting printer object pointers into our own 912264Sjacobs * representation of a printer object because we need the 922264Sjacobs * service context to operate against the individual printer 932264Sjacobs * objects. We free the list now because we no longer need 942264Sjacobs * it and would have no way of freeing it later. 952264Sjacobs */ 962264Sjacobs if ((result == PAPI_OK) && (svc_printers != NULL)) { 972264Sjacobs int i; 982264Sjacobs 992264Sjacobs *printers = NULL; 1002264Sjacobs for (i = 0; svc_printers[i] != NULL; i++) { 1012264Sjacobs printer_t *p = NULL; 1022264Sjacobs 1032264Sjacobs if ((p = calloc(1, sizeof (*p))) == NULL) 1042264Sjacobs return (PAPI_TEMPORARY_ERROR); 1052264Sjacobs 1062264Sjacobs p->svc = svc; 1072264Sjacobs p->printer = svc_printers[i]; 1082264Sjacobs list_append(printers, p); 1092264Sjacobs } 1102264Sjacobs free(svc_printers); 1112264Sjacobs } 1122264Sjacobs 1132264Sjacobs return (result); 1142264Sjacobs } 1152264Sjacobs 1162264Sjacobs /* Get printer attributes from it's print service */ 1172264Sjacobs static papi_status_t 1182264Sjacobs printer_from_service(service_t *svc, printer_t *p, char **requested_attrs) 1192264Sjacobs { 1202264Sjacobs papi_status_t result; 1212264Sjacobs papi_service_t p_svc = NULL; 1222264Sjacobs papi_printer_t printer = NULL; 1232264Sjacobs char *psm = NULL; 1242264Sjacobs char *uri = NULL; 1252264Sjacobs 1262264Sjacobs /* get the psm and uri from the attributes */ 1272264Sjacobs papiAttributeListGetString(p->attributes, NULL, 1282264Sjacobs "print-service-module", &psm); 1292264Sjacobs papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri); 1302264Sjacobs papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported", 1312264Sjacobs &uri); 1322264Sjacobs 1332264Sjacobs /* contact the service for the printer */ 1342264Sjacobs result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user, 1352264Sjacobs svc->password, svc->authCB, svc->encryption, 1362264Sjacobs svc->app_data); 1372264Sjacobs if (result != PAPI_OK) 1382264Sjacobs return (result); 1392264Sjacobs 1402264Sjacobs /* get the printer from the service */ 1412264Sjacobs result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer); 1422264Sjacobs if (result == PAPI_OK) { 1432264Sjacobs papi_attribute_t **attributes; 1442264Sjacobs 1452264Sjacobs attributes = papiPrinterGetAttributeList(printer); 1462264Sjacobs copy_attributes(&p->attributes, attributes); 1472264Sjacobs } 1482264Sjacobs papiPrinterFree(printer); 1492264Sjacobs papiServiceDestroy(p_svc); 1502264Sjacobs 1512264Sjacobs return (result); 1522264Sjacobs } 1532264Sjacobs 1542264Sjacobs /* are the requested attributes contained in the list */ 1552264Sjacobs static int 1562264Sjacobs contained(char **requested, papi_attribute_t **list) 1572264Sjacobs { 1582264Sjacobs int i; 1592264Sjacobs 1602264Sjacobs if (requested == NULL) /* we want every possible attribute */ 1612264Sjacobs return (0); 1622264Sjacobs 1632264Sjacobs for (i = 0; requested[i] != NULL; i++) 1642264Sjacobs if (papiAttributeListFind(list, requested[i]) == NULL) 1652264Sjacobs return (0); 1662264Sjacobs 1672264Sjacobs return (1); 1682264Sjacobs } 1692264Sjacobs 1702264Sjacobs /* Enumerate a list of printers from the Name Service */ 1712264Sjacobs static papi_status_t 1722264Sjacobs printers_from_name_service(service_t *svc, char **requested_attrs, 1732264Sjacobs papi_filter_t *filter, papi_printer_t **printers) 1742264Sjacobs { 1752264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 1762264Sjacobs papi_attribute_t **attrs; 1772264Sjacobs 1782264Sjacobs if ((svc == NULL) || (printers == NULL)) 1792264Sjacobs return (PAPI_BAD_ARGUMENT); 1802264Sjacobs 1812264Sjacobs /* retrieve printers from the nameservice */ 182*2792Sjacobs setprinterentry(0, NULL); 1832264Sjacobs while ((attrs = getprinterentry(NULL)) != NULL) { 1842264Sjacobs printer_t *p = NULL; 1852264Sjacobs 1862264Sjacobs if ((p = calloc(1, sizeof (*p))) == NULL) 1872264Sjacobs return (PAPI_TEMPORARY_ERROR); 1882264Sjacobs 1892264Sjacobs p->attributes = attrs; 1902264Sjacobs list_append(printers, p); 1912264Sjacobs } 1922264Sjacobs 1932264Sjacobs /* if we have printers, check if our request has been satisfied */ 1942264Sjacobs if ((printers != NULL) && (*printers != NULL)) { 1952264Sjacobs int i; 1962264Sjacobs 1972264Sjacobs /* walk through the list */ 1982264Sjacobs for (i = 0; (*printers)[i] != NULL; i++) { 1992264Sjacobs printer_t *p = (*printers)[i]; 2002264Sjacobs 2012264Sjacobs /* see if the name service satisfied the request */ 2022264Sjacobs if (contained(requested_attrs, p->attributes) == 0) 2032264Sjacobs printer_from_service(svc, p, requested_attrs); 2042264Sjacobs } 2052264Sjacobs } 2062264Sjacobs 2072264Sjacobs return (PAPI_OK); 2082264Sjacobs } 2092264Sjacobs 2102264Sjacobs papi_status_t 2112264Sjacobs papiPrintersList(papi_service_t handle, char **requested_attrs, 2122264Sjacobs papi_filter_t *filter, papi_printer_t **printers) 2132264Sjacobs { 2142264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 2152264Sjacobs service_t *svc = handle; 2162264Sjacobs papi_printer_t *svc_printers = NULL; 2172264Sjacobs papi_status_t (*f)(); 2182264Sjacobs 2192264Sjacobs if ((svc == NULL) || (printers == NULL)) 2202264Sjacobs return (PAPI_BAD_ARGUMENT); 2212264Sjacobs 2222264Sjacobs if (svc->so_handle != NULL) /* connected, use the print svc */ 2232264Sjacobs result = printers_from_service(svc, requested_attrs, 2242264Sjacobs filter, printers); 2252264Sjacobs else /* not connected, use the name svc */ 2262264Sjacobs result = printers_from_name_service(svc, requested_attrs, 2272264Sjacobs filter, printers); 2282264Sjacobs 2292264Sjacobs return (result); 2302264Sjacobs } 2312264Sjacobs 2322264Sjacobs papi_status_t 2332264Sjacobs papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs, 2342264Sjacobs papi_attribute_t **job_attributes, papi_printer_t *printer) 2352264Sjacobs { 2362264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 2372264Sjacobs service_t *svc = handle; 2382264Sjacobs printer_t *p = NULL; 2392264Sjacobs papi_status_t (*f)(); 2402264Sjacobs 2412264Sjacobs if ((svc == NULL) || (name == NULL) || (printer == NULL)) 2422264Sjacobs return (PAPI_BAD_ARGUMENT); 2432264Sjacobs 2442264Sjacobs if ((result = service_connect(svc, name)) != PAPI_OK) 2452264Sjacobs return (result); 2462264Sjacobs 2472264Sjacobs if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 2482264Sjacobs return (PAPI_TEMPORARY_ERROR); 2492264Sjacobs 2502264Sjacobs if ((svc->name != NULL) && (svc->svc_handle != NULL) && 2512264Sjacobs (svc->uri != NULL)) { 2522264Sjacobs p->svc = svc; 2532264Sjacobs f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery"); 2542264Sjacobs if (f != NULL) 2552264Sjacobs result = f(svc->svc_handle, svc->name, requested_attrs, 2562264Sjacobs job_attributes, &p->printer); 2572264Sjacobs } else { 2582264Sjacobs setprinterentry(0, NULL); 2592264Sjacobs p->attributes = getprinterbyname(name, NULL); 2602264Sjacobs if (p->attributes == NULL) 2612264Sjacobs result = PAPI_NOT_FOUND; 2622264Sjacobs else 2632264Sjacobs result = PAPI_OK; 2642264Sjacobs } 2652264Sjacobs 2662264Sjacobs return (result); 2672264Sjacobs } 2682264Sjacobs 2692264Sjacobs static papi_status_t 2702264Sjacobs _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message, 2712264Sjacobs char *function) 2722264Sjacobs { 2732264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 2742264Sjacobs service_t *svc = handle; 2752264Sjacobs papi_status_t (*f)(); 2762264Sjacobs 2772264Sjacobs if ((svc == NULL) || (name == NULL)) 2782264Sjacobs return (PAPI_BAD_ARGUMENT); 2792264Sjacobs 2802264Sjacobs if ((result = service_connect(svc, name)) != PAPI_OK) 2812264Sjacobs return (result); 2822264Sjacobs 2832264Sjacobs f = (papi_status_t (*)())psm_sym(svc, function); 2842264Sjacobs if (f != NULL) 2852264Sjacobs result = f(svc->svc_handle, svc->name, message); 2862264Sjacobs 2872264Sjacobs return (result); 2882264Sjacobs } 2892264Sjacobs 2902264Sjacobs static papi_status_t 2912264Sjacobs _papi_printer_enable_or_resume(papi_service_t handle, char *name, 2922264Sjacobs char *function) 2932264Sjacobs { 2942264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 2952264Sjacobs service_t *svc = handle; 2962264Sjacobs papi_status_t (*f)(); 2972264Sjacobs 2982264Sjacobs if ((svc == NULL) || (name == NULL)) 2992264Sjacobs return (PAPI_BAD_ARGUMENT); 3002264Sjacobs 3012264Sjacobs if ((result = service_connect(svc, name)) != PAPI_OK) 3022264Sjacobs return (result); 3032264Sjacobs 3042264Sjacobs f = (papi_status_t (*)())psm_sym(svc, function); 3052264Sjacobs if (f != NULL) 3062264Sjacobs result = f(svc->svc_handle, svc->name); 3072264Sjacobs 3082264Sjacobs return (result); 3092264Sjacobs } 3102264Sjacobs 3112264Sjacobs papi_status_t 3122264Sjacobs papiPrinterDisable(papi_service_t handle, char *name, char *message) 3132264Sjacobs { 3142264Sjacobs return (_papi_printer_disable_or_pause(handle, name, message, 3152264Sjacobs "papiPrinterDisable")); 3162264Sjacobs } 3172264Sjacobs 3182264Sjacobs papi_status_t 3192264Sjacobs papiPrinterPause(papi_service_t handle, char *name, char *message) 3202264Sjacobs { 3212264Sjacobs return (_papi_printer_disable_or_pause(handle, name, message, 3222264Sjacobs "papiPrinterPause")); 3232264Sjacobs } 3242264Sjacobs 3252264Sjacobs papi_status_t 3262264Sjacobs papiPrinterEnable(papi_service_t handle, char *name) 3272264Sjacobs { 3282264Sjacobs return (_papi_printer_enable_or_resume(handle, name, 3292264Sjacobs "papiPrinterEnable")); 3302264Sjacobs } 3312264Sjacobs 3322264Sjacobs papi_status_t 3332264Sjacobs papiPrinterResume(papi_service_t handle, char *name) 3342264Sjacobs { 3352264Sjacobs return (_papi_printer_enable_or_resume(handle, name, 3362264Sjacobs "papiPrinterResume")); 3372264Sjacobs } 3382264Sjacobs 3392264Sjacobs static papi_status_t 3402264Sjacobs _papi_printer_add_or_modify(papi_service_t handle, char *name, 3412264Sjacobs papi_attribute_t **attributes, papi_printer_t *printer, 3422264Sjacobs char *function) 3432264Sjacobs { 3442264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3452264Sjacobs service_t *svc = handle; 3462264Sjacobs printer_t *p = NULL; 3472264Sjacobs papi_status_t (*f)(); 3482264Sjacobs 3492264Sjacobs if ((svc == NULL) || (name == NULL) || (attributes == NULL)) 3502264Sjacobs return (PAPI_BAD_ARGUMENT); 3512264Sjacobs 3522264Sjacobs if ((result = service_connect(svc, name)) != PAPI_OK) 3532264Sjacobs return (result); 3542264Sjacobs 3552264Sjacobs if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 3562264Sjacobs return (PAPI_TEMPORARY_ERROR); 3572264Sjacobs 3582264Sjacobs p->svc = svc; 3592264Sjacobs f = (papi_status_t (*)())psm_sym(p->svc, function); 3602264Sjacobs if (f != NULL) 3612264Sjacobs result = f(svc->svc_handle, svc->name, attributes, 3622264Sjacobs &p->printer); 3632264Sjacobs 3642264Sjacobs return (result); 3652264Sjacobs } 3662264Sjacobs 3672264Sjacobs papi_status_t 3682264Sjacobs papiPrinterAdd(papi_service_t handle, char *name, 3692264Sjacobs papi_attribute_t **attributes, papi_printer_t *printer) 3702264Sjacobs { 3712264Sjacobs return (_papi_printer_add_or_modify(handle, name, attributes, printer, 3722264Sjacobs "papiPrinterAdd")); 3732264Sjacobs } 3742264Sjacobs 3752264Sjacobs papi_status_t 3762264Sjacobs papiPrinterModify(papi_service_t handle, char *name, 3772264Sjacobs papi_attribute_t **attributes, papi_printer_t *printer) 3782264Sjacobs { 3792264Sjacobs return (_papi_printer_add_or_modify(handle, name, attributes, printer, 3802264Sjacobs "papiPrinterModify")); 3812264Sjacobs } 3822264Sjacobs 3832264Sjacobs 3842264Sjacobs papi_status_t 3852264Sjacobs papiPrinterRemove(papi_service_t handle, char *name) 3862264Sjacobs { 3872264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 3882264Sjacobs service_t *svc = handle; 3892264Sjacobs papi_status_t (*f)(); 3902264Sjacobs 3912264Sjacobs if ((svc == NULL) || (name == NULL)) 3922264Sjacobs return (PAPI_BAD_ARGUMENT); 3932264Sjacobs 3942264Sjacobs if ((result = service_connect(svc, name)) != PAPI_OK) 3952264Sjacobs return (result); 3962264Sjacobs 3972264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove"); 3982264Sjacobs if (f != NULL) 3992264Sjacobs result = f(svc->svc_handle, svc->name); 4002264Sjacobs 4012264Sjacobs return (result); 4022264Sjacobs } 4032264Sjacobs 4042264Sjacobs papi_status_t 4052264Sjacobs papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) 4062264Sjacobs { 4072264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4082264Sjacobs service_t *svc = handle; 4092264Sjacobs papi_job_t *svc_jobs = NULL; 4102264Sjacobs papi_status_t (*f)(); 4112264Sjacobs 4122264Sjacobs if ((svc == NULL) || (name == NULL)) 4132264Sjacobs return (PAPI_BAD_ARGUMENT); 4142264Sjacobs 4152264Sjacobs if ((result = service_connect(svc, name)) != PAPI_OK) 4162264Sjacobs return (result); 4172264Sjacobs 4182264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs"); 4192264Sjacobs if (f != NULL) 4202264Sjacobs result = f(svc->svc_handle, svc->name, &svc_jobs); 4212264Sjacobs 4222264Sjacobs /* 4232264Sjacobs * copy the resulting job object pointers into our own 4242264Sjacobs * representation of a job object because we need the 4252264Sjacobs * service context to operate against the individual job 4262264Sjacobs * objects. We free the list now because we no longer need 4272264Sjacobs * it and would have no way of freeing it later. 4282264Sjacobs */ 4292264Sjacobs if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) { 4302264Sjacobs int i; 4312264Sjacobs 4322264Sjacobs *jobs = NULL; 4332264Sjacobs for (i = 0; svc_jobs[i] != NULL; i++) { 4342264Sjacobs job_t *j = NULL; 4352264Sjacobs 4362264Sjacobs if ((j = calloc(1, sizeof (*j))) == NULL) 4372264Sjacobs return (PAPI_TEMPORARY_ERROR); 4382264Sjacobs 4392264Sjacobs j->svc = svc; 4402264Sjacobs j->job = svc_jobs[i]; 4412264Sjacobs list_append(jobs, j); 4422264Sjacobs } 4432264Sjacobs free(svc_jobs); 4442264Sjacobs } 4452264Sjacobs 4462264Sjacobs return (result); 4472264Sjacobs } 4482264Sjacobs 4492264Sjacobs papi_status_t 4502264Sjacobs papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs, 4512264Sjacobs int type_mask, int max_num_jobs, papi_job_t **jobs) 4522264Sjacobs { 4532264Sjacobs papi_status_t result = PAPI_INTERNAL_ERROR; 4542264Sjacobs service_t *svc = handle; 4552264Sjacobs papi_job_t *svc_jobs = NULL; 4562264Sjacobs papi_status_t (*f)(); 4572264Sjacobs 4582264Sjacobs if ((svc == NULL) || (name == NULL) || (jobs == NULL)) 4592264Sjacobs return (PAPI_BAD_ARGUMENT); 4602264Sjacobs 4612264Sjacobs if ((result = service_connect(svc, name)) != PAPI_OK) 4622264Sjacobs return (result); 4632264Sjacobs 4642264Sjacobs f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs"); 4652264Sjacobs if (f != NULL) 4662264Sjacobs result = f(svc->svc_handle, svc->name, requested_attrs, 4672264Sjacobs type_mask, max_num_jobs, &svc_jobs); 4682264Sjacobs 4692264Sjacobs /* 4702264Sjacobs * copy the resulting job object pointers into our own 4712264Sjacobs * representation of a job object because we need the 4722264Sjacobs * service context to operate against the individual job 4732264Sjacobs * objects. We free the list now because we no longer need 4742264Sjacobs * it and would have no way of freeing it later. 4752264Sjacobs */ 4762264Sjacobs if ((result == PAPI_OK) && (svc_jobs != NULL)) { 4772264Sjacobs int i; 4782264Sjacobs 4792264Sjacobs *jobs = NULL; 4802264Sjacobs for (i = 0; svc_jobs[i] != NULL; i++) { 4812264Sjacobs job_t *j = NULL; 4822264Sjacobs 4832264Sjacobs if ((j = calloc(1, sizeof (*j))) == NULL) 4842264Sjacobs return (PAPI_TEMPORARY_ERROR); 4852264Sjacobs 4862264Sjacobs j->svc = svc; 4872264Sjacobs j->job = svc_jobs[i]; 4882264Sjacobs list_append(jobs, j); 4892264Sjacobs } 4902264Sjacobs free(svc_jobs); 4912264Sjacobs } 4922264Sjacobs 4932264Sjacobs return (result); 4942264Sjacobs } 4952264Sjacobs 4962264Sjacobs papi_attribute_t ** 4972264Sjacobs papiPrinterGetAttributeList(papi_printer_t printer) 4982264Sjacobs { 4992264Sjacobs papi_attribute_t **result = NULL; 5002264Sjacobs printer_t *p = printer; 5012264Sjacobs 5022264Sjacobs if ((p != NULL) && (p->printer != NULL)) { 5032264Sjacobs papi_attribute_t **(*f)(); 5042264Sjacobs 5052264Sjacobs f = (papi_attribute_t **(*)())psm_sym(p->svc, 5062264Sjacobs "papiPrinterGetAttributeList"); 5072264Sjacobs if (f != NULL) 5082264Sjacobs result = f(p->printer); 5092264Sjacobs } else 5102264Sjacobs result = p->attributes; 5112264Sjacobs 5122264Sjacobs return (result); 5132264Sjacobs } 514