]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Got rid of last vestiges of unsigned char * code for I18N - sticking with
authormike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 21 Apr 1999 14:12:23 +0000 (14:12 +0000)
committermike <mike@7a7537e8-13f0-0310-91df-b6672ffda945>
Wed, 21 Apr 1999 14:12:23 +0000 (14:12 +0000)
plain char because we don't do any comparisons and each compiler gives
different warnings/errors...

ippRead() didn't employ a blocking read for each variable read, which caused
problems under some circumstances.

ppdOpenFile() didn't handle buggy PPD files that declared VariablePaperSize
false and still had CustomPageSize commands...

Added password authorization handling to cupsDoRequest() - automatically
asks for a password (from the console) if one is needed.  [Note: the GUIs
will need to implement their own version of this.]

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

cups/cups.h
cups/emit.c
cups/http.c
cups/ipp.c
cups/ipp.h
cups/language.c
cups/language.h
cups/ppd.c
cups/ppd.h
cups/testppd.c
cups/util.c

index 2814ed21194a7d03ca092929808b08d04088e42b..222dadd297efc4d3c1986d61d5083eaf33e80a93 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: cups.h,v 1.7 1999/04/19 21:13:25 mike Exp $"
+ * "$Id: cups.h,v 1.8 1999/04/21 14:12:16 mike Exp $"
  *
  *   API definitions for the Common UNIX Printing System (CUPS).
  *
@@ -109,7 +109,7 @@ extern int          cupsGetClasses(char ***classes);
 extern char            *cupsGetPPD(char *printer);
 extern char            *cupsGetDefault(void);
 extern int             cupsGetPrinters(char ***printers);
