summaryrefslogtreecommitdiff
path: root/src/set.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/set.c')
-rw-r--r--src/set.c498
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);
-}
-