Author: mladen.turk(a)jboss.com
Date: 2008-04-07 06:38:16 -0400 (Mon, 07 Apr 2008)
New Revision: 1524
Modified:
trunk/build/install/xtool/xtool.c
Log:
Add JDK/JRE detection tool
Modified: trunk/build/install/xtool/xtool.c
===================================================================
--- trunk/build/install/xtool/xtool.c 2008-04-07 09:11:13 UTC (rev 1523)
+++ trunk/build/install/xtool/xtool.c 2008-04-07 10:38:16 UTC (rev 1524)
@@ -512,12 +512,16 @@
char *cp, *argp, *res;
size_t saved_lengths[MAX_SAVED_LENGTHS];
int nargs = 0;
+ size_t len;
+ va_list adummy;
/* Pass one --- find length of required string */
- size_t len = strlen(str);
- va_list adummy;
+ if (!str)
+ return NULL;
+
+ len = strlen(str);
va_start(adummy, str);
saved_lengths[nargs++] = len;
while ((cp = va_arg(adummy, char *)) != NULL) {
@@ -1592,7 +1596,27 @@
return rv;
}
+static char *x_getenv(const char *str)
+{
+ wchar_t ibuf[256];
+ wchar_t ebuf[INFO_BUFFER_SIZE];
+ char *rv = NULL;
+ if (MultiByteToWideChar(CP_UTF8, 0, str, -1, ibuf, 256)) {
+ DWORD el = GetEnvironmentVariableW(ibuf, ebuf,
+ INFO_BUFFER_SIZE);
+ if (el > INFO_BUFFER_SIZE) {
+ if (xtrace)
+ warnx("expansion string to large %d", el);
+ }
+ else if (el) {
+ rv = x_strdup_utf8(ebuf);
+ }
+ }
+ return rv;
+}
+
+
/* This is the helper code to resolve late bound entry points
* missing from one or more releases of the Win32 API
*/
@@ -2404,8 +2428,8 @@
}
k->sam = reg_flags(sam);
- if ((i = RegOpenKeyExW(r, k->name, 0, k->sam, &k->key))
- != ERROR_SUCCESS) {
+ if ((i = RegOpenKeyExW(r, k->name, 0,
+ k->sam, &k->key)) != ERROR_SUCCESS) {
i = x_cerror(i);
x_free(k);
errno = i;
@@ -2446,8 +2470,8 @@
errno = EINVAL;
return errno;
}
- if ((i = RegOpenKeyExW(r, k.name, 0, k.sam, &k.key))
- != ERROR_SUCCESS) {
+ if ((i = RegOpenKeyExW(r, k.name, 0,
+ k.sam, &k.key)) != ERROR_SUCCESS) {
errno = x_cerror(i);
return errno;
}
@@ -3536,6 +3560,24 @@
return retval;
}
+static int prog_jdk_usage(int retval)
+{
+ fprintf(stderr, "Usage: %s [OPTION]... [PATH]\n", progname);
+ fprintf(stderr, "Find java SDK or JRE paths\n\n");
+ fprintf(stderr, " -e Use environment variable.\n");
+ fprintf(stderr, " -E STRING Use environment variable instead
JAVA_HOME.\n");
+ fprintf(stderr, " -j Find JRE insted of JDK.\n");
+ fprintf(stderr, " -d Find jvm.dll insted location.\n");
+ fprintf(stderr, " -s Favor server JRE version.\n");
+ fprintf(stderr, " -r STRING Registry access mode.\n");
+ fprintf(stderr, " a all access\n");
+ fprintf(stderr, " r read access\n");
+ fprintf(stderr, " 32 operate on the 32-bit registry
view\n");
+ fprintf(stderr, " 64 operate on the 64-bit registry
view\n\n");
+ print_stdusage();
+ return retval;
+}
+
/*
* ---------------------------------------------------------------------
* end of programs usage
@@ -4686,7 +4728,7 @@
if (!GuiInitialize()) {
return x_perror(0, "Windows GUI");
}
- while ((ch = getopt(argc, argv, "g:n:o:p:st:T:qhqv", 1)) != EOF) {
+ while ((ch = getopt(argc, argv, "g:n:o:p:st:T:qhqv", 0)) != EOF) {
switch (ch) {
case '.':
if (!stricmp(optarg, "verbose"))
@@ -4821,7 +4863,7 @@
int rt = REG_NONE;
x_registry_t *reg = NULL;
- while ((ch = getopt(argc, argv, "ad:f:m:r:t:hqvV", 1)) != EOF) {
+ while ((ch = getopt(argc, argv, "ad:f:m:r:t:hqvV", 0)) != EOF) {
switch (ch) {
case '.':
if (!stricmp(optarg, "verbose"))
@@ -5011,7 +5053,8 @@
int icon = MB_ICONQUESTION;
int modal = MB_TASKMODAL;
char *p, *msg = NULL;
- while ((ch = getopt(argc, argv, "i:st:hqvV", 1)) != EOF) {
+
+ while ((ch = getopt(argc, argv, "i:st:hqvV", 0)) != EOF) {
switch (ch) {
case '.':
if (!stricmp(optarg, "verbose"))
@@ -5125,6 +5168,235 @@
return rv;
}
+static const char *jvm_paths[] = {
+ "\\server\\jvm.dll",
+ "\\client\\jvm.dll",
+ "\\jrockit\\jvm.dll",
+ "\\server\\jvm.dll",
+ NULL
+};
+
+static const char *jdk_keys[] = {
+ "HKLM\\SOFTWARE\\JavaSoft\\Java Development Kit",
+ "HKLM\\SOFTWARE\\JRockit\\Java Development Kit",
+ NULL
+};
+
+static const char *jre_keys[] = {
+ "HKLM\\SOFTWARE\\JavaSoft\\Java Runtime Environment",
+ "HKLM\\SOFTWARE\\JRockit\\Java Runtime Environment",
+ NULL
+};
+
+static int prog_jdk(int argc, const char **argv, const char **env)
+{
+ int i, ch, rv = 0;
+ int useenv = 0;
+ int server = 0;
+ int getjre = 0;
+ int jredll = 0;
+ char *penv = NULL;
+ char *home = NULL;
+ char *jred = NULL;
+ char *jbin = NULL;
+ char *jreh = NULL;
+ char *regm = NULL;
+
+ while ((ch = getopt(argc, argv, "deE:r:jshqvV", 0)) != EOF) {
+ switch (ch) {
+ case '.':
+ if (!stricmp(optarg, "verbose"))
+ xtrace = 1;
+ else if (!stricmp(optarg, "version"))
+ return print_banner(1);
+ else if (!stricmp(optarg, "help"))
+ return prog_jdk_usage(0);
+ else
+ return prog_jdk_usage(EINVAL);
+ break;
+ case 'v':
+ xtrace = 1;
+ break;
+ case 'V':
+ xtrace = 9;
+ break;
+ case 'q':
+ xquiet = 1;
+ break;
+ case 'h':
+ return prog_jdk_usage(0);
+ break;
+ case 'e':
+ useenv = 1;
+ break;
+ case 'E':
+ useenv = 1;
+ penv = x_strdup(optarg);
+ break;
+ case 'r':
+ regm = x_strdup(optarg);
+ break;
+ case 's':
+ server = 1;
+ break;
+ case 'j':
+ getjre = 1;
+ break;
+ case 'd':
+ jredll = 1;
+ break;
+ case '?':
+ case ':':
+ return EINVAL;
+ break;
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ if (argc > 0) {
+ home = x_fullpath(argv[0]);
+ printf("Home is %s\n", home);
+ }
+ if (useenv) {
+ const char *senv = NULL;
+ if (home) {
+ if (getjre) {
+ jreh = x_strdup(home);
+ }
+ }
+ else if (penv) {
+ senv = penv;
+ home = x_getenv(senv);
+ }
+ else if (getjre) {
+ senv = "JRE_HOME";
+ if (!(home = x_getenv(senv))) {
+ senv = "JAVA_HOME";
+ home = x_getenv(senv);
+ if (home) {
+ size_t l = strlen(home);
+ if (home[l - 1] == '\\' ||
+ home[l - 1] == '/')
+ home[l - 1] = '\0';
+ jreh = x_strvcat(home, "\\jre", NULL);
+ x_free(home);
+ home = x_strdup(jreh);
+ }
+ }
+ else {
+ jreh = x_strdup(home);
+ }
+ }
+ else {
+ senv = "JAVA_HOME";
+ home = x_getenv(senv);
+ }
+ if (home) {
+ size_t l = strlen(home);
+ if (home[l - 1] == '\\' ||
+ home[l - 1] == '/')
+ home[l - 1] = '\0';
+ jbin = x_strvcat(home, "\\bin", NULL);
+ if (!x_fattrib(jbin)) {
+ rv = x_perror(ENOTDIR, jbin);
+ goto cleanup;
+ }
+ if (!jreh)
+ jreh = x_strvcat(home, "\\jre", NULL);
+ if (!x_fattrib(jreh)) {
+ rv = x_perror(ENOTDIR, jreh);
+ goto cleanup;
+ }
+ }
+ else {
+ rv = x_perror(ENOENT, senv);
+ goto cleanup;
+ }
+ if (xtrace > 1) {
+ warnx("JDK %s", home);
+ warnx("JRE %s", jreh);
+ warnx("BIN %s", jbin);
+ }
+ }
+ else {
+ x_registry_t *reg = NULL;
+ const char **keys;
+ if (getjre)
+ keys = jre_keys;
+ else
+ keys = jdk_keys;
+ for (i = 0; keys[i]; i++) {
+ if ((reg = reg_open(keys[i], regm ? regm : "r"))) {
+ char *cv = reg_value(reg, "CurrentVersion", 0);
+ if (cv) {
+ char *ck = x_strvcat(keys[i], "\\", cv, NULL);
+ reg_close(reg);
+ if ((reg = reg_open(ck, regm ? regm : "r"))) {
+ home = reg_value(reg, "JavaHome", 0);
+ if (home) {
+ size_t l = strlen(home);
+ if (home[l - 1] == '\\' ||
+ home[l - 1] == '/')
+ home[l - 1] = '\0';
+ if (getjre) {
+ jreh = x_strdup(home);
+ jred = reg_value(reg, "RuntimeLib", 0);
+ }
+ else {
+ jreh = x_strvcat(home, "\\jre", NULL);
+ jbin = x_strvcat(jreh, "\\bin", NULL);
+ }
+ }
+ }
+ x_free(ck);
+ }
+ x_free(cv);
+ }
+ reg_close(reg);
+ if (home)
+ break;
+ }
+ if (!home) {
+ rv = x_perror(ENOENT, "JavaHome Registry search");
+ goto cleanup;
+ }
+ }
+ if (jredll && jbin) {
+ if (server)
+ i = 0;
+ else
+ i = 1;
+ for (; jvm_paths[i]; i++) {
+ jred = x_strvcat(jbin, jvm_paths[i], NULL);
+ if (x_fattrib(jred))
+ break;
+ x_free(jred);
+ jred = NULL;
+ }
+ if (!jred) {
+ rv = x_perror(ENOENT, "jvm.dll");
+ goto cleanup;
+ }
+ }
+
+cleanup:
+ if (rv == 0) {
+ if (jred) {
+ fputs(jred, stdout);
+ }
+ else if (home)
+ fputs(home, stdout);
+ fflush(stdout);
+ }
+ x_free(regm);
+ x_free(jreh);
+ x_free(jbin);
+ x_free(jred);
+ x_free(home);
+ x_free(penv);
+ return rv;
+}
+
/*
* ---------------------------------------------------------------------
* end of programs
@@ -5149,6 +5421,7 @@
{ "html", prog_html },
{ "reg", prog_reg },
{ "msg", prog_msg },
+ { "jdk", prog_jdk },
{ NULL, NULL }
};