diff --git a/Makefile b/Makefile index 9013763..848a03f 100644 --- a/Makefile +++ b/Makefile @@ -7,7 +7,7 @@ PID_DIR = /var/run # ############################ SRC = $(wildcard *.c) -TARGET = qnapd +TARGET = diskwatch BUILD_DIR = build CFLAGS = -O2 -g -pipe -Wall -Wno-unused-result -DPROGNAME='"$(TARGET)"' CFLAGS += -MMD -MF $(BUILD_DIR)/$(*D)/$(*F).d diff --git a/TODO b/TODO deleted file mode 100644 index b63741d..0000000 --- a/TODO +++ /dev/null @@ -1,8 +0,0 @@ -- dynamic pages -- refresh of dynamic pages (clock, loadavg) - -- disk utilization (MB/GB) - - mntpoints given in config - -- network usage? -- cpu usage? diff --git a/diskwatch.c b/diskwatch.c index 963cb2a..1e90b6d 100644 --- a/diskwatch.c +++ b/diskwatch.c @@ -31,7 +31,6 @@ #include "configfile.h" #include "diskwatch.h" #include "event.h" -#include "lcd.h" #include "list.h" #include "logging.h" @@ -56,79 +55,11 @@ struct disk_entry { struct diskwatch { struct list_head disk_list; - struct lcddev *lcd; struct event_timeout *check_timeout; }; static struct diskwatch diskwatch_glob; -static int diskwatch_check_standby(struct disk_entry *entry); - -static int lcdpage_diskwatch(struct lcddev *lcd, int event, void *privdata) -{ - static struct disk_entry *entry; - struct diskwatch *dwatch = (struct diskwatch *)privdata; - - if (entry == NULL) { - if (list_empty(&dwatch->disk_list)) { - return LCDPAGE_COMMAND_NEXT; - } - - entry = list_entry(dwatch->disk_list.next, struct disk_entry, list); - } - - switch (event) { - case LCDPAGE_EVENT_BUTTON1: - if (entry->list.next == &dwatch->disk_list) { - entry = NULL; - return LCDPAGE_COMMAND_NEXT; - } - - entry = list_entry(entry->list.next, struct disk_entry, list); - lcd_set_backlight(lcd, 1); - break; - - case LCDPAGE_EVENT_ENTER: - entry = list_entry(dwatch->disk_list.next, struct disk_entry, list); - lcd_set_backlight(lcd, 1); - break; - - case LCDPAGE_EVENT_BACKLIGHT: - case LCDPAGE_EVENT_EXIT: - return 0; - - default: - break; - } - - char line1[32]; - char line2[32]; - - snprintf(line1, sizeof(line1), "DISK(%s):", entry->device); - if (entry->flags & F_PRESENT) { - diskwatch_check_standby(entry); - - if (entry->flags & F_STANDBY) { - snprintf(line2, sizeof(line2), "STANDBY"); - } else { - int timeout = entry->standby_timeout - time(NULL); - int hours = timeout / 3600; - timeout = timeout % 3600; - int minutes = timeout / 60; - timeout = timeout % 60; - - snprintf(line2, sizeof(line2), "RUN -%02d:%02d:%02d", hours, minutes, timeout); - } - - } else { - snprintf(line2, sizeof(line2), "not present"); - } - - lcd_setlines(lcd, line1, line2); - - return 1000; -} - static int diskwatch_check_standby(struct disk_entry *entry) { if (!(entry->flags & F_PRESENT)) @@ -315,7 +246,7 @@ void diskwatch_exit(void) } } -int diskwatch_init(struct lcddev *lcd) +int diskwatch_init(void) { struct diskwatch *dwatch = &diskwatch_glob; @@ -331,10 +262,5 @@ int diskwatch_init(struct lcddev *lcd) config_get_int("diskwatch", "check_interval", &check_interval, 60); dwatch->check_timeout = event_add_timeout_ms(check_interval * 1000, diskwatch_check_stats, 0, dwatch); - dwatch->lcd = lcd; - if (dwatch->lcd != NULL) { - lcd_addpage_cb(dwatch->lcd, 150, lcdpage_diskwatch, dwatch); - } - return 0; } diff --git a/diskwatch.conf b/diskwatch.conf new file mode 100644 index 0000000..28bb3f4 --- /dev/null +++ b/diskwatch.conf @@ -0,0 +1,11 @@ +[global] +pidfile diskwatch.pid +logfile diskwatch.log + +[diskwatch] +check_interval 60 + +#disk /dev/sda,7200 +disk /dev/sdb,120 +#disk /dev/sdc,7200 +#disk /dev/sdd,7200 diff --git a/diskwatch.h b/diskwatch.h index c7fa4db..f4a85f5 100644 --- a/diskwatch.h +++ b/diskwatch.h @@ -1,9 +1,7 @@ #ifndef _DISKWATCH_H_ #define _DISKWATCH_H_ -#include "lcd.h" - void diskwatch_exit(void); -int diskwatch_init(struct lcddev *lcd); +int diskwatch_init(void); #endif /* _DISKWATCH_H_ */ diff --git a/lcd.c b/lcd.c deleted file mode 100644 index 48d739d..0000000 --- a/lcd.c +++ /dev/null @@ -1,699 +0,0 @@ -/*************************************************************************** - * Copyright (C) 05/2011 by Olaf Rempel * - * razzor@kopf-tisch.de * - * * - * 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 * - * MERCHANTABILITY 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 -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "event.h" -#include "lcd.h" -#include "list.h" -#include "logging.h" - -#define _LCD_DEBUG 0 -#define _LCD_DUMMY 1 - -#define LCD_SCROLL_SPEED 750 /* 750ms */ -#define LCD_RESET_TIMEOUT 250 /* 250ms */ -#define LCD_RESET_RETRY_TIMEOUT 10000 /* 10s */ - -#define A125_CMD_GETBUTTON { 0x4D, 0x06 } // not tried -#define A125_CMD_SETLINE { 0x4D, 0x0C, 0x00, 0x10 } // [2] is line, append 16 chars -#define A125_CMD_CLEAR { 0x4D, 0x0D } // works, but slow -#define A125_CMD_BACKLIGHT { 0x4D, 0x5E, 0x00 } // [2] is on/off -#define A125_CMD_RESET { 0x4D, 0xFF } - -#define A125_EVENT_ID { 0x53, 0x01 } // never seen -#define A125_EVENT_BUTTON1 { 0x53, 0x05, 0x00, 0x01 } -#define A125_EVENT_BUTTON2 { 0x53, 0x05, 0x00, 0x02 } -#define A125_EVENT_VERSION { 0x53, 0x08 } // never seen -#define A125_EVENT_ACTINFO { 0x53, 0xAA } -#define A125_EVENT_INVALID { 0x53, 0xFB } // never seen - -struct lcdpage { - struct list_head list; - int priority; - - int (*callback)(struct lcddev *dev, int event, void *privdata); - void *privdata; -}; - -enum lcdstate { - LCD_STATE_NOT_INITIALIZED = 0x00, - LCD_STATE_INITIALIZING, - LCD_STATE_INITIALIZING_FAILED, - LCD_STATE_READY, -}; - -struct lcddev { - int fd; -#if (_LCD_DUMMY) - struct event_fd *fakedevice_event; -#endif /* (_LCD_DUMMY) */ - struct termios oldtio; - - enum lcdstate state; - - int backlight_enabled; - int backlight_timeout_ms; - - struct list_head page_list; - struct lcdpage *current_page; - - const char *line_data[2]; - int line_length[2]; - int scroll_pos; - - int update_ms; - - struct event_fd *read_event; - struct event_timeout *reset_timeout; - struct event_timeout *backlight_timeout; - struct event_timeout *scroll_timeout; - struct event_timeout *update_timeout; -}; - -static void lcd_pagecallback(struct lcddev *dev, int event); - -void lcd_close(struct lcddev *dev) -{ - if (dev->current_page) { - dev->current_page->callback(dev, LCDPAGE_EVENT_EXIT, dev->current_page->privdata); - dev->current_page = NULL; - } - - struct lcdpage *search, *tmp; - list_for_each_entry_safe(search, tmp, &dev->page_list, list) { - free(search); - } - - if (dev->reset_timeout) { - event_remove_timeout(dev->reset_timeout); - dev->reset_timeout = NULL; - } - - if (dev->backlight_timeout) { - event_remove_timeout(dev->backlight_timeout); - dev->backlight_timeout = NULL; - } - - if (dev->update_timeout) { - event_remove_timeout(dev->update_timeout); - dev->update_timeout = NULL; - } - - if (dev->scroll_timeout) { - event_remove_timeout(dev->scroll_timeout); - dev->scroll_timeout = NULL; - } - - if (dev->read_event) { - event_remove_fd(dev->read_event); - dev->read_event = NULL; - } - -#if (_LCD_DUMMY) - if (dev->fakedevice_event != NULL) { - int fd = event_get_fd(dev->fakedevice_event); - event_remove_fd(dev->fakedevice_event); - dev->fakedevice_event = NULL; - close(fd); - - } else -#endif /* (_LCD_DUMMY) */ - { - tcsetattr(dev->fd, TCSANOW, &dev->oldtio); - } - - close(dev->fd); - free(dev); -} - -static int lcd_realdevice_open(struct lcddev *dev, const char *device) -{ - dev->fd = open(device, O_RDWR | O_NOCTTY); - if (dev->fd < 0) { - log_print(LOG_ERROR, "%s(): failed to open '%s'", __FUNCTION__, device); - return -1; - } - - if (fcntl(dev->fd, F_SETFD, FD_CLOEXEC) < 0) { - log_print(LOG_ERROR, "%s(): fcntl(FD_CLOEXEC)", __FUNCTION__); - close(dev->fd); - return -1; - } - - tcgetattr(dev->fd, &dev->oldtio); - - struct termios newtio; - memset(&newtio, 0, sizeof(newtio)); - newtio.c_iflag |= IGNBRK; - newtio.c_lflag &= ~(ISIG | ICANON | ECHO); - newtio.c_cflag = B1200 | CS8 | CLOCAL | CREAD; - newtio.c_cc[VMIN] = 1; - newtio.c_cc[VTIME] = 0; - cfsetospeed(&newtio, B1200); - cfsetispeed(&newtio, B1200); - - int err = tcsetattr(dev->fd, TCSAFLUSH, &newtio); - if (err < 0) { - log_print(LOG_ERROR, "%s(): failed to set termios", __FUNCTION__); - close(dev->fd); - return -1; - } - - return 0; -} - -#if (_LCD_DUMMY) -static int lcd_fakedevice_reply(int fd, void *privdata) -{ - struct lcddev *dev = (struct lcddev *)privdata; - char buf[32]; - - if (read(fd, buf, sizeof(buf)) <= 0) { - dev->fakedevice_event = NULL; - return -1; - } - - char reset_expect[] = A125_CMD_RESET; - if (memcmp(buf, reset_expect, sizeof(reset_expect)) == 0) { - char actinfo_cmd[] = A125_EVENT_ACTINFO; - write(fd, actinfo_cmd, sizeof(actinfo_cmd)); - } - - return 0; -} - -static int lcd_fakedevice_open(struct lcddev *dev) -{ - int fd[2]; - - if (socketpair(AF_LOCAL, SOCK_STREAM, 0 , fd) < 0) { - log_print(LOG_ERROR, "%s(): socketpair() failed", __FUNCTION__); - return -1; - } - - if (fcntl(fd[0], F_SETFD, FD_CLOEXEC) < 0) { - log_print(LOG_ERROR, "%s(): fcntl(FD_CLOEXEC)", __FUNCTION__); - close(fd[0]); - close(fd[1]); - return -1; - } - - if (fcntl(fd[1], F_SETFD, FD_CLOEXEC) < 0) { - log_print(LOG_ERROR, "%s(): fcntl(FD_CLOEXEC)", __FUNCTION__); - close(fd[0]); - close(fd[1]); - return -1; - } - - dev->fd = fd[0]; - dev->fakedevice_event = event_add_readfd(NULL, fd[1], lcd_fakedevice_reply, dev); - return 0; -} -#endif /* (_LCD_DUMMY) */ - -#if (_LCD_DEBUG > 1) -static void lcd_dump(const char *prefix, int len, int size, const char *data) -{ - int i; - int pos = 0; - char buf[256]; - - for (i = 0; i < len; i++) { - pos += snprintf(buf, sizeof(buf) - pos, "0x%X ", (unsigned char)data[i]); - } - - log_print(LOG_DEBUG, "%s:[%d/%d]: %s", prefix, len, size, buf); -} -#endif /* (_LCD_DEBUG > 1) */ - -static int lcd_read(struct lcddev *dev, const char *buf, int len) -{ - int retval = 0, cnt = 0; - while (cnt < len) { - retval = read(dev->fd, (char *)buf + cnt, len - cnt); - if (retval <= 0) - break; - - cnt += retval; - } -#if (_LCD_DEBUG > 1) - lcd_dump(__FUNCTION__, cnt, len, buf); -#endif /* (_LCD_DEBUG > 1) */ - return (cnt != 0) ? cnt : retval; -} - -static int lcd_write(struct lcddev *dev, char *buf, int len) -{ - int retval = write(dev->fd, buf, len); - -#if (_LCD_DEBUG > 1) - lcd_dump(__FUNCTION__, retval, len, buf); -#endif /* (_LCD_DEBUG > 1) */ - return retval; -} - -static void lcd_reset(struct lcddev *dev); - -static int lcd_reset_retry_timeout_cb(int timerid, void *privdata) -{ - struct lcddev *dev = (struct lcddev *)privdata; - dev->reset_timeout = NULL; - - lcd_reset(dev); - return -1; /* singleshot */ -} - -static int lcd_reset_timeout_cb(int timerid, void *privdata) -{ - struct lcddev *dev = (struct lcddev *)privdata; - - log_print(LOG_ERROR, "failed to initalize LCD"); - dev->state = LCD_STATE_INITIALIZING_FAILED; - - dev->reset_timeout = event_add_timeout_ms(LCD_RESET_RETRY_TIMEOUT, lcd_reset_retry_timeout_cb, 0, dev); - - return -1; /* singleshot */ -} - -static void lcd_reset(struct lcddev *dev) -{ -#if (_LCD_DEBUG > 0) - log_print(LOG_DEBUG, "%s()", __FUNCTION__); -#endif /* (_LCD_DEBUG > 0) */ - - char cmd[] = A125_CMD_RESET; - lcd_write(dev, cmd, sizeof(cmd)); - - /* force next backlight command */ - dev->backlight_enabled = -1; - - dev->state = LCD_STATE_INITIALIZING; - - dev->reset_timeout = event_add_timeout_ms(LCD_RESET_TIMEOUT, lcd_reset_timeout_cb, 0, dev); -} - -static int lcd_backlight(struct lcddev *dev, int enable) -{ - if (dev->state != LCD_STATE_READY) - return -1; - -#if (_LCD_DEBUG > 0) - log_print(LOG_DEBUG, "%s(%d)", __FUNCTION__, enable); -#endif /* (_LCD_DEBUG > 0) */ - - if (dev->backlight_enabled != enable) { - char cmd[] = A125_CMD_BACKLIGHT; - - cmd[2] = (enable) ? 0x01 : 0x00; - lcd_write(dev, cmd, sizeof(cmd)); - - dev->backlight_enabled = enable; - } - - return 0; -} - -static int lcd_backlight_timeout_cb(int timerid, void *privdata) -{ - struct lcddev *dev = (struct lcddev *)privdata; - dev->backlight_timeout = NULL; - - lcd_set_backlight(dev, 0); - - return -1; /* singleshot */ -} - -int lcd_set_backlight(struct lcddev *dev, int enable) -{ - if (dev->backlight_timeout != NULL) { - event_remove_timeout(dev->backlight_timeout); - dev->backlight_timeout = NULL; - } - - if (!enable) { - lcd_pagecallback(dev, LCDPAGE_EVENT_BACKLIGHT); - - /* callback re-enabled backlight */ - if (dev->backlight_timeout != NULL) { - return 0; - } - } - - int retval = lcd_backlight(dev, enable); - - if (enable) { - /* start backlight timeout */ - dev->backlight_timeout = event_add_timeout_ms(dev->backlight_timeout_ms, lcd_backlight_timeout_cb, 0, dev); - - } else { - /* disable updates (display is not visible) */ - if (dev->update_timeout != NULL) { - event_remove_timeout(dev->update_timeout); - dev->update_timeout = NULL; - } - - /* disable scrolling (display is not visible) */ - if (dev->scroll_timeout != NULL) { - event_remove_timeout(dev->scroll_timeout); - dev->scroll_timeout = NULL; - } - } - - return retval; -} - -static int lcd_update_timeout_cb(int timerid, void *privdata) -{ - struct lcddev *dev = (struct lcddev *)privdata; - - dev->update_timeout = NULL; - lcd_pagecallback(dev, LCDPAGE_EVENT_UPDATE); - - return -1; /* singleshot */ -} - -static void lcd_update_start(struct lcddev *dev, int update_ms) -{ - dev->update_ms = update_ms; - - if (dev->update_timeout != NULL) { - event_remove_timeout(dev->update_timeout); - dev->update_timeout = NULL; - } - - if (update_ms > 0) { - dev->update_timeout = event_add_timeout_ms(update_ms, lcd_update_timeout_cb, 0, dev); - } -} - -static int lcd_read_cb(int fd, void *privdata) -{ - struct lcddev *dev = (struct lcddev *)privdata; - - char buf[4]; - int size = (dev->state != LCD_STATE_INITIALIZING) ? sizeof(buf) : 2; - int len = lcd_read(dev, buf, size); - - if (dev->state == LCD_STATE_INITIALIZING) { - char expect[] = A125_EVENT_ACTINFO; - - if (len != sizeof(expect)) - return 0; - - if (memcmp(buf, expect, sizeof(expect)) == 0) { - event_remove_timeout(dev->reset_timeout); - dev->reset_timeout = NULL; - - dev->state = LCD_STATE_READY; - - /* trigger application to set data */ - lcd_pagecallback(dev, LCDPAGE_EVENT_ENTER); - } - - } else if (dev->state == LCD_STATE_READY) { - char expect1[] = A125_EVENT_BUTTON1; - char expect2[] = A125_EVENT_BUTTON2; - - if (len != sizeof(expect1) && len != sizeof(expect2)) - return 0; - - if (memcmp(buf, expect1, sizeof(buf)) == 0) { - lcd_pagecallback(dev, LCDPAGE_EVENT_BUTTON1); - - } else if (memcmp(buf, expect2, sizeof(buf)) == 0) { - lcd_pagecallback(dev, LCDPAGE_EVENT_BUTTON2); - } - } - - return 0; -} - -static int lcd_setline(struct lcddev *dev, int line, int len, const char *buf) -{ - if (dev->state != LCD_STATE_READY) - return -1; - - char cmd[20 +1] = A125_CMD_SETLINE; - cmd[2] = line; - - memset(cmd +4, ' ', 16); - memcpy(cmd +4, buf, (len > 16) ? 16 : len); - cmd[20] = '\0'; - -#if (_LCD_DEBUG > 0) - log_print(LOG_DEBUG, "%s(%d, '%-16s')", __FUNCTION__, line, cmd +4); -#endif /* (_LCD_DEBUG > 0) */ - - lcd_write(dev, cmd, 20); - return 0; -} - -static int lcd_scroll_timeout_cb(int timerid, void *privdata) -{ - struct lcddev *dev = (struct lcddev *)privdata; - int i, reset_pos = 0; - - for (i = 0; i < 2; i++) { - int line_pos = dev->scroll_pos; - if (line_pos < 0) - line_pos = 0; - - /* mark line as complete if one space is visible after message */ - if ((dev->line_length[i] - line_pos) <= 15) { - reset_pos++; - } - - /* do not scroll further if message is not visible */ - if ((dev->line_length[i] - line_pos) < 0) { - line_pos = dev->line_length[i]; - } - - lcd_setline(dev, i, dev->line_length[i] - line_pos, dev->line_data[i] + line_pos); - } - - dev->scroll_pos++; - - if (reset_pos == 2) - dev->scroll_pos = -1; - - /* periodic */ - return 0; -} - -static void lcd_scroll_start(struct lcddev *dev) -{ - if (dev->scroll_timeout != NULL) { - event_remove_timeout(dev->scroll_timeout); - dev->scroll_timeout = NULL; - } - - if ((dev->line_length[0] > 16) || (dev->line_length[1] > 16)) { - dev->scroll_timeout = event_add_timeout_ms(LCD_SCROLL_SPEED, lcd_scroll_timeout_cb, 0, dev); - } -} - -int lcd_setlines(struct lcddev *dev, const char *line1, const char *line2) -{ - int i; - int line_length[2] = { 0, 0 }; - const char *line[2] = { line1, line2 }; - - for (i = 0; i < 2; i++) { - if (line[i] != NULL) { - line_length[i] = strlen(line[i]); - - if ((line_length[i] == dev->line_length[i]) && (dev->line_data[i] != NULL)) { - if (memcmp(line[i], dev->line_data[i], line_length[i]) == 0) { - /* same data, no update needed */ - continue; - } - } - } - - if (dev->line_data[i] != NULL) { - free((void *)dev->line_data[i]); - dev->line_data[i] = NULL; - } - - if (line[i] != NULL) { - dev->line_data[i] = strdup(line[i]); - } - dev->line_length[i] = line_length[i]; - - if (dev->backlight_enabled) { - lcd_setline(dev, i, dev->line_length[i], dev->line_data[i]); - - dev->scroll_pos = 0; - lcd_scroll_start(dev); - } - } - - return 0; -} - -static void lcd_pagecallback(struct lcddev *dev, int event) -{ - if (dev->state != LCD_STATE_READY) { - return; - } - - if (dev->current_page == NULL) { - if (list_empty(&dev->page_list)) { - return; - } - - dev->current_page = list_entry(dev->page_list.next, struct lcdpage, list); - } - - if ((dev->backlight_enabled == 0x00) && ((event == LCDPAGE_EVENT_BUTTON1) || (event == LCDPAGE_EVENT_BUTTON2))) { - lcd_set_backlight(dev, 1); - - event = LCDPAGE_EVENT_UPDATE; - - /* restart scrolling if needed */ - lcd_scroll_start(dev); - } - - int next; - do { -#if (_LCD_DEBUG > 0) - log_print(LOG_DEBUG, "%s: cb(%p, 0x%x)", __FUNCTION__, dev->current_page, event); -#endif - int retval = dev->current_page->callback(dev, event, dev->current_page->privdata); -#if (_LCD_DEBUG > 0) - log_print(LOG_DEBUG, "%s: cb(%p, 0x%x) => 0x%x", __FUNCTION__, dev->current_page, event, retval); -#endif - - next = (retval == LCDPAGE_COMMAND_NEXT); - if (next) { - struct lcdpage *page = dev->current_page; - - if (page->list.next != &dev->page_list) { - page = list_entry(page->list.next, struct lcdpage, list); - } else { - page = list_entry(page->list.next->next, struct lcdpage, list); - } - - /* no other page ready */ - if (page == dev->current_page) { - break; - } - - /* remove update interval for next page */ - if (dev->update_timeout != NULL) { - event_remove_timeout(dev->update_timeout); - dev->update_timeout = NULL; - } - - /* remove scroll interval for next page */ - if (dev->scroll_timeout != NULL) { - event_remove_timeout(dev->scroll_timeout); - dev->scroll_timeout = NULL; - } - - dev->current_page->callback(dev, LCDPAGE_EVENT_EXIT, dev->current_page->privdata); - dev->current_page = page; - event = LCDPAGE_EVENT_ENTER; - - /* retval is update interval */ - } else if ((event != LCDPAGE_EVENT_BACKLIGHT) && (event != LCDPAGE_EVENT_EXIT)) { - lcd_update_start(dev, retval); - } - } while (next); -} - -int lcd_addpage_cb(struct lcddev *dev, - int priority, - int (*event_callback)(struct lcddev *dev, int event, void *privdata), - void *event_privdata) -{ - struct lcdpage *page = malloc(sizeof(struct lcdpage)); - if (page == NULL) { - log_print(LOG_ERROR, "%s(): out of memory", __FUNCTION__); - return -1; - } - - page->priority = priority; - page->callback = event_callback; - page->privdata = event_privdata; - - int inserted = 0; - struct lcdpage *search; - list_for_each_entry(search, &dev->page_list, list) { - if (page->priority > search->priority) { - list_add_tail(&page->list, &search->list); - inserted = 1; - break; - } - } - - if (!inserted) { - list_add_tail(&page->list, &dev->page_list); - } - - if (dev->current_page == NULL) { - lcd_pagecallback(dev, LCDPAGE_EVENT_ENTER); - } - - return 0; -} - -struct lcddev * lcd_open(const char *devicename, int backlight_timeout) -{ - struct lcddev *dev = malloc(sizeof(struct lcddev)); - if (dev == NULL) { - log_print(LOG_ERROR, "%s(): out of memory", __FUNCTION__); - return NULL; - } - - memset(dev, 0, sizeof(struct lcddev)); - - INIT_LIST_HEAD(&dev->page_list); - - int retval; -#if (_LCD_DUMMY) - if (strncmp(devicename, "dummy", 5) == 0) { - retval = lcd_fakedevice_open(dev); - } else -#endif /* (_LCD_DUMMY) */ - { - retval = lcd_realdevice_open(dev, devicename); - } - - if (retval < 0) { - free(dev); - return NULL; - } - - dev->read_event = event_add_readfd(NULL, dev->fd, lcd_read_cb, dev); - dev->backlight_timeout_ms = backlight_timeout * 1000; - - lcd_reset(dev); - return dev; -} diff --git a/lcd.h b/lcd.h deleted file mode 100644 index afdbbe2..0000000 --- a/lcd.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _LCD_H_ -#define _LCD_H_ - -struct lcddev; /* private data */ - -struct lcddev * lcd_open(const char *devicename, int backlight_timeout); -void lcd_close(struct lcddev *dev); - -int lcd_set_backlight(struct lcddev *dev, int enable); -int lcd_setlines(struct lcddev *dev, const char *line1, const char *line2); - -#define LCDPAGE_EVENT_BUTTON1 0xFFFFFF01 /* button "enter" pressed */ -#define LCDPAGE_EVENT_BUTTON2 0xFFFFFF02 /* button "select" pressed */ -#define LCDPAGE_EVENT_BACKLIGHT 0xFFFFFF03 /* backlight timeout */ -#define LCDPAGE_EVENT_ENTER 0xFFFFFF05 /* page entered */ -#define LCDPAGE_EVENT_EXIT 0xFFFFFF06 /* page left */ -#define LCDPAGE_EVENT_UPDATE 0xFFFFFF07 /* update content */ -#define LCDPAGE_COMMAND_NEXT 0xFFFFFF80 /* change to next page */ - -int lcd_addpage_cb(struct lcddev *dev, - int priority, - int (*event_callback)(struct lcddev *dev, int event, void *privdata), - void *event_privdata); - -#endif /* _LCD_H_ */ diff --git a/lcdpage.c b/lcdpage.c deleted file mode 100644 index b29f065..0000000 --- a/lcdpage.c +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * Copyright (C) 12/2012 by Olaf Rempel * - * razzor@kopf-tisch.de * - * * - * 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 * - * MERCHANTABILITY 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 -#include -#include -#include - -#include -#include -#include - -#include "lcd.h" -#include "lcdpage.h" - -/* - * system: - * - os version done - * - kernel version done - * - hostname done - * - date/time done - * - uptime done - * - avgload done - * - cpu usage - * - memory/swap usage - * - temperature done (pic.c) - * - fan error done (pic.c) - * - * disk drives: - * - temperature -> disk - * - state (idle / running), time to idle -> disk - * - current i/o (aggregated?) - * - * partitions: - * - used / free / total - * - * ethernet interface: - * - link (10/100/1000) - * - current i/o - * - * ip interface: - * - ip address/netmask - * - default gateway - * - dns - * - */ - -static int lcdpage_system(struct lcddev *dev, int event, void *privdata) -{ - static int subpage; - int retval = 0; - char line1[64]; - char line2[64]; - - memset(line1, 0x00, sizeof(line1)); - memset(line2, 0x00, sizeof(line2)); - - switch (event) { - case LCDPAGE_EVENT_BUTTON1: - lcd_set_backlight(dev, 1); - subpage++; - break; - - case LCDPAGE_EVENT_ENTER: - lcd_set_backlight(dev, 1); - subpage = 0; - break; - - case LCDPAGE_EVENT_BACKLIGHT: - case LCDPAGE_EVENT_EXIT: - return 0; - - default: - break; - } - - if (subpage == 0) { - FILE *fp = fopen("/etc/issue.net", "r"); - if (fp != NULL) { - fread(line1, 1, sizeof(line1), fp); - fclose(fp); - - char *trim = memchr(line1, 0x0A, sizeof(line1)); - if (trim != NULL) - *trim = '\0'; - - trim = memchr(line1, 0x0D, sizeof(line1)); - if (trim != NULL) - *trim = '\0'; - } else { - strcpy(line1, ""); - } - - struct utsname utsbuf; - uname(&utsbuf); - - snprintf(line2, sizeof(line2), "%s %s", utsbuf.sysname, utsbuf.release); - - lcd_setlines(dev, line1, line2); - - } else if (subpage == 1) { - /* copy hostname */ - if (gethostname(line2, sizeof(line2)) < 0) { - strcpy(line2, ""); - } - - int len = strlen(line2); - line2[len++] = '.'; - - /* append domainname */ - if (getdomainname(line2 + len, sizeof(line2) - len) < 0) { - strcpy(line2 + len, "unknown"); - } - - lcd_setlines(dev, "Hostname:", line2); - - } else if (subpage == 2) { - struct tm tmp; - time_t now; - - time(&now); - localtime_r(&now, &tmp); - - strftime(line1, sizeof(line1), "Time: %H:%M:%S", &tmp); - strftime(line2, sizeof(line2), "Date: %Y/%m/%d", &tmp); - - lcd_setlines(dev, line1, line2); - retval = 1000; /* update every second */ - - } else if (subpage == 3) { - struct sysinfo info; - - if (sysinfo(&info) < 0) { - return 0; - } - - int tmp, days, hours, minutes; - - days = info.uptime / 86400; - tmp = info.uptime % 86400; - - hours = tmp / 3600; - tmp = tmp % 3600; - - minutes = tmp / 60; - tmp = tmp % 60; - - snprintf(line2, sizeof(line2), " %03dd %02d:%02d:%02d", days, hours, minutes, tmp); - lcd_setlines(dev, "Uptime:", line2); - retval = 1000; - - } else if (subpage == 4) { - double loadavg[3]; - - if (getloadavg(loadavg, 3) < 0) { - return 0; - } - - snprintf(line2, sizeof(line2), " %1.2f %1.2f %1.2f", loadavg[0], loadavg[1], loadavg[2]); - lcd_setlines(dev, "Load Average:", line2); - retval = 1000; - - } else { - return LCDPAGE_COMMAND_NEXT; - } - - /* update every 1000ms */ - return retval; -} - -static int lcdpage_network(struct lcddev *dev, int event, void *privdata) -{ - static int subpage; - - switch (event) { - case LCDPAGE_EVENT_BUTTON1: - lcd_set_backlight(dev, 1); - subpage++; - break; - - case LCDPAGE_EVENT_ENTER: - lcd_set_backlight(dev, 1); - subpage = 0; - break; - - case LCDPAGE_EVENT_BACKLIGHT: - case LCDPAGE_EVENT_EXIT: - return 0; - - default: - break; - } - - switch (subpage) { - case 0: - lcd_setlines(dev, "Address(br0):", "10.10.250.135"); - break; - case 1: - lcd_setlines(dev, "Netmask(br0):", "255.255.0.0"); - break; - case 2: - lcd_setlines(dev, "Gateway(br0):", "10.10.250.250"); - break; - default: - return LCDPAGE_COMMAND_NEXT; - } - - return 0; -} - -void lcdpage_free(void) -{ - /* nothing to do, lcdpages are cleaned up in lcd_close() */ -} - -int lcdpage_init(struct lcddev *dev) -{ - lcd_addpage_cb(dev, 200, lcdpage_system, NULL); - lcd_addpage_cb(dev, 100, lcdpage_network, NULL); - - return 0; -} diff --git a/lcdpage.h b/lcdpage.h deleted file mode 100644 index 3d89f39..0000000 --- a/lcdpage.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef _LCDPAGE_H_ -#define _LCDPAGE_H_ - -#include "lcd.h" - -int lcdpage_init(struct lcddev *dev); -void lcdpage_free(void); - -#endif /* _LCDPAGE_H_ */ diff --git a/qnapd.c b/main.c similarity index 77% rename from qnapd.c rename to main.c index a5fc651..6cd2292 100644 --- a/qnapd.c +++ b/main.c @@ -28,18 +28,13 @@ #include "configfile.h" #include "diskwatch.h" #include "event.h" -#include "lcd.h" -#include "lcdpage.h" #include "logging.h" -#include "pic.h" #include "pidfile.h" #include "signals.h" -#define DEFAULT_CONFIG "qnapd.conf" -#define DEFAULT_LOGFILE "qnapd.log" -#define DEFAULT_PIDFILE "qnapd.pid" - -#define LCD_TIMEOUT 15 +#define DEFAULT_CONFIG "diskwatch.conf" +#define DEFAULT_LOGFILE "diskwatch.log" +#define DEFAULT_PIDFILE "diskwatch.pid" static struct option opts[] = { { "config", 1, 0, 'c' }, @@ -83,7 +78,7 @@ int main(int argc, char *argv[]) break; case 'h': /* help */ - printf("Usage: qnapd [options]\n" + printf("Usage: diskwatch [options]\n" "Options: \n" " --config -c configfile use this configfile\n" " --debug -d do not fork and log to stderr\n" @@ -109,7 +104,7 @@ int main(int argc, char *argv[]) /* check pidfile */ const char *pidfile = config_get_string("global", "pidfile", DEFAULT_PIDFILE); if (pidfile_check(pidfile, 1) != 0) { - log_print(LOG_ERROR, "qnapd already running"); + log_print(LOG_ERROR, "diskwatch already running"); exit(1); } @@ -134,42 +129,13 @@ int main(int argc, char *argv[]) signal_init(); signal_add_callback(SIGHUP, trigger_restart, NULL); - log_print(LOG_EVERYTIME, "qnapd started (pid:%d)", getpid()); + log_print(LOG_EVERYTIME, "diskwatch started (pid:%d)", getpid()); while (1) { - struct lcddev *lcd = NULL; - struct picdev *pic = NULL; int abort = 0; do { - const char *devicename = config_get_string("global", "lcddevice", NULL); - if (devicename != NULL) { - int lcdtimeout; - - config_get_int("global", "lcdtimeout", &lcdtimeout, LCD_TIMEOUT); - - lcd = lcd_open(devicename, lcdtimeout); - if (lcd == NULL) { - abort = 1; - break; - } - - if (lcdpage_init(lcd) < 0) { - abort = 1; - break; - } - } - - devicename = config_get_string("global", "picdevice", NULL); - if (devicename != NULL) { - pic = pic_open(devicename, lcd); - if (pic == NULL) { - abort = 1; - break; - } - } - - if (diskwatch_init(lcd) < 0) { + if (diskwatch_init() < 0) { abort = 1; break; } @@ -180,15 +146,6 @@ int main(int argc, char *argv[]) diskwatch_exit(); - if (pic != NULL) { - pic_close(pic); - } - - if (lcd != NULL) { - lcdpage_free(); - lcd_close(lcd); - } - config_free(); if (abort) @@ -201,7 +158,7 @@ int main(int argc, char *argv[]) if (!debug && log_init(logfile) < 0) break; - log_print(LOG_EVERYTIME, "qnapd restarted (pid:%d) ", getpid()); + log_print(LOG_EVERYTIME, "diskwatch restarted (pid:%d) ", getpid()); } return 0; diff --git a/pic.c b/pic.c deleted file mode 100644 index 596e59f..0000000 --- a/pic.c +++ /dev/null @@ -1,257 +0,0 @@ -/*************************************************************************** - * Copyright (C) 02/2012 by Olaf Rempel * - * razzor@kopf-tisch.de * - * * - * 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 * - * MERCHANTABILITY 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 -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "event.h" -#include "lcd.h" -#include "logging.h" -#include "pic.h" - -struct picdev { - int fd; - struct termios oldtio; - - int fan_speed; - int fan_error; - int temperature; - - struct event_fd *read_event; -}; - -static int pic_close_device(struct picdev *dev) -{ - tcsetattr(dev->fd, TCSANOW, &dev->oldtio); - close(dev->fd); - return 0; -} - -static int pic_open_device(struct picdev *dev, const char *device) -{ - dev->fd = open(device, O_RDWR | O_NOCTTY); - if (dev->fd < 0) { - log_print(LOG_ERROR, "%s(): failed to open '%s'", __FUNCTION__, device); - return -1; - } - - if (fcntl(dev->fd, F_SETFD, FD_CLOEXEC) < 0) { - log_print(LOG_ERROR, "%s(): fcntl(FD_CLOEXEC)", __FUNCTION__); - close(dev->fd); - return -1; - } - - tcgetattr(dev->fd, &dev->oldtio); - - struct termios newtio; - memset(&newtio, 0, sizeof(newtio)); - newtio.c_iflag |= IGNBRK; - newtio.c_lflag &= ~(ISIG | ICANON | ECHO); - newtio.c_cflag = B19200 | CS8 | CLOCAL | CREAD; - newtio.c_cc[VMIN] = 1; - newtio.c_cc[VTIME] = 0; - cfsetospeed(&newtio, B19200); - cfsetispeed(&newtio, B19200); - - int err = tcsetattr(dev->fd, TCSAFLUSH, &newtio); - if (err < 0) { - log_print(LOG_ERROR, "%s(): failed to set termios", __FUNCTION__); - close(dev->fd); - return -1; - } - - return 0; -} - -int pic_set_fanspeed(struct picdev *dev, char value) -{ - if (value < PIC_CMD_FANSPEED_0 || value > PIC_CMD_FANSPEED_5) - return -1; - - dev->fan_speed = value - PIC_CMD_FANSPEED_0; - - write(dev->fd, &value, 1); - return 0; -} - -int pic_set_buzzer(struct picdev *dev, char value) -{ - if (value < PIC_CMD_BUZZ_SHORT || value > PIC_CMD_BUZZ_LONG) - return -1; - - write(dev->fd, &value, 1); - return 0; -} - -int pic_set_status_led(struct picdev *dev, char value) -{ - if (value < PIC_CMD_STATUSLED_RED_2HZ || value > PIC_CMD_STATUSLED_REDGREEN_1HZ) - return -1; - - write(dev->fd, &value, 1); - return 0; -} - -int pic_set_usb_led(struct picdev *dev, char value) -{ - if (value < PIC_CMD_USBLED_ON || value > PIC_CMD_USBLED_OFF) - return -1; - - write(dev->fd, &value, 1); - return 0; -} - -static int pic_read_cb(int fd, void *privdata) -{ - struct picdev *dev = (struct picdev *)privdata; - - unsigned char event; - int len = read(dev->fd, &event, 1); - if (len < 0) - return -1; - - switch (event) - { - case PIC_EVENT_FAN1_ERR: - pic_set_buzzer(dev, PIC_CMD_BUZZ_SHORT); - dev->fan_error = 1; - break; - - case PIC_EVENT_FAN1_OK: - dev->fan_error = 0; - break; - - case PIC_EVENT_FAN2_ERR: - case PIC_EVENT_FAN2_OK: - break; - - case PIC_EVENT_TEMP_RANGE_MIN ... PIC_EVENT_TEMP_RANGE_MAX: - dev->temperature = event - 128; - break; - - case PIC_EVENT_TEMP_WARN: - pic_set_buzzer(dev, PIC_CMD_BUZZ_SHORT); - dev->temperature = 75; - break; - - case PIC_EVENT_TEMP_CRIT: - dev->temperature = 80; - break; - - default: - log_print(LOG_DEBUG, "%s(): unknown event 0x%02x", __FUNCTION__, event); - break; - } - - return 0; -} - -static int lcdpage_case(struct lcddev *lcd, int event, void *privdata) -{ - struct picdev *dev = (struct picdev *)privdata; - - switch (event) { - case LCDPAGE_EVENT_BUTTON1: - return LCDPAGE_COMMAND_NEXT; - - case LCDPAGE_EVENT_BUTTON2: - { - int fan_speed = PIC_CMD_FANSPEED_0 + dev->fan_speed +1; - - if (fan_speed > PIC_CMD_FANSPEED_5) - fan_speed = PIC_CMD_FANSPEED_0; - - pic_set_fanspeed(dev, fan_speed); - lcd_set_backlight(lcd, 1); - break; - } - - case LCDPAGE_EVENT_ENTER: - lcd_set_backlight(lcd, 1); - break; - - case LCDPAGE_EVENT_BACKLIGHT: - case LCDPAGE_EVENT_EXIT: - return 0; - - default: - break; - } - - char line1_ok[] = "FAN(OK): TEMP:"; - char line1_err[] = "FAN(ERR): TEMP:"; - char line2[20]; - - snprintf(line2, sizeof(line2), "[ ] %02d C ", dev->temperature); - - int i; - for (i = 1; i <= dev->fan_speed; i++) { - line2[i] = '#'; - } - - lcd_setlines(lcd, (dev->fan_error ? line1_err : line1_ok), line2); - return 1000; -} - -struct picdev * pic_open(const char *devicename, struct lcddev *lcd) -{ - struct picdev *dev = malloc(sizeof(struct picdev)); - if (dev == NULL) { - log_print(LOG_ERROR, "%s(): out of memory", __FUNCTION__); - return NULL; - } - - memset(dev, 0, sizeof(struct picdev)); - - if (pic_open_device(dev, devicename) < 0) { - free(dev); - return NULL; - } - - dev->read_event = event_add_readfd(NULL, dev->fd, pic_read_cb, dev); - - if (lcd != NULL) { - lcd_addpage_cb(lcd, 190, lcdpage_case, dev); - } - - pic_set_fanspeed(dev, PIC_CMD_FANSPEED_1); - pic_set_status_led(dev, PIC_CMD_STATUSLED_GREENON); - - return dev; -} - -void pic_close(struct picdev *dev) -{ - if (dev->read_event != NULL) { - event_remove_fd(dev->read_event); - dev->read_event = NULL; - } - - pic_close_device(dev); - - free(dev); -} diff --git a/pic.h b/pic.h deleted file mode 100644 index 55921d5..0000000 --- a/pic.h +++ /dev/null @@ -1,64 +0,0 @@ -#ifndef _PIC_H_ -#define _PIC_H_ - -struct picdev; /* private data */ - -struct picdev * pic_open(const char *devicename, struct lcddev *lcd); -void pic_close(struct picdev *dev); - -#define PIC_CMD_FANSPEED_0 0x30 -#define PIC_CMD_FANSPEED_1 0x31 -#define PIC_CMD_FANSPEED_2 0x32 -#define PIC_CMD_FANSPEED_3 0x33 -#define PIC_CMD_FANSPEED_4 0x34 -#define PIC_CMD_FANSPEED_5 0x35 - -#define PIC_CMD_POWER_OFF 0x41 - -#define PIC_CMD_AUTOPOWER_ON 0x48 -#define PIC_CMD_AUTOPOWER_OFF 0x49 - -#define PIC_EVENT_POWER_BUTTON 0x40 - -#define PIC_CMD_POWERLED_OFF 0x4B -#define PIC_CMD_POWERLED_2HZ 0x4C -#define PIC_CMD_POWERLED_ON 0x4D -#define PIC_CMD_POWERLED_1HZ 0x4E - -#define PIC_CMD_BUZZ_SHORT 0x50 -#define PIC_CMD_BUZZ_LONG 0x51 - -#define PIC_CMD_STATUSLED_RED_2HZ 0x54 -#define PIC_CMD_STATUSLED_GREEN_2HZ 0x55 -#define PIC_CMD_STATUSLED_GREENON 0x56 -#define PIC_CMD_STATUSLED_REDON 0x57 -#define PIC_CMD_STATUSLED_REDGREEN_2HZ 0x58 -#define PIC_CMD_STATUSLED_OFF 0x59 -#define PIC_CMD_STATUSLED_GREEN_1HZ 0x5A -#define PIC_CMD_STATUSLED_RED_1HZ 0x5B -#define PIC_CMD_STATUSLED_REDGREEN_1HZ 0x5C - -#define PIC_CMD_USBLED_ON 0x60 -#define PIC_CMD_USBLED_8HZ 0x61 -#define PIC_CMD_USBLED_OFF 0x62 - -#define PIC_EVENT_FAN1_ERR 0x73 -#define PIC_EVENT_FAN1_OK 0x74 -#define PIC_EVENT_FAN2_ERR 0x75 -#define PIC_EVENT_FAN2_OK 0x76 -#define PIC_EVENT_FAN3_ERR 0x77 -#define PIC_EVENT_FAN3_OK 0x78 -#define PIC_EVENT_FAN4_ERR 0x79 -#define PIC_EVENT_FAN4_OK 0x7A - -#define PIC_EVENT_TEMP_RANGE_MIN 0x80 /* 0°C */ -#define PIC_EVENT_TEMP_RANGE_MAX 0xC6 /* 70°C */ -#define PIC_EVENT_TEMP_WARN 0x38 /* 71-79°C */ -#define PIC_EVENT_TEMP_CRIT 0x39 /* >= 80°C */ - -int pic_set_fanspeed(struct picdev *dev, char value); -int pic_set_buzzer(struct picdev *dev, char value); -int pic_set_status_led(struct picdev *dev, char value); -int pic_set_usb_led(struct picdev *dev, char value); - -#endif /* _PIC_H_ */ diff --git a/qnapd.conf b/qnapd.conf deleted file mode 100644 index 9d790ba..0000000 --- a/qnapd.conf +++ /dev/null @@ -1,20 +0,0 @@ -[global] - -#lcddevice /dev/ttyS0 -#picdevice /dev/ttyS1 - -#lcddevice dummy - -lcdtimeout 15 - -pidfile qnapd.pid -logfile qnapd.log - -[diskwatch] -check_interval 60 -hddtemp_server 127.0.0.1:7634 - -#disk /dev/sda,7200 -#disk /dev/sdb,7200 -#disk /dev/sdc,7200 -#disk /dev/sdd,7200