view defaults.c @ 2:fba0b6e6cdc7

Added tag ALPHA for changeset ff5e05767bd3
author darius@midget.dons.net.au
date Tue, 23 Oct 2007 10:09:09 +0930
parents ff5e05767bd3
children
line wrap: on
line source

/* $Id: defaults.c,v 1.1.1.1 1997/12/06 05:41:28 darius Exp $ */

/* defaults.c
 *
 * Kevin P. Smith  6/11/89
 * Bill Dyess      9/29/93  - moved all default settings to resetDefaults
 *                           from main
 * Bill Dyess	   11/8/93  - created expandFilename function
 * Bill Dyess      11/20/93 - added #include capability
 */
#include "copyright2.h"
#include <stdio.h>
#ifdef hpux
#include <time.h>
#else
#include <sys/time.h>
#endif
#ifdef __STDC__
#include <stdlib.h>
#endif
#include<ctype.h>
#include<pwd.h>
#include <string.h>
#include <stdlib.h>
#include "Wlib.h"
#include "defs.h"
#include "struct.h"
#include "data.h"
#include "proto.h"

#define MAXLINE 1024

/* list of files to search for [BDyess] */
static char *filelist[] = {".paradiserc",".netrekrc",".xtrekrc",NULL};

/* Prototypes */
static FILE *findDefaults P((char *home, char **deffile, char *base));

char   *
expandFilename(filename)
    char   *filename;
/* expands ~ (home dir) and environment vars in filenames.  This is primarily
   for filenames specified in the .xtrekrc file, where the shell never gets
   a chance to expand them.  [BDyess] */
{
    char    buf[MAXLINE], *src = filename, *dest = buf, tmpbuf[MAXLINE],
           *tmppntr, *envpntr;
    struct passwd *pw;

    if (!src)
	return filename;
    while (*src) {
	if (*src == '~') {
	    src++;
	    if (*src != '/' && *src) {	/* ~username */
		tmppntr = tmpbuf;
		while (isalpha(*src))
		    *tmppntr++ = *src++;
		*tmppntr = 0;
		pw = getpwnam(tmpbuf);
		if (!pw) {
		    fprintf(stderr, "Error: can't find username %s, inserting ~ literally.\n", tmpbuf);
		    *dest++ = '~';
		    strcpy(dest, tmpbuf);
		} else
		    strcpy(dest, pw->pw_dir);
	    } else {		/* just ~, insert $HOME */
		envpntr = getenv("HOME");
		if (envpntr != NULL)
		    strcpy(dest, envpntr);
		else
		    printf("HOME environment variable missing, ignoring ~.\n");
	    }
	    while (*dest)
		dest++;
	} else if (*src == '$') {
	    /* copy the shortest env var that matches */
	    /* if in {}'s, the work is done for us */
	    src++;
	    if (*src == '{') {
		src++;
		tmppntr = tmpbuf;
		while (*src != '}' && *src)
		    *tmppntr++ = *src;
		*tmppntr = 0;
		envpntr = getenv(tmpbuf);
		if (envpntr)
		    strcpy(dest, getenv(tmpbuf));
		while (*dest)
		    dest++;
	    } else if (*src) {	/* we have to work */
		tmppntr = tmpbuf;
		*tmppntr++ = *src++;
		*tmppntr = 0;
		while (!getenv(tmpbuf) && *src) {
		    *tmppntr++ = *src++;
		    *tmppntr = 0;
		}
		if (*src)
		    strcpy(dest, getenv(tmpbuf));
		while (*dest)
		    dest++;
	    }
	} else if (*src == '\\') {	/* escaped char */
	    src++;
	    if (*src)
		*dest++ = *src++;
	} else {		/* just a regular char */
	    *dest++ = *src++;
	}
    }
    *dest = 0;
    dest = (char *) realloc(filename, strlen(buf) + 1);
    strcpy(dest, buf);
    return dest;
}

void
freeDefaults()
{
    struct stringlist *tmp;
    while (defaults) {
	tmp = defaults;
	defaults = defaults->next;
	free(tmp->string);
	free(tmp->value);
	free(tmp);
    }
}

