diff options
Diffstat (limited to 'sysexec.c')
-rw-r--r-- | sysexec.c | 179 |
1 files changed, 148 insertions, 31 deletions
@@ -1,36 +1,22 @@ /* - * uAnytun + * rhdropbox * - * uAnytun is a tiny implementation of SATP. Unlike Anytun which is a full - * featured implementation uAnytun has no support for multiple connections - * or synchronisation. It is a small single threaded implementation intended - * to act as a client on small platforms. - * The secure anycast tunneling protocol (satp) defines a protocol used - * for communication between any combination of unicast and anycast - * tunnel endpoints. It has less protocol overhead than IPSec in Tunnel - * mode and allows tunneling of every ETHER TYPE protocol (e.g. - * ethernet, ip, arp ...). satp directly includes cryptography and - * message authentication based on the methodes used by SRTP. It is - * intended to deliver a generic, scaleable and secure solution for - * tunneling and relaying of packets of any protocol. - * + * Copyright (C) 2009 Christian Pointner <equinox@helsinki.at> * - * Copyright (C) 2007-2008 Christian Pointner <equinox@anytun.org> + * This file is part of rhdropbox. * - * This file is part of uAnytun. - * - * uAnytun is free software: you can redistribute it and/or modify + * rhdropbox 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. * - * uAnytun is distributed in the hope that it will be useful, + * rhdropbox 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 uAnytun. If not, see <http://www.gnu.org/licenses/>. + * along with rhdropbox. If not, see <http://www.gnu.org/licenses/>. */ #include "datatypes.h" @@ -47,7 +33,119 @@ #include "sysexec.h" #include "log.h" -int uanytun_exec(const char* script, char* const argv[], char* const evp[]) +void child_list_init(child_list_t* list) +{ + if(!list) + return; + + list->first_ = NULL; +} + +void child_list_clear(child_list_t* list) +{ + if(!list) + return; + + while(list->first_) { + child_list_element_t* tmp; + tmp = list->first_; + list->first_ = tmp->next_; + if(tmp->script_) + free(tmp->script_); + free(tmp); + } +} + +int child_list_add(child_list_t* list, pid_t pid, const char* script, int err_fd) +{ + if(!list) + return -1; + + if(!list->first_) { + list->first_ = malloc(sizeof(child_list_element_t)); + if(!list->first_) + return -2; + + list->first_->next_ = 0; + list->first_->pid_ = pid; + list->first_->err_fd_ = err_fd; + list->first_->script_ = strdup(script); + if(!list->first_->script_) { + free(list->first_); + list->first_ = NULL; + return -2; + } + } + else { + child_list_element_t* tmp = list->first_; + while(tmp->next_) + tmp = tmp->next_; + + tmp->next_ = malloc(sizeof(child_list_element_t)); + if(!tmp->next_) + return -2; + + tmp->next_->next_ = 0; + tmp->next_->pid_ = pid; + tmp->next_->err_fd_ = err_fd; + tmp->next_->script_ = strdup(script); + if(!tmp->next_->script_) { + free(tmp->next_); + tmp->next_ = NULL; + return -2; + } + } + return 0; +} + +void child_list_rm(child_list_t* list, pid_t pid) +{ + if(!list) + return; + + child_list_element_t* tmp = NULL; + if(list->first_->pid_ == pid) { + tmp = list->first_; + list->first_ = list->first_->next_; + + if(tmp->script_) + free(tmp->script_); + free(tmp); + return; + } + + child_list_element_t* prev = list->first_; + tmp = list->first_->next_; + while(tmp) { + if(tmp->pid_ == pid) { + prev->next_ = tmp->next_; + + if(tmp->script_) + free(tmp->script_); + free(tmp); + return; + } + prev = tmp; + tmp = tmp->next_; + } +} + +child_list_element_t* child_list_find(child_list_t* list, pid_t pid) +{ + if(!list) + return NULL; + + child_list_element_t* tmp = list->first_; + while(tmp) { + if(tmp->pid_ == pid) + return tmp; + tmp = tmp->next_; + } + + return NULL; +} + +int rh_exec(const char* script, char* const argv[], char* const evp[], child_list_t* child_lst) { if(!script) return -1; @@ -88,28 +186,47 @@ int uanytun_exec(const char* script, char* const argv[], char* const evp[]) } close(pipefd[1]); + log_printf(NOTICE, "called script '%s' with pid %d", script, pid); + return child_list_add(child_lst, pid, script, pipefd[0]); +} + +int rh_waitpid(child_list_t* child_lst) +{ int status = 0; - waitpid(pid, &status, 0); + pid_t pid = waitpid(-1, &status, WNOHANG); + if(!pid || (pid < 0 && errno == ECHILD)) + return 0; + if(pid < 0) { + log_printf(ERROR, "waitpid returned with error: %s", strerror(errno)); + return pid; + } + + child_list_element_t* child = child_list_find(child_lst, pid); + if(!child) { + log_printf(ERROR, "waitpid returned unknown child pid (%d)", pid); + return 0; + } fd_set rfds; FD_ZERO(&rfds); - FD_SET(pipefd[0], &rfds); + FD_SET(child->err_fd_, &rfds); struct timeval tv = { 0 , 0 }; - if(select(pipefd[0]+1, &rfds, NULL, NULL, &tv) == 1) { + if(select(child->err_fd_+1, &rfds, NULL, NULL, &tv) == 1) { int err = 0; - if(read(pipefd[0], (void*)(&err), sizeof(err)) >= sizeof(err)) { - log_printf(NOTICE, "script '%s' exec() error: %s", script, strerror(err)); - close(pipefd[0]); + if(read(child->err_fd_, (void*)(&err), sizeof(err)) >= sizeof(err)) { + log_printf(NOTICE, "script '%s' exec() error: %s", child->script_, strerror(err)); + close(child->script_); return -1; } } if(WIFEXITED(status)) - log_printf(NOTICE, "script '%s' returned %d", script, WEXITSTATUS(status)); + log_printf(NOTICE, "script '%s' (pid %d) returned %d", child->script_, child->pid_, WEXITSTATUS(status)); else if(WIFSIGNALED(status)) - log_printf(NOTICE, "script '%s' terminated after signal %d", script, WTERMSIG(status)); + log_printf(NOTICE, "script '%s' (pid %d) terminated after signal %d", child->script_, child->pid_, WTERMSIG(status)); else - log_printf(ERROR, "executing script '%s': unkown error", script); + log_printf(ERROR, "executing script '%s' (pid %d): unkown error", child->script_, child->pid_); - close(pipefd[0]); + close(child->err_fd_); return status; } + |