ccnfilewatch.c
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <errno.h>
00024 #include <fcntl.h>
00025 #include <inttypes.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <string.h>
00029 #include <time.h>
00030 #include <unistd.h>
00031 #include <sys/poll.h>
00032 #include <sys/stat.h>
00033 #include <sys/time.h>
00034
00035 static int
00036 usage(const char *progname) {
00037 fprintf(stderr, "%s" " wrong args\n", progname);
00038 exit(1);
00039 }
00040
00041 static int
00042 statchanged(struct stat *prev, struct stat *curr)
00043 {
00044 if (curr->st_size != prev->st_size)
00045 return(1);
00046 if (curr->st_mtime != prev->st_mtime)
00047 return(1);
00048 return(0);
00049 }
00050
00051 static void
00052 printstat(FILE *out, struct stat *s)
00053 {
00054 struct timeval now;
00055 time_t sec;
00056 unsigned usec;
00057
00058 gettimeofday(&now, NULL);
00059 sec = s->st_mtime;
00060 usec = 0;
00061 if (now.tv_sec <= s->st_mtime + 1) {
00062
00063 sec = now.tv_sec;
00064 usec = now.tv_usec;
00065 }
00066 fprintf(out, "%lu.%06u d=%u,i=%lu %ju\n",
00067 (unsigned long)sec,
00068 usec,
00069 (unsigned)s->st_dev,
00070 (unsigned long)s->st_ino,
00071 (uintmax_t)(s->st_size)
00072 );
00073 }
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095 #define FW_NBUF 4
00096 int
00097 ccn_filewatch(const char *path,
00098 FILE *out,
00099 off_t minsize,
00100 off_t maxsize,
00101 time_t maxsec,
00102 int msecstable,
00103 int msecpoll)
00104 {
00105 int fd = -1;
00106 int res = 0;
00107 unsigned i = 0;
00108 const unsigned int nbuf = FW_NBUF;
00109 struct stat stats[FW_NBUF];
00110 struct stat *curr = NULL;
00111 struct stat *prev = NULL;
00112 struct stat statname = {0};
00113 struct pollfd dummy[1];
00114 time_t elapsed = 0;
00115 unsigned elapsedms = 0;
00116 unsigned stablems = 0;
00117
00118 memset(stats, 0, sizeof(stats));
00119 memset(dummy, 0, sizeof(dummy));
00120 errno = EINVAL;
00121 if (msecpoll < 1)
00122 return(-1);
00123 if (msecstable < 1)
00124 return(-1);
00125 fd = open(path, O_RDONLY, 0);
00126 if (fd < 0)
00127 return(-1);
00128 for (i = 0;;) {
00129 curr = &(stats[i % nbuf]);
00130 res = fstat(fd, curr);
00131 if (res == -1)
00132 break;
00133 if (prev == NULL || statchanged(prev, curr)) {
00134 printstat(out, curr);
00135 prev = curr;
00136 stablems = 0;
00137 if (maxsize != 0 && curr->st_size > maxsize) {
00138 res = -2;
00139 break;
00140 }
00141 i++;
00142 }
00143 else {
00144 stablems += msecpoll;
00145 if (stablems >= msecstable && curr->st_size >= minsize) {
00146 res = 0;
00147 break;
00148 }
00149 }
00150 res = poll(dummy, 0, msecpoll);
00151 if (res != 0) abort();
00152 elapsedms += msecpoll;
00153 if (elapsed + elapsedms / 1000 > maxsec) {
00154 res = -3;
00155 break;
00156 }
00157 if (elapsedms >= 3000) {
00158 elapsed += elapsedms / 1000;
00159 elapsedms %= 1000;
00160 res = stat(path, &statname);
00161 if (res < 0 ||
00162 statname.st_dev != curr->st_dev ||
00163 statname.st_ino != curr->st_ino) {
00164 res = -4;
00165 break;
00166 }
00167 fflush(out);
00168 }
00169 }
00170 close(fd);
00171 fflush(out);
00172 return(res);
00173 }
00174
00175 int
00176 main(int argc, char** argv)
00177 {
00178 int opt = 0;
00179 int res = 0;
00180 const char *path = NULL;
00181 FILE *out = stdout;
00182 off_t minsize = 1;
00183 off_t maxsize = 0;
00184 time_t maxsec = 600;
00185 int msecstable = 5000;
00186 int msecpoll = 100;
00187
00188 while ((opt = getopt(argc, argv, "h")) != -1) {
00189 switch (opt) {
00190 case 'a':
00191 break;
00192 case 'h':
00193 default:
00194 usage(argv[0]);
00195 }
00196 }
00197 if (argv[optind] == NULL || argv[optind + 1] != NULL)
00198 usage(argv[0]);
00199 path = argv[optind];
00200 res = ccn_filewatch(path,
00201 out,
00202 minsize,
00203 maxsize,
00204 maxsec,
00205 msecstable,
00206 msecpoll);
00207 if (res == -1)
00208 perror(path);
00209 exit(-res);
00210 }