/
niceSOFT
/
tdnf
Обзор
Документация
Войти
/
niceSOFT
/
tdnf
Код
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
dev
llconf/modules.c
293 строки
8 KB
Shreenidhi Shedi
Harden TDNF build by enforcing various GCC build flags
19 сен 2025, 06:41
19 сен 2025, 06:41
2457ea6
Код
Авторство
О чём код?
/* -*- linux-c -*- */ /* This file is part of llconf2 Copyright (C) 2004-2007 Oliver Kurth <oku@debian.org> This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <stdlib.h> #include <stdio.h> #include <string.h> #include <errno.h> #include <dlfcn.h> #include "strutils.h" #include "nodes.h" #include "modules.h" struct cnfmodule *cnfmodules = NULL; /** Register a module. * This will usually be called by the parser module * in one of the register_* functions. * @param cm pointer to the module * @param opt_root pointer to the root of the options tree. Can be NULL. */ void register_cnfmodule(struct cnfmodule *cm, struct cnfnode *opt_root) { struct cnfmodule **pcm; /* we also check if the module is already registered - otherwise we may get very weird results. */ for(pcm = &cnfmodules; *pcm && *pcm != cm; pcm = &((*pcm)->next)); if(!*pcm){ *pcm = cm; cm->opt_root = opt_root; cm->next = NULL; } } void unregister_all(void) { cnfmodules = NULL; } /** Destroy a module previously created using clone_cnfmodule(). * free the resources of a module. The module MUST have been created by clone_module. * @param cm pointer to the module to be destroyed */ void destroy_cnfmodule(struct cnfmodule *cm) { if(cm->default_file) free(cm->default_file); if(cm->name) free((char *)cm->name); if(cm->opt_root) destroy_cnftree(cm->opt_root); free(cm); } /** Clone a module. * Copy a module structure, and give the copy a new name, and optionally * another default file and options. * @param cm pointer to the module to be copied * @param new_name pointer to the name of the new module * @param default_file pointer to the new default file. If NULL, the value of the original will be copied * @param opt_root pointer to the root of the options tree. If NULL, the value of the original will be copied * @return pointer to the new module */ struct cnfmodule *clone_cnfmodule(struct cnfmodule *cm, const char *new_name, const char *default_file, struct cnfnode *opt_root) { struct cnfmodule *new_cm; new_cm = malloc(sizeof(struct cnfmodule)); memset(new_cm, 0, sizeof(struct cnfmodule)); if(new_name) new_cm->name = strdup(new_name); else if(cm->name) new_cm->name = strdup(cm->name); if(default_file) new_cm->default_file = strdup(default_file); else if(cm->default_file) new_cm->default_file = strdup(cm->default_file); if(opt_root) new_cm->opt_root = opt_root; else if(cm->opt_root) new_cm->opt_root = cm->opt_root; new_cm->parser = cm->parser; new_cm->unparser = cm->unparser; return new_cm; } /** Find a module by name. * Searches in the list of registered modules for a module with a matching name. * @param name the name * @return pointer to the found module, or NULL if no module was found. */ struct cnfmodule *find_cnfmodule(const char *name) { struct cnfmodule *cm; for(cm = cnfmodules; cm; cm = cm->next){ if(strcmp(cm->name, name) == 0) return cm; } return NULL; } /** Set module options. * @param cm pointer to the module * @param opt_root pointer to the root of the options tree. Although the * @param opt_root syntax of this tree depends on the implementation of the module, * @param opt_root this will most likely be one returned by the parse_options() function * @sa parse_options */ void cnfmodule_setopts(struct cnfmodule *cm, struct cnfnode *opt_root) { cm->opt_root = opt_root; } /** Set module options. @param cm pointer to the module @param name pointer to the name */ #if 0 static void cnfmodule_setname(struct cnfmodule *cm, const char *name) { if(cm->name) free((char *)cm->name); cm->name = strdup(name); } #endif /** Parse module options * Parse an option string into a cnfnode tree. This can be used to * set options for a particular node. * @param string * @return the root to the options tree */ struct cnfnode *parse_options(const char *string) { struct cnfnode *cn_top; const char *p; char buf[256]; cn_top = create_cnfnode("(root)"); p = string; while(p && *p){ char *q = buf; struct cnfnode *cn; while(*p && *p != '=' && *p != ',' && q < buf+255) *q++ = *p++; *q = 0; cn = create_cnfnode(buf); append_node(cn_top, cn); if(*p == '='){ p++; q = buf; while(*p && *p != ',' && q < buf+255) *q++ = *p++; *q = 0; cnfnode_setval(cn, buf); }else cnfnode_setval(cn, ""); if(*p) p++; } return cn_top; } /** Parse from a stream. * @param cm pointer to the module * @param fin pointer to the stream * @return if successful, the pointer to root of the parsed tree. */ struct cnfnode *cnfmodule_parse(struct cnfmodule *cm, FILE *fin) { struct cnfnode *cn_root = NULL; cn_root = cm->parser(cm, fin); return cn_root; } /** Parse from a file. * @param cm pointer to the module * @param fname pointer to the filename. If NULL, the default of the module will be used. * @return if successful, the pointer to root of the parsed tree. */ struct cnfnode *cnfmodule_parse_file(struct cnfmodule *cm, const char *fname) { struct cnfnode *cn_root = NULL; FILE *fin; if(fname == NULL) fname = cm->default_file; if(fname){ if((fin = fopen(fname, "r"))){ cn_root = cnfmodule_parse(cm, fin); fclose(fin); } } return cn_root; } /** Unparse to a stream. * @param cm pointer to the module * @param fout pointer to the stream * @param cn_root the pointer to root of the parsed tree * @return 0 if successful */ int cnfmodule_unparse(struct cnfmodule *cm, FILE* fout, struct cnfnode *cn_root) { return cm->unparser(cm, fout, cn_root); } /** Unparse to a file. * @param cm pointer to the module * @param fname pointer to the filename. If NULL, the default of the module will be used. * @param cn_root the pointer to root of the parsed tree * @return 0 if successful */ int cnfmodule_unparse_file(struct cnfmodule *cm, const char *fname, struct cnfnode *cn_root) { int ret = -1; if(fname == NULL) fname = cm->default_file; if(fname){ FILE *fout; if((fout = fopen(fname, "w"))){ ret = cnfmodule_unparse(cm, fout, cn_root); fclose(fout); } } return ret; } /** Load a shared library module * Load a shared library module and register a new parser by calling a * register function. The register function needs to have a register function of the prototype * void llconf_register_foo(struct cnfnode *opt_root), with 'foo' replaced by the name. * @param name name of the parser * @param path path to the shared library object * @param opt_root pointer to the root of the options tree. Can be NULL. * @return 0 on success */ int cnfmodule_register_plugin(const char *name, const char *path, struct cnfnode *opt_root) { void *dlh; dlh = dlopen(path, RTLD_LAZY); if(dlh){ char fname[256]; struct cnfmodule *(*fe_reg_func)(struct cnfnode *); snprintf(fname, sizeof(fname), "llconf_register_%s", name); dlerror(); /* Clear any existing error */ fe_reg_func = dlsym(dlh, fname); if(dlerror() == NULL) fe_reg_func(opt_root); else{ dlclose(dlh); return -2; } }else{ return -1; } /* Technically correct coverity issue (dlh is leaked), but low impact */ /* coverity[leaked_storage] */ return 0; }