Guest User

src/lex.c

a guest
Mar 29th, 2021
253
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 34.33 KB | None | 0 0
  1. /***[lex.c]*******************************************************[TAB=4]****\
  2. *                                                                            *
  3. * PHP/FI                                                                     *
  4. *                                                                            *
  5. * Copyright 1995,1996 Rasmus Lerdorf                                         *
  6. *                                                                            *
  7. *  This program is free software; you can redistribute it and/or modify      *
  8. *  it under the terms of the GNU General Public License as published by      *
  9. *  the Free Software Foundation; either version 2 of the License, or         *
  10. *  (at your option) any later version.                                       *
  11. *                                                                            *
  12. *  This program is distributed in the hope that it will be useful,           *
  13. *  but WITHOUT ANY WARRANTY; without even the implied warranty of            *
  14. *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             *
  15. *  GNU General Public License for more details.                              *
  16. *                                                                            *
  17. *  You should have received a copy of the GNU General Public License         *
  18. *  along with this program; if not, write to the Free Software               *
  19. *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.                 *
  20. *                                                                            *
  21. \****************************************************************************/
  22. /* $Id: lex.c,v 1.64 1996/05/29 12:00:34 rasmus Exp $ */
  23. #include <stdlib.h>
  24. #include <string.h>
  25. #include <ctype.h>
  26. #include <errno.h>
  27. #include <php.h>
  28. #if PHP_HAVE_MMAP
  29. #include <sys/mman.h>
  30. #endif
  31. #if HAVE_UNISTD_H
  32. #include <unistd.h>
  33. #endif
  34. #include <parse.h>
  35. #if APACHE
  36. #include "http_protocol.h"
  37. #endif
  38.  
  39. #if PHP_HAVE_MMAP
  40. static caddr_t pa=NULL;
  41. static long pa_pos=0L;
  42. #else
  43. static char *pa=NULL;
  44. static long pa_pos=0L;
  45. #endif
  46. static int gfd = 0;
  47. static long gsize = 0L;
  48. static int state = 0;
  49. static int lstate = 0;
  50. static int inIf=-1;
  51. static int inWhile=-1;
  52. static unsigned char inbuf[LINEBUFSIZE];    /* input line buffer  */
  53. static unsigned char obuf[LINEBUFSIZE];     /* output line buffer */
  54. static int inpos=0; /* current position in inbuf */
  55. static int outpos=0; /* current position in inbuf */
  56. static int inlength=0; /* current length of inbuf */
  57. static int g_length=0; /* current length of inbuf */
  58. static int NewExpr=1;
  59. static int inmarker;  /* marked position in inbuf      */
  60. static int tokenmarker; /* marked position in inbuf      */
  61. static long SeekPos=0L;
  62. static int ExitCalled=0;
  63. static int ClearIt=0;
  64. static long iterwhile=0L;
  65. static int LastToken=0;
  66. #if TEXT_MAGIC
  67. static int TextMagic=0;
  68. #endif
  69.  
  70. static FileStack *top = NULL;
  71. static FuncStack *functop = NULL;
  72. static FuncStack *cur_func=NULL;
  73. static int no_httpd = 0;
  74. static int eval_mode = 0;
  75. static long cfstart = 0;
  76.  
  77. static FuncArgList *funcarg_top = NULL;
  78. static FuncArgList *funcarg_bot = NULL;
  79.  
  80. int yylex_linenumber = 0;
  81.  
  82. typedef struct _cmd_table_t {
  83.     char *cmd;
  84.     unsigned int token;
  85.     void (*fnc)(void);
  86. } cmd_table_t;
  87.  
  88. /* Command hash table
  89.  * The hash is extremely simplistic and just based on the length of the
  90.  * command.
  91.  */
  92. static cmd_table_t cmd_table[22][35] = {
  93.     { { NULL,0,NULL } },        /* 0 */
  94.  
  95.     { { NULL,0,NULL } },        /* 1 */
  96.  
  97.     { { "if", IF, NULL },        /* 2 */
  98.       { NULL,0,NULL } },
  99.  
  100.     { { "max", INTFUNC1,ArrayMax }, /* 3 */
  101.       { "min", INTFUNC1,ArrayMin },
  102.       { "key", KEY,NULL },
  103.       { "end", END,NULL },
  104.       { "sin", INTFUNC1,Sin },
  105.       { "cos", INTFUNC1,Cos },
  106.       { "tan", INTFUNC1,Tan },
  107.       { "exp", INTFUNC1,Exp },
  108.       { "log", INTFUNC1,mathLog },
  109.       { "abs", INTFUNC1,Abs },
  110.       { "ord", INTFUNC1,Ord },
  111.       { "chr", INTFUNC1,Chr },
  112.       { NULL,0,NULL } },
  113.  
  114.     { { "echo",PHPECHO,NULL },     /* 4 */
  115.       { "else",ELSE,NULL },
  116.       { "case",CASE,NULL },
  117.       { "feof",INTFUNC1,Feof },
  118.       { "msql",INTFUNC2,Msql },
  119.       { "exit",EXIT,NULL },
  120.       { "eval",INTFUNC1,Eval },
  121.       { "exec",EXEC,NULL },
  122.       { "time",INTFUNC0,UnixTime },
  123.       { "date",DATE,NULL },
  124.       { "next",PHPNEXT,NULL },
  125.       { "prev",PREV,NULL },
  126.       { "sort",INTFUNC1,Sort },
  127.       { "rand",INTFUNC0,Rand },
  128.       { "sqrt",INTFUNC1,Sqrt },
  129.       { "file",INTFUNC1,File },
  130.       { NULL,0,NULL } },
  131.  
  132.     { { "endif",ENDIF,NULL },   /* 5 */
  133.       { "while",WHILE,NULL },
  134.       { "break",BREAK,NULL },
  135.       { "isset",ISSET,NULL },
  136.       { "count",INTFUNC1,Count },
  137.       { "crypt",CRYPT,NULL },
  138.       { "srand",INTFUNC1,Srand },
  139.       { "sleep",INTFUNC1,Sleep },
  140.       { "fopen",INTFUNC2,Fopen },
  141.       { "popen",INTFUNC2,Popen },
  142.       { "fgets",INTFUNC2,Fgets },
  143.       { "fputs",INTFUNC2,Fputs },
  144.       { "fseek",INTFUNC2,Fseek },
  145.       { "ftell",INTFUNC1,Ftell },
  146.       { "reset",RESET,NULL },
  147.       { "chdir",INTFUNC1,ChDir },
  148.       { "chmod",INTFUNC2,ChMod },
  149.       { "chown",INTFUNC2,ChOwn },
  150.       { "chgrp",INTFUNC2,ChGrp },
  151.       { "mkdir",INTFUNC2,MkDir },
  152.       { "log10",INTFUNC1,mathLog10 },
  153.       { "unset",UNSET,NULL },
  154.       { NULL,0,NULL } },
  155.  
  156.     { { "elseif",ELSEIF,NULL }, /* 6 */
  157.       { "switch",SWITCH,NULL },
  158.       { "strlen",INTFUNC1,StrLen },
  159.       { "strval",INTFUNC1,StrVal },
  160.       { "intval",INTFUNC1,IntVal },
  161.       { "strtok",STRTOK,NULL },
  162.       { "strstr",INTFUNC2,StrStr },
  163.       { "strchr",INTFUNC2,StrStr },
  164.       { "substr",INTFUNC3,SubStr },
  165.       { "system",SYSTEM,NULL },
  166.       { "header",HEADER,NULL },
  167.       { "return",RETURN,NULL },
  168.       { "global",GLOBAL,NULL },
  169.       { "static",STATIC,NULL },
  170.       { "gmdate",GMDATE,NULL },
  171.       { "dblist",INTFUNC0,ListSupportedDBs },
  172.       { "unlink",INTFUNC1,Unlink },
  173.       { "rename",INTFUNC2,Rename },
  174.       { "putenv",INTFUNC1,PutEnv },
  175.       { "getenv",INTFUNC1,GetEnv },
  176.       { "mktime",MKTIME,NULL },
  177.       { "fclose",INTFUNC1,Fclose },
  178.       { "pclose",INTFUNC1,Pclose },
  179.       { "rewind",INTFUNC1,Rewind },
  180.       { "bindec",INTFUNC1,BinDec },
  181.       { "decbin",INTFUNC1,DecBin },
  182.       { "hexdec",INTFUNC1,HexDec },
  183.       { "dechex",INTFUNC1,DecHex },
  184.       { "octdec",INTFUNC1,OctDec },
  185.       { "decoct",INTFUNC1,DecOct },
  186.       { "usleep",INTFUNC1,USleep },
  187.       { "pg_tty",INTFUNC1,PGtty },
  188.       { "fgetss",INTFUNC2,Fgetss },
  189.       { NULL,0,NULL } },
  190.  
  191.     { { "default", DEFAULT,NULL }, /* 7 */
  192.       { "include", INCLUDE,NULL },
  193.       { "dbmopen", INTFUNC2,dbmOpen },
  194.       { "strrchr", INTFUNC2,StrrChr },
  195.       { "sprintf", INTFUNC2,Sprintf },
  196.       { "opendir", INTFUNC1,OpenDir },
  197.       { "readdir", INTFUNC0,ReadDir },
  198.       { "tempnam", INTFUNC2,TempNam },
  199.       { "settype", INTFUNC2,SetType },
  200.       { "gettype", INTFUNC1,GetType },
  201.       { "ucfirst", INTFUNC1,UcFirst },
  202.       { "pg_exec", INTFUNC2,PGexec },
  203.       { "pg_host", INTFUNC1,PGhost },
  204.       { "pg_port", INTFUNC1,PGport },
  205.       { "phpinfo", INTFUNC0,Info },
  206.       { NULL,0,NULL } },
  207.  
  208.     { { "endwhile",ENDWHILE,NULL }, /* 8 */
  209.       { "function",FUNCTION,NULL },
  210.       { "dbmclose",INTFUNC1,dbmClose },
  211.       { "dbmfetch",INTFUNC2,dbmFetch },
  212.       { "gettotal",INTFUNC0,GetTotal },
  213.       { "gettoday",INTFUNC0,GetToday },
  214.       { "closedir",INTFUNC0,CloseDir },
  215.       { "filesize",FILESIZE,NULL },
  216.       { "getmyuid",INTFUNC0,GetMyUid },
  217.       { "getmypid",INTFUNC0,GetMyPid },
  218.       { "imagegif",IMAGEGIF,NULL },
  219.       { "imagearc",IMAGEARC,NULL },
  220.       { "pg_close",INTFUNC1,PGclose },
  221.       { NULL,0,NULL } },
  222.  
  223.     { { "endswitch", ENDSWITCH,NULL }, /* 9 */
  224.       { "reg_match", REG_MATCH,NULL },
  225.       { "dbminsert", INTFUNC3,dbmInsert },
  226.       { "dbmexists", INTFUNC2,dbmExists },
  227.       { "dbmdelete", INTFUNC2,dbmDelete },
  228.       { "rewinddir", INTFUNC0,RewindDir },
  229.       { "fileperms", FILEPERMS,NULL },
  230.       { "fileinode", FILEINODE,NULL },
  231.       { "fileowner", FILEOWNER,NULL },
  232.       { "filegroup", FILEGROUP,NULL },
  233.       { "fileatime", FILEATIME,NULL },
  234.       { "filemtime", FILEMTIME,NULL },
  235.       { "filectime", FILECTIME,NULL },
  236.       { "getlogdir", INTFUNC0,GetLogDir },
  237.       { "getaccdir", INTFUNC0,GetAccDir },
  238.       { "imageline", INTFUNC6,ImageLine },
  239.       { "imagefill", INTFUNC4,ImageFill },
  240.       { "imagechar", IMAGECHAR,NULL },
  241.       { "doubleval", INTFUNC1,DoubleVal },
  242.       { "securevar", INTFUNC1,SecureVar },
  243.       { "fsockopen", INTFUNC2,FSockOpen },
  244.       { "microtime", INTFUNC0,MicroTime },
  245.       { "urlencode", INTFUNC1,UrlEncode },
  246.       { "quotemeta", INTFUNC1,QuoteMeta },
  247.       { "pg_result", INTFUNC3,PG_result },
  248.       { "pg_dbname", INTFUNC1,PGdbName },
  249.       { NULL,0,NULL } },        
  250.  
  251.     { { "strtoupper", INTFUNC1,StrToUpper }, /* 10 */
  252.       { "strtolower", INTFUNC1,StrToLower },
  253.       { "reg_search", REG_SEARCH,NULL },
  254.       { "dbmreplace", INTFUNC3,dbmReplace },
  255.       { "dbmnextkey", INTFUNC2,dbmNextKey },
  256.       { "getlogfile", INTFUNC0,GetLogFile },
  257.       { "getlastref", INTFUNC0,GetLastRef },
  258.       { "getlastmod", INTFUNC0,GetLastMod },
  259.       { "getmyinode", INTFUNC0,GetMyInode },
  260.       { "getrandmax", INTFUNC0,GetRandMax },
  261.       { "setlogging", INTFUNC1,SetLogging },
  262.       { "pg_numrows", INTFUNC1,PGnumRows },
  263.       { "pg_options", INTFUNC1,PGoptions },
  264.       { "pg_connect", INTFUNC5,PGconnect },
  265.       { "phpversion", INTFUNC0,PHPVersion },
  266.       { NULL,0,NULL } },
  267.  
  268.     { { "msql_result", INTFUNC3,MsqlResult }, /* 11 */
  269.       { "reg_replace", INTFUNC3,RegReplace },
  270.       { "dbmfirstkey", INTFUNC1,dbmFirstKey },
  271.       { "getlasthost", INTFUNC0,GetLastHost },
  272.       { "imagecreate", INTFUNC2,ImageCreate },
  273.       { "imagecharup", IMAGECHAR,NULL },
  274.       { "imagestring", IMAGESTRING,NULL },
  275.       { "setshowinfo", INTFUNC1,SetShowInfo },
  276.       { "msql_dbname", INTFUNC2,MsqlDBName },
  277.       { "msql_dropdb", INTFUNC2,MsqlDropDB },
  278.       { "pg_fieldnum", INTFUNC2,PGfieldNum },
  279.       { NULL,0,NULL } },
  280.  
  281.     { { "getlastemail", INTFUNC0,GetLastEmail }, /* 12 */
  282.       { "msql_connect", INTFUNC1,MsqlConnect },
  283.       { "msql_numrows", INTFUNC1,MsqlNumRows },
  284.       { "msql_regcase", INTFUNC1,MsqlRegCase },
  285.       { "imagedestroy", INTFUNC1,ImageDestroy },
  286.       { "imagepolygon", IMAGEPOLYGON,NULL },
  287.       { "msql_listdbs", INTFUNC0,MsqlListDBs },
  288.       { "pg_numfields", INTFUNC1,PGnumFields },
  289.       { "pg_fieldname", INTFUNC2,PGfieldName },
  290.       { "pg_fieldtype", INTFUNC2,PGfieldType },
  291.       { "pg_fieldsize", INTFUNC2,PGfieldSize },
  292.       { NULL,0,NULL } },
  293.  
  294.     { { "gethostbyaddr", INTFUNC1,GetHostByAddr }, /* 13 */
  295.       { "gethostbyname", INTFUNC1,GetHostByName },
  296.       { "getlastaccess", INTFUNC0,GetLastAccess },
  297.       { "msql_fieldlen", MSQL_FIELDLEN,NULL },
  298.       { "imagesetpixel", INTFUNC4,ImageSetPixel },
  299.       { "imagestringup", IMAGESTRINGUP,NULL },
  300.       { "msql_createdb", INTFUNC1,MsqlCreateDB },
  301.       { "pg_freeresult", INTFUNC1,PGfreeResult },
  302.       { "pg_getlastoid", INTFUNC0,PGgetlastoid },
  303.       { NULL,0,NULL } },
  304.  
  305.     { { "getlastbrowser", INTFUNC0,GetLastBrowser }, /* 14 */
  306.       { "msql_fieldname", MSQL_FIELDNAME,NULL },
  307.       { "msql_fieldtype", MSQL_FIELDTYPE,NULL },
  308.       { "msql_numfields", INTFUNC1,MsqlNumFields },
  309.       { "imagerectangle", INTFUNC6,ImageRectangle },
  310.       { "imageinterlace", INTFUNC2,ImageInterlace },
  311.       { "msql_tablename", INTFUNC2,MsqlTableName },
  312.       { "pg_fieldprtlen", INTFUNC3,PGfieldPrtLen },
  313.       { "escapeshellcmd", INTFUNC1,EscapeShellCmd },
  314.       { NULL,0,NULL } },
  315.  
  316.     { { "msql_freeresult", INTFUNC1,MsqlFreeResult }, /* 15 */
  317.       { "msql_fieldflags", MSQL_FIELDFLAGS,NULL },
  318.       { "msql_listtables", INTFUNC1,MsqlListTables },
  319.       { "getstartlogging", INTFUNC0,GetStartLogging },
  320.       { NULL,0,NULL } },
  321.  
  322.     { { "htmlspecialchars", INTFUNC1,HtmlSpecialChars }, /* 16 */
  323.       { "imagecopyresized", IMAGECOPYRESIZED,NULL },
  324.       { NULL,0,NULL } }, /* 16 */
  325.  
  326.     { { "imagefilltoborder", INTFUNC5,ImageFillToBorder }, /* 17 */
  327.       { "seterrorreporting", INTFUNC1,SetErrorReporting },
  328.       { NULL,0,NULL } },
  329.  
  330.     { { "imagecolorallocate", INTFUNC4,ImageColorAllocate }, /* 18 */
  331.       { "imagefilledpolygon", IMAGEFILLEDPOLYGON,NULL },
  332.       { "imagecreatefromgif", INTFUNC1,ImageCreateFromGif },
  333.       { NULL,0,NULL } },
  334.  
  335.     { { NULL,0,NULL } }, /* 19 */
  336.  
  337.     { { "imagefilledrectangle", INTFUNC6,ImageFilledRectangle }, /* 20 */
  338.       { NULL,0,NULL } },
  339.  
  340.     { { "imagecolortransparent", INTFUNC2,ImageColorTransparent }, /* 21 */
  341.       { NULL,0,NULL } }
  342.  
  343. };
  344.  
  345. void IntFunc(unsigned char *fnc_name) {
  346.     int i=0;
  347.     int cmdlen = strlen(fnc_name);
  348.    
  349.     while(cmd_table[cmdlen][i].cmd) {
  350.         if(!strncasecmp(fnc_name,cmd_table[cmdlen][i].cmd,cmdlen)) {
  351.             cmd_table[cmdlen][i].fnc();
  352.             break;
  353.         }  
  354.         i++;
  355.     }
  356. }
  357.  
  358. /* Push a new file or function onto the file stack
  359.  * This is used for function calls and includes
  360.  */
  361. void FilePush(char *fn, long file_size, int fd) {
  362.     FileStack *new;
  363.  
  364.     new = emalloc(0,sizeof(FileStack));
  365.     new->pa = pa;
  366.     new->size = file_size;
  367.     new->fd = fd;
  368.     new->pos = SeekPos + inpos;
  369.     new->state = state;
  370.     new->lstate = lstate;
  371.     new->next = top;
  372.     new->lineno = yylex_linenumber-1;
  373. #if DEBUG
  374.     Debug("Filename/Function name pushed onto file/function stack: [%s]\n",fn);
  375. #endif
  376.     new->filename = estrdup(0,fn);  /* Also holds function names */
  377.     top = new;
  378. }
  379.  
  380. /* Pop a file or a function from the file stack */
  381. #if PHP_HAVE_MMAP
  382. caddr_t FilePop(void) {
  383. #else
  384. char *FilePop(void) {
  385. #endif
  386.     FileStack *s;
  387.  
  388.     if((top && top->fd != -1) || !top) {
  389. #if PHP_HAVE_MMAP
  390.         if(pa && !cur_func && !eval_mode) {
  391. #if DEBUG
  392.             Debug("munmap'ing %ld bytes\n",gsize);
  393. #endif
  394.             munmap(pa,gsize);
  395.             pa=NULL;
  396.             close(gfd);
  397.         }
  398. #else
  399.         if(pa && !cur_func && !eval_mode) pa=NULL;
  400. #endif
  401.     }
  402.     if(top) {
  403.         pa = top->pa;
  404.         gfd = top->fd;
  405.         gsize = top->size;
  406.         state = top->state;
  407.         lstate = top->lstate;
  408.         yylex_linenumber = top->lineno;
  409.         if(cur_func) {
  410.             PopStackFrame();
  411.             PopCondMatchMarks();
  412. #if DEBUG
  413.             Debug("Calling PopStackFrame() from FilePop\n");
  414. #endif
  415.         }
  416.         if(!eval_mode) {
  417.             if(top->fd==-1) { /* nested function call */
  418.                 cur_func = FindFunc(top->filename,&gsize,NULL);
  419. #if DEBUG
  420.                 Debug("Current function is now [%s]\n",cur_func->name);
  421. #endif
  422.             } else {
  423.                 SetCurrentFilename(top->filename);
  424.                 SetCurrentFileSize(top->size);
  425.                 cur_func=NULL;
  426. #if DEBUG
  427.                 Debug("Current Function set to NULL\n");
  428. #endif
  429.             }
  430.         } else {
  431.             eval_mode=0;
  432.             PopCondMatchMarks();
  433.         }
  434.         pa_pos = top->pos;
  435.         s = top;
  436.         top = top->next;
  437.         inpos = -1;
  438.         tokenmarker = 0;
  439.         return(pa);
  440.     } else return(NULL);
  441. }
  442.  
  443. void Include(void) {
  444.     Stack *s;
  445.     int fd;
  446.     char *ofn=NULL;
  447.     long file_size=0L;
  448.     long ofile_size=0L;
  449.  
  450.     s = Pop();
  451.     if(!s) {
  452.         Error("Stack error in include");
  453.         return;
  454.     }
  455.     if(s->strval) {
  456. #if DEBUG
  457.         Debug("Include %s\n",s->strval);
  458. #endif
  459.         ofn = estrdup(0,GetCurrentFilename());
  460.         ofile_size = GetCurrentFileSize();
  461.         fd = OpenFile(s->strval,0,&file_size);
  462.         if(fd>-1) {
  463.             FilePush(ofn,ofile_size,gfd);
  464.             gfd = fd;
  465.             ParserInit(fd,file_size,no_httpd,NULL);
  466.             yyparse();
  467.             if(ExitCalled) state=99;
  468.         } else {
  469.             Error("Include error: %d %s",errno,strerror(errno));
  470.         }
  471.     }
  472. }
  473.  
  474. void Eval(void) {
  475.     Stack *s;
  476.  
  477.     s = Pop();
  478.     if(!s) {
  479.         Error("Stack error in eval");
  480.         return;
  481.     }
  482.     if(s->strval) {
  483. #if DEBUG
  484.         Debug("Eval %s\n",s->strval);
  485. #endif
  486.         eval_mode=1;
  487.         FilePush(GetCurrentFilename(),GetCurrentFileSize(),gfd);
  488.         StripSlashes(s->strval);
  489.         ParserInit(-1,strlen(s->strval),no_httpd,s->strval);
  490.         PushCondMatchMarks();
  491.         yyparse();
  492.         if(ExitCalled) state=99;
  493.     }
  494. }
  495.  
  496. int outputchar(unsigned char ch) {
  497.     if(GetCurrentState(NULL)) {
  498. #if DEBUG
  499.         Debug("Calling php_header from outputchar()\n");
  500. #endif
  501.         php_header(0,NULL);
  502. #if APACHE
  503.         if(rputc(ch,php_rqst)==EOF) {
  504.             /* browser has probably gone away */
  505.             return(-1);
  506.         }
  507. #else
  508.         if(fputc(ch,stdout)==EOF) {
  509.             /* browser has probably gone away */
  510.             return(-1);
  511.         }
  512. #endif
  513.     }
  514.     return(0);
  515. }
  516.  
  517. int outputline(unsigned char *line) {
  518.     line[outpos]='\0';
  519.     outpos=0;
  520.     if(GetCurrentState(NULL)) {
  521. #if DEBUG
  522.         Debug("Calling php_header from outputline()\n");
  523. #endif
  524.         php_header(0,NULL);
  525. #if APACHE
  526.         if(PUTS(line)==EOF) {
  527.             /* browser has probably gone away */
  528.             return(-1);
  529.         }
  530. #else
  531. #if DEBUG
  532.         Debug("sending line [%s]\n",line);
  533. #endif
  534. #if TEXT_MAGIC
  535.         if(TextMagic) text_magic(line);
  536. #endif
  537.         if(fputs(line,stdout)==EOF) {
  538.             /* browser has probably gone away */
  539.             return(-1);
  540.         }
  541. #endif
  542.     }
  543.     return(0);
  544. }
  545.  
  546. /*
  547.  * This reads a line into the input buffer if inpos is -1 and returns the
  548.  * first char.  If inpos is not -1, it returns the char at inpos
  549.  */
  550. unsigned char getnextchar(void) {
  551.     unsigned char ch;
  552.     int i=0;
  553.     int cont=1;
  554.  
  555.     if(inpos==-1 || inpos>=g_length) {
  556.         /* Read the next line with something on it into the buffer */
  557.         g_length=0;
  558.         inlength=0;
  559.         while(g_length==0) {
  560.             SeekPos = pa_pos;
  561.             if(SeekPos > gsize) {
  562. #if DEBUG
  563.                 Debug("End of File/Function\n");
  564. #endif
  565.                 return(0);
  566.             }
  567.             yylex_linenumber++;
  568.             cont=1;
  569.             i=0;
  570.             while(cont) {
  571.                 ch = *(pa+pa_pos+i);
  572.                 if(ch==10 || ch==13 || ch==0 || i==LINEBUFSIZE-1) cont=0;
  573.                 if(SeekPos+i >= gsize) {
  574.                     if(!eval_mode) {
  575. #if DEBUG
  576.                         Debug("End of File/Function\n");
  577. #endif
  578.                         return(0);
  579.                     } else cont=0;
  580.                 }
  581.                 inbuf[i++] = ch;
  582.             }
  583.             g_length=i;
  584.             inlength=i;
  585.             pa_pos = SeekPos;
  586.             pa_pos+=i;
  587.             if(!g_length) {
  588.                 if(outputchar('\n')<0) return(0);
  589.             }
  590.         }
  591.         inpos=0;
  592.     }  
  593.     ch = inbuf[inpos++];
  594.     return(ch);
  595. }
  596.  
  597. char *lookaheadword(void) {
  598.     static char temp[32];
  599.     char ch, *st=NULL;
  600.     int i=0,l=0;
  601.    
  602.     while(1) {
  603.         ch = *(pa + pa_pos + inpos - inlength + i++);
  604.         if(!st && isspace(ch)) continue;
  605.         if(!st) st=pa+pa_pos + inpos - inlength + (i-1);
  606.         if(isspace(ch) || !ch) break;
  607.         l++;
  608.     }  
  609.     if(!st) return NULL;
  610.     if(l>31) l=31;
  611.     strncpy(temp,st,l);
  612.     return(temp);
  613. }
  614.  
  615. /* Push a character back into the input buffer.  This character will be
  616.  * the next character processed when yyparse() calls yylex() again.
  617.  */
  618. void putback(unsigned char ch) {
  619.     if(inpos>0) {
  620.         inpos--;
  621.         inbuf[inpos]=ch;
  622.     }
  623. }
  624.  
  625. int output_from_marker(void) {
  626.     int i;
  627.    
  628.     i=inmarker;
  629.     while(i<inpos) {
  630.         if(outputchar(inbuf[i++])<0) return(-1);
  631.     }
  632.     return(0);
  633. }
  634.  
  635. unsigned char *MakeToken(char *string, int len) {
  636.     unsigned char *s;
  637.  
  638.     s = (unsigned char *)emalloc(2,sizeof(unsigned char)*(len+1));
  639.     memcpy(s,string,len);  
  640.     *(s+len) = '\0';   
  641.     return(s);
  642. }
  643.  
  644. /* Look up a command in the command hash table
  645.  * If not found, assume it is a user-defined function and return CUSTOMFUNC
  646.  */
  647. int CommandLookup(int cmdlen, YYSTYPE *lvalp) {
  648.     register int i=0;
  649.  
  650.     while(cmd_table[cmdlen][i].cmd) {
  651.         if(!strncasecmp(&inbuf[tokenmarker],cmd_table[cmdlen][i].cmd,cmdlen)) {
  652.             *lvalp = (YYSTYPE) MakeToken(&inbuf[tokenmarker],cmdlen);
  653.             LastToken = cmd_table[cmdlen][i].token;
  654.             return(cmd_table[cmdlen][i].token);
  655.         }  
  656.         i++;
  657.     }
  658.     *lvalp = (YYSTYPE) MakeToken(&inbuf[tokenmarker],cmdlen);
  659.     return(CUSTOMFUNC);
  660. }
  661.  
  662. /* Hand-crafted Lexical analyzer using Bison's Pure_Parser calling convention */
  663. int yylex(YYSTYPE *lvalp) {
  664.     register unsigned char c;
  665.     int tokenlen=0;
  666.     unsigned char *s, d;
  667.     char temp[8];
  668.     int bs=0, cst, active, ret;
  669.     char *look = NULL;
  670.  
  671.     php_pool_clear(1);
  672.  
  673.     cst = GetCurrentState(&active);
  674.     if(lstate==99) {
  675. #if DEBUG
  676.         Debug("Parser exiting\n");
  677. #endif
  678.         return(0);
  679.     }
  680.     if(ClearIt && LastToken!=RETURN && !cur_func && !eval_mode && cst) { ClearStack(); ClearIt=0; }
  681.  
  682.     while(1) switch(state) {
  683.         case 0:  /* start of token '<' gets us to state 1 */
  684.             lstate=0;
  685.             c = getnextchar();
  686.             if(!c) {
  687.                 if(outpos) outputline(obuf);
  688.                 state=99; break;
  689.             }
  690.             if(no_httpd && inpos==1 && c=='#') {
  691.                 state=80;
  692.                 break;
  693.             }
  694.             if(c!='<') {
  695.                 obuf[outpos++]=c;
  696.                 if(c==10 || c==13 || outpos > LINEBUFSIZE-1) outputline(obuf);
  697.                 break;
  698.             }
  699.             if(outpos) outputline(obuf);
  700.             inmarker=inpos-1;
  701.             /* fall-through */
  702.  
  703.         case 1: /* '?' or '!?' gets us to state 2 */
  704.             lstate=1;
  705.             c = getnextchar();
  706.             if(!c) { state=99; break; }
  707.             if(c=='!') {
  708.                 d = getnextchar();
  709.                 if(!d) {
  710.                     putback(c);
  711.                     state=99;
  712.                     break;
  713.                 }
  714.                 if(d != '?') {
  715.                     putback(d);
  716.                 } else {
  717.                     c = d; /* discard '!' */
  718.                 }
  719.             }
  720.             if(c!='?') {
  721.                 putback(c);
  722.                 if(output_from_marker() < 0) {
  723.                     state=99; break;
  724.                 }
  725.                 state=0;
  726.                 break;
  727.             }  
  728.             NewExpr=1;
  729.             state=2;
  730.             /* fall-through */
  731.  
  732.         case 2: /* Start of  a command - [a-z][A-Z] gets us to state 3 */
  733.                 /* Start of a number  - [0-9] takes us to state 10 */
  734.             lstate=2;
  735.             c = getnextchar();
  736.             if(!c) { state=99; break; }
  737.             if(c==VAR_INIT_CHAR) {
  738.                 state=40;
  739.                 tokenlen=0;
  740.                 tokenmarker=inpos;
  741.                 break;
  742.             }
  743.             if(c=='=') { state=15; break; }
  744.             if(isdigit(c)) {
  745.                 state=10;
  746.                 tokenlen=1;
  747.                 tokenmarker=inpos-1;
  748.                 break;
  749.             }
  750.             if(c==';') {
  751.                 NewExpr=1;
  752.                 ClearIt=1;
  753.                 return(c);
  754.             }
  755.             if(c=='(') {
  756.                 NewExpr=1;
  757.                 if(inIf>-1) inIf++;
  758.                 if(inWhile>-1) inWhile++;  
  759.                 return(c);
  760.             }
  761.             if(c==')') {
  762.                 if(inIf>-1) inIf--;
  763.                 if(inIf==0) inIf=-1;
  764.                 if(inWhile>-1) inWhile--;
  765.                 if(inWhile==0) inWhile=-1;
  766.                 NewExpr=0;
  767.                 return(c);
  768.             }  
  769.             if(c=='>') { state=20; break; }
  770.             if(c=='<') { state=21; break; }
  771.             if(c==' ' || c=='\t' || c=='\n' || c==10 || c==13) break;
  772.             if(c=='\'') {
  773.                 state = 9;
  774.                 tokenlen=0;
  775.                 tokenmarker=inpos;
  776.                 break;
  777.             }
  778.             if(c=='\"') {
  779.                 state=30;
  780.                 tokenlen=0;
  781.                 tokenmarker=inpos;
  782.                 break;
  783.             }  
  784.             if(c=='.') {
  785.                 state=11;
  786.                 tokenlen=1;
  787.                 tokenmarker=inpos-1;
  788.                 break;
  789.             }
  790.             if(c=='@') { return(c); }
  791.             if(c=='{') {
  792.                 NewExpr=1;
  793.                 ClearIt=1;
  794.                 return(c);
  795.             }
  796.             if(c=='!') { state=12; break; }
  797.             if(c=='&') { state=13; break; }
  798.             if(c=='|') { state=14; break; }
  799.             if(c=='+') { state=16; break; }
  800.             if(c=='-') { state=17; break; }
  801.             if(c=='/') { state=18; break; }
  802.             if(c=='%') { state=8; break; }
  803.             if(c=='*') { state=19; break; }
  804.             if(c==',') {
  805.                 NewExpr=1;
  806.                 return(',');
  807.             }
  808.             if(c=='}') {
  809.                 look = lookaheadword();
  810.                 if(strcasecmp(look,"else") && strcasecmp(look,"elseif")) {
  811.                     NewExpr=1;
  812.                     ret = BraceCheck();
  813.                     if(ret) {
  814.                         putback(';');
  815.                         ClearIt=1;
  816.                         return(ret);
  817.                     }
  818.                     return('}');
  819.                 } else {
  820.                     break;
  821.                 }
  822.             }
  823.             if(c==']') return(c);
  824.             if(c < 32) {
  825.                 c = getnextchar();
  826.                 if(!c) state=99;
  827.                 break;
  828.             }
  829.             if(!isalpha(c) && c != '_') {
  830.                 putback(c);
  831.                 if(output_from_marker() < 0) {
  832.                     state=99; break;
  833.                 }
  834.                 state=0;
  835.                 break;
  836.             }
  837.             tokenlen=1;
  838.             tokenmarker=inpos-1;
  839.             /* fall-through */
  840.  
  841.         case 3: /* continue command - non [a-z][A-Z] gets us to state 4 */
  842.             lstate=3;
  843.             while(isalpha((c=getnextchar())) || c=='_') tokenlen++;
  844.             if(!c) { state=99; break; }
  845.             putback(c);
  846.            
  847.         case 4: /* command finished */
  848.             if(active==-5) {
  849.                 CondPop(&active);
  850.                 CondPush(0,-6);
  851.                 s = (unsigned char *) MakeToken(&inbuf[tokenmarker],tokenlen);
  852.                 if(s && *s) {
  853.                     *lvalp = (YYSTYPE) s;
  854.                     lstate=4;
  855.                     return(FUNCNAME);
  856.                 }
  857.             }
  858.                
  859.             if(tokenlen > MAX_CMD_LEN) {
  860.                 /* unrecognized command */
  861.                 if(output_from_marker()<0) {
  862.                     lstate=4;
  863.                     state=99; break;
  864.                 }
  865.                 state=0;
  866.                 break;
  867.             }
  868.             state=2;
  869.             if(tokenlen==2 && !strncasecmp(&inbuf[tokenmarker],"if",2)) {
  870.                 inIf++;
  871.             } else if(tokenlen==6 && !strncasecmp(&inbuf[tokenmarker],"elseif",6)) {
  872.                 inIf++;    
  873.             } else if(tokenlen==5 && !strncasecmp(&inbuf[tokenmarker],"while",5)) {
  874.                 if(iterwhile==SeekPos) { /* Iteration of a previous loop */
  875.                     inWhile++;
  876.                 } else {  /* new while loop */
  877.                     inWhile++;
  878.                     if(GetCurrentState(NULL)) {
  879.                         WhilePush(SeekPos,tokenmarker,yylex_linenumber-1);
  880.                     }
  881.                 }
  882.             }
  883.             NewExpr=1;
  884.             lstate=4;
  885.             return(CommandLookup(tokenlen,lvalp));
  886.             break;
  887.  
  888.         case 8: /* % */
  889.             lstate=8;
  890.             state=2;
  891.             NewExpr=1;
  892.             return('%');
  893.             break;
  894.  
  895.         case 9: /* 'c' */
  896.             lstate=9;
  897.             NewExpr=0;
  898.             while(1) {
  899.                 c=getnextchar();
  900.                 if(c=='\\') {
  901.                     bs=bs?0:1;
  902.                     tokenlen++;
  903.                     continue;
  904.                 }
  905.                 if(bs) {
  906.                     tokenlen++;
  907.                     bs=0;
  908.                     continue;
  909.                 }  
  910.                 if(c=='\'' || !c) break;
  911.                 tokenlen++;
  912.             }
  913.             if(!c) { state=99; break; }
  914.             s = (unsigned char *) MakeToken(&inbuf[tokenmarker],tokenlen);
  915.             if(s && *s) {
  916.                 sprintf(temp,"%d",(int)*s);
  917.             } else strcpy(temp,"0");
  918.             *lvalp = (YYSTYPE) MakeToken(temp,strlen(temp));
  919.             state = 2;
  920.             return(LNUMBER);
  921.            
  922.         case 10: /* LNUMBER */
  923.             lstate=10;
  924.             NewExpr=0;
  925.             while(isdigit((c=getnextchar()))) tokenlen++;
  926.             if(!c) { state=99; break; }
  927.             if(c=='.') { tokenlen++; state=11; break; }
  928.             putback(c);
  929.             *lvalp = (YYSTYPE) MakeToken(&inbuf[tokenmarker],tokenlen);
  930.             state = 2;
  931.             return(LNUMBER);
  932.  
  933.         case 11: /* Double */
  934.             lstate=11;
  935.             NewExpr=0;
  936.             while(isdigit((c=getnextchar()))) tokenlen++;
  937.             if(!c) { state=99; break; }
  938.             putback(c);
  939.             *lvalp = (YYSTYPE) MakeToken(&inbuf[tokenmarker],tokenlen);
  940.             state = 2;
  941.             return(DNUMBER);
  942.  
  943.         case 12: /* ! */
  944.             lstate=12;
  945.             NewExpr=1;
  946.             c = getnextchar();
  947.             state=2;
  948.             if(c=='=') return(COND_NE);
  949.             else {
  950.                 putback(c);
  951.                 return(NOT);
  952.             }
  953.             break;
  954.  
  955.         case 13: /* & */
  956.             lstate=13;
  957.             NewExpr=1;
  958.             c = getnextchar();
  959.             state=2;
  960.             if(c=='&') return(LOG_AND);
  961.             else if(c=='=') return(ANDEQ);
  962.             else {
  963.                 putback(c);
  964.                 return('&');
  965.             }
  966.             break;
  967.  
  968.         case 14: /* | */
  969.             lstate=14;
  970.             NewExpr=1;
  971.             c = getnextchar();
  972.             state=2;
  973.             if(c=='|') return(LOG_OR);
  974.             else if(c=='=') return(OREQ);
  975.             else {
  976.                 putback(c);
  977.                 return('|');
  978.             }
  979.             break;
  980.            
  981.         case 15: /* = */
  982.             lstate=15;
  983.             NewExpr=1;
  984.             c = getnextchar();
  985.             state=2;
  986.             if(c=='=') return(COND_EQ);
  987.             else {
  988.                 putback(c);
  989.                 return('=');
  990.             }
  991.             break;
  992.  
  993.         case 16: /* + */
  994.             lstate=16;
  995.             c = getnextchar();
  996.             state=2;
  997.             if(c=='+') return(INC);
  998.             else if(c=='=') return(PEQ);
  999.             else {
  1000.                 putback(c);
  1001.                 NewExpr=1;
  1002.                 return('+');
  1003.             }
  1004.             break;
  1005.  
  1006.         case 17: /* - */
  1007.             lstate=17;
  1008.             c = getnextchar();
  1009.             state=2;
  1010.             if(c=='-') return(DEC);
  1011.             else if(c=='=') return(MEQ);
  1012.             else {
  1013.                 putback(c);
  1014.                 if(NewExpr) {
  1015.                     NewExpr=0;
  1016.                     return(NEG);
  1017.                 } else {
  1018.                     NewExpr=1;
  1019.                     return('-');
  1020.                 }
  1021.             }
  1022.             break;
  1023.  
  1024.         case 18: /* / */
  1025.             lstate=18;
  1026.             c = getnextchar();
  1027.             state=2;
  1028.             if(c=='*') {
  1029.                 while(1) {
  1030.                     c=getnextchar();
  1031.                     if((c=='/' && inbuf[inpos-2]=='*') || (!c)) break;
  1032.                 }
  1033.                 if(!c) { state=99; break; }
  1034.                 tokenlen=0;
  1035.                 tokenmarker=inpos;
  1036.                 state=2;
  1037.                 break;
  1038.             } else {
  1039.                 putback(c);
  1040.                 NewExpr=1;
  1041.                 return('/');
  1042.             }
  1043.             break;
  1044.  
  1045.         case 19: /* * */
  1046.             lstate=19;
  1047.             state=2;
  1048.             NewExpr=1;
  1049.             return('*');
  1050.             break;
  1051.    
  1052.         case 20: /* > */
  1053.             lstate=20;
  1054.             NewExpr=1;
  1055.             if(inIf>-1 || inWhile>-1) {
  1056.                 state=2;
  1057.                 c=getnextchar();
  1058.                 if(c=='=') return(COND_GE);
  1059.                 putback(c);
  1060.                 return(COND_GT);
  1061.             }
  1062.             state=0;
  1063.             ClearIt=1;
  1064.             return(END_TAG);
  1065.  
  1066.         case 21: /* < */
  1067.             lstate=21;
  1068.             NewExpr=1;
  1069.             if(inIf>-1 || inWhile>-1) {
  1070.                 state=2;
  1071.                 c=getnextchar();
  1072.                 if(c=='=') return(COND_LE);
  1073.                 putback(c);
  1074.                 return(COND_LT);
  1075.             }
  1076.             return('<');
  1077.  
  1078.         case 30: /* string */
  1079.             lstate=30;
  1080.             NewExpr=0;
  1081.             while(1) {
  1082.                 c=getnextchar();
  1083.                 if(c=='\\') {
  1084.                     bs=bs?0:1;
  1085.                     tokenlen++;
  1086.                     continue;
  1087.                 }
  1088.                 if(bs) {
  1089.                     tokenlen++;
  1090.                     bs=0;
  1091.                     continue;
  1092.                 }  
  1093.                 if(c=='\"' || !c) break;
  1094.                 tokenlen++;
  1095.             }
  1096.             if(!c) { state=99; break; }
  1097.             *lvalp = (YYSTYPE) MakeToken(&inbuf[tokenmarker],tokenlen);
  1098.             state = 2;
  1099.             return(STRING);
  1100.  
  1101.         case 40: /* Variable */
  1102.             lstate=40;
  1103.             NewExpr=0;
  1104.             while((c=getnextchar()) && ((isalnum(c) || c=='_') || (c==VAR_INIT_CHAR && tokenlen==0))) tokenlen++;
  1105.             if(!c) { state=99; break; }
  1106.             *lvalp = (YYSTYPE) MakeToken(&inbuf[tokenmarker],tokenlen);
  1107.             state = 2;
  1108.             while(c==' ' || c=='\t' || c=='\n') c=getnextchar();
  1109.             if(c=='[') return(ARRAY);
  1110.             putback(c);
  1111.             return(VAR);
  1112.         case 80: /* Ignore # lines in command line mode */
  1113.             state=lstate;
  1114.             lstate=80;
  1115.             while((c=getnextchar()) && c!=10 && c!=13);
  1116.             if(!c) { state=99; break; }
  1117.             break;
  1118.            
  1119.         case 99: /* EOF reached */
  1120.             lstate=99;
  1121.             state=0;
  1122.             pa = FilePop();
  1123.             return(END_OF_FILE);       
  1124.     }
  1125.     return(0);
  1126. } /* yylex */
  1127.  
  1128. /* Yacc Error Function */
  1129. void yyerror(char *string) {
  1130. #if DEBUG
  1131.     Debug("Printing error [%s] %d\n",string,state);
  1132. #endif
  1133.     if(string) Error("%s", string);
  1134.     else Error("Unknown error");
  1135. }
  1136.  
  1137. void php_init_lex(void) {
  1138. #if PHP_HAVE_MMAP
  1139.     pa=NULL;
  1140. #else
  1141.     pa=NULL;
  1142. #endif
  1143.     pa_pos=0L;
  1144.     gfd = 0;
  1145.     gsize = 0L;
  1146.     state = 0;
  1147.     lstate = 0;
  1148.     inIf=-1;
  1149.     inWhile=-1;
  1150.     inpos=0; /* current position in inbuf */
  1151.     outpos=0;
  1152.     inlength=0; /* current length of inbuf */
  1153.     g_length=0;
  1154.     NewExpr=1;
  1155.     ClearIt=0;
  1156.     LastToken=0;
  1157.     iterwhile=0L;
  1158.     SeekPos=0L;
  1159.     top = NULL;
  1160.     functop = NULL;
  1161.     cur_func=NULL;
  1162.     no_httpd = 0;
  1163.     cfstart = 0;
  1164.     funcarg_top = NULL;
  1165.     funcarg_bot = NULL;
  1166.     ExitCalled=0;
  1167.     eval_mode=0;
  1168. #if TEXT_MAGIC
  1169.     TextMagic=0;
  1170. #endif
  1171. }
  1172.  
  1173. #if TEXT_MAGIC
  1174. void set_text_magic(int mode) {
  1175.     TextMagic=mode;
  1176. }
  1177. #endif
  1178.  
  1179. /* Initializes the parser by filling the input buffer, if needed,
  1180.  * and setting various lexer variables
  1181.  */
  1182. void ParserInit(int fd, long file_size, int nh, char *fbuf) {
  1183.     no_httpd = nh;
  1184.  
  1185.     if(fd!=-1) {
  1186. #if PHP_HAVE_MMAP
  1187. #if DEBUG
  1188.         Debug("mmap'ing %ld bytes\n",file_size);
  1189. #endif
  1190.         pa = mmap(NULL, file_size, PROT_READ, MAP_PRIVATE, fd, 0);
  1191.         pa_pos = 0L;
  1192. #else
  1193.         {
  1194.         FILE *fp;
  1195.  
  1196.         fp = fdopen(fd,"r");
  1197.         pa = emalloc(0,file_size + 1);
  1198.         fread(pa,1,file_size,fp);
  1199.         pa_pos = 0L;
  1200.         fclose(fp);
  1201.         }
  1202. #endif
  1203.         gfd = fd;
  1204.         state = 0;
  1205.         lstate = 0;
  1206.         inIf=-1;
  1207.         inWhile=-1;
  1208.     } else { /* For functions */
  1209.         state = 2;
  1210.         pa = fbuf;
  1211.         pa_pos = 0L;
  1212.     }
  1213.     gsize = file_size;
  1214.     inpos = -1;
  1215.     tokenmarker=0;
  1216.     yylex_linenumber = 0;
  1217. }  
  1218.  
  1219. /* Iterate a while loop */
  1220. void WhileAgain(long seekpos, int offset, int lineno) {
  1221.     pa_pos = seekpos+offset;
  1222.     yylex_linenumber = lineno;
  1223.     tokenmarker = 0;
  1224.     state=2;
  1225.     iterwhile=pa_pos;
  1226. }
  1227.  
  1228. int NewWhileIteration(void) {
  1229.     return(iterwhile!=SeekPos);
  1230. }
  1231.  
  1232. /*
  1233.  * If footer is false, logging and footer printing will not take
  1234.  * place regardless of the current setting of showinfo and logging.
  1235.  * This is mainly to allow internally generated pages from acc.c to
  1236.  * not trigger these mechanisms.
  1237.  */
  1238. void Exit(int footer) {
  1239. #if DEBUG
  1240.     Debug("Exit called\n");
  1241. #endif
  1242.     if(!ExitCalled) ExitCalled=1;
  1243.     else return;
  1244. #if DEBUG
  1245.     Debug("Calling php_header from Exit()\n");
  1246. #endif
  1247.     php_header(0,NULL); /* just in case it hasn't been sent yet. */
  1248. #if PHP_HAVE_MMAP
  1249.     if(pa) {
  1250. #if DEBUG
  1251.         Debug("munmap'ing %ld bytes\n",gsize);
  1252. #endif
  1253.         munmap(pa,gsize);
  1254.         pa=NULL;
  1255. #ifndef APACHE
  1256.         close(gfd);
  1257. #endif
  1258.     }
  1259. #else
  1260.     pa=NULL;
  1261. #endif
  1262.     if(!no_httpd) {
  1263. #if defined(LOGGING) || defined(MSQLLOGGING)
  1264.         if(footer && getshowinfo()) ShowPageInfo();
  1265. #endif
  1266.         if(footer && getlogging()) {
  1267. #if MSQLLOGGING
  1268.             MsqlLog(GetCurrentPI());
  1269. #endif
  1270. #if LOGGING
  1271.             Log(GetCurrentPI());
  1272. #endif
  1273.         }
  1274.     }
  1275.     MsqlClose();
  1276.     PGcloseAll();
  1277.     dbmCloseAll();
  1278. #if DEBUG
  1279.     php_pool_show();
  1280.     CloseDebug();
  1281. #endif
  1282.     state=99;  /* This causes the parser to exit on its next iteration */
  1283. }
  1284.  
  1285. /* Called from error.c to generate useful debugging info on an error */
  1286. char *GetCurrentLexLine(int *pos, int *length) {
  1287.     *pos = inpos;
  1288.     *length = inlength;
  1289.     return(inbuf);
  1290. }
  1291.  
  1292. /* Save a function in memory and create a frame for static variables */
  1293. void DefineFunc(unsigned char *fnc) {
  1294.     int len, i=0,active;
  1295.     unsigned char *buf;
  1296.     long bufsize;
  1297.     FuncStack *new;
  1298.  
  1299.     /* Check to see if we have an internal function by this name */
  1300.     len = strlen(fnc);
  1301.     while(cmd_table[len][i].cmd) {
  1302.         if(!strncasecmp(fnc,cmd_table[len][i].cmd,len)) {
  1303.             Error("\"%s\" is the name of an internal function",fnc);
  1304.             return;
  1305.         }  
  1306.         i++;
  1307.     }
  1308.     bufsize = SeekPos + inpos - cfstart;
  1309.     i=0;
  1310.     while(*(pa+cfstart+i) && *(pa+cfstart+i)!='(') i++;
  1311.     cfstart += i;
  1312.     bufsize -= i;
  1313.     i=bufsize;
  1314.     while(*(pa+cfstart+i) && *(pa+cfstart+i)!=')') i--;
  1315.     bufsize = i;
  1316.     buf = emalloc(0,bufsize+1);
  1317.     memcpy(buf,pa+cfstart+1,bufsize-1);
  1318.     buf[bufsize]='\0';
  1319.  
  1320.     new = emalloc(0,sizeof(FuncStack));
  1321.     new->next = functop;
  1322.     functop = new;
  1323.     new->name = estrdup(0,fnc);
  1324.     new->buf = buf;
  1325.     new->size = bufsize-1;
  1326.     new->frame = emalloc(0,sizeof(VarTree));
  1327.     new->frame->type = STRING;
  1328.     new->frame->count=1;
  1329.     new->frame->name = estrdup(0,fnc);
  1330.     new->frame->strval = estrdup(0,fnc);
  1331.     new->frame->iname=NULL;
  1332.     new->frame->intval = 0;
  1333.     new->frame->douval = 0.0;
  1334.     new->frame->flag = 0;
  1335.     new->frame->scope = 0;
  1336.     new->frame->left=NULL;
  1337.     new->frame->right=NULL;
  1338.     new->frame->next=NULL;
  1339.     new->frame->prev=NULL;
  1340.     new->frame->lacc=new->frame;
  1341.     new->frame->lastnode=new->frame;
  1342.     new->params = funcarg_bot;
  1343.     funcarg_top = NULL;
  1344.     funcarg_bot = NULL;
  1345.     CondPop(&active);
  1346. }
  1347.  
  1348. /* Mark start of a function definition */
  1349. void InitFunc(void) {
  1350.     cfstart = SeekPos + inpos;
  1351.     CondPush(0,-5);
  1352. }
  1353.  
  1354. /* Find a function in the function list and return its definition pointer */
  1355. FuncStack *FindFunc(char *name, long *func_size, VarTree **frame) {
  1356.     FuncStack *f;
  1357.  
  1358.     f = functop;
  1359.     while(f) {
  1360.         if(!strcasecmp(f->name,name)) {
  1361.             *func_size = f->size;
  1362.             if(frame) *frame = f->frame;
  1363.             return(f);
  1364.         }
  1365.         f = f->next;
  1366.     }
  1367.     return(NULL);
  1368. }
  1369.  
  1370. /* Return the static variable function frame for the currently executing function */
  1371. VarTree *GetFuncFrame(void) {
  1372.     if(!cur_func) return(NULL);
  1373.     return(cur_func->frame);
  1374. }
  1375.  
  1376. /* Execute the specified function */
  1377. void RunFunc(unsigned char *name) {
  1378.     char *ofn=NULL;
  1379.     long func_size=0L;
  1380.     long ofile_size=0L;
  1381.     FuncStack *f;
  1382.     FuncArgList *arg;
  1383.  
  1384. #if DEBUG
  1385.     Debug("Running function [%s]\n",name);
  1386. #endif
  1387.     f = FindFunc(name, &func_size, NULL);
  1388.     if(!f) {
  1389.         Error("No function named %s",name);
  1390.         return;
  1391.     }
  1392.     if(cur_func) { /* Nested function call */
  1393.         FilePush(cur_func->name,gsize,-1);
  1394.     } else {
  1395.         ofn = estrdup(0,GetCurrentFilename());
  1396.         ofile_size = GetCurrentFileSize();
  1397.         FilePush(ofn,ofile_size,gfd);
  1398.     }
  1399.     cur_func = f;
  1400.     ParserInit(-1,func_size,no_httpd,f->buf);
  1401.     PushStackFrame();
  1402.     PushCondMatchMarks();
  1403.     arg = f->params;
  1404.     while(arg) {
  1405.         SetVar(arg->arg,0,0);
  1406.         arg = arg->prev;
  1407.     }  
  1408.     yyparse();
  1409.     if(ExitCalled) state=99;
  1410. }
  1411.  
  1412. /* Doubly-linked argument list */
  1413. void AddToArgList(unsigned char *arg) {
  1414.     FuncArgList *new;
  1415.  
  1416.     new = emalloc(0,sizeof(FuncArgList));
  1417.     new->next = funcarg_top;
  1418.     if(new->next) new->next->prev = new;
  1419.     else funcarg_bot = new;
  1420.     new->prev = NULL;
  1421.     new->arg = estrdup(0,arg);
  1422.     funcarg_top = new;
  1423. }
  1424.  
  1425. FuncArgList *GetFuncArgList(void) {
  1426.     return funcarg_top;
  1427. }
  1428.  
  1429. void ClearFuncArgList(void) {
  1430.     FuncArgList *top, *next;
  1431.  
  1432.     if(!funcarg_top) return;
  1433.     top = funcarg_top;
  1434.     next = top->next;
  1435.     while(next) {
  1436.         top = next;
  1437.         next = top->next;
  1438.     }
  1439.     funcarg_top=NULL;
  1440.     funcarg_bot=NULL;
  1441. }
  1442.  
  1443. void Return(void) {
  1444.     putback(0);
  1445. }
  1446.  
Advertisement
Add Comment
Please, Sign In to add comment