]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
More I18N unsigned char -> char fixes.
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 21 Apr 1999 14:14:57 +0000 (14:14 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 21 Apr 1999 14:14:57 +0000 (14:14 +0000)
Now parse the PPD file to build required IPP printer attributes.

Implemented optional IPP printer control operations.

Fixed Basic authorization code (wasn't looking for Basic keyword in
authorization line).

git-svn-id: svn+ssh://src.apple.com/svn/cups/cups.org/trunk@231 7a7537e8-13f0-0310-91df-b6672ffda945

scheduler/auth.c
scheduler/client.c
scheduler/ipp.c
scheduler/printers.c
scheduler/printers.h

index 21dc701418251663c94d1bdd0edb2353329dd460..d5ea0b0720358d10701a3cdf82458f8ffc182325 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$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).
  *
@@ -339,10 +339,18 @@ IsAuthorized(client_t *con)       /* I - Connection */
   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);
@@ -352,7 +360,11 @@ IsAuthorized(client_t *con)        /* I - Connection */
     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 */
 
  /*
@@ -365,7 +377,7 @@ IsAuthorized(client_t *con) /* I - Connection */
     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 */
@@ -388,7 +400,11 @@ IsAuthorized(client_t *con)        /* I - Connection */
   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)
@@ -539,5 +555,5 @@ check_auth(unsigned ip,             /* I - Client address */
 
 
 /*
- * 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 $".
  */
index caa243692e61c43e5ef102d92be58bdd981c8789..da59825195b72948d59b0973f6e8351ccc9ea2d8 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$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.
  *
@@ -442,6 +442,17 @@ ReadClient(client_t *con)  /* I - Client to read from */
     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)
@@ -528,11 +539,9 @@ ReadClient(client_t *con)  /* I - Client to read from */
          * 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))
@@ -591,6 +600,17 @@ ReadClient(client_t *con)  /* I - Client to read from */
          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)
@@ -875,7 +895,7 @@ SendError(client_t      *con,       /* I - Connection */
     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);
@@ -1251,14 +1271,23 @@ check_if_modified(client_t    *con,             /* I - Client connection */
 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);
@@ -1284,7 +1313,9 @@ get_file(client_t    *con,        /* I - Client connection */
   * 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
@@ -1304,9 +1335,12 @@ get_file(client_t    *con,       /* I - Client connection */
     * 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);
+    }
   }
 
  /*
@@ -1516,5 +1550,5 @@ pipe_command(client_t *con,       /* I - Client connection */
 
 
 /*
- * 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 $".
  */
index 0a3954681fd7364f47c239465809ed918cae13a9..c13bcb988a70878719bd9f8279742a54e546b8d5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$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);
@@ -66,7 +51,10 @@ static void  get_job_attrs(client_t *con, ipp_attribute_t *uri);
 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);
 
@@ -220,6 +208,18 @@ ProcessIPPRequest(client_t *con)   /* I - Client connection */
         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;
@@ -250,6 +250,14 @@ ProcessIPPRequest(client_t *con)   /* I - Client connection */
         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;
@@ -262,6 +270,74 @@ ProcessIPPRequest(client_t *con)   /* I - Client connection */
 }
 
 
+/*
+ * '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.
  */
@@ -269,6 +345,16 @@ ProcessIPPRequest(client_t *con)   /* I - Client connection */
 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);
 }
 
@@ -280,10 +366,95 @@ add_class(client_t *con)          /* I - Client connection */
 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.
  */
@@ -492,6 +663,16 @@ copy_attrs(ipp_t *to,              /* I - Destination request */
 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);
 }
 
@@ -503,6 +684,16 @@ delete_class(client_t *con)                /* I - Client connection */
 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);
 }
 
@@ -835,6 +1026,7 @@ get_printers(client_t *con)                /* I - Client connection */
   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));
@@ -853,6 +1045,8 @@ get_printers(client_t *con)                /* I - Client connection */
   * OK, build a list of printers for this printer...
   */
 
+  curtime = time(NULL);
+
   for (count = 0, printer = Printers;
        count < limit && printer != NULL;
        printer = printer->next)
@@ -874,11 +1068,17 @@ get_printers(client_t *con)              /* I - Client connection */
       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);
@@ -912,6 +1112,7 @@ get_printer_attrs(client_t        *con,    /* I - Client connection */
   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));
@@ -952,6 +1153,8 @@ get_printer_attrs(client_t        *con,    /* I - Client connection */
   else
     printer = FindPrinter(dest);
 
+  curtime = time(NULL);
+
   copy_attrs(con->response, printer->attrs);
 
   ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_ENUM, "printer-state",
@@ -961,6 +1164,14 @@ get_printer_attrs(client_t        *con,   /* I - Client connection */
     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
@@ -998,6 +1209,7 @@ print_job(client_t        *con,            /* I - Client connection */
                                        /* Supertype of file */
                        type[MIME_MAX_TYPE];
                                        /* Subtype of file */
+  printer_t            *printer;       /* Printer data */
 
 
   DEBUG_printf(("print_job(%08x, %08x)\n", con, uri));
@@ -1086,6 +1298,24 @@ print_job(client_t        *con,          /* I - Client connection */
     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...
   */
@@ -1151,6 +1381,80 @@ print_job(client_t        *con,          /* I - Client connection */
 }
 
 
+/*
+ * '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.
  */
@@ -1159,9 +1463,6 @@ static void
 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])
@@ -1169,11 +1470,11 @@ send_ipp_error(client_t     *con,       /* I - Client connection */
 
   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));
@@ -1182,6 +1483,150 @@ send_ipp_error(client_t     *con,       /* I - Client connection */
 }
 
 
+/*
+ * '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.
  */
@@ -1326,5 +1771,5 @@ validate_job(client_t        *con,        /* I - Client connection */
 
 
 /*
- * 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 $".
  */
index 80635a257a3ddc7d078baa8261d9571f2b406aad..65480153938304f88b048323016a586c3001674d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$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.
  */
@@ -47,7 +54,6 @@ AddPrinter(char *name)                /* I - Name of printer */
   printer_t    *p,             /* New printer */
                *current,       /* Current printer in list */
                *prev;          /* Previous printer in list */
-  ipp_attribute_t *attr;       /* IPP attribute for printer */
 
 
  /*
@@ -64,11 +70,10 @@ AddPrinter(char *name)              /* I - Name of 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...
@@ -77,7 +82,7 @@ AddPrinter(char *name)                /* I - Name of printer */
   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;
 
  /*
@@ -167,7 +172,7 @@ FindPrinter(char *name)             /* I - Name of printer to find */
 
 
   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;
@@ -309,19 +314,17 @@ LoadAllPrinters(void)
     }
     
     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)
     {
      /*
@@ -413,14 +416,27 @@ SaveAllPrinters(void)
 }
 
 
+/*
+ * '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);
@@ -430,5 +446,194 @@ StopPrinter(printer_t *p)
 
 
 /*
- * 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 $".
  */
index fcf2633a4361b2d581227650f6971e89bce5da3e..fc8419c67266ce86d8e9e6f16d70d0cdbbf967a5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$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.
  *
@@ -31,19 +31,18 @@ typedef struct printer_str
   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 */
@@ -74,5 +73,5 @@ extern void           StopPrinter(printer_t *p);
 
 
 /*
- * 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 $".
  */