summaryrefslogtreecommitdiff
path: root/berkeley
diff options
context:
space:
mode:
authorjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>2006-01-13 01:51:53 +0000
committerjlovell <jlovell@a1ca3aef-8c08-0410-bb20-df032aa958be>2006-01-13 01:51:53 +0000
commitef416fc25c4af449e930416117bedb12fc9924ba (patch)
tree11f8aa8c5d3565a17d4a6d5121d3edba22e2a21e /berkeley
parent9ec11526e139aeacf6a052799a6aa22cbbe6ebb2 (diff)
downloadcups-ef416fc25c4af449e930416117bedb12fc9924ba.tar.gz
Load cups into easysw/current.
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@2 a1ca3aef-8c08-0410-bb20-df032aa958be
Diffstat (limited to 'berkeley')
-rw-r--r--berkeley/Dependencies14
-rw-r--r--berkeley/Makefile112
-rw-r--r--berkeley/lpc.c524
-rw-r--r--berkeley/lpq.c640
-rw-r--r--berkeley/lpr.c495
-rw-r--r--berkeley/lprm.c284
6 files changed, 2069 insertions, 0 deletions
diff --git a/berkeley/Dependencies b/berkeley/Dependencies
new file mode 100644
index 000000000..ceb85278c
--- /dev/null
+++ b/berkeley/Dependencies
@@ -0,0 +1,14 @@
+# DO NOT DELETE
+
+lpc.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lpc.o: ../cups/ppd.h ../cups/file.h ../cups/i18n.h ../cups/language.h
+lpc.o: ../cups/array.h ../cups/debug.h ../cups/string.h ../config.h
+lpq.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lpq.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/file.h
+lpq.o: ../cups/i18n.h ../cups/language.h ../cups/array.h ../cups/debug.h
+lpr.o: ../cups/string.h ../config.h ../cups/cups.h ../cups/ipp.h
+lpr.o: ../cups/http.h ../cups/md5.h ../cups/ppd.h ../cups/file.h
+lpr.o: ../cups/i18n.h ../cups/language.h ../cups/array.h
+lprm.o: ../cups/cups.h ../cups/ipp.h ../cups/http.h ../cups/md5.h
+lprm.o: ../cups/ppd.h ../cups/file.h ../cups/i18n.h ../cups/language.h
+lprm.o: ../cups/array.h ../cups/string.h ../config.h
diff --git a/berkeley/Makefile b/berkeley/Makefile
new file mode 100644
index 000000000..454f6d657
--- /dev/null
+++ b/berkeley/Makefile
@@ -0,0 +1,112 @@
+#
+# "$Id: Makefile 4494 2005-02-18 02:18:11Z mike $"
+#
+# Berkeley commands makefile for the Common UNIX Printing System (CUPS).
+#
+# Copyright 1997-2005 by Easy Software Products, all rights reserved.
+#
+# 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
+#
+
+include ../Makedefs
+
+TARGETS = lpc lpq lpr lprm
+OBJS = lpc.o lpq.o lpr.o lprm.o
+
+
+#
+# Make all targets...
+#
+
+all: $(TARGETS)
+
+
+#
+# Clean all object files...
+#
+
+clean:
+ $(RM) $(OBJS) $(TARGETS)
+
+
+#
+# Update dependencies (without system header dependencies...)
+#
+
+depend:
+ makedepend -Y -I.. -fDependencies $(OBJS:.o=.c) >/dev/null 2>&1
+
+
+#
+# Install all targets...
+#
+
+install: all
+ $(INSTALL_DIR) $(BINDIR)
+ $(INSTALL_BIN) lpq $(BINDIR)
+ $(INSTALL_BIN) lpr $(BINDIR)
+ $(INSTALL_BIN) lprm $(BINDIR)
+ $(INSTALL_DIR) $(SBINDIR)
+ $(INSTALL_BIN) lpc $(SBINDIR)
+
+
+#
+# lpc
+#
+
+lpc: lpc.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpc lpc.o $(LIBS)
+
+
+#
+# lpq
+#
+
+lpq: lpq.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpq lpq.o $(LIBS)
+
+
+#
+# lpr
+#
+
+lpr: lpr.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lpr lpr.o $(LIBS)
+
+
+#
+# lprm
+#
+
+lprm: lprm.o ../cups/$(LIBCUPS)
+ echo Linking $@...
+ $(CC) $(LDFLAGS) -o lprm lprm.o $(LIBS)
+
+
+#
+# Dependencies...
+#
+
+include Dependencies
+
+
+#
+# End of "$Id: Makefile 4494 2005-02-18 02:18:11Z mike $".
+#
diff --git a/berkeley/lpc.c b/berkeley/lpc.c
new file mode 100644
index 000000000..4b80a618d
--- /dev/null
+++ b/berkeley/lpc.c
@@ -0,0 +1,524 @@
+/*
+ * "$Id: lpc.c 4906 2006-01-10 20:53:28Z mike $"
+ *
+ * "lpc" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2006 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 <stdio.h>
+#include <stdlib.h>
+#include <cups/cups.h>
+#include <cups/i18n.h>
+#include <cups/debug.h>
+#include <cups/string.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int compare_strings(const char *, const char *, int);
+static void do_command(http_t *, const char *, const char *);
+static void show_help(const char *);
+static void show_status(http_t *, const 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 trailing whitespace...
+ */
+
+ for (params = line + strlen(line) - 1; params >= line;)
+ if (!isspace(*params & 255))
+ break;
+ else
+ *params-- = '\0';
+
+ /*
+ * Strip leading whitespace...
+ */
+
+ for (params = line; isspace(*params & 255); params ++);
+
+ if (params > line)
+ _cups_strcpy(line, params);
+
+ if (!line[0])
+ {
+ /*
+ * Nothing left, just show a prompt...
+ */
+
+ printf("lpc> ");
+ continue;
+ }
+
+ /*
+ * Find any options in the string...
+ */
+
+ 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) ||
+ !compare_strings(line, "exit", 2))
+ 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(const char *s, /* I - Command-line string */
+ const 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 */
+ const char *command, /* I - Command string */
+ const char *params) /* I - Parameters for command */
+{
+ if (!compare_strings(command, "status", 4))
+ show_status(http, params);
+ else if (!compare_strings(command, "help", 1) || !strcmp(command, "?"))
+ show_help(params);
+ else
+ _cupsLangPrintf(stdout, cupsLangDefault(),
+ _("%s is not implemented by the CUPS version of lpc.\n"),
+ command);
+}
+
+
+/*
+ * 'show_help()' - Show help messages.
+ */
+
+static void
+show_help(const char *command) /* I - Command to describe or NULL */
+{
+ if (!command)
+ {
+ _cupsLangPrintf(stdout, cupsLangDefault(),
+ _("Commands may be abbreviated. Commands are:\n"
+ "\n"
+ "exit help quit status ?\n"));
+ }
+ else if (!compare_strings(command, "help", 1) || !strcmp(command, "?"))
+ _cupsLangPrintf(stdout, cupsLangDefault(),
+ _("help\t\tget help on commands\n"));
+ else if (!compare_strings(command, "status", 4))
+ _cupsLangPrintf(stdout, cupsLangDefault(),
+ _("status\t\tshow status of daemon and queue\n"));
+ else
+ _cupsLangPrintf(stdout, cupsLangDefault(),
+ _("?Invalid help command unknown\n"));
+}
+
+
+/*
+ * 'show_status()' - Show printers.
+ */
+
+static void
+show_status(http_t *http, /* I - HTTP connection to server */
+ const 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 */
+ const 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(http=%p, dests=\"%s\")\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") &&
+ attr->value_tag == IPP_TAG_NAME)
+ printer = attr->values[0].string.text;
+
+ if (!strcmp(attr->name, "device-uri") &&
+ attr->value_tag == IPP_TAG_URI)
+ device = attr->values[0].string.text;
+
+ if (!strcmp(attr->name, "printer-state") &&
+ attr->value_tag == IPP_TAG_ENUM)
+ pstate = (ipp_pstate_t)attr->values[0].integer;
+
+ if (!strcmp(attr->name, "printer-is-accepting-jobs") &&
+ 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;
+ }
+
+ /*
+ * A single 'all' printer name is special, meaning all printers.
+ */
+
+ if (dests != NULL && !strcmp(dests, "all"))
+ dests = NULL;
+
+ /*
+ * 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)
+ {
+ /*
+ * 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);
+
+ httpAssembleURIf(printer_uri, sizeof(printer_uri), "ipp", NULL,
+ "localhost", 631, "/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)
+ {
+ /*
+ * Grab the number of jobs for the printer.
+ */
+
+ for (jattr = jobs->attrs; jattr != NULL; jattr = jattr->next)
+ if (jattr->name && !strcmp(jattr->name, "job-id"))
+ jobcount ++;
+
+ ippDelete(jobs);
+ }
+
+ /*
+ * Display it...
+ */
+
+ printf("%s:\n", printer);
+ if (!strncmp(device, "file:", 5))
+ _cupsLangPrintf(stdout, language,
+ _("\tprinter is on device \'%s\' speed -1\n"),
+ device + 5);
+ else
+ {
+ /*
+ * Just show the scheme...
+ */
+
+ if ((delimiter = strchr(device, ':')) != NULL )
+ {
+ *delimiter = '\0';
+ _cupsLangPrintf(stdout, language,
+ _("\tprinter is on device \'%s\' speed -1\n"),
+ device);
+ }
+ }
+
+ if (accepting)
+ _cupsLangPuts(stdout, language, _("\tqueuing is enabled\n"));
+ else
+ _cupsLangPuts(stdout, language, _("\tqueuing is disabled\n"));
+
+ if (pstate != IPP_PRINTER_STOPPED)
+ _cupsLangPuts(stdout, language, _("\tprinting is enabled\n"));
+ else
+ _cupsLangPuts(stdout, language, _("\tprinting is disabled\n"));
+
+ if (jobcount == 0)
+ _cupsLangPuts(stdout, language, _("\tno entries\n"));
+ else
+ _cupsLangPrintf(stdout, language, _("\t%d entries\n"), jobcount);
+
+ _cupsLangPuts(stdout, language, _("\tdaemon present\n"));
+ }
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+}
+
+
+/*
+ * End of "$Id: lpc.c 4906 2006-01-10 20:53:28Z mike $".
+ */
diff --git a/berkeley/lpq.c b/berkeley/lpq.c
new file mode 100644
index 000000000..a5e009171
--- /dev/null
+++ b/berkeley/lpq.c
@@ -0,0 +1,640 @@
+/*
+ * "$Id: lpq.c 4906 2006-01-10 20:53:28Z mike $"
+ *
+ * "lpq" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2006 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.
+ * show_jobs() - Show jobs.
+ * show_printer() - Show printer status.
+ * usage() - Show program usage.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <cups/string.h>
+#include <cups/cups.h>
+#include <cups/i18n.h>
+#include <cups/debug.h>
+
+
+/*
+ * Local functions...
+ */
+
+static int show_jobs(http_t *, const char *, const char *, const int,
+ const int);
+static void show_printer(http_t *, const char *);
+static void usage(void);
+
+
+/*
+ * 'main()' - Parse options and commands.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i; /* Looping var */
+ http_t *http; /* Connection to server */
+ const char *dest, /* Desired printer */
+ *user, /* Desired user */
+ *val; /* Environment variable name */
+ char *instance; /* Printer instance */
+ int id, /* Desired job ID */
+ all, /* All printers */
+ interval, /* Reporting interval */
+ longstatus; /* Show file details */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests; /* Destinations */
+ cups_lang_t *language; /* Language */
+#ifdef HAVE_SSL
+ http_encryption_t encryption; /* Encryption? */
+#endif /* HAVE_SSL */
+
+
+ language = cupsLangDefault();
+
+ /*
+ * Connect to the scheduler...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(),
+ cupsEncryption())) == NULL)
+ {
+ _cupsLangPuts(stderr, language,
+ _("lpq: Unable to contact server!\n"));
+ return (1);
+ }
+
+ /*
+ * Check for command-line options...
+ */
+
+ dest = NULL;
+ user = NULL;
+ id = 0;
+ interval = 0;
+ longstatus = 0;
+ all = 0;
+ num_dests = cupsGetDests(&dests);
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '+')
+ interval = atoi(argv[i] + 1);
+ else if (argv[i][0] == '-')
+ {
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_SSL
+ encryption = HTTP_ENCRYPT_REQUIRED;
+
+ if (http)
+ httpEncryption(http, encryption);
+#else
+ _cupsLangPrintf(stderr, language,
+ _("%s: Sorry, no encryption support compiled in!\n"),
+ argv[0]);
+#endif /* HAVE_SSL */
+ break;
+
+ case 'P' : /* Printer */
+ if (argv[i][2])
+ dest = argv[i] + 2;
+ else
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ httpClose(http);
+ cupsFreeDests(num_dests, dests);
+
+ usage();
+ }
+
+ dest = argv[i];
+ }
+
+ if ((instance = strchr(dest, '/')) != NULL)
+ *instance++ = '\0';
+
+ if (cupsGetDest(dest, instance, num_dests, dests) == NULL)
+ {
+ if (instance)
+ _cupsLangPrintf(stderr, language,
+ _("lpq: Unknown destination \"%s/%s\"!\n"),
+ dest, instance);
+ else
+ _cupsLangPrintf(stderr, language,
+ _("lpq: Unknown destination \"%s\"!\n"), dest);
+
+ return (1);
+ }
+ break;
+
+ case 'a' : /* All printers */
+ all = 1;
+ break;
+
+ case 'l' : /* Long status */
+ longstatus = 1;
+ break;
+
+ default :
+ httpClose(http);
+ cupsFreeDests(num_dests, dests);
+
+ usage();
+ break;
+ }
+ }
+ else if (isdigit(argv[i][0] & 255))
+ id = atoi(argv[i]);
+ else
+ user = argv[i];
+
+ if (dest == NULL && !all)
+ {
+ for (i = 0; i < num_dests; i ++)
+ if (dests[i].is_default)
+ dest = dests[i].name;
+
+ if (dest == NULL)
+ {
+ val = NULL;
+
+ if ((dest = getenv("LPDEST")) == NULL)
+ {
+ if ((dest = getenv("PRINTER")) != NULL)
+ {
+ if (!strcmp(dest, "lp"))
+ dest = NULL;
+ else
+ val = "PRINTER";
+ }
+ }
+ else
+ val = "LPDEST";
+
+ if (dest && !cupsGetDest(dest, NULL, num_dests, dests))
+ _cupsLangPrintf(stderr, language,
+ _("lp: error - %s environment variable names "
+ "non-existent destination \"%s\"!\n"),
+ val, dest);
+ else
+ _cupsLangPuts(stderr, language,
+ _("lpq: error - no default destination available.\n"));
+ httpClose(http);
+ cupsFreeDests(num_dests, dests);
+ return (1);
+ }
+ }
+
+ /*
+ * Show the status in a loop...
+ */
+
+ for (;;)
+ {
+ if (dest)
+ show_printer(http, dest);
+
+ i = show_jobs(http, dest, user, id, longstatus);
+
+ if (i && interval)
+ {
+ fflush(stdout);
+ sleep(interval);
+ }
+ else
+ break;
+ }
+
+ /*
+ * Close the connection to the server and return...
+ */
+
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * 'show_jobs()' - Show jobs.
+ */
+
+static int /* O - Number of jobs in queue */
+show_jobs(http_t *http, /* I - HTTP connection to server */
+ const char *dest, /* I - Destination */
+ const char *user, /* I - User */
+ const int id, /* I - Job ID */
+ const int longstatus)/* I - 1 if long report desired */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ const char *jobdest, /* Pointer into job-printer-uri */
+ *jobuser, /* Pointer to job-originating-user-name */
+ *jobname; /* Pointer to job-name */
+ ipp_jstate_t jobstate; /* job-state */
+ int jobid, /* job-id */
+ jobsize, /* job-k-octets */
+#ifdef __osf__
+ jobpriority, /* job-priority */
+#endif /* __osf__ */
+ jobcount, /* Number of jobs */
+ jobcopies, /* Number of copies */
+ rank; /* Rank of job */
+ char resource[1024]; /* Resource string */
+ char rankstr[255]; /* Rank string */
+ char namestr[1024]; /* Job name string */
+ static const char *ranks[10] =/* Ranking strings */
+ {
+ "th",
+ "st",
+ "nd",
+ "rd",
+ "th",
+ "th",
+ "th",
+ "th",
+ "th",
+ "th"
+ };
+
+
+ DEBUG_printf(("show_jobs(%08x, %08x, %08x, %d, %d)\n", http, dest, user, id,
+ longstatus));
+
+ if (http == NULL)
+ return (0);
+
+ /*
+ * Build an IPP_GET_JOBS or IPP_GET_JOB_ATTRIBUTES request, which requires
+ * the following attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * job-uri or printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = id ? IPP_GET_JOB_ATTRIBUTES : IPP_GET_JOBS;
+ request->request.op.request_id = 1;
+
+ language = cupsLangDefault();
+
+ attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, cupsLangEncoding(language));
+
+ attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, language->language);
+
+ if (dest == NULL)
+ {
+ if (id)
+ sprintf(resource, "ipp://localhost/jobs/%d", id);
+ else
+ strcpy(resource, "ipp://localhost/jobs");
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri",
+ NULL, resource);
+ }
+ else
+ {
+ httpAssembleURIf(resource, sizeof(resource), "ipp", NULL, "localhost", 0,
+ "/printers/%s", dest);
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+ NULL, resource);
+ }
+
+ if (user)
+ {
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, user);
+ ippAddBoolean(request, IPP_TAG_OPERATION, "my-jobs", 1);
+ }
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ jobcount = 0;
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ _cupsLangPrintf(stderr, language, _("lpq: get-jobs failed: %s\n"),
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return (0);
+ }
+
+ rank = 1;
+
+ /*
+ * Loop through the job list and display them...
+ */
+
+ 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_JOB)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ /*
+ * Pull the needed attributes from this job...
+ */
+
+ jobid = 0;
+ jobsize = 0;
+#ifdef __osf__
+ jobpriority = 50;
+#endif /* __osf__ */
+ jobstate = IPP_JOB_PENDING;
+ jobname = "untitled";
+ jobuser = NULL;
+ jobdest = NULL;
+ jobcopies = 1;
+
+ while (attr != NULL && attr->group_tag == IPP_TAG_JOB)
+ {
+ if (strcmp(attr->name, "job-id") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobid = attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-k-octets") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobsize = attr->values[0].integer;
+
+#ifdef __osf__
+ if (strcmp(attr->name, "job-priority") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobpriority = attr->values[0].integer;
+#endif /* __osf__ */
+
+ if (strcmp(attr->name, "job-state") == 0 &&
+ attr->value_tag == IPP_TAG_ENUM)
+ jobstate = (ipp_jstate_t)attr->values[0].integer;
+
+ if (strcmp(attr->name, "job-printer-uri") == 0 &&
+ attr->value_tag == IPP_TAG_URI)
+ if ((jobdest = strrchr(attr->values[0].string.text, '/')) != NULL)
+ jobdest ++;
+
+ if (strcmp(attr->name, "job-originating-user-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ jobuser = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "job-name") == 0 &&
+ attr->value_tag == IPP_TAG_NAME)
+ jobname = attr->values[0].string.text;
+
+ if (strcmp(attr->name, "copies") == 0 &&
+ attr->value_tag == IPP_TAG_INTEGER)
+ jobcopies = attr->values[0].integer;
+
+ attr = attr->next;
+ }
+
+ /*
+ * See if we have everything needed...
+ */
+
+ if (jobdest == NULL || jobid == 0)
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
+ if (!longstatus && jobcount == 0)
+#ifdef __osf__
+ _cupsLangPuts(stdout, language,
+ _("Rank Owner Pri Job Files"
+ " Total Size\n"));
+#else
+ _cupsLangPuts(stdout, language,
+ _("Rank Owner Job File(s)"
+ " Total Size\n"));
+#endif /* __osf__ */
+
+ jobcount ++;
+
+ /*
+ * Display the job...
+ */
+
+ if (jobstate == IPP_JOB_PROCESSING)
+ strcpy(rankstr, "active");
+ else
+ {
+ /*
+ * Make the rank show the "correct" suffix for each number
+ * (11-13 are the only special cases, for English anyways...)
+ */
+
+ if ((rank % 100) >= 11 && (rank % 100) <= 13)
+ snprintf(rankstr, sizeof(rankstr), "%dth", rank);
+ else
+ snprintf(rankstr, sizeof(rankstr), "%d%s", rank, ranks[rank % 10]);
+
+ rank ++;
+ }
+
+ if (longstatus)
+ {
+ _cupsLangPuts(stdout, language, "");
+
+ if (jobcopies > 1)
+ snprintf(namestr, sizeof(namestr), "%d copies of %s", jobcopies,
+ jobname);
+ else
+ strlcpy(namestr, jobname, sizeof(namestr));
+
+ _cupsLangPrintf(stdout, language, _("%s: %-33.33s [job %d localhost]\n"),
+ jobuser, rankstr, jobid);
+ _cupsLangPrintf(stdout, language, _(" %-39.39s %.0f bytes\n"),
+ namestr, 1024.0 * jobsize);
+ }
+ else
+#ifdef __osf__
+ _cupsLangPrintf(stdout, language,
+ _("%-6s %-10.10s %-4d %-10d %-27.27s %.0f bytes\n"),
+ rankstr, jobuser, jobpriority, jobid, jobname,
+ 1024.0 * jobsize);
+#else
+ _cupsLangPrintf(stdout, language,
+ _("%-7s %-7.7s %-7d %-31.31s %.0f bytes\n"),
+ rankstr, jobuser, jobid, jobname, 1024.0 * jobsize);
+#endif /* __osf */
+
+ if (attr == NULL)
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ _cupsLangPrintf(stderr, language, _("lpq: get-jobs failed: %s\n"),
+ ippErrorString(cupsLastError()));
+ return (0);
+ }
+
+ if (jobcount == 0)
+ _cupsLangPuts(stdout, language, _("no entries\n"));
+
+ return (jobcount);
+}
+
+
+/*
+ * 'show_printer()' - Show printer status.
+ */
+
+static void
+show_printer(http_t *http, /* I - HTTP connection to server */
+ const char *dest) /* I - Destination */
+{
+ ipp_t *request, /* IPP Request */
+ *response; /* IPP Response */
+ ipp_attribute_t *attr; /* Current attribute */
+ cups_lang_t *language; /* Default language */
+ ipp_pstate_t state; /* Printer state */
+ char uri[HTTP_MAX_URI];
+ /* Printer URI */
+
+
+ if (http == NULL)
+ return;
+
+ /*
+ * Build an IPP_GET_PRINTER_ATTRIBUTES request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = IPP_GET_PRINTER_ATTRIBUTES;
+ 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);
+
+ httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
+ "/printers/%s", dest);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if ((response = cupsDoRequest(http, request, "/")) != NULL)
+ {
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lpq: get-printer-attributes failed: %s\n"),
+ ippErrorString(response->request.status.status_code));
+ ippDelete(response);
+ return;
+ }
+
+ if ((attr = ippFindAttribute(response, "printer-state", IPP_TAG_ENUM)) != NULL)
+ state = (ipp_pstate_t)attr->values[0].integer;
+ else
+ state = IPP_PRINTER_STOPPED;
+
+ switch (state)
+ {
+ case IPP_PRINTER_IDLE :
+ _cupsLangPrintf(stdout, language, _("%s is ready\n"), dest);
+ break;
+ case IPP_PRINTER_PROCESSING :
+ _cupsLangPrintf(stdout, language, _("%s is ready and printing\n"),
+ dest);
+ break;
+ case IPP_PRINTER_STOPPED :
+ _cupsLangPrintf(stdout, language, _("%s is not ready\n"), dest);
+ break;
+ }
+
+ ippDelete(response);
+ }
+ else
+ _cupsLangPrintf(stderr, language,
+ _("lpq: get-printer-attributes failed: %s\n"),
+ ippErrorString(cupsLastError()));
+}
+
+
+/*
+ * 'usage()' - Show program usage.
+ */
+
+static void
+usage(void)
+{
+ _cupsLangPuts(stderr, cupsLangDefault(),
+ _("Usage: lpq [-P dest] [-l] [+interval]\n"));
+ exit(1);
+}
+
+
+/*
+ * End of "$Id: lpq.c 4906 2006-01-10 20:53:28Z mike $".
+ */
diff --git a/berkeley/lpr.c b/berkeley/lpr.c
new file mode 100644
index 000000000..58c9202f4
--- /dev/null
+++ b/berkeley/lpr.c
@@ -0,0 +1,495 @@
+/*
+ * "$Id: lpr.c 4906 2006-01-10 20:53:28Z mike $"
+ *
+ * "lpr" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2006 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 send files for printing.
+ * sighandler() - Signal catcher for when we print from stdin...
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include <cups/string.h>
+#include <cups/cups.h>
+#include <cups/i18n.h>
+
+#ifndef WIN32
+# include <unistd.h>
+# include <signal.h>
+
+
+/*
+ * Local functions.
+ */
+
+void sighandler(int);
+#endif /* !WIN32 */
+
+
+/*
+ * Globals...
+ */
+
+char tempfile[1024]; /* Temporary file for printing from stdin */
+
+
+/*
+ * 'main()' - Parse options and send files for printing.
+ */
+
+int
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ int i, j; /* Looping var */
+ int job_id; /* Job ID */
+ char ch; /* Option character */
+ char *printer, /* Destination printer or class */
+ *instance; /* Instance */
+ const char *title, /* Job title */
+ *val; /* Environment variable name */
+ int num_copies; /* Number of copies per file */
+ int num_files; /* Number of files to print */
+ const char *files[1000]; /* Files to print */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests, /* Destinations */
+ *dest; /* Selected destination */
+ int num_options; /* Number of options */
+ cups_option_t *options; /* Options */
+ int deletefile; /* Delete file after print? */
+ char buffer[8192]; /* Copy buffer */
+ int temp; /* Temporary file descriptor */
+ cups_lang_t *language; /* Language information */
+#if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
+ struct sigaction action; /* Signal action */
+ struct sigaction oldaction; /* Old signal action */
+#endif /* HAVE_SIGACTION && !HAVE_SIGSET */
+
+
+ deletefile = 0;
+ printer = NULL;
+ num_dests = 0;
+ dests = NULL;
+ num_options = 0;
+ options = NULL;
+ num_files = 0;
+ title = NULL;
+ language = cupsLangDefault();
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-')
+ switch (ch = argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_SSL
+ cupsSetEncryption(HTTP_ENCRYPT_REQUIRED);
+#else
+ _cupsLangPrintf(stderr, language,
+ _("%s: Sorry, no encryption support compiled in!\n"),
+ argv[0]);
+#endif /* HAVE_SSL */
+ break;
+
+ case '1' : /* TROFF font set 1 */
+ case '2' : /* TROFF font set 2 */
+ case '3' : /* TROFF font set 3 */
+ case '4' : /* TROFF font set 4 */
+ case 'i' : /* indent */
+ case 'w' : /* width */
+ if (argv[i][2] == '\0')
+ {
+ i ++;
+
+ if (i >= argc)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - expected value after -%c "
+ "option!\n"), ch);
+ return (1);
+ }
+ }
+
+ case 'c' : /* CIFPLOT */
+ case 'd' : /* DVI */
+ case 'f' : /* FORTRAN */
+ case 'g' : /* plot */
+ case 'n' : /* Ditroff */
+ case 't' : /* Troff */
+ case 'v' : /* Raster image */
+ _cupsLangPrintf(stderr, language,
+ _("lpr: warning - \'%c\' format modifier not "
+ "supported - output may not be correct!\n"), ch);
+ break;
+
+ case 'o' : /* Option */
+ if (argv[i][2] != '\0')
+ num_options = cupsParseOptions(argv[i] + 2, num_options, &options);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ _cupsLangPuts(stderr, language,
+ _("lpr: error - expected option=value after "
+ "-o option!\n"));
+ return (1);
+ }
+
+ num_options = cupsParseOptions(argv[i], num_options, &options);
+ }
+ break;
+
+ case 'l' : /* Literal/raw */
+ num_options = cupsAddOption("raw", "", num_options, &options);
+ break;
+
+ case 'p' : /* Prettyprint */
+ num_options = cupsAddOption("prettyprint", "", num_options, &options);
+ break;
+
+ case 'h' : /* Suppress burst page */
+ num_options = cupsAddOption("job-sheets", "none", num_options, &options);
+ break;
+
+ case 's' : /* Don't use symlinks */
+ break;
+
+ case 'm' : /* Mail on completion */
+ _cupsLangPuts(stderr, language,
+ _("lpr: warning - email notification is not "
+ "currently supported!\n"));
+ break;
+
+ case 'q' : /* Queue file but don't print */
+ num_options = cupsAddOption("job-hold-until", "indefinite",
+ num_options, &options);
+ break;
+
+ case 'r' : /* Remove file after printing */
+ deletefile = 1;
+ break;
+
+ case 'P' : /* Destination printer or class */
+ if (argv[i][2] != '\0')
+ printer = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ _cupsLangPuts(stderr, language,
+ _("lpr: error - expected destination after -P "
+ "option!\n"));
+ return (1);
+ }
+
+ printer = argv[i];
+ }
+
+ if ((instance = strrchr(printer, '/')) != NULL)
+ *instance++ = '\0';
+
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((dest = cupsGetDest(printer, instance, num_dests, dests)) != NULL)
+ {
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ }
+ break;
+
+ case '#' : /* Number of copies */
+ if (argv[i][2] != '\0')
+ num_copies = atoi(argv[i] + 2);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ _cupsLangPuts(stderr, language,
+ _("lpr: error - expected copy count after -# "
+ "option!\n"));
+ return (1);
+ }
+
+ num_copies = atoi(argv[i]);
+ }
+
+ sprintf(buffer, "%d", num_copies);
+ num_options = cupsAddOption("copies", buffer, num_options, &options);
+ break;
+
+ case 'C' : /* Class */
+ case 'J' : /* Job name */
+ case 'T' : /* Title */
+ if (argv[i][2] != '\0')
+ title = argv[i] + 2;
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - expected name after -%c "
+ "option!\n"), ch);
+ return (1);
+ }
+
+ title = argv[i];
+ }
+ break;
+
+ case 'U' : /* User */
+ if (argv[i][2] != '\0')
+ cupsSetUser(argv[i] + 2);
+ else
+ {
+ i ++;
+ if (i >= argc)
+ {
+ _cupsLangPuts(stderr, language,
+ _("lpr: error - expected username after -U "
+ "option!\n"));
+ return (1);
+ }
+
+ cupsSetUser(argv[i]);
+ }
+ break;
+
+ default :
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - unknown option \'%c\'!\n"),
+ argv[i][1]);
+ return (1);
+ }
+ else if (num_files < 1000)
+ {
+ /*
+ * Print a file...
+ */
+
+ if (access(argv[i], R_OK) != 0)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - unable to access \"%s\" - %s\n"),
+ argv[i], strerror(errno));
+ return (1);
+ }
+
+ files[num_files] = argv[i];
+ num_files ++;
+
+ if (title == NULL)
+ {
+ if ((title = strrchr(argv[i], '/')) != NULL)
+ title ++;
+ else
+ title = argv[i];
+ }
+ }
+ else
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - too many files - \"%s\"\n"), argv[i]);
+ /*
+ * See if we have any files to print; if not, print from stdin...
+ */
+
+ if (printer == NULL)
+ {
+ if (num_dests == 0)
+ num_dests = cupsGetDests(&dests);
+
+ if ((dest = cupsGetDest(NULL, NULL, num_dests, dests)) != NULL)
+ {
+ printer = dest->name;
+
+ for (j = 0; j < dest->num_options; j ++)
+ if (cupsGetOption(dest->options[j].name, num_options, options) == NULL)
+ num_options = cupsAddOption(dest->options[j].name,
+ dest->options[j].value,
+ num_options, &options);
+ }
+ }
+
+ if (printer == NULL)
+ {
+ val = NULL;
+
+ if ((printer = getenv("LPDEST")) == NULL)
+ {
+ if ((printer = getenv("PRINTER")) != NULL)
+ {
+ if (!strcmp(printer, "lp"))
+ printer = NULL;
+ else
+ val = "PRINTER";
+ }
+ }
+ else
+ val = "LPDEST";
+
+ if (printer && !cupsGetDest(printer, NULL, num_dests, dests))
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - %s environment variable names "
+ "non-existent destination \"%s\"!\n"),
+ val, printer);
+ else if (cupsLastError() == IPP_NOT_FOUND)
+ _cupsLangPuts(stderr, language,
+ _("lpr: error - no default destination available.\n"));
+ else
+ _cupsLangPuts(stderr, language,
+ _("lpr: error - scheduler not responding!\n"));
+
+ return (1);
+ }
+
+ if (num_files > 0)
+ {
+ job_id = cupsPrintFiles(printer, num_files, files, title, num_options, options);
+
+ if (deletefile && job_id > 0)
+ {
+ /*
+ * Delete print files after printing...
+ */
+
+ for (i = 0; i < num_files; i ++)
+ unlink(files[i]);
+ }
+ }
+ else
+ {
+ num_files = 1;
+
+#ifndef WIN32
+# if defined(HAVE_SIGSET)
+ sigset(SIGHUP, sighandler);
+ if (sigset(SIGINT, sighandler) == SIG_IGN)
+ sigset(SIGINT, SIG_IGN);
+ sigset(SIGTERM, sighandler);
+# elif defined(HAVE_SIGACTION)
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = sighandler;
+
+ sigaction(SIGHUP, &action, NULL);
+ sigaction(SIGINT, NULL, &oldaction);
+ if (oldaction.sa_handler != SIG_IGN)
+ sigaction(SIGINT, &action, NULL);
+ sigaction(SIGTERM, &action, NULL);
+# else
+ signal(SIGHUP, sighandler);
+ if (signal(SIGINT, sighandler) == SIG_IGN)
+ signal(SIGINT, SIG_IGN);
+ signal(SIGTERM, sighandler);
+# endif
+#endif /* !WIN32 */
+
+ if ((temp = cupsTempFd(tempfile, sizeof(tempfile))) < 0)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - unable to create temporary file "
+ "\"%s\" - %s\n"),
+ tempfile, strerror(errno));
+ return (1);
+ }
+
+ while ((i = read(0, buffer, sizeof(buffer))) > 0)
+ if (write(temp, buffer, i) < 0)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - unable to write to temporary file "
+ "\"%s\" - %s\n"),
+ tempfile, strerror(errno));
+ close(temp);
+ unlink(tempfile);
+ return (1);
+ }
+
+ i = lseek(temp, 0, SEEK_CUR);
+ close(temp);
+
+ if (i == 0)
+ {
+ _cupsLangPuts(stderr, language,
+ _("lpr: error - stdin is empty, so no job has been sent.\n"));
+ unlink(tempfile);
+ return (1);
+ }
+
+ if (title)
+ job_id = cupsPrintFile(printer, tempfile, title, num_options, options);
+ else
+ job_id = cupsPrintFile(printer, tempfile, "(stdin)", num_options, options);
+
+ unlink(tempfile);
+ }
+
+ if (job_id < 1)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lpr: error - unable to print file: %s\n"),
+ ippErrorString(cupsLastError()));
+ return (1);
+ }
+
+ return (0);
+}
+
+
+#ifndef WIN32
+/*
+ * 'sighandler()' - Signal catcher for when we print from stdin...
+ */
+
+void
+sighandler(int s) /* I - Signal number */
+{
+ /*
+ * Remove the temporary file we're using to print from stdin...
+ */
+
+ unlink(tempfile);
+
+ /*
+ * Exit...
+ */
+
+ exit(s);
+}
+#endif /* !WIN32 */
+
+
+/*
+ * End of "$Id: lpr.c 4906 2006-01-10 20:53:28Z mike $".
+ */
diff --git a/berkeley/lprm.c b/berkeley/lprm.c
new file mode 100644
index 000000000..f6fe9fc6b
--- /dev/null
+++ b/berkeley/lprm.c
@@ -0,0 +1,284 @@
+/*
+ * "$Id: lprm.c 4906 2006-01-10 20:53:28Z mike $"
+ *
+ * "lprm" command for the Common UNIX Printing System (CUPS).
+ *
+ * Copyright 1997-2006 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 cancel jobs.
+ */
+
+/*
+ * Include necessary headers...
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <cups/cups.h>
+#include <cups/i18n.h>
+#include <cups/string.h>
+
+
+/*
+ * 'main()' - Parse options and cancel jobs.
+ */
+
+int /* O - Exit status */
+main(int argc, /* I - Number of command-line arguments */
+ char *argv[]) /* I - Command-line arguments */
+{
+ http_t *http; /* HTTP connection to server */
+ int i; /* Looping var */
+ int job_id; /* Job ID */
+ const char *dest; /* Destination printer */
+ char *instance; /* Pointer to instance name */
+ char uri[1024]; /* Printer or job URI */
+ ipp_t *request; /* IPP request */
+ ipp_t *response; /* IPP response */
+ ipp_op_t op; /* Operation */
+ cups_lang_t *language; /* Language */
+ int num_dests; /* Number of destinations */
+ cups_dest_t *dests; /* Destinations */
+ http_encryption_t encryption; /* Encryption? */
+
+
+ /*
+ * Setup to cancel individual print jobs...
+ */
+
+ op = IPP_CANCEL_JOB;
+ job_id = 0;
+ dest = NULL;
+ response = NULL;
+ http = NULL;
+ encryption = cupsEncryption();
+ language = cupsLangDefault();
+ num_dests = cupsGetDests(&dests);
+
+ for (i = 0; i < num_dests; i ++)
+ if (dests[i].is_default)
+ dest = dests[i].name;
+
+ /*
+ * Open a connection to the server...
+ */
+
+ if ((http = httpConnectEncrypt(cupsServer(), ippPort(), encryption)) == NULL)
+ {
+ _cupsLangPuts(stderr, language, _("lprm: Unable to contact server!\n"));
+ cupsFreeDests(num_dests, dests);
+ return (1);
+ }
+
+ /*
+ * Process command-line arguments...
+ */
+
+ for (i = 1; i < argc; i ++)
+ if (argv[i][0] == '-' && argv[i][1] != '\0')
+ switch (argv[i][1])
+ {
+ case 'E' : /* Encrypt */
+#ifdef HAVE_SSL
+ encryption = HTTP_ENCRYPT_REQUIRED;
+
+ httpEncryption(http, encryption);
+#else
+ _cupsLangPrintf(stderr, language,
+ _("%s: Sorry, no encryption support compiled in!\n"),
+ argv[0]);
+#endif /* HAVE_SSL */
+ break;
+
+ case 'P' : /* Cancel jobs on a printer */
+ if (argv[i][2])
+ dest = argv[i] + 2;
+ else
+ {
+ i ++;
+ dest = argv[i];
+ }
+
+ if ((instance = strchr(dest, '/')) != NULL)
+ *instance = '\0';
+
+ if (cupsGetDest(dest, NULL, num_dests, dests) == NULL)
+ {
+ _cupsLangPrintf(stderr, language,
+ _("lprm: Unknown destination \"%s\"!\n"), dest);
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return(1);
+ }
+ break;
+
+ default :
+ _cupsLangPrintf(stderr, language,
+ _("lprm: Unknown option \'%c\'!\n"), argv[i][1]);
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+ else
+ {
+ /*
+ * Cancel a job or printer...
+ */
+
+ if (isdigit(argv[i][0] & 255) &&
+ cupsGetDest(argv[i], NULL, num_dests, dests) == NULL)
+ {
+ dest = NULL;
+ op = IPP_CANCEL_JOB;
+ job_id = atoi(argv[i]);
+ }
+ else if (strcmp(argv[i], "-") == 0)
+ {
+ /*
+ * Cancel all jobs
+ */
+
+ op = IPP_PURGE_JOBS;
+ }
+ else
+ {
+ dest = argv[i];
+ job_id = 0;
+ }
+
+ /*
+ * Build an IPP request, which requires the following
+ * attributes:
+ *
+ * attributes-charset
+ * attributes-natural-language
+ * printer-uri + job-id *or* job-uri
+ * [requesting-user-name]
+ */
+
+ request = ippNew();
+
+ request->request.op.operation_id = op;
+ request->request.op.request_id = 1;
+
+ 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);
+
+ if (dest)
+ {
+ httpAssembleURIf(uri, sizeof(uri), "ipp", NULL, "localhost", 0,
+ "/printers/%s", dest);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI,
+ "printer-uri", NULL, uri);
+ ippAddInteger(request, IPP_TAG_OPERATION, IPP_TAG_INTEGER, "job-id",
+ job_id);
+ }
+ else
+ {
+ sprintf(uri, "ipp://localhost/jobs/%d", job_id);
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL,
+ uri);
+ }
+
+ ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
+ "requesting-user-name", NULL, cupsUser());
+
+ /*
+ * Do the request and get back a response...
+ */
+
+ if (op == IPP_PURGE_JOBS)
+ response = cupsDoRequest(http, request, "/admin/");
+ else
+ response = cupsDoRequest(http, request, "/jobs/");
+
+ if (response != NULL)
+ {
+ switch (response->request.status.status_code)
+ {
+ case IPP_NOT_FOUND :
+ _cupsLangPuts(stderr, language,
+ _("lprm: Job or printer not found!\n"));
+ break;
+ case IPP_NOT_AUTHORIZED :
+ _cupsLangPuts(stderr, language,
+ _("lprm: Not authorized to lprm job(s)!\n"));
+ break;
+ case IPP_FORBIDDEN :
+ _cupsLangPrintf(stderr, language,
+ _("lprm: You don't own job ID %d!\n"), job_id);
+ break;
+ default :
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ _cupsLangPuts(stderr, language,
+ _("lprm: Unable to lprm job(s)!\n"));
+ break;
+ }
+
+ if (response->request.status.status_code > IPP_OK_CONFLICT)
+ {
+ ippDelete(response);
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+
+ ippDelete(response);
+ }
+ else
+ {
+ _cupsLangPuts(stderr, language,
+ _("lprm: Unable to cancel job(s)!\n"));
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+ }
+
+ /*
+ * If nothing has been cancelled yet, cancel the current job on the specified
+ * (or default) printer...
+ */
+
+ if (response == NULL)
+ if (!cupsCancelJob(dest, 0))
+ {
+ _cupsLangPuts(stderr, language,
+ _("lprm: Unable to cancel job(s)!\n"));
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+ return (1);
+ }
+
+ cupsFreeDests(num_dests, dests);
+ httpClose(http);
+
+ return (0);
+}
+
+
+/*
+ * End of "$Id: lprm.c 4906 2006-01-10 20:53:28Z mike $".
+ */