summaryrefslogtreecommitdiff
path: root/usr/src/lib/print/mod_ipp/mod_ipp.c
diff options
context:
space:
mode:
authorjacobs <none@none>2006-06-22 13:28:31 -0700
committerjacobs <none@none>2006-06-22 13:28:31 -0700
commit355b4669e025ff377602b6fc7caaf30dbc218371 (patch)
tree29a740456e8d09f935e18068ce72814285fafeec /usr/src/lib/print/mod_ipp/mod_ipp.c
parent5d0bc3ededb82d77f7c33d8f58e517a837ba5140 (diff)
downloadillumos-gate-355b4669e025ff377602b6fc7caaf30dbc218371.tar.gz
LSARC/2003/547 PAPI Print Commands
LSARC/2006/172 PAPI Print Commands Packaging Breakout 4144591 lpstat -d reports *process* default printer as *system* default printer 4299193 lp -cd <queue> <file> causes multiple -d options errors 4327963 RFE cancel on local queue should not require in.lpd 4331220 lpmove doesn't work on remote print queues 4470602 Customer wants to increase print limit of 52 files to 300 4949866 lpstat shows FAILED printers due to expanded status message 4994469 lpadmin doesn't add filter definitions for printers 6302778 RUNPATH & RPATH errors in SUNWipplu package 6314007 lpstat should report paper type list supported by a printer 6317991 lprm -Pprintername - command results in aSegmentation fault 6338002 lpsched support for PAPI is incomplete 6346505 print commands should use PAPI for service interaction (LSARC/2003/547) 6364267 psm-lpsched has replicated code 6389273 RUNPATH and RPATH failures in SUNWippcore --HG-- rename : usr/src/cmd/lp/cmd/cancel.c => deleted_files/usr/src/cmd/lp/cmd/cancel.c rename : usr/src/cmd/lp/cmd/comb.c => deleted_files/usr/src/cmd/lp/cmd/comb.c rename : usr/src/cmd/lp/cmd/lp.c => deleted_files/usr/src/cmd/lp/cmd/lp.c rename : usr/src/cmd/lp/cmd/lpc/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpc/Makefile rename : usr/src/cmd/lp/cmd/lpc/cmds.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmds.c rename : usr/src/cmd/lp/cmd/lpc/cmdtab.c => deleted_files/usr/src/cmd/lp/cmd/lpc/cmdtab.c rename : usr/src/cmd/lp/cmd/lpc/fatalmsg.c => deleted_files/usr/src/cmd/lp/cmd/lpc/fatalmsg.c rename : usr/src/cmd/lp/cmd/lpc/global.c => deleted_files/usr/src/cmd/lp/cmd/lpc/global.c rename : usr/src/cmd/lp/cmd/lpc/lpc.c => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.c rename : usr/src/cmd/lp/cmd/lpc/lpc.h => deleted_files/usr/src/cmd/lp/cmd/lpc/lpc.h rename : usr/src/cmd/lp/cmd/lpc/process.c => deleted_files/usr/src/cmd/lp/cmd/lpc/process.c rename : usr/src/cmd/lp/cmd/lpc/sndrcv.c => deleted_files/usr/src/cmd/lp/cmd/lpc/sndrcv.c rename : usr/src/cmd/lp/cmd/lpc/topq.c => deleted_files/usr/src/cmd/lp/cmd/lpc/topq.c rename : usr/src/cmd/lp/cmd/lpmove.c => deleted_files/usr/src/cmd/lp/cmd/lpmove.c rename : usr/src/cmd/lp/cmd/lpstat/Makefile => deleted_files/usr/src/cmd/lp/cmd/lpstat/Makefile rename : usr/src/cmd/lp/cmd/lpstat/accept.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/accept.c rename : usr/src/cmd/lp/cmd/lpstat/add_mounted.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/add_mounted.c rename : usr/src/cmd/lp/cmd/lpstat/charset.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/charset.c rename : usr/src/cmd/lp/cmd/lpstat/class.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/class.c rename : usr/src/cmd/lp/cmd/lpstat/device.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/device.c rename : usr/src/cmd/lp/cmd/lpstat/done.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/done.c rename : usr/src/cmd/lp/cmd/lpstat/form.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/form.c rename : usr/src/cmd/lp/cmd/lpstat/lpstat.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.c rename : usr/src/cmd/lp/cmd/lpstat/lpstat.h => deleted_files/usr/src/cmd/lp/cmd/lpstat/lpstat.h rename : usr/src/cmd/lp/cmd/lpstat/output.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/output.c rename : usr/src/cmd/lp/cmd/lpstat/parse.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/parse.c rename : usr/src/cmd/lp/cmd/lpstat/printer.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/printer.c rename : usr/src/cmd/lp/cmd/lpstat/request.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/request.c rename : usr/src/cmd/lp/cmd/lpstat/send_message.c => deleted_files/usr/src/cmd/lp/cmd/lpstat/send_message.c rename : usr/src/cmd/lp/lib/papi/attribute.c => deleted_files/usr/src/cmd/lp/lib/papi/attribute.c rename : usr/src/cmd/lp/lib/papi/list.c => deleted_files/usr/src/cmd/lp/lib/papi/list.c rename : usr/src/cmd/lp/lib/papi/papi.h => deleted_files/usr/src/cmd/lp/lib/papi/papi.h rename : usr/src/cmd/lp/lib/papi/status.c => deleted_files/usr/src/cmd/lp/lib/papi/status.c rename : usr/src/cmd/print/cancel/Makefile => deleted_files/usr/src/cmd/print/cancel/Makefile rename : usr/src/cmd/print/cancel/cancel.c => deleted_files/usr/src/cmd/print/cancel/cancel.c rename : usr/src/cmd/print/cancel/cancel_list.c => deleted_files/usr/src/cmd/print/cancel/cancel_list.c rename : usr/src/cmd/print/cancel/cancel_list.h => deleted_files/usr/src/cmd/print/cancel/cancel_list.h rename : usr/src/cmd/print/lp/Makefile => deleted_files/usr/src/cmd/print/lp/Makefile rename : usr/src/cmd/print/lpmove/Makefile => deleted_files/usr/src/cmd/print/lpmove/Makefile rename : usr/src/cmd/print/lpmove/lpmove.c => deleted_files/usr/src/cmd/print/lpmove/lpmove.c rename : usr/src/cmd/print/lpstat/Makefile => deleted_files/usr/src/cmd/print/lpstat/Makefile rename : usr/src/cmd/print/lpstat/bsd-functions.c => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.c rename : usr/src/cmd/print/lpstat/bsd-functions.h => deleted_files/usr/src/cmd/print/lpstat/bsd-functions.h rename : usr/src/cmd/print/lpstat/lpstat.c => deleted_files/usr/src/cmd/print/lpstat/lpstat.c rename : usr/src/cmd/print/lpstat/parse.h => deleted_files/usr/src/cmd/print/lpstat/parse.h rename : usr/src/cmd/print/lpstat/parse_bsd.c => deleted_files/usr/src/cmd/print/lpstat/parse_bsd.c rename : usr/src/cmd/print/lpstat/sysv-functions.c => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.c rename : usr/src/cmd/print/lpstat/sysv-functions.h => deleted_files/usr/src/cmd/print/lpstat/sysv-functions.h rename : usr/src/cmd/print/scripts/accept => deleted_files/usr/src/cmd/print/scripts/accept rename : usr/src/cmd/lp/lib/papi/mapfile-vers => usr/src/cmd/lp/lib/papi/mapfile rename : usr/src/cmd/print/lp/cleanup.xml => usr/src/cmd/print/gateway/cleanup.xml rename : usr/src/cmd/print/lp/print-cleanup => usr/src/cmd/print/gateway/print-cleanup rename : usr/src/cmd/print/lp/lp.c => usr/src/cmd/print/gateway/printd.c rename : usr/src/lib/print/job.c => usr/src/lib/print/libprint/common/job.c rename : usr/src/lib/print/job.h => usr/src/lib/print/libprint/common/job.h rename : usr/src/lib/print/list.c => usr/src/lib/print/libprint/common/list.c rename : usr/src/lib/print/list.h => usr/src/lib/print/libprint/common/list.h rename : usr/src/lib/print/llib-lprint => usr/src/lib/print/libprint/common/llib-lprint rename : usr/src/lib/print/mapfile-vers => usr/src/lib/print/libprint/common/mapfile-vers rename : usr/src/lib/print/misc.c => usr/src/lib/print/libprint/common/misc.c rename : usr/src/lib/print/misc.h => usr/src/lib/print/libprint/common/misc.h rename : usr/src/lib/print/network.c => usr/src/lib/print/libprint/common/network.c rename : usr/src/lib/print/network.h => usr/src/lib/print/libprint/common/network.h rename : usr/src/lib/print/ns.c => usr/src/lib/print/libprint/common/ns.c rename : usr/src/lib/print/ns.h => usr/src/lib/print/libprint/common/ns.h rename : usr/src/lib/print/ns_bsd_addr.c => usr/src/lib/print/libprint/common/ns_bsd_addr.c rename : usr/src/lib/print/ns_cmn_kvp.c => usr/src/lib/print/libprint/common/ns_cmn_kvp.c rename : usr/src/lib/print/ns_cmn_printer.c => usr/src/lib/print/libprint/common/ns_cmn_printer.c rename : usr/src/lib/print/nss_convert.c => usr/src/lib/print/libprint/common/nss_convert.c rename : usr/src/lib/print/nss_ldap.c => usr/src/lib/print/libprint/common/nss_ldap.c rename : usr/src/lib/print/nss_printer.c => usr/src/lib/print/libprint/common/nss_printer.c rename : usr/src/lib/print/nss_write.c => usr/src/lib/print/libprint/common/nss_write.c rename : usr/src/lib/print/sunPrinter.at.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.at.conf.txt rename : usr/src/lib/print/sunPrinter.oc.conf.txt => usr/src/lib/print/libprint/common/sunPrinter.oc.conf.txt
Diffstat (limited to 'usr/src/lib/print/mod_ipp/mod_ipp.c')
-rw-r--r--usr/src/lib/print/mod_ipp/mod_ipp.c552
1 files changed, 552 insertions, 0 deletions
diff --git a/usr/src/lib/print/mod_ipp/mod_ipp.c b/usr/src/lib/print/mod_ipp/mod_ipp.c
new file mode 100644
index 0000000000..2d9ece2287
--- /dev/null
+++ b/usr/src/lib/print/mod_ipp/mod_ipp.c
@@ -0,0 +1,552 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+
+/*
+ * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ *
+ */
+
+/* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */
+
+#pragma ident "%Z%%M% %I% %E% SMI"
+
+/*
+ * Internet Printing Protocol (IPP) module for Apache.
+ */
+
+#include "ap_config.h"
+
+#include <stdio.h>
+#include <time.h>
+#include <sys/time.h>
+#include <values.h>
+#include <libintl.h>
+#include <alloca.h>
+
+#include "httpd.h"
+#include "http_config.h"
+#include "http_core.h"
+#include "http_protocol.h"
+#include "http_log.h"
+#include "http_main.h"
+#include "papi.h"
+#ifndef APACHE_RELEASE /* appears to only exist in Apache 1.X */
+#define APACHE2
+#include "apr_compat.h"
+#endif
+
+#include <papi.h>
+#include <ipp-listener.h>
+
+#ifndef APACHE2
+module MODULE_VAR_EXPORT ipp_module;
+#else
+module AP_MODULE_DECLARE_DATA ipp_module;
+#endif
+
+#ifndef AP_INIT_TAKE1 /* Apache 2.X has this, but 1.3.X does not */
+#define AP_INIT_NO_ARGS(directive, action, arg, where, mesg) \
+ { directive, action, arg, where, NO_ARGS, mesg }
+#define AP_INIT_TAKE1(directive, action, arg, where, mesg) \
+ { directive, action, arg, where, TAKE1, mesg }
+#define AP_INIT_TAKE2(directive, action, arg, where, mesg) \
+ { directive, action, arg, where, TAKE2, mesg }
+#endif
+
+typedef struct {
+ int conformance;
+ char *default_user;
+ char *default_svc;
+ papi_attribute_t **operations;
+} IPPListenerConfig;
+
+#ifdef DEBUG
+void
+dump_buffer(FILE *fp, char *tag, char *buffer, int bytes)
+{
+ int i, j, ch;
+
+ fprintf(fp, "%s %d(0x%x) bytes\n", (tag ? tag : ""), bytes, bytes);
+ for (i = 0; i < bytes; i += 16) {
+ fprintf(fp, "%s ", (tag ? tag : ""));
+
+ for (j = 0; j < 16 && (i + j) < bytes; j ++)
+ fprintf(fp, " %02X", buffer[i + j] & 255);
+
+ while (j < 16) {
+ fprintf(fp, " ");
+ j++;
+ }
+
+ fprintf(fp, " ");
+ for (j = 0; j < 16 && (i + j) < bytes; j ++) {
+ ch = buffer[i + j] & 255;
+ if (ch < ' ' || ch == 127)
+ ch = '.';
+ putc(ch, fp);
+ }
+ putc('\n', fp);
+ }
+ fflush(fp);
+}
+#endif
+
+static ssize_t
+read_data(void *fd, void *buf, size_t siz)
+{
+ ssize_t len_read;
+ request_rec *ap_r = (request_rec *)fd;
+
+ len_read = ap_get_client_block(ap_r, buf, siz);
+#ifndef APACHE2
+ ap_reset_timeout(ap_r);
+#endif
+
+#ifdef DEBUG
+ fprintf(stderr, "read_data(0x%8.8x, 0x%8.8x, %d): %d",
+ fd, buf, siz, len_read);
+ if (len_read < 0)
+ fprintf(stderr, ": %s", strerror(errno));
+ putc('\n', stderr);
+ dump_buffer(stderr, "read_data:", buf, len_read);
+#endif
+
+ return (len_read);
+}
+
+static ssize_t
+write_data(void *fd, void *buf, size_t siz)
+{
+ ssize_t len_written;
+ request_rec *ap_r = (request_rec *)fd;
+
+#ifndef APACHE2
+ ap_reset_timeout(ap_r);
+#endif
+#ifdef DEBUG
+ dump_buffer(stderr, "write_data:", buf, siz);
+#endif
+ len_written = ap_rwrite(buf, siz, ap_r);
+
+ return (len_written);
+}
+
+static void
+discard_data(request_rec *r)
+{
+#ifdef APACHE2
+ (void) ap_discard_request_body(r);
+#else
+ /*
+ * This is taken from ap_discard_request_body(). The reason we can't
+ * just use it in Apache 1.3 is that it does various timeout things we
+ * don't want it to do. Apache 2.0 doesn't do that, so we can safely
+ * use the normal function.
+ */
+ if (r->read_chunked || r->remaining > 0) {
+ char dumpbuf[HUGE_STRING_LEN];
+ int i;
+
+ do {
+ i = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN);
+#ifdef DEBUG
+ dump_buffer(stderr, "discarded", dumpbuf, i);
+#endif
+ } while (i > 0);
+ }
+#endif
+}
+
+void _log_rerror(const char *file, int line, int level, request_rec *r,
+ const char *fmt, ...)
+{
+ va_list args;
+ size_t size;
+ char *message = alloca(BUFSIZ);
+
+ va_start(args, fmt);
+ /*
+ * fill in the message. If the buffer is too small, allocate
+ * one that is large enough and fill it in.
+ */
+ if ((size = vsnprintf(message, BUFSIZ, fmt, args)) >= BUFSIZ)
+ if ((message = alloca(size)) != NULL)
+ vsnprintf(message, size, fmt, args);
+ va_end(args);
+
+#ifdef APACHE2
+ ap_log_rerror(file, line, level, NULL, r, message);
+#else
+ ap_log_rerror(file, line, level, r, message);
+#endif
+}
+
+static int
+ipp_handler(request_rec *r)
+{
+ papi_attribute_t **request = NULL, **response = NULL;
+ IPPListenerConfig *config;
+ papi_status_t status;
+ int ret;
+
+ /* Really, IPP is all POST requests */
+ if (r->method_number != M_POST)
+ return (DECLINED);
+
+#ifndef APACHE2
+ /*
+ * An IPP request must have a MIME type of "application/ipp"
+ * (RFC-2910, Section 4, page 19). If it doesn't match this
+ * MIME type, we should decline the request and let someone else
+ * try and handle it.
+ */
+ if (r->headers_in != NULL) {
+ char *mime_type = (char *)ap_table_get(r->headers_in,
+ "Content-Type");
+
+ if ((mime_type == NULL) ||
+ (strcasecmp(mime_type, "application/ipp") != 0))
+ return (DECLINED);
+ }
+#endif
+ /* CHUNKED_DECHUNK might not work right for IPP? */
+ if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK)
+ return (ret);
+
+ if (!ap_should_client_block(r))
+ return (HTTP_INTERNAL_SERVER_ERROR);
+
+#ifndef APACHE2
+ ap_soft_timeout("ipp_module: read/reply request ", r);
+#endif
+ /* read the IPP request off the network */
+ status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST);
+
+ if (status != PAPI_OK)
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "read failed: %s\n", papiStatusString(status));
+#ifdef DEBUG
+ papiAttributeListPrint(stderr, request, "request (%d) ", getpid());
+#endif
+
+ (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
+ "originating-host", (char *)
+#ifdef APACHE2
+ ap_get_remote_host
+ (r->connection, r->per_dir_config, REMOTE_NAME, NULL));
+#else
+ ap_get_remote_host
+ (r->connection, r->per_dir_config, REMOTE_NAME));
+#endif
+
+ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
+ "uri-port", ap_get_server_port(r));
+ if (r->headers_in != NULL) {
+ char *host = (char *)ap_table_get(r->headers_in, "Host");
+
+ if ((host == NULL) || (host[0] == '\0'))
+ host = (char *)ap_get_server_name(r);
+
+ (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
+ "uri-host", host);
+ }
+ (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
+ "uri-path", r->uri);
+
+ config = ap_get_module_config(r->per_dir_config, &ipp_module);
+ if (config != NULL) {
+ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
+ "conformance", config->conformance);
+ (void) papiAttributeListAddCollection(&request, PAPI_ATTR_EXCL,
+ "operations", config->operations);
+ if (config->default_user != NULL)
+ (void) papiAttributeListAddString(&request,
+ PAPI_ATTR_EXCL, "default-user",
+ config->default_user);
+ if (config->default_svc != NULL)
+ (void) papiAttributeListAddString(&request,
+ PAPI_ATTR_EXCL, "default-service",
+ config->default_svc);
+ }
+
+ /*
+ * For Trusted Solaris, pass the fd number of the socket connection
+ * to the backend so the it can be forwarded to the backend print
+ * service to retrieve the sensativity label off of a multi-level
+ * port.
+ */
+ (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
+ "peer-socket", ap_bfileno(r->connection->client, B_RD));
+
+ /* process the request */
+ status = ipp_process_request(request, &response, read_data, r);
+ if (status != PAPI_OK) {
+ errno = 0;
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "request failed: %s\n", papiStatusString(status));
+ discard_data(r);
+ }
+#ifdef DEBUG
+ fprintf(stderr, "processing result: %s\n", papiStatusString(status));
+ papiAttributeListPrint(stderr, response, "response (%d) ", getpid());
+#endif
+
+ /*
+ * If the client is using chunking and we have not yet received the
+ * final "0" sized chunk, we need to discard any data that may
+ * remain in the post request.
+ */
+ if ((r->read_chunked != 0) &&
+ (ap_table_get(r->headers_in, "Content-Length") == NULL))
+ discard_data(r);
+
+ /* write an IPP response back to the network */
+ r->content_type = "application/ipp";
+
+#ifndef APACHE2
+ ap_send_http_header(r);
+#endif
+
+ status = ipp_write_message(write_data, r, response);
+ if (status != PAPI_OK)
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "write failed: %s\n", papiStatusString(status));
+#ifdef DEBUG
+ fprintf(stderr, "write result: %s\n", papiStatusString(status));
+ fflush(stderr);
+#endif
+
+ papiAttributeListFree(request);
+ papiAttributeListFree(response);
+
+#ifndef APACHE2
+ ap_kill_timeout(r);
+ if (ap_rflush(r) < 0)
+ _log_rerror(APLOG_MARK, APLOG_ERR, r,
+ "flush failed, response may not have been sent");
+#endif
+
+ return (OK);
+}
+
+
+/*ARGSUSED1*/
+static void *
+create_ipp_dir_config(
+#ifndef APACHE2
+ pool *p,
+#else
+ apr_pool_t *p,
+#endif
+ char *dirspec)
+{
+ IPPListenerConfig *config =
+#ifndef APACHE2
+ ap_pcalloc(p, sizeof (*config));
+#else
+ apr_pcalloc(p, sizeof (*config));
+#endif
+
+ if (config != NULL) {
+ (void) memset(config, 0, sizeof (*config));
+ config->conformance = IPP_PARSE_CONFORMANCE_RASH;
+ config->default_user = NULL;
+ config->default_svc = NULL;
+ (void) ipp_configure_operation(&config->operations, "required",
+ "enable");
+ }
+
+ return (config);
+}
+
+/*ARGSUSED0*/
+static const char *
+ipp_conformance(cmd_parms *cmd, void *cfg, const char *arg)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+
+ if (strncasecmp(arg, "automatic", 4) == 0) {
+ config->conformance = IPP_PARSE_CONFORMANCE_RASH;
+ } else if (strcasecmp(arg, "1.0") == 0) {
+ config->conformance = IPP_PARSE_CONFORMANCE_LOOSE;
+ } else if (strcasecmp(arg, "1.1") == 0) {
+ config->conformance = IPP_PARSE_CONFORMANCE_STRICT;
+ } else {
+ return ("unknown conformance, try (automatic/1.0/1.1)");
+ }
+
+ return (NULL);
+}
+
+/*ARGSUSED0*/
+static const char *
+ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+ papi_status_t status;
+
+ status = ipp_configure_operation(&config->operations, op, toggle);
+ switch (status) {
+ case PAPI_OK:
+ return (NULL);
+ case PAPI_BAD_ARGUMENT:
+ return (gettext("internal error (invalid argument)"));
+ default:
+ return (papiStatusString(status));
+ }
+
+ /* NOTREACHED */
+ /* return (gettext("contact your software vendor")); */
+}
+
+static const char *
+ipp_default_user(cmd_parms *cmd, void *cfg, const char *arg)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+
+ config->default_user = (char *)arg;
+
+ return (NULL);
+}
+
+static const char *
+ipp_default_svc(cmd_parms *cmd, void *cfg, const char *arg)
+{
+ IPPListenerConfig *config = (IPPListenerConfig *)cfg;
+
+ config->default_svc = (char *)arg;
+
+ return (NULL);
+}
+
+#ifdef DEBUG
+/*ARGSUSED0*/
+static const char *
+ipp_module_hang(cmd_parms *cmd, void *cfg)
+{
+ static int i = 1;
+
+ /* wait so we can attach a debugger, assign i = 0, and step through */
+ while (i);
+
+ return (NULL);
+}
+#endif /* DEBUG */
+
+static const command_rec ipp_cmds[] =
+{
+ AP_INIT_TAKE1("ipp-conformance", ipp_conformance, NULL, ACCESS_CONF,
+ "IPP protocol conformance (loose/strict)"),
+ AP_INIT_TAKE2("ipp-operation", ipp_operation, NULL, ACCESS_CONF,
+ "IPP protocol operations to enable/disable)"),
+ AP_INIT_TAKE1("ipp-default-user", ipp_default_user, NULL, ACCESS_CONF,
+ "default user for various operations"),
+ AP_INIT_TAKE1("ipp-default-service", ipp_default_svc, NULL, ACCESS_CONF,
+ "default service for various operations"),
+#ifdef DEBUG
+ AP_INIT_NO_ARGS("ipp-module-hang", ipp_module_hang, NULL, ACCESS_CONF,
+ "hang the module until we can attach a debugger (no args)"),
+#endif
+ { NULL }
+};
+
+#ifdef APACHE2
+/*ARGSUSED0*/
+static const char *
+ipp_method(const request_rec *r)
+{
+ return ("ipp");
+}
+
+/*ARGSUSED0*/
+static unsigned short
+ipp_port(const request_rec *r)
+{
+ return (631);
+}
+
+/* Dispatch list for API hooks */
+/*ARGSUSED0*/
+static void
+ipp_register_hooks(apr_pool_t *p)
+{
+ static const char * const modules[] = { "mod_dir.c", NULL };
+
+ /* Need to make sure we don't get directory listings by accident */
+ ap_hook_handler(ipp_handler, NULL, modules, APR_HOOK_MIDDLE);
+ ap_hook_default_port(ipp_port, NULL, NULL, APR_HOOK_MIDDLE);
+ ap_hook_http_method(ipp_method, NULL, NULL, APR_HOOK_MIDDLE);
+}
+
+module AP_MODULE_DECLARE_DATA ipp_module = {
+ STANDARD20_MODULE_STUFF,
+ create_ipp_dir_config, /* create per-dir config */
+ NULL, /* merge per-dir config */
+ NULL, /* create per-server config */
+ NULL, /* merge per-server config */
+ ipp_cmds, /* table of config commands */
+ ipp_register_hooks /* register hooks */
+};
+
+#else /* Apache 1.X */
+
+/* Dispatch list of content handlers */
+static const handler_rec ipp_handlers[] = {
+ /*
+ * This handler association causes all IPP request with the
+ * correct MIME type to call the protocol handler.
+ */
+ { "application/ipp", ipp_handler },
+ /*
+ * This hander association is causes everything to go through the IPP
+ * protocol request handler. This is necessary because client POST
+ * request may be for something outside of the normal printer-uri
+ * space.
+ */
+ { "*/*", ipp_handler },
+
+ { NULL, NULL }
+};
+
+
+module MODULE_VAR_EXPORT ipp_module = {
+ STANDARD_MODULE_STUFF,
+ NULL, /* module initializer */
+ create_ipp_dir_config, /* create per-dir config structures */
+ NULL, /* merge per-dir config structures */
+ NULL, /* create per-server config structures */
+ NULL, /* merge per-server config structures */
+ ipp_cmds, /* table of config file commands */
+ ipp_handlers, /* [#8] MIME-typed-dispatched handlers */
+ NULL, /* [#1] URI to filename translation */
+ NULL, /* [#4] validate user id from request */
+ NULL, /* [#5] check if the user is ok _here_ */
+ NULL, /* [#3] check access by host address */
+ NULL, /* [#6] determine MIME type */
+ NULL, /* [#7] pre-run fixups */
+ NULL, /* [#9] log a transaction */
+ NULL, /* [#2] header parser */
+ NULL, /* child_init */
+ NULL, /* child_exit */
+ NULL /* [#0] post read-request */
+};
+#endif