char   *
initDefaults(deffile)
    char   *deffile;		/* As opposed to defile? */
{
    FILE   *fp;
    char    buf[MAXLINE];
    char   *includeFile;
    char   *home;
    char   *v, *r;
    struct stringlist *new;
    int     ok, i;
    int     skip = 0;

    /* if(defaults) freeDefaults(); */
    if (!deffile) {
	deffile = (char *) malloc(256);
	home = getenv("HOME");
#ifdef AMIGA
	/*
	   This is VERY MISLEADING.  Really want to say home="netrek:" but
	   that causes other problems.  ixemul.library will translate
	   "/netrek" into "netrek:" Unless configured not to.  Does by
	   default. Yuck, what a mess. -JR
	*/
	if (!home)
	    home = "/netrek";
#endif				/* AMIGA */
        for(i = 0;filelist[i];i++) {
	  /* home == NULL means search the current directory [BDyess] */
	  fp = findDefaults(NULL, &deffile, filelist[i]);
	  if(fp) break;
	  fp = findDefaults(home, &deffile, filelist[i]);
	  if(fp) break;
	}
    } else {
	fp = fopen(deffile, "r");
    }
#ifdef SYS_RC
    if (!fp) {
	fp = fopen(SYS_RC, "r");
	if (!fp)
	    return deffile;
	printf("Using %s as defaults file.\n", SYS_RC);
    } else {
	printf("Using %s as defaults file.\n", deffile);
    }
#else
    if (!fp)
	return deffile;
#endif
    printf("Reading defaults from %s.\n", deffile);
    while (fgets(buf, MAXLINE - 1, fp)) {
	if (skip) {
	    skip = strncmpi(buf, "paradise-include", 16);
	    continue;
	} else {
	    skip = !strncmpi(buf, "paradise-exclude", 16);
	    if (skip)
		continue;
	}
	/* if (*buf=='#' || *buf==';') continue; */
	v = buf;
	if (*buf == '#') {
	    if (strncmpi(buf + 1, "include", 7) == 0) {	/* #include statement */
		v = buf + 8;
		ok = 0;
		while (*v == ' ' || *v == '<' || *v == '"') {
		    if (*v != ' ')
			ok = 1;
		    v++;
		}
		if (!ok)
		    continue;	/* must have " or < before filename */
		includeFile = strdup(v);
		r = includeFile + strlen(includeFile) - 1;
		*r = 0;		/* remove trailing \n */
		r--;
		ok = 0;
		while ((*r == '"' || *r == '>' || *r == ' ') && r > includeFile) {
		    if (*r != ' ')
			ok = 1;
		    *r = 0;
		    r--;
		}
		if (!ok || r <= includeFile)
		    continue;	/* if no ending '>' or '"' */
		/* or no filename, forget it */
		includeFile = expandFilename(includeFile);
		initDefaults(includeFile);	/* recursively add the file  */
		free(includeFile);
	    }
	    continue;
	}
	if (*buf != 0)
	    buf[strlen(buf) - 1] = 0;
	while (*v != ':' && *v != 0) {
	    v++;
	}
	if (*v == 0)
	    continue;
	*v = 0;
	v++;
	while (*v == ' ' || *v == '\t') {
	    v++;
	}
	if (*v != 0) {
	    new = (struct stringlist *) malloc(sizeof(struct stringlist));
	    new->next = defaults;
	    if(defaults)
		defaults->prev=new;
	    new->prev = NULL;
	    new->string = strdup(buf);
	    new->value = strdup(v);
	    new->searched = 0;
	    defaults = new;
	}
    }
    fclose(fp);
    return deffile;
}

#if 0
char   *
strdup(str)
    char   *str;
{
    char   *s;

    s = (char *) malloc(strlen(str) + 1);
    strcpy(s, str);
    return (s);
}
#endif

/* changed to search the entire defaults list once instead of as many as 
   three times.  This is faster unless you have a "default.nickname:" entry
   for almost every default on every server... -JR */

