? cpufreqd-2.3.0.tar.bz2
? cpufreqd-2.3.0.tar.gz
? src/cpufreqd_acpi.c.gcov
? src/cpufreqd_date.c
? utils/getspeed.gcno
? utils/setspeed.gcno
Index: ChangeLog
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/ChangeLog,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- ChangeLog	19 Nov 2006 17:39:06 -0000	1.17
+++ ChangeLog	21 Jul 2008 07:06:31 -0000	1.18
@@ -1,3 +1,11 @@
+version 2.3.0
+-------------
+* use sysfs acpi class devices to read system status (/proc is not supported
+anymore, if you don't want't to switch to /sys do not install this version of
+cpufreqd)
+* rescan batteries on acpi events
+* fix invalid profile checking
+
 version 2.2.1
 -------------
 * Fix CMD_CUR_PROFILES or better, fix current_profile traking
Index: configure.in
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/configure.in,v
retrieving revision 1.22
retrieving revision 1.23
diff -u -r1.22 -r1.23
--- configure.in	22 Nov 2006 17:56:57 -0000	1.22
+++ configure.in	21 Jul 2008 07:06:32 -0000	1.23
@@ -1,5 +1,5 @@
 # Process this file with autoconf to produce a configure script.
-AC_INIT([cpufreqd],[2.2.1],[malattia@linux.it], [cpufreqd])
+AC_INIT([cpufreqd],[2.3.0],[malattia@linux.it], [cpufreqd])
 AC_CANONICAL_TARGET([])
 
 AM_INIT_AUTOMAKE(1.8 dist-bzip2 foreign)
Index: prepare.sh
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/prepare.sh,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- prepare.sh	25 Sep 2005 16:58:40 -0000	1.5
+++ prepare.sh	30 Jun 2008 16:10:38 -0000	1.6
@@ -1,5 +1,5 @@
-
 #!/bin/bash
+
 WANT_AUTOMAKE="1.8" aclocal && libtoolize -c -f && \
 aclocal && autoconf && automake -a -c --foreign \
 && chmod +x ltmain.sh
Index: src/Makefile.am
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/Makefile.am,v
retrieving revision 1.19
retrieving revision 1.20
diff -u -r1.19 -r1.20
--- src/Makefile.am	23 Sep 2006 14:03:04 -0000	1.19
+++ src/Makefile.am	29 Jun 2008 06:23:09 -0000	1.20
@@ -104,10 +104,10 @@
 		cpufreqd_acpi_temperature.c
 
 cpufreqd_acpi_la_CFLAGS = \
-		$(AM_CFLAGS) -I/@PTHREAD_SRCDIR@/include
+		$(AM_CFLAGS) -I/@PTHREAD_SRCDIR@/include -I/usr/include/sysfs
 
 cpufreqd_acpi_la_LDFLAGS = \
-		-module -avoid-version -L/@PTHREAD_SRCDIR@/lib -lpthread
+		-module -avoid-version -L/@PTHREAD_SRCDIR@/lib -lpthread -lsysfs
 
 #cpufreqd_acpi_ac_la_SOURCES = \
 #		cpufreqd_acpi_ac.c
Index: src/config_parser.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/config_parser.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -r1.40 -r1.41
--- src/config_parser.c	4 Jul 2006 21:54:37 -0000	1.40
+++ src/config_parser.c	20 Jul 2008 14:59:58 -0000	1.41
@@ -834,8 +834,7 @@
 				
 				strncpy(profile_name, strstr(token, ":") + 1, MAX_STRING_LEN);
 				cpu_num = atoi(token + 3);
