📄 ipp2.c
字号:
/* * "$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 agan4014job_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);#endifstatic 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.version[1]); send_ipp_error(con, IPP_VERSION_NOT_SUPPORTED); } else if (con->request->attrs == NULL) { LogMessage(L_ERROR, "ProcessIPPRequest: no attributes in request!"); send_ipp_error(con, IPP_BAD_REQUEST); } else { /* * Make sure that the attributes are provided in the correct order and * don't repeat groups... */ for (attr = con->request->attrs, group = attr->group_tag; attr != NULL; attr = attr->next) if (attr->group_tag < group) { /* * Out of order; return an error... */ LogMessage(L_ERROR, "ProcessIPPRequest: attribute groups are out of order!"); send_ipp_error(con, IPP_BAD_REQUEST); break; } else group = attr->group_tag; if (attr == NULL) { /* * Then make sure that the first three attributes are: * * attributes-charset * attributes-natural-language * printer-uri/job-uri */ attr = con->request->attrs; if (attr != NULL && strcmp(attr->name, "attributes-charset") == 0 && attr->value_tag == IPP_TAG_CHARSET) charset = attr; else charset = NULL; if (attr) attr = attr->next; if (attr != NULL && strcmp(attr->name, "attributes-natural-language") == 0 && attr->value_tag == IPP_TAG_LANGUAGE) language = attr; else language = NULL; if ((attr = ippFindAttribute(con->request, "printer-uri", IPP_TAG_URI)) != NULL) uri = attr; else if ((attr = ippFindAttribute(con->request, "job-uri", IPP_TAG_URI)) != NULL) uri = attr; else uri = NULL; if (charset) ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, charset->values[0].string.text); else ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET, "attributes-charset", NULL, DefaultCharset); if (language) ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->values[0].string.text); else ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, DefaultLanguage); if (charset == NULL || language == NULL || (uri == NULL && con->request->request.op.operation_id != CUPS_GET_DEFAULT && con->request->request.op.operation_id != CUPS_GET_PRINTERS && con->request->request.op.operation_id != CUPS_GET_CLASSES && con->request->request.op.operation_id != CUPS_GET_DEVICES && con->request->request.op.operation_id != CUPS_GET_PPDS)) { /* * Return an error, since attributes-charset, * attributes-natural-language, and printer-uri/job-uri are required * for all operations. */ if (charset == NULL) LogMessage(L_ERROR, "ProcessIPPRequest: missing attributes-charset attribute!"); if (language == NULL) LogMessage(L_ERROR, "ProcessIPPRequest: missing attributes-natural-language attribute!"); if (uri == NULL) LogMessage(L_ERROR, "ProcessIPPRequest: missing printer-uri or job-uri attribute!"); LogMessage(L_DEBUG, "Request attributes follow..."); for (attr = con->request->attrs; attr != NULL; attr = attr->next) LogMessage(L_DEBUG, "attr \"%s\": group_tag = %x, value_tag = %x", attr->name ? attr->name : "(null)", attr->group_tag, attr->value_tag); LogMessage(L_DEBUG, "End of attributes..."); send_ipp_error(con, IPP_BAD_REQUEST); } else { /* * OK, all the checks pass so far; make sure requesting-user-name is * not "root" from a remote host... */ if ((username = ippFindAttribute(con->request, "requesting-user-name", IPP_TAG_NAME)) != NULL) { /* * Check for root user... */ if (strcmp(username->values[0].string.text, "root") == 0 && ntohl(con->http.hostaddr.sin_addr.s_addr) != 0x7f000001 && strcmp(con->username, "root") != 0) { /* * Remote unauthenticated user masquerading as local root... */ free(username->values[0].string.text); username->values[0].string.text = strdup(RemoteRoot); } } /* * Then try processing the operation... */ if (uri) LogMessage(L_DEBUG2, "ProcessIPPRequest: URI=\"%s\"", uri->values[0].string.text); switch (con->request->request.op.operation_id) { case IPP_PRINT_JOB : print_job(con, uri); break; case IPP_GET_JOBS : get_jobs(con, uri); break; case IPP_GET_PRINTER_ATTRIBUTES : get_printer_attrs(con, uri); break;#if 0 case IPP_VALIDATE_JOB : validate_job(con, uri); break; case IPP_CREATE_JOB : create_job(con, uri); break; case IPP_SEND_DOCUMENT : send_document(con, uri); break; case IPP_CANCEL_JOB : cancel_job(con, uri); break; case IPP_GET_JOB_ATTRIBUTES : get_job_attrs(con, uri); break; case IPP_HOLD_JOB : hold_job(con, uri); break; case IPP_RELEASE_JOB : release_job(con, uri); break; case IPP_RESTART_JOB : restart_job(con, uri); break; case IPP_PAUSE_PRINTER : stop_printer(con, uri); break; case IPP_RESUME_PRINTER : start_printer(con, uri); break; case IPP_PURGE_JOBS : cancel_all_jobs(con, uri); break; case IPP_SET_JOB_ATTRIBUTES : set_job_attrs(con, uri); break; case CUPS_GET_DEFAULT : get_default(con); break; case CUPS_GET_PRINTERS : get_printers(con, 0); break; case CUPS_GET_CLASSES : get_printers(con, CUPS_PRINTER_CLASS); break; case CUPS_ADD_PRINTER : add_printer(con, uri); break; case CUPS_DELETE_PRINTER : delete_printer(con, uri); break; case CUPS_ADD_CLASS : add_class(con, uri); break; case CUPS_DELETE_CLASS : delete_printer(con, uri); break; case CUPS_ACCEPT_JOBS : case IPP_ENABLE_PRINTER : accept_jobs(con, uri); break; case CUPS_REJECT_JOBS : case IPP_DISABLE_PRINTER : reject_jobs(con, uri); break; case CUPS_SET_DEFAULT : set_default(con, uri); break; case CUPS_GET_DEVICES : get_devices(con); break; case CUPS_GET_PPDS : get_ppds(con); break; case CUPS_MOVE_JOB : move_job(con, uri); break;#endif default : send_ipp_error(con, IPP_OPERATION_NOT_SUPPORTED); } } } } LogMessage(L_DEBUG, "ProcessIPPRequest: %d status_code=%x", con->http.fd, con->response->request.status.status_code); if (SendHeader(con, HTTP_OK, "application/ipp")) {#if 0 if (con->http.version == HTTP_1_1) { con->http.data_encoding = HTTP_ENCODE_CHUNKED; httpPrintf(HTTP(con), "Transfer-Encoding: chunked\r\n\r\n"); } else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -