Print this page
2837 - remove print/lp* from gate and use CUPS from userland

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/print/mod_ipp/mod_ipp.c
          +++ new/usr/src/lib/print/mod_ipp/mod_ipp.c
↓ open down ↓ 16 lines elided ↑ open up ↑
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23   23   * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24   24   * Use is subject to license terms.
  25   25   *
  26   26   */
       27 +/*
       28 + * Copyright (c) 2013 Andrew Stormont.  All rights reserved.
       29 + */
  27   30  
  28   31  /* $Id: mod_ipp.c 149 2006-04-25 16:55:01Z njacobs $ */
  29   32  
  30      -#pragma ident   "%Z%%M% %I%     %E% SMI"
  31      -
  32   33  /*
  33   34   * Internet Printing Protocol (IPP) module for Apache.
  34   35   */
  35   36  
  36   37  #include "ap_config.h"
  37   38  
  38   39  #include <stdio.h>
  39   40  #include <time.h>
  40   41  #include <sys/time.h>
  41   42  #include <values.h>
  42   43  #include <libintl.h>
  43   44  #include <alloca.h>
  44   45  
  45   46  #include "httpd.h"
  46   47  #include "http_config.h"
  47   48  #include "http_core.h"
  48   49  #include "http_protocol.h"
  49   50  #include "http_log.h"
  50   51  #include "http_main.h"
  51   52  #include "papi.h"
  52      -#ifndef APACHE_RELEASE  /* appears to only exist in Apache 1.X */
  53      -#define APACHE2
  54      -#include "apr_compat.h"
       53 +/* Try and guess the version of apache */
       54 +#ifdef APACHE_RELEASE
       55 +# define AP_SERVER_MAJORVERSION_NUMBER 1
       56 +# define AP_SERVER_MINORVERSION_NUMBER 0
       57 +#else
       58 +# ifndef AP_SERVER_MAJORVERSION_NUMBER
       59 +#  define AP_SERVER_MAJORVERSION_NUMBER 2
       60 +# endif
       61 +# ifndef AP_SERVER_MINORVERSION_NUMBER
       62 +#  define AP_SERVER_MINORVERSION_NUMBER 0
       63 +# endif
  55   64  #endif
  56   65  
  57   66  #include <papi.h>
  58   67  #include <ipp-listener.h>
  59   68  
  60      -#ifndef APACHE2
       69 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
  61   70  module MODULE_VAR_EXPORT ipp_module;
  62   71  #else
  63   72  module AP_MODULE_DECLARE_DATA ipp_module;
  64   73  #endif
  65   74  
  66   75  #ifndef AP_INIT_TAKE1   /* Apache 2.X has this, but 1.3.X does not */
  67   76  #define AP_INIT_NO_ARGS(directive, action, arg, where, mesg) \
  68   77          { directive, action, arg, where, NO_ARGS, mesg }
  69   78  #define AP_INIT_TAKE1(directive, action, arg, where, mesg) \
  70   79          { directive, action, arg, where, TAKE1, mesg }
↓ open down ↓ 39 lines elided ↑ open up ↑
 110  119  }
 111  120  #endif
 112  121  
 113  122  static ssize_t
 114  123  read_data(void *fd, void *buf, size_t siz)
 115  124  {
 116  125          ssize_t len_read;
 117  126          request_rec *ap_r = (request_rec *)fd;
 118  127  
 119  128          len_read = ap_get_client_block(ap_r, buf, siz);
 120      -#ifndef APACHE2
      129 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 121  130          ap_reset_timeout(ap_r);
 122  131  #endif
 123  132  
 124  133  #ifdef DEBUG
 125  134          fprintf(stderr, "read_data(0x%8.8x, 0x%8.8x, %d): %d",
 126  135                          fd, buf, siz, len_read);
 127  136          if (len_read < 0)
 128  137                  fprintf(stderr, ": %s", strerror(errno));
 129  138          putc('\n', stderr);
 130  139          dump_buffer(stderr, "read_data:", buf, len_read);
↓ open down ↓ 1 lines elided ↑ open up ↑
 132  141  
 133  142          return (len_read);
 134  143  }
 135  144  
 136  145  static ssize_t
 137  146  write_data(void *fd, void *buf, size_t siz)
 138  147  {
 139  148          ssize_t len_written;
 140  149          request_rec *ap_r = (request_rec *)fd;
 141  150  
 142      -#ifndef APACHE2
      151 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 143  152          ap_reset_timeout(ap_r);
 144  153  #endif
 145  154  #ifdef DEBUG
 146  155          dump_buffer(stderr, "write_data:", buf, siz);
 147  156  #endif
 148  157          len_written = ap_rwrite(buf, siz, ap_r);
 149  158  
 150  159          return (len_written);
 151  160  }
 152  161  
 153  162  static void
 154  163  discard_data(request_rec *r)
 155  164  {
 156      -#ifdef APACHE2
      165 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 157  166          (void) ap_discard_request_body(r);
 158  167  #else
 159  168          /*
 160  169           * This is taken from ap_discard_request_body().  The reason we can't
 161  170           * just use it in Apache 1.3 is that it does various timeout things we
 162  171           * don't want it to do.  Apache 2.0 doesn't do that, so we can safely
 163  172           * use the normal function.
 164  173           */
 165  174          if (r->read_chunked || r->remaining > 0) {
 166  175                  char dumpbuf[HUGE_STRING_LEN];
↓ open down ↓ 2 lines elided ↑ open up ↑
 169  178                  do {
 170  179                          i = ap_get_client_block(r, dumpbuf, HUGE_STRING_LEN);
 171  180  #ifdef DEBUG
 172  181                          dump_buffer(stderr, "discarded", dumpbuf, i);
 173  182  #endif
 174  183                  } while (i > 0);
 175  184          }
 176  185  #endif
 177  186  }
 178  187  
      188 +#if AP_SERVER_MAJORVERSION_NUMBER > 2 || AP_SERVER_MINORVERSION_NUMBER > 3
      189 +void _log_rerror(const char *file, int line, int module_index,
      190 +        int level, request_rec *r, const char *fmt, ...)
      191 +#else
 179  192  void _log_rerror(const char *file, int line, int level, request_rec *r,
 180  193          const char *fmt, ...)
      194 +#endif
 181  195  {
 182  196          va_list args;
 183  197          size_t size;
 184  198          char *message = alloca(BUFSIZ);
 185  199  
 186  200          va_start(args, fmt);
 187  201          /*
 188  202           * fill in the message.  If the buffer is too small, allocate
 189  203           * one that is large enough and fill it in.
 190  204           */
 191  205          if ((size = vsnprintf(message, BUFSIZ, fmt, args)) >= BUFSIZ)
 192  206                  if ((message = alloca(size)) != NULL)
 193  207                          vsnprintf(message, size, fmt, args);
 194  208          va_end(args);
 195  209  
 196      -#ifdef APACHE2
      210 +#if AP_SERVER_MAJORVERSION_NUMBER > 2 || AP_SERVER_MINORVERSION_NUMBER > 3
      211 +        ap_log_rerror(file, line, module_index, level, APR_SUCCESS, r, message);
      212 +#elif AP_SERVER_MAJORVERSION_NUMBER > 1
 197  213          ap_log_rerror(file, line, level, NULL, r, message);
 198  214  #else
 199  215          ap_log_rerror(file, line, level, r, message);
 200  216  #endif
 201  217  }
 202  218  
 203  219  static int
 204  220  ipp_handler(request_rec *r)
 205  221  {
 206  222          papi_attribute_t **request = NULL, **response = NULL;
 207  223          IPPListenerConfig *config;
 208  224          papi_status_t status;
 209  225          int ret;
      226 +#if AP_SERVER_MAJORVERSION_NUMBER > 1
      227 +        apr_os_sock_t *os_sock = NULL;
      228 +        apr_status_t st;
      229 +#endif
 210  230  
 211  231          /* Really, IPP is all POST requests */
 212  232          if (r->method_number != M_POST)
 213  233                  return (DECLINED);
 214  234  
 215      -#ifndef APACHE2
      235 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 216  236          /*
 217  237           * An IPP request must have a MIME type of "application/ipp"
 218  238           * (RFC-2910, Section 4, page 19).  If it doesn't match this
 219  239           * MIME type, we should decline the request and let someone else
 220  240           * try and handle it.
 221  241           */
 222  242          if (r->headers_in != NULL) {
 223  243                  char *mime_type = (char *)ap_table_get(r->headers_in,
 224  244                                                          "Content-Type");
 225  245  
↓ open down ↓ 2 lines elided ↑ open up ↑
 228  248                          return (DECLINED);
 229  249          }
 230  250  #endif
 231  251          /* CHUNKED_DECHUNK might not work right for IPP? */
 232  252          if ((ret = ap_setup_client_block(r, REQUEST_CHUNKED_DECHUNK)) != OK)
 233  253                  return (ret);
 234  254  
 235  255          if (!ap_should_client_block(r))
 236  256                  return (HTTP_INTERNAL_SERVER_ERROR);
 237  257  
 238      -#ifndef APACHE2
      258 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 239  259          ap_soft_timeout("ipp_module: read/reply request ", r);
 240  260  #endif
 241  261          /* read the IPP request off the network */
 242  262          status = ipp_read_message(read_data, r, &request, IPP_TYPE_REQUEST);
 243  263  
 244  264          if (status != PAPI_OK)
 245  265                  _log_rerror(APLOG_MARK, APLOG_ERR, r,
 246  266                          "read failed: %s\n", papiStatusString(status));
 247  267  #ifdef DEBUG
 248  268          papiAttributeListPrint(stderr, request, "request (%d)  ", getpid());
 249  269  #endif
 250  270  
 251  271          (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
 252  272                  "originating-host", (char *)
 253      -#ifdef APACHE2
      273 +#if AP_SERVER_MAJORVERSION_NUMBER >= 2
 254  274                  ap_get_remote_host
 255  275                          (r->connection, r->per_dir_config, REMOTE_NAME, NULL));
 256  276  #else
 257  277                  ap_get_remote_host
 258  278                          (r->connection, r->per_dir_config, REMOTE_NAME));
 259  279  #endif
 260  280  
 261  281          (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
 262  282                                  "uri-port", ap_get_server_port(r));
 263  283          if (r->headers_in != NULL) {
      284 +#if AP_SERVER_MAJORVERSION_NUMBER >= 2 || AP_SERVER_MINORVERSION_NUMBER > 2
      285 +                char *host = (char *)apr_table_get(r->headers_in, "Host");
      286 +#else
 264  287                  char *host = (char *)ap_table_get(r->headers_in, "Host");
      288 +#endif
 265  289  
 266  290                  if ((host == NULL) || (host[0] == '\0'))
 267  291                          host = (char *)ap_get_server_name(r);
 268  292  
 269  293                  (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
 270  294                                  "uri-host", host);
 271  295          }
 272  296          (void) papiAttributeListAddString(&request, PAPI_ATTR_EXCL,
 273  297                                  "uri-path", r->uri);
 274  298  
