added key value storage
authorChristian Pointner <equinox@realraum.at>
Sat, 6 Mar 2010 13:39:58 +0000 (13:39 +0000)
committerChristian Pointner <equinox@realraum.at>
Sat, 6 Mar 2010 13:39:58 +0000 (13:39 +0000)
first working version ????

powersensordaemon/COMMANDS.txt
powersensordaemon/Makefile
powersensordaemon/command_queue.h
powersensordaemon/key_value_storage.c [new file with mode: 0644]
powersensordaemon/key_value_storage.h [new file with mode: 0644]
powersensordaemon/options.c
powersensordaemon/options.h
powersensordaemon/powerids.txt
powersensordaemon/powersensordaemon.c
powersensordaemon/sampledev.txt

index 76041fe..5419633 100644 (file)
@@ -1,7 +1,7 @@
 
 == Commands accepted by daemon ==
 
-COMMAND:= power $POWERID (on|off) |  listen $EVENT | sample $SAMPLEDEV | log <logtext>
+COMMAND:= power (on|off) $POWERID | listen $EVENT | sample $SAMPLEDEV | log <logtext>
 POWERID:= werkzeug | stereo | labor | schreibtisch | logo | idee
 EVENT:= all | request | temp | photo | movement | button | none
 SAMPLEDEV:=temp[0-9]+ | photo[0-9]+
index ae62b3b..b3a2692 100644 (file)
@@ -29,6 +29,7 @@ OBJ := log.o \
        sig_handler.o \
        options.o \
        string_list.o \
+       key_value_storage.o \
        command_queue.o \
        client_list.o \
        powersensordaemon.o
index a9b6bf7..6ace3ec 100644 (file)
@@ -24,7 +24,7 @@
 
 #include <sys/time.h>
 
