== 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]+
sig_handler.o \
options.o \
string_list.o \
+ key_value_storage.o \
command_queue.o \
client_list.o \
powersensordaemon.o
#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 {
--- /dev/null
+/*
+ * 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");
+}
--- /dev/null
+/*
+ * 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
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <errno.h>
#include "log.h"
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)
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)
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()
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");
}
#define POWERSENSORDAEMON_options_h_INCLUDED
#include "string_list.h"
+#include "key_value_storage.h"
struct options_struct {
char* progname_;
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();
-a werkzeug
-b stereo
-c labor
-d schreibtisch
-e logo
-f idee
+werkzeug a
+stereo b
+labor c
+schreibtisch d
+logo e
+idee f
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;
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);
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))
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) {
}
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)
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(;;) {
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;
}
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");
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;
}
}
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_)
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) {