/* * 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 #include #include #include #include #include #include #include #include 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); } }