-enum cmd_id_enum { POWER, SAMPLE, LOG , LISTEN };
+enum cmd_id_enum { POWER_ON, POWER_OFF, SAMPLE, LOG , LISTEN };
 typedef enum cmd_id_enum cmd_id_t;
 
 struct cmd_struct {
diff --git a/powersensordaemon/key_value_storage.c b/powersensordaemon/key_value_storage.c
new file mode 100644 (file)
index 0000000..7f4b584
--- /dev/null
@@ -0,0 +1,92 @@
+/*
+ *  rhctl
+ *
+ *  Copyright (C) 2009 Christian Pointner <equinox@spreadspace.org>
+ *
+ *  This file is part of rhctl.
+ *
+ *  rhctl 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 3 of the License, or
+ *  any later version.
+ *
+ *  rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <stdio.h>
+#include <string.h>
+
+#include "key_value_storage.h"
+
+void key_value_storage_init(key_value_storage_t* stor)
+{
+  if(!stor)
+    return;
+
+  string_list_init(&(stor->keys_));
+  string_list_init(&(stor->values_));
+}
+
+void key_value_storage_clear(key_value_storage_t* stor)
+{
+  if(!stor)
+    return;
+
+  string_list_clear(&(stor->keys_));
+  string_list_clear(&(stor->values_));
+}
+
+int key_value_storage_add(key_value_storage_t* stor, const char* key, const char* value)
+{
+  if(!stor || !key || !value)
+    return -1;
+
+  int ret = string_list_add(&(stor->keys_), key);
+  if(ret!=0) 
+    return ret;
+
+  ret = string_list_add(&(stor->values_), value);
+  if(ret!=0) 
+    return ret;
+
+  return 0;
+}
+
+char* key_value_storage_find(key_value_storage_t* stor, const char* key)
+{
+  if(!stor || !key)
+    return NULL;
+
+  string_list_element_t* k = stor->keys_.first_;
+  string_list_element_t* v = stor->values_.first_;
+  while(v && k) {
+    if(!strcmp(k->string_, key))
+      return v->string_;
+    
+    k = k->next_;
+    v = v->next_;
+  }
+
+  return NULL;
+}
+
+void key_value_storage_print(key_value_storage_t* stor, const char* head, const char* sep, const char* tail)
+{
+  if(!stor)
+    return;
+
+  string_list_element_t* k = stor->keys_.first_;
+  string_list_element_t* v = stor->values_.first_;
+  while(v && k) {
+    printf("%s%s%s%s%s", head, k->string_, sep, v->string_, tail);
+    k = k->next_;
+    v = v->next_;
+  }
+  printf("\n");
+}
diff --git a/powersensordaemon/key_value_storage.h b/powersensordaemon/key_value_storage.h
new file mode 100644 (file)
index 0000000..bf7a493
--- /dev/null
@@ -0,0 +1,41 @@
+/*
+ *  rhctl
+ *
+ *  Copyright (C) 2009 Christian Pointner <equinox@spreadspace.org>
+ *
+ *  This file is part of rhctl.
+ *
+ *  rhctl 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 3 of the License, or
+ *  any later version.
+ *
+ *  rhctl 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 rhctl. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef RHCTL_key_value_storage_h_INCLUDED
+#define RHCTL_key_value_storage_h_INCLUDED
+
+#include "string_list.h"
+
+struct key_value_storage_struct {
+  string_list_t keys_;
+  string_list_t values_;
+};
+typedef struct key_value_storage_struct key_value_storage_t;
+
+void key_value_storage_init(key_value_storage_t* stor);
+void key_value_storage_clear(key_value_storage_t* stor);
+int key_value_storage_add(key_value_storage_t* stor, const char* key, const char* value);
+char* key_value_storage_find(key_value_storage_t* stor, const char* key);
+
+void key_value_storage_print(key_value_storage_t* stor, const char* head, const char* sep, const char* tail);
+
+
+#endif
index 92635ed..3411f9d 100644 (file)
@@ -27,6 +27,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
+#include <errno.h>
 
 #include "log.h"
 
@@ -182,18 +183,52 @@ int options_parse(options_t* opt, int argc, char* argv[])
   return 0;
 }
 
-void options_parse_post(options_t* opt)
+
+int options_parse_key_value_file(const char* filename, key_value_storage_t* storage)
+{
+  FILE* file = fopen(filename, "r");
+  if(file) {
+    char buf[100];
+    while(fgets(buf, 100, file) != NULL) {
+      char* tmp, *key, *value;
+      for(tmp = buf;*tmp == ' '; ++tmp);
+      if(*(key = tmp) == 0) continue;
+      for(;*tmp != ' ' && *tmp != 0;++tmp);
+      if(*tmp == 0) continue;
+      *tmp=0;
+      ++tmp;
+      for(;*tmp == ' ';++tmp);
+      if(*(value = tmp) == 0) continue;
+      for(;*tmp != ' ' && *tmp != 0 && *tmp != '\n';++tmp);
+      *tmp = 0;
+      
+      if(key_value_storage_add(storage, key, value))
+        return -2;
+    }
+    fclose(file);
+  }
+  else {
+    log_printf(ERROR,"unable to open conf file (%s): %s", filename, strerror(errno));
+    return -1;
+  }
+}
+
+int options_parse_post(options_t* opt)
 {
   if(!opt)
-    return;
+    return -1;
 
-/*   if(opt->powerid_file_) { */
-/*         // read powerids */
-/*   }   */
+  if(opt->powerid_file_) {
+    int ret = options_parse_key_value_file(opt->powerid_file_, &opt->powerids_);
+    if(ret)
+      return ret;
+  }
 
-/*   if(opt->sampledev_file_) { */
-/*         // read powerids */
-/*   }   */
+  if(opt->sampledev_file_) {
+    int ret = options_parse_key_value_file(opt->sampledev_file_, &opt->sampledevs_);
+    if(ret)
+      return ret;
+  }
 }
 
 void options_default(options_t* opt)
@@ -212,7 +247,9 @@ void options_default(options_t* opt)
   opt->tty_dev_ = strdup("/dev/ttyUSB0");
   opt->command_sock_ = strdup("/var/run/powersensordaemon/cmd.sock");
   opt->powerid_file_ = NULL;
+  key_value_storage_init(&opt->powerids_);
   opt->sampledev_file_ = NULL;
