keep-ctx-alive.c (4491B)
1 // $Id$ --*- c -*-- 2 3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de> 4 // 5 // This program is free software; you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation; version 2 of the License. 8 // 9 // This program is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with this program; if not, write to the Free Software 16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 17 18 19 #ifdef HAVE_CONFIG_H 20 # include <config.h> 21 #endif 22 23 #include "util.h" 24 25 #include <lib/vserver.h> 26 #include <lib/internal.h> 27 28 #include <getopt.h> 29 #include <errno.h> 30 #include <sys/socket.h> 31 #include <sys/un.h> 32 #include <sys/select.h> 33 34 #define ENSC_WRAPPERS_PREFIX "keep-ctx-alive: " 35 #define ENSC_WRAPPERS_VSERVER 1 36 #define ENSC_WRAPPERS_SOCKET 1 37 #define ENSC_WRAPPERS_UNISTD 1 38 #define ENSC_WRAPPERS_IOSOCK 1 39 #define ENSC_WRAPPERS_IO 1 40 #include <wrappers.h> 41 42 43 #define CMD_HELP 0x1000 44 #define CMD_VERSION 0x1001 45 #define CMD_SOCKET 0x4000 46 #define CMD_TIMEOUT 0x4001 47 #define CMD_QUIT 0x4002 48 49 int wrapper_exit_code = 1; 50 51 struct option const 52 CMDLINE_OPTIONS[] = { 53 { "help", no_argument, 0, CMD_HELP }, 54 { "version", no_argument, 0, CMD_VERSION }, 55 { "socket", required_argument, 0, CMD_SOCKET }, 56 { "timeout", required_argument, 0, CMD_TIMEOUT }, 57 { "quit", required_argument, 0, CMD_QUIT }, 58 {0,0,0,0}, 59 }; 60 61 static void 62 showHelp(int fd, char const *cmd, int res) 63 { 64 WRITE_MSG(fd, "Usage:\n "); 65 WRITE_STR(fd, cmd); 66 WRITE_MSG(fd, 67 " --socket <filename> [--timeout <seconds>]\n" 68 "\n" 69 "Please report bugs to " PACKAGE_BUGREPORT "\n"); 70 71 exit(res); 72 } 73 74 static void 75 showVersion() 76 { 77 WRITE_MSG(1, 78 "keep-ctx-alive " VERSION " -- keeps a context alive\n" 79 "This program is part of " PACKAGE_STRING "\n\n" 80 "Copyright (C) 2004 Enrico Scholz\n" 81 VERSION_COPYRIGHT_DISCLAIMER); 82 exit(0); 83 } 84 85 static void 86 printXid(int fd) 87 { 88 xid_t xid = Evc_get_task_xid(0); 89 char buf[sizeof(xid)*3 + 2]; 90 size_t l; 91 92 l = utilvserver_fmt_long(buf, xid); 93 EwriteAll(fd, buf, l); 94 Eclose(fd); 95 } 96 97 static void handleMessage(int fd) 98 { 99 char buf[128]; 100 size_t len; 101 struct sockaddr_un addr; 102 socklen_t addr_len = sizeof(addr); 103 int new_fd = Eaccept(fd, &addr, &addr_len); 104 105 len = Erecv(new_fd, buf, sizeof buf,0); 106 if (len==0) exit(1); 107 108 // TODO: handle message??? 109 exit(0); 110 } 111 112 static int 113 sendQuitSignal(char const *filename, char const *msg) 114 { 115 int fd; 116 struct sockaddr_un addr; 117 118 ENSC_INIT_UNIX_SOCK(addr, filename); 119 fd = Esocket(PF_UNIX, SOCK_STREAM, 0); 120 Econnect(fd, &addr, sizeof(addr)); 121 122 if (msg) EsendAll(fd, msg, strlen(msg)); 123 Eclose(fd); 124 125 return EXIT_SUCCESS; 126 } 127 128 static int 129 doit(char const *filename, struct timeval *timeout) 130 { 131 int fd; 132 struct sockaddr_un sock; 133 pid_t pid; 134 fd_set fdset; 135 136 ENSC_INIT_UNIX_SOCK(sock, filename); 137 138 fd = Esocket(PF_UNIX, SOCK_STREAM, 0); 139 Ebind(fd, &sock, sizeof sock); 140 Elisten(fd, 5); 141 142 printXid(1); 143 144 FD_ZERO(&fdset); 145 FD_SET(fd, &fdset); 146 147 pid = Efork(); 148 if (pid==0) { 149 Eselect(fd+1, &fdset, 0,0, timeout); 150 if (FD_ISSET(fd, &fdset)) handleMessage(fd); 151 exit(1); 152 } 153 154 return EXIT_SUCCESS; 155 } 156 157 int main(int argc, char *argv[]) 158 { 159 char const * socket_name = 0; 160 struct timeval timeout = { 0,0 }; 161 struct timeval *timeout_ptr = 0; 162 char const * quit_msg = false; 163 164 while (1) { 165 int c = getopt_long(argc, argv, "+", CMDLINE_OPTIONS, 0); 166 if (c==-1) break; 167 168 switch (c) { 169 case CMD_HELP : showHelp(1, argv[0], 0); 170 case CMD_VERSION : showVersion(); 171 case CMD_SOCKET : socket_name = optarg; break; 172 case CMD_QUIT : quit_msg = optarg; break; 173 case CMD_TIMEOUT : 174 timeout.tv_sec = atoi(optarg); 175 timeout_ptr = &timeout; 176 break; 177 default : 178 WRITE_MSG(2, "Try '"); 179 WRITE_STR(2, argv[0]); 180 WRITE_MSG(2, " --help' for more information.\n"); 181 return 255; 182 break; 183 } 184 } 185 186 if (socket_name==0) 187 WRITE_MSG(2, "reserve-context: No socketname specified\n"); 188 if (quit_msg) 189 return sendQuitSignal(socket_name, quit_msg); 190 else 191 return doit(socket_name, timeout_ptr); 192 193 return EXIT_FAILURE; 194 }