/* This utility pick a record file produced by redir --record and play it back to a server. It uses the timestamp to simulate the original rate. It sends the output to stdout Written by Jacques Gélinas (jack@solucorp.qc.ca). License under the GPL. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static long long getnow () { struct timeval tv; gettimeofday (&tv,NULL); return tv.tv_sec *(long long)1000000 + tv.tv_usec; } /* Wait some seconds and monitor the socket for input */ static void playback_wait (int sock, long long usecs) { long long end = getnow()+usecs; while (getnow()<=end){ fd_set in; struct timeval timeout; FD_ZERO (&in); FD_SET (sock,&in); timeout.tv_sec = 1; timeout.tv_usec = 0; // printf ("wait %d delai=%ld\n",seconds,end-time(NULL)); select (sock+1,&in,NULL,NULL,&timeout); if (FD_ISSET(sock,&in)){ char buf[1000000]; int bytes = read (sock,buf,sizeof(buf)); if (bytes > 0) write (1,buf,bytes); } } } static void playback_file (int sock, const char *file, bool burst) { FILE *fin = fopen (file,"r"); if (fin == NULL){ fprintf (stderr,"Can't open file %s (%s)\n",file ,strerror(errno)); }else{ fprintf (stderr,"Playing file %s\n",file); struct timeval last; last.tv_sec = last.tv_usec = 0; char head[26]; while (fread(head,1,26,fin)==26){ struct timeval ti; size_t bytes; char buf[4096]; head[25] = '\0'; if (sscanf (head+3,"%08lx.%08lx:%u",&ti.tv_sec,&ti.tv_usec,&bytes)==3){ assert(bytes<=4096); fprintf (stderr,"Reading %u bytes\n",bytes); if (fread(buf,1,bytes,fin)==bytes){ if (last.tv_sec != 0){ long long t1 = (long long)last.tv_sec *1000000 + last.tv_usec; long long t2 = (long long)ti.tv_sec *1000000 + ti.tv_usec; playback_wait (sock,t2-t1); } last = ti; printf ("--------------------\n"); fflush(stdout); write (1,buf,bytes); printf ("====================\n"); fflush(stdout); write (sock,buf,bytes); }else{ fprintf (stderr,"Short record\n"); break; } }else{ fprintf (stderr,"Invalid header: %s\n",head); break; } } } fclose (fin); } int main (int argc, char *argv[]) { glocal int ret = -1; glocal const char *host = NULL; glocal const char *port = NULL; glocal bool burst = true; glocal.ret = (argc,argv); extern const char *version; setproginfo ("playback",version ,"playback one or more file recorded by redir --record"); setarg ('b',"burst","Do not wait",glocal.burst,false); setarg ('h',"host","Connect to host",glocal.host,true); setarg ('p',"port","Connect to port",glocal.port,true); glocal int argc = argc; glocal char **argv = argv; (glocal.host,glocal.port,10); for (int i=0; i return 0; return glocal.ret; }