/*
- * "$Id: auth.c,v 1.5 1999/03/03 21:17:56 mike Exp $"
+ * "$Id: auth.c,v 1.6 1999/04/21 14:14:55 mike Exp $"
*
* Authorization routines for the Common UNIX Printing System (CUPS).
*
endpwent(); /* Close the password file */
if (pw == NULL) /* No such user... */
+ {
+ LogMessage(LOG_INFO, "IsAuthorized: Unknown username \"%s\".",
+ con->username);
return (HTTP_UNAUTHORIZED);
+ }
if (pw->pw_passwd[0] == '\0') /* Don't allow blank passwords! */
+ {
+ LogMessage(LOG_WARN, "IsAuthorized: Username \"%s\" has no password; access denied.",
+ con->username);
return (HTTP_UNAUTHORIZED);
+ }
#ifdef HAVE_SHADOW_H
spw = getspnam(con->username);
return (HTTP_UNAUTHORIZED);
if (spw->sp_pwdp[0] == '\0') /* Don't allow blank passwords! */
+ {
+ LogMessage(LOG_WARN, "IsAuthorized: Username \"%s\" has no password; access denied.",
+ con->username);
return (HTTP_UNAUTHORIZED);
+ }
#endif /* HAVE_SHADOW_H */
/*
if (spw != NULL)
{
if (strcmp(spw->sp_pwdp, crypt(con->password, spw->sp_pwdp)) != 0)
- return (HTTP_UNAUTHORIZED);
+ return (HTTP_UNAUTHORIZED);
}
else
#endif /* HAVE_SHADOW_H */
endgrent();
if (grp == NULL) /* No group by that name??? */
+ {
+ LogMessage(LOG_WARN, "IsAuthorized: group name \"%s\" does not exist!",
+ best->group_name);
return (HTTP_UNAUTHORIZED);
+ }
for (i = 0; grp->gr_mem[i] != NULL; i ++)
if (strcmp(con->username, grp->gr_mem[i]) == 0)
/*
- * End of "$Id: auth.c,v 1.5 1999/03/03 21:17:56 mike Exp $".
+ * End of "$Id: auth.c,v 1.6 1999/04/21 14:14:55 mike Exp $".
*/
/*
- * "$Id: client.c,v 1.10 1999/04/19 21:17:09 mike Exp $"
+ * "$Id: client.c,v 1.11 1999/04/21 14:14:56 mike Exp $"
*
* Client routines for the Common UNIX Printing System (CUPS) scheduler.
*
else switch (con->http.state)
{
case HTTP_GET_SEND :
+ if (strncmp(con->uri, "/printers", 9) == 0 &&
+ strcmp(con->uri + strlen(con->uri) - 4, ".ppd") == 0)
+ {
+ /*
+ * Send PPD file...
+ */
+
+ sprintf(command, "/ppd/%s", con->uri + 10);
+ strcpy(con->uri, command);
+ }
+
if (strncmp(con->uri, "/printers", 9) == 0 ||
strncmp(con->uri, "/classes", 8) == 0 ||
strncmp(con->uri, "/jobs", 5) == 0)
* content-type field will be "application/ipp"...
*/
- httpGetLength(&(con->http));
-
if (strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE], "application/ipp") == 0)
con->request = ippNew();
- else if (strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE], "application/ipp") == 0 &&
+ else if (strcmp(con->http.fields[HTTP_FIELD_CONTENT_TYPE], "application/x-www-form-urlencoded") == 0 &&
(strncmp(con->uri, "/printers", 9) == 0 ||
strncmp(con->uri, "/classes", 8) == 0 ||
strncmp(con->uri, "/jobs", 5) == 0))
return (0);
case HTTP_HEAD :
+ if (strncmp(con->uri, "/printers", 9) == 0 &&
+ strcmp(con->uri + strlen(con->uri) - 4, ".ppd") == 0)
+ {
+ /*
+ * Send PPD file...
+ */
+
+ sprintf(command, "/ppd/%s", con->uri + 10);
+ strcpy(con->uri, command);
+ }
+
if (strncmp(con->uri, "/printers/", 10) == 0 ||
strncmp(con->uri, "/classes/", 9) == 0 ||
strncmp(con->uri, "/jobs/", 6) == 0)
sprintf(message, "<HTML><HEAD><TITLE>%d %s</TITLE></HEAD>"
"<BODY><H1>%s</H1>%s</BODY></HTML>\n",
code, httpStatus(code), httpStatus(code),
- con->language ? (char *)con->language->messages[code] : httpStatus(code));
+ con->language ? con->language->messages[code] : httpStatus(code));
if (httpPrintf(HTTP(con), "Content-Type: text/html\r\n") < 0)
return (0);
static void
decode_basic_auth(client_t *con) /* I - Client to decode to */
{
- char value[1024]; /* Value string */
+ char *s, /* Authorization string */
+ value[1024]; /* Value string */
/*
* Decode the string and pull the username and password out...
*/
- httpDecode64(value, con->http.fields[HTTP_FIELD_AUTHORIZATION]);
+ s = con->http.fields[HTTP_FIELD_AUTHORIZATION];
+ if (strncmp(s, "Basic", 5) != 0)
+ return;
+
+ s += 5;
+ while (isspace(*s))
+ s ++;
+
+ httpDecode64(value, s);
LogMessage(LOG_DEBUG, "decode_basic_auth() %d Authorization=\"%s\"",
con->http.fd, value);
* Need to add DocumentRoot global...
*/
- if (con->language != NULL)
+ if (strncmp(con->uri, "/ppd/", 5) == 0)
+ sprintf(filename, "%s%s", ServerRoot, con->uri);
+ else if (con->language != NULL)
sprintf(filename, "%s/%s%s", DocumentRoot, con->language->language,
con->uri);
else
* Drop the language prefix and try the current directory...
*/
- sprintf(filename, "%s%s", DocumentRoot, con->uri);
+ if (strncmp(con->uri, "/ppd/", 5) != 0)
+ {
+ sprintf(filename, "%s%s", DocumentRoot, con->uri);
- status = stat(filename, filestats);
+ status = stat(filename, filestats);
+ }
}
/*
/*
- * End of "$Id: client.c,v 1.10 1999/04/19 21:17:09 mike Exp $".
+ * End of "$Id: client.c,v 1.11 1999/04/21 14:14:56 mike Exp $".
*/
/*
- * "$Id: ipp.c,v 1.7 1999/04/19 21:17:09 mike Exp $"
+ * "$Id: ipp.c,v 1.8 1999/04/21 14:14:56 mike Exp $"
*
* IPP routines for the Common UNIX Printing System (CUPS) scheduler.
*
*
* Contents:
*
- * ProcessIPPRequest() - Process an incoming IPP request...
- * add_class() - Add a class to the system.
- * add_printer() - Add a printer to the system.
- * cancel_job() - Cancel a print job.
- * copy_attrs() - Copy attributes from one request to another.
- * delete_class() - Remove a class from the system.
- * delete_printer() - Remove a printer from the system.
- * get_classes() - Get a list of classes.
- * get_default() - Get the default destination.
- * get_jobs() - Get a list of jobs for the specified printer.
- * get_job_attrs() - Get job attributes.
- * get_printers() - Get a list of printers.
- * get_printer_attrs() - Get printer attributes.
- * print_job() - Print a file to a printer or class.
- * send_ipp_error() - Send an error status back to the IPP client.
- * validate_dest() - Validate a printer class destination.
- * validate_job() - Validate printer options and destination.
*/
/*
* Local functions...
*/
+static void accept_jobs(client_t *con, ipp_attribute_t *uri);
static void add_class(client_t *con);
static void add_printer(client_t *con);
+static void cancel_all_jobs(client_t *con, ipp_attribute_t *uri);
static void cancel_job(client_t *con, ipp_attribute_t *uri);
static void copy_attrs(ipp_t *to, ipp_t *from);
static void delete_class(client_t *con);
static void get_printers(client_t *con);
static void get_printer_attrs(client_t *con, ipp_attribute_t *uri);
static void print_job(client_t *con, ipp_attribute_t *uri);
+static void reject_jobs(client_t *con, ipp_attribute_t *uri);
static void send_ipp_error(client_t *con, ipp_status_t status);
+static void start_printer(client_t *con, ipp_attribute_t *uri);
+static void stop_printer(client_t *con, ipp_attribute_t *uri);
static char *validate_dest(char *resource, cups_ptype_t *dtype);
static void validate_job(client_t *con, ipp_attribute_t *uri);
get_printer_attrs(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 CUPS_GET_DEFAULT :
get_default(con);
break;
break;
#endif /* 0 */
+ case CUPS_ACCEPT_JOBS :
+ accept_jobs(con, uri);
+ break;
+
+ case CUPS_REJECT_JOBS :
+ reject_jobs(con, uri);
+ break;
+
default :
send_ipp_error(con, IPP_OPERATION_NOT_SUPPORTED);
return;
}
+/*
+ * 'accept_jobs()' - Accept print jobs to a printer.
+ */
+
+static void
+accept_jobs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer or class URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+
+
+ DEBUG_printf(("accept_jobs(%08x, %08x)\n", con, uri));
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = validate_dest(resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ DEBUG_printf(("accept_jobs: resource name \'%s\' no good!\n",
+ resource));
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Accept jobs sent to the printer...
+ */
+
+ printer = FindPrinter(name);
+ printer->accepting = 1;
+ printer->state_message[0] = '\0';
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
/*
* 'add_class()' - Add a class to the system.
*/
static void
add_class(client_t *con) /* I - Client connection */
{
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
send_ipp_error(con, IPP_OPERATION_NOT_SUPPORTED);
}
static void
add_printer(client_t *con) /* I - Client connection */
{
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
send_ipp_error(con, IPP_OPERATION_NOT_SUPPORTED);
}
+/*
+ * 'cancel_all_jobs()' - Cancel all print jobs.
+ */
+
+static void
+cancel_all_jobs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Job or Printer URI */
+{
+ ipp_attribute_t *attr; /* Current attribute */
+ char *dest; /* Destination */
+ cups_ptype_t dtype; /* Destination type */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+
+
+ DEBUG_printf(("cancel_all_jobs(%08x, %08x)\n", con, uri));
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * See if we have a printer URI...
+ */
+
+ if (strcmp(uri->name, "printer-uri") != 0)
+ {
+ DEBUG_printf(("cancel_all_jobs: bad %s attribute \'%s\'!\n",
+ uri->name, uri->values[0].string.text));
+ send_ipp_error(con, IPP_BAD_REQUEST);
+ return;
+ }
+
+ /*
+ * And if the destination is valid...
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port,
+ resource);
+
+ if ((dest = validate_dest(resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ DEBUG_printf(("cancel_all_jobs: resource name \'%s\' no good!\n",
+ resource));
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Cancel all of the jobs and return...
+ */
+
+ CancelJobs(dest);
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
/*
* 'cancel_job()' - Cancel a print job.
*/
static void
delete_class(client_t *con) /* I - Client connection */
{
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
send_ipp_error(con, IPP_OPERATION_NOT_SUPPORTED);
}
static void
delete_printer(client_t *con) /* I - Client connection */
{
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
send_ipp_error(con, IPP_OPERATION_NOT_SUPPORTED);
}
int limit; /* Maximum number of printers to return */
int count; /* Number of printers that match */
printer_t *printer; /* Current printer pointer */
+ time_t curtime; /* Current time */
DEBUG_printf(("get_printers(%08x)\n", con));
* OK, build a list of printers for this printer...
*/
+ curtime = time(NULL);
+
for (count = 0, printer = Printers;
count < limit && printer != NULL;
printer = printer->next)
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
"printer-state-message", NULL, printer->state_message);
- ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs", 1);
+ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
+ printer->accepting);
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_URI,
"printer-device-uri", NULL, printer->device_uri);
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "printer-up-time", curtime - StartTime);
+ ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
+ ippTimeToDate(curtime));
+
copy_attrs(con->response, printer->attrs);
ippAddSeparator(con->response);
int port; /* Port portion of URI */
printer_t *printer; /* Printer */
class_t *pclass; /* Printer class */
+ time_t curtime; /* Current time */
DEBUG_printf(("get_printer_attrs(%08x, %08x)\n", con, uri));
else
printer = FindPrinter(dest);
+ curtime = time(NULL);
+
copy_attrs(con->response, printer->attrs);
ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
"printer-state-message", NULL, printer->state_message);
+ ippAddBoolean(con->response, IPP_TAG_PRINTER, "printer-is-accepting-jobs",
+ printer->accepting);
+
+ ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "printer-up-time", curtime - StartTime);
+ ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
+ ippTimeToDate(curtime));
+
if (ippFindAttribute(con->request, "requested-attributes", IPP_TAG_KEYWORD) != NULL)
con->response->request.status.status_code = IPP_OK_SUBST;
else
/* Supertype of file */
type[MIME_MAX_TYPE];
/* Subtype of file */
+ printer_t *printer; /* Printer data */
DEBUG_printf(("print_job(%08x, %08x)\n", con, uri));
return;
}
+ /*
+ * See if the printer is accepting jobs...
+ */
+
+ if (dtype == CUPS_PRINTER_CLASS)
+ {
+ }
+ else
+ {
+ printer = FindPrinter(dest);
+
+ if (!printer->accepting)
+ {
+ send_ipp_error(con, IPP_NOT_ACCEPTING);
+ return;
+ }
+ }
+
/*
* Create the job and set things up...
*/
}
+/*
+ * 'reject_jobs()' - Reject print jobs to a printer.
+ */
+
+static void
+reject_jobs(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer or class URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+ ipp_attribute_t *attr; /* printer-state-message text */
+
+
+ DEBUG_printf(("reject_jobs(%08x, %08x)\n", con, uri));
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = validate_dest(resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ DEBUG_printf(("reject_jobs: resource name \'%s\' no good!\n",
+ resource));
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Reject jobs sent to the printer...
+ */
+
+ printer = FindPrinter(name);
+ printer->accepting = 0;
+
+ if ((attr = ippFindAttribute(con->request, "printer-state-message",
+ IPP_TAG_TEXT)) == NULL)
+ strcpy(printer->state_message, "Rejecting Jobs");
+ else
+ strcpy(printer->state_message, attr->values[0].string.text);
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
/*
* 'send_ipp_error()' - Send an error status back to the IPP client.
*/
send_ipp_error(client_t *con, /* I - Client connection */
ipp_status_t status) /* I - IPP status code */
{
- ipp_attribute_t *attr; /* Current attribute */
-
-
DEBUG_printf(("send_ipp_error(%08x, %04x)\n", con, status));
if (con->filename[0])
con->response->request.status.status_code = status;
- attr = ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
- "attributes-charset", NULL, DefaultCharset);
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+ "attributes-charset", NULL, DefaultCharset);
- attr = ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
- "attributes-natural-language", NULL, DefaultLanguage);
+ ippAddString(con->response, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+ "attributes-natural-language", NULL, DefaultLanguage);
SendHeader(con, HTTP_OK, "application/ipp");
httpPrintf(HTTP(con), "Content-Length: %d\r\n\r\n", ippLength(con->response));
}
+/*
+ * 'start_printer()' - Start a printer.
+ */
+
+static void
+start_printer(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+
+ DEBUG_printf(("start_printer(%08x, %08x)\n", con, uri));
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = validate_dest(resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ DEBUG_printf(("start_printer: resource name \'%s\' no good!\n",
+ resource));
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Start the printer...
+ */
+
+ printer = FindPrinter(name);
+
+ StartPrinter(printer);
+
+ printer->state_message[0] = '\0';
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
+/*
+ * 'stop_printer()' - Stop a printer.
+ */
+
+static void
+stop_printer(client_t *con, /* I - Client connection */
+ ipp_attribute_t *uri) /* I - Printer URI */
+{
+ cups_ptype_t dtype; /* Destination type (printer or class) */
+ char method[HTTP_MAX_URI],
+ /* Method portion of URI */
+ username[HTTP_MAX_URI],
+ /* Username portion of URI */
+ host[HTTP_MAX_URI],
+ /* Host portion of URI */
+ resource[HTTP_MAX_URI];
+ /* Resource portion of URI */
+ int port; /* Port portion of URI */
+ char *name; /* Printer name */
+ printer_t *printer; /* Printer data */
+ ipp_attribute_t *attr; /* printer-state-message attribute */
+
+
+ DEBUG_printf(("stop_printer(%08x, %08x)\n", con, uri));
+
+ /*
+ * Was this operation called from the correct URI?
+ */
+
+ if (strncmp(con->uri, "/admin/", 7) != 0)
+ {
+ send_ipp_error(con, IPP_NOT_AUTHORIZED);
+ return;
+ }
+
+ /*
+ * Is the destination valid?
+ */
+
+ httpSeparate(uri->values[0].string.text, method, username, host, &port, resource);
+
+ if ((name = validate_dest(resource, &dtype)) == NULL)
+ {
+ /*
+ * Bad URI...
+ */
+
+ DEBUG_printf(("stop_printer: resource name \'%s\' no good!\n",
+ resource));
+ send_ipp_error(con, IPP_NOT_FOUND);
+ return;
+ }
+
+ /*
+ * Stop the printer...
+ */
+
+ printer = FindPrinter(name);
+
+ StopPrinter(printer);
+
+ if ((attr = ippFindAttribute(con->request, "printer-state-message",
+ IPP_TAG_TEXT)) == NULL)
+ strcpy(printer->state_message, "Paused");
+ else
+ strcpy(printer->state_message, attr->values[0].string.text);
+
+ /*
+ * Everything was ok, so return OK status...
+ */
+
+ con->response->request.status.status_code = IPP_OK;
+}
+
+
/*
* 'validate_dest()' - Validate a printer class destination.
*/
/*
- * End of "$Id: ipp.c,v 1.7 1999/04/19 21:17:09 mike Exp $".
+ * End of "$Id: ipp.c,v 1.8 1999/04/21 14:14:56 mike Exp $".
*/
/*
- * "$Id: printers.c,v 1.9 1999/04/16 20:47:48 mike Exp $"
+ * "$Id: printers.c,v 1.10 1999/04/21 14:14:57 mike Exp $"
*
* for the Common UNIX Printing System (CUPS).
*
#include "cupsd.h"
+/*
+ * Local functions...
+ */
+
+static void set_printer_attrs(printer_t *);
+
+
/*
* 'AddPrinter()' - Add a printer to the system.
*/
printer_t *p, /* New printer */
*current, /* Current printer in list */
*prev; /* Previous printer in list */
- ipp_attribute_t *attr; /* IPP attribute for printer */
/*
if ((p = calloc(sizeof(printer_t), 1)) == NULL)
return (NULL);
- strcpy((char *)p->name, name);
- p->state = IPP_PRINTER_STOPPED;
- p->attrs = ippNew();
- attr = ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME,
- "printer-name", NULL, name);
+ strcpy(p->name, name);
+ p->state = IPP_PRINTER_STOPPED;
+ p->accepting = 1;
+ set_printer_attrs(p);
/*
* Insert the printer in the printer list alphabetically...
for (prev = NULL, current = Printers;
current != NULL;
prev = current, current = current->next)
- if (strcasecmp((char *)p->name, (char *)current->name) < 0)
+ if (strcasecmp(p->name, current->name) < 0)
break;
/*
for (p = Printers; p != NULL; p = p->next)
- switch (strcasecmp(name, (char *)p->name))
+ switch (strcasecmp(name, p->name))
{
case 1 : /* name > p->name */
break;
}
else if (strcmp(name, "Info") == 0)
- strncpy((char *)p->info, value, sizeof(p->info) - 1);
+ strncpy(p->info, value, sizeof(p->info) - 1);
else if (strcmp(name, "MoreInfo") == 0)
- strncpy((char *)p->more_info, value, sizeof(p->more_info) - 1);
+ strncpy(p->more_info, value, sizeof(p->more_info) - 1);
else if (strcmp(name, "Location") == 0)
- strncpy((char *)p->location, value, sizeof(p->location) - 1);
+ strncpy(p->location, value, sizeof(p->location) - 1);
else if (strcmp(name, "DeviceURI") == 0)
strncpy(p->device_uri, value, sizeof(p->device_uri) - 1);
else if (strcmp(name, "Username") == 0)
- strncpy((char *)p->username, value, sizeof(p->username) - 1);
+ strncpy(p->username, value, sizeof(p->username) - 1);
else if (strcmp(name, "Password") == 0)
- strncpy((char *)p->password, value, sizeof(p->password) - 1);
- else if (strcmp(name, "PPDFile") == 0)
- strncpy(p->ppd, value, sizeof(p->ppd) - 1);
+ strncpy(p->password, value, sizeof(p->password) - 1);
else if (strcmp(name, "AddFilter") == 0)
{
/*
}
+/*
+ * 'StartPrinter()' - Start printing jobs on a printer.
+ */
+
void
-StartPrinter(printer_t *p)
+StartPrinter(printer_t *p) /* I - Printer to start */
{
+ if (p->state == IPP_PRINTER_STOPPED)
+ {
+ p->state = IPP_PRINTER_IDLE;
+ CheckJobs();
+ }
}
+/*
+ * 'StopPrinter()' - Stop a printer from printing any jobs...
+ */
+
void
-StopPrinter(printer_t *p)
+StopPrinter(printer_t *p) /* I - Printer to stop */
{
if (p->job)
StopJob(((job_t *)p->job)->id);
/*
- * End of "$Id: printers.c,v 1.9 1999/04/16 20:47:48 mike Exp $".
+ * 'set_printer_attrs()' - Set printer attributes based upon the PPD file.
+ */
+
+static void
+set_printer_attrs(printer_t *p) /* I - Printer to setup */
+{
+ char uri[HTTP_MAX_URI];/* URI for printer */
+ int i; /* Looping var */
+ char filename[1024]; /* Name of PPD file */
+ int num_media; /* Number of media options */
+ ppd_file_t *ppd; /* PPD file data */
+ ppd_option_t *input_slot, /* InputSlot options */
+ *media_type, /* MediaType options */
+ *page_size; /* PageSize options */
+ ipp_attribute_t *attr; /* Attribute data */
+ ipp_value_t *val; /* Attribute value */
+ int nups[3] = /* number-up-supported values */
+ { 1, 2, 4 };
+ ipp_orient_t orients[4] = /* orientation-requested-supported values */
+ {
+ IPP_PORTRAIT,
+ IPP_LANDSCAPE,
+ IPP_REVERSE_LANDSCAPE,
+ IPP_REVERSE_PORTRAIT
+ };
+ char *sides[3] = /* sides-supported values */
+ {
+ "one",
+ "two-long-edge",
+ "two-short-edge"
+ };
+ ipp_op_t ops[] = /* operations-supported values */
+ {
+ IPP_PRINT_JOB,
+ IPP_VALIDATE_JOB,
+ IPP_CANCEL_JOB,
+ IPP_GET_JOB_ATTRIBUTES,
+ IPP_GET_JOBS,
+ IPP_GET_PRINTER_ATTRIBUTES,
+ IPP_PAUSE_PRINTER,
+ IPP_RESUME_PRINTER,
+ IPP_PURGE_JOBS,
+ CUPS_GET_DEFAULT,
+ CUPS_GET_PRINTERS,
+ CUPS_ADD_PRINTER,
+ CUPS_DELETE_PRINTER,
+ CUPS_GET_CLASSES,
+ CUPS_ADD_CLASS,
+ CUPS_DELETE_CLASS,
+ CUPS_ACCEPT_JOBS,
+ CUPS_REJECT_JOBS
+ };
+ char *charsets[] = /* charset-supported values */
+ {
+ "us-ascii",
+ "iso-8859-1",
+ "iso-8859-2",
+ "iso-8859-3",
+ "iso-8859-4",
+ "iso-8859-5",
+ "iso-8859-6",
+ "iso-8859-7",
+ "iso-8859-8",
+ "iso-8859-9",
+ "iso-8859-10",
+ "utf-8"
+ };
+
+
+ /*
+ * Create the required IPP attributes for a printer...
+ */
+
+ if (p->attrs)
+ ippDelete(p->attrs);
+
+ p->attrs = ippNew();
+
+ sprintf(uri, "ipp://%s:%d/printers/%s", ServerName,
+ ntohs(Listeners[0].address.sin_port), p->name);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-uri-supported",
+ NULL, uri);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "uri-security-supported", NULL, "none");
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_NAME, "printer-name", NULL,
+ p->name);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-location",
+ NULL, p->location);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT, "printer-info",
+ NULL, p->info);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_URI, "printer-more-info",
+ NULL, p->more_info);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "pdl-override-supported", NULL, "not-attempted");
+ ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM, "operations-supported",
+ sizeof(ops) / sizeof(ops[0]), ops);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-configured",
+ NULL, DefaultCharset);
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_CHARSET, "charset-supported",
+ sizeof(charsets) / sizeof(charsets[0]), NULL, charsets);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "natural-language-configured", NULL, DefaultLanguage);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_LANGUAGE,
+ "generated-natural-language-supported", NULL, DefaultLanguage);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
+ "document-format-default", NULL, "application/octet-stream");
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_MIMETYPE,
+ "document-format-supported", NULL, "application/octet-stream");
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-priority-supported", 100);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "job-priority-default", 50);
+ ippAddRange(p->attrs, IPP_TAG_PRINTER, "copies-supported", 1, 100);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "copies-default", 1);
+ ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "page-ranges-supported", 1);
+ ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "number-up-supported", 3, nups);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+ "number-up-default", 1);
+ ippAddIntegers(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "orientation-requested-supported", 4, orients);
+ ippAddInteger(p->attrs, IPP_TAG_PRINTER, IPP_TAG_ENUM,
+ "orientation-requested-default", IPP_PORTRAIT);
+
+ /*
+ * Assign additional attributes from the PPD file (if any)...
+ */
+
+ sprintf(filename, "%s/ppd/%s.ppd", ServerRoot, p->name);
+ if ((ppd = ppdOpenFile(filename)) != NULL)
+ {
+ /*
+ * Add make/model and other various attributes...
+ */
+
+ ippAddBoolean(p->attrs, IPP_TAG_PRINTER, "color-supported",
+ ppd->color_device);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_TEXT,
+ "printer-make-and-model", NULL, ppd->nickname);
+
+ /*
+ * Add media options from the PPD file...
+ */
+
+ if ((input_slot = ppdFindOption(ppd, "InputSlot")) != NULL)
+ num_media = input_slot->num_choices;
+ else
+ num_media = 0;
+
+ if ((media_type = ppdFindOption(ppd, "MediaType")) != NULL)
+ num_media += media_type->num_choices;
+
+ if ((page_size = ppdFindOption(ppd, "PageSize")) != NULL)
+ num_media += page_size->num_choices;
+
+ attr = ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD,
+ "media-supported", num_media, NULL, NULL);
+ val = attr->values;
+
+ if (input_slot != NULL)
+ for (i = 0; i < input_slot->num_choices; i ++, val ++)
+ val->string.text = strdup(input_slot->choices[i].choice);
+
+ if (media_type != NULL)
+ for (i = 0; i < media_type->num_choices; i ++, val ++)
+ val->string.text = strdup(media_type->choices[i].choice);
+
+ if (page_size != NULL)
+ for (i = 0; i < page_size->num_choices; i ++, val ++)
+ val->string.text = strdup(page_size->choices[i].choice);
+
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "media-default",
+ NULL, page_size->defchoice);
+
+ if (ppdFindOption(ppd, "Duplex") != NULL)
+ {
+ ippAddStrings(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-supported",
+ 3, NULL, sides);
+ ippAddString(p->attrs, IPP_TAG_PRINTER, IPP_TAG_KEYWORD, "sides-default",
+ NULL, "one");
+ }
+
+ ppdClose(ppd);
+ }
+}
+
+
+/*
+ * End of "$Id: printers.c,v 1.10 1999/04/21 14:14:57 mike Exp $".
*/
/*
- * "$Id: printers.h,v 1.7 1999/04/19 21:17:10 mike Exp $"
+ * "$Id: printers.h,v 1.8 1999/04/21 14:14:57 mike Exp $"
*
* Printer definitions for the Common UNIX Printing System (CUPS) scheduler.
*
struct printer_str *next; /* Next printer in list */
char uri[HTTP_MAX_URI], /* Printer URI */
hostname[HTTP_MAX_HOST],/* Host printer resides on */
- name[IPP_MAX_NAME]; /* Printer name */
- unsigned char location[IPP_MAX_NAME], /* Location code */
+ name[IPP_MAX_NAME], /* Printer name */
+ location[IPP_MAX_NAME], /* Location code */
info[IPP_MAX_NAME], /* Description */
more_info[HTTP_MAX_URI],/* URL for site-specific info */
- make_model[IPP_MAX_NAME],/* Make and model from PPD file */
username[MAX_USERPASS], /* Username for remote system */
password[MAX_USERPASS]; /* Password for remote system */
+ int accepting; /* Accepting jobs? */
ipp_pstate_t state; /* Printer state */
char state_message[1024]; /* Printer state message */
cups_ptype_t type; /* Printer type (color, small, etc.) */
time_t state_time; /* Time at this state */
- char ppd[HTTP_MAX_URI], /* PPD file name */
- device_uri[HTTP_MAX_URI],/* Device URI */
+ char device_uri[HTTP_MAX_URI],/* Device URI */
backend[1024]; /* Backend to use */
mime_type_t *filetype; /* Pseudo-filetype for printer */
void *job; /* Current job in queue */
/*
- * End of "$Id: printers.h,v 1.7 1999/04/19 21:17:10 mike Exp $".
+ * End of "$Id: printers.h,v 1.8 1999/04/21 14:14:57 mike Exp $".
*/