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 2007 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, -1); 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, name, -1); 160 161 if (requested_attrs != NULL) { 162 int i; 163 164 for (i = 0; requested_attrs[i] != NULL; i++) 165 papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 166 "requested-attributes", requested_attrs[i]); 167 } 168 169 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 170 "operational-attributes-group", op); 171 papiAttributeListFree(op); 172 result = ipp_send_request(svc, request, &response); 173 papiAttributeListFree(request); 174 175 op = NULL; 176 papiAttributeListGetCollection(response, NULL, 177 "printer-attributes-group", &op); 178 copy_attributes(&p->attributes, op); 179 papiAttributeListFree(response); 180 181 return (result); 182 } 183 184 static papi_status_t 185 _printer_enable_disable_pause_resume_delete(papi_service_t handle, char *name, 186 char *message, uint16_t type) 187 { 188 papi_status_t result = PAPI_INTERNAL_ERROR; 189 service_t *svc = handle; 190 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 191 192 if ((svc == NULL) || (name == NULL)) 193 return (PAPI_BAD_ARGUMENT); 194 195 /* if we are already connected, use that connection. */ 196 if (svc->connection == NULL) 197 if ((result = service_connect(svc, name)) != PAPI_OK) 198 return (result); 199 200 ipp_initialize_request(svc, &request, type); 201 202 ipp_initialize_operational_attributes(svc, &op, name, -1); 203 204 switch (type) { 205 case OPID_DISABLE_PRINTER: 206 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, 207 "printer-message-from-operator", message); 208 break; 209 case OPID_PAUSE_PRINTER: 210 papiAttributeListAddString(&op, PAPI_ATTR_REPLACE, 211 "printer-state-message", message); 212 break; 213 default: /* a message value is of no use */ 214 break; 215 } 216 217 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 218 "operational-attributes-group", op); 219 papiAttributeListFree(op); 220 result = ipp_send_request(svc, request, &response); 221 papiAttributeListFree(request); 222 papiAttributeListFree(response); 223 224 return (result); 225 } 226 227 papi_status_t 228 papiPrinterEnable(papi_service_t handle, char *name) 229 { 230 return (_printer_enable_disable_pause_resume_delete(handle, name, 231 NULL, OPID_ENABLE_PRINTER)); 232 } 233 234 papi_status_t 235 papiPrinterResume(papi_service_t handle, char *name) 236 { 237 return (_printer_enable_disable_pause_resume_delete(handle, name, 238 NULL, OPID_RESUME_PRINTER)); 239 } 240 241 papi_status_t 242 papiPrinterPause(papi_service_t handle, char *name, char *message) 243 { 244 return (_printer_enable_disable_pause_resume_delete(handle, name, 245 message, OPID_PAUSE_PRINTER)); 246 } 247 248 papi_status_t 249 papiPrinterDisable(papi_service_t handle, char *name, char *message) 250 { 251 return (_printer_enable_disable_pause_resume_delete(handle, name, 252 message, OPID_PAUSE_PRINTER)); 253 } 254 255 /* 256 * there is no IPP create operation, the set-printer-attibutes operation 257 * is the closest we have, so we will assume that the server will create 258 * a printer and set attributes if there is none. 259 */ 260 papi_status_t 261 papiPrinterAdd(papi_service_t handle, char *name, 262 papi_attribute_t **attributes, papi_printer_t *printer) 263 { 264 return (papiPrinterModify(handle, name, attributes, printer)); 265 } 266 267 papi_status_t 268 papiPrinterModify(papi_service_t handle, char *name, 269 papi_attribute_t **attributes, papi_printer_t *printer) 270 { 271 papi_status_t result = PAPI_INTERNAL_ERROR; 272 service_t *svc = handle; 273 printer_t *p = NULL; 274 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 275 276 if ((svc == NULL) || (name == NULL) || (printer == NULL)) 277 return (PAPI_BAD_ARGUMENT); 278 279 /* if we are already connected, use that connection. */ 280 if (svc->connection == NULL) 281 if ((result = service_connect(svc, name)) != PAPI_OK) 282 return (result); 283 284 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 285 return (PAPI_TEMPORARY_ERROR); 286 287 ipp_initialize_request(svc, &request, OPID_SET_PRINTER_ATTRIBUTES); 288 289 ipp_initialize_operational_attributes(svc, &op, name, -1); 290 291 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 292 "operational-attributes-group", op); 293 papiAttributeListFree(op); 294 295 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 296 "printer-attributes-group", attributes); 297 result = ipp_send_request(svc, request, &response); 298 papiAttributeListFree(request); 299 300 op = NULL; 301 papiAttributeListGetCollection(response, NULL, 302 "printer-attributes-group", &op); 303 copy_attributes(&p->attributes, op); 304 papiAttributeListFree(response); 305 306 return (result); 307 } 308 309 papi_status_t 310 papiPrinterRemove(papi_service_t handle, char *name) 311 { 312 return (_printer_enable_disable_pause_resume_delete(handle, name, 313 NULL, OPID_CUPS_DELETE_PRINTER)); 314 } 315 316 papi_status_t 317 papiPrinterPurgeJobs(papi_service_t handle, char *name, 318 papi_job_t **jobs) 319 { 320 papi_status_t status, result = PAPI_INTERNAL_ERROR; 321 service_t *svc = handle; 322 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 323 void *iter = NULL; 324 325 326 if ((svc == NULL) || (name == NULL)) 327 return (PAPI_BAD_ARGUMENT); 328 329 /* if we are already connected, use that connection. */ 330 if (svc->connection == NULL) 331 if ((result = service_connect(svc, name)) != PAPI_OK) 332 return (result); 333 334 ipp_initialize_request(svc, &request, OPID_PURGE_JOBS); 335 336 ipp_initialize_operational_attributes(svc, &op, name, -1); 337 338 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 339 "operational-attributes-group", op); 340 papiAttributeListFree(op); 341 result = ipp_send_request(svc, request, &response); 342 papiAttributeListFree(request); 343 344 op = NULL; 345 for (status = papiAttributeListGetCollection(response, &iter, 346 "job-attributes-group", &op); 347 status == PAPI_OK; 348 status = papiAttributeListGetCollection(response, &iter, 349 NULL, &op)) { 350 job_t *j = NULL; 351 352 if ((j = calloc(1, sizeof (*j))) == NULL) 353 return (PAPI_TEMPORARY_ERROR); 354 355 copy_attributes(&j->attributes, op); 356 op = NULL; 357 list_append(jobs, j); 358 } 359 papiAttributeListFree(response); 360 361 return (result); 362 } 363 364 papi_status_t 365 papiPrinterListJobs(papi_service_t handle, char *name, 366 char **requested_attrs, int type_mask, 367 int max_num_jobs, papi_job_t **jobs) 368 { 369 papi_status_t status, result = PAPI_INTERNAL_ERROR; 370 service_t *svc = handle; 371 papi_attribute_t **request = NULL, **op = NULL, **response = NULL; 372 void *iter = NULL; 373 374 if ((svc == NULL) || (name == NULL)) 375 return (PAPI_BAD_ARGUMENT); 376 377 /* if we are already connected, use that connection. */ 378 if (svc->connection == NULL) 379 if ((result = service_connect(svc, name)) != PAPI_OK) 380 return (result); 381 382 ipp_initialize_request(svc, &request, OPID_GET_JOBS); 383 384 ipp_initialize_operational_attributes(svc, &op, name, -1); 385 386 if (requested_attrs != NULL) { 387 int i; 388 389 for (i = 0; requested_attrs[i] != NULL; i++) 390 papiAttributeListAddString(&op, PAPI_ATTR_APPEND, 391 "requested-attributes", requested_attrs[i]); 392 } 393 394 papiAttributeListAddCollection(&request, PAPI_ATTR_REPLACE, 395 "operational-attributes-group", op); 396 papiAttributeListFree(op); 397 result = ipp_send_request(svc, request, &response); 398 papiAttributeListFree(request); 399 400 op = NULL; 401 for (status = papiAttributeListGetCollection(response, &iter, 402 "job-attributes-group", &op); 403 status == PAPI_OK; 404 status = papiAttributeListGetCollection(response, &iter, 405 NULL, &op)) { 406 job_t *j = NULL; 407 408 if ((j = calloc(1, sizeof (*j))) == NULL) 409 return (PAPI_TEMPORARY_ERROR); 410 411 copy_attributes(&j->attributes, op); 412 op = NULL; 413 list_append(jobs, j); 414 } 415 papiAttributeListFree(response); 416 417 return (result); 418 } 419 420 papi_attribute_t ** 421 papiPrinterGetAttributeList(papi_printer_t printer) 422 { 423 papi_attribute_t **result = NULL; 424 printer_t *p = printer; 425 426 if (p != NULL) 427 result = p->attributes; 428 429 return (result); 430 } 431