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 while ((attrs = getprinterentry(NULL)) != NULL) { 183 printer_t *p = NULL; 184 185 if ((p = calloc(1, sizeof (*p))) == NULL) 186 return (PAPI_TEMPORARY_ERROR); 187 188 p->attributes = attrs; 189 list_append(printers, p); 190 } 191 192 /* if we have printers, check if our request has been satisfied */ 193 if ((printers != NULL) && (*printers != NULL)) { 194 int i; 195 196 /* walk through the list */ 197 for (i = 0; (*printers)[i] != NULL; i++) { 198 printer_t *p = (*printers)[i]; 199 200 /* see if the name service satisfied the request */ 201 if (contained(requested_attrs, p->attributes) == 0) 202 printer_from_service(svc, p, requested_attrs); 203 } 204 } 205 206 return (PAPI_OK); 207 } 208 209 papi_status_t 210 papiPrintersList(papi_service_t handle, char **requested_attrs, 211 papi_filter_t *filter, papi_printer_t **printers) 212 { 213 papi_status_t result = PAPI_INTERNAL_ERROR; 214 service_t *svc = handle; 215 papi_printer_t *svc_printers = NULL; 216 papi_status_t (*f)(); 217 218 if ((svc == NULL) || (printers == NULL)) 219 return (PAPI_BAD_ARGUMENT); 220 221 if (svc->so_handle != NULL) /* connected, use the print svc */ 222 result = printers_from_service(svc, requested_attrs, 223 filter, printers); 224 else /* not connected, use the name svc */ 225 result = printers_from_name_service(svc, requested_attrs, 226 filter, printers); 227 228 return (result); 229 } 230 231 papi_status_t 232 papiPrinterQuery(papi_service_t handle, char *name, char **requested_attrs, 233 papi_attribute_t **job_attributes, papi_printer_t *printer) 234 { 235 papi_status_t result = PAPI_INTERNAL_ERROR; 236 service_t *svc = handle; 237 printer_t *p = NULL; 238 papi_status_t (*f)(); 239 240 if ((svc == NULL) || (name == NULL) || (printer == NULL)) 241 return (PAPI_BAD_ARGUMENT); 242 243 if ((result = service_connect(svc, name)) != PAPI_OK) 244 return (result); 245 246 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 247 return (PAPI_TEMPORARY_ERROR); 248 249 if ((svc->name != NULL) && (svc->svc_handle != NULL) && 250 (svc->uri != NULL)) { 251 p->svc = svc; 252 f = (papi_status_t (*)())psm_sym(p->svc, "papiPrinterQuery"); 253 if (f != NULL) 254 result = f(svc->svc_handle, svc->name, requested_attrs, 255 job_attributes, &p->printer); 256 } else { 257 setprinterentry(0, NULL); 258 p->attributes = getprinterbyname(name, NULL); 259 if (p->attributes == NULL) 260 result = PAPI_NOT_FOUND; 261 else 262 result = PAPI_OK; 263 } 264 265 return (result); 266 } 267 268 static papi_status_t 269 _papi_printer_disable_or_pause(papi_service_t handle, char *name, char *message, 270 char *function) 271 { 272 papi_status_t result = PAPI_INTERNAL_ERROR; 273 service_t *svc = handle; 274 papi_status_t (*f)(); 275 276 if ((svc == NULL) || (name == NULL)) 277 return (PAPI_BAD_ARGUMENT); 278 279 if ((result = service_connect(svc, name)) != PAPI_OK) 280 return (result); 281 282 f = (papi_status_t (*)())psm_sym(svc, function); 283 if (f != NULL) 284 result = f(svc->svc_handle, svc->name, message); 285 286 return (result); 287 } 288 289 static papi_status_t 290 _papi_printer_enable_or_resume(papi_service_t handle, char *name, 291 char *function) 292 { 293 papi_status_t result = PAPI_INTERNAL_ERROR; 294 service_t *svc = handle; 295 papi_status_t (*f)(); 296 297 if ((svc == NULL) || (name == NULL)) 298 return (PAPI_BAD_ARGUMENT); 299 300 if ((result = service_connect(svc, name)) != PAPI_OK) 301 return (result); 302 303 f = (papi_status_t (*)())psm_sym(svc, function); 304 if (f != NULL) 305 result = f(svc->svc_handle, svc->name); 306 307 return (result); 308 } 309 310 papi_status_t 311 papiPrinterDisable(papi_service_t handle, char *name, char *message) 312 { 313 return (_papi_printer_disable_or_pause(handle, name, message, 314 "papiPrinterDisable")); 315 } 316 317 papi_status_t 318 papiPrinterPause(papi_service_t handle, char *name, char *message) 319 { 320 return (_papi_printer_disable_or_pause(handle, name, message, 321 "papiPrinterPause")); 322 } 323 324 papi_status_t 325 papiPrinterEnable(papi_service_t handle, char *name) 326 { 327 return (_papi_printer_enable_or_resume(handle, name, 328 "papiPrinterEnable")); 329 } 330 331 papi_status_t 332 papiPrinterResume(papi_service_t handle, char *name) 333 { 334 return (_papi_printer_enable_or_resume(handle, name, 335 "papiPrinterResume")); 336 } 337 338 static papi_status_t 339 _papi_printer_add_or_modify(papi_service_t handle, char *name, 340 papi_attribute_t **attributes, papi_printer_t *printer, 341 char *function) 342 { 343 papi_status_t result = PAPI_INTERNAL_ERROR; 344 service_t *svc = handle; 345 printer_t *p = NULL; 346 papi_status_t (*f)(); 347 348 if ((svc == NULL) || (name == NULL) || (attributes == NULL)) 349 return (PAPI_BAD_ARGUMENT); 350 351 if ((result = service_connect(svc, name)) != PAPI_OK) 352 return (result); 353 354 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 355 return (PAPI_TEMPORARY_ERROR); 356 357 p->svc = svc; 358 f = (papi_status_t (*)())psm_sym(p->svc, function); 359 if (f != NULL) 360 result = f(svc->svc_handle, svc->name, attributes, 361 &p->printer); 362 363 return (result); 364 } 365 366 papi_status_t 367 papiPrinterAdd(papi_service_t handle, char *name, 368 papi_attribute_t **attributes, papi_printer_t *printer) 369 { 370 return (_papi_printer_add_or_modify(handle, name, attributes, printer, 371 "papiPrinterAdd")); 372 } 373 374 papi_status_t 375 papiPrinterModify(papi_service_t handle, char *name, 376 papi_attribute_t **attributes, papi_printer_t *printer) 377 { 378 return (_papi_printer_add_or_modify(handle, name, attributes, printer, 379 "papiPrinterModify")); 380 } 381 382 383 papi_status_t 384 papiPrinterRemove(papi_service_t handle, char *name) 385 { 386 papi_status_t result = PAPI_INTERNAL_ERROR; 387 service_t *svc = handle; 388 papi_status_t (*f)(); 389 390 if ((svc == NULL) || (name == NULL)) 391 return (PAPI_BAD_ARGUMENT); 392 393 if ((result = service_connect(svc, name)) != PAPI_OK) 394 return (result); 395 396 f = (papi_status_t (*)())psm_sym(svc, "papiPrinterRemove"); 397 if (f != NULL) 398 result = f(svc->svc_handle, svc->name); 399 400 return (result); 401 } 402 403 papi_status_t 404 papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) 405 { 406 papi_status_t result = PAPI_INTERNAL_ERROR; 407 service_t *svc = handle; 408 papi_job_t *svc_jobs = NULL; 409 papi_status_t (*f)(); 410 411 if ((svc == NULL) || (name == NULL)) 412 return (PAPI_BAD_ARGUMENT); 413 414 if ((result = service_connect(svc, name)) != PAPI_OK) 415 return (result); 416 417 f = (papi_status_t (*)())psm_sym(svc, "papiPrinterPurgeJobs"); 418 if (f != NULL) 419 result = f(svc->svc_handle, svc->name, &svc_jobs); 420 421 /* 422 * copy the resulting job object pointers into our own 423 * representation of a job object because we need the 424 * service context to operate against the individual job 425 * objects. We free the list now because we no longer need 426 * it and would have no way of freeing it later. 427 */ 428 if ((result == PAPI_OK) && (svc_jobs != NULL) && (jobs != NULL)) { 429 int i; 430 431 *jobs = NULL; 432 for (i = 0; svc_jobs[i] != NULL; i++) { 433 job_t *j = NULL; 434 435 if ((j = calloc(1, sizeof (*j))) == NULL) 436 return (PAPI_TEMPORARY_ERROR); 437 438 j->svc = svc; 439 j->job = svc_jobs[i]; 440 list_append(jobs, j); 441 } 442 free(svc_jobs); 443 } 444 445 return (result); 446 } 447 448 papi_status_t 449 papiPrinterListJobs(papi_service_t handle, char *name, char **requested_attrs, 450 int type_mask, int max_num_jobs, papi_job_t **jobs) 451 { 452 papi_status_t result = PAPI_INTERNAL_ERROR; 453 service_t *svc = handle; 454 papi_job_t *svc_jobs = NULL; 455 papi_status_t (*f)(); 456 457 if ((svc == NULL) || (name == NULL) || (jobs == NULL)) 458 return (PAPI_BAD_ARGUMENT); 459 460 if ((result = service_connect(svc, name)) != PAPI_OK) 461 return (result); 462 463 f = (papi_status_t (*)())psm_sym(svc, "papiPrinterListJobs"); 464 if (f != NULL) 465 result = f(svc->svc_handle, svc->name, requested_attrs, 466 type_mask, max_num_jobs, &svc_jobs); 467 468 /* 469 * copy the resulting job object pointers into our own 470 * representation of a job object because we need the 471 * service context to operate against the individual job 472 * objects. We free the list now because we no longer need 473 * it and would have no way of freeing it later. 474 */ 475 if ((result == PAPI_OK) && (svc_jobs != NULL)) { 476 int i; 477 478 *jobs = NULL; 479 for (i = 0; svc_jobs[i] != NULL; i++) { 480 job_t *j = NULL; 481 482 if ((j = calloc(1, sizeof (*j))) == NULL) 483 return (PAPI_TEMPORARY_ERROR); 484 485 j->svc = svc; 486 j->job = svc_jobs[i]; 487 list_append(jobs, j); 488 } 489 free(svc_jobs); 490 } 491 492 return (result); 493 } 494 495 papi_attribute_t ** 496 papiPrinterGetAttributeList(papi_printer_t printer) 497 { 498 papi_attribute_t **result = NULL; 499 printer_t *p = printer; 500 501 if ((p != NULL) && (p->printer != NULL)) { 502 papi_attribute_t **(*f)(); 503 504 f = (papi_attribute_t **(*)())psm_sym(p->svc, 505 "papiPrinterGetAttributeList"); 506 if (f != NULL) 507 result = f(p->printer); 508 } else 509 result = p->attributes; 510 511 return (result); 512 } 513