static int search_ndbm(mnt_map *m, DBM *db, char *key, char **val) { datum k, v; k.dptr = key; k.dsize = strlen(key) + 1; v = dbm_fetch(db, k); if (v.dptr) { if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX)) *val = sun_entry2amd(key, v.dptr); else *val = xstrdup(v.dptr); return 0; } return ENOENT; }
/* * Try to locate a key using NIS+. */ int nisplus_search(mnt_map *m, char *map, char *key, char **val, time_t *tp) { nis_result *result; int error = 0; struct nisplus_search_callback_data data; nis_name index; char *org; /* if map does not have ".org_dir" then append it */ size_t l; org = strstr(map, NISPLUS_ORGDIR); if (org == NULL) org = NISPLUS_ORGDIR; else org = ""; /* make some room for the NIS index */ l = sizeof('[') /* for opening selection criteria */ + sizeof(NISPLUS_KEY) + strlen(key) + sizeof(']') /* for closing selection criteria */ + sizeof(',') /* + 1 for , separator */ + strlen(map) + sizeof(NISPLUS_ORGDIR); index = xmalloc(l); if (index == NULL) { plog(XLOG_ERROR, "Unable to create index %s: %s", map, strerror(ENOMEM)); return ENOMEM; } xsnprintf(index, l, "[%s%s],%s%s", NISPLUS_KEY, key, map, org); data.key = key; data.value = NULL; dlog("NISplus search for %s", index); result = nis_list(index, EXPAND_NAME | FOLLOW_LINKS | FOLLOW_PATH, (int (*)()) nisplus_search_callback, &data); /* free off the NIS index */ XFREE(index); if (result == NULL) { plog(XLOG_ERROR, "nisplus_search: %s: %s", map, strerror(ENOMEM)); return ENOMEM; } /* * Do something interesting with the return code */ switch (result->status) { case NIS_SUCCESS: case NIS_CBRESULTS: if (data.value == NULL) { nis_object *value = result->objects.objects_val; dlog("NISplus search found <nothing>"); dlog("NISplus search for %s: %s(%d)", map, nis_sperrno(result->status), result->status); if (value != NULL) data.value = strnsave(ENTRY_VAL(value, 1), ENTRY_LEN(value, 1)); } if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX)) { *val = sun_entry2amd(key, data.value); XFREE(data.value); /* strnsave malloc'ed it above */ } else *val = data.value; if (*val) { error = 0; dlog("NISplus search found %s", *val); } else { error = ENOENT; dlog("NISplus search found nothing"); } *tp = 0; break; case NIS_NOSUCHNAME: dlog("NISplus search returned %d", result->status); error = ENOENT; break; default: plog(XLOG_ERROR, "nisplus_search: %s: %s", map, nis_sperrno(result->status)); error = EIO; break; } nis_freeresult(result); return error; }
/* * Try to locate a key in a file */ static int file_search_or_reload(mnt_map *m, FILE *fp, char *map, char *key, char **val, void (*fn) (mnt_map *m, char *, char *)) { char key_val[INFO_MAX_LINE_LEN]; int chuck = 0; int line_no = 0; while (file_read_line(key_val, sizeof(key_val), fp)) { char *kp; char *cp; char *hash; int len = strlen(key_val); line_no++; /* * Make sure we got the whole line */ if (key_val[len - 1] != '\n') { plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map); chuck = 1; } else { key_val[len - 1] = '\0'; } /* * Strip comments */ hash = strchr(key_val, '#'); if (hash) *hash = '\0'; /* * Find start of key */ for (kp = key_val; *kp && isascii((unsigned char)*kp) && isspace((unsigned char)*kp); kp++) ; /* * Ignore blank lines */ if (!*kp) goto again; /* * Find end of key */ for (cp = kp; *cp && (!isascii((unsigned char)*cp) || !isspace((unsigned char)*cp)); cp++) ; /* * Check whether key matches */ if (*cp) *cp++ = '\0'; if (fn || (*key == *kp && STREQ(key, kp))) { while (*cp && isascii((unsigned char)*cp) && isspace((unsigned char)*cp)) cp++; if (*cp) { /* * Return a copy of the data */ char *dc; /* if m->cfm == NULL, not using amd.conf file */ if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX)) dc = sun_entry2amd(kp, cp); else dc = xstrdup(cp); if (fn) { (*fn) (m, xstrdup(kp), dc); } else { *val = dc; dlog("%s returns %s", key, dc); } if (!fn) return 0; } else { plog(XLOG_USER, "%s: line %d has no value field", map, line_no); } } again: /* * If the last read didn't get a whole line then * throw away the remainder before continuing... */ if (chuck) { while (fgets(key_val, sizeof(key_val), fp) && !strchr(key_val, '\n')) ; chuck = 0; } } return fn ? 0 : ENOENT; }
/* * Parse the stream sun_in, convert the map information to amd, write * the results to amd_out. */ static int sun2amd_convert(FILE *sun_in, FILE *amd_out) { char line_buff[INFO_MAX_LINE_LEN], *tmp, *key, *entry; int pos, line = 0, retval = 1; /* just to be safe */ memset(line_buff, 0, sizeof(line_buff)); /* Read the input line by line and do the conversion. */ while ((pos = file_read_line(line_buff, sizeof(line_buff), sun_in))) { line++; line_buff[pos - 1] = '\0'; /* remove comments */ if ((tmp = strchr(line_buff, '#')) != NULL) { *tmp = '\0'; } /* find start of key */ key = line_buff; while (*key != '\0' && isspace((unsigned char)*key)) { key++; } /* ignore blank lines */ if (*key == '\0') { continue; } /* find the end of the key and NULL terminate */ tmp = key; while (*tmp != '\0' && isspace((unsigned char)*tmp) == 0) { tmp++; } if (*tmp == '\0') { plog(XLOG_ERROR, "map line %d has no entry", line); goto err; } *tmp++ = '\0'; if (*tmp == '\0') { plog(XLOG_ERROR, "map line %d has no entry", line); goto err; } entry = tmp; /* convert the sun entry to an amd entry */ if ((tmp = sun_entry2amd(key, entry)) == NULL) { plog(XLOG_ERROR, "parse error on line %d", line); goto err; } if (fprintf(amd_out, "%s %s\n", key, tmp) < 0) { plog(XLOG_ERROR, "can't write to output stream: %s", strerror(errno)); goto err; } /* just to be safe */ memset(line_buff, 0, sizeof(line_buff)); } /* success */ retval = 0; err: return retval; }
/* * Try to locate a value in a query answer */ static int exec_parse_qanswer(mnt_map *m, int fd, char *map, char *key, char **pval, time_t *tp) { char qanswer[INFO_MAX_LINE_LEN], *dc = NULL; int chuck = 0; int line_no = 0; while (read_line(qanswer, sizeof(qanswer), fd)) { char *cp; char *hash; int len = strlen(qanswer); line_no++; /* * Make sure we got the whole line */ if (qanswer[len - 1] != '\n') { plog(XLOG_WARNING, "line %d in \"%s\" is too long", line_no, map); chuck = 1; } else { qanswer[len - 1] = '\0'; } /* * Strip comments */ hash = strchr(qanswer, '#'); if (hash) *hash = '\0'; /* * Find beginning of value (query answer) */ for (cp = qanswer; *cp && !isascii((unsigned char)*cp) && !isspace((unsigned char)*cp); cp++) ;; /* Ignore blank lines */ if (!*cp) goto again; /* * Return a copy of the data */ if (m->cfm && (m->cfm->cfm_flags & CFM_SUN_MAP_SYNTAX)) dc = sun_entry2amd(key, cp); else dc = xstrdup(cp); *pval = dc; dlog("%s returns %s", key, dc); close(fd); return 0; again: /* * If the last read didn't get a whole line then * throw away the remainder before continuing... */ if (chuck) { while (fgets_timed(qanswer, sizeof(qanswer), fd, gopt.exec_map_timeout) && !strchr(qanswer, '\n')) ; chuck = 0; } } return ENOENT; }