diff --git a/mozilla/modules/libpref/public/prefapi.h b/mozilla/modules/libpref/public/prefapi.h index 964d8f812d2..c7e14158dd6 100644 --- a/mozilla/modules/libpref/public/prefapi.h +++ b/mozilla/modules/libpref/public/prefapi.h @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in @@ -31,12 +31,44 @@ #include "plhash.h" #endif +#define NEW_PREF_ARCH + NSPR_BEGIN_EXTERN_C -#ifdef XP_PC +/* +// +// Error codes +// +*/ + +typedef int PROFILE_ERROR; + + +/* Error numbers between -100 and -999 are reserved for individual stores */ +/* Error numbers less than -1000 are reserved for the profile manager */ + +typedef enum { + PREF_BAD_PASSWORD = -12, + PREF_CANT_DELETE_NET_PROFILE = -11, + PREF_NETPROFILE_DIR_EXISTS = -10, + PREF_PROFILE_DIR_EXISTS = -9, + PREF_PROFILE_EXISTS = -8, + PREF_BAD_PARAMETER = -7, + PREF_DOES_NOT_EXIST = -6, + PREF_OUT_OF_MEMORY = -5, + PREF_TYPE_CHANGE_ERR = -4, + PREF_NOT_INITIALIZED = -3, + PREF_BAD_LOCKFILE = -2, + PREF_ERROR = -1, + PREF_NOERROR = 0, + PREF_OK = 0, /* same as PREF_NOERROR */ + PREF_VALUECHANGED = 1, + PREF_PROFILE_UPGRADE = 2 +} PrefResult; + +#if defined(XP_PC) // horrible pre-declaration...so kill me. -int pref_InitInitialObjects(JSContext *js_context,JSObject *js_object); -PR_EXTERN(int) pref_savePref(PRHashEntry *he, int i, void *arg); +PrefResult pref_InitInitialObjects(JSContext *js_context,JSObject *js_object); #endif /* @@ -61,23 +93,34 @@ PR_EXTERN(int) pref_savePref(PRHashEntry *he, int i, void *arg); // */ -PR_EXTERN(int) +PR_EXTERN(PrefResult) PREF_ReadUserJSFile(char *filename); -/* LI_STUFF read in an li prefs file and give it a name- preobably temporary */ -PR_EXTERN(int) +PR_EXTERN(PrefResult) PREF_ReadLIJSFile(char *filename); -PR_EXTERN(int) +#if defined (XP_PC) || defined (XP_MAC) +/* PREF_Init actually returns a profile object */ +PR_EXTERN(void *) +PREF_InitProfile(void); + +PR_EXTERN(void *) +PREF_GetCurrentProfile(void); +#endif + +PR_EXTERN(PRBool) PREF_Init(char *filename); -PR_EXTERN(int) +PR_EXTERN(PrefResult) +PREF_LockPref(const char *key); + +PR_EXTERN(PrefResult) PREF_GetConfigContext(JSContext **js_context); -PR_EXTERN(int) +PR_EXTERN(PrefResult) PREF_GetGlobalConfigObject(JSObject **js_object); -PR_EXTERN(int) +PR_EXTERN(PrefResult) PREF_GetPrefConfigObject(JSObject **js_object); /* @@ -94,7 +137,7 @@ PREF_Cleanup(); // otherwise, evaluates the contents of the file as a JS buffer. // */ -PR_EXTERN(int) +PR_EXTERN(PrefResult) PREF_ReadLockFile(const char *filename); /* @@ -113,19 +156,19 @@ PREF_ReadLockFile(const char *filename); // PREF_RegisterCallback() for any user values that have changed. // */ -PR_EXTERN(int) +PR_EXTERN(JSBool) PREF_EvaluateJSBuffer(const char * js_buffer, size_t length); /* // Like the above but does not generate callbacks. */ -PR_EXTERN(int) +PR_EXTERN(JSBool) PREF_QuietEvaluateJSBuffer(const char * js_buffer, size_t length); /* // Like the above but does not generate callbacks and executes in scope of global config object */ -PR_EXTERN(int) +PR_EXTERN(JSBool) PREF_QuietEvaluateJSBufferWithGlobalScope(const char * js_buffer, size_t length); /* @@ -135,24 +178,30 @@ PREF_QuietEvaluateJSBufferWithGlobalScope(const char * js_buffer, size_t length) */ PR_EXTERN(JSBool) PREF_EvaluateConfigScript(const char * js_buffer, size_t length, - const char* filename, PRBool bGlobalContext, PRBool bCallbacks); + const char* filename, PRBool bGlobalContext, PRBool bCallbacks, + PRBool skipFirstLine); /* // -// Error codes +// Actions that can be passed to various functions to perform an operation on a pref key // */ -enum { - PREF_OUT_OF_MEMORY = -5, - PREF_TYPE_CHANGE_ERR = -4, - PREF_NOT_INITIALIZED = -3, - PREF_BAD_LOCKFILE = -2, - PREF_ERROR = -1, - PREF_NOERROR = 0, - PREF_OK = 0, /* same as PREF_NOERROR */ - PREF_VALUECHANGED = 1 -}; + +typedef enum { PREF_SETDEFAULT, PREF_SETUSER, + PREF_LOCK, PREF_SETCONFIG, PREF_SETLI } PrefAction; + +/* +// +// Preference flags, including the native type of the preference +// +*/ + +typedef enum { PREF_INVALID = 0, + PREF_LOCKED = 1, PREF_USERSET = 2, PREF_CONFIG = 4, PREF_REMOTE = 8, + PREF_LILOCAL = 16, PREF_STRING = 32, PREF_INT = 64, PREF_BOOL = 128, + PREF_VALUETYPE_MASK = (PREF_STRING | PREF_INT | PREF_BOOL) + } PrefType; /* // @@ -165,13 +214,13 @@ enum { // (triggering a callback), or PREF_NOERROR if the value was unchanged. // */ -PR_EXTERN(int) PREF_SetCharPref(const char *pref,const char* value); -PR_EXTERN(int) PREF_SetIntPref(const char *pref,int32 value); -PR_EXTERN(int) PREF_SetBoolPref(const char *pref,PRBool value); -PR_EXTERN(int) PREF_SetBinaryPref(const char *pref,void * value, long size); -PR_EXTERN(int) PREF_SetColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue); -PR_EXTERN(int) PREF_SetColorPrefDWord(const char *pref_name, uint32 colorref); -PR_EXTERN(int) PREF_SetRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom); +PR_EXTERN(PrefResult) PREF_SetCharPref(const char *pref,const char* value); +PR_EXTERN(PrefResult) PREF_SetIntPref(const char *pref,int32 value); +PR_EXTERN(PrefResult) PREF_SetBoolPref(const char *pref,PRBool value); +PR_EXTERN(PrefResult) PREF_SetBinaryPref(const char *pref,void * value, long size); +PR_EXTERN(PrefResult) PREF_SetColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue); +PR_EXTERN(PrefResult) PREF_SetColorPrefDWord(const char *pref_name, uint32 colorref); +PR_EXTERN(PrefResult) PREF_SetRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom); /* // @@ -182,12 +231,12 @@ PR_EXTERN(int) PREF_SetRectPref(const char *pref_name, int16 left, int16 top, in // be saved out to disk. // */ -PR_EXTERN(int) PREF_SetDefaultCharPref(const char *pref,const char* value); -PR_EXTERN(int) PREF_SetDefaultIntPref(const char *pref,int32 value); -PR_EXTERN(int) PREF_SetDefaultBoolPref(const char *pref,PRBool value); -PR_EXTERN(int) PREF_SetDefaultBinaryPref(const char *pref,void * value, long size); -PR_EXTERN(int) PREF_SetDefaultColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue); -PR_EXTERN(int) PREF_SetDefaultRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom); +PR_EXTERN(PrefResult) PREF_SetDefaultCharPref(const char *pref,const char* value); +PR_EXTERN(PrefResult) PREF_SetDefaultIntPref(const char *pref,int32 value); +PR_EXTERN(PrefResult) PREF_SetDefaultBoolPref(const char *pref,PRBool value); +PR_EXTERN(PrefResult) PREF_SetDefaultBinaryPref(const char *pref,void * value, long size); +PR_EXTERN(PrefResult) PREF_SetDefaultColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue); +PR_EXTERN(PrefResult) PREF_SetDefaultRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom); /* // @@ -207,13 +256,13 @@ PR_EXTERN(int) PREF_SetDefaultRectPref(const char *pref_name, int16 left, int16 // (if it is reasonably possible) // */ -PR_EXTERN(int) PREF_GetCharPref(const char *pref, char * return_buf, int * buf_length); -PR_EXTERN(int) PREF_GetIntPref(const char *pref, int32 * return_int); -PR_EXTERN(int) PREF_GetBoolPref(const char *pref, XP_Bool * return_val); -PR_EXTERN(int) PREF_GetBinaryPref(const char *pref, void * return_val, int * buf_length); -PR_EXTERN(int) PREF_GetColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue); -PR_EXTERN(int) PREF_GetColorPrefDWord(const char *pref_name, uint32 *colorref); -PR_EXTERN(int) PREF_GetRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom); +PR_EXTERN(PrefResult) PREF_GetCharPref(const char *pref, char * return_buf, int * buf_length); +PR_EXTERN(PrefResult) PREF_GetIntPref(const char *pref, int32 * return_int); +PR_EXTERN(PrefResult) PREF_GetBoolPref(const char *pref, XP_Bool * return_val); +PR_EXTERN(PrefResult) PREF_GetBinaryPref(const char *pref, void * return_val, int * buf_length); +PR_EXTERN(PrefResult) PREF_GetColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue); +PR_EXTERN(PrefResult) PREF_GetColorPrefDWord(const char *pref_name, uint32 *colorref); +PR_EXTERN(PrefResult) PREF_GetRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom); /* // @@ -222,11 +271,11 @@ PR_EXTERN(int) PREF_GetRectPref(const char *pref_name, int16 *left, int16 *top, // the caller will need to be responsible for freeing it... // */ -PR_EXTERN(int) PREF_CopyCharPref(const char *pref, char ** return_buf); -PR_EXTERN(int) PREF_CopyBinaryPref(const char *pref_name, void ** return_value, int *size); +PR_EXTERN(PrefResult) PREF_CopyCharPref(const char *pref, char ** return_buf); +PR_EXTERN(PrefResult) PREF_CopyBinaryPref(const char *pref_name, void ** return_value, int *size); -PR_EXTERN(int) PREF_CopyDefaultCharPref( const char *pref_name, char ** return_buffer ); -PR_EXTERN(int) PREF_CopyDefaultBinaryPref(const char *pref, void ** return_val, int * size); +PR_EXTERN(PrefResult) PREF_CopyDefaultCharPref( const char *pref_name, char ** return_buffer ); +PR_EXTERN(PrefResult) PREF_CopyDefaultBinaryPref(const char *pref, void ** return_val, int * size); /* // @@ -237,8 +286,8 @@ PR_EXTERN(int) PREF_CopyDefaultBinaryPref(const char *pref, void ** return_val, // between paths and aliases flattened into binary strings. // */ -PR_EXTERN(int) PREF_CopyPathPref(const char *pref, char ** return_buf); -PR_EXTERN(int) PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default); +PR_EXTERN(PrefResult) PREF_CopyPathPref(const char *pref, char ** return_buf); +PR_EXTERN(PrefResult) PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default); /* // @@ -248,13 +297,13 @@ PR_EXTERN(int) PREF_SetPathPref(const char *pref_name, const char *path, PRBool // // */ -PR_EXTERN(int) PREF_GetDefaultCharPref(const char *pref, char * return_buf, int * buf_length); -PR_EXTERN(int) PREF_GetDefaultIntPref(const char *pref, int32 * return_int); -PR_EXTERN(int) PREF_GetDefaultBoolPref(const char *pref, XP_Bool * return_val); -PR_EXTERN(int) PREF_GetDefaultBinaryPref(const char *pref, void * return_val, int * buf_length); -PR_EXTERN(int) PREF_GetDefaultColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue); -PR_EXTERN(int) PREF_GetDefaultColorPrefDWord(const char *pref_name, uint32 *colorref); -PR_EXTERN(int) PREF_GetDefaultRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom); +PR_EXTERN(PrefResult) PREF_GetDefaultCharPref(const char *pref, char * return_buf, int * buf_length); +PR_EXTERN(PrefResult) PREF_GetDefaultIntPref(const char *pref, int32 * return_int); +PR_EXTERN(PrefResult) PREF_GetDefaultBoolPref(const char *pref, XP_Bool * return_val); +PR_EXTERN(PrefResult) PREF_GetDefaultBinaryPref(const char *pref, void * return_val, int * buf_length); +PR_EXTERN(PrefResult) PREF_GetDefaultColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue); +PR_EXTERN(PrefResult) PREF_GetDefaultColorPrefDWord(const char *pref_name, uint32 *colorref); +PR_EXTERN(PrefResult) PREF_GetDefaultRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom); /* // @@ -270,35 +319,43 @@ PR_EXTERN(int) PREF_GetDefaultRectPref(const char *pref_name, int16 *left, int16 // The caller is responsible for freeing the returned string. // */ -PR_EXTERN(int) PREF_CopyConfigString(const char *obj_name, char **return_buffer); -PR_EXTERN(int) PREF_CopyIndexConfigString(const char *obj_name, int index, +PR_EXTERN(PrefResult) PREF_CopyConfigString(const char *obj_name, char **return_buffer); +PR_EXTERN(PrefResult) PREF_CopyIndexConfigString(const char *obj_name, int index, const char *field, char **return_buffer); -PR_EXTERN(int) PREF_GetConfigInt(const char *obj_name, int32 *return_int); -PR_EXTERN(int) PREF_GetConfigBool(const char *obj_name, XP_Bool *return_bool); +PR_EXTERN(PrefResult) PREF_GetConfigInt(const char *obj_name, int32 *return_int); +PR_EXTERN(PrefResult) PREF_GetConfigBool(const char *obj_name, XP_Bool *return_bool); -/* OLD:: */PR_EXTERN(int) PREF_GetConfigString(const char *obj_name, char * return_buffer, int size, +/* OLD:: */PR_EXTERN(PrefResult) PREF_GetConfigString(const char *obj_name, char * return_buffer, int size, int index, const char *field); +/* + * Listpref API + */ +PR_EXTERN(PrefResult) PREF_GetListPref(const char *pref_name, char*** list); +PR_EXTERN(PrefResult) PREF_SetListPref(const char *pref_name, char** list); +PR_EXTERN(PrefResult) PREF_AppendListPref(const char *pref_name, const char *value); +PR_EXTERN(PrefResult) PREF_FreeListPref(char*** list); + /* // -// PRBool funtion that returns whether or not the preference is locked and therefore +// PRBool function that returns whether or not the preference is locked and therefore // cannot be changed. // */ PR_EXTERN(PRBool) PREF_PrefIsLocked(const char *pref_name); -PR_EXTERN(int) PREF_GetPrefType(const char *pref_name); +PR_EXTERN(PrefType) PREF_GetPrefType(const char *pref_name); /* // // Cause the preference file to be written to disk // */ -PR_EXTERN(int) PREF_SavePrefFile(void); -PR_EXTERN(int) PREF_SavePrefFileAs(const char *filename); +PR_EXTERN(PrefResult) PREF_SavePrefFile(void); +PR_EXTERN(PrefResult) PREF_SavePrefFileAs(const char *filename); /* LI_STUFF */ -PR_EXTERN(int) PREF_SaveLIPrefFile(const char *filename); +PR_EXTERN(PrefResult) PREF_SaveLIPrefFile(const char *filename); /* @@ -310,12 +367,12 @@ PR_EXTERN(char *) PREF_AboutConfig(); /* * Delete a branch of the tree */ -PR_EXTERN(int) PREF_DeleteBranch(const char *branch_name); +PR_EXTERN(PrefResult) PREF_DeleteBranch(const char *branch_name); /* * Clears the given pref (reverts it to its default value) */ -PR_EXTERN(int) PREF_ClearUserPref(const char *pref_name); +PR_EXTERN(PrefResult) PREF_ClearUserPref(const char *pref_name); /* * Creates an iterator over the children of a node. Sample code: @@ -332,7 +389,7 @@ PR_EXTERN(int) PREF_ClearUserPref(const char *pref_name); * "mime.image_gif", then * "mime.image_jpeg", etc. */ -PR_EXTERN(int) PREF_CreateChildList(const char* parent_node, char **child_list); +PR_EXTERN(PrefResult) PREF_CreateChildList(const char* parent_node, char **child_list); PR_EXTERN(char*) PREF_NextChild(char *child_list, int *index); /* @@ -346,13 +403,13 @@ PR_EXTERN(char*) PREF_NextChild(char *child_list, int *index); * * */ -PR_EXTERN(int) PREF_CopyPrefsTree(const char *srcRoot, const char *destRoot); +PR_EXTERN(PrefResult) PREF_CopyPrefsTree(const char *srcRoot, const char *destRoot); /* // // The callback function will get passed the pref_node which triggered the call // and the void * instance_data which was passed to the register callback function. -// Return a non-zero result to pass an error up to the caller. +// Return a non-zero result (a PrefResult enumerated value) to pass an error up to the caller. // */ typedef int (*PrefChangedFunc) (const char *, void *); @@ -367,7 +424,7 @@ typedef int (*PrefChangedFunc) (const char *, void *); */ PR_EXTERN(void) PREF_RegisterCallback( const char* domain, PrefChangedFunc callback, void* instance_data ); -PR_EXTERN(int) PREF_UnregisterCallback( const char* domain, +PR_EXTERN(PrefResult) PREF_UnregisterCallback( const char* domain, PrefChangedFunc callback, void* instance_data ); /* @@ -376,11 +433,14 @@ PR_EXTERN(int) PREF_UnregisterCallback( const char* domain, PR_EXTERN(PRBool) PREF_IsAutoAdminEnabled(void); #ifdef XP_UNIX +struct fe_icon_data; typedef void* XmStringPtr; typedef void* KeySymPtr; PR_EXTERN(void) PREF_AlterSplashIcon(struct fe_icon_data*); PR_EXTERN(PRBool) PREF_GetLabelAndMnemonic(char*, char**, XmStringPtr xmstring, KeySymPtr keysym); PR_EXTERN(PRBool) PREF_GetUrl(char*, char**); +PR_EXTERN(void) PREF_SetCallbacksStatus(PRBool status); +PR_EXTERN(PrefResult) PREF_LoadLDAPPrefs(void); #endif NSPR_END_EXTERN_C diff --git a/mozilla/modules/libpref/src/mac/macpref.cp b/mozilla/modules/libpref/src/mac/macpref.cp index 32c1174ce93..9cd2ec72ee6 100644 --- a/mozilla/modules/libpref/src/mac/macpref.cp +++ b/mozilla/modules/libpref/src/mac/macpref.cp @@ -99,26 +99,24 @@ JSBool pref_InitInitialObjects() * Convert between cross-platform file/folder pathname strings * and Mac aliases flattened into binary strings */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyPathPref(const char *pref_name, char ** return_buffer) { - int dirSize, result; - AliasHandle aliasH = NULL; + int dirSize; char *dirAliasBuf = NULL; - OSErr err; - FSSpec fileSpec; - Boolean changed; - - result = PREF_CopyBinaryPref(pref_name, &dirAliasBuf, &dirSize); + PrefResult result = PREF_CopyBinaryPref(pref_name, &dirAliasBuf, &dirSize); if (result != PREF_NOERROR) return result; // Cast to an alias record and resolve. - err = PtrToHand(dirAliasBuf, &(Handle) aliasH, dirSize); + AliasHandle aliasH = NULL; + OSErr err = PtrToHand(dirAliasBuf, &(Handle) aliasH, dirSize); free(dirAliasBuf); if (err != noErr) return PREF_ERROR; // not enough memory? + FSSpec fileSpec; + Boolean changed; err = ::ResolveAlias(NULL, aliasH, &fileSpec, &changed); DisposeHandle((Handle) aliasH); if (err != noErr) @@ -129,7 +127,7 @@ PREF_CopyPathPref(const char *pref_name, char ** return_buffer) return PREF_NOERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default) { FSSpec fileSpec; @@ -142,7 +140,7 @@ PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default) if (err != noErr) return PREF_ERROR; - int result; + PrefResult result; Size bytes = GetHandleSize((Handle) aliasH); HLock((Handle) aliasH); diff --git a/mozilla/modules/libpref/src/nsPref.cpp b/mozilla/modules/libpref/src/nsPref.cpp index b6461e5513d..755fe9442ea 100644 --- a/mozilla/modules/libpref/src/nsPref.cpp +++ b/mozilla/modules/libpref/src/nsPref.cpp @@ -255,7 +255,8 @@ NS_IMETHODIMP nsPref::EvaluateConfigScript(const char * js_buffer, length, filename, bGlobalContext, - bCallbacks)); + bCallbacks, + PR_TRUE)); } /* diff --git a/mozilla/modules/libpref/src/prefapi.c b/mozilla/modules/libpref/src/prefapi.c index 05f314ca7be..ce449e6061b 100644 --- a/mozilla/modules/libpref/src/prefapi.c +++ b/mozilla/modules/libpref/src/prefapi.c @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in @@ -79,23 +79,17 @@ JSObject * m_GlobalConfigObject = NULL; static char * m_filename = NULL; static char * m_lifilename = NULL; static struct CallbackNode* m_Callbacks = NULL; -static PRBool m_ErrorOpeningUserPrefs = FALSE; -static PRBool m_CallbacksEnabled = FALSE; -static PRBool m_IsAnyPrefLocked = FALSE; +static PRBool m_ErrorOpeningUserPrefs = PR_FALSE; +static PRBool m_CallbacksEnabled = PR_FALSE; +static PRBool m_IsAnyPrefLocked = PR_FALSE; static PRHashTable* m_HashTable = NULL; - -/* LI_STUFF - PREF_LILOCAL here to flag prefs as transferable or not */ -typedef enum { PREF_LOCKED = 1, PREF_USERSET = 2, PREF_CONFIG = 4, - PREF_STRING = 8, PREF_INT = 16, PREF_BOOL = 32, - PREF_LILOCAL = 64 } PrefType; -/* LI_STUFF PREF_SETLI here to flag prefs as transferable or not */ -typedef enum { PREF_SETDEFAULT, PREF_SETUSER, - PREF_LOCK, PREF_SETCONFIG, PREF_SETLI } PrefAction; +static char * m_SavedLine = NULL; #define PREF_IS_LOCKED(pref) ((pref)->flags & PREF_LOCKED) #define PREF_IS_CONFIG(pref) ((pref)->flags & PREF_CONFIG) #define PREF_HAS_USER_VALUE(pref) ((pref)->flags & PREF_USERSET) #define PREF_HAS_LI_VALUE(pref) ((pref)->flags & PREF_LILOCAL) /* LI_STUFF */ +#define PREF_TYPE(pref) (PrefType)((pref)->flags & PREF_VALUETYPE_MASK) typedef union { @@ -112,6 +106,7 @@ typedef struct } PrefNode; static JSBool pref_HashJSPref(unsigned int argc, jsval *argv, PrefAction action); +static XP_Bool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type); /* Hash table allocation */ PR_IMPLEMENT(void *) @@ -168,19 +163,24 @@ struct CallbackNode { }; /* -- Prototypes */ -int pref_DoCallback(const char* changed_pref); -int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash, PRBool bGlobalContext); +PrefResult pref_DoCallback(const char* changed_pref); +PrefResult pref_OpenFile( + const char* filename, + PRBool is_error_fatal, + PRBool verifyHash, + PRBool bGlobalContext, + PRBool skipFirstLine); PRBool pref_VerifyLockFile(char* buf, long buflen); -int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default); -int pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default); -int pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default); -int pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default); +PrefResult pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default); +PrefResult pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default); +PrefResult pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default); +PrefResult pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default); JSBool PR_CALLBACK pref_BranchCallback(JSContext *cx, JSScript *script); void pref_ErrorReporter(JSContext *cx, const char *message,JSErrorReport *report); void pref_Alert(char* msg); -int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action); +PrefResult pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action); /* -- Platform specific function extern */ #if !defined(XP_WIN) && !defined(XP_OS2) @@ -233,12 +233,17 @@ static JSClass autoconf_class = { JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub }; -int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash, PRBool bGlobalContext) +PrefResult pref_OpenFile( + const char* filename, + PRBool is_error_fatal, + PRBool verifyHash, + PRBool bGlobalContext, + PRBool skipFirstLine) { - int ok = PREF_ERROR; + PrefResult ok = PREF_ERROR; FILE *fp; struct stat stats; - long fileLength; + size_t fileLength; stats.st_size = 0; if ( stat(filename, (struct stat *) &stats) == -1 ) @@ -254,12 +259,12 @@ int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash if (readBuf) { fileLength = fread(readBuf, sizeof(char), fileLength, fp); - if ( verifyHash && pref_VerifyLockFile(readBuf, fileLength) == FALSE ) + if ( verifyHash && pref_VerifyLockFile(readBuf, fileLength) == PR_FALSE ) { ok = PREF_BAD_LOCKFILE; } else if ( PREF_EvaluateConfigScript(readBuf, fileLength, - filename, bGlobalContext, FALSE ) == JS_TRUE ) + filename, bGlobalContext, PR_FALSE, skipFirstLine ) == JS_TRUE ) { ok = PREF_NOERROR; } @@ -270,7 +275,7 @@ int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash /* If the user prefs file exists but generates an error, don't clobber the file when we try to save it. */ if ((!readBuf || ok != PREF_NOERROR) && is_error_fatal) - m_ErrorOpeningUserPrefs = TRUE; + m_ErrorOpeningUserPrefs = PR_TRUE; #ifdef XP_PC if (m_ErrorOpeningUserPrefs && is_error_fatal) MessageBox(NULL,"Error in preference file (prefs.js). Default preferences will be used.","Netscape - Warning", MB_OK); @@ -287,14 +292,14 @@ int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash PRBool pref_VerifyLockFile(char* buf, long buflen) { #ifndef NO_SECURITY - PRBool success = FALSE; + PRBool success = PR_FALSE; const int obscure_value = 7; const long hash_length = 51; /* len = 48 chars of MD5 + // + EOL */ unsigned char digest[16]; char szHash[64]; /* Unobscure file by subtracting some value from every char. */ - unsigned int i; + long i; for (i = 0; i < buflen; i++) { buf[i] -= obscure_value; } @@ -328,43 +333,43 @@ PRBool pref_VerifyLockFile(char* buf, long buflen) #else /* * Should return 'success', but since the MD5 code is stubbed out, - * just return 'TRUE' until we have a replacement. + * just return 'PR_TRUE' until we have a replacement. */ - return TRUE; + return PR_TRUE; #endif } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ReadLIJSFile(char *filename) { - int ok; + PrefResult ok; if (filename) m_lifilename = strdup(filename); - ok = pref_OpenFile(filename, FALSE, FALSE, FALSE); + ok = pref_OpenFile(filename, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ReadUserJSFile(char *filename) { - int ok = pref_OpenFile(filename, FALSE, FALSE, TRUE); + PrefResult ok = pref_OpenFile(filename, PR_FALSE, PR_FALSE, PR_TRUE, PR_FALSE); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PRBool) PREF_Init(char *filename) { - JSBool ok = JS_TRUE; + PRBool ok = PR_TRUE; /* --ML hash test */ if (!m_HashTable) m_HashTable = PR_NewHashTable(2048, PR_HashString, PR_CompareStrings, PR_CompareValues, &pref_HashAllocOps, NULL); if (!m_HashTable) - return 0; + return PR_FALSE; if (filename) { if (m_filename) /* happens if PREF_Init is called twice (it is) */ @@ -378,7 +383,7 @@ PREF_Init(char *filename) if (!m_mochaContext) { m_mochaContext = JS_NewContext(m_mochaTaskState, 8192); /* ???? What size? */ if (!m_mochaContext) { - return 0; + return PR_FALSE; } JS_BeginRequest(m_mochaContext); @@ -386,7 +391,7 @@ PREF_Init(char *filename) m_GlobalConfigObject = JS_NewObject(m_mochaContext, &global_class, NULL, NULL); if (!m_GlobalConfigObject) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } /* MLM - need a global object for set version call now. */ @@ -397,7 +402,7 @@ PREF_Init(char *filename) if (!JS_InitStandardClasses(m_mochaContext, m_GlobalConfigObject)) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } JS_SetBranchCallback(m_mochaContext, pref_BranchCallback); @@ -415,14 +420,14 @@ PREF_Init(char *filename) m_mochaPrefObject, autoconf_props)) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } if (!JS_DefineFunctions(m_mochaContext, m_mochaPrefObject, autoconf_methods)) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } } @@ -435,19 +440,19 @@ PREF_Init(char *filename) } if (ok && filename) { - ok = (JSBool) (pref_OpenFile(filename, TRUE, FALSE, FALSE) == PREF_NOERROR); + ok = (JSBool) (pref_OpenFile(filename, PR_TRUE, PR_FALSE, PR_FALSE, PR_TRUE) == PREF_NOERROR); } else if (!ok) { - m_ErrorOpeningUserPrefs = TRUE; + m_ErrorOpeningUserPrefs = PR_TRUE; } JS_EndRequest(m_mochaContext); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigContext(JSContext **js_context) { - if (!js_context) return FALSE; + if (!js_context) return PREF_ERROR; *js_context = NULL; if (m_mochaContext) { @@ -455,31 +460,31 @@ PREF_GetConfigContext(JSContext **js_context) JS_SetContextThread(m_mochaContext); } - return TRUE; + return PREF_NOERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetGlobalConfigObject(JSObject **js_object) { - if (!js_object) return FALSE; + if (!js_object) return PREF_ERROR; *js_object = NULL; if (m_GlobalConfigObject) *js_object = m_GlobalConfigObject; - return TRUE; + return PREF_NOERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetPrefConfigObject(JSObject **js_object) { - if (!js_object) return FALSE; + if (!js_object) return PREF_ERROR; *js_object = NULL; if (m_mochaPrefObject) *js_object = m_mochaPrefObject; - return TRUE; + return PREF_NOERROR; } /* Frees the callback list. */ @@ -504,11 +509,11 @@ PREF_Cleanup() PR_HashTableDestroy(m_HashTable); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ReadLockFile(const char *filename) { /* - return pref_OpenFile(filename, FALSE, FALSE, TRUE); + return pref_OpenFile(filename, PR_FALSE, PR_FALSE, PR_TRUE); Lock files are obscured, and the security code to read them has been removed from the free source. So don't even try to read one. @@ -518,10 +523,16 @@ PREF_ReadLockFile(const char *filename) return PREF_ERROR; } +void PREF_SetCallbacksStatus( PRBool status ) +{ + m_CallbacksEnabled = status; +} + /* This is more recent than the below 3 routines which should be obsoleted */ PR_IMPLEMENT(JSBool) PREF_EvaluateConfigScript(const char * js_buffer, size_t length, - const char* filename, PRBool bGlobalContext, PRBool bCallbacks) + const char* filename, PRBool bGlobalContext, PRBool bCallbacks, + PRBool skipFirstLine) { JSBool ok; jsval result; @@ -540,28 +551,54 @@ PREF_EvaluateConfigScript(const char * js_buffer, size_t length, errReporter = JS_SetErrorReporter(m_mochaContext, pref_ErrorReporter); m_CallbacksEnabled = bCallbacks; + if (skipFirstLine) { + /* In order to protect the privacy of the JavaScript preferences file + * from loading by the browser, we make the first line unparseable + * by JavaScript. We must skip that line here before executing + * the JavaScript code. + */ + unsigned int i=0; + while (i < length) { + char c = js_buffer[i++]; + if (c == '\r') { + if (js_buffer[i] == '\n') + i++; + break; + } + if (c == '\n') + break; + } + m_SavedLine = malloc(i+1); + if (!m_SavedLine) + return JS_FALSE; + memcpy(m_SavedLine, js_buffer, i); + m_SavedLine[i] = '\0'; + length -= i; + js_buffer += i; + } + ok = JS_EvaluateScript(m_mochaContext, scope, js_buffer, length, filename, 0, &result); - m_CallbacksEnabled = TRUE; /* ?? want to enable after reading user/lock file */ + m_CallbacksEnabled = PR_TRUE; /* ?? want to enable after reading user/lock file */ JS_SetErrorReporter(m_mochaContext, errReporter); JS_EndRequest(m_mochaContext); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(JSBool) PREF_EvaluateJSBuffer(const char * js_buffer, size_t length) { /* old routine that no longer triggers callbacks */ - int ret; + JSBool ret; ret = PREF_QuietEvaluateJSBuffer(js_buffer, length); return ret; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(JSBool) PREF_QuietEvaluateJSBuffer(const char * js_buffer, size_t length) { JSBool ok; @@ -579,7 +616,7 @@ PREF_QuietEvaluateJSBuffer(const char * js_buffer, size_t length) return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(JSBool) PREF_QuietEvaluateJSBufferWithGlobalScope(const char * js_buffer, size_t length) { JSBool ok; @@ -626,9 +663,9 @@ static char * str_escape(const char * original) { } /* -// External calls - */ -PR_IMPLEMENT(int) +** External calls +*/ +PR_IMPLEMENT(PrefResult) PREF_SetCharPref(const char *pref_name, const char *value) { PrefValue pref; @@ -637,7 +674,7 @@ PREF_SetCharPref(const char *pref_name, const char *value) return pref_HashPref(pref_name, pref, PREF_STRING, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetIntPref(const char *pref_name, int32 value) { PrefValue pref; @@ -646,7 +683,7 @@ PREF_SetIntPref(const char *pref_name, int32 value) return pref_HashPref(pref_name, pref, PREF_INT, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetBoolPref(const char *pref_name, PRBool value) { PrefValue pref; @@ -655,7 +692,7 @@ PREF_SetBoolPref(const char *pref_name, PRBool value) return pref_HashPref(pref_name, pref, PREF_BOOL, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetBinaryPref(const char *pref_name, void * value, long size) { char* buf = PL_Base64Encode(value, size, NULL); @@ -669,7 +706,7 @@ PREF_SetBinaryPref(const char *pref_name, void * value, long size) return PREF_ERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue) { char colstr[63]; @@ -684,7 +721,7 @@ PREF_SetColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue) #define MYGetGValue(rgb) ((uint8) (((uint16) (rgb)) >> 8)) #define MYGetRValue(rgb) ((uint8) (rgb)) -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetColorPrefDWord(const char *pref_name, uint32 colorref) { int red,green,blue; @@ -700,7 +737,7 @@ PREF_SetColorPrefDWord(const char *pref_name, uint32 colorref) return pref_HashPref(pref_name, pref, PREF_STRING, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom) { char rectstr[63]; @@ -712,9 +749,9 @@ PREF_SetRectPref(const char *pref_name, int16 left, int16 top, int16 right, int1 } /* -// DEFAULT VERSIONS: Call internal with (set_default == TRUE) - */ -PR_IMPLEMENT(int) +** DEFAULT VERSIONS: Call internal with (set_default == PR_TRUE) +*/ +PR_IMPLEMENT(PrefResult) PREF_SetDefaultCharPref(const char *pref_name,const char *value) { PrefValue pref; @@ -724,7 +761,7 @@ PREF_SetDefaultCharPref(const char *pref_name,const char *value) } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultIntPref(const char *pref_name,int32 value) { PrefValue pref; @@ -733,7 +770,7 @@ PREF_SetDefaultIntPref(const char *pref_name,int32 value) return pref_HashPref(pref_name, pref, PREF_INT, PREF_SETDEFAULT); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultBoolPref(const char *pref_name,PRBool value) { PrefValue pref; @@ -742,7 +779,7 @@ PREF_SetDefaultBoolPref(const char *pref_name,PRBool value) return pref_HashPref(pref_name, pref, PREF_BOOL, PREF_SETDEFAULT); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultBinaryPref(const char *pref_name,void * value,long size) { char* buf = PL_Base64Encode(value, size, NULL); @@ -755,7 +792,7 @@ PREF_SetDefaultBinaryPref(const char *pref_name,void * value,long size) return PREF_ERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue) { char colstr[63]; @@ -764,7 +801,7 @@ PREF_SetDefaultColorPref(const char *pref_name, uint8 red, uint8 green, uint8 bl return PREF_SetDefaultCharPref(pref_name, colstr); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom) { char rectstr[63]; @@ -780,7 +817,10 @@ pref_saveLIPref(PRHashEntry *he, int i, void *arg) { char **prefArray = (char**) arg; PrefNode *pref = (PrefNode *) he->value; - if (pref && PREF_HAS_USER_VALUE(pref) && !PREF_HAS_LI_VALUE(pref)) { + if (pref && PREF_HAS_USER_VALUE(pref) && !PREF_HAS_LI_VALUE(pref) && + pref_ValueChanged(pref->defaultPref, + pref->userPref, + (PrefType) PREF_TYPE(pref))) { char buf[2048]; if (pref->flags & PREF_STRING) { @@ -833,7 +873,14 @@ pref_savePref(PRHashEntry *he, int i, void *arg) char **prefArray = (char**) arg; PrefNode *pref = (PrefNode *) he->value; - if (pref && PREF_HAS_USER_VALUE(pref)) { + PR_ASSERT(pref); + if (!pref) + return 0; + + if (PREF_HAS_USER_VALUE(pref) && + pref_ValueChanged(pref->defaultPref, + pref->userPref, + (PrefType) PREF_TYPE(pref))) { char buf[2048]; if (pref->flags & PREF_STRING) { @@ -910,12 +957,12 @@ This is called by them and does the right thing. #define PREF_FILE_BANNER "// Netscape User Preferences" LINEBREAK \ "// This is a generated file! Do not edit." LINEBREAK LINEBREAK -PR_IMPLEMENT(int) -PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { - int success = PREF_ERROR; +PR_IMPLEMENT(PrefResult) +PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) +{ + PrefResult success = PREF_ERROR; FILE * fp; char **valueArray = NULL; - int valueIdx; if (!m_HashTable) return PREF_NOT_INITIALIZED; @@ -933,14 +980,16 @@ PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { return PREF_OUT_OF_MEMORY; fp = fopen(filename, "w"); - if (fp) { + if (fp) + { + PRUint32 valueIdx; fwrite(PREF_FILE_BANNER, sizeof(char), PL_strlen(PREF_FILE_BANNER), fp); /* LI_STUFF here we pass in the heSaveProc proc used so that li can do its own thing */ PR_HashTableEnumerateEntries(m_HashTable, heSaveProc, valueArray); /* Sort the preferences to make a readable file on disk */ - XP_QSORT (valueArray, m_HashTable->nentries, sizeof(char*), pref_CompareStrings); + XP_QSORT(valueArray, m_HashTable->nentries, sizeof(char*), pref_CompareStrings); for (valueIdx = 0; valueIdx < m_HashTable->nentries; valueIdx++) { if (valueArray[valueIdx]) @@ -955,7 +1004,7 @@ PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { success = PREF_NOERROR; } else - success = errno; + success = (PrefResult)errno; /* Really? */ PR_Free(valueArray); @@ -963,33 +1012,116 @@ PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SavePrefFile() { - if (!m_HashTable) +#if 0// defined(XP_MAC) || defined(XP_PC) + return (PrefResult)pref_SaveProfile(); +#else + if (!m_HashTable) return PREF_NOT_INITIALIZED; - return (PREF_SavePrefFileWith(m_filename, pref_savePref)); + + return (PREF_SavePrefFileWith(m_filename, pref_savePref)); +#endif } -/* LI_STUFF Create a saveprefFile for LI for outsiders to call */ -PR_IMPLEMENT(int) +/* + * We need to flag a bunch of prefs as local that aren't initialized via all.js. + * This seems the safest way to do this. + */ +PR_IMPLEMENT(PrefResult) +PREF_SetSpecialPrefsLocal(void) +{ + static char *prefName[] = { + "ab_dir.outliner_geometry", + "addressbook.outliner_geometry", + "bookmarks.outliner_geometry", + "browser.bookmark_columns_win", + "browser.history_file", + "browser.sarcache.directory", + "browser.user_history_file", + "browser.win_height", + "browser.win_width", + "category.thread_columns_win", + "comppicker.outliner_geometry", + "editor.html_editor", + "editor.template_history_0", + "editor.template_last_loc", + "editor.win_height", + "editor.win_width", + "helpers.global_mailcap_file", + "helpers.global_mime_types_file", + "helpers.private_mailcap_file", + "helpers.private_mime_types_file", + "history.outliner_geometry", + "intl.font_charset", + "intl.font_spec_list", + "mail.addr_book.sliderwidth", + "mail.addr_picker.sliderwidth", + "mail.compose.win_height", + "mail.compose.win_width", + "mail.composition.addresspane.outliner_geometry", + "mail.folder.win_height", + "mail.folder.win_width", + "mail.folderpane.outliner_geometry", + "mail.imap.root_dir", + "mail.mailfilter.outliner_geometry", + "mail.msg.win_height", + "mail.msg.win_width", + "mail.subscribepane.all_groups.outliner_geometry", + "mail.subscribepane.new_groups.outliner_geometry", + "mail.subscribepane.search_groups.outliner_geometry", + "mail.thread.win_height", + "mail.thread.win_width", + "mail.thread_columns_win", + "mail.threadpane.messagepane_height", + "mail.threadpane.outliner_geometry", + "mailnews.3Pane_folder_columns_win", + "mailnews.3pane_folder_width", + "mailnews.3pane_thread_height", + "mailnews.abook_columns_win", + "mailnews.folder_columns_win", + "mailnews.ldapsearch_columns_win", + "news.thread_columns_win", + "preferences.lang.outliner_geometry", + "profile.name", + "profile.numprofiles", + "taskbar.x", + "taskbar.y", + "profile.directory" + }; + PrefNode* pref; + int i; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + for (i = 0; i < (sizeof(prefName)/sizeof(prefName[0])); i++) { + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, prefName[i]); + if (pref) + pref->flags |= PREF_LILOCAL; + } + return PREF_OK; +} + +PR_IMPLEMENT(PrefResult) PREF_SaveLIPrefFile(const char *filename) { if (!m_HashTable) return PREF_NOT_INITIALIZED; + PREF_SetSpecialPrefsLocal(); return (PREF_SavePrefFileWith(((filename) ? filename : m_lifilename), pref_saveLIPref)); } -/* LI_STUFF pass in the pref_savePref proc used instead of assuming it so that li can share that code too */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SavePrefFileAs(const char *filename) { return PREF_SavePrefFileWith(filename, pref_savePref); } -int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default) +PrefResult pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; char* stringVal; PrefNode* pref; @@ -999,17 +1131,19 @@ int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); - if (pref) { + if (pref) + { if (get_default || PREF_IS_LOCKED(pref) || !PREF_HAS_USER_VALUE(pref)) stringVal = pref->defaultPref.stringVal; else stringVal = pref->userPref.stringVal; - if (stringVal) { - if (*length == 0) { + if (stringVal) + { + if (*length == 0) *length = strlen(stringVal) + 1; - } - else { + else + { PL_strncpy(return_buffer, stringVal, PR_MIN(*length - 1, strlen(stringVal) + 1)); return_buffer[*length - 1] = '\0'; } @@ -1019,9 +1153,9 @@ int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, return result; } -int pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default) +PrefResult pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; char* stringVal; PrefNode* pref; @@ -1044,9 +1178,9 @@ int pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_d return result; } -int pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default) +PrefResult pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; PrefNode* pref; if (!m_HashTable) @@ -1063,9 +1197,9 @@ int pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default return result; } -int pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default) +PrefResult pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; PrefNode* pref; if (!m_HashTable) @@ -1083,37 +1217,37 @@ int pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_d } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetCharPref(const char *pref_name, char * return_buffer, int * length) { - return pref_GetCharPref(pref_name, return_buffer, length, FALSE); + return pref_GetCharPref(pref_name, return_buffer, length, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyCharPref(const char *pref_name, char ** return_buffer) { - return pref_CopyCharPref(pref_name, return_buffer, FALSE); + return pref_CopyCharPref(pref_name, return_buffer, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetIntPref(const char *pref_name,int32 * return_int) { - return pref_GetIntPref(pref_name, return_int, FALSE); + return pref_GetIntPref(pref_name, return_int, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetBoolPref(const char *pref_name, XP_Bool * return_value) { - return pref_GetBoolPref(pref_name, return_value, FALSE); + return pref_GetBoolPref(pref_name, return_value, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue) { char colstr[8]; int iSize = 8; - int result = PREF_GetCharPref(pref_name, colstr, &iSize); + PrefResult result = PREF_GetCharPref(pref_name, colstr, &iSize); if (result == PREF_NOERROR) { int r, g, b; @@ -1128,32 +1262,29 @@ PREF_GetColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue) #define MYRGB(r, g ,b) ((uint32) (((uint8) (r) | ((uint16) (g) << 8)) | (((uint32) (uint8) (b)) << 16))) -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetColorPrefDWord(const char *pref_name, uint32 *colorref) { - char colstr[8]; - int iSize = 8; - uint8 red=0, green=0, blue=0; + uint8 red, green, blue; + PrefResult result; + + PR_ASSERT(colorref); + + result = PREF_GetColorPref(pref_name, &red, &green, &blue); + + if (result == PREF_NOERROR) { + *colorref = MYRGB(red,green,blue); + } - int result = PREF_GetCharPref(pref_name, colstr, &iSize); - - if (result == 0) { - int r, g, b; - sscanf(colstr, "#%02X%02X%02X", &r, &g, &b); - red = r; - green = g; - blue = b; - } - *colorref = MYRGB(red,green,blue); return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom) { char rectstr[64]; int iSize=64; - int result = PREF_GetCharPref(pref_name, rectstr, &iSize); + PrefResult result = PREF_GetCharPref(pref_name, rectstr, &iSize); if (result == PREF_NOERROR) { int l, t, r, b; @@ -1164,20 +1295,20 @@ PREF_GetRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, i return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetBinaryPref(const char *pref_name, void * return_value, int *size) { char* buf; - int result; + PrefResult result; - if (!m_mochaPrefObject || !return_value) return -1; + if (!m_mochaPrefObject || !return_value) return PREF_ERROR; result = PREF_CopyCharPref(pref_name, &buf); if (result == PREF_NOERROR) { if (strlen(buf) == 0) { /* don't decode empty string ? */ PR_Free(buf); - return -1; + return PREF_ERROR; } PL_Base64Decode(buf, *size, return_value); @@ -1187,16 +1318,16 @@ PREF_GetBinaryPref(const char *pref_name, void * return_value, int *size) return result; } -typedef int (*CharPrefReadFunc)(const char*, char**); +typedef PrefResult (*CharPrefReadFunc)(const char*, char**); -static int +static PrefResult ReadCharPrefUsing(const char *pref_name, void** return_value, int *size, CharPrefReadFunc inFunc) { char* buf; - int result; + PrefResult result; if (!m_mochaPrefObject || !return_value) - return -1; + return PREF_ERROR; *return_value = NULL; result = inFunc(pref_name, &buf); @@ -1204,7 +1335,7 @@ ReadCharPrefUsing(const char *pref_name, void** return_value, int *size, CharPre if (result == PREF_NOERROR) { if (strlen(buf) == 0) { /* do not decode empty string? */ PR_Free(buf); - return -1; + return PREF_ERROR; } *return_value = PL_Base64Decode(buf, 0, NULL); @@ -1215,26 +1346,26 @@ ReadCharPrefUsing(const char *pref_name, void** return_value, int *size, CharPre return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyBinaryPref(const char *pref_name, void ** return_value, int *size) { return ReadCharPrefUsing(pref_name, return_value, size, PREF_CopyCharPref); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyDefaultBinaryPref(const char *pref_name, void ** return_value, int *size) { return ReadCharPrefUsing(pref_name, return_value, size, PREF_CopyDefaultCharPref); } #ifndef XP_MAC -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyPathPref(const char *pref_name, char ** return_buffer) { return PREF_CopyCharPref(pref_name, return_buffer); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default) { PrefAction action = set_default ? PREF_SETDEFAULT : PREF_SETUSER; @@ -1246,44 +1377,44 @@ PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default) #endif /* XP_MAC */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultCharPref(const char *pref_name, char * return_buffer, int * length) { - return pref_GetCharPref(pref_name, return_buffer, length, TRUE); + return pref_GetCharPref(pref_name, return_buffer, length, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyDefaultCharPref(const char *pref_name, char ** return_buffer) { - return pref_CopyCharPref(pref_name, return_buffer, TRUE); + return pref_CopyCharPref(pref_name, return_buffer, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultIntPref(const char *pref_name, int32 * return_int) { - return pref_GetIntPref(pref_name, return_int, TRUE); + return pref_GetIntPref(pref_name, return_int, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultBoolPref(const char *pref_name, XP_Bool * return_value) { - return pref_GetBoolPref(pref_name, return_value, TRUE); + return pref_GetBoolPref(pref_name, return_value, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultBinaryPref(const char *pref_name, void * return_value, int * length) { - PR_ASSERT( FALSE ); - return TRUE; + PR_ASSERT( PR_FALSE ); + return PREF_ERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue) { char colstr[8]; int iSize = 8; - int result = PREF_GetDefaultCharPref(pref_name, colstr, &iSize); + PrefResult result = PREF_GetDefaultCharPref(pref_name, colstr, &iSize); if (result == PREF_NOERROR) { int r, g, b; @@ -1296,32 +1427,29 @@ PREF_GetDefaultColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultColorPrefDWord(const char *pref_name, uint32 * colorref) { - char colstr[8]; - int iSize = 8; - uint8 red=0, green=0, blue=0; + uint8 red, green, blue; + PrefResult result; + + PR_ASSERT(colorref); + + result = PREF_GetDefaultColorPref(pref_name, &red, &green, &blue); + + if (result == PREF_NOERROR) { + *colorref = MYRGB(red,green,blue); + } - int result = PREF_GetDefaultCharPref(pref_name, colstr, &iSize); - - if (result == PREF_NOERROR) { - int r, g, b; - sscanf(colstr, "#%02X%02X%02X", &r, &g, &b); - red = r; - green = g; - blue = b; - } - *colorref = MYRGB(red,green,blue); return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom) { char rectstr[256]; int iLen = 256; - int result = PREF_GetDefaultCharPref(pref_name, (char *)&rectstr, &iLen); + PrefResult result = PREF_GetDefaultCharPref(pref_name, (char *)&rectstr, &iLen); if (result == PREF_NOERROR) { sscanf(rectstr, "%d,%d,%d,%d", left, top, right, bottom); @@ -1345,7 +1473,7 @@ pref_DeleteItem(PRHashEntry *he, int i, void *arg) return HT_ENUMERATE_NEXT; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_DeleteBranch(const char *branch_name) { char* branch_dot = PR_smprintf("%s.", branch_name); @@ -1355,17 +1483,22 @@ PREF_DeleteBranch(const char *branch_name) PR_HashTableEnumerateEntries(m_HashTable, pref_DeleteItem, (void*) branch_dot); PR_Free(branch_dot); - return 0; + return PREF_NOERROR; } /* LI_STUFF add a function to clear the li pref does anyone use this?? */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ClearLIPref(const char *pref_name) { - int success = PREF_ERROR; - PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); + PrefResult success = PREF_ERROR; + PrefNode* pref; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); if (pref && PREF_HAS_LI_VALUE(pref)) { pref->flags &= ~PREF_LILOCAL; if (m_CallbacksEnabled) @@ -1377,11 +1510,16 @@ PREF_ClearLIPref(const char *pref_name) -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ClearUserPref(const char *pref_name) { - int success = PREF_ERROR; - PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); + PrefResult success = PREF_ERROR; + PrefNode* pref; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); if (pref && PREF_HAS_USER_VALUE(pref)) { pref->flags &= ~PREF_USERSET; if (m_CallbacksEnabled) @@ -1392,21 +1530,21 @@ PREF_ClearUserPref(const char *pref_name) } /* Prototype Admin Kit support */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigString(const char *obj_name, char * return_buffer, int size, int index, const char *field) { - PR_ASSERT( FALSE ); - return -1; + PR_ASSERT( PR_FALSE ); + return PREF_ERROR; } /* * Administration Kit support */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyConfigString(const char *obj_name, char **return_buffer) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, obj_name); if (pref && pref->flags & PREF_STRING) { @@ -1417,11 +1555,11 @@ PREF_CopyConfigString(const char *obj_name, char **return_buffer) return success; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyIndexConfigString(const char *obj_name, int index, const char *field, char **return_buffer) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref; char* setup_buf = PR_smprintf("%s_%d.%s", obj_name, index, field); @@ -1436,10 +1574,10 @@ PREF_CopyIndexConfigString(const char *obj_name, return success; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigInt(const char *obj_name, int32 *return_int) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, obj_name); @@ -1451,10 +1589,10 @@ PREF_GetConfigInt(const char *obj_name, int32 *return_int) return success; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigBool(const char *obj_name, XP_Bool *return_bool) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, obj_name); @@ -1466,35 +1604,72 @@ PREF_GetConfigBool(const char *obj_name, XP_Bool *return_bool) return success; } +PrefResult pref_UnlockPref(const char *key) +{ + PrefNode* pref; + PrefResult result = PREF_OK; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, key); + if (!pref) { + return PREF_DOES_NOT_EXIST; + } + + if (PREF_IS_LOCKED(pref)) { + pref->flags &= ~PREF_LOCKED; + if (m_CallbacksEnabled) { + pref_DoCallback(key); + } + } + + return PREF_OK; +} + +PrefResult pref_LockPref(const char *key) +{ + PrefNode* pref; + PrefResult result = PREF_OK; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, key); + if (!pref) { + return PREF_DOES_NOT_EXIST; + } + + + return pref_HashPref(key, pref->defaultPref, (PrefType)pref->flags, PREF_LOCK); +} + +PR_IMPLEMENT(PrefResult) +PREF_LockPref(const char *key) +{ + return pref_LockPref(key); +} + /* * Hash table functions */ -static PRBool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type) +static XP_Bool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type) { - PRBool changed = TRUE; - switch (type) { - case PREF_STRING: - if (oldValue.stringVal && newValue.stringVal) - changed = (strcmp(oldValue.stringVal, newValue.stringVal) != 0); - break; - - case PREF_INT: - changed = oldValue.intVal != newValue.intVal; - break; - - case PREF_BOOL: - changed = oldValue.boolVal != newValue.boolVal; - break; - default: - /* PREF_LOCKED, PREF_USERSET, PREF_CONFIG, PREF_LILOCAL */ - break; - } + PRBool changed = PR_TRUE; + if (type & PREF_STRING) { + if (oldValue.stringVal && newValue.stringVal) + changed = (strcmp(oldValue.stringVal, newValue.stringVal) != 0); + } else if (type & PREF_INT) { + changed = oldValue.intVal != newValue.intVal; + } else if (type & PREF_BOOL) { + changed = oldValue.boolVal != newValue.boolVal; + } return changed; } static void pref_SetValue(PrefValue* oldValue, PrefValue newValue, PrefType type) { - switch (type) { + switch (type & PREF_VALUETYPE_MASK) { case PREF_STRING: PR_ASSERT(newValue.stringVal); PR_FREEIF(oldValue->stringVal); @@ -1506,10 +1681,10 @@ static void pref_SetValue(PrefValue* oldValue, PrefValue newValue, PrefType type } } -int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action) +PrefResult pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action) { PrefNode* pref; - int result = PREF_OK; + PrefResult result = PREF_OK; if (!m_HashTable) return PREF_NOT_INITIALIZED; @@ -1528,7 +1703,7 @@ int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction ac pref->defaultPref.intVal = (int32) -5632; PR_HashTableAdd(m_HashTable, PL_strdup(key), pref); } - else if (!(pref->flags & type)) { + else if ((pref->flags & PREF_VALUETYPE_MASK) != (type & PREF_VALUETYPE_MASK)) { PR_ASSERT(0); /* this shouldn't happen */ return PREF_TYPE_CHANGE_ERR; } @@ -1586,19 +1761,19 @@ int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction ac result = PREF_VALUECHANGED; } pref->flags |= PREF_LOCKED; - m_IsAnyPrefLocked = TRUE; + m_IsAnyPrefLocked = PR_TRUE; break; } if (result == PREF_VALUECHANGED && m_CallbacksEnabled) { - int result2 = pref_DoCallback(key); + PrefResult result2 = pref_DoCallback(key); if (result2 < 0) result = result2; } return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefType) PREF_GetPrefType(const char *pref_name) { PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); @@ -1610,7 +1785,7 @@ PREF_GetPrefType(const char *pref_name) else if (pref->flags & PREF_BOOL) return PREF_BOOL; } - return PREF_ERROR; + return PREF_INVALID; } JSBool PR_CALLBACK pref_NativeDefaultPref @@ -1691,7 +1866,7 @@ JSBool PR_CALLBACK pref_NativeGetPref { void* value = NULL; PrefNode* pref; - PRBool prefExists = TRUE; + PRBool prefExists = PR_TRUE; if (argc >= 1 && JSVAL_IS_STRING(argv[0])) { @@ -1721,11 +1896,11 @@ JSBool PR_CALLBACK pref_NativeGetPref PR_IMPLEMENT(PRBool) PREF_PrefIsLocked(const char *pref_name) { - PRBool result = FALSE; + PRBool result = PR_FALSE; if (m_IsAnyPrefLocked) { PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); if (pref && PREF_IS_LOCKED(pref)) - result = TRUE; + result = PR_TRUE; } return result; @@ -1755,7 +1930,7 @@ pref_addChild(PRHashEntry *he, int i, void *arg) char* nextdelim; int parentlen = strlen(pcs->parent); char* substring; - PRBool substringBordersSeparator = FALSE; + PRBool substringBordersSeparator = PR_FALSE; strncpy(buf, he->key, PR_MIN(512, strlen(he->key) + 1)); nextdelim = buf + parentlen; @@ -1794,7 +1969,7 @@ pref_addChild(PRHashEntry *he, int i, void *arg) return 0; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CreateChildList(const char* parent_node, char **child_list) { PrefChildIter pcs; @@ -1805,7 +1980,10 @@ PREF_CreateChildList(const char* parent_node, char **child_list) pcs.bufsize = 2048; #endif pcs.childList = (char*) malloc(sizeof(char) * pcs.bufsize); - pcs.parent = PR_smprintf("%s.", parent_node); + if (*parent_node > 0) + pcs.parent = PR_smprintf("%s.", parent_node); + else + pcs.parent = PL_strdup(""); if (!pcs.parent || !pcs.childList) return PREF_OUT_OF_MEMORY; pcs.childList[0] = '\0'; @@ -1826,7 +2004,7 @@ PREF_NextChild(char *child_list, int *index) *index += strlen(child) + 1; return child; } -#if 0 /* LANDING HACK */ + /*---------------------------------------------------------------------------------------- * pref_copyTree * @@ -1842,25 +2020,25 @@ PREF_NextChild(char *child_list, int *index) * Copy all the prefs under mail. to newmail.: pref_copyTree("mail", "newmail", "mail") * --------------------------------------------------------------------------------------*/ -int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *curSrcBranch) +PrefResult pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *curSrcBranch) { - int result = PREF_NOERROR; + PrefResult result = PREF_NOERROR; char* children = NULL; if ( PREF_CreateChildList(curSrcBranch, &children) == PREF_NOERROR ) { int index = 0; - int srcPrefixLen = XP_STRLEN(srcPrefix); + int srcPrefixLen = PL_strlen(srcPrefix); char* child = NULL; while ( (child = PREF_NextChild(children, &index)) != NULL) { - int prefType; + PrefType prefType; char *destPrefName = NULL; char *childStart = (srcPrefixLen > 0) ? (child + srcPrefixLen + 1) : child; - XP_ASSERT( XP_STRNCMP(child, curSrcBranch, srcPrefixLen) == 0 ); + PR_ASSERT( PL_strncmp(child, curSrcBranch, srcPrefixLen) == 0 ); if (*destPrefix > 0) destPrefName = PR_smprintf("%s.%s", destPrefix, childStart); @@ -1876,7 +2054,7 @@ int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *cur if ( ! PREF_PrefIsLocked(destPrefName) ) /* returns true if the prefs exists, and is locked */ { /* PREF_GetPrefType masks out the other bits of the pref flag, so we only - every get the values in the switch. + ever get the values in the switch. */ prefType = PREF_GetPrefType(child); @@ -1890,7 +2068,7 @@ int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *cur if (result == PREF_NOERROR) result = PREF_SetCharPref(destPrefName, prefVal); - XP_FREEIF(prefVal); + PR_FREEIF(prefVal); } break; @@ -1922,34 +2100,33 @@ int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *cur default: /* we should never get here */ - XP_ASSERT(FALSE); + PR_ASSERT(PR_FALSE); break; } } /* is not locked */ - XP_FREEIF(destPrefName); + PR_FREEIF(destPrefName); /* Recurse */ if (result == PREF_NOERROR || result == PREF_VALUECHANGED) result = pref_copyTree(srcPrefix, destPrefix, child); } - XP_FREE(children); + PR_Free(children); } return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyPrefsTree(const char *srcRoot, const char *destRoot) { - XP_ASSERT(srcRoot != NULL); - XP_ASSERT(destRoot != NULL); + PR_ASSERT(srcRoot != NULL); + PR_ASSERT(destRoot != NULL); return pref_copyTree(srcRoot, destRoot, srcRoot); } -#endif /* LANDING HACK */ /* Adds a node to the beginning of the callback list. */ @@ -1970,12 +2147,12 @@ PREF_RegisterCallback(const char *pref_node, } /* Deletes a node from the callback list. */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_UnregisterCallback(const char *pref_node, PrefChangedFunc callback, void * instance_data) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; struct CallbackNode* node = m_Callbacks; struct CallbackNode* prev_node = NULL; @@ -2003,32 +2180,29 @@ PREF_UnregisterCallback(const char *pref_node, return result; } -int pref_DoCallback(const char* changed_pref) +PrefResult pref_DoCallback(const char* changed_pref) { - int result = PREF_OK; + PrefResult result = PREF_OK; struct CallbackNode* node; for (node = m_Callbacks; node != NULL; node = node->next) { if ( PL_strncmp(changed_pref, node->domain, strlen(node->domain)) == 0 ) { int result2 = (*node->func) (changed_pref, node->data); - if (result2 != PREF_OK) - result = result2; + if (result2 != 0) + result = (PrefResult)result2; } } return result; } /* !! Front ends need to implement */ -#ifndef XP_MAC +#ifndef XP_MAC // see macpref.cp PR_IMPLEMENT(PRBool) PREF_IsAutoAdminEnabled() { - if (m_AutoAdminLib == NULL) - m_AutoAdminLib = pref_LoadAutoAdminLib(); - - return (m_AutoAdminLib != NULL); + return PR_TRUE; } -#endif +#endif // XP_MAC /* Called from JavaScript */ typedef char* (*ldap_func)(char*, char*, char*, char*, char**); @@ -2093,7 +2267,6 @@ JSBool PR_CALLBACK pref_NativeGetLDAPAttr return JS_TRUE; } -/* LI_STUFF ?? add some debugging stuff here. */ /* Dump debugging info in response to about:config. */ PR_IMPLEMENT(int) @@ -2104,28 +2277,36 @@ pref_printDebugInfo(PRHashEntry *he, int i, void *arg) PrefChildIter* pcs = (PrefChildIter*) arg; PrefNode *pref = (PrefNode *) he->value; - if (PREF_HAS_USER_VALUE(pref) && !PREF_IS_LOCKED(pref)) { + PR_ASSERT(pref); + if (!pref) + return PREF_NOERROR; + + if (PREF_HAS_USER_VALUE(pref) && + pref_ValueChanged(pref->defaultPref, + pref->userPref, + (PrefType) PREF_TYPE(pref)) && + !PREF_IS_LOCKED(pref)) + { buf1 = PR_smprintf("%s = ", (char*) he->key); val = pref->userPref; } - else { + else + { buf1 = PR_smprintf("%s = ", PREF_IS_LOCKED(pref) ? "red" : (PREF_IS_CONFIG(pref) ? "black" : "green"), (char*) he->key); val = pref->defaultPref; } - if (pref->flags & PREF_STRING) { + if (pref->flags & PREF_STRING) buf2 = PR_smprintf("%s %s
", buf1, val.stringVal); - } - else if (pref->flags & PREF_INT) { + else if (pref->flags & PREF_INT) buf2 = PR_smprintf("%s %d

