📄 wpa_cli.c
字号:
static int wpa_cli_exec(const char *program, const char *arg1, const char *arg2){ char *cmd; size_t len; len = strlen(program) + strlen(arg1) + strlen(arg2) + 3; cmd = malloc(len); if (cmd == NULL) return -1; snprintf(cmd, len, "%s %s %s", program, arg1, arg2); system(cmd); free(cmd); return 0;}static void wpa_cli_action_process(const char *msg){ const char *pos; pos = msg; if (*pos == '<') { /* skip priority */ pos = strchr(pos, '>'); if (pos) pos++; else pos = msg; } if (str_match(pos, WPA_EVENT_CONNECTED)) { wpa_cli_exec(action_file, ctrl_ifname, "CONNECTED"); } else if (str_match(pos, WPA_EVENT_DISCONNECTED)) { wpa_cli_exec(action_file, ctrl_ifname, "DISCONNECTED"); } else if (str_match(pos, WPA_EVENT_TERMINATING)) { printf("wpa_supplicant is terminating - stop monitoring\n"); wpa_cli_quit = 1; }}static void wpa_cli_action_cb(char *msg, size_t len){ wpa_cli_action_process(msg);}static void wpa_cli_recv_pending(struct wpa_ctrl *ctrl, int in_read, int action_monitor){ int first = 1; if (ctrl_conn == NULL) return; while (wpa_ctrl_pending(ctrl)) { char buf[256]; size_t len = sizeof(buf) - 1; if (wpa_ctrl_recv(ctrl, buf, &len) == 0) { buf[len] = '\0'; if (action_monitor) wpa_cli_action_process(buf); else { if (in_read && first) printf("\n"); first = 0; printf("%s\n", buf); } } else { printf("Could not read pending message.\n"); break; } }}#ifdef CONFIG_READLINEstatic char * wpa_cli_cmd_gen(const char *text, int state){ static int i, len; const char *cmd; if (state == 0) { i = 0; len = strlen(text); } while ((cmd = wpa_cli_commands[i].cmd)) { i++; if (strncasecmp(cmd, text, len) == 0) return strdup(cmd); } return NULL;}static char * wpa_cli_dummy_gen(const char *text, int state){ return NULL;}static char ** wpa_cli_completion(const char *text, int start, int end){ return rl_completion_matches(text, start == 0 ? wpa_cli_cmd_gen : wpa_cli_dummy_gen);}#endif /* CONFIG_READLINE */static void wpa_cli_interactive(void){#define max_args 10 char cmdbuf[256], *cmd, *argv[max_args], *pos; int argc;#ifdef CONFIG_READLINE char *home, *hfile = NULL;#endif /* CONFIG_READLINE */ printf("\nInteractive mode\n\n");#ifdef CONFIG_READLINE rl_attempted_completion_function = wpa_cli_completion; home = getenv("HOME"); if (home) { const char *fname = ".wpa_cli_history"; int hfile_len = strlen(home) + 1 + strlen(fname) + 1; hfile = malloc(hfile_len); if (hfile) { snprintf(hfile, hfile_len, "%s/%s", home, fname); read_history(hfile); stifle_history(100); } }#endif /* CONFIG_READLINE */ do { wpa_cli_recv_pending(ctrl_conn, 0, 0);#ifndef CONFIG_NATIVE_WINDOWS alarm(1);#endif /* CONFIG_NATIVE_WINDOWS */#ifdef CONFIG_READLINE cmd = readline("> "); if (cmd && *cmd) { HIST_ENTRY *h; while (next_history()) ; h = previous_history(); if (h == NULL || strcmp(cmd, h->line) != 0) add_history(cmd); next_history(); }#else /* CONFIG_READLINE */ printf("> "); cmd = fgets(cmdbuf, sizeof(cmdbuf), stdin);#endif /* CONFIG_READLINE */#ifndef CONFIG_NATIVE_WINDOWS alarm(0);#endif /* CONFIG_NATIVE_WINDOWS */ if (cmd == NULL) break; pos = cmd; while (*pos != '\0') { if (*pos == '\n') { *pos = '\0'; break; } pos++; } argc = 0; pos = cmd; for (;;) { while (*pos == ' ') pos++; if (*pos == '\0') break; argv[argc] = pos; argc++; if (argc == max_args) break; if (*pos == '"') { char *pos2 = strrchr(pos, '"'); if (pos2) pos = pos2 + 1; } while (*pos != '\0' && *pos != ' ') pos++; if (*pos == ' ') *pos++ = '\0'; } if (argc) wpa_request(ctrl_conn, argc, argv); if (cmd != cmdbuf) free(cmd); } while (!wpa_cli_quit);#ifdef CONFIG_READLINE if (hfile) { /* Save command history, excluding lines that may contain * passwords. */ HIST_ENTRY *h; history_set_pos(0); h = next_history(); while (h) { char *p = h->line; while (*p == ' ' || *p == '\t') p++; if (strncasecmp(p, "pa", 2) == 0 || strncasecmp(p, "o", 1) == 0 || strncasecmp(p, "n", 1)) { h = remove_history(where_history()); if (h) { free(h->line); free(h->data); free(h); } h = current_history(); } else { h = next_history(); } } write_history(hfile); free(hfile); }#endif /* CONFIG_READLINE */}static void wpa_cli_action(struct wpa_ctrl *ctrl){ fd_set rfds; int fd, res; struct timeval tv; char buf[16]; size_t len; fd = wpa_ctrl_get_fd(ctrl); while (!wpa_cli_quit) { FD_ZERO(&rfds); FD_SET(fd, &rfds); tv.tv_sec = 2; tv.tv_usec = 0; res = select(fd + 1, &rfds, NULL, NULL, &tv); if (res < 0 && errno != EINTR) { perror("select"); break; } if (FD_ISSET(fd, &rfds)) wpa_cli_recv_pending(ctrl, 0, 1); else { /* verify that connection is still working */ len = sizeof(buf) - 1; if (wpa_ctrl_request(ctrl, "PING", 4, buf, &len, wpa_cli_action_cb) < 0 || len < 4 || memcmp(buf, "PONG", 4) != 0) { printf("wpa_supplicant did not reply to PING " "command - exiting\n"); break; } } }}static void wpa_cli_cleanup(void){ wpa_cli_close_connection(); if (pid_file) unlink(pid_file);#ifdef CONFIG_NATIVE_WINDOWS WSACleanup();#endif /* CONFIG_NATIVE_WINDOWS */}static void wpa_cli_terminate(int sig){ wpa_cli_cleanup(); exit(0);}#ifndef CONFIG_NATIVE_WINDOWSstatic void wpa_cli_alarm(int sig){ if (ctrl_conn && _wpa_ctrl_command(ctrl_conn, "PING", 0)) { printf("Connection to wpa_supplicant lost - trying to " "reconnect\n"); wpa_cli_close_connection(); } if (!ctrl_conn) { ctrl_conn = wpa_cli_open_connection(ctrl_ifname); if (ctrl_conn) { printf("Connection to wpa_supplicant " "re-established\n"); if (wpa_ctrl_attach(ctrl_conn) == 0) { wpa_cli_attached = 1; } else { printf("Warning: Failed to attach to " "wpa_supplicant.\n"); } } } if (ctrl_conn) wpa_cli_recv_pending(ctrl_conn, 1, 0); alarm(1);}#endif /* CONFIG_NATIVE_WINDOWS */int main(int argc, char *argv[]){ int interactive; int warning_displayed = 0; int c; int daemonize = 0; FILE *f; const char *global = NULL;#ifdef CONFIG_NATIVE_WINDOWS WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 0), &wsaData)) { printf("Could not find a usable WinSock.dll\n"); return -1; }#endif /* CONFIG_NATIVE_WINDOWS */ for (;;) { c = getopt(argc, argv, "a:Bg:hi:p:P:v"); if (c < 0) break; switch (c) { case 'a': action_file = optarg; break; case 'B': daemonize = 1; break; case 'g': global = optarg; break; case 'h': usage(); return 0; case 'v': printf("%s\n", wpa_cli_version); return 0; case 'i': ctrl_ifname = strdup(optarg); break; case 'p': ctrl_iface_dir = optarg; break; case 'P': pid_file = optarg; break; default: usage(); return -1; } } interactive = (argc == optind) && (action_file == NULL); if (interactive) printf("%s\n\n%s\n\n", wpa_cli_version, wpa_cli_license); if (global) { ctrl_conn = wpa_ctrl_open(global); if (ctrl_conn == NULL) { perror("Failed to connect to wpa_supplicant - " "wpa_ctrl_open"); return -1; } } for (; !global;) { if (ctrl_ifname == NULL) { struct dirent *dent; DIR *dir = opendir(ctrl_iface_dir); if (dir) { while ((dent = readdir(dir))) { if (strcmp(dent->d_name, ".") == 0 || strcmp(dent->d_name, "..") == 0) continue; printf("Selected interface '%s'\n", dent->d_name); ctrl_ifname = strdup(dent->d_name); break; } closedir(dir); } } ctrl_conn = wpa_cli_open_connection(ctrl_ifname); if (ctrl_conn) { if (warning_displayed) printf("Connection established.\n"); break; } if (!interactive) { perror("Failed to connect to wpa_supplicant - " "wpa_ctrl_open"); return -1; } if (!warning_displayed) { printf("Could not connect to wpa_supplicant - " "re-trying\n"); warning_displayed = 1; } sleep(1); continue; } signal(SIGINT, wpa_cli_terminate); signal(SIGTERM, wpa_cli_terminate);#ifndef CONFIG_NATIVE_WINDOWS signal(SIGALRM, wpa_cli_alarm);#endif /* CONFIG_NATIVE_WINDOWS */ if (interactive || action_file) { if (wpa_ctrl_attach(ctrl_conn) == 0) { wpa_cli_attached = 1; } else { printf("Warning: Failed to attach to " "wpa_supplicant.\n"); if (!interactive) return -1; } } if (daemonize && daemon(0, 0)) { perror("daemon"); return -1; } if (pid_file) { f = fopen(pid_file, "w"); if (f) { fprintf(f, "%u\n", getpid()); fclose(f); } } if (interactive) wpa_cli_interactive(); else if (action_file) wpa_cli_action(ctrl_conn); else wpa_request(ctrl_conn, argc - optind, &argv[optind]); free(ctrl_ifname); wpa_cli_cleanup(); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -