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
error(const char * msg,int lc)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
is_num(const char * str)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
check_line(char * v[],int lc)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 **
get_line(FILE * fp,char * v[])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
parse_line(char ** v,elem * e)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
read_in_protolist(const char * pname,elem_list * list,int verbose)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