diff options
Diffstat (limited to 'src/set.c')
-rw-r--r-- | src/set.c | 498 |
1 files changed, 0 insertions, 498 deletions
diff --git a/src/set.c b/src/set.c deleted file mode 100644 index fb2d613..0000000 --- a/src/set.c +++ /dev/null @@ -1,498 +0,0 @@ -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <dirent.h> - -#include "cli_val.h" -#include "cli_objects.h" -#include "cli_path_utils.h" - -static void handle_defaults(void); - -static void make_dir() -{ - mkdir_p(m_path.path); -} -/*************************************************** - set_validate: - validate value against definition - return TRUE if OK, FALSE otherwise -****************************************************/ -boolean set_validate(vtw_def *defp, char *valp, boolean empty_val) -{ - boolean res; - int status; - struct stat statbuf; - char* path_end=NULL; - - if (!empty_val) { - { - clind_path_ref tp = clind_path_construct(t_path.path); - if(tp) { - path_end=clind_path_pop_string(tp); - } - clind_path_destruct(&tp); - } - - if (strcmp(path_end, TAG_NAME) == 0) { - /* it was a tag, so the def is at 1 level up */ - pop_path(&t_path); - } else { - /* it's actual value, so the tmpl path is fine */ - free(path_end); - path_end = NULL; - } - } - push_path(&t_path, DEF_NAME); - if (lstat(t_path.path, &statbuf) < 0 || - (statbuf.st_mode & S_IFMT) != S_IFREG) { - fprintf(out_stream, "The specified configuration node is not valid\n"); - bye("Can not set value (4), no definition for %s, template %s", - m_path.path,t_path.path); - } - /* defniition present */ - if ((status = parse_def(defp, t_path.path, FALSE))) { - bye("parse error: %d\n", status); - } - pop_path(&t_path); - if(path_end) { - push_path(&t_path,path_end); - free(path_end); - path_end=NULL; - } - if (defp->def_type == ERROR_TYPE) { - /* no type in def. setting value not allowed. */ - fprintf(out_stream, "The specified configuration node is not valid\n"); - bye("Can not set value: no type for %s, template %s", - m_path.path, t_path.path); - } - if (empty_val) { - if (defp->def_type != TEXT_TYPE || defp->tag || defp->multi){ - printf("Empty string may be assigned only to TEXT type leaf node\n"); - fprintf(out_stream, "Empty value is not allowed\n"); - return FALSE; - } - return TRUE; - } - - //apply limit count here, needs to be defined as a tag,multi and have a value set - - //NOTE: changed behavior for def_tag==1. Needs signed 32 support in parser where -1 - //represents embedded tag node... TODO - if ((defp->tag || defp->multi) && (defp->def_tag != 0 || defp->def_multi != 0)) { - //get count of siblings - - char path[2048]; - char val[2048]; - char last_val[2048]; - char *pos = rindex(m_path.path,'/'); - if (pos != NULL) { - int offset = pos - m_path.path; - strncpy(path,m_path.path,offset); - path[offset] = '\0'; - - strncpy(val,m_path.path + offset + 1, strlen(m_path.path) - offset - 1); - val[strlen(m_path.path) - offset - 1] = '\0'; - - // fprintf(out_stream,"val: %s, offset: %d, path: %s\n",val,offset,m_path.path); - - int entity_count = 0; - if (defp->def_tag) { - struct dirent* entry; - DIR* dirp = opendir(path); /* There should be error handling after this */ - if (dirp != NULL) { - while ((entry = readdir(dirp)) != NULL) { - if (strcmp(entry->d_name,".") != 0 && - strcmp(entry->d_name,"..") != 0 && - strcmp(val,entry->d_name) != 0) { - strcpy(last_val,entry->d_name); - entity_count++; - } - } - closedir(dirp); - } - } - else if (defp->def_multi) { - //fopen file and count number of lines - char buf[4096]; - sprintf(buf,"%s/node.val",m_path.path); - FILE *fp = fopen(buf,"r"); - if (fp) { - char *line = NULL; - size_t len = 0; - while (getline(&line,&len,fp) != -1) { - ++entity_count; - } - if (line) { - free(line); - } - fclose(fp); - } - } - - if (defp->tag && entity_count == 1 && defp->def_tag < 0) { - //this is the special case, where the previous value should be deleted here... - char command[8192]; - //let unionfs handle the diff - sprintf(command, "mv %s/%s %s/%s", path,last_val,path,val); - system(command); - } - - if (defp->tag) { - if (defp->def_tag > 0 && entity_count >= defp->def_tag) { - char *p = rindex(path,'/'); - char tmp[2048]; - if (p != NULL) { - int off = p - path; - strncpy(tmp,path + off + 1, strlen(path) - off - 1); - tmp[strlen(path) - off - 1] = '\0'; - fprintf(out_stream,"Number of values exceeded for '%s', allowed: %d, actual: %d\n",tmp,defp->def_tag,entity_count); - } - else { - fprintf(out_stream,"Number of values exceeded, allowed: %d, actual: %d\n",defp->def_tag,entity_count); - } - return FALSE; - } - } - else { - if (defp->def_multi > 0 && entity_count >= defp->def_multi) { - fprintf(out_stream,"Number of values exceeded, allowed: %d, actual: %d\n",defp->def_multi,entity_count); - return FALSE; - } - } - } - } - - res = validate_value(defp, valp); - return res; -} - -int main(int argc, char **argv) -{ - - int ai; - struct stat statbuf; - vtw_def def; - boolean last_tag; - int status; - FILE *fp; - boolean res; - char *cp; - boolean need_mod = FALSE, not_new = FALSE; - boolean empty_val = FALSE; - - /* this is needed before calling certain glib functions */ - g_type_init(); - - if (initialize_output("Set") == -1) { - bye("can't initialize output\n"); - } - - dump_log( argc, argv); - init_edit(); - last_tag = FALSE; - - /* extend both paths per arguments given */ - /* last argument is new value */ - for (ai = 1; ai < argc; ++ai) { - if (!*argv[ai]) { /* empty string */ - if (ai < argc -1) { - fprintf(out_stream, "Empty value is not allowed after \"%s\"\n", - argv[ai - 1]); - bye("empty string in argument list \n"); - } - empty_val = TRUE; - last_tag = FALSE; - break; - } - push_path(&t_path, argv[ai]); - push_path(&m_path, argv[ai]); - if (lstat(t_path.path, &statbuf) >= 0) { - if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { - bye("INTERNAL:regular file %s in templates", t_path.path); - } - last_tag = FALSE; - continue; - } /*else */ - pop_path(&t_path); - push_path(&t_path, TAG_NAME); - if (lstat(t_path.path, &statbuf) >= 0) { - if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { - bye("INTERNAL:regular file %s in templates", t_path.path); - } - last_tag = TRUE; - /* every time tag match, need to verify*/ - if(!set_validate(&def, argv[ai], FALSE)) { - bye("value \"%s\" is not valid\n", argv[ai]); - } - continue; - } - /* no match */ - break; - } - - if (ai == argc) { - /* full path found */ - /* every tag match validated already */ - /* non tag matches are OK by definition */ - /* do we already have it? */ - if (lstat(m_path.path, &statbuf) >= 0) { - printf("Node [%s] already exists\n", m_path.path + strlen(get_mdirp())); - /* not an error */ - exit(0); - } - /* else */ - /* prevent value node without actual value */ - push_path(&t_path, DEF_NAME); - if (lstat(t_path.path, &statbuf) >= 0) { - if ((status = parse_def(&def, t_path.path, FALSE))) { - bye("parse error: %d\n", status); - } - if (def.def_type != ERROR_TYPE && !def.tag) { - fprintf(out_stream, - "The specified configuration node requires a value\n"); - bye("Must provide actual value\n"); - } - if (def.def_type == ERROR_TYPE && !def.tag) { - pop_path(&t_path); - if(!validate_value(&def, "")) { - bye("validate_value failed\n"); - } - push_path(&t_path, DEF_NAME); - } - } - touch(); - pop_path(&t_path); - make_dir(); - handle_defaults(); - exit(0); - } - if(ai < argc -1 || last_tag) { - fprintf(out_stream, "The specified configuration node is not valid\n"); - bye("There is no appropriate template for %s", - m_path.path + strlen(get_mdirp())); - } - /*ai == argc -1, must be actual value */ - if (!empty_val) { - pop_path(&m_path); /* pop the actual value at the end */ - pop_path(&t_path); /* pop the "node.tag" */ - } - handle_defaults(); - - if(!set_validate(&def, argv[argc-1], empty_val)) { - bye("value \"%s\" is not valid\n", argv[argc - 1]); - } - push_path(&m_path, VAL_NAME); - /* set value */ - if (lstat(m_path.path, &statbuf) >= 0) { - valstruct new_value, old_value; - not_new = TRUE; - if ((statbuf.st_mode & S_IFMT) != S_IFREG) - bye("Not a regular file at path \"%s\"", m_path.path); - /* check if this new value */ - status = char2val(&def, argv[argc - 1], &new_value); - if (status) - exit(0); - cp = NULL; - pop_path(&m_path); /* get_value will push VAL_NAME */ - status = get_value(&cp, &m_path); - if (status != VTWERR_OK) - bye("Cannot read old value %s\n", m_path.path); - status = char2val(&def, cp, &old_value); - if (status != VTWERR_OK) - bye("Corrupted old value ---- \n%s\n-----\n", cp); - res = val_cmp(&new_value, &old_value, IN_COND); - if (res) { - if (def.multi) { - printf("Already in multivalue\n"); - } else { - printf("The same value \"%s\" for path \"%s\"\n", cp, m_path.path); - } - /* not treating as error */ - exit(0); - } - } else { - pop_path(&m_path); - } - make_dir(); - - - if (!def.multi) { - char path[strlen(m_path.path)+5]; - sprintf(path, "%s/def",m_path.path); - unlink(path); - } - - push_path(&m_path, VAL_NAME); - if(not_new && !def.multi) { - /* it is not multi and seen from M */ - /* is it in C */ - switch_path(CPATH); - if (lstat(m_path.path, &statbuf) < 0) - /* yes, we are modifying original value */ - need_mod = TRUE; - switch_path(MPATH); - } - touch(); - /* in case of multi we always append, never overwrite */ - /* in case of single we always overwrite */ - /* append and overwrite work the same for new file */ - fp = fopen(m_path.path, def.multi?"a":"w"); - if (fp == NULL) - bye("Can not open value file %s", m_path.path); - if (fputs(argv[argc-1], fp) < 0 || fputc('\n',fp) < 0) - bye("Error writing file %s", m_path.path); - if (need_mod) { - pop_path(&m_path); /* get rid of "value" */ - char filename[strlen(m_path.path) + sizeof(MOD_NAME)+1]; - sprintf(filename, "%s/" MOD_NAME, m_path.path); - touch_file(filename); - } - return 0; -} - -static char * -last_path_segment(const char *path) -{ - char *tmp = strrchr(path, '/'); - return ((tmp) ? (tmp + 1) : tmp); -} - -/* handle_default(mpath, tpath, exclude) - * create any nodes with default values at the current level. - * mpath: working path - * tpath: template path - * exclude: path to exclude - */ -static void -handle_default(vtw_path *mpath, vtw_path *tpath, char *exclude) -{ - DIR *dp; - struct dirent *dirp; - char *uename = NULL; - struct stat statbuf; - vtw_def def; - int status; - FILE *fp; - - if ((dp = opendir(tpath->path)) == NULL) { - perror("handle_default: opendir"); - bye("opendir failed\n"); - } - - while ((dirp = readdir(dp)) != NULL) { - if (strcmp(dirp->d_name, ".") == 0 - || strcmp(dirp->d_name, "..") == 0 - || strcmp(dirp->d_name, MOD_NAME) == 0 - || strcmp(dirp->d_name, DEF_NAME) == 0 - || strcmp(dirp->d_name, TAG_NAME) == 0 - || strcmp(dirp->d_name, exclude) == 0) { - continue; - } - if (uename) { - free(uename); - uename = NULL; - } - uename = clind_unescape(dirp->d_name); - push_path(tpath, uename); - if (lstat(tpath->path, &statbuf) < 0) { - fprintf(stderr, "no template directory [%s]\n", tpath->path); - pop_path(tpath); - continue; - } - if ((statbuf.st_mode & S_IFMT) != S_IFDIR) { - fprintf(stderr, "non-directory [%s]\n", tpath->path); - pop_path(tpath); - continue; - } - push_path(tpath, DEF_NAME); - if (lstat(tpath->path, &statbuf) < 0) { - /* no definition */ - pop_path(tpath); /* definition */ - pop_path(tpath); /* child */ - continue; - } - if ((status = parse_def(&def, tpath->path, FALSE))) { - /* template parse error. abort. */ - bye("Parse error in [%s]\n", tpath->path); - } - if (def.def_default) { - push_path(mpath, uename); - - push_path(mpath, VAL_NAME); - if (lstat(mpath->path, &statbuf) < 0) { - /* no value. add the default */ - pop_path(mpath); - touch_dir(mpath->path); /* make sure directory exist */ - - //create def marker - char def_file[strlen(mpath->path)+8]; - sprintf(def_file,"%s/def",mpath->path); - fp = fopen(def_file, "w"); - if (fp == NULL) - bye("Can not open def file %s", def_file); - fputs("empty\n", fp); - fclose(fp); - - push_path(mpath, VAL_NAME); - fp = fopen(mpath->path, "w"); - if (fp == NULL) { - bye("Can not open value file %s", mpath->path); - } - if (fputs(def.def_default, fp) < 0 - || fputc('\n',fp) < 0) { - bye("Error writing file %s", mpath->path); - } - fclose(fp); - - } - pop_path(mpath); /* value */ - pop_path(mpath); /* child */ - } - free_def(&def); - pop_path(tpath); /* definition */ - pop_path(tpath); /* child */ - } - if (uename) { - free(uename); - } - closedir(dp); -} - -/* handle_defaults() - * create any nodes with default values along the current "global" - * configuration/template path (m_path/t_path). - */ -static void -handle_defaults() -{ - vtw_path mpath; - vtw_path tpath; - char *path_end = strdup(""); - - memset(&mpath, 0, sizeof(mpath)); - memset(&tpath, 0, sizeof(tpath)); - copy_path(&mpath, &m_path); - copy_path(&tpath, &t_path); - - while (mpath.path_lev > 0) { - handle_default(&mpath, &tpath, path_end); - - if (mpath.path_lev == 1) { - break; - } - - free(path_end); - path_end = strdup(last_path_segment(tpath.path)); - pop_path(&mpath); - pop_path(&tpath); - } - - free(path_end); - free_path(&mpath); - free_path(&tpath); -} - |