/*
* "$Id: ipp.c,v 1.235 2005/01/03 19:29:59 mike Exp $"
*
* Contents:
*
* ProcessIPPRequest() - Process an incoming IPP request...
* accept_jobs() - Accept print jobs to a printer.
* add_class() - Add a class to the system.
* add_file() - Add a file to a job.
* add_job_state_reasons() - Add the "job-state-reasons" attribute based
* upon the job and printer state...
* add_printer() - Add a printer to the system.
* add_printer_state_reasons() - Add the "printer-state-reasons" attribute
* based upon the printer state...
* add_queued_job_count() - Add the "queued-job-count" attribute for
* cancel_all_jobs() - Cancel all print jobs.
* cancel_job() - Cancel a print job.
* check_quotas() - Check quotas for a printer and user.
* copy_attribute() - Copy a single attribute.
* copy_attrs() - Copy attributes from one request to another.
* copy_banner() - Copy a banner file to the requests directory
* for the specified job.
* copy_file() - Copy a PPD file or interface script...
* copy_model() - Copy a PPD model file, substituting default
* values as needed...
* create_job() - Print a file to a printer or class.
* delete_printer() - Remove a printer or class from the system.
* get_default() - Get the default destination.
* get_devices() - Get the list of available devices on the
* local system.
* get_jobs() - Get a list of jobs for the specified printer.
* get_job_attrs() - Get job attributes.
* get_ppds() - Get the list of PPD files on the local
* system.
* get_printer_attrs() - Get printer attributes.
* get_printers() - Get a list of printers.
* hold_job() - Hold a print job.
* move_job() - Move a job to a new destination.
* ppd_add_default() - Add a PPD default choice.
* ppd_parse_line() - Parse a PPD default line.
* print_job() - Print a file to a printer or class.
* read_ps_line() - Read a line from a PS file...
* read_ps_job_ticket() - Reads a job ticket embedded in a PS file.
* reject_jobs() - Reject print jobs to a printer.
* release_job() - Release a held print job.
* restart_job() - Restart an old print job.
* send_document() - Send a file to a printer or class.
* send_ipp_error() - Send an error status back to the IPP client.
* set_default() - Set the default destination...
* set_job_attrs() - Set job attributes.
* start_printer() - Start a printer.
* stop_printer() - Stop a printer.
* validate_job() - Validate printer options and destination.
* validate_user() - Validate the user for the request.
*/
/*
* Include necessary headers...
*/
#include "cupsd.h"
#include <pwd.h>
#include <grp.h>
#ifndef agan4014
#include "job.h"
#endif
#ifdef HAVE_LIBPAPER
# include <paper.h>
#endif /* HAVE_LIBPAPER */
#ifndef agan4014
job_t *Jobs = NULL;
#endif
/*
* Local functions...
*/
#if 0
/*
* PPD default choice structure...
*/
typedef struct
{
char option[PPD_MAX_NAME]; /* Main keyword (option name) */
char choice[PPD_MAX_NAME]; /* Option keyword (choice name) */
} ppd_default_t;
static int add_file(client_t *con, job_t *job, mime_type_t *filetype,
int compression);
static void accept_jobs(client_t *con, ipp_attribute_t *uri);
static void add_class(client_t *con, ipp_attribute_t *uri);
static void add_job_state_reasons(client_t *con, job_t *job);
static void cancel_all_jobs(client_t *con, ipp_attribute_t *uri);
static void cancel_job(client_t *con, ipp_attribute_t *uri);
static int check_quotas(client_t *con, printer_t *p);
static int copy_banner(client_t *con, job_t *job, const char *name);
static int copy_file(const char *from, const char *to);
static int copy_model(const char *from, const char *to);
static void create_job(client_t *con, ipp_attribute_t *uri);
static void delete_printer(client_t *con, ipp_attribute_t *uri);
static void get_default(client_t *con);
static void get_devices(client_t *con);
static void get_job_attrs(client_t *con, ipp_attribute_t *uri);
static void get_ppds(client_t *con);
static void get_printers(client_t *con, int type);
static void hold_job(client_t *con, ipp_attribute_t *uri);
static void move_job(client_t *con, ipp_attribute_t *uri);
static int ppd_add_default(const char *option, const char *choice,
int num_defaults, ppd_default_t **defaults);
static int ppd_parse_line(const char *line, char *option, int olen,
char *choice, int clen);
static void read_ps_job_ticket(client_t *con);
static void reject_jobs(client_t *con, ipp_attribute_t *uri);
static void release_job(client_t *con, ipp_attribute_t *uri);
static void restart_job(client_t *con, ipp_attribute_t *uri);
static void send_document(client_t *con, ipp_attribute_t *uri);
static void set_default(client_t *con, ipp_attribute_t *uri);
static void set_job_attrs(client_t *con, ipp_attribute_t *uri);
static void start_printer(client_t *con, ipp_attribute_t *uri);
static void stop_printer(client_t *con, ipp_attribute_t *uri);
static void validate_job(client_t *con, ipp_attribute_t *uri);
static int validate_user(client_t *con, const char *owner, char *username,
int userlen);
static void add_printer(client_t *con, ipp_attribute_t *uri);
#endif
static void send_ipp_error(client_t *con, ipp_status_t status);
static void print_job(client_t *con, ipp_attribute_t *uri);
static void get_jobs(client_t *con, ipp_attribute_t *uri);
static void get_printer_attrs(client_t *con, ipp_attribute_t *uri);
static void add_printer_state_reasons(client_t *con, printer_t *p);
static void add_queued_job_count(client_t *con, printer_t *p);
static ipp_attribute_t *copy_attribute(ipp_t *to, ipp_attribute_t *attr,
int quickcopy);
static void copy_attrs(ipp_t *to, ipp_t *from, ipp_attribute_t *req,
ipp_tag_t group, int quickcopy);
/*
* 'ProcessIPPRequest()' - Process an incoming IPP request...
*/
int /* O - 1 on success, 0 on failure */
ProcessIPPRequest(client_t *con) /* I - Client connection */
{
ipp_tag_t group; /* Current group tag */
ipp_attribute_t *attr; /* Current attribute */
ipp_attribute_t *charset; /* Character set attribute */
ipp_attribute_t *language; /* Language attribute */
ipp_attribute_t *uri; /* Printer URI attribute */
ipp_attribute_t *username; /* requesting-user-name attr */
DEBUG_printf(("Function ProcessIPPRequest() start......\n"));
LogMessage(L_DEBUG2, "ProcessIPPRequest(%p[%d]): operation_id = %04x",
con, con->http.fd, con->request->request.op.operation_id);
/*
* First build an empty response message for this request...
*/
con->response = ippNew();
con->response->request.status.version[0] = con->request->request.op.version[0];
con->response->request.status.version[1] = con->request->request.op.version[1];
con->response->request.status.request_id = con->request->request.op.request_id;
/*
* Then validate the request header and required attributes...
*/
if (con->request->request.any.version[0] != 1)
{
/*
* Return an error, since we only support IPP 1.x.
*/
LogMessage(L_ERROR, "ProcessIPPRequest: bad request version (%d.%d)!",
con->request->request.any.version[0],
con->request->request.any.versi