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 * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /*LINTLIBRARY*/ 27 28 #include <stdlib.h> 29 #include <string.h> 30 #include <libintl.h> 31 #include <papi_impl.h> 32 #include <lp.h> 33 34 extern int isclass(char *); 35 36 void 37 papiPrinterFree(papi_printer_t printer) 38 { 39 printer_t *tmp = printer; 40 41 if (tmp != NULL) { 42 papiAttributeListFree(tmp->attributes); 43 free(tmp); 44 } 45 } 46 47 void 48 papiPrinterListFree(papi_printer_t *printers) 49 { 50 if (printers != NULL) { 51 int i; 52 53 for (i = 0; printers[i] != NULL; i++) 54 papiPrinterFree(printers[i]); 55 free(printers); 56 } 57 } 58 59 papi_status_t 60 papiPrintersList(papi_service_t handle, char **requested_attrs, 61 papi_filter_t *filter, papi_printer_t **printers) 62 { 63 service_t *svc = handle; 64 printer_t *p = NULL; 65 short status = MOK; 66 char *printer = NULL, 67 *form = NULL, 68 *request_id = NULL, 69 *character_set = NULL, 70 *reject_reason = NULL, 71 *disable_reason = NULL; 72 short printer_status = 0; 73 long enable_date = 0, reject_date = 0; 74 75 if ((handle == NULL) || (printers == NULL)) 76 return (PAPI_BAD_ARGUMENT); 77 78 if ((filter == NULL) || 79 ((filter->filter.bitmask.mask & PAPI_PRINTER_LOCAL) == 80 (filter->filter.bitmask.value & PAPI_PRINTER_LOCAL))) { 81 /* ask the spooler for the printer(s) and state */ 82 if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, NAME_ALL) < 0) 83 return (PAPI_SERVICE_UNAVAILABLE); 84 85 do { 86 if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, 87 &printer, &form, &character_set, 88 &disable_reason, &reject_reason, 89 &printer_status, &request_id, 90 &enable_date, &reject_date) < 0) 91 return (PAPI_SERVICE_UNAVAILABLE); 92 93 if ((p = calloc(1, sizeof (*p))) == NULL) 94 return (PAPI_TEMPORARY_ERROR); 95 96 lpsched_printer_configuration_to_attributes(svc, p, 97 printer); 98 99 printer_status_to_attributes(p, printer, form, 100 character_set, disable_reason, 101 reject_reason, printer_status, 102 request_id, enable_date, reject_date); 103 104 list_append(printers, p); 105 106 } while (status == MOKMORE); 107 } 108 109 if ((filter == NULL) || 110 ((filter->filter.bitmask.mask & PAPI_PRINTER_CLASS) == 111 (filter->filter.bitmask.value & PAPI_PRINTER_CLASS))) { 112 /* ask the spooler for the class(es) and state */ 113 if (snd_msg(svc, S_INQUIRE_CLASS, NAME_ALL) < 0) 114 return (PAPI_SERVICE_UNAVAILABLE); 115 116 do { 117 if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &printer, 118 &printer_status, &reject_reason, 119 &reject_date) < 0) 120 return (PAPI_SERVICE_UNAVAILABLE); 121 122 if ((p = calloc(1, sizeof (*p))) == NULL) 123 return (PAPI_TEMPORARY_ERROR); 124 125 lpsched_class_configuration_to_attributes(svc, p, 126 printer); 127 128 class_status_to_attributes(p, printer, printer_status, 129 reject_reason, reject_date); 130 131 list_append(printers, p); 132 133 } while (status == MOKMORE); 134 } 135 136 return (PAPI_OK); 137 } 138 139 papi_status_t 140 papiPrinterQuery(papi_service_t handle, char *name, 141 char **requested_attrs, 142 papi_attribute_t **job_attrs, 143 papi_printer_t *printer) 144 { 145 papi_status_t pst; 146 service_t *svc = handle; 147 printer_t *p = NULL; 148 char *dest; 149 short status = MOK; 150 char *pname = NULL, 151 *form = NULL, 152 *request_id = NULL, 153 *character_set = NULL, 154 *reject_reason = NULL, 155 *disable_reason = NULL; 156 short printer_status = 0; 157 long enable_date = 0, reject_date = 0; 158 159 if ((handle == NULL) || (name == NULL) || (printer == NULL)) 160 return (PAPI_BAD_ARGUMENT); 161 162 if ((*printer = p = calloc(1, sizeof (*p))) == NULL) 163 return (PAPI_TEMPORARY_ERROR); 164 165 dest = printer_name_from_uri_id(name, -1); 166 167 if (strcmp(dest, "_default") == 0) { 168 static char *_default; 169 170 if (_default == NULL) { 171 int fd; 172 static char buf[128]; 173 174 if ((fd = open("/etc/lp/default", O_RDONLY)) >= 0) { 175 read(fd, buf, sizeof (buf)); 176 close(fd); 177 _default = strtok(buf, " \t\n"); 178 } 179 } 180 dest = _default; 181 } 182 183 if (isprinter(dest) != 0) { 184 pst = lpsched_printer_configuration_to_attributes(svc, p, dest); 185 if (pst != PAPI_OK) 186 return (pst); 187 188 /* get the spooler status data now */ 189 if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, dest) < 0) 190 return (PAPI_SERVICE_UNAVAILABLE); 191 192 if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, &pname, 193 &form, &character_set, &disable_reason, 194 &reject_reason, &printer_status, &request_id, 195 &enable_date, &reject_date) < 0) 196 return (PAPI_SERVICE_UNAVAILABLE); 197 198 printer_status_to_attributes(p, pname, form, character_set, 199 disable_reason, reject_reason, printer_status, 200 request_id, enable_date, reject_date); 201 } else if (isclass(dest) != 0) { 202 pst = lpsched_class_configuration_to_attributes(svc, p, dest); 203 if (pst != PAPI_OK) 204 return (pst); 205 206 /* get the spooler status data now */ 207 if (snd_msg(svc, S_INQUIRE_CLASS, dest) < 0) 208 return (PAPI_SERVICE_UNAVAILABLE); 209 210 if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &pname, 211 &printer_status, &reject_reason, 212 &reject_date) < 0) 213 return (PAPI_SERVICE_UNAVAILABLE); 214 215 class_status_to_attributes(p, pname, printer_status, 216 reject_reason, reject_date); 217 } else if (strcmp(dest, "PrintService") == 0) { 218 /* fill the printer object with service information */ 219 lpsched_service_information(&p->attributes); 220 } else 221 return (PAPI_NOT_FOUND); 222 223 free(dest); 224 225 return (PAPI_OK); 226 } 227 228 papi_status_t 229 papiPrinterAdd(papi_service_t handle, char *name, 230 papi_attribute_t **attributes, papi_printer_t *result) 231 { 232 papi_status_t status; 233 printer_t *p = NULL; 234 char *dest; 235 236 if ((handle == NULL) || (name == NULL) || (attributes == NULL)) 237 return (PAPI_BAD_ARGUMENT); 238 239 dest = printer_name_from_uri_id(name, -1); 240 241 if (isprinter(dest) != 0) { 242 status = lpsched_add_modify_printer(handle, dest, 243 attributes, 0); 244 245 if ((*result = p = calloc(1, sizeof (*p))) != NULL) 246 lpsched_printer_configuration_to_attributes(handle, p, 247 dest); 248 else 249 status = PAPI_TEMPORARY_ERROR; 250 251 } else if (isclass(dest) != 0) { 252 status = lpsched_add_modify_class(handle, dest, attributes); 253 254 if ((*result = p = calloc(1, sizeof (*p))) != NULL) 255 lpsched_class_configuration_to_attributes(handle, p, 256 dest); 257 else 258 status = PAPI_TEMPORARY_ERROR; 259 260 } else 261 status = PAPI_NOT_FOUND; 262 263 free(dest); 264 265 return (status); 266 } 267 268 papi_status_t 269 papiPrinterModify(papi_service_t handle, char *name, 270 papi_attribute_t **attributes, papi_printer_t *result) 271 { 272 papi_status_t status; 273 printer_t *p = NULL; 274 char *dest; 275 276 if ((handle == NULL) || (name == NULL) || (attributes == NULL)) 277 return (PAPI_BAD_ARGUMENT); 278 279 dest = printer_name_from_uri_id(name, -1); 280 281 if (isprinter(dest) != 0) { 282 status = lpsched_add_modify_printer(handle, dest, 283 attributes, 1); 284 285 if ((*result = p = calloc(1, sizeof (*p))) != NULL) 286 lpsched_printer_configuration_to_attributes(handle, p, 287 dest); 288 else 289 status = PAPI_TEMPORARY_ERROR; 290 } else if (isclass(dest) != 0) { 291 status = lpsched_add_modify_class(handle, dest, attributes); 292 293 if ((*result = p = calloc(1, sizeof (*p))) != NULL) 294 lpsched_class_configuration_to_attributes(handle, p, 295 dest); 296 else 297 status = PAPI_TEMPORARY_ERROR; 298 } else 299 status = PAPI_NOT_FOUND; 300 301 free(dest); 302 303 return (status); 304 } 305 306 papi_status_t 307 papiPrinterRemove(papi_service_t handle, char *name) 308 { 309 papi_status_t result; 310 char *dest; 311 312 if ((handle == NULL) || (name == NULL)) 313 return (PAPI_BAD_ARGUMENT); 314 315 dest = printer_name_from_uri_id(name, -1); 316 317 if (isprinter(dest) != 0) { 318 result = lpsched_remove_printer(handle, dest); 319 } else if (isclass(dest) != 0) { 320 result = lpsched_remove_class(handle, dest); 321 } else 322 result = PAPI_NOT_FOUND; 323 324 free(dest); 325 326 return (result); 327 } 328 329 papi_status_t 330 papiPrinterDisable(papi_service_t handle, char *name, char *message) 331 { 332 papi_status_t result; 333 334 if ((handle == NULL) || (name == NULL)) 335 return (PAPI_BAD_ARGUMENT); 336 337 result = lpsched_disable_printer(handle, name, message); 338 339 return (result); 340 } 341 342 papi_status_t 343 papiPrinterEnable(papi_service_t handle, char *name) 344 { 345 papi_status_t result; 346 347 if ((handle == NULL) || (name == NULL)) 348 return (PAPI_BAD_ARGUMENT); 349 350 result = lpsched_enable_printer(handle, name); 351 352 return (result); 353 } 354 355 papi_status_t 356 papiPrinterPause(papi_service_t handle, char *name, char *message) 357 { 358 papi_status_t result; 359 360 if ((handle == NULL) || (name == NULL)) 361 return (PAPI_BAD_ARGUMENT); 362 363 result = lpsched_reject_printer(handle, name, message); 364 365 return (result); 366 } 367 368 papi_status_t 369 papiPrinterResume(papi_service_t handle, char *name) 370 { 371 papi_status_t result; 372 373 if ((handle == NULL) || (name == NULL)) 374 return (PAPI_BAD_ARGUMENT); 375 376 result = lpsched_accept_printer(handle, name); 377 378 return (result); 379 } 380 381 papi_status_t 382 papiPrinterPurgeJobs(papi_service_t handle, char *name, papi_job_t **jobs) 383 { 384 service_t *svc = handle; 385 papi_status_t result = PAPI_OK_SUBST; 386 short more; 387 long status; 388 char *dest; 389 char *req_id; 390 391 if ((handle == NULL) || (name == NULL)) 392 return (PAPI_BAD_ARGUMENT); 393 394 dest = printer_name_from_uri_id(name, -1); 395 more = snd_msg(svc, S_CANCEL, dest, "", ""); 396 free(dest); 397 if (more < 0) 398 return (PAPI_SERVICE_UNAVAILABLE); 399 400 do { 401 if (rcv_msg(svc, R_CANCEL, &more, &status, &req_id) < 0) 402 return (PAPI_SERVICE_UNAVAILABLE); 403 404 switch (status) { 405 case MOK: 406 papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 407 "canceled-jobs", req_id); 408 break; 409 case M2LATE: 410 case MUNKNOWN: 411 case MNOINFO: 412 papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 413 "cancel-failed", req_id); 414 result = PAPI_DEVICE_ERROR; 415 break; 416 case MNOPERM: 417 papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 418 "cancel-failed", req_id); 419 result = PAPI_NOT_AUTHORIZED; 420 break; 421 default: 422 detailed_error(svc, gettext("cancel failed, bad status (%d)\n"), 423 status); 424 return (PAPI_DEVICE_ERROR); 425 } 426 } while (more == MOKMORE); 427 428 return (result); 429 } 430 431 papi_status_t 432 papiPrinterListJobs(papi_service_t handle, char *name, 433 char **requested_attrs, int type_mask, 434 int max_num_jobs, papi_job_t **jobs) 435 { 436 service_t *svc = handle; 437 char *dest; 438 short rc; 439 int count = 1; 440 441 if ((handle == NULL) || (name == NULL) || (jobs == NULL)) 442 return (PAPI_BAD_ARGUMENT); 443 444 dest = printer_name_from_uri_id(name, -1); 445 446 rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", dest, "", "", ""); 447 free(dest); 448 if (rc < 0) 449 return (PAPI_SERVICE_UNAVAILABLE); 450 451 do { 452 job_t *job = NULL; 453 char *dest = NULL, 454 *ptr, 455 *form = NULL, 456 *req_id = NULL, 457 *charset = NULL, 458 *owner = NULL, 459 *slabel = NULL, 460 *file = NULL; 461 char request_file[128]; 462 time_t date = 0; 463 size_t size = 0; 464 short rank = 0, state = 0; 465 466 if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &req_id, 467 &owner, &slabel, &size, &date, &state, &dest, 468 &form, &charset, &rank, &file) < 0) 469 return (PAPI_SERVICE_UNAVAILABLE); 470 471 if ((rc != MOK) && (rc != MOKMORE)) 472 continue; 473 /* 474 * at this point, we should check to see if the job matches the 475 * selection criterion defined in "type_mask". 476 */ 477 478 /* too many yet? */ 479 if ((max_num_jobs != 0) && (count++ > max_num_jobs)) 480 continue; 481 482 if ((job = calloc(1, sizeof (*job))) == NULL) 483 continue; 484 485 /* Request file is <req_id>-0 */ 486 if ((ptr = strrchr(req_id, '-')) != NULL) { 487 ++ptr; 488 snprintf(request_file, sizeof (request_file), 489 "%s-0", ptr); 490 } 491 492 lpsched_read_job_configuration(svc, job, request_file); 493 494 job_status_to_attributes(job, req_id, owner, slabel, size, 495 date, state, dest, form, charset, rank, file); 496 497 list_append(jobs, job); 498 499 } while (rc == MOKMORE); 500 501 if (rc == MNOINFO) /* If no jobs are found, it's still ok */ 502 rc = MOK; 503 504 return (lpsched_status_to_papi_status(rc)); 505 } 506 507 papi_attribute_t ** 508 papiPrinterGetAttributeList(papi_printer_t printer) 509 { 510 printer_t *tmp = printer; 511 512 if (tmp == NULL) 513 return (NULL); 514 515 return (tmp->attributes); 516 } 517