src/default.c \
src/file.c \
src/hashmap.c \
+ src/init.c \
src/log.c \
src/main.c \
src/opt/config.c \
src/opt/env.c \
src/opt/filter.c \
src/opt/loglevel.c \
+ src/opt/out.c \
src/opt/piecel.c \
src/opt/set.c \
src/opt/watch.c \
inc/default.h \
inc/file.h \
inc/hashmap.h \
+ inc/init.h \
inc/log.h \
inc/main.h \
inc/opt.h \
#ifndef __FILE_H_
#define __FILE_H_
+#include<libgen.h>
+#include<stdio.h>
+#include<stdlib.h>
+#include<string.h>
+
struct file {
- const char *name;
+ char *name;
+ char *path;
};
void file_free(struct file*);
+int file_init(struct file**,const char*);
#endif
void *hashmap_find(struct hash_map*,void*,size_t);
void hashmap_free(struct hash_map*);
int hashmap_init(struct hash_map**,size_t);
-int hashmap_insert(struct hash_map*,void*,size_t,void*);
+int hashmap_insert(struct hash_map*,const void*,size_t,void*);
void *hashmap_remove(struct hash_map*,void*,size_t);
#endif
--- /dev/null
+#ifndef __INIT_H_
+#define __INIT_H_
+
+#include<getopt.h>
+
+#include<default.h>
+#include<setup.h>
+#include<shutdown.h>
+#include<usage.h>
+
+int init(int,char**);
+
+#endif
#ifndef __MAIN_H_
#define __MAIN_H_
-#include<getopt.h>
#include<stdlib.h>
#include<add.h>
-#include<default.h>
-#include<log.h>
-#include<setup.h>
-#include<shutdown.h>
-#include<usage.h>
-
-#define MAIN_SHUTDOWN_MESSAGE "shutting down...\n"
+#include<init.h>
int main(int,char**);
#define OPT_MESSAGE_FILE_FILTER_SET "set file filter to %s\n"
#define OPT_MESSAGE_FILE_FILTER_UNKNOWN "unknown file filter: %s\n"
#define OPT_MESSAGE_LOADING_CONFIG_FILE "loading config file %s\n"
+#define OPT_MESSAGE_OUT_REDIRECT "redirecting output to %s\n"
#define OPT_MESSAGE_PIECE_LENGTH_INVALID "invalid piece length of %llu\npiece length must be >16384 and a power of 2\n"
#define OPT_MESSAGE_PIECE_LENGTH_SET "piece length set to %llu\n"
#define OPT_MESSAGE_UNABLE_OPEN_FILE "unable to open file %s\n"
int opt_set(const char*,const char*);
int opt_set_file_filter(const char*);
void opt_set_log_level(enum log_level);
+int opt_set_out_stream(const char*);
int opt_set_piece_length(const char*);
int opt_set_worker_threads(const char*);
#include<log.h>
+#define SHUTDOWN_MESSAGE_COMPLETE "shutdown completed\n\n\n"
#define SHUTDOWN_MESSAGE_LOGGING_FAILED "graceful shutdown of logging thread failed\n"
#define SHUTDOWN_MESSAGE_LOGGING_SUCCESS "shutdown logging thread successfully\n"
static struct hash_map *add_queue;
static int add_find_all();
+static int add_queue_resize();
+static int add_to_queue();
static int ftw_helper(const char*,const struct stat*,int);
int add() {
if(add_find_all(session.torrents[i])<0) { return -1; }
}
+ for(size_t i=0;i<add_queue->size;i++) {
+ if(add_queue->map[i]!=NULL) {
+ log_info("to add: %s\n",((struct file*)add_queue->map[i])->path);
+ }
+ }
+
hashmap_free(add_queue);
return -1;
}
log_info(ADD_MESSAGE_ADDING_TORRENT,p->root,p->name);
if(ftw(p->root,&ftw_helper,64)<0) {
- perror("nftw");
+ perror("ftw");
return -1;
}
return -1;
}
+static int add_queue_resize(size_t new_size) {
+ struct file *p;
+ struct hash_map *new, *old;
+ int ret;
+
+ if(hashmap_init(&new,new_size)<0) { return -1; }
+
+ for(size_t i=0;i<add_queue->size;i++) {
+ p = add_queue->map[i];
+ if(p!=NULL) {
+ if((ret = hashmap_insert(new,p->path,strlen(p->path),p))<=0) {
+ if(ret<0) { return -1; }
+ hashmap_free(new);
+ return add_queue_resize(new_size<<1);
+ }
+ }
+ }
+
+ for(size_t i=0;i<add_queue->size;i++) {
+ add_queue->map[i] = NULL;
+ }
+
+ old = add_queue;
+ add_queue = new;
+
+ hashmap_free(old);
+
+ return 1;
+}
+
+static int add_to_queue(const char *path) {
+ struct file *to_add;
+ int ret;
+
+ if(file_init(&to_add,path)<0) { return -1; }
+ while((ret = hashmap_insert(add_queue,path,strlen(path),to_add))<=0) {
+ if(ret<0) { return -1; }
+ if(add_queue_resize(add_queue->size<<1)<0) { return -1; }
+ }
+
+ return 1;
+}
+
static int ftw_helper(const char *path, const struct stat *st, int typeflag) {
if(typeflag!=FTW_F) { return 0; }
- log_info("adding %s\n",path);
switch(global_options.file_filter) {
case FILE_FILTER_IGNORE_DOTFILES:
if(file_filter_ignore_dotfiles(path)<0) { return 0; }
if(file_filter_all(path)<0) { return 0; }
break;
}
+
+ if(add_to_queue(path)<0) { return -1; }
+
return 0;
}
// logging needs to be setup first
logging_thread = pthread_self();
-#ifndef NDEBUG
- opt_set_log_level(LOG_LEVEL_VERBOSE);
-#else
- opt_set_log_level(LOG_LEVEL_DEFAULT);
-#endif
- // end logging section
-
log_info(DEFAULT_MESSAGE_SETTING_DEFAULTS);
+ // suppress output temporarily
+ opt_set_log_level(LOG_LEVEL_SILENT);
+
if(opt_set_piece_length("16384")<0) { return -1; }
{
if(opt_set_file_filter("default")<0) { return -1; }
+ // restore logging output
+#ifndef NDEBUG
+ opt_set_log_level(LOG_LEVEL_VERBOSE);
+#else
+ opt_set_log_level(LOG_LEVEL_DEFAULT);
+#endif
+
if(default_add_all_directories()<0) { return -1; }
return 1;
#include<file.h>
void file_free(struct file *p) {
- return;
+ free(p->name);
+}
+
+int file_init(struct file **p, const char *path) {
+ char *b;
+
+ if(NULL==p) { return -1; }
+ if(0==strlen(path)) { return -1; }
+
+ *p = malloc(sizeof(struct file));
+ if(NULL==(*p)) {
+ perror("malloc");
+ return -1;
+ }
+
+ (*p)->path = strdup(path);
+ b = basename((*p)->path);
+
+ (*p)->name = strdup(b);
+
+ return 1;
}
return 1;
}
-int hashmap_insert(struct hash_map *p, void *key, size_t key_size, void *value) {
+int hashmap_insert(struct hash_map *p, const void *key, size_t key_size, void *value) {
unsigned char hash[crypto_shorthash_BYTES];
size_t index;
--- /dev/null
+#include<init.h>
+
+static struct option long_options[] = {
+ {"config-file", required_argument, 0, 'c'},
+ {"daemon", no_argument, 0, 'd'},
+ {"file-filter", required_argument, 0, 'f'},
+ {"help", no_argument, 0, 'h'},
+ {"log-file", required_argument, 0, 'l'},
+ {"quiet", no_argument, 0, 'q'},
+ {"verbose", no_argument, 0, 'v'},
+ {"watch", required_argument, 0, 'w'},
+ {"worker-threads", required_argument, 0, 1},
+ {0,0,0,0}
+};
+
+int init(int argc, char **argv) {
+ int c;
+
+ shutdown_register();
+
+ if(setup_session()<0) { return -1; }
+
+ if(defaults()<0) { return -1; }
+ if(opt_load_from_env()<0) { return -1; }
+
+ while(1) {
+ int option_index = 0;
+
+ if((c = getopt_long(argc,argv,"c:df:hl:qvw:",long_options,&option_index))==-1) { break; }
+
+ switch(c) {
+ case 1:
+ if(opt_set_worker_threads(optarg)<0) { return -1; }
+ break;
+ case 'c':
+ if(opt_load_config_file(optarg)<0) { return -1; }
+ break;
+ case 'd':
+ printf("not implemented\n");
+ return -1;
+ break;
+ case 'f':
+ if(opt_set_file_filter(optarg)<0) { return -1; }
+ break;
+ case 'h':
+ usage();
+ return -1;
+ case 'l':
+ if(opt_set_out_stream(optarg)<0) { return -1; }
+ break;
+ case 'q':
+ opt_set_log_level(LOG_LEVEL_SILENT);
+ break;
+ case 'v':
+ opt_set_log_level(LOG_LEVEL_VERBOSE);
+ break;
+ case 'w':
+ if(opt_add_watch(optarg)<0) { return -1; }
+ break;
+ case '?':
+ default:
+ return -1;
+ }
+ }
+
+ return 1;
+}
#include<main.h>
-static struct option long_options[] = {
- {"config-file", required_argument, 0, 'c'},
- {"daemon", no_argument, 0, 'd'},
- {"file_filter", required_argument, 0, 'f'},
- {"help", no_argument, 0, 'h'},
- {"quiet", no_argument, 0, 'q'},
- {"verbose", no_argument, 0, 'v'},
- {"watch", required_argument, 0, 'w'},
- {"worker-threads", required_argument, 0, 1},
- {0,0,0,0}
-};
-
int main(int argc, char **argv) {
- int c;
-
- shutdown_register();
-
- if(setup_session()<0) { return EXIT_FAILURE; }
-
- 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:df:hqvw:",long_options,&option_index))==-1) { break; }
-
- switch(c) {
- case 1:
- if(opt_set_worker_threads(optarg)<0) { return EXIT_FAILURE; }
- break;
- case 'c':
- if(opt_load_config_file(optarg)<0) { return EXIT_FAILURE; }
- break;
- case 'd':
- log_err("not implemented\n");
- return EXIT_FAILURE;
- break;
- case 'f':
- if(opt_set_file_filter(optarg)<0) { return EXIT_FAILURE; }
- break;
- case 'h':
- usage();
- return EXIT_FAILURE;
- case 'q':
- opt_set_log_level(LOG_LEVEL_SILENT);
- break;
- 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;
- }
- }
+ if(init(argc,argv)<0) { return EXIT_FAILURE; }
if(setup_logging()<0) { return EXIT_FAILURE; }
--- /dev/null
+#include<opt.h>
+
+int opt_set_out_stream(const char *path) {
+ log_info(OPT_MESSAGE_OUT_REDIRECT,path);
+
+ stdout = freopen(path,"a+",stdout);
+ if(NULL==stdout) {
+ perror("freopen");
+ return -1;
+ }
+
+ return 1;
+}
void shutdown() {
shutdown_logging();
+
+ log_msg(SHUTDOWN_MESSAGE_COMPLETE);
}
static void shutdown_logging() {
log_err("\t--daemon, -d\n");
log_err("\t--file-filter=<filter>, -f <filter>\n");
log_err("\t--help, -h\n");
+ log_err("\t--log-file=<file>, -l <file>\n");
log_err("\t--quiet, -q\n");
log_err("\t--verbose, -v\n");
log_err("\t--watch=<directory>, -w <directory>\n");