+/*
+ * Delete one argument
+ */
+void
+http_arg_remove(struct http_arg_list *list, struct http_arg *arg)
+{
+ TAILQ_REMOVE(list, arg, link);
+ free(arg->key);
+ free(arg->val);
+ free(arg);
+}
+
+
/*
* Delete all arguments associated with a connection
*/
http_arg_flush(struct http_arg_list *list)
{
http_arg_t *ra;
- while((ra = TAILQ_FIRST(list)) != NULL) {
- TAILQ_REMOVE(list, ra, link);
- free(ra->key);
- free(ra->val);
- free(ra);
- }
+ while((ra = TAILQ_FIRST(list)) != NULL)
+ http_arg_remove(list, ra);
}
TAILQ_INIT(list);
}
+void http_arg_remove(struct http_arg_list *list, struct http_arg *arg);
void http_arg_flush(struct http_arg_list *list);
char *http_arg_get(struct http_arg_list *list, const char *name);
/*
* Functions
*/
+ void (*mn_delete) (mpegts_network_t*, int delconf);
void (*mn_display_name) (mpegts_network_t*, char *buf, size_t len);
void (*mn_config_save) (mpegts_network_t*);
mpegts_mux_t* (*mn_create_mux)
im->mm_iptv_atsc ? DVB_SYS_ATSC_ALL : DVB_SYS_DVBT);
}
-/* **************************************************************************
- * IPTV network
- * *************************************************************************/
-
static void
-iptv_network_class_delete ( idnode_t *in )
+iptv_network_delete ( mpegts_network_t *mn, int delconf )
{
- iptv_network_t *mn = (iptv_network_t*)in;
- char *s = mn->in_url;
+ iptv_network_t *in = (iptv_network_t*)mn;
+ char *s = in->in_url;
- if (in->in_class == &iptv_auto_network_class)
- iptv_auto_network_done((iptv_network_t *)in);
+ if (in->mn_id.in_class == &iptv_auto_network_class)
+ iptv_auto_network_done(in);
/* Remove config */
- hts_settings_remove("input/iptv/networks/%s",
- idnode_uuid_as_sstr(in));
+ if (delconf)
+ hts_settings_remove("input/iptv/networks/%s",
+ idnode_uuid_as_sstr(&in->mn_id));
/* delete */
- free(mn->in_remove_args);
- mpegts_network_delete((mpegts_network_t *)mn, 1);
+ free(in->in_remove_args);
+ mpegts_network_delete(mn, delconf);
free(s);
}
+/* **************************************************************************
+ * IPTV network
+ * *************************************************************************/
+
+static void
+iptv_network_class_delete ( idnode_t *in )
+{
+ return iptv_network_delete((mpegts_network_t *)in, 1);
+}
+
extern const idclass_t mpegts_network_class;
const idclass_t iptv_network_class = {
.ic_super = &mpegts_network_class,
free(in);
return NULL;
}
+ in->mn_delete = iptv_network_delete;
in->mn_create_service = iptv_network_create_service;
in->mn_mux_class = iptv_network_mux_class;
in->mn_mux_create2 = iptv_network_create_mux2;
pthread_join(iptv_thread, NULL);
tvhpoll_destroy(iptv_poll);
pthread_mutex_lock(&global_lock);
+ mpegts_network_unregister_builder(&iptv_auto_network_class);
mpegts_network_unregister_builder(&iptv_network_class);
+ mpegts_network_class_delete(&iptv_auto_network_class, 0);
mpegts_network_class_delete(&iptv_network_class, 0);
mpegts_input_stop_all((mpegts_input_t*)iptv_input);
mpegts_input_delete((mpegts_input_t *)iptv_input, 0);
if (urlparse(url, &u))
return;
if (u.host == NULL || u.host[0] == '\0')
- return;
+ goto end;
/* remove requested arguments */
if (!http_args_empty(remove_args)) {
for (ra2 = TAILQ_FIRST(&args); ra2; ra2 = ra2_next) {
ra2_next = TAILQ_NEXT(ra2, link);
if (strcmp(ra1->key, ra2->key) == 0)
- TAILQ_REMOVE(&args, ra2, link);
+ http_arg_remove(&args, ra2);
}
free(u.query);
u.query = NULL;
u.query = htsbuf_to_string(&q);
htsbuf_queue_flush(&q);
}
+ http_arg_flush(&args);
tvh_strlcatf(url2, sizeof(url2), l, "%s://", u.scheme);
if (u.user && u.user[0] && u.pass && u.pass[0])
tvh_strlcatf(url2, sizeof(url2), l, "%s:%s@", u.user, u.pass);
if (change)
idnode_notify_changed(&im->mm_id);
(*total)++;
- return;
+ goto end;
}
}
(*total)++;
(*count)++;
}
+
+end:
+ urlreset(&u);
}
/*
if (!strncmp(data, "#EXTM3U", 7))
r = iptv_auto_network_process_m3u(in, data, last_url, &remove_args, in->in_channel_number);
+ http_arg_flush(&remove_args);
+
if (r == 0) {
count = 0;
LIST_FOREACH(mm, &in->mn_muxes, mm_network_link)
static int
iptv_auto_network_file(iptv_network_t *in, const char *filename)
{
- int fd;
+ int fd, res;
struct stat st;
char *data, *last_url;
size_t r;
last_url = strrchr(filename, '/');
if (last_url)
last_url++;
- return iptv_auto_network_process(in, last_url, data, off);
+ res = iptv_auto_network_process(in, last_url, data, off);
+ } else {
+ res = -1;
}
- return -1;
+ free(data);
+ return res;
}
/*
pthread_mutex_lock(&global_lock);
+ if (in->in_http_client == NULL)
+ goto out;
+
if (hc->hc_code == HTTP_STATUS_OK && hc->hc_result == 0 && hc->hc_data_size > 0)
iptv_auto_network_process(in, last_url, hc->hc_data, hc->hc_data_size);
else
/* note: http_client_close must be called outside http_client callbacks */
gtimer_arm(&in->in_fetch_timer, iptv_auto_network_fetch_done, hc, 0);
+out:
pthread_mutex_unlock(&global_lock);
+ urlreset(&u);
return 0;
}
http_client_t *hc;
url_t u;
+ memset(&u, 0, sizeof(u));
+
if (strncmp(in->in_url, "file://", 7) == 0) {
iptv_auto_network_file(in, in->in_url + 7);
goto arm;
in->in_http_client = NULL;
}
- memset(&u, 0, sizeof(u));
if (urlparse(in->in_url, &u) < 0) {
tvherror("iptv", "wrong url for network '%s'", in->mn_network_name);
goto arm;
in->in_http_client = hc;
arm:
+ urlreset(&u);
gtimer_arm(&in->in_auto_timer, iptv_auto_network_fetch, in,
MAX(1, in->in_refetch_period) * 60);
}
void
iptv_auto_network_done( iptv_network_t *in )
{
- gtimer_disarm(&in->in_auto_timer);
- gtimer_disarm(&in->in_fetch_timer);
if (in->in_http_client) {
http_client_close(in->in_http_client);
in->in_http_client = NULL;
}
+ gtimer_disarm(&in->in_auto_timer);
+ gtimer_disarm(&in->in_fetch_timer);
}
} else {
tvherror("iptv", "m3u url invalid '%s'", url);
}
+ urlreset(&u);
free(url);
return 0;
}
mn->mn_create_service = mpegts_network_create_service;
mn->mn_mux_class = mpegts_network_mux_class;
mn->mn_mux_create2 = mpegts_network_mux_create2;
+ mn->mn_delete = mpegts_network_delete;
/* Add to global list */
LIST_INSERT_HEAD(&mpegts_network_all, mn, mn_global_link);
for (mn = LIST_FIRST(&mpegts_network_all); mn != NULL; mn = n) {
n = LIST_NEXT(mn, mn_global_link);
if (mn->mn_id.in_class == idc)
- mpegts_network_delete(mn, delconf);
+ mn->mn_delete(mn, delconf);
}
}