+ ret = write(door_fd, &c, 1);
+ } while(!ret || (ret == -1 && errno == EINTR));
+
+ if(ret > 0) {
+ cmd->sent = 1;
+ return 0;
+ }
+
+ return ret;
+}
+
+int send_response(int fd, const char* response)
+{
+ if(!response)
+ return -1;
+
+ int len = strlen(response);
+ int offset = 0;
+ int ret;
+ for(;;) {
+ ret = write(fd, &response[offset], strlen(response));
+ if(ret < 0) {
+ if(errno != EINTR)
+ return ret;
+
+ ret = 0;
+ }
+
+ offset += ret;
+ if(offset+1 >= len)
+ break;
+ }
+ do {
+ ret = write(fd, "\n", 1);
+ } while(!ret || (ret == -1 && errno == EINTR));
+
+ if(ret > 0)
+ return 0;
+
+ return ret;
+}
+
+int handle_command(const char* cmd, int fd, cmd_t** cmd_q, client_t* client_lst)
+{
+ if(!cmd_q || !cmd)
+ return -1;
+
+ cmd_id_t cmd_id;
+ if(!strncmp(cmd, "open", 4))
+ cmd_id = OPEN;
+ else if(!strncmp(cmd, "close", 5))
+ cmd_id = CLOSE;
+ else if(!strncmp(cmd, "toggle", 6))
+ cmd_id = TOGGLE;
+ else if(!strncmp(cmd, "reset", 5))
+ cmd_id = RESET;
+ else if(!strncmp(cmd, "status", 6))
+ cmd_id = STATUS;
+ else if(!strncmp(cmd, "log", 3))
+ cmd_id = LOG;
+ else if(!strncmp(cmd, "listen", 6)) {
+ client_t* listener = client_find(client_lst, fd);
+ if(listener) {
+ log_printf(DEBUG, "adding status listener %d", fd);
+ listener->status_listener = 1;
+ }
+ else
+ log_printf(ERROR, "unable to add status listener %d", fd);
+
+ return 0;
+ }
+ else {
+ log_printf(WARNING, "unknown command '%s'", cmd);
+ return 1;
+ }
+ char* param = strchr(cmd, ' ');
+ if(param)
+ param++;
+
+ switch(cmd_id) {
+ case OPEN:
+ case CLOSE:
+ case TOGGLE:
+ case STATUS:
+ case RESET: {
+ int ret = cmd_push(cmd_q, fd, cmd_id, param);
+ if(ret)
+ return ret;
+
+ log_printf(NOTICE, "command: %s", cmd);
+ break;
+ }
+ case LOG: {
+ if(param && param[0])
+ log_printf(NOTICE, "ext msg: %s", param);
+ else
+ log_printf(DEBUG, "ignoring empty ext log message");
+ break;
+ }
+ }
+
+ return 0;
+}
+
+int process_cmd(int fd, cmd_t **cmd_q, client_t* client_lst)
+{
+ log_printf(DEBUG, "processing command from %d", fd);
+
+ static char buffer[100];
+ int ret = 0;
+ do { // TODO: replace this whith a actually working readline
+ memset(buffer, 0, 100);