/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=2 et sw=2 tw=80: */ /* Copyright (c) 2013 D. Richard Hipp This program is free software; you can redistribute it and/or modify it under the terms of the Simplified BSD License (also known as the "2-Clause License" or "FreeBSD License".) This program 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. Author contact information: drh@hwaci.com http://www.hwaci.com/drh/ ***************************************************************************** A simple tool for dumping blobs to stdout. */ #include "fossil-scm/fossil-cli.h" #include "fossil-scm/fossil-internal.h" static void fcli_local_help(){ printf("Usage:\n\t%s [options] command [command-options]\n\n", fcli.appName); puts("Views and manipulates fossil configuration data.\n"); puts("Options:\n"); puts("\t-g|--global Uses the global config table.\n"); puts("\t-r|--repo Uses the repository config table.\n"); puts("\t-c|--checkout Uses the checkout-local config table.\n"); puts("Commands:\n"); puts("\tls [-glob STRING] [-v]" "\n\tLists the config entries from the specified config. " "The --glob=STRING option can be used to filter by property names. " "The -v|--values flag enables display of the config values.\n" ); puts("\tset KEY [VALUE]\n\tSets a configuration value. If the value " "is not provided then it is assumed to represent a boolean flag " "and is set to \"1\".\n"); puts("\tunset KEY\n\tRemoves the given config key from the db.\n"); } static struct ConfigApp { char doGlobal; char doLocal; char doRepo; char showValues; char * lsGlob; fsl_confdb_t mode0; } ConfigApp = { 0,0,0, 0/*showValues*/, NULL/*lsGlob*/, FSL_CONFDB_GLOBAL/*mode0*/ }; static int fapp_ls(fsl_cx * f, fsl_confdb_t mode, char const * nameGlob, char showVals){ int rc; fsl_db * db = fsl_config_for_role(f, mode); fsl_stmt st = fsl_stmt_empty; int nameWidth = -30; if(!db){ if(FSL_CONFDB_GLOBAL==mode){ /* special case: auto-open config db */ rc = fsl_config_open(f, NULL); if(!rc){ db = fsl_cx_db_config(f); assert(db); } } if(!db){ return fcli_err_set(FSL_RC_MISUSE, "Config db role #%d is not opened.", mode); } } rc = fsl_db_prepare(db, &st, "SELECT name, value FROM %s ORDER BY name", fsl_config_table_for_role(mode)); while(FSL_RC_STEP_ROW==fsl_stmt_step(&st)){ char const * name = fsl_stmt_g_text(&st, 0, NULL); if(nameGlob && !fsl_str_glob(nameGlob, name)) continue; if(showVals){ f_out("%*s %s\n", nameWidth, name, fsl_stmt_g_text(&st,1,NULL)); }else{ f_out("%s\n", name); } } fsl_stmt_finalize(&st); return rc; } static int fcmd_ls(){ fsl_cx * f = fcli_cx(); int rc = 0; int didSomething = 0; ConfigApp.showValues = fcli_flag2("v", "values", NULL); fcli_flag("glob", &ConfigApp.lsGlob); if(fcli_has_unused_flags(0)) return fcli_error()->code; /* f_out("Global config db: %s\n", fsl_cx_db_file_config(f, NULL)); */ #define DUMP(MODE) \ ++didSomething; \ rc = fapp_ls(f, MODE, ConfigApp.lsGlob, ConfigApp.showValues) if(ConfigApp.doGlobal){ DUMP(FSL_CONFDB_GLOBAL); } if(!rc && ConfigApp.doRepo){ DUMP(FSL_CONFDB_REPO); } if(!rc && ConfigApp.doLocal){ DUMP(FSL_CONFDB_CKOUT); } #undef DUMP assert(didSomething); return rc; } static int fcmd_set(){ char * key = NULL; char * val = NULL; fsl_cx * f = fcli_cx(); int rc; key = fcli_next_arg(1); if(!key){ return fcli_err_set(FSL_RC_MISUSE,"Missing property key argument."); } val = fcli_next_arg(1); if(fcli_has_unused_flags(0)){ rc = fcli_error()->code; }else{ FCLI_V(("Setting %s = %s\n", key, (val && *val) ? val : "1")); rc = fsl_config_set_text(f, ConfigApp.mode0, key, (val && *val) ? val : "1"); } fsl_free(key); fsl_free(val); return rc; } static int fcmd_unset(){ char * key = NULL; fsl_cx * f = fcli_cx(); int rc = 0; int count = 0; if(fcli_has_unused_flags(0)) return fcli_error()->code; rc = fsl_config_transaction_begin(f, ConfigApp.mode0); if(!rc){ while( !rc && (key = fcli_next_arg(1)) ){ ++count; FCLI_V(("Unsetting: %s\n", key)); rc = fsl_config_unset(f, ConfigApp.mode0, key); fsl_free(key); } fsl_config_transaction_end(f, ConfigApp.mode0, rc ? 1 : 0); } if(!count){ rc = fcli_err_set(FSL_RC_MISUSE,"Missing property key argument."); } return rc; } static const FossilCommand ConfigCmds[] = { {"ls", fcmd_ls}, {"set", fcmd_set}, {"unset", fcmd_unset}, {NULL,NULL} }; static int fapp_main(fsl_cx * f){ ConfigApp.doGlobal = fcli_flag2("g","global",NULL); ConfigApp.doRepo = fcli_flag2("r","repo",NULL); ConfigApp.doLocal = fcli_flag2("c","checkout",NULL); /* Set the main config mode for commands which use only one config. Priority order: -c -r -g */ if(ConfigApp.doGlobal){ int rc; ConfigApp.mode0 = FSL_CONFDB_GLOBAL; rc = fsl_config_open( f, 0 ); if(rc) return rc; } else if(ConfigApp.doLocal) ConfigApp.mode0 = FSL_CONFDB_CKOUT; else if(ConfigApp.doRepo) ConfigApp.mode0 = FSL_CONFDB_REPO; else{ return fcli_err_set(FSL_RC_MISUSE, "No config db specified. Use one of: " "-g[lobal], -r[epo], -c[heckout]"); } return fcli_dispatch_commands(ConfigCmds, 0); } int main(int argc, char * const * argv ){ int rc = 0; fcli.appHelp = fcli_local_help; rc = fcli_setup(argc, argv); if(FSL_RC_BREAK==rc) /* --help */ return 0; else if(rc) goto end; rc = fapp_main(fcli_cx()); fsl_free(ConfigApp.lsGlob); end: return fcli_end_of_main(rc); }