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