↓ open down ↓ 9 lines elided ↑ open up ↑
 284  308                                                  config->default_user);
 285  309                  if (config->default_svc != NULL)
 286  310                          (void) papiAttributeListAddString(&request,
 287  311                                          PAPI_ATTR_EXCL, "default-service",
 288  312                                          config->default_svc);
 289  313          }
 290  314  
 291  315          /*
 292  316           * For Trusted Solaris, pass the fd number of the socket connection
 293  317           * to the backend so the it can be forwarded to the backend print
 294      -         * service to retrieve the sensativity label off of a multi-level
      318 +         * service to retrieve the sensitivity label off of a multi-level
 295  319           * port.
 296  320           */
      321 +#if AP_SERVER_MAJORVERSION_NUMBER > 1
      322 +        st = apr_os_sock_get(os_sock, r->connection->cs->pfd.desc.s);
      323 +        if (st == APR_SUCCESS) {
      324 +                (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
      325 +                        "peer-socket", (int)os_sock);
      326 +        }
      327 +#else
 297  328          (void) papiAttributeListAddInteger(&request, PAPI_ATTR_EXCL,
 298      -                        "peer-socket", ap_bfileno(r->connection->client, B_RD));
      329 +                "peer-socket", ap_bfileno(r->connection->client, B_RD));
      330 +#endif
 299  331  
 300  332          /* process the request */
 301  333          status = ipp_process_request(request, &response, read_data, r);
 302  334          if (status != PAPI_OK) {
 303  335                  errno = 0;
 304  336                  _log_rerror(APLOG_MARK, APLOG_ERR, r,
 305  337                          "request failed: %s\n", papiStatusString(status));
 306  338                  discard_data(r);
 307  339          }
 308  340  #ifdef DEBUG
 309  341          fprintf(stderr, "processing result: %s\n", papiStatusString(status));
 310  342          papiAttributeListPrint(stderr, response, "response (%d)  ", getpid());
 311  343  #endif
 312  344  
 313  345          /*
 314  346           * If the client is using chunking and we have not yet received the
 315  347           * final "0" sized chunk, we need to discard any data that may
 316  348           * remain in the post request.
 317  349           */
 318  350          if ((r->read_chunked != 0) &&
      351 +#if AP_SERVER_MAJORVERSION_NUMBER >= 2 || AP_SERVER_MINORVERSION_NUMBER > 2
      352 +            (apr_table_get(r->headers_in, "Content-Length") == NULL))
      353 +#else
 319  354              (ap_table_get(r->headers_in, "Content-Length") == NULL))
      355 +#endif
 320  356                  discard_data(r);
 321  357  
 322  358          /* write an IPP response back to the network */
 323  359          r->content_type = "application/ipp";
 324  360  
 325      -#ifndef APACHE2
      361 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 326  362          ap_send_http_header(r);
 327  363  #endif
 328  364  
 329  365          status = ipp_write_message(write_data, r, response);
 330  366          if (status != PAPI_OK)
 331  367                  _log_rerror(APLOG_MARK, APLOG_ERR, r,
 332  368                          "write failed: %s\n", papiStatusString(status));
 333  369  #ifdef DEBUG
 334  370          fprintf(stderr, "write result: %s\n", papiStatusString(status));
 335  371          fflush(stderr);
 336  372  #endif
 337  373  
 338  374          papiAttributeListFree(request);
 339  375          papiAttributeListFree(response);
 340  376  
 341      -#ifndef APACHE2
      377 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 342  378          ap_kill_timeout(r);
 343  379          if (ap_rflush(r) < 0)
 344  380                  _log_rerror(APLOG_MARK, APLOG_ERR, r,
 345  381                          "flush failed, response may not have been sent");
 346  382  #endif
 347  383  
 348  384          return (OK);
 349  385  }
 350  386  
 351  387  
 352  388  /*ARGSUSED1*/
 353  389  static void *
 354  390  create_ipp_dir_config(
 355      -#ifndef APACHE2
      391 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 356  392          pool *p,
 357  393  #else
 358  394          apr_pool_t *p,
 359  395  #endif
 360  396          char *dirspec)
 361  397  {
 362  398          IPPListenerConfig *config =
 363      -#ifndef APACHE2
      399 +#if AP_SERVER_MAJORVERSION_NUMBER < 2
 364  400                  ap_pcalloc(p, sizeof (*config));
 365  401  #else
 366  402                  apr_pcalloc(p, sizeof (*config));
 367  403  #endif
 368  404  
 369  405          if (config != NULL) {
 370  406                  (void) memset(config, 0, sizeof (*config));
 371  407                  config->conformance = IPP_PARSE_CONFORMANCE_RASH;
 372  408                  config->default_user = NULL;
 373  409                  config->default_svc = NULL;
↓ open down ↓ 18 lines elided ↑ open up ↑
 392  428                  config->conformance = IPP_PARSE_CONFORMANCE_STRICT;
 393  429          } else {
 394  430                  return ("unknown conformance, try (automatic/1.0/1.1)");
 395  431          }
 396  432  
 397  433          return (NULL);
 398  434  }
 399  435  
 400  436  /*ARGSUSED0*/
 401  437  static const char *
 402      -ipp_operation(cmd_parms *cmd, void *cfg, char *op, char *toggle)
      438 +ipp_operation(cmd_parms *cmd, void *cfg, const char *op, const char *toggle)
 403  439  {
 404  440          IPPListenerConfig *config = (IPPListenerConfig *)cfg;
 405  441          papi_status_t status;
 406  442  
 407  443          status = ipp_configure_operation(&config->operations, op, toggle);
 408  444          switch (status) {
 409  445          case PAPI_OK:
 410  446                  return (NULL);
 411  447          case PAPI_BAD_ARGUMENT:
 412  448                  return (gettext("internal error (invalid argument)"));
↓ open down ↓ 49 lines elided ↑ open up ↑
 462  498                  "default user for various operations"),
 463  499          AP_INIT_TAKE1("ipp-default-service", ipp_default_svc, NULL, ACCESS_CONF,
 464  500                  "default service for various operations"),
 465  501  #ifdef DEBUG
 466  502          AP_INIT_NO_ARGS("ipp-module-hang", ipp_module_hang, NULL, ACCESS_CONF,
 467  503                  "hang the module until we can attach a debugger (no args)"),
 468  504  #endif
 469  505          { NULL }
 470  506  };
 471  507  
 472      -#ifdef APACHE2
      508 +#if AP_SERVER_MAJORVERSION_NUMBER >= 2
 473  509  /*ARGSUSED0*/
 474  510  static const char *
 475  511  ipp_method(const request_rec *r)
 476  512  {
 477  513          return ("ipp");
 478  514  }
 479  515  
 480  516  /*ARGSUSED0*/
 481  517  static unsigned short
 482  518  ipp_port(const request_rec *r)
