cdirt/ascii/
cdirt/data/BULL/
cdirt/data/ZONES/PENDING/
cdirt/pending/
cdirt/src/utils/
cdirt/utils/
#include <stdio.h>
#include <string.h>
#include <netdb.h>
#include <sys/socket.h>
#include <sys/utsname.h>
#include <ctype.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

#define OPT_FILE   ".config.opts"
#define IN_FILE    ".config.pri"
#define IN_FILE2   ".config.mkfile"
#define OUT_FILE   ".config.pri.tmp"
#define OUT_FILE2  ".config.mkfile.tmp"
#define BASIC  1
#define CUSTOM 2

#define answer_exists(x)   (x && x != '\n' && x != '\r')

#define CUSTOM_STR      "<CUSTOM>"
#define DEFAULT_STR     "<DEFAULT"
#define HEADER 		"<HEADER>"
#define P_HOSTNAME      "<PROMPT_HOSTNAME>"
#define P_INSTALL 	"<PROMPT_INSTALL>"
#define P_BASELOC	"<PROMPT_BASELOC>"
#define P_CFLAGS        "<PROMPT_CFLAGS>"
#define P_LDFLAGS       "<PROMPT_LDFLAGS>"
#define P_LOADDEFTS     "<PROMPT_LOADDEFTS>"
#define P_VERBOSE       "<PROMPT_CONFIG_VERBOSE>"
#define P_PROMPT 	"<PROMPT>"
#define P_VAL		"<PROMPT_VAL>"
#define P_YN		"<PROMPT_YN>"
#define P_NY		"<PROMPT_NY>"

void get_val(char *, char *, char *, char *);
char *probe_ldflags(void);
char *detect_arch (char *);
char *detect_os (char *);
void detect(char *deft, FILE*);

int ignore = 0;
int load_stored = 0;
int verbose = 1;
FILE *outf, *outf2;


char *replace_deft(char *s, char *deft) {
  static char retbuff[100];
  char *p;

  if ((p = strstr(s, "<deft>"))) {
    *p = 0;
    p += 6;
    sprintf(retbuff, "%s[%s]%s", s, deft, p);
    return(retbuff);
  }
  else
    return(s);
}

char *load_stored_deft(char *s) {
  char buff[100];
  char var[100];
  static char val[100];
  char *p, *q;
  FILE *fpr;

  if ((fpr = fopen(IN_FILE2, "r"))) {
    while(1) {
      fgets(buff, 99, fpr);
      if (feof(fpr))
        break;
      if (!*(strchr(buff, '=') + 1)) {
        fclose(fpr);
        return(NULL);
      }
      if ((p = strchr(buff, '\n')))
	*p = 0;
      
      p = strchr(buff, '=');
      *(p-1) = 0;
      p += 2;
      
      if (!strcmp(var, buff)) {
	fclose(fpr);
	return(p);
      }
    }
    fclose(fpr);
  }

  if ((fpr = fopen(IN_FILE, "r"))) {
    while(1) {
      fgets(buff, 99, fpr);
      if (feof(fpr))
	break;

      p = strchr(buff, ' ') + 1;
      
      if (!strncmp(buff, "#define ", strlen("#define "))) {
	if (!(q = strchr(p , ' '))) {
	  if (!strncmp(p, s, strlen(s))) {
	    fclose(fpr);
	    return("Y");
	  }
	}
	else {
	  if (!strncmp(p, s, strlen(s))) {
	    fclose(fpr);
	    if ((p = strchr(q+1, '"'))) {
	      *p = 0;
	      q = p;
	    }
            if ((p = strchr(q+1, '"')))
              *p = 0;
	    if ((p = strchr(q+1, '\n')))
	      *p = 0;
	    return(strcpy(val, q+1));
	  }
	}
      }
      else if (!strncmp(buff, "#undef ", strlen("#undef "))) { 
	if (!(q = strchr(p , ' '))) {
	  if (!strncmp(p, s, strlen(s))) {
	    fclose(fpr);
	    return("N");
	  }
	}
	else {
	  if (!strncmp(p, s, strlen(s))) {
	    fclose(fpr);
            if ((p = strchr(q+1, '"'))) {
              *p = 0;
              q = p;
            }
            if ((p = strchr(q+1, '"')))
              *p = 0;
	    if ((p = strchr(q+1, '\n')))
              *p = 0;
            return(strcpy(val, q+1));
	  }
	}
      }
    }
  }
  fclose(fpr);
  return(NULL);
}

void get_val(char *prmpt, char *rslt, char *deft, char *option) {
  char buff[256] = "\0";
  char *ptr, *retloc, *def;

  if (!load_stored || !((def = load_stored_deft(option))))
    def = deft;

  if (!ignore) {
    ptr = strchr(prmpt, '>') + 2;
    
    if ((retloc = strchr(ptr, '\n')))
      *retloc = 0;
    
    printf("%s ", replace_deft(ptr, def));
    fgets(buff, 255, stdin);

    if (!answer_exists(*buff))
      strcpy(rslt, def);
    else {
      if ((retloc = strchr(buff, '\n')))
        *retloc = 0;     
      strcpy(rslt, buff);
    }
  }
  else
    strcpy(rslt, def);
}