char   *
getdefault(str)
    char   *str;
{
    struct stringlist *slNick=0, *slFlavor=0, *slNorm=0, *sl;
    char    tempNick[80], tempFlavor[80];
    char *val;

    if (!str)
	return NULL;
    if (!strlen(str))
	return NULL;

    if (defNickName)
	sprintf(tempNick, "%s.%s", str, defNickName);

    if (defFlavor)
	sprintf(tempFlavor, "%s.%s", str, defFlavor);

    for(sl=defaults;sl;sl=sl->next) {
	if(defNickName && !strcmpi(sl->string, tempNick)) {
	    return sl->value;
	    /* in case there's ever a reason to keep searching: */
	    if(!slNick)
		slNick=sl;
	} else if(defFlavor && !strcmpi(sl->string, tempFlavor)) {
	    if(!slFlavor)
		slFlavor = sl;
	}

	if (!strcmpi(sl->string, str)) {
	    if(!slNorm)
		slNorm = sl;
	}
    }
    if(slNick)
	return slNick->value;
    if(slFlavor)
	return slFlavor->value;
    if(slNorm)
	return slNorm->value;

    return (NULL);
}

#if NO_STRCMPI && !defined(sgi)
int
strcmpi(str1, str2)
    char   *str1, *str2;
{
    for (;;) {
	register char c1 = *str1, c2 = *str2;
	if (c1 <= 'z' && c1 >= 'a')
	    c1 += 'A' - 'a';
	if (c2 <= 'z' && c2 >= 'a')
	    c2 += 'A' - 'a';
	if (c1 != c2)
	    return (c2 - c1);
	if (c1 == 0 || c2 == 0)
	    return (0);
	str1++;
	str2++;
    }
    return (strcmp(str1, str2));
}
#endif

#if NO_STRNCMPI && !defined(sgi)
int
strncmpi(str1, str2, len)
    char   *str1, *str2;
    int     len;
{
    int     i;

    for (i = 0; i < len; i++) {
	if (tolower(*str1) != tolower(*str2))
	    return (*str2 - *str1);
	if (*str1 == 0 || *str2 == 0)
	    return (0);
	str1++;
	str2++;
    }
    return 0;
}
#endif

int
booleanDefault(def, preferred)
    char   *def;
    int     preferred;
{
    char   *str;

    str = getdefault(def);
    if (str == NULL)
	return (preferred);
    if (!strcmpi(str, "on") || !strcmpi(str, "true") || !strcmpi(str, "1")) {
	return (1);
    } else {
	return (0);
    }
}

int
intDefault(def, preferred)
    char   *def;
    int     preferred;
{
    char   *str;

    str = getdefault(def);
    if (!str)
	return preferred;
    return atoi(str);
}

/* gets the default for the given def and returns it if it exists.
   Otherwise returns a fresh copy of the preferred string */
char   *
stringDefault(def, preferred)
    char   *def;
    char   *preferred;
{
    char   *str;

    str = getdefault(def);
    if (!str)
	return strdup(preferred);
    return strdup(str);
}

/* no default file given on command line.
   See if serverName is defined.  If it exists we look for
   HOME/.xtrekrc-<serverName> and .xtrekrc-<serverName>
   Otherwise we try DEFAULT_SERVER. */
/* modified to accept .paradiserc (or any base filename) 12/21/93 [BDyess] */
/* extended to check for for unadorned base and to return a fp [BDyess] */

static FILE *
findDefaults(home, deffile, base)
    char   *home, **deffile, *base;
{
    FILE   *fp;

    /* check base-serverName */
    if (serverName) {
	if (home)
	    sprintf(*deffile, "%s/%s-%s", home, base, serverName);
	else
	    sprintf(*deffile, "%s-%s", base, serverName);
	fp = fopen(*deffile, "r");
	if (fp)
	    return fp;
    }
    /* check base-DEFAULT_SERVER */
    if (home)
	sprintf(*deffile, "%s/%s-%s", home, base, DEFAULT_SERVER);
    else
	sprintf(*deffile, "%s-%s", base, DEFAULT_SERVER);
    fp = fopen(*deffile, "r");
    if (fp)
	return fp;

    /* check just base */
    if (home)
	sprintf(*deffile, "%s/%s", home, base);
    else
	strcpy(*deffile, base);
    fp = fopen(*deffile, "r");
    return fp;
}

/* default ship code, courtesy of Robert Blackburn <blackburn@Virginia.EDU>.
   used by main(), modified to accept 2 letter initials 11/15/91 TC */
/* modified to accept pt/ut's 10/10/93 [BDyess] */

