/*! \brief Event loop listening for signals and remote commands. */ static void event_loop(server_t *server) { uint8_t buf[KNOT_WIRE_MAX_PKTSIZE]; size_t buflen = sizeof(buf); /* Read control socket configuration. */ conf_val_t listen_val = conf_get(conf(), C_CTL, C_LISTEN); conf_val_t rundir_val = conf_get(conf(), C_SRV, C_RUNDIR); char *rundir = conf_abs_path(&rundir_val, NULL); struct sockaddr_storage addr = conf_addr(&listen_val, rundir); free(rundir); /* Bind to control interface (error logging is inside the function. */ int remote = remote_bind(&addr); sigset_t empty; (void)sigemptyset(&empty); /* Run event loop. */ for (;;) { int ret = remote_poll(remote, &empty); /* Events. */ if (ret > 0) { ret = remote_process(server, &addr, remote, buf, buflen); if (ret == KNOT_CTL_STOP) { break; } } /* Interrupts. */ if (sig_req_stop) { break; } if (sig_req_reload) { sig_req_reload = false; server_reload(server, conf()->filename); } } server_stop(server); /* Close remote control interface. */ remote_unbind(&addr, remote); /* Wait for server to finish. */ server_wait(server); }
gboolean remote_recv(GIOChannel * source, GIOCondition condition, gpointer data) { if ((condition & G_IO_ERR) || (condition & G_IO_HUP)) { remote_destroy(); return FALSE; } if (condition & G_IO_IN) { char buf[512]; int len; struct msghdr msg; struct cmsghdr *cmsg = NULL; struct ucred *pcred; struct iovec iov[1]; char mbuf[CMSG_SPACE(sizeof (struct ucred))]; memset(&msg, 0, sizeof msg); memset(mbuf, 0, sizeof mbuf); msg.msg_name = &csun; msg.msg_namelen = sizeof csun; iov[0].iov_base = buf; iov[0].iov_len = 512; msg.msg_iov = iov; msg.msg_iovlen = 1; msg.msg_control = mbuf; msg.msg_controllen = sizeof mbuf; if ((len = recvmsg(sck, &msg, 0)) == -1) { print_debug("%s: recvmsg: %s\n", GGadu_PLUGIN_NAME, strerror(errno)); return TRUE; } /* szukamy w danych dodatkowych przes³anych uwierzytelnieñ */ for (cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) { if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_CREDENTIALS) { pcred = (struct ucred *) CMSG_DATA(cmsg); break; } } if (cmsg == NULL) { /* nie znale¼li¶my ¿adnych uwierzytelnieñ, wiêc ignorujemy pakiet */ print_debug("%s: no credentials, discarding\n", GGadu_PLUGIN_NAME); return TRUE; } /* sprawdzanie uwierzytelnieñ * w zale¿no¶ci od opcji sprawdzane jest: * - uid * - gid */ print_debug("%s: pid=%d, uid=%d, gid=%d\n", GGadu_PLUGIN_NAME, pcred->pid, pcred->uid, pcred->gid); if (var_same_uid && pcred->uid != getuid()) { print_debug("%s: z³y uid (%d != %d)\n", GGadu_PLUGIN_NAME, pcred->uid, getuid()); return TRUE; } if (var_same_gid && pcred->gid != getgid()) { print_debug("%s: z³y gid (%d != %d)\n", GGadu_PLUGIN_NAME, pcred->gid, getgid()); return TRUE; } /* sprawdzenie poprawno¶ci danych */ if (len == 0) /* nie mo¿e byæ */ { print_debug("%s: recvmsg() = 0, a nie powinno\n", GGadu_PLUGIN_NAME); return TRUE; } if (buf[len - 1] != '\0') { print_debug("%s: b³êdny pakiet\n", GGadu_PLUGIN_NAME); return TRUE; } /* csun = msg.msg_name; */ csunlen = msg.msg_namelen; /* przes³anie danych do przetworzenia */ remote_process(buf); } return TRUE; }