initial: modular iptv-dl with runtime config from ~/.iptv-downloader/config.json
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* iptv-dl — IPTV Downloader
|
||||
* Config: ~/.iptv-downloader/config.json (or $IPTV_DL_CONFIG, or --config PATH)
|
||||
* Build: make
|
||||
*/
|
||||
#include "config.h"
|
||||
#include "http.h"
|
||||
#include "queue.h"
|
||||
#include "notify.h"
|
||||
#include "server.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
#include <netinet/in.h>
|
||||
#include <signal.h>
|
||||
#include <curl/curl.h>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
const char *cfg_path = NULL;
|
||||
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (!strcmp(argv[i], "--config") && i+1 < argc) cfg_path = argv[++i];
|
||||
else if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h")) {
|
||||
fprintf(stderr,
|
||||
"Usage: %s [--config PATH] [--dump-config]\n"
|
||||
" --config PATH load config from PATH\n"
|
||||
" --dump-config print active config and exit\n"
|
||||
"Config search order:\n"
|
||||
" --config arg → $IPTV_DL_CONFIG → ~/.iptv-downloader/config.json\n"
|
||||
" → /etc/iptv-downloader/config.json → built-in defaults\n",
|
||||
argv[0]);
|
||||
return 0;
|
||||
} else if (!strcmp(argv[i], "--dump-config")) {
|
||||
config_load(cfg_path);
|
||||
config_dump();
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
config_load(cfg_path);
|
||||
|
||||
if (!http_load_templates()) {
|
||||
fprintf(stderr, "iptv-dl: failed to load templates from %s/\n", g_cfg.template_dir);
|
||||
return 1;
|
||||
}
|
||||
|
||||
mkdir(g_cfg.data_dir, 0755);
|
||||
history_load();
|
||||
notify_load();
|
||||
clean_partials();
|
||||
|
||||
curl_global_init(CURL_GLOBAL_ALL);
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
pthread_t worker;
|
||||
pthread_create(&worker, NULL, dl_worker, NULL);
|
||||
pthread_detach(worker);
|
||||
|
||||
int srv = socket(AF_INET, SOCK_STREAM, 0);
|
||||
int opt = 1; setsockopt(srv, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
|
||||
struct sockaddr_in addr = {0};
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons((unsigned short)g_cfg.port);
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
if (bind(srv, (struct sockaddr*)&addr, sizeof(addr)) < 0) { perror("bind"); return 1; }
|
||||
listen(srv, BACKLOG);
|
||||
fprintf(stderr, "iptv-dl :%d (template_dir=%s data_dir=%s)\n",
|
||||
g_cfg.port, g_cfg.template_dir, g_cfg.data_dir);
|
||||
|
||||
for (;;) {
|
||||
struct sockaddr_in cli; socklen_t clen = sizeof(cli);
|
||||
int cfd = accept(srv, (struct sockaddr*)&cli, &clen);
|
||||
if (cfd < 0) continue;
|
||||
int *p = malloc(sizeof(int)); *p = cfd;
|
||||
pthread_t tid; pthread_create(&tid, NULL, handle_conn, p); pthread_detach(tid);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user