/*
 * At this point the property list looks like this :
 *
 *       entry <-- userHead
 *         |
 *         V
 *       entry
 *         |
 *         V
 *     (more entries)
 *         |
 *         V
 *        NULL
 *
 * We want to store everything between userHead and installHead (i.e. user
 * specific properties) in the user properties file.
 */
void storePropertyFile(char *filename, PropertyFileEntry* userHead) {
  PropertyFileEntry *entry;
  FILE *fp = NULL;
  int index;
  char buf[4096], *dir, *p;

  /* create directories if they don't exist */
  dir = strdup(filename);
  p = strrchr(dir, FILE_SEPARATOR);
  if (p != NULL) {
    if (p > dir && *(p-1) != ':') *p = 0;
    else *(p+1) = 0;
    recursive_create_directory(dir);
  }
  free(dir);

  fp = fopen(filename, "wb");
  if (!fp) return;

  for (entry = userHead; entry != NULL; entry = entry->next) {
    if ((index = GetJREIndex(entry->key)) == -1 ||
	isJRERegistered(index) == 0 ||
	isJREConfirmed(index) == 1) {
      /* if it's a regular (non JRE) entry, or an unregistered JRE, or a
	 confirmed JRE, write it to the file */
      if (entry->key != NULL && entry->value != NULL) {
	int i = 0;
	char *p = entry->key;
	char *output = NULL;
	while (*p != 0) {
	  if (*p == '\\') {
	    buf[i++] = '\\';
	  }
	  buf[i++] = *p++;
	}
	buf[i++] = '=';
	p = entry->value;
	while (*p != 0) {
	  if (*p == '\\') {
	    buf[i++] = '\\';
	  }
	  buf[i++] = *p++;
	}
	buf[i] = 0;
	strcat(buf, "\n");
	output = sysMBCSToSeqUnicode(buf); 
	fwrite(output, 1, strlen(output), fp); 
	free(output); 
      }
    }
  }
  fclose(fp);
}
/*
 * Get a list of all the JREs from the registry.  For each JRE in this
 * list, 1. add it to the config list if it's not already there, and
 * 2. mark it as "confirmed" in the config list.  Then, remove all
 * unconfirmed registered JREs from the config list.
 */
