src/log.c \
src/main.c \
src/opt/config.c \
+ src/opt/env.c \
src/opt/loglevel.c \
+ src/opt/set.c \
+ src/opt/watch.c \
src/setup.c \
src/usage.c
AC_CHECK_LIB([pthread],[pthread_create])
# Checks for header files.
-AC_CHECK_HEADERS([stdlib.h])
+AC_CHECK_HEADERS([stdlib.h string.h])
# Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_SIZE_T
# Checks for library functions.
AC_FUNC_MALLOC
+AC_CHECK_FUNCS([atexit])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
#ifndef __OPT_H_
#define __OPT_H_
+#include<string.h>
+#include<sys/stat.h>
+
#include<log.h>
-#define OPT_LOADING_CONFIG_FILE_MESSAGE "loading config file %s\n"
+#define OPT_MESSAGE_CONFIG_FILE_FORMAT_ERROR "invalid format in config file %s:%d\n"
+#define OPT_MESSAGE_LOADING_CONFIG_FILE "loading config file %s\n"
+#define OPT_MESSAGE_UNABLE_OPEN_FILE "unable to open file %s\n"
+#define OPT_MESSAGE_UNKNOWN_OPTION "unknown option %s\n"
+#define OPT_MESSAGE_WATCH_ADD_SUCCESS "watching %s\n"
+#define OPT_MESSAGE_WATCH_INVALID_DIRECTORY "watching directory %s failed\n"
+int opt_add_watch(char*);
int opt_load_config_file(char*);
+int opt_load_from_env();
+int opt_set(char*,char*);
void opt_set_log_level(enum log_level);
#endif
{"help", no_argument, 0, 'h'},
{"quiet", no_argument, &verbose_flag, LOG_LEVEL_SILENT},
{"verbose", no_argument, &verbose_flag, LOG_LEVEL_VERBOSE},
+ {"watch", required_argument, 0, 'w'},
{0,0,0,0}
};
int c;
if(defaults()<0) { return EXIT_FAILURE; }
+ if(opt_load_from_env()<0) { return EXIT_FAILURE; }
while(1) {
int option_index = 0;
- if((c = getopt_long(argc,argv,"c:dhqv",long_options,&option_index))==-1) { break; }
+ if((c = getopt_long(argc,argv,"c:dhqvw:",long_options,&option_index))==-1) { break; }
switch(c) {
case 'c':
case 'v':
opt_set_log_level(LOG_LEVEL_VERBOSE);
break;
+ case 'w':
+ if(opt_add_watch(optarg)<0) { return EXIT_FAILURE; }
+ break;
case '?':
default:
return EXIT_FAILURE;
#include<opt.h>
+#define SET_OPT(x,f) { \
+ if(strcmp(x,field)==0) { \
+ if(f(buf)<0) { goto clean; } \
+ } \
+}
+
int opt_load_config_file(char *path) {
- log_info(OPT_LOADING_CONFIG_FILE_MESSAGE,path);
- log_err("not implemented\n");
- return -1;
+ FILE *fp;
+ char field[100];
+ char buf[1024];
+ int line, i;
+
+ log_info(OPT_MESSAGE_LOADING_CONFIG_FILE,path);
+
+ fp = fopen(path,"r");
+ if(NULL==fp) {
+ perror("fopen");
+ log_err(OPT_MESSAGE_UNABLE_OPEN_FILE,path);
+ return -1;
+ }
+
+ line = 0;
+ while(fgets(buf,1024,fp)!=NULL) {
+ line++;
+ // skip lines prefixed with # or empty lines
+ if(buf[0]=='#') { continue; }
+ if(buf[0]=='\n') { continue; }
+
+ if(sscanf(buf,"%[^=\n]=%[^\n]",field,buf)!=2) {
+ log_err(OPT_MESSAGE_CONFIG_FILE_FORMAT_ERROR,path,line);
+ goto clean;
+ }
+
+ if((i = opt_set(field,buf))<=0) { goto clean; }
+ }
+
+ return 1;
+ clean:
+ fclose(fp);
+ return -1;
}
--- /dev/null
+#include<opt.h>
+
+#define CHECK_ENV(x,f) { \
+ p = getenv("SEEDER_"x); \
+ if(p!=NULL) { \
+ if(f(p)<0) { \
+ return -1; \
+ } \
+ } \
+}
+
+int opt_load_from_env() {
+ char *p;
+
+ CHECK_ENV("CONFIG",opt_load_config_file);
+
+ return 1;
+}
--- /dev/null
+#include<opt.h>
+
+struct option_lookup_table_entry {
+ char *key;
+ int (*function)(char*);
+};
+
+struct option_lookup_table_entry option_lookup_table[] = {
+ {"watch",&opt_add_watch},
+ {NULL,NULL}
+};
+
+int opt_set(char *key, char *value) {
+ struct option_lookup_table_entry p;
+ size_t i;
+
+ i = 0;
+ p = option_lookup_table[i];
+ while(p.key!=NULL) {
+ if(strcmp(p.key,key)==0) {
+ return p.function(value);
+ }
+
+ i++;
+ p = option_lookup_table[i];
+ }
+
+ log_err(OPT_MESSAGE_UNKNOWN_OPTION,key);
+ return 0;
+}
--- /dev/null
+#include<opt.h>
+
+int opt_add_watch(char *directory) {
+ struct stat st;
+
+ if(stat(directory,&st)!=0) {
+ perror("stat");
+ log_err(OPT_MESSAGE_WATCH_INVALID_DIRECTORY,directory);
+ return -1;
+ }
+
+ if(!S_ISDIR(st.st_mode)) {
+ log_err(OPT_MESSAGE_WATCH_INVALID_DIRECTORY,directory);
+ return -1;
+ }
+
+ log_msg(OPT_MESSAGE_WATCH_ADD_SUCCESS,directory);
+
+ log_err("not implemented\n");
+ return 1;
+}
#include<usage.h>
void usage() {
+ log_err("Usage:\n");
+ log_err("\tseederd [options]\n");
+ log_err("\n");
+ log_err("Options:\n");
+ log_err("\t--config-file=<path>, -c <path>\n");
+ log_err("\t--daemon, -d\n");
+ log_err("\t--help, -h\n");
+ log_err("\t--quiet, -q\n");
+ log_err("\t--verbose, -v\n");
+ log_err("\t--watch=<directory>, -w <directory>\n");
}