-extern int             cupsPrintFile(char *printer, char *filename,
+extern int             cupsPrintFile(char *printer, char *filename, char *title,
                                      int num_options, cups_option_t *options);
 
 extern int             cupsAddOption(char *name, char *value, int num_options,
@@ -129,5 +129,5 @@ extern int          cupsMarkOptions(ppd_file_t *ppd, int num_options,
 #endif /* !_CUPS_CUPS_H_ */
 
 /*
- * End of "$Id: cups.h,v 1.7 1999/04/19 21:13:25 mike Exp $".
+ * End of "$Id: cups.h,v 1.8 1999/04/21 14:12:16 mike Exp $".
  */
index 6bf44aa892359f6df1ed3530a4f74ebf502d6d49..fb89a20c0df9b921d507d5510a20b591019a56c5 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: emit.c,v 1.11 1999/04/09 14:21:23 mike Exp $"
+ * "$Id: emit.c,v 1.12 1999/04/21 14:12:16 mike Exp $"
  *
  *   PPD code emission routines for the Common UNIX Printing System (CUPS).
  *
@@ -113,13 +113,13 @@ ppdEmit(ppd_file_t    *ppd,               /* I - PPD file record */
 
       if (choices[i]->code != NULL && choices[i]->code[0] != '\0')
       {
-        if (fputs((char *)choices[i]->code, fp) < 0)
+        if (fputs(choices[i]->code, fp) < 0)
         {
           free(choices);
           return (-1);
         }
 
-        if (choices[i]->code[strlen((char *)choices[i]->code) - 1] != '\n')
+        if (choices[i]->code[strlen(choices[i]->code) - 1] != '\n')
           putc('\n', fp);
       }
 
@@ -129,7 +129,7 @@ ppdEmit(ppd_file_t    *ppd,         /* I - PPD file record */
         return (-1);
       }
     }
-    else if (fputs((char *)choices[i]->code, fp) < 0)
+    else if (fputs(choices[i]->code, fp) < 0)
     {
       free(choices);
       return (-1);
@@ -174,7 +174,7 @@ ppdEmitFd(ppd_file_t    *ppd,               /* I - PPD file record */
         return (-1);
       }
 
-      if (write(fd, choices[i]->code, strlen((char *)choices[i]->code)) < 1)
+      if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1)
       {
         free(choices);
         return (-1);
@@ -186,7 +186,7 @@ ppdEmitFd(ppd_file_t    *ppd,               /* I - PPD file record */
         return (-1);
       }
     }
-    else if (write(fd, choices[i]->code, strlen((char *)choices[i]->code)) < 1)
+    else if (write(fd, choices[i]->code, strlen(choices[i]->code)) < 1)
     {
       free(choices);
       return (-1);
@@ -297,5 +297,5 @@ ppd_collect(ppd_file_t    *ppd,             /* I - PPD file data */
 
 
 /*
- * End of "$Id: emit.c,v 1.11 1999/04/09 14:21:23 mike Exp $".
+ * End of "$Id: emit.c,v 1.12 1999/04/21 14:12:16 mike Exp $".
  */
index ca2686f861060be8eb4b2084ed18b4446b2a2ba1..260432df0b2091be789d7cab370bbe14316da86d 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: http.c,v 1.23 1999/04/16 16:57:48 mike Exp $"
+ * "$Id: http.c,v 1.24 1999/04/21 14:12:17 mike Exp $"
  *
  *   HTTP routines for the Common UNIX Printing System (CUPS) scheduler.
  *
@@ -742,6 +742,7 @@ httpWrite(http_t *http,                     /* I - HTTP data */
     bytes = send(http->fd, buffer, length, 0);
     if (bytes < 0)
     {
+      perror("httpWrite");
       DEBUG_puts("httpWrite: error writing data...\n");
       return (-1);
     }
@@ -1348,5 +1349,5 @@ http_send(http_t       *http,     /* I - HTTP data */
 
 
 /*
- * End of "$Id: http.c,v 1.23 1999/04/16 16:57:48 mike Exp $".
+ * End of "$Id: http.c,v 1.24 1999/04/21 14:12:17 mike Exp $".
  */
index 419ebecef11d92527f4ae87af447cf32e4927077..c41fcd33c1310c1df10ee4248a19144aa51c8113 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ipp.c,v 1.10 1999/03/21 02:10:01 mike Exp $"
+ * "$Id: ipp.c,v 1.11 1999/04/21 14:12:18 mike Exp $"
  *
  *   Internet Printing Protocol support functions for the Common UNIX
  *   Printing System (CUPS).
@@ -44,6 +44,7 @@
  *   ippTimeToDate()     - Convert from UNIX time to RFC 1903 format.
  *   ippWrite()          - Write data for an IPP request.
  *   add_attr()          - Add a new attribute to the request.
+ *   ipp_read()          - Semi-blocking read on a HTTP connection...
  */
 
 /*
@@ -63,6 +64,7 @@
  */
 
 static ipp_attribute_t *add_attr(ipp_t *ipp, int num_values);
+static int             ipp_read(http_t *http, char *buffer, int length);
 
 
 /*
@@ -740,7 +742,7 @@ ippRead(http_t *http,               /* I - HTTP data */
         * Get the request header...
        */
 
-        if ((n = httpRead(http, buffer, 8)) < 8)
+        if ((n = ipp_read(http, buffer, 8)) < 8)
        {
          DEBUG_printf(("ippRead: Unable to read header (%d bytes read)!\n", n));
          return (n == 0 ? IPP_IDLE : IPP_ERROR);
@@ -779,7 +781,7 @@ ippRead(http_t *http,               /* I - HTTP data */
          break;
 
     case IPP_ATTRIBUTE :
-        while (httpRead(http, buffer, 1) > 0)
+        while (ipp_read(http, buffer, 1) > 0)
        {
         /*
          * Read this attribute...
@@ -819,7 +821,7 @@ ippRead(http_t *http,               /* I - HTTP data */
          * Get the name...
          */
 
-          if (httpRead(http, buffer, 2) < 2)
+          if (ipp_read(http, buffer, 2) < 2)
          {
            DEBUG_puts("ippRead: unable to read name length!");
            return (IPP_ERROR);
@@ -849,7 +851,7 @@ ippRead(http_t *http,               /* I - HTTP data */
            * New attribute; read the name and add it...
            */
 
-           if (httpRead(http, buffer, n) < n)
+           if (ipp_read(http, buffer, n) < n)
            {
              DEBUG_puts("ippRead: unable to read name!");
              return (IPP_ERROR);
@@ -866,7 +868,7 @@ ippRead(http_t *http,               /* I - HTTP data */
            attr->num_values = 0;
          }
 
-         if (httpRead(http, buffer, 2) < 2)
+         if (ipp_read(http, buffer, 2) < 2)
          {
            DEBUG_puts("ippRead: unable to read value length!");
            return (IPP_ERROR);
@@ -879,7 +881,7 @@ ippRead(http_t *http,               /* I - HTTP data */
          {
            case IPP_TAG_INTEGER :
            case IPP_TAG_ENUM :
-               if (httpRead(http, buffer, 4) < 4)
+               if (ipp_read(http, buffer, 4) < 4)
                  return (IPP_ERROR);
 
                n = (((((buffer[0] << 8) | buffer[1]) << 8) | buffer[2]) << 8) |
@@ -888,7 +890,7 @@ ippRead(http_t *http,               /* I - HTTP data */
                 attr->values[attr->num_values].integer = n;
                break;
            case IPP_TAG_BOOLEAN :
-               if (httpRead(http, buffer, 1) < 1)
+               if (ipp_read(http, buffer, 1) < 1)
                  return (IPP_ERROR);
 
                 attr->values[attr->num_values].boolean = buffer[0];
@@ -902,7 +904,7 @@ ippRead(http_t *http,               /* I - HTTP data */
            case IPP_TAG_CHARSET :
            case IPP_TAG_LANGUAGE :
            case IPP_TAG_MIMETYPE :
-               if (httpRead(http, buffer, n) < n)
+               if (ipp_read(http, buffer, n) < n)
                  return (IPP_ERROR);
 
                 buffer[n] = '\0';
@@ -911,13 +913,13 @@ ippRead(http_t *http,             /* I - HTTP data */
                 attr->values[attr->num_values].string.text = strdup(buffer);
                break;
            case IPP_TAG_DATE :
-               if (httpRead(http, buffer, 11) < 11)
+               if (ipp_read(http, buffer, 11) < 11)
                  return (IPP_ERROR);
 
                 memcpy(attr->values[attr->num_values].date, buffer, 11);
                break;
            case IPP_TAG_RESOLUTION :
-               if (httpRead(http, buffer, 9) < 9)
+               if (ipp_read(http, buffer, 9) < 9)
                  return (IPP_ERROR);
 
                 attr->values[attr->num_values].resolution.xres =
@@ -930,7 +932,7 @@ ippRead(http_t *http,               /* I - HTTP data */
                    (ipp_res_t)buffer[8];
                break;
            case IPP_TAG_RANGE :
-               if (httpRead(http, buffer, 8) < 8)
+               if (ipp_read(http, buffer, 8) < 8)
                  return (IPP_ERROR);
 
                 attr->values[attr->num_values].range.lower =
@@ -942,19 +944,19 @@ ippRead(http_t *http,             /* I - HTTP data */
                break;
            case IPP_TAG_TEXTLANG :
            case IPP_TAG_NAMELANG :
-               if (httpRead(http, buffer, n) < n)
+               if (ipp_read(http, buffer, n) < n)
                  return (IPP_ERROR);
 
                 buffer[n] = '\0';
 
                 attr->values[attr->num_values].string.charset = strdup(buffer);
 
-               if (httpRead(http, buffer, 2) < 2)
+               if (ipp_read(http, buffer, 2) < 2)
                  return (IPP_ERROR);
 
                n = (buffer[0] << 8) | buffer[1];
 
-               if (httpRead(http, buffer, n) < n)
+               if (ipp_read(http, buffer, n) < n)
                  return (IPP_ERROR);
 
                 buffer[n] = '\0';
@@ -1418,5 +1420,35 @@ add_attr(ipp_t *ipp,                     /* I - IPP request */
 
 
 /*
- * End of "$Id: ipp.c,v 1.10 1999/03/21 02:10:01 mike Exp $".
+ * 'ipp_read()' - Semi-blocking read on a HTTP connection...
+ */
+
+static int             /* O - Number of bytes read */
+ipp_read(http_t *http, /* I - Client connection */
+         char   *buffer,/* O - Buffer for data */
+        int    length) /* I - Total length */
+{
+  int  tbytes,         /* Total bytes read */
+       bytes;          /* Bytes read this pass */
+
+
+ /*
+  * Loop until all bytes are read...
+  */
+
+  for (tbytes = 0; tbytes < length; tbytes += bytes, buffer += bytes)
+    if ((bytes = httpRead(http, buffer, length - tbytes)) <= 0)
+      break;
+
+ /*
+  * Return the number of bytes read...
+  */
+
+  return (tbytes);
+}
+
+
+
+/*
+ * End of "$Id: ipp.c,v 1.11 1999/04/21 14:12:18 mike Exp $".
  */
index a344a781c5dddf28419b072b6de141b752191936..e5d23b523479bacce1ab7b5fe62387066c3f1809 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ipp.h,v 1.8 1999/03/21 02:10:03 mike Exp $"
+ * "$Id: ipp.h,v 1.9 1999/04/21 14:12:18 mike Exp $"
  *
  *   Internet Printing Protocol definitions for the Common UNIX Printing
  *   System (CUPS).
@@ -115,13 +115,6 @@ typedef enum                       /**** Finishings... ****/
   IPP_FINISH_BIND
 } ipp_finish_t;
 
-typedef enum                   /**** Duplex/Sides... ****/
-{
-  IPP_SIDES_ONE,
-  IPP_SIDES_TWO_LONG_EDGE,
-  IPP_SIDES_TWO_SHORT_EDGE
-} ipp_sides_t;
-
 typedef enum                   /**** Orientation... ****/
 {
   IPP_PORTRAIT = 3,            /* No rotation */
@@ -189,7 +182,9 @@ typedef enum                        /**** IPP operations... ****/
   CUPS_DELETE_PRINTER,
   CUPS_GET_CLASSES,
   CUPS_ADD_CLASS,
-  CUPS_DELETE_CLASS
+  CUPS_DELETE_CLASS,
+  CUPS_ACCEPT_JOBS,
+  CUPS_REJECT_JOBS
 } ipp_op_t;
 
 typedef enum                   /**** IPP status codes... ****/
@@ -337,5 +332,5 @@ extern int          ippPort(void);
 #endif /* !_CUPS_IPP_H_ */
 
 /*
- * End of "$Id: ipp.h,v 1.8 1999/03/21 02:10:03 mike Exp $".
+ * End of "$Id: ipp.h,v 1.9 1999/04/21 14:12:18 mike Exp $".
  */
index 49fe97031e9988a1d40d037906cc91a4a542f7f8..bf1e98e557369ea34486cbba1ba95b9e89f2caf6 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: language.c,v 1.3 1999/02/26 15:10:25 mike Exp $"
+ * "$Id: language.c,v 1.4 1999/04/21 14:12:19 mike Exp $"
  *
  *   for the Common UNIX Printing System (CUPS).
  *
@@ -46,7 +46,7 @@
  */
 
 static cups_lang_t     *lang_cache = NULL;     /* Language string cache */
-static unsigned char   *lang_blank = "";       /* Blank constant string */
+static char            *lang_blank = "";       /* Blank constant string */
 static char            *lang_encodings[] =     /* Encoding strings */
                        {
                          "us-ascii",
@@ -330,7 +330,7 @@ cupsLangGet(char *language) /* I - Language or locale */
     while (isspace(*text))
       text ++;
     
-    lang->messages[msg] = (unsigned char *)strdup(text);
+    lang->messages[msg] = strdup(text);
   }
 
  /*
@@ -344,5 +344,5 @@ cupsLangGet(char *language) /* I - Language or locale */
 
 
 /*
- * End of "$Id: language.c,v 1.3 1999/02/26 15:10:25 mike Exp $".
+ * End of "$Id: language.c,v 1.4 1999/04/21 14:12:19 mike Exp $".
  */
index da537b567e1dba9608c20f1b3aac724525114c85..3e3d774d4b5c52b1092e45f4a8be7723a561469c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: language.h,v 1.4 1999/04/19 21:13:26 mike Exp $"
+ * "$Id: language.h,v 1.5 1999/04/21 14:12:20 mike Exp $"
  *
  *   Multi-language support for the Common UNIX Printing System (CUPS).
  *
@@ -155,7 +155,7 @@ typedef struct cups_lang_str        /**** Language Cache Structure ****/
   int                  used;           /* Number of times this entry has been used. */
   cups_encoding_t      encoding;       /* Text encoding */
   char                 language[16];   /* Language/locale name */
-  unsigned char                *messages[CUPS_MSG_MAX];
+  char                 *messages[CUPS_MSG_MAX];
                                        /* Message array */
 } cups_lang_t;
 
@@ -172,5 +172,5 @@ extern cups_lang_t  *cupsLangGet(char *language);
 #define                        cupsLangString(lang,msg) (lang)->messages[(msg)]
 
 /*
- * End of "$Id: language.h,v 1.4 1999/04/19 21:13:26 mike Exp $".
+ * End of "$Id: language.h,v 1.5 1999/04/21 14:12:20 mike Exp $".
  */
index fb9a97f168de19352f49b699c62135894c0ba2e1..bcef399bf7825dee3d54a330715b7b5de6718750 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ppd.c,v 1.15 1999/04/16 16:57:49 mike Exp $"
+ * "$Id: ppd.c,v 1.16 1999/04/21 14:12:20 mike Exp $"
  *
  *   PPD file routines for the Common UNIX Printing System (CUPS).
  *
@@ -46,6 +46,7 @@
  * Include necessary headers.
  */
 
+/*#define DEBUG*/
 #include "ppd.h"
 #include <stdlib.h>
 #include <ctype.h>
@@ -75,8 +76,8 @@
  */
 
 static int             ppd_read(FILE *fp, char *keyword, char *option,
-                                unsigned char *text, unsigned char **string);
-static void            ppd_decode(unsigned char *string);
+                                char *text, char **string);
+static void            ppd_decode(char *string);
 static void            ppd_free_group(ppd_group_t *group);
 static void            ppd_free_option(ppd_option_t *option);
 static ppd_group_t     *ppd_get_group(ppd_file_t *ppd, char *name);
@@ -255,7 +256,7 @@ ppd_get_group(ppd_file_t *ppd,      /* I - PPD file */
 
 
   for (i = ppd->num_groups, group = ppd->groups; i > 0; i --, group ++)
-    if (strcmp((char *)group->text, name) == 0)
+    if (strcmp(group->text, name) == 0)
       break;
 
   if (i == 0)
@@ -274,7 +275,7 @@ ppd_get_group(ppd_file_t *ppd,      /* I - PPD file */
     ppd->num_groups ++;
 
     memset(group, 0, sizeof(ppd_group_t));
-    strcpy((char *)group->text, name);
+    strcpy(group->text, name);
   }
 
   return (group);
@@ -399,10 +400,10 @@ ppdOpen(FILE *fp)         /* I - File to read from */
   ppd_size_t   *size;          /* Current page size */
   int          mask;           /* Line data mask */
   char         keyword[41],    /* Keyword from file */
-               name[41];       /* Option from file */
-  unsigned char        text[81],       /* Human-readable text from file */
-               *string;        /* Code/text from file */
-  char         *sptr,          /* Pointer into string */
+               name[41],       /* Option from file */
+               text[81],       /* Human-readable text from file */
+               *string,        /* Code/text from file */
+               *sptr,          /* Pointer into string */
                *nameptr;       /* Pointer into name */
   float                order;          /* Order dependency number */
   ppd_section_t        section;        /* Order dependency section */
@@ -473,7 +474,7 @@ ppdOpen(FILE *fp)           /* I - File to read from */
 
     if (string != NULL)
     {
-      if (strlen((char *)string) > 40)
+      if (strlen(string) > 40)
         printf(", string = %08x", string);
       else
         printf(", string = \"%s\"", string);
@@ -483,15 +484,15 @@ ppdOpen(FILE *fp)         /* I - File to read from */
 #endif /* DEBUG */
 
     if (strcmp(keyword, "LanguageLevel") == 0)
-      ppd->language_level = atoi((char *)string);
+      ppd->language_level = atoi(string);
     else if (strcmp(keyword, "LanguageEncoding") == 0)
     {
-      ppd->lang_encoding = (char *)string;
+      ppd->lang_encoding = string;
       string = NULL;                   /* Don't free this string below */
     }
     else if (strcmp(keyword, "LanguageVersion") == 0)
     {
-      ppd->lang_version = (char *)string;
+      ppd->lang_version = string;
       string = NULL;                   /* Don't free this string below */
     }
     else if (strcmp(keyword, "Manufacturer") == 0)
@@ -501,7 +502,7 @@ ppdOpen(FILE *fp)           /* I - File to read from */
     }
     else if (strcmp(keyword, "ModelName") == 0)
     {
-      ppd->modelname = (char *)string;
+      ppd->modelname = string;
       string = NULL;                   /* Don't free this string below */
     }
     else if (strcmp(keyword, "NickName") == 0)
@@ -521,7 +522,7 @@ ppdOpen(FILE *fp)           /* I - File to read from */
     }
     else if (strcmp(keyword, "TTRasterizer") == 0)
     {
-      ppd->ttrasterizer = (char *)string;
+      ppd->ttrasterizer = string;
       string = NULL;                   /* Don't free this string below */
     }
     else if (strcmp(keyword, "JCLBegin") == 0)
@@ -543,30 +544,30 @@ ppdOpen(FILE *fp)         /* I - File to read from */
       string = NULL;                   /* Don't free this string below */
     }
     else if (strcmp(keyword, "AccurateScreensSupport") == 0)
-      ppd->accurate_screens = strcmp((char *)string, "True") == 0;
+      ppd->accurate_screens = strcmp(string, "True") == 0;
     else if (strcmp(keyword, "ColorDevice") == 0)
-      ppd->color_device = strcmp((char *)string, "True") == 0;
+      ppd->color_device = strcmp(string, "True") == 0;
     else if (strcmp(keyword, "ContoneOnly") == 0)
-      ppd->contone_only = strcmp((char *)string, "True") == 0;
+      ppd->contone_only = strcmp(string, "True") == 0;
     else if (strcmp(keyword, "DefaultColorSpace") == 0)
     {
-      if (strcmp((char *)string, "CMY") == 0)
+      if (strcmp(string, "CMY") == 0)
         ppd->colorspace = PPD_CS_CMY;
-      else if (strcmp((char *)string, "CMYK") == 0)
+      else if (strcmp(string, "CMYK") == 0)
         ppd->colorspace = PPD_CS_CMYK;
-      else if (strcmp((char *)string, "RGB") == 0)
+      else if (strcmp(string, "RGB") == 0)
         ppd->colorspace = PPD_CS_RGB;
-      else if (strcmp((char *)string, "RGBK") == 0)
+      else if (strcmp(string, "RGBK") == 0)
         ppd->colorspace = PPD_CS_RGBK;
-      else if (strcmp((char *)string, "N") == 0)
+      else if (strcmp(string, "N") == 0)
         ppd->colorspace = PPD_CS_N;
       else
         ppd->colorspace = PPD_CS_GRAY;
     }
     else if (strcmp(keyword, "cupsManualCopies") == 0)
-      ppd->manual_copies = strcmp((char *)string, "True") == 0;
+      ppd->manual_copies = strcmp(string, "True") == 0;
     else if (strcmp(keyword, "cupsModelNumber") == 0)
-      ppd->model_number = atoi((char *)string);
+      ppd->model_number = atoi(string);
     else if (strcmp(keyword, "cupsColorProfile") == 0)
     {
       if (ppd->num_profiles == 0)
@@ -581,8 +582,8 @@ ppdOpen(FILE *fp)           /* I - File to read from */
 
       memset(profile, 0, sizeof(ppd_profile_t));
       strcpy(profile->resolution, name);
-      strcpy(profile->media_type, (char *)text);
-      sscanf((char *)string, "%f%f%f%f%f%f%f%f%f%f", &(profile->density),
+      strcpy(profile->media_type, text);
+      sscanf(string, "%f%f%f%f%f%f%f%f%f%f", &(profile->density),
             profile->matrix[0] + 0, profile->matrix[0] + 1,
             profile->matrix[0] + 2, profile->matrix[1] + 0,
             profile->matrix[1] + 1, profile->matrix[1] + 2,
@@ -590,7 +591,7 @@ ppdOpen(FILE *fp)           /* I - File to read from */
             profile->matrix[2] + 2);
     }
     else if (strcmp(keyword, "VariablePaperSize") == 0 &&
-             strcmp((char *)string, "True") == 0)
+             strcmp(string, "True") == 0)
     {
       ppd->variable_sizes = 1;
 
@@ -625,29 +626,30 @@ ppdOpen(FILE *fp)         /* I - File to read from */
        return (NULL);
       }
 
-      strcpy((char *)choice->text, "Custom Size");
+      strcpy(choice->text, "Custom Size");
       group  = NULL;
       option = NULL;
     }
     else if (strcmp(keyword, "MaxMediaWidth") == 0)
-      ppd->custom_max[0] = atof((char *)string);
+      ppd->custom_max[0] = atof(string);
     else if (strcmp(keyword, "MaxMediaHeight") == 0)
-      ppd->custom_max[1] = atof((char *)string);
+      ppd->custom_max[1] = atof(string);
     else if (strcmp(keyword, "ParamCustomPageSize") == 0)
     {
       if (strcmp(name, "Width") == 0)
-        sscanf((char *)string, "%*s%*s%f%f", ppd->custom_min + 0,
+        sscanf(string, "%*s%*s%f%f", ppd->custom_min + 0,
               ppd->custom_max + 0);
       else if (strcmp(name, "Height") == 0)
-        sscanf((char *)string, "%*s%*s%f%f", ppd->custom_min + 1,
+        sscanf(string, "%*s%*s%f%f", ppd->custom_min + 1,
               ppd->custom_max + 1);
     }
     else if (strcmp(keyword, "HWMargins") == 0)
-      sscanf((char *)string, "%f%f%f%f", ppd->custom_margins + 0,
+      sscanf(string, "%f%f%f%f", ppd->custom_margins + 0,
              ppd->custom_margins + 1, ppd->custom_margins + 2,
              ppd->custom_margins + 3);
     else if (strcmp(keyword, "CustomPageSize") == 0 &&
-             strcmp(name, "True") == 0)
+             strcmp(name, "True") == 0 &&
+            ppd->variable_sizes)
     {
       if ((option = ppdFindOption(ppd, "PageSize")) == NULL)
       {
@@ -669,14 +671,14 @@ ppdOpen(FILE *fp)         /* I - File to read from */
     }
     else if (strcmp(keyword, "LandscapeOrientation") == 0)
     {
-      if (strcmp((char *)string, "Minus90") == 0)
+      if (strcmp(string, "Minus90") == 0)
         ppd->landscape = -90;
       else
         ppd->landscape = 90;
     }
     else if (strcmp(keyword, "Emulators") == 0)
     {
-      for (count = 1, sptr = (char *)string; sptr != NULL;)
+      for (count = 1, sptr = string; sptr != NULL;)
         if ((sptr = strchr(sptr, ' ')) != NULL)
        {
          count ++;
@@ -687,7 +689,7 @@ ppdOpen(FILE *fp)           /* I - File to read from */
       ppd->num_emulations = count;
       ppd->emulations     = calloc(sizeof(ppd_emul_t), count);
 
-      for (i = 0, sptr = (char *)string; i < count; i ++)
+      for (i = 0, sptr = string; i < count; i ++)
       {
         for (nameptr = ppd->emulations[i].name; *sptr != '\0' && *sptr != ' ';)
          *nameptr ++ = *sptr ++;
@@ -729,11 +731,10 @@ ppdOpen(FILE *fp)         /* I - File to read from */
       }
       else
       {
-        ppd->patches = realloc(ppd->patches, strlen((char *)ppd->patches) +
-                                            strlen((char *)string) + 1);
+        ppd->patches = realloc(ppd->patches, strlen(ppd->patches) +
+                                            strlen(string) + 1);
 
-        strcpy((char *)ppd->patches + strlen((char *)ppd->patches),
-              (char *)string);
+        strcpy(ppd->patches + strlen(ppd->patches), string);
       }
     }
     else if (strcmp(keyword, "OpenUI") == 0)
@@ -799,14 +800,14 @@ ppdOpen(FILE *fp)         /* I - File to read from */
       * Now fill in the initial information for the option...
       */
 
-      if (strcmp((char *)string, "PickMany") == 0)
+      if (strcmp(string, "PickMany") == 0)
         option->ui = PPD_UI_PICKMANY;
-      else if (strcmp((char *)string, "Boolean") == 0)
+      else if (strcmp(string, "Boolean") == 0)
         option->ui = PPD_UI_BOOLEAN;
       else
         option->ui = PPD_UI_PICKONE;
 
-      strcpy((char *)option->text, (char *)text);
+      strcpy(option->text, text);
 
       option->section = PPD_ORDER_ANY;
     }
@@ -852,14 +853,14 @@ ppdOpen(FILE *fp)         /* I - File to read from */
       * Now fill in the initial information for the option...
       */
 
-      if (strcmp((char *)string, "PickMany") == 0)
+      if (strcmp(string, "PickMany") == 0)
         option->ui = PPD_UI_PICKMANY;
-      else if (strcmp((char *)string, "Boolean") == 0)
+      else if (strcmp(string, "Boolean") == 0)
         option->ui = PPD_UI_BOOLEAN;
       else
         option->ui = PPD_UI_PICKONE;
 
-      strcpy((char *)option->text, (char *)text);
+      strcpy(option->text, text);
 
       option->section = PPD_ORDER_JCL;
       group = NULL;
@@ -880,10 +881,10 @@ ppdOpen(FILE *fp)         /* I - File to read from */
        return (NULL);
       }
 
-      if (strchr((char *)string, '/') != NULL) /* Just show human readable text */
-        strcpy((char *)string, strchr((char *)string, '/') + 1);
+      if (strchr(string, '/') != NULL) /* Just show human readable text */
+        strcpy(string, strchr(string, '/') + 1);
 
-      group = ppd_get_group(ppd, (char *)string);
+      group = ppd_get_group(ppd, string);
     }
     else if (strcmp(keyword, "CloseGroup") == 0)
       group = NULL;
@@ -918,14 +919,14 @@ ppdOpen(FILE *fp)         /* I - File to read from */
       group->num_subgroups ++;
 
       memset(subgroup, 0, sizeof(ppd_group_t));
-      strcpy((char *)subgroup->text, (char *)string);
+      strcpy(subgroup->text, string);
     }
     else if (strcmp(keyword, "CloseSubGroup") == 0)
       subgroup = NULL;
     else if (strcmp(keyword, "OrderDependency") == 0 ||
              strcmp(keyword, "NonUIOrderDependency") == 0)
     {
-      if (sscanf((char *)string, "%f%s%s", &order, name, keyword) != 3)
+      if (sscanf(string, "%f%s%s", &order, name, keyword) != 3)
       {
         ppdClose(ppd);
        free(string);
@@ -977,8 +978,8 @@ ppdOpen(FILE *fp)           /* I - File to read from */
     }
     else if (strncmp(keyword, "Default", 7) == 0)
     {
-      if (strchr((char *)string, '/') != NULL)
-        *strchr((char *)string, '/') = '\0';
+      if (strchr(string, '/') != NULL)
+        *strchr(string, '/') = '\0';
 
       if (option == NULL)
       {
@@ -994,14 +995,14 @@ ppdOpen(FILE *fp)         /* I - File to read from */
           for (i = 0; i < group->num_options; i ++)
            if (strcmp(keyword, group->options[i].keyword) == 0)
            {
-             strcpy(group->options[i].defchoice, (char *)string);
+             strcpy(group->options[i].defchoice, string);
              break;
            }
 
         group = NULL;
       }
       else
-        strcpy(option->defchoice, (char *)string);
+        strcpy(option->defchoice, string);
     }
     else if (strcmp(keyword, "UIConstraints") == 0 ||
              strcmp(keyword, "NonUIConstraints") == 0)
@@ -1023,7 +1024,7 @@ ppdOpen(FILE *fp)         /* I - File to read from */
       constraint += ppd->num_consts;
       ppd->num_consts ++;
 
-      switch (sscanf((char *)string, "%s%s%s%s", constraint->option1,
+      switch (sscanf(string, "%s%s%s%s", constraint->option1,
                      constraint->choice1, constraint->option2,
                     constraint->choice2))
       {
@@ -1073,12 +1074,12 @@ ppdOpen(FILE *fp)               /* I - File to read from */
     else if (strcmp(keyword, "PaperDimension") == 0)
     {
       if ((size = ppdPageSize(ppd, name)) != NULL)
-        sscanf((char *)string, "%f%f", &(size->width), &(size->length));
+        sscanf(string, "%f%f", &(size->width), &(size->length));
     }
     else if (strcmp(keyword, "ImageableArea") == 0)
     {
       if ((size = ppdPageSize(ppd, name)) != NULL)
-       sscanf((char *)string, "%f%f%f%f", &(size->left), &(size->bottom),
+       sscanf(string, "%f%f%f%f", &(size->left), &(size->bottom),
               &(size->right), &(size->top));
     }
     else if (option != NULL &&
@@ -1101,13 +1102,13 @@ ppdOpen(FILE *fp)               /* I - File to read from */
       choice = ppd_add_choice(option, name);
 
       if (mask & PPD_TEXT)
-        strcpy((char *)choice->text, (char *)text);
+        strcpy(choice->text, text);
       else if (strcmp(name, "True") == 0)
-        strcpy((char *)choice->text, "Yes");
+        strcpy(choice->text, "Yes");
       else if (strcmp(name, "False") == 0)
-        strcpy((char *)choice->text, "No");
+        strcpy(choice->text, "No");
       else
-        strcpy((char *)choice->text, name);
+        strcpy(choice->text, name);
 
       if (strncmp(keyword, "JCL", 3) == 0)
         ppd_decode(string);            /* Decode quoted string */
@@ -1231,20 +1232,20 @@ ppdOpenFile(char *filename)     /* I - File to read from */
  */
 
 static int                     /* O - Bitmask of fields read */
-ppd_read(FILE          *fp,    /* I - File to read from */
-         char          *keyword,/* O - Keyword from line */
-        char          *option, /* O - Option from line */
-         unsigned char *text,  /* O - Human-readable text from line */
-        unsigned char **string)/* O - Code/string data */
+ppd_read(FILE *fp,             /* I - File to read from */
+         char *keyword,                /* O - Keyword from line */
+        char *option,          /* O - Option from line */
+         char *text,           /* O - Human-readable text from line */
+        char **string)         /* O - Code/string data */
 {
   int          ch,             /* Character from file */
                endquote,       /* Waiting for an end quote */
                mask;           /* Mask to be returned */
   char         *keyptr,        /* Keyword pointer */
-               *optptr;        /* Option pointer */
-  unsigned char        *textptr,       /* Text pointer */
-               *strptr;        /* Pointer into string */
-  unsigned char        *lineptr,       /* Current position in line buffer */
+               *optptr,        /* Option pointer */
+               *textptr,       /* Text pointer */
+               *strptr,        /* Pointer into string */
+               *lineptr,       /* Current position in line buffer */
                line[262144];   /* Line buffer (256k) */
 
 
@@ -1334,9 +1335,9 @@ ppd_read(FILE          *fp,       /* I - File to read from */
     if (line[0] != '*')                        /* All lines start with an asterisk */
       continue;
 
-    if (strncmp((char *)line, "*%", 2) == 0 || /* Comment line */
-        strncmp((char *)line, "*?", 2) == 0 || /* Query line */
-        strcmp((char *)line, "*End") == 0)     /* End of multi-line string */
+    if (strncmp(line, "*%", 2) == 0 || /* Comment line */
+        strncmp(line, "*?", 2) == 0 || /* Query line */
+        strcmp(line, "*End") == 0)     /* End of multi-line string */
       continue;
 
    /*
@@ -1397,7 +1398,7 @@ ppd_read(FILE          *fp,       /* I - File to read from */
       * Get string...
       */
 
-      *string = malloc(strlen((char *)lineptr) + 1);
+      *string = malloc(strlen(lineptr) + 1);
 
       while (*lineptr == ':' || isspace(*lineptr))
         lineptr ++;
@@ -1428,10 +1429,10 @@ ppd_read(FILE          *fp,     /* I - File to read from */
  */
 
 static void
-ppd_decode(unsigned char *string)      /* I - String to decode */
+ppd_decode(char *string)       /* I - String to decode */
 {
-  unsigned char        *inptr,                 /* Input pointer */
-               *outptr;                /* Output pointer */
+  char *inptr,                 /* Input pointer */
+       *outptr;                /* Output pointer */
 
 
   inptr  = string;
@@ -1478,5 +1479,5 @@ ppd_decode(unsigned char *string) /* I - String to decode */
 
 
 /*
- * End of "$Id: ppd.c,v 1.15 1999/04/16 16:57:49 mike Exp $".
+ * End of "$Id: ppd.c,v 1.16 1999/04/21 14:12:20 mike Exp $".
  */
index 6467dafd0a1bfa5bd76d851035723bcb6ad5fbc8..a3d73f4a94d8b0f09cf7e59f23e72cf01ea0c007 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: ppd.h,v 1.13 1999/04/09 14:21:25 mike Exp $"
+ * "$Id: ppd.h,v 1.14 1999/04/21 14:12:21 mike Exp $"
  *
  *   PostScript Printer Description definitions for the Common UNIX Printing
  *   System (CUPS).
@@ -92,8 +92,8 @@ typedef enum                  /**** Colorspaces ****/
 typedef struct                 /**** Option choices ****/
 {
   char         marked,         /* 0 if not selected, 1 otherwise */
-               choice[41];     /* Computer-readable option name */
-  unsigned char        text[81],       /* Human-readable option name */
+               choice[41],     /* Computer-readable option name */
+               text[81],       /* Human-readable option name */
                *code;          /* Code to send for this option */
   void         *option;        /* Pointer to parent option structure */
 } ppd_choice_t;
@@ -102,8 +102,8 @@ typedef struct                      /**** Options ****/
 {
   char         conflicted,     /* 0 if no conflicts exist, 1 otherwise */
                keyword[41],    /* Option keyword name ("PageSize", etc.) */
-               defchoice[41];  /* Default option choice */
-  unsigned char        text[81];       /* Human-readable text */
+               defchoice[41],  /* Default option choice */
+               text[81];       /* Human-readable text */
   ppd_ui_t     ui;             /* Type of UI option */
   ppd_section_t        section;        /* Section for command */
   float                order;          /* Order number */
@@ -113,7 +113,7 @@ typedef struct                      /**** Options ****/
 
 typedef struct ppd_group_str   /**** Groups ****/
 {
-  unsigned char        text[81];       /* Human-readable group name */
+  char         text[81];       /* Human-readable group name */
   int          num_options;    /* Number of options */
   ppd_option_t *options;       /* Options */
   int          num_subgroups;  /* Number of sub-groups */
@@ -143,8 +143,8 @@ typedef struct                      /**** Page Sizes ****/
 
 typedef struct                 /**** Emulators ****/
 {
-  char         name[41];       /* Emulator name */
-  unsigned char        *start,         /* Code to switch to this emulation */
+  char         name[41],       /* Emulator name */
+               *start,         /* Code to switch to this emulation */
                *stop;          /* Code to stop this emulation */
 } ppd_emul_t;
 
@@ -167,17 +167,17 @@ typedef struct                    /**** Files ****/
                model_number,   /* Device-specific model number */
                manual_copies;  /* 1 = Copies done manually, 0 = hardware */
   ppd_cs_t     colorspace;     /* Default colorspace */
-  unsigned char        *patches;       /* Patch commands to be sent to printer */
+  char         *patches;       /* Patch commands to be sent to printer */
   int          num_emulations; /* Number of emulations supported */
   ppd_emul_t   *emulations;    /* Emulations and the code to invoke them */
-  unsigned char        *jcl_begin,     /* Start JCL commands */
+  char         *jcl_begin,     /* Start JCL commands */
                *jcl_ps,        /* Enter PostScript interpreter */
-               *jcl_end;       /* End JCL commands */
-  char         *lang_encoding, /* Language encoding */
+               *jcl_end,       /* End JCL commands */
+               *lang_encoding, /* Language encoding */
                *lang_version,  /* Language version (English, Spanish, etc.) */
                *modelname,     /* Model name (general) */
-               *ttrasterizer;  /* Truetype rasterizer */
-  unsigned char        *manufacturer,  /* Manufacturer name */
+               *ttrasterizer,  /* Truetype rasterizer */
+               *manufacturer,  /* Manufacturer name */
                *product,       /* Product name (from PS RIP/interpreter) */
                *nickname,      /* Nickname (specific) */
                *shortnickname; /* Short version of nickname */
@@ -232,5 +232,5 @@ extern float                ppdPageWidth(ppd_file_t *ppd, char *name);
 #endif /* !_CUPS_PPD_H_ */
 
 /*
- * End of "$Id: ppd.h,v 1.13 1999/04/09 14:21:25 mike Exp $".
+ * End of "$Id: ppd.h,v 1.14 1999/04/21 14:12:21 mike Exp $".
  */
index fb6e262a7fc300ccae19b3bd7682659314ffc8cf..ecc43aec58f092520c0af2541f1da4ae0964fdd3 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: testppd.c,v 1.10 1999/04/07 14:44:14 mike Exp $"
+ * "$Id: testppd.c,v 1.11 1999/04/21 14:12:22 mike Exp $"
  *
  *   PPD test program for the Common UNIX Printing System (CUPS).
  *
@@ -32,7 +32,7 @@
  * Include necessary headers...
  */
 
-#include "ppd.h"
+#include "cups.h"
 #include "string.h"
 
 
@@ -45,6 +45,7 @@ main(int  argc,                       /* I - Number of command-line arguments */
      char *argv[])             /* I - Command-line arguments */
 {
   int          i, j, k, m, n;  /* Looping vars */
+  char         *filename;      /* File to load */
   ppd_file_t   *ppd;           /* PPD file record */
   ppd_size_t   *size;          /* Size record */
   ppd_group_t  *group;         /* UI group */
@@ -67,13 +68,18 @@ main(int  argc,                     /* I - Number of command-line arguments */
 
   for (i = 1; i < argc; i ++)
   {
-    if ((ppd = ppdOpenFile(argv[i])) == NULL)
+    if (strstr(argv[i], ".ppd"))
+      filename = argv[i];
+    else
+      filename = cupsGetPPD(argv[i]);
+
+    if ((ppd = ppdOpenFile(filename)) == NULL)
     {
-      fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", argv[i]);
+      fprintf(stderr, "Unable to open \'%s\' as a PPD file!\n", filename);
       continue;
     }
 
-    printf("FILE: %s\n", argv[i]);
+    printf("FILE: %s\n", filename);
     printf("    language_level = %d\n", ppd->language_level);
     printf("    color_device = %s\n", ppd->color_device ? "TRUE" : "FALSE");
     printf("    variable_sizes = %s\n", ppd->variable_sizes ? "TRUE" : "FALSE");
@@ -112,7 +118,7 @@ main(int  argc,                     /* I - Number of command-line arguments */
     printf("    nickname = %s\n", ppd->nickname);
     printf("    shortnickname = %s\n", ppd->shortnickname);
     printf("    patches = %d bytes\n",
-           ppd->patches == NULL ? 0 : strlen((char *)ppd->patches));
+           ppd->patches == NULL ? 0 : strlen(ppd->patches));
 
     printf("    num_groups = %d\n", ppd->num_groups);
     for (j = 0, group = ppd->groups; j < ppd->num_groups; j ++, group ++)
@@ -173,5 +179,5 @@ main(int  argc,                     /* I - Number of command-line arguments */
 
 
 /*
- * End of "$Id: testppd.c,v 1.10 1999/04/07 14:44:14 mike Exp $".
+ * End of "$Id: testppd.c,v 1.11 1999/04/21 14:12:22 mike Exp $".
  */
index 34d114365ea56961472c0c790a664093c41eecf9..1f73ed1513716211a8f41602f84eedcc63c31d84 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * "$Id: util.c,v 1.9 1999/04/19 21:13:26 mike Exp $"
+ * "$Id: util.c,v 1.10 1999/04/21 14:12:23 mike Exp $"
  *
  *   Printing utilities for the Common UNIX Printing System (CUPS).
  *
  *
  * Contents:
  *
+ *   cupsCancelJob()   - Cancel a print job.
+ *   cupsDoRequest()   - Do an IPP request...
+ *   cupsGetClasses()  - Get a list of printer classes.
+ *   cupsGetDefault()  - Get the default printer or class.
+ *   cupsGetPPD()      - Get the PPD file for a printer.
+ *   cupsGetPrinters() - Get a list of printers.
+ *   cupsPrintFile()   - Print a file to a printer or class.
+ *   cups_connect()    - Connect to the specified host...
  */
 
 /*
 #include <ctype.h>
 #include <errno.h>
 #include <sys/stat.h>
+#if defined(WIN32) || defined(__EMX__)
+#  include <io.h>
+#else
+#  include <unistd.h>
+#endif /* WIN32 || __EMX__ */
 
 
 /*
  * Local globals...
  */
 
-static http_t  *cupsServer = NULL;
+static http_t  *cups_server = NULL;
+
+
+/*
+ * Local functions...
+ */
+
+static char    *cups_connect(char *name, char *printer, char *hostname);
 
 
 /*
  * 'cupsCancelJob()' - Cancel a print job.
  */
 
-int
-cupsCancelJob(char *printer,
-              int  job)
+int                            /* O - 1 on success, 0 on failure */
+cupsCancelJob(char *name,      /* I - Name of printer or class */
+              int  job)                /* I - Job ID */
 {
-  return (0);
+  char         printer[HTTP_MAX_URI],  /* Printer name */
+               hostname[HTTP_MAX_URI], /* Hostname */
+               uri[HTTP_MAX_URI];      /* Printer URI */
+  ipp_t                *request,               /* IPP request */
+               *response;              /* IPP response */
+  cups_lang_t  *language;              /* Language info */
+
+
+ /*
+  * See if we can connect to the server...
+  */
+
+  if (!cups_connect(name, printer, hostname))
+    return (NULL);
+
+ /*
+  * Build an IPP_CANCEL_JOB request, which requires the following
+  * attributes:
+  *
+  *    attributes-charset
+  *    attributes-natural-language
+  *    printer-uri
+  *    job-id
+  */
+
+  request = ippNew();
+
+  request->request.op.operation_id = IPP_CANCEL_JOB;
+  request->request.op.request_id   = 1;
+
+  language = cupsLangDefault();
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+               "attributes-charset", NULL, cupsLangEncoding(language));
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+               "attributes-natural-language", NULL,
+               language != NULL ? language->language : "C");
+
+  sprintf(uri, "ipp://%s:%d/printers/%s", hostname, ippPort(), printer);
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+               NULL, uri);
+
+  ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, "job-id", job);
+
+ /*
+  * Do the request...
+  */
+
+  if ((response = cupsDoRequest(cups_server, request, "/jobs/")) == NULL)
+    return (0);
+
+  ippDelete(response);
+  return (1);
 }
 
 
@@ -70,6 +143,13 @@ cupsDoRequest(http_t *http, /* I - HTTP connection to server */
 {
   ipp_t                *response;      /* IPP response data */
   char         length[255];    /* Content-Length field */
+  char         *password,      /* Password string */
+               plain[255],     /* Plaintext username:password */
+               encode[255];    /* Encoded username:password */
+  http_status_t        status;         /* Status of HTTP request */
+  char         junk[8192];     /* Junk buffer for error data */
+  static char  authstring[255] = "";
+                               /* Authorization string */
 
 
   DEBUG_printf(("cupsDoRequest(%08x, %08s, \'%s\')\n", http, request, resource));
@@ -82,26 +162,64 @@ cupsDoRequest(http_t *http,        /* I - HTTP connection to server */
   httpClearFields(http);
   httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length);
   httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
+  httpSetField(http, HTTP_FIELD_AUTHORIZATION, authstring);
 
  /*
-  * Try the request (twice, if needed)...
+  * Try the request...
   */
 
   if (httpPost(http, resource))
-    if (httpPost(http, resource))
-    {
-      ippDelete(request);
-      return (NULL);
-    }
+  {
+    ippDelete(request);
+    return (NULL);
+  }
 
  /*
   * Send the IPP data and wait for the response...
   */
 
-  if (ippWrite(http, request) != IPP_DATA)
-    response = NULL;
-  else if (httpUpdate(http) != HTTP_OK)
+  ippWrite(http, request);
+
+  if ((status = httpUpdate(http)) == HTTP_UNAUTHORIZED)
+  {
+   /*
+    * Flush any error message...
+    */
+
+    while (httpRead(http, junk, sizeof(junk)) > 0);
+
+    if ((password = getpass("Password:")) != NULL)
+    {
+     /*
+      * Got a password; now send it to the server...
+      */
+
+      sprintf(plain, "%s:%s", cuserid(NULL), password);
+      httpEncode64(encode, plain);
+      sprintf(authstring, "Basic %s", encode);
+
+      httpClearFields(http);
+      httpSetField(http, HTTP_FIELD_CONTENT_LENGTH, length);
+      httpSetField(http, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
+      httpSetField(http, HTTP_FIELD_AUTHORIZATION, authstring);
+
+      httpPost(http, resource);
+      request->state = IPP_IDLE;
+      ippWrite(http, request);
+      status = httpUpdate(http);
+    }
+  }
+
+  if (status != HTTP_OK)
+  {
+   /*
+    * Flush any error message...
+    */
+
+    while (httpRead(http, junk, sizeof(junk)) > 0);
+
     response = NULL;
+  }
   else
   {
    /*
@@ -114,6 +232,12 @@ cupsDoRequest(http_t *http,        /* I - HTTP connection to server */
     {
       ippDelete(response);
       response = NULL;
+
+     /*
+      * Flush any remaining data...
+      */
+
+      while (httpRead(http, junk, sizeof(junk)) > 0);
     }
   }
 
@@ -131,10 +255,76 @@ cupsDoRequest(http_t *http,       /* I - HTTP connection to server */
  * 'cupsGetClasses()' - Get a list of printer classes.
  */
 
-int
-cupsGetClasses(char ***classes)
+int                            /* O - Number of classes */
+cupsGetClasses(char ***classes)        /* O - Classes */
 {
-  return (0);
+  int          n;              /* Number of classes */
+  ipp_t                *request,       /* IPP Request */
+               *response;      /* IPP Response */
+  ipp_attribute_t *attr;       /* Current attribute */
+  cups_lang_t  *language;      /* Default language */
+
+
+ /*
+  * Try to connect to the server...
+  */
+
+  if (!cups_connect("default", NULL, NULL))
+    return (NULL);
+
+ /*
+  * Build a CUPS_GET_CLASSES request, which requires the following
+  * attributes:
+  *
+  *    attributes-charset
+  *    attributes-natural-language
+  */
+
+  request = ippNew();
+
+  request->request.op.operation_id = CUPS_GET_CLASSES;
+  request->request.op.request_id   = 1;
+
+  language = cupsLangDefault();
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+                      "attributes-charset", NULL, cupsLangEncoding(language));
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+                      "attributes-natural-language", NULL, language->language);
+
+ /*
+  * Do the request and get back a response...
+  */
+
+  n        = 0;
+  *classes = NULL;
+
+  if ((response = cupsDoRequest(cups_server, request, "/classes/")) != NULL)
+  {
+    for (attr = response->attrs; attr != NULL; attr = attr->next)
+      if (strcmp(attr->name, "printer-name") == 0 &&
+          attr->value_tag == IPP_TAG_NAME)
+      {
+        if (n == 0)
+         *classes = malloc(sizeof(char *));
+       else
+         *classes = realloc(*classes, sizeof(char *) * (n + 1));
+
+       if (*classes == NULL)
+       {
+         ippDelete(response);
+         return (0);
+       }
+
+        (*classes)[n] = strdup(attr->values[0].string.text);
+       n ++;
+      }
+
+    ippDelete(response);
+  }
+
+  return (n);
 }
 
 
@@ -166,9 +356,8 @@ cupsGetDefault(void)
   * Try to connect to the server...
   */
 
-  if (cupsServer == NULL)
-    if ((cupsServer = httpConnect("localhost", ippPort())) == NULL)
-      return (NULL);
+  if (!cups_connect("default", NULL, NULL))
+    return (NULL);
 
  /*
   * Build a CUPS_GET_DEFAULT request, which requires the following
@@ -185,17 +374,17 @@ cupsGetDefault(void)
 
   language = cupsLangDefault();
 
-  attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                      "attributes-charset", NULL, cupsLangEncoding(language));
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+               "attributes-charset", NULL, cupsLangEncoding(language));
 
-  attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-                      "attributes-natural-language", NULL, language->language);
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+               "attributes-natural-language", NULL, language->language);
 
  /*
   * Do the request and get back a response...
   */
 
-  if ((response = cupsDoRequest(cupsServer, request, "/printers/")) != NULL)
+  if ((response = cupsDoRequest(cups_server, request, "/printers/")) != NULL)
   {
     if ((attr = ippFindAttribute(response, "printer-name", IPP_TAG_NAME)) != NULL)
     {
@@ -215,9 +404,86 @@ cupsGetDefault(void)
  * 'cupsGetPPD()' - Get the PPD file for a printer.
  */
 
-char *
-cupsGetPPD(char *printer)
+char *                         /* O - Filename for PPD file */
+cupsGetPPD(char *name)         /* I - Printer name */
 {
+  FILE         *fp;                    /* PPD file */
+  int          bytes;                  /* Number of bytes read */
+  char         buffer[8192];           /* Buffer for file */
+  char         printer[HTTP_MAX_URI],  /* Printer name */
+               hostname[HTTP_MAX_URI], /* Hostname */
+               resource[HTTP_MAX_URI]; /* Resource name */
+  static char  filename[HTTP_MAX_URI]; /* Local filename */
+  char         *tempdir;               /* Temporary file directory */
+  struct stat  fileinfo;               /* File information */
+
+
+ /*
+  * See if we can connect to the server...
+  */
+
+  if (!cups_connect(name, printer, hostname))
+    return (NULL);
+
+ /*
+  * Then check for the cache file...
+  */
+
+#if defined(WIN32) || defined(__EMX__)
+  tempdir = "C:/WINDOWS/TEMP";
+#else
+  if ((tempdir = getenv("TMPDIR")) == NULL)
+    tempdir = "/tmp";
+#endif /* WIN32 || __EMX__ */
+
+  sprintf(filename, "%s/%s.ppd", tempdir, printer);
+  if (stat(filename, &fileinfo))
+    memset(&fileinfo, 0, sizeof(fileinfo));
+
+ /*
+  * And send a request to the HTTP server using "if-modified-since"...
+  */
+
+  sprintf(resource, "/printers/%s.ppd", printer);
+
+  httpClearFields(cups_server);
+  httpSetField(cups_server, HTTP_FIELD_HOST, hostname);
+  httpSetField(cups_server, HTTP_FIELD_IF_MODIFIED_SINCE,
+               httpGetDateString(fileinfo.st_mtime));
+  httpGet(cups_server, resource);
+
+  switch (httpUpdate(cups_server))
+  {
+    case HTTP_OK : /* New file - get it! */
+        break;
+    case HTTP_NOT_MODIFIED : /* File hasn't been modified; use the current copy */
+        return (filename);
+    default :
+        return (NULL);
+  }
+
+ /*
+  * OK, we need to copy the file; open the file and copy it...
+  */
+
+  unlink(filename);
+  if ((fp = fopen(filename, "w")) == NULL)
+  {
+   /*
+    * Can't open file; close the server connection and return NULL...
+    */
+
+    httpClose(cups_server);
+    cups_server = NULL;
+    return (NULL);
+  }
+
+  while ((bytes = httpRead(cups_server, buffer, sizeof(buffer))) > 0)
+    fwrite(buffer, bytes, 1, fp);
+
+  fclose(fp);
+
+  return (filename);
 }
 
 
@@ -225,10 +491,76 @@ cupsGetPPD(char *printer)
  * 'cupsGetPrinters()' - Get a list of printers.
  */
 
-int
-cupsGetPrinters(char ***printers)
+int                                    /* O - Number of printers */
+cupsGetPrinters(char ***printers)      /* O - Printers */
 {
-  return (0);
+  int          n;              /* Number of printers */
+  ipp_t                *request,       /* IPP Request */
+               *response;      /* IPP Response */
+  ipp_attribute_t *attr;       /* Current attribute */
+  cups_lang_t  *language;      /* Default language */
+
+
+ /*
+  * Try to connect to the server...
+  */
+
+  if (!cups_connect("default", NULL, NULL))
+    return (NULL);
+
+ /*
+  * Build a CUPS_GET_PRINTERS request, which requires the following
+  * attributes:
+  *
+  *    attributes-charset
+  *    attributes-natural-language
+  */
+
+  request = ippNew();
+
+  request->request.op.operation_id = CUPS_GET_PRINTERS;
+  request->request.op.request_id   = 1;
+
+  language = cupsLangDefault();
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+                      "attributes-charset", NULL, cupsLangEncoding(language));
+
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+                      "attributes-natural-language", NULL, language->language);
+
+ /*
+  * Do the request and get back a response...
+  */
+
+  n         = 0;
+  *printers = NULL;
+
+  if ((response = cupsDoRequest(cups_server, request, "/printers/")) != NULL)
+  {
+    for (attr = response->attrs; attr != NULL; attr = attr->next)
+      if (strcmp(attr->name, "printer-name") == 0 &&
+          attr->value_tag == IPP_TAG_NAME)
+      {
+        if (n == 0)
+         *printers = malloc(sizeof(char *));
+       else
+         *printers = realloc(*printers, sizeof(char *) * (n + 1));
+
+       if (*printers == NULL)
+       {
+         ippDelete(response);
+         return (0);
+       }
+
+        (*printers)[n] = strdup(attr->values[0].string.text);
+       n ++;
+      }
+
+    ippDelete(response);
+  }
+
+  return (n);
 }
 
 
@@ -237,31 +569,34 @@ cupsGetPrinters(char ***printers)
  */
 
 int                                    /* O - Job ID */
-cupsPrintFile(char          *printer,  /* I - Printer or class name */
+cupsPrintFile(char          *name,     /* I - Printer or class name */
               char          *filename, /* I - File to print */
+             char          *title,     /* I - Title of job */
               int           num_options,/* I - Number of options */
              cups_option_t *options)   /* I - Options */
 {
-  int                  i;                      /* Looping var */
-  int                  n, n2;                  /* Attribute values */
-  char                 *name,                  /* Name of option */
-                       *val,                   /* Pointer to option value */
-                       *s;                     /* Pointer into option value */
-  ipp_t                        *request;               /* IPP request */
-  ipp_t                        *response;              /* IPP response */
-  char                 uri[HTTP_MAX_URI];      /* Printer URI */
-  cups_lang_t          *language;              /* Language to use */
-  ipp_attribute_t      *attr;                  /* IPP attribute */
-  struct stat          filestats;              /* File information */
-  FILE                 *fp;                    /* File pointer */
-  char                 buffer[8192];           /* Copy buffer */
-  int                  jobid;                  /* New job ID */
-  
+  int          i;                      /* Looping var */
+  int          n, n2;                  /* Attribute values */
+  char         *option,                /* Name of option */
+               *val,                   /* Pointer to option value */
+               *s;                     /* Pointer into option value */
+  ipp_t                *request;               /* IPP request */
+  ipp_t                *response;              /* IPP response */
+  ipp_attribute_t *attr;               /* IPP job-id attribute */
+  char         hostname[HTTP_MAX_URI], /* Hostname */
+               printer[HTTP_MAX_URI],  /* Printer or class name */
+               uri[HTTP_MAX_URI];      /* Printer URI */
+  cups_lang_t  *language;              /* Language to use */
+  struct stat  filestats;              /* File information */
+  FILE         *fp;                    /* File pointer */
+  char         buffer[8192];           /* Copy buffer */
+  int          jobid;                  /* New job ID */
+
 
   DEBUG_printf(("cupsPrintFile(\'%s\', \'%s\', %d, %08x)\n",
                 printer, filename, num_options, options));
 
-  if (printer == NULL || filename == NULL)
+  if (name == NULL || filename == NULL)
     return (0);
 
  /*
@@ -287,15 +622,14 @@ cupsPrintFile(char          *printer,     /* I - Printer or class name */
     return (0);
   }
 
-  if (cupsServer == NULL)
-    if ((cupsServer = httpConnect("localhost", ippPort())) == NULL)
-    {
-      DEBUG_printf(("cupsPrintFile: Unable to open connection - %s.\n",
-                    strerror(errno)));
-      fclose(fp);
-      ippDelete(request);
-      return (0);
-    }
+  if (!cups_connect(name, printer, hostname))
+  {
+    DEBUG_printf(("cupsPrintFile: Unable to open connection - %s.\n",
+                  strerror(errno)));
+    fclose(fp);
+    ippDelete(request);
+    return (0);
+  }
 
  /*
   * Build a standard CUPS URI for the printer and fill the standard IPP
@@ -305,31 +639,34 @@ cupsPrintFile(char          *printer,     /* I - Printer or class name */
   request->request.op.operation_id = IPP_PRINT_JOB;
   request->request.op.request_id   = 1;
 
-  sprintf(uri, "http://localhost:%d/printers/%s", ippPort(), printer);
+  sprintf(uri, "ipp://%s:%d/printers/%s", hostname, ippPort(), printer);
 
   language = cupsLangDefault();
 
-  attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
-                      "attributes-charset", NULL, cupsLangEncoding(language));
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET,
+               "attributes-charset", NULL, cupsLangEncoding(language));
 
-  attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
-                      "attributes-natural-language", NULL,
-                      language != NULL ? language->language : "C");
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE,
+               "attributes-natural-language", NULL,
+               language != NULL ? language->language : "C");
 
-  attr = ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
-                      NULL, uri);
+  ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
+               NULL, uri);
 
-  attr = ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
-                      NULL, "application/octet-stream");
+  ippAddString(request, IPP_TAG_JOB, IPP_TAG_MIMETYPE, "document-format",
+               NULL, "application/octet-stream");
 
 #if defined(WIN32) || defined(__EMX__)
-  attr = ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "requesting-user-name",
-                      NULL, "WindowsUser");
+  ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "requesting-user-name",
+               NULL, "WindowsUser");
 #else
-  attr = ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "requesting-user-name",
-                      NULL, cuserid(NULL));
+  ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "requesting-user-name",
+               NULL, cuserid(NULL));
 #endif /* WIN32 || __EMX__ */
 
+  if (title)
+    ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-name", NULL, title);
+
  /*
   * Then add all options on the command-line...
   */
@@ -342,8 +679,8 @@ cupsPrintFile(char          *printer,       /* I - Printer or class name */
     * option=value, option=low-high, and option=MxN.
     */
 
-    name = options[i].name;
-    val  = options[i].value;
+    option = options[i].name;
+    val    = options[i].value;
 
     if (*val == '\0')
       val = NULL;
@@ -377,10 +714,10 @@ cupsPrintFile(char          *printer,     /* I - Printer or class name */
     }
     else
     {
-      if (strncmp(name, "no", 2) == 0)
+      if (strncmp(option, "no", 2) == 0)
       {
-       name += 2;
-       n    = 0;
+       option += 2;
+       n      = 0;
       }
       else
         n = 1;
@@ -395,12 +732,9 @@ cupsPrintFile(char          *printer,      /* I - Printer or class name */
       */
 
       DEBUG_printf(("cupsPrintJob: Adding string option \'%s\' with value \'%s\'...\n",
-                    name, val));
+                    option, val));
 
-      if (strcmp(name, "job-name") == 0)
-        ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, name, NULL, val);
-      else
-        ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, name, NULL, val);
+      ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val);
     }
     else if (val != NULL)
     {
@@ -410,32 +744,32 @@ cupsPrintFile(char          *printer,     /* I - Printer or class name */
 
       if (*s == '-')
       {
-        n2   = strtol(s + 1, NULL, 0);
-        ippAddRange(request, IPP_TAG_JOB, name, n, n2);
+        n2 = strtol(s + 1, NULL, 0);
+        ippAddRange(request, IPP_TAG_JOB, option, n, n2);
 
        DEBUG_printf(("cupsPrintJob: Adding range option \'%s\' with value %d-%d...\n",
-                      name, n, n2));
+                      option, n, n2));
       }
       else if (*s == 'x')
       {
         n2 = strtol(s + 1, &s, 0);
 
        if (strcmp(s, "dpc") == 0)
-          ippAddResolution(request, IPP_TAG_JOB, name, IPP_RES_PER_CM, n, n2);
+          ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_CM, n, n2);
         else if (strcmp(s, "dpi") == 0)
-          ippAddResolution(request, IPP_TAG_JOB, name, IPP_RES_PER_INCH, n, n2);
+          ippAddResolution(request, IPP_TAG_JOB, option, IPP_RES_PER_INCH, n, n2);
         else
-          ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, name, NULL, val);
+          ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, option, NULL, val);
 
        DEBUG_printf(("cupsPrintJob: Adding resolution option \'%s\' with value %s...\n",
-                      name, val));
+                      option, val));
       }
       else
       {
-        ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, name, n);
+        ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_INTEGER, option, n);
 
        DEBUG_printf(("cupsPrintJob: Adding integer option \'%s\' with value %d...\n",
-                      name, n));
+                      option, n));
       }
     }
     else
@@ -445,8 +779,8 @@ cupsPrintFile(char          *printer,       /* I - Printer or class name */
       */
 
       DEBUG_printf(("cupsPrintJob: Adding boolean option \'%s\' with value %d...\n",
-                    name, n));
-      ippAddBoolean(request, IPP_TAG_JOB, name, (char)n);
+                    option, n));
+      ippAddBoolean(request, IPP_TAG_JOB, option, (char)n);
     }
   }
 
@@ -454,11 +788,11 @@ cupsPrintFile(char          *printer,     /* I - Printer or class name */
   * Setup the necessary HTTP fields...
   */
 
-  httpClearFields(cupsServer);
-  httpSetField(cupsServer, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
+  httpClearFields(cups_server);
+  httpSetField(cups_server, HTTP_FIELD_CONTENT_TYPE, "application/ipp");
 
-  sprintf(buffer, "%u", ippLength(request) + filestats.st_size);
-  httpSetField(cupsServer, HTTP_FIELD_CONTENT_LENGTH, buffer);
+  sprintf(buffer, "%u", (unsigned)(ippLength(request) + filestats.st_size));
+  httpSetField(cups_server, HTTP_FIELD_CONTENT_LENGTH, buffer);
 
  /*
   * Finally, issue a POST request for the printer and send the IPP data and
@@ -469,12 +803,12 @@ cupsPrintFile(char          *printer,     /* I - Printer or class name */
 
   response = ippNew();
 
-  if (httpPost(cupsServer, uri))
+  if (httpPost(cups_server, uri))
   {
     DEBUG_puts("httpPost() failed.");
     jobid = 0;
   }
-  else if (ippWrite(cupsServer, request) == IPP_ERROR)
+  else if (ippWrite(cups_server, request) == IPP_ERROR)
   {
     DEBUG_puts("ippWrite() failed.");
     jobid = 0;
@@ -482,25 +816,25 @@ cupsPrintFile(char          *printer,     /* I - Printer or class name */
   else
   {
     while ((i = fread(buffer, 1, sizeof(buffer), fp)) > 0)
-      if (httpWrite(cupsServer, buffer, i) < i)
+      if (httpWrite(cups_server, buffer, i) < i)
       {
         DEBUG_puts("httpWrite() failed.");
 
        fclose(fp);
        ippDelete(request);
        ippDelete(response);
-       httpClose(cupsServer);
+       httpClose(cups_server);
        return (0);
       }
 
-    httpWrite(cupsServer, buffer, 0);
+    httpWrite(cups_server, buffer, 0);
 
-    if (httpUpdate(cupsServer) == HTTP_ERROR)
+    if (httpUpdate(cups_server) == HTTP_ERROR)
     {
       DEBUG_printf(("httpUpdate() failed (%d).\n", status));
       jobid = 0;
     }
-    else if ((ippRead(cupsServer, response)) == IPP_ERROR)
+    else if ((ippRead(cups_server, response)) == IPP_ERROR)
     {
       DEBUG_puts("ippRead() failed.");
       jobid = 0;
@@ -529,5 +863,51 @@ cupsPrintFile(char          *printer,      /* I - Printer or class name */
 
 
 /*
- * End of "$Id: util.c,v 1.9 1999/04/19 21:13:26 mike Exp $".
+ * 'cups_connect()' - Connect to the specified host...
+ */
+
+static char *                  /* I - Printer name if success, NULL if fail */
+cups_connect(char *name,       /* I - Destination (printer[@host]) */
+            char *printer,     /* O - Printer name */
+             char *hostname)   /* O - Hostname */
+{
+  char         hostbuf[HTTP_MAX_URI];
+                               /* Name of host */
+  static char  printerbuf[HTTP_MAX_URI];
+                               /* Name of printer or class */
+
+
+  if (name == NULL)
+    return (NULL);
+
+  if (sscanf(name, "%[^@]@%s", printerbuf, hostbuf) == 1)
+    strcpy(hostbuf, "localhost");
+
+  if (hostname != NULL)
+    strcpy(hostname, hostbuf);
+  else
+    hostname = hostbuf;
+
+  if (printer != NULL)
+    strcpy(printer, printerbuf);
+  else
+    printer = printerbuf;
+
+  if (cups_server != NULL)
+  {
+    if (strcasecmp(cups_server->hostname, hostname) == 0)
+      return (printer);
+
+    httpClose(cups_server);
+  }
+
+  if ((cups_server = httpConnect(hostname, ippPort())) == NULL)
+    return (NULL);
+  else
+    return (printer);
+}
+
+
+/*
+ * End of "$Id: util.c,v 1.10 1999/04/21 14:12:23 mike Exp $".
  */