1 /* 2 * CDDL HEADER START 3 * 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. 7 * 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. 12 * 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] 18 * 19 * CDDL HEADER END 20 */ 21 22 /* 23 * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 */ 27 28 /* $Id: printer.c 151 2006-04-25 16:55:34Z njacobs $ */ 29 30 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 /*LINTLIBRARY*/ 33 34 #include <stdlib.h> 35 #include <papi_impl.h> 36 37 void 38 papiPrinterFree(papi_printer_t printer) 39 { 40 printer_t *tmp = printer; 41 42 if (tmp != NULL) { 43 void (*f)(); 44 45 f = (void (*)())psm_sym(tmp->svc, "papiPrinterFree"); 46 if (f != NULL) 47 f(tmp->printer); 48 if (tmp->attributes != NULL) 49 papiAttributeListFree(tmp->attributes); 50 if (tmp->svc_is_internal != 0) 51 papiServiceDestroy(tmp->svc); 52 free(tmp); 53 } 54 } 55 56 void 57 papiPrinterListFree(papi_printer_t *printers) 58 { 59 if (printers != NULL) { 60 int i; 61 62 for (i = 0; printers[i] != NULL; i++) 63 papiPrinterFree(printers[i]); 64 free(printers); 65 } 66 } 67 68 /* Enumerate a list of printers from the loaded print service. */ 69 static papi_status_t 70 printers_from_service(service_t *svc, char **requested_attrs, 71 papi_filter_t *filter, papi_printer_t **printers) 72 { 73 papi_status_t result = PAPI_INTERNAL_ERROR; 74 papi_printer_t *svc_printers = NULL; 75 papi_status_t (*f)(); 76 77 if ((svc == NULL) || (printers == NULL)) 78 return (PAPI_BAD_ARGUMENT); 79 80 /* connect to the service if we are not connected */ 81 if ((result = service_connect(svc, svc->name)) != PAPI_OK) 82 return (result); 83 84 f = (papi_status_t (*)())psm_sym(svc, "papiPrintersList"); 85 if (f != NULL) 86 result = f(svc->svc_handle, requested_attrs, filter, 87 &svc_printers); 88 89 /* 90 * copy the resulting printer object pointers into our own 91 * representation of a printer object because we need the 92 * service context to operate against the individual printer 93 * objects. We free the list now because we no longer need 94 * it and would have no way of freeing it later. 95 */ 96 if ((result == PAPI_OK) && (svc_printers != NULL)) { 97 int i; 98 99 *printers = NULL; 100 for (i = 0; svc_printers[i] != NULL; i++) { 101 printer_t *p = NULL; 102 103 if ((p = calloc(1, sizeof (*p))) == NULL) 104 return (PAPI_TEMPORARY_ERROR); 105 106 p->svc = svc; 107 p->printer = svc_printers[i]; 108 list_append(printers, p); 109 } 110 free(svc_printers); 111 } 112 113 return (result); 114 } 115 116 /* Get printer attributes from it's print service */ 117 static papi_status_t 118 printer_from_service(service_t *svc, printer_t *p, char **requested_attrs) 119 { 120 papi_status_t result; 121 papi_service_t p_svc = NULL; 122 papi_printer_t printer = NULL; 123 char *psm = NULL; 124 char *uri = NULL; 125 126 /* get the psm and uri from the attributes */ 127 papiAttributeListGetString(p->attributes, NULL, 128 "print-service-module", &psm); 129 papiAttributeListGetString(p->attributes, NULL, "printer-name", &uri); 130 papiAttributeListGetString(p->attributes, NULL, "printer-uri-supported", 131 &uri); 132 133 /* contact the service for the printer */ 134 result = papiServiceCreate((papi_service_t *)&p_svc, psm, svc->user, 135 svc->password, svc->authCB, svc->encryption, 136 svc->app_data); 137 if (result != PAPI_OK) 138 return (result); 139 140 /* get the printer from the service */ 141 result = papiPrinterQuery(p_svc, uri, requested_attrs, NULL, &printer); 142 if (result == PAPI_OK) { 143 papi_attribute_t **attributes; 144 145 attributes = papiPrinterGetAttributeList(printer); 146 copy_attributes(&p->attributes, attributes); 147 } 148 papiPrinterFree(printer); 149 papiServiceDestroy(p_svc); 150 151 return (result); 152 } 153 154 /* are the requested attributes contained in the list */ 155 static int 156 contained(char **requested, papi_attribute_t **list) 157 { 158 int i; 159 160 if (requested == NULL) /* we want every possible attribute */ 161 return (0); 162 163 for (i = 0; requested[i] != NULL; i++) 164 if (papiAttributeListFind(list, requested[i]) == NULL) 165 return (0); 166 167 return (1); 168 } 169 170 /* Enumerate a list of printers from the Name Service */ 171 static papi_status_t 172 printers_from_name_service(service_t *svc, char **requested_attrs, 173 papi_filter_t *filter, papi_printer_t **printers) 174 { 175 papi_status_t result = PAPI_INTERNAL_ERROR; 176 papi_attribute_t **attrs; 177 178 if ((svc == NULL) || (printers == NULL)) 179 return (PAPI_BAD_ARGUMENT); 180 181 /* retrieve printers from the nameservice */ 182 setprinterentry(0, NULL); 183 while ((attrs = getprinterentry(NULL)) != NULL) { 184 printer_t *p = NULL; 185 186 if ((p = calloc(1, sizeof (*p))) == NULL) 187 return (PAPI_TEMPORARY_ERROR); 188 189 p->attributes = attrs; 190 list_append(printers, p); 191 } 192 193 /* if we have printers, check if our request has been satisfied */ 194 if ((printers != NULL) && (*printers != NULL)) { 195 int i; 196 197 /* walk through the list */ 198 for (i = 0; (*printers)[i] != NULL; i++) { 199 printer_t *p = (*printers)[i]; 200 201 /* see if the name service satisfied the request */ 202 if (contained(requested_attrs, p->attributes) == 0) 203 printer_from_service(svc, p, requested_attrs); 204 } 205 } 206 207 return (PAPI_OK); 208 } 209 210 papi_status_t 211 papiPrintersList(papi_service_t handle, char **requested_attrs, 212 papi_filter_t *filter, papi_printer_t **printers) 213 { 214 papi_status_t result = PAPI_INTERNAL_ERROR; 215 service_t *svc = handle; 216 papi_printer_t *svc_printers = NULL; 217 papi_status_t (*f)(); 218 219 if ((svc == NULL) || (printers == NULL)) 220 return (PAPI_BAD_ARGUMENT); 221 222 if (svc->so_handle != NULL) /* connected, use the print svc */ 223 result = printers_from_service(svc, requested_attrs, 224 filter, printers); 225 else /* not connected, use the name svc */ 226 result = printers_from_name_service(svc, requested_attrs, 227 filter, printers); 228 229 return (result); 230 } 231 232 papi_status_t 233 papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs, 234 papi_attribute_t **job_attributes, papi_printer_t *printer) 235 { 236 papi_status_t result = PAPI_INTERNAL_ERROR; 237 service_t *svc = handle; 238 printer_t *p = NULL; 239 papi_status_t (*f)(); 240 241 if ((svc == NULL) || (name == NULL) || (printer == NULL)) 242 return (PAPI_BAD_ARGUMENT); 243 244 if ((result = service_connect(svc, name)) != PAPI_OK) 245 return (result); 246 247 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 248 return (PAPI_TEMPORARY_ERROR); 249 250 if ((svc->name != NULL) && (svc->svc_handle != NULL) && 251 (svc->uri != NULL)) { 252 p->svc = svc; 253 f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery"); 254 if (f != NULL) 255 result = f(svc->svc_handle, svc->name, requested_attrs, 256 job_attributes, &p->printer); 257 } else { 258 setprinterentry(0, NULL); 259 p->attributes = getprinterbyname(name, NULL); 260 if (p->attributes == NULL) 261 result = PAPI_NOT_FOUND; 262 else 263 result = PAPI_OK; 264 } 265 266 return (result); 267 } 268 269 static papi_status_t 270 _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message, 271 char *function) 272 { 273 papi_status_t result = PAPI_INTERNAL_ERROR; 274 service_t *svc = handle; 275 papi_status_t (*f)(); 276 277 if ((svc == NULL) || (name == NULL)) 278 return (PAPI_BAD_ARGUMENT); 279 280 if ((result = service_connect(svc, name)) != PAPI_OK) 281 return (result); 282 283 f = (papi_status_t (*)())psm_sym(svc, function); 284 if (f != NULL) 285 result = f(svc->svc_handle, svc->name, message); 286 287 return (result); 288 } 289 290 static papi_status_t 291 _papi_printer_enable_or_resume(papi_service_t handle, char *name, 292 char *function) 293 { 294 papi_status_t result = PAPI_INTERNAL_ERROR; 295 service_t *svc = handle; 296 papi_status_t (*f)(); 297 298 if ((svc == NULL) || (name == NULL)) 299 return (PAPI_BAD_ARGUMENT); 300 301 if ((result = service_connect(svc, name)) != PAPI_OK) 302 return (result); 303 304 f = (papi_status_t (*)())psm_sym(svc, function); 305 if (f != NULL) 306 result = f(svc->svc_handle, svc->name); 307 308 return (result); 309 } 310 311 papi_status_t 312 papiPrinterDisable(papi_service_t handle, char *name, char *message) 313 { 314 return (_papi_printer_disable_or_pause(handle, name, message, 315 "papiPrinterDisable")); 316 } 317 318 papi_status_t 319 papiPrinterPause(papi_service_t handle, char *name, char *message) 320 { 321 return (_papi_printer_disable_or_pause(handle, name, message, 322 "papiPrinterPause")); 323 } 324 325 papi_status_t 326 papiPrinterEnable(papi_service_t handle, char *name) 327 { 328 return (_papi_printer_enable_or_resume(handle, name, 329 "papiPrinterEnable")); 330 } 331 332 papi_status_t 333 papiPrinterResume(papi_service_t handle, char *name) 334 { 335 return (_papi_printer_enable_or_resume(handle, name, 336 "papiPrinterResume")); 337 } 338 339 static papi_status_t 340 _papi_printer_add_or_modify(papi_service_t handle, char *name, 341 papi_attribute_t **attributes, papi_printer_t *printer, 342 char *function) 343 { 344 papi_status_t result = PAPI_INTERNAL_ERROR; 345 service_t *svc = handle; 346 printer_t *p = NULL; 347 papi_status_t (*f)(); 348 349 if ((svc == NULL) || (name == NULL) || (attributes == NULL)) 350 return (PAPI_BAD_ARGUMENT); 351 352 if ((result = service_connect(svc, name)) != PAPI_OK) 353 return (result); 354 355 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 356 return (PAPI_TEMPORARY_ERROR); 357 358 p->svc = svc; 359 f = (papi_status_t (*)())psm_sym(p->svc, function); 360 if (f != NULL) 361 result = f(svc->svc_handle, svc->name, attributes, 362 &p->printer); 363 364 return (result); 365 } 366 367 papi_status_t 368 papiPrinterAdd(papi_service_t handle, char *name, 369 papi_attribute_t **attributes, papi_printer_t *printer) 370 { 371 return (_papi_printer_add_or_modify(handle, name, attributes, printer, 372 "papiPrinterAdd")); 373 } 374 375 papi_status_t 376 papiPrinterModify(papi_service_t handle, char *name, 377 papi_attribute_t **attributes, papi_printer_t *printer) 378 { 379 return (_papi_printer_add_or_modify(handle, name, attributes, printer, 380 "papiPrinterModify")); 381 } 382 383 384 papi_status_t 385 papiPrinterRemove(papi_service_t handle, char *name) 386 { 387 papi_status_t result = PAPI_INTERNAL_ERROR; 388 service_t *svc = handle; 389 papi_status_t (*f)(); 390 391 if ((svc == NULL) || (name == NULL)) 392 return (PAPI_BAD_ARGUMENT); 393 394 if ((result = service_connect(svc, name)) != PAPI_OK) 395 return (result); 396 397 f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove"); 398 if (f != NULL) 399 result = f(svc->svc_handle, svc->name); 400 401 return (result); 402 } 403 404 papi_status_t 405 papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) 406 { 407 papi_status_t result = PAPI_INTERNAL_ERROR; 408 service_t *svc = handle; 409 papi_job_t *svc_jobs = NULL; 410 papi_status_t (*f)(); 411 412 if ((svc == NULL) || (name == NULL)) 413 return (PAPI_BAD_ARGUMENT); 414 415 if ((result = service_connect(svc, name)) != PAPI_OK) 416 return (result); 417 418 f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs"); 419 if (f != NULL) 420 result = f(svc->svc_handle, svc->name, &svc_jobs); 421 422 /* 423 * copy the resulting job object pointers into our own 424 * representation of a job object because we need the 425 * service context to operate against the individual job 426 * objects. We free the list now because we no longer need 427 * it and would have no way of freeing it later. 428 */ 429 if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) { 430 int i; 431 432 *jobs = NULL; 433 for (i = 0; svc_jobs[i] != NULL; i++) { 434 job_t *j = NULL; 435 436 if ((j = calloc(1, sizeof (*j))) == NULL) 437 return (PAPI_TEMPORARY_ERROR); 438 439 j->svc = svc; 440 j->job = svc_jobs[i]; 441 list_append(jobs, j); 442 } 443 free(svc_jobs); 444 } 445 446 return (result); 447 } 448 449 papi_status_t 450 papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs, 451 int type_mask, int max_num_jobs, papi_job_t **jobs) 452 { 453 papi_status_t result = PAPI_INTERNAL_ERROR; 454 service_t *svc = handle; 455 papi_job_t *svc_jobs = NULL; 456 papi_status_t (*f)(); 457 458 if ((svc == NULL) || (name == NULL) || (jobs == NULL)) 459 return (PAPI_BAD_ARGUMENT); 460 461 if ((result = service_connect(svc, name)) != PAPI_OK) 462 return (result); 463 464 f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs"); 465 if (f != NULL) 466 result = f(svc->svc_handle, svc->name, requested_attrs, 467 type_mask, max_num_jobs, &svc_jobs); 468 469 /* 470 * copy the resulting job object pointers into our own 471 * representation of a job object because we need the 472 * service context to operate against the individual job 473 * objects. We free the list now because we no longer need 474 * it and would have no way of freeing it later. 475 */ 476 if ((result == PAPI_OK) && (svc_jobs != NULL)) { 477 int i; 478 479 *jobs = NULL; 480 for (i = 0; svc_jobs[i] != NULL; i++) { 481 job_t *j = NULL; 482 483 if ((j = calloc(1, sizeof (*j))) == NULL) 484 return (PAPI_TEMPORARY_ERROR); 485 486 j->svc = svc; 487 j->job = svc_jobs[i]; 488 list_append(jobs, j); 489 } 490 free(svc_jobs); 491 } 492 493 return (result); 494 } 495 496 papi_attribute_t ** 497 papiPrinterGetAttributeList(papi_printer_t printer) 498 { 499 papi_attribute_t **result = NULL; 500 printer_t *p = printer; 501 502 if ((p != NULL) && (p->printer != NULL)) { 503 papi_attribute_t **(*f)(); 504 505 f = (papi_attribute_t **(*)())psm_sym(p->svc, 506 "papiPrinterGetAttributeList"); 507 if (f != NULL) 508 result = f(p->printer); 509 } else 510 result = p->attributes; 511 512 return (result); 513 } 514