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