1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 24*0Sstevel@tonic-gate * Use is subject to license terms. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate /*LINTLIBRARY*/ 30*0Sstevel@tonic-gate 31*0Sstevel@tonic-gate #include <stdlib.h> 32*0Sstevel@tonic-gate #include <string.h> 33*0Sstevel@tonic-gate #include <libintl.h> 34*0Sstevel@tonic-gate #include <papi_impl.h> 35*0Sstevel@tonic-gate #include <lp.h> 36*0Sstevel@tonic-gate 37*0Sstevel@tonic-gate extern int isclass(char *); 38*0Sstevel@tonic-gate 39*0Sstevel@tonic-gate void 40*0Sstevel@tonic-gate papiPrinterFree(papi_printer_t printer) 41*0Sstevel@tonic-gate { 42*0Sstevel@tonic-gate printer_t *tmp = printer; 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate if (tmp != NULL) { 45*0Sstevel@tonic-gate papiAttributeListFree(tmp->attributes); 46*0Sstevel@tonic-gate free(tmp); 47*0Sstevel@tonic-gate } 48*0Sstevel@tonic-gate } 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate void 51*0Sstevel@tonic-gate papiPrinterListFree(papi_printer_t *printers) 52*0Sstevel@tonic-gate { 53*0Sstevel@tonic-gate if (printers != NULL) { 54*0Sstevel@tonic-gate int i; 55*0Sstevel@tonic-gate 56*0Sstevel@tonic-gate for (i = 0; printers[i] != NULL; i++) 57*0Sstevel@tonic-gate papiPrinterFree(printers[i]); 58*0Sstevel@tonic-gate free(printers); 59*0Sstevel@tonic-gate } 60*0Sstevel@tonic-gate } 61*0Sstevel@tonic-gate 62*0Sstevel@tonic-gate papi_status_t 63*0Sstevel@tonic-gate papiPrintersList(papi_service_t handle, const char **requested_attrs, 64*0Sstevel@tonic-gate const papi_filter_t *filter, papi_printer_t **printers) 65*0Sstevel@tonic-gate { 66*0Sstevel@tonic-gate service_t *svc = handle; 67*0Sstevel@tonic-gate printer_t *p = NULL; 68*0Sstevel@tonic-gate short status = MOK; 69*0Sstevel@tonic-gate char *printer = NULL, 70*0Sstevel@tonic-gate *form = NULL, 71*0Sstevel@tonic-gate *request_id = NULL, 72*0Sstevel@tonic-gate *character_set = NULL, 73*0Sstevel@tonic-gate *reject_reason = NULL, 74*0Sstevel@tonic-gate *disable_reason = NULL; 75*0Sstevel@tonic-gate short printer_status = 0; 76*0Sstevel@tonic-gate long enable_date = 0, reject_date = 0; 77*0Sstevel@tonic-gate 78*0Sstevel@tonic-gate if ((handle == NULL) || (printers == NULL)) 79*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 80*0Sstevel@tonic-gate 81*0Sstevel@tonic-gate if ((filter == NULL) || 82*0Sstevel@tonic-gate ((filter->filter.bitmask.mask & PAPI_PRINTER_LOCAL) == 83*0Sstevel@tonic-gate (filter->filter.bitmask.value & PAPI_PRINTER_LOCAL))) { 84*0Sstevel@tonic-gate /* ask the spooler for the printer(s) and state */ 85*0Sstevel@tonic-gate if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, NAME_ALL) < 0) 86*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 87*0Sstevel@tonic-gate 88*0Sstevel@tonic-gate do { 89*0Sstevel@tonic-gate if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, 90*0Sstevel@tonic-gate &printer, &form, &character_set, 91*0Sstevel@tonic-gate &disable_reason, &reject_reason, 92*0Sstevel@tonic-gate &printer_status, &request_id, 93*0Sstevel@tonic-gate &enable_date, &reject_date) < 0) 94*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 95*0Sstevel@tonic-gate 96*0Sstevel@tonic-gate if ((p = calloc(1, sizeof (*p))) == NULL) 97*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 98*0Sstevel@tonic-gate 99*0Sstevel@tonic-gate lpsched_printer_configuration_to_attributes(svc, p, 100*0Sstevel@tonic-gate printer); 101*0Sstevel@tonic-gate 102*0Sstevel@tonic-gate printer_status_to_attributes(p, printer, form, 103*0Sstevel@tonic-gate character_set, disable_reason, 104*0Sstevel@tonic-gate reject_reason, printer_status, 105*0Sstevel@tonic-gate request_id, enable_date, reject_date); 106*0Sstevel@tonic-gate 107*0Sstevel@tonic-gate list_append(printers, p); 108*0Sstevel@tonic-gate 109*0Sstevel@tonic-gate } while (status == MOKMORE); 110*0Sstevel@tonic-gate } 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate if ((filter == NULL) || 113*0Sstevel@tonic-gate ((filter->filter.bitmask.mask & PAPI_PRINTER_CLASS) == 114*0Sstevel@tonic-gate (filter->filter.bitmask.value & PAPI_PRINTER_CLASS))) { 115*0Sstevel@tonic-gate /* ask the spooler for the class(es) and state */ 116*0Sstevel@tonic-gate if (snd_msg(svc, S_INQUIRE_CLASS, NAME_ALL) < 0) 117*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate do { 120*0Sstevel@tonic-gate if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &printer, 121*0Sstevel@tonic-gate &printer_status, &reject_reason, 122*0Sstevel@tonic-gate &reject_date) < 0) 123*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 124*0Sstevel@tonic-gate 125*0Sstevel@tonic-gate if ((p = calloc(1, sizeof (*p))) == NULL) 126*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 127*0Sstevel@tonic-gate 128*0Sstevel@tonic-gate lpsched_class_configuration_to_attributes(svc, p, 129*0Sstevel@tonic-gate printer); 130*0Sstevel@tonic-gate 131*0Sstevel@tonic-gate class_status_to_attributes(p, printer, printer_status, 132*0Sstevel@tonic-gate reject_reason, reject_date); 133*0Sstevel@tonic-gate 134*0Sstevel@tonic-gate list_append(printers, p); 135*0Sstevel@tonic-gate 136*0Sstevel@tonic-gate } while (status == MOKMORE); 137*0Sstevel@tonic-gate } 138*0Sstevel@tonic-gate 139*0Sstevel@tonic-gate return (PAPI_OK); 140*0Sstevel@tonic-gate } 141*0Sstevel@tonic-gate 142*0Sstevel@tonic-gate papi_status_t 143*0Sstevel@tonic-gate papiPrinterQuery(papi_service_t handle, const char *name, 144*0Sstevel@tonic-gate const char **requested_attrs, 145*0Sstevel@tonic-gate const papi_attribute_t **job_attrs, 146*0Sstevel@tonic-gate papi_printer_t *printer) 147*0Sstevel@tonic-gate { 148*0Sstevel@tonic-gate papi_status_t pst; 149*0Sstevel@tonic-gate service_t *svc = handle; 150*0Sstevel@tonic-gate printer_t *p = NULL; 151*0Sstevel@tonic-gate char *dest; 152*0Sstevel@tonic-gate short status = MOK; 153*0Sstevel@tonic-gate char *pname = NULL, 154*0Sstevel@tonic-gate *form = NULL, 155*0Sstevel@tonic-gate *request_id = NULL, 156*0Sstevel@tonic-gate *character_set = NULL, 157*0Sstevel@tonic-gate *reject_reason = NULL, 158*0Sstevel@tonic-gate *disable_reason = NULL; 159*0Sstevel@tonic-gate short printer_status = 0; 160*0Sstevel@tonic-gate long enable_date = 0, reject_date = 0; 161*0Sstevel@tonic-gate 162*0Sstevel@tonic-gate if ((handle == NULL) || (name == NULL) || (printer == NULL)) 163*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 166*0Sstevel@tonic-gate return (PAPI_TEMPORARY_ERROR); 167*0Sstevel@tonic-gate 168*0Sstevel@tonic-gate dest = printer_name_from_uri_id(name, -1); 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate if (isprinter(dest) != 0) { 171*0Sstevel@tonic-gate pst = lpsched_printer_configuration_to_attributes(svc, p, dest); 172*0Sstevel@tonic-gate if (pst != PAPI_OK) 173*0Sstevel@tonic-gate return (pst); 174*0Sstevel@tonic-gate 175*0Sstevel@tonic-gate /* get the spooler status data now */ 176*0Sstevel@tonic-gate if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, dest) < 0) 177*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, &pname, 180*0Sstevel@tonic-gate &form, &character_set, &disable_reason, 181*0Sstevel@tonic-gate &reject_reason, &printer_status, &request_id, 182*0Sstevel@tonic-gate &enable_date, &reject_date) < 0) 183*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 184*0Sstevel@tonic-gate 185*0Sstevel@tonic-gate printer_status_to_attributes(p, pname, form, character_set, 186*0Sstevel@tonic-gate disable_reason, reject_reason, printer_status, 187*0Sstevel@tonic-gate request_id, enable_date, reject_date); 188*0Sstevel@tonic-gate } else if (isclass(dest) != 0) { 189*0Sstevel@tonic-gate pst = lpsched_class_configuration_to_attributes(svc, p, dest); 190*0Sstevel@tonic-gate if (pst != PAPI_OK) 191*0Sstevel@tonic-gate return (pst); 192*0Sstevel@tonic-gate 193*0Sstevel@tonic-gate /* get the spooler status data now */ 194*0Sstevel@tonic-gate if (snd_msg(svc, S_INQUIRE_CLASS, dest) < 0) 195*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 196*0Sstevel@tonic-gate 197*0Sstevel@tonic-gate if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &pname, 198*0Sstevel@tonic-gate &printer_status, &reject_reason, 199*0Sstevel@tonic-gate &reject_date) < 0) 200*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 201*0Sstevel@tonic-gate 202*0Sstevel@tonic-gate class_status_to_attributes(p, pname, printer_status, 203*0Sstevel@tonic-gate reject_reason, reject_date); 204*0Sstevel@tonic-gate } else if (strcmp(dest, "PrintService") == 0) { 205*0Sstevel@tonic-gate /* fill the printer object with service information */ 206*0Sstevel@tonic-gate lpsched_service_information(p); 207*0Sstevel@tonic-gate } else 208*0Sstevel@tonic-gate return (PAPI_NOT_FOUND); 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate free(dest); 211*0Sstevel@tonic-gate 212*0Sstevel@tonic-gate return (PAPI_OK); 213*0Sstevel@tonic-gate } 214*0Sstevel@tonic-gate 215*0Sstevel@tonic-gate papi_status_t 216*0Sstevel@tonic-gate papiPrinterModify(papi_service_t handle, const char *name, 217*0Sstevel@tonic-gate const papi_attribute_t **attributes, papi_printer_t *result) 218*0Sstevel@tonic-gate { 219*0Sstevel@tonic-gate service_t *svc = handle; 220*0Sstevel@tonic-gate 221*0Sstevel@tonic-gate if ((svc == NULL) || (name == NULL) || (attributes == NULL)) 222*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate return (PAPI_OPERATION_NOT_SUPPORTED); 225*0Sstevel@tonic-gate } 226*0Sstevel@tonic-gate 227*0Sstevel@tonic-gate papi_status_t 228*0Sstevel@tonic-gate papiPrinterPause(papi_service_t handle, const char *name, const char *message) 229*0Sstevel@tonic-gate { 230*0Sstevel@tonic-gate papi_status_t result; 231*0Sstevel@tonic-gate 232*0Sstevel@tonic-gate if ((handle == NULL) || (name == NULL)) 233*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 234*0Sstevel@tonic-gate 235*0Sstevel@tonic-gate result = lpsched_disable_printer(handle, name, message); 236*0Sstevel@tonic-gate 237*0Sstevel@tonic-gate return (result); 238*0Sstevel@tonic-gate } 239*0Sstevel@tonic-gate 240*0Sstevel@tonic-gate papi_status_t 241*0Sstevel@tonic-gate papiPrinterResume(papi_service_t handle, const char *name) 242*0Sstevel@tonic-gate { 243*0Sstevel@tonic-gate papi_status_t result; 244*0Sstevel@tonic-gate 245*0Sstevel@tonic-gate if ((handle == NULL) || (name == NULL)) 246*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 247*0Sstevel@tonic-gate 248*0Sstevel@tonic-gate result = lpsched_enable_printer(handle, name); 249*0Sstevel@tonic-gate 250*0Sstevel@tonic-gate return (result); 251*0Sstevel@tonic-gate } 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate papi_status_t 254*0Sstevel@tonic-gate papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs) 255*0Sstevel@tonic-gate { 256*0Sstevel@tonic-gate service_t *svc = handle; 257*0Sstevel@tonic-gate papi_status_t result = PAPI_OK_SUBST; 258*0Sstevel@tonic-gate short more; 259*0Sstevel@tonic-gate long status; 260*0Sstevel@tonic-gate char *dest; 261*0Sstevel@tonic-gate char *req_id; 262*0Sstevel@tonic-gate 263*0Sstevel@tonic-gate if ((handle == NULL) || (name == NULL)) 264*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 265*0Sstevel@tonic-gate 266*0Sstevel@tonic-gate dest = printer_name_from_uri_id(name, -1); 267*0Sstevel@tonic-gate if (snd_msg(svc, S_CANCEL, dest, "", "") < 0) 268*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate free(dest); 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate do { 273*0Sstevel@tonic-gate if (rcv_msg(svc, R_CANCEL, &more, &status, &req_id) < 0) 274*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 275*0Sstevel@tonic-gate 276*0Sstevel@tonic-gate switch (status) { 277*0Sstevel@tonic-gate case MOK: 278*0Sstevel@tonic-gate papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 279*0Sstevel@tonic-gate "canceled-jobs", req_id); 280*0Sstevel@tonic-gate break; 281*0Sstevel@tonic-gate case M2LATE: 282*0Sstevel@tonic-gate case MUNKNOWN: 283*0Sstevel@tonic-gate case MNOINFO: 284*0Sstevel@tonic-gate papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 285*0Sstevel@tonic-gate "cancel-failed", req_id); 286*0Sstevel@tonic-gate result = PAPI_DEVICE_ERROR; 287*0Sstevel@tonic-gate break; 288*0Sstevel@tonic-gate case MNOPERM: 289*0Sstevel@tonic-gate papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 290*0Sstevel@tonic-gate "cancel-failed", req_id); 291*0Sstevel@tonic-gate result = PAPI_NOT_AUTHORIZED; 292*0Sstevel@tonic-gate break; 293*0Sstevel@tonic-gate default: 294*0Sstevel@tonic-gate detailed_error(svc, gettext("cancel failed, bad status (%d)\n"), 295*0Sstevel@tonic-gate status); 296*0Sstevel@tonic-gate return (PAPI_DEVICE_ERROR); 297*0Sstevel@tonic-gate } 298*0Sstevel@tonic-gate } while (more == MOKMORE); 299*0Sstevel@tonic-gate 300*0Sstevel@tonic-gate return (result); 301*0Sstevel@tonic-gate } 302*0Sstevel@tonic-gate 303*0Sstevel@tonic-gate papi_status_t 304*0Sstevel@tonic-gate papiPrinterListJobs(papi_service_t handle, const char *name, 305*0Sstevel@tonic-gate const char **requested_attrs, const int type_mask, 306*0Sstevel@tonic-gate const int max_num_jobs, papi_job_t **jobs) 307*0Sstevel@tonic-gate { 308*0Sstevel@tonic-gate service_t *svc = handle; 309*0Sstevel@tonic-gate char *dest; 310*0Sstevel@tonic-gate short rc; 311*0Sstevel@tonic-gate int count = 1; 312*0Sstevel@tonic-gate 313*0Sstevel@tonic-gate if ((handle == NULL) || (name == NULL) || (jobs == NULL)) 314*0Sstevel@tonic-gate return (PAPI_BAD_ARGUMENT); 315*0Sstevel@tonic-gate 316*0Sstevel@tonic-gate dest = printer_name_from_uri_id(name, -1); 317*0Sstevel@tonic-gate 318*0Sstevel@tonic-gate rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", dest, "", "", ""); 319*0Sstevel@tonic-gate free(dest); 320*0Sstevel@tonic-gate if (rc < 0) 321*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 322*0Sstevel@tonic-gate 323*0Sstevel@tonic-gate do { 324*0Sstevel@tonic-gate job_t *job = NULL; 325*0Sstevel@tonic-gate char *dest = NULL, 326*0Sstevel@tonic-gate *ptr, 327*0Sstevel@tonic-gate *form = NULL, 328*0Sstevel@tonic-gate *req_id = NULL, 329*0Sstevel@tonic-gate *charset = NULL, 330*0Sstevel@tonic-gate *owner = NULL, 331*0Sstevel@tonic-gate *file = NULL; 332*0Sstevel@tonic-gate time_t date = 0; 333*0Sstevel@tonic-gate size_t size = 0; 334*0Sstevel@tonic-gate short rank = 0, state = 0; 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &req_id, 337*0Sstevel@tonic-gate &owner, &size, &date, &state, &dest, &form, 338*0Sstevel@tonic-gate &charset, &rank, &file) < 0) 339*0Sstevel@tonic-gate return (PAPI_SERVICE_UNAVAILABLE); 340*0Sstevel@tonic-gate 341*0Sstevel@tonic-gate if ((rc != MOK) && (rc != MOKMORE)) 342*0Sstevel@tonic-gate continue; 343*0Sstevel@tonic-gate /* 344*0Sstevel@tonic-gate * at this point, we should check to see if the job matches the 345*0Sstevel@tonic-gate * selection criterion defined in "type_mask". 346*0Sstevel@tonic-gate */ 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate /* too many yet? */ 349*0Sstevel@tonic-gate if ((max_num_jobs != 0) && (count++ > max_num_jobs)) 350*0Sstevel@tonic-gate continue; 351*0Sstevel@tonic-gate 352*0Sstevel@tonic-gate if ((job = calloc(1, sizeof (*job))) == NULL) 353*0Sstevel@tonic-gate continue; 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate job_status_to_attributes(job, req_id, owner, size, date, state, 356*0Sstevel@tonic-gate dest, form, charset, rank, file); 357*0Sstevel@tonic-gate 358*0Sstevel@tonic-gate if ((ptr = strrchr(file, '-')) != NULL) { 359*0Sstevel@tonic-gate *++ptr = '0'; 360*0Sstevel@tonic-gate *++ptr = NULL; 361*0Sstevel@tonic-gate } 362*0Sstevel@tonic-gate 363*0Sstevel@tonic-gate lpsched_read_job_configuration(svc, job, file); 364*0Sstevel@tonic-gate 365*0Sstevel@tonic-gate list_append(jobs, job); 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate } while (rc == MOKMORE); 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate if (rc == MNOINFO) /* If no jobs are found, it's still ok */ 370*0Sstevel@tonic-gate rc = MOK; 371*0Sstevel@tonic-gate 372*0Sstevel@tonic-gate return (lpsched_status_to_papi_status(rc)); 373*0Sstevel@tonic-gate } 374*0Sstevel@tonic-gate 375*0Sstevel@tonic-gate papi_attribute_t ** 376*0Sstevel@tonic-gate papiPrinterGetAttributeList(papi_printer_t printer) 377*0Sstevel@tonic-gate { 378*0Sstevel@tonic-gate printer_t *tmp = printer; 379*0Sstevel@tonic-gate 380*0Sstevel@tonic-gate if (tmp == NULL) 381*0Sstevel@tonic-gate return (NULL); 382*0Sstevel@tonic-gate 383*0Sstevel@tonic-gate return (tmp->attributes); 384*0Sstevel@tonic-gate } 385