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 2009 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 * 26 */ 27 28 /* $Id: lpc.c 146 2006-03-24 00:26:54Z njacobs $ */ 29 30 #include <stdio.h> 31 #include <stdlib.h> 32 #include <unistd.h> 33 #include <string.h> 34 #include <locale.h> 35 #include <libintl.h> 36 #include <papi.h> 37 #include "common.h" 38 39 typedef int (cmd_handler_t)(papi_service_t, char **); 40 41 static papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; 42 43 /* ARGSUSED0 */ 44 static int 45 lpc_exit(papi_service_t svc, char **args) 46 { 47 exit(0); 48 /* NOTREACHED */ 49 return (0); 50 } 51 52 static int 53 lpc_status(papi_service_t svc, char **args) 54 { 55 papi_status_t status; 56 papi_printer_t p = NULL; 57 char *pattrs[] = { "printer-state", "printer-state-reasons", 58 "printer-is-accepting-jobs", NULL }; 59 char *destination = args[1]; 60 61 status = papiPrinterQuery(svc, destination, pattrs, NULL, &p); 62 if (status == PAPI_OK) { 63 papi_attribute_t **list = papiPrinterGetAttributeList(p); 64 char accepting = 0; 65 int32_t state = 0; 66 67 printf("%s:\n", destination); 68 69 (void) papiAttributeListGetBoolean(list, NULL, 70 "printer-is-accepting-jobs", &accepting); 71 printf(gettext("\tqueueing is %s\n"), 72 (accepting ? gettext("enabled") : gettext("disabled"))); 73 74 (void) papiAttributeListGetInteger(list, NULL, 75 "printer-state", &state); 76 printf("\tprinting is %s\n", 77 ((state != 0x05) ? gettext("enabled") : 78 gettext("disabled"))); 79 80 if (state != 0x03) { /* !idle */ 81 papi_job_t *jobs = NULL; 82 int i = 0; 83 84 (void) papiPrinterListJobs(svc, destination, NULL, 85 PAPI_LIST_JOBS_ALL, 0, &jobs); 86 if (jobs != NULL) { 87 for (i = 0; jobs[i] != NULL; i++); 88 papiJobListFree(jobs); 89 } 90 printf(gettext("\t%d entries in spool area\n"), i); 91 } else 92 printf(gettext("\tno entries\n")); 93 94 if (state == 0x04) 95 printf(gettext("\tdaemon present\n")); 96 97 } else { 98 fprintf(stderr, "%s: %s\n", destination, 99 verbose_papi_message(svc, status)); 100 return (-1); 101 } 102 103 papiPrinterFree(p); 104 105 return (0); 106 } 107 108 static int 109 lpc_abort(papi_service_t svc, char **args) 110 { 111 papi_status_t status; 112 char *destination = args[1]; 113 114 if (destination == NULL) { 115 fprintf(stderr, gettext("Usage: abort (destination)\n")); 116 return (-1); 117 } 118 119 status = papiPrinterPause(svc, destination, "paused via lpc abort"); 120 if (status == PAPI_OK) { 121 printf(gettext("%s: processing disabled after current job\n"), 122 destination); 123 } else { 124 fprintf(stderr, "%s: %s\n", destination, 125 verbose_papi_message(svc, status)); 126 } 127 128 return (0); 129 } 130 131 static int 132 lpc_clean(papi_service_t svc, char **args) 133 { 134 papi_status_t status; 135 papi_job_t *jobs = NULL; 136 char *destination = args[1]; 137 138 if (destination == NULL) { 139 fprintf(stderr, gettext("Usage: clean (destination)\n")); 140 return (-1); 141 } 142 143 status = papiPrinterPurgeJobs(svc, destination, &jobs); 144 if (status != PAPI_OK) { 145 fprintf(stderr, gettext("clean: %s: %s\n"), destination, 146 verbose_papi_message(svc, status)); 147 return (-1); 148 } 149 150 if (jobs != NULL) { 151 int i; 152 153 for (i = 0; jobs[i] != NULL; i++) 154 printf(gettext("\t%s-%d: cancelled\n"), destination, 155 papiJobGetId(jobs[i])); 156 157 papiJobListFree(jobs); 158 } 159 160 return (0); 161 } 162 163 static int 164 lpc_disable(papi_service_t svc, char **args) 165 { 166 papi_status_t status; 167 char *destination = args[1]; 168 169 if (destination == NULL) { 170 fprintf(stderr, gettext("Usage: disable: (destination)\n")); 171 return (-1); 172 } 173 174 status = papiPrinterDisable(svc, destination, NULL); 175 if (status != PAPI_OK) { 176 fprintf(stderr, gettext("disable: %s: %s\n"), destination, 177 verbose_papi_message(svc, status)); 178 return (-1); 179 } 180 181 return (0); 182 } 183 184 static int 185 lpc_enable(papi_service_t svc, char **args) 186 { 187 papi_status_t status; 188 char *destination = args[1]; 189 190 if (destination == NULL) { 191 fprintf(stderr, gettext("Usage: enable: (destination)\n")); 192 return (-1); 193 } 194 195 status = papiPrinterEnable(svc, destination); 196 if (status != PAPI_OK) { 197 fprintf(stderr, gettext("enable: %s: %s\n"), destination, 198 verbose_papi_message(svc, status)); 199 return (-1); 200 } 201 202 return (0); 203 } 204 205 static int 206 lpc_restart(papi_service_t svc, char **args) 207 { 208 int rc = 0; 209 210 rc += lpc_disable(svc, args); 211 rc += lpc_enable(svc, args); 212 213 return (rc); 214 } 215 216 static int 217 lpc_start(papi_service_t svc, char **args) 218 { 219 papi_status_t status; 220 char *destination = args[1]; 221 222 if (destination == NULL) { 223 fprintf(stderr, gettext("Usage: start (destination)\n")); 224 return (-1); 225 } 226 227 status = papiPrinterResume(svc, destination); 228 if (status != PAPI_OK) { 229 fprintf(stderr, gettext("start: %s: %s\n"), destination, 230 verbose_papi_message(svc, status)); 231 return (-1); 232 } 233 234 return (0); 235 } 236 237 static int 238 lpc_stop(papi_service_t svc, char **args) 239 { 240 papi_status_t status; 241 char *destination = args[1]; 242 243 if (destination == NULL) { 244 fprintf(stderr, gettext("Usage: stop (destination)\n")); 245 return (-1); 246 } 247 248 status = papiPrinterPause(svc, destination, "paused via lpc"); 249 if (status != PAPI_OK) { 250 fprintf(stderr, gettext("stop: %s: %s\n"), destination, 251 verbose_papi_message(svc, status)); 252 return (-1); 253 } 254 255 return (0); 256 } 257 258 static int 259 lpc_topq(papi_service_t svc, char **args) 260 { 261 papi_status_t status; 262 char *destination = args[1]; 263 char *idstr = args[2]; 264 int32_t id; 265 266 if (destination == NULL || idstr == NULL) { 267 fprintf(stderr, gettext("Usage: topq (destination) (id)\n")); 268 return (-1); 269 } 270 id = atoi(idstr); 271 272 status = papiJobPromote(svc, destination, id); 273 if (status != PAPI_OK) { 274 fprintf(stderr, gettext("topq: %s-%d: %s\n"), destination, id, 275 verbose_papi_message(svc, status)); 276 return (-1); 277 } 278 279 return (0); 280 } 281 282 static int 283 lpc_up(papi_service_t svc, char **args) 284 { 285 int rc = 0; 286 287 rc += lpc_enable(svc, args); 288 rc += lpc_start(svc, args); 289 290 return (rc); 291 } 292 293 static int 294 lpc_down(papi_service_t svc, char **args) 295 { 296 int rc = 0; 297 298 rc += lpc_disable(svc, args); 299 rc += lpc_stop(svc, args); 300 301 return (rc); 302 } 303 304 static int lpc_help(papi_service_t svc, char **args); /* forward reference */ 305 306 static char help_help[] = "get help on commands"; 307 static char help_exit[] = "exit lpc"; 308 static char help_status[] = "show status of daemon and queue"; 309 static char help_abort[] = 310 "disable print queue terminating any active job processing"; 311 static char help_clean[] = "remove all jobs from a queue"; 312 static char help_disable[] = "turn off spooling to a queue"; 313 static char help_down[] = 314 "turn off queueing and printing for a queue and set a reason"; 315 static char help_enable[] = "turn on spooling to a queue"; 316 static char help_restart[] = "restart job processing for a queue"; 317 static char help_start[] = "turn on printing from a queue"; 318 static char help_stop[] = "turn off printing from a queue"; 319 static char help_up[] = "turn on queueing and printing for a queue"; 320 static char help_topq[] = "put a job at the top of the queue"; 321 322 static struct { 323 char *cmd; 324 int (*handler)(papi_service_t svc, char **args); 325 char *help_string; 326 int num_args; 327 } cmd_tab[] = { 328 { "?", lpc_help, help_help, 0 }, 329 { "help", lpc_help, help_help, 0 }, 330 { "exit", lpc_exit, help_exit, 0 }, 331 { "quit", lpc_exit, help_exit, 0 }, 332 { "status", lpc_status, help_status, 1 }, 333 { "abort", lpc_abort, help_abort, 1 }, 334 { "clean", lpc_clean, help_clean, 1 }, 335 { "disable", lpc_disable, help_disable, 1 }, 336 { "down", lpc_down, help_down, 2 }, 337 { "enable", lpc_enable, help_enable, 1 }, 338 { "restart", lpc_restart, help_restart, 1 }, 339 { "start", lpc_start, help_start, 1 }, 340 { "stop", lpc_stop, help_stop, 1 }, 341 { "up", lpc_up, help_up, 1 }, 342 { "topq", lpc_topq, help_topq, 2 }, 343 { NULL, NULL, NULL, 0 } 344 }; 345 346 static int 347 lpc_handler(char *cmd, cmd_handler_t **handler) 348 { 349 int i; 350 351 for (i = 0; cmd_tab[i].cmd != NULL; i++) 352 if (strcmp(cmd, cmd_tab[i].cmd) == 0) { 353 *handler = cmd_tab[i].handler; 354 return (cmd_tab[i].num_args); 355 } 356 return (-1); 357 } 358 359 static char * 360 lpc_helptext(char *cmd) 361 { 362 int i; 363 364 for (i = 0; cmd_tab[i].cmd != NULL; i++) 365 if (strcmp(cmd, cmd_tab[i].cmd) == 0) 366 return (gettext(cmd_tab[i].help_string)); 367 return (NULL); 368 } 369 370 /* ARGSUSED0 */ 371 static int 372 lpc_help(papi_service_t svc, char **args) 373 { 374 if (args[1] == NULL) { 375 int i; 376 377 printf(gettext("Commands are:\n\n")); 378 for (i = 0; cmd_tab[i].cmd != NULL; i++) { 379 printf("\t%s", cmd_tab[i].cmd); 380 if ((i % 7) == 6) 381 printf("\n"); 382 } 383 if ((i % 7) != 6) 384 printf("\n"); 385 } else { 386 char *helptext = lpc_helptext(args[1]); 387 388 if (helptext == NULL) 389 helptext = gettext("no such command"); 390 391 printf("%s: %s\n", args[1], helptext); 392 } 393 394 return (0); 395 } 396 397 static int 398 process_one(int (*handler)(papi_service_t, char **), char **av, int expected) 399 { 400 int rc = -1; 401 papi_status_t status = PAPI_OK; 402 papi_service_t svc = NULL; 403 char *printer = av[1]; 404 405 if ((printer != NULL) && (expected != 0)) { 406 status = papiServiceCreate(&svc, printer, NULL, NULL, 407 cli_auth_callback, encryption, NULL); 408 if (status != PAPI_OK) { 409 fprintf(stderr, gettext( 410 "Failed to contact service for %s: %s\n"), 411 printer, verbose_papi_message(svc, status)); 412 } 413 } 414 415 if (status == PAPI_OK) 416 rc = handler(svc, av); 417 418 if (svc != NULL) 419 papiServiceDestroy(svc); 420 421 return (rc); 422 } 423 424 static int 425 process_all(int (*handler)(papi_service_t, char **), char **av, int expected) 426 { 427 papi_status_t status; 428 papi_service_t svc = NULL; 429 char **printers; 430 int rc = 0; 431 432 status = papiServiceCreate(&svc, NULL, NULL, NULL, NULL, 433 encryption, NULL); 434 if (status != PAPI_OK) { 435 fprintf(stderr, gettext("Failed to contact service: %s\n"), 436 verbose_papi_message(svc, status)); 437 return (-1); 438 } 439 440 if ((printers = interest_list(svc)) != NULL) { 441 int i; 442 443 for (i = 0; printers[i] != NULL; i++) { 444 av[1] = printers[i]; 445 rc += process_one(handler, av, expected); 446 } 447 } 448 449 papiServiceDestroy(svc); 450 451 return (rc); 452 } 453 454 static int 455 process(int ac, char **av) 456 { 457 int (*handler)(papi_service_t, char **) = NULL; 458 int num_args = -1; 459 460 char *printer = av[1]; 461 int rc = -1; 462 463 if ((num_args = lpc_handler(av[0], &handler)) < 0) { 464 printf(gettext("%s: invalid command\n"), av[0]); 465 return (-1); 466 } 467 468 if (((ac == 0) && (num_args == 1)) || 469 ((printer != NULL) && strcmp(printer, "all") == 0)) 470 rc = process_all(handler, av, num_args); 471 else if (num_args < ac) { 472 int i; 473 char *argv[4]; 474 475 memset(argv, 0, sizeof (argv)); 476 argv[0] = av[0]; 477 478 if (strcmp(av[0], "topq") == 0) { 479 argv[1] = av[1]; 480 for (i = 2; i <= ac; i++) { 481 argv[2] = av[i]; 482 process_one(handler, argv, num_args); 483 } 484 } else 485 for (i = 1; i <= ac; i++) { 486 argv[1] = av[i]; 487 process_one(handler, argv, num_args); 488 } 489 } else 490 rc = process_one(handler, av, num_args); 491 492 return (rc); 493 } 494 495 static void 496 usage(char *program) 497 { 498 char *name; 499 500 if ((name = strrchr(program, '/')) == NULL) 501 name = program; 502 else 503 name++; 504 505 fprintf(stdout, 506 gettext("Usage: %s [ command [ parameter...]]\n"), 507 name); 508 exit(1); 509 } 510 511 static void 512 lpc_shell() 513 { 514 for (;;) { 515 char line[256]; 516 char **av = NULL; 517 int ac = 0; 518 519 /* prompt */ 520 fprintf(stdout, "lpc> "); 521 fflush(stdout); 522 523 /* get command */ 524 if (fgets(line, sizeof (line), stdin) == NULL) 525 exit(1); 526 if ((av = strsplit(line, " \t\n")) != NULL) 527 for (ac = 0; av[ac] != NULL; ac++); 528 else 529 continue; 530 531 if (ac > 0) 532 (void) process(ac - 1, av); 533 free(av); 534 } 535 } 536 537 int 538 main(int ac, char *av[]) 539 { 540 int result = 0; 541 int c; 542 543 (void) setlocale(LC_ALL, ""); 544 (void) textdomain("SUNW_OST_OSCMD"); 545 546 while ((c = getopt(ac, av, "E")) != EOF) 547 switch (c) { 548 case 'E': 549 encryption = PAPI_ENCRYPT_ALWAYS; 550 break; 551 default: 552 usage(av[0]); 553 } 554 555 if (optind == ac) 556 lpc_shell(); 557 else 558 result = process(ac - optind - 1, &av[optind]); 559 560 return (result); 561 } 562