#ifdef USE_TCP
static void simple_http(int sock) {
- const char *RSP =
- "HTTP/1.0 200 OK\r\nContent-Type: video/mp2t\r\nConnection: close\r\n\r\n\r\n";
- char drain[1024] = "";
- int err;
-
- WHOAMI;
- //TODO POLL
- do {
- err = read(sock, drain, sizeof drain);
- if (err <= 0)
- return;
- drain[err] = 0;
- DPRINT("%s\n", drain);
- } while (!strstr(drain, "\r\n\r\n"));
-
- send(sock, RSP, strlen(RSP), MSG_NOSIGNAL);
-
- DPRINT ("simple http response sent\n");
+ const char *RSP =
+ "HTTP/1.0 200 OK\r\nContent-Type: video/mp2t\r\nConnection: close\r\n\r\n\r\n";
+ char drain[1024] = "";
+ int err;
+
+ WHOAMI;
+ //TODO POLL
+ do {
+ err = read(sock, drain, sizeof drain);
+ if (err <= 0)
+ return;
+ drain[err] = 0;
+ DPRINT("%s\n", drain);
+ } while (!strstr(drain, "\r\n\r\n"));
+
+ send(sock, RSP, strlen(RSP), MSG_NOSIGNAL);
+
+ DPRINT ("simple http response sent\n");
}
size_t fetch_send(void *ptr, size_t size, size_t nmemb, void *stream) {
- size_t bytesize = size * nmemb;
+ size_t bytesize = size * nmemb;
- int sent;
+ int sent;
- WHOAMI;
+ WHOAMI;
- if (conn < 0)
- conn = accept(sock, NULL, NULL);
+ if (conn < 0)
+ conn = accept(sock, NULL, NULL);
- if (conn >= 0 && !flag_conn) {
- DPRINT("Connection accepted\n");
- flag_conn = 1;
- simple_http(conn);
- }
+ if (conn >= 0 && !flag_conn) {
+ DPRINT("Connection accepted\n");
+ flag_conn = 1;
+ simple_http(conn);
+ }
- if (flag_conn) {
- sent = send(conn, ptr, bytesize, MSG_NOSIGNAL);
- if (sent <= 0) {
- DPRINT("Pious Teardown!\n");
- shutdown(conn, SHUT_RDWR);
- close(conn);
- conn = -1;
- flag_conn = 0;
- }
- }
+ if (flag_conn) {
+ sent = send(conn, ptr, bytesize, MSG_NOSIGNAL);
+ if (sent <= 0) {
+ DPRINT("Pious Teardown!\n");
+ shutdown(conn, SHUT_RDWR);
+ close(conn);
+ conn = -1;
+ flag_conn = 0;
+ }
+ }
(void)stream;
- return bytesize;
+ return bytesize;
}
static int prepare_tcp_dream(const char *ip, unsigned short port) {
- int err = -1;
- struct sockaddr_in lob;
- WHOAMI;
+ int err = -1;
+ struct sockaddr_in lob;
+ WHOAMI;
- sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
- if (sock < 0)
- goto ERR_SOCK;
+ sock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
+ if (sock < 0)
+ goto ERR_SOCK;
- lob.sin_family = AF_INET;
- lob.sin_port = htons(port);
- lob.sin_addr.s_addr = inet_addr(ip);
+ lob.sin_family = AF_INET;
+ lob.sin_port = htons(port);
+ lob.sin_addr.s_addr = inet_addr(ip);
- err = bind(sock, (const struct sockaddr*) &lob, sizeof lob);
+ err = bind(sock, (const struct sockaddr*) &lob, sizeof lob);
- if (err < 0)
- goto ERR_BIND;
+ if (err < 0)
+ goto ERR_BIND;
- err = listen(sock, 5);
+ err = listen(sock, 5);
- if (err < 0)
- goto ERR_LSTN;
+ if (err < 0)
+ goto ERR_LSTN;
- flag_conn = 0;
- conn = -1;
- err = 0;
+ flag_conn = 0;
+ conn = -1;
+ err = 0;
- goto ERR_SUCC;
+ goto ERR_SUCC;
ERR_LSTN:
ERR_BIND:
- close(sock);
+ close(sock);
ERR_SOCK:
ERR_SUCC:
- return err;
+ return err;
}
static void cleanup_tcp_dream(void){
- WHOAMI;
- if (conn>=0){
- shutdown(conn, SHUT_RDWR);
- close(conn);
- conn = -1;
- flag_conn = 0;
- }
- close(sock);
+ WHOAMI;
+ if (conn>=0){
+ shutdown(conn, SHUT_RDWR);
+ close(conn);
+ conn = -1;
+ flag_conn = 0;
+ }
+ close(sock);
}
#else
static void prepare_tcp_dream(void){}
size_t fetch_send(void *ptr, size_t size, size_t nmemb, void *stream) {
- return (size * nmemb);
+ return (size * nmemb);
}
#endif
int curly_init(void) {
- CURLcode cc;
- WHOAMI;
+ CURLcode cc;
+ WHOAMI;
- cc = curl_global_init(CURL_GLOBAL_NOTHING);
- if (cc != CURLE_OK)
- return -1;
- return 0;
+ cc = curl_global_init(CURL_GLOBAL_NOTHING);
+ if (cc != CURLE_OK)
+ return -1;
+ return 0;
}
void curly_cleanup(void) {
- WHOAMI;
- curl_global_cleanup();
+ WHOAMI;
+ curl_global_cleanup();
}
static CURL *sch;
int curly_stream_init(const char *ip, unsigned short port) {
- int err;
+ int err;
- WHOAMI;
+ WHOAMI;
- sch = curl_easy_init();
- bufsize = BSIZE;
+ sch = curl_easy_init();
+ bufsize = BSIZE;
//TODO error handling
- err = prepare_tcp_dream(ip, port);
+ err = prepare_tcp_dream(ip, port);
- return (sch != NULL && 0 == err);
+ return (sch != NULL && 0 == err);
}
void curly_stream_cleanup(void) {
- WHOAMI;
+ WHOAMI;
- if (sch)
- curl_easy_cleanup(sch);
+ if (sch)
+ curl_easy_cleanup(sch);
- cleanup_tcp_dream();
- sch = NULL;
+ cleanup_tcp_dream();
+ sch = NULL;
}
#ifdef USE_TC7200_WORKAROUND
#endif
int curly_stream(const char *from_url, unsigned long duration) {
- CURLcode cc = CURLE_COULDNT_CONNECT;
- int err = -1;
- double abps, size;
+ CURLcode cc = CURLE_COULDNT_CONNECT;
+ int err = -1;
+ double abps, size;
+#ifdef USE_TC7200_WORKAROUND
+ static int tc7200_deathcounter = 0;
+#endif
#ifdef USE_TC7200_WORKAROUND
static int tc7200_deathcounter = 0;
#endif
- WHOAMI;
+ WHOAMI;
#ifdef USE_TCP
- //when we don't have a client don't actually stream anything
- //but try to take just as long
- time_t st = time(NULL);
+ //when we don't have a client don't actually stream anything
+ //but try to take just as long
+ time_t st = time(NULL);
while (conn < 0 && (unsigned long)(time(NULL)-st) < duration) {
- conn = accept(sock, NULL, NULL);
- usleep(1);
- }
+ conn = accept(sock, NULL, NULL);
+ usleep(1);
+ }
- if (conn < 0){
- abps = 0;
- size = 0;
- cc = CURLE_OK;
- goto FAKED;
- }
+ if (conn < 0){
+ abps = 0;
+ size = 0;
+ cc = CURLE_OK;
+ goto FAKED;
+ }
#endif
- if (!sch)
- goto OUT;
+ if (!sch)
+ goto OUT;
- cc = curl_easy_setopt(sch, CURLOPT_URL, from_url);
- if (CURLE_OK != cc)
- goto OUT;
+ cc = curl_easy_setopt(sch, CURLOPT_URL, from_url);
+ if (CURLE_OK != cc)
+ goto OUT;
#ifdef USE_TCP
- cc = curl_easy_setopt(sch, CURLOPT_WRITEFUNCTION, fetch_send);
+ cc = curl_easy_setopt(sch, CURLOPT_WRITEFUNCTION, fetch_send);
#else
- cc = curl_easy_setopt(sch, CURLOPT_WRITEDATA, stdout);
+ cc = curl_easy_setopt(sch, CURLOPT_WRITEDATA, stdout);
#endif
- if (CURLE_OK != cc)
- goto OUT;
+ if (CURLE_OK != cc)
+ goto OUT;
- curl_easy_setopt(sch, CURLOPT_BUFFERSIZE, bufsize);
+ curl_easy_setopt(sch, CURLOPT_BUFFERSIZE, bufsize);
#ifdef USE_TC7200_WORKAROUND
//this is to work around a fucked up tc7200 router
#endif
#ifdef DEBUG
- curl_easy_setopt(sch, CURLOPT_VERBOSE, 1L);
+ curl_easy_setopt(sch, CURLOPT_VERBOSE, 1L);
#endif
- curl_easy_setopt(sch, CURLOPT_TIMEOUT, 6*duration); //better than never timing out
+ curl_easy_setopt(sch, CURLOPT_TIMEOUT, 6*duration); //better than never timing out
- cc = curl_easy_perform(sch);
+ cc = curl_easy_perform(sch);
- if (CURLE_OK != cc)
- goto OUT;
+ if (CURLE_OK != cc)
+ goto OUT;
- cc = curl_easy_getinfo(sch,CURLINFO_SIZE_DOWNLOAD, &size);
- cc |= curl_easy_getinfo(sch,CURLINFO_SPEED_DOWNLOAD, &abps);
+ cc = curl_easy_getinfo(sch,CURLINFO_SIZE_DOWNLOAD, &size);
+ cc |= curl_easy_getinfo(sch,CURLINFO_SPEED_DOWNLOAD, &abps);
FAKED:
- if (CURLE_OK == cc)
- printf("%8.0f bytes @ %4.2f KB/s (%lu real seconds)\n", size, abps / 1000.0, time(NULL)-st);
+ if (CURLE_OK == cc)
+ printf("%8.0f bytes @ %4.2f KB/s (%lu real seconds)\n", size, abps / 1000.0, time(NULL)-st);
- err = 0;
+ err = 0;
OUT:
- return err;
+ return err;
}
#endif
- CURL *ch = NULL;
- CURLcode cc;
+ CURL *ch = NULL;
+ CURLcode cc;
#ifdef USE_STREAM
- FILE *f;
+ FILE *f;
#endif
- int err = -1;
- WHOAMI;
+ int err = -1;
+ WHOAMI;
#ifdef USE_STREAM
- f = fopen(to_file, "w");
+ f = fopen(to_file, "w");
- if (!f)
- goto OUT;
+ if (!f)
+ goto OUT;
#endif
- /*
- if (sch)
- ch = sch;
- else
- */
+ /*
+ if (sch)
+ ch = sch;
+ else
+ */
- ch = curl_easy_init();
+ ch = curl_easy_init();
- if (!ch)
- goto OUT;
+ if (!ch)
+ goto OUT;
- cc = curl_easy_setopt(ch, CURLOPT_URL, from_url);
- if (CURLE_OK != cc)
- goto OUT;
+ cc = curl_easy_setopt(ch, CURLOPT_URL, from_url);
+ if (CURLE_OK != cc)
+ goto OUT;
WHOAMI;
cc = curl_easy_perform(ch);
- if (CURLE_OK != cc)
- goto OUT;
+ if (CURLE_OK != cc)
+ goto OUT;
- err = 0;
+ err = 0;
OUT:
#ifdef USE_STREAM
if (f)
- fclose(f);
+ fclose(f);
#endif
- //if (ch && ch!=sch) curl_easy_cleanup(ch);
+ //if (ch && ch!=sch) curl_easy_cleanup(ch);
- if (ch)
- curl_easy_cleanup(ch);
+ if (ch)
+ curl_easy_cleanup(ch);
- return err;
+ return err;
}
int curly_is_connected(void){
- WHOAMI;
+ WHOAMI;
#ifdef USE_TCP
- return flag_conn;
+ return flag_conn;
#else
- return 1;
+ return 1;
#endif
}
}
struct item {
- char url[1024];
- unsigned int hash;
- //will be set to 1 after streamed
- int done;
- // will be set to 1 when it can be purged from the list
- // this is true when done is 1 and after the last refresh round
- // this hash was no longer present in the m3u8
- int purge;
- struct item *next;
- unsigned long duration;
- int is_streamlist;
- int bandwidth;
+ char url[1024];
+ unsigned int hash;
+ //will be set to 1 after streamed
+ int done;
+ // will be set to 1 when it can be purged from the list
+ // this is true when done is 1 and after the last refresh round
+ // this hash was no longer present in the m3u8
+ int purge;
+ struct item *next;
+ unsigned long duration;
+ int is_streamlist;
+ int bandwidth;
};
static void *zalloc(size_t size) {
- void *ptr;
+ void *ptr;
- WHOAMI;
+ WHOAMI;
- ptr = malloc(size);
- if (ptr)
- memset(ptr, 0, size);
+ ptr = malloc(size);
+ if (ptr)
+ memset(ptr, 0, size);
- return ptr;
+ return ptr;
}
static void print_list(void) {
#ifdef DEBUG
- struct item *n = head;
- int i = 0;
+ struct item *n = head;
+ int i = 0;
- WHOAMI;
+ WHOAMI;
- while (n != NULL) {
- DPRINT("[%d] %s:%lu:%X:%d:%d\n", ++i, n->url, n->duration, n->hash, n->done,
- n->purge);
- n = n->next;
- }
+ while (n != NULL) {
+ DPRINT("[%d] %s:%lu:%X:%d:%d\n", ++i, n->url, n->duration, n->hash, n->done,
+ n->purge);
+ n = n->next;
+ }
#endif
}
struct item *find_hash(unsigned int hash) {
- struct item *n = head;
+ struct item *n = head;
- WHOAMI;
+ WHOAMI;
- while (n != NULL) {
- if (n->hash == hash)
- break;
- n = n->next;
- }
- return n;
+ while (n != NULL) {
+ if (n->hash == hash)
+ break;
+ n = n->next;
+ }
+ return n;
}
static int compute_hash(const char *s) {
- int hash = 0;
- unsigned char bcc = 0;
-
- WHOAMI;
-
- while (*s) {
- bcc ^= *s;
- hash ^= bcc;
- hash <<= 2;
- s++;
- }
- return hash;
+ int hash = 0;
+ unsigned char bcc = 0;
+
+ WHOAMI;
+
+ while (*s) {
+ bcc ^= *s;
+ hash ^= bcc;
+ hash <<= 2;
+ s++;
+ }
+ return hash;
}
static void purge_run(int killemall) {
- struct item *n;
+ struct item *n;
- WHOAMI;
+ WHOAMI;
//purge here
while (head && (head->purge || killemall)) {
- DPRINT("Purging %s:%X:%d:%d\n", head->url, head->hash, head->done,
- head->purge);
- n = head;
- head = head->next;
- free(n);
- }
+ DPRINT("Purging %s:%X:%d:%d\n", head->url, head->hash, head->done,
+ head->purge);
+ n = head;
+ head = head->next;
+ free(n);
+ }
}
static void purge_prepare(void) {
- struct item *n;
+ struct item *n;
- WHOAMI;
+ WHOAMI;
- //mark done entries as ok to purge
- //don't mark curr as ok to purge because we might
- //still need it to advance to its next in emulate_stream()
- for (n = head; n && n->done && n!=curr; n = n->next){
- n->purge = 1;
- }
+ //mark done entries as ok to purge
+ //don't mark curr as ok to purge because we might
+ //still need it to advance to its next in emulate_stream()
+ for (n = head; n && n->done && n!=curr; n = n->next){
+ n->purge = 1;
+ }
}
void emulate_stream(void) {
- int err;
-
- WHOAMI;
-
- if (!curr) {
- //this should never happen, no reasonable way to recover
- fprintf(stderr,"curr is NULL, bailing out\n");
- in_game = 0;
- return;
- }
-
- if (curr->done){
- if (curr->next){
- curr = curr->next;
- } else {
- //we end up here if we are faster than the server can produce
- if (!live) {
- in_game = 0;
- } else {
- DPRINT("sleeping\n");
- sleep(1);
- }
- return;
- }
- }
-
- do {
- printf("Streaming %s (%lu)\n", curr->url, curr->duration);
+ int err;
+
+ WHOAMI;
+
+ if (!curr) {
+ //this should never happen, no reasonable way to recover
+ fprintf(stderr,"curr is NULL, bailing out\n");
+ in_game = 0;
+ return;
+ }
+
+ if (curr->done){
+ if (curr->next){
+ curr = curr->next;
+ } else {
+ //we end up here if we are faster than the server can produce
+ if (!live) {
+ in_game = 0;
+ } else {
+ DPRINT("sleeping\n");
+ sleep(1);
+ }
+ return;
+ }
+ }
+
+ do {
+ printf("Streaming %s (%lu)\n", curr->url, curr->duration);
#if 1
- err = curly_stream(curr->url, curr->duration);
+ err = curly_stream(curr->url, curr->duration);
#else
- err = -1; curly_fake_stream();
+ err = -1; curly_fake_stream();
#endif
- if (err){
- DPRINT("Streaming failed\n");
- }
+ if (err){
+ DPRINT("Streaming failed\n");
+ }
- } while (0);
+ } while (0);
- curr->done = 1;
+ curr->done = 1;
}
#ifdef USE_STREAM
#endif
#ifdef USE_STREAM
- FILE *f;
+ FILE *f;
#endif
- char buf[1024];
- struct item *n;
- struct item *p;
- unsigned int thash;
- unsigned long lval;
+ char buf[1024];
+ struct item *n;
+ struct item *p;
+ unsigned int thash;
+ unsigned long lval;
- int plist,pid,bw;
+ int plist,pid,bw;
- const char *v;
- MTAG m;
- int urloff;
+ const char *v;
+ MTAG m;
+ int urloff;
- WHOAMI;
+ WHOAMI;
- plist = pid = bw = 0;
+ plist = pid = bw = 0;
- DPRINT("Reloading M3U8\n");
+ DPRINT("Reloading M3U8\n");
#ifdef USE_STREAM
f = fopen(from_file, "r");
#endif
- if (!f)
- return -1;
+ if (!f)
+ return -1;
#ifdef USE_STREAM
- while (fgets(buf, sizeof buf, f)) {
+ while (fgets(buf, sizeof buf, f)) {
#else
- while (mgets(buf, sizeof buf, f)) {
+ while (mgets(buf, sizeof buf, f)) {
#endif
- if (buf[strlen(buf) - 1] == '\n')
- buf[strlen(buf) - 1] = 0;
- if (buf[strlen(buf) - 1] == '\r')
- buf[strlen(buf) - 1] = 0;
-
- m = m3u8_parse(buf, &v);
-
- if (M_EXTINF == m){
- m3u8_get_property(P_DURATION, v, &lval);
- }
- if (M_X_ENDLIST == m){
- printf("This is not a live stream!\n");
- live = 0;
- }
- if (M_X_STREAM_INF == m){
- //playlist entry detected;
- plist = 1;
- m3u8_get_property(P_BANDWIDTH, v, &lval);
- bw = lval;
- m3u8_get_property(P_PROGRAM_ID, v, &lval);
- pid = lval;
- printf ("PID: %d BW:%d\n",pid, bw);
- }
-
- if (M_URL != m) continue;
-
- /*
- position to add will be determined by the hash of new entry vs hashes already in the list
- that is...all new hashes will be added at tail unless this entry's hash is already in the list
- the entry is not then not added but the next new one will be added after this one
- this will in degenerate into adding at tail if m3u8 refresh interval is too long (old entries purged)
- */
-
- thash = compute_hash(buf);
-
- if ((p = find_hash(thash))) {
- //element is still in the newest m3u8
- //hold onto it some longer
- p->purge = 0;
- continue;
- }
-
- n = zalloc(sizeof(struct item));
- n->hash = thash;
- n->is_streamlist = plist;
- n->bandwidth = bw;
-
- urloff = 0;
-
- if (strncmp(buf,"http://",7)){
- strcpy(n->url,urlbase);
- urloff = strlen(urlbase);
- }
-
- strcpy(n->url+urloff, buf);
- n->duration = lval;
-
- if (!head) {
- //XXX curr is always first, which is not what we want in certain scenarios
- head = tail = curr = n;
- } else {
- if (!p || p == tail) { //hash not found
- tail->next = n;
- tail = n;
- } else {
- n->next = p->next;
- p->next = n;
- }
- }
- }
+ if (buf[strlen(buf) - 1] == '\n')
+ buf[strlen(buf) - 1] = 0;
+ if (buf[strlen(buf) - 1] == '\r')
+ buf[strlen(buf) - 1] = 0;
+
+ m = m3u8_parse(buf, &v);
+
+ if (M_EXTINF == m){
+ m3u8_get_property(P_DURATION, v, &lval);
+ }
+ if (M_X_ENDLIST == m){
+ printf("This is not a live stream!\n");
+ live = 0;
+ }
+ if (M_X_STREAM_INF == m){
+ //playlist entry detected;
+ plist = 1;
+ m3u8_get_property(P_BANDWIDTH, v, &lval);
+ bw = lval;
+ m3u8_get_property(P_PROGRAM_ID, v, &lval);
+ pid = lval;
+ printf ("PID: %d BW:%d\n",pid, bw);
+ }
+
+ if (M_URL != m) continue;
+
+ /*
+ position to add will be determined by the hash of new entry vs hashes already in the list
+ that is...all new hashes will be added at tail unless this entry's hash is already in the list
+ the entry is not then not added but the next new one will be added after this one
+ this will in degenerate into adding at tail if m3u8 refresh interval is too long (old entries purged)
+ */
+
+ thash = compute_hash(buf);
+
+ if ((p = find_hash(thash))) {
+ //element is still in the newest m3u8
+ //hold onto it some longer
+ p->purge = 0;
+ continue;
+ }
+
+ n = zalloc(sizeof(struct item));
+ n->hash = thash;
+ n->is_streamlist = plist;
+ n->bandwidth = bw;
+
+ urloff = 0;
+
+ if (strncmp(buf,"http://",7)){
+ strcpy(n->url,urlbase);
+ urloff = strlen(urlbase);
+ }
+
+ strcpy(n->url+urloff, buf);
+ n->duration = lval;
+
+ if (!head) {
+ //XXX curr is always first, which is not what we want in certain scenarios
+ head = tail = curr = n;
+ } else {
+ if (!p || p == tail) { //hash not found
+ tail->next = n;
+ tail = n;
+ } else {
+ n->next = p->next;
+ p->next = n;
+ }
+ }
+ }
#ifdef USE_STREAM
- fclose(f);
+ fclose(f);
#endif
- return 0;
+ return 0;
}
const char *choose_url(void){
- struct item *n;
- const char *u;
- int bw = 0;
-
- WHOAMI;
-
- n = head;
- u = head->url;
- while (n){
- //choose first matching url, >= to choose last, but could lead to problems, allow user selection!
- if (n->bandwidth>bw) {u = n->url; bw=n->bandwidth; }
- n->done = 1;
- n->purge = 1;
- n=n->next;
- }
-
- printf ("Final BW: %d | URL: %s\n",bw, u);
- return u;
+ struct item *n;
+ const char *u;
+ int bw = 0;
+
+ WHOAMI;
+
+ n = head;
+ u = head->url;
+ while (n){
+ //choose first matching url, >= to choose last, but could lead to problems, allow user selection!
+ if (n->bandwidth>bw) {u = n->url; bw=n->bandwidth; }
+ n->done = 1;
+ n->purge = 1;
+ n=n->next;
+ }
+
+ printf ("Final BW: %d | URL: %s\n",bw, u);
+ return u;
}
static void reset_base(char *base, char *url){
- WHOAMI;
+ WHOAMI;
- strcpy(base,url);
- //TODO risky dice
- *(strrchr(base, '/')+1) = 0;
+ strcpy(base,url);
+ //TODO risky dice
+ *(strrchr(base, '/')+1) = 0;
}
int main(int argc, char *argv[]) {
- time_t last, now;
+ time_t last, now;
- int refreshed;
- int refresh_period = 20;
- char url[1024];
- char base[1024];
+ int refreshed;
+ int refresh_period = 20;
+ char url[1024];
+ char base[1024];
- if (argc>1)
- strcpy(url, argv[1]);
- else
- strcpy(url, QVC_MASTER_M3U8);
+ if (argc>1)
+ strcpy(url, argv[1]);
+ else
+ strcpy(url, QVC_MASTER_M3U8);
- printf ("Master URL: %s\n",url);
+ printf ("Master URL: %s\n",url);
- reset_base(base, url);
+ reset_base(base, url);
- curly_init();
+ curly_init();
curly_stream_init("0.0.0.0",7120);
- last = now = 0;
- head = tail = curr = NULL;
- live = in_game = 1;
+ last = now = 0;
+ head = tail = curr = NULL;
+ live = in_game = 1;
signal(SIGTERM, handle_signal);
signal(SIGINT, handle_signal);
- while (in_game) {
- now = time(NULL);
- if (live && now-last>=refresh_period) {
- DPRINT("Refreshing M3U8 after %d real seconds\n",(int)(last?now-last:0));
+ while (in_game) {
+ now = time(NULL);
+ if (live && now-last>=refresh_period) {
+ DPRINT("Refreshing M3U8 after %d real seconds\n",(int)(last?now-last:0));
#ifdef USE_STREAM
- refreshed = (0 == curly_refresh_m3u8(url, PLS));
+ refreshed = (0 == curly_refresh_m3u8(url, PLS));
#else
MFILE *f = mopen(NULL, 0, "w+");
refreshed = (0 == curly_refresh_m3u8(url, f));
#endif
- if (refreshed) {
- last = now = time(NULL);
- purge_prepare();
+ if (refreshed) {
+ last = now = time(NULL);
+ purge_prepare();
#ifdef USE_STREAM
- if (0 == reload_m3u8(PLS, base)) {
+ if (0 == reload_m3u8(PLS, base)) {
#else
if (0 == reload_m3u8(f, base)) {
mclose(f);
#endif
- refreshed = 0;
+ refreshed = 0;
purge_run(0);
- print_list();
+ print_list();
- if (head->is_streamlist){
- strcpy (url, choose_url());
- reset_base(base, url);
- curr = NULL; //so purge will not spare it
+ if (head->is_streamlist){
+ strcpy (url, choose_url());
+ reset_base(base, url);
+ curr = NULL; //so purge will not spare it
purge_run(0);
- last = 0;
- continue;
- }
- }
- } else {
- DPRINT ("Could not load M3U8 from %s!\n",url);
- sleep (1);
- }
- }
+ last = 0;
+ continue;
+ }
+ }
+ } else {
+ DPRINT ("Could not load M3U8 from %s!\n",url);
+ sleep (1);
+ }
+ }
- emulate_stream();
+ emulate_stream();
- }
+ }
purge_run(1);
- curly_stream_cleanup();
- curly_cleanup();
- return 0;
+ curly_stream_cleanup();
+ curly_cleanup();
+ return 0;
}