2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2007, Dave Pare, Jeff Bailey, Thomas Ruschak,
4 * Ken Stevens, Steve McClure
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * See files README, COPYING and CREDITS in the root of the source
23 * tree for related information and legal notices. It is expected
24 * that future projects/authors will amend these files as needed.
28 * main.c: client main function
30 * Known contributors to this file:
33 * Ron Koenderink, 2004-2005
34 * Markus Armbruster, 2005
47 #include <sys/types.h>
65 static volatile sig_atomic_t interrupt;
66 static void intr(int sig);
67 static int handleintr(int);
70 main(int ac, char **av)
73 WORD wVersionRequested;
79 SECURITY_ATTRIBUTES security;
88 struct ioqueue server;
105 * stdout is unbuffered under Windows if connected to a character
106 * device, and putchar() screws up when printing multibyte strings
107 * bytewise to an unbuffered stream. Switch stdout to line-
108 * buffered mode. Unfortunately, ISO C allows implementations to
109 * screw that up, and of course Windows does. Manual flushing
110 * after each prompt is required.
112 setvbuf(stdout, NULL, _IOLBF, 4096);
113 wVersionRequested = MAKEWORD(2, 0);
114 err = WSAStartup(wVersionRequested, &WsaData);
116 printf("WSAStartup Failed, error code %d\n", err);
123 memset(argv, 0, sizeof(argv));
124 saveargv(ac, av, argv);
127 for (i = j = 1; i < ac; ++i) {
129 if (strcmp(ptr, "-2") == 0) {
131 fprintf(stderr, "-2: Missing filename!\n");
134 auxout_fname = argv[i + 1];
137 } else if (strcmp(ptr, "-k") == 0) {
140 } else if (strcmp(ptr, "-u") == 0) {
141 utf8 = eight_bit_clean = 1;
148 if (auxout_fname && (auxout_fp = fopen(auxout_fname, "a")) == NULL) {
149 fprintf(stderr, "Unable to open %s for append\n", auxout_fname);
153 port = getenv("EMPIREPORT");
156 host = getenv("EMPIREHOST");
159 sock = tcp_connect(host, port);
160 cname = getenv("COUNTRY");
163 pname = getenv("PLAYER");
166 uname = getenv("LOGNAME");
171 pwd = getpwuid(getuid());
173 fprintf(stderr, "You don't exist. Go away\n");
176 uname = pwd->pw_name;
180 unamesize = sizeof(unamebuf);
181 if (GetUserName(unamebuf, &unamesize)) {
183 if ((unamesize <= 0 ) || (strlen(uname) <= 0))
189 if (!login(sock, uname, cname, pname, send_kill, utf8)) {
197 ioq_init(&server, 2048);
201 FD_SET(0, &savemask);
202 FD_SET(sock, &savemask);
203 sigemptyset(&sa.sa_mask);
205 sa.sa_handler = intr;
206 sigaction(SIGINT, &sa, NULL);
207 sa.sa_handler = SIG_IGN;
208 sigaction(SIGPIPE, &sa, NULL);
209 while (FD_ISSET(sock, &savemask)) {
211 n = select(sock + 1, &mask, NULL, NULL, NULL);
213 if (!handleintr(sock))
218 if (errno == EINTR) {
221 FD_CLR(sock, &savemask);
224 if (FD_ISSET(0, &mask)) {
225 if (!termio(0, sock, auxout_fp)) {
226 if (retry++ >= RETRY) {
227 FD_CLR(0, &savemask);
233 if (FD_ISSET(sock, &mask)) {
234 if (!serverio(sock, &server))
235 FD_CLR(sock, &savemask);
237 servercmd(&server, auxout_fp);
242 signal(SIGINT, intr);
248 if (!isatty(fileno(stdin)))
251 security.nLength = sizeof(SECURITY_ATTRIBUTES);
252 security.lpSecurityDescriptor = NULL;
253 security.bInheritHandle = TRUE;
254 hStdIn = CreateFile("CONIN$",
255 GENERIC_READ | GENERIC_WRITE,
256 FILE_SHARE_READ | FILE_SHARE_WRITE,
257 &security, OPEN_EXISTING, (DWORD) NULL, NULL);
259 if (hStdIn == INVALID_HANDLE_VALUE) {
260 printf("Error getting hStdIn.\n");
265 err = GetConsoleMode(hStdIn, &stdinmode);
267 printf("Error getting console mode.\n");
271 stdinmode |= ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
272 err = SetConsoleMode(hStdIn, stdinmode);
274 printf("Error setting console mode.\n");
282 FD_SET(sock, &readfds);
283 n = select(sock + 1, &readfds, NULL, NULL, &tm);
285 if (!handleintr(sock))
290 if (errno == EINTR) {
291 errno = WSAGetLastError();
293 (void)closesocket(sock);
297 if (bRedirected == 1) {
298 if (!termio(0, sock, auxout_fp))
300 } else if (bRedirected == 0) {
301 if (WaitForSingleObject(hStdIn, 10) != WAIT_TIMEOUT) {
302 termio(-1, sock, auxout_fp);
303 FlushConsoleInputBuffer(hStdIn);
306 if (FD_ISSET(sock, &readfds)) {
307 if (!serverio(sock, &server))
310 servercmd(&server, auxout_fp);
314 if (bRedirected == 0)
319 (void)closesocket(sock);
323 return 0; /* Shut the compiler up */
331 signal(SIGINT, intr);
339 /* tacky, but it works */
341 if (write(s, "\naborted\n", 1 + 7 + 1) <= 0)
343 if (send(s, "\naborted\n", 1 + 7 + 1, 0) <= 0)