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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include "synonyms.h" 30 #include <ctype.h> 31 #include <stdio.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <nss_dbdefs.h> 35 #include <limits.h> 36 37 /* 38 * ALIGN? is there an official definition of this? 39 * We use sizeof(long) to cover what we want 40 * for both the 32-bit world and 64-bit world. 41 */ 42 43 #define ALIGN(x) ((((long)(x)) + sizeof (long) - 1) & ~(sizeof (long) - 1)) 44 45 nss_XbyY_buf_t * 46 _nss_XbyY_buf_alloc(int struct_size, int buffer_size) 47 { 48 nss_XbyY_buf_t *b; 49 50 /* Use one malloc for dbargs, result struct and buffer */ 51 b = (nss_XbyY_buf_t *) 52 malloc(ALIGN(sizeof (*b)) + struct_size + buffer_size); 53 if (b == 0) { 54 return (0); 55 } 56 b->result = (void *)ALIGN(&b[1]); 57 b->buffer = (char *)(b->result) + struct_size; 58 b->buflen = buffer_size; 59 return (b); 60 } 61 62 void 63 _nss_XbyY_buf_free(nss_XbyY_buf_t *b) 64 { 65 if (b != 0) { 66 free(b); 67 } 68 } 69 70 /* === Comment: used by fget{gr,pw,sp}ent */ 71 /* ==== Should do ye olde syslog()ing of suspiciously long lines */ 72 73 void 74 _nss_XbyY_fgets(FILE *f, nss_XbyY_args_t *b) 75 { 76 char buf[LINE_MAX]; 77 int len, parsestat; 78 79 if (fgets(buf, LINE_MAX, f) == 0) { 80 /* End of file */ 81 b->returnval = 0; 82 b->erange = 0; 83 return; 84 } 85 len = (int)strlen(buf); 86 /* len >= 0 (otherwise we would have got EOF) */ 87 if (buf[len - 1] != '\n') { 88 if ((len + 1) == LINE_MAX) { 89 /* Line too long for buffer; too bad */ 90 while (fgets(buf, LINE_MAX, f) != 0 && 91 buf[strlen(buf) - 1] != '\n') { 92 ; 93 } 94 b->returnval = 0; 95 b->erange = 1; 96 return; 97 } 98 /* case where the file is not terminated with a Newline */ 99 len++; 100 } 101 parsestat = (*b->str2ent)(buf, (len - 1), b->buf.result, b->buf.buffer, 102 b->buf.buflen); 103 if (parsestat == NSS_STR_PARSE_ERANGE) { 104 b->returnval = 0; 105 b->erange = 1; 106 } else if (parsestat == NSS_STR_PARSE_SUCCESS) { 107 b->returnval = b->buf.result; 108 } 109 } 110 111 /* 112 * parse the aliases string into the buffer and if successful return 113 * a char ** pointer to the beginning of the aliases. 114 * 115 * CAUTION: (instr, instr+lenstr) and (buffer, buffer+buflen) are 116 * non-intersecting memory areas. Since this is an internal interface, 117 * we should be able to live with that. 118 */ 119 char ** 120 _nss_netdb_aliases(const char *instr, int lenstr, char *buffer, int buflen) 121 /* "instr" is the beginning of the aliases string */ 122 /* "buffer" has the return val for success */ 123 /* "buflen" is the length of the buffer available for aliases */ 124 { 125 /* 126 * Build the alias-list in the start of the buffer, and copy 127 * the strings to the end of the buffer. 128 */ 129 const char 130 *instr_limit = instr + lenstr; 131 char *copyptr = buffer + buflen; 132 char **aliasp = (char **)ROUND_UP(buffer, sizeof (*aliasp)); 133 char **alias_start = aliasp; 134 int nstrings = 0; 135 136 for (;;) { 137 const char *str_start; 138 size_t str_len; 139 140 while (instr < instr_limit && isspace(*instr)) { 141 instr++; 142 } 143 if (instr >= instr_limit || *instr == '#') { 144 break; 145 } 146 str_start = instr; 147 while (instr < instr_limit && !isspace(*instr)) { 148 instr++; 149 } 150 151 ++nstrings; 152 153 str_len = instr - str_start; 154 copyptr -= str_len + 1; 155 if (copyptr <= (char *)(&aliasp[nstrings + 1])) { 156 /* Has to be room for the pointer to */ 157 /* the alias we're about to add, */ 158 /* as well as the final NULL ptr. */ 159 return (0); 160 } 161 *aliasp++ = copyptr; 162 (void) memcpy(copyptr, str_start, str_len); 163 copyptr[str_len] = '\0'; 164 } 165 *aliasp++ = 0; 166 return (alias_start); 167 } 168