+#include <linux/fs.h>
+
+#include <pio.h>
+#include <hdd.h>
+#include <plog.h>
+
+static const char *PROVIDER_NAME = "atasmart";
+
+static int filter_sd(const char *p)
+{
+ return strlen(p) == 8 && !strncmp(p, "/dev/sd", 7);
+}
+
+static void provider_data_free(void *data)
+{
+ sk_disk_free((SkDisk *)data);
+}
+
+static SkDisk *get_disk(struct psensor *s)
+{
+ return (SkDisk *)s->provider_data;
+}
+
+static struct psensor *
+create_sensor(char *id, char *name, SkDisk *disk, int values_max_length)
+{
+ struct psensor *s;
+ int t;
+
+ t = SENSOR_TYPE_ATASMART | SENSOR_TYPE_HDD | SENSOR_TYPE_TEMP;
+
+ s = psensor_create(id,
+ strdup(name),
+ strdup(_("Disk")),
+ t,
+ values_max_length);
+
+ s->provider_data = disk;
+ s->provider_data_free_fct = &provider_data_free;
+
+ return s;
+}
+
+/*
+ * Performs the same tests than sk_disk_open and outputs the result.
+ */
+static void analyze_disk(const char *dname)
+{
+ int f;
+ struct stat st;
+ uint64_t size;
+
+ log_fct("Analyze %s", dname);
+
+ f = open(dname, O_RDONLY|O_NOCTTY|O_NONBLOCK|O_CLOEXEC);
+
+ if (f < 0) {
+ log_fct("Could not open file %s: %s", dname, strerror(errno));
+ goto fail;
+ }
+
+ if (fstat(f, &st) < 0) {
+ log_fct("fstat fails %s: %s", dname, strerror(errno));
+ goto fail;
+ }
+
+ if (!S_ISBLK(st.st_mode)) {
+ log_fct("!S_ISBLK fails %s", dname);
+ goto fail;
+ }