зеркало из https://github.com/mozilla/pjs.git
320 строки
7.8 KiB
C++
320 строки
7.8 KiB
C++
/* -*- Mode: C; c-basic-offset: 2; tab-width: 4; indent-tabs-mode: nil; -*- */
|
|
/* ***** BEGIN LICENSE BLOCK *****
|
|
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
|
*
|
|
* The contents of this file are subject to the Mozilla Public License Version
|
|
* 1.1 (the "License"); you may not use this file except in compliance with
|
|
* the License. You may obtain a copy of the License at
|
|
* http://www.mozilla.org/MPL/
|
|
*
|
|
* Software distributed under the License is distributed on an "AS IS" basis,
|
|
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
|
* for the specific language governing rights and limitations under the
|
|
* License.
|
|
*
|
|
* The Original Code is MOZCE Lib.
|
|
*
|
|
* The Initial Developer of the Original Code is Doug Turner <dougt@meer.net>.
|
|
|
|
* Portions created by the Initial Developer are Copyright (C) 2005
|
|
* the Initial Developer. All Rights Reserved.
|
|
*
|
|
* Contributor(s):
|
|
* John Wolfe <wolfe@lobo.us>
|
|
*
|
|
* Alternatively, the contents of this file may be used under the terms of
|
|
* either the GNU General Public License Version 2 or later (the "GPL"), or
|
|
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
|
|
* in which case the provisions of the GPL or the LGPL are applicable instead
|
|
* of those above. If you wish to allow use of your version of this file only
|
|
* under the terms of either the GPL or the LGPL, and not to allow others to
|
|
* use your version of this file under the terms of the MPL, indicate your
|
|
* decision by deleting the provisions above and replace them with the notice
|
|
* and other provisions required by the GPL or the LGPL. If you do not delete
|
|
* the provisions above, a recipient may use your version of this file under
|
|
* the terms of any one of the MPL, the GPL or the LGPL.
|
|
*
|
|
* ***** END LICENSE BLOCK ***** */
|
|
|
|
#include "include/mozce_shunt.h"
|
|
#include "time_conversions.h"
|
|
#include <stdlib.h>
|
|
#include "Windows.h"
|
|
|
|
////////////////////////////////////////////////////////
|
|
// Environment Variable Stuff
|
|
////////////////////////////////////////////////////////
|
|
|
|
typedef struct env_entry env_entry;
|
|
|
|
#define ENV_IS_STATIC 0
|
|
#define ENV_FREE_KEY 1
|
|
#define ENV_FREE_BOTH 2
|
|
|
|
struct env_entry {
|
|
char *key;
|
|
char *value;
|
|
int flag;
|
|
env_entry *next;
|
|
};
|
|
|
|
static bool env_ready = false;
|
|
static env_entry *env_head = NULL;
|
|
|
|
static env_entry *
|
|
env_find_key(const char *key)
|
|
{
|
|
env_entry *entry = env_head;
|
|
while (entry) {
|
|
if (strcmp(entry->key, key) == 0)
|
|
return entry;
|
|
|
|
entry = entry->next;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
static void
|
|
putenv_internal(char *key, char *value, int flag)
|
|
{
|
|
env_entry *entry = env_find_key(key);
|
|
if (entry) {
|
|
// get rid of old key/value; if flag is set, then
|
|
// they're static strings and we don't touch them
|
|
if (entry->flag == ENV_FREE_BOTH)
|
|
free (entry->value);
|
|
if (entry->flag == ENV_FREE_KEY)
|
|
free (entry->key);
|
|
} else {
|
|
entry = new env_entry;
|
|
entry->next = env_head;
|
|
env_head = entry;
|
|
}
|
|
|
|
entry->key = key;
|
|
entry->value = value;
|
|
entry->flag = flag;
|
|
}
|
|
|
|
static void
|
|
init_initial_env() {
|
|
env_ready = true;
|
|
|
|
putenv_internal("NSS_DEFAULT_DB_TYPE", "sql", ENV_IS_STATIC);
|
|
putenv_internal("NSPR_FD_CACHE_SIZE_LOW", "10", ENV_IS_STATIC);
|
|
putenv_internal("NSPR_FD_CACHE_SIZE_HIGH", "30", ENV_IS_STATIC);
|
|
putenv_internal("XRE_PROFILE_NAME", "default", ENV_IS_STATIC);
|
|
putenv_internal("tmp", "/Temp", ENV_IS_STATIC);
|
|
}
|
|
|
|
void
|
|
putenv_copy(const char *k, const char *v)
|
|
{
|
|
if (!env_ready)
|
|
init_initial_env();
|
|
|
|
putenv_internal(strdup(k), strdup(v), ENV_FREE_BOTH);
|
|
}
|
|
|
|
int
|
|
putenv(const char *envstr)
|
|
{
|
|
if (!env_ready)
|
|
init_initial_env();
|
|
|
|
char *key = strdup(envstr);
|
|
char *value = strchr(key, '=');
|
|
if (!value) {
|
|
free(key);
|
|
return -1;
|
|
}
|
|
|
|
*value++ = '\0';
|
|
|
|
putenv_internal(key, value, ENV_FREE_KEY);
|
|
|
|
return 0;
|
|
}
|
|
|
|
char *
|
|
getenv(const char* name)
|
|
{
|
|
if (!env_ready)
|
|
init_initial_env();
|
|
|
|
env_entry *entry = env_find_key(name);
|
|
if (entry && entry->value[0] != 0) {
|
|
return entry->value;
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
char
|
|
GetEnvironmentVariableW(const unsigned short* lpName,
|
|
unsigned short* lpBuffer,
|
|
unsigned long nSize)
|
|
{
|
|
char key[256];
|
|
int rv = WideCharToMultiByte(CP_ACP, 0, lpName, -1, key, 255, NULL, NULL);
|
|
if (rv <= 0)
|
|
return 0;
|
|
|
|
key[rv] = 0;
|
|
|
|
char* val = getenv(key);
|
|
|
|
if (!val)
|
|
return 0;
|
|
|
|
// strlen(val)+1, let MBTWC convert the nul byte for us
|
|
return MultiByteToWideChar(CP_ACP, 0, val, strlen(val)+1, lpBuffer, nSize);
|
|
}
|
|
|
|
char
|
|
SetEnvironmentVariableW(const unsigned short* name,
|
|
const unsigned short* value)
|
|
{
|
|
char key[256];
|
|
char val[256];
|
|
int rv;
|
|
|
|
rv = WideCharToMultiByte(CP_ACP, 0, name, -1, key, 255, NULL, NULL);
|
|
if (rv < 0)
|
|
return rv;
|
|
|
|
key[rv] = 0;
|
|
|
|
rv = WideCharToMultiByte(CP_ACP, 0, value, -1, val, 255, NULL, NULL);
|
|
if (rv < 0)
|
|
return rv;
|
|
|
|
val[rv] = 0;
|
|
|
|
putenv_copy(key, val);
|
|
return 0;
|
|
}
|
|
|
|
|
|
unsigned int ExpandEnvironmentStringsW(const unsigned short* lpSrc,
|
|
unsigned short* lpDst,
|
|
unsigned int nSize)
|
|
{
|
|
if ( NULL == lpDst )
|
|
return 0;
|
|
|
|
unsigned int size = 0;
|
|
unsigned int index = 0;
|
|
unsigned int origLen = wcslen(lpSrc);
|
|
|
|
const unsigned short *pIn = lpSrc;
|
|
unsigned short *pOut = lpDst;
|
|
|
|
while ( index < origLen ) {
|
|
|
|
if (*pIn != L'%') { // Regular char, copy over
|
|
if ( size < nSize ) *pOut = *pIn, pOut++;
|
|
index++, size++, pIn++;
|
|
continue;
|
|
}
|
|
|
|
// Have a starting '%' - look for matching '%'
|
|
int envlen = 0;
|
|
const unsigned short *pTmp = ++pIn; // Move past original '%'
|
|
while ( L'%' != *pTmp ) {
|
|
envlen++, pTmp++;
|
|
if ( origLen < index + envlen ) { // Ran past end of original
|
|
SetLastError(ERROR_INVALID_PARAMETER); // buffer without matching '%'
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
if ( 0 == envlen ) { // Encountered a "%%" - mapping to "%"
|
|
size++;
|
|
if ( size < nSize ) *pOut = *pIn, pOut++;
|
|
pIn++;
|
|
index += 2;
|
|
} else {
|
|
// Encountered a "%something%" - mapping "something"
|
|
char key[256];
|
|
int k = WideCharToMultiByte(CP_ACP, 0, pIn, envlen, key, 255, NULL, NULL);
|
|
key[k] = 0;
|
|
char *pC = getenv(key);
|
|
if ( NULL != pC ) {
|
|
int n = MultiByteToWideChar( CP_ACP, 0, pC, -1, pOut, nSize - size );
|
|
if ( n > 0 ) {
|
|
size += n - 1; // Account for trailing zero
|
|
pOut += n - 1;
|
|
}
|
|
}
|
|
index += envlen + 2;
|
|
pIn = ++pTmp;
|
|
}
|
|
}
|
|
|
|
if ( size < nSize ) lpDst[size] = 0;
|
|
return size;
|
|
}
|
|
|
|
unsigned short *
|
|
mozce_GetEnvironmentCL()
|
|
{
|
|
env_entry *entry = env_head;
|
|
int len = 0;
|
|
while (entry) {
|
|
if (entry->flag == ENV_IS_STATIC) {
|
|
entry = entry->next;
|
|
continue;
|
|
}
|
|
|
|
len += strlen(entry->key);
|
|
len += strlen(entry->value);
|
|
|
|
// for each env var, 11 chars of " --environ:", 3 chars of '"="', and a null at the end
|
|
len += 11 + 3 + 1;
|
|
|
|
entry = entry->next;
|
|
}
|
|
|
|
if (len == 0) {
|
|
return wcsdup(L"");
|
|
}
|
|
|
|
wchar_t *env = (wchar_t*) malloc(sizeof(wchar_t) * (len+1));
|
|
if (!env)
|
|
return NULL;
|
|
|
|
entry = env_head;
|
|
|
|
int pos = 0;
|
|
while (entry) {
|
|
if (entry->flag == ENV_IS_STATIC) {
|
|
entry = entry->next;
|
|
continue;
|
|
}
|
|
|
|
if (strchr(entry->key, '"') || strchr(entry->value, '"')) {
|
|
// argh, we don't have a good way of encoding the ", so let's just
|
|
// ignore this var for now
|
|
RETAILMSG(1, (L"Skipping environment variable with quote marks in key or value! %S -> %s\r\n", entry->key, entry->value));
|
|
entry = entry->next;
|
|
continue;
|
|
}
|
|
|
|
wcscpy (env+pos, L" --environ:\"");
|
|
pos += 12;
|
|
pos += MultiByteToWideChar(CP_ACP, 0, entry->key, strlen(entry->key), env+pos, len-pos);
|
|
env[pos++] = '=';
|
|
pos += MultiByteToWideChar(CP_ACP, 0, entry->value, strlen(entry->value), env+pos, len-pos);
|
|
env[pos++] = '\"';
|
|
|
|
entry = entry->next;
|
|
}
|
|
|
|
env[pos] = '\0';
|
|
|
|
return env;
|
|
|
|
}
|