/* * "$Id: lpc.c,v 1.1.1.12 2005/01/04 19:15:03 jlovell Exp $" * * "lpc" command for the Common UNIX Printing System (CUPS). * * Copyright 1997-2005 by Easy Software Products. * * These coded instructions, statements, and computer programs are the * property of Easy Software Products and are protected by Federal * copyright law. Distribution and use rights are outlined in the file * "LICENSE.txt" which should have been included with this file. If this * file is missing or damaged please contact Easy Software Products * at: * * Attn: CUPS Licensing Information * Easy Software Products * 44141 Airport View Drive, Suite 204 * Hollywood, Maryland 20636 USA * * Voice: (301) 373-9600 * EMail: cups-info@cups.org * WWW: http://www.cups.org * * Contents: * * main() - Parse options and commands. * compare_strings() - Compare two command-line strings. * do_command() - Do an lpc command... * show_help() - Show help messages. * show_status() - Show printers. */ /* * Include necessary headers... */ #include #include #include #include #include #include #include /* * Local functions... */ static int compare_strings(char *, char *, int); static void do_command(http_t *, char *, char *); static void show_help(char *); static void show_status(http_t *, char *); /* * 'main()' - Parse options and commands. */ int main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { http_t *http; /* Connection to server */ char line[1024], /* Input line from user */ *params; /* Pointer to parameters */ /* * Connect to the scheduler... */ http = httpConnectEncrypt(cupsServer(), ippPort(), cupsEncryption()); if (argc > 1) { /* * Process a single command on the command-line... */ do_command(http, argv[1], argv[2]); } else { /* * Do the command prompt thing... */ printf("lpc> "); while (fgets(line, sizeof(line), stdin) != NULL) { /* * Strip the trailing newline... */ line[strlen(line) - 1] = '\0'; /* * Find any options in the string... */ while (isspace(line[0] & 255)) cups_strcpy(line, line + 1); for (params = line; *params != '\0'; params ++) if (isspace(*params & 255)) break; /* * Remove whitespace between the command and parameters... */ while (isspace(*params & 255)) *params++ = '\0'; /* * The "quit" and "exit" commands exit; otherwise, process as needed... */ if (compare_strings(line, "quit", 1) == 0 || compare_strings(line, "exit", 2) == 0) break; if (*params == '\0') do_command(http, line, NULL); else do_command(http, line, params); /* * Put another prompt out to the user... */ printf("lpc> "); } } /* * Close the connection to the server and return... */ httpClose(http); return (0); } /* * 'compare_strings()' - Compare two command-line strings. */ static int /* O - -1 or 1 = no match, 0 = match */ compare_strings(char *s, /* I - Command-line string */ char *t, /* I - Option string */ int tmin) /* I - Minimum number of unique chars in option */ { int slen; /* Length of command-line string */ slen = strlen(s); if (slen < tmin) return (-1); else return (strncmp(s, t, slen)); } /* * 'do_command()' - Do an lpc command... */ static void do_command(http_t *http, /* I - HTTP connection to server */ char *command, /* I - Command string */ char *params) /* I - Parameters for command */ { if (compare_strings(command, "status", 4) == 0) show_status(http, params); else if (compare_strings(command, "help", 1) == 0 || strcmp(command, "?") == 0) show_help(params); else printf("%s is not implemented by the CUPS version of lpc.\n", command); } /* * 'show_help()' - Show help messages. */ static void show_help(char *command) /* I - Command to describe or NULL */ { if (command == NULL) { puts("Commands may be abbreviated. Commands are:"); puts(""); puts("exit help quit status ?"); } else if (compare_strings(command, "help", 1) == 0 || strcmp(command, "?") == 0) puts("help\t\tget help on commands"); else if (compare_strings(command, "status", 4) == 0) puts("status\t\tshow status of daemon and queue"); else puts("?Invalid help command unknown"); } /* * 'show_status()' - Show printers. */ static void show_status(http_t *http, /* I - HTTP connection to server */ char *dests) /* I - Destinations */ { ipp_t *request, /* IPP Request */ *response, /* IPP Response */ *jobs; /* IPP Get Jobs response */ ipp_attribute_t *attr, /* Current attribute */ *jattr; /* Current job attribute */ cups_lang_t *language; /* Default language */ char *printer, /* Printer name */ *device, /* Device URI */ *delimiter; /* Char search result */ ipp_pstate_t pstate; /* Printer state */ int accepting; /* Is printer accepting jobs? */ int jobcount; /* Count of current jobs */ char *dptr, /* Pointer into destination list */ *ptr; /* Pointer into printer name */ int match; /* Non-zero if this job matches */ char printer_uri[HTTP_MAX_URI]; /* Printer URI */ static const char *requested[] = { /* Requested attributes */ "printer-name", "device-uri", "printer-state", "printer-is-accepting-jobs" }; DEBUG_printf(("show_status(%08x, %08x)\n", http, dests)); if (http == NULL) return; /* * Build a CUPS_GET_PRINTERS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language */ request = ippNew(); request->request.op.operation_id = CUPS_GET_PRINTERS; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(language)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); ippAddStrings(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", sizeof(requested) / sizeof(requested[0]), NULL, requested); /* * Do the request and get back a response... */ if ((response = cupsDoRequest(http, request, "/")) != NULL) { DEBUG_puts("show_status: request succeeded..."); /* * Loop through the printers returned in the list and display * their status... */ for (attr = response->attrs; attr != NULL; attr = attr->next) { /* * Skip leading attributes until we hit a job... */ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER) attr = attr->next; if (attr == NULL) break; /* * Pull the needed attributes from this job... */ printer = NULL; device = "file:/dev/null"; pstate = IPP_PRINTER_IDLE; jobcount = 0; accepting = 1; while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && attr->value_tag == IPP_TAG_NAME) printer = attr->values[0].string.text; if (strcmp(attr->name, "device-uri") == 0 && attr->value_tag == IPP_TAG_URI) device = attr->values[0].string.text; if (strcmp(attr->name, "printer-state") == 0 && attr->value_tag == IPP_TAG_ENUM) pstate = (ipp_pstate_t)attr->values[0].integer; if (strcmp(attr->name, "printer-is-accepting-jobs") == 0 && attr->value_tag == IPP_TAG_BOOLEAN) accepting = attr->values[0].boolean; attr = attr->next; } /* * See if we have everything needed... */ if (printer == NULL) { if (attr == NULL) break; else continue; } /* * See if this is a printer we're interested in... */ match = dests == NULL; if (dests != NULL) { for (dptr = dests; *dptr != '\0';) { /* * Skip leading whitespace and commas... */ while (isspace(*dptr & 255) || *dptr == ',') dptr ++; if (*dptr == '\0') break; /* * Compare names... */ for (ptr = printer; *ptr != '\0' && *dptr != '\0' && *ptr == *dptr; ptr ++, dptr ++); if (*ptr == '\0' && (*dptr == '\0' || *dptr == ',' || isspace(*dptr & 255))) { match = 1; break; } /* * Skip trailing junk... */ while (!isspace(*dptr & 255) && *dptr != '\0') dptr ++; while (isspace(*dptr & 255) || *dptr == ',') dptr ++; if (*dptr == '\0') break; } } /* * Display the printer entry if needed... */ if (match) { /* * If the printer state is "IPP_PRINTER_PROCESSING", then grab the * current job for the printer. */ if (pstate == IPP_PRINTER_PROCESSING) { /* * Build an IPP_GET_JOBS request, which requires the following * attributes: * * attributes-charset * attributes-natural-language * printer-uri * limit */ request = ippNew(); request->request.op.operation_id = IPP_GET_JOBS; request->request.op.request_id = 1; language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, cupsLangEncoding(language)); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); snprintf(printer_uri, sizeof(printer_uri), "ipp://localhost/printers/%s", printer); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, printer_uri); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", NULL, "job-id"); if ((jobs = cupsDoRequest(http, request, "/")) != NULL) { for (jattr = jobs->attrs; jattr != NULL; jattr = jattr->next) if (jattr->name && strcmp(jattr->name, "job-id") == 0) jobcount ++; ippDelete(jobs); } } /* * Display it... */ printf("%s:\n", printer); if (strncmp(device, "file:", 5) == 0) printf("\tprinter is on device \'%s\' speed -1\n", device + 5); else { /* * Just show the method... */ if ((delimiter = strchr(device, ':')) != NULL ) { *delimiter = '\0'; printf("\tprinter is on device \'%s\' speed -1\n", device); } } printf("\tqueuing is %sabled\n", accepting ? "en" : "dis"); printf("\tprinting is %sabled\n", pstate == IPP_PRINTER_STOPPED ? "dis" : "en"); if (jobcount == 0) puts("\tno entries"); else printf("\t%d entries\n", jobcount); puts("\tdaemon present"); } if (attr == NULL) break; } ippDelete(response); } } /* * End of "$Id: lpc.c,v 1.1.1.12 2005/01/04 19:15:03 jlovell Exp $". */