int
defaultShip(preferred)
    int     preferred;
{
    char   *type;

    type = getdefault("defaultship");
    if (type == NULL)
	return preferred;
    if ((strcmpi(type, "scout") == 0) || (strcmpi(type, "SC") == 0))
	return SCOUT;
    else if ((strcmpi(type, "destroyer") == 0) || (strcmpi(type, "DD") == 0))
	return DESTROYER;
    else if ((strcmpi(type, "cruiser") == 0) || (strcmpi(type, "CA") == 0))
	return CRUISER;
    else if ((strcmpi(type, "battleship") == 0) || (strcmpi(type, "BB") == 0))
	return BATTLESHIP;
    else if ((strcmpi(type, "assault") == 0) || (strcmpi(type, "AS") == 0))
	return ASSAULT;
    else if ((strcmpi(type, "starbase") == 0) || (strcmpi(type, "SB") == 0))
	return STARBASE;
    else if ((strcmpi(type, "jumpship") == 0) || (strcmpi(type, "JS") == 0))
	return JUMPSHIP;
    else if ((strcmpi(type, "warbase") == 0) || (strcmpi(type, "WB") == 0))
	return WARBASE;
    else if ((strcmpi(type, "flagship") == 0) || (strcmpi(type, "FL") == 0))
	return FLAGSHIP;
    else if ((strcmpi(type, "lightcruiser") == 0) || (strcmpi(type, "CL") == 0))
	return LIGHTCRUISER;
    else if ((strcmpi(type, "carrier") == 0) || (strcmpi(type, "CV") == 0))
	return CARRIER;
    else if ((strcmpi(type, "patrol") == 0) || (strcmpi(type, "PT") == 0))
	return PATROL;
    else if ((strcmpi(type, "utility") == 0) || (strcmpi(type, "UT") == 0))
	return UTILITY;
    else
	return preferred;
}

void
initLogFile()
{
    if (logFile && logmess) {
	logfilehandle = fopen(logFile, "a");
	if (!logfilehandle) {
	    fprintf(stderr, "Can't open %s: ", logFile);
	    perror("");
	    logFile = NULL;
	} else {
	    printf("Opening %s for logging\n", logFile);
	    fprintf(logfilehandle, "\n-----------------------------------------------------------------\nStarted logging for server %s at%s\n-----------------------------------------------------------------\n",
		    serverName, timeString(time(NULL)));
	}
    }
}

