+/*
+ * howmuchuseit.c
+ *
+ * Copyright (C) 2011
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABLILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details. You should have received a
+ * copy of the GNU General Public License along with this program; if
+ * not, write to the Free Software Foundation, Inc, 59 Temple Place -
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ */
+
+#include <sys/select.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <signal.h>
+
+#include "howmuchuseit.h"
+
+struct context {
+ FILE *fout;
+ time_t start;
+ int is_verbose;
+ int is_working;
+};
+
+struct context *g_ctx = NULL;
+
+void sig_handler(int sig);
+void now_not_working(struct context *ctx);
+
+void now_working(struct context *ctx)
+{
+ if (ctx->is_working == 0) {
+ ctx->start = time(NULL);
+ if (ctx->is_verbose) {
+ printf("now is working\n");
+ }
+ ctx->is_working = 1;
+ }
+}
+
+void now_not_working(struct context *ctx)
+{
+ time_t curtime;
+
+ if (ctx->is_working == 1) {
+ curtime = time(NULL);
+ fprintf(ctx->fout, "%ld:%ld\n", (long int)curtime, (long int)(curtime - ctx->start));
+ fflush(ctx->fout);
+ if (ctx->is_verbose) {
+ printf("now not is working\n");
+ }
+ ctx->is_working = 0;
+ }
+}
+
+
+void sig_handler(int sig)
+{
+ if (g_ctx) {
+ time_t curtime;
+
+ now_not_working(g_ctx);
+ curtime = time(NULL);
+ fprintf(g_ctx->fout, "# end at %ld\n", (long int)curtime);
+ fflush(g_ctx->fout);
+ }
+
+ exit (0);
+}
+
+int main(int argc, char *argv[])
+{
+ time_t curtime;
+ struct context ctx;
+ int inactive_time = 10;
+ int argd, fd[MAX_FD], fd_n;
+ char fd_name[MAX_FD][PATH_MAX+1];
+ int is_daemon = 0;
+ int is_verbose = 0;
+ char fd_max = -1, fd_path[PATH_MAX+1], bf[1024];
+ int i;
+
+ fd_set rfds;
+ struct timeval tv;
+ int retval;
+
+ ctx.is_working = 0;
+
+ for (argd = 1 ; argd < argc ; argd++) {
+ if (strcmp(argv[argd], "-i") == 0) {
+ if ((argd+1) < argc) {
+ inactive_time = atoi(argv[argd+1]);
+ argd++;
+ }
+ }
+ else if (strcmp(argv[argd], "-d") == 0) {
+ is_daemon = 1;
+ }
+ else if (strcmp(argv[argd], "-v") == 0) {
+ is_verbose = 1;
+ }
+ else {
+ break;
+ }
+ }
+
+ if (is_daemon) {
+ is_verbose = 0;
+ }
+
+ if (is_daemon) {
+ if (daemon(0, 0) != 0) {
+ exit(3);
+ }
+ }
+
+ for (fd_n = 0; argd < argc ; argd++, fd_n++) {
+ sprintf(fd_path, "%s/%s", EVENT_PATH, argv[argd]);
+ strcpy(fd_name[fd_n], argv[argd]);
+ if ((fd[fd_n] = open(fd_path, O_RDONLY)) == -1) {
+ exit(1);
+ }
+ if (is_verbose) {
+ printf("[%s] opened for read\n", fd_path);
+ }
+ if (fd_max < fd[fd_n]) {
+ fd_max = fd[fd_n];
+ }
+ }
+
+ if ((ctx.fout = fopen(OUTPUT_FILE, "a")) == NULL) {
+ exit(2);
+ }
+
+ curtime = time(NULL);
+ fprintf(ctx.fout, "# start at %ld\n", (long int)curtime);
+ fflush(ctx.fout);
+
+ ctx.is_verbose = is_verbose;
+ g_ctx = &ctx;
+
+ signal(SIGINT, sig_handler);
+ signal(SIGTERM, sig_handler);
+
+ if (is_verbose) {
+ printf("[%s] opened for append\n", OUTPUT_FILE);
+ }
+
+ while (1) {
+ FD_ZERO(&rfds);
+ for (i = 0 ; i < fd_n ; i++) {
+ FD_SET(fd[i], &rfds);
+ }
+ tv.tv_sec = inactive_time;
+ tv.tv_usec = 0;
+
+ retval = select(fd_max+1, &rfds, NULL, NULL, &tv);
+ /* Don't rely on the value of tv now! */
+
+ if (retval > 0) {
+ for (i = 0 ; i < fd_n ; i++) {
+ if(FD_ISSET(fd[i], &rfds)) {
+ if (is_verbose) {
+ printf("data from [%s]\n", fd_name[i]);
+ }
+ read(fd[i], bf, 1024);
+ }
+ }
+ now_working(&ctx);
+ }
+ else if (retval == 0) {
+ now_not_working(&ctx);
+
+
+ }
+ if (is_verbose) {
+ fflush(stdout);
+ }
+ }
+
+
+ exit (0);
+ return (0);
+}