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 146 2006-03-24 00:26:54Z 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 #include <config-site.h> 38 39 void 40 papiPrinterFree(papi_printer_t printer) 41 { 42 printer_t *tmp = printer; 43 44 if (tmp != NULL) { 45 if (tmp->attributes != NULL) 46 papiAttributeListFree(tmp->attributes); 47 free(tmp); 48 } 49 } 50 51 void 52 papiPrinterListFree(papi_printer_t *printers) 53 { 54 if (printers != NULL) { 55 int i; 56 57 for (i = 0; printers[i] != NULL; i++) 58 papiPrinterFree(printers[i]); 59 free(printers); 60 } 61 } 62 63 /* 64 * Enumeration of printers is not part of the IPP specification, so many 65 * servers will probably not respond back with a list of printers, but 66 * CUPS has implemented an extension to IPP to enumerate printers and 67 * classes. the Apache/mod_ipp IPP listener module available in Solaris 68 * implements this IPP extension, so CUPS and Solaris can provide this 69 * to IPP clients. 70 */ 71 #ifndef OPID_CUPS_GET_PRINTERS /* for servers that will enumerate */ 72 #define OPID_CUPS_GET_PRINTERS 0x4002 73 #endif /* OPID_CUPS_GET_PRINTERS */ 74 #ifndef OPID_CUPS_DELETE_PRINTER /* for servers that can delete */ 75 #define OPID_CUPS_DELETE_PRINTER 0x4004 76 #endif /* OPID_CUPS_DELETE_PRINTER */ 77 #ifndef OPID_CUPS_GET_CLASSES /* for servers that will enumerate */ 78 #define OPID_CUPS_GET_CLASSES 0x4005 79 #endif /* OPID_CUPS_GET_CLASSES */ 80 81 papi_status_t 82 papiPrintersList(papi_service_t handle, char **requested_attrs, 83 papi_filter_t *filter, papi_printer_t **printers) 84 { 85 papi_status_t status, result = PAPI_INTERNAL_ERROR; 86 service_t *svc = handle; 87 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 88 void *iter = NULL; 89 90 if ((svc == NULL) || (printers == NULL)) 91 return (PAPI_BAD_ARGUMENT); 92 93 /* if we are already connected, use that connection. */ 94 if (svc->connection == NULL) 95 if ((result = service_connect(svc, DEFAULT_DEST)) != PAPI_OK) 96 return (result); 97 ipp_initialize_request(svc, &request, OPID_CUPS_GET_PRINTERS); 98 99 ipp_initialize_operational_attributes(svc, &op, NULL); 100 101 if (requested_attrs != NULL) { 102 int i; 103 104 for (i = 0; requested_attrs[i] != NULL; i++) 105 papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 106 "requested-attributes", requested_attrs[i]); 107 } 108 109 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 110 "operational-attributes-group", op); 111 papiAttributeListFree(op); 112 result = ipp_send_request(svc, request, &response); 113 papiAttributeListFree(request); 114 115 op = NULL; 116 for (status = papiAttributeListGetCollection(response, &iter, 117 "printer-attributes-group", &op); 118 status == PAPI_OK; 119 status = papiAttributeListGetCollection(response, &iter, 120 NULL, &op)) { 121 printer_t *p = NULL; 122 123 if ((p = calloc(1, sizeof (*p))) == NULL) 124 return (PAPI_TEMPORARY_ERROR); 125 126 copy_attributes(&p->attributes, op); 127 op = NULL; 128 list_append(printers, p); 129 } 130 papiAttributeListFree(response); 131 132 return (result); 133 } 134 135 papi_status_t 136 papiPrinterQuery(papi_service_t handle, char *name, 137 char **requested_attrs, 138 papi_attribute_t **job_attributes, 139 papi_printer_t *printer) 140 { 141 papi_status_t result = PAPI_INTERNAL_ERROR; 142 service_t *svc = handle; 143 printer_t *p = NULL; 144 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 145 146 if ((svc == NULL) || (name == NULL) || (printer == NULL)) 147 return (PAPI_BAD_ARGUMENT); 148 149 /* if we are already connected, use that connection. */ 150 if (svc->connection == NULL) 151 if ((result = service_connect(svc, name)) != PAPI_OK) 152 return (result); 153 154 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 155 return (PAPI_TEMPORARY_ERROR); 156 157 ipp_initialize_request(svc, &request, OPID_GET_PRINTER_ATTRIBUTES); 158 159 ipp_initialize_operational_attributes(svc, &op, NULL); 160 ipp_add_printer_uri(svc, name, &op); 161 162 if (requested_attrs != NULL) { 163 int i; 164 165 for (i = 0; requested_attrs[i] != NULL; i++) 166 papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 167 "requested-attributes", requested_attrs[i]); 168 } 169 170 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 171 "operational-attributes-group", op); 172 papiAttributeListFree(op); 173 result = ipp_send_request(svc, request, &response); 174 papiAttributeListFree(request); 175 176 op = NULL; 177 papiAttributeListGetCollection(response, NULL, 178 "printer-attributes-group", &op); 179 copy_attributes(&p->attributes, op); 180 papiAttributeListFree(response); 181 182 return (result); 183 } 184 185 static papi_status_t 186 _printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name, 187 char *message, uint16_t type) 188 { 189 papi_status_t result = PAPI_INTERNAL_ERROR; 190 service_t *svc = handle; 191 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 192 193 if ((svc == NULL) || (name == NULL)) 194 return (PAPI_BAD_ARGUMENT); 195 196 /* if we are already connected, use that connection. */ 197 if (svc->connection == NULL) 198 if ((result = service_connect(svc, name)) != PAPI_OK) 199 return (result); 200 201 ipp_initialize_request(svc, &request, type); 202 203 ipp_initialize_operational_attributes(svc, &op, NULL); 204 ipp_add_printer_uri(svc, name, &op); 205 206 switch (type) { 207 case OPID_DISABLE_PRINTER: 208 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, 209 "printer-message-from-operator", message); 210 break; 211 case OPID_PAUSE_PRINTER: 212 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, 213 "printer-state-message", message); 214 break; 215 default: /* a message value is of no use */ 216 break; 217 } 218 219 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 220 "operational-attributes-group", op); 221 papiAttributeListFree(op); 222 result = ipp_send_request(svc, request, &response); 223 papiAttributeListFree(request); 224 papiAttributeListFree(response); 225 226 return (result); 227 } 228 229 papi_status_t 230 papiPrinterEnable(papi_service_t handle, char *name) 231 { 232 return (_printer_enable_disable_pause_resume_delete(handle, name, 233 NULL, OPID_ENABLE_PRINTER)); 234 } 235 236 papi_status_t 237 papiPrinterResume(papi_service_t handle, char *name) 238 { 239 return (_printer_enable_disable_pause_resume_delete(handle, name, 240 NULL, OPID_RESUME_PRINTER)); 241 } 242 243 papi_status_t 244 papiPrinterPause(papi_service_t handle, char *name, char *message) 245 { 246 return (_printer_enable_disable_pause_resume_delete(handle, name, 247 message, OPID_PAUSE_PRINTER)); 248 } 249 250 papi_status_t 251 papiPrinterDisable(papi_service_t handle, char *name, char *message) 252 { 253 return (_printer_enable_disable_pause_resume_delete(handle, name, 254 message, OPID_PAUSE_PRINTER)); 255 } 256 257 /* 258 * there is no IPP create operation, the set-printer-attibutes operation 259 * is the closest we have, so we will assume that the server will create 260 * a printer and set attributes if there is none. 261 */ 262 papi_status_t 263 papiPrinterAdd(papi_service_t handle, char *name, 264 papi_attribute_t **attributes, papi_printer_t *printer) 265 { 266 return (papiPrinterModify(handle, name, attributes, printer)); 267 } 268 269 papi_status_t 270 papiPrinterModify(papi_service_t handle, char *name, 271 papi_attribute_t **attributes, papi_printer_t *printer) 272 { 273 papi_status_t result = PAPI_INTERNAL_ERROR; 274 service_t *svc = handle; 275 printer_t *p = NULL; 276 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 277 278 if ((svc == NULL) || (name == NULL) || (printer == NULL)) 279 return (PAPI_BAD_ARGUMENT); 280 281 /* if we are already connected, use that connection. */ 282 if (svc->connection == NULL) 283 if ((result = service_connect(svc, name)) != PAPI_OK) 284 return (result); 285 286 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 287 return (PAPI_TEMPORARY_ERROR); 288 289 ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES); 290 291 ipp_initialize_operational_attributes(svc, &op, NULL); 292 ipp_add_printer_uri(svc, name, &op); 293 294 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 295 "operational-attributes-group", op); 296 papiAttributeListFree(op); 297 298 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 299 "printer-attributes-group", attributes); 300 result = ipp_send_request(svc, request, &response); 301 papiAttributeListFree(request); 302 303 op = NULL; 304 papiAttributeListGetCollection(response, NULL, 305 "printer-attributes-group", &op); 306 copy_attributes(&p->attributes, op); 307 papiAttributeListFree(response); 308 309 return (result); 310 } 311 312 papi_status_t 313 papiPrinterRemove(papi_service_t handle, char *name) 314 { 315 return (_printer_enable_disable_pause_resume_delete(handle, name, 316 NULL, OPID_CUPS_DELETE_PRINTER)); 317 } 318 319 papi_status_t 320 papiPrinterPurgeJobs(papi_service_t handle, char *name, 321 papi_job_t **jobs) 322 { 323 papi_status_t status, result = PAPI_INTERNAL_ERROR; 324 service_t *svc = handle; 325 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 326 void *iter = NULL; 327 328 329 if ((svc == NULL) || (name == NULL)) 330 return (PAPI_BAD_ARGUMENT); 331 332 /* if we are already connected, use that connection. */ 333 if (svc->connection == NULL) 334 if ((result = service_connect(svc, name)) != PAPI_OK) 335 return (result); 336 337 ipp_initialize_request(svc, &request, OPID_PURGE_JOBS); 338 339 ipp_initialize_operational_attributes(svc, &op, NULL); 340 ipp_add_printer_uri(svc, name, &op); 341 342 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 343 "operational-attributes-group", op); 344 papiAttributeListFree(op); 345 result = ipp_send_request(svc, request, &response); 346 papiAttributeListFree(request); 347 348 op = NULL; 349 for (status = papiAttributeListGetCollection(response, &iter, 350 "job-attributes-group", &op); 351 status == PAPI_OK; 352 status = papiAttributeListGetCollection(response, &iter, 353 NULL, &op)) { 354 job_t *j = NULL; 355 356 if ((j = calloc(1, sizeof (*j))) == NULL) 357 return (PAPI_TEMPORARY_ERROR); 358 359 copy_attributes(&j->attributes, op); 360 op = NULL; 361 list_append(jobs, j); 362 } 363 papiAttributeListFree(response); 364 365 return (result); 366 } 367 368 papi_status_t 369 papiPrinterListJobs(papi_service_t handle, char *name, 370 char **requested_attrs, int type_mask, 371 int max_num_jobs, papi_job_t **jobs) 372 { 373 papi_status_t status, result = PAPI_INTERNAL_ERROR; 374 service_t *svc = handle; 375 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 376 void *iter = NULL; 377 378 if ((svc == NULL) || (name == NULL)) 379 return (PAPI_BAD_ARGUMENT); 380 381 /* if we are already connected, use that connection. */ 382 if (svc->connection == NULL) 383 if ((result = service_connect(svc, name)) != PAPI_OK) 384 return (result); 385 386 ipp_initialize_request(svc, &request, OPID_GET_JOBS); 387 388 ipp_initialize_operational_attributes(svc, &op, NULL); 389 ipp_add_printer_uri(svc, name, &op); 390 391 if (requested_attrs != NULL) { 392 int i; 393 394 for (i = 0; requested_attrs[i] != NULL; i++) 395 papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 396 "requested-attributes", requested_attrs[i]); 397 } 398 399 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 400 "operational-attributes-group", op); 401 papiAttributeListFree(op); 402 result = ipp_send_request(svc, request, &response); 403 papiAttributeListFree(request); 404 405 op = NULL; 406 for (status = papiAttributeListGetCollection(response, &iter, 407 "job-attributes-group", &op); 408 status == PAPI_OK; 409 status = papiAttributeListGetCollection(response, &iter, 410 NULL, &op)) { 411 job_t *j = NULL; 412 413 if ((j = calloc(1, sizeof (*j))) == NULL) 414 return (PAPI_TEMPORARY_ERROR); 415 416 copy_attributes(&j->attributes, op); 417 op = NULL; 418 list_append(jobs, j); 419 } 420 papiAttributeListFree(response); 421 422 return (result); 423 } 424 425 papi_attribute_t ** 426 papiPrinterGetAttributeList(papi_printer_t printer) 427 { 428 papi_attribute_t **result = NULL; 429 printer_t *p = printer; 430 431 if (p != NULL) 432 result = p->attributes; 433 434 return (result); 435 } 436