📄 swutil.c
字号:
/* swutil.c - general purpose utilities for SQLweb/*/* Copyright (c) 1995-1999 Applied Information Technologies, Inc./* All Rights Reserved./* /* Distributed uder the GNU General Public License which was included in/* the file named "LICENSE" in the package that you recieved./* If not, write to:/* The Free Software Foundation, Inc.,/* 675 Mass Ave, Cambridge, MA 02139, USA. *//* #define USEHASHTABLE */#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <string.h>#include <stdarg.h>/* #include <time.h> */#include <sys/stat.h>#include "sqlweb.h"/*/* internal functions */static eBoolean_t GetSymbolREF(char *pName,SYMBOL **pSym);static eBoolean_t GetARRSymbolREF(char *pName,int iIndex,SYMBOL **pSym);static eBoolean_t iPrintSymbol(SYMBOL *pSym);static eBoolean_t ClearHTMLBuf();static void unescape_url(char *url);static int CmpTags(TAG *pTag1, TAG *pTag2);static int CmpTagName(TAG *pTag1, char *pTagName);static eBoolean_t FreePI_opt(PI *pPI, eBoolean_t bFreelPI);static eBoolean_t AddHTMLHeader(char *pHeader);static eBoolean_t CalcFileSize (char *pFileName ,long *plFileSize ,eBoolean_t bEscapeFlag );/*/* Global variables */static LIST *glSymbolTable; /* Global Symbol Table */static LIST *glMsg = NULL_LIST; /* Error/Message Stack */static LIST *glTagList = NULL_LIST; /* The Tag List */static char gsHTMLBuf[MAX_HTMLBUF_SIZE];/* The HTML Buffer */static char *gpHTMLBuf = gsHTMLBuf; /* Pointer into HTML Buffer */static int giHTMLDebugLevel=0; /* Debugging Level */static LIST *glPIFreeList = NULL_LIST; /* List of Free'd PI's */static LIST *glPIAFreeList =NULL_LIST; /* List of Free'd PIA's */static char *gpEmptyString = ""; /* Empty String for DupBuf */static LIST *glHeaderList = NULL_LIST; /* List of HTML Headers */eBoolean_tPrintHTMLErrStack(){ char sBuf[MAX_BUFSIZ], *pBuf; SYMBOL *pSym; char *pErrHeader = "<H1>SQLweb Error</H1>"; PrintHTMLHeader("text/html"); if(ISeTrue(GetSymbolValueREF("SQLWEB_ERROR_HEADER",&pBuf))) { pErrHeader=pBuf; } OutputHTML("%s\n", pErrHeader);/* if(ISeTrue(GetSymbolREF("SQLWEB_MESSAGE",&pSym))){/* OutputHTML("Last SQLWEB_MESSAGE: %s<BR>\n",pSym->pValue);/* } */ while( MsgPop(sBuf) ) { OutputHTML("%s<BR>\n",sBuf); } FlushHTMLBuf(); return(eTrue);}eBoolean_tBuildSymbolTable(char *pBuf){ char *pName ,*pEndName ,*pValue ,*pEndValue ; /* /* Load Entire Environment into SYMBOL Table */ for(pName=pBuf;pName; pName = pEndValue? pEndValue+1 :0){ pEndName=strchr(pName,'='); if(pEndName) { *pEndName=0; pValue = pEndName+1; pEndValue=strchr(pValue,'&'); if(pEndValue) { *pEndValue=0; } unescape_url(pName); unescape_url(pValue); FRMSym(DupBuf(pName),DupBuf(pValue)); } } return(eTrue);}eBoolean_tGetSymbolValue (char *pName ,char *pOutValue ){ SYMBOL *pSym; DebugHTML(__FILE__,__LINE__,6,"GetSymbolValue(%s)",pName); if(ISeTrue(GetSymbolREF(pName,&pSym))){ strcpy(pOutValue,pSym->pValue); return(eTrue); } *pOutValue = 0; return(eFalse);}eBoolean_tGetSymbolValueREF (char *pName ,char **pOutValue ){ SYMBOL *pSym; DebugHTML(__FILE__,__LINE__,6,"GetSymbolValueREF(%s)",pName); if(ISeTrue(GetSymbolREF(pName,&pSym))){ (*pOutValue) = pSym->pValue; return(eTrue); } (*pOutValue) = 0; return(eFalse);}eBoolean_tGetRawSymbolValueREF (char *pName ,char **pOutValue ,long *lSize ){ SYMBOL *pSym; DebugHTML(__FILE__,__LINE__,6,"GetRawSymbolValueREF(%s)",pName); if(ISeTrue(GetSymbolREF(pName,&pSym))){ (*pOutValue) = pSym->pValue; (*lSize) = pSym->lSize; return(eTrue); } (*pOutValue) = 0; (*lSize) = 0; return(eFalse);}eBoolean_tGetARRSymbolValueREF (char *pName ,int iIndex ,char **pOutValue ){ SYMBOL *pSym; DebugHTML(__FILE__,__LINE__,6,"GetARRSymbolValueREF(%s,%d)",pName,iIndex); if(ISeTrue(GetARRSymbolREF(pName,iIndex,&pSym))){ (*pOutValue) = pSym->pValue; return(eTrue); } (*pOutValue) = 0; return(eFalse);}static eBoolean_tGetSymbolREF (char *pName ,SYMBOL **pSym ){ SYMBOL Sym; /* HASH Table restriction... */ Sym.pName = pName; /* only search by struct.. */ (*pSym)= l_find(glSymbolTable,GetSymbolName,&Sym); if(*pSym) { return(eTrue); } return(eFalse);}static eBoolean_tGetARRSymbolREF (char *pName ,int iIndex ,SYMBOL **pSym ){ SYMBOL Sym; /* HASH Table restriction... */ Sym.pName = pName; /* only search by struct.. */ for( (*pSym)= l_find(glSymbolTable,GetSymbolName,&Sym) ; (*pSym) && (iIndex-->0) ; (*pSym)=l_fnext(glSymbolTable)) { if((*pSym) && !is_casematch((*pSym)->pName,pName)) { *pSym=0; return(eFalse); } } if(*pSym && is_casematch((*pSym)->pName,pName)) { return(eTrue); } *pSym=0; return(eFalse);}eBoolean_tIsSymbolValue (char *pName ,char *pValue ){ SYMBOL Sym,*pSym; DebugHTML(__FILE__,__LINE__,6,"IsSymbolValue(%s,%s)",pName,pValue); Sym.pName = pName; Sym.pValue = pValue; for( pSym=l_find(glSymbolTable,GetSymbolName,&Sym); pSym && is_casematch(pSym->pName,pName); pSym=l_fnext(glSymbolTable)) { if(is_match(pSym->pValue,pValue)) return(eTrue); } return(eFalse);}/*/* Supports the HASH function requirements/* returns the "HASH" key string for the struct. */#ifdef USEHASHTABLEchar *GetSymbolName(SYMBOL *pSym){ /* fprintf(stderr,"KEY(%s)\n",pSym->pName); */ return(pSym->pName);}#elseintGetSymbolName(SYMBOL *pSym,SYMBOL *p2) { return(iStrCaseCmp(pSym->pName,p2->pName)); }#endif/*/* Compare two symbols, supports LIST functions */intiCmpSymbolNames(SYMBOL *pSym1, SYMBOL *pSym2){ return( iStrCaseCmp( pSym1->pName, pSym2->pName) );}/*/* Compare a SYMBOL to a "Symbol Name" */intiCmpSymbolpName(SYMBOL *pSym, char *pName){ return(iStrCaseCmp(pSym->pName,pName));}static eBoolean_tiPrintSymbol(SYMBOL *pSym){ OutputHTML("<!%s=\"%s\">\n",pSym->pName,pSym->pValue); return(eTrue);}eBoolean_tiPrintHTMLSymbol(SYMBOL *pSym){ char sBuf[MAX_TOKVAL_SIZE] ,*pBuf ; if(pSym->pValue && iStrLen(pSym->pValue)>0) { char *pValue = pSym->pValue; pBuf = sBuf; while(*pValue && (pBuf-sBuf<sizeof(sBuf)) ){ if(*pValue == '<') { strcpy(pBuf,"<"); pBuf += 4; ++pValue; } else if(*pValue == '>') { strcpy(pBuf,">"); pBuf += 4; ++pValue; } else { *pBuf++ = *pValue++; } } *pBuf=0; OutputHTML(" %s=\"%s\"", pSym->pName, sBuf); } else OutputHTML(" %s", pSym->pName); return(eTrue);}charx2c(char *what){ register char digit; digit =(char)(what[0] >= 'A' ?((what[0] & 0xdf)-'A')+10 :(what[0]-'0')); digit *=16; digit +=(char)(what[1] >= 'A' ?((what[1] & 0xdf)-'A')+10 :(what[1]-'0')); return(digit);}voidunescape_url(char *url){ register int x,y; for(x=0,y=0;url[y];++x,++y) { if(url[y]=='+') { url[y]=' '; } if((url[x] = url[y]) == '%') { url[x] = x2c(&url[y+1]); y+=2; } } url[x] = '\0'; return;}/*/* Push Message onto the Error Stack for/* later display to the end user. */voidMsgPush ( const char *pFmt , ... ){ va_list pParms; register char *pMsg; char sBuf[BUFSIZ]; /* Build PrintF style buffer */ va_start(pParms,pFmt); vsprintf(sBuf,pFmt,pParms); if(glMsg==NULL_LIST) { if((glMsg=l_create("QUEUE"))==NULL_LIST) { DebugHTML(__FILE__,__LINE__,0,"MsgPush:Failed:%s",sBuf); /* fprintf(stderr,"MsgStack:Push:l_create Failed,%s\n",sBuf); /* fflush(stderr); */ return; /* (eFalse) */ } } /* /* Store message in list */ pMsg=DupBuf(sBuf); if(!ENQ(glMsg,pMsg) ) { return; /* (eFalse); */ } return; /* (eTrue); */}/*/* Pop Message off the Error Stack to/* display to the end user. */eBoolean_tMsgPop(char *pOutMsgBuf ){ char *pMsg; DebugHTML(__FILE__,__LINE__,9,"MsgPop:%x:%d\n",glMsg,l_size(glMsg)); if(!glMsg) { *pOutMsgBuf=0; return(eFalse); } pMsg=DEQ(glMsg); if(!pMsg) { *pOutMsgBuf=0; return(eFalse); } strcpy(pOutMsgBuf, pMsg); /* free(pMsg); */ return(eTrue);}eBoolean_tAddSymbol (int iType ,char *pName ,char *pValue ,eBoolean_t bReplace ,long lSize ){ SYMBOL *pSym; /* /* Replace Symbol (if bReplace FLAG && if found) */ if(ISeTrue(bReplace) && ISeTrue(GetSymbolREF(pName,&pSym))){ /* fprintf(stderr,"Replace:%s:%s=%s\n",pName,pSym->pValue,pValue); fflush(stderr); */ if((iType!=ENV_SYMBOL && iType!=INI_SYMBOL) && (pSym->iType == ENV_SYMBOL || pSym->iType == INI_SYMBOL)) { DebugHTML(__FILE__,__LINE__,0 ,"AddSymbol:Attempted to overwrite CGI or INI Symbol:%s" ,pName ); } else { pSym->pValue = pValue; pSym->lSize = lSize; } return(eTrue); } /* Duplicate or NOT FOUND */ DebugHTML(__FILE__,__LINE__,5,"Calling NewPIA(%s)",pName); pSym = NewPIA(); if(!pSym){ MsgPush("NewPIA Failed in AddSymbol"); return(eFalse); } /* (void)memset((pSym),0,sizeof(SYMBOL)); */ pSym->iType = iType; pSym->pValue= pValue; pSym->pName = DupBuf(pName); pSym->lSize = lSize; if( glSymbolTable==NULL_LIST) {# ifdef USEHASHTABLE glSymbolTable=l_create("HASH");# else glSymbolTable=l_create("ASCEND");# endif if(glSymbolTable==NULL_LIST){ MsgPush("l_create Failed in AddSymbol"); return(eFalse); } } RETeFalse(l_insert(glSymbolTable,GetSymbolName,pSym) ,"l_insert Failed in AddSymbol" ); return(eTrue);}eBoolean_tOutputHTML ( const char *pFmt ,... ){ va_list pParms; unsigned int iBufLen; char sBuf[MAX_BUFSIZ]; /* /* Build PrintF style buffer */ va_start(pParms,pFmt); iBufLen = vsprintf(sBuf,pFmt,pParms); if(iBufLen>sizeof(gsHTMLBuf)) { MsgPush("OutputHTML:Buffer Overflow"); return(eFalse); } if(iBufLen>(sizeof(gsHTMLBuf)-(gpHTMLBuf-gsHTMLBuf))) { FlushHTMLBuf(); } strcpy(gpHTMLBuf,sBuf); gpHTMLBuf += iBufLen; return(eTrue);}static eBoolean_tClearHTMLBuf(){ gpHTMLBuf=gsHTMLBuf; *gpHTMLBuf=0; return(eTrue);}eBoolean_tFlushHTMLBuf(){ /* First ensure the text/html header has been issued. */ PrintHTMLHeader("text/html"); fprintf(stdout,"%s",gsHTMLBuf); fflush(stdout); return( ClearHTMLBuf() );}eBoolean_tPrintHTMLHeader(char *pContentType){ static int iHeader; if( iHeader==0) { char *p; if(ISCOOKED){ fprintf(stdout,"Content-type: %s\n",pContentType); fprintf(stdout,"Cache-Control: no-cache\n"); while( (p=POP(glHeaderList)) ) { fprintf(stdout,"%s\n",p); } /* fprintf(stdout,"Date: %s\n",sNow); /* fprintf(stdout,"Expires: %s\n",sNow); */ fprintf(stdout,"\n"); fflush(stdout); } else { fprintf(stdout ,"<!doctype html public \"-//IETF//DTD HTML//EN\">\n" );/* fprintf(stdout,"<!Copyright (c) 1995 Applied Information Technologies, Inc.>\n");/* fprintf(stdout,"<!\tAll Rights Reserved.>\n"); */ } fflush (stdout); } iHeader=1; return(eTrue);}eBoolean_tDebugHTMLSet(int iDebugLevel){ giHTMLDebugLevel=iDebugLevel; return(eTrue);}intDebugHTMLGet(){ return(giHTMLDebugLevel);}eBoolean_tDebugHTML (char *pFileName ,int iLine ,int iDebugLevel ,char *pFmt ,... ){ va_list pParms; char sBuf[MAX_BUFSIZ]; if(iDebugLevel>giHTMLDebugLevel) return(eTrue); /* Build PrintF style buffer */ va_start(pParms,pFmt); vsprintf(sBuf,pFmt,pParms); OutputHTML("<! %8.8s:%5.5d:%1.1d:%s>\n" ,pFileName ,iLine ,iDebugLevel ,sBuf ); FlushHTMLBuf(); return(eTrue);}eBoolean_tShowSymbolTable(){ return(l_scan(glSymbolTable,(PFI)iPrintSymbol));}static intCmpTags(TAG *pTag1, TAG *pTag2){ return(iStrCmp(pTag1->pTagName,pTag2->pTagName));}static intCmpTagName(TAG *pTag1, char *pTagName){ return(iStrCaseCmp(pTag1->pTagName,pTagName));}eBoolean_tGetTAGByName (char *pTagName ,TAG **pTAG ){ (*pTAG) = l_find(glTagList,CmpTagName,pTagName); if(!(*pTAG)) { /* DebugHTML(__FILE__,__LINE__,2,"GetTAGByName(%s):DFLT",pTagName); */ (*pTAG) = (TAG*)malloc(sizeof(TAG)); if( !(*pTAG) ) { MsgPush("malloc failed"); return(eFalse); } (void)memset((*pTAG),0,sizeof(TAG)); (*pTAG)->pTagName = DupBuf(pTagName); (*pTAG)->pTagEmptyInd = "N"; (*pTAG)->pTagDesc = 0; (*pTAG)->pTagAfterInd = "N"; (*pTAG)->pTagLinkDesc = ""; /* Since, we've got a "DEFAULT" Tag, there is no need to increase /* the size of the list (it'll just slow down subsequent lookups. /* */ l_insert(glTagList,CmpTags,(*pTAG)); return(eTrue); } /* else { /* DebugHTML(__FILE__,__LINE__,2,"GetTAGByName(%s):FOUND",pTagName); /* } */ return(eTrue);}/* Load a Tag given a line like so:/* NAME | EMPTY_IND | AFTER_IND | LINK_DESC | */eBoolean_tLoadTag(char *pTagData){ char *pStart, *pSep, SEP_CHAR='|'; TAG *pTag; pTag = (TAG*)malloc(sizeof(TAG)); if(!pTag){ MsgPush("malloc failed"); return(eFalse); } memset(pTag,0,sizeof(TAG)); pStart = pTagData; pSep=strchr(pTagData,SEP_CHAR); if(pSep) *pSep++=0 ; pTag->pTagName = DupBuf(pStart); pStart = pSep;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -