src/main.c \
src/opt/config.c \
src/opt/env.c \
+ src/opt/filter.c \
src/opt/loglevel.c \
src/opt/piecel.c \
src/opt/set.c \
src/tree.c \
src/usage.c \
src/util/dir.c \
- src/util/file.c
+ src/util/file.c \
+ src/util/filter.c
seederd_SOURCES += \
inc/add.h \
#include<hashmap.h>
#include<log.h>
+#include<util.h>
#define ADD_MESSAGE_ADDING_TORRENT "adding all files in %s to torrent named %s\n"
#include<torrent.h>
#include<util.h>
+enum file_filters {
+ FILE_FILTER_IGNORE_DOTFILES,
+ FILE_FILTER_ALL,
+ FILE_FILTER_DEFAULT = FILE_FILTER_IGNORE_DOTFILES
+};
+
struct options {
unsigned int worker_threads;
unsigned long long piece_length;
int verbose_flag;
+ enum file_filters file_filter;
};
extern struct options global_options;
#define OPT_MESSAGE_CONFIG_FILE_FORMAT_ERROR "invalid format in config file %s:%d\n"
#define OPT_MESSAGE_ENV_LOADING "loading settings from environment\n"
#define OPT_MESSAGE_ENV_LOADING_END "finished loading settings from environment\n"
+#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_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_WORKER_THREADS_INVALID "invalid value to option worker_threads: %u\n"
#define OPT_MESSAGE_WORKER_THREADS_SET "number of worker threads set to %u\n"
-int opt_add_watch(char*);
+int opt_add_watch(const char*);
int opt_load_config_file(char*);
int opt_load_from_env();
-int opt_set(char*,char*);
+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_piece_length(char*);
-int opt_set_worker_threads(char*);
+int opt_set_piece_length(const char*);
+int opt_set_worker_threads(const char*);
#endif
};
void torrent_free(struct torrent*);
-int torrent_init(struct torrent**,char*,char*);
+int torrent_init(struct torrent**,const char*,const char*);
#endif
#include<dirent.h>
#include<stdio.h>
+#include<string.h>
#include<sys/stat.h>
-int file_filter(char*);
-void find(char*);
-int is_directory(char*);
-int is_file(char*);
+#include<log.h>
+
+int file_filter_all(const char*);
+int file_filter_ignore_dotfiles(const char*);
+int is_directory(const char*);
+int is_file(const char*);
#endif
}
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; }
+ break;
+ case FILE_FILTER_ALL:
+ if(file_filter_all(path)<0) { return 0; }
+ break;
+ }
return 0;
}
if(opt_set_worker_threads(buf)<0) { return -1; }
}
+ if(opt_set_file_filter("default")<0) { return -1; }
+
if(default_add_all_directories()<0) { return -1; }
return 1;
void *log_poll(void *p) {
log_info(LOG_THREAD_START_MESSAGE);
while(1) {
- pthread_mutex_lock(&logging_mutex);
log_print();
- pthread_mutex_unlock(&logging_mutex);
}
return NULL;
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'},
while(1) {
int option_index = 0;
- if((c = getopt_long(argc,argv,"c:dhqvw:",long_options,&option_index))==-1) { break; }
+ if((c = getopt_long(argc,argv,"c:df:hqvw:",long_options,&option_index))==-1) { break; }
switch(c) {
case 1:
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;
#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) {
FILE *fp;
char field[100];
--- /dev/null
+#include<opt.h>
+
+int opt_set_file_filter(const char *filter) {
+ if(strcmp(filter,"default")==0) {
+ global_options.file_filter = FILE_FILTER_DEFAULT;
+ } else if(strcmp(filter,"-dotfiles")==0) {
+ global_options.file_filter = FILE_FILTER_IGNORE_DOTFILES;
+ } else if(strcmp(filter,"all")==0) {
+ global_options.file_filter = FILE_FILTER_ALL;
+ } else {
+ log_err(OPT_MESSAGE_FILE_FILTER_UNKNOWN,filter);
+ return -1;
+ }
+
+ log_info(OPT_MESSAGE_FILE_FILTER_SET,filter);
+ return 1;
+}
#include<opt.h>
-int opt_set_piece_length(char *length) {
+int opt_set_piece_length(const char *length) {
char *end;
unsigned long long i;
struct option_lookup_table_entry {
char *key;
- int (*function)(char*);
+ int (*function)(const char*);
};
struct option_lookup_table_entry option_lookup_table[] = {
+ {"file_filter",&opt_set_file_filter},
{"piece_length",&opt_set_piece_length},
{"watch",&opt_add_watch},
{"worker_threads",&opt_set_worker_threads},
{NULL,NULL}
};
-int opt_set(char *key, char *value) {
+int opt_set(const char *key, const char *value) {
struct option_lookup_table_entry p;
size_t i;
#include<opt.h>
-int opt_add_watch(char *directory) {
+int opt_add_watch(const char *directory) {
struct torrent *p;
+ char *name;
if(!is_directory(directory)) {
log_err(OPT_MESSAGE_WATCH_INVALID_DIRECTORY,directory);
return -1;
}
- if(torrent_init(&p,directory,basename(directory))<0) { return -1; }
+ name = strdup(directory);
+ name = basename(name);
+
+ if(torrent_init(&p,directory,name)<0) { return -1; }
if(session_torrent_add(p)<0) { return -1; }
log_msg(OPT_MESSAGE_WATCH_ADD_SUCCESS,p->root,p->name);
#include<opt.h>
-int opt_set_worker_threads(char *str) {
+int opt_set_worker_threads(const char *str) {
char *end;
global_options.worker_threads = strtoul(str,&end,10);
free(p);
}
-int torrent_init(struct torrent **torrent_p, char *root, char *name) {
+int torrent_init(struct torrent **torrent_p, const char *root, const char *name) {
*(torrent_p) = malloc(sizeof(struct torrent));
if(NULL==(*torrent_p)) {
perror("malloc");
(*torrent_p)->name = NULL;
(*torrent_p)->file_tree = NULL;
- (*torrent_p)->root = malloc(strlen(root)+1);
+ (*torrent_p)->root = strdup(root);
if(NULL==(*torrent_p)->root) {
- perror("malloc");
+ perror("strdup");
torrent_free(*torrent_p);
return -1;
}
- strcpy((*torrent_p)->root,root);
- (*torrent_p)->name = malloc(strlen(name)+1);
+ (*torrent_p)->name = strdup(name);
if(NULL==(*torrent_p)->name) {
- perror("malloc");
+ perror("strdup");
torrent_free(*torrent_p);
return -1;
}
- strcpy((*torrent_p)->name,name);
return 1;
}
log_err("Options:\n");
log_err("\t--config-file=<path>, -c <path>\n");
log_err("\t--daemon, -d\n");
+ log_err("\t--file-filter=<filter>, -f <filter>\n");
log_err("\t--help, -h\n");
log_err("\t--quiet, -q\n");
log_err("\t--verbose, -v\n");
#include<util.h>
-int is_directory(char *path) {
+int is_directory(const char *path) {
struct stat st;
if(stat(path,&st)!=0) {
#include<util.h>
-int is_file(char *path) {
+int is_file(const char *path) {
struct stat st;
if(stat(path,&st)!=0) {
--- /dev/null
+#include<util.h>
+
+int file_filter_all(const char *path) {
+ return 1;
+}
+
+int file_filter_ignore_dotfiles(const char *path) {
+ const char *p;
+ if(NULL==path) { return -1; }
+
+ p = path;
+ while((p = strchr(p, '/'))!=NULL) {
+ p++;
+ log_info("p: %s\n",p);
+ if(p[0]=='.') { return -1; }
+ }
+
+ return 1;
+}
+++ /dev/null
-#include<util.h>
-
-int file_filter(char *path) {
- /* scandir requires non-zero return values to include */
- char *p;
- if(NULL==path) { return false; }
-
- p = strrchr(path, '/');
-
- if(NULL==p) {
- p = path;
- } else {
- p++;
- }
-
- if(p[0]=='.') { return 0; }
-
- return 1;
-}
-
-void find(char *path) {
- if(is_file(path)<0) {
-
-}