X-Git-Url: https://git.realraum.at/?p=svn42.git;a=blobdiff_plain;f=powersensordaemon%2Fpowersensordaemon.c;h=133533e2391085edd816e5a805d76d67eb1cad09;hp=99dbf74154d13248adee2f853d5db301ae3c5c0e;hb=a34e51d757fe52cb19de2937ae1b211894167524;hpb=efb533dcb175bf15fd003a635d77b6ff15756b6f diff --git a/powersensordaemon/powersensordaemon.c b/powersensordaemon/powersensordaemon.c index 99dbf74..133533e 100644 --- a/powersensordaemon/powersensordaemon.c +++ b/powersensordaemon/powersensordaemon.c @@ -40,6 +40,8 @@ #include "daemon.h" +#include "autosample.h" + int init_command_socket(const char* path) { int fd = socket(AF_UNIX, SOCK_STREAM, 0); @@ -74,19 +76,50 @@ int init_command_socket(const char* path) return fd; } +void clear_fd(int fd) +{ + fd_set fds; + struct timeval tv; + FD_ZERO(&fds); + FD_SET(fd, &fds); + tv.tv_sec = 0; + tv.tv_usec = 50000; + for(;;) { + int ret = select(fd+1, &fds, NULL, NULL, &tv); + if(ret > 0) { + char buffer[100]; + ret = read(fd, buffer, sizeof(buffer)); + } + else + break; + } +} + int send_command(int tty_fd, cmd_t* cmd) { if(!cmd) return -1; - char c; + if(!cmd->param) + return 0; + + unsigned int j,cmd_param_len = strnlen(cmd->param,60); + + char c[cmd_param_len]; switch(cmd->cmd) { - case POWER: { - c = 'A'; // get command from powerids[cmd->param] + case POWER_ON: { + for (j=0; j< cmd_param_len; j++) + c[j] = toupper(cmd->param[j]); + break; + } + case POWER_OFF: { + for (j=0; j< cmd_param_len; j++) + c[j] = tolower(cmd->param[j]); break; } case SAMPLE: { - c = 'T'; // get command from sampledevs[cmd->param] + for (j=0; j< cmd_param_len; j++) + c[j] = cmd->param[j]; break; } default: return 0; @@ -94,7 +127,7 @@ int send_command(int tty_fd, cmd_t* cmd) int ret; do { - ret = write(tty_fd, &c, 1); + ret = write(tty_fd, c, cmd_param_len); } while(!ret || (ret == -1 && errno == EINTR)); if(ret > 0) { @@ -147,7 +180,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 +188,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 +208,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 +242,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) @@ -207,16 +265,14 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst) if(!param || !strncmp(param, "all", 3)) { listener->request_listener = 1; listener->error_listener = 1; - listener->temp_listener = 1; - listener->photo_listener = 1; + listener->sensor_listener = 1; listener->movement_listener = 1; listener->button_listener = 1; } else if(!strncmp(param, "none", 4)) { listener->request_listener = 0; listener->error_listener = 0; - listener->temp_listener = 0; - listener->photo_listener = 0; + listener->sensor_listener = 0; listener->movement_listener = 0; listener->button_listener = 0; } @@ -224,10 +280,8 @@ int process_cmd(const char* cmd, int fd, cmd_t **cmd_q, client_t* client_lst) listener->request_listener = 1; else if(!strncmp(param, "error", 5)) listener->error_listener = 1; - else if(!strncmp(param, "temp", 4)) - listener->temp_listener = 1; - else if(!strncmp(param, "photo", 5)) - listener->photo_listener = 1; + else if(!strncmp(param, "sensor", 6)) + listener->sensor_listener = 1; else if(!strncmp(param, "movement", 8)) listener->movement_listener = 1; else if(!strncmp(param, "button", 6)) @@ -248,21 +302,21 @@ 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_readline(read_buffer_t* buffer, int fd, cmd_t** cmd_q, client_t* client_lst, options_t* opt) { int ret = 0; for(;;) { - ret = recv(fd, &buffer->buf[buffer->offset], 1, 0); - if(!ret) + ret = read(fd, &buffer->buf[buffer->offset], 1); + if(!ret || (ret == -1 && errno == EBADF)) return 2; - if(ret == -1 && errno == EAGAIN) + if(ret == -1 && (errno == EAGAIN || errno == EWOULDBLOCK)) return 0; else if(ret < 0) break; 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; } @@ -278,8 +332,9 @@ int nonblock_recvline(read_buffer_t* buffer, int fd, cmd_t** cmd_q, client_t* cl return ret; } -int process_tty(read_buffer_t* buffer, int tty_fd, cmd_t **cmd_q, client_t* client_lst) +int process_tty(read_buffer_t* buffer, int tty_fd, cmd_t **cmd_q, client_t* client_lst, options_t* opt) { + u_int8_t *response_data; int ret = 0; struct timeval tv; fd_set fds; @@ -311,28 +366,54 @@ int process_tty(read_buffer_t* buffer, int tty_fd, cmd_t **cmd_q, client_t* clie log_printf(NOTICE, "firmware: %s", buffer->buf); + /* modify response if necessary */ + response_data = buffer->buf; + if(!strncmp(buffer->buf, "Sensor ", 7)) { + if (buffer->buf[7] != 0) + { + char *sampledev_key; + if (asprintf(&sampledev_key, "%c",buffer->buf[7])) + { + char const *sampledev_name = key_value_storage_find_first_stringvalue(&(opt->sampledevs_), sampledev_key); + if(sampledev_name) + { + char *rev_lookuped_output; + if (asprintf(&rev_lookuped_output, "%s%s", sampledev_name, &(buffer->buf[8]) )) + response_data = rev_lookuped_output; + } + else + log_printf(WARNING, "unknown sample device key '%s' encountered", sampledev_key); + free(sampledev_key); + } + } + } + int cmd_fd = -1; if(cmd_q && (*cmd_q)) { cmd_fd = (*cmd_q)->fd; - send_response(cmd_fd, buffer->buf); + send_response(cmd_fd, response_data); } if(!strncmp(buffer->buf, "Error:", 6)) { - SEND_TO_LISTENER(error_listener, "error", cmd_fd, buffer->buf); + SEND_TO_LISTENER(error_listener, "error", cmd_fd, response_data); } if(!strncmp(buffer->buf, "movement", 8)) { - SEND_TO_LISTENER(movement_listener, "movement", cmd_fd, buffer->buf); + SEND_TO_LISTENER(movement_listener, "movement", cmd_fd, response_data); } if(!strncmp(buffer->buf, "PanicButton", 11)) { - SEND_TO_LISTENER(button_listener, "panic buttont", cmd_fd, buffer->buf); + SEND_TO_LISTENER(button_listener, "panic button", cmd_fd, response_data); } - if(!strncmp(buffer->buf, "Temp ", 5)) { - SEND_TO_LISTENER(temp_listener, "", cmd_fd, buffer->buf); + if(!strncmp(buffer->buf, "Sensor ", 7)) { + SEND_TO_LISTENER(sensor_listener, "sensor data", cmd_fd, response_data); } + /* free allocated buffer if response was modified */ + if (response_data != buffer->buf) + free(response_data); + cmd_pop(cmd_q); buffer->offset = 0; return 0; @@ -349,20 +430,31 @@ 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, autosample_process_t* autosample, options_t* opt) { log_printf(NOTICE, "entering main loop"); fd_set readfds, tmpfds; FD_ZERO(&readfds); + + clear_fd(tty_fd); FD_SET(tty_fd, &readfds); FD_SET(cmd_listen_fd, &readfds); int max_fd = tty_fd > cmd_listen_fd ? tty_fd : cmd_listen_fd; + + u_int8_t autosample_enabled = 0; + if(autosample->pid_ > 0) { + clear_fd(autosample->write_fd_); + FD_SET(autosample->write_fd_, &readfds); + max_fd = (max_fd < autosample->write_fd_) ? autosample->write_fd_ : max_fd; + } cmd_t* cmd_q = NULL; client_t* client_lst = NULL; read_buffer_t tty_buffer; tty_buffer.offset = 0; + read_buffer_t autosample_buffer; + autosample_buffer.offset = 0; int sig_fd = signal_init(); if(sig_fd < 0) @@ -402,7 +494,7 @@ int main_loop(int tty_fd, int cmd_listen_fd) } if(FD_ISSET(tty_fd, &tmpfds)) { - return_value = process_tty(&tty_buffer, tty_fd, &cmd_q, client_lst); + return_value = process_tty(&tty_buffer, tty_fd, &cmd_q, client_lst, opt); if(return_value) break; } @@ -421,10 +513,22 @@ int main_loop(int tty_fd, int cmd_listen_fd) client_add(&client_lst, new_fd); } + if(autosample->pid_ > 0 && FD_ISSET(autosample->write_fd_, &tmpfds)) { + return_value = nonblock_readline(&autosample_buffer, autosample->write_fd_, &cmd_q, client_lst, opt); + if(return_value == 2) { + log_printf(WARNING, "autosample not running, removing pipe to it"); + FD_CLR(autosample->write_fd_, &readfds); + return_value = 0; + continue; + } + if(return_value) + break; + } + 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_readline(&(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; @@ -438,11 +542,31 @@ int main_loop(int tty_fd, int cmd_listen_fd) break; } - lst = lst->next; + if(lst) + lst = lst->next; } if(cmd_q && !cmd_q->sent) send_command(tty_fd, cmd_q); + + if(autosample->pid_ > 0) { + lst = client_lst; + int listener_cnt = 0; + while(lst) { + if(lst->sensor_listener) + listener_cnt++; + lst = lst->next; + } + if((!autosample_enabled && listener_cnt > 0) || + (autosample_enabled && listener_cnt == 0)) { + if(autosample_enabled) autosample_enabled = 0; + else autosample_enabled = 1; + int ret; + do { + ret = write(autosample->read_fd_, &autosample_enabled, 1); + } while(!ret || (ret == -1 && errno == EINTR)); + } + } } cmd_clear(&cmd_q); @@ -487,21 +611,7 @@ int setup_tty(int fd) return ret; } - fd_set fds; - struct timeval tv; - FD_ZERO(&fds); - FD_SET(fd, &fds); - tv.tv_sec = 0; - tv.tv_usec = 50000; - for(;;) { - ret = select(fd+1, &fds, NULL, NULL, &tv); - if(ret > 0) { - char buffer[100]; - ret = read(fd, buffer, sizeof(buffer)); - } - else - break; - } + clear_fd(fd); return 0; } @@ -550,7 +660,11 @@ 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); + } priv_info_t priv; if(opt.username_) @@ -592,6 +706,20 @@ int main(int argc, char* argv[]) fprintf(pid_file, "%d", pid); fclose(pid_file); } + + autosample_process_t autosample; + autosample.pid_ = -1; + autosample.write_fd_ = -1; + autosample.read_fd_ = -1; + if(key_value_storage_length(&opt.autosampledevs_) > 0) { + log_printf(NOTICE, "starting autosample process"); + int ret = start_autosample_process(&opt, &autosample); + if(ret == -1) { + options_clear(&opt); + log_close(); + exit(1); + } + } int cmd_listen_fd = init_command_socket(opt.command_sock_); if(cmd_listen_fd < 0) { @@ -610,7 +738,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, &autosample, &opt); } if(ret == 2) { @@ -626,6 +754,8 @@ int main(int argc, char* argv[]) close(cmd_listen_fd); if(tty_fd > 0) close(tty_fd); + if(autosample.pid_ > 0) + kill(autosample.pid_, SIGTERM); if(!ret) log_printf(NOTICE, "normal shutdown");