int RescanJREs(int verbose) {
  JREDescription reg_list[255];
  int nJREs = 0;
  int i, j;
  char *path;
  char *osname;
  char *osarch;
  int return_value = FALSE;
  int haveRegistry = 1;

  memset(reg_list, 0, sizeof(JREDescription) * 255);
  sysGetRegistryJREs(reg_list, &nJREs);
 
  /**
   * On Unix platforms, reg_list[i].product_version == NULL,
   * because sysGetRegistryJREs Unix implementation fakes a registry entry
   */
  if(nJREs==0) {
      haveRegistry = 0;
  } else if(nJREs==1) {
      haveRegistry = reg_list[0].product_version != NULL;
  }
 
  for (i = 0; i < nJREs; i++) {
    /* check if the JRE is already in the list */
    int match = 0;
    /* compare path in Unicode format */
    char *reg_path = sysMBCSToSeqUnicode(reg_list[i].path);
    if(!haveRegistry) {
        // earmark the system JRE in case we have no registry
        nonRegisteredSystemJRE = strdup(reg_path);
    }

    for (j = 0; j < nIndices; j++) {
      int index = indexArray[j].index;
      path = GetJREJavaCmd(index);
      osname = GetJREOsName(index);
      osarch = GetJREOsArch(index);    
      if (path != NULL && sysStrCaseCmp(path, reg_path) == 0) {
        if(verbose) {
            printf("test %d: path:<%s> regPath<%s> match \n", index, path, reg_path);
        }
        /* make sure osname and osarch matches too, if they are specified */
        if (osname == NULL || (osname != NULL && sysStrCaseCmp(osname, reg_list[i].osname) == 0)) {
          if(verbose) {
              printf("test %d: osname:<%s> regOsname<%s> match \n", index, 
                (osname==NULL)?"NULL":osname, (reg_list[i].osname==NULL)?"NULL":reg_list[i].osname);
          }
          /* only compare osarch if osname is SunOS */
          if (osarch == NULL || (osname != NULL && strcmp(osname, "SunOS") != 0) || (osarch != NULL && sysStrCaseCmp(osarch, reg_list[i].osarch) == 0)) {
            if(verbose) {
                printf("test %d: osarch:<%s> regOsarch<%s> match \n", index, osarch, 
                    (reg_list[i].osarch==NULL)?"NULL":reg_list[i].osarch);
            }
            /**
             * it matches.  mark it confirmed and registered 
             * now match only if version is matching. 
	     *
	     * since product version may contain milestones, e.g. 1.6.0_11-beta
	     * compare only the version string without milestone.
             */
            if ( !haveRegistry ||
                 ( GetJREProductVersion(index) != NULL && 
                   reg_list[i].product_version != NULL &&
                   sysStrNCaseCmp(GetJREProductVersion(index), 
				  reg_list[i].product_version,
				  strlen(reg_list[i].product_version)) == 0) ) 
            {
                if(verbose) {
                    printf("test %d: productV:<%s> regProductV<%s> match \n", index, 
                        (GetJREProductVersion(index)==NULL)?"NULL":GetJREProductVersion(index), 
                        (reg_list[i].product_version==NULL)?"NULL":reg_list[i].product_version);
                }
                match = 1;
                indexArray[j].confirmed = 1;
                if (!isJRERegistered(index) && haveRegistry) {
                    SetJRERegistered(index, "true");
                    return_value = TRUE;
                }
            } else if(verbose) {
                printf("test %d: productV:<%s> regProductV<%s> doesn't match \n", index, 
                        (GetJREProductVersion(index)==NULL)?"NULL":GetJREProductVersion(index), 
                        (reg_list[i].product_version==NULL)?"NULL":reg_list[i].product_version);
            }
          } else if(verbose) {
            printf("test %d: osarch:<%s> regOsarch<%s> doesn't match \n", index, 
                    (osarch==NULL)?"NULL":osarch,
                    (reg_list[i].osarch==NULL)?"NULL":reg_list[i].osarch);
          }
        } else if(verbose) {
          printf("test %d: osname:<%s> regOsname<%s> doesn't match \n", index, 
                    (osname==NULL)?"NULL":osname,
                    (reg_list[i].osname==NULL)?"NULL":reg_list[i].osname);
        }
        /* keep going here - may be more with same path */
      } else if(verbose) {
          printf("test %d: path:<%s> regPath<%s> doesn't match\n", index, 
                    (path==NULL)?"NULL":path,
                    (reg_path==NULL)?"NULL":reg_path);
      }
    }

    /* if there was no match we need to add the JRE to the list */
    if (match == 0) {
      int new = getUniqueIndexArrayIndex();
      UpdateJREInfo(&reg_list[i]);

      /* fix for 4813021 */
      /* check to make sure all the info exist before adding */
      if (!(reg_list[i].platform_version == NULL ||
          reg_list[i].product_version == NULL ||
          reg_list[i].href == NULL ||
          reg_list[i].osname == NULL ||
          reg_list[i].osarch == NULL)) {

        indexArray[nIndices].index = new;
        indexArray[nIndices++].confirmed = 1;
        SetJREPlatformVersion(new, reg_list[i].platform_version);
        SetJREProductVersion(new, reg_list[i].product_version);
        SetJRELocation(new, reg_list[i].href);
        SetJREJavaCmd(new, reg_list[i].path);
        SetJREOsName(new, reg_list[i].osname);
        SetJREOsArch(new, reg_list[i].osarch);
        SetJREEnabled(new, "true");
        if ( haveRegistry ) {
            SetJRERegistered(new, "true");
        } else {
            SetJRERegistered(new, "false");
        }
        return_value = TRUE;
        if(verbose) {
            printf("test add new %d: regPath<%s>, registered: %d\n", new, 
                (reg_list[i].path==NULL)?"NULL":reg_list[i].path,
                isJRERegistered(new));
        }
      }