📄 textgen.c
字号:
/* -*- Mode: C; c-basic-offset: 4; indent-tabs-mode: nil -*- *//* * 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. */#include "prmon.h"#include "muteximp.h"#include "nlsutil.h"#include "serv.h" /* for SSM_DEBUG */#include "ssmerrs.h"#include "resource.h"#include "kgenctxt.h"#include "textgen.h"#include "minihttp.h"#include "certlist.h"#include "ssldlgs.h"#include "oldfunc.h"#include "pkcs11ui.h"#include "signtextres.h"#include "prmem.h"#include "certres.h"#include "advisor.h"char *resBundleNames[] = { "psm_text", "psm_ui", "psm_bin", "psm_doc"};static char *digits_ch = "0123456789";typedef enum{ TEXTGEN_PUNCT_LEFTBRACE = (int) 0, TEXTGEN_PUNCT_RIGHTBRACE, TEXTGEN_PUNCT_SINGLEQUOTE, TEXTGEN_PUNCT_COMMA, TEXTGEN_PUNCT_DOLLAR, TEXTGEN_PUNCT_SPACE, TEXTGEN_PUNCT_PERCENT, TEXTGEN_PUNCT_MAX_INDEX} PunctIndex;static char *punct_ch = "{}',$ %"; /* make this match the enum above */typedef struct KeywordHandlerEntry{ char *keyword; KeywordHandlerFunc func;} KeywordHandlerEntry;static SSMCollection *keyword_handlers = NULL;/* These should only have to be initialized once */static UniChar *digits = NULL;/* Forward declarations */SSMStatus SSM_GetAndExpandTextKeyedByString(SSMTextGenContext *cx, const char *key, char **result);/* password keyword handler */SSMStatus SSM_ReSetPasswordKeywordHandler(SSMTextGenContext * cx);SSMStatus SSM_ShowFollowupKeywordHandler(SSMTextGenContext * cx);SSMStatus SSM_PasswordPrefKeywordHandler(SSMTextGenContext * cx);/* Return PR_TRUE if (ch) is a digit. */PRBoolSSMTextGen_IsUniCharNumeric(UniChar ch){ int i; if (digits) { for (i=0;i<10;i++) { if (digits[i] == ch) return PR_TRUE; } } return PR_FALSE;}/* Given a string and offset of a left brace, find the matching right brace. */static intSSMTextGen_FindRightBrace(char *str){ int i, startOff = 0; int result = -1, len; char *raw; if (!punct_ch[0] || !str || (startOff < 0)) return -1; /* didn't initialize earlier, or bad params */ /* Get the length of the source string */ len = PL_strlen(str); raw = str; /* Walk along the string until we find either a left or right brace. */ for(i=startOff+1;(i < len) && (result < 0);i++) { if (raw[i] == punct_ch[TEXTGEN_PUNCT_LEFTBRACE]) { /* Another left brace. Recurse. Assigning back to i is ok, because we'll increment before the next check (and avoid double-counting the terminating right brace on which i sits after this call). */ i += SSMTextGen_FindRightBrace(&str[i]); } else if (raw[i] == punct_ch[TEXTGEN_PUNCT_RIGHTBRACE]) { /* Found the end. Return now. */ result = i; break; } } return result;}static SSMStatusSSMTextGen_DequotifyString(char *str){ if (str == NULL) { return SSM_FAILURE; } while ((str = PL_strchr(str, '\'')) != NULL) { if (str[1] == '\'') { memmove(str, &str[1], PL_strlen(&str[1])+1); } str++; } return SSM_SUCCESS;}PRBoolSSMTextGen_StringContainsFormatParams(char *str){ while ((str = PL_strchr(str, punct_ch[TEXTGEN_PUNCT_PERCENT])) != NULL) { if (isdigit(str[1])) { return PR_TRUE; } str++; } return PR_FALSE;}static PRInt32SSMTextGen_CountCommas(char *str){ PRInt32 result = 0; while ((str = PL_strchr(str,punct_ch[TEXTGEN_PUNCT_COMMA])) != NULL) { result++; str++; } return result;}/* Show a stack frame. */voidSSMTextGen_Show(SSMTextGenContext *cx){ char *temp_ch = NULL; temp_ch = cx->m_keyword; SSM_DEBUG("{%s", temp_ch); if (cx->m_params && (SSM_Count(cx->m_params) > 0)) { char *param = (char *) SSM_At(cx->m_params, 0); int i = 0; while(param) { temp_ch = param; printf("%c%s", ((i==0)? '/':','), temp_ch); param = (char *) SSM_At(cx->m_params, ++i); } } printf("}\n");}/* Trace back a text gen context. */voidSSMTextGen_DoTraceback(SSMTextGenContext *cx){ if (!cx) return; /* Depth first traceback */ if ((cx->m_caller) && (cx->m_caller != cx)) SSMTextGen_DoTraceback(cx->m_caller); SSMTextGen_Show(cx);}voidSSMTextGen_Traceback(char *reason, SSMTextGenContext *cx){ if (reason) SSM_DEBUG("ERROR - %s\n", reason); SSM_DEBUG("Traceback:\n"); if (!cx) SSM_DEBUG("(None available)\n"); else SSMTextGen_DoTraceback(cx); SSM_DEBUG("-- End of traceback --\n");}/* Create/destroy a textgen context. */SSMStatusSSMTextGen_NewContext(SSMTextGenContext *caller, /* can be NULL */ HTTPRequest *req, char *keyword, char **params, SSMTextGenContext **result){ SSMStatus rv = SSM_SUCCESS; SSMTextGenContext *cx = (SSMTextGenContext *) PR_CALLOC(sizeof(SSMTextGenContext)); if (!cx) goto loser; /* Create the collection within the context. */ cx->m_params = SSM_NewCollection(); if (!cx->m_params) goto loser; cx->m_caller = caller; cx->m_request = req; if (keyword) cx->m_keyword = PL_strdup(keyword); else cx->m_keyword = PL_strdup(""); if (cx->m_keyword == NULL) goto loser; cx->m_result = PL_strdup(""); if (params) { char *p; PRIntn i; for(i=0; params[i] != NULL; i++) { p = params[i]; if (p) SSM_Enqueue(cx->m_params, SSM_PRIORITY_NORMAL, p); } } goto done; loser: if (rv == SSM_SUCCESS) rv = SSM_FAILURE; if (cx) { if (cx->m_params) { /* Couldn't finish filling out the params. The parameter strings are still owned by the caller at this point, so clear out the collection before destroying the context. */ char *tmp; SSMStatus trv; /* Deallocate the parameters individually, then destroy the parameter collection. */ trv = SSM_Dequeue(cx->m_params, SSM_PRIORITY_NORMAL, (void **) &tmp, PR_FALSE); while ((trv == PR_SUCCESS) && tmp) { trv = SSM_Dequeue(cx->m_params, SSM_PRIORITY_NORMAL, (void **) &tmp, PR_FALSE); } } SSMTextGen_DestroyContext(cx); cx = NULL; } done: *result = cx; return rv;}SSMStatusSSMTextGen_NewTopLevelContext(HTTPRequest *req, SSMTextGenContext **result){ SSMTextGenContext *cx = NULL; SSMStatus rv = SSM_SUCCESS; rv = SSMTextGen_NewContext(NULL, req, NULL, NULL, &cx); *result = cx; return rv;}static SSMTextGenContext *SSMTextGen_PushStack(SSMTextGenContext *cx, char *key, char **params){ SSMTextGenContext *newcx = NULL; SSMStatus rv; rv = SSMTextGen_NewContext(cx, cx->m_request, key, params, &newcx); if (rv != SSM_SUCCESS) SSMTextGen_Traceback("Couldn't push textgen context stack", cx);#if 0 if (newcx) { SSM_DEBUG("New stack frame: "); SSMTextGen_Show(newcx); }#endif return newcx;}voidSSMTextGen_DestroyContext(SSMTextGenContext *cx){ PRInt32 i; if (cx->m_params) { char *tmp; SSMStatus rv; /* Deallocate the parameters individually, then destroy the parameter collection. */ rv = SSM_Dequeue(cx->m_params, SSM_PRIORITY_NORMAL, (void **) &tmp, PR_FALSE); while ((rv == PR_SUCCESS) && tmp) { PR_Free(tmp); rv = SSM_Dequeue(cx->m_params, SSM_PRIORITY_NORMAL, (void **) &tmp, PR_FALSE); } SSM_DestroyCollection(cx->m_params); } if (cx->m_keyword) PR_Free(cx->m_keyword); if (cx->m_result) PR_Free(cx->m_result); for(i=0;i<SSM_RESBNDL_COUNT;i++) { } PR_Free(cx);}SSMResource *SSMTextGen_GetControlConnection(SSMTextGenContext *cx){ if (cx && cx->m_request && cx->m_request->ctrlconn) return &(cx->m_request->ctrlconn->super.super); else return NULL;}SSMResource *SSMTextGen_GetTargetObject(SSMTextGenContext *cx){ if (cx && cx->m_request && cx->m_request->target) return cx->m_request->target; else return SSMTextGen_GetControlConnection(cx);}/* Allocate/deallocate an array of UTF8 Strings. */static voidSSMTextGen_DeleteStringPtrArray(char **array){ PRInt32 i; if (array) { for(i=0; array[i] != NULL; i++) { PR_Free(array[i]); array[i] = NULL; } PR_Free(array); }}/* Given a comma-delimited UnicodeString, split the first string off and put the remainder of the fields into an array. */static SSMStatusSSMTextGen_SplitKeywordParams(const char *orig, char **keywdResult, char ***paramResult){ char **params = NULL; char *keywd; char *space, *cursor, *comma; PRInt32 argLen;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -