Fixed restoration of the panel divider position.
[psensor.git] / src / lib / slog.c
index f1b2f5b..d6c4bc2 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2010-2012 jeanfi@gmail.com
+ * Copyright (C) 2010-2014 jeanfi@gmail.com
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License as
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
  * 02110-1301 USA
  */
+#define _LARGEFILE_SOURCE 1
+#include "config.h"
+
 #include <locale.h>
 #include <libintl.h>
 #define _(str) gettext(str)
 
 #include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/stat.h>
 #include <sys/time.h>
+#include <sys/types.h>
+#include <unistd.h>
 
+#include "bool.h"
 #include "config.h"
-#include "log.h"
+#include <plog.h>
+#include <pmutex.h>
+#include "ptime.h"
 #include "slog.h"
 
 static FILE *file;
-static struct timeval stv;
+static double *last_values;
+static int period;
+static struct psensor **sensors;
+static pthread_mutex_t *sensors_mutex;
+static pthread_t thread;
+static time_t st;
 
-int slog_init(const char *path, struct psensor **sensors)
+static const char *DEFAULT_FILENAME = "sensors.log";
+
+static char *time_to_str(time_t *t)
 {
-       file = fopen(path, "a");
+       struct tm lt;
+       char *str;
 
-       if (!file) {
-               log_err(_("Cannot open sensor log file: %s"), path);
-               return 0;
+       if (!localtime_r(t, &lt))
+               return NULL;
+
+       str = malloc(64);
+
+       if (strftime(str, 64, "%s", &lt))
+               return str;
+
+       free(str);
+       return NULL;
+}
+
+static char *get_default_path(void)
+{
+       char *home, *path, *dir;
+
+       home = getenv("HOME");
+
+       if (home) {
+               dir = malloc(strlen(home)+1+strlen(".psensor")+1);
+               sprintf(dir, "%s/%s", home, ".psensor");
+               mkdir(dir, 0777);
+
+               path = malloc(strlen(dir)+1+strlen(DEFAULT_FILENAME)+1);
+               sprintf(path, "%s/%s", dir, DEFAULT_FILENAME);
+
+               free(dir);
+
+               return path;
        }
 
-       if (gettimeofday(&stv, NULL)) {
-               log_err(_("slog_init: gettimeofday failed."));
+       log_warn(_("HOME variable not set."));
+       return strdup(DEFAULT_FILENAME);
+}
+
+static bool slog_open(const char *path, struct psensor **sensors)
+{
+       char *lpath, *t;
+
+       if (file) {
+               log_err(_("Sensor log file already open."));
                return 0;
        }
 
-       fprintf(file, "I,%ld,%s\n", stv.tv_sec, VERSION);
+       lpath = path ? (char *)path : get_default_path();
+
+       file = fopen(lpath, "a");
+
+       if (!file)
+               log_err(_("Cannot open sensor log file: %s."), lpath);
+
+       if (!path)
+               free((char *)lpath);
+
+       if (!file)
+               return 0;
+
+       st = time(NULL);
+       t = time_to_str(&st);
+
+       fprintf(file, "I,%s,%s\n", t, VERSION);
 
        while (*sensors) {
-               fprintf(file, "S,%s\n", (*sensors)->id);
+               fprintf(file, "S,%s,%x\n", (*sensors)->id,  (*sensors)->type);
                sensors++;
        }
 
@@ -56,30 +125,91 @@ int slog_init(const char *path, struct psensor **sensors)
        return 1;
 }
 
-void slog_write_sensors(struct psensor **sensors)
+static void slog_write_sensors(struct psensor **sensors)
 {
+       int count, i;
+       double v;
        struct timeval tv;
+       bool first_call;
 
-       if (!file)
-               return ;
+       if (!file) {
+               log_debug(_("Sensor log file not open."));
+               return;
+       }
+
+       gettimeofday(&tv, NULL);
+
+       count = psensor_list_size(sensors);
 
-       if (gettimeofday(&tv, NULL)) {
-               log_err(_("slog_write_sensors: gettimeofday failed."));
-               return ;
+       if (last_values) {
+               first_call = 0;
+       } else {
+               first_call = 1;
+               last_values = malloc(count * sizeof(double));
        }
 
-       fprintf(file, "M,%ld", tv.tv_sec - stv.tv_sec);
-       while (*sensors) {
-               fprintf(file, ",%.1f", psensor_get_current_value(*sensors));
-               sensors++;
+       fprintf(file, "%ld", (long int)(tv.tv_sec - st));
+       for (i = 0; i < count; i++) {
+               v = psensor_get_current_value(sensors[i]);
+
+               if (!first_call && last_values[i] == v)
+                       fputc(',', file);
+               else
+                       fprintf(file, ",%.1f", v);
+
+               last_values[i] = v;
        }
+
        fputc('\n', file);
 
        fflush(file);
 }
 
-void slog_close()
+static void *slog_routine(void *data)
+{
+       while (1) {
+               pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+               pmutex_lock(sensors_mutex);
+               slog_write_sensors(sensors);
+               pmutex_unlock(sensors_mutex);
+               pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
+               sleep(period);
+       }
+
+       pthread_exit(NULL);
+}
+
+void slog_close(void)
 {
-       if (file)
+       if (file) {
+               pthread_cancel(thread);
+
                fclose(file);
+               file = NULL;
+               free(last_values);
+               last_values = NULL;
+       } else {
+               log_debug(_("Sensor log not open, cannot close."));
+       }
+}
+
+bool slog_activate(const char *path,
+                  struct psensor **ss,
+                  pthread_mutex_t *mutex,
+                  int p)
+{
+       bool ret;
+
+       sensors = ss;
+       sensors_mutex = mutex;
+       period = p;
+
+       pthread_mutex_lock(mutex);
+       ret = slog_open(path, sensors);
+       pthread_mutex_unlock(mutex);
+
+       if (ret)
+               pthread_create(&thread, NULL, slog_routine, NULL);
+
+       return ret;
 }