From 2d247fd827decde5b21e95947dbb3ea6c1647557 Mon Sep 17 00:00:00 2001 From: Henrik Hautakoski Date: Fri, 22 Oct 2010 16:46:58 +0200 Subject: [PATCH] throwing away the client and let database functionality always be built. The debug output used in client/stdout.c should coexist with the database. via __DEBUG__ macro. --- Makefile | 18 +- src/{client/mysql.c => archived.c} | 405 +++++++++++++---------------- src/client/stdout.c | 88 ------- 3 files changed, 190 insertions(+), 321 deletions(-) rename src/{client/mysql.c => archived.c} (56%) delete mode 100644 src/client/stdout.c diff --git a/Makefile b/Makefile index 79223cc..233d83c 100644 --- a/Makefile +++ b/Makefile @@ -3,9 +3,9 @@ # CC = gcc -CFLAGS = -O2 -Werror +CFLAGS = -O2 -Werror `mysql_config --cflags` LD = $(CC) -LDFLAGS = +LDFLAGS = -L/usr/lib/mysql -lmysqlclient FINDOBJ = find . -name "*.o" -type f -printf "%P\n" @@ -28,16 +28,6 @@ endif obj = -ifeq ($(DEBUG), 2) - obj += src/client/stdout.o -else - CFLAGS += `mysql_config --cflags` - LDFLAGS += -L/usr/lib/mysql -lmysqlclient - obj += src/ini/iniparser.o - obj += src/ini/dictionary.o - obj += src/client/mysql.o -endif - obj += src/rbtree.o obj += src/path.o obj += src/strbuf.o @@ -49,6 +39,10 @@ obj += src/event.o obj += src/fscrawl.o obj += src/queue.o +obj += src/ini/iniparser.o +obj += src/ini/dictionary.o +obj += src/archived.o + .PHONY : all clean cleaner all : $(PROGRAM) diff --git a/src/client/mysql.c b/src/archived.c similarity index 56% rename from src/client/mysql.c rename to src/archived.c index 5b9985e..247db58 100644 --- a/src/client/mysql.c +++ b/src/archived.c @@ -1,11 +1,14 @@ -/* client/mysql.c +/* archived.c * - * (C) Copyright 2010 Fredric Nilsson + * Copyright (C) 2010 Fredric Nilsson * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . */ #include @@ -16,14 +19,13 @@ #include -#include "../notify.h" -#include "../event.h" -#include "../xalloc.h" -#include "../ini/iniparser.h" -#include "../util.h" -#include "../debug.h" +#include "notify.h" +#include "xalloc.h" +#include "ini/iniparser.h" +#include "util.h" +#include "debug.h" -typedef struct { +struct config { char *host; int port; char *username; @@ -34,104 +36,11 @@ typedef struct { unsigned long thread; MYSQL* connection; my_bool reconnect; +}; -} database; - -static database db; - +static struct config db = { NULL, 3306, NULL, NULL, NULL, NULL, 0, NULL, 0 }; static dictionary *config = NULL; -/* - * Converts error codes to string - */ -static const char* client_error(int error) { - - switch (error) { - case 1: - return "Missing 'host' in configuration"; - case 2: - return "Missing 'username' in configuration"; - case 3: - return "Missing 'password' in configuration"; - case 4: - return "Missing 'database' in configuration"; - case 5: - return "Missing 'table' in configuration"; - case 6: - return mysql_error(db.connection); - case 7: - return "Error while creating table"; - case 8: - return "Lost connection to database. Could not reconnect"; - case 9: - return "Missing configuration"; - } - - return "Unkown error"; -} - - -/* - * Close database connection - */ -static int client_exit() { - - /* Close database connection */ - mysql_close(db.connection); - - /* Another leak fix */ - mysql_library_end(); - - return 0; -} - - -/* Only way to exit the application properly - when in main loop is by signal */ -static void clean_exit(int excode) { - - time_t t = time(NULL); - - notify_exit(); - - /* Clean mysql */ - int status = client_exit(); - if (0 != status) { - const char *str = client_error(status); - fprintf(stderr,"%s", str); - } - - /* Clean config */ - iniparser_freedict(config); - - printf("\nprocess exit at: %s", ctime(&t)); - exit(excode); - -} - -/* Signal handler */ -static void sighandl(int sig) { - - switch(sig) { - /* normal exit signals */ - case SIGTERM : - case SIGKILL : - case SIGQUIT : - case SIGINT : - clean_exit(EXIT_SUCCESS); - /* segmentation violation, let user now */ - case SIGSEGV : - fprintf(stderr, "SEGFAULT: o no he didn't\n"); - clean_exit(EXIT_FAILURE); - case SIGUSR1 : - case SIGUSR2 : - printf("notify stat:\n"); - notify_stat(); - /* don't know why, but everything goes bananas if we keep executing */ - clean_exit(EXIT_SUCCESS); - } -} - /* * Database setup */ @@ -154,9 +63,9 @@ static int database_setup() { /* Build query Notice: -1 for "%s" in stmt_create and \0 */ - char *stmt = (char *) xmalloc(strlen(stmt_create) + strlen(db.table) - 1); - if (stmt == NULL || sprintf(stmt, stmt_create, db.table) < 0) - return 7; + char *stmt = xmalloc(strlen(stmt_create) + strlen(db.table) - 1); + + sprintf(stmt, stmt_create, db.table); /* Run mysql query */ ret = mysql_query(db.connection, stmt); @@ -168,7 +77,7 @@ static int database_setup() { } /* Build new query */ - stmt = (char *) xrealloc(stmt, strlen(stmt_trunc) + strlen(db.table) - 1); + stmt = xrealloc(stmt, strlen(stmt_trunc) + strlen(db.table) - 1); if (sprintf(stmt, stmt_trunc, db.table) < 0) return 8; @@ -181,46 +90,13 @@ static int database_setup() { return 6; } - return 0; } - /* * Initialize database connection and connect to database */ -static int client_init() { - - /* Load database information from ini config */ - db.host = iniparser_getstring(config, "mysql:host", NULL); - db.port = iniparser_getint(config, "mysql:port", 3306); - db.username = iniparser_getstring(config, "mysql:username", NULL); - db.password = iniparser_getstring(config, "mysql:password", NULL); - db.database = iniparser_getstring(config, "mysql:database", NULL); - db.table = iniparser_getstring(config, "mysql:table", NULL); - - /* Return exit code for missconfiguration */ - if (NULL == db.host) - return 1; - - if (NULL == db.username) - return 2; - - if (NULL == db.password) - return 3; - - if (NULL == db.database) - return 4; - - if (NULL == db.table) - return 5; - - /* Enable reconnection */ - if (1 == iniparser_getboolean(config, "mysql:reconnect", 1)) { - db.reconnect = 1; - } else { - db.reconnect = 0; - } +static int init_db() { /* Init. database connection */ db.connection = mysql_init(NULL); @@ -229,44 +105,148 @@ static int client_init() { mysql_options(db.connection, MYSQL_OPT_RECONNECT, &db.reconnect); /* Connect to database */ - if (!mysql_real_connect(db.connection, db.host, db.username, db.password, db.database, db.port, NULL, 0)) - return 6; + if (!mysql_real_connect(db.connection, db.host, db.username, db.password, db.database, db.port, NULL, 0)) { + fprintf(stderr, "mysql: Could not connect to database (%s)\n", mysql_error(db.connection)); + return -1; + } /* Save mysql thread id */ db.thread = mysql_thread_id(db.connection); -#ifdef DB_DEBUG - fprintf(stderr, "output_init(): %li\n", db.thread); -#endif - /* Setup database */ return database_setup(); - } +static int load_dbconf(const char *file) { + + int status = 0; + + if (config) + return -1; + + if (file_exists(file)) { + config = iniparser_load(file); + if (NULL == config) { + fprintf(stderr, "Could not load configuration file '%s'\n", file); + return -1; + } + } else { + fprintf(stderr, "Configuration file '%s' don't exist\n", file); + return -1; + } + + db.host = iniparser_getstring(config, "mysql:host", NULL); + db.port = iniparser_getint(config, "mysql:port", 3306); + db.username = iniparser_getstring(config, "mysql:username", NULL); + db.password = iniparser_getstring(config, "mysql:password", NULL); + db.database = iniparser_getstring(config, "mysql:database", NULL); + db.table = iniparser_getstring(config, "mysql:table", NULL); + db.reconnect = iniparser_getboolean(config, "mysql:reconnect", 1); + + if (NULL == db.host) { + fprintf(stderr, "Missing 'host' in configuration\n"); + status = -1; + } + if (NULL == db.username) { + fprintf(stderr, "Missing 'username' in configuration\n"); + status = -1; + } + if (NULL == db.password) { + fprintf(stderr, "Missing 'password' in configuration\n"); + status = -1; + } + if (NULL == db.database) { + fprintf(stderr, "Missing 'database' in configuration\n"); + status = -1; + } + if (NULL == db.table) { + fprintf(stderr, "Missing 'table' in configuration\n"); + status = -1; + } + + return status; +} + +/* + * Close database connection + */ +static int mysql_exit() { + + /* Close database connection */ + mysql_close(db.connection); + + /* memory leak fix */ + mysql_library_end(); + + return 0; +} + +/* Only way to exit the application properly + when in main loop is by signal */ +static void clean_exit(int excode) { + + time_t t = time(NULL); + + notify_exit(); + + /* Clean mysql */ + mysql_exit(); + + if (config) + iniparser_freedict(config); + + printf("\nprocess exit at: %s", ctime(&t)); + exit(excode); +} + +/* Signal handler */ +static void sighandl(int sig) { + + switch(sig) { + /* normal exit signals */ + case SIGTERM : + case SIGKILL : + case SIGINT : + clean_exit(EXIT_SUCCESS); + /* segmentation violation, let user now */ + case SIGSEGV : + fprintf(stderr, "SEGFAULT: o no he didn't\n"); + clean_exit(EXIT_FAILURE); + case SIGUSR1 : + case SIGUSR2 : + printf("notify stat:\n"); + notify_stat(); + /* don't know why, but everything goes bananas if we keep executing */ + clean_exit(EXIT_SUCCESS); + } +} /* * Process events */ -static int client_process(notify_event *event) { +static int process(notify_event *event) { int ret = 0, dir = 0; char *stmt; + dprint("%s: (%c) %s%s\n", notify_event_typetostr(event), + event->dir ? 'D' : 'F', event->path, event->filename); + /* Skip if event is unknown */ if (NOTIFY_UNKNOWN == event->type) return 0; + + if (mysql_ping(db.connection) != 0) { + fprintf(stderr, "mysql: Lost connection to database. Could not reconnect\n"); + return -1; + } /* Insert new row in database */ if (NOTIFY_CREATE == event->type) { char stmt_insert[] = "INSERT INTO `%s` (`Path`, `Base`, `Type`, `Status`, `Date`) VALUES('%s','%s','%i','0', NOW())"; - if(mysql_ping(db.connection) != 0) { - return 8; - } - - stmt = (char *)xmalloc(sizeof(char) * (strlen(stmt_insert) + strlen(db.table) + strlen(event->path)*2 + strlen(event->filename)*2 - 6)); + stmt = xmalloc(strlen(stmt_insert) + strlen(db.table) + strlen(event->path)*2 + strlen(event->filename)*2 - 6); /* Escape paths */ char *escaped_path = xmalloc(strlen(event->path) * 2 + 1); @@ -274,32 +254,22 @@ static int client_process(notify_event *event) { mysql_real_escape_string(db.connection, escaped_path, event->path, strlen(event->path)); mysql_real_escape_string(db.connection, escaped_filename, event->filename, strlen(event->filename)); - - /* dir :D */ - if (event->dir == 1) { - dir = 1; - } - + /* Create mysql query */ - sprintf(stmt, stmt_insert, db.table, escaped_path, escaped_filename, dir); + sprintf(stmt, stmt_insert, db.table, escaped_path, escaped_filename, event->dir == 1); - /* Run mysql query */ - ret = mysql_real_query(db.connection, stmt, strlen(stmt)); - - /* Clean up */ - xfree(stmt); - xfree(escaped_path); - xfree(escaped_filename); + ret = mysql_real_query(db.connection, stmt, strlen(stmt)); + /* Clean up */ + xfree(stmt); + xfree(escaped_path); + xfree(escaped_filename); + /* Delete row in database */ } else if (NOTIFY_DELETE == event->type) { char stmt_delete[] = "DELETE FROM `%s` WHERE `Path` LIKE '%s%s%%' OR (`Path` = '%s' AND `Base` = '%s')"; - if(mysql_ping(db.connection) != 0) { - return 8; - } - /* Escape paths */ char *escaped_path = xmalloc(strlen(event->path) * 2 + 1); char *escaped_filename = xmalloc(strlen(event->filename) * 2 + 1); @@ -310,41 +280,37 @@ static int client_process(notify_event *event) { stmt = xmalloc(strlen(stmt_delete) + strlen(db.table) + strlen(escaped_path)*2 + strlen(escaped_filename)*2 + 1); /* Create mysql query */ - sprintf(stmt, stmt_delete, db.table, escaped_path, escaped_filename, escaped_path, escaped_filename); + sprintf(stmt, stmt_delete, db.table, escaped_path, escaped_filename, escaped_path, escaped_filename); - /* Run mysql query */ - ret = mysql_query(db.connection, stmt); + ret = mysql_query(db.connection, stmt); - /* Clean up */ - xfree(stmt); - xfree(escaped_path); - xfree(escaped_filename); - - } - - /* Make sure query was successfull */ - if(ret != 0) { - return 6; + /* Clean up */ + xfree(stmt); + xfree(escaped_path); + xfree(escaped_filename); } #ifdef __DEBUG__ - - if(db.thread != mysql_thread_id(db.connection)) { - fprintf(stderr, "Connection was lost. Reconnected. Old_Thread: %li, New_Thread: %li\n", db.thread, mysql_thread_id(db.connection)); + /* Make sure query was successfull */ + if (ret != 0) { + fprintf(stderr, "mysql: can't execute query\n"); + return -1; } + if (db.thread != mysql_thread_id(db.connection)) { + fprintf(stderr, "mysql: Connection was lost. Reconnected." + "Old_Thread: %li, New_Thread: %li\n", db.thread, mysql_thread_id(db.connection)); + } #endif return 0; } - /* * The main loop - read events from notify API */ static void main_loop() { - int status; notify_event *event; for(;;) { @@ -354,9 +320,7 @@ static void main_loop() { if (event == NULL) continue; - status = client_process(event); - if (status) - fprintf(stderr,"%s", client_error(status)); + process(event); notify_event_del(event); } @@ -366,23 +330,38 @@ int main(int argc, char **argv) { /* Return value */ int ret; + char *configfile = "config.ini", *rootdir; /* Validate arguments */ - if (argc != 2) { - - printf("Usage: %s \n" - "Root Directory - Path to indexroot. All subdirectories will be indexed.\n", argv[0]); + if (argc > 3 && !strcmp(argv[1], "-c")) { + configfile = argv[2]; + rootdir = argv[3]; + } else if (argc > 1 && strcmp(argv[1], "-c")) { + rootdir = argv[1]; + } else { + fprintf(stderr, "Usage: archived [-c ] \n" + "config - path to the configuration file\n" + "Root Directory - Path to indexroot. All subdirectories will be indexed.\n"); return EXIT_FAILURE; } /* Load configuration */ - if (file_exists("config.ini")) { - config = iniparser_load("config.ini"); - if (NULL == config) { - fprintf(stderr, "Could not load configuration"); - return EXIT_FAILURE; - } + if (load_dbconf(configfile) < 0) + return EXIT_FAILURE; + + ret = init_db(); + if (ret == -1) + return EXIT_FAILURE; + + ret = notify_init(); + if (ret == -1) + return EXIT_FAILURE; + + ret = notify_add_watch(rootdir); + if (ret == -1) { + fprintf(stderr, "Invalid path: %s\n", rootdir); + return EXIT_FAILURE; } /* Setup signal handlers */ @@ -393,23 +372,7 @@ int main(int argc, char **argv) { signal(SIGUSR1, sighandl); signal(SIGUSR2, sighandl); - ret = client_init(); - if (ret) { - fprintf(stderr, "%s", client_error(ret)); - return EXIT_FAILURE; - } - - ret = notify_init(); - if (ret == -1) - return EXIT_FAILURE; - - ret = notify_add_watch(argv[1]); - if (ret == -1) { - fprintf(stderr, "Invalid path: %s\n", argv[1]); - return EXIT_FAILURE; - } - main_loop(); - return (EXIT_SUCCESS); + return EXIT_SUCCESS; } diff --git a/src/client/stdout.c b/src/client/stdout.c deleted file mode 100644 index f392e54..0000000 --- a/src/client/stdout.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Debugging client - * - * Copyright (C) 2010 Henrik Hautakoski - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - */ -#include -#include -#include -#include -#include "../notify.h" - -static void p_exit_time() { - - time_t t = time(NULL); - printf("\nprocess exit at: %s", ctime(&t)); -} - -static void sighandler(int sig) { - - p_exit_time(); - - if (sig == SIGSEGV) { - fprintf(stderr, "Segmentation fault\n"); - abort(); - } - - notify_exit(); - exit(EXIT_SUCCESS); -} - -static void pevent(notify_event *ev) { - - const char *strtype = notify_event_typetostr(ev); - char slash = ev->dir ? '/' : '\0'; - - printf("%s : %s%s%c\n", strtype, ev->path, ev->filename, slash); -} - -static void mainloop() { - - notify_event *event; - - for(;;) { - - event = notify_read(); - - if (event == NULL) - continue; - - pevent(event); - - notify_event_del(event); - } -} - -int main(int argc, char **argv) { - - int rc; - - if (argc < 2) { - fprintf(stderr, "usage: %s \n", argv[0]); - return EXIT_FAILURE; - } - - signal(SIGINT, sighandler); - signal(SIGTERM, sighandler); - signal(SIGQUIT, sighandler); - signal(SIGSEGV, sighandler); - - rc = notify_init(); - if (rc < 0) - return EXIT_FAILURE; - - rc = notify_add_watch(argv[1]); - if (rc < 0) { - fprintf(stderr, "Invalid path: %s\n", argv[1]); - return EXIT_FAILURE; - } - - mainloop(); - - return EXIT_SUCCESS; -}