↓ open down ↓ 4 lines elided ↑ open up ↑
 487  523  /* Dispatch list for API hooks */
 488  524  /*ARGSUSED0*/
 489  525  static void
 490  526  ipp_register_hooks(apr_pool_t *p)
 491  527  {
 492  528          static const char * const modules[] = { "mod_dir.c", NULL };
 493  529  
 494  530          /* Need to make sure we don't get directory listings by accident */
 495  531          ap_hook_handler(ipp_handler, NULL, modules, APR_HOOK_MIDDLE);
 496  532          ap_hook_default_port(ipp_port, NULL, NULL, APR_HOOK_MIDDLE);
      533 +#if AP_SERVER_MAJORVERSION_NUMBER >= 2
      534 +        ap_hook_http_scheme(ipp_method, NULL, NULL, APR_HOOK_MIDDLE);
      535 +#else
 497  536          ap_hook_http_method(ipp_method, NULL, NULL, APR_HOOK_MIDDLE);
      537 +#endif
 498  538  }
 499  539  
 500  540  module AP_MODULE_DECLARE_DATA ipp_module = {
 501  541          STANDARD20_MODULE_STUFF,
 502  542          create_ipp_dir_config,          /* create per-dir    config     */
 503  543          NULL,                           /* merge  per-dir    config     */
 504  544          NULL,                           /* create per-server config     */
 505  545          NULL,                           /* merge  per-server config     */
 506  546          ipp_cmds,                       /* table of config commands     */
 507  547          ipp_register_hooks              /* register hooks               */
↓ open down ↓ 45 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX