Fixed a bug for level 0 which must now be defined in the configuration file.
[breezed.git] / breezed.c
index 42a830b..6c4895b 100644 (file)
--- a/breezed.c
+++ b/breezed.c
@@ -3,7 +3,7 @@
 
    breezed is a fan speed control daemon for Linux computers.
 
-   Copyright (c) 2008, 2009 Francois Fleuret
+   Copyright (c) 2008, 2009, 2010 Francois Fleuret
    Written by Francois Fleuret <francois@fleuret.org>
 
    This file is part of breezed.
@@ -30,7 +30,7 @@
 #include <string.h>
 
 const int major_version_number = 1;
-const int minor_version_number = 3;
+const int minor_version_number = 4;
 
 const int buffer_size = 1024;
 
@@ -56,6 +56,7 @@ int file_fan_fd;
 
 int nb_temperature_thresholds;
 int *temperature_thresholds = 0;
+char **speed_names = 0;
 
 int nb_file_thermal = 0;
 char **file_thermal = 0;
@@ -63,6 +64,19 @@ int *file_thermal_fd = 0;
 
 char *configuration_file;
 
+/********************************************************************/
+
+/* malloc with error checking.  */
+
+void *safe_malloc(size_t n) {
+  void *p = malloc(n);
+  if (!p && n != 0) {
+    fprintf(stderr, "Can not allocate memory: %s\n", strerror(errno));
+    exit(EXIT_FAILURE);
+  }
+  return p;
+}
+
 /******************************************************************/
 
 char *next_word(char *buffer, char *r, int buffer_size) {
@@ -82,7 +96,7 @@ char *next_word(char *buffer, char *r, int buffer_size) {
             (*r != '\t') && (*r != ' ') && (*r != ',')) {
         if(s == buffer + buffer_size) {
           fprintf(stderr, "Buffer overflow in next_word.\n");
-          exit(1);
+          exit(EXIT_FAILURE);
         }
         *s++ = *r++;
       }
@@ -99,11 +113,11 @@ char *next_word(char *buffer, char *r, int buffer_size) {
 void set_fan_level(int fan_fd, int f, int max_fan_level) {
   char buffer[buffer_size];
   if(f < 0 || f > max_fan_level) f = max_fan_level;
-  sprintf(buffer, "level %d\n", f);
+  sprintf(buffer, "level %s\n", speed_names[f]);
   if(write(fan_fd, buffer, strlen(buffer)) < 0) {
     fprintf(stderr, "Error in setting the fan level (%s).\n",
             strerror(errno));
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 }
 
@@ -112,7 +126,7 @@ void define_thermal_files(char *definition) {
 
   if(file_thermal) {
     fprintf(stderr, "Thermal files already defined.\n");
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   char *s;
@@ -122,8 +136,8 @@ void define_thermal_files(char *definition) {
     nb_file_thermal++;
   }
 
-  file_thermal = (char **) malloc(nb_file_thermal * sizeof(char *));
-  file_thermal_fd = (int *) malloc(nb_file_thermal * sizeof(int));
+  file_thermal = safe_malloc(nb_file_thermal * sizeof(char *));
+  file_thermal_fd = safe_malloc(nb_file_thermal * sizeof(int));
   s = definition;
   int k = 0;
   while(s) {
@@ -138,12 +152,13 @@ void define_temperature_thresholds(char *definition) {
 
   if(temperature_thresholds) {
     fprintf(stderr, "Temperature thresholds already defined.\n");
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
-  nb_temperature_thresholds = 1;
+  nb_temperature_thresholds = 0;
+
+  char *s, *u;
 
-  char *s;
   s = definition;
   while(s) {
     s = next_word(token, s, buffer_size);
@@ -151,22 +166,46 @@ void define_temperature_thresholds(char *definition) {
   }
 
   temperature_thresholds =
-    (int *) malloc(nb_temperature_thresholds * sizeof(int));
+    safe_malloc(nb_temperature_thresholds * sizeof(int));
 
-  temperature_thresholds[0] = -1;
+  speed_names =
+    safe_malloc(nb_temperature_thresholds * sizeof(char *));
 
   s = definition;
-  int k = 1;
+  int k = 0;
   while(s) {
     s = next_word(token, s, buffer_size);
-    temperature_thresholds[k] = atoi(token);
+    u = token;
+    while(*u && *u != ':') { u++; }
+    if(*u) {
+      *u = '\0';
+      temperature_thresholds[k] = atoi(token);
+      u++;
+      speed_names[k] = strdup(u);
+    } else {
+      temperature_thresholds[k] = atoi(token);
+      snprintf(token, buffer_size, "%d", k);
+      speed_names[k] = strdup(token);
+    }
+
     if(k > 0 &&
        temperature_thresholds[k] < temperature_thresholds[k-1]) {
       fprintf(stderr, "The temperature thresholds have to be increasing.\n");
-      exit(0);
+      exit(EXIT_FAILURE);
     }
     k++;
   }
+
+  if(nb_temperature_thresholds <= 0) {
+    fprintf(stderr, "There has to be at least one temperature.\n");
+    exit(EXIT_FAILURE);
+  }
+
+  if(temperature_thresholds[0] > 0) {
+    fprintf(stderr, "The lowest temperature has to be 0.\n");
+    exit(EXIT_FAILURE);
+  }
+
 }
 
 void evaluate_one_configuration_line(char *line, int line_number) {
@@ -179,7 +218,7 @@ void evaluate_one_configuration_line(char *line, int line_number) {
     if(s == 0) {
       fprintf(stderr, "Missing parameter in %s:%d\n",
               configuration_file, line_number);
-      exit(1);
+      exit(EXIT_FAILURE);
     }
     define_thermal_files(s);
   }
@@ -191,12 +230,12 @@ void evaluate_one_configuration_line(char *line, int line_number) {
   else if(strcmp(token, "fan_file") == 0) {
     if(file_fan) {
       fprintf(stderr, "Fan file already defined.\n");
-      exit(1);
+      exit(EXIT_FAILURE);
     }
     if(s == 0) {
       fprintf(stderr, "Missing parameter in %s:%d\n",
               configuration_file, line_number);
-      exit(1);
+      exit(EXIT_FAILURE);
     }
     file_fan = strdup(s);
   }
@@ -205,7 +244,7 @@ void evaluate_one_configuration_line(char *line, int line_number) {
     if(s == 0) {
       fprintf(stderr, "Missing parameter in %s:%d\n",
               configuration_file, line_number);
-      exit(1);
+      exit(EXIT_FAILURE);
     }
     define_temperature_thresholds(s);
   }
@@ -213,7 +252,7 @@ void evaluate_one_configuration_line(char *line, int line_number) {
   else if(token[0] && token[0] != '#') {
     fprintf(stderr, "Unknown keyword '%s' in %s:%d.\n",
             token, configuration_file, line_number);
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 }
 
@@ -251,7 +290,7 @@ int main(int argc, char **argv) {
       i++;
       if(i == argc) {
         fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
-        exit(1);
+        exit(EXIT_FAILURE);
       }
 
       free(configuration_file);
@@ -265,7 +304,7 @@ int main(int argc, char **argv) {
       i++;
       if(i == argc) {
         fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
-        exit(1);
+        exit(EXIT_FAILURE);
       }
       define_thermal_files(argv[i]);
       i++;
@@ -276,12 +315,12 @@ int main(int argc, char **argv) {
       i++;
       if(i == argc) {
         fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
-        exit(1);
+        exit(EXIT_FAILURE);
       }
 
       if(file_fan) {
         fprintf(stderr, "Fan file already defined.\n");
-        exit(1);
+        exit(EXIT_FAILURE);
       }
       file_fan = strdup(argv[i]);
 
@@ -294,7 +333,7 @@ int main(int argc, char **argv) {
 
       if(i == argc) {
         fprintf(stderr, "Missing parameter for %s.\n", argv[i - 1]);
-        exit(1);
+        exit(EXIT_FAILURE);
       }
 
       define_temperature_thresholds(argv[i]);
@@ -348,7 +387,7 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
 
     else {
       fprintf(stderr, "Unknown argument %s.\n", argv[i]);
-      exit(1);
+      exit(EXIT_FAILURE);
     }
   }
 
@@ -364,7 +403,7 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
 
     if(!file) {
       fprintf(stderr, "Can not open `%s' for reading.\n", configuration_file);
-      exit(1);
+      exit(EXIT_FAILURE);
     }
 
     start = 0;
@@ -404,7 +443,7 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
                 buffer_size);
         fprintf(stderr, raw_line);
         fprintf(stderr, "\n");
-        exit(1);
+        exit(EXIT_FAILURE);
       }
 
       /* If we got a line, we replace the carriage return by a \0 to
@@ -432,17 +471,17 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
 
   if(nb_temperature_thresholds == 0) {
     fprintf(stderr, "No temperature threshold was provided.\n");
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   if(nb_file_thermal == 0) {
     fprintf(stderr, "No thermal file was provided.\n");
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   if(file_fan == 0){
     fprintf(stderr, "No fan file was provided.\n");
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   for(i = 0; i < nb_file_thermal; i++) {
@@ -450,7 +489,7 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
     if(file_thermal_fd[i] < 0) {
       fprintf(stderr, "Can not open %s for reading (%s).\n",
               file_thermal[i], strerror(errno));
-      exit(1);
+      exit(EXIT_FAILURE);
     }
   }
 
@@ -459,7 +498,7 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
   if(file_fan_fd < 0) {
     fprintf(stderr, "Can not open %s for writing (%s).\n",
             file_fan, strerror(errno));
-    exit(1);
+    exit(EXIT_FAILURE);
   }
 
   /******************************************************************/
@@ -472,8 +511,9 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
     printf("file_fan %s\n", file_fan);
 
     for(t = 0; t < nb_temperature_thresholds; t++) {
-      printf("temperature_thresholds[%d] %d",
-             t, temperature_thresholds[t]);
+      printf("temperature_thresholds[%d] = %d speed_names[%d] = \"%s\"\n",
+             t, temperature_thresholds[t],
+             t, speed_names[t]);
     }
   }
 
@@ -540,13 +580,13 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
           fprintf(stderr, "Error while reading %s (too large).\n",
                   file_thermal[i]);
         }
-        exit(1);
+        exit(EXIT_FAILURE);
       }
     }
 
     if(temperature < 0) {
       fprintf(stderr, "Could not read a meaningful temperature.\n");
-      exit(1);
+      exit(EXIT_FAILURE);
     }
 
     nb_rounds_since_last_change++;
@@ -576,7 +616,7 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
 
     /* We set it every time, even when there is no change, to handle
        when the level has been modified somewhere else (for instance
-       when combing back from suspend). */
+       when coming back from suspend). */
 
     set_fan_level(file_fan_fd, new_level, nb_temperature_thresholds - 1);
 
@@ -584,8 +624,10 @@ Written by Francois Fleuret (francois@fleuret.org).\n",
       nb_rounds_since_last_change = 0;
       last_level = new_level;
       if(debug) {
-        printf("Temperature is %dC setting the fan level to %d.",
-               temperature, new_level);
+        printf("Temperature is %dC setting the fan level to %d (%s).\n",
+               temperature,
+               new_level,
+               speed_names[new_level]);
       }
     }