📄 prefs.c
字号:
if (tmp->value == NULL) { goto loser; } } else { tmp->value = NULL; } return tmp;loser: pref_free_pref_item(tmp); return NULL;}static PrefItemNode* pref_new_pref_item_node(PrefItem* item){ PrefItemNode* node = NULL; PR_ASSERT(item != NULL); node = (PrefItemNode*)PR_NEWZAP(PrefItemNode); if (node == NULL) { /* failed: bail out */ return node; } /* initialize elements to the right values */ PR_INIT_CLIST(&node->link); node->item = item; return node;}/* Append a PrefItem to the list */static SSMStatus pref_append_item_unlocked(PrefItem* pref, PRCList* list){ PrefItemNode* node = NULL; PR_ASSERT((pref != NULL) && (list != NULL)); node = pref_new_pref_item_node(pref); if (node == NULL) { return PR_FAILURE; } /* append the link */ PR_APPEND_LINK(&node->link, list); return PR_SUCCESS;}/* Append a PrefItem made from (key, value) into the list */static SSMStatus pref_append_pref_unlocked(PrefSet* prefs, char* key, char* value){ PrefItem* pref = NULL; pref = pref_new_pref_item(key, value); if (pref == NULL) { return PR_FAILURE; } return pref_append_item_unlocked(pref, &prefs->list);}/* Modify (old) by comparing with (new) * - returns PR_SUCCESS if everything went right; PR_FAILURE if PL_strdup() * failed */static SSMStatus pref_reset_value(char** oldStr, char* newStr){ PR_ASSERT(oldStr != NULL); if (newStr == NULL) { if (*oldStr != NULL) { PR_Free(*oldStr); *oldStr = newStr; } return PR_SUCCESS; } if (*oldStr != NULL) { if (PL_strcmp(*oldStr, newStr) != 0) { /* different: reset it */ PR_Free(*oldStr); *oldStr = PL_strdup(newStr); if (*oldStr == NULL) { return PR_FAILURE; } } } else { *oldStr = PL_strdup(newStr); if (*oldStr == NULL) { return PR_FAILURE; } } return PR_SUCCESS;}/* Retrieve (value) that belongs to (key) in (prefs) * - return PR_SUCCESS if key exists; PR_FAILURE otherwise * - (value) may be NULL * - returned (value) is a pointer to an existing string, not a new string */static SSMStatus pref_get_pref_unlocked(PrefSet* prefs, char* key, char** value){ PRCList* link = NULL; PR_ASSERT((prefs != NULL) && (key != NULL) && (value != NULL)); /* in case of failure */ *value = NULL; /* first make sure the list is not empty */ if (PR_CLIST_IS_EMPTY(&prefs->list)) { return PR_FAILURE; } /* walk the list to find the key */ for (link = PR_LIST_HEAD(&prefs->list); link != &prefs->list; link = PR_NEXT_LINK(link)) { PrefItemNode* node = (PrefItemNode*)link; if (PL_strcmp(node->item->key, key) == 0) { /* found the key: return the value whatever it is */ *value = node->item->value; return PR_SUCCESS; } } /* we couldn't find the key: return NULL */ return PR_FAILURE;}/* Set (value) for (key) in (prefs) * - if (key) exists, reset (value) (if necessary) * - if (key) does not exist, insert this item into (prefs) * - we do not care if (value) is NULL * - when new elements are created, they are allocated on the heap */static SSMStatus pref_set_pref_unlocked(PrefSet* prefs, char* key, char* value){ PRCList* link = NULL; PrefItem* item = NULL; PR_ASSERT((prefs != NULL) && (key != NULL)); if (!PR_CLIST_IS_EMPTY(&prefs->list)) { for (link = PR_LIST_HEAD(&prefs->list); link != &prefs->list; link = PR_NEXT_LINK(link)) { PrefItemNode* node = (PrefItemNode*)link; if (PL_strcmp(node->item->key, key) == 0) { /* found the key */ return pref_reset_value(&node->item->value, value); } } } /* either the list was empty or the key was not found */ return pref_append_pref_unlocked(prefs, key, value);}/* Compare (value) with the stored value under (key) * - returns PR_TRUE if the key does not exist or the values do not match * - returns PR_FALSE only if the key exists and the values match */static PRBool pref_pref_changed_unlocked(PrefSet* prefs, char* key, char* value){ PRCList* link = NULL; PrefItem* item = NULL; PRBool rv = PR_TRUE; PR_ASSERT((prefs != NULL) && (key != NULL)); if (!PR_CLIST_IS_EMPTY(&prefs->list)) { for (link = PR_LIST_HEAD(&prefs->list); link != &prefs->list; link = PR_NEXT_LINK(link)) { PrefItemNode* node = (PrefItemNode*)link; if (PL_strcmp(node->item->key, key) == 0) { /* found the key */ if (((value == NULL) && (node->item->value == NULL)) || (value != NULL) && (node->item->value != NULL) && (PL_strcmp(node->item->value, value) == 0)) { rv = PR_FALSE; } goto done; } } /* exhausted the list but could not find the key */ }done: return rv;}static void pref_clean_out_list(PRCList* list){ PRCList* link = NULL; PR_ASSERT(list != NULL); if (PR_CLIST_IS_EMPTY(list)) { /* we're already done */ return; } link = PR_LIST_HEAD(list); while (link != list) { PrefItemNode* node = (PrefItemNode*)link; pref_free_pref_item(node->item); link = PR_NEXT_LINK(link); if (node != NULL) { PR_Free(node); } } return;}PrefSet* PREF_NewPrefs(void){ SSMStatus status; PrefSet* prefs = NULL; int i; /* initialize the structure */ prefs = (PrefSet*)PR_NEWZAP(PrefSet); if (prefs == NULL) { goto loser; } prefs->lock = PR_NewLock(); if (prefs->lock == NULL) { goto loser; } PR_INIT_CLIST(&prefs->list); /* fill the list with default data */ for (i = 0; pref_defaults[i].key != NULL; i++) { PR_Lock(prefs->lock); status = pref_append_pref_unlocked(prefs, pref_defaults[i].key, pref_defaults[i].value); PR_Unlock(prefs->lock); if (status != PR_SUCCESS) { goto loser; } } return prefs;loser: if (prefs != NULL) { if (prefs->lock != NULL) { PR_DestroyLock(prefs->lock); } PR_Free(prefs); } return NULL;}SSMStatus PREF_ClosePrefs(PrefSet* prefs){ if (prefs == NULL) { goto loser; } if (prefs->lock == NULL) { goto loser; } /* clean out the list */ PR_Lock(prefs->lock); pref_clean_out_list(&prefs->list); PR_Unlock(prefs->lock); PR_DestroyLock(prefs->lock); PR_Free(prefs); return PR_SUCCESS;loser: return PR_FAILURE;}SSMStatus PREF_GetStringPref(PrefSet* prefs, char* key, char** value){ SSMStatus rv; /* in case of failure */ *value = NULL; if ((prefs == NULL) || (key == NULL) || (value == NULL)) { return PR_FAILURE; } PR_Lock(prefs->lock); rv = pref_get_pref_unlocked(prefs, key, value); PR_Unlock(prefs->lock); return rv;}SSMStatus PREF_CopyStringPref(PrefSet* prefs, char* key, char** value){ SSMStatus rv; char* tmp = NULL; *value = NULL; rv = PREF_GetStringPref(prefs, key, &tmp); if (tmp != NULL) { *value = PL_strdup(tmp); if (*value == NULL && rv == PR_SUCCESS) { rv = PR_FAILURE; } } return rv;}SSMStatus PREF_SetStringPref(PrefSet* prefs, char* key, char* value){ SSMStatus rv; if ((prefs == NULL) || (key == NULL)) { return PR_FAILURE; } PR_Lock(prefs->lock); rv = pref_set_pref_unlocked(prefs, key, value); PR_Unlock(prefs->lock); return rv;}PRBool PREF_StringPrefChanged(PrefSet* prefs, char* key, char* value){ PRBool rv; PR_ASSERT((prefs != NULL) && (key != NULL)); if ((prefs == NULL) || (key == NULL)) { return PR_TRUE; /* this really is an error */ } PR_Lock(prefs->lock); rv = pref_pref_changed_unlocked(prefs, key, value); PR_Unlock(prefs->lock); return rv;}SSMStatus PREF_GetBoolPref(PrefSet* prefs, char* key, PRBool* value){ SSMStatus rv; char* tmp = NULL; if ((prefs == NULL) || (key == NULL) || (value == NULL)) { return PR_FAILURE; } PR_Lock(prefs->lock); rv = pref_get_pref_unlocked(prefs, key, &tmp); PR_Unlock(prefs->lock); if (rv != PR_SUCCESS) { /* pref item was not found */ return rv; } if (PL_strcmp(tmp, STRING_TRUE) == 0) { *value = PR_TRUE; } else if (PL_strcmp(tmp, STRING_FALSE) == 0) { *value = PR_FALSE; } else { return PR_FAILURE; } return PR_SUCCESS;}SSMStatus PREF_SetBoolPref(PrefSet* prefs, char* key, PRBool value){ SSMStatus rv; char* tmp = NULL; if ((prefs == NULL) || (key == NULL)) { return PR_FAILURE; } if (value == PR_FALSE) { tmp = STRING_FALSE; } else if (value == PR_TRUE) { tmp = STRING_TRUE; } else { PR_ASSERT(0); } PR_Lock(prefs->lock); rv = pref_set_pref_unlocked(prefs, key, tmp); PR_Unlock(prefs->lock); return rv;}PRBool PREF_BoolPrefChanged(PrefSet* prefs, char* key, PRBool value){ PRBool rv; char* tmp = NULL; PR_ASSERT((prefs != NULL) && (key != NULL)); if ((prefs == NULL) || (key == NULL)) { return PR_TRUE; /* this really is an error */ } if (value == PR_FALSE) { tmp = STRING_FALSE; } else if (value = PR_TRUE) { tmp = STRING_TRUE; } else { PR_ASSERT(0); } PR_Lock(prefs->lock); rv = pref_pref_changed_unlocked(prefs, key, tmp); PR_Unlock(prefs->lock); return rv;}SSMStatus PREF_GetIntPref(PrefSet* prefs, char* key, PRIntn* value){ SSMStatus rv; char* tmp = NULL; if ((prefs == NULL) || (key == NULL) || (value == NULL)) { return PR_FAILURE; } PR_Lock(prefs->lock); rv = pref_get_pref_unlocked(prefs, key, &tmp); PR_Unlock(prefs->lock); if (rv != PR_SUCCESS) { /* pref item was not found */ return rv; } /* convert char* into integer */ *value = atoi(tmp); return PR_SUCCESS;}SSMStatus PREF_SetIntPref(PrefSet* prefs, char* key, PRIntn value){ SSMStatus rv; char* tmp = NULL; if ((prefs == NULL) || (key == NULL)) { return PR_FAILURE; } tmp = PR_smprintf("%d", value); if (tmp == NULL) { return PR_FAILURE; } PR_Lock(prefs->lock); rv = pref_set_pref_unlocked(prefs, key, tmp); PR_Unlock(prefs->lock); PR_Free(tmp); return rv;}PRBool PREF_IntPrefChanged(PrefSet* prefs, char* key, PRIntn value){ PRBool rv; char* tmp = NULL; PR_ASSERT((prefs != NULL) && (key != NULL)); if ((prefs == NULL) || (key == NULL)) { return PR_TRUE; /* this really is an error */ } tmp = PR_smprintf("%d", value); if (tmp == NULL) { return PR_TRUE; } PR_Lock(prefs->lock); rv = pref_pref_changed_unlocked(prefs, key, tmp); PR_Unlock(prefs->lock); PR_Free(tmp); return rv;}/****************** * These functions allow to handle multiple options specified in * prefs. ******************/#include "connect.h" /* don't know what to include to use PR_Zalloc */SSMStatus pref_append_value(char *** list, char * value){ SSMStatus rv = SSM_SUCCESS; static int size, cursize; if (!list || !value) return SSM_FAILURE; /* Quick and dirty check if we already have that value in the list - * only check the value directly before. Preferences keys seem to go * in clusters so that might actually work untill there is a better way */ if (*list && **list && !PL_strcmp(value, (*list)[cursize-1])) return rv; if (!*list) { size = 12; cursize = 0; *list = (char **)PORT_ZAlloc(sizeof(char *)* size); if (!*list) { rv = SSM_ERR_OUT_OF_MEMORY; goto done; } } else if (cursize == size-2) { size = size + 12; *list = (char **)PR_Realloc(*list, sizeof(char *)*size); if (!*list) { rv = SSM_ERR_OUT_OF_MEMORY; goto done; } /* clear the memory */ memset(*list+cursize, 0, sizeof(char*)*(size-cursize)); } (*list)[cursize] = PL_strdup(value); cursize++; done: return rv;}/****** retrieve all the values for a parent key: * SSMStatus * PREF_CreateChildList(PrefSet * prefs, * const char* parent_key, * char **child_list); * * For parent key x.y retrieves key names directly below x.y : * x.y.a, x.y.b, x.y.c, etc. * * For parent_key == NULL returns all the preferences values. * (Why would anyone want to do that? ) * * Allocates and returns char * array with all the requested values. * Caller is responsible for freeing memory. * * Used for LDAP server look-up for UI. *****/SSMStatus PREF_CreateChildList(PrefSet * prefs, const char* parent_key, char ***child_list){ SSMStatus rv = SSM_FAILURE; PRCList * link = NULL; char * child, * tmp; int parent_key_len = parent_key?strlen(parent_key):0; if (!prefs || !child_list) goto loser; *child_list = NULL; /* walk the list until find interesting key */ if (!PR_CLIST_IS_EMPTY(&prefs->list)) { for (link = PR_LIST_HEAD(&prefs->list); link != &prefs->list; link = PR_NEXT_LINK(link)) { PrefItemNode* node = (PrefItemNode*)link; if (!parent_key || ((tmp = strstr(node->item->key, parent_key)) && tmp[parent_key_len] == '.')) { /* found the key */ /* append "child" string: "child" in parent.child.more */ child = PL_strdup(node->item->key + parent_key_len + 1); tmp = strtok(child, "."); rv = pref_append_value(child_list, tmp); PR_Free(child); if (rv != SSM_SUCCESS) goto loser; } } } rv = SSM_SUCCESS; loser: return rv;}#endif /* PREFS LITE */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -