From 04df12f7fcb6663231290cbba39f7d4d2db99d0c Mon Sep 17 00:00:00 2001 From: Theodore Tso Date: Wed, 3 Mar 1999 04:56:15 +0000 Subject: [PATCH] test_profile.c: Added ability to test profile set functions, and in a batch mode. prof_init.c (profile_flush): Add new public function for flushing changes made to the profile. prof_parse.c (profile_write_tree_file): Add official internal function for flushing out a profile tree to a FILE *. configure.in, prof_file.c (rw_access): Add new function which checks to see whether we have read/write access, and emulate this for losing non-POSIX OS's. prof_file.c (profile_flush_file): Add support for writing modified profile file's. Call profile_flush_file from profile_close_file(). Also fixed minor bugs in prof_tree.c which affected renaming sections and modifying existing relations. git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@11237 dc483132-0cff-0310-8789-dd5450dbe970 --- src/util/profile/ChangeLog | 17 ++++ src/util/profile/Makefile.in | 5 +- src/util/profile/argv_parse.c | 163 ++++++++++++++++++++++++++++++++ src/util/profile/argv_parse.h | 43 +++++++++ src/util/profile/configure.in | 2 +- src/util/profile/krb5.conf | 59 ++++++++++-- src/util/profile/prof_file.c | 99 +++++++++++++++++++ src/util/profile/prof_init.c | 13 +++ src/util/profile/prof_int.h | 7 ++ src/util/profile/prof_parse.c | 54 ++--------- src/util/profile/prof_tree.c | 42 ++++---- src/util/profile/profile.hin | 3 + src/util/profile/test_parse.c | 8 +- src/util/profile/test_profile.c | 97 ++++++++++++++++++- 14 files changed, 531 insertions(+), 81 deletions(-) create mode 100644 src/util/profile/argv_parse.c create mode 100644 src/util/profile/argv_parse.h diff --git a/src/util/profile/ChangeLog b/src/util/profile/ChangeLog index 983ccb3c6..b54fe058e 100644 --- a/src/util/profile/ChangeLog +++ b/src/util/profile/ChangeLog @@ -1,5 +1,22 @@ Tue Mar 2 18:55:50 1999 Theodore Y. Ts'o + * test_profile.c: Added ability to test profile set functions, and + in a batch mode. + + * prof_init.c (profile_flush): Add new public function for + flushing changes made to the profile. + + * prof_parse.c (profile_write_tree_file): Add official internal + function for flushing out a profile tree to a FILE *. + + * configure.in, prof_file.c (rw_access): Add new function which + checks to see whether we have read/write access, and + emulate this for losing non-POSIX OS's. + + * prof_file.c (profile_flush_file): Add support for writing + modified profile file's. Call profile_flush_file from + profile_close_file(). + * prof_tree.c: Add new functions profile_get_node_name, profile_get_node_value, profile_find_node, profile_remove_node, profile_set_relation_value, diff --git a/src/util/profile/Makefile.in b/src/util/profile/Makefile.in index 86cd74eb5..34b9b2e3e 100644 --- a/src/util/profile/Makefile.in +++ b/src/util/profile/Makefile.in @@ -78,8 +78,9 @@ awk-windows: test_parse: test_parse.$(OBJEXT) $(OBJS) $(DEPLIBS) $(CC_LINK) -o test_parse test_parse.$(OBJEXT) $(OBJS) $(MLIBS) -test_profile: test_profile.$(OBJEXT) $(OBJS) $(DEPLIBS) - $(CC_LINK) -o test_profile test_profile.$(OBJEXT) $(OBJS) $(MLIBS) +test_profile: test_profile.$(OBJEXT) argv_parse.$(OBJEXT) $(OBJS) $(DEPLIBS) + $(CC_LINK) -o test_profile test_profile.$(OBJEXT) \ + argv_parse.$(OBJEXT) $(OBJS) $(MLIBS) test_parse.exe: $(CC) $(CFLAGS2) -o test_parse.exe test_parse.c \ diff --git a/src/util/profile/argv_parse.c b/src/util/profile/argv_parse.c new file mode 100644 index 000000000..d5f1073d3 --- /dev/null +++ b/src/util/profile/argv_parse.c @@ -0,0 +1,163 @@ +/* + * argv_parse.c --- utility function for parsing a string into a + * argc, argv array. + * + * This file defines a function argv_parse() which parsing a + * passed-in string, handling double quotes and backslashes, and + * creates an allocated argv vector which can be freed using the + * argv_free() function. + * + * See argv_parse.h for the formal definition of the functions. + * + * Copyright 1999 by Theodore Ts'o. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose with or without fee is hereby granted, provided that + * the above copyright notice and this permission notice appear in all + * copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE + * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't + * it sick that the U.S. culture of lawsuit-happy lawyers requires + * this kind of disclaimer?) + * + * Version 1.1, modified 2/27/1999 + */ + +#include +#include +#include "argv_parse.h" + +#define STATE_WHITESPACE 1 +#define STATE_TOKEN 2 +#define STATE_QUOTED 3 + +/* + * Returns 0 on success, -1 on failure. + */ +int argv_parse(char *in_buf, int *ret_argc, char ***ret_argv) +{ + int argc = 0, max_argc = 0; + char **argv, **new_argv, *buf, ch; + char *cp = 0, *outcp = 0; + int state = STATE_WHITESPACE; + + buf = malloc(strlen(in_buf)+1); + if (!buf) + return -1; + + max_argc = 0; argc = 0; argv = 0; + outcp = buf; + for (cp = in_buf; (ch = *cp); cp++) { + if (state == STATE_WHITESPACE) { + if (isspace(ch)) + continue; + /* Not whitespace, so start a new token */ + state = STATE_TOKEN; + if (argc >= max_argc) { + max_argc += 3; + new_argv = realloc(argv, + (max_argc+1)*sizeof(char *)); + if (!new_argv) { + if (argv) free(argv); + free(buf); + return -1; + } + argv = new_argv; + } + argv[argc++] = outcp; + } + if (state == STATE_QUOTED) { + if (ch == '"') + state = STATE_TOKEN; + else + *outcp++ = ch; + continue; + } + /* Must be processing characters in a word */ + if (isspace(ch)) { + /* + * Terminate the current word and start + * looking for the beginning of the next word. + */ + *outcp++ = 0; + state = STATE_WHITESPACE; + continue; + } + if (ch == '"') { + state = STATE_QUOTED; + continue; + } + if (ch == '\\') { + ch = *++cp; + switch (ch) { + case '\0': + ch = '\\'; cp--; break; + case 'n': + ch = '\n'; break; + case 't': + ch = '\t'; break; + case 'b': + ch = '\b'; break; + } + } + *outcp++ = ch; + } + if (state != STATE_WHITESPACE) + *outcp++ = '\0'; + if (argv == 0) { + argv = malloc(sizeof(char *)); + free(buf); + } + argv[argc] = 0; + if (ret_argc) + *ret_argc = argc; + if (ret_argv) + *ret_argv = argv; + return 0; +} + +void argv_free(char **argv) +{ + if (*argv) + free(*argv); + free(argv); +} + +#ifdef DEBUG +/* + * For debugging + */ + +#include + +int main(int argc, char **argv) +{ + int ac, ret; + char **av, **cpp; + char buf[256]; + + while (!feof(stdin)) { + if (fgets(buf, sizeof(buf), stdin) == NULL) + break; + ret = argv_parse(buf, &ac, &av); + if (ret != 0) { + printf("Argv_parse returned %d!\n", ret); + continue; + } + printf("Argv_parse returned %d arguments...\n", ac); + for (cpp = av; *cpp; cpp++) { + if (cpp != av) + printf(", "); + printf("'%s'", *cpp); + } + printf("\n"); + argv_free(av); + } + exit(0); +} +#endif /* DEBUG */ diff --git a/src/util/profile/argv_parse.h b/src/util/profile/argv_parse.h new file mode 100644 index 000000000..84568e7bd --- /dev/null +++ b/src/util/profile/argv_parse.h @@ -0,0 +1,43 @@ +/* + * argv_parse.h --- header file for the argv parser. + * + * This file defines the interface for the functions argv_parse() and + * argv_free(). + * + *********************************************************************** + * int argv_parse(char *in_buf, int *ret_argc, char ***ret_argv) + * + * This function takes as its first argument a string which it will + * parse into an argv argument vector, with each white-space separated + * word placed into its own slot in the argv. This function handles + * double quotes and backslashes so that the parsed words can contain + * special characters. The count of the number words found in the + * parsed string, as well as the argument vector, are returned into + * ret_argc and ret_argv, respectively. + *********************************************************************** + * extern void argv_free(char **argv); + * + * This function frees the argument vector created by argv_parse(). + *********************************************************************** + * + * Copyright 1999 by Theodore Ts'o. + * + * Permission to use, copy, modify, and distribute this software for + * any purpose with or without fee is hereby granted, provided that + * the above copyright notice and this permission notice appear in all + * copies. THE SOFTWARE IS PROVIDED "AS IS" AND THEODORE TS'O (THE + * AUTHOR) DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, + * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER + * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR + * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. (Isn't + * it sick that the U.S. culture of lawsuit-happy lawyers requires + * this kind of disclaimer?) + * + * Version 1.1, modified 2/27/1999 + */ + +extern int argv_parse(char *in_buf, int *ret_argc, char ***ret_argv); +extern void argv_free(char **argv); diff --git a/src/util/profile/configure.in b/src/util/profile/configure.in index 850f3befb..aa6b49df8 100644 --- a/src/util/profile/configure.in +++ b/src/util/profile/configure.in @@ -5,7 +5,7 @@ AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(int) AC_CHECK_SIZEOF(long) AC_CHECK_HEADERS(unistd.h stdlib.h) -AC_HAVE_FUNCS(stat) +AC_HAVE_FUNCS(stat access) AC_PROG_AWK KRB5_BUILD_LIBOBJS KRB5_BUILD_PROGRAM diff --git a/src/util/profile/krb5.conf b/src/util/profile/krb5.conf index c4f62d2ba..01eb66ce8 100644 --- a/src/util/profile/krb5.conf +++ b/src/util/profile/krb5.conf @@ -1,12 +1,57 @@ +[libdefaults] + default_realm = ATHENA.MIT.EDU + default_tgs_enctypes = des-cbc-crc + default_tkt_enctypes = des-cbc-crc + krb4_config = /etc/athena/krb.conf + krb4_realms = /etc/athena/krb.realms + default_keytab_name = FILE:/etc/krb5.keytab + kdc_timesync = 1 + ccache_type = 4 + [realms] ATHENA.MIT.EDU = { - kdc = KERBEROS.MIT.EDU:88 - kdc = KERBEROS-1.MIT.EDU:88 - admin_server = KERBEROS.MIT.EDU +# kdc = kerberos-2000.mit.edu + kdc = kerberos.mit.edu:88 + kdc = kerberos-1.mit.edu:88 + kdc = kerberos-2.mit.edu:88 + kdc = kerberos-3.mit.edu:88 + admin_server = kerberos.mit.edu + default_domain = mit.edu + } + MEDIA-LAB.MIT.EDU = { + kdc = kerberos.media.mit.edu + admin_server = kerberos.media.mit.edu + } + ZONE.MIT.EDU = { + kdc = casio.mit.edu + kdc = seiko.mit.edu + admin_server = casio.mit.edu + } + MOOF.MIT.EDU = { + kdc = three-headed-dogcow.mit.edu:88 + kdc = three-headed-dogcow-1.mit.edu:88 + admin_server = three-headed-dogcow.mit.edu + } + CYGNUS.COM = { + kdc = KERBEROS-1.CYGNUS.COM + kdc = KERBEROS.CYGNUS.COM + admin_server = KERBEROS.CYGNUS.COM + } + GREY17.ORG = { + kdc = kerberos.grey17.org + admin_server = kerberos.grey17.org + } + IHTFP.ORG = { + kdc = kerberos.ihtfp.org + admin_server = kerberos.ihtfp.org } -[kdc] - port = 88 +[domain_realm] + .mit.edu = ATHENA.MIT.EDU + mit.edu = ATHENA.MIT.EDU + .media.mit.edu = MEDIA-LAB.MIT.EDU + media.mit.edu = MEDIA-LAB.MIT.EDU -[libdefaults] - ticket_lifetime = 10 hours +[login] + krb4_convert = true + krb4_get_tickets = true diff --git a/src/util/profile/prof_file.c b/src/util/profile/prof_file.c index fde687482..3bdb5d6f3 100644 --- a/src/util/profile/prof_file.c +++ b/src/util/profile/prof_file.c @@ -6,6 +6,9 @@ #ifdef HAVE_STDLIB_H #include #endif +#ifdef HAVE_UNISTD_H +#include +#endif #include #include "prof_int.h" @@ -20,9 +23,36 @@ #if defined(_MSDOS) || defined(_WIN32) +#include +#define HAVE_STAT #define stat _stat #endif +static int rw_access(filename) + const char *filename; +{ +#ifdef HAVE_ACCESS + if (access(filename, W_OK) == 0) + return 1; + else + return 0; +#else + /* + * We're on a substandard OS that doesn't support access. So + * we kludge a test using stdio routines, and hope fopen + * checks the r/w permissions. + */ + FILE *f; + + f = fopen(filename, "r+"); + if (f) { + fclose(f); + return 1; + } + return 0; +#endif +} + errcode_t profile_open_file(filename, ret_prof) const char *filename; prf_file_t *ret_prof; @@ -99,6 +129,9 @@ errcode_t profile_update_file(prf) if (f == NULL) return errno; prf->upd_serial++; + prf->flags = 0; + if (rw_access(prf->filename)) + prf->flags |= PROFILE_FILE_RW; retval = profile_parse_file(f, &prf->root); fclose(f); if (retval) @@ -109,9 +142,75 @@ errcode_t profile_update_file(prf) return 0; } +errcode_t profile_flush_file(prf) + prf_file_t prf; +{ + FILE *f; + char *new_name = 0, *old_name = 0; + errcode_t retval = 0; + + if (!prf || prf->magic != PROF_MAGIC_FILE) + return PROF_MAGIC_FILE; + + if ((prf->flags & PROFILE_FILE_DIRTY) == 0) + return 0; + + retval = ENOMEM; + new_name = malloc(strlen(prf->filename) + 5); + if (!new_name) + goto errout; + old_name = malloc(strlen(prf->filename) + 5); + if (!old_name) + goto errout; + + sprintf(new_name, "%s.$$$", prf->filename); + sprintf(old_name, "%s.bak", prf->filename); + + f = fopen(new_name, "w"); + if (!f) { + retval = errno; + goto errout; + } + + profile_write_tree_file(prf->root, f); + if (fclose(f) != 0) { + retval = errno; + goto errout; + } + + unlink(old_name); + if (rename(prf->filename, old_name)) { + retval = errno; + goto errout; + } + if (rename(new_name, prf->filename)) { + retval = errno; + rename(old_name, prf->filename); /* back out... */ + goto errout; + } + + prf->flags = 0; + if (rw_access(prf->filename)) + prf->flags |= PROFILE_FILE_RW; + retval = 0; + +errout: + if (new_name) + free(new_name); + if (old_name) + free(old_name); + return retval; +} + + errcode_t profile_close_file(prf) prf_file_t prf; { + errcode_t retval; + + retval = profile_flush_file(prf); + if (retval) + return retval; if (prf->filename) free(prf->filename); if (prf->root) diff --git a/src/util/profile/prof_init.c b/src/util/profile/prof_init.c index d88d5f3ac..6a076612f 100644 --- a/src/util/profile/prof_init.c +++ b/src/util/profile/prof_init.c @@ -119,6 +119,19 @@ profile_init_path(filepath, ret_profile) return retval; } +KRB5_DLLIMP errcode_t KRB5_CALLCONV +profile_flush(profile) + profile_t profile; +{ + if (!profile || profile->magic != PROF_MAGIC_PROFILE) + return PROF_MAGIC_PROFILE; + + if (profile->first_file) + return profile_flush_file(profile->first_file); + + return 0; +} + KRB5_DLLIMP void KRB5_CALLCONV profile_release(profile) diff --git a/src/util/profile/prof_int.h b/src/util/profile/prof_int.h index 143bd53e8..312b78e2b 100644 --- a/src/util/profile/prof_int.h +++ b/src/util/profile/prof_int.h @@ -81,6 +81,10 @@ typedef struct _profile_t *profile_t; errcode_t profile_parse_file PROTOTYPE((FILE *f, struct profile_node **root)); +errcode_t profile_write_tree_file + PROTOTYPE((struct profile_node *root, FILE *dstfile)); + + /* prof_tree.c */ void profile_free_node @@ -165,6 +169,9 @@ errcode_t profile_open_file errcode_t profile_update_file PROTOTYPE ((prf_file_t profile)); +errcode_t profile_flush_file + PROTOTYPE ((prf_file_t profile)); + errcode_t profile_close_file PROTOTYPE ((prf_file_t profile)); diff --git a/src/util/profile/prof_parse.c b/src/util/profile/prof_parse.c index 833f80d35..0e3cffe74 100644 --- a/src/util/profile/prof_parse.c +++ b/src/util/profile/prof_parse.c @@ -319,51 +319,7 @@ static void output_quoted_string(str, f) #define EOL "\n" #endif -#if !defined(_MSDOS) && !defined(_WIN32) - -void dump_profile(root, level) - struct profile_node *root; - int level; -{ - int i; - struct profile_node *p; - void *iter; - long retval; - char *name, *value; - - iter = 0; - do { - retval = profile_find_node_relation(root, 0, &iter, - &name, &value); - if (retval) - break; - for (i=0; i < level; i++) - printf(" "); - if (need_double_quotes(value)) { - fputs(name, stdout); - fputs(" = ", stdout); - output_quoted_string(value, stdout); - fputs(EOL, stdout); - } else - printf("%s = '%s'%s", name, value, EOL); - } while (iter != 0); - - iter = 0; - do { - retval = profile_find_node_subsection(root, 0, &iter, - &name, &p); - if (retval) - break; - for (i=0; i < level; i++) - printf(" "); - printf("[%s]%s", name, EOL); - dump_profile(p, level+1); - } while (iter != 0); -} -#endif /* !_MSDOS && !_WIN32 */ - - -void dump_profile_to_file(root, level, dstfile) +static void dump_profile_to_file(root, level, dstfile) struct profile_node *root; int level; FILE *dstfile; @@ -416,3 +372,11 @@ void dump_profile_to_file(root, level, dstfile) } } while (iter != 0); } + +errcode_t profile_write_tree_file(root, dstfile) + struct profile_node *root; + FILE *dstfile; +{ + dump_profile_to_file(root, 0, dstfile); + return 0; +} diff --git a/src/util/profile/prof_tree.c b/src/util/profile/prof_tree.c index 5fde5e930..47160906a 100644 --- a/src/util/profile/prof_tree.c +++ b/src/util/profile/prof_tree.c @@ -594,7 +594,7 @@ errcode_t profile_set_relation_value(node, new_value) CHECK_MAGIC(node); - if (node->value) + if (!node->value) return PROF_SET_SECTION_VALUE; cp = malloc(strlen(new_value)+1); @@ -644,25 +644,31 @@ errcode_t profile_rename_node(node, new_name) } /* - * OK, let's detach the node + * If we need to move the node, do it now. */ - if (node->prev) - node->prev->next = node->next; - else - node->parent->first_child = node->next; - - if (node->next) - node->next->prev = node->prev; + if ((p != node) && (last != node)) { + /* + * OK, let's detach the node + */ + if (node->prev) + node->prev->next = node->next; + else + node->parent->first_child = node->next; + if (node->next) + node->next->prev = node->prev; - /* - * Now let's reattach it in the right place. - */ - if (p) - p->prev = node; - if (last) - last->next = node; - else - node->parent->first_child = node; + /* + * Now let's reattach it in the right place. + */ + if (p) + p->prev = node; + if (last) + last->next = node; + else + node->parent->first_child = node; + node->next = p; + node->prev = last; + } free(node->name); node->name = new_string; diff --git a/src/util/profile/profile.hin b/src/util/profile/profile.hin index 581de74ed..bbc2d0b16 100644 --- a/src/util/profile/profile.hin +++ b/src/util/profile/profile.hin @@ -41,6 +41,9 @@ KRB5_DLLIMP long KRB5_CALLCONV profile_init KRB5_DLLIMP long KRB5_CALLCONV profile_init_path PROTOTYPE ((const char *filepath, profile_t *ret_profile)); +KRB5_DLLIMP errcode_t KRB5_CALLCONV profile_flush + PROTOTYPE ((profile_t profile)); + KRB5_DLLIMP void KRB5_CALLCONV profile_release PROTOTYPE ((profile_t profile)); diff --git a/src/util/profile/test_parse.c b/src/util/profile/test_parse.c index 2f00d9e81..29e2b5940 100644 --- a/src/util/profile/test_parse.c +++ b/src/util/profile/test_parse.c @@ -38,12 +38,8 @@ int main(argc, argv) fclose(f); printf("\n\nDebugging dump.\n"); -#if 0 - dump_profile(root, 0); -#else - dump_profile_to_file(root, 0, stdout); -#endif - + profile_write_tree_file(root, stdout); + retval = profile_verify_node(root); if (retval) { printf("profile_verify_node reported an error: %s\n", diff --git a/src/util/profile/test_profile.c b/src/util/profile/test_profile.c index 4b2df6d36..a36b778bc 100644 --- a/src/util/profile/test_profile.c +++ b/src/util/profile/test_profile.c @@ -8,6 +8,7 @@ #endif #include "prof_int.h" +#include "argv_parse.h" #ifndef _MSDOS #include "com_err.h" #else @@ -22,6 +23,96 @@ void com_err (char *fmt, long err, char *msg) { const char *program_name = "test_profile"; +#define PRINT_VALUE 1 +#define PRINT_VALUES 2 + +static void do_batchmode(profile) + profile_t profile; +{ + errcode_t retval; + int argc, ret; + char **argv, **values, **cpp; + char buf[256]; + const char **names, *value; + char *cmd; + int print_status; + + while (!feof(stdin)) { + if (fgets(buf, sizeof(buf), stdin) == NULL) + break; + printf(">%s", buf); + ret = argv_parse(buf, &argc, &argv); + if (ret != 0) { + printf("Argv_parse returned %d!\n", ret); + continue; + } + cmd = *(argv); + names = (const char **) argv + 1; + print_status = 0; + retval = 0; + if (cmd == 0) { + argv_free(argv); + continue; + } + if (!strcmp(cmd, "query")) { + retval = profile_get_values(profile, names, &values); + print_status = PRINT_VALUES; + } else if (!strcmp(cmd, "query1")) { + retval = profile_get_value(profile, names, &value); + print_status = PRINT_VALUE; + } else if (!strcmp(cmd, "list_sections")) { + retval = profile_get_subsection_names(profile, names, + &values); + print_status = PRINT_VALUES; + } else if (!strcmp(cmd, "list_relations")) { + retval = profile_get_relation_names(profile, names, + &values); + print_status = PRINT_VALUES; + } else if (!strcmp(cmd, "dump")) { + retval = profile_write_tree_file + (profile->first_file->root, stdout); + } else if (!strcmp(cmd, "clear")) { + retval = profile_clear_relation(profile, names); + } else if (!strcmp(cmd, "update")) { + retval = profile_update_relation(profile, names+2, + *names, *(names+1)); + } else if (!strcmp(cmd, "verify")) { + retval = profile_verify_node + (profile->first_file->root); + } else if (!strcmp(cmd, "rename_section")) { + retval = profile_rename_section(profile, names+1, + *names); + } else if (!strcmp(cmd, "add")) { + retval = profile_add_relation(profile, names+1, + *names); + } else if (!strcmp(cmd, "flush")) { + retval = profile_flush(profile); + } else { + printf("Invalid command.\n"); + } + if (retval) { + com_err(cmd, retval, ""); + print_status = 0; + } + switch (print_status) { + case PRINT_VALUE: + printf("%s\n", value); + break; + case PRINT_VALUES: + for (cpp = values; *cpp; cpp++) + printf("%s\n", *cpp); + profile_free_list(values); + break; + } + printf("\n"); + argv_free(argv); + } + profile_release(profile); + exit(0); + +} + + int main(argc, argv) int argc; char **argv; @@ -34,8 +125,8 @@ int main(argc, argv) char *cmd; int print_value = 0; - if (argc < 3) { - fprintf(stderr, "Usage: %s filename cmd argset\n", program_name); + if (argc < 2) { + fprintf(stderr, "Usage: %s filename [cmd argset]\n", program_name); exit(1); } @@ -48,6 +139,8 @@ int main(argc, argv) } cmd = *(argv+2); names = (const char **) argv+3; + if (!cmd || !strcmp(cmd, "batch")) + do_batchmode(profile); if (!strcmp(cmd, "query")) { retval = profile_get_values(profile, names, &values); } else if (!strcmp(cmd, "query1")) { -- 2.26.2