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