Deleted Added
full compact
libmap.c (116513) libmap.c (120038)
1/*
1/*
2 * $FreeBSD: head/libexec/rtld-elf/libmap.c 116513 2003-06-18 05:31:08Z mdodd $
2 * $FreeBSD: head/libexec/rtld-elf/libmap.c 120038 2003-09-13 21:43:08Z mdodd $
3 */
4
5#include <stdio.h>
6#include <ctype.h>
7#include <string.h>
8#include <stdlib.h>
9#include <sys/queue.h>
10#include <sys/param.h>
11
12#include "debug.h"
13#include "rtld.h"
14#include "libmap.h"
15
16#ifndef _PATH_LIBMAP_CONF
17#define _PATH_LIBMAP_CONF "/etc/libmap.conf"
18#endif
19
20TAILQ_HEAD(lm_list, lm);
21struct lm {
22 char *f;
23 char *t;
24
25 TAILQ_ENTRY(lm) lm_link;
26};
27
28TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head);
29struct lmp {
30 char *p;
31 struct lm_list lml;
32 TAILQ_ENTRY(lmp) lmp_link;
33};
34
35static void lm_add (const char *, const char *, const char *);
36static void lm_free (struct lm_list *);
37static char * lml_find (struct lm_list *, const char *);
38static struct lm_list * lmp_find (const char *);
39static struct lm_list * lmp_init (char *);
40
41#define iseol(c) (((c) == '#') || ((c) == '\0') || \
42 ((c) == '\n') || ((c) == '\r'))
43
3 */
4
5#include <stdio.h>
6#include <ctype.h>
7#include <string.h>
8#include <stdlib.h>
9#include <sys/queue.h>
10#include <sys/param.h>
11
12#include "debug.h"
13#include "rtld.h"
14#include "libmap.h"
15
16#ifndef _PATH_LIBMAP_CONF
17#define _PATH_LIBMAP_CONF "/etc/libmap.conf"
18#endif
19
20TAILQ_HEAD(lm_list, lm);
21struct lm {
22 char *f;
23 char *t;
24
25 TAILQ_ENTRY(lm) lm_link;
26};
27
28TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head);
29struct lmp {
30 char *p;
31 struct lm_list lml;
32 TAILQ_ENTRY(lmp) lmp_link;
33};
34
35static void lm_add (const char *, const char *, const char *);
36static void lm_free (struct lm_list *);
37static char * lml_find (struct lm_list *, const char *);
38static struct lm_list * lmp_find (const char *);
39static struct lm_list * lmp_init (char *);
40
41#define iseol(c) (((c) == '#') || ((c) == '\0') || \
42 ((c) == '\n') || ((c) == '\r'))
43
44void
44int
45lm_init (void)
46{
47 FILE *fp;
48 char *cp;
49 char *f, *t, *p, *c;
50 char prog[MAXPATHLEN];
51 char line[MAXPATHLEN + 2];
52
53 dbg("%s()", __func__);
54
55 TAILQ_INIT(&lmp_head);
56
57 if ((fp = fopen(_PATH_LIBMAP_CONF, "r")) == NULL)
45lm_init (void)
46{
47 FILE *fp;
48 char *cp;
49 char *f, *t, *p, *c;
50 char prog[MAXPATHLEN];
51 char line[MAXPATHLEN + 2];
52
53 dbg("%s()", __func__);
54
55 TAILQ_INIT(&lmp_head);
56
57 if ((fp = fopen(_PATH_LIBMAP_CONF, "r")) == NULL)
58 return;
58 return (1);
59
60 p = NULL;
61 while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) {
62 t = f = c = NULL;
63
64 /* Skip over leading space */
65 while (isspace(*cp)) cp++;
66
67 /* Found a comment or EOL */
68 if (iseol(*cp)) continue;
69
70 /* Found a constraint selector */
71 if (*cp == '[') {
72 cp++;
73
74 /* Skip leading space */
75 while (isspace(*cp)) cp++;
76
77 /* Found comment, EOL or end of selector */
78 if (iseol(*cp) || *cp == ']')
79 continue;
80
81 c = cp++;
82 /* Skip to end of word */
83 while (!isspace(*cp) && !iseol(*cp) && *cp != ']')
84 cp++;
85
86 /* Skip and zero out trailing space */
87 while (isspace(*cp)) *cp++ = '\0';
88
89 /* Check if there is a closing brace */
90 if (*cp != ']') continue;
91
92 /* Terminate string if there was no trailing space */
93 *cp++ = '\0';
94
95 /*
96 * There should be nothing except whitespace or comment
97 from this point to the end of the line.
98 */
99 while(isspace(*cp)) *cp++;
100 if (!iseol(*cp)) continue;
101
102 strcpy(prog, c);
103 p = prog;
104 continue;
105 }
106
107 /* Parse the 'from' candidate. */
108 f = cp++;
109 while (!isspace(*cp) && !iseol(*cp)) cp++;
110
111 /* Skip and zero out the trailing whitespace */
112 while (isspace(*cp)) *cp++ = '\0';
113
114 /* Found a comment or EOL */
115 if (iseol(*cp)) continue;
116
117 /* Parse 'to' mapping */
118 t = cp++;
119 while (!isspace(*cp) && !iseol(*cp)) cp++;
120
121 /* Skip and zero out the trailing whitespace */
122 while (isspace(*cp)) *cp++ = '\0';
123
124 /* Should be no extra tokens at this point */
125 if (!iseol(*cp)) continue;
126
127 *cp = '\0';
128 lm_add(p, f, t);
129 }
130 fclose(fp);
59
60 p = NULL;
61 while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) {
62 t = f = c = NULL;
63
64 /* Skip over leading space */
65 while (isspace(*cp)) cp++;
66
67 /* Found a comment or EOL */
68 if (iseol(*cp)) continue;
69
70 /* Found a constraint selector */
71 if (*cp == '[') {
72 cp++;
73
74 /* Skip leading space */
75 while (isspace(*cp)) cp++;
76
77 /* Found comment, EOL or end of selector */
78 if (iseol(*cp) || *cp == ']')
79 continue;
80
81 c = cp++;
82 /* Skip to end of word */
83 while (!isspace(*cp) && !iseol(*cp) && *cp != ']')
84 cp++;
85
86 /* Skip and zero out trailing space */
87 while (isspace(*cp)) *cp++ = '\0';
88
89 /* Check if there is a closing brace */
90 if (*cp != ']') continue;
91
92 /* Terminate string if there was no trailing space */
93 *cp++ = '\0';
94
95 /*
96 * There should be nothing except whitespace or comment
97 from this point to the end of the line.
98 */
99 while(isspace(*cp)) *cp++;
100 if (!iseol(*cp)) continue;
101
102 strcpy(prog, c);
103 p = prog;
104 continue;
105 }
106
107 /* Parse the 'from' candidate. */
108 f = cp++;
109 while (!isspace(*cp) && !iseol(*cp)) cp++;
110
111 /* Skip and zero out the trailing whitespace */
112 while (isspace(*cp)) *cp++ = '\0';
113
114 /* Found a comment or EOL */
115 if (iseol(*cp)) continue;
116
117 /* Parse 'to' mapping */
118 t = cp++;
119 while (!isspace(*cp) && !iseol(*cp)) cp++;
120
121 /* Skip and zero out the trailing whitespace */
122 while (isspace(*cp)) *cp++ = '\0';
123
124 /* Should be no extra tokens at this point */
125 if (!iseol(*cp)) continue;
126
127 *cp = '\0';
128 lm_add(p, f, t);
129 }
130 fclose(fp);
131 return;
131 return (0);
132}
133
134static void
135lm_free (struct lm_list *lml)
136{
137 struct lm *lm;
138
139 dbg("%s(%p)", __func__, lml);
140
141 while (!TAILQ_EMPTY(lml)) {
142 lm = TAILQ_FIRST(lml);
143 TAILQ_REMOVE(lml, lm, lm_link);
144 free(lm->f);
145 free(lm->t);
146 free(lm);
147 }
148 return;
149}
150
151void
152lm_fini (void)
153{
154 struct lmp *lmp;
155
156 dbg("%s()", __func__);
157
158 while (!TAILQ_EMPTY(&lmp_head)) {
159 lmp = TAILQ_FIRST(&lmp_head);
160 TAILQ_REMOVE(&lmp_head, lmp, lmp_link);
161 free(lmp->p);
162 lm_free(&lmp->lml);
163 free(lmp);
164 }
165 return;
166}
167
168static void
169lm_add (const char *p, const char *f, const char *t)
170{
171 struct lm_list *lml;
172 struct lm *lm;
173
174 if (p == NULL)
175 p = "$DEFAULT$";
176
177 dbg("%s(\"%s\", \"%s\", \"%s\")", __func__, p, f, t);
178
179 if ((lml = lmp_find(p)) == NULL)
180 lml = lmp_init(xstrdup(p));
181
182 lm = xmalloc(sizeof(struct lm));
183 lm->f = xstrdup(f);
184 lm->t = xstrdup(t);
185 TAILQ_INSERT_HEAD(lml, lm, lm_link);
186}
187
188char *
189lm_find (const char *p, const char *f)
190{
191 struct lm_list *lml;
192 char *t;
193
194 dbg("%s(\"%s\", \"%s\")", __func__, p, f);
195
196 if (p != NULL && (lml = lmp_find(p)) != NULL) {
197 t = lml_find(lml, f);
198 if (t != NULL) {
199 /*
200 * Add a global mapping if we have
201 * a successful constrained match.
202 */
203 lm_add(NULL, f, t);
204 return (t);
205 }
206 }
207 lml = lmp_find("$DEFAULT$");
208 if (lml != NULL)
209 return (lml_find(lml, f));
210 else
211 return (NULL);
212}
213
214static char *
215lml_find (struct lm_list *lmh, const char *f)
216{
217 struct lm *lm;
218
219 dbg("%s(%p, \"%s\")", __func__, lmh, f);
220
221 TAILQ_FOREACH(lm, lmh, lm_link)
222 if ((strncmp(f, lm->f, strlen(lm->f)) == 0) &&
223 (strlen(f) == strlen(lm->f)))
224 return (lm->t);
225 return NULL;
226}
227
228static struct lm_list *
229lmp_find (const char *n)
230{
231 struct lmp *lmp;
232
233 dbg("%s(\"%s\")", __func__, n);
234
235 TAILQ_FOREACH(lmp, &lmp_head, lmp_link)
236 if ((strncmp(n, lmp->p, strlen(lmp->p)) == 0) &&
237 (strlen(n) == strlen(lmp->p)))
238 return (&lmp->lml);
239 return (NULL);
240}
241
242static struct lm_list *
243lmp_init (char *n)
244{
245 struct lmp *lmp;
246
247 dbg("%s(\"%s\")", __func__, n);
248
249 lmp = xmalloc(sizeof(struct lmp));
250 lmp->p = n;
251 TAILQ_INIT(&lmp->lml);
252 TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link);
253
254 return (&lmp->lml);
255}
132}
133
134static void
135lm_free (struct lm_list *lml)
136{
137 struct lm *lm;
138
139 dbg("%s(%p)", __func__, lml);
140
141 while (!TAILQ_EMPTY(lml)) {
142 lm = TAILQ_FIRST(lml);
143 TAILQ_REMOVE(lml, lm, lm_link);
144 free(lm->f);
145 free(lm->t);
146 free(lm);
147 }
148 return;
149}
150
151void
152lm_fini (void)
153{
154 struct lmp *lmp;
155
156 dbg("%s()", __func__);
157
158 while (!TAILQ_EMPTY(&lmp_head)) {
159 lmp = TAILQ_FIRST(&lmp_head);
160 TAILQ_REMOVE(&lmp_head, lmp, lmp_link);
161 free(lmp->p);
162 lm_free(&lmp->lml);
163 free(lmp);
164 }
165 return;
166}
167
168static void
169lm_add (const char *p, const char *f, const char *t)
170{
171 struct lm_list *lml;
172 struct lm *lm;
173
174 if (p == NULL)
175 p = "$DEFAULT$";
176
177 dbg("%s(\"%s\", \"%s\", \"%s\")", __func__, p, f, t);
178
179 if ((lml = lmp_find(p)) == NULL)
180 lml = lmp_init(xstrdup(p));
181
182 lm = xmalloc(sizeof(struct lm));
183 lm->f = xstrdup(f);
184 lm->t = xstrdup(t);
185 TAILQ_INSERT_HEAD(lml, lm, lm_link);
186}
187
188char *
189lm_find (const char *p, const char *f)
190{
191 struct lm_list *lml;
192 char *t;
193
194 dbg("%s(\"%s\", \"%s\")", __func__, p, f);
195
196 if (p != NULL && (lml = lmp_find(p)) != NULL) {
197 t = lml_find(lml, f);
198 if (t != NULL) {
199 /*
200 * Add a global mapping if we have
201 * a successful constrained match.
202 */
203 lm_add(NULL, f, t);
204 return (t);
205 }
206 }
207 lml = lmp_find("$DEFAULT$");
208 if (lml != NULL)
209 return (lml_find(lml, f));
210 else
211 return (NULL);
212}
213
214static char *
215lml_find (struct lm_list *lmh, const char *f)
216{
217 struct lm *lm;
218
219 dbg("%s(%p, \"%s\")", __func__, lmh, f);
220
221 TAILQ_FOREACH(lm, lmh, lm_link)
222 if ((strncmp(f, lm->f, strlen(lm->f)) == 0) &&
223 (strlen(f) == strlen(lm->f)))
224 return (lm->t);
225 return NULL;
226}
227
228static struct lm_list *
229lmp_find (const char *n)
230{
231 struct lmp *lmp;
232
233 dbg("%s(\"%s\")", __func__, n);
234
235 TAILQ_FOREACH(lmp, &lmp_head, lmp_link)
236 if ((strncmp(n, lmp->p, strlen(lmp->p)) == 0) &&
237 (strlen(n) == strlen(lmp->p)))
238 return (&lmp->lml);
239 return (NULL);
240}
241
242static struct lm_list *
243lmp_init (char *n)
244{
245 struct lmp *lmp;
246
247 dbg("%s(\"%s\")", __func__, n);
248
249 lmp = xmalloc(sizeof(struct lmp));
250 lmp->p = n;
251 TAILQ_INIT(&lmp->lml);
252 TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link);
253
254 return (&lmp->lml);
255}