handle IPv6 sources
[record-dvb] / record-dvb.c
CommitLineData
5c2e3e44 1#include <features.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/time.h>
5#include <time.h>
6#include <sys/socket.h>
7#include <sys/types.h>
8#include <sys/stat.h>
89ec024f 9#include <sys/select.h>
5c2e3e44 10#include <fcntl.h>
11#include <unistd.h>
12#include <strings.h>
c0833e33 13#include <netdb.h>
5c2e3e44 14
15#include "http.h"
16#include "mcast.h"
8447845f 17#include "sap.h"
c0833e33 18#include "common.h"
5c2e3e44 19
657d048d 20#define CHUNKSIZE 3000
21#define GTOD_INTERVAL 100
22#define MAX_ERROR_SLEEP 60
5c2e3e44 23
24void record(int(*open_fn)(char *), char *url, char *outfile, int duration)
25{
26 struct timeval start, curr;
4710a9f8 27 int bytes, recvd, written, count = 0;
34d3d284 28 int error_sleep = 0;
5c2e3e44 29 char buffer[CHUNKSIZE];
5c2e3e44 30 int in, out;
89ec024f 31 fd_set rfds;
32 struct timeval tv;
33 int retval;
5c2e3e44 34
4710a9f8 35 if ((in = (*open_fn)(url)) < 0) {
36 fprintf(stderr,"Can't open url %s!\n",url);
5c2e3e44 37 exit(EXIT_FAILURE);
38 }
39
4710a9f8 40 if ((out = open(outfile, O_CREAT|O_TRUNC|O_WRONLY|O_LARGEFILE, 00644)) < 0) {
41 perror("open");
5c2e3e44 42 exit(EXIT_FAILURE);
43 }
44
45 printf("Recording from %s for %d seconds...\n", url, duration);
46
47 gettimeofday(&start, NULL);
6ac47f90 48 curr = start;
5c2e3e44 49
50 do {
34d3d284 51 if (error_sleep) {
52 sleep(error_sleep);
53 printf("Reconnecting... ");
b973e875 54 if ((in = (*open_fn)(url)) < 0) {
657d048d 55 if (error_sleep < MAX_ERROR_SLEEP)
34d3d284 56 error_sleep *= 2;
57
657d048d 58 if (error_sleep > MAX_ERROR_SLEEP)
59 error_sleep = MAX_ERROR_SLEEP;
60
34d3d284 61 printf("failed\n");
b973e875 62 continue;
34d3d284 63 } else {
64 printf("succeeded\n");
65 error_sleep = 0;
b973e875 66 }
5c2e3e44 67 }
34d3d284 68
89ec024f 69 FD_ZERO(&rfds);
70 FD_SET(in, &rfds);
71
72 tv.tv_sec = 1;
73 tv.tv_usec = 0;
74
75 if ((retval = select(in + 1, &rfds, NULL, NULL, &tv)) == -1) {
76 error_sleep = 1;
77 continue;
78 }
79
80 if (!retval) {
81 gettimeofday(&curr, NULL);
82 continue;
83 }
84
34d3d284 85 if ((recvd = recv(in, buffer, CHUNKSIZE, 0)) < 1) {
86 error_sleep = 1;
87 continue;
88 }
5c2e3e44 89 written = 0;
90 do {
4710a9f8 91 if ((bytes = write(out, buffer, recvd-written)) < 0) {
5c2e3e44 92 perror("write");
93 exit(EXIT_FAILURE);
94 }
4710a9f8 95 written += bytes;
96 } while(written < recvd);
6ac47f90 97
4710a9f8 98 if (!(++count % GTOD_INTERVAL))
6ac47f90 99 gettimeofday(&curr, NULL);
5c2e3e44 100 } while (curr.tv_sec < start.tv_sec+duration);
101
102 close(out);
103 close(in);
104 shutdown(in, SHUT_RDWR);
105}
106
107int main(int argc, char **argv)
108{
109 int duration;
110 char *url;
111 char *outfile;
112 int(*open_fn)(char *);
113
114 if (argc == 4) {
115 url = argv[1];
6a3dc096 116 duration = atoi(argv[2])*60;
5c2e3e44 117 outfile = argv[3];
118 } else {
460e6d22 119 fprintf(stderr,"Syntax: %s URL duration_in_minutes outfile\n", argv[0]);
5c2e3e44 120 exit(EXIT_FAILURE);
121 }
122
c0833e33 123 if (!is_url(url)) {
8447845f 124 char *service_url;
125 if ((service_url = get_url_from_sap(url))) {
126 printf("SAP says: '%s' -> %s\n", url, service_url);
127 url = service_url;
128 }
129 }
130
5c2e3e44 131 if (is_http(url)) {
132 open_fn = &open_http;
133 } else if (is_mcast(url)) {
134 open_fn = &open_mcast;
135 } else {
8447845f 136 printf("URL '%s' not supported!\n", url);
5c2e3e44 137 exit(EXIT_FAILURE);
138 }
139
140 record(open_fn, url, outfile, duration);
141
142 return EXIT_SUCCESS;
143}
Impressum, Datenschutz