1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 /*
  22  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  23  * Use is subject to license terms.
  24  */
  25 
  26 #pragma ident   "%Z%%M% %I%     %E% SMI"
  27 
  28 /*
  29  * This file contains an extremely rudimentary implementation of PPD file
  30  * parsing support.  The parsing done here converts the contents of a PPD
  31  * file into a set of PAPI attributes that applications can use to build
  32  * print panels.
  33  */
  34 
  35 #include <stdio.h>
  36 #include <ctype.h>
  37 #include <string.h>
  38 #include <papi.h>
  39 
  40 static void
  41 process_line(char *line, char **key, char **value, char **comment)
  42 {
  43         char *ptr, *ptr2;
  44 
  45         *key = &line[1];
  46         *value = NULL;
  47         *comment = NULL;
  48 
  49         if ((ptr = strchr(line, ':')) == NULL)
  50                 return;
  51 
  52         /*
  53          * line is in the form:
  54          *    *key: value/comment
  55          * or
  56          *    *key value/comment: data
  57          */
  58         *ptr++ = NULL;
  59         while (isspace(*ptr) != 0)
  60                 ptr++;
  61 
  62         if ((ptr2 = strchr(line, ' ')) != NULL) {
  63                 ptr = ptr2;
  64                 /*
  65                  * line is in the form:
  66                  *    *key value/comment: data
  67                  */
  68                 *ptr++ = NULL;
  69                 while (*ptr == ' ')
  70                         ptr++;
  71         }
  72 
  73         if (*ptr == '*')
  74                 ptr++;
  75 
  76         *value = ptr;
  77 
  78         if ((ptr = strchr(ptr, '/')) != NULL) {
  79                 *ptr++ = NULL;
  80                 *comment = ptr;
  81         }
  82 }
  83 
  84 papi_status_t
  85 PPDFileToAttributesList(papi_attribute_t ***attributes, char *filename)
  86 {
  87         papi_status_t status = PAPI_OK;
  88         FILE *fp;
  89         char line[256];
  90         char capability[256];
  91         char def[256];
  92         char supported[256];
  93         char *current_group_name = NULL;
  94 
  95         int ui = 0;
  96 
  97         if ((fp = fopen(filename, "r")) == NULL)
  98                 return (PAPI_NOT_POSSIBLE);
  99 
 100         while ((status == PAPI_OK) &&
 101                         (fgets(line, sizeof (line), fp) != NULL)) {
 102                 char *key = NULL, *value = NULL, *text = NULL;
 103 
 104                 /* we want *key...: "value" */
 105                 if (line[0] != '*')
 106                         continue;
 107 
 108                 if (strchr(line, ':') == NULL)
 109                         continue;
 110 
 111                 if ((text = strrchr(line, '\n')) != NULL)
 112                         *text = NULL;
 113 
 114                 process_line(line, &key, &value, &text);
 115 
 116                 if ((strcasecmp(key, "PageSize") == 0) ||
 117                     (strcasecmp(key, "InputSlot") == 0))
 118                         key = "media";
 119 
 120                 if (strcasecmp(key, "OpenGroup") == 0) {
 121                         if (value == NULL)
 122                                 value = "unknown";
 123                         current_group_name = strdup(value);
 124                 } else if (strcasecmp(key, "OpenUI") == 0) {
 125                         if ((strcasecmp(value, "PageSize") == 0) ||
 126                             (strcasecmp(value, "InputSlot") == 0))
 127                                 value = "media";
 128                         snprintf(capability, sizeof (capability), "%s", value);
 129                         snprintf(def, sizeof (def),
 130                                         "%s-default", value);
 131                         snprintf(supported, sizeof (supported),
 132                                         "%s-supported", value);
 133                         ui = 1;
 134                 } else if (strcasecmp(key, "CloseGroup") == 0) {
 135                         /* do nothing */
 136                 } else if (strcasecmp(key, "CloseUI") == 0) {
 137                         ui = 0;
 138                         /* do nothing */
 139                 } else if (strcasecmp(key, "Manufacturer") == 0) {
 140                         status = papiAttributeListAddString(attributes,
 141                                         PAPI_ATTR_EXCL,
 142                                         "printer-make", value);
 143                 } else if (strcasecmp(key, "ModelName") == 0) {
 144                         status = papiAttributeListAddString(attributes,
 145                                         PAPI_ATTR_EXCL,
 146                                         "printer-model", value);
 147                 } else if (strcasecmp(key, "ShortNickName") == 0) {
 148                         status = papiAttributeListAddString(attributes,
 149                                         PAPI_ATTR_EXCL,
 150                                         "printer-make-and-model", value);
 151                 } else if ((strncasecmp(key, "Default", 7) == 0) && ui) {
 152                         status = papiAttributeListAddString(attributes,
 153                                         PAPI_ATTR_EXCL,
 154                                         def, value);
 155                 } else if ((strcasecmp(key, capability) == 0) && ui) {
 156                         status = papiAttributeListAddString(attributes,
 157                                         PAPI_ATTR_APPEND,
 158                                         supported, value);
 159                 }
 160         }
 161         fclose(fp);
 162 
 163         return (status);
 164 }