129ade362SMatthew N. Dodd /* 229ade362SMatthew N. Dodd * $FreeBSD$ 329ade362SMatthew N. Dodd */ 429ade362SMatthew N. Dodd 529ade362SMatthew N. Dodd #include <stdio.h> 629ade362SMatthew N. Dodd #include <ctype.h> 729ade362SMatthew N. Dodd #include <string.h> 829ade362SMatthew N. Dodd #include <stdlib.h> 929ade362SMatthew N. Dodd #include <sys/queue.h> 1029ade362SMatthew N. Dodd #include <sys/param.h> 1129ade362SMatthew N. Dodd 1229ade362SMatthew N. Dodd #ifndef _PATH_LIBMAP_CONF 1329ade362SMatthew N. Dodd #define _PATH_LIBMAP_CONF "/etc/libmap.conf" 1429ade362SMatthew N. Dodd #endif 1529ade362SMatthew N. Dodd 1629ade362SMatthew N. Dodd TAILQ_HEAD(lm_list, lm); 1729ade362SMatthew N. Dodd struct lm { 1829ade362SMatthew N. Dodd char *f; 1929ade362SMatthew N. Dodd char *t; 2029ade362SMatthew N. Dodd 2129ade362SMatthew N. Dodd TAILQ_ENTRY(lm) lm_link; 2229ade362SMatthew N. Dodd }; 2329ade362SMatthew N. Dodd 2429ade362SMatthew N. Dodd TAILQ_HEAD(lmp_list, lmp) lmp_head = TAILQ_HEAD_INITIALIZER(lmp_head); 2529ade362SMatthew N. Dodd struct lmp { 2629ade362SMatthew N. Dodd char *p; 2729ade362SMatthew N. Dodd struct lm_list lml; 2829ade362SMatthew N. Dodd TAILQ_ENTRY(lmp) lmp_link; 2929ade362SMatthew N. Dodd }; 3029ade362SMatthew N. Dodd 3129ade362SMatthew N. Dodd static void lm_add (char *, char *, char *); 3229ade362SMatthew N. Dodd static void lm_free (struct lm_list *); 3329ade362SMatthew N. Dodd static char * lml_find (struct lm_list *, const char *); 3429ade362SMatthew N. Dodd static struct lm_list * lmp_find (const char *); 3529ade362SMatthew N. Dodd static struct lm_list * lmp_init (char *); 3629ade362SMatthew N. Dodd 37*623b6bd2SMatthew N. Dodd #define iseol(c) (((c) == '#') || ((c) == '\0') || \ 38*623b6bd2SMatthew N. Dodd ((c) == '\n') || ((c) == '\r')) 39*623b6bd2SMatthew N. Dodd 4029ade362SMatthew N. Dodd void 4129ade362SMatthew N. Dodd lm_init (void) 4229ade362SMatthew N. Dodd { 4329ade362SMatthew N. Dodd FILE *fp; 4429ade362SMatthew N. Dodd char *cp; 4529ade362SMatthew N. Dodd char *f, *t, *p; 4629ade362SMatthew N. Dodd char prog[MAXPATHLEN]; 4729ade362SMatthew N. Dodd char line[MAXPATHLEN + 2]; 4829ade362SMatthew N. Dodd 4929ade362SMatthew N. Dodd TAILQ_INIT(&lmp_head); 5029ade362SMatthew N. Dodd 5129ade362SMatthew N. Dodd if ((fp = fopen(_PATH_LIBMAP_CONF, "r")) == NULL) 5229ade362SMatthew N. Dodd return; 5329ade362SMatthew N. Dodd 5429ade362SMatthew N. Dodd p = NULL; 5529ade362SMatthew N. Dodd while ((cp = fgets(line, MAXPATHLEN + 1, fp)) != NULL) { 5629ade362SMatthew N. Dodd t = f = NULL; 57*623b6bd2SMatthew N. Dodd 5829ade362SMatthew N. Dodd /* Skip over leading space */ 59*623b6bd2SMatthew N. Dodd while (isspace(*cp)) cp++; 60*623b6bd2SMatthew N. Dodd 6129ade362SMatthew N. Dodd /* Found a comment or EOL */ 62*623b6bd2SMatthew N. Dodd if (iseol(*cp)) goto next; 63*623b6bd2SMatthew N. Dodd 64*623b6bd2SMatthew N. Dodd /* Found a constraint selector */ 6529ade362SMatthew N. Dodd if (*cp == '[') { 6629ade362SMatthew N. Dodd cp++; 67*623b6bd2SMatthew N. Dodd 6829ade362SMatthew N. Dodd /* Skip leading space */ 69*623b6bd2SMatthew N. Dodd while (isspace(*cp)) cp++; 70*623b6bd2SMatthew N. Dodd 7129ade362SMatthew N. Dodd /* Found comment, EOL or end of selector */ 72*623b6bd2SMatthew N. Dodd if (iseol(*cp) || *cp == ']') goto next; 73*623b6bd2SMatthew N. Dodd 7429ade362SMatthew N. Dodd p = cp; 7529ade362SMatthew N. Dodd /* Skip to end of word */ 76*623b6bd2SMatthew N. Dodd while (!isspace(*cp) && !iseol(*cp) && *cp != ']') cp++; 77*623b6bd2SMatthew N. Dodd 78*623b6bd2SMatthew N. Dodd /* Skip and zero out trailing space */ 79*623b6bd2SMatthew N. Dodd while (isspace(*cp)) *cp++ = '\0'; 80*623b6bd2SMatthew N. Dodd 81*623b6bd2SMatthew N. Dodd /* Check if there is a closing brace */ 82*623b6bd2SMatthew N. Dodd if (*cp != ']') goto next; 83*623b6bd2SMatthew N. Dodd 84*623b6bd2SMatthew N. Dodd /* Terminate string if there was no trailing space */ 8529ade362SMatthew N. Dodd *cp++ = '\0'; 86*623b6bd2SMatthew N. Dodd 87*623b6bd2SMatthew N. Dodd /* 88*623b6bd2SMatthew N. Dodd * There should be nothing except whitespace or comment 89*623b6bd2SMatthew N. Dodd * from this point to the end of the line. 90*623b6bd2SMatthew N. Dodd */ 91*623b6bd2SMatthew N. Dodd while(isspace(*cp++)); 92*623b6bd2SMatthew N. Dodd if (*cp != '\0' && *cp != '#') goto next; 93*623b6bd2SMatthew N. Dodd 94*623b6bd2SMatthew N. Dodd if (strlen(p) > 0) { 9529ade362SMatthew N. Dodd bzero(prog, MAXPATHLEN); 9629ade362SMatthew N. Dodd strncpy(prog, p, strlen(p)); 9729ade362SMatthew N. Dodd p = prog; 9829ade362SMatthew N. Dodd } 99*623b6bd2SMatthew N. Dodd goto next; 100*623b6bd2SMatthew N. Dodd } 101*623b6bd2SMatthew N. Dodd 102*623b6bd2SMatthew N. Dodd /* Parse the 'from' candidate. */ 10329ade362SMatthew N. Dodd f = cp; 104*623b6bd2SMatthew N. Dodd while (!isspace(*cp) && !iseol(*cp)) cp++; 10529ade362SMatthew N. Dodd *cp++ = '\0'; 10629ade362SMatthew N. Dodd 107*623b6bd2SMatthew N. Dodd /* Skip and zero out the trailing whitespace */ 108*623b6bd2SMatthew N. Dodd while (isspace(*cp)) *cp++ = '\0'; 109*623b6bd2SMatthew N. Dodd 110*623b6bd2SMatthew N. Dodd /* Found a comment or EOL */ 111*623b6bd2SMatthew N. Dodd if (iseol(*cp)) goto next; 112*623b6bd2SMatthew N. Dodd 113*623b6bd2SMatthew N. Dodd /* Parse 'to' mapping */ 114*623b6bd2SMatthew N. Dodd t = cp; 115*623b6bd2SMatthew N. Dodd while (!isspace(*cp) && !iseol(*cp)) cp++; 116*623b6bd2SMatthew N. Dodd *cp++ = '\0'; 117*623b6bd2SMatthew N. Dodd 118*623b6bd2SMatthew N. Dodd if ((strlen(f) > 0) && (strlen(t) > 0)) 11929ade362SMatthew N. Dodd lm_add(p, strdup(f), strdup(t)); 120*623b6bd2SMatthew N. Dodd next: 12129ade362SMatthew N. Dodd bzero(line, sizeof(line)); 12229ade362SMatthew N. Dodd } 12329ade362SMatthew N. Dodd (void)fclose(fp); 12429ade362SMatthew N. Dodd return; 12529ade362SMatthew N. Dodd } 12629ade362SMatthew N. Dodd 12729ade362SMatthew N. Dodd static void 12829ade362SMatthew N. Dodd lm_free (struct lm_list *lml) 12929ade362SMatthew N. Dodd { 13029ade362SMatthew N. Dodd struct lm *lm; 13129ade362SMatthew N. Dodd 13229ade362SMatthew N. Dodd while (!TAILQ_EMPTY(lml)) { 13329ade362SMatthew N. Dodd lm = TAILQ_FIRST(lml); 13429ade362SMatthew N. Dodd TAILQ_REMOVE(lml, lm, lm_link); 13529ade362SMatthew N. Dodd free(lm->f); 13629ade362SMatthew N. Dodd free(lm->t); 13729ade362SMatthew N. Dodd free(lm); 13829ade362SMatthew N. Dodd } 13929ade362SMatthew N. Dodd return; 14029ade362SMatthew N. Dodd } 14129ade362SMatthew N. Dodd 14229ade362SMatthew N. Dodd void 14329ade362SMatthew N. Dodd lm_fini (void) 14429ade362SMatthew N. Dodd { 14529ade362SMatthew N. Dodd struct lmp *lmp; 14629ade362SMatthew N. Dodd 14729ade362SMatthew N. Dodd while (!TAILQ_EMPTY(&lmp_head)) { 14829ade362SMatthew N. Dodd lmp = TAILQ_FIRST(&lmp_head); 14929ade362SMatthew N. Dodd TAILQ_REMOVE(&lmp_head, lmp, lmp_link); 15029ade362SMatthew N. Dodd free(lmp->p); 15129ade362SMatthew N. Dodd lm_free(&lmp->lml); 15229ade362SMatthew N. Dodd free(lmp); 15329ade362SMatthew N. Dodd } 15429ade362SMatthew N. Dodd return; 15529ade362SMatthew N. Dodd } 15629ade362SMatthew N. Dodd 15729ade362SMatthew N. Dodd static void 15829ade362SMatthew N. Dodd lm_add (char *p, char *f, char *t) 15929ade362SMatthew N. Dodd { 16029ade362SMatthew N. Dodd struct lm_list *lml; 16129ade362SMatthew N. Dodd struct lm *lm; 16229ade362SMatthew N. Dodd 16329ade362SMatthew N. Dodd if (p == NULL) 16429ade362SMatthew N. Dodd p = "$DEFAULT$"; 16529ade362SMatthew N. Dodd 16629ade362SMatthew N. Dodd #if 0 16729ade362SMatthew N. Dodd printf("%s(\"%s\", \"%s\", \"%s\")\n", __func__, p, f, t); 16829ade362SMatthew N. Dodd #endif 16929ade362SMatthew N. Dodd 17029ade362SMatthew N. Dodd if ((lml = lmp_find(p)) == NULL) 17129ade362SMatthew N. Dodd lml = lmp_init(strdup(p)); 17229ade362SMatthew N. Dodd 17329ade362SMatthew N. Dodd lm = malloc(sizeof(struct lm)); 17429ade362SMatthew N. Dodd lm->f = f; 17529ade362SMatthew N. Dodd lm->t = t; 17629ade362SMatthew N. Dodd TAILQ_INSERT_HEAD(lml, lm, lm_link); 17729ade362SMatthew N. Dodd } 17829ade362SMatthew N. Dodd 17929ade362SMatthew N. Dodd char * 18029ade362SMatthew N. Dodd lm_find (const char *p, const char *f) 18129ade362SMatthew N. Dodd { 18229ade362SMatthew N. Dodd struct lm_list *lml; 18329ade362SMatthew N. Dodd char *t; 18429ade362SMatthew N. Dodd 18529ade362SMatthew N. Dodd if (p != NULL && (lml = lmp_find(p)) != NULL) { 18629ade362SMatthew N. Dodd t = lml_find(lml, f); 18729ade362SMatthew N. Dodd if (t != NULL) 18829ade362SMatthew N. Dodd return (t); 18929ade362SMatthew N. Dodd } 19029ade362SMatthew N. Dodd lml = lmp_find("$DEFAULT$"); 19129ade362SMatthew N. Dodd if (lml != NULL) 19229ade362SMatthew N. Dodd return (lml_find(lml, f)); 19329ade362SMatthew N. Dodd else 19429ade362SMatthew N. Dodd return (NULL); 19529ade362SMatthew N. Dodd } 19629ade362SMatthew N. Dodd 19729ade362SMatthew N. Dodd static char * 19829ade362SMatthew N. Dodd lml_find (struct lm_list *lmh, const char *f) 19929ade362SMatthew N. Dodd { 20029ade362SMatthew N. Dodd struct lm *lm; 20129ade362SMatthew N. Dodd 20229ade362SMatthew N. Dodd TAILQ_FOREACH(lm, lmh, lm_link) 20329ade362SMatthew N. Dodd if ((strncmp(f, lm->f, strlen(lm->f)) == 0) && 20429ade362SMatthew N. Dodd (strlen(f) == strlen(lm->f))) 20529ade362SMatthew N. Dodd return (lm->t); 20629ade362SMatthew N. Dodd return NULL; 20729ade362SMatthew N. Dodd } 20829ade362SMatthew N. Dodd 20929ade362SMatthew N. Dodd static struct lm_list * 21029ade362SMatthew N. Dodd lmp_find (const char *n) 21129ade362SMatthew N. Dodd { 21229ade362SMatthew N. Dodd struct lmp *lmp; 21329ade362SMatthew N. Dodd 21429ade362SMatthew N. Dodd TAILQ_FOREACH(lmp, &lmp_head, lmp_link) 21529ade362SMatthew N. Dodd if ((strncmp(n, lmp->p, strlen(lmp->p)) == 0) && 21629ade362SMatthew N. Dodd (strlen(n) == strlen(lmp->p))) 21729ade362SMatthew N. Dodd return (&lmp->lml); 21829ade362SMatthew N. Dodd return (NULL); 21929ade362SMatthew N. Dodd } 22029ade362SMatthew N. Dodd 22129ade362SMatthew N. Dodd static struct lm_list * 22229ade362SMatthew N. Dodd lmp_init (char *n) 22329ade362SMatthew N. Dodd { 22429ade362SMatthew N. Dodd struct lmp *lmp; 22529ade362SMatthew N. Dodd 22629ade362SMatthew N. Dodd lmp = malloc(sizeof(struct lmp)); 22729ade362SMatthew N. Dodd lmp->p = n; 22829ade362SMatthew N. Dodd TAILQ_INIT(&lmp->lml); 22929ade362SMatthew N. Dodd TAILQ_INSERT_HEAD(&lmp_head, lmp, lmp_link); 23029ade362SMatthew N. Dodd 23129ade362SMatthew N. Dodd return (&lmp->lml); 23229ade362SMatthew N. Dodd } 233