summaryrefslogtreecommitdiff
path: root/src/delete.c
diff options
context:
space:
mode:
authorAn-Cheng Huang <ancheng@vyatta.com>2007-09-25 15:55:26 -0700
committerAn-Cheng Huang <ancheng@vyatta.com>2007-09-25 15:55:26 -0700
commite9a79a249cec69fc178098d2f75db9389068510a (patch)
tree0e366094b7fecd3988c243fbbb574015e0c900c8 /src/delete.c
downloadvyatta-cfg-e9a79a249cec69fc178098d2f75db9389068510a.tar.gz
vyatta-cfg-e9a79a249cec69fc178098d2f75db9389068510a.zip
initial import (from eureka /cli) plus new build system.upstream
Diffstat (limited to 'src/delete.c')
-rw-r--r--src/delete.c258
1 files changed, 258 insertions, 0 deletions
diff --git a/src/delete.c b/src/delete.c
new file mode 100644
index 0000000..a825a22
--- /dev/null
+++ b/src/delete.c
@@ -0,0 +1,258 @@
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <sys/stat.h>
+#include <dirent.h>
+
+#include "cli_val.h"
+#include "cli_objects.h"
+
+static void remove_rf(boolean do_umount)
+{
+ char *command;
+ touch();
+ if (do_umount) {
+ command = my_malloc(strlen(get_mdirp()) + 20, "delete");
+ sprintf(command, "sudo umount %s", get_mdirp());
+ system(command);
+ free(command);
+ }
+ command = my_malloc(strlen(m_path.path) + 10, "delete");
+ sprintf(command, "rm -rf %s", m_path.path);
+ system(command);
+ free(command);
+ if (do_umount) {
+ command = my_malloc(strlen(get_mdirp()) + strlen(get_cdirp()) +
+ strlen(get_mdirp()) + 100,
+ "delete");
+ sprintf(command, "sudo mount -t unionfs -o dirs=%s=rw:%s=ro:"
+ " unionfs %s", get_cdirp(), get_adirp(), get_mdirp());
+ system(command);
+ free(command);
+ }
+}
+/***************************************************
+ set_validate:
+ validate value against definition
+ return TRUE if OK, FALSE otherwise
+****************************************************/
+boolean set_validate(vtw_def *defp, char *valp)
+{
+ boolean res;
+ int status;
+ struct stat statbuf;
+
+ pop_path(&t_path); /* it was tag or real value */
+ push_path(&t_path, DEF_NAME);
+ if (lstat(t_path.path, &statbuf) < 0 ||
+ (statbuf.st_mode & S_IFMT) != S_IFREG) {
+ bye("Can not set value (2), no definition for %s", m_path.path);
+ }
+ /* defniition present */
+ memset(defp, 0, sizeof(vtw_def));
+ if ((status = parse_def(defp, t_path.path, FALSE)))
+ exit(status);
+ res = validate_value(defp, valp);
+ pop_path(&t_path);
+ return res;
+}
+
+int main(int argc, char **argv)
+{
+ int ai;
+ struct stat statbuf;
+ vtw_def def;
+ boolean last_tag=0;
+ int status;
+ FILE *fp;
+ boolean res;
+ char *cp, *delp, *endp;
+ boolean do_umount;
+
+ if (argc < 2) {
+ fprintf(stderr, "Need to specify the config node to delete\n");
+ exit(1);
+ }
+
+ dump_log( argc, argv);
+ do_umount = FALSE;
+ init_edit();
+ /* extend both paths per arguments given */
+ /* last argument is new value */
+ for (ai = 1; ai < argc; ++ai) {
+ 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;
+ continue;
+ }
+ /* no match */
+ break;
+ }
+ /*
+ cases:
+ multiple tag-value - not achild
+ mutilple tag-value - not the last child
+ multiple tag-value - last child
+ single value modified
+ signle value unmodified
+ multiple non-tag value - the last value
+ multiple non-tag value - not the last value
+ regular child
+ */
+ if (ai == argc) {
+ /* full path found */
+ /* all cases except multiple non-tag value */
+ /* check for single value */
+ if (last_tag) {
+ /* case of multiple tag-value
+ was this a real child?
+ was it the last child?
+ */
+ struct dirent *dirp;
+ DIR *dp;
+
+ if (lstat(m_path.path, &statbuf) < 0)
+ bye("Nothing to delete at %s", m_path.path);
+ remove_rf(FALSE);
+ pop_path(&m_path);
+ if ((dp = opendir(m_path.path)) == NULL){
+ INTERNAL;
+ }
+ while ((dirp = readdir(dp)) != NULL) {
+ /*do we have real child */
+ if (strcmp(dirp->d_name, ".") &&
+ strcmp(dirp->d_name, "..") &&
+ strcmp(dirp->d_name, MOD_NAME) && /* XXX */
+ strcmp(dirp->d_name, LOCK_NAME) && /* XXX */
+ strncmp(dirp->d_name, ".wh.", 4) )
+ break;
+ }
+ if (dirp == NULL) {
+ /* no real children left */
+ /* kill parent also */
+ remove_rf(FALSE);
+ }
+ exit(0);
+ }
+ /*not tag */
+ push_path(&t_path, DEF_NAME);
+ if (lstat(t_path.path, &statbuf) >= 0 &&
+ (statbuf.st_mode & S_IFMT) == S_IFREG) {
+ /* defniition present */
+ memset(&def, 0, sizeof(vtw_def));
+ if ((status = parse_def(&def, t_path.path, FALSE)))
+ exit(status);
+ if (!def.tag && !def.multi && def.def_type!= ERROR_TYPE) {
+ /* signgle value */
+ /* is it modified ==
+ it is in C, but not OPAQUE */
+ switch_path(CPATH);
+ if(lstat(m_path.path, &statbuf) >= 0) {
+ push_path(&m_path, OPQ_NAME);
+ if(lstat(m_path.path, &statbuf) < 0) {
+ /* yes remove from C only */
+ pop_path(&m_path);
+ remove_rf(TRUE);
+ exit(0);
+ }
+ pop_path(&m_path); /*OPQ_NAME */
+ }
+ switch_path(MPATH);
+ }
+ }
+ /* else no defnition, remove it also */
+ remove_rf(FALSE);
+ exit(0);
+ }
+ if(ai < argc -1 || last_tag) {
+ bye("There is no appropriate template for %s",
+ m_path.path + strlen(get_mdirp()));
+ }
+ /*ai == argc -1, must be actual value */
+ pop_path(&m_path); /*it was value, not path segment */
+ push_path(&m_path, VAL_NAME);
+ /* set value */
+ if (lstat(m_path.path, &statbuf) < 0)
+ bye("Nothing to delete at %s", m_path.path);
+ if ((statbuf.st_mode & S_IFMT) != S_IFREG)
+ bye("Not a regular file %s", m_path.path);
+ /* get definition to deal with potential multi */
+ pop_path(&t_path); /* it was tag or real value */
+ push_path(&t_path, DEF_NAME);
+ if (lstat(t_path.path, &statbuf) < 0 ||
+ (statbuf.st_mode & S_IFMT) != S_IFREG) {
+ bye("Can not delete value, no definition for %s", m_path.path);
+ }
+ /* defniition present */
+ memset(&def, 0, sizeof(vtw_def));
+ if ((status = parse_def(&def, t_path.path, FALSE)))
+ exit(status);
+ if (def.multi) {
+ /* delete from multivalue */
+ valstruct new_value, old_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)
+ bye("Not in multivalue");
+ touch();
+ if (old_value.cnt) {
+ push_path(&m_path, VAL_NAME);
+ fp = fopen(m_path.path, "w");
+ if (fp == NULL)
+ bye("Can not open value file %s", m_path.path);
+ if (is_in_cond_tik()) {
+ for(delp=cp;delp && is_in_cond_tik(); dec_in_cond_tik()) {
+ delp = strchr(delp, '\n');
+ if (!delp)
+ INTERNAL;
+ ++delp; /* over \n */
+ }
+ /* write "left" of deleted */
+ fwrite(cp, 1, delp-cp, fp);
+ }else
+ delp = cp;
+ /* find end of value */
+ endp = strchr(delp, '\n');
+ if (endp && *++endp) {
+ /* write "right" of deleted */
+ fwrite(endp, 1, strlen(endp), fp);
+ /* need the final '\n' */
+ fwrite("\n", 1, 1, fp);
+ }
+ fclose(fp);
+ return 0;
+ }
+ /* it multi with only 1 value, remove */
+ remove_rf(FALSE);
+ return 0;
+ }
+ bye("There is no appropriate template for %s",
+ m_path.path + strlen(get_mdirp()));
+
+ return 0;
+}
+