]> git.zerfleddert.de Git - record-dvb/blobdiff - record-dvb.c
enforce timeouts
[record-dvb] / record-dvb.c
index d32eba1fe0576d63a75f9c5328d6c85d7b01703b..9356348343fe4f81d20cc0cf580f8c63b95fd1f2 100644 (file)
@@ -6,52 +6,95 @@
 #include <sys/socket.h>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/select.h>
 #include <fcntl.h>
 #include <unistd.h>
 #include <strings.h>
 
 #include "http.h"
 #include "mcast.h"
+#include "sap.h"
 
-#define CHUNKSIZE 1500
+#define CHUNKSIZE      3000
+#define GTOD_INTERVAL  100
+#define MAX_ERROR_SLEEP        60
 
 void record(int(*open_fn)(char *), char *url, char *outfile, int duration)
 {
        struct timeval start, curr;
-       int bytes, written;
+       int bytes, recvd, written, count = 0;
+       int error_sleep = 0;
        char buffer[CHUNKSIZE];
-       int i;
        int in, out;
+       fd_set rfds;
+       struct timeval tv;
+       int retval;
 
-       if ((out = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_LARGEFILE, 00644)) < 0) {
-               perror("open");
+       if ((in = (*open_fn)(url)) < 0) {
+               fprintf(stderr,"Can't open url %s!\n",url);
                exit(EXIT_FAILURE);
        }
 
-       if ((in = (*open_fn)(url)) < 0) {
-               fprintf(stderr,"Can't open url %s!\n",url);
+       if ((out = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_LARGEFILE, 00644)) < 0) {
+               perror("open");
                exit(EXIT_FAILURE);
        }
 
        printf("Recording from %s for %d seconds...\n", url, duration);
 
        gettimeofday(&start, NULL);
+       curr = start;
 
        do {
-               if ((bytes = recv(in, buffer, CHUNKSIZE, 0)) < 1) {
-                       /* TODO: Insert better connection-loss recovery here */
-                       in = (*open_fn)(url);
+               if (error_sleep) {
+                       sleep(error_sleep);
+                       printf("Reconnecting... ");
+                       if ((in = (*open_fn)(url)) < 0) {
+                               if (error_sleep < MAX_ERROR_SLEEP)
+                                       error_sleep *= 2;
+
+                               if (error_sleep > MAX_ERROR_SLEEP)
+                                       error_sleep = MAX_ERROR_SLEEP;
+
+                               printf("failed\n");
+                               continue;
+                       } else {
+                               printf("succeeded\n");
+                               error_sleep = 0;
+                       }
+               }
+
+               FD_ZERO(&rfds);
+               FD_SET(in, &rfds);
+
+               tv.tv_sec = 1;
+               tv.tv_usec = 0;
+
+               if ((retval = select(in + 1, &rfds, NULL, NULL, &tv)) == -1) {
+                       error_sleep = 1;
+                       continue;
+               }
+
+               if (!retval) {
+                       gettimeofday(&curr, NULL);
+                       continue;
+               }
+
+               if ((recvd = recv(in, buffer, CHUNKSIZE, 0)) < 1) {
+                       error_sleep = 1;
+                       continue;
                }
                written = 0;
                do {
-                       if ((i = write(out, buffer, bytes-written)) < 0) {
+                       if ((bytes = write(out, buffer, recvd-written)) < 0) {
                                perror("write");
                                exit(EXIT_FAILURE);
                        }
-                       written += i;
-               } while(written < bytes);
+                       written += bytes;
+               } while(written < recvd);
 
-               gettimeofday(&curr, NULL);
+               if (!(++count % GTOD_INTERVAL))
+                       gettimeofday(&curr, NULL);
        } while (curr.tv_sec < start.tv_sec+duration);
 
        close(out);
@@ -68,19 +111,27 @@ int main(int argc, char **argv)
 
        if (argc == 4) {
                url = argv[1];
-               duration = atol(argv[2])*60;
+               duration = atoi(argv[2])*60;
                outfile = argv[3];
        } else {
                fprintf(stderr,"Syntax: %s URL duration_in_minutes outfile\n", argv[0]);
                exit(EXIT_FAILURE);
        }
 
+       if (!is_http(url) && !is_mcast(url)) {
+               char *service_url;
+               if ((service_url = get_url_from_sap(url))) {
+                       printf("SAP says: '%s' -> %s\n", url, service_url);
+                       url = service_url;
+               }
+       }
+
        if (is_http(url)) {
                open_fn = &open_http;
        } else if (is_mcast(url)) {
                open_fn = &open_mcast;
        } else {
-               printf("URL %s not supported!\n", url);
+               printf("URL '%s' not supported!\n", url);
                exit(EXIT_FAILURE);
        }
 
Impressum, Datenschutz