", buf1, val.intVal); - } - else if (pref->flags & PREF_BOOL) { + else if (pref->flags & PREF_BOOL) buf2 = PR_smprintf("%s %s
", buf1, val.boolVal ? "true" : "false"); - } - if ((PL_strlen(buf2) + PL_strlen(pcs->childList) + 1) > pcs->bufsize) { + if ((PL_strlen(buf2) + PL_strlen(pcs->childList) + 1) > pcs->bufsize) + { pcs->bufsize *= 3; pcs->childList = (char*) realloc(pcs->childList, sizeof(char) * pcs->bufsize); if (!pcs->childList) @@ -2291,18 +2472,18 @@ pref_LoadAutoAdminLib() { if (getenv("MOZILLA_HOME")) { - strcpy(aalib, getenv("MOZILLA_HOME")); - lib = PR_LoadLibrary(strcat(aalib, ADMNLIBNAME)); + PL_strcpy(aalib, getenv("MOZILLA_HOME")); + lib = PR_LoadLibrary(PL_strcat(aalib, ADMNLIBNAME)); } if (lib == NULL) { fe_GetProgramDirectory(aalib, sizeof(aalib)-1); - lib = PR_LoadLibrary(strcat(aalib, ADMNLIBNAME)); + lib = PR_LoadLibrary(PL_strcat(aalib, ADMNLIBNAME)); } if (lib == NULL) { - (void) strcpy(aalib, "/usr/local/netscape/"); - lib = PR_LoadLibrary(strcat(aalib, ADMNLIBNAME)); + (void) PL_strcpy(aalib, "/usr/local/netscape/"); + lib = PR_LoadLibrary(PL_strcat(aalib, ADMNLIBNAME)); } } } @@ -2378,4 +2559,153 @@ static JSBool pref_HashJSPref(unsigned int argc, jsval *argv, PrefAction action) return JS_TRUE; } +/* + * pref_CountListMembers + */ +static int +pref_CountListMembers(char* list) +{ + int members = 0; + char* p = list = PL_strdup(list); + for ( p = strtok(p, ","); p != NULL; p = strtok(NULL, ",") ) { + members++; + } + + PR_FREEIF(list); + + return members; +} + + +/* + * PREF_GetListPref + * Splits a comma separated strings into an array of strings. + * The array of strings is actually just an array of pointers into a copy + * of the value returned by PREF_CopyCharPref(). So, we don't have to + * allocate each string separately. + */ +PR_IMPLEMENT(PrefResult) +PREF_GetListPref(const char* pref, char*** list) +{ + char* value; + char** p; + int num_members; + + *list = NULL; + + if ( PREF_CopyCharPref(pref, &value) != PREF_OK || value == NULL ) { + return PREF_ERROR; + } + + num_members = pref_CountListMembers(value); + + p = *list = (char**) PR_MALLOC((num_members+1) * sizeof(char**)); + if ( *list == NULL ) return PREF_ERROR; + + for ( *p = strtok(value, ","); + *p != NULL; + *(++p) = strtok(NULL, ",") ) /* Empty body */ ; + + /* Copy each entry so that users can free them. */ + for ( p = *list; *p != NULL; p++ ) { + *p = PL_strdup(*p); + } + + PR_Free(value); + + return PREF_OK; +} + + +/* + * PREF_SetListPref + * TODO: Call Javascript callback to make sure user is allowed to make this + * change. + */ +PR_IMPLEMENT(PrefResult) +PREF_SetListPref(const char* pref, char** list) +{ + PrefResult status; + int len; + char** p; + char* value = NULL; + + if ( pref == NULL || list == NULL ) return PREF_ERROR; + + for ( len = 0, p = list; p != NULL && *p != NULL; p++ ) { + len+= (PL_strlen(*p)+1); /* The '+1' is for a comma or '\0' */ + } + + if ( len <= 0 || (value = PR_MALLOC(len)) == NULL ) { + return PREF_ERROR; + } + + (void) PL_strcpy(value, *list); + for ( p = list+1; p != NULL && *p != NULL; p++ ) { + (void) PL_strcat(value, ","); + (void) PL_strcat(value, *p); + } + + status = PREF_SetCharPref(pref, value); + + PR_FREEIF(value); + + return status; +} + + +PR_IMPLEMENT(PrefResult) +PREF_AppendListPref(const char* pref, const char* value) +{ + char *pListPref = NULL, *pNewList = NULL; + int nPrefLen = 0; + + PREF_CopyCharPref(pref, &pListPref); + + if (pListPref) + { + nPrefLen = PL_strlen(pListPref); + } + + if (nPrefLen == 0) { + PREF_SetCharPref(pref, value); + } else { + pNewList = (char *) PR_MALLOC((nPrefLen + PL_strlen(value) + 2)); + if (pNewList) { + PL_strcpy(pNewList, pListPref); + PL_strcat(pNewList, ","); + PL_strcat(pNewList, value); + PREF_SetCharPref(pref, pNewList); + PR_Free(pNewList); + } + + } + + PR_FREEIF(pListPref); + + return PREF_NOERROR; +} + +/* + * PREF_FreeListPref + * Free each element in the list, then free the list, then NULL the + * list out. + */ +PR_IMPLEMENT(PrefResult) +PREF_FreeListPref(char*** list) +{ + char** p; + + if ( list == NULL ) return PREF_ERROR; + + for ( p = *list; *p != NULL; p++ ) { + PR_Free(*p); + } + + PR_FREEIF(*list); + + *list = NULL; + + return PREF_OK; +} diff --git a/mozilla/modules/libpref/src/prefapi.cpp b/mozilla/modules/libpref/src/prefapi.cpp index 05f314ca7be..ce449e6061b 100644 --- a/mozilla/modules/libpref/src/prefapi.cpp +++ b/mozilla/modules/libpref/src/prefapi.cpp @@ -1,4 +1,4 @@ -/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- +/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- * * The contents of this file are subject to the Netscape Public License * Version 1.0 (the "NPL"); you may not use this file except in @@ -79,23 +79,17 @@ JSObject * m_GlobalConfigObject = NULL; static char * m_filename = NULL; static char * m_lifilename = NULL; static struct CallbackNode* m_Callbacks = NULL; -static PRBool m_ErrorOpeningUserPrefs = FALSE; -static PRBool m_CallbacksEnabled = FALSE; -static PRBool m_IsAnyPrefLocked = FALSE; +static PRBool m_ErrorOpeningUserPrefs = PR_FALSE; +static PRBool m_CallbacksEnabled = PR_FALSE; +static PRBool m_IsAnyPrefLocked = PR_FALSE; static PRHashTable* m_HashTable = NULL; - -/* LI_STUFF - PREF_LILOCAL here to flag prefs as transferable or not */ -typedef enum { PREF_LOCKED = 1, PREF_USERSET = 2, PREF_CONFIG = 4, - PREF_STRING = 8, PREF_INT = 16, PREF_BOOL = 32, - PREF_LILOCAL = 64 } PrefType; -/* LI_STUFF PREF_SETLI here to flag prefs as transferable or not */ -typedef enum { PREF_SETDEFAULT, PREF_SETUSER, - PREF_LOCK, PREF_SETCONFIG, PREF_SETLI } PrefAction; +static char * m_SavedLine = NULL; #define PREF_IS_LOCKED(pref) ((pref)->flags & PREF_LOCKED) #define PREF_IS_CONFIG(pref) ((pref)->flags & PREF_CONFIG) #define PREF_HAS_USER_VALUE(pref) ((pref)->flags & PREF_USERSET) #define PREF_HAS_LI_VALUE(pref) ((pref)->flags & PREF_LILOCAL) /* LI_STUFF */ +#define PREF_TYPE(pref) (PrefType)((pref)->flags & PREF_VALUETYPE_MASK) typedef union { @@ -112,6 +106,7 @@ typedef struct } PrefNode; static JSBool pref_HashJSPref(unsigned int argc, jsval *argv, PrefAction action); +static XP_Bool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type); /* Hash table allocation */ PR_IMPLEMENT(void *) @@ -168,19 +163,24 @@ struct CallbackNode { }; /* -- Prototypes */ -int pref_DoCallback(const char* changed_pref); -int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash, PRBool bGlobalContext); +PrefResult pref_DoCallback(const char* changed_pref); +PrefResult pref_OpenFile( + const char* filename, + PRBool is_error_fatal, + PRBool verifyHash, + PRBool bGlobalContext, + PRBool skipFirstLine); PRBool pref_VerifyLockFile(char* buf, long buflen); -int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default); -int pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default); -int pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default); -int pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default); +PrefResult pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default); +PrefResult pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default); +PrefResult pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default); +PrefResult pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default); JSBool PR_CALLBACK pref_BranchCallback(JSContext *cx, JSScript *script); void pref_ErrorReporter(JSContext *cx, const char *message,JSErrorReport *report); void pref_Alert(char* msg); -int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action); +PrefResult pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action); /* -- Platform specific function extern */ #if !defined(XP_WIN) && !defined(XP_OS2) @@ -233,12 +233,17 @@ static JSClass autoconf_class = { JS_EnumerateStub, JS_ResolveStub, JS_ConvertStub, JS_FinalizeStub }; -int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash, PRBool bGlobalContext) +PrefResult pref_OpenFile( + const char* filename, + PRBool is_error_fatal, + PRBool verifyHash, + PRBool bGlobalContext, + PRBool skipFirstLine) { - int ok = PREF_ERROR; + PrefResult ok = PREF_ERROR; FILE *fp; struct stat stats; - long fileLength; + size_t fileLength; stats.st_size = 0; if ( stat(filename, (struct stat *) &stats) == -1 ) @@ -254,12 +259,12 @@ int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash if (readBuf) { fileLength = fread(readBuf, sizeof(char), fileLength, fp); - if ( verifyHash && pref_VerifyLockFile(readBuf, fileLength) == FALSE ) + if ( verifyHash && pref_VerifyLockFile(readBuf, fileLength) == PR_FALSE ) { ok = PREF_BAD_LOCKFILE; } else if ( PREF_EvaluateConfigScript(readBuf, fileLength, - filename, bGlobalContext, FALSE ) == JS_TRUE ) + filename, bGlobalContext, PR_FALSE, skipFirstLine ) == JS_TRUE ) { ok = PREF_NOERROR; } @@ -270,7 +275,7 @@ int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash /* If the user prefs file exists but generates an error, don't clobber the file when we try to save it. */ if ((!readBuf || ok != PREF_NOERROR) && is_error_fatal) - m_ErrorOpeningUserPrefs = TRUE; + m_ErrorOpeningUserPrefs = PR_TRUE; #ifdef XP_PC if (m_ErrorOpeningUserPrefs && is_error_fatal) MessageBox(NULL,"Error in preference file (prefs.js). Default preferences will be used.","Netscape - Warning", MB_OK); @@ -287,14 +292,14 @@ int pref_OpenFile(const char* filename, PRBool is_error_fatal, PRBool verifyHash PRBool pref_VerifyLockFile(char* buf, long buflen) { #ifndef NO_SECURITY - PRBool success = FALSE; + PRBool success = PR_FALSE; const int obscure_value = 7; const long hash_length = 51; /* len = 48 chars of MD5 + // + EOL */ unsigned char digest[16]; char szHash[64]; /* Unobscure file by subtracting some value from every char. */ - unsigned int i; + long i; for (i = 0; i < buflen; i++) { buf[i] -= obscure_value; } @@ -328,43 +333,43 @@ PRBool pref_VerifyLockFile(char* buf, long buflen) #else /* * Should return 'success', but since the MD5 code is stubbed out, - * just return 'TRUE' until we have a replacement. + * just return 'PR_TRUE' until we have a replacement. */ - return TRUE; + return PR_TRUE; #endif } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ReadLIJSFile(char *filename) { - int ok; + PrefResult ok; if (filename) m_lifilename = strdup(filename); - ok = pref_OpenFile(filename, FALSE, FALSE, FALSE); + ok = pref_OpenFile(filename, PR_FALSE, PR_FALSE, PR_FALSE, PR_FALSE); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ReadUserJSFile(char *filename) { - int ok = pref_OpenFile(filename, FALSE, FALSE, TRUE); + PrefResult ok = pref_OpenFile(filename, PR_FALSE, PR_FALSE, PR_TRUE, PR_FALSE); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PRBool) PREF_Init(char *filename) { - JSBool ok = JS_TRUE; + PRBool ok = PR_TRUE; /* --ML hash test */ if (!m_HashTable) m_HashTable = PR_NewHashTable(2048, PR_HashString, PR_CompareStrings, PR_CompareValues, &pref_HashAllocOps, NULL); if (!m_HashTable) - return 0; + return PR_FALSE; if (filename) { if (m_filename) /* happens if PREF_Init is called twice (it is) */ @@ -378,7 +383,7 @@ PREF_Init(char *filename) if (!m_mochaContext) { m_mochaContext = JS_NewContext(m_mochaTaskState, 8192); /* ???? What size? */ if (!m_mochaContext) { - return 0; + return PR_FALSE; } JS_BeginRequest(m_mochaContext); @@ -386,7 +391,7 @@ PREF_Init(char *filename) m_GlobalConfigObject = JS_NewObject(m_mochaContext, &global_class, NULL, NULL); if (!m_GlobalConfigObject) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } /* MLM - need a global object for set version call now. */ @@ -397,7 +402,7 @@ PREF_Init(char *filename) if (!JS_InitStandardClasses(m_mochaContext, m_GlobalConfigObject)) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } JS_SetBranchCallback(m_mochaContext, pref_BranchCallback); @@ -415,14 +420,14 @@ PREF_Init(char *filename) m_mochaPrefObject, autoconf_props)) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } if (!JS_DefineFunctions(m_mochaContext, m_mochaPrefObject, autoconf_methods)) { JS_EndRequest(m_mochaContext); - return 0; + return PR_FALSE; } } @@ -435,19 +440,19 @@ PREF_Init(char *filename) } if (ok && filename) { - ok = (JSBool) (pref_OpenFile(filename, TRUE, FALSE, FALSE) == PREF_NOERROR); + ok = (JSBool) (pref_OpenFile(filename, PR_TRUE, PR_FALSE, PR_FALSE, PR_TRUE) == PREF_NOERROR); } else if (!ok) { - m_ErrorOpeningUserPrefs = TRUE; + m_ErrorOpeningUserPrefs = PR_TRUE; } JS_EndRequest(m_mochaContext); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigContext(JSContext **js_context) { - if (!js_context) return FALSE; + if (!js_context) return PREF_ERROR; *js_context = NULL; if (m_mochaContext) { @@ -455,31 +460,31 @@ PREF_GetConfigContext(JSContext **js_context) JS_SetContextThread(m_mochaContext); } - return TRUE; + return PREF_NOERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetGlobalConfigObject(JSObject **js_object) { - if (!js_object) return FALSE; + if (!js_object) return PREF_ERROR; *js_object = NULL; if (m_GlobalConfigObject) *js_object = m_GlobalConfigObject; - return TRUE; + return PREF_NOERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetPrefConfigObject(JSObject **js_object) { - if (!js_object) return FALSE; + if (!js_object) return PREF_ERROR; *js_object = NULL; if (m_mochaPrefObject) *js_object = m_mochaPrefObject; - return TRUE; + return PREF_NOERROR; } /* Frees the callback list. */ @@ -504,11 +509,11 @@ PREF_Cleanup() PR_HashTableDestroy(m_HashTable); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ReadLockFile(const char *filename) { /* - return pref_OpenFile(filename, FALSE, FALSE, TRUE); + return pref_OpenFile(filename, PR_FALSE, PR_FALSE, PR_TRUE); Lock files are obscured, and the security code to read them has been removed from the free source. So don't even try to read one. @@ -518,10 +523,16 @@ PREF_ReadLockFile(const char *filename) return PREF_ERROR; } +void PREF_SetCallbacksStatus( PRBool status ) +{ + m_CallbacksEnabled = status; +} + /* This is more recent than the below 3 routines which should be obsoleted */ PR_IMPLEMENT(JSBool) PREF_EvaluateConfigScript(const char * js_buffer, size_t length, - const char* filename, PRBool bGlobalContext, PRBool bCallbacks) + const char* filename, PRBool bGlobalContext, PRBool bCallbacks, + PRBool skipFirstLine) { JSBool ok; jsval result; @@ -540,28 +551,54 @@ PREF_EvaluateConfigScript(const char * js_buffer, size_t length, errReporter = JS_SetErrorReporter(m_mochaContext, pref_ErrorReporter); m_CallbacksEnabled = bCallbacks; + if (skipFirstLine) { + /* In order to protect the privacy of the JavaScript preferences file + * from loading by the browser, we make the first line unparseable + * by JavaScript. We must skip that line here before executing + * the JavaScript code. + */ + unsigned int i=0; + while (i < length) { + char c = js_buffer[i++]; + if (c == '\r') { + if (js_buffer[i] == '\n') + i++; + break; + } + if (c == '\n') + break; + } + m_SavedLine = malloc(i+1); + if (!m_SavedLine) + return JS_FALSE; + memcpy(m_SavedLine, js_buffer, i); + m_SavedLine[i] = '\0'; + length -= i; + js_buffer += i; + } + ok = JS_EvaluateScript(m_mochaContext, scope, js_buffer, length, filename, 0, &result); - m_CallbacksEnabled = TRUE; /* ?? want to enable after reading user/lock file */ + m_CallbacksEnabled = PR_TRUE; /* ?? want to enable after reading user/lock file */ JS_SetErrorReporter(m_mochaContext, errReporter); JS_EndRequest(m_mochaContext); return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(JSBool) PREF_EvaluateJSBuffer(const char * js_buffer, size_t length) { /* old routine that no longer triggers callbacks */ - int ret; + JSBool ret; ret = PREF_QuietEvaluateJSBuffer(js_buffer, length); return ret; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(JSBool) PREF_QuietEvaluateJSBuffer(const char * js_buffer, size_t length) { JSBool ok; @@ -579,7 +616,7 @@ PREF_QuietEvaluateJSBuffer(const char * js_buffer, size_t length) return ok; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(JSBool) PREF_QuietEvaluateJSBufferWithGlobalScope(const char * js_buffer, size_t length) { JSBool ok; @@ -626,9 +663,9 @@ static char * str_escape(const char * original) { } /* -// External calls - */ -PR_IMPLEMENT(int) +** External calls +*/ +PR_IMPLEMENT(PrefResult) PREF_SetCharPref(const char *pref_name, const char *value) { PrefValue pref; @@ -637,7 +674,7 @@ PREF_SetCharPref(const char *pref_name, const char *value) return pref_HashPref(pref_name, pref, PREF_STRING, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetIntPref(const char *pref_name, int32 value) { PrefValue pref; @@ -646,7 +683,7 @@ PREF_SetIntPref(const char *pref_name, int32 value) return pref_HashPref(pref_name, pref, PREF_INT, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetBoolPref(const char *pref_name, PRBool value) { PrefValue pref; @@ -655,7 +692,7 @@ PREF_SetBoolPref(const char *pref_name, PRBool value) return pref_HashPref(pref_name, pref, PREF_BOOL, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetBinaryPref(const char *pref_name, void * value, long size) { char* buf = PL_Base64Encode(value, size, NULL); @@ -669,7 +706,7 @@ PREF_SetBinaryPref(const char *pref_name, void * value, long size) return PREF_ERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue) { char colstr[63]; @@ -684,7 +721,7 @@ PREF_SetColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue) #define MYGetGValue(rgb) ((uint8) (((uint16) (rgb)) >> 8)) #define MYGetRValue(rgb) ((uint8) (rgb)) -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetColorPrefDWord(const char *pref_name, uint32 colorref) { int red,green,blue; @@ -700,7 +737,7 @@ PREF_SetColorPrefDWord(const char *pref_name, uint32 colorref) return pref_HashPref(pref_name, pref, PREF_STRING, PREF_SETUSER); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom) { char rectstr[63]; @@ -712,9 +749,9 @@ PREF_SetRectPref(const char *pref_name, int16 left, int16 top, int16 right, int1 } /* -// DEFAULT VERSIONS: Call internal with (set_default == TRUE) - */ -PR_IMPLEMENT(int) +** DEFAULT VERSIONS: Call internal with (set_default == PR_TRUE) +*/ +PR_IMPLEMENT(PrefResult) PREF_SetDefaultCharPref(const char *pref_name,const char *value) { PrefValue pref; @@ -724,7 +761,7 @@ PREF_SetDefaultCharPref(const char *pref_name,const char *value) } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultIntPref(const char *pref_name,int32 value) { PrefValue pref; @@ -733,7 +770,7 @@ PREF_SetDefaultIntPref(const char *pref_name,int32 value) return pref_HashPref(pref_name, pref, PREF_INT, PREF_SETDEFAULT); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultBoolPref(const char *pref_name,PRBool value) { PrefValue pref; @@ -742,7 +779,7 @@ PREF_SetDefaultBoolPref(const char *pref_name,PRBool value) return pref_HashPref(pref_name, pref, PREF_BOOL, PREF_SETDEFAULT); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultBinaryPref(const char *pref_name,void * value,long size) { char* buf = PL_Base64Encode(value, size, NULL); @@ -755,7 +792,7 @@ PREF_SetDefaultBinaryPref(const char *pref_name,void * value,long size) return PREF_ERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultColorPref(const char *pref_name, uint8 red, uint8 green, uint8 blue) { char colstr[63]; @@ -764,7 +801,7 @@ PREF_SetDefaultColorPref(const char *pref_name, uint8 red, uint8 green, uint8 bl return PREF_SetDefaultCharPref(pref_name, colstr); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetDefaultRectPref(const char *pref_name, int16 left, int16 top, int16 right, int16 bottom) { char rectstr[63]; @@ -780,7 +817,10 @@ pref_saveLIPref(PRHashEntry *he, int i, void *arg) { char **prefArray = (char**) arg; PrefNode *pref = (PrefNode *) he->value; - if (pref && PREF_HAS_USER_VALUE(pref) && !PREF_HAS_LI_VALUE(pref)) { + if (pref && PREF_HAS_USER_VALUE(pref) && !PREF_HAS_LI_VALUE(pref) && + pref_ValueChanged(pref->defaultPref, + pref->userPref, + (PrefType) PREF_TYPE(pref))) { char buf[2048]; if (pref->flags & PREF_STRING) { @@ -833,7 +873,14 @@ pref_savePref(PRHashEntry *he, int i, void *arg) char **prefArray = (char**) arg; PrefNode *pref = (PrefNode *) he->value; - if (pref && PREF_HAS_USER_VALUE(pref)) { + PR_ASSERT(pref); + if (!pref) + return 0; + + if (PREF_HAS_USER_VALUE(pref) && + pref_ValueChanged(pref->defaultPref, + pref->userPref, + (PrefType) PREF_TYPE(pref))) { char buf[2048]; if (pref->flags & PREF_STRING) { @@ -910,12 +957,12 @@ This is called by them and does the right thing. #define PREF_FILE_BANNER "// Netscape User Preferences" LINEBREAK \ "// This is a generated file! Do not edit." LINEBREAK LINEBREAK -PR_IMPLEMENT(int) -PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { - int success = PREF_ERROR; +PR_IMPLEMENT(PrefResult) +PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) +{ + PrefResult success = PREF_ERROR; FILE * fp; char **valueArray = NULL; - int valueIdx; if (!m_HashTable) return PREF_NOT_INITIALIZED; @@ -933,14 +980,16 @@ PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { return PREF_OUT_OF_MEMORY; fp = fopen(filename, "w"); - if (fp) { + if (fp) + { + PRUint32 valueIdx; fwrite(PREF_FILE_BANNER, sizeof(char), PL_strlen(PREF_FILE_BANNER), fp); /* LI_STUFF here we pass in the heSaveProc proc used so that li can do its own thing */ PR_HashTableEnumerateEntries(m_HashTable, heSaveProc, valueArray); /* Sort the preferences to make a readable file on disk */ - XP_QSORT (valueArray, m_HashTable->nentries, sizeof(char*), pref_CompareStrings); + XP_QSORT(valueArray, m_HashTable->nentries, sizeof(char*), pref_CompareStrings); for (valueIdx = 0; valueIdx < m_HashTable->nentries; valueIdx++) { if (valueArray[valueIdx]) @@ -955,7 +1004,7 @@ PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { success = PREF_NOERROR; } else - success = errno; + success = (PrefResult)errno; /* Really? */ PR_Free(valueArray); @@ -963,33 +1012,116 @@ PREF_SavePrefFileWith(const char *filename, PRHashEnumerator heSaveProc) { } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SavePrefFile() { - if (!m_HashTable) +#if 0// defined(XP_MAC) || defined(XP_PC) + return (PrefResult)pref_SaveProfile(); +#else + if (!m_HashTable) return PREF_NOT_INITIALIZED; - return (PREF_SavePrefFileWith(m_filename, pref_savePref)); + + return (PREF_SavePrefFileWith(m_filename, pref_savePref)); +#endif } -/* LI_STUFF Create a saveprefFile for LI for outsiders to call */ -PR_IMPLEMENT(int) +/* + * We need to flag a bunch of prefs as local that aren't initialized via all.js. + * This seems the safest way to do this. + */ +PR_IMPLEMENT(PrefResult) +PREF_SetSpecialPrefsLocal(void) +{ + static char *prefName[] = { + "ab_dir.outliner_geometry", + "addressbook.outliner_geometry", + "bookmarks.outliner_geometry", + "browser.bookmark_columns_win", + "browser.history_file", + "browser.sarcache.directory", + "browser.user_history_file", + "browser.win_height", + "browser.win_width", + "category.thread_columns_win", + "comppicker.outliner_geometry", + "editor.html_editor", + "editor.template_history_0", + "editor.template_last_loc", + "editor.win_height", + "editor.win_width", + "helpers.global_mailcap_file", + "helpers.global_mime_types_file", + "helpers.private_mailcap_file", + "helpers.private_mime_types_file", + "history.outliner_geometry", + "intl.font_charset", + "intl.font_spec_list", + "mail.addr_book.sliderwidth", + "mail.addr_picker.sliderwidth", + "mail.compose.win_height", + "mail.compose.win_width", + "mail.composition.addresspane.outliner_geometry", + "mail.folder.win_height", + "mail.folder.win_width", + "mail.folderpane.outliner_geometry", + "mail.imap.root_dir", + "mail.mailfilter.outliner_geometry", + "mail.msg.win_height", + "mail.msg.win_width", + "mail.subscribepane.all_groups.outliner_geometry", + "mail.subscribepane.new_groups.outliner_geometry", + "mail.subscribepane.search_groups.outliner_geometry", + "mail.thread.win_height", + "mail.thread.win_width", + "mail.thread_columns_win", + "mail.threadpane.messagepane_height", + "mail.threadpane.outliner_geometry", + "mailnews.3Pane_folder_columns_win", + "mailnews.3pane_folder_width", + "mailnews.3pane_thread_height", + "mailnews.abook_columns_win", + "mailnews.folder_columns_win", + "mailnews.ldapsearch_columns_win", + "news.thread_columns_win", + "preferences.lang.outliner_geometry", + "profile.name", + "profile.numprofiles", + "taskbar.x", + "taskbar.y", + "profile.directory" + }; + PrefNode* pref; + int i; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + for (i = 0; i < (sizeof(prefName)/sizeof(prefName[0])); i++) { + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, prefName[i]); + if (pref) + pref->flags |= PREF_LILOCAL; + } + return PREF_OK; +} + +PR_IMPLEMENT(PrefResult) PREF_SaveLIPrefFile(const char *filename) { if (!m_HashTable) return PREF_NOT_INITIALIZED; + PREF_SetSpecialPrefsLocal(); return (PREF_SavePrefFileWith(((filename) ? filename : m_lifilename), pref_saveLIPref)); } -/* LI_STUFF pass in the pref_savePref proc used instead of assuming it so that li can share that code too */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SavePrefFileAs(const char *filename) { return PREF_SavePrefFileWith(filename, pref_savePref); } -int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default) +PrefResult pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; char* stringVal; PrefNode* pref; @@ -999,17 +1131,19 @@ int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); - if (pref) { + if (pref) + { if (get_default || PREF_IS_LOCKED(pref) || !PREF_HAS_USER_VALUE(pref)) stringVal = pref->defaultPref.stringVal; else stringVal = pref->userPref.stringVal; - if (stringVal) { - if (*length == 0) { + if (stringVal) + { + if (*length == 0) *length = strlen(stringVal) + 1; - } - else { + else + { PL_strncpy(return_buffer, stringVal, PR_MIN(*length - 1, strlen(stringVal) + 1)); return_buffer[*length - 1] = '\0'; } @@ -1019,9 +1153,9 @@ int pref_GetCharPref(const char *pref_name, char * return_buffer, int * length, return result; } -int pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default) +PrefResult pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; char* stringVal; PrefNode* pref; @@ -1044,9 +1178,9 @@ int pref_CopyCharPref(const char *pref_name, char ** return_buffer, PRBool get_d return result; } -int pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default) +PrefResult pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; PrefNode* pref; if (!m_HashTable) @@ -1063,9 +1197,9 @@ int pref_GetIntPref(const char *pref_name,int32 * return_int, PRBool get_default return result; } -int pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default) +PrefResult pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_default) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; PrefNode* pref; if (!m_HashTable) @@ -1083,37 +1217,37 @@ int pref_GetBoolPref(const char *pref_name, XP_Bool * return_value, PRBool get_d } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetCharPref(const char *pref_name, char * return_buffer, int * length) { - return pref_GetCharPref(pref_name, return_buffer, length, FALSE); + return pref_GetCharPref(pref_name, return_buffer, length, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyCharPref(const char *pref_name, char ** return_buffer) { - return pref_CopyCharPref(pref_name, return_buffer, FALSE); + return pref_CopyCharPref(pref_name, return_buffer, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetIntPref(const char *pref_name,int32 * return_int) { - return pref_GetIntPref(pref_name, return_int, FALSE); + return pref_GetIntPref(pref_name, return_int, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetBoolPref(const char *pref_name, XP_Bool * return_value) { - return pref_GetBoolPref(pref_name, return_value, FALSE); + return pref_GetBoolPref(pref_name, return_value, PR_FALSE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue) { char colstr[8]; int iSize = 8; - int result = PREF_GetCharPref(pref_name, colstr, &iSize); + PrefResult result = PREF_GetCharPref(pref_name, colstr, &iSize); if (result == PREF_NOERROR) { int r, g, b; @@ -1128,32 +1262,29 @@ PREF_GetColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue) #define MYRGB(r, g ,b) ((uint32) (((uint8) (r) | ((uint16) (g) << 8)) | (((uint32) (uint8) (b)) << 16))) -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetColorPrefDWord(const char *pref_name, uint32 *colorref) { - char colstr[8]; - int iSize = 8; - uint8 red=0, green=0, blue=0; + uint8 red, green, blue; + PrefResult result; + + PR_ASSERT(colorref); + + result = PREF_GetColorPref(pref_name, &red, &green, &blue); + + if (result == PREF_NOERROR) { + *colorref = MYRGB(red,green,blue); + } - int result = PREF_GetCharPref(pref_name, colstr, &iSize); - - if (result == 0) { - int r, g, b; - sscanf(colstr, "#%02X%02X%02X", &r, &g, &b); - red = r; - green = g; - blue = b; - } - *colorref = MYRGB(red,green,blue); return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom) { char rectstr[64]; int iSize=64; - int result = PREF_GetCharPref(pref_name, rectstr, &iSize); + PrefResult result = PREF_GetCharPref(pref_name, rectstr, &iSize); if (result == PREF_NOERROR) { int l, t, r, b; @@ -1164,20 +1295,20 @@ PREF_GetRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, i return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetBinaryPref(const char *pref_name, void * return_value, int *size) { char* buf; - int result; + PrefResult result; - if (!m_mochaPrefObject || !return_value) return -1; + if (!m_mochaPrefObject || !return_value) return PREF_ERROR; result = PREF_CopyCharPref(pref_name, &buf); if (result == PREF_NOERROR) { if (strlen(buf) == 0) { /* don't decode empty string ? */ PR_Free(buf); - return -1; + return PREF_ERROR; } PL_Base64Decode(buf, *size, return_value); @@ -1187,16 +1318,16 @@ PREF_GetBinaryPref(const char *pref_name, void * return_value, int *size) return result; } -typedef int (*CharPrefReadFunc)(const char*, char**); +typedef PrefResult (*CharPrefReadFunc)(const char*, char**); -static int +static PrefResult ReadCharPrefUsing(const char *pref_name, void** return_value, int *size, CharPrefReadFunc inFunc) { char* buf; - int result; + PrefResult result; if (!m_mochaPrefObject || !return_value) - return -1; + return PREF_ERROR; *return_value = NULL; result = inFunc(pref_name, &buf); @@ -1204,7 +1335,7 @@ ReadCharPrefUsing(const char *pref_name, void** return_value, int *size, CharPre if (result == PREF_NOERROR) { if (strlen(buf) == 0) { /* do not decode empty string? */ PR_Free(buf); - return -1; + return PREF_ERROR; } *return_value = PL_Base64Decode(buf, 0, NULL); @@ -1215,26 +1346,26 @@ ReadCharPrefUsing(const char *pref_name, void** return_value, int *size, CharPre return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyBinaryPref(const char *pref_name, void ** return_value, int *size) { return ReadCharPrefUsing(pref_name, return_value, size, PREF_CopyCharPref); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyDefaultBinaryPref(const char *pref_name, void ** return_value, int *size) { return ReadCharPrefUsing(pref_name, return_value, size, PREF_CopyDefaultCharPref); } #ifndef XP_MAC -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyPathPref(const char *pref_name, char ** return_buffer) { return PREF_CopyCharPref(pref_name, return_buffer); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default) { PrefAction action = set_default ? PREF_SETDEFAULT : PREF_SETUSER; @@ -1246,44 +1377,44 @@ PREF_SetPathPref(const char *pref_name, const char *path, PRBool set_default) #endif /* XP_MAC */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultCharPref(const char *pref_name, char * return_buffer, int * length) { - return pref_GetCharPref(pref_name, return_buffer, length, TRUE); + return pref_GetCharPref(pref_name, return_buffer, length, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyDefaultCharPref(const char *pref_name, char ** return_buffer) { - return pref_CopyCharPref(pref_name, return_buffer, TRUE); + return pref_CopyCharPref(pref_name, return_buffer, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultIntPref(const char *pref_name, int32 * return_int) { - return pref_GetIntPref(pref_name, return_int, TRUE); + return pref_GetIntPref(pref_name, return_int, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultBoolPref(const char *pref_name, XP_Bool * return_value) { - return pref_GetBoolPref(pref_name, return_value, TRUE); + return pref_GetBoolPref(pref_name, return_value, PR_TRUE); } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultBinaryPref(const char *pref_name, void * return_value, int * length) { - PR_ASSERT( FALSE ); - return TRUE; + PR_ASSERT( PR_FALSE ); + return PREF_ERROR; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 *blue) { char colstr[8]; int iSize = 8; - int result = PREF_GetDefaultCharPref(pref_name, colstr, &iSize); + PrefResult result = PREF_GetDefaultCharPref(pref_name, colstr, &iSize); if (result == PREF_NOERROR) { int r, g, b; @@ -1296,32 +1427,29 @@ PREF_GetDefaultColorPref(const char *pref_name, uint8 *red, uint8 *green, uint8 return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultColorPrefDWord(const char *pref_name, uint32 * colorref) { - char colstr[8]; - int iSize = 8; - uint8 red=0, green=0, blue=0; + uint8 red, green, blue; + PrefResult result; + + PR_ASSERT(colorref); + + result = PREF_GetDefaultColorPref(pref_name, &red, &green, &blue); + + if (result == PREF_NOERROR) { + *colorref = MYRGB(red,green,blue); + } - int result = PREF_GetDefaultCharPref(pref_name, colstr, &iSize); - - if (result == PREF_NOERROR) { - int r, g, b; - sscanf(colstr, "#%02X%02X%02X", &r, &g, &b); - red = r; - green = g; - blue = b; - } - *colorref = MYRGB(red,green,blue); return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetDefaultRectPref(const char *pref_name, int16 *left, int16 *top, int16 *right, int16 *bottom) { char rectstr[256]; int iLen = 256; - int result = PREF_GetDefaultCharPref(pref_name, (char *)&rectstr, &iLen); + PrefResult result = PREF_GetDefaultCharPref(pref_name, (char *)&rectstr, &iLen); if (result == PREF_NOERROR) { sscanf(rectstr, "%d,%d,%d,%d", left, top, right, bottom); @@ -1345,7 +1473,7 @@ pref_DeleteItem(PRHashEntry *he, int i, void *arg) return HT_ENUMERATE_NEXT; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_DeleteBranch(const char *branch_name) { char* branch_dot = PR_smprintf("%s.", branch_name); @@ -1355,17 +1483,22 @@ PREF_DeleteBranch(const char *branch_name) PR_HashTableEnumerateEntries(m_HashTable, pref_DeleteItem, (void*) branch_dot); PR_Free(branch_dot); - return 0; + return PREF_NOERROR; } /* LI_STUFF add a function to clear the li pref does anyone use this?? */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ClearLIPref(const char *pref_name) { - int success = PREF_ERROR; - PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); + PrefResult success = PREF_ERROR; + PrefNode* pref; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); if (pref && PREF_HAS_LI_VALUE(pref)) { pref->flags &= ~PREF_LILOCAL; if (m_CallbacksEnabled) @@ -1377,11 +1510,16 @@ PREF_ClearLIPref(const char *pref_name) -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_ClearUserPref(const char *pref_name) { - int success = PREF_ERROR; - PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); + PrefResult success = PREF_ERROR; + PrefNode* pref; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); if (pref && PREF_HAS_USER_VALUE(pref)) { pref->flags &= ~PREF_USERSET; if (m_CallbacksEnabled) @@ -1392,21 +1530,21 @@ PREF_ClearUserPref(const char *pref_name) } /* Prototype Admin Kit support */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigString(const char *obj_name, char * return_buffer, int size, int index, const char *field) { - PR_ASSERT( FALSE ); - return -1; + PR_ASSERT( PR_FALSE ); + return PREF_ERROR; } /* * Administration Kit support */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyConfigString(const char *obj_name, char **return_buffer) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, obj_name); if (pref && pref->flags & PREF_STRING) { @@ -1417,11 +1555,11 @@ PREF_CopyConfigString(const char *obj_name, char **return_buffer) return success; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyIndexConfigString(const char *obj_name, int index, const char *field, char **return_buffer) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref; char* setup_buf = PR_smprintf("%s_%d.%s", obj_name, index, field); @@ -1436,10 +1574,10 @@ PREF_CopyIndexConfigString(const char *obj_name, return success; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigInt(const char *obj_name, int32 *return_int) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, obj_name); @@ -1451,10 +1589,10 @@ PREF_GetConfigInt(const char *obj_name, int32 *return_int) return success; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_GetConfigBool(const char *obj_name, XP_Bool *return_bool) { - int success = PREF_ERROR; + PrefResult success = PREF_ERROR; PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, obj_name); @@ -1466,35 +1604,72 @@ PREF_GetConfigBool(const char *obj_name, XP_Bool *return_bool) return success; } +PrefResult pref_UnlockPref(const char *key) +{ + PrefNode* pref; + PrefResult result = PREF_OK; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, key); + if (!pref) { + return PREF_DOES_NOT_EXIST; + } + + if (PREF_IS_LOCKED(pref)) { + pref->flags &= ~PREF_LOCKED; + if (m_CallbacksEnabled) { + pref_DoCallback(key); + } + } + + return PREF_OK; +} + +PrefResult pref_LockPref(const char *key) +{ + PrefNode* pref; + PrefResult result = PREF_OK; + + if (!m_HashTable) + return PREF_NOT_INITIALIZED; + + pref = (PrefNode*) PR_HashTableLookup(m_HashTable, key); + if (!pref) { + return PREF_DOES_NOT_EXIST; + } + + + return pref_HashPref(key, pref->defaultPref, (PrefType)pref->flags, PREF_LOCK); +} + +PR_IMPLEMENT(PrefResult) +PREF_LockPref(const char *key) +{ + return pref_LockPref(key); +} + /* * Hash table functions */ -static PRBool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type) +static XP_Bool pref_ValueChanged(PrefValue oldValue, PrefValue newValue, PrefType type) { - PRBool changed = TRUE; - switch (type) { - case PREF_STRING: - if (oldValue.stringVal && newValue.stringVal) - changed = (strcmp(oldValue.stringVal, newValue.stringVal) != 0); - break; - - case PREF_INT: - changed = oldValue.intVal != newValue.intVal; - break; - - case PREF_BOOL: - changed = oldValue.boolVal != newValue.boolVal; - break; - default: - /* PREF_LOCKED, PREF_USERSET, PREF_CONFIG, PREF_LILOCAL */ - break; - } + PRBool changed = PR_TRUE; + if (type & PREF_STRING) { + if (oldValue.stringVal && newValue.stringVal) + changed = (strcmp(oldValue.stringVal, newValue.stringVal) != 0); + } else if (type & PREF_INT) { + changed = oldValue.intVal != newValue.intVal; + } else if (type & PREF_BOOL) { + changed = oldValue.boolVal != newValue.boolVal; + } return changed; } static void pref_SetValue(PrefValue* oldValue, PrefValue newValue, PrefType type) { - switch (type) { + switch (type & PREF_VALUETYPE_MASK) { case PREF_STRING: PR_ASSERT(newValue.stringVal); PR_FREEIF(oldValue->stringVal); @@ -1506,10 +1681,10 @@ static void pref_SetValue(PrefValue* oldValue, PrefValue newValue, PrefType type } } -int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action) +PrefResult pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction action) { PrefNode* pref; - int result = PREF_OK; + PrefResult result = PREF_OK; if (!m_HashTable) return PREF_NOT_INITIALIZED; @@ -1528,7 +1703,7 @@ int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction ac pref->defaultPref.intVal = (int32) -5632; PR_HashTableAdd(m_HashTable, PL_strdup(key), pref); } - else if (!(pref->flags & type)) { + else if ((pref->flags & PREF_VALUETYPE_MASK) != (type & PREF_VALUETYPE_MASK)) { PR_ASSERT(0); /* this shouldn't happen */ return PREF_TYPE_CHANGE_ERR; } @@ -1586,19 +1761,19 @@ int pref_HashPref(const char *key, PrefValue value, PrefType type, PrefAction ac result = PREF_VALUECHANGED; } pref->flags |= PREF_LOCKED; - m_IsAnyPrefLocked = TRUE; + m_IsAnyPrefLocked = PR_TRUE; break; } if (result == PREF_VALUECHANGED && m_CallbacksEnabled) { - int result2 = pref_DoCallback(key); + PrefResult result2 = pref_DoCallback(key); if (result2 < 0) result = result2; } return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefType) PREF_GetPrefType(const char *pref_name) { PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); @@ -1610,7 +1785,7 @@ PREF_GetPrefType(const char *pref_name) else if (pref->flags & PREF_BOOL) return PREF_BOOL; } - return PREF_ERROR; + return PREF_INVALID; } JSBool PR_CALLBACK pref_NativeDefaultPref @@ -1691,7 +1866,7 @@ JSBool PR_CALLBACK pref_NativeGetPref { void* value = NULL; PrefNode* pref; - PRBool prefExists = TRUE; + PRBool prefExists = PR_TRUE; if (argc >= 1 && JSVAL_IS_STRING(argv[0])) { @@ -1721,11 +1896,11 @@ JSBool PR_CALLBACK pref_NativeGetPref PR_IMPLEMENT(PRBool) PREF_PrefIsLocked(const char *pref_name) { - PRBool result = FALSE; + PRBool result = PR_FALSE; if (m_IsAnyPrefLocked) { PrefNode* pref = (PrefNode*) PR_HashTableLookup(m_HashTable, pref_name); if (pref && PREF_IS_LOCKED(pref)) - result = TRUE; + result = PR_TRUE; } return result; @@ -1755,7 +1930,7 @@ pref_addChild(PRHashEntry *he, int i, void *arg) char* nextdelim; int parentlen = strlen(pcs->parent); char* substring; - PRBool substringBordersSeparator = FALSE; + PRBool substringBordersSeparator = PR_FALSE; strncpy(buf, he->key, PR_MIN(512, strlen(he->key) + 1)); nextdelim = buf + parentlen; @@ -1794,7 +1969,7 @@ pref_addChild(PRHashEntry *he, int i, void *arg) return 0; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CreateChildList(const char* parent_node, char **child_list) { PrefChildIter pcs; @@ -1805,7 +1980,10 @@ PREF_CreateChildList(const char* parent_node, char **child_list) pcs.bufsize = 2048; #endif pcs.childList = (char*) malloc(sizeof(char) * pcs.bufsize); - pcs.parent = PR_smprintf("%s.", parent_node); + if (*parent_node > 0) + pcs.parent = PR_smprintf("%s.", parent_node); + else + pcs.parent = PL_strdup(""); if (!pcs.parent || !pcs.childList) return PREF_OUT_OF_MEMORY; pcs.childList[0] = '\0'; @@ -1826,7 +2004,7 @@ PREF_NextChild(char *child_list, int *index) *index += strlen(child) + 1; return child; } -#if 0 /* LANDING HACK */ + /*---------------------------------------------------------------------------------------- * pref_copyTree * @@ -1842,25 +2020,25 @@ PREF_NextChild(char *child_list, int *index) * Copy all the prefs under mail. to newmail.: pref_copyTree("mail", "newmail", "mail") * --------------------------------------------------------------------------------------*/ -int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *curSrcBranch) +PrefResult pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *curSrcBranch) { - int result = PREF_NOERROR; + PrefResult result = PREF_NOERROR; char* children = NULL; if ( PREF_CreateChildList(curSrcBranch, &children) == PREF_NOERROR ) { int index = 0; - int srcPrefixLen = XP_STRLEN(srcPrefix); + int srcPrefixLen = PL_strlen(srcPrefix); char* child = NULL; while ( (child = PREF_NextChild(children, &index)) != NULL) { - int prefType; + PrefType prefType; char *destPrefName = NULL; char *childStart = (srcPrefixLen > 0) ? (child + srcPrefixLen + 1) : child; - XP_ASSERT( XP_STRNCMP(child, curSrcBranch, srcPrefixLen) == 0 ); + PR_ASSERT( PL_strncmp(child, curSrcBranch, srcPrefixLen) == 0 ); if (*destPrefix > 0) destPrefName = PR_smprintf("%s.%s", destPrefix, childStart); @@ -1876,7 +2054,7 @@ int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *cur if ( ! PREF_PrefIsLocked(destPrefName) ) /* returns true if the prefs exists, and is locked */ { /* PREF_GetPrefType masks out the other bits of the pref flag, so we only - every get the values in the switch. + ever get the values in the switch. */ prefType = PREF_GetPrefType(child); @@ -1890,7 +2068,7 @@ int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *cur if (result == PREF_NOERROR) result = PREF_SetCharPref(destPrefName, prefVal); - XP_FREEIF(prefVal); + PR_FREEIF(prefVal); } break; @@ -1922,34 +2100,33 @@ int pref_copyTree(const char *srcPrefix, const char *destPrefix, const char *cur default: /* we should never get here */ - XP_ASSERT(FALSE); + PR_ASSERT(PR_FALSE); break; } } /* is not locked */ - XP_FREEIF(destPrefName); + PR_FREEIF(destPrefName); /* Recurse */ if (result == PREF_NOERROR || result == PREF_VALUECHANGED) result = pref_copyTree(srcPrefix, destPrefix, child); } - XP_FREE(children); + PR_Free(children); } return result; } -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_CopyPrefsTree(const char *srcRoot, const char *destRoot) { - XP_ASSERT(srcRoot != NULL); - XP_ASSERT(destRoot != NULL); + PR_ASSERT(srcRoot != NULL); + PR_ASSERT(destRoot != NULL); return pref_copyTree(srcRoot, destRoot, srcRoot); } -#endif /* LANDING HACK */ /* Adds a node to the beginning of the callback list. */ @@ -1970,12 +2147,12 @@ PREF_RegisterCallback(const char *pref_node, } /* Deletes a node from the callback list. */ -PR_IMPLEMENT(int) +PR_IMPLEMENT(PrefResult) PREF_UnregisterCallback(const char *pref_node, PrefChangedFunc callback, void * instance_data) { - int result = PREF_ERROR; + PrefResult result = PREF_ERROR; struct CallbackNode* node = m_Callbacks; struct CallbackNode* prev_node = NULL; @@ -2003,32 +2180,29 @@ PREF_UnregisterCallback(const char *pref_node, return result; } -int pref_DoCallback(const char* changed_pref) +PrefResult pref_DoCallback(const char* changed_pref) { - int result = PREF_OK; + PrefResult result = PREF_OK; struct CallbackNode* node; for (node = m_Callbacks; node != NULL; node = node->next) { if ( PL_strncmp(changed_pref, node->domain, strlen(node->domain)) == 0 ) { int result2 = (*node->func) (changed_pref, node->data); - if (result2 != PREF_OK) - result = result2; + if (result2 != 0) + result = (PrefResult)result2; } } return result; } /* !! Front ends need to implement */ -#ifndef XP_MAC +#ifndef XP_MAC // see macpref.cp PR_IMPLEMENT(PRBool) PREF_IsAutoAdminEnabled() { - if (m_AutoAdminLib == NULL) - m_AutoAdminLib = pref_LoadAutoAdminLib(); - - return (m_AutoAdminLib != NULL); + return PR_TRUE; } -#endif +#endif // XP_MAC /* Called from JavaScript */ typedef char* (*ldap_func)(char*, char*, char*, char*, char**); @@ -2093,7 +2267,6 @@ JSBool PR_CALLBACK pref_NativeGetLDAPAttr return JS_TRUE; } -/* LI_STUFF ?? add some debugging stuff here. */ /* Dump debugging info in response to about:config. */ PR_IMPLEMENT(int) @@ -2104,28 +2277,36 @@ pref_printDebugInfo(PRHashEntry *he, int i, void *arg) PrefChildIter* pcs = (PrefChildIter*) arg; PrefNode *pref = (PrefNode *) he->value; - if (PREF_HAS_USER_VALUE(pref) && !PREF_IS_LOCKED(pref)) { + PR_ASSERT(pref); + if (!pref) + return PREF_NOERROR; + + if (PREF_HAS_USER_VALUE(pref) && + pref_ValueChanged(pref->defaultPref, + pref->userPref, + (PrefType) PREF_TYPE(pref)) && + !PREF_IS_LOCKED(pref)) + { buf1 = PR_smprintf("%s = ", (char*) he->key); val = pref->userPref; } - else { + else + { buf1 = PR_smprintf("%s = ", PREF_IS_LOCKED(pref) ? "red" : (PREF_IS_CONFIG(pref) ? "black" : "green"), (char*) he->key); val = pref->defaultPref; } - if (pref->flags & PREF_STRING) { + if (pref->flags & PREF_STRING) buf2 = PR_smprintf("%s %s
", buf1, val.stringVal); - } - else if (pref->flags & PREF_INT) { + else if (pref->flags & PREF_INT) buf2 = PR_smprintf("%s %d

