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