swutil.c
上传用户:aidanglao
上传日期:2007-01-07
资源大小:69k
文件大小:27k
源码类别:

Oracle数据库

开发平台:

Unix_Linux

  1. /* swutil.c - general purpose utilities for SQLweb
  2. /*
  3. /* Copyright (c) 1995-1999 Applied Information Technologies, Inc.
  4. /* All Rights Reserved.
  5. /*  
  6. /* Distributed uder the GNU General Public License which was included in
  7. /* the file named "LICENSE" in the package that you recieved.
  8. /* If not, write to:
  9. /* The Free Software Foundation, Inc.,
  10. /* 675 Mass Ave, Cambridge, MA 02139, USA.
  11.  */
  12. /* #define USEHASHTABLE
  13.  */
  14. #include <stdio.h>
  15. #include <stdlib.h>
  16. #include <sys/types.h>
  17. #include <string.h>
  18. #include <stdarg.h>
  19. /* #include <time.h>
  20.  */
  21. #include <sys/stat.h>
  22. #include "sqlweb.h"
  23. /*
  24. /* internal functions 
  25.  */
  26. static eBoolean_t GetSymbolREF(char *pName,SYMBOL **pSym);
  27. static eBoolean_t GetARRSymbolREF(char *pName,int iIndex,SYMBOL **pSym);
  28. static eBoolean_t iPrintSymbol(SYMBOL *pSym);
  29. static eBoolean_t ClearHTMLBuf();
  30. static void unescape_url(char *url);
  31. static int CmpTags(TAG *pTag1, TAG *pTag2);
  32. static int CmpTagName(TAG *pTag1, char *pTagName);
  33. static eBoolean_t FreePI_opt(PI *pPI, eBoolean_t bFreelPI);
  34. static eBoolean_t AddHTMLHeader(char *pHeader);
  35. static eBoolean_t CalcFileSize
  36. (char *pFileName
  37. ,long *plFileSize
  38. ,eBoolean_t bEscapeFlag
  39. );
  40. /*
  41. /* Global variables
  42.  */
  43. static LIST *glSymbolTable; /* Global Symbol Table */
  44. static LIST *glMsg = NULL_LIST; /* Error/Message Stack */
  45. static LIST *glTagList = NULL_LIST; /* The Tag List */
  46. static char gsHTMLBuf[MAX_HTMLBUF_SIZE];/* The HTML Buffer */
  47. static char *gpHTMLBuf = gsHTMLBuf; /* Pointer into HTML Buffer */
  48. static int giHTMLDebugLevel=0; /* Debugging Level */
  49. static LIST *glPIFreeList = NULL_LIST; /* List of Free'd PI's */
  50. static LIST *glPIAFreeList =NULL_LIST; /* List of Free'd PIA's */
  51. static char *gpEmptyString = ""; /* Empty String for DupBuf */
  52. static LIST *glHeaderList = NULL_LIST; /* List of HTML Headers */
  53. eBoolean_t
  54. PrintHTMLErrStack()
  55. {
  56.     char sBuf[MAX_BUFSIZ], *pBuf;
  57.     SYMBOL *pSym;
  58.     char *pErrHeader = "<H1>SQLweb Error</H1>";
  59.     PrintHTMLHeader("text/html");
  60.     if(ISeTrue(GetSymbolValueREF("SQLWEB_ERROR_HEADER",&pBuf))) {
  61. pErrHeader=pBuf;
  62.     }
  63.     OutputHTML("%sn", pErrHeader);
  64. /*  if(ISeTrue(GetSymbolREF("SQLWEB_MESSAGE",&pSym))){
  65. /* OutputHTML("Last SQLWEB_MESSAGE: %s<BR>n",pSym->pValue);
  66. /*  } */
  67.     while( MsgPop(sBuf) ) {
  68. OutputHTML("%s<BR>n",sBuf);
  69.     }
  70.     FlushHTMLBuf();
  71.     return(eTrue);
  72. }
  73. eBoolean_t
  74. BuildSymbolTable(char *pBuf)
  75. {
  76.     char *pName
  77. ,*pEndName
  78. ,*pValue
  79. ,*pEndValue
  80.     ;
  81.     /*
  82.     /* Load Entire Environment into SYMBOL Table
  83.      */
  84.     for(pName=pBuf;pName; pName = pEndValue? pEndValue+1 :0){
  85. pEndName=strchr(pName,'=');
  86. if(pEndName) {
  87.     *pEndName=0;
  88.     pValue = pEndName+1;
  89.     pEndValue=strchr(pValue,'&');
  90.     if(pEndValue) {
  91. *pEndValue=0;
  92.     }
  93.     unescape_url(pName);
  94.     unescape_url(pValue);
  95.     FRMSym(DupBuf(pName),DupBuf(pValue));
  96. }
  97.     }
  98.     return(eTrue);
  99. }
  100. eBoolean_t
  101. GetSymbolValue
  102.     (char *pName
  103.     ,char *pOutValue
  104.     )
  105. {
  106.     SYMBOL *pSym;
  107.     DebugHTML(__FILE__,__LINE__,6,"GetSymbolValue(%s)",pName);
  108.     if(ISeTrue(GetSymbolREF(pName,&pSym))){
  109. strcpy(pOutValue,pSym->pValue);
  110. return(eTrue);
  111.     }
  112.     *pOutValue = 0;
  113.     return(eFalse);
  114. }
  115. eBoolean_t
  116. GetSymbolValueREF
  117.     (char *pName
  118.     ,char **pOutValue
  119.     )
  120. {
  121.     SYMBOL *pSym;
  122.     DebugHTML(__FILE__,__LINE__,6,"GetSymbolValueREF(%s)",pName);
  123.     if(ISeTrue(GetSymbolREF(pName,&pSym))){
  124. (*pOutValue) = pSym->pValue;
  125. return(eTrue);
  126.     }
  127.     (*pOutValue) = 0;
  128.     return(eFalse);
  129. }
  130. eBoolean_t
  131. GetRawSymbolValueREF
  132.     (char *pName
  133.     ,char **pOutValue
  134.     ,long *lSize
  135.     )
  136. {
  137.     SYMBOL *pSym;
  138.     DebugHTML(__FILE__,__LINE__,6,"GetRawSymbolValueREF(%s)",pName);
  139.     if(ISeTrue(GetSymbolREF(pName,&pSym))){
  140. (*pOutValue) = pSym->pValue;
  141. (*lSize)     = pSym->lSize;
  142. return(eTrue);
  143.     }
  144.     (*pOutValue) = 0;
  145.     (*lSize) = 0;
  146.     return(eFalse);
  147. }
  148. eBoolean_t
  149. GetARRSymbolValueREF
  150.     (char *pName
  151.     ,int iIndex
  152.     ,char **pOutValue
  153.     )
  154. {
  155.     SYMBOL *pSym;
  156.     DebugHTML(__FILE__,__LINE__,6,"GetARRSymbolValueREF(%s,%d)",pName,iIndex);
  157.     if(ISeTrue(GetARRSymbolREF(pName,iIndex,&pSym))){
  158. (*pOutValue) = pSym->pValue;
  159. return(eTrue);
  160.     }
  161.     (*pOutValue) = 0;
  162.     return(eFalse);
  163. }
  164. static eBoolean_t
  165. GetSymbolREF
  166.     (char *pName
  167.     ,SYMBOL **pSym
  168.     )
  169. {
  170.     SYMBOL Sym; /* HASH Table restriction... */
  171.     Sym.pName = pName; /* only search by struct.. */
  172.     (*pSym)= l_find(glSymbolTable,GetSymbolName,&Sym);
  173.     if(*pSym) {
  174. return(eTrue);
  175.     }
  176.     return(eFalse);
  177. }
  178. static eBoolean_t
  179. GetARRSymbolREF
  180.     (char *pName
  181.     ,int iIndex
  182.     ,SYMBOL **pSym
  183.     )
  184. {
  185.     SYMBOL Sym; /* HASH Table restriction... */
  186.     Sym.pName = pName; /* only search by struct.. */
  187.     for(  (*pSym)= l_find(glSymbolTable,GetSymbolName,&Sym)
  188. ; (*pSym) && (iIndex-->0)
  189. ; (*pSym)=l_fnext(glSymbolTable))
  190.     {
  191. if((*pSym) && !is_casematch((*pSym)->pName,pName)) {
  192.     *pSym=0;
  193.     return(eFalse);
  194. }
  195.     }
  196.     if(*pSym && is_casematch((*pSym)->pName,pName)) {
  197. return(eTrue);
  198.     }
  199.     *pSym=0;
  200.     return(eFalse);
  201. }
  202. eBoolean_t
  203. IsSymbolValue
  204.     (char *pName
  205.     ,char *pValue
  206.     )
  207. {
  208.     SYMBOL Sym,*pSym;
  209.     DebugHTML(__FILE__,__LINE__,6,"IsSymbolValue(%s,%s)",pName,pValue);
  210.     Sym.pName = pName;
  211.     Sym.pValue = pValue;
  212.     for( pSym=l_find(glSymbolTable,GetSymbolName,&Sym);
  213.  pSym && is_casematch(pSym->pName,pName);
  214.  pSym=l_fnext(glSymbolTable))
  215.     {
  216. if(is_match(pSym->pValue,pValue))
  217.     return(eTrue);
  218.     }
  219.     return(eFalse);
  220. }
  221. /*
  222. /* Supports the HASH function requirements
  223. /* returns the "HASH" key string for the struct.
  224.  */
  225. #ifdef USEHASHTABLE
  226. char *
  227. GetSymbolName(SYMBOL *pSym)
  228. {
  229.     /* fprintf(stderr,"KEY(%s)n",pSym->pName);
  230.      */
  231.     return(pSym->pName);
  232. }
  233. #else
  234. int
  235. GetSymbolName(SYMBOL *pSym,SYMBOL *p2)
  236.     { return(iStrCaseCmp(pSym->pName,p2->pName)); }
  237. #endif
  238. /*
  239. /* Compare two symbols, supports LIST functions
  240.  */
  241. int
  242. iCmpSymbolNames(SYMBOL *pSym1, SYMBOL *pSym2)
  243. {
  244.     return( iStrCaseCmp( pSym1->pName, pSym2->pName) );
  245. }
  246. /*
  247. /* Compare a SYMBOL to a "Symbol Name"
  248.  */
  249. int
  250. iCmpSymbolpName(SYMBOL *pSym, char *pName)
  251. {
  252.     return(iStrCaseCmp(pSym->pName,pName));
  253. }
  254. static eBoolean_t
  255. iPrintSymbol(SYMBOL *pSym)
  256. {
  257.     OutputHTML("<!%s="%s">n",pSym->pName,pSym->pValue);
  258.     return(eTrue);
  259. }
  260. eBoolean_t
  261. iPrintHTMLSymbol(SYMBOL *pSym)
  262. {
  263.     char sBuf[MAX_TOKVAL_SIZE]
  264. ,*pBuf
  265. ;
  266.     if(pSym->pValue && iStrLen(pSym->pValue)>0) {
  267. char *pValue = pSym->pValue;
  268. pBuf = sBuf;
  269. while(*pValue && (pBuf-sBuf<sizeof(sBuf)) ){
  270.     if(*pValue == '<') {
  271. strcpy(pBuf,"&lt;");
  272. pBuf += 4;
  273. ++pValue;
  274.     } else if(*pValue == '>') {
  275. strcpy(pBuf,"&gt;");
  276. pBuf += 4;
  277. ++pValue;
  278.     } else {
  279. *pBuf++ = *pValue++;
  280.     }
  281. }
  282. *pBuf=0;
  283. OutputHTML(" %s="%s"", pSym->pName, sBuf);
  284.     }
  285.     else
  286. OutputHTML(" %s", pSym->pName);
  287.     return(eTrue);
  288. }
  289. char
  290. x2c(char *what)
  291. {
  292.     register char digit;
  293.     digit  =(char)(what[0] >= 'A' ?((what[0] & 0xdf)-'A')+10 :(what[0]-'0'));
  294.     digit *=16;
  295.     digit +=(char)(what[1] >= 'A' ?((what[1] & 0xdf)-'A')+10 :(what[1]-'0'));
  296.     return(digit);
  297. }
  298. void
  299. unescape_url(char *url)
  300. {
  301.     register int x,y;
  302.     for(x=0,y=0;url[y];++x,++y) {
  303. if(url[y]=='+') {
  304.     url[y]=' ';
  305. }
  306.         if((url[x] = url[y]) == '%') {
  307.             url[x] = x2c(&url[y+1]);
  308.             y+=2;
  309.         }
  310.     }
  311.     url[x] = '';
  312.     return;
  313. }
  314. /*
  315. /* Push Message onto the Error Stack for
  316. /* later display to the end user.
  317.  */
  318. void
  319. MsgPush
  320.     (
  321.     const char *pFmt
  322.     , ...
  323.     )
  324. {
  325.     va_list pParms;
  326.     register char *pMsg;
  327.     char sBuf[BUFSIZ];
  328.     /* Build PrintF style buffer
  329.      */
  330.     va_start(pParms,pFmt);
  331.     vsprintf(sBuf,pFmt,pParms);
  332.     if(glMsg==NULL_LIST) {
  333.         if((glMsg=l_create("QUEUE"))==NULL_LIST) {
  334.    DebugHTML(__FILE__,__LINE__,0,"MsgPush:Failed:%s",sBuf);
  335.    /* fprintf(stderr,"MsgStack:Push:l_create Failed,%sn",sBuf);
  336.    /* fflush(stderr);
  337.     */
  338.            return; /* (eFalse) */
  339. }
  340.     }
  341.     /*
  342.     /* Store message in list 
  343.      */
  344.     pMsg=DupBuf(sBuf);
  345.     if(!ENQ(glMsg,pMsg) ) {
  346. return; /* (eFalse); */
  347.     }
  348.     return; /* (eTrue); */
  349. }
  350. /*
  351. /* Pop Message off the Error Stack to
  352. /* display to the end user.
  353.  */
  354. eBoolean_t
  355. MsgPop(char *pOutMsgBuf )
  356. {
  357.     char *pMsg;
  358.     DebugHTML(__FILE__,__LINE__,9,"MsgPop:%x:%dn",glMsg,l_size(glMsg));
  359.     if(!glMsg) {
  360. *pOutMsgBuf=0;
  361. return(eFalse);
  362.     }
  363.     pMsg=DEQ(glMsg);
  364.     if(!pMsg) {
  365. *pOutMsgBuf=0;
  366. return(eFalse);
  367.     }
  368.     strcpy(pOutMsgBuf, pMsg);
  369.     /* free(pMsg);
  370.      */
  371.     return(eTrue);
  372. }
  373. eBoolean_t
  374. AddSymbol
  375.     (int iType
  376.     ,char *pName
  377.     ,char *pValue
  378.     ,eBoolean_t bReplace
  379.     ,long lSize
  380.     )
  381. {
  382.     SYMBOL *pSym;
  383.     /*
  384.     /* Replace Symbol (if bReplace FLAG && if found)
  385.      */
  386.     if(ISeTrue(bReplace) && ISeTrue(GetSymbolREF(pName,&pSym))){
  387. /*
  388. fprintf(stderr,"Replace:%s:%s=%sn",pName,pSym->pValue,pValue);
  389. fflush(stderr);
  390.  */
  391. if((iType!=ENV_SYMBOL && iType!=INI_SYMBOL)
  392.     && (pSym->iType == ENV_SYMBOL || pSym->iType == INI_SYMBOL))
  393. {
  394.     DebugHTML(__FILE__,__LINE__,0
  395.      ,"AddSymbol:Attempted to overwrite CGI or INI Symbol:%s"
  396.      ,pName
  397.      );
  398. } else {
  399.     pSym->pValue = pValue;
  400.     pSym->lSize = lSize;
  401. }
  402. return(eTrue);
  403.     }
  404.     /* Duplicate or NOT FOUND
  405.      */
  406.     DebugHTML(__FILE__,__LINE__,5,"Calling NewPIA(%s)",pName);
  407.     pSym = NewPIA();
  408.     if(!pSym){
  409. MsgPush("NewPIA Failed in AddSymbol");
  410. return(eFalse);
  411.     }
  412.     /* (void)memset((pSym),0,sizeof(SYMBOL));
  413.      */
  414.     pSym->iType = iType;
  415.     pSym->pValue= pValue;
  416.     pSym->pName = DupBuf(pName);
  417.     pSym->lSize = lSize;
  418.     if( glSymbolTable==NULL_LIST) {
  419. # ifdef USEHASHTABLE
  420.     glSymbolTable=l_create("HASH");
  421. # else
  422.     glSymbolTable=l_create("ASCEND");
  423. # endif
  424. if(glSymbolTable==NULL_LIST){
  425.     MsgPush("l_create Failed in AddSymbol");
  426.     return(eFalse);
  427. }
  428.     }
  429.     RETeFalse(l_insert(glSymbolTable,GetSymbolName,pSym)
  430.      ,"l_insert Failed in AddSymbol"
  431.      );
  432.     return(eTrue);
  433. }
  434. eBoolean_t
  435. OutputHTML
  436.     (
  437.     const char *pFmt
  438.     ,...
  439.     )
  440. {
  441.     va_list pParms;
  442.     unsigned int iBufLen;
  443.     char sBuf[MAX_BUFSIZ];
  444.     /*
  445.     /* Build PrintF style buffer
  446.      */
  447.     va_start(pParms,pFmt);
  448.     
  449.     iBufLen = vsprintf(sBuf,pFmt,pParms);
  450.     if(iBufLen>sizeof(gsHTMLBuf)) {
  451. MsgPush("OutputHTML:Buffer Overflow");
  452. return(eFalse);
  453.     }
  454.     if(iBufLen>(sizeof(gsHTMLBuf)-(gpHTMLBuf-gsHTMLBuf))) {
  455. FlushHTMLBuf();
  456.     }
  457.     strcpy(gpHTMLBuf,sBuf);
  458.     gpHTMLBuf += iBufLen;
  459.     return(eTrue);
  460. }
  461. static eBoolean_t
  462. ClearHTMLBuf()
  463. {
  464.     gpHTMLBuf=gsHTMLBuf;
  465.     *gpHTMLBuf=0;
  466.     return(eTrue);
  467. }
  468. eBoolean_t
  469. FlushHTMLBuf()
  470. {
  471.     /* First ensure the text/html header has been issued.
  472.      */
  473.     PrintHTMLHeader("text/html");
  474.     fprintf(stdout,"%s",gsHTMLBuf);
  475.     fflush(stdout);
  476.     return( ClearHTMLBuf() );
  477. }
  478. eBoolean_t
  479. PrintHTMLHeader(char *pContentType)
  480. {
  481.     static int iHeader;
  482.     if( iHeader==0) {
  483. char *p;
  484. if(ISCOOKED){
  485.     fprintf(stdout,"Content-type: %sn",pContentType);
  486.     fprintf(stdout,"Cache-Control: no-cachen");
  487.     while( (p=POP(glHeaderList)) ) {
  488. fprintf(stdout,"%sn",p);
  489.     }
  490. /*     fprintf(stdout,"Date: %sn",sNow);
  491. /*     fprintf(stdout,"Expires: %sn",sNow);
  492.  */
  493.     fprintf(stdout,"n");
  494.     fflush(stdout);
  495. } else {
  496.     fprintf(stdout
  497.    ,"<!doctype html public "-//IETF//DTD HTML//EN">n"
  498.    );
  499. /*     fprintf(stdout,"<!Copyright (c) 1995 Applied Information Technologies, Inc.>n");
  500. /*     fprintf(stdout,"<!tAll Rights Reserved.>n");
  501.  */
  502. }
  503. fflush (stdout);
  504.     }
  505.     iHeader=1;
  506.     return(eTrue);
  507. }
  508. eBoolean_t
  509. DebugHTMLSet(int iDebugLevel)
  510. {
  511.     giHTMLDebugLevel=iDebugLevel;
  512.     return(eTrue);
  513. }
  514. int
  515. DebugHTMLGet()
  516. {
  517.     return(giHTMLDebugLevel);
  518. }
  519. eBoolean_t
  520. DebugHTML
  521.     (char *pFileName
  522.     ,int iLine
  523.     ,int iDebugLevel
  524.     ,char *pFmt
  525.     ,...
  526.     )
  527. {
  528.     va_list pParms;
  529.     char sBuf[MAX_BUFSIZ];
  530.     if(iDebugLevel>giHTMLDebugLevel)
  531. return(eTrue);
  532.     /* Build PrintF style buffer
  533.      */
  534.     va_start(pParms,pFmt);
  535.     vsprintf(sBuf,pFmt,pParms);
  536.     OutputHTML("<! %8.8s:%5.5d:%1.1d:%s>n"
  537. ,pFileName
  538. ,iLine
  539. ,iDebugLevel
  540. ,sBuf
  541. );
  542.     FlushHTMLBuf();
  543.     return(eTrue);
  544. }
  545. eBoolean_t
  546. ShowSymbolTable()
  547. {
  548.     return(l_scan(glSymbolTable,(PFI)iPrintSymbol));
  549. }
  550. static int
  551. CmpTags(TAG *pTag1, TAG *pTag2)
  552. {
  553.     return(iStrCmp(pTag1->pTagName,pTag2->pTagName));
  554. }
  555. static int
  556. CmpTagName(TAG *pTag1, char *pTagName)
  557. {
  558.     return(iStrCaseCmp(pTag1->pTagName,pTagName));
  559. }
  560. eBoolean_t
  561. GetTAGByName
  562.     (char *pTagName
  563.     ,TAG **pTAG
  564.     )
  565. {
  566.     (*pTAG) = l_find(glTagList,CmpTagName,pTagName);
  567.     if(!(*pTAG)) {
  568. /* DebugHTML(__FILE__,__LINE__,2,"GetTAGByName(%s):DFLT",pTagName);
  569.  */
  570. (*pTAG) = (TAG*)malloc(sizeof(TAG));
  571. if( !(*pTAG) ) {
  572.     MsgPush("malloc failed");
  573.     return(eFalse);
  574. }
  575. (void)memset((*pTAG),0,sizeof(TAG));
  576. (*pTAG)->pTagName = DupBuf(pTagName);
  577. (*pTAG)->pTagEmptyInd = "N";
  578. (*pTAG)->pTagDesc = 0;
  579. (*pTAG)->pTagAfterInd = "N";
  580. (*pTAG)->pTagLinkDesc = "";
  581. /* Since, we've got a "DEFAULT" Tag, there is no need to increase
  582. /* the size of the list (it'll just slow down subsequent lookups.
  583. /*
  584.  */
  585. l_insert(glTagList,CmpTags,(*pTAG));
  586. return(eTrue);
  587.     }
  588.     /* else {
  589.     /* DebugHTML(__FILE__,__LINE__,2,"GetTAGByName(%s):FOUND",pTagName);
  590.     /* }
  591.      */
  592.     return(eTrue);
  593. }
  594. /* Load a Tag given a line like so:
  595. /* NAME | EMPTY_IND | AFTER_IND | LINK_DESC |
  596.  */
  597. eBoolean_t
  598. LoadTag(char *pTagData)
  599. {
  600.     char *pStart, *pSep, SEP_CHAR='|';
  601.     TAG *pTag;
  602.     pTag = (TAG*)malloc(sizeof(TAG));
  603.     if(!pTag){
  604. MsgPush("malloc failed");
  605. return(eFalse);
  606.     }
  607.     memset(pTag,0,sizeof(TAG));
  608.     pStart = pTagData;
  609.     pSep=strchr(pTagData,SEP_CHAR);
  610.     if(pSep) *pSep++=0 ;
  611.     pTag->pTagName = DupBuf(pStart);
  612.     pStart = pSep;
  613.     pSep=strchr(pSep,SEP_CHAR);
  614.     if(pSep) *pSep++ = 0;
  615.     pTag->pTagEmptyInd = DupBuf(pStart);
  616.     pStart = pSep;
  617.     pSep=strchr(pSep,SEP_CHAR);
  618.     if(pSep) *pSep++ = 0;
  619.     pTag->pTagAfterInd = DupBuf(pStart);
  620.     pStart = pSep;
  621.     pSep=strchr(pSep,SEP_CHAR);
  622.     if(pSep) *pSep++ = 0;
  623.     pTag->pTagLinkDesc = DupBuf(pStart);
  624.     if(!glTagList) {
  625. glTagList = l_create("BTREE");
  626.     }
  627. /*
  628. /*    fprintf(stderr,"T=%s,A=%s,e=%sn"
  629. /*    ,pTag->pTagName
  630. /*    ,pTag->pTagAfterInd
  631. /*    ,pTag->pTagEmptyInd
  632. /*    );
  633.  */
  634.     l_insert(glTagList,CmpTags,pTag);
  635.     return(eTrue);
  636. }
  637. void
  638. LogMsg
  639.     (
  640.     const char *pFmt
  641.     ,...
  642.     )
  643. {
  644.     va_list pParms;
  645.     char sBuf[MAX_BUFSIZ]
  646. ,*pFilename;
  647.     static FILE *pLogFile;
  648.     if(pLogFile== (FILE*)0) {
  649. if(ISeTrue(GetSymbolValueREF("SQLWEB_LOGFILE",&pFilename))) {
  650.     pLogFile=fopen(pFilename,"a");
  651.     if(!pLogFile)
  652.        return; /* (Failed) */
  653. }
  654.     }
  655.     /* Build PrintF style buffer
  656.      */
  657.     va_start(pParms,pFmt);
  658.     vsprintf(sBuf,pFmt,pParms);
  659.     fprintf(pLogFile,"%sn",sBuf);
  660.     fflush(pLogFile);
  661.     return;
  662. }
  663. void *
  664. DupMem(const char *pMem, long lSize)
  665. {
  666.     char *p;
  667.     if(pMem && lSize>0) {
  668. p = malloc(lSize);
  669. if(p){
  670.     (void)memset(p,0,lSize);
  671.     memcpy(p,pMem,lSize);
  672.     return(p);
  673. }
  674.     }
  675.     DebugHTML(__FILE__,__LINE__,5,"DupMem(EmptyString)");
  676.     return(gpEmptyString);
  677. }
  678. char *
  679. DupBuf(const char *pBuf)
  680. {
  681.     if(pBuf && iStrLen(pBuf)>0 ) {
  682. DebugHTML(__FILE__,__LINE__,5,"DupBuf(%s)",pBuf);
  683. return( strdup(pBuf) );
  684.     }
  685.     DebugHTML(__FILE__,__LINE__,5,"DupBuf(**Null**,[%x])",pBuf);
  686.     return(gpEmptyString);
  687. }
  688. void
  689. FreeBuf(char *pBuf)
  690. {
  691.     if(pBuf && pBuf!=gpEmptyString)
  692. free(pBuf);
  693.     return;
  694. }
  695. PI *
  696. NewPI()
  697. {
  698.     PI *pPI;
  699.     if(!glPIFreeList){
  700. glPIFreeList=l_create("QUEUE");
  701. if(!glPIFreeList) {
  702.     MsgPush("NewPI:l_create failed");
  703.     return(0);
  704. }
  705.     }
  706.     if(l_size(glPIFreeList)>0) {
  707. DebugHTML(__FILE__,__LINE__,5,"NewPI:POP(%d)",l_size(glPIFreeList));
  708. pPI=(PI*)POP(glPIFreeList);
  709.     } else {
  710. DebugHTML(__FILE__,__LINE__,5,"NewPI:Malloc");
  711. pPI=(PI*)malloc(sizeof(PI));
  712.     }
  713.     if(!pPI) {
  714. MsgPush("NewPI:malloc or POP failed");
  715. return(0);
  716.     }
  717.     (void)memset(pPI,0,sizeof(PI));
  718.     return(pPI);
  719. }
  720. eBoolean_t
  721. FreePIr(PI *pPI)
  722. {
  723.     return( FreePI_opt(pPI,eTrue) );
  724. }
  725. eBoolean_t
  726. FreePI(PI *pPI)
  727. {
  728.     return( FreePI_opt(pPI,eFalse) );
  729. }
  730. static eBoolean_t
  731. FreePI_opt(PI *pPI, eBoolean_t bFreelPI)
  732. {
  733.     DebugHTML(__FILE__,__LINE__,5,"FreePI[%x](%s,%d)"
  734. ,pPI
  735. ,pPI->pTagName
  736. ,pPI->iLineNbr
  737. );
  738.     if(!glPIFreeList){
  739. glPIFreeList=l_create("QUEUE");
  740. if(!glPIFreeList) {
  741.     MsgPush("FreePI:l_create failed");
  742.     return(eFalse);
  743. }
  744.     }
  745.     /*
  746.     /* Free Attributes
  747.      */
  748.     RETeFalse(l_scan(pPI->lPIA,(PFI)FreePIA)
  749.      ,"FreePI:l_scan(PIA) Failed"
  750.      );
  751.     l_destroy(pPI->lPIA);
  752.     /* DON'T Call Recursively to l_scan(lPI,FreePI)
  753.     /* Because each PI Free's itself before returning
  754.      */
  755.     if(ISeTrue(bFreelPI)) {
  756. l_scan(pPI->lPI,(PFI)FreePIr);
  757.     }
  758.     l_destroy(pPI->lPI);
  759.     FreeBuf(pPI->pTagName);
  760.     FreeBuf(pPI->pPiContents);
  761.     /*
  762.     /* Store This PI on the FreeLIst
  763.      */
  764.     DebugHTML(__FILE__,__LINE__,5,"FreePI:PUSH(%d)",l_size(glPIFreeList));
  765.     (void)memset(pPI,0,sizeof(PI));
  766.     PUSH(glPIFreeList,pPI);
  767.     return(eTrue);
  768. }
  769. SYMBOL *
  770. NewPIA()
  771. {
  772.     SYMBOL *pPIA;
  773.     if(!glPIAFreeList){
  774. glPIAFreeList=l_create("QUEUE");
  775. if(!glPIAFreeList) {
  776.     MsgPush("NewPI:l_create failed");
  777.     return(0);
  778. }
  779.     }
  780.     if(l_size(glPIAFreeList)>0) {
  781. DebugHTML(__FILE__,__LINE__,5,"NewPIA:POP(%d)",l_size(glPIAFreeList));
  782. pPIA=(SYMBOL*)POP(glPIAFreeList);
  783.     } else {
  784. DebugHTML(__FILE__,__LINE__,5,"NewPIA:Malloc",l_size(glPIAFreeList));
  785. pPIA=(SYMBOL*)malloc(sizeof(SYMBOL));
  786.     }
  787.     if(!pPIA) {
  788. MsgPush("NewPIA:malloc or POP failed");
  789. return(0);
  790.     }
  791.     (void)memset(pPIA,0,sizeof(SYMBOL));
  792.     return(pPIA);
  793. }
  794. eBoolean_t
  795. FreePIA(SYMBOL *pPIA)
  796. {
  797.     if(!glPIAFreeList){
  798. glPIAFreeList=l_create("QUEUE");
  799. if(!glPIAFreeList) {
  800.     MsgPush("NewPI:l_create failed");
  801.     return(eFalse);
  802. }
  803.     }
  804.     FreeBuf(pPIA->pName);
  805.     FreeBuf(pPIA->pValue);
  806.     DebugHTML(__FILE__,__LINE__,5,"FreePIA:PUSH(%d)",l_size(glPIAFreeList));
  807.     (void)memset(pPIA,0,sizeof(SYMBOL));
  808.     PUSH(glPIAFreeList,pPIA);
  809.     return(eTrue);
  810. }
  811. static eBoolean_t
  812. AddHTMLHeader(char *pHeader)
  813. {
  814.     if(glHeaderList==NULL_LIST) {
  815.         if((glHeaderList=l_create("QUEUE"))==NULL_LIST) {
  816.    DebugHTML(__FILE__,__LINE__,0,"MsgPush:Failed:%s",pHeader);
  817.            return(eFalse);
  818. }
  819.     }
  820.     PUSH(glHeaderList,DupBuf(pHeader));
  821.     return(eTrue);
  822. }
  823. eBoolean_t
  824. LoadTEXT(char *pFileName
  825. ,char *pFileType
  826. ,PI *pPI
  827. )
  828. {
  829.     long lContentLength = 0;
  830.     int c;
  831.     eBoolean_t bEscapeFlag;
  832.     FILE *pFile;
  833.     char *pContents, *p;
  834.     bEscapeFlag = eFalse;
  835.     if(is_casematch(pFileType,"TEXT")) {
  836. bEscapeFlag = eTrue;
  837.     }
  838.     if(ISeFalse(CalcFileSize(pFileName, &lContentLength, bEscapeFlag))) {
  839. DebugHTML(__FILE__,__LINE__,0,"Failed to CalcFileSize %s",pFileName);
  840. return(eFalse);
  841.     }
  842.     DebugHTML(__FILE__,__LINE__,3,"FileSize:%s:%d",pFileName,lContentLength);
  843.     pContents = malloc( lContentLength +1 );
  844.     if( !pContents ){
  845. DebugHTML(__FILE__,__LINE__,0
  846. ,"LoadTEXT: Failed to malloc(%d) for %s"
  847. ,lContentLength
  848. ,pFileName
  849. );
  850. return(eFalse);
  851.     }
  852.     (void)memset(pContents,0,lContentLength+1);
  853.     if( (FILE *)0 == (pFile = fopen(pFileName,"r")) ) {
  854. DebugHTML(__FILE__,__LINE__,0
  855.      ,"LoadTEXT: Failed to open: %s", pFileName
  856.      );
  857. return(eFalse);
  858.     }
  859.     /* lContentLength = read ( iFile, pContents, lContentLength );
  860.      */
  861.     p = pContents;
  862.     while( EOF != (c=getc(pFile)) ) {
  863. if(ISeTrue(bEscapeFlag)){
  864.     switch(c){
  865. case '<': /* &lt; */
  866.     strcpy(p,"&lt;");
  867.     p += 4;
  868.     break;
  869. case '>': /* &gt; */
  870.     strcpy(p,"&gt;");
  871.     p += 4;
  872.     break;
  873. case '&': /* &amp; */
  874.     strcpy(p,"&amp;");
  875.     p += 5;
  876.     break;
  877. default:
  878.     *p++ = c;
  879.     }
  880. } else {
  881.     *p++ = c;
  882. }
  883.     }
  884.     *p=0;
  885.     fclose(pFile);
  886.     pPI->pPiContents=pContents;
  887.     return(eTrue);
  888. /*
  889. DebugHTML(__FILE__,__LINE__,0
  890.  ,"INCLUDE: Unknown FILETYPE(%s) failed to load text file: %s"
  891. ,sFileType
  892. ,sFileName
  893.      );
  894.  */
  895. }
  896. static eBoolean_t
  897. CalcFileSize(
  898.  char *pFileName
  899. ,long *plFileSize
  900. ,eBoolean_t bEscapeFlag
  901. )
  902. {
  903.     FILE *pF;
  904.     struct stat StatBuf;
  905.     int c;
  906.     (*plFileSize)=0; /* firstly, init "out" variable */
  907.     if(ISeFalse(bEscapeFlag)) {
  908. if( -1 == stat(pFileName,&StatBuf)) {
  909.     DebugHTML(__FILE__,__LINE__,0
  910.  ,"CalfFileSize: Failed to stat: %s", pFileName
  911.  );
  912.     return(eFalse);
  913. }
  914. (*plFileSize) = StatBuf.st_size;
  915. return(eTrue);
  916.     }
  917.     pF = fopen(pFileName,"r");
  918.     if(!pF){
  919. DebugHTML(__FILE__,__LINE__,0
  920.      ,"CalcFileSize: Failed to open: %s", pFileName
  921.      );
  922. return(eFalse);
  923.     }
  924.     while( EOF != (c=getc(pF)) ){
  925. switch(c){
  926.     case '<': /* &lt; */
  927.     case '>': /* &gt; */
  928. (*plFileSize) += 4;
  929. break;
  930.     case '&': /* &amp; */
  931. (*plFileSize) += 5;
  932. break;
  933.     default:
  934. (*plFileSize)++;
  935. }
  936.     }
  937.     fclose(pF);
  938.     return(eTrue);
  939. }
  940. #define EXPAND_CHUNK_SIZE 64
  941. eBoolean_t
  942. ExpandString(char *pIn, char **pRet)
  943. {
  944.     char sName[MAX_TOK_SIZE]
  945. ,*pValue
  946. ;
  947.     char  *pOut=0
  948.  ,*pTmp
  949. ;
  950.     unsigned long ulOutSize = EXPAND_CHUNK_SIZE;
  951.     eBoolean_t bExpand = eTrue;
  952.     int iExpandCount=1;
  953.     DebugHTML(__FILE__,__LINE__,5
  954.     ,"ExpandString(%x:%s)"
  955.     ,pIn
  956.     ,(pIn && *pIn)?pIn:"Huh?"
  957.     );
  958.     if(!pIn || !(*pIn)) {
  959. DebugHTML(__FILE__,__LINE__,5,"ExpandString:empty");
  960. (*pRet) = DupBuf(0);
  961. return(eTrue);
  962.     }
  963.     /*
  964.     /* Allocate a Buffer to hold Processed Output
  965.      */
  966.     pOut = (*pRet) = (char*)malloc(ulOutSize+1);
  967.     if(!(*pRet)) {
  968. MsgPush("malloc failed");
  969. return(eFalse);
  970.     }
  971.     (void)memset((*pRet),0,ulOutSize+1);
  972.     /* Don't automatically expand the initial buffer */
  973.     bExpand = eFalse;
  974.     while(*pIn) {
  975. /* Increase string size in increments of EXPAND_CHUNK_SIZE */
  976. if( ISeTrue(bExpand) || (pOut-(*pRet)) >= ulOutSize ){
  977.     iExpandCount++;
  978.     DebugHTML(__FILE__,__LINE__,3
  979. ,"ExpandString:expanding string(F=%s:pos=%d,max=%d)"
  980. ,ISeTrue(bExpand)?"TRUE":"FALSE"
  981. ,(pOut-(*pRet))
  982. ,ulOutSize
  983. );
  984.     bExpand=eFalse;
  985.     if(pOut) *pOut=0;
  986.     ulOutSize += (EXPAND_CHUNK_SIZE * iExpandCount);
  987.     (*pRet) = realloc((*pRet),ulOutSize+1);
  988.     if(!(*pRet)) {
  989. MsgPush("realloc failed");
  990. return(eFalse);
  991.     }
  992.     pOut =(*pRet) +((*pRet)? iStrLen(*pRet):0);
  993. }
  994. switch((int)*pIn){
  995.     char *pColon;
  996.     case ':':
  997.         pColon = pIn;
  998. if( isalpha(*(pIn+1)) ){
  999.     char *pTmp = sName;
  1000.     while( isalnum(*pTmp = *(++pIn)) || *pTmp=='_' )
  1001. ++pTmp;
  1002.     *pTmp=0;
  1003.     if(ISeTrue(GetSymbolValueREF(sName,&pValue))) {
  1004. DebugHTML(__FILE__,__LINE__,4
  1005. ,"ExpandString(%s=%s):pOut=%s,Pos=%d,VLen=%d"
  1006. ,sName
  1007. ,pValue
  1008. ,pOut
  1009. ,pOut-(*pRet)
  1010. ,(iStrLen(pValue)+1)
  1011. );
  1012. if((iStrLen(pValue)+1) > (ulOutSize-(pOut-(*pRet))))
  1013. {
  1014.     bExpand=eTrue;
  1015.     pIn = pColon;
  1016.     continue;
  1017. }
  1018. /* This implements simple, one-level
  1019. /* symbol name expansion
  1020.  */
  1021. strcpy(pOut,pValue);
  1022. pOut += iStrLen(pValue);
  1023. /* Either way, continue with next element in loop
  1024.  */
  1025. continue;
  1026.     }
  1027.     DebugHTML(__FILE__,__LINE__,3,"NoSym(%s)",sName);
  1028.     *pOut++=':';
  1029.     strcpy(pOut,sName);
  1030.     pOut += iStrLen(sName);
  1031.     continue;
  1032. }
  1033. if( (*(pIn+1))==':' ){
  1034.     pIn++; /* Skip it */
  1035. }
  1036. *pOut++ = *pIn++;
  1037. continue;
  1038.     default :
  1039. *pOut++ = *pIn++;
  1040. break;
  1041. }
  1042.     }
  1043.     *pOut=0;
  1044.     pTmp = (*pRet);
  1045.     (*pRet) = DupBuf(pTmp);
  1046.     free(pTmp);
  1047.     return(eTrue);
  1048. }
  1049. /*
  1050. /* Also, replace any non-standard HTML character
  1051. /* with its CODE %34, or whatever....
  1052.  */
  1053. eBoolean_t
  1054. ExpandContents(PI *pPI)
  1055. {
  1056.     char *pPiContents=0;
  1057.     DebugHTML(__FILE__,__LINE__,6
  1058.     ,"ExpandContents:(%x:%x(%s=%s)):t=%s;l=%d"
  1059.     ,pPI
  1060.     ,pPI->pPiContents
  1061.     ,pPI->pPiContents?pPI->pPiContents:"Huh?"
  1062.     ,pPI->pTagName
  1063.     ,pPI->pTag->pTagName
  1064.     ,pPI->iLineNbr
  1065.     );
  1066.     if(!pPI->pPiContents|| !(*pPI->pPiContents)) {
  1067. DebugHTML(__FILE__,__LINE__,3
  1068. ,"ExpandContents:empty(%x):t=%s==%s;l=%d"
  1069. ,pPI->pPiContents
  1070. ,pPI->pTagName
  1071. ,pPI->pTag->pTagName
  1072. ,pPI->iLineNbr
  1073. );
  1074. pPI->pPiContents = DupBuf(0);
  1075. return(eTrue);
  1076.     }
  1077.     RETeFalse(ExpandString(pPI->pPiContents,&pPiContents)
  1078.      ,"ExpandString Failed in ExpandContents"
  1079.      );
  1080.     pPI->pPiContents = pPiContents;
  1081.     return(eTrue);
  1082. }
  1083. /* eBoolean_t
  1084. /* RemoveCharCodes(char *pIn, char *pOut)
  1085. /* {
  1086. /*     if(!pIn) {
  1087. /*  /* Make sure pout exists before writing to it
  1088. /*   */
  1089. /*  if(pOut) {
  1090. /*      *pOut=0;
  1091. /*      return(eTrue);
  1092. /*  }
  1093. /*  return(eFalse);
  1094. /*     }
  1095. /* 
  1096. /*     while(*pIn){
  1097. /*  if(*pIn=='&'){
  1098. /*      if(strncasecmp("&GT;",pIn,4)==0){
  1099. /*  *pOut++ = '>';
  1100. /*  pIn += 4;
  1101. /*      }
  1102. /*      else if(strncasecmp("&LT;",pIn,4)==0){
  1103. /*  *pOut++ = '<';
  1104. /*  pIn += 4;
  1105. /*      }
  1106. /*      else if(strncasecmp("&AMP;",pIn,5)==0){
  1107. /*  *pOut++ = '&';
  1108. /*  pIn += 5;
  1109. /*      }
  1110. /*      else if(strncasecmp("&QUOT;",pIn,6)==0){
  1111. /*  *pOut++ = '"';
  1112. /*  pIn += 6;
  1113. /*      }
  1114. /*      else {
  1115. /*  *pOut++ = *pIn++;
  1116. /*      }
  1117. /*  } else {
  1118. /*      *pOut++ = *pIn++;
  1119. /*  }
  1120. /*     }
  1121. /*     *pOut=0;
  1122. /*     return(eTrue);
  1123. /* }
  1124. /* */
  1125. eBoolean_t
  1126. RemoveCharCodes(char *pIn)
  1127. {
  1128.     char *pOut, *pStart;
  1129.     if(!pIn) {
  1130. DebugHTML(__FILE__,__LINE__,4,"RemoveCharCodes(Empty)");
  1131. return(eTrue);
  1132.     }
  1133.     pOut = pStart = pIn;
  1134.     while(*pIn){
  1135. if(*pIn=='&'){
  1136.     if(bStrNCaseMatch("&GT;",pIn,4)){
  1137. *pOut++ = '>';
  1138. pIn += 4;
  1139.     }
  1140.     else if(bStrNCaseMatch("&LT;",pIn,4)){
  1141. *pOut++ = '<';
  1142. pIn += 4;
  1143.     }
  1144.     else if(bStrNCaseMatch("&AMP;",pIn,5)){
  1145. *pOut++ = '&';
  1146. pIn += 5;
  1147.     }
  1148.     else if(bStrNCaseMatch("&QUOT;",pIn,6)){
  1149. *pOut++ = '"';
  1150. pIn += 6;
  1151.     }
  1152.     else {
  1153. if(pOut != pIn) {
  1154.     *pOut++ = *pIn++;
  1155. }
  1156. else {
  1157.     pOut++; pIn++;
  1158. }
  1159.     }
  1160. } else {
  1161.     if(pOut != pIn) {
  1162. *pOut++ = *pIn++;
  1163.     }
  1164.     else {
  1165. pOut++; pIn++;
  1166.     }
  1167. }
  1168.     }
  1169.     *pOut=0;
  1170.     unescape_url(pStart);
  1171.     return(eTrue);
  1172. }
  1173. extern int
  1174. iStrLen(char *s)
  1175. {
  1176.     if(!s) return(0);
  1177.     return(strlen(s));
  1178. }
  1179. extern int
  1180. iStrCmp(char *s, char *t)
  1181. {
  1182.     if(s&&t) return(strcmp(s,t));
  1183.     if(!s&&!t) return(0);
  1184.     return(1);
  1185. }
  1186. extern int
  1187. iStrCaseCmp(char *s, char *t)
  1188. {
  1189.     if(s&&t) return(strcasecmp(s,t));
  1190.     if(!s && !t) return(0);
  1191.     return(1);
  1192. }
  1193. extern eBoolean_t
  1194. bStrMatch(char *s,char *t)
  1195. {
  1196.     if(s&&t) return( (strcmp(s,t)==0)?eTrue:eFalse);
  1197.     if(!s && !t) return(eTrue); /* Never mind Codd&Date */
  1198.     return(eFalse);
  1199. }
  1200. extern eBoolean_t
  1201. bStrNMatch(char *s,char *t,int n)
  1202. {
  1203.     if(s&&t) return( (strncmp(s,t,n)==0)?eTrue:eFalse);
  1204.     if(!s && !t) return(eTrue); /* Never mind Codd&Date */
  1205.     return(eFalse);
  1206. }
  1207. extern eBoolean_t
  1208. bStrCaseMatch(char *s,char *t)
  1209. {
  1210.     if(s&&t) return( (strcasecmp(s,t)==0)?eTrue:eFalse);
  1211.     if(!s && !t) return(eTrue); /* Never mind Codd&Date */
  1212.     return(eFalse);
  1213. }
  1214. extern eBoolean_t
  1215. bStrNCaseMatch(char *s,char *t,int n)
  1216. {
  1217.     if(s&&t) return( (strncasecmp(s,t,n)==0)?eTrue:eFalse);
  1218.     if(!s && !t) return(eTrue); /* Never mind Codd&Date */
  1219.     return(eFalse);
  1220. }
  1221. extern eBoolean_t
  1222. GetCookieValueREF(char *pName, char **pBuf, long *lSize)
  1223. {
  1224.     SYMBOL *pSym, Sym;
  1225.     Sym.pName=pName;
  1226.     *pBuf=0;
  1227.     *lSize=0L;
  1228.     if(glCookie==NULL_LIST)
  1229. return(eTrue);
  1230.     pSym=(SYMBOL*)l_find(glCookie,GetSymbolName,&Sym);
  1231.     if(pSym) {
  1232. (*pBuf)=pSym->pValue;
  1233. *lSize =pSym->lSize;
  1234.     }
  1235.     return(eTrue);
  1236. }