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 2007 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 #include <stdio.h> 29 #include <fcntl.h> 30 #include <strings.h> 31 #include <ctype.h> 32 #include <stdlib.h> 33 34 #include "list.h" 35 #include "proto_list.h" 36 37 #define FS " \t\n" 38 39 static void 40 error(const char *msg, int lc) 41 { 42 (void) fprintf(stderr, "warning: line %d - %s\n", lc, msg); 43 } 44 45 /* 46 * int is_num() 47 * 48 * returns 1 if the string is entirely numeric - if not it returns 0 49 * 50 */ 51 static int 52 is_num(const char *str) 53 { 54 int i; 55 int len = strlen(str); 56 57 if (len < 1) 58 return (0); 59 60 for (i = 0; i < len; i++) 61 if (!isdigit(str[i])) 62 return (0); 63 return (1); 64 } 65 66 /* 67 * void check_line() 68 * 69 * try and do some sanity/syntax checking against the line just 70 * read in - print warning messages as errors are encountered. 71 * 72 * these are simple checks, but then they catch the simple errors-:) 73 * 74 */ 75 static void 76 check_line(char *v[], int lc) 77 { 78 if ((!v[NAME]) || ((int)strlen(v[NAME]) < 1)) 79 error("bad name", lc); 80 81 if ((!v[SRC]) || ((int)strlen(v[SRC])) < 1) 82 error("bad source/symbolic line", lc); 83 84 if ((!v[PERM]) || ((int)strlen(v[PERM]) < 3) || (!is_num(v[PERM]))) 85 error("bad permissions", lc); 86 87 if ((!v[OWNR]) || ((int)strlen(v[OWNR]) < 2)) 88 error("bad owner", lc); 89 90 if ((!v[GRP]) || ((int)strlen(v[GRP]) < 2)) 91 error("bad group", lc); 92 93 if ((!v[INO]) || (!is_num(v[INO]))) 94 error("bad i-node", lc); 95 96 if ((!v[LCNT]) || (!is_num(v[LCNT]))) 97 error("bad link-count", lc); 98 99 if ((!v[CODE]) || ((*v[CODE] != 'f') && (*v[CODE] != 'c') && 100 (*v[CODE] != 'd') && (*v[CODE] != 'b') && 101 (*v[CODE] != 'v') && (*v[CODE] != 'e') && 102 (*v[CODE] != 's')) || ((int)strlen(v[CODE]) > 1)) 103 error("bad type", lc); 104 105 if ((!v[MAJOR]) || ((!is_num(v[MAJOR])) && (*v[MAJOR] != '-'))) 106 error("bad major number", lc); 107 108 if ((!v[MINOR]) || ((!is_num(v[MINOR])) && (*v[MINOR] != '-'))) 109 error("bad minor number", lc); 110 } 111 112 static char ** 113 get_line(FILE *fp, char *v[]) 114 { 115 char *rc; 116 char *p; 117 int len; 118 int cont = 1; 119 static char buf[BUFSIZ]; 120 static int line_count = 0; 121 122 p = buf; 123 p[0] = '\0'; 124 125 do { 126 rc = fgets(p, BUFSIZ, fp); 127 line_count ++; 128 /* 129 * check for continuation marks at the end of the 130 * line - if it exists then append the next line at the 131 * end of this one. 132 */ 133 if (buf[0] == '#') { 134 /* 135 * skip comments. 136 */ 137 continue; 138 } else if ((rc != NULL) && ((len = strlen(p)) > 1) && 139 (p[len - 2] == '\\')) { 140 /* 141 * check for continuation marks at the end of the 142 * line - if it exists then append the next line at the 143 * end of this one. 144 */ 145 p += len - 2; 146 } else 147 cont = 0; 148 } while (cont); 149 150 if (rc == NULL) 151 return (NULL); 152 153 /* 154 * breakup the line into the various fields. 155 */ 156 v[PROTOS] = index(buf, ';'); 157 if (v[PROTOS]) 158 *v[PROTOS]++ = '\0'; 159 v[0] = strtok(buf, FS); 160 for (cont = 1; cont < FIELDS - 1; cont++) 161 v[cont] = strtok(NULL, FS); 162 163 check_line(v, line_count); 164 165 return (v); 166 } 167 168 static void 169 parse_line(char **v, elem *e) 170 { 171 e->flag = 0; 172 e->pkgs = NULL; 173 e->arch = P_ISA; 174 (void) strcpy(e->name, v[NAME]); 175 e->perm = strtol(v[PERM], NULL, 8); 176 (void) strcpy(e->owner, v[OWNR]); 177 (void) strcpy(e->group, v[GRP]); 178 e->inode = atoi(v[INO]); 179 e->ref_cnt = atoi(v[LCNT]); 180 e->file_type = *v[CODE]; 181 if ((v[MAJOR][0] == '-') && (v[MAJOR][1] == '\0')) 182 e->major = -1; 183 else 184 e->major = atoi(v[MAJOR]); 185 186 if ((v[MINOR][0] == '-') && (v[MINOR][1] == '\0')) 187 e->minor = -1; 188 else 189 e->minor = atoi(v[MINOR]); 190 191 if ((v[SYM][0] == '-') && (v[SYM][1] == '\0')) 192 e->symsrc = NULL; 193 else { 194 e->symsrc = malloc(strlen(v[SYM]) + 1); 195 (void) strcpy(e->symsrc, v[SYM]); 196 if (e->file_type != SYM_LINK_T) 197 #if defined(__sparc) 198 if (strncmp(e->symsrc, "sun4/", 5) == 0) 199 e->arch = P_SUN4; 200 else if (strncmp(e->symsrc, "sun4c/", 6) == 0) 201 e->arch = P_SUN4c; 202 else if (strncmp(e->symsrc, "sun4u/", 6) == 0) 203 e->arch = P_SUN4u; 204 else if (strncmp(e->symsrc, "sun4d/", 6) == 0) 205 e->arch = P_SUN4d; 206 else if (strncmp(e->symsrc, "sun4e/", 6) == 0) 207 e->arch = P_SUN4e; 208 else if (strncmp(e->symsrc, "sun4m/", 6) == 0) 209 e->arch = P_SUN4m; 210 else if (strncmp(e->symsrc, "sun4v/", 6) == 0) 211 e->arch = P_SUN4v; 212 #elif defined(__i386) 213 if (strncmp(e->symsrc, "i86pc/", 6) == 0) 214 e->arch = P_I86PC; 215 #elif defined(__ppc) 216 if (strncmp(e->symsrc, "prep/", 5) == 0) 217 e->arch = P_PREP; 218 #else 219 #error "Unknown instruction set" 220 #endif 221 else { 222 (void) fprintf(stderr, 223 "warning: Unknown relocation architecture " 224 "for %s\n", e->symsrc); 225 } 226 227 } 228 } 229 230 int 231 read_in_protolist(const char *pname, elem_list *list, int verbose) 232 { 233 FILE *proto_fp; 234 char *line_vec[FIELDS]; 235 int count = 0; 236 static elem *e = NULL; 237 238 list->type = PROTOLIST_LIST; 239 240 if ((proto_fp = fopen(pname, "r")) == NULL) { 241 perror(pname); 242 exit(1); 243 } 244 245 if (verbose) 246 (void) printf("reading in proto_list(%s)...\n", pname); 247 248 count = 0; 249 while (get_line(proto_fp, line_vec)) { 250 if (!e) 251 e = (elem *)calloc(1, sizeof (elem)); 252 253 parse_line(line_vec, e); 254 if (!find_elem(list, e, FOLLOW_LINK)) { 255 add_elem(list, e); 256 e = NULL; 257 count++; 258 } 259 } 260 261 if (verbose) 262 (void) printf("read in %d lines\n", count); 263 264 (void) fclose(proto_fp); 265 266 return (count); 267 } 268