int main(void) {
  char line[256];
  char dir[256];
  char deft[256];
  char answer[256];
  char define[256];
  char buff[256];
  int install;
  FILE *optptr, *f1, *f2;

  if (!(optptr = fopen(OPT_FILE, "r"))) {
    printf("Unable to read options file.\n");
    exit(1);
  }

  if (!(outf = fopen(OUT_FILE, "w"))) {
    printf("Unable to store config file.\n");
    exit(1);
  }

  if (!(outf2 = fopen(OUT_FILE2, "w"))) {
    printf("Unable to store second config file.\n");
    exit(1);
  }

  while(1) {
    fgets(line, 255, optptr);
    if (feof(optptr))
      break;
    if (*line != '<') {
      if (!ignore && verbose)
        printf(line);
    }
    else {
      if (!strcmp(line, HEADER))      /* special types */
        continue;
      else if (!strncmp(line, P_LOADDEFTS, strlen(P_LOADDEFTS))) {
	if ((f1 = fopen(IN_FILE, "r")) && (f2 = fopen(IN_FILE2, "r"))) {
	  printf("\nWould you like to load the previous settings you chose as "
	         "the default\nvalues? You will then be able to hit enter on "
	         "the ones you wish to\nremain the same.\n\n");
	  
	  fclose(f1); fclose(f2);
	  printf("Load previous settings [Y]? ");
	  fgets(answer, 255, stdin);
	  if (tolower(*answer) != 'n')
	    load_stored = 1;
	}
      }
      else if (!strncmp(line, P_VERBOSE, strlen(P_VERBOSE))) {
	get_val(line, answer, "Y", "CONFIG_VERBOSE");
	if (tolower(*answer) == 'n') {
	  verbose = 0;
	  fprintf(outf, "#undef CONFIG_VERBOSE\n");
	}
	else
	  fprintf(outf, "#define CONFIG_VERBOSE\n");
      }
      else if (!strncmp(line, P_HOSTNAME, strlen(P_HOSTNAME))) {
	get_val(line, answer, "localhost", "_HOSTNAME_");
        detect(answer, outf);
      }
      else if (!strncmp(line, P_INSTALL, strlen(P_INSTALL))) {
        get_val(line, answer, "B", "INSTALL");
	fprintf(outf, "#define INSTALL \"%s\"\n", answer);
	if (tolower(*answer) == 'b')
          install = BASIC;
        else
          install = CUSTOM;
      }
      else if (!strncmp(line, P_LDFLAGS, strlen(P_LDFLAGS))) {
        get_val(line, answer, deft, "LDOPT");
        fprintf(outf2, "LDOPT =%s %s\n", answer, probe_ldflags());
      }
      else if (!strncmp(line, P_CFLAGS, strlen(P_CFLAGS))) {
        get_val(line, answer, deft, "COPT");
        fprintf(outf2, "COPT =%s\n", answer);
      }
      else if (!strncmp(line, P_BASELOC, strlen(P_BASELOC))) {
        getcwd(dir, sizeof(dir));
        sprintf(buff, "<PROMPT_BASELOC> Base location for MUD <deft>:");
	get_val(buff, answer, dir, "ROOTDIR");
        fprintf(outf, "#define BASE_LOC \"%s\"\n", answer);
        fprintf(outf2, "ROOTDIR = %s/\n", answer);
      }
      else if (!strncmp(line, P_PROMPT, strlen(P_PROMPT))) {
        get_val(line, answer, deft, define);
        fprintf(outf, "#define %s \"%s\"\n", define, answer);
      }
      else if (!strncmp(line, P_VAL, strlen(P_VAL))) {
        get_val(line, answer, deft, define);
        fprintf(outf, "#define %s %s\n", define, answer);
      }
      else if (!strncmp(line, P_YN, strlen(P_YN))) {
        get_val(line, answer, "Y", define);
        if (tolower(*answer) == 'y')
          fprintf(outf, "#define %s\n", define);
        else
          fprintf(outf, "#undef %s\n", define);
      }
      else if (!strncmp(line, P_NY, strlen(P_NY))) {
        get_val(line, answer, "N", define);
        if (tolower(*answer) == 'n')
          fprintf(outf, "#undef %s\n", define);
        else
          fprintf(outf, "#define %s\n", define);
      }
      else if (!strncmp(line, CUSTOM_STR, strlen(CUSTOM_STR))) {
        if (install != CUSTOM)
          ignore = 1;
      }
      else if (!strncmp(line, DEFAULT_STR, strlen(DEFAULT_STR))) {
        char *ptr;
        ptr = strchr(line, '=') + 1;
        *(strchr(ptr, '>')) = 0;
        strcpy(deft, ptr);
      }
      else {
        *(strchr(line + 1, '>')) = 0;
        strcpy(define, line + 1);
        *deft = 0;
      }
    }
  }

  fclose(outf);
  fclose(outf2);
  fclose(optptr);
  return(0);
}

int is_ipaddr(char *str) {
  char *p, *q;

  if ((q = strchr(str, '\n')))
    *q = 0;
    
  for (p = str ; *p ; p++)
    if (*p != '.' && !isdigit(*p))
      return(0);

  return(1);
}

void detect (char *hostname, FILE *fil) {
  struct utsname name;
  struct hostent *h;
  struct in_addr in;
  int failed;
  char filename[100];
  char ipname[100];
  FILE *fp;

  sprintf (filename, "include/MACHINE.H");

  if ((fp = fopen (filename, "wt")) == NULL)
    exit();

  if (uname(&name) == -1)
    failed = 1;
  else
    failed = 0;

  fprintf (fp, "#ifndef _MACHINE_H\n");
  fprintf (fp, "#define _MACHINE_H\n\n");

  if (!failed) {
    fprintf (fp, "#define %s\n", detect_arch (name.machine));
    fprintf (fp, "#define %s\n\n", detect_os (name.sysname));
  }

  fprintf (fp, "#define _ARCH_\t\"%s\"\n", failed ? 
	   "_UNKNOWN_ARCH_" : name.machine);

  if (is_ipaddr(hostname)) {
    strcpy(ipname, hostname);
    if ((h = gethostbyaddr(hostname, strlen(hostname), AF_INET)))
      strcpy(hostname, h->h_name);
    else {
      printf("\nHostname lookup failed.  Edit MACHINE.H manually.\n");
      strcpy(hostname, "<Your Hostname>");
    }
  }
  else {
    if ((h = gethostbyname(hostname))) {
      bcopy (h->h_addr_list[0], &(in.s_addr), h->h_length);
      strcpy(ipname, inet_ntoa(in));
    }
    else {
      printf("\nIP address lookup failed.  Edit MACHINE.H manually.\n");
      strcpy(ipname, "<Your IP#>");
    } 
  }

  fprintf (fp, "#define _HOSTNAME_\t\"%s\"\n", hostname);
  fprintf (fil, "#define HOSTNAME \"%s\"\n", hostname);
  fprintf (fp, "#define _IPNAME_\t\"%s\"\n", ipname);
  fprintf (fp, "#define _VERSION_\t\"%s\"\n", failed ? 
	   "_UNKNOWN_VERSION_" : name.release);
  fprintf (fp, "#define _OS_\t\"%s\"\n\n", failed ?
	   "_UNKNOWN_OS_" : name.sysname);
  fprintf (fp, "#endif\n");
  fclose (fp);
}

char *detect_arch (char arch[65]) {
  if ((strstr (arch, "i386")) != NULL)
    return "_I386_";

  if ((strstr (arch, "i486")) != NULL)
    return "_I486_";

  if ((strstr (arch, "i586")) != NULL)
    return "_I586_";

  if ((strstr (arch, "i686")) != NULL)
    return "_I686_";

  if ((strstr (arch, "sun")) != NULL)
    return "_SUN_";

  if ((strstr (arch, "mac68k")) != NULL)
    return "_MAC68K_";

  return "_UNKNOWN_ARCH_";
}

char *detect_os(char os[65]) {
  if ((strstr (os, "Linux")) != NULL)
    return "_LINUX_";

  if ((strstr (os, "SunOS")) != NULL)
    return "_SUNOS_";

  if ((strstr (os, "NetBSD")) != NULL)
    return "_NETBSD_";

  if ((strstr (os, "BSD")) != NULL)
    return "_BSD_";

  return "_UNKNOWN_OS_";
}


int file_exists(char *fname) {
  FILE *p;
  
  if ((p = fopen(fname, "r"))) {
    fclose(p);
    return(1);
  }
  else
    return(0);
}

char *probe_ldflags(void) {
  static char buff[256];

  *buff = 0;

  if (file_exists("/usr/lib/libm.a"))
    strcat(buff, "-L/usr/lib -lm ");
  else if (file_exists("/usr/local/lib/libm.a"))
    strcat(buff, "-L/usr/local/lib -lm ");
  else if (file_exists("/lib/libm.a"))
    strcat(buff, "-L/lib/libm.a -lm ");

  if (file_exists("/usr/lib/libcrypt.a"))
    strcat(buff, "-L/usr/lib -lcrypt");
  else if (file_exists("/usr/local/lib/libcrypt.a"))
    strcat(buff, "-L/usr/local/lib -lcrypt");
  else if (file_exists("/lib/libcrypt.a"))
    strcat(buff, "-L/lib/libm.a -lcrypt");

  return(buff);    
}