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