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 2008 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 /* 27 * This file contains routines necessary to convert a string buffer into 28 * a printer object. 29 */ 30 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <unistd.h> 34 #include <sys/types.h> 35 #include <string.h> 36 #include <stdarg.h> 37 #include <syslog.h> 38 39 #include <ns.h> 40 #include <list.h> 41 42 #define ESCAPE_CHARS "\\\n=:" /* \, \n, =, : */ 43 44 /* 45 * Just like strncat(3C), but escapes the supplied characters. 46 * This allows the escape character '\' and seperators to be part of the 47 * keys or values. 48 */ 49 char * 50 strncat_escaped(char *d, char *s, int len, char *escape) 51 { 52 char *t = d; 53 54 while ((*t != '\0') && (len > 0)) 55 len--, t++; 56 57 if (escape == NULL) 58 escape = "\\"; 59 60 while ((*s != '\0') && (len > 0)) { 61 if (strchr(escape, *s) != NULL) 62 len--, *t++ = '\\'; 63 len--, *t++ = *s++; 64 } 65 *t = '\0'; 66 67 return (d); 68 } 69 70 71 72 char * 73 _cvt_printer_to_entry(ns_printer_t *printer, char *buf, int buflen) 74 { 75 int i, len; 76 int bufferok = 1; 77 78 (void) memset(buf, 0, buflen); 79 80 if ((printer == NULL) || (printer->attributes == NULL)) 81 return (NULL); 82 83 if (snprintf(buf, buflen, "%s", printer->name) >= buflen) { 84 (void) memset(buf, 0, buflen); 85 syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow"); 86 return (NULL); 87 } 88 89 if ((printer->aliases != NULL) && (printer->aliases[0] != NULL)) { 90 char **alias = printer->aliases; 91 92 while (*alias != NULL) { 93 (void) strlcat(buf, "|", buflen); 94 (void) strncat_escaped(buf, *alias++, buflen, 95 ESCAPE_CHARS); 96 } 97 } 98 99 if (strlcat(buf, ":", buflen) >= buflen) { 100 (void) memset(buf, 0, buflen); 101 syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow"); 102 return (NULL); 103 } 104 105 len = strlen(buf); 106 107 for (i = 0; printer->attributes[i] != NULL && bufferok; i++) { 108 ns_kvp_t *kvp = printer->attributes[i]; 109 110 if (kvp->value == NULL) 111 continue; 112 (void) strlcat(buf, "\\\n\t:", buflen); 113 (void) strncat_escaped(buf, kvp->key, buflen, ESCAPE_CHARS); 114 (void) strlcat(buf, "=", buflen); 115 (void) strncat_escaped(buf, kvp->value, buflen, ESCAPE_CHARS); 116 if (strlcat(buf, ":", buflen) >= buflen) { 117 bufferok = 0; 118 } 119 } 120 121 if (!bufferok) { 122 (void) memset(buf, 0, buflen); 123 syslog(LOG_ERR, "_cvt_printer_to_entry: buffer overflow"); 124 return (NULL); 125 } 126 127 if (strlen(buf) == len) { /* there were no attributes */ 128 (void) memset(buf, 0, buflen); 129 buf = NULL; 130 } 131 132 return (buf); 133 } 134 135 136 ns_printer_t * 137 _cvt_nss_entry_to_printer(char *entry, char *ns) 138 { 139 char *name = NULL, *key = NULL, **aliases = NULL, *cp, buf[BUFSIZ]; 140 int in_namelist = 1, buf_pos = 0; 141 ns_printer_t *printer = NULL; 142 143 if (entry == NULL) 144 return (NULL); 145 146 (void) memset(buf, 0, sizeof (buf)); 147 for (cp = entry; *cp != '\0'; cp++) { 148 switch (*cp) { 149 case ':': /* end of kvp */ 150 if (in_namelist != 0) { 151 if (name == NULL) 152 name = strdup(buf); 153 else 154 aliases = (char **)list_append( 155 (void **)aliases, 156 (void *)strdup(buf)); 157 printer = (ns_printer_t *)ns_printer_create( 158 name, aliases, ns, NULL); 159 in_namelist = 0; 160 } else if (key != NULL) { 161 (void) ns_set_value_from_string(key, buf, 162 printer); 163 } 164 (void) memset(buf, 0, sizeof (buf)); 165 buf_pos = 0; 166 key = NULL; 167 break; 168 case '=': /* kvp seperator */ 169 if (key == NULL) { 170 key = strdup(buf); 171 (void) memset(buf, 0, sizeof (buf)); 172 buf_pos = 0; 173 } else { 174 buf[buf_pos++] = *cp; 175 } 176 break; 177 case '|': /* namelist seperator */ 178 if (in_namelist != 0) { 179 if (name == NULL) 180 name = strdup(buf); 181 else 182 aliases = (char **)list_append( 183 (void **)aliases, 184 (void *)strdup(buf)); 185 (void) memset(buf, 0, sizeof (buf)); 186 buf_pos = 0; 187 } else { 188 /* add it to the buffer */ 189 buf[buf_pos++] = *cp; 190 } 191 break; 192 case '\\': /* escape char */ 193 buf[buf_pos++] = *(++cp); 194 break; 195 default: 196 buf[buf_pos++] = *cp; 197 } 198 199 } 200 201 if (key != NULL) 202 (void) ns_set_value_from_string(key, buf, printer); 203 204 return (printer); 205 } 206