-
-				if (!profile_name) {
+				if (profile_name[0]) {
 					clog(LOG_ERR, "Wrong format for Profile name \"%s\".\n",
 							token);
 					return -1;
Index: src/cpufreqd.h
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd.h,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- src/cpufreqd.h	22 Nov 2006 17:56:58 -0000	1.18
+++ src/cpufreqd.h	21 Jul 2008 07:06:32 -0000	1.19
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2002-2006  Mattia Dongili <malattia@linux.it>
+ *  Copyright (C) 2002-2008  Mattia Dongili <malattia@linux.it>
  *                           George Staikos <staikos@0wned.org>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -17,10 +17,14 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
 #ifndef __CPUFREQD_H__
 #define __CPUFREQD_H__
 
-#define __CPUFREQD_VERSION__	"2.2.1"
+#define __CPUFREQD_VERSION__	VERSION
 #define __CPUFREQD_MAINTAINER__	"malattia@linux.it"
 
 #ifdef __GNUC__
@@ -29,10 +33,6 @@
 #  define __UNUSED__
 #endif
 
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
 #ifndef CPUFREQD_CONFDIR
 #  define CPUFREQD_CONFDIR  "/etc/"
 #endif
Index: src/cpufreqd_acpi.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_acpi.c,v
retrieving revision 1.4
retrieving revision 1.7
diff -u -r1.4 -r1.7
--- src/cpufreqd_acpi.c	21 Jun 2006 21:20:00 -0000	1.4
+++ src/cpufreqd_acpi.c	27 Jul 2008 07:47:42 -0000	1.7
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2006  Mattia Dongili <malattia@linux.it>
+ *  Copyright (C) 2006-2008  Mattia Dongili <malattia@linux.it>
  *
  *  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
@@ -16,6 +16,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <errno.h>
 #include <stdio.h>
 #include <string.h>
 
@@ -140,3 +141,147 @@
 struct cpufreqd_plugin *create_plugin (void) {
 	return &acpi;
 }
+
+/* 
+ * exported functions used in all the acpi components
+ *
+ */
+
+/* read_value 
+ *
+ * read the value and perform no conversion, requires an open sysfs attribute
+ */
+int read_value(struct sysfs_attribute *attr)
+{
+	if (sysfs_read_attribute(attr)) {
+		clog(LOG_NOTICE, "couldn't read %s (%s)\n",
+				attr->path, strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
+/* read_int
+ *
+ * read char value into an integer, requires an open sysfs attribute
+ */
+int read_int(struct sysfs_attribute *attr, int *value)
+{
+	if (read_value(attr) != 0)
+		return -1;
+	sscanf(attr->value, "%d\n", value);
+	return 0;
+}
+
+/* put_attribute
+ *
+ * closes a sysfs_attribute previously obtained through
+ * get_class_device_attribute.
+ */
+void put_attribute(struct sysfs_attribute *attr) {
+	clog(LOG_DEBUG, "closing %s.\n", attr->path);
+	sysfs_close_attribute(attr);
+}
+
+/* get_class_device_attribute
+ *
+ * Tried to get the attribute `attrname` from the class device `clsdev`.
+ * If the attribute is returned on success, NULL on failure.
+ * The attribute can be closes with put_attribute.
+ */
+struct sysfs_attribute *get_class_device_attribute(struct sysfs_class_device *clsdev,
+		const char *attrname)
+{
+
+	char path[SYSFS_PATH_MAX];
+	struct sysfs_attribute *attr = NULL;
+
+	snprintf(path, SYSFS_PATH_MAX, "%s/%s", clsdev->path, attrname);
+	attr = sysfs_open_attribute(path);
+	if (!attr) {
+		clog(LOG_WARNING, "couldn't open %s (%s)\n", path,
+				strerror(errno));
+		return NULL;
+	}
+	clog(LOG_INFO, "found %s - path %s\n", attr->name, attr->path);
+	return attr;
+
+}
+
+/* put_class_device
+ *
+ * Close class devices previously discovered with find_class_device
+ */
+void put_class_device(struct sysfs_class_device *clsdev)
+{
+	clog(LOG_DEBUG, "Closing device '%s'\n", clsdev->name);
+	sysfs_close_class_device(clsdev);
+}
+
+/* find_class_device
+ *
+ * Read class devices for `clsname` looking for `devtype` in the `type` attribute.
+ * If `devtype` matches the device type the callback is invoked with the 
+ * struct sysfs_class_device pointer as argument.
+ *
+ * Returns the number of class devices of type devtype found.
+ */
+int find_class_device(const char *clsname, const char *devtype,
+		int (*clsdev_callback)(struct sysfs_class_device *cls))
+{
+
+	struct sysfs_attribute *attr = NULL;
+	struct dlist *devs = NULL;
+	struct sysfs_class *cls = NULL;
+	struct sysfs_class_device *clsdev = NULL;
+	char type[256];
+	int clscount = 0;
+
+	cls = sysfs_open_class(clsname);
+	if (!cls) {
+		clog(LOG_NOTICE, "class '%s' not found (%s)\n", clsname,
+				strerror(errno));
+		return -1;
+	}
+
+	/* read `clsname` devices */
+	devs = sysfs_get_class_devices(cls);
+	if (!cls) {
+		clog(LOG_INFO, "class '%s' not found (%s)\n", clsname,
+				strerror(errno));
+		sysfs_close_class(cls);
+		return -1;
+	}
+	dlist_for_each_data(devs, clsdev, struct sysfs_class_device) {
+		clog(LOG_INFO, "found %s\n", clsdev->path);
+
+		/* read the `type` attribute */
+		attr = sysfs_get_classdev_attr(clsdev, "type");
+		if (!attr) {
+			clog(LOG_NOTICE, "attribute 'type' not found for %s (%s).\n",
+					clsdev->name, strerror(errno));
+			continue;
+		}
+		/* check if devtype matches */
+		if (sysfs_read_attribute(attr)) {
+			clog(LOG_NOTICE, "couldn't read %s (%s)\n",
+					attr->path, strerror(errno));
+		}
+		sscanf(attr->value, "%255[a-zA-Z0-9 ]\n", type);
+		clog(LOG_DEBUG, "%s is of type %s\n", clsdev->name, type);
+		if (strncmp(type, devtype, 256) == 0) {
+			struct sysfs_class_device *cdev = 
+				sysfs_open_class_device(clsname, clsdev->name);
+			if (cdev) {
+				clscount++;
+				if (clsdev_callback(cdev) != 0)
+					sysfs_close_class_device(cdev);
+			} else
+				clog(LOG_WARNING, "couldn't open %s (%s)\n",
+						clsdev->name , strerror(errno));
+
+		}
+	}
+	sysfs_close_class(cls);
+	return clscount;
+}
Index: src/cpufreqd_acpi.h
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_acpi.h,v
retrieving revision 1.1
retrieving revision 1.3
diff -u -r1.1 -r1.3
--- src/cpufreqd_acpi.h	21 May 2006 11:53:39 -0000	1.1
+++ src/cpufreqd_acpi.h	20 Jul 2008 14:48:38 -0000	1.3
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2006  Mattia Dongili <malattia@linux.it>
+ *  Copyright (C) 2006-2008  Mattia Dongili <malattia@linux.it>
  *
  *  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
@@ -16,6 +16,7 @@
  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include <sysfs/libsysfs.h>
 #include "cpufreqd.h"
 
 struct acpi_configuration {
@@ -26,3 +27,15 @@
 	int watch_temperature;
 	char acpid_sock_path[MAX_PATH_LEN];
 };
+
+int read_value(struct sysfs_attribute *attr);
+int read_int(struct sysfs_attribute *attr, int *value);
+
+
+void put_attribute(struct sysfs_attribute *attr);
+struct sysfs_attribute *get_class_device_attribute(struct sysfs_class_device *clsdev,
+		const char *attrname);
+
+void put_class_device(struct sysfs_class_device *clsdev);
+int find_class_device(const char *clsname, const char *devtype,
+		int (*clsdev_callback)(struct sysfs_class_device *cls));
Index: src/cpufreqd_acpi_ac.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_acpi_ac.c,v
retrieving revision 1.14
retrieving revision 1.18
diff -u -r1.14 -r1.18
--- src/cpufreqd_acpi_ac.c	12 May 2006 18:08:40 -0000	1.14
+++ src/cpufreqd_acpi_ac.c	21 Jul 2008 07:56:28 -0000	1.18
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2002-2006  Mattia Dongili <malattia@linux.it>
+ *  Copyright (C) 2002-2008  Mattia Dongili <malattia@linux.it>
  *                           George Staikos <staikos@0wned.org>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -23,21 +23,33 @@
 #include <stdlib.h>
 #include <string.h>
 #include "cpufreqd_plugin.h"
+#include "cpufreqd_acpi.h"
 #include "cpufreqd_acpi_ac.h"
 
-#define ACPI_AC_DIR "/proc/acpi/ac_adapter/"
-#define ACPI_AC_FILE "/state"
-#define ACPI_AC_FORMAT "state:                   %s\n"
+#define POWER_SUPPLY "power_supply"
+#define AC_TYPE "Mains"
+#define AC_ONLINE "online"
 
 #define PLUGGED   1
 #define UNPLUGGED 0
 
-static char *ac_filelist[64];
+static struct sysfs_attribute *mains[64];
 static unsigned short ac_state;
 static int ac_dir_num;
 
-static int no_dots(const struct dirent *d) {
-	return d->d_name[0]!= '.';
+static int mains_callback(struct sysfs_class_device *cdev) {
+	struct sysfs_attribute *attr = get_class_device_attribute(cdev,
+			AC_ONLINE);
+	if (attr) {
+		/* success */
+		mains[ac_dir_num] = attr;
+		ac_dir_num++;
+	}
+	/* we don't care about the class_device
+	 * returning 1 will force find_class_device
+	 * to close it
+	 */
+	return 1;
 }
 
 /*  static int acpi_ac_init(void)
@@ -45,36 +57,18 @@
  *  test if AC dirs are present
  */
 int acpi_ac_init(void) {
-	struct dirent **namelist = NULL;
-	int n = 0;
-
-	/* get AC path */
-	n = scandir(ACPI_AC_DIR, &namelist, no_dots, NULL);
-	if (n > 0) {
-		ac_dir_num = n;
-		*ac_filelist = malloc(n * 64 * sizeof(char));
-		while (n--) {
-			snprintf(ac_filelist[n], 64, "%s%s%s", ACPI_AC_DIR, namelist[n]->d_name, ACPI_AC_FILE);
-			clog(LOG_INFO, "AC path %s\n", ac_filelist[n]);
-			free(namelist[n]);
-		} 
-		free(namelist);
-
-	} else if (n < 0) {
-		clog(LOG_DEBUG, "no acpi_ac module compiled or inserted? (%s: %s)\n",
-				ACPI_AC_DIR, strerror(errno));
-		return -1;
 
-	} else {
-		clog(LOG_NOTICE, "no ac adapters found, not a laptop?\n");
+	find_class_device(POWER_SUPPLY, AC_TYPE, mains_callback);
+	if (ac_dir_num <= 0) {
+		clog(LOG_INFO, "No AC adapters found\n");
 		return -1;
 	}
 	return 0;
 }
 
 int acpi_ac_exit(void) {
-	if (ac_filelist != NULL)
-		free(*ac_filelist);
+	while (--ac_dir_num >= 0)
+		put_attribute(mains[ac_dir_num]);
 	clog(LOG_INFO, "exited.\n");
 	return 0;
 }
@@ -84,23 +78,18 @@
  *  reads temperature valuse ant compute a medium value
  */
 int acpi_ac_update(void) {
-	char temp[50];
-	int i=0;
-	FILE *fp = NULL;
+	int value;
+	int i = 0;
 
 	ac_state = UNPLUGGED;
 	clog(LOG_DEBUG, "called\n");
-	for (i=0; i<ac_dir_num; i++) {
-		fp = fopen(ac_filelist[i], "r");
-		if (!fp) {
-			clog(LOG_ERR, "%s: %s\n", ac_filelist[i], strerror(errno));
-			return -1;
-		}
-		fscanf(fp, ACPI_AC_FORMAT, temp);
-		fclose(fp);
+	for (i = 0; i < ac_dir_num; i++) {
+		/* check power_supply type */
+		if (read_int(mains[i], &value))
+				continue;
 
-		clog(LOG_DEBUG, "read %s\n", temp);
-		ac_state |= (strncmp(temp, "on-line", 7)==0 ? PLUGGED : UNPLUGGED);
+		clog(LOG_DEBUG, "read %s:%d\n", mains[i]->path, value);
+		ac_state |= value ? PLUGGED : UNPLUGGED;
 	}
 
 	clog(LOG_INFO, "ac_adapter is %s\n",
Index: src/cpufreqd_acpi_battery.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_acpi_battery.c,v
retrieving revision 1.18
retrieving revision 1.22
diff -u -r1.18 -r1.22
--- src/cpufreqd_acpi_battery.c	11 Jun 2006 20:15:56 -0000	1.18
+++ src/cpufreqd_acpi_battery.c	21 Jul 2008 07:56:28 -0000	1.22
@@ -27,24 +27,29 @@
 #include "cpufreqd_acpi_event.h"
 #include "cpufreqd_acpi_battery.h"
 
-#define ACPI_BATTERY_DIR        "/proc/acpi/battery/"
-#define ACPI_BATTERY_STATE_FILE "/state"
-#define ACPI_BATTERY_INFO_FILE  "/info"
-#define ACPI_BATTERY_FULL_CAPACITY_FMT  "last full capacity:      %d %sh\n"
-#define ACPI_BATTERY_REM_CAPACITY_FMT   "remaining capacity:      %d %sh\n"
-#define ACPI_BATTERY_PRESENT_RATE	"present rate:            %d %s\n"
-#define ACPI_BATTERY_DISCHARGING	"charging state:          discharging\n"
-#define ACPI_BATTERY_CHARGING		"charging state:          charging\n"
+#define POWER_SUPPLY	"power_supply"
+#define BATTERY_TYPE	"Battery"
+#define ENERGY_FULL	"energy_full"
+#define ENERGY_NOW	"energy_now"
+#define PRESENT		"present"
+#define STATUS		"status"
+#define CURRENT_NOW	"current_now"
 
 struct battery_info {
 	int capacity;
-	float remaining;
+	int remaining;
 	int present_rate;
-	int present;
-	int discharging;
-	int level;
-	char name[32];
-	char path[100];
+	int level; /* computed percentage */
+	int is_present;
+
+	struct sysfs_class_device *cdev;
+	struct sysfs_attribute *energy_full; /* last full capacity */
+	struct sysfs_attribute *energy_now; /* remaining capacity */
+	struct sysfs_attribute *present;
+	struct sysfs_attribute *status;
+	struct sysfs_attribute *current_now; /* present rate */
+
+	int open;
 };
 
 struct battery_interval {
@@ -52,124 +57,145 @@
 	struct battery_info *bat;
 };
 
-static struct battery_info *infos;
-static int bat_num;
-static int battery_level;
+/* don't want to handle more than 8 batteries... yet */
+static struct battery_info info[8];
+static int bat_dir_num;
+static int avg_battery_level;
 static double check_timeout;
 static double old_time;
 extern struct acpi_configuration acpi_config;
 
-/* int no_dots(const struct dirent *d)
- * 
- * Filter function for scandir, returns
- * 0 if the first char of d_name is not
- * a dot.
- */
-static int no_dots(const struct dirent *d) {
-	return d->d_name[0]!= '.';
-}
-
+/* validate if the requested battery exists */
 static struct battery_info *get_battery_info(const char *name)
 {
 	int i;
 	struct battery_info *ret = NULL;
 	
-	for (i=0; i<bat_num; i++) {
-		if (strncmp(infos[i].name, name, 32) == 0) {
-			ret = &infos[i];
+	for (i = 0; i < bat_dir_num; i++) {
+		if (strncmp(info[i].cdev->name, name, SYSFS_NAME_LEN) == 0) {
+			ret = &info[i];
 			break;
 		}
 	}
 	return ret;
 }
 
-/*  static int check_battery(char *dirname)
- *
- *  check if the battery is present and read infos.
- */
-static void check_battery(struct battery_info *info) {
-	FILE *fp;
-	char file_name[256];
-	char ignore[100];
-	char line[100];
-	int tmp;
-
-	snprintf(file_name, 256, "%s%s", info->path, ACPI_BATTERY_INFO_FILE);
-	/** /proc/acpi/battery/.../info **/
-	fp = fopen(file_name, "r");
-	if (!fp) {
-		clog(LOG_ERR , "%s: %s\n", file_name, strerror(errno));
-		return;
-	}
-
-	/* reset some info */
-	info->present = 0;
-
-	while (fgets(line, 100, fp)) {
-		if(sscanf(line, ACPI_BATTERY_FULL_CAPACITY_FMT, &tmp, ignore) == 2) {
-			info->capacity = tmp;
-			clog(LOG_DEBUG, "%s - capacity: %d\n", info->name,
-					info->capacity);
-			info->present = 1;
-		}
-	}
-	fclose(fp);
-}
+/* close all the attributes and reset the open status */
+static void close_battery(struct battery_info *binfo) {
 
-/*  static int acpi_battery_init(void)
- *
- *  test if BATTERY dirs are present
- */
-int acpi_battery_init(void) {
-	struct dirent **namelist = NULL;
-	int n = 0;
+	if (!binfo->open) return;
 
-	/* get batteries paths */
-	bat_num = n = scandir(ACPI_BATTERY_DIR, &namelist, no_dots, NULL);
-	if (n > 0) {
-		infos = malloc( bat_num*sizeof(struct battery_info) );
-
-		while (n--) {
-			/* put the path into the array */
-			snprintf(infos[n].name, 32, "%s", namelist[n]->d_name);
-			snprintf(infos[n].path, 100, "%s%s", ACPI_BATTERY_DIR, namelist[n]->d_name);
-			infos[n].present = 0;
-			infos[n].capacity = 0;
-			/* check this battery */
-			check_battery(&(infos[n]));
-
-			clog(LOG_INFO, "%s battery path: %s, %s, capacity:%d\n",
-					infos[n].name, infos[n].path, 
-					infos[n].present?"present":"absent", infos[n].capacity);
-			
-			free(namelist[n]);
-		}
-		free(namelist);
-		clog(LOG_INFO, "found %d battery slots\n", bat_num);
+	if (binfo->energy_full)
+		put_attribute(binfo->energy_full);
+	if (binfo->energy_now)
+		put_attribute(binfo->energy_now);
+	if (binfo->present)
+		put_attribute(binfo->present);
+	if (binfo->status)
+		put_attribute(binfo->status);
+	if (binfo->current_now)
+		put_attribute(binfo->current_now);
+
+	binfo->open = 0;
+}
+/* read battery levels as reported by hw */
+static int read_battery(struct battery_info *binfo) {
+	clog(LOG_DEBUG, "%s - reading battery levels\n", binfo->cdev->name);
 
-	} else if (n < 0) {
-		clog(LOG_ERR, "error, acpi_battery module not compiled or inserted (%s: %s)?\n",
-				ACPI_BATTERY_DIR, strerror(errno));
-		clog(LOG_ERR, "exiting.\n");
+	if (read_int(binfo->current_now, &binfo->present_rate) != 0) {
+		clog(LOG_ERR, "Skipping %s\n", binfo->cdev->name);
+		return -1;
+	}
+	if (read_int(binfo->energy_now, &binfo->remaining) != 0) {
+		clog(LOG_ERR, "Skipping %s\n", binfo->cdev->name);
 		return -1;
+	}
+	if (read_value(binfo->status) != 0) {
+		clog(LOG_ERR, "Skipping %s\n", binfo->cdev->name);
+		return -1;
+	}
+	clog(LOG_DEBUG, "%s - remaining capacity: %d\n",
+			binfo->cdev->name, binfo->remaining);
+	return 0;
+}
+/* open all the required attributes and set the open status */
+static int open_battery(struct battery_info *binfo) {
+	binfo->open = 1;
 
-	} else {
-		clog(LOG_ERR, "no batteries found, not a laptop?\n");
-		clog(LOG_ERR, "exiting.\n");
+	binfo->energy_full = get_class_device_attribute(binfo->cdev, ENERGY_FULL);
+	if (!binfo->energy_full)
+		return -1;
+	binfo->energy_now = get_class_device_attribute(binfo->cdev, ENERGY_NOW);
+	if (!binfo->energy_now)
+		return -1;
+	binfo->present = get_class_device_attribute(binfo->cdev, PRESENT);
+	if (!binfo->present)
+		return -1;
+	binfo->status = get_class_device_attribute(binfo->cdev, STATUS);
+	if (!binfo->status)
+		return -1;
+	binfo->current_now = get_class_device_attribute(binfo->cdev, CURRENT_NOW);
+	if (!binfo->current_now)
+		return -1;
+
+	/* read the last full capacity, this is not going to change
+	 * very often, so no need to poke it later */
+	if (read_int(binfo->energy_full, &binfo->capacity) != 0) {
+		clog(LOG_WARNING, "Couldn't read %s capacity (%s)\n",
+				binfo->cdev->name, strerror(errno));
 		return -1;
 	}
+	return 0;
+}
 
+/* set the battery class device into the battery_info array */
+static int clsdev_callback(struct sysfs_class_device *cdev) {
+	clog(LOG_DEBUG, "Got device %s\n", cdev->name);
+	info[bat_dir_num].cdev = cdev;
+	bat_dir_num++;
 	return 0;
 }
 
+/*  int acpi_battery_init(void)
+ *
+ *  this never fails since batteries are hotpluggable and
+ *  we can easily rescan for availability later (see acpi_battery_update
+ *  when an event is pending)
+ */
+int acpi_battery_init(void) {
+	int i;
+
+	find_class_device(POWER_SUPPLY, BATTERY_TYPE, &clsdev_callback);
+	if (bat_dir_num <= 0) {
+		clog(LOG_INFO, "No Batteries found\n");
+		return 0;
+	}
+	/* open the required attributes */
+	for (i = 0; i < bat_dir_num; i++) {
+		clog(LOG_DEBUG, "Opening %s attributes\n", info[i].cdev->name);
+		if (open_battery(&info[i]) != 0) {
+			clog(LOG_WARNING, "Couldn't open %s attributes\n",
+					info[i].cdev->name);
+			close_battery(&info[i]);
+		}
+	}
+	clog(LOG_INFO, "found %d Batter%s\n", bat_dir_num,
+			bat_dir_num > 1 ? "ies" : "y");
+	return 0;
+}
 int acpi_battery_exit(void) {
-	if (infos != NULL) {
-		free(infos);
+	/* also reset values since this is called on pending
+	 * acpi events to rescan batteries
+	 */
+	while (--bat_dir_num >= 0) {
+		close_battery(&info[bat_dir_num]);
+		put_class_device(info[bat_dir_num].cdev);
+		info[bat_dir_num].cdev = NULL;
 	}
+	bat_dir_num = 0;
 	clog(LOG_INFO, "exited.\n");
 	return 0;
 }
-
 /*
  *  Parses entries of the form %d-%d (min-max)
  */
@@ -193,7 +219,7 @@
 			free(ret);
 			return -1;
 		}
-		clog(LOG_INFO, "parsed %s %d-%d\n", ret->bat->name, ret->min, ret->max);
+		clog(LOG_INFO, "parsed %s %d-%d\n", ret->bat->cdev->name, ret->min, ret->max);
 
 	} else if (sscanf(ev, "%32[a-zA-Z0-9]:%d", battery_name, &(ret->min)) == 2) {
 		/* validate battery name and assign pointer to struct battery_info */
@@ -204,7 +230,7 @@
 			return -1;
 		}
 		ret->max = ret->min;
-		clog(LOG_INFO, "parsed %s %d\n", ret->bat->name, ret->min);
+		clog(LOG_INFO, "parsed %s %d\n", ret->bat->cdev->name, ret->min);
 
 	} else if (sscanf(ev, "%d-%d", &(ret->min), &(ret->max)) == 2) {
 		clog(LOG_INFO, "parsed %d-%d\n", ret->min, ret->max);
@@ -231,14 +257,14 @@
 
 int acpi_battery_evaluate(const void *s) {
 	const struct battery_interval *bi = (const struct battery_interval *)s;
-	int level = battery_level;
+	int level = avg_battery_level;
 
 	if (bi != NULL && bi->bat != NULL) {
-		level = bi->bat->present ? bi->bat->level : -1;
+		level = bi->bat->present->value ? bi->bat->level : -1;
 	}
 
 	clog(LOG_DEBUG, "called %d-%d [%s:%d]\n", bi->min, bi->max, 
-			bi != NULL && bi->bat != NULL ? bi->bat->name : "Medium", level);
+			bi != NULL && bi->bat != NULL ? bi->bat->cdev->name : "Avg", level);
 
 	return (level >= bi->min && level <= bi->max) ? MATCH : DONT_MATCH;
 }
@@ -248,11 +274,7 @@
  *  reads temperature valuse ant compute a medium value
  */
 int acpi_battery_update(void) {
-	FILE *fp;
-	char ignore[100];
-	char file_name[256];
-	char line[100];
-	int i=0, total_capacity=0, total_remaining=0, tmp=0, n_read=0;
+	int i = 0, total_capacity = 0, total_remaining = 0, n_read = 0;
 	double elapsed_time = 0.0;
 	double current_time = 0.0;
 #if 0
@@ -267,86 +289,78 @@
 	/* decrement timeout */
 	check_timeout -= elapsed_time;
 
+	/* if there is a pending event rescan batteries */
+	if (is_event_pending()) {
+		clog(LOG_NOTICE, "Re-scanning available batteries\n");
+		acpi_battery_exit();
+		acpi_battery_init();
+		/* force timeout expiration */
+		check_timeout = -1;
+	}
+
 	/* Read battery informations */
-	for (i=0; i<bat_num; i++) {
+	for (i = 0; i < bat_dir_num; i++) {
+		
+		if (read_int(info[i].present, &info[i].is_present) != 0) {
+			clog(LOG_INFO, "Skipping %s\n", info[i].cdev->name);
+			continue;
+		}
 
 		/* if battery not present skip to the next one */
-		if (!infos[i].present || infos[i].capacity <= 0) {
+		if (!info[i].is_present || info[i].capacity <= 0) {
 			continue;
 		}
+		clog(LOG_INFO, "%s - present\n", info[i].cdev->name);
 
-		/* if check_timeout is expired or an event is pending read battery */
-		if (check_timeout <= 0 || is_event_pending()) {
-			clog(LOG_DEBUG, "%s - reading battery\n", infos[i].name);
+		/* if check_timeout is expired */
+		if (check_timeout <= 0) {
 			check_timeout = acpi_config.battery_update_interval;
-			/**
-			 ** /proc/acpi/battery/.../state
-			 **/
-			snprintf(file_name, 256, "%s%s", infos[i].path, ACPI_BATTERY_STATE_FILE);
-			fp = fopen(file_name, "r");
-			if (!fp) {
-				clog(LOG_ERR, "%s: %s\n", file_name, strerror(errno));
-				clog(LOG_INFO, "battery path %s disappeared? "
-						"send SIGHUP to re-read batteries\n",
-						infos[i].path);
-				continue;
-			}
-
-			infos[i].discharging = 0;
-			while (fgets(line, 100, fp)) {
-				if (sscanf(line, ACPI_BATTERY_REM_CAPACITY_FMT, &tmp, ignore) == 2) {
-					infos[i].remaining = tmp;
-					total_remaining += infos[i].remaining;
-					total_capacity += infos[i].capacity;
-					n_read++;
-					clog(LOG_DEBUG, "%s - remaining capacity: %.2f\n",
-							infos[i].name, infos[i].remaining);
-				}
-				if(sscanf(line, ACPI_BATTERY_PRESENT_RATE, &tmp, ignore) == 2) {
-					infos[i].present_rate = tmp;
-					clog(LOG_DEBUG, "%s - present rate: %d\n",
-							infos[i].name, infos[i].present_rate);
-				}
-				if(strstr(line, ACPI_BATTERY_DISCHARGING) != NULL) {
-					infos[i].discharging = 1;
-				}
-			}
-			fclose(fp);
+			if (read_battery(&info[i]) == 0)
+				n_read++;
+			else
+				clog(LOG_INFO, "Unable to read battery %s\n",
+						info[i].cdev->name);
 		} else {
 			/* estimate battery life */
-			clog(LOG_DEBUG, "%s - estimating battery life (timeout: %0.2f)\n",
-					infos[i].name, check_timeout);
-			if (infos[i].discharging)
-				infos[i].remaining -= ((float)infos[i].present_rate * elapsed_time) / 3600.0;
-			else if ((int)infos[i].remaining < infos[i].capacity)
-				infos[i].remaining += ((float)infos[i].present_rate * elapsed_time) / 3600.0;
-			total_remaining += infos[i].remaining;
-			total_capacity += infos[i].capacity;
-			n_read++;
-			clog(LOG_DEBUG, "%s - remaining capacity: %.2f\n",
-					infos[i].name, infos[i].remaining);
+			clog(LOG_DEBUG, "%s - estimating battery life (timeout: %0.2f"
+					" - status: %s)\n",
+					info[i].cdev->name, check_timeout,
+					info[i].status->value);
+
+			if (strncmp(info[i].status->value, "Discharging", 11) == 0)
+				info[i].remaining -= ((float)info[i].present_rate * elapsed_time) / 3600.0;
+
+			else if (strncmp(info[i].status->value, "Full", 4) != 0 &&
+					(int)info[i].remaining < info[i].capacity)
+				info[i].remaining += ((float)info[i].present_rate * elapsed_time) / 3600.0;
+
+			clog(LOG_DEBUG, "%s - remaining capacity: %d\n",
+					info[i].cdev->name, info[i].remaining);
 		}
+		n_read++;
+		total_remaining += info[i].remaining;
+		total_capacity += info[i].capacity;
 
-		infos[i].level = 100 * (infos[i].remaining / (double)infos[i].capacity);
-		clog(LOG_INFO, "battery life for %s is %d%%\n", infos[i].name, infos[i].level);
+		info[i].level = 100 * (info[i].remaining / (double)info[i].capacity);
+		clog(LOG_INFO, "battery life for %s is %d%%\n", info[i].cdev->name, info[i].level);
 #if 0
-		if (infos[i].present_rate > 0) {
-			remaining_secs = 3600 * infos[i].remaining / infos[i].present_rate;
+		if (info[i].present_rate > 0) {
+			remaining_secs = 3600 * info[i].remaining / info[i].present_rate;
 			remaining_hours = (int) remaining_secs / 3600;
 			remaining_minutes = (remaining_secs - (remaining_hours * 3600)) / 60;
 			clog(LOG_INFO, "battery time for %s is %d:%0.2d\n",
-					infos[i].name, remaining_hours, remaining_minutes);
+					info[i].cdev->name, remaining_hours, remaining_minutes);
 		}
 #endif
-	} /* end infos loop */
+	} /* end info loop */
 
 	/* calculates medium battery life between all batteries */
 	if (total_capacity > 0)
-		battery_level = 100 * (total_remaining / (double)total_capacity);
+		avg_battery_level = 100 * (total_remaining / (double)total_capacity);
 	else
-		battery_level = -1;
+		avg_battery_level = -1;
 
-	clog(LOG_INFO, "medium battery life %d%%\n", battery_level);
+	clog(LOG_INFO, "average battery life %d%%\n", avg_battery_level);
 
 	return 0;
 }
Index: src/cpufreqd_acpi_event.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_acpi_event.c,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- src/cpufreqd_acpi_event.c	21 Jun 2006 21:20:01 -0000	1.7
+++ src/cpufreqd_acpi_event.c	27 Jul 2008 07:46:35 -0000	1.8
@@ -33,6 +33,7 @@
 #include <sys/types.h>
 #include <sys/un.h>
 #include <sys/wait.h>
+#include <time.h>
 #include <unistd.h>
 #include "cpufreqd_plugin.h"
 #include "cpufreqd_acpi.h"
@@ -54,6 +55,64 @@
 static short event_pending;
 extern struct acpi_configuration acpi_config;
 
+static void close_acpi_event(void) {
+	if (event_fd) {
+		clog(LOG_DEBUG, "closing event handle.\n");
+		if (close(event_fd))
+			clog(LOG_ERR, "Couldn't close the ACPI event handler (%s).\n",
+					strerror(errno));
+	}
+	event_fd = 0;
+}
+
+static int open_acpi_event (void) {
+#if 0
+	/* try to open /proc/acpi/event */
+	event_fd = open("/proc/acpi/event", O_RDONLY);
+#endif
+	/* or fallback to the acpid socket */
+	if (event_fd <= 0 && acpi_config.acpid_sock_path[0]) {
+		struct sockaddr_un sck;
+		sck.sun_family = AF_UNIX;
+		strncpy(sck.sun_path, acpi_config.acpid_sock_path, 108);
+		sck.sun_path[107] = '\0';
+
+		if ((event_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
+			clog(LOG_ERR, "Couldn't open acpid socket (%s).\n",
+					strerror(errno));
+			event_fd = 0;
+			return -1;
+		}
+
+		if (connect(event_fd, (struct sockaddr *)&sck, sizeof(sck)) == -1) {
+			clog(LOG_NOTICE, "Couldn't connect to acpid socket %s (%s).\n",
+					acpi_config.acpid_sock_path, strerror(errno));
+			close_acpi_event();
+			return -1;
+		}
+	} else if (event_fd <= 0) {
+		clog(LOG_ERR, "Couldn't open ACPI event device (%s).\n",
+				strerror(errno));
+		event_fd = 0;
+		return -1;
+	} else if (!acpi_config.acpid_sock_path[0]) {
+		clog(LOG_ERR, "No acpid socket given (%s).\n", acpi_config.acpid_sock_path);
+		return -1;
+	} else {
+		clog(LOG_ERR, "Unknown error (%d)-(%s).\n", event_fd, acpi_config.acpid_sock_path);
+		return -1;
+
+	}
+
+	if (fcntl(event_fd, F_SETFL, O_NONBLOCK) == -1) {
+		clog(LOG_ERR, "Couldn't set O_NONBLOCK on ACPI event handler (%s).\n",
+				strerror(errno));
+		close(event_fd);
+		return -1;
+	}
+	return 0;
+}
+
 /*  Waits for ACPI events on the file descriptor opened previously.
  *  This function uses poll(2) to wait for readable data in order
  *  to only wake cpufreqd once in case multiple events are available.
@@ -67,27 +126,33 @@
 	pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
 
-	rfd.fd = event_fd;
 	rfd.events = POLLIN | POLLPRI;
-	rfd.revents = 0;
 	
 	while (1) {
-		ret = poll(&rfd, 1, -1);
+		while (!event_fd && open_acpi_event() != 0) {
+			struct timespec req = { .tv_sec = 5, .tv_nsec = 0 };
+			nanosleep(&req, NULL);
+		}
 
-		if (ret < 0 && errno == EINTR)
-			continue;
+		rfd.fd = event_fd;
+		rfd.revents = 0;
+		ret = poll(&rfd, 1, -1);
 
-		else if (ret < 0) {
+		if (ret < 0) {
 			clog(LOG_ERR, "Error polling ACPI Event handler: %s\n",
 					strerror(errno));
-			break;
+			if (errno == EINTR)
+				close_acpi_event();
+			continue;
 		}
 		
 		/* barf and exit on any error condition */
+		/* close the FD and try too reopen it every 5 seconds */
 		if (rfd.revents & ~POLLIN) {
 			clog(LOG_ERR, "Error polling ACPI Event handler (0x%.4x).\n",
 					rfd.revents);
-			break;
+			close_acpi_event();
+			continue;
 		}
 		while ((read_chars = read(event_fd, buf, MAX_STRING_LEN-1)) > 0) {
 			buf[read_chars-1] = '\0';
@@ -97,10 +162,12 @@
 		if (read_chars < 0 && errno != EAGAIN && errno != EINTR) {
 			clog(LOG_DEBUG, "Error reading the ACPI event handler (%d)\n",
 					strerror(errno), read_chars);
-			break;
+			close_acpi_event();
+			continue;
 		} else if (read_chars == 0) {
 			clog(LOG_DEBUG, "ACPI event handler disappeared.\n");
-			break;
+			close_acpi_event();
+			continue;
 		}
 
 		/* mark pending event */
@@ -109,7 +176,6 @@
 		acpi_event_unlock();
 		/* Ring the bell!! */
 		wake_cpufreqd();
-		rfd.revents = 0;
 	}
 
 	/* set acpi_event as inactive */
@@ -141,45 +207,6 @@
 
 	event_pending = 1;
 
-	/* try to open /proc/acpi/event */
-#if 0
-	event_fd = open("/proc/acpi/event", O_RDONLY);
-#endif
-	
-	/* or fallback to the acpid socket */
-	if (event_fd <= 0 && acpi_config.acpid_sock_path[0]) {
-		struct sockaddr_un sck;
-		sck.sun_family = AF_UNIX;
-		strncpy(sck.sun_path, acpi_config.acpid_sock_path, 108);
-		sck.sun_path[107] = '\0';
-
-		if ((event_fd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
-			clog(LOG_ERR, "Couldn't open acpid socket (%s).\n",
-					strerror(errno));
-			return -1;
-		}
-
-		if (connect(event_fd, (struct sockaddr *)&sck, sizeof(sck)) == -1) {
-			clog(LOG_ERR, "Couldn't connect to acpid socket %s (%s).\n",
-					acpi_config.acpid_sock_path, strerror(errno));
-			return -1;
-		}
-	} else if (event_fd <= 0) {
-		clog(LOG_ERR, "Couldn't open ACPI event device (%s).\n",
-				strerror(errno));
-		return -1;
-	} else {
-		clog(LOG_ERR, "No acpid socket given.\n");
-		return -1;
-	}
-
-	if (fcntl(event_fd, F_SETFL, O_NONBLOCK) == -1) {
-		clog(LOG_ERR, "Couldn't set O_NONBLOCK on ACPI event handler (%s).\n",
-				strerror(errno));
-		close(event_fd);
-		return -1;
-	}
-	
 	/* launch exec thread */
 	if ((ret = pthread_create(&event_thread, NULL, &event_wait, NULL)) != 0) {
 		clog(LOG_ERR, "Unable to launch thread: %s\n", strerror(ret));
@@ -206,12 +233,9 @@
 					strerror(ret));
 		event_thread = 0;
 	}
-	
-	if (event_fd) {
-		clog(LOG_DEBUG, "closing event handle.\n");
-		close(event_fd);
-		event_fd = 0;
-	}
+
+	/* just in case the event thread missed it */
+	close_acpi_event();
 	
 	clog(LOG_INFO, "acpi_event exited.\n");
 	return 0;
Index: src/cpufreqd_acpi_temperature.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_acpi_temperature.c,v
retrieving revision 1.17
retrieving revision 1.20
diff -u -r1.17 -r1.20
--- src/cpufreqd_acpi_temperature.c	25 Jun 2006 15:47:38 -0000	1.17
+++ src/cpufreqd_acpi_temperature.c	21 Jul 2008 07:56:28 -0000	1.20
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2002-2006  Mattia Dongili <malattia@linux.it>
+ *  Copyright (C) 2002-2008  Mattia Dongili <malattia@linux.it>
  *                           George Staikos <staikos@0wned.org>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -23,16 +23,17 @@
 #include <stdlib.h>
 #include <string.h>
 #include "cpufreqd_plugin.h"
+#include "cpufreqd_acpi.h"
 #include "cpufreqd_acpi_temperature.h"
 
-#define ACPI_TEMPERATURE_DIR "/proc/acpi/thermal_zone/"
-#define ACPI_TEMPERATURE_FILE "temperature"
-#define ACPI_TEMPERATURE_FORMAT "temperature:             %ld C\n"
+#define THERMAL "thermal"
+#define THERMAL_TYPE "ACPI thermal zone"
+#define THERMAL_TEMP "temp"
 
 struct thermal_zone {
-	char name[32];
-	char zone_path[64];
-	long int temperature;
+	int temperature;
+	struct sysfs_class_device *cdev;
+	struct sysfs_attribute *temp;
 };
 
 struct temperature_interval {
@@ -40,22 +41,17 @@
 	struct thermal_zone *tz;
 };
 
-static struct thermal_zone *atz_list;
-static int temp_dir_num;
-static long int temperature;
-
-static int no_dots(const struct dirent *d)
-{
-	return d->d_name[0]!= '.';
-}
+static struct thermal_zone atz_list[64];
+static int atz_dir_num;
+static long int temp_avg;
 
 static struct thermal_zone *get_thermal_zone(const char *name)
 {
 	int i;
 	struct thermal_zone *ret = NULL;
 	
-	for (i=0; i<temp_dir_num; i++) {
-		if (strncmp(atz_list[i].name, name, 32) == 0) {
+	for (i = 0; i < atz_dir_num; i++) {
+		if (strncmp(atz_list[i].cdev->name, name, 32) == 0) {
 			ret = &atz_list[i];
 			break;
 		}
@@ -63,6 +59,19 @@
 	return ret;
 }
 
+static int atz_callback(struct sysfs_class_device *cdev)
+{
+	atz_list[atz_dir_num].cdev = cdev;
+	atz_list[atz_dir_num].temp = get_class_device_attribute(cdev,
+			THERMAL_TEMP);
+	if (!atz_list[atz_dir_num].temp)
+		return 1;
+
+	clog(LOG_DEBUG, "Found %s\n", cdev->name);
+	atz_dir_num++;
+	return 0;
+}
+
 /*  static int acpi_temperature_init(void)
  *
  *  test if ATZ dirs are present and read their 
@@ -70,42 +79,22 @@
  */
 int acpi_temperature_init(void)
 {
-	struct dirent **namelist = NULL;
-	int n = 0;
-
-	/* get ATZ path */
-	n = scandir(ACPI_TEMPERATURE_DIR, &namelist, no_dots, NULL);
-	if (n > 0) {
-		temp_dir_num = n;
-		atz_list = malloc(n * sizeof(struct thermal_zone));
-		while (n--) {
-			snprintf(atz_list[n].name, 32, "%s", namelist[n]->d_name);
-			snprintf(atz_list[n].zone_path, 64, "%s%s/",
-					ACPI_TEMPERATURE_DIR, namelist[n]->d_name);
-			clog(LOG_INFO, "TEMP path: %s name: %s\n",
-					atz_list[n].zone_path, atz_list[n].name);
-			free(namelist[n]);
-		} 
-		free(namelist);
-
-	} else if (n < -1) {
-		clog(LOG_NOTICE, "no acpi_temperature support %s:%s\n", 
-				ACPI_TEMPERATURE_DIR, strerror(errno));
-		return -1;
-
-	} else {
-		clog(LOG_NOTICE, "no acpi_temperature support found %s\n", 
-				ACPI_TEMPERATURE_DIR);
+	find_class_device(THERMAL, THERMAL_TYPE, atz_callback);
+	if (atz_dir_num <= 0) {
+		clog(LOG_INFO, "No thermal zones found\n");
 		return -1;
 	}
-
+	clog(LOG_NOTICE, "found %d ACPI Thermal Zone%s\n", atz_dir_num,
+			atz_dir_num > 1 ? "s" : "");
 	return 0;
 }
 
 int acpi_temperature_exit(void) 
 {
-	if (atz_list != NULL)
-		free(atz_list);
+	while (--atz_dir_num >= 0) {
+		put_attribute(atz_list[atz_dir_num].temp);
+		put_class_device(atz_list[atz_dir_num].cdev);
+	}
 	clog(LOG_INFO, "exited.\n");
 	return 0;
 }
@@ -131,7 +120,7 @@
 			return -1;
 		}
 		clog(LOG_INFO, "parsed %s %d-%d\n",
-				ret->tz->name, ret->min, ret->max);
+				ret->tz->cdev->name, ret->min, ret->max);
 
 	} else if (sscanf(ev, "%32[a-zA-Z0-9]:%d", atz_name, &(ret->min)) == 2) {
 		/* validate zone name and assign pointer to struct thermal_zone */
@@ -141,7 +130,7 @@
 			return -1;
 		}
 		ret->max = ret->min;
-		clog(LOG_INFO, "parsed %s %d\n", ret->tz->name, ret->min);
+		clog(LOG_INFO, "parsed %s %d\n", ret->tz->cdev->name, ret->min);
 
 	} else if (sscanf(ev, "%d-%d", &(ret->min), &(ret->max)) == 2) {
 		clog(LOG_INFO, "parsed %d-%d\n", ret->min, ret->max);
@@ -168,15 +157,16 @@
 int acpi_temperature_evaluate(const void *s)
 {
 	const struct temperature_interval *ti = (const struct temperature_interval *)s;
-	long int temp = temperature;
+	long int temp = temp_avg;
 
 	if (ti != NULL && ti->tz != NULL)
 		temp = ti->tz->temperature;
 		
-	clog(LOG_DEBUG, "called %d-%d [%s:%d]\n", ti->min, ti->max, 
-			ti != NULL && ti->tz != NULL ? ti->tz->name : "Medium", temp);
+	clog(LOG_DEBUG, "called %d-%d [%s:%.1f]\n", ti->min, ti->max, 
+			ti != NULL && ti->tz != NULL ? ti->tz->cdev->name : "Avg",
+			(float)temp / 1000);
 
-	return (temp <= ti->max && temp >= ti->min) ? MATCH : DONT_MATCH;
+	return (temp <= (ti->max * 1000) && temp >= (ti->min * 1000)) ? MATCH : DONT_MATCH;
 }
 
 /*  static int acpi_temperature_update(void)
@@ -185,39 +175,28 @@
  */
 int acpi_temperature_update(void)
 {
-	char fname[256];
 	int count = 0, i = 0;
-	long int t = 0;
-	FILE *fp = NULL;
 
 	clog(LOG_DEBUG, "called\n");
 
-	temperature = 0;
-	for (i=0; i<temp_dir_num; i++) {
-		snprintf(fname, 255, "%s%s", atz_list[i].zone_path, ACPI_TEMPERATURE_FILE);
-		fp = fopen(fname, "r");
-		if (fp) {
-			if (fscanf(fp, ACPI_TEMPERATURE_FORMAT, &t) == 1) {
-				count++;
-				temperature += t;
-				atz_list[i].temperature = t;
-				clog(LOG_INFO, "temperature for %s is %ldC\n",
-						atz_list[i].name, atz_list[i].temperature);
-			}
-			fclose(fp);
-
-		} else {
-			clog(LOG_ERR, "%s: %s\n", fname, strerror(errno));
-			clog(LOG_ERR, "ATZ path %s disappeared? send SIGHUP to re-read Temp zones\n",
-					atz_list[i].zone_path);
+	temp_avg = 0;
+	for (i = 0; i < atz_dir_num; i++) {
+
+		if (read_int(atz_list[i].temp, &atz_list[i].temperature)) {
+			continue;
 		}
+		count++;
+		temp_avg += atz_list[i].temperature;
+		clog(LOG_INFO, "temperature for %s is %.1fC\n",
+				atz_list[i].cdev->name,
+				(float)atz_list[i].temperature / 1000);
 	}
 
 	/* compute global medium value */
 	if (count > 0) {
-		temperature = (float)temperature / (float)count;
+		temp_avg = (float)temp_avg / (float)count;
 	}
-	clog(LOG_INFO, "medium temperature is %ldC\n", temperature);
+	clog(LOG_INFO, "temperature average is %.1fC\n", (float)temp_avg / 1000);
 	return 0;
 }
 
Index: src/cpufreqd_apm.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_apm.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- src/cpufreqd_apm.c	11 Sep 2005 18:56:12 -0000	1.11
+++ src/cpufreqd_apm.c	21 Jul 2008 07:56:28 -0000	1.12
@@ -48,7 +48,7 @@
 
 	rc = stat(APM_PROC_FILE, &sb);
 	if (rc < 0) {
-		clog(LOG_ERR, "%s: %s\n", APM_PROC_FILE, strerror(errno));
+		clog(LOG_INFO, "%s: %s\n", APM_PROC_FILE, strerror(errno));
 		return -1;
 	}
 	return 0;
Index: src/cpufreqd_nforce2.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_nforce2.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- src/cpufreqd_nforce2.c	2 Jul 2006 20:14:13 -0000	1.11
+++ src/cpufreqd_nforce2.c	21 Jul 2008 07:56:28 -0000	1.12
@@ -64,12 +64,12 @@
 	struct stat sb;
 
 	if (!vcore_path[0]) {
-		clog(LOG_CRIT, "Unconfigured, exiting.\n");
+		clog(LOG_INFO, "Unconfigured, exiting.\n");
 		return -1;
 	}
 	/* check vcore_path */
 	if (stat(vcore_path, &sb) != 0) {
-		clog(LOG_CRIT, "Unable to find %s.\n", vcore_path);
+		clog(LOG_INFO, "Unable to find %s.\n", vcore_path);
 		return -1;
 	}
 	return 0;
Index: src/cpufreqd_pmu.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_pmu.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- src/cpufreqd_pmu.c	11 Sep 2005 17:22:08 -0000	1.2
+++ src/cpufreqd_pmu.c	21 Jul 2008 07:56:28 -0000	1.3
@@ -109,7 +109,7 @@
 
 	fp = fopen(PMU_INFO_FILE, "r");
 	if (!fp) {
-		clog(LOG_ERR, "%s: %s\n", PMU_INFO_FILE, strerror(errno));
+		clog(LOG_INFO, "%s: %s\n", PMU_INFO_FILE, strerror(errno));
 		return -1;
 	}
 
Index: src/cpufreqd_sensors.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_sensors.c,v
retrieving revision 1.11
retrieving revision 1.12
diff -u -r1.11 -r1.12
--- src/cpufreqd_sensors.c	13 Sep 2005 13:43:12 -0000	1.11
+++ src/cpufreqd_sensors.c	21 Jul 2008 07:56:28 -0000	1.12
@@ -70,14 +70,14 @@
 
 	/* did we succeed opening a config file? */
 	if(config == NULL) {
-		clog(LOG_ERR, "no sensors.conf found, sensors disabled!\n");
+		clog(LOG_INFO, "no sensors.conf found, sensors disabled!\n");
 		return -1;
 	}
 
 	clog(LOG_INFO, "using %s\n", sensors_conffile);
 
 	if(sensors_init(config)) {
-		clog(LOG_ERR, "sensors_init() failed, sensosrs disabled!\n");
+		clog(LOG_ERR, "sensors_init() failed, sensors disabled!\n");
 		fclose(config);
 		return -1;
 	}
Index: src/cpufreqd_tau.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/cpufreqd_tau.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- src/cpufreqd_tau.c	23 Sep 2006 14:03:04 -0000	1.1
+++ src/cpufreqd_tau.c	21 Jul 2008 07:56:28 -0000	1.2
@@ -93,7 +93,7 @@
 
 	fp = fopen(CPU_INFO_FILE, "r");
 	if (!fp) {
-		clog(LOG_ERR, "%s: %s\n", CPU_INFO_FILE, strerror(errno));
+		clog(LOG_INFO, "%s: %s\n", CPU_INFO_FILE, strerror(errno));
 		return -1;
 	}
 
Index: src/main.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/main.c,v
retrieving revision 1.60
retrieving revision 1.61
diff -u -r1.60 -r1.61
--- src/main.c	13 Nov 2006 21:54:30 -0000	1.60
+++ src/main.c	20 Jul 2008 14:50:30 -0000	1.61
@@ -1,5 +1,5 @@
 /*
- *  Copyright (C) 2002-2006  Mattia Dongili <malattia@linux.it>
+ *  Copyright (C) 2002-2008  Mattia Dongili <malattia@linux.it>
  *                           George Staikos <staikos@0wned.org>
  *
  *  This program is free software; you can redistribute it and/or modify
@@ -147,7 +147,7 @@
 	} /* end foreach rule entry */
 	if (directives > 0)
 		return hits + (100 * hits / directives);
-	clog(LOG_INFO, "No evaulatable directives in Rule \"%s\".\n", rule->name);
+	clog(LOG_INFO, "No evaluatable directives in Rule \"%s\".\n", rule->name);
 	return 0;
 }
 
@@ -293,12 +293,12 @@
 static int read_args (int argc, char *argv[]) {
 
 	static struct option long_options[] = {
-		{ "help", 0, 0, 'h' }, 
-		{ "version", 0, 0, 'v' }, 
-		{ "file", 1, 0, 'f' },
-		{ "no-daemon", 0, 0, 'D' },
-		{ "manual", 0, 0, 'm' },
-		{ "verbosity", 1, 0, 'V' },
+		{ "help",	0, 0, 'h' }, 
+		{ "version",	0, 0, 'v' }, 
+		{ "file",	1, 0, 'f' },
+		{ "no-daemon",	0, 0, 'D' },
+		{ "manual",	0, 0, 'm' },
+		{ "verbosity",	1, 0, 'V' },
 		{ 0, 0, 0, 0 }, 
 	};
 	int ch,option_index = 0;
Index: src/plugin_utils.c
===================================================================
RCS file: /cvsroot/cpufreqd/sources2/src/plugin_utils.c,v
retrieving revision 1.21
retrieving revision 1.22
diff -u -r1.21 -r1.22
--- src/plugin_utils.c	2 Jan 2006 18:00:21 -0000	1.21
+++ src/plugin_utils.c	27 Jul 2008 07:47:42 -0000	1.22
@@ -274,7 +274,7 @@
 		/* try to post-configure the plugin */
 		if (plugin->plugin->plugin_post_conf != NULL
 				&& plugin->plugin->plugin_post_conf() != 0) {
-			clog(LOG_ERR, "Unable to configure plugin %s, removing\n",
+			clog(LOG_NOTICE, "Unable to configure plugin %s, removing\n",
 					plugin->plugin->plugin_name);
 
 			/* the next call is currently useless due to the fact that
