#include "module.h"
#include "system.h"
-extern void close_displays(void);
+#ifdef __cplusplus
+extern "C" {
+#endif
-#include <signal.h>
-#include <unistd.h>
-#include <pwd.h>
-#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
+#include <signal.h>
+
+#if (defined (__CYGWIN32__) || defined (__MINGW32__))
+#include <unistd.h>
+#endif
-/* (should flush the following includes?) */
+#ifdef __CYGWIN32__
+#include <limits.h>
#include <sys/file.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <sys/ioctl.h>
+#include <pwd.h>
+void cygwin_conv_to_full_win32_path(const char *path, char *win32_path);
+#endif
+
+#ifdef _MSC_VER
+#include <io.h>
+#include <windows.h>
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#define F_OK 0
/* Default names for places. */
#undef XCONQDATA
#ifndef XCONQDATA
-#define XCONQDATA ".."
+/* The Windows app should now live in the top directory. */
+#define XCONQDATA "."
#endif
#ifndef XCONQLIB
#define XCONQIMAGES "images"
#endif
-#ifndef XCONQSCORES
-#define XCONQSCORES "scores"
+#ifdef __CYGWIN32__
+/* used in xconq.c and xtconq.c */
+uid_t games_uid;
#endif
-static char *game_homedir(void);
-static char *game_filename(char *namevar, char *defaultname);
-static char *score_file_pathname(char *name);
+void extract_dirname (char **dirname, char *pathname);
-uid_t games_uid;
+static void stop_handler(int sig);
+static void crash_handler(int sig);
+static void hup_handler(int sig);
+
+char *xcq_program_name = NULL;
+FILE *xcq_fstdout = NULL;
char *
default_library_pathname(void)
{
- char *name;
-
- name = xmalloc(strlen(XCONQDATA) + 1 + strlen(XCONQLIB) + 1);
- strcpy(name, XCONQDATA);
- strcat(name, "\\");
+ char *name = NULL;
+ char *tmpname = NULL;
+
+ if (xcq_program_name) {
+ extract_dirname(&tmpname, xcq_program_name);
+ name = (char *)xmalloc(strlen(tmpname) + 1 + strlen(XCONQLIB) + 1);
+ strcpy(name, tmpname);
+ free(tmpname);
+ }
+ else {
+ name = (char *)xmalloc(strlen(XCONQDATA) + 1 + strlen(XCONQLIB) + 1);
+ strcpy(name, XCONQDATA);
+ }
+ strcat(name, "/");
strcat(name, XCONQLIB);
return name;
}
char *
-default_images_pathname(void)
+default_images_pathname(char *libpath)
{
char *name;
- name = xmalloc(strlen(XCONQDATA) + 1 + strlen(XCONQIMAGES) + 1);
- strcpy(name, XCONQDATA);
- strcat(name, "\\");
+ if (libpath == NULL)
+ libpath = default_library_pathname();
+ name = (char *)xmalloc(strlen(libpath) + 4 + strlen(XCONQIMAGES) + 1);
+ strcpy(name, libpath);
+ strcat(name, "/../");
strcat(name, XCONQIMAGES);
return name;
}
return spbuf;
}
-static char *savegamename;
-
-char *
-saved_game_filename(void)
-{
- if (savegamename == NULL)
- savegamename = game_filename("XCONQSAVEFILE", SAVEFILE);
- return savegamename;
-}
-
-char *
-checkpoint_filename(int n)
-{
- char *str, *home;
-
- home = game_homedir();
- str = xmalloc(strlen(home) + 40);
- sprintf(str, "%s\\Check%d.Xconq", home, n);
- return str;
-}
-
-static char *preferences_name;
-
-char *
-preferences_filename(void)
-{
- if (preferences_name == NULL)
- preferences_name = game_filename("XCONQPREFERENCES", PREFERENCESFILE);
- return preferences_name;
-}
-
-char *
-error_save_filename(void)
+void
+save_game(char *fname)
{
- /* No need to cache name, will only get requested once. */
- return game_filename("XCONQERRORFILE", ERRORFILE);
-}
+ char *name;
-char *
-statistics_filename(void)
-{
- /* No need to cache name, will only get requested once. */
- return game_filename("XCONQSTATSFILE", STATSFILE);
+ name = copy_string(game_filename("", fname));
+ write_entire_game_state(name);
}
static char *homedir;
-static char *
+char *
game_homedir(void)
{
char *str;
+#ifdef __CYGWIN32__
struct passwd *pwd;
+ char *homedirconv = NULL;
+ char *pc = NULL;
+#endif
if (homedir != NULL)
return homedir;
if ((str = getenv("XCONQ_HOME")) != NULL) {
homedir = copy_string(str);
} else if ((str = getenv("HOME")) != NULL) {
- homedir = xmalloc(strlen(str) + 20);
+ homedir = (char *) xmalloc(strlen(str) + 20);
strcpy(homedir, str);
- strcat(homedir, "/_xconq");
+ strcat(homedir, "/xconq");
+#ifdef __CYGWIN32__
} else if ((pwd = getpwuid(getuid())) != NULL) {
- homedir = xmalloc(strlen(pwd->pw_dir) + 20);
+ homedir = (char *) xmalloc(strlen(pwd->pw_dir) + 20);
strcpy(homedir, pwd->pw_dir);
- strcat(homedir, "/_xconq");
+ strcat(homedir, "/xconq");
+#endif
} else {
- homedir = ".";
+ homedir = "./save";
}
+
+ /* Convert to something that can actually be used by native Win32
+ Tcl/Tk and perhaps others as well.
+ */
+#ifdef __CYGWIN32__
+ homedirconv = (char *) xmalloc(PATH_MAX + 1);
+ cygwin_conv_to_full_win32_path(homedir, homedirconv);
+ /*
+ for (pc = homedirconv; *pc; pc++)
+ if (*pc == '\\')
+ *pc = '/';
+ */
+ free(homedir);
+ homedir = homedirconv;
+#endif
+
/* Try to ensure that the directory exists. */
if (access(homedir, F_OK) != 0) {
+#ifdef __CYGWIN32__
mkdir(homedir, 0755);
+#elif defined (_MSC_VER) || defined (__MWERKS__)
+ CreateDirectory(homedir, NULL);
+#else
+ mkdir(homedir);
+#endif
/* (should warn of problems) */
}
return homedir;
}
-
-static char *
+
+char *
game_filename(char *namevar, char *defaultname)
{
char *str, *home;
- if ((str = getenv(namevar)) != NULL && *str)
- return copy_string(str);
+ if (namevar && (str = getenv(namevar)) != NULL && *str) {
+ return copy_string(str);
+ }
home = game_homedir();
- str = xmalloc(strlen(home) + 1 + strlen(defaultname) + 1);
+ str = (char *)xmalloc(strlen(home) + 1 + strlen(defaultname) + 1);
strcpy(str, home);
- strcat(str, "\\");
+ strcat(str, "/");
strcat(str, defaultname);
return str;
}
return fopen(filename, mode);
}
-/* Attempt to open a library file. */
-
-FILE *
-open_module_library_file(Module *module)
-{
- LibraryPath *p;
- FILE *fp;
-
- /* Don't try to do on anon modules? */
- if (module->name == NULL)
- return NULL;
- for_all_library_paths(p) {
- /* Generate library pathname. */
- make_pathname(p->path, module->name, "g", spbuf);
- /* Now try to open the file. */
- fp = open_file(spbuf, "r");
- if (fp != NULL) {
- /* Remember the filename where we found it. */
- module->filename = copy_string(spbuf);
- return fp;
- }
- }
- return NULL;
-}
-
-FILE *
-open_module_explicit_file(Module *module)
-{
- if (module->filename == NULL)
- return NULL;
- return (open_file(module->filename, "r"));
-}
-
FILE *
open_library_file(char *filename)
{
- char fullnamebuf[1024];
+ char fullnamebuf[BUFSIZE];
LibraryPath *p;
FILE *fp = NULL;
FILE *
open_scorefile_for_reading(char *name)
{
- char *fname;
FILE *fp;
- fname = score_file_pathname(name);
- fp = open_file(fname, "r");
- if (fp == NULL) {
- run_warning("Unable to open \"%s\" for reading;
-will retry once if you continue", fname);
- fp = open_file(fname, "r");
- }
+ fp = open_file(game_filename(NULL, name), "r");
return fp;
}
FILE *
open_scorefile_for_writing(char *name)
{
- char *fname;
FILE *fp;
- fname = score_file_pathname(name);
- fp = open_file(fname, "a");
- if (fp == NULL) {
- run_warning("Unable to open \"%s\" for writing;
-will retry once if you continue", fname);
- fp = open_file(fname, "a");
- }
+ fp = open_file(game_filename(NULL, name), "a");
return fp;
}
fclose(fp);
}
-static char *scorenamebuf;
-
-static char *
-score_file_pathname(char *name)
-{
- char *scorepath, extrabuf[BUFSIZE];
-
- /* (Note that this wires in the name on the first call, so cannot
- be called with different names. We could make this smarter, but
- no point to it right now.) */
- if (scorenamebuf == NULL) {
- scorepath = getenv("XCONQ_SCORES");
- if (empty_string(scorepath)) {
- strcpy(extrabuf, XCONQDATA);
- strcat(extrabuf, "\\");
- strcat(extrabuf, XCONQSCORES);
- scorepath = extrabuf;
- }
- scorenamebuf = xmalloc(strlen(scorepath) + 1 + strlen(name) + 10);
- make_pathname(scorepath, name, NULL, scorenamebuf);
- }
- return scorenamebuf;
-}
-
void
make_pathname(char *path, char *name, char *extn, char *pathbuf)
{
}
}
+/* Get dirname of a given file. */
+
+void
+extract_dirname (char **dirname, char *pathname)
+{
+ char *pdelim = NULL;
+
+ *dirname = copy_string(pathname);
+ pdelim = strrchr(*dirname, '/');
+ if (!pdelim)
+ pdelim = strrchr(*dirname, '\\');
+ else
+ *pdelim = 0;
+ if (!pdelim)
+ **dirname = 0;
+ else
+ *pdelim = 0;
+}
+
/* Remove a given file. */
int
/* Default behavior on explicit kill. */
-void stop_handler(int sig);
-void crash_handler(int sig);
-void hup_handler(int sig);
-
-void
+static void
stop_handler(int sig)
{
close_displays();
/* This routine attempts to save the state before dying. */
-void
+static void
crash_handler(int sig)
{
static int already_been_here = FALSE;
printf("Fatal error encountered. Signal %d\n", sig);
write_entire_game_state(error_save_filename());
}
+#ifdef __cplusplus
+ throw "snafu";
+#else
abort();
+#endif
}
/* Accidental disconnection saves state. */
-void
+static void
hup_handler(int sig)
{
static int already_been_here = FALSE;
printf("Somebody was disconnected, saving the game.\n");
write_entire_game_state(error_save_filename());
}
+#ifdef __cplusplus
+ throw "snafu";
+#else
abort();
+#endif
}
void
signal(SIGINT, SIG_DFL);
/* signal(SIGINT, crash_handler); */
}
- signal(SIGHUP, hup_handler);
signal(SIGSEGV, crash_handler);
signal(SIGFPE, crash_handler);
signal(SIGILL, crash_handler);
signal(SIGINT, crash_handler);
- signal(SIGQUIT, crash_handler);
signal(SIGTERM, crash_handler);
/* The following signals may not be available everywhere. */
+#ifdef SIGHUP
+ signal(SIGHUP, hup_handler);
+#endif
+#ifdef SIGQUIT
+ signal(SIGQUIT, crash_handler);
+#endif
#ifdef SIGBUS
signal(SIGBUS, crash_handler);
-#endif /* SIGBUS */
+#endif
#ifdef SIGSYS
signal(SIGSYS, crash_handler);
-#endif /* SIGSYS */
+#endif
+}
+
+char *
+error_save_filename(void)
+{
+ /* No need to cache name, will only get requested once. */
+ return game_filename("XCONQERRORFILE", ERRORFILE);
}
struct timeval reallasttime = { 0, 0 };