Author: mladen.turk(a)jboss.com
Date: 2008-04-04 12:22:22 -0400 (Fri, 04 Apr 2008)
New Revision: 1520
Modified:
trunk/build/install/installer/main.c
Log:
Use mktemp from xtools and add eula page
Modified: trunk/build/install/installer/main.c
===================================================================
--- trunk/build/install/installer/main.c 2008-04-04 16:17:51 UTC (rev 1519)
+++ trunk/build/install/installer/main.c 2008-04-04 16:22:22 UTC (rev 1520)
@@ -38,6 +38,8 @@
#include "crypt.h"
#include "unzvers.h"
+#define DEF_WWIDTH 505
+#define DEF_WHEIGHT 360
#define MAX_CMDLINE 16384
#define IS_INVALID_HANDLE(x) (((x) == NULL || (x) == INVALID_HANDLE_VALUE))
@@ -69,7 +71,7 @@
static LPSTR szProgramName = NULL;
static LPSTR szProgramPath = NULL;
-static CHAR szTempPath[MAX_PATH] = { 0 };
+static LPSTR szTempPath = NULL;
static int c_errno_table[] = {
@@ -165,15 +167,16 @@
return c_errno_table[err];
}
-static void x_perror(const char *msg)
+static void x_perror(int err, const char *msg)
{
- int err = errno;
+ if (err == 0)
+ err = x_cerror(errno);
- errno = x_cerror(err);
-
#ifdef _CONSOLE
- if (!opt_Quiet)
+ if (!opt_Quiet) {
+ errno = err;
perror(msg);
+ }
if (opt_Verbose)
fprintf(stderr, "(%s): exit(%d)\n", GetProgramName(), err);
#else
@@ -196,7 +199,7 @@
void *ptr = calloc(1, len);
if (!ptr) {
- x_perror("Malloc");
+ x_perror(0, "Malloc");
}
return ptr;
}
@@ -245,6 +248,121 @@
return x_strdup(full);
}
+/*
+ * Replacement for the strncpy() function. We roll our
+ * own to implement these specific changes:
+ * (1) strncpy() doesn't always null terminate and we want it to.
+ * (2) strncpy() null fills, which is bogus, esp. when copy 8byte
+ * strings into 8k blocks.
+ * (3) Instead of returning the pointer to the beginning of
+ * the destination string, we return a pointer to the
+ * terminating '\0' to allow us to "check" for truncation
+ *
+ * x_strncpy() follows the same call structure as strncpy().
+ */
+static char *x_strncpy(char *d, const char *s, size_t l)
+{
+ char *dst, *end;
+ if (l == 0)
+ return d;
+ if (s == NULL) {
+ *d = '\0';
+ return d;
+ }
+ dst = d;
+ end = d + l - 1;
+
+ for (; dst < end; ++dst, ++s) {
+ if (!(*dst = *s))
+ return dst;
+ }
+
+ *dst = '\0'; /* always null terminate */
+ return dst;
+}
+
+static const unsigned char padchar[] =
+"0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
+static int randseed = 0;
+
+static char *x_mktemp(const char *pattern, int file)
+{
+ char path[MAX_PATH] = { 0 };
+ int randnum;
+ char pbuf[MAX_PATH];
+ register char *start, *trv, *suffp;
+
+ if (pattern)
+ x_strncpy(pbuf, pattern, MAX_PATH);
+ else
+ strcpy(pbuf, "_sx.XXXXXXXX");
+
+ if (GetTempPathA(MAX_PATH - strlen(pbuf) - 1, path) == 0) {
+ x_perror(0, "Temp Path");
+ return NULL;
+ }
+ strcat(path, pbuf);
+ for (trv = path; *trv; ++trv)
+ ;
+ suffp = trv;
+ --trv;
+ if (trv < path) {
+ x_perror(EINVAL, "Temp Path");
+ return NULL;
+ }
+
+ if (randseed == 0) {
+ randseed = (int)time(NULL);
+ srand(randseed);
+ }
+ /* Fill space with random characters */
+ while (*trv == 'X') {
+ randnum = rand() % (sizeof(padchar) - 1);
+ *trv-- = padchar[randnum];
+ }
+ start = trv + 1;
+
+ for (;;) {
+ if (access(path, 0)) {
+ if (errno == ENOENT) {
+ if (file) {
+ FILE *fp = fopen(path, "w");
+ if (!fp) {
+ x_perror(0, path);
+ return NULL;
+ }
+ fclose(fp);
+ }
+ else {
+ if (mkdir(path)) {
+ x_perror(0, path);
+ return NULL;
+ }
+ }
+ return x_strdup(path);
+ }
+ }
+ /* If we have a collision, cycle through the space of filenames */
+ for (trv = start;;) {
+ char *pad;
+ if (*trv == '\0' || trv == suffp) {
+ x_perror(ENOENT, "Temp Path");
+ return NULL;
+ }
+ pad = strchr((char *)padchar, *trv);
+ if (pad == NULL || !*++pad) {
+ *trv++ = padchar[0];
+ }
+ else {
+ *trv++ = *pad;
+ break;
+ }
+ }
+
+ }
+ return NULL;
+}
+
LPCSTR
GetProgramName()
{
@@ -546,21 +664,21 @@
}
static BOOL
-AcceptLicensePage()
+AcceptLicensePage(LPCSTR szPage)
{
HANDLE hHtml;
CHAR sBuf[MAX_PATH] = { 0 };
CHAR *retVal;
BOOL rv = FALSE;
- hHtml = DHTMLDialogInit(GetModuleHandle(NULL), "/HTML_LGPLMAIN");
+ hHtml = DHTMLDialogInit(GetModuleHandle(NULL), szPage);
if (IS_INVALID_HANDLE(hHtml))
return FALSE;
sprintf(sBuf, "%s", GetProgramName());
DHTMLDialogRun(NULL, hHtml,
GuiLoadResource(IDS_LICTITLE, 0),
- 505, 360, 0, INFINITE,
+ DEF_WWIDTH, DEF_WHEIGHT, 0, INFINITE,
sBuf);
retVal = DHTMLDialogResult(hHtml);
if (retVal && !strncmp(retVal, "OK", 2)) {
@@ -608,7 +726,7 @@
if (fp) {
if (retVal && *retVal) {
if (!strncmp(retVal, "OK", 2))
- rv = TRUE;
+ rv = TRUE;
fputs(retVal, fp);
}
else
@@ -627,8 +745,9 @@
if (cleanup++)
return;
- if (szTempPath[0])
+ if (szTempPath)
SXDeleteDirectory(szTempPath);
+ x_free(szTempPath);
GuiTerminate();
}
@@ -664,7 +783,7 @@
int nShowCmd)
{
#endif
- int i, r, ch;
+ int r, ch;
int ap = 1;
size_t l;
BOOL selectDest = TRUE;
@@ -678,21 +797,22 @@
LPSTR szHtmlTitle = NULL;
LPSTR szHtmlParams = NULL;
LPSTR szHtmlResult = NULL;
- DWORD dwHtmlWidth = 505;
- DWORD dwHtmlHeight = 360;
- DWORD dwTimeout = INFINITE;
+ DWORD dwHtmlWidth = DEF_WWIDTH;
+ DWORD dwHtmlHeight = DEF_WHEIGHT;
+ DWORD dwWinTimeout = INFINITE;
DWORD dwFlags = 0;
PROCESS_INFORMATION prInfo;
-
+ LPCSTR szEulaPage = "/HTML_EULAMAIN";
+
atexit(ExitCleanup);
if (!GuiInitialize()) {
exit(-1);
}
- while ((ch = getopt(__argc, __argv, "aAd:f:h:n:p:qQr:st:vVw:")) != EOF) {
+ while ((ch = getopt(__argc, __argv, "aAd:f:gh:n:p:qQr:st:vVw:")) != EOF) {
switch (ch) {
+ case 'A':
case 'a':
- case 'A':
GuiAboutBox(NULL);
r = 0;
goto cleanup;
@@ -712,6 +832,9 @@
opt_Verbose = TRUE;
#endif
break;
+ case 'g':
+ szEulaPage = "/HTML_LGPLMAIN";
+ break;
case 'd':
if (*optarg != '~') {
if (x_fullpath(optarg, szDest))
@@ -742,7 +865,7 @@
}
break;
case 't':
- dwTimeout = (DWORD)atoi(optarg);
+ dwWinTimeout = (DWORD)atoi(optarg);
break;
case 'w':
dwHtmlWidth = (DWORD)atoi(optarg);
@@ -762,14 +885,14 @@
if (szHtmlPage) {
if (!szHtmlTitle) {
r = EINVAL;
- goto cleanup;
+ goto cleanup;
}
if (RunCustomPage(szHtmlPage,
szHtmlTitle,
szHtmlParams,
dwHtmlWidth,
dwHtmlHeight,
- dwTimeout,
+ dwWinTimeout,
dwFlags,
szHtmlResult)) {
r = 0;
@@ -780,10 +903,11 @@
x_free(szHtmlTitle);
x_free(szHtmlParams);
x_free(szHtmlResult);
- goto cleanup;
+ goto cleanup;
}
+
/* Standard Install */
- if (!opt_Quiet && !AcceptLicensePage()) {
+ if (!opt_Quiet && !AcceptLicensePage(szEulaPage)) {
r = EPERM;
goto cleanup;
}
@@ -805,7 +929,7 @@
msg,
FALSE)) {
if (SXCreateDirectory(szDest)) {
- x_perror(szDest);
+ x_perror(0, szDest);
}
}
else {
@@ -814,7 +938,7 @@
}
}
else {
- x_perror(szDest);
+ x_perror(0, szDest);
}
}
if (GetSystemDirectory(szBuf, MAX_PATH - 20)) {
@@ -828,31 +952,12 @@
strcpy(szCmdExe, szBuf);
}
else {
- x_perror("System Directory");
+ x_perror(0, "System Directory");
}
- if (GetTempPathA(MAX_PATH - 20, szBuf) == 0) {
- x_perror("Temp Path");
+ if (!(szTempPath = x_mktemp(NULL, 0))) {
+ x_perror(EPERM, "Creating Temp directory");
}
- for (i = 0; i < 100; i++) {
- CHAR szTmp[MAX_PATH];
- if (GetTempFileName(szBuf, "_sx", _getpid(), szTmp) == 0) {
- x_perror("Temp File");
- }
- if (!mkdir(szTmp)) {
- strcpy(szTempPath, szTmp);
- break;
- }
- else {
- if (errno != EEXIST) {
- x_perror("Creating Temp directory");
- }
- }
- }
- if (!szTempPath[0]) {
- errno = EPERM;
- x_perror("Creating Temp directory");
- }
strcpy(szWorkDir, szTempPath);
strcat(szWorkDir, DIR_BATCH);
ppUnizpArgs[3] = szTempPath;
@@ -864,8 +969,7 @@
r = unzip(4, ppUnizpArgs);
if (r != 0) {
SetLastError(ERROR_INVALID_BLOCK);
- errno = EINVAL;
- x_perror("Uncompressing");
+ x_perror(EINVAL, "Uncompressing");
}
DESTROYGLOBALS();
szCmdLine = BuildCommandLine(szCmdExe,