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 2006 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 #pragma ident "%Z%%M% %I% %E% SMI" 31 32 #include <stdio.h> 33 #include <stdlib.h> 34 #include <unistd.h> 35 #include <string.h> 36 #include <locale.h> 37 #include <libintl.h> 38 #include <papi.h> 39 #include "common.h" 40 41 typedef int (cmd_handler_t)(papi_service_t, char **); 42 43 static papi_encryption_t encryption = PAPI_ENCRYPT_NEVER; 44 45 /* ARGSUSED0 */ 46 static int 47 lpc_exit(papi_service_t svc, char **args) 48 { 49 exit(0); 50 /* NOTREACHED */ 51 return (0); 52 } 53 54 static int 55 lpc_status(papi_service_t svc, char **args) 56 { 57 papi_status_t status; 58 papi_printer_t p = NULL; 59 char *pattrs[] = { "printer-state", "printer-state-reasons", 60 "printer-is-accepting-jobs", NULL }; 61 char *destination = args[1]; 62 63 status = papiPrinterQuery(svc, destination, pattrs, NULL, &p); 64 if (status == PAPI_OK) { 65 papi_attribute_t **list = papiPrinterGetAttributeList(p); 66 char accepting = 0; 67 int32_t state = 0; 68 69 printf("%s:\n", destination); 70 71 (void) papiAttributeListGetBoolean(list, NULL, 72 "printer-is-accepting-jobs", &accepting); 73 printf(gettext("\tqueueing is %s\n"), 74 (accepting ? gettext("enabled") : gettext("disabled"))); 75 76 (void) papiAttributeListGetInteger(list, NULL, 77 "printer-state", &state); 78 printf("\tprinting is %s\n", 79 ((state != 0x05) ? gettext("enabled") : 80 gettext("disabled"))); 81 82 if (state != 0x03) { /* !idle */ 83 papi_job_t *jobs = NULL; 84 int i = 0; 85 86 (void) papiPrinterListJobs(svc, destination, NULL, 87 PAPI_LIST_JOBS_ALL, 0, &jobs); 88 if (jobs != NULL) { 89 for (i = 0; jobs[i] != NULL; i++); 90 papiJobListFree(jobs); 91 } 92 printf(gettext("\t%d entries in spool area\n"), i); 93 } else 94 printf(gettext("\tno entries\n")); 95 96 if (state == 0x04) 97 printf(gettext("\tdaemon present\n")); 98 99 } else { 100 fprintf(stderr, "%s: %s\n", destination, 101 verbose_papi_message(svc, status)); 102 return (-1); 103 } 104 105 papiPrinterFree(p); 106 107 return (0); 108 } 109 110 static int 111 lpc_abort(papi_service_t svc, char **args) 112 { 113 papi_status_t status; 114 char *destination = args[1]; 115 116 if (destination == NULL) { 117 fprintf(stderr, gettext("Usage: abort (destination)\n")); 118 return (-1); 119 } 120 121 status = papiPrinterPause(svc, destination, "paused via lpc abort"); 122 if (status == PAPI_OK) { 123 printf(gettext("%s: processing disabled after current job\n"), 124 destination); 125 } else { 126 fprintf(stderr, "%s: %s\n", destination, 127 verbose_papi_message(svc, status)); 128 } 129 130 return (0); 131 } 132 133 static int 134 lpc_clean(papi_service_t svc, char **args) 135 { 136 papi_status_t status; 137 papi_job_t *jobs = NULL; 138 char *destination = args[1]; 139 140 if (destination == NULL) { 141 fprintf(stderr, gettext("Usage: clean (destination)\n")); 142 return (-1); 143 } 144 145 status = papiPrinterPurgeJobs(svc, destination, &jobs); 146 if (status != PAPI_OK) { 147 fprintf(stderr, gettext("clean: %s: %s\n"), destination, 148 verbose_papi_message(svc, status)); 149 return (-1); 150 } 151 152 if (jobs != NULL) { 153 int i; 154 155 for (i = 0; jobs[i] != NULL; i++) 156 printf(gettext("\t%s-%d: cancelled\n"), destination, 157 papiJobGetId(jobs[i])); 158 159 papiJobListFree(jobs); 160 } 161 162 return (0); 163 } 164 165 static int 166 lpc_disable(papi_service_t svc, char **args) 167 { 168 papi_status_t status; 169 char *destination = args[1]; 170 171 if (destination == NULL) { 172 fprintf(stderr, gettext("Usage: disable: (destination)\n")); 173 return (-1); 174 } 175 176 status = papiPrinterDisable(svc, destination, NULL); 177 if (status != PAPI_OK) { 178 fprintf(stderr, gettext("disable: %s: %s\n"), destination, 179 verbose_papi_message(svc, status)); 180 return (-1); 181 } 182 183 return (0); 184 } 185 186 static int 187 lpc_enable(papi_service_t svc, char **args) 188 { 189 papi_status_t status; 190 char *destination = args[1]; 191 192 if (destination == NULL) { 193 fprintf(stderr, gettext("Usage: enable: (destination)\n")); 194 return (-1); 195 } 196 197 status = papiPrinterEnable(svc, destination); 198 if (status != PAPI_OK) { 199 fprintf(stderr, gettext("enable: %s: %s\n"), destination, 200 verbose_papi_message(svc, status)); 201 return (-1); 202 } 203 204 return (0); 205 } 206 207 static int 208 lpc_restart(papi_service_t svc, char **args) 209 { 210 int rc = 0; 211 212 rc += lpc_disable(svc, args); 213 rc += lpc_enable(svc, args); 214 215 return (rc); 216 } 217 218 static int 219 lpc_start(papi_service_t svc, char **args) 220 { 221 papi_status_t status; 222 char *destination = args[1]; 223 224 if (destination == NULL) { 225 fprintf(stderr, gettext("Usage: start (destination)\n")); 226 return (-1); 227 } 228 229 status = papiPrinterResume(svc, destination); 230 if (status != PAPI_OK) { 231 fprintf(stderr, gettext("start: %s: %s\n"), destination, 232 verbose_papi_message(svc, status)); 233 return (-1); 234 } 235 236 return (0); 237 } 238 239 static int 240 lpc_stop(papi_service_t svc, char **args) 241 { 242 papi_status_t status; 243 char *destination = args[1]; 244 245 if (destination == NULL) { 246 fprintf(stderr, gettext("Usage: stop (destination)\n")); 247 return (-1); 248 } 249 250 status = papiPrinterPause(svc, destination, "paused via lpc"); 251 if (status != PAPI_OK) { 252 fprintf(stderr, gettext("stop: %s: %s\n"), destination, 253 verbose_papi_message(svc, status)); 254 return (-1); 255 } 256 257 return (0); 258 } 259 260 static int 261 lpc_topq(papi_service_t svc, char **args) 262 { 263 papi_status_t status; 264 char *destination = args[1]; 265 int32_t id = atoi(args[2]); 266 267 if (destination == NULL) { 268 fprintf(stderr, gettext("Usage: topq (destination) (id)\n")); 269 return (-1); 270 } 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 != 0)) || 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 529 (void) process(ac - 1, av); 530 free(av); 531 } 532 } 533 534 int 535 main(int ac, char *av[]) 536 { 537 int result = 0; 538 int c; 539 540 (void) setlocale(LC_ALL, ""); 541 (void) textdomain("SUNW_OST_OSCMD"); 542 543 while ((c = getopt(ac, av, "E")) != EOF) 544 switch (c) { 545 case 'E': 546 encryption = PAPI_ENCRYPT_ALWAYS; 547 break; 548 default: 549 usage(av[0]); 550 } 551 552 if (optind == ac) 553 lpc_shell(); 554 else 555 result = process(ac - optind - 1, &av[optind]); 556 557 return (result); 558 } 559