+  key_value_storage_init(&opt->sampledevs_);
 }
 
 void options_clear(options_t* opt)
@@ -238,6 +275,10 @@ void options_clear(options_t* opt)
     free(opt->command_sock_);
   if(opt->powerid_file_)
     free(opt->powerid_file_);
+  key_value_storage_clear(&opt->powerids_);
+  if(opt->sampledev_file_)
+    free(opt->sampledev_file_);
+  key_value_storage_clear(&opt->sampledevs_);
 }
 
 void options_print_usage()
@@ -275,5 +316,9 @@ void options_print(options_t* opt)
   printf("tty_dev: '%s'\n", opt->tty_dev_);
   printf("command_sock: '%s'\n", opt->command_sock_);
   printf("powerid_file: '%s'\n", opt->powerid_file_);
+  printf("powerids: \n");
+  key_value_storage_print(&opt->powerids_, "  '", "' -> '", "'\n");
   printf("sampledev_file: '%s'\n", opt->sampledev_file_);
+  printf("sampledevs: \n");
+  key_value_storage_print(&opt->sampledevs_, "  '", "' -> '", "'\n");
 }
index f20a3aa..ab7b525 100644 (file)
@@ -23,6 +23,7 @@
 #define POWERSENSORDAEMON_options_h_INCLUDED
 
 #include "string_list.h"
+#include "key_value_storage.h"
 
 struct options_struct {
   char* progname_;
@@ -36,14 +37,17 @@ struct options_struct {
   char* tty_dev_;
   char* command_sock_;
   char* powerid_file_;
+  key_value_storage_t powerids_;
   char* sampledev_file_;
+  key_value_storage_t sampledevs_;
 };
 typedef struct options_struct options_t;
 
 int options_parse_hex_string(const char* hex, buffer_t* buffer);
 
 int options_parse(options_t* opt, int argc, char* argv[]);
-void options_parse_post(options_t* opt);
+int options_parse_key_value_file(const char* filename, key_value_storage_t* storage);
+int options_parse_post(options_t* opt);
 void options_default(options_t* opt);
 void options_clear(options_t* opt);
 void options_print_usage();
index 52e9be2..e792b3e 100644 (file)
@@ -1,6 +1,6 @@
-a werkzeug
-b stereo
-c labor
-d schreibtisch
-e logo
-f idee
+werkzeug      a
+stereo        b
+labor         c
+schreibtisch  d
+logo          e
+idee          f
index 99dbf74..fcb181b 100644 (file)
@@ -81,12 +81,22 @@ int send_command(int tty_fd, cmd_t* cmd)
   
   char c;
   switch(cmd->cmd) {
-  case POWER: {
-    c = 'A'; // get command from powerids[cmd->param]
+  case POWER_ON: {
+    if(!cmd->param)
+      return 0;
+    c = toupper(cmd->param[0]);
+    break;
+  }
+  case POWER_OFF: {
+    if(!cmd->param)
+      return 0;
+    c = tolower(cmd->param[0]);
     break;
   }
   case SAMPLE: {
-    c = 'T'; // get command from sampledevs[cmd->param]
+    if(!cmd->param)
+      return 0;
+    c = cmd->param[0];
     break;
   }
   default: return 0;
@@ -147,7 +157,7 @@ int send_response(int fd, const char* response)
       log_printf(DEBUG, "sent %s to %d additional listeners", TYPE_NAME,listener_cnt);
   
 
-int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst)
+int process_cmd(char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt)
 {
   log_printf(DEBUG, "processing command from %d", fd);
 
@@ -155,8 +165,14 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst)
     return -1;
   
   cmd_id_t cmd_id;
-  if(!strncmp(cmd, "power", 5))
-    cmd_id = POWER;
+  if(!strncmp(cmd, "power on", 8)) {
+    cmd_id = POWER_ON;
+    cmd[5] = '_';
+  }
+  else if(!strncmp(cmd, "power off", 9)) {
+    cmd_id = POWER_OFF;
+    cmd[5] = '_';
+  }
   else if(!strncmp(cmd, "sample", 6))
     cmd_id = SAMPLE;
   else if(!strncmp(cmd, "log", 3))
@@ -169,10 +185,28 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst)
     return 0;
   }
   char* param = strchr(cmd, ' ');
