void dict_load_fp(const char *dict_name, VSTREAM *fp) { const char *myname = "dict_load_fp"; VSTRING *buf; char *member; char *val; int lineno; const char *err; struct stat st; DICT *dict; /* * Instantiate the dictionary even if the file is empty. */ DICT_FIND_FOR_UPDATE(dict, dict_name); buf = vstring_alloc(100); lineno = 0; if (fstat(vstream_fileno(fp), &st) < 0) msg_fatal("fstat %s: %m", VSTREAM_PATH(fp)); while (readlline(buf, fp, &lineno)) { if ((err = split_nameval(STR(buf), &member, &val)) != 0) msg_fatal("%s, line %d: %s: \"%s\"", VSTREAM_PATH(fp), lineno, err, STR(buf)); if (msg_verbose > 1) msg_info("%s: %s = %s", myname, member, val); if (dict->update(dict, member, val) != 0) msg_fatal("%s, line %d: unable to update %s:%s", VSTREAM_PATH(fp), lineno, dict->type, dict->name); } vstring_free(buf); dict->owner.uid = st.st_uid; dict->owner.status = (st.st_uid != 0); }
DICT *dict_open3(const char *dict_type, const char *dict_name, int open_flags, int dict_flags) { const char *myname = "dict_open"; DICT_OPEN_INFO *dp; DICT *dict; if (*dict_type == 0 || *dict_name == 0) msg_fatal("open dictionary: expecting \"type:name\" form instead of \"%s:%s\"", dict_type, dict_name); if (dict_open_hash == 0) dict_open_init(); if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags, "unsupported dictionary type: %s", dict_type)); if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0) return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags, "cannot open %s:%s: %m", dict_type, dict_name)); if (msg_verbose) msg_info("%s: %s:%s", myname, dict_type, dict_name); /* XXX the choice between wait-for-lock or no-wait is hard-coded. */ if (dict_flags & DICT_FLAG_OPEN_LOCK) { if (dict_flags & DICT_FLAG_LOCK) msg_panic("%s: attempt to open %s:%s with both \"open\" lock and \"access\" lock", myname, dict_type, dict_name); if (dict->lock(dict, MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0) msg_fatal("%s:%s: unable to get exclusive lock: %m", dict_type, dict_name); } return (dict); }
static void dict_node_free(char *ptr) { DICT_NODE *node = (DICT_NODE *) ptr; DICT *dict = node->dict; if (dict->close) dict->close(dict); myfree((char *) node); }
int dict_update(const char *dict_name, const char *member, const char *value) { const char *myname = "dict_update"; DICT *dict; DICT_FIND_FOR_UPDATE(dict, dict_name); if (msg_verbose > 1) msg_info("%s: %s = %s", myname, member, value); return (dict->update(dict, member, value)); }
int dict_sequence(const char *dict_name, const int func, const char **member, const char **value) { const char *myname = "dict_sequence"; DICT *dict; DICT_FIND_FOR_LOOKUP(dict, dict_name); if (msg_verbose > 1) msg_info("%s: sequence func %d", myname, func); return (dict ? dict->sequence(dict, func, member, value) : DICT_STAT_FAIL); }
static const char *dict_eval_lookup(const char *key, int unused_type, char *dict_name) { const char *pp = 0; DICT *dict; /* * XXX how would one recover? */ DICT_FIND_FOR_LOOKUP(dict, dict_name); if (dict != 0 && (pp = dict->lookup(dict, key)) == 0 && dict->error != 0) msg_fatal("dictionary %s: lookup %s: operation failed", dict_name, key); return (pp); }
DICT *dict_open3(const char *dict_type, const char *dict_name, int open_flags, int dict_flags) { const char *myname = "dict_open"; DICT_OPEN_INFO *dp; DICT_OPEN_FN open_fn; DICT *dict; if (*dict_type == 0 || *dict_name == 0) msg_fatal("open dictionary: expecting \"type:name\" form instead of \"%s:%s\"", dict_type, dict_name); if (dict_open_hash == 0) dict_open_init(); if ((dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type)) == 0) { if (dict_open_extend_hook != 0 && (open_fn = dict_open_extend_hook(dict_type)) != 0) { dict_open_register(dict_type, open_fn); dp = (DICT_OPEN_INFO *) htable_find(dict_open_hash, dict_type); } if (dp == 0) return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags, "unsupported dictionary type: %s", dict_type)); } if ((dict = dp->open(dict_name, open_flags, dict_flags)) == 0) return (dict_surrogate(dict_type, dict_name, open_flags, dict_flags, "cannot open %s:%s: %m", dict_type, dict_name)); if (msg_verbose) msg_info("%s: %s:%s", myname, dict_type, dict_name); /* XXX The choice between wait-for-lock or no-wait is hard-coded. */ if (dict->flags & DICT_FLAG_OPEN_LOCK) { if (dict->flags & DICT_FLAG_LOCK) msg_panic("%s: attempt to open %s:%s with both \"open\" lock and \"access\" lock", myname, dict_type, dict_name); /* Multi-writer safe map: downgrade persistent lock to temporary. */ if (dict->flags & DICT_FLAG_MULTI_WRITER) { dict->flags &= ~DICT_FLAG_OPEN_LOCK; dict->flags |= DICT_FLAG_LOCK; } /* Multi-writer unsafe map: acquire exclusive lock or bust. */ else if (dict->lock(dict, MYFLOCK_OP_EXCLUSIVE | MYFLOCK_OP_NOWAIT) < 0) msg_fatal("%s:%s: unable to get exclusive lock: %m", dict_type, dict_name); } return (dict); }
const char *dict_lookup(const char *dict_name, const char *member) { const char *myname = "dict_lookup"; DICT *dict; const char *ret; DICT_FIND_FOR_LOOKUP(dict, dict_name); if (dict != 0) { ret = dict->lookup(dict, member); if (msg_verbose > 1) msg_info("%s: %s = %s", myname, member, ret ? ret : dict->error ? "(error)" : "(notfound)"); return (ret); } else { if (msg_verbose > 1) msg_info("%s: %s = %s", myname, member, "(notfound)"); return (0); } }
void dict_load_fp(const char *dict_name, VSTREAM *fp) { const char *myname = "dict_load_fp"; VSTRING *buf; char *member; char *val; const char *old; int old_lineno; int lineno; const char *err; struct stat st; DICT *dict; /* * Instantiate the dictionary even if the file is empty. */ DICT_FIND_FOR_UPDATE(dict, dict_name); buf = vstring_alloc(100); old_lineno = lineno = 0; if (fstat(vstream_fileno(fp), &st) < 0) msg_fatal("fstat %s: %m", VSTREAM_PATH(fp)); for ( /* void */ ; readlline(buf, fp, &lineno); old_lineno = lineno) { if ((err = split_nameval(STR(buf), &member, &val)) != 0) msg_fatal("%s, line %s: %s: \"%s\"", VSTREAM_PATH(fp), format_line_number((VSTRING *) 0, old_lineno + 1, lineno), err, STR(buf)); if (msg_verbose > 1) msg_info("%s: %s = %s", myname, member, val); if ((old = dict->lookup(dict, member)) != 0 && strcmp(old, val) != 0) msg_warn("%s, line %d: overriding earlier entry: %s=%s", VSTREAM_PATH(fp), lineno, member, old); if (dict->update(dict, member, val) != 0) msg_fatal("%s, line %d: unable to update %s:%s", VSTREAM_PATH(fp), lineno, dict->type, dict->name); } vstring_free(buf); dict->owner.uid = st.st_uid; dict->owner.status = (st.st_uid != 0); }
static void pcf_show_master_any_param(VSTREAM *fp, int mode, PCF_MASTER_ENT *masterp) { const char *myname = "pcf_show_master_any_param"; ARGV *argv = argv_alloc(10); DICT *dict = masterp->all_params; const char *param_name; const char *param_value; int param_count = 0; int how; char **cpp; /* * Print parameters in sorted order. The number of parameters per * master.cf entry is small, so we optmiize for code simplicity and don't * worry about the cost of double lookup. */ /* Look up the parameter names and ignore the values. */ for (how = DICT_SEQ_FUN_FIRST; dict->sequence(dict, how, ¶m_name, ¶m_value) == 0; how = DICT_SEQ_FUN_NEXT) { argv_add(argv, param_name, ARGV_END); param_count++; } /* Print the parameters in sorted order. */ qsort(argv->argv, param_count, sizeof(argv->argv[0]), pcf_sort_argv_cb); for (cpp = argv->argv; (param_name = *cpp) != 0; cpp++) { if ((param_value = dict_get(dict, param_name)) == 0) msg_panic("%s: parameter name not found: %s", myname, param_name); pcf_print_master_param(fp, mode, masterp, param_name, param_value); } /* * Clean up. */ argv_free(argv); }
void save(void *_obj, const cfgParam *params, QFile &out, DICT &dict) { char *obj = (char*)(_obj); char **p_str; const cfgParam *p; unsigned long *pp; paramProc *proc; for (p = params; p->type; p++){ switch (p->type){ case PARAM_PROC: proc = (paramProc*)(p->offs); save(proc(obj), (cfgParam*)(p->defValue), out, dict); break; case PARAM_OFFS: save(obj + p->offs, (cfgParam*)(p->defValue), out, dict); break; default: if (dict.find(p->name) != dict.end()) break; dict.insert(p->name); bool writeEmpty = false; string value; string *s; string v; list<unsigned long> *l; list<unsigned long>::iterator it; switch (p->type){ case PARAM_ULONG: if (*((unsigned long*)(obj + p->offs)) != p->defValue){ char buf[32]; snprintf(buf, sizeof(buf), "%lu", *((unsigned long*)(obj + p->offs))); value = buf; } break; case PARAM_USHORT: if (*((unsigned short*)(obj + p->offs)) != (unsigned short)(p->defValue)){ char buf[32]; snprintf(buf, sizeof(buf), "%u", *((unsigned short*)(obj + p->offs))); value = buf; } break; case PARAM_SHORT: if (*((short*)(obj + p->offs)) != (short)(p->defValue)){ char buf[32]; snprintf(buf, sizeof(buf), "%i", *((short*)(obj + p->offs))); value = buf; } break; case PARAM_STRING: s = (string*)(obj + p->offs); v = ""; if (p->defValue) v = (const char*)(p->defValue); if (strcmp(s->c_str(), v.c_str())){ value = *s; writeEmpty = true; } break; case PARAM_CHARS: p_str = (char**)(obj + p->offs); if (*p_str){ if ((p->defValue == 0) || strcmp(*p_str, (const char*)(p->defValue))) value = *p_str; }else{ if (p->defValue){ value = ""; writeEmpty = true; } } break; case PARAM_BOOL: if (*((bool*)(obj + p->offs)) != (bool)(p->defValue)) value = *((bool*)(obj + p->offs)) ? "true" : "false"; break; case PARAM_I18N:{ p_str = (char**)(obj + p->offs); if (*p_str){ QString vStr; if (p->defValue){ vStr = i18n((const char*)(p->defValue)); if (strcmp(*p_str, vStr.local8Bit())) value = *p_str; }else{ value = *p_str; } }else{ if (p->defValue){ value = ""; writeEmpty = true; } } break; } case PARAM_ULONGS:{ l = (list<unsigned long>*)(obj + p->offs); if (l->size()){ for (it = l->begin(); it != l->end(); ++it){ char b[15]; snprintf(b, sizeof(b), "%lu", *it); if (value.length()) value += ","; value += b; } } break; } case PARAM_LIST:{ pp = *((unsigned long**)(obj + p->offs)); if (pp){ unsigned n = *(pp++); for (unsigned i = 0; i < n; i++, pp++){ char b[15]; snprintf(b, sizeof(b), "%lu", *pp); if (value.length()) value += ","; value += b; } } break; } case PARAM_CHAR: if (obj[p->offs] != (char)(p->defValue)){ char buf[32]; snprintf(buf, sizeof(buf), "%u", *((char*)(obj + p->offs))); value = buf; } break; default: l = (list<unsigned long>*)(obj + p->offs); for (it = l->begin(); it != l->end(); ++it){ writeStr(out, "["); writeStr(out, p->name); writeStr(out, "]\n"); save((void*)(*it), (const cfgParam*)(p->defValue), out); } if (l->size()) writeStr(out, "[]\n"); } if ((value.size() == 0) && !writeEmpty) continue; value = quoteString(value); writeStr(out, p->name); writeStr(out, "="); writeStr(out, value.c_str()); writeStr(out, "\n"); } } }