#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 <netdb.h>
#include "http.h"
#include "mcast.h"
+#include "sap.h"
+#include "common.h"
-#define CHUNKSIZE 8192
+#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) {
- perror("recv");
- exit(EXIT_FAILURE);
+ 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);
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 outfile\n", argv[0]);
+ fprintf(stderr,"Syntax: %s URL|SAPServiceName duration_in_minutes outfile\n", argv[0]);
exit(EXIT_FAILURE);
}
+ if (!is_url(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);
}