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