2 * Empire - A multi-player, client/server Internet based war game.
3 * Copyright (C) 1986-2005, 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 the "LEGAL", "LICENSE", "CREDITS" and "README" files for all the
23 * related information and legal notices. It is expected that any future
24 * projects/authors will amend these files as needed.
28 * main.c: client main function
30 * Known contributors to this file:
48 #include <sys/types.h>
56 #include <sys/socket.h>
58 #include <netinet/in.h>
77 static void intr(int sig);
81 main(int ac, char **av)
89 SECURITY_ATTRIBUTES security;
97 struct ioqueue server;
103 struct sockaddr_in sin;
115 * stdout is unbuffered under Windows if connected to a character
116 * device, and putchar() screws up when printing multibyte strings
117 * bytewise to an unbuffered stream. Switch stdout to line-
118 * buffered mode. Unfortunately, ISO C allows implementations to
119 * screw that up, and of course Windows does. Manual flushing
120 * after each prompt is required.
122 setvbuf(stdout, NULL, _IOLBF, 4096);
123 err = WSAStartup(0x0101, &WsaData);
124 if (err == SOCKET_ERROR) {
125 printf("WSAStartup Failed\n");
132 memset(argv, 0, sizeof(argv));
133 saveargv(ac, av, argv);
136 for (i = j = 1; i < ac; ++i) {
138 if (strcmp(ptr, "-2") == 0) {
140 fprintf(stderr, "-2: Missing filename!\n");
143 auxout_fname = argv[i + 1];
146 } else if (strcmp(ptr, "-k") == 0) {
149 } else if (strcmp(ptr, "-u") == 0) {
150 utf8 = eight_bit_clean = 1;
157 if (auxout_fname && (auxout_fp = fopen(auxout_fname, "a")) == NULL) {
158 fprintf(stderr, "Unable to open %s for append\n", auxout_fname);
162 port = getenv("EMPIREPORT");
165 if (!hostport(port, &sin)) {
166 fprintf(stderr, "Can't resolve Empire port %s\n", port);
169 host = getenv("EMPIREHOST");
172 if (!hostaddr(host, &sin)) {
173 fprintf(stderr, "Can't resolve Empire host %s\n", host);
176 if ((sock = hostconnect(&sin)) < 0) {
177 perror("Can't connect to Empire server");
180 cname = getenv("COUNTRY");
183 pname = getenv("PLAYER");
186 uname = getenv("LOGNAME");
191 pwd = getpwuid(getuid());
193 fprintf(stderr, "You don't exist. Go away\n");
196 uname = pwd->pw_name;
200 unamesize = sizeof(unamebuf);
201 if (GetUserName(unamebuf, &unamesize)) {
203 if ((unamesize <= 0 ) || (strlen(uname) <= 0))
209 if (!login(sock, uname, cname, pname, send_kill, utf8)) {
213 ioq_init(&server, 2048);
217 FD_SET(0, &savemask);
218 FD_SET(sock, &savemask);
220 (void)signal(SIGINT, intr);
222 (void)signal(SIGPIPE, SIG_IGN);
223 while (FD_ISSET(sock, &savemask)) {
225 n = select(sock + 1, &mask, NULL, NULL, NULL);
227 if (!handleintr(sock))
232 if (errno == EINTR) {
235 FD_CLR(sock, &savemask);
238 if (FD_ISSET(0, &mask)) {
239 if (!termio(0, sock, auxout_fp)) {
240 if (retry++ >= RETRY) {
241 FD_CLR(0, &savemask);
247 if (FD_ISSET(sock, &mask)) {
248 if (!serverio(sock, &server))
249 FD_CLR(sock, &savemask);
251 servercmd(&server, auxout_fp);
260 if (!_isatty(_fileno(stdin)))
263 security.nLength = sizeof(SECURITY_ATTRIBUTES);
264 security.lpSecurityDescriptor = NULL;
265 security.bInheritHandle = TRUE;
266 hStdIn = CreateFile("CONIN$",
267 GENERIC_READ | GENERIC_WRITE,
268 FILE_SHARE_READ | FILE_SHARE_WRITE,
269 &security, OPEN_EXISTING, (DWORD) NULL, NULL);
271 if (hStdIn == INVALID_HANDLE_VALUE) {
272 printf("Error getting hStdIn.\n");
277 err = GetConsoleMode(hStdIn, &stdinmode);
279 printf("Error getting console mode.\n");
283 stdinmode |= ENABLE_LINE_INPUT | ENABLE_ECHO_INPUT;
284 err = SetConsoleMode(hStdIn, stdinmode);
286 printf("Error setting console mode.\n");
294 FD_SET(sock, &readfds);
295 n = select(sock + 1, &readfds, NULL, NULL, &tm);
297 if (!handleintr(sock))
302 if (errno == EINTR) {
303 errno = WSAGetLastError();
309 if (bRedirected == 1) {
310 if (!termio(0, sock, auxout_fp))
312 } else if (bRedirected == 0) {
313 if (WaitForSingleObject(hStdIn, 10) != WAIT_TIMEOUT) {
314 termio(-1, sock, auxout_fp);
315 FlushConsoleInputBuffer(hStdIn);
318 if (FD_ISSET(sock, &readfds)) {
319 if (!serverio(sock, &server))
322 servercmd(&server, auxout_fp);
326 if (bRedirected == 0)
331 return 0; /* Shut the compiler up */
339 signal(SIGINT, intr);
342 signal(SIGINT, intr);