", buf1, val.intVal); - } - else if (pref->flags & PREF_BOOL) { + else if (pref->flags & PREF_BOOL) buf2 = PR_smprintf("%s %s
", buf1, val.boolVal ? "true" : "false"); - } - if ((PL_strlen(buf2) + PL_strlen(pcs->childList) + 1) > pcs->bufsize) { + if ((PL_strlen(buf2) + PL_strlen(pcs->childList) + 1) > pcs->bufsize) + { pcs->bufsize *= 3; pcs->childList = (char*) realloc(pcs->childList, sizeof(char) * pcs->bufsize); if (!pcs->childList) @@ -2291,18 +2472,18 @@ pref_LoadAutoAdminLib() { if (getenv("MOZILLA_HOME")) { - strcpy(aalib, getenv("MOZILLA_HOME")); - lib = PR_LoadLibrary(strcat(aalib, ADMNLIBNAME)); + PL_strcpy(aalib, getenv("MOZILLA_HOME")); + lib = PR_LoadLibrary(PL_strcat(aalib, ADMNLIBNAME)); } if (lib == NULL) { fe_GetProgramDirectory(aalib, sizeof(aalib)-1); - lib = PR_LoadLibrary(strcat(aalib, ADMNLIBNAME)); + lib = PR_LoadLibrary(PL_strcat(aalib, ADMNLIBNAME)); } if (lib == NULL) { - (void) strcpy(aalib, "/usr/local/netscape/"); - lib = PR_LoadLibrary(strcat(aalib, ADMNLIBNAME)); + (void) PL_strcpy(aalib, "/usr/local/netscape/"); + lib = PR_LoadLibrary(PL_strcat(aalib, ADMNLIBNAME)); } } } @@ -2378,4 +2559,153 @@ static JSBool pref_HashJSPref(unsigned int argc, jsval *argv, PrefAction action) return JS_TRUE; } +/* + * pref_CountListMembers + */ +static int +pref_CountListMembers(char* list) +{ + int members = 0; + char* p = list = PL_strdup(list); + for ( p = strtok(p, ","); p != NULL; p = strtok(NULL, ",") ) { + members++; + } + + PR_FREEIF(list); + + return members; +} + + +/* + * PREF_GetListPref + * Splits a comma separated strings into an array of strings. + * The array of strings is actually just an array of pointers into a copy + * of the value returned by PREF_CopyCharPref(). So, we don't have to + * allocate each string separately. + */ +PR_IMPLEMENT(PrefResult) +PREF_GetListPref(const char* pref, char*** list) +{ + char* value; + char** p; + int num_members; + + *list = NULL; + + if ( PREF_CopyCharPref(pref, &value) != PREF_OK || value == NULL ) { + return PREF_ERROR; + } + + num_members = pref_CountListMembers(value); + + p = *list = (char**) PR_MALLOC((num_members+1) * sizeof(char**)); + if ( *list == NULL ) return PREF_ERROR; + + for ( *p = strtok(value, ","); + *p != NULL; + *(++p) = strtok(NULL, ",") ) /* Empty body */ ; + + /* Copy each entry so that users can free them. */ + for ( p = *list; *p != NULL; p++ ) { + *p = PL_strdup(*p); + } + + PR_Free(value); + + return PREF_OK; +} + + +/* + * PREF_SetListPref + * TODO: Call Javascript callback to make sure user is allowed to make this + * change. + */ +PR_IMPLEMENT(PrefResult) +PREF_SetListPref(const char* pref, char** list) +{ + PrefResult status; + int len; + char** p; + char* value = NULL; + + if ( pref == NULL || list == NULL ) return PREF_ERROR; + + for ( len = 0, p = list; p != NULL && *p != NULL; p++ ) { + len+= (PL_strlen(*p)+1); /* The '+1' is for a comma or '\0' */ + } + + if ( len <= 0 || (value = PR_MALLOC(len)) == NULL ) { + return PREF_ERROR; + } + + (void) PL_strcpy(value, *list); + for ( p = list+1; p != NULL && *p != NULL; p++ ) { + (void) PL_strcat(value, ","); + (void) PL_strcat(value, *p); + } + + status = PREF_SetCharPref(pref, value); + + PR_FREEIF(value); + + return status; +} + + +PR_IMPLEMENT(PrefResult) +PREF_AppendListPref(const char* pref, const char* value) +{ + char *pListPref = NULL, *pNewList = NULL; + int nPrefLen = 0; + + PREF_CopyCharPref(pref, &pListPref); + + if (pListPref) + { + nPrefLen = PL_strlen(pListPref); + } + + if (nPrefLen == 0) { + PREF_SetCharPref(pref, value); + } else { + pNewList = (char *) PR_MALLOC((nPrefLen + PL_strlen(value) + 2)); + if (pNewList) { + PL_strcpy(pNewList, pListPref); + PL_strcat(pNewList, ","); + PL_strcat(pNewList, value); + PREF_SetCharPref(pref, pNewList); + PR_Free(pNewList); + } + + } + + PR_FREEIF(pListPref); + + return PREF_NOERROR; +} + +/* + * PREF_FreeListPref + * Free each element in the list, then free the list, then NULL the + * list out. + */ +PR_IMPLEMENT(PrefResult) +PREF_FreeListPref(char*** list) +{ + char** p; + + if ( list == NULL ) return PREF_ERROR; + + for ( p = *list; *p != NULL; p++ ) { + PR_Free(*p); + } + + PR_FREEIF(*list); + + *list = NULL; + + return PREF_OK; +}