#include #include #include #include #include #include #define DATABASE_PATH (FTAG_ROOT "/ftag.sqlite3") static void ftag_init(int, char **); static void ftag_help(int, char **); static void ftag_tag(int, char **); /* Parse arguments using an array of available commands. ARGV[0] has to match * the "name" field of an entry of COMMANDS. */ static void parse_args(int argc, char ** argv, const struct ftag_command *commands, int command_count); struct ftag_command { const char *name; void (*func)(int argc, char **argv); }; static const struct ftag_command toplevel_commands[] = { {.name = "init", .func = ftag_init}, {.name = "help", .func = ftag_help} }; static const int toplevel_command_count = sizeof(toplevel_commands) / sizeof(struct ftag_command); static sqlite3 *db; static void __sqlite3_check(int rc, sqlite3 *db, const char *file, int line) { if (rc == SQLITE_OK) return; fprintf(stderr, "%s:%d: %s\n", file, line, sqlite3_errmsg(db)); assert(0); } #define sqlite3_check(RC, DB) __sqlite3_check(RC, DB, __FILE__, __LINE__) static void ftag_init(int, char **) { char cmd[1024]; memset(cmd, 0, sizeof(cmd)); snprintf(cmd, sizeof(cmd)-1, "sqlite3 %s < %s", DATABASE_PATH, FTAG_ROOT "/sql/init.sql"); execl("/usr/bin/sh", "/usr/bin/sh", "-c", cmd, NULL); perror("exec"); exit(EXIT_FAILURE); } static void ftag_help(int, char **) { printf("Usage: ftag COMMAND [COMMAND-ARG]...\n"); printf("Available values for COMMAND:\n"); printf(" init initialize the database\n"); printf(" help print this message\n"); printf("Configuration:\n"); printf(" database path %s\n", DATABASE_PATH); printf(" ftag root %s\n", FTAG_ROOT); } static void parse_args(int argc, char **argv, const struct ftag_command *commands, int command_count) { assert(argc > 0); assert(command_count > 0); for (int i = 0; i < command_count; i++) { if (strcmp(argv[0], commands[i].name) == 0) { commands[i].func(argc-1, argv+1); return; } } } int main(int argc, char *argv[]) { if (argc == 1) { ftag_help(0, NULL); exit(EXIT_FAILURE); } parse_args(argc-1, argv+1, toplevel_commands, toplevel_command_count); return EXIT_SUCCESS; }