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