src/opt/loglevel.c \
src/opt/out.c \
src/opt/piecel.c \
+ src/opt/port.c \
src/opt/set.c \
src/opt/watch.c \
src/opt/worker.c \
src/rss/init.c \
src/session.c \
src/setup.c \
- src/shutdown.c \
src/torrent/add.c \
src/torrent/file.c \
src/torrent/free.c \
inc/rss.h \
inc/session.h \
inc/setup.h \
- inc/shutdown.h \
inc/torrent.h \
inc/tree.h \
inc/usage.h \
#define log_info(...) log_message(LOG_LEVEL_VERBOSE,stdout,__VA_ARGS__)
#define log_msg(...) log_message(LOG_LEVEL_DEFAULT,stdout,__VA_ARGS__)
-#define LOG_FLUSH_MESSAGE "flushing log queue...\n"
-#define LOG_THREAD_START_MESSAGE "logging thread start\n"
+#define LOG_MESSAGE_FLUSH "flushing log queue...\n"
+#define LOG_MESSAGE_SHUTDOWN_FAILED "failed to shutdown logging thread successfully\nlog entries might be missing\n"
+#define LOG_MESSAGE_SHUTDOWN_SUCCESS "shutdown logging thread\n"
+#define LOG_MESSAGE_THREAD_START "logging thread start\n"
#define LOG_ENTRY_MAX_LENGTH 100
#define LOG_QUEUE_SIZE 100
#define TIMESTAMP_BUF_LENGTH 20
int log_entries_init();
void log_message(enum log_level,FILE*,const char*,...);
void *log_poll(void*);
+void log_shutdown();
#endif
#ifndef __NET_H_
#define __NET_H_
+#include<opt.h>
+
#include<netdb.h>
#include<stdio.h>
#include<stdlib.h>
char *feed_url;
enum file_filters file_filter;
unsigned long long piece_length;
+ char *port;
int verbose_flag;
unsigned int worker_threads;
};
#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_INVALID_PORT "invalid port: %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_PORT_SET "port set to %lu\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 "adding all files in %s to torrent with name %s\n"
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_port(const char*);
int opt_set_worker_threads(const char*);
#endif
if(opt_set_feed_url("")<0) { return -1; }
if(opt_set_file_filter("default")<0) { return -1; }
if(opt_set_piece_length("16384")<0) { return -1; }
+ if(opt_set_port("5150")<0) { return -1; }
{
char buf[10];
{"file-filter", required_argument, 0, 'f'},
{"help", no_argument, 0, 'h'},
{"log-file", required_argument, 0, 'l'},
+ {"port", required_argument, 0, 'p'},
{"quiet", no_argument, 0, 'q'},
{"verbose", no_argument, 0, 'v'},
{"watch-directory", required_argument, 0, 'w'},
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; }
+ if(setup_logging()<0) { return -1; }
+
while(1) {
int option_index = 0;
- if((c = getopt_long(argc,argv,"c:df:hl:qu:vw:",long_options,&option_index))==-1) { break; }
+ if((c = getopt_long(argc,argv,"c:df:hl:p:qu:vw:",long_options,&option_index))==-1) { break; }
switch(c) {
case 1:
case 'l':
if(opt_set_out_stream(optarg)<0) { return -1; }
break;
+ case 'p':
+ if(opt_set_port(optarg)<0) { return -1; }
+ break;
case 'q':
opt_set_log_level(LOG_LEVEL_SILENT);
break;
pthread_mutex_lock(&logging_mutex);
if(helper.start!=NULL) {
- fputs(LOG_FLUSH_MESSAGE,stderr);
+ fputs(LOG_MESSAGE_FLUSH,stderr);
}
while(helper.start!=NULL) {
pthread_cleanup_push(log_entries_clean,NULL);
pthread_cleanup_push(log_flush,NULL);
- log_info(LOG_THREAD_START_MESSAGE);
+ log_info(LOG_MESSAGE_THREAD_START);
while(1) {
pthread_testcancel();
return NULL;
}
+
+void log_shutdown() {
+ int ret_cancel, ret_join;
+ void *res;
+
+ ret_cancel = pthread_cancel(logging_thread);
+ ret_join = pthread_join(logging_thread,&res);
+
+ logging_thread = pthread_self();
+ if((ret_cancel!=0)||(ret_join!=0)||(res!=PTHREAD_CANCELED)) {
+ log_err(LOG_MESSAGE_SHUTDOWN_FAILED);
+ } else {
+ log_msg(LOG_MESSAGE_SHUTDOWN_SUCCESS);
+ }
+}
int main(int argc, char **argv) {
if(init(argc,argv)<0) { return EXIT_FAILURE; }
- if(setup_logging()<0) { return EXIT_FAILURE; }
-
if(add()<0) { return EXIT_FAILURE; }
if(feeds()<0) { return EXIT_FAILURE; }
if(watch()<0) { return EXIT_FAILURE; }
sock_fd = listen_sock(&hints);
if(sock_fd<0) { return -1; }
+ if(listen(sock_fd,MAX_BACKLOG)!=0) {
+ perror("listen");
+ return -1;
+ }
+
return 1;
}
struct addrinfo *p, *res;
int sock_fd;
- if(getaddrinfo(NULL,"5150",hints,&res)!=0) {
+ if(getaddrinfo(NULL,global_options.port,hints,&res)!=0) {
perror("getaddrinfo");
return -1;
}
if(p==NULL) { return -1; }
- if(listen(sock_fd,MAX_BACKLOG)!=0) {
- perror("listen");
- return -1;
- }
-
return sock_fd;
}
CHECK_ENV("FILE_FILTER",opt_set_file_filter);
CHECK_ENV("LOG_FILE",opt_set_out_stream);
CHECK_ENV("PIECE_LENGTH",opt_set_piece_length);
+ CHECK_ENV("PORT",opt_set_port);
CHECK_ENV("WORKER_THREADS",opt_set_worker_threads);
log_info(OPT_MESSAGE_ENV_LOADING_END);
--- /dev/null
+#include<opt.h>
+
+int opt_set_port(const char *port_string) {
+ char *end;
+ unsigned long i;
+
+ if(NULL==port_string) { return -1; }
+
+ i = strtoul(port_string,&end,10);
+
+ if((i>65535)||((NULL!=end)&&(*end!='\0'))) {
+ log_err(OPT_MESSAGE_INVALID_PORT,port_string);
+ return -1;
+ }
+
+ if(global_options.port!=NULL) { free(global_options.port); }
+
+ global_options.port = strdup(port_string);
+ if(NULL==global_options.port) { return -1; }
+
+ log_info(OPT_MESSAGE_PORT_SET,i);
+
+ return 1;
+}
{"feed_url",&opt_set_feed_url},
{"file_filter",&opt_set_file_filter},
{"piece_length",&opt_set_piece_length},
+ {"port",&opt_set_port},
{"watch_directory",&opt_add_watch},
{"worker_threads",&opt_set_worker_threads},
{NULL,NULL}
return -1;
}
+ if(0!=atexit(&log_shutdown)) {
+ perror("atexit");
+ return -1;
+ }
+
return 1;
}
$(top_srcdir)/src/opt/loglevel.c \
$(top_srcdir)/src/opt/out.c \
$(top_srcdir)/src/opt/piecel.c \
+ $(top_srcdir)/src/opt/port.c \
$(top_srcdir)/src/opt/set.c \
$(top_srcdir)/src/opt/watch.c \
$(top_srcdir)/src/opt/worker.c \
static void opt_set_feed_url_basic_test();
static void opt_set_file_filter_basic_test();
static void opt_set_piece_length_basic_test();
+static void opt_set_port_basic_test();
static void opt_set_worker_threads_basic_test();
int main() {
opt_set_feed_url_basic_test();
opt_set_file_filter_basic_test();
opt_set_piece_length_basic_test();
+ opt_set_port_basic_test();
opt_set_worker_threads_basic_test();
clean_env();
assert(1==defaults());
}
+static void opt_set_port_basic_test() {
+ assert(-1==opt_set_port(NULL));
+ assert(-1==opt_set_port("lkndsaoifjasdo"));
+
+ assert(-1==opt_set_port("999999"));
+
+ assert(1==opt_set_port("0111"));
+ assert(1==opt_set_port("5150"));
+
+ assert(1==defaults());
+}
+
+
static void opt_set_worker_threads_basic_test() {
assert(-1==opt_set_worker_threads(NULL));
assert(-1==opt_set_worker_threads("notanumber"));