int main(int argc, char **argv) { #ifdef ANDROID_CHANGES int control = android_get_control_and_arguments(&argc, &argv); ENGINE *e; if (control != -1) { pname = "%p"; monitor_fd(control, NULL); ENGINE_load_dynamic(); e = ENGINE_by_id("keystore"); if (!e || !ENGINE_init(e)) { do_plog(LLV_ERROR, "ipsec-tools: cannot load keystore engine"); exit(1); } } #endif do_plog(LLV_INFO, "ipsec-tools 0.7.3 (http://ipsec-tools.sf.net)\n"); signal(SIGHUP, terminate); signal(SIGINT, terminate); signal(SIGTERM, terminate); signal(SIGPIPE, SIG_IGN); atexit(terminated); setup(argc, argv); #ifdef ANDROID_CHANGES shutdown(control, SHUT_WR); setuid(AID_VPN); #endif while (1) { struct timeval *tv = schedular(); int timeout = tv->tv_sec * 1000 + tv->tv_usec / 1000 + 1; if (poll(pollfds, monitors, timeout) > 0) { int i; for (i = 0; i < monitors; ++i) { if (pollfds[i].revents & POLLHUP) { do_plog(LLV_ERROR, "Connection is closed\n", pollfds[i].fd); exit(1); } if (pollfds[i].revents & POLLIN) { callbacks[i](pollfds[i].fd); } } } } #ifdef ANDROID_CHANGES if (e) { ENGINE_finish(e); ENGINE_free(e); } #endif return 0; }
int main(int argc, char **argv) { struct pollfd pollfds[3]; int control = -1; int timeout; int status; #ifdef ANDROID_CHANGES control = android_get_control_and_arguments(&argc, &argv); shutdown(control, SHUT_WR); #endif srandom(time(NULL)); if (pipe(signals) == -1) { log_print(FATAL, "Pipe() %s", strerror(errno)); exit(SYSTEM_ERROR); } fcntl(signals[0], F_SETFD, FD_CLOEXEC); fcntl(signals[1], F_SETFD, FD_CLOEXEC); timeout = initialize(argc, argv); signal(SIGHUP, interrupt); signal(SIGINT, interrupt); signal(SIGTERM, interrupt); signal(SIGCHLD, interrupt); signal(SIGPIPE, SIG_IGN); atexit(stop_pppd); pollfds[0].fd = the_socket; pollfds[0].events = POLLIN; pollfds[1].fd = signals[0]; pollfds[1].events = POLLIN; pollfds[2].fd = control; pollfds[2].events = 0; while (timeout >= 0) { if (poll(pollfds, 3, timeout ? timeout : -1) == -1 && errno != EINTR) { log_print(FATAL, "Poll() %s", strerror(errno)); exit(SYSTEM_ERROR); } if (pollfds[1].revents) { break; } if (pollfds[2].revents) { interrupt(SIGTERM); } timeout = pollfds[0].revents ? the_protocol->process() : the_protocol->timeout(); #ifdef ANDROID_CHANGES if (!access("/data/misc/vpn/abort", F_OK)) { interrupt(SIGTERM); } if (!timeout) { timeout = 5000; } #endif } if (timeout < 0) { status = -timeout; } else { int signal; read(signals[0], &signal, sizeof(int)); log_print(INFO, "Received signal %d", signal); if (signal == SIGCHLD && waitpid(pppd_pid, &status, WNOHANG) == pppd_pid && WIFEXITED(status)) { status = WEXITSTATUS(status); log_print(INFO, "Pppd is terminated (status = %d)", status); status += PPPD_EXITED; pppd_pid = 0; } else { status = USER_REQUESTED; } } stop_pppd(); the_protocol->shutdown(); log_print(INFO, "Mtpd is terminated (status = %d)", status); return status; }