📄 prefs.c
字号:
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- *//* * The contents of this file are subject to the Mozilla Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is the Netscape security libraries. * * The Initial Developer of the Original Code is Netscape * Communications Corporation. Portions created by Netscape are * Copyright (C) 1994-2000 Netscape Communications Corporation. All * Rights Reserved. * * Contributor(s): * * Alternatively, the contents of this file may be used under the * terms of the GNU General Public License Version 2 or later (the * "GPL"), in which case the provisions of the GPL are applicable * instead of those above. If you wish to allow use of your * version of this file only under the terms of the GPL and not to * allow others to use your version of this file under the MPL, * indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by * the GPL. If you do not delete the provisions above, a recipient * may use your version of this file under either the MPL or the * GPL. */#if 0#include "prtypes.h"#include "prlock.h"#include "prmem.h"#include "prio.h"#include "prlog.h"#include "prerror.h"#include "prclist.h"#include "plstr.h"#include "prefs.h"/* Number of hash buckets. As we add prefs, we should raise this. */#define NUM_BUCKETS 64static struct { PRLock *lock; PRCList list;} pref_file_list = { NULL };struct PrefFileStr { PRCList link; PRLock *lock; int ref_cnt; PrefFile *next; char *filename; PRBool modified; PLHashTable *hash;};typedef struct DefaultPrefs { char *key; char *value;} DefaultPrefs;DefaultPrefs pref_defaults[] = { { "enable_ssl2", "true" }, { "enable_ssl3", "true" }, { NULL, NULL }};static PLHashNumberpref_HashString(const void *key){ PLHashNumber result; char *string; result = 0; string = (char *)key; while(*string != '\0') { result = (result << 4) + (result >> 28); result += *string; string++; } return result;}static PRIntnpref_HashCompareKey(const void *v1, const void *v2){ if (strcmp(v1, v2) == 0) return 1; else return 0;}static PRIntnpref_HashCompareValue(const void *v1, const void *v2){ if (v1 == v2) return 1; else return 0;}static void *pref_allocTable(void *pool, PRSize size){ return PR_Malloc(size);}static voidpref_freeTable(void *pool, void *item){ PR_Free(item);}static PLHashEntry *pref_allocEntry(void *pool, const void *key){ return PR_NEW(PLHashEntry);}static voidpref_freeEntry(void *pool, PLHashEntry *he, PRUintn flag){ PR_Free(he->value); if (flag == HT_FREE_ENTRY) PR_DELETE(he);}static PLHashAllocOps pref_HashAllocOps = { pref_allocTable, pref_freeTable, pref_allocEntry, pref_freeEntry};struct StringBufStr { char *str; int len; int space;};typedef struct StringBufStr StringBuf;static StringBuf *str_create(int space){ StringBuf *buf; buf = PR_NEW(StringBuf); if (buf == NULL) goto loser; buf->str = PR_Malloc(space + 1); if (buf->str == NULL) goto loser; buf->str[0] = '\0'; buf->len = 0; buf->space = space; return buf;loser: if (buf != NULL) { if (buf->str != NULL) PR_Free(buf->str); PR_DELETE(buf); } return NULL;}static SSMStatusstr_addchar(StringBuf *buf, char c){ int len, space; PR_ASSERT(buf->len <= buf->space); /* If we had a previous allocation failure, fail immediately. */ if (buf->space == 0) goto loser; if (buf->len == buf->space) { buf->space *= 2; buf->str = PR_Realloc(buf->str, buf->space + 1); if (buf->str == NULL) goto loser; } buf->str[len] = c; len++; buf->str[len] = '\0'; return PR_SUCCESS;loser: buf->space = 0; buf->len = 0; return PR_FAILURE;}static voidstr_clear(StringBuf *buf){ buf->len = 0; buf->str[0] = '\0';}static char *str_dup(StringBuf *buf){ return PL_strdup(buf->str);}static voidstr_destroy(StringBuf *buf){ if (buf != NULL) { if (buf->str != NULL) PR_Free(buf->str); PR_DELETE(buf); }}typedef enum ParseState { parse_key, parse_value } ParseState;static SSMStatuspref_ReadPrefs(PrefFile *prefs){ PRFileDesc *fd; StringBuf *keybuf, *valbuf; char *readbuf; int i, readlen; SSMStatus rv; char c; ParseState parse_state; fd = PR_Open(prefs->filename, PR_RDONLY, 0); if (fd == NULL) { /* No prefs file is okay. Just don't do anything. */ if (PR_GetError() == PR_FILE_NOT_FOUND_ERROR) return PR_SUCCESS; else return PR_FAILURE; } keybuf = str_create(128); if (keybuf == NULL) goto loser; valbuf = str_create(128); if (valbuf == NULL) goto loser; readbuf = PR_Malloc(1024); if (readbuf == NULL) goto loser; readlen = PR_Read(fd, readbuf, 1024); i = 0; while(readlen != 0) { c = readbuf[i]; switch(parse_state) { case parse_key: if (c == ':') { parse_state = parse_value; } else { str_addchar(keybuf, c); } break; case parse_value: if (c == '\n') { PLHashEntry *entry; char *key, *val; key = str_dup(keybuf); val = str_dup(valbuf); entry = PL_HashTableAdd(prefs->hash, key, val); if (entry == NULL) { PR_Free(key); PR_Free(val); } parse_state = parse_key; } else { str_addchar(valbuf, c); } break; } i++; if (i == readlen) { readlen = PR_Read(fd, readbuf, 1024); i = 0; } } rv = PR_SUCCESS;done: if (fd != NULL) PR_Close(fd); if (keybuf != NULL) str_destroy(keybuf); if (valbuf != NULL) str_destroy(valbuf); if (readbuf != NULL) PR_Free(readbuf); return rv;loser: rv = PR_FAILURE; goto done;}static PrefFile *pref_OpenNewPrefFile(char *filename){ PrefFile *prefs; PRFileDesc *fd; SSMStatus status; prefs = PR_NEW(PrefFile); if (prefs == NULL) goto loser; prefs->lock = PR_NewLock(); if (prefs->lock == NULL) goto loser; prefs->filename = PL_strdup(filename); if (prefs->filename == NULL) goto loser; prefs->hash = PL_NewHashTable(NUM_BUCKETS, pref_HashString, pref_HashCompareKey, pref_HashCompareValue, NULL, NULL); if (prefs->hash == NULL) goto loser; status = pref_ReadPrefs(prefs); if (status != PR_SUCCESS) goto loser; prefs->ref_cnt = 1; return prefs;loser: if (prefs != NULL) { if (prefs->lock != NULL) PR_DestroyLock(prefs->lock); if (prefs->filename != NULL) PR_Free(prefs->filename); if (prefs->hash != NULL) { PL_HashTableDestroy(prefs->hash); } PR_DELETE(prefs); } return NULL;}PrefFile *PREF_OpenPrefs(char *filename){ PrefFile *prefs; PRCList *link, *list; /* Init the global file list if this is the first time. */ if (pref_file_list.lock == NULL) { pref_file_list.lock = PR_NewLock(); if (pref_file_list.lock == NULL) return NULL; PR_INIT_CLIST(&pref_file_list.list); } /* First, check to see if we've already got this file open. */ PR_Lock(pref_file_list.lock); list = &pref_file_list.list; for (link = PR_LIST_HEAD(list); link != list; link = PR_NEXT_LINK(link)) { prefs = (PrefFile *)link; if (PL_strcmp(filename, prefs->filename) == 0) { PR_Lock(prefs->lock); prefs->ref_cnt++; PR_Unlock(prefs->lock); PR_Unlock(pref_file_list.lock); return prefs; } } /* We don't already have this prefs file open, so open it. */ prefs = pref_OpenNewPrefFile(filename); if (prefs == NULL) goto loser; PR_INSERT_BEFORE(&prefs->link, list); PR_Unlock(pref_file_list.lock); return prefs;loser: PR_Unlock(pref_file_list.lock); return NULL;}static PRIntnpref_writeEnumerator(PLHashEntry *he, PRIntn i, void *arg){ PRFileDesc *fd = (PRFileDesc *)arg; PR_Write(fd, he->key, PL_strlen(he->key)); PR_Write(fd, ":", 1); PR_Write(fd, he->value, PL_strlen(he->value)); PR_Write(fd, "\n", 1); return HT_ENUMERATE_NEXT;}SSMStatusPREF_WritePrefs(PrefFile *prefs){ PRFileDesc *fd; SSMStatus status = PR_SUCCESS; PR_Lock(prefs->lock); if (prefs->modified == PR_FALSE) goto done; fd = PR_Open(prefs->filename, PR_RDWR | PR_CREATE_FILE | PR_TRUNCATE, 0600); if (fd == NULL) { status = PR_FAILURE; goto done; } PL_HashTableEnumerateEntries(prefs->hash, pref_writeEnumerator, fd);done: PR_Unlock(prefs->lock); PR_Close(fd); return status;}SSMStatusPREF_ClosePrefs(PrefFile *prefs){ SSMStatus status; PR_Lock(pref_file_list.lock); PR_Lock(prefs->lock); PR_ASSERT(prefs->ref_cnt >= 1); prefs->ref_cnt--; if (prefs->ref_cnt > 0) { PR_Unlock(prefs->lock); PR_Unlock(pref_file_list.lock); return PR_SUCCESS; } PR_REMOVE_LINK(&prefs->link); PR_Unlock(pref_file_list.lock); status = PREF_WritePrefs(prefs); PR_DestroyLock(prefs->lock); PR_Free(prefs->filename); PL_HashTableDestroy(prefs->hash); PR_Free(prefs); return status;}static SSMStatuspref_SetStringPref_unlocked(PrefFile *prefs, char *name, char *value){ PLHashEntry *entry; char *key, *val; key = PL_strdup(key); if (key == NULL) goto loser; val = PL_strdup(value); if (val == NULL) goto loser; entry = PL_HashTableAdd(prefs->hash, key, val); if (entry == NULL) goto loser; return PR_SUCCESS;loser: if (key != NULL) PR_Free(key); if (val != NULL) PR_Free(val); return PR_FAILURE;}SSMStatusPREF_SetStringPref(PrefFile *prefs, char *name, char *value){ SSMStatus status; PR_Lock(prefs->lock); status = pref_SetStringPref_unlocked(prefs, name, value); prefs->modified = PR_TRUE; PR_Unlock(prefs->lock); return status;}char *PREF_GetStringPref(PrefFile *prefs, char *name){ char *val; PR_Lock(prefs->lock); val = PL_HashTableLookup(prefs->hash, name); if (val != NULL) val = PL_strdup(val); PR_Unlock(prefs->lock); return val;}static SSMStatuspref_SetDefaultPrefs(PrefFile *prefs){ DefaultPrefs *dp; SSMStatus status = PR_SUCCESS; PR_Lock(prefs->lock); dp = pref_defaults; while(dp->key != NULL) { status = pref_SetStringPref_unlocked(prefs, dp->key, dp->value); if (status != PR_SUCCESS) goto loser; dp++; }loser: PR_Unlock(prefs->lock); return status;}#else /* PREFS LITE *//*------------------------------------------------------*/#include "nspr.h"#include "prtypes.h"#include "prclist.h"#include "prlock.h"#include "prmem.h"#include "prlog.h"#include "plstr.h"#include "prefs.h"struct PrefSetStr { PRCList list; PRLock* lock; PRBool modified;};typedef struct PrefItemStr { char* key; char* value;} PrefItem;typedef struct PrefItemNodeStr { PRCList link; PrefItem* item;} PrefItemNode;/* Default values with which a PrefSet is initialized * This list contains only PSM-owned (i.e. security items) */ PrefItem pref_defaults[] = { {"security.enable_ssl2", "true"}, {"security.enable_ssl3", "true"}, {"security.default_personal_cert", "Ask Every Time"}, {"security.default_mail_cert", NULL}, {"security.ask_for_password", "2"}, {"security.password_lifetime", "480"}, {NULL, NULL}};/* keys need to be in sync with the list given in prefs.h */char* STRING_TRUE = "true";char* STRING_FALSE = "false";static void pref_free_pref_item(PrefItem* pref){ if (pref != NULL) { if (pref->key != NULL) { PR_Free(pref->key); } if (pref->value != NULL) { PR_Free(pref->value); } PR_Free(pref); }}static PrefItem* pref_new_pref_item(char* key, char* value){ PrefItem* tmp = NULL; PR_ASSERT(key != NULL); tmp = (PrefItem*)PR_NEWZAP(PrefItem); if (tmp == NULL) { return tmp; } tmp->key = PL_strdup(key); if (tmp->key == NULL) { goto loser; } if (value != NULL) { tmp->value = PL_strdup(value);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -