/*
 * Copyright 1988, 1989, 1990, 1991 Massachusetts Institute of Technology
 */

#include <stdio.h>
#include <ctype.h>
#include <sys/file.h>
#include "gconfig.h"

main(argc, argv)
     int argc;
     char **argv;
{
  FILE *fp, *dirfile, *cur_file, *temp_file;
  OptionLine *optionlist = (OptionLine *)NULL;
  OptionLine *temp_option, *prev_option = (OptionLine *)NULL;
  char temp[1024], *cur_point, cur_dir[1024], cur_name[1024], temp_name[1024];
  char conffile[1024];
  int temp_len, cur_place;
  /* TOP hack */
  int nsubs = 0;
  int i;
  char top_dir[1024];

  if (argc == 1) strcpy(conffile, GCONFFILE);
  else {
    if (strcmp(argv[1], "-help") == 0) {
      fprintf(stderr, "usage: gconfig [configuration file/-help]\n");
      exit (0);
    }
    else strcpy(conffile, argv[1]);
  }

  fp = fopen(conffile, "r");
  if (fp == (FILE *)NULL) {
    fprintf(stderr, "gconfig: Unable to open configuration file: %s\n",
	    conffile);
    exit(1);
  }
  while(!feof(fp)) {
    if (fgets(temp, 1024, fp) == NULL) break;
    if (temp[0] == '#' || temp[0] == ' ' || temp[0] == '\0' ||
	!isalpha(temp[0])) continue;
    temp_option = (OptionLine *)malloc(sizeof(OptionLine));
    if (temp_option == (OptionLine *)NULL) {
      fprintf(stderr, "gconfig: failed OptionLine malloc.\n");
      exit(2);
    }
    temp_option->prev = prev_option;
    if (prev_option)
      prev_option->next = temp_option;
    if (!optionlist)
      optionlist = temp_option;
    prev_option = temp_option;
    temp_len = strlen(temp);
    temp_option->option_text = (char *)malloc((temp_len + 1) * sizeof(char));
    if (temp_option->option_text == (char *)NULL) {
      fprintf(stderr, "gconfig: failed option_text malloc.\n");
      exit(3);
    }
    strcpy(temp_option->option_text, temp);
    cur_point = temp;
    cur_place = 0;
    temp_option->macro_name[0] = '\0';
    while (cur_point && isalnum(*cur_point)) {
      temp_option->macro_name[cur_place++] = *cur_point;
      cur_point++;
    }
#ifdef SHOWPARSE
    printf("macro_name = %s\n",temp_option->macro_name);
    printf("option_text = %s",temp_option->option_text);
#endif /* SHOWPARSE */
  }
#ifdef SHOWPARSE
  temp_option = optionlist;
  while (temp_option) {
    printf("macro_name = %s\n",temp_option->macro_name);
    printf("option_text = %s",temp_option->option_text);
    temp_option = temp_option->next;
  }
#endif /* SHOWPARSE */
  fclose(fp);
  dirfile = fopen(GCONFDIRS, "r");
  if (dirfile == (FILE *)NULL) {
    fprintf(stderr, "gconfig: Unable to open directory list file: %s\n",
	    GCONFDIRS);
    exit(4);
  }
  printf("Using %s as directory list file\n",GCONFDIRS);
  printf("Working on directories:\n");
  while (!feof(dirfile)) {
    if (fgets(temp, 1024, dirfile) == NULL) break;
    sscanf(temp, "%s", cur_dir);

    printf("   %s\n", cur_dir);
    fflush(stdout);

    /* TOP hack */
    for (i = 0, nsubs = 0; i < strlen(cur_dir); i++)
      if (cur_dir[i] == '/')
	++nsubs;
    top_dir[0] = '\0';
    for (i=0;i< nsubs; i++) {
      strcat(top_dir, "..");
      if ((i+1) < nsubs)
	strcat (top_dir, "/");
    }
      
    sprintf(cur_name, "%s/makefile", cur_dir);
    cur_file = fopen(cur_name, "r");
    if (cur_file == (FILE *)NULL) {
      sprintf(cur_name, "%s/Makefile", cur_dir);
      cur_file = fopen(cur_name, "r");
    }
    if (cur_file == (FILE *)NULL) {
      fprintf(stderr, 
	      "gconfig: Unable to open description file in %s, skipping.\n",
	      cur_dir);
      break;
    }
    sprintf(temp_name, "%s/tmp.%d", cur_dir, getpid());
    temp_file = fopen(temp_name, "w");
    if (temp_file == (FILE *)NULL) {
      fprintf(stderr, "gconfig: Unable to open temporary file %s\n",
	      temp_name);
      exit(5);
    }
    fprintf(temp_file, PRESTRING, conffile);
    fprintf(temp_file, "TOP = %s\n", top_dir);
    temp_option = optionlist;
    while (temp_option != NULL) {
	fputs(temp_option->option_text, temp_file);
	temp_option = temp_option->next;
    }
    fputs(POSTSTRING, temp_file);

    while(!feof(cur_file)) {
      if (fgets(temp, 1024, cur_file) == NULL) break;
	
      temp_option = optionlist;
      while (temp_option != NULL) {
	if (!strncmp(temp_option->macro_name, temp, 
		     strlen(temp_option->macro_name))) break;
	if (!strncmp(PRESTRING, temp, 20)) break;
	if (!strncmp(POSTSTRING, temp, strlen(POSTSTRING))) break;
	if (!strncmp("TOP =", temp, 5)) break;
	temp_option = temp_option->next;
      }
      if (!temp_option) fputs(temp, temp_file);
/*      else fputs(temp_option->option_text, temp_file);*/
    }
    fclose(cur_file);
    fclose(temp_file);
    sprintf(temp, "%s.pre", cur_name);
    if (grename(cur_name, temp) == -1) {
      fprintf(stderr, "Failed to rename %s to %s\n", cur_name, temp);
    }
    else {
      if (grename(temp_name, cur_name) == 1) {
	fprintf(stderr, "Failed to rename %s to %s\n", cur_name, temp);
      }
    }
  }
  fclose(dirfile);

  printf("  done.\n");

  exit(0);
}

int grename(fromfile, tofile)
     char *fromfile, *tofile;
{
  int res;
  res = access(tofile, F_OK);
  if (res == 0) {
    if (unlink(tofile) == -1) {
      perror("unlink");
      return -1;
    }
  }
    
  if (link(fromfile, tofile) == -1) {
    perror("link");
    return -1;
  }
  return(unlink(fromfile));
}


