/*
* 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
* 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.
*
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */
/*
* Internet Printing Protocol (IPP) module for Apache.
*/
#include "ap_config.h"
#include <stdio.h>
#include <unistd.h>
#include <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"
#ifndef APACHE2
#include "apr_compat.h"
#endif /* APACHE2 */
#include "papi.h"
#include <papi.h>
#include <ipp-listener.h>
#ifndef APACHE2
#else
#endif
#ifndef AP_INIT_TAKE1 /* Apache 2.X has this, but 1.3.X does not */
#endif
typedef struct {
int conformance;
char *default_user;
char *default_svc;
#ifdef DEBUG
void
{
int i, j, ch;
for (i = 0; i < bytes; i += 16) {
for (j = 0; j < 16 && (i + j) < bytes; j ++)
while (j < 16) {
j++;
}
for (j = 0; j < 16 && (i + j) < bytes; j ++) {
ch = '.';
}
}
}
#endif
static ssize_t
{
#ifndef APACHE2
#endif
#ifdef DEBUG
if (len_read < 0)
#endif
return (len_read);
}
static ssize_t
{
#ifndef APACHE2
#endif
#ifdef DEBUG
#endif
return (len_written);
}
static void
{
#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 {
#ifdef DEBUG
#endif
} while (i > 0);
}
#endif
}
const char *fmt, ...)
{
/*
* fill in the message. If the buffer is too small, allocate
* one that is large enough and fill it in.
*/
#ifdef APACHE2
#else
#endif
}
static int
{
const char *s;
int ret;
/* Really, IPP is all POST requests */
if (r->method_number != M_POST)
return (DECLINED);
/*
* 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)
return (DECLINED);
return (DECLINED);
/* CHUNKED_DECHUNK might not work right for IPP? */
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 */
#ifdef DEBUG
#endif
#ifdef APACHE2
REMOTE_NAME, NULL);
#else
#endif
"originating-host", (char *)s);
"uri-port", ap_get_server_port(r));
if (r->headers_in != NULL) {
host = (char *)ap_get_server_name(r);
"uri-host", host);
}
"uri-path", r->uri);
(void) papiAttributeListAddString(&request,
PAPI_ATTR_EXCL, "default-user",
(void) papiAttributeListAddString(&request,
PAPI_ATTR_EXCL, "default-service",
}
/*
* 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.
*/
#ifdef APACHE2
/*
* In Apache 2.4 and later, could use: ap_get_conn_socket()
* Apache 2.2 uses ap_get_module_config() but that needs
* &core_module, for .module_index (which is just zero).
* Could either inline that with index zero, or declare
* core_module here. Latter seems less evil.
*/
{
extern module core_module;
}
#else
#endif
if (sockfd != -1) {
(void) papiAttributeListAddInteger(&request,
}
/* process the request */
errno = 0;
discard_data(r);
}
#ifdef DEBUG
#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) &&
discard_data(r);
/* write an IPP response back to the network */
r->content_type = "application/ipp";
#ifndef APACHE2
#endif
#ifdef DEBUG
#endif
#ifndef APACHE2
ap_kill_timeout(r);
if (ap_rflush(r) < 0)
"flush failed, response may not have been sent");
#endif
return (OK);
}
/*ARGSUSED1*/
static void *
#ifndef APACHE2
pool *p,
#else
apr_pool_t *p,
#endif
char *dirspec)
{
#ifndef APACHE2
#else
#endif
"required", "enable");
}
return (config);
}
/*ARGSUSED0*/
static const char *
{
} else {
return ("unknown conformance, try (automatic/1.0/1.1)");
}
return (NULL);
}
/*ARGSUSED0*/
static const char *
{
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 *
{
return (NULL);
}
static const char *
{
return (NULL);
}
#ifdef DEBUG
/*ARGSUSED0*/
static const char *
{
/*
* Wait so we can attach with a debugger. Once attached,
* assign ipp_module_hang_sleeping = 0 and step through.
*/
while (ipp_module_hang_sleeping)
sleep(1);
return (NULL);
}
#endif /* DEBUG */
{
"default user for various operations"),
"default service for various operations"),
#ifdef DEBUG
"hang the module until we can attach a debugger (no args)"),
#endif
{ NULL }
};
#ifdef APACHE2
/*ARGSUSED0*/
static const char *
{
return ("ipp");
}
/*ARGSUSED0*/
static unsigned short
{
return (631);
}
/* Dispatch list for API hooks */
/*ARGSUSED0*/
static void
{
/* Need to make sure we don't get directory listings by accident */
}
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 */
/*
* 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, /* 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