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 2017 Gary Mills
  23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  */
  26 
  27 /*
  28  * This file contains an extremely rudimentary implementation of PPD file
  29  * parsing support.  The parsing done here converts the contents of a PPD
  30  * file into a set of PAPI attributes that applications can use to build
  31  * print panels.
  32  */
  33 
  34 #include <stdio.h>
  35 #include <ctype.h>
  36 #include <string.h>
  37 #include <papi.h>
  38 
  39 static void
  40 process_line(char *line, char **key, char **value, char **comment)
  41 {
  42         char *ptr, *ptr2;
  43 
  44         *key = &line[1];
  45         *value = NULL;
  46         *comment = NULL;
  47 
  48         if ((ptr = strchr(line, ':')) == NULL)
  49                 return;
  50 
  51         /*
  52          * line is in the form:
  53          *    *key: value/comment
  54          * or
  55          *    *key value/comment: data
  56          */
  57         *ptr++ = NULL;
  58         while (isspace(*ptr) != 0)
  59                 ptr++;
  60 
  61         if ((ptr2 = strchr(line, ' ')) != NULL) {
  62                 ptr = ptr2;
  63                 /*
  64                  * line is in the form:
  65                  *    *key value/comment: data
  66                  */
  67                 *ptr++ = NULL;
  68                 while (*ptr == ' ')
  69                         ptr++;
  70         }
  71 
  72         if (*ptr == '*')
  73                 ptr++;
  74 
  75         *value = ptr;
  76 
  77         if ((ptr = strchr(ptr, '/')) != NULL) {
  78                 *ptr++ = NULL;
  79                 *comment = ptr;
  80         }
  81 }
  82 
  83 papi_status_t
  84 PPDFileToAttributesList(papi_attribute_t ***attributes, char *filename)
  85 {
  86         papi_status_t status = PAPI_OK;
  87         FILE *fp;
  88         char line[256];
  89         char capability[256];
  90         char def[256];
  91         char supported[256];
  92 
  93         int ui = 0;
  94 
  95         if ((fp = fopen(filename, "r")) == NULL)
  96                 return (PAPI_NOT_POSSIBLE);
  97 
  98         while ((status == PAPI_OK) &&
  99                         (fgets(line, sizeof (line), fp) != NULL)) {
 100                 char *key = NULL, *value = NULL, *text = NULL;
 101 
 102                 /* we want *key...: "value" */
 103                 if (line[0] != '*')
 104                         continue;
 105 
 106                 if (strchr(line, ':') == NULL)
 107                         continue;
 108 
 109                 if ((text = strrchr(line, '\n')) != NULL)
 110                         *text = NULL;
 111 
 112                 process_line(line, &key, &value, &text);
 113 
 114                 if ((strcasecmp(key, "PageSize") == 0) ||
 115                     (strcasecmp(key, "InputSlot") == 0))
 116                         key = "media";
 117 
 118                 if (strcasecmp(key, "OpenGroup") == 0) {
 119                         if (value == NULL)
 120                                 value = "unknown";
 121                 } else if (strcasecmp(key, "OpenUI") == 0) {
 122                         if ((strcasecmp(value, "PageSize") == 0) ||
 123                             (strcasecmp(value, "InputSlot") == 0))
 124                                 value = "media";
 125                         snprintf(capability, sizeof (capability), "%s", value);
 126                         snprintf(def, sizeof (def),
 127                                         "%s-default", value);
 128                         snprintf(supported, sizeof (supported),
 129                                         "%s-supported", value);
 130                         ui = 1;
 131                 } else if (strcasecmp(key, "CloseGroup") == 0) {
 132                         /* do nothing */
 133                 } else if (strcasecmp(key, "CloseUI") == 0) {
 134                         ui = 0;
 135                         /* do nothing */
 136                 } else if (strcasecmp(key, "Manufacturer") == 0) {
 137                         status = papiAttributeListAddString(attributes,
 138                                         PAPI_ATTR_EXCL,
 139                                         "printer-make", value);
 140                 } else if (strcasecmp(key, "ModelName") == 0) {
 141                         status = papiAttributeListAddString(attributes,
 142                                         PAPI_ATTR_EXCL,
 143                                         "printer-model", value);
 144                 } else if (strcasecmp(key, "ShortNickName") == 0) {
 145                         status = papiAttributeListAddString(attributes,
 146                                         PAPI_ATTR_EXCL,
 147                                         "printer-make-and-model", value);
 148                 } else if ((strncasecmp(key, "Default", 7) == 0) && ui) {
 149                         status = papiAttributeListAddString(attributes,
 150                                         PAPI_ATTR_EXCL,
 151                                         def, value);
 152                 } else if ((strcasecmp(key, capability) == 0) && ui) {
 153                         status = papiAttributeListAddString(attributes,
 154                                         PAPI_ATTR_APPEND,
 155                                         supported, value);
 156                 }
 157         }
 158         fclose(fp);
 159 
 160         return (status);
 161 }