void setextlibpath(const char *name, const char *val) { int flag; char *p, *cp; if (!strcmp(name, "BEGINLIBPATH")) flag = BEGIN_LIBPATH; else if (!strcmp(name, "ENDLIBPATH")) flag = END_LIBPATH; else if (!strcmp(name, "LIBPATHSTRICT")) flag = LIBPATHSTRICT; else return; /* convert slashes to backslashes */ strdupx(cp, val, ATEMP); for (p = cp; *p; p++) { if (*p == '/') *p = '\\'; } DosSetExtLIBPATH(cp, flag); afree(cp, ATEMP); }
int main(int argc, char **argv, char **envp) { int i; #if defined(_MSC_VER) intptr_t rc; #endif FILE *pStdErr = stderr; FILE *pStdOut = stdout; /* * Parse arguments. */ if (argc <= 1) return usage(pStdErr, name(argv[0])); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { int fd; int fdOpened; int fOpen; char *psz = &argv[i][1]; if (*psz == '-') { /* '--' ? */ if (!psz[1]) { i++; break; } /* convert to short. */ if (!strcmp(psz, "-help")) psz = "h"; else if (!strcmp(psz, "-version")) psz = "V"; else if (!strcmp(psz, "-env")) psz = "E"; else if (!strcmp(psz, "-chdir")) psz = "C"; else if (!strcmp(psz, "-zap-env")) psz = "Z"; else if (!strcmp(psz, "-close")) psz = "c"; } /* * Deal with the obligatory help and version switches first. */ if (*psz == 'h') { usage(pStdOut, name(argv[0])); return 0; } if (*psz == 'V') { printf("kmk_redirect - kBuild version %d.%d.%d (r%u)\n" "Copyright (C) 2007-2009 knut st. osmundsen\n", KBUILD_VERSION_MAJOR, KBUILD_VERSION_MINOR, KBUILD_VERSION_PATCH, KBUILD_SVN_REV); return 0; } /* * Environment switch? */ if (*psz == 'E') { psz++; if (*psz == ':' || *psz == '=') psz++; else { if (i + 1 >= argc) { fprintf(pStdErr, "%s: syntax error: no argument for %s\n", name(argv[0]), argv[i]); return 1; } psz = argv[++i]; } #ifdef __OS2__ if ( !strncmp(psz, "BEGINLIBPATH=", sizeof("BEGINLIBPATH=") - 1) || !strncmp(psz, "ENDLIBPATH=", sizeof("ENDLIBPATH=") - 1) || !strncmp(psz, "LIBPATHSTRICT=", sizeof("LIBPATHSTRICT=") - 1)) { ULONG ulVar = *psz == 'B' ? BEGIN_LIBPATH : *psz == 'E' ? END_LIBPATH : LIBPATHSTRICT; const char *pszVal = strchr(psz, '=') + 1; APIRET rc = DosSetExtLIBPATH(pszVal, ulVar); if (rc) { fprintf(pStdErr, "%s: error: DosSetExtLibPath(\"%s\", %.*s (%lu)): %lu\n", name(argv[0]), pszVal, pszVal - psz - 1, psz, ulVar, rc); return 1; } } else #endif /* __OS2__ */ if (putenv(psz)) { fprintf(pStdErr, "%s: error: putenv(\"%s\"): %s\n", name(argv[0]), psz, strerror(errno)); return 1; } continue; } /* * Change directory switch? */ if (*psz == 'C') { psz++; if (*psz == ':' || *psz == '=') psz++; else { if (i + 1 >= argc) { fprintf(pStdErr, "%s: syntax error: no argument for %s\n", name(argv[0]), argv[i]); return 1; } psz = argv[++i]; } if (!chdir(psz)) continue; #ifdef _MSC_VER { /* drop trailing slash if any. */ size_t cch = strlen(psz); if ( cch > 2 && (psz[cch - 1] == '/' || psz[cch - 1] == '\\') && psz[cch - 1] != ':') { int rc2; char *pszCopy = strdup(psz); do pszCopy[--cch] = '\0'; while ( cch > 2 && (pszCopy[cch - 1] == '/' || pszCopy[cch - 1] == '\\') && pszCopy[cch - 1] != ':'); rc2 = chdir(pszCopy); free(pszCopy); if (!rc2) continue; } } #endif fprintf(pStdErr, "%s: error: chdir(\"%s\"): %s\n", name(argv[0]), psz, strerror(errno)); return 1; } /* * Zap environment switch? * This is a bit of a hack. */ if (*psz == 'Z') { unsigned j = 0; while (envp[j] != NULL) j++; while (j-- > 0) { char *pszEqual = strchr(envp[j], '='); char *pszCopy; if (pszEqual) *pszEqual = '\0'; pszCopy = strdup(envp[j]); if (pszEqual) *pszEqual = '='; #if defined(_MSC_VER) || defined(__OS2__) putenv(pszCopy); #else unsetenv(pszCopy); #endif free(pszCopy); } continue; } /* * Close the specified file descriptor (no stderr/out/in aliases). */ if (*psz == 'c') { psz++; if (!*psz) { i++; if (i >= argc) { fprintf(pStdErr, "%s: syntax error: missing filename argument.\n", name(argv[0])); return 1; } psz = argv[i]; } fd = (int)strtol(psz, &psz, 0); if (!fd || *psz) { fprintf(pStdErr, "%s: error: failed to convert '%s' to a number\n", name(argv[0]), argv[i]); return 1; } if (fd < 0) { fprintf(pStdErr, "%s: error: negative fd %d (%s)\n", name(argv[0]), fd, argv[i]); return 1; } /** @todo deal with stderr */ close(fd); continue; } /* * Parse a file descriptor argument. */ /* mode */ switch (*psz) { case 'r': psz++; if (*psz == '+') { fOpen = O_RDWR; psz++; } else fOpen = O_RDONLY; break; case 'w': psz++; if (*psz == '+') { psz++; fOpen = O_RDWR | O_CREAT | O_TRUNC; } else fOpen = O_WRONLY | O_CREAT | O_TRUNC; break; case 'a': psz++; if (*psz == '+') { psz++; fOpen = O_RDWR | O_CREAT | O_APPEND; } else fOpen = O_WRONLY | O_CREAT | O_APPEND; break; case 'i': /* make sure stdin is read-only. */ fOpen = O_RDONLY; break; case '+': fprintf(pStdErr, "%s: syntax error: Unexpected '+' in '%s'\n", name(argv[0]), argv[i]); return 1; default: fOpen = O_RDWR | O_CREAT | O_TRUNC; break; } /* binary / text modifiers */ switch (*psz) { case 'b': #ifdef O_BINARY fOpen |= O_BINARY; #endif psz++; break; case 't': #ifdef O_TEXT fOpen |= O_TEXT; #endif psz++; break; default: #ifdef O_BINARY fOpen |= O_BINARY; #endif break; } /* convert to file descriptor number */ switch (*psz) { case 'i': fd = 0; psz++; break; case 'o': fd = 1; psz++; break; case 'e': fd = 2; psz++; break; case '0': if (!psz[1]) { fd = 0; psz++; break; } case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': fd = (int)strtol(psz, &psz, 0); if (!fd) { fprintf(pStdErr, "%s: error: failed to convert '%s' to a number\n", name(argv[0]), argv[i]); return 1; } if (fd < 0) { fprintf(pStdErr, "%s: error: negative fd %d (%s)\n", name(argv[0]), fd, argv[i]); return 1; } break; /* * Invalid argument. */ default: fprintf(pStdErr, "%s: error: failed to convert '%s' ('%s') to a file descriptor\n", name(argv[0]), psz, argv[i]); return 1; } /* * Check for the filename. */ if (*psz) { if (*psz != ':' && *psz != '=') { fprintf(pStdErr, "%s: syntax error: characters following the file descriptor: '%s' ('%s')\n", name(argv[0]), psz, argv[i]); return 1; } psz++; } else { i++; if (i >= argc) { fprintf(pStdErr, "%s: syntax error: missing filename argument.\n", name(argv[0])); return 1; } psz = argv[i]; } /* * Setup the redirection. */ if (fd == fileno(pStdErr)) { /* * Move stderr to a new location, making it close on exec. * If pStdOut has already teamed up with pStdErr, update it too. */ FILE *pNew; fdOpened = dup(fileno(pStdErr)); if (fdOpened == -1) { fprintf(pStdErr, "%s: error: failed to dup stderr (%d): %s\n", name(argv[0]), fileno(pStdErr), strerror(errno)); return 1; } #ifdef _MSC_VER /** @todo figure out how to make the handle close-on-exec. We'll simply close it for now. * SetHandleInformation + set FNOINHERIT in CRT. */ #else if (fcntl(fdOpened, F_SETFD, FD_CLOEXEC) == -1) { fprintf(pStdErr, "%s: error: failed to make stderr (%d) close-on-exec: %s\n", name(argv[0]), fdOpened, strerror(errno)); return 1; } #endif pNew = fdopen(fdOpened, "w"); if (!pNew) { fprintf(pStdErr, "%s: error: failed to fdopen the new stderr (%d): %s\n", name(argv[0]), fdOpened, strerror(errno)); return 1; } if (pStdOut == pStdErr) pStdOut = pNew; pStdErr = pNew; } else if (fd == 1 && pStdOut != pStdErr) pStdOut = pStdErr; /* * Close and open the new file descriptor. */ close(fd); #if defined(_MSC_VER) if (!strcmp(psz, "/dev/null")) psz = (char *)"nul"; #endif fdOpened = open(psz, fOpen, 0666); if (fdOpened == -1) { fprintf(pStdErr, "%s: error: failed to open '%s' as %d: %s\n", name(argv[0]), psz, fd, strerror(errno)); return 1; } if (fdOpened != fd) { /* move it (dup2 returns 0 on MSC). */ if (dup2(fdOpened, fd) == -1) { fprintf(pStdErr, "%s: error: failed to dup '%s' as %d: %s\n", name(argv[0]), psz, fd, strerror(errno)); return 1; } close(fdOpened); } } else { fprintf(pStdErr, "%s: syntax error: Invalid argument '%s'.\n", name(argv[0]), argv[i]); return usage(pStdErr, name(argv[0])); } } /* * Make sure there's something to execute. */ if (i >= argc) { fprintf(pStdErr, "%s: syntax error: nothing to execute!\n", name(argv[0])); return usage(pStdErr, name(argv[0])); } #if defined(_MSC_VER) if (fileno(pStdErr) != 2) /* no close-on-exec flag on windows */ { fclose(pStdErr); pStdErr = NULL; } /** @todo * We'll have to find the '--' in the commandline and pass that * on to CreateProcess or spawn. Otherwise, the argument qouting * is gonna be messed up. */ rc = _spawnvp(_P_WAIT, argv[i], &argv[i]); if (rc == -1 && pStdErr) { fprintf(pStdErr, "%s: error: _spawnvp(_P_WAIT, \"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno)); rc = 1; } return rc; #else execvp(argv[i], &argv[i]); fprintf(pStdErr, "%s: error: _execvp(_P_WAIT, \"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno)); return 1; #endif }
int main(int argc, char *argv[]) { int do_load,do_unload,do_help,do_path; do_load=do_unload=do_help=do_path=0; char basepath[CCHMAXPATH]; if (argc == 1) do_help = 1; else { for (int i=1; i < argc; i++) { if (strnicmp(argv[i],"-l", 2) == 0) do_load = 1; else if (strnicmp(argv[i],"-u", 2) == 0) do_unload = 1; else if (strnicmp(argv[i],"-h", 2) == 0) do_help = 1; else if (strnicmp(argv[i],"-?", 2) == 0) do_help = 1; else if (strnicmp(argv[i],"-p", 2) == 0) { if (argc > i+1) { strcpy(basepath, argv[i+1]); if (basepath[strlen(basepath)] !='\\') { strcat(basepath, "\\"); } do_path = 1; } else { do_help = 1; } } } } if (do_help) { printf("%s for OS/2 preloader\n"\ "\n"\ "Usage: %s [-h] [-l | -u] [-p path]\n"\ " -h display this help\n"\ " -l load modules\n"\ " -u unload modules\n"\ " -p specify fully qualified path to directory where EXE is located\n", MOZ_APP_DISPLAYNAME, argv[0]); return(1); } if (do_unload) { HEV hev = NULLHANDLE; if (DosOpenEventSem(SEMNAME, &hev) == NO_ERROR) { if (DosPostEventSem(hev) == NO_ERROR) { if (DosCloseEventSem(hev) == NO_ERROR) { return(0); } } } printf("%s for OS/2 preloader is not running\n", MOZ_APP_DISPLAYNAME); return(1); } if (do_path == 0) { /* Get the name of this EXE and use its location as the path */ HMODULE hmodule; DosQueryModFromEIP(&hmodule, NULL, 0, NULL, NULL, (ULONG)ForceModuleLoad); DosQueryModuleName(hmodule, CCHMAXPATH, basepath); char *pchar = strrchr(basepath, '\\'); pchar++; *pchar = '\0'; } if (do_load) { ULONG ulCurMaxFH; LONG ulReqFH = 40; DosSetRelMaxFH(&ulReqFH, &ulCurMaxFH); HEV hev; if (DosCreateEventSem(SEMNAME, &hev, DC_SEM_SHARED, FALSE) != NO_ERROR) { printf("%s for OS/2 preloader is already running\n", MOZ_APP_DISPLAYNAME); return(1); } /* Add directory where EXE is located to LIBPATH */ DosSetExtLIBPATH(basepath, BEGIN_LIBPATH); /* loop through list loading named modules */ char filepath[CCHMAXPATH]; HMODULE hmod; int i = 0, nummodules = 0; while (bindir[i]) { strcpy(filepath,basepath); strcat(filepath,bindir[i]); if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) { ForceModuleLoad(hmod); nummodules++; } i++; } i = 0; while (compdir[i]) { strcpy(filepath, basepath); strcat(filepath, "COMPONENTS\\"); strcat(filepath, compdir[i]); if (DosLoadModule(NULL, 0, filepath, &hmod) == NO_ERROR) { ForceModuleLoad(hmod); nummodules++; } i++; } if (nummodules > 0) { if (DosWaitEventSem(hev, SEM_INDEFINITE_WAIT) != NO_ERROR) { printf("DosWaitEventSem failed\n"); return(1); } if (DosCloseEventSem(hev) != NO_ERROR) { printf("DosCloseEventSem failed\n"); return(1); } } else { printf("No modules available to load\n"); } } return(0); }
// add a variable to the environment or alias to the alias list int add_list( char *envstr, PCH pchList ) { char *line; PCH feptr, env_arg, env_end, last_var; unsigned int length; int rval = 0; ULONG size; // size of environment or alias blocks // OS/2 & NT need semaphores to keep processes from simultaneously // writing the alias list HMTX SemHandle = 0; char szVarName[32]; if ( pchList == 0L ) pchList = glpEnvironment; line = envstr; if ( *line == '=' ) { return ( error( ERROR_4DOS_BAD_SYNTAX, envstr )); } for ( ; (( *line ) && ( *line != '=' )); line++ ) { if ( pchList == glpAliasList ) { if ( iswhite( *line )) { strcpy( line, skipspace( line ) ); break; } } else // ensure environment entry is in upper case *line = (unsigned char)_ctoupper( *line ); } if ( *line == '=' ) { // point to the first char of the argument line++; // collapse whitespace around '=' in aliases, but not in env // variables, for COMMAND.COM compatibility (set abc def= ghi) if ( pchList == glpAliasList ) strcpy( line, skipspace( line )); } else if ( *line ) { // add the missing '=' strins( line, "=" ); line++; } // removing single back quotes at the beginning and end of an alias // argument (they're illegal there; the user is probably making a // mistake with ALIAS /R) if (( *line == SINGLE_QUOTE ) && ( pchList == glpAliasList )) { // remove leading single quote strcpy( line, line + 1 ); // remove trailing single quote if ((( length = strlen( line )) != 0 ) && ( line[--length] == SINGLE_QUOTE )) line[length] = '\0'; } // block other processes & threads while updating alias list if ( pchList == glpAliasList ) { // disable signals temporarily HoldSignals(); // get & lock a semaphore RequestSemaphore( &SemHandle, SEMAPHORE_NAME ); } // get pointers to beginning & end of alias/environment space size = QueryMemSize( pchList ); env_end = pchList + ( size - 4 ); // get pointer to end of environment or alias variables last_var = end_of_env( pchList ); length = strlen( envstr ) + 1; // special case for BeginLIBPATH and EndLIBPATH sscanf( envstr, "%31[^=]", szVarName ); if (stricmp( szVarName, BEGINLIBPATH ) == 0) { if ((DosSetExtLIBPATH( line, BEGIN_LIBPATH ) == NO_ERROR)) return 0; return ERROR_EXIT; } if (stricmp( szVarName, ENDLIBPATH ) == 0) { if ((DosSetExtLIBPATH( line, END_LIBPATH ) == NO_ERROR)) return 0; return ERROR_EXIT; } // check for modification or deletion of existing entry if (( env_arg = get_list( envstr, pchList )) != 0L ) { // get the start of the alias or variable name for ( feptr = env_arg; (( feptr > pchList ) && ( feptr[-1] != '\0' )); feptr-- ) ; if ( *line == '\0' ) { // delete an alias or environment variable memmove( feptr, next_env( feptr ), (unsigned int)( last_var - next_env(feptr)) + 1); } else { // get the relative length (vs. the old variable) length = strlen( line ) - strlen( env_arg ); } } if ( *line != '\0' ) { // check for out of environment space if (( last_var + length ) >= env_end ) { // boost environment or alias list size if ( ReallocMem( pchList, size + ENVIRONMENT_SIZE ) == NULL) { rval = error((( pchList == glpAliasList ) ? ERROR_4DOS_OUT_OF_ALIAS : ERROR_4DOS_OUT_OF_ENVIRONMENT), NULL); goto add_bye; } // adjust the environment / alias list size size = QueryMemSize( pchList ); if ( pchList == glpEnvironment ) gpIniptr->EnvSize = (unsigned int)size; else if ( pchList == glpAliasList ) gpIniptr->AliasSize = (unsigned int)size; } if ( env_arg != 0L ) { // modify an existing alias or environment variable // adjust the space & insert new value feptr = next_env( feptr ); memmove(( feptr + length ), feptr, (unsigned int)( last_var - feptr) + 1 ); strcpy( env_arg, line ); } else { // put it at the end & add an extra null strcpy( last_var, envstr ); last_var[length] = '\0'; } } add_bye: if ( pchList == glpAliasList ) { // clear the semaphore FreeSemaphore( SemHandle ); EnableSignals(); } return rval; }
HRESULT InitializeXPIStub() { char szBuf[MAX_BUF]; char szXPIStubFile[MAX_BUF]; char szEDosQueryProcAddr[MAX_BUF]; APIRET rc; hXPIStubInst = NULL; if(!GetPrivateProfileString("Messages", "ERROR_DOSQUERYPROCADDR", "", szEDosQueryProcAddr, sizeof(szEDosQueryProcAddr), szFileIniInstall)) return(1); /* change current directory to where xpistub.dll */ /* change current directory to where xpistub.dll */ strcpy(szBuf, siCFXpcomFile.szDestination); AppendBackSlash(szBuf, sizeof(szBuf)); strcat(szBuf, "bin"); chdir(szBuf); /* Set LIBPATHSTRICT */ DosSetExtLIBPATH("T", LIBPATHSTRICT); /* Add it to LIBPATH */ DosSetExtLIBPATH(szBuf, BEGIN_LIBPATH); /* build full path to xpistub.dll */ strcpy(szXPIStubFile, szBuf); AppendBackSlash(szXPIStubFile, sizeof(szXPIStubFile)); strcat(szXPIStubFile, "xpistub.dll"); if(FileExists(szXPIStubFile) == FALSE) return(2); /* load xpistub.dll */ if (DosLoadModule(NULL, 0, szXPIStubFile, &hXPIStubInst) != NO_ERROR) { sprintf(szBuf, szEDllLoad, szXPIStubFile); PrintError(szBuf, ERROR_CODE_SHOW); return(1); } if(DosQueryProcAddr(hXPIStubInst, 0, "_XPI_Init", &pfnXpiInit) != NO_ERROR) { sprintf(szBuf, szEDosQueryProcAddr, "_XPI_Init"); PrintError(szBuf, ERROR_CODE_SHOW); return(1); } if(DosQueryProcAddr(hXPIStubInst, 0, "_XPI_Install", &pfnXpiInstall) != NO_ERROR) { sprintf(szBuf, szEDosQueryProcAddr, "_XPI_Install"); PrintError(szBuf, ERROR_CODE_SHOW); return(1); } if(DosQueryProcAddr(hXPIStubInst, 0, "_XPI_Exit", &pfnXpiExit) != NO_ERROR) { sprintf(szBuf, szEDosQueryProcAddr, "_XPI_Exit"); PrintError(szBuf, ERROR_CODE_SHOW); return(1); } return(0); }
HRESULT SmartUpdateJars() { DWORD dwIndex0; siC *siCObject = NULL; HRESULT hrResult; char szBuf[MAX_BUF]; char szEXpiInstall[MAX_BUF]; char szArchive[MAX_BUF]; char szMsgSmartUpdateStart[MAX_BUF]; char szDlgExtractingTitle[MAX_BUF]; if(!GetPrivateProfileString("Messages", "MSG_SMARTUPDATE_START", "", szMsgSmartUpdateStart, sizeof(szMsgSmartUpdateStart), szFileIniInstall)) return(1); if(!GetPrivateProfileString("Messages", "DLG_EXTRACTING_TITLE", "", szDlgExtractingTitle, sizeof(szDlgExtractingTitle), szFileIniInstall)) return(1); if(!GetPrivateProfileString("Messages", "STR_PROCESSINGFILE", "", szStrProcessingFile, sizeof(szStrProcessingFile), szFileIniInstall)) exit(1); if(!GetPrivateProfileString("Messages", "STR_INSTALLING", "", szStrInstalling, sizeof(szStrInstalling), szFileIniInstall)) exit(1); if(!GetPrivateProfileString("Messages", "STR_COPYINGFILE", "", szStrCopyingFile, sizeof(szStrCopyingFile), szFileIniInstall)) exit(1); ShowMessage(szMsgSmartUpdateStart, TRUE); if(InitializeXPIStub() == WIZ_OK) { LogISXPInstall(W_START); strcpy(szBuf, sgProduct.szPath); if(*sgProduct.szSubPath != '\0') { AppendBackSlash(szBuf, sizeof(szBuf)); strcat(szBuf, sgProduct.szSubPath); } hrResult = pfnXpiInit(szBuf, FILE_INSTALL_LOG, cbXPIProgress); /* Unset LIBPATHSTRICT */ DosSetExtLIBPATH("F", LIBPATHSTRICT); ShowMessage(szMsgSmartUpdateStart, FALSE); InitProgressDlg(); GetTotalArchivesToInstall(); WinSetWindowText(dlgInfo.hWndDlg, szDlgExtractingTitle); dwIndex0 = 0; dwCurrentArchive = 0; siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); while(siCObject) { if(siCObject->dwAttributes & SIC_SELECTED) /* Since the archive is selected, we need to process the file ops here */ ProcessFileOps(T_PRE_ARCHIVE, siCObject->szReferenceName); /* launch smartupdate engine for earch jar to be installed */ if((siCObject->dwAttributes & SIC_SELECTED) && !(siCObject->dwAttributes & SIC_LAUNCHAPP) && !(siCObject->dwAttributes & SIC_DOWNLOAD_ONLY)) { strcpy(szArchive, sgProduct.szAlternateArchiveSearchPath); AppendBackSlash(szArchive, sizeof(szArchive)); strcat(szArchive, siCObject->szArchiveName); if((*sgProduct.szAlternateArchiveSearchPath == '\0') || (!FileExists(szArchive))) { strcpy(szArchive, szSetupDir); AppendBackSlash(szArchive, sizeof(szArchive)); strcat(szArchive, siCObject->szArchiveName); if(!FileExists(szArchive)) { strcpy(szArchive, szTempDir); AppendBackSlash(szArchive, sizeof(szArchive)); strcat(szArchive, siCObject->szArchiveName); if(!FileExists(szArchive)) { char szEFileNotFound[MAX_BUF]; if(GetPrivateProfileString("Messages", "ERROR_FILE_NOT_FOUND", "", szEFileNotFound, sizeof(szEFileNotFound), szFileIniInstall)) { sprintf(szBuf, szEFileNotFound, szArchive); PrintError(szBuf, ERROR_CODE_HIDE); } return(1); } } } if(dwCurrentArchive == 0) { ++dwCurrentArchive; UpdateGaugeArchiveProgressBar((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); } sprintf(szBuf, szStrInstalling, siCObject->szDescriptionShort); WinSetDlgItemText(dlgInfo.hWndDlg, IDC_STATUS0, szBuf); LogISXPInstallComponent(siCObject->szDescriptionShort); hrResult = pfnXpiInstall(szArchive, "", 0xFFFF); if(hrResult == E_REBOOT) bReboot = TRUE; else if((hrResult != WIZ_OK) && !(siCObject->dwAttributes & SIC_IGNORE_XPINSTALL_ERROR)) { LogMSXPInstallStatus(siCObject->szArchiveName, hrResult); LogISXPInstallComponentResult(hrResult); if(GetPrivateProfileString("Messages", "ERROR_XPI_INSTALL", "", szEXpiInstall, sizeof(szEXpiInstall), szFileIniInstall)) { char szErrorString[MAX_BUF]; GetErrorString(hrResult, szErrorString, sizeof(szErrorString)); sprintf(szBuf, "%s - %s: %d %s", szEXpiInstall, siCObject->szDescriptionShort, hrResult, szErrorString); PrintError(szBuf, ERROR_CODE_HIDE); } /* break out of the siCObject while loop */ break; } ++dwCurrentArchive; UpdateGaugeArchiveProgressBar((unsigned)(((double)(dwCurrentArchive)/(double)dwTotalArchives)*(double)100)); ProcessWindowsMessages(); LogISXPInstallComponentResult(hrResult); if((hrResult != WIZ_OK) && (siCObject->dwAttributes & SIC_IGNORE_XPINSTALL_ERROR)) /* reset the result to WIZ_OK if there was an error and the * component's attributes contains SIC_IGNORE_XPINSTALL_ERROR. * This should be done after LogISXPInstallComponentResult() * because we still should log the error value. */ hrResult = WIZ_OK; } if(siCObject->dwAttributes & SIC_SELECTED) /* Since the archive is selected, we need to do the file ops here */ ProcessFileOps(T_POST_ARCHIVE, siCObject->szReferenceName); ++dwIndex0; siCObject = SiCNodeGetObject(dwIndex0, TRUE, AC_ALL); } /* while(siCObject) */ LogMSXPInstallStatus(NULL, hrResult); pfnXpiExit(); if(sgProduct.ulMode != SILENT) WinDestroyWindow(dlgInfo.hWndDlg); } else { ShowMessage(szMsgSmartUpdateStart, FALSE); } DeInitializeXPIStub(); LogISXPInstall(W_END); return(hrResult); }
int main(int argc, char **argv) { nsresult rv; char *lastSlash; char iniPath[MAXPATHLEN]; char tmpPath[MAXPATHLEN]; char greDir[MAXPATHLEN]; PRBool greFound = PR_FALSE; #if defined(XP_MACOSX) CFBundleRef appBundle = CFBundleGetMainBundle(); if (!appBundle) return 1; CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(appBundle); if (!resourcesURL) return 1; CFURLRef absResourcesURL = CFURLCopyAbsoluteURL(resourcesURL); CFRelease(resourcesURL); if (!absResourcesURL) return 1; CFURLRef iniFileURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, absResourcesURL, CFSTR("application.ini"), false); CFRelease(absResourcesURL); if (!iniFileURL) return 1; CFStringRef iniPathStr = CFURLCopyFileSystemPath(iniFileURL, kCFURLPOSIXPathStyle); CFRelease(iniFileURL); if (!iniPathStr) return 1; CFStringGetCString(iniPathStr, iniPath, sizeof(iniPath), kCFStringEncodingUTF8); CFRelease(iniPathStr); #else #ifdef XP_WIN wchar_t wide_path[MAX_PATH]; if (!::GetModuleFileNameW(NULL, wide_path, MAX_PATH)) return 1; WideCharToMultiByte(CP_UTF8, 0, wide_path,-1, iniPath, MAX_PATH, NULL, NULL); #elif defined(XP_OS2) PPIB ppib; PTIB ptib; DosGetInfoBlocks(&ptib, &ppib); DosQueryModuleName(ppib->pib_hmte, sizeof(iniPath), iniPath); #elif defined(XP_BEOS) BEntry e((const char *)argv[0], true); // traverse symlink BPath p; status_t err; err = e.GetPath(&p); NS_ASSERTION(err == B_OK, "realpath failed"); if (err == B_OK) // p.Path returns a pointer, so use strcpy to store path in iniPath strcpy(iniPath, p.Path()); #else // on unix, there is no official way to get the path of the current binary. // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to // multiple applications, we will try a series of techniques: // // 1) use realpath() on argv[0], which works unless we're loaded from the // PATH // 2) manually walk through the PATH and look for ourself // 3) give up struct stat fileStat; if (!realpath(argv[0], iniPath) || stat(iniPath, &fileStat)) { const char *path = getenv("PATH"); if (!path) return 1; char *pathdup = strdup(path); if (!pathdup) return 1; PRBool found = PR_FALSE; char *token = strtok(pathdup, ":"); while (token) { sprintf(tmpPath, "%s/%s", token, argv[0]); if (realpath(tmpPath, iniPath) && stat(iniPath, &fileStat) == 0) { found = PR_TRUE; break; } token = strtok(NULL, ":"); } free (pathdup); if (!found) return 1; } #endif lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR); if (!lastSlash) return 1; *(++lastSlash) = '\0'; // On Linux/Win, look for XULRunner in appdir/xulrunner snprintf(greDir, sizeof(greDir), "%sxulrunner" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, iniPath); greFound = FolderExists(greDir); strncpy(lastSlash, "application.ini", sizeof(iniPath) - (lastSlash - iniPath)); #endif // If -app parameter was passed in, it is now time to take it under // consideration. const char *appDataFile; appDataFile = getenv("XUL_APP_FILE"); if (!appDataFile || !*appDataFile) if (argc > 1 && IsArg(argv[1], "app")) { if (argc == 2) { Output(PR_FALSE, "specify APP-FILE (optional)\n"); return 1; } argv[1] = argv[0]; ++argv; --argc; appDataFile = argv[1]; argv[1] = argv[0]; ++argv; --argc; char kAppEnv[MAXPATHLEN]; snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile); if (putenv(kAppEnv)) Output(PR_FALSE, "Couldn't set %s.\n", kAppEnv); char *result = (char*) calloc(sizeof(char), MAXPATHLEN); if (NS_FAILED(GetRealPath(appDataFile, &result))) { Output(PR_TRUE, "Invalid application.ini path.\n"); return 1; } // We have a valid application.ini path passed in to the -app parameter // but not yet a valid greDir, so lets look for it also on the same folder // as the stub. if (!greFound) { lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR); if (!lastSlash) return 1; *(++lastSlash) = '\0'; snprintf(greDir, sizeof(greDir), "%s" XPCOM_DLL, iniPath); greFound = FolderExists(greDir); } // copy it back. strcpy(iniPath, result); } nsINIParser parser; rv = parser.Init(iniPath); if (NS_FAILED(rv)) { fprintf(stderr, "Could not read application.ini\n"); return 1; } #ifdef WINCE // On Windows Mobile and WinCE, we can save a lot of time by not // waiting for XUL and XPCOM to load up. Let's see if we can find // an existing app window to forward our command-line to now. // Shouldn't attempt this if the -no-remote parameter has been provided. bool noRemote = false; for (int i = 1; i < argc; i++) { if (IsArg(argv[i], "no-remote")) { noRemote = true; break; } } if (!noRemote) { char windowName[512]; // Is there a const for appname like VERSION_MAXLEN? rv = parser.GetString("App", "Name", windowName, sizeof(windowName)); if (NS_FAILED(rv)) { fprintf(stderr, "Couldn't figure out the application name\n"); return 1; } // Lookup the hidden message window created by nsNativeAppSupport strncat(windowName, "MessageWindow", sizeof(windowName) - strlen(windowName)); WCHAR wWindowName[512]; MultiByteToWideChar(CP_UTF8, 0, windowName, -1, wWindowName, sizeof(wWindowName)); HWND wnd = ::FindWindowW(wWindowName, NULL); if (wnd) { // Forward the command-line and bail out ForwardToWindow(wnd); return 0; } } #endif if (!greFound) { char minVersion[VERSION_MAXLEN]; // If a gecko maxVersion is not specified, we assume that the app uses only // frozen APIs, and is therefore compatible with any xulrunner 1.x. char maxVersion[VERSION_MAXLEN] = "1.*"; GREVersionRange range = { minVersion, PR_TRUE, maxVersion, PR_TRUE }; rv = parser.GetString("Gecko", "MinVersion", minVersion, sizeof(minVersion)); if (NS_FAILED(rv)) { fprintf(stderr, "The application.ini does not specify a [Gecko] MinVersion\n"); return 1; } rv = parser.GetString("Gecko", "MaxVersion", maxVersion, sizeof(maxVersion)); if (NS_SUCCEEDED(rv)) range.upperInclusive = PR_TRUE; static const GREProperty kProperties[] = { { "xulrunner", "true" } }; rv = GRE_GetGREPathWithProperties(&range, 1, kProperties, NS_ARRAY_LENGTH(kProperties), greDir, sizeof(greDir)); if (NS_FAILED(rv)) { // XXXbsmedberg: Do something much smarter here: notify the // user/offer to download/? Output(PR_FALSE, "Could not find compatible GRE between version %s and %s.\n", range.lower, range.upper); return 1; } #ifdef XP_UNIX // Using a symlinked greDir will fail during startup. Not sure why, but if // we resolve the symlink, everything works as expected. char resolved_greDir[MAXPATHLEN] = ""; if (realpath(greDir, resolved_greDir) && *resolved_greDir) { strncpy(greDir, resolved_greDir, MAXPATHLEN); } #endif } #ifdef XP_OS2 // On OS/2 we need to set BEGINLIBPATH to be able to find XULRunner DLLs strcpy(tmpPath, greDir); lastSlash = strrchr(tmpPath, PATH_SEPARATOR_CHAR); if (lastSlash) { *lastSlash = '\0'; } DosSetExtLIBPATH(tmpPath, BEGIN_LIBPATH); #endif rv = XPCOMGlueStartup(greDir); if (NS_FAILED(rv)) { if (rv == NS_ERROR_OUT_OF_MEMORY) { char applicationName[2000] = "this application"; parser.GetString("App", "Name", applicationName, sizeof(applicationName)); Output(PR_TRUE, "Not enough memory available to start %s.\n", applicationName); } else { Output(PR_TRUE, "Couldn't load XPCOM.\n"); } return 1; } static const nsDynamicFunctionLoad kXULFuncs[] = { { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData }, { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData }, { "XRE_main", (NSFuncPtr*) &XRE_main }, { nsnull, nsnull } }; rv = XPCOMGlueLoadXULFunctions(kXULFuncs); if (NS_FAILED(rv)) { Output(PR_TRUE, "Couldn't load XRE functions.\n"); return 1; } NS_LogInit(); int retval; { // Scope COMPtr and AutoAppData nsCOMPtr<nsILocalFile> iniFile; #ifdef XP_WIN // On Windows and Windows CE, iniPath is UTF-8 encoded, // so we need to convert it. rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(iniPath), PR_FALSE, getter_AddRefs(iniFile)); #else rv = NS_NewNativeLocalFile(nsDependentCString(iniPath), PR_FALSE, getter_AddRefs(iniFile)); #endif if (NS_FAILED(rv)) { Output(PR_TRUE, "Couldn't find application.ini file.\n"); return 1; } AutoAppData appData(iniFile); if (!appData) { Output(PR_TRUE, "Error: couldn't parse application.ini.\n"); return 1; } NS_ASSERTION(appData->directory, "Failed to get app directory."); if (!appData->xreDirectory) { // chop "libxul.so" off the GRE path lastSlash = strrchr(greDir, PATH_SEPARATOR_CHAR); if (lastSlash) { *lastSlash = '\0'; } #ifdef XP_WIN // same as iniPath. NS_NewLocalFile(NS_ConvertUTF8toUTF16(greDir), PR_FALSE, &appData->xreDirectory); #else NS_NewNativeLocalFile(nsDependentCString(greDir), PR_FALSE, &appData->xreDirectory); #endif } retval = XRE_main(argc, argv, appData); } NS_LogTerm(); XPCOMGlueShutdown(); return retval; }
int main(int argc, char **argv) { nsresult rv; char *lastSlash; char iniPath[MAXPATHLEN]; char tmpPath[MAXPATHLEN]; char greDir[MAXPATHLEN]; bool greFound = false; #if defined(XP_MACOSX) CFBundleRef appBundle = CFBundleGetMainBundle(); if (!appBundle) return 1; CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(appBundle); if (!resourcesURL) return 1; CFURLRef absResourcesURL = CFURLCopyAbsoluteURL(resourcesURL); CFRelease(resourcesURL); if (!absResourcesURL) return 1; CFURLRef iniFileURL = CFURLCreateCopyAppendingPathComponent(kCFAllocatorDefault, absResourcesURL, CFSTR("application.ini"), false); CFRelease(absResourcesURL); if (!iniFileURL) return 1; CFStringRef iniPathStr = CFURLCopyFileSystemPath(iniFileURL, kCFURLPOSIXPathStyle); CFRelease(iniFileURL); if (!iniPathStr) return 1; CFStringGetCString(iniPathStr, iniPath, sizeof(iniPath), kCFStringEncodingUTF8); CFRelease(iniPathStr); #else #ifdef XP_WIN wchar_t wide_path[MAX_PATH]; if (!::GetModuleFileNameW(NULL, wide_path, MAX_PATH)) return 1; WideCharToMultiByte(CP_UTF8, 0, wide_path,-1, iniPath, MAX_PATH, NULL, NULL); #elif defined(XP_OS2) PPIB ppib; PTIB ptib; DosGetInfoBlocks(&ptib, &ppib); DosQueryModuleName(ppib->pib_hmte, sizeof(iniPath), iniPath); #else // on unix, there is no official way to get the path of the current binary. // instead of using the MOZILLA_FIVE_HOME hack, which doesn't scale to // multiple applications, we will try a series of techniques: // // 1) use realpath() on argv[0], which works unless we're loaded from the // PATH // 2) manually walk through the PATH and look for ourself // 3) give up struct stat fileStat; strncpy(tmpPath, argv[0], sizeof(tmpPath)); lastSlash = strrchr(tmpPath, '/'); if (lastSlash) { *lastSlash = 0; realpath(tmpPath, iniPath); } else { const char *path = getenv("PATH"); if (!path) return 1; char *pathdup = strdup(path); if (!pathdup) return 1; bool found = false; char *token = strtok(pathdup, ":"); while (token) { sprintf(tmpPath, "%s/%s", token, argv[0]); if (stat(tmpPath, &fileStat) == 0) { found = true; lastSlash = strrchr(tmpPath, '/'); *lastSlash = 0; realpath(tmpPath, iniPath); break; } token = strtok(NULL, ":"); } free (pathdup); if (!found) return 1; } lastSlash = iniPath + strlen(iniPath); *lastSlash = '/'; #endif #ifndef XP_UNIX lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR); if (!lastSlash) return 1; #endif *(++lastSlash) = '\0'; // On Linux/Win, look for XULRunner in appdir/xulrunner snprintf(greDir, sizeof(greDir), "%sxulrunner" XPCOM_FILE_PATH_SEPARATOR XPCOM_DLL, iniPath); greFound = FolderExists(greDir); #ifdef XP_UNIX if (greFound) { char resolved_greDir[MAXPATHLEN] = ""; if (realpath(greDir, resolved_greDir) && *resolved_greDir) { strncpy(greDir, resolved_greDir, MAXPATHLEN); } } #endif strncpy(lastSlash, "application.ini", sizeof(iniPath) - (lastSlash - iniPath)); #endif // If -app parameter was passed in, it is now time to take it under // consideration. const char *appDataFile; appDataFile = getenv("XUL_APP_FILE"); if (!appDataFile || !*appDataFile) if (argc > 1 && IsArg(argv[1], "app")) { if (argc == 2) { Output(false, "specify APP-FILE (optional)\n"); return 1; } argv[1] = argv[0]; ++argv; --argc; appDataFile = argv[1]; argv[1] = argv[0]; ++argv; --argc; char kAppEnv[MAXPATHLEN]; snprintf(kAppEnv, MAXPATHLEN, "XUL_APP_FILE=%s", appDataFile); if (putenv(kAppEnv)) Output(false, "Couldn't set %s.\n", kAppEnv); char *result = (char*) calloc(sizeof(char), MAXPATHLEN); if (NS_FAILED(GetRealPath(appDataFile, &result))) { Output(true, "Invalid application.ini path.\n"); return 1; } // We have a valid application.ini path passed in to the -app parameter // but not yet a valid greDir, so lets look for it also on the same folder // as the stub. if (!greFound) { lastSlash = strrchr(iniPath, PATH_SEPARATOR_CHAR); if (!lastSlash) return 1; *(++lastSlash) = '\0'; snprintf(greDir, sizeof(greDir), "%s" XPCOM_DLL, iniPath); greFound = FolderExists(greDir); } // copy it back. strcpy(iniPath, result); } nsINIParser parser; rv = parser.Init(iniPath); if (NS_FAILED(rv)) { fprintf(stderr, "Could not read application.ini\n"); return 1; } if (!greFound) { #ifdef XP_MACOSX // Check for <bundle>/Contents/Frameworks/XUL.framework/libxpcom.dylib CFURLRef fwurl = CFBundleCopyPrivateFrameworksURL(appBundle); CFURLRef absfwurl = nullptr; if (fwurl) { absfwurl = CFURLCopyAbsoluteURL(fwurl); CFRelease(fwurl); } if (absfwurl) { CFURLRef xulurl = CFURLCreateCopyAppendingPathComponent(NULL, absfwurl, CFSTR("XUL.framework"), true); if (xulurl) { CFURLRef xpcomurl = CFURLCreateCopyAppendingPathComponent(NULL, xulurl, CFSTR("libxpcom.dylib"), false); if (xpcomurl) { char tbuffer[MAXPATHLEN]; if (CFURLGetFileSystemRepresentation(xpcomurl, true, (UInt8*) tbuffer, sizeof(tbuffer)) && access(tbuffer, R_OK | X_OK) == 0) { if (realpath(tbuffer, greDir)) { greFound = true; } else { greDir[0] = '\0'; } } CFRelease(xpcomurl); } CFRelease(xulurl); } CFRelease(absfwurl); } #endif if (!greFound) { Output(false, "Could not find the Mozilla runtime.\n"); return 1; } } #ifdef XP_OS2 // On OS/2 we need to set BEGINLIBPATH to be able to find XULRunner DLLs strcpy(tmpPath, greDir); lastSlash = strrchr(tmpPath, PATH_SEPARATOR_CHAR); if (lastSlash) { *lastSlash = '\0'; } DosSetExtLIBPATH(tmpPath, BEGIN_LIBPATH); #endif rv = XPCOMGlueStartup(greDir); if (NS_FAILED(rv)) { if (rv == NS_ERROR_OUT_OF_MEMORY) { char applicationName[2000] = "this application"; parser.GetString("App", "Name", applicationName, sizeof(applicationName)); Output(true, "Not enough memory available to start %s.\n", applicationName); } else { Output(true, "Couldn't load XPCOM.\n"); } return 1; } static const nsDynamicFunctionLoad kXULFuncs[] = { { "XRE_CreateAppData", (NSFuncPtr*) &XRE_CreateAppData }, { "XRE_FreeAppData", (NSFuncPtr*) &XRE_FreeAppData }, { "XRE_main", (NSFuncPtr*) &XRE_main }, { nullptr, nullptr } }; rv = XPCOMGlueLoadXULFunctions(kXULFuncs); if (NS_FAILED(rv)) { Output(true, "Couldn't load XRE functions.\n"); return 1; } NS_LogInit(); int retval; { // Scope COMPtr and AutoAppData nsCOMPtr<nsIFile> iniFile; #ifdef XP_WIN // On Windows iniPath is UTF-8 encoded so we need to convert it. rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(iniPath), false, getter_AddRefs(iniFile)); #else rv = NS_NewNativeLocalFile(nsDependentCString(iniPath), false, getter_AddRefs(iniFile)); #endif if (NS_FAILED(rv)) { Output(true, "Couldn't find application.ini file.\n"); return 1; } AutoAppData appData(iniFile); if (!appData) { Output(true, "Error: couldn't parse application.ini.\n"); return 1; } NS_ASSERTION(appData->directory, "Failed to get app directory."); if (!appData->xreDirectory) { // chop "libxul.so" off the GRE path lastSlash = strrchr(greDir, PATH_SEPARATOR_CHAR); if (lastSlash) { *lastSlash = '\0'; } #ifdef XP_WIN // same as iniPath. NS_NewLocalFile(NS_ConvertUTF8toUTF16(greDir), false, &appData->xreDirectory); #else NS_NewNativeLocalFile(nsDependentCString(greDir), false, &appData->xreDirectory); #endif } retval = XRE_main(argc, argv, appData, 0); } NS_LogTerm(); return retval; }