-  if(param) 
+  if(param)
     param++;
 
-  if(cmd_id == POWER || cmd_id == SAMPLE) {
+  if(cmd_id == POWER_ON || cmd_id == POWER_OFF) {
+    char* orig_param = param;
+    param = key_value_storage_find(&opt->powerids_, param);
+    if(!param) {
+      send_response(fd, "Error: invalid power id");
+      log_printf(WARNING, "invalid power id '%s' in command from %d", orig_param, fd);
+    }
+  }
+
+  if(cmd_id == SAMPLE) {
+    char* orig_param = param;
+    param = key_value_storage_find(&opt->sampledevs_, param);
+    if(!param) {
+      send_response(fd, "Error: invalid sample device");
+      log_printf(WARNING, "invalid sample device '%s' in command from %d", orig_param, fd);
+    }
+  }
+
+  if(cmd_id == POWER_ON || cmd_id == POWER_OFF || cmd_id == SAMPLE) {
     char* resp;
     asprintf(&resp, "Request: %s", cmd);
     if(resp) {
@@ -185,7 +219,8 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst)
   }
 
   switch(cmd_id) {
-  case POWER:
+  case POWER_ON:
+  case POWER_OFF:
   case SAMPLE: {
     int ret = cmd_push(cmd_q, fd, cmd_id, param);
     if(ret)
@@ -248,7 +283,7 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst)
   return 0;
 }
 
-int nonblock_recvline(read_buffer_t* buffer, int fd, cmd_t** cmd_q, client_t* client_lst)
+int nonblock_recvline(read_buffer_t* buffer, int fd, cmd_t** cmd_q, client_t* client_lst, options_t* opt)
 {
   int ret = 0;
   for(;;) {
@@ -262,7 +297,7 @@ int nonblock_recvline(read_buffer_t* buffer, int fd, cmd_t** cmd_q, client_t* cl
 
     if(buffer->buf[buffer->offset] == '\n') {
       buffer->buf[buffer->offset] = 0;
-      ret = process_cmd(buffer->buf, fd, cmd_q, client_lst);
+      ret = process_cmd(buffer->buf, fd, cmd_q, client_lst, opt);
       buffer->offset = 0;
       break;
     }
@@ -349,7 +384,7 @@ int process_tty(read_buffer_t* buffer, int tty_fd, cmd_t **cmd_q, client_t* clie
   return ret;
 }
 
-int main_loop(int tty_fd, int cmd_listen_fd)
+int main_loop(int tty_fd, int cmd_listen_fd, options_t* opt)
 {
   log_printf(NOTICE, "entering main loop");
 
@@ -424,7 +459,7 @@ int main_loop(int tty_fd, int cmd_listen_fd)
     client_t* lst = client_lst;
     while(lst) {
       if(FD_ISSET(lst->fd, &tmpfds)) {
-        return_value = nonblock_recvline(&(lst->buffer), lst->fd, &cmd_q, client_lst);
+        return_value = nonblock_recvline(&(lst->buffer), lst->fd, &cmd_q, client_lst, opt);
         if(return_value == 2) {
           log_printf(DEBUG, "removing closed command connection (fd=%d)", lst->fd);
           client_t* deletee = lst;
@@ -550,7 +585,13 @@ int main(int argc, char* argv[])
     }
   }
   log_printf(NOTICE, "just started...");
-  options_parse_post(&opt);
+  if(options_parse_post(&opt)) {
+    options_clear(&opt);
+    log_close();
+    exit(-1);
+  }
+
+  options_print(&opt);
 
   priv_info_t priv;
   if(opt.username_)
@@ -610,7 +651,7 @@ int main(int argc, char* argv[])
       if(ret)
         ret = 2;
       else
-        ret = main_loop(tty_fd, cmd_listen_fd);
+        ret = main_loop(tty_fd, cmd_listen_fd, &opt);
     }
 
     if(ret == 2) {