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, const char **requested_attrs, 63 const 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, const char *name, 143 const char **requested_attrs, 144 const 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 (isprinter(dest) != 0) { 170 pst = lpsched_printer_configuration_to_attributes(svc, p, dest); 171 if (pst != PAPI_OK) 172 return (pst); 173 174 /* get the spooler status data now */ 175 if (snd_msg(svc, S_INQUIRE_PRINTER_STATUS, dest) < 0) 176 return (PAPI_SERVICE_UNAVAILABLE); 177 178 if (rcv_msg(svc, R_INQUIRE_PRINTER_STATUS, &status, &pname, 179 &form, &character_set, &disable_reason, 180 &reject_reason, &printer_status, &request_id, 181 &enable_date, &reject_date) < 0) 182 return (PAPI_SERVICE_UNAVAILABLE); 183 184 printer_status_to_attributes(p, pname, form, character_set, 185 disable_reason, reject_reason, printer_status, 186 request_id, enable_date, reject_date); 187 } else if (isclass(dest) != 0) { 188 pst = lpsched_class_configuration_to_attributes(svc, p, dest); 189 if (pst != PAPI_OK) 190 return (pst); 191 192 /* get the spooler status data now */ 193 if (snd_msg(svc, S_INQUIRE_CLASS, dest) < 0) 194 return (PAPI_SERVICE_UNAVAILABLE); 195 196 if (rcv_msg(svc, R_INQUIRE_CLASS, &status, &pname, 197 &printer_status, &reject_reason, 198 &reject_date) < 0) 199 return (PAPI_SERVICE_UNAVAILABLE); 200 201 class_status_to_attributes(p, pname, printer_status, 202 reject_reason, reject_date); 203 } else if (strcmp(dest, "PrintService") == 0) { 204 /* fill the printer object with service information */ 205 lpsched_service_information(p); 206 } else 207 return (PAPI_NOT_FOUND); 208 209 free(dest); 210 211 return (PAPI_OK); 212 } 213 214 papi_status_t 215 papiPrinterModify(papi_service_t handle, const char *name, 216 const papi_attribute_t **attributes, papi_printer_t *result) 217 { 218 service_t *svc = handle; 219 220 if ((svc == NULL) || (name == NULL) || (attributes == NULL)) 221 return (PAPI_BAD_ARGUMENT); 222 223 return (PAPI_OPERATION_NOT_SUPPORTED); 224 } 225 226 papi_status_t 227 papiPrinterPause(papi_service_t handle, const char *name, const char *message) 228 { 229 papi_status_t result; 230 231 if ((handle == NULL) || (name == NULL)) 232 return (PAPI_BAD_ARGUMENT); 233 234 result = lpsched_disable_printer(handle, name, message); 235 236 return (result); 237 } 238 239 papi_status_t 240 papiPrinterResume(papi_service_t handle, const char *name) 241 { 242 papi_status_t result; 243 244 if ((handle == NULL) || (name == NULL)) 245 return (PAPI_BAD_ARGUMENT); 246 247 result = lpsched_enable_printer(handle, name); 248 249 return (result); 250 } 251 252 papi_status_t 253 papiPrinterPurgeJobs(papi_service_t handle, const char *name, papi_job_t **jobs) 254 { 255 service_t *svc = handle; 256 papi_status_t result = PAPI_OK_SUBST; 257 short more; 258 long status; 259 char *dest; 260 char *req_id; 261 262 if ((handle == NULL) || (name == NULL)) 263 return (PAPI_BAD_ARGUMENT); 264 265 dest = printer_name_from_uri_id(name, -1); 266 if (snd_msg(svc, S_CANCEL, dest, "", "") < 0) 267 return (PAPI_SERVICE_UNAVAILABLE); 268 269 free(dest); 270 271 do { 272 if (rcv_msg(svc, R_CANCEL, &more, &status, &req_id) < 0) 273 return (PAPI_SERVICE_UNAVAILABLE); 274 275 switch (status) { 276 case MOK: 277 papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 278 "canceled-jobs", req_id); 279 break; 280 case M2LATE: 281 case MUNKNOWN: 282 case MNOINFO: 283 papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 284 "cancel-failed", req_id); 285 result = PAPI_DEVICE_ERROR; 286 break; 287 case MNOPERM: 288 papiAttributeListAddString(&svc->attributes, PAPI_ATTR_APPEND, 289 "cancel-failed", req_id); 290 result = PAPI_NOT_AUTHORIZED; 291 break; 292 default: 293 detailed_error(svc, gettext("cancel failed, bad status (%d)\n"), 294 status); 295 return (PAPI_DEVICE_ERROR); 296 } 297 } while (more == MOKMORE); 298 299 return (result); 300 } 301 302 papi_status_t 303 papiPrinterListJobs(papi_service_t handle, const char *name, 304 const char **requested_attrs, const int type_mask, 305 const int max_num_jobs, papi_job_t **jobs) 306 { 307 service_t *svc = handle; 308 char *dest; 309 short rc; 310 int count = 1; 311 312 if ((handle == NULL) || (name == NULL) || (jobs == NULL)) 313 return (PAPI_BAD_ARGUMENT); 314 315 dest = printer_name_from_uri_id(name, -1); 316 317 rc = snd_msg(svc, S_INQUIRE_REQUEST_RANK, 0, "", dest, "", "", ""); 318 free(dest); 319 if (rc < 0) 320 return (PAPI_SERVICE_UNAVAILABLE); 321 322 do { 323 job_t *job = NULL; 324 char *dest = NULL, 325 *ptr, 326 *form = NULL, 327 *req_id = NULL, 328 *charset = NULL, 329 *owner = NULL, 330 *slabel = NULL, 331 *file = NULL; 332 time_t date = 0; 333 size_t size = 0; 334 short rank = 0, state = 0; 335 336 if (rcv_msg(svc, R_INQUIRE_REQUEST_RANK, &rc, &req_id, 337 &owner, &slabel, &size, &date, &state, &dest, 338 &form, &charset, &rank, &file) < 0) 339 return (PAPI_SERVICE_UNAVAILABLE); 340 341 if ((rc != MOK) && (rc != MOKMORE)) 342 continue; 343 /* 344 * at this point, we should check to see if the job matches the 345 * selection criterion defined in "type_mask". 346 */ 347 348 /* too many yet? */ 349 if ((max_num_jobs != 0) && (count++ > max_num_jobs)) 350 continue; 351 352 if ((job = calloc(1, sizeof (*job))) == NULL) 353 continue; 354 355 job_status_to_attributes(job, req_id, owner, slabel, size, 356 date, state, dest, form, charset, rank, file); 357 358 if ((ptr = strrchr(file, '-')) != NULL) { 359 *++ptr = '0'; 360 *++ptr = NULL; 361 } 362 363 lpsched_read_job_configuration(svc, job, file); 364 365 list_append(jobs, job); 366 367 } while (rc == MOKMORE); 368 369 if (rc == MNOINFO) /* If no jobs are found, it's still ok */ 370 rc = MOK; 371 372 return (lpsched_status_to_papi_status(rc)); 373 } 374 375 papi_attribute_t ** 376 papiPrinterGetAttributeList(papi_printer_t printer) 377 { 378 printer_t *tmp = printer; 379 380 if (tmp == NULL) 381 return (NULL); 382 383 return (tmp->attributes); 384 } 385