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