int main(int argc, char **argv) { /* Init configuration */ init_config(); parse_commandline(argc, argv); switch(config.command) { case WDCTL_STATUS: wdctl_status(); break; // 停掉 wifidog进程 case WDCTL_STOP: wdctl_stop(); break; case WDCTL_KILL: wdctl_reset(); break; case WDCTL_RESTART: wdctl_restart(); break; default: /* XXX NEVER REACHED */ fprintf(stderr, "Oops\n"); exit(1); break; } exit(0); }
static void wdctl_restart(int afd) { int sock, fd; char *sock_name; struct sockaddr_un sa_un; s_config * conf = NULL; t_client * client = NULL; char * tempstring = NULL; pid_t pid; ssize_t written; socklen_t len; conf = config_get_config(); debug(LOG_NOTICE, "Will restart myself"); /* * First, prepare the internal socket */ memset(&sa_un, 0, sizeof(sa_un)); sock_name = conf->internal_sock; debug(LOG_DEBUG, "Socket name: %s", sock_name); if (strlen(sock_name) > (sizeof(sa_un.sun_path) - 1)) { /* TODO: Die handler with logging.... */ debug(LOG_ERR, "INTERNAL socket name too long"); return; } debug(LOG_DEBUG, "Creating socket"); sock = socket(PF_UNIX, SOCK_STREAM, 0); debug(LOG_DEBUG, "Got internal socket %d", sock); /* If it exists, delete... Not the cleanest way to deal. */ unlink(sock_name); debug(LOG_DEBUG, "Filling sockaddr_un"); strcpy(sa_un.sun_path, sock_name); /* XXX No size check because we check a few lines before. */ sa_un.sun_family = AF_UNIX; debug(LOG_DEBUG, "Binding socket (%s) (%d)", sa_un.sun_path, strlen(sock_name)); /* Which to use, AF_UNIX, PF_UNIX, AF_LOCAL, PF_LOCAL? */ if (bind(sock, (struct sockaddr *)&sa_un, strlen(sock_name) + sizeof(sa_un.sun_family))) { debug(LOG_ERR, "Could not bind internal socket: %s", strerror(errno)); return; } if (listen(sock, 5)) { debug(LOG_ERR, "Could not listen on internal socket: %s", strerror(errno)); return; } /* * The internal socket is ready, fork and exec ourselves */ debug(LOG_DEBUG, "Forking in preparation for exec()..."); pid = safe_fork(); if (pid > 0) { /* Parent */ /* Wait for the child to connect to our socket :*/ debug(LOG_DEBUG, "Waiting for child to connect on internal socket"); len = sizeof(sa_un); if ((fd = accept(sock, (struct sockaddr *)&sa_un, &len)) == -1){ debug(LOG_ERR, "Accept failed on internal socket: %s", strerror(errno)); close(sock); return; } close(sock); debug(LOG_DEBUG, "Received connection from child. Sending them all existing clients"); /* The child is connected. Send them over the socket the existing clients */ LOCK_CLIENT_LIST(); client = client_get_first_client(); while (client) { /* Send this client */ safe_asprintf(&tempstring, "CLIENT|ip=%s|mac=%s|token=%s|fw_connection_state=%u|fd=%d|counters_incoming=%llu|counters_outgoing=%llu|counters_last_updated=%lu\n", client->ip, client->mac, client->token, client->fw_connection_state, client->fd, client->counters.incoming, client->counters.outgoing, client->counters.last_updated); debug(LOG_DEBUG, "Sending to child client data: %s", tempstring); len = 0; while (len != strlen(tempstring)) { written = write(fd, (tempstring + len), strlen(tempstring) - len); if (written == -1) { debug(LOG_ERR, "Failed to write client data to child: %s", strerror(errno)); free(tempstring); break; } else { len += written; } } free(tempstring); client = client->next; } UNLOCK_CLIENT_LIST(); close(fd); debug(LOG_INFO, "Sent all existing clients to child. Committing suicide!"); shutdown(afd, 2); close(afd); /* Our job in life is done. Commit suicide! */ wdctl_stop(afd); } else { /* Child */ close(wdctl_socket_server); close(icmp_fd); close(sock); shutdown(afd, 2); close(afd); debug(LOG_NOTICE, "Re-executing myself (%s)", restartargv[0]); setsid(); execvp(restartargv[0], restartargv); /* If we've reached here the exec() failed - die quickly and silently */ debug(LOG_ERR, "I failed to re-execute myself: %s", strerror(errno)); debug(LOG_ERR, "Exiting without cleanup"); exit(1); } }
// called by thread_wdctl(), 专门创建一个线程来处理wdctl进程发来的命令 // *@arg = socket fd (与wdctl进程通讯) static void * thread_wdctl_handler(void *arg) { int fd, done, i; char request[MAX_BUF]; ssize_t read_bytes, len; debug(LOG_DEBUG, "Entering thread_wdctl_handler...."); fd = (int)arg; debug(LOG_DEBUG, "Read bytes and stuff from %d", fd); /* Init variables */ read_bytes = 0; done = 0; memset(request, 0, sizeof(request)); /* Read.... */ while (!done && read_bytes < (sizeof(request) - 1)) { len = read(fd, request + read_bytes, sizeof(request) - read_bytes); /* Have we gotten a command yet? */ for (i = read_bytes; i < (read_bytes + len); i++) { if (request[i] == '\r' || request[i] == '\n') { request[i] = '\0'; done = 1; } } /* Increment position */ read_bytes += len; } debug(LOG_DEBUG, "recv wdctl cmd : %s", request); // add by lijg, 2013-05-27, for debug it if (strncmp(request, "status", 6) == 0) { wdctl_status(fd); } else if (strncmp(request, "stop", 4) == 0) { // 停掉wifidog命令 wdctl_stop(fd); } else if (strncmp(request, "reset", 5) == 0) { wdctl_reset(fd, (request + 6)); } else if (strncmp(request, "restart", 7) == 0) { wdctl_restart(fd); } if (!done) { debug(LOG_ERR, "Invalid wdctl request."); shutdown(fd, 2); close(fd); pthread_exit(NULL); } debug(LOG_DEBUG, "Request received: [%s]", request); shutdown(fd, 2); close(fd); debug(LOG_DEBUG, "Exiting thread_wdctl_handler...."); return NULL; }
int main(int argc, char **argv) { /* Init configuration */ init_config(); parse_commandline(argc, argv); switch (config.command) { case WDCTL_STATUS: wdctl_status(); break; case WDCTL_STOP: wdctl_stop(); break; case WDCTL_KILL: wdctl_reset(); break; case WDCTL_RESTART: wdctl_restart(); break; //>>> liudf added 20151225 case WDCTL_ADD_TRUSTED_DOMAINS: wdctl_add_trusted_domains(); break; case WDCTL_ADD_TRUSTED_IPLIST: wdctl_add_trusted_iplist(); break; case WDCTL_REPARSE_TRUSTED_DOMAINS: wdctl_reparse_trusted_domains(); break; case WDCTL_CLEAR_TRUSTED_DOMAINS: wdctl_clear_trusted_domains(); break; case WDCTL_SHOW_TRUSTED_DOMAINS: wdctl_show_trusted_domains(); break; case WDCTL_ADD_DOMAIN_IP: wdctl_add_domain_ip(); break; case WDCTL_ADD_ROAM_MACLIST: wdctl_add_roam_maclist(); break; case WDCTL_SHOW_ROAM_MACLIST: wdctl_show_roam_maclist(); break; case WDCTL_CLEAR_ROAM_MACLIST: wdctl_clear_roam_maclist(); break; case WDCTL_ADD_TRUSTED_MACLIST: wdctl_add_trusted_maclist(); break; case WDCTL_SHOW_TRUSTED_MACLIST: wdctl_show_trusted_maclist(); break; case WDCTL_CLEAR_TRUSTED_MACLIST: wdctl_clear_trusted_maclist(); break; case WDCTL_ADD_UNTRUSTED_MACLIST: wdctl_add_untrusted_maclist(); break; case WDCTL_SHOW_UNTRUSTED_MACLIST: wdctl_show_untrusted_maclist(); break; case WDCTL_CLEAR_UNTRUSTED_MACLIST: wdctl_clear_untrusted_maclist(); break; case WDCTL_USER_CFG_SAVE: wdctl_user_cfg_save(); break; case WDCTL_ADD_WILDCARD_DOMAIN: break; //<<< liudf end default: /* XXX NEVER REACHED */ fprintf(stderr, "Oops\n"); exit(1); break; } exit(0); }