Detect speedrec in PATH.
[doldaconnect.git] / config / speedrec.c
CommitLineData
d3372da9 1#include <string.h>
2#include <stdio.h>
3#include <stdlib.h>
4#include <sys/file.h>
5#include <unistd.h>
6#include <fcntl.h>
7#include <errno.h>
8#include <time.h>
9#include <sys/poll.h>
10#include <signal.h>
11
12char buf[4096];
13volatile int eof;
14
15void sighandler(int sig)
16{
17 eof = 1;
18}
19
20int main(int argc, char **argv)
21{
22 int i;
23 int ret, fd;
24 time_t starttime, endtime;
25 long long numbytes;
26 size_t datalen;
27 struct pollfd pfd[2];
28 FILE *recfile;
29 int thisrec, numrecs, numuses, maxrec;
30 int recs[5];
31
32 if(argc < 2)
33 {
34 fprintf(stderr, "usage: speedrec recfile\n");
35 exit(1);
36 }
37 numbytes = 0;
38 starttime = endtime = 0;
39 datalen = 0;
40 eof = 0;
41 signal(SIGHUP, sighandler);
42 signal(SIGINT, sighandler);
43 signal(SIGTERM, sighandler);
44 while(1)
45 {
46 pfd[0].fd = 0;
47 if(eof || (datalen >= sizeof(buf)))
48 pfd[0].events = 0;
49 else
50 pfd[0].events = POLLIN;
51 pfd[1].fd = 1;
52 if(datalen > 0)
53 pfd[1].events = POLLOUT;
54 else
55 pfd[1].events = 0;
56 pfd[0].revents = pfd[1].revents = 0;
57 ret = poll(pfd, 2, -1);
58 if((ret < 0) && (errno != EINTR))
59 {
60 perror("cannot poll");
61 exit(1);
62 }
63 if(pfd[0].revents & (POLLIN | POLLERR | POLLHUP | POLLNVAL))
64 {
65 ret = read(0, buf + datalen, sizeof(buf) - datalen);
66 if((ret < 0) && (errno != EINTR))
67 {
68 perror("cannot read");
69 exit(1);
70 }
71 if(ret == 0)
72 eof = 1;
73 if(ret > 0)
74 {
75 datalen += ret;
76 if(starttime == 0)
77 starttime = time(NULL);
78 endtime = time(NULL);
79 }
80 numbytes += ret;
81 }
82 if(pfd[1].revents & (POLLOUT | POLLERR | POLLHUP | POLLNVAL))
83 {
84 ret = write(1, buf, datalen);
85 if((ret < 0) && (errno != EINTR))
86 {
87 perror("cannot write");
88 exit(1);
89 }
90 memmove(buf, buf + ret, datalen -= ret);
91 }
92 if(eof && (datalen == 0))
93 break;
94 }
95 if((starttime == 0) || (endtime == 0) || (endtime == starttime))
96 exit(0);
97 if(numbytes == 0)
98 exit(0);
99 thisrec = (int)(numbytes / ((long long)(endtime - starttime)));
100 if((fd = open(argv[1], O_RDWR | O_CREAT, 0666)) < 0)
101 {
102 perror(argv[1]);
103 exit(1);
104 }
105 recfile = fdopen(fd, "r+");
106 close(0);
107 close(1);
108 flock(fd, LOCK_EX);
109 if(fscanf(recfile, "%i\n", &numuses) < 1)
110 numuses = 0;
111 if(fscanf(recfile, "%i\n", &maxrec) < 1)
112 maxrec = 0;
113 if(fscanf(recfile, "%i\n", &numrecs) < 1)
114 numrecs = 0;
115 for(i = 0; i < numrecs; i++)
116 fscanf(recfile, "%i\n", &recs[i]);
117 if(numrecs == 5)
118 {
119 for(i = 0; i < 4; i++)
120 recs[i] = recs[i + 1];
121 numrecs = 4;
122 }
123 recs[numrecs++] = thisrec;
124 rewind(recfile);
125 ftruncate(fd, 0);
126 fprintf(recfile, "%i\n", numuses + 1);
127 fprintf(recfile, "%i\n", (thisrec > maxrec)?thisrec:maxrec);
128 fprintf(recfile, "%i\n", numrecs);
129 for(i = 0; i < numrecs; i++)
130 fprintf(recfile, "%i\n", recs[i]);
131 flock(fd, LOCK_UN);
132 fclose(recfile);
133 return(0);
134}