void
resetDefaults()
{
    char   *buf;
#ifdef AUTHORIZE
    if (RSA_Client >= 0)
	RSA_Client = booleanDefault("useRSA", RSA_Client);
    else
	RSA_Client = (RSA_Client == -2);
#endif


    showShields = booleanDefault("showshields", showShields);
    showStats = booleanDefault("showstats", showStats);
    keeppeace = booleanDefault("keeppeace", keeppeace);
    reportKills = booleanDefault("reportkills", reportKills);
#if 0
    blk_altbits = booleanDefault("altbitmaps", blk_altbits);
#endif
    blk_showStars = booleanDefault("showstars", blk_showStars);
    showMySpeed = booleanDefault("showMySpeed", showMySpeed);
    showTractorPressor = booleanDefault("showTractorPressor",
					showTractorPressor);
    /* show all tractor/pressor beams, not just your own [BDyess] */
    showAllTractorPressor = booleanDefault("showAllTractorPressor",
					   showAllTractorPressor);
    showLock = intDefault("showLock", showLock);
    drawgrid = booleanDefault("showgrid", drawgrid);
    showgalactic = intDefault("showgalactic", showgalactic);
    showlocal = intDefault("showlocal", showlocal);
    namemode = booleanDefault("namemode", namemode);

    Dashboard = booleanDefault("newDashboard", Dashboard);
    cup_half_full = booleanDefault("newDashboard2", cup_half_full);
    if (cup_half_full)
	Dashboard = 2;
    Dashboard = intDefault("Dashboard", Dashboard);

    unixSoundPath = stringDefault("soundPath", "?");
    unixSoundDev  = stringDefault("soundDev", "?");

    cloakchars = stringDefault("cloakchars", "??");
    cloakcharslen = strlen(cloakchars);

    showPhaser = intDefault("showPhaser", showPhaser);
    logmess = booleanDefault("logging", logmess);
    logFile = getdefault("logfile");
    if(logFile)
	logFile=expandFilename(strdup(logFile));

    initLogFile();
#ifdef VARY_HULL
    vary_hull = booleanDefault("warnhull", vary_hull);
#endif				/* VARY_HULL */

#ifdef TOOLS
  shelltools = booleanDefault("shellTools", shelltools);
#endif
    warpStreaks = booleanDefault("warpStreaks", warpStreaks);
    use_msgw = booleanDefault("useMsgw", use_msgw);
    logPhaserMissed = booleanDefault("logPhaserMissed", logPhaserMissed);
    phaserStats = booleanDefault("phaserStats", phaserStats);
    jubileePhasers = booleanDefault("jubileePhasers", jubileePhasers);
    show_shield_dam = booleanDefault("showShieldDam", show_shield_dam);
    updateSpeed = intDefault("udpupdates", updateSpeed);
    updateSpeed = intDefault("updatespersecond", updateSpeed);
    updateSpeed = intDefault("updatespersec", updateSpeed);
    extraBorder = booleanDefault("extraAlertBorder", extraBorder);
    if (booleanDefault("galacticfrequent", 0))
	mapmode = GMAP_FREQUENT;
#ifdef CONTINUOUS_MOUSE
    continuousMouse = booleanDefault("continuousMouse", continuousMouse);
    if (continuousMouse)
	buttonRepeatMask = 1 << W_LBUTTON | 1 << W_RBUTTON | 1 << W_MBUTTON;
    clickDelay = intDefault("clickDelay", clickDelay);
    if (booleanDefault("continuousMouse.L", 0))
	buttonRepeatMask |= 1 << W_LBUTTON;
    if (booleanDefault("continuousMouse.M", 0))
	buttonRepeatMask |= 1 << W_MBUTTON;
    if (booleanDefault("continuousMouse.R", 0))
	buttonRepeatMask |= 1 << W_RBUTTON;
    if (buttonRepeatMask)
	continuousMouse = 1;
#endif				/* CONTINUOUS_MOUSE */
    autoQuit = intDefault("autoQuit", autoQuit);
    if (autoQuit > 199) {
	autoQuit = 199;
	printf("autoQuit reduced to 199\n");
    }
    pigSelf = booleanDefault("pigSelf", pigSelf);
    /* info icon shows info in place of the icon bitmap [BDyess] */
    infoIcon = booleanDefault("infoIcon", infoIcon);
    showGalacticSequence = stringDefault("showGalacticSequence", "012345");
    for (buf = showGalacticSequence; *buf; buf++) {
	if (*buf - '0' > 5) {
	    fprintf(stderr, "Error in showGalacticSequence: %d too high, ignoring\n", *buf);
	    free(showGalacticSequence);
	    showGalacticSequence = strdup("012345");
	    break;
	}
    }
    showLocalSequence = stringDefault("showLocalSequence", "01234");
    for (buf = showLocalSequence; *buf; buf++) {
	if (*buf - '0' > 4) {
	    fprintf(stderr, "Error in showLocalSequence: %d too high, ignoring\n", *buf);
	    free(showLocalSequence);
	    showLocalSequence = strdup("01234");
	    break;
	}
    }

#ifdef ATM
    udpDebug = booleanDefault("udpDebug", udpDebug);
    udpClientSend = intDefault("udpClientSend", udpClientSend);
    /* note: requires send */
    udpClientRecv = intDefault("udpClientReceive", udpClientRecv);
    tryUdp = booleanDefault("tryUdp", tryUdp);
    udpSequenceChk = booleanDefault("udpSequenceCheck", udpSequenceChk);
#endif				/* ATM */

    tryShort = booleanDefault("tryShort", tryShort);	/* auto-try S_P [BDyess] */

    /* playerlist settings */
    robsort = booleanDefault("robsort", robsort);
    sortPlayers = booleanDefault("sortPlayers", sortPlayers);
    hideNoKills = booleanDefault("hidenokills", hideNoKills);
    showDead = booleanDefault("showDead", showDead);
    showPreLogins = booleanDefault("showPreLogins", showPreLogins);
    sortOutfitting = booleanDefault("sortOutfitting", sortOutfitting);
    timerType = intDefault("timertype", timerType);
#ifdef WIDE_PLIST
    /*
       default: old playerlist (ie, no format string), number shiptype rank
       name kills wins losses ratio offense defense di, number shiptype name
       kills login ratio totalrating di [BDyess]
    */
    playerListStart = stringDefault("playerList",
				    ",nTRNKWLr O D d,nTR N  K lrSd");
    playerList = playerListStart;
    resizePlayerList = booleanDefault("resizePlayerList",resizePlayerList);
#endif				/* WIDE_PLIST */

#ifdef PACKET_LIGHTS
    packetLights = booleanDefault("packetLights", packetLights);
#endif				/* PACKET_LIGHTS */

    viewBox = booleanDefault("viewBox", viewBox);
    sectorNums = booleanDefault("sectorNums", sectorNums);
    lockLine = booleanDefault("lockLine", lockLine);
    mapSort = booleanDefault("mapSort", mapSort);
    autoSetWar = intDefault("autoSetWar", autoSetWar);
    tacPlanetInfo = intDefault("tacPlanetInfo", tacPlanetInfo);

    /* metaFork = booleanDefault("metaFork",metaFork); */

    keepInfo = intDefault("keepInfo", keepInfo);

#ifdef NOWARP
    /* if there are alternatives to message warp, use it anyway? -JR */
    warp = booleanDefault("messageWarp", warp);
#endif

#ifdef CHECK_DROPPED
    reportDroppedPackets = booleanDefault("reportDroppedPackets", reportDroppedPackets);
#endif

    askforUpdate = booleanDefault("askforUpdate", askforUpdate);
    lowercaset = booleanDefault("lowercaset", lowercaset);
    scrollBeep = booleanDefault("scrollBeep", scrollBeep);
#ifdef SHORT_PACKETS
    godToAllOnKills = booleanDefault("godToAllOnKills",godToAllOnKills);
#endif

    autoZoom=intDefault("autoZoom", autoZoom);
    autoUnZoom = intDefault("autoUnZoom",autoUnZoom);
    autoZoomOverride = intDefault("autoZoomOverride",autoZoomOverride);

#ifdef BEEPLITE
    {
	DefLite = booleanDefault("DefLite", DefLite);
	UseLite = booleanDefault("UseLite", UseLite);

	if (DefLite)
	    litedefaults();

	beep_lite_cycle_time_planet = intDefault("planetCycleTime",
					       beep_lite_cycle_time_planet);
	beep_lite_cycle_time_player = intDefault("playerCycleTime",
					       beep_lite_cycle_time_player);
    }
#endif				/* BEEPLITE */

#ifdef COW_HAS_IT_WHY_SHOULDNT_WE
    showMapAtMotd = booleanDefault("showMapAtMotd",showMapAtMotd);
#endif

#ifdef LOCAL_SHIPSTATS
    localShipStats=booleanDefault("localShipStats",localShipStats);
    statString = stringDefault("statString","DSEWF");
    statHeight = intDefault("statHeight",statHeight);
    if(statHeight<4) statHeight=4;
    if(statHeight>100) statHeight = 100;
    localStatsX = intDefault("localStatsX", localStatsX);
    localStatsY = intDefault("localStatsY", localStatsY);
#endif

#ifdef SHOW_IND
    showIND = booleanDefault("showIND",showIND);
#endif

#ifdef HOCKEY
    galacticHockeyLines = booleanDefault("galacticHockeyLines",
    				galacticHockeyLines);
    tacticalHockeyLines = booleanDefault("tacticalHockeyLines",
    				tacticalHockeyLines);
    cleanHockeyGalactic = booleanDefault("cleanHockeyGalactic",
    				cleanHockeyGalactic);
    teamColorHockeyLines = booleanDefault("teamColorHockeyLines",
    				teamColorHockeyLines);
#endif /*HOCKEY*/

#ifdef AMIGA
    getAmigaDefs();
#endif

#ifdef SOUND
    getSoundDefs();
#endif

    redrawDelay = intDefault("redrawDelay",redrawDelay);

    initkeymap(-1);
#ifdef MACROS
    initMacros();
#endif				/* MACROS */

    /*
       sendOptionsPacket();
    *//* There is nothing on the server side that should be controlled by
       xtrekrc variables. */
}