Hex Artifact Content
Not logged in

Artifact 0e9e18ccfe0dfbad65eb8eced7262508b22527ea:

File src/cgi.c part of check-in [88948d582a] - Fixed memleaks of date-related header strings. by stephan on 2008-02-16 18:49:39.

0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68  (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76  lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c  ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65  ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73  s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20  tributed in the 
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c  hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20  l be useful,.** 
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20  but WITHOUT ANY 
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75  WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69  t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a  ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54  * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52  Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55   A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20  RPOSE.  See the 
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50  GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f  ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a  r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c  ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20  d have received 
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e  a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63  U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e  .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72  g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69  ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65  te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20  ation, Inc., 59 
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53  Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73  uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31  ton, MA  02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20  307, USA..**.** 
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69  Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20  nformation:.**  
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a   drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68  *   http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a  waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 43 20 66 75 6e 63   contains C func
0380: 74 69 6f 6e 73 20 61 6e 64 20 70 72 6f 63 65 64  tions and proced
0390: 75 72 65 73 20 74 68 61 74 20 70 72 6f 76 69 64  ures that provid
03a0: 65 20 75 73 65 66 75 6c 0a 2a 2a 20 73 65 72 76  e useful.** serv
03b0: 69 63 65 73 20 74 6f 20 43 47 49 20 70 72 6f 67  ices to CGI prog
03c0: 72 61 6d 73 2e 20 20 54 68 65 72 65 20 61 72 65  rams.  There are
03d0: 20 70 72 6f 63 65 64 75 72 65 73 20 66 6f 72 20   procedures for 
03e0: 70 61 72 73 69 6e 67 20 61 6e 64 0a 2a 2a 20 64  parsing and.** d
03f0: 69 73 70 65 6e 73 69 6e 67 20 51 55 45 52 59 5f  ispensing QUERY_
0400: 53 54 52 49 4e 47 20 70 61 72 61 6d 65 74 65 72  STRING parameter
0410: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2c 20 74  s and cookies, t
0420: 68 65 20 22 6d 70 72 69 6e 74 66 28 29 22 0a 2a  he "mprintf()".*
0430: 2a 20 66 6f 72 6d 61 74 74 69 6e 67 20 66 75 6e  * formatting fun
0440: 63 74 69 6f 6e 20 61 6e 64 20 69 74 73 20 63 6f  ction and its co
0450: 75 73 69 6e 73 2c 20 61 6e 64 20 72 6f 75 74 69  usins, and routi
0460: 6e 65 73 20 74 6f 20 65 6e 63 6f 64 65 20 61 6e  nes to encode an
0470: 64 0a 2a 2a 20 64 65 63 6f 64 65 20 73 74 72 69  d.** decode stri
0480: 6e 67 73 20 69 6e 20 48 54 4d 4c 20 6f 72 20 48  ngs in HTML or H
0490: 54 54 50 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  TTP..*/.#include
04a0: 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 66 64   "config.h".#ifd
04b0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 23  ef __MINGW32__.#
04c0: 20 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e 64 6f    include <windo
04d0: 77 73 2e 68 3e 20 20 20 20 20 20 20 20 20 20 20  ws.h>           
04e0: 2f 2a 20 66 6f 72 20 53 6c 65 65 70 20 6f 6e 63  /* for Sleep onc
04f0: 65 20 73 65 72 76 65 72 20 77 6f 72 6b 73 20 61  e server works a
0500: 67 61 69 6e 20 2a 2f 0a 23 20 20 69 6e 63 6c 75  gain */.#  inclu
0510: 64 65 20 3c 77 69 6e 73 6f 63 6b 32 2e 68 3e 20  de <winsock2.h> 
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 6f 63 6b           /* sock
0530: 65 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f  et operations */
0540: 0a 23 20 20 64 65 66 69 6e 65 20 73 6c 65 65 70  .#  define sleep
0550: 20 53 6c 65 65 70 20 20 20 20 20 20 20 20 20 20   Sleep          
0560: 20 20 2f 2a 20 77 69 6e 64 6f 77 73 20 64 6f 65    /* windows doe
0570: 73 20 6e 6f 74 20 68 61 76 65 20 73 6c 65 65 70  s not have sleep
0580: 2c 20 62 75 74 20 53 6c 65 65 70 20 2a 2f 0a 23  , but Sleep */.#
0590: 20 20 69 6e 63 6c 75 64 65 20 3c 77 73 32 74 63    include <ws2tc
05a0: 70 69 70 2e 68 3e 20 20 20 20 20 20 20 20 20 20  pip.h>          
05b0: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64  .#else.#  includ
05c0: 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e  e <sys/socket.h>
05d0: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74  .#  include <net
05e0: 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e  inet/in.h>.#  in
05f0: 63 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74  clude <arpa/inet
0600: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c  .h>.#  include <
0610: 73 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20  sys/times.h>.#  
0620: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d  include <sys/tim
0630: 65 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20  e.h>.#  include 
0640: 3c 73 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20  <sys/wait.h>.#  
0650: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c  include <sys/sel
0660: 65 63 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69  ect.h>.#endif.#i
0670: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a  nclude <time.h>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e  #include <stdio.
0690: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h>.#include <std
06a0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  lib.h>.#include 
06b0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c  <unistd.h>.#incl
06c0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66  ude "cgi.h"..#if
06d0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a   INTERFACE./*.**
06e0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63   Shortcuts for c
06f0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50  gi_parameter.  P
0700: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68  ("x") returns th
0710: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79  e value of query
0720: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72   parameter.** or
0730: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20   cookie "x", or 
0740: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73  NULL if there is
0750: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74   no such paramet
0760: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50  er or cookie.  P
0770: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f  D("x","y").** do
0780: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65  es the same exce
0790: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e  pt "y" is return
07a0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e  ed in place of N
07b0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20  ULL if there is 
07c0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64  not match..*/.#d
07d0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20  efine P(x)      
07e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28    cgi_parameter(
07f0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50  (x),0).#define P
0800: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70  D(x,y)     cgi_p
0810: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29  arameter((x),(y)
0820: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20  ).#define QP(x) 
0830: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73        quotable_s
0840: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65  tring(cgi_parame
0850: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66  ter((x),0)).#def
0860: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20  ine QPD(x,y)    
0870: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28  quotable_string(
0880: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78  cgi_parameter((x
0890: 29 2c 28 79 29 29 29 0a 0a 0a 2f 2a 0a 2a 2a 20  ),(y))).../*.** 
08a0: 44 65 73 74 69 6e 61 74 69 6f 6e 73 20 66 6f 72  Destinations for
08b0: 20 6f 75 74 70 75 74 20 74 65 78 74 2e 0a 2a 2f   output text..*/
08c0: 0a 23 64 65 66 69 6e 65 20 43 47 49 5f 48 45 41  .#define CGI_HEA
08d0: 44 45 52 20 20 20 30 0a 23 64 65 66 69 6e 65 20  DER   0.#define 
08e0: 43 47 49 5f 42 4f 44 59 20 20 20 20 20 31 0a 0a  CGI_BODY     1..
08f0: 23 65 6e 64 69 66 20 2f 2a 20 49 4e 54 45 52 46  #endif /* INTERF
0900: 41 43 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50 72  ACE */../*.** Pr
0910: 6f 76 69 64 65 20 61 20 72 65 6c 69 61 62 6c 65  ovide a reliable
0920: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
0930: 6f 66 20 61 20 63 61 73 65 6c 65 73 73 20 73 74  of a caseless st
0940: 72 69 6e 67 20 63 6f 6d 70 61 72 69 73 6f 6e 0a  ring comparison.
0950: 2a 2a 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  ** function..*/.
0960: 23 64 65 66 69 6e 65 20 73 74 72 69 63 6d 70 20  #define stricmp 
0970: 73 71 6c 69 74 65 33 53 74 72 49 43 6d 70 0a 65  sqlite3StrICmp.e
0980: 78 74 65 72 6e 20 69 6e 74 20 73 71 6c 69 74 65  xtern int sqlite
0990: 33 53 74 72 49 43 6d 70 28 63 6f 6e 73 74 20 63  3StrICmp(const c
09a0: 68 61 72 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72  har*, const char
09b0: 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 48  *);../*.** The H
09c0: 54 54 50 20 72 65 70 6c 79 20 69 73 20 67 65 6e  TTP reply is gen
09d0: 65 72 61 74 65 64 20 69 6e 20 74 77 6f 20 70 69  erated in two pi
09e0: 65 63 65 73 3a 20 74 68 65 20 68 65 61 64 65 72  eces: the header
09f0: 20 61 6e 64 20 74 68 65 20 62 6f 64 79 2e 0a 2a   and the body..*
0a00: 2a 20 54 68 65 73 65 20 70 69 65 63 65 73 20 61  * These pieces a
0a10: 72 65 20 67 65 6e 65 72 61 74 65 64 20 73 65 70  re generated sep
0a20: 61 72 61 74 65 6c 79 20 62 65 63 61 75 73 65 20  arately because 
0a30: 74 68 65 79 20 61 72 65 20 6e 6f 74 20 6e 65 63  they are not nec
0a40: 65 73 73 61 72 79 0a 2a 2a 20 70 72 6f 64 75 63  essary.** produc
0a50: 65 64 20 69 6e 20 6f 72 64 65 72 2e 20 20 50 61  ed in order.  Pa
0a60: 72 74 73 20 6f 66 20 74 68 65 20 68 65 61 64 65  rts of the heade
0a70: 72 20 6d 69 67 68 74 20 62 65 20 62 75 69 6c 74  r might be built
0a80: 20 61 66 74 65 72 20 61 6c 6c 20 6f 72 0a 2a 2a   after all or.**
0a90: 20 70 61 72 74 20 6f 66 20 74 68 65 20 62 6f 64   part of the bod
0aa0: 79 2e 20 20 54 68 65 20 68 65 61 64 65 72 20 61  y.  The header a
0ab0: 6e 64 20 62 6f 64 79 20 61 72 65 20 61 63 63 75  nd body are accu
0ac0: 6d 75 6c 61 74 65 64 20 69 6e 20 73 65 70 61 72  mulated in separ
0ad0: 61 74 65 0a 2a 2a 20 42 6c 6f 62 20 73 74 72 75  ate.** Blob stru
0ae0: 63 74 75 72 65 73 20 74 68 65 6e 20 6f 75 74 70  ctures then outp
0af0: 75 74 20 73 65 71 75 65 6e 74 69 61 6c 6c 79 20  ut sequentially 
0b00: 6f 6e 63 65 20 65 76 65 72 79 74 68 69 6e 67 20  once everything 
0b10: 68 61 73 20 62 65 65 6e 0a 2a 2a 20 62 75 69 6c  has been.** buil
0b20: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 67 69  t..**.** The cgi
0b30: 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 29 20 69  _destination() i
0b40: 6e 74 65 72 66 61 63 65 20 73 77 69 74 63 68 20  nterface switch 
0b50: 62 65 74 77 65 65 6e 20 74 68 65 20 62 75 66 66  between the buff
0b60: 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42  ers..*/.static B
0b70: 6c 6f 62 20 2a 70 43 6f 6e 74 65 6e 74 3b 0a 73  lob *pContent;.s
0b80: 74 61 74 69 63 20 42 6c 6f 62 20 63 67 69 43 6f  tatic Blob cgiCo
0b90: 6e 74 65 6e 74 5b 32 5d 20 3d 20 7b 20 42 4c 4f  ntent[2] = { BLO
0ba0: 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52 2c 20 42  B_INITIALIZER, B
0bb0: 4c 4f 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52 20  LOB_INITIALIZER 
0bc0: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68  };../*.** Set th
0bd0: 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 62 75  e destination bu
0be0: 66 66 65 72 20 69 6e 74 6f 20 77 68 69 63 68 20  ffer into which 
0bf0: 74 6f 20 61 63 63 75 6d 75 6c 61 74 65 20 43 47  to accumulate CG
0c00: 49 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76 6f  I content..*/.vo
0c10: 69 64 20 63 67 69 5f 64 65 73 74 69 6e 61 74 69  id cgi_destinati
0c20: 6f 6e 28 69 6e 74 20 64 65 73 74 29 7b 0a 20 20  on(int dest){.  
0c30: 73 77 69 74 63 68 28 20 64 65 73 74 20 29 7b 0a  switch( dest ){.
0c40: 20 20 20 20 63 61 73 65 20 43 47 49 5f 48 45 41      case CGI_HEA
0c50: 44 45 52 3a 20 7b 0a 20 20 20 20 20 20 70 43 6f  DER: {.      pCo
0c60: 6e 74 65 6e 74 20 3d 20 26 63 67 69 43 6f 6e 74  ntent = &cgiCont
0c70: 65 6e 74 5b 30 5d 3b 0a 20 20 20 20 20 20 62 72  ent[0];.      br
0c80: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63  eak;.    }.    c
0c90: 61 73 65 20 43 47 49 5f 42 4f 44 59 3a 20 7b 0a  ase CGI_BODY: {.
0ca0: 20 20 20 20 20 20 70 43 6f 6e 74 65 6e 74 20 3d        pContent =
0cb0: 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 3b   &cgiContent[1];
0cc0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
0cd0: 20 20 7d 0a 20 20 20 20 64 65 66 61 75 6c 74 3a    }.    default:
0ce0: 20 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 61 6e   {.      cgi_pan
0cf0: 69 63 28 22 62 61 64 20 64 65 73 74 69 6e 61 74  ic("bad destinat
0d00: 69 6f 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  ion");.    }.  }
0d10: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64  .}../*.** Append
0d20: 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74   reply content t
0d30: 6f 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 65  o what already e
0d40: 78 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63  xists..*/.void c
0d50: 67 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e  gi_append_conten
0d60: 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44  t(const char *zD
0d70: 61 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b 0a  ata, int nAmt){.
0d80: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 43    blob_append(pC
0d90: 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c 20 6e  ontent, zData, n
0da0: 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  Amt);.}../*.** R
0db0: 65 73 65 74 20 74 68 65 20 48 54 54 50 20 72 65  eset the HTTP re
0dc0: 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 20 61  ply text to be a
0dd0: 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 2e 0a  n empty string..
0de0: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 73 65  */.void cgi_rese
0df0: 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 29 7b  t_content(void){
0e00: 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63  .  blob_reset(&c
0e10: 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 20  giContent[0]);. 
0e20: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67 69   blob_reset(&cgi
0e30: 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 7d 0a 0a  Content[1]);.}..
0e40: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70  /*.** Return a p
0e50: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43 47  ointer to the CG
0e60: 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a 2a  I output blob..*
0e70: 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74 70  /.Blob *cgi_outp
0e80: 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a 20  ut_blob(void){. 
0e90: 20 72 65 74 75 72 6e 20 70 43 6f 6e 74 65 6e 74   return pContent
0ea0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 62 69  ;.}../*.** Combi
0eb0: 6e 65 20 74 68 65 20 68 65 61 64 65 72 20 61 6e  ne the header an
0ec0: 64 20 62 6f 64 79 20 6f 66 20 74 68 65 20 43 47  d body of the CG
0ed0: 49 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20  I into a single 
0ee0: 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69  string..*/.stati
0ef0: 63 20 76 6f 69 64 20 63 67 69 5f 63 6f 6d 62 69  c void cgi_combi
0f00: 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 6f  ne_header_and_bo
0f10: 64 79 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20  dy(void){.  int 
0f20: 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a 65  size = blob_size
0f30: 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29  (&cgiContent[1])
0f40: 3b 0a 20 20 69 66 28 20 73 69 7a 65 3e 30 20 29  ;.  if( size>0 )
0f50: 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e  {.    blob_appen
0f60: 64 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d  d(&cgiContent[0]
0f70: 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63  , blob_buffer(&c
0f80: 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 2c 20 73  giContent[1]), s
0f90: 69 7a 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72  ize);.    blob_r
0fa0: 65 73 65 74 28 26 63 67 69 43 6f 6e 74 65 6e 74  eset(&cgiContent
0fb0: 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a  [1]);.  }.}../*.
0fc0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e  ** Return a poin
0fd0: 74 65 72 20 74 6f 20 74 68 65 20 48 54 54 50 20  ter to the HTTP 
0fe0: 72 65 70 6c 79 20 74 65 78 74 2e 0a 2a 2f 0a 63  reply text..*/.c
0ff0: 68 61 72 20 2a 63 67 69 5f 65 78 74 72 61 63 74  har *cgi_extract
1000: 5f 63 6f 6e 74 65 6e 74 28 69 6e 74 20 2a 70 6e  _content(int *pn
1010: 41 6d 74 29 7b 0a 20 20 63 67 69 5f 63 6f 6d 62  Amt){.  cgi_comb
1020: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62  ine_header_and_b
1030: 6f 64 79 28 29 3b 0a 20 20 72 65 74 75 72 6e 20  ody();.  return 
1040: 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 69  blob_buffer(&cgi
1050: 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 7d 0a 0a  Content[0]);.}..
1060: 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c  /*.** Additional
1070: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73 65   information use
1080: 64 20 74 6f 20 66 6f 72 6d 20 74 68 65 20 48 54  d to form the HT
1090: 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 73 74 61 74  TP reply.*/.stat
10a0: 69 63 20 63 68 61 72 20 2a 7a 43 6f 6e 74 65 6e  ic char *zConten
10b0: 74 54 79 70 65 20 3d 20 22 74 65 78 74 2f 68 74  tType = "text/ht
10c0: 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 43 6f 6e 74  ml";     /* Cont
10d0: 65 6e 74 20 74 79 70 65 20 6f 66 20 74 68 65 20  ent type of the 
10e0: 72 65 70 6c 79 20 2a 2f 0a 73 74 61 74 69 63 20  reply */.static 
10f0: 63 68 61 72 20 2a 7a 52 65 70 6c 79 53 74 61 74  char *zReplyStat
1100: 75 73 20 3d 20 22 4f 4b 22 3b 20 20 20 20 20 20  us = "OK";      
1110: 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 73        /* Reply s
1120: 74 61 74 75 73 20 64 65 73 63 72 69 70 74 69 6f  tatus descriptio
1130: 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  n */.static int 
1140: 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 32  iReplyStatus = 2
1150: 30 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  00;             
1160: 20 20 2f 2a 20 52 65 70 6c 79 20 73 74 61 74 75    /* Reply statu
1170: 73 20 63 6f 64 65 20 2a 2f 0a 73 74 61 74 69 63  s code */.static
1180: 20 42 6c 6f 62 20 65 78 74 72 61 48 65 61 64 65   Blob extraHeade
1190: 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 4c  r = BLOB_INITIAL
11a0: 49 5a 45 52 3b 20 20 2f 2a 20 45 78 74 72 61 20  IZER;  /* Extra 
11b0: 68 65 61 64 65 72 20 74 65 78 74 20 2a 2f 0a 73  header text */.s
11c0: 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 48 74  tatic int fullHt
11d0: 74 70 52 65 70 6c 79 20 3d 20 30 3b 20 20 20 20  tpReply = 0;    
11e0: 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 61 20    /* True for a 
11f0: 66 75 6c 6c 2d 62 6c 6f 77 6e 20 48 54 54 50 20  full-blown HTTP 
1200: 68 65 61 64 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a 2a  header */../*.**
1210: 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 20 63   Set the reply c
1220: 6f 6e 74 65 6e 74 20 74 79 70 65 0a 2a 2f 0a 76  ontent type.*/.v
1230: 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74  oid cgi_set_cont
1240: 65 6e 74 5f 74 79 70 65 28 63 6f 6e 73 74 20 63  ent_type(const c
1250: 68 61 72 20 2a 7a 54 79 70 65 29 7b 0a 20 20 7a  har *zType){.  z
1260: 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 6d 70  ContentType = mp
1270: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 54 79 70  rintf("%s", zTyp
1280: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  e);.}../*.** Set
1290: 20 74 68 65 20 72 65 70 6c 79 20 63 6f 6e 74 65   the reply conte
12a0: 6e 74 20 74 6f 20 74 68 65 20 73 70 65 63 69 66  nt to the specif
12b0: 69 65 64 20 42 4c 4f 42 2e 0a 2a 2f 0a 76 6f 69  ied BLOB..*/.voi
12c0: 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 65 6e  d cgi_set_conten
12d0: 74 28 42 6c 6f 62 20 2a 70 4e 65 77 43 6f 6e 74  t(Blob *pNewCont
12e0: 65 6e 74 29 7b 0a 20 20 63 67 69 5f 72 65 73 65  ent){.  cgi_rese
12f0: 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63  t_content();.  c
1300: 67 69 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 43  gi_destination(C
1310: 47 49 5f 48 45 41 44 45 52 29 3b 0a 20 20 63 67  GI_HEADER);.  cg
1320: 69 43 6f 6e 74 65 6e 74 5b 30 5d 20 3d 20 2a 70  iContent[0] = *p
1330: 4e 65 77 43 6f 6e 74 65 6e 74 3b 0a 20 20 62 6c  NewContent;.  bl
1340: 6f 62 5f 7a 65 72 6f 28 70 4e 65 77 43 6f 6e 74  ob_zero(pNewCont
1350: 65 6e 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53  ent);.}../*.** S
1360: 65 74 20 74 68 65 20 72 65 70 6c 79 20 73 74 61  et the reply sta
1370: 74 75 73 20 63 6f 64 65 0a 2a 2f 0a 76 6f 69 64  tus code.*/.void
1380: 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28   cgi_set_status(
1390: 69 6e 74 20 69 53 74 61 74 2c 20 63 6f 6e 73 74  int iStat, const
13a0: 20 63 68 61 72 20 2a 7a 53 74 61 74 29 7b 0a 20   char *zStat){. 
13b0: 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20   zReplyStatus = 
13c0: 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 53  mprintf("%s", zS
13d0: 74 61 74 29 3b 0a 20 20 69 52 65 70 6c 79 53 74  tat);.  iReplySt
13e0: 61 74 75 73 20 3d 20 69 53 74 61 74 3b 0a 7d 0a  atus = iStat;.}.
13f0: 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 65  ./*.** Append te
1400: 78 74 20 74 6f 20 74 68 65 20 68 65 61 64 65 72  xt to the header
1410: 20 6f 66 20 61 6e 20 48 54 54 50 20 72 65 70 6c   of an HTTP repl
1420: 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 61 70  y.*/.void cgi_ap
1430: 70 65 6e 64 5f 68 65 61 64 65 72 28 63 6f 6e 73  pend_header(cons
1440: 74 20 63 68 61 72 20 2a 7a 4c 69 6e 65 29 7b 0a  t char *zLine){.
1450: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 65    blob_append(&e
1460: 78 74 72 61 48 65 61 64 65 72 2c 20 7a 4c 69 6e  xtraHeader, zLin
1470: 65 2c 20 2d 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  e, -1);.}../*.**
1480: 20 53 65 74 20 61 20 63 6f 6f 6b 69 65 2e 0a 2a   Set a cookie..*
1490: 2a 0a 2a 2a 20 5a 65 72 6f 20 6c 69 66 65 74 69  *.** Zero lifeti
14a0: 6d 65 20 69 6d 70 6c 69 65 73 20 61 20 73 65 73  me implies a ses
14b0: 73 69 6f 6e 20 63 6f 6f 6b 69 65 2e 0a 2a 2f 0a  sion cookie..*/.
14c0: 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6f  void cgi_set_coo
14d0: 6b 69 65 28 0a 20 20 63 6f 6e 73 74 20 63 68 61  kie(.  const cha
14e0: 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 2f 2a 20  r *zName,    /* 
14f0: 4e 61 6d 65 20 6f 66 20 74 68 65 20 63 6f 6f 6b  Name of the cook
1500: 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ie */.  const ch
1510: 61 72 20 2a 7a 56 61 6c 75 65 2c 20 20 20 2f 2a  ar *zValue,   /*
1520: 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20 63 6f   Value of the co
1530: 6f 6b 69 65 2e 20 20 41 75 74 6f 6d 61 74 69 63  okie.  Automatic
1540: 61 6c 6c 79 20 65 73 63 61 70 65 64 20 2a 2f 0a  ally escaped */.
1550: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50    const char *zP
1560: 61 74 68 2c 20 20 20 20 2f 2a 20 50 61 74 68 20  ath,    /* Path 
1570: 63 6f 6f 6b 69 65 20 61 70 70 6c 69 65 73 20 74  cookie applies t
1580: 6f 2e 20 20 4e 55 4c 4c 20 6d 65 61 6e 73 20 22  o.  NULL means "
1590: 2f 22 20 2a 2f 0a 20 20 69 6e 74 20 6c 69 66 65  /" */.  int life
15a0: 74 69 6d 65 20 20 20 20 20 20 20 20 20 20 2f 2a  time          /*
15b0: 20 45 78 70 69 72 61 74 69 6f 6e 20 6f 66 20 74   Expiration of t
15c0: 68 65 20 63 6f 6f 6b 69 65 20 69 6e 20 73 65 63  he cookie in sec
15d0: 6f 6e 64 73 20 66 72 6f 6d 20 6e 6f 77 20 2a 2f  onds from now */
15e0: 0a 29 7b 0a 20 20 69 66 28 20 7a 50 61 74 68 3d  .){.  if( zPath=
15f0: 3d 30 20 29 20 7a 50 61 74 68 20 3d 20 67 2e 7a  =0 ) zPath = g.z
1600: 54 6f 70 3b 0a 20 20 69 66 28 20 6c 69 66 65 74  Top;.  if( lifet
1610: 69 6d 65 3e 30 20 29 7b 0a 20 20 20 20 6c 69 66  ime>0 ){.    lif
1620: 65 74 69 6d 65 20 2b 3d 20 28 69 6e 74 29 74 69  etime += (int)ti
1630: 6d 65 28 30 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  me(0);.    blob_
1640: 61 70 70 65 6e 64 66 28 26 65 78 74 72 61 48 65  appendf(&extraHe
1650: 61 64 65 72 2c 0a 20 20 20 20 20 20 20 22 53 65  ader,.       "Se
1660: 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d 25 74 3b  t-Cookie: %s=%t;
1670: 20 50 61 74 68 3d 25 73 3b 20 65 78 70 69 72 65   Path=%s; expire
1680: 73 3d 25 7a 3b 20 56 65 72 73 69 6f 6e 3d 31 5c  s=%z; Version=1\
1690: 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e  r\n",.        zN
16a0: 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50 61  ame, zValue, zPa
16b0: 74 68 2c 20 63 67 69 5f 72 66 63 38 32 32 5f 64  th, cgi_rfc822_d
16c0: 61 74 65 73 74 61 6d 70 28 6c 69 66 65 74 69 6d  atestamp(lifetim
16d0: 65 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20  e));.  }else{.  
16e0: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26    blob_appendf(&
16f0: 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20  extraHeader,.   
1700: 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a      "Set-Cookie:
1710: 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b   %s=%t; Path=%s;
1720: 20 56 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c   Version=1\r\n",
1730: 0a 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 7a  .       zName, z
1740: 56 61 6c 75 65 2c 20 7a 50 61 74 68 29 3b 0a 20  Value, zPath);. 
1750: 20 7d 0a 7d 0a 0a 23 69 66 20 30 0a 2f 2a 0a 2a   }.}..#if 0./*.*
1760: 2a 20 41 64 64 20 61 6e 20 45 54 61 67 20 68 65  * Add an ETag he
1770: 61 64 65 72 20 6c 69 6e 65 0a 2a 2f 0a 73 74 61  ader line.*/.sta
1780: 74 69 63 20 63 68 61 72 20 2a 63 67 69 5f 61 64  tic char *cgi_ad
1790: 64 5f 65 74 61 67 28 63 68 61 72 20 2a 7a 54 78  d_etag(char *zTx
17a0: 74 2c 20 69 6e 74 20 6e 4c 65 6e 29 7b 0a 20 20  t, int nLen){.  
17b0: 4d 44 35 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a  MD5Context ctx;.
17c0: 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20    unsigned char 
17d0: 64 69 67 65 73 74 5b 31 36 5d 3b 0a 20 20 69 6e  digest[16];.  in
17e0: 74 20 69 2c 20 6a 3b 0a 20 20 63 68 61 72 20 7a  t i, j;.  char z
17f0: 45 54 61 67 5b 36 34 5d 3b 0a 0a 20 20 4d 44 35  ETag[64];..  MD5
1800: 49 6e 69 74 28 26 63 74 78 29 3b 0a 20 20 4d 44  Init(&ctx);.  MD
1810: 35 55 70 64 61 74 65 28 26 63 74 78 2c 7a 54 78  5Update(&ctx,zTx
1820: 74 2c 6e 4c 65 6e 29 3b 0a 20 20 4d 44 35 46 69  t,nLen);.  MD5Fi
1830: 6e 61 6c 28 64 69 67 65 73 74 2c 26 63 74 78 29  nal(digest,&ctx)
1840: 3b 0a 20 20 66 6f 72 28 6a 3d 69 3d 30 3b 20 69  ;.  for(j=i=0; i
1850: 3c 31 36 3b 20 69 2b 2b 2c 6a 2b 3d 32 29 7b 0a  <16; i++,j+=2){.
1860: 20 20 20 20 62 70 72 69 6e 74 66 28 26 7a 45 54      bprintf(&zET
1870: 61 67 5b 6a 5d 2c 73 69 7a 65 6f 66 28 7a 45 54  ag[j],sizeof(zET
1880: 61 67 29 2d 6a 2c 22 25 30 32 78 22 2c 28 69 6e  ag)-j,"%02x",(in
1890: 74 29 64 69 67 65 73 74 5b 69 5d 29 3b 0a 20 20  t)digest[i]);.  
18a0: 7d 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66  }.  blob_appendf
18b0: 28 26 65 78 74 72 61 48 65 61 64 65 72 2c 20 22  (&extraHeader, "
18c0: 45 54 61 67 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a  ETag: %s\r\n", z
18d0: 45 54 61 67 29 3b 0a 20 20 72 65 74 75 72 6e 20  ETag);.  return 
18e0: 73 74 72 64 75 70 28 7a 45 54 61 67 29 3b 0a 7d  strdup(zETag);.}
18f0: 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 73 6f 6d 65 20  ../*.** Do some 
1900: 63 61 63 68 65 20 63 6f 6e 74 72 6f 6c 20 73 74  cache control st
1910: 75 66 66 2e 20 46 69 72 73 74 2c 20 77 65 20 67  uff. First, we g
1920: 65 6e 65 72 61 74 65 20 61 6e 20 45 54 61 67 20  enerate an ETag 
1930: 61 6e 64 20 69 6e 63 6c 75 64 65 20 69 74 20 69  and include it i
1940: 6e 0a 2a 2a 20 74 68 65 20 72 65 73 70 6f 6e 73  n.** the respons
1950: 65 20 68 65 61 64 65 72 73 2e 20 53 65 63 6f 6e  e headers. Secon
1960: 64 2c 20 77 65 20 64 6f 20 77 68 61 74 65 76 65  d, we do whateve
1970: 72 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 74  r is necessary t
1980: 6f 20 64 65 74 65 72 6d 69 6e 65 20 69 66 0a 2a  o determine if.*
1990: 2a 20 74 68 65 20 72 65 71 75 65 73 74 20 77 61  * the request wa
19a0: 73 20 61 73 6b 69 6e 67 20 61 62 6f 75 74 20 63  s asking about c
19b0: 61 63 68 69 6e 67 20 61 6e 64 20 77 68 65 74 68  aching and wheth
19c0: 65 72 20 77 65 20 6e 65 65 64 20 74 6f 20 73 65  er we need to se
19d0: 6e 64 20 62 61 63 6b 20 74 68 65 0a 2a 2a 20 72  nd back the.** r
19e0: 65 73 70 6f 6e 73 65 20 62 6f 64 79 2e 20 49 66  esponse body. If
19f0: 20 77 65 20 73 68 6f 75 6c 64 6e 27 74 20 73 65   we shouldn't se
1a00: 6e 64 20 61 20 62 6f 64 79 2c 20 72 65 74 75 72  nd a body, retur
1a10: 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a  n non-zero..**.*
1a20: 2a 20 43 75 72 72 65 6e 74 6c 79 2c 20 77 65 20  * Currently, we 
1a30: 6a 75 73 74 20 63 68 65 63 6b 20 74 68 65 20 45  just check the E
1a40: 54 61 67 20 61 67 61 69 6e 73 74 20 61 6e 79 20  Tag against any 
1a50: 49 66 2d 4e 6f 6e 65 2d 4d 61 74 63 68 20 68 65  If-None-Match he
1a60: 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 46 49 58 4d  ader..**.** FIXM
1a70: 45 3a 20 49 6e 20 73 6f 6d 65 20 63 61 73 65 73  E: In some cases
1a80: 20 28 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 66   (attachments, f
1a90: 69 6c 65 20 63 6f 6e 74 65 6e 74 73 29 20 77 65  ile contents) we
1aa0: 20 63 6f 75 6c 64 20 63 68 65 63 6b 0a 2a 2a 20   could check.** 
1ab0: 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e 63  If-Modified-Sinc
1ac0: 65 20 68 65 61 64 65 72 73 20 61 6e 64 20 61 6c  e headers and al
1ad0: 77 61 79 73 20 69 6e 63 6c 75 64 65 20 4c 61 73  ways include Las
1ae0: 74 2d 4d 6f 64 69 66 69 65 64 20 69 6e 20 72 65  t-Modified in re
1af0: 73 70 6f 6e 73 65 73 2e 0a 2a 2f 0a 73 74 61 74  sponses..*/.stat
1b00: 69 63 20 69 6e 74 20 63 68 65 63 6b 5f 63 61 63  ic int check_cac
1b10: 68 65 5f 63 6f 6e 74 72 6f 6c 28 76 6f 69 64 29  he_control(void)
1b20: 7b 0a 20 20 2f 2a 20 46 49 58 4d 45 3a 20 74 68  {.  /* FIXME: th
1b30: 65 72 65 27 73 20 73 6f 6d 65 20 67 6f 74 63 68  ere's some gotch
1b40: 61 73 20 77 74 68 20 63 6f 6f 6b 69 65 73 20 61  as wth cookies a
1b50: 6e 64 20 73 6f 6d 65 20 68 65 61 64 65 72 73 2e  nd some headers.
1b60: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 54 61   */.  char *zETa
1b70: 67 20 3d 20 63 67 69 5f 61 64 64 5f 65 74 61 67  g = cgi_add_etag
1b80: 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67  (blob_buffer(&cg
1b90: 69 43 6f 6e 74 65 6e 74 29 2c 62 6c 6f 62 5f 73  iContent),blob_s
1ba0: 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 29  ize(&cgiContent)
1bb0: 29 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 61 74 63  );.  char *zMatc
1bc0: 68 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f 4e  h = P("HTTP_IF_N
1bd0: 4f 4e 45 5f 4d 41 54 43 48 22 29 3b 0a 0a 20 20  ONE_MATCH");..  
1be0: 69 66 28 20 7a 45 54 61 67 21 3d 30 20 26 26 20  if( zETag!=0 && 
1bf0: 7a 4d 61 74 63 68 21 3d 30 20 29 20 7b 0a 20 20  zMatch!=0 ) {.  
1c00: 20 20 63 68 61 72 20 2a 7a 42 75 66 20 3d 20 73    char *zBuf = s
1c10: 74 72 64 75 70 28 7a 4d 61 74 63 68 29 3b 0a 20  trdup(zMatch);. 
1c20: 20 20 20 69 66 28 20 7a 42 75 66 21 3d 30 20 29     if( zBuf!=0 )
1c30: 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 54  {.      char *zT
1c40: 6f 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 63 68  ok = 0;.      ch
1c50: 61 72 20 2a 7a 50 6f 73 3b 0a 20 20 20 20 20 20  ar *zPos;.      
1c60: 66 6f 72 28 20 7a 54 6f 6b 20 3d 20 73 74 72 74  for( zTok = strt
1c70: 6f 6b 5f 72 28 7a 42 75 66 2c 20 22 2c 5c 22 22  ok_r(zBuf, ",\""
1c80: 2c 26 7a 50 6f 73 29 3b 0a 20 20 20 20 20 20 20  ,&zPos);.       
1c90: 20 20 20 20 7a 54 6f 6b 20 26 26 20 73 74 72 63      zTok && strc
1ca0: 61 73 65 63 6d 70 28 7a 54 6f 6b 2c 7a 45 54 61  asecmp(zTok,zETa
1cb0: 67 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 7a  g);.           z
1cc0: 54 6f 6b 20 3d 20 20 73 74 72 74 6f 6b 5f 72 28  Tok =  strtok_r(
1cd0: 30 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 29  0, ",\"",&zPos))
1ce0: 7b 7d 0a 20 20 20 20 20 20 66 72 65 65 28 7a 42  {}.      free(zB
1cf0: 75 66 29 3b 0a 20 20 20 20 20 20 69 66 28 7a 54  uf);.      if(zT
1d00: 6f 6b 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20  ok) return 1;.  
1d10: 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72 65 74    }.  }.  .  ret
1d20: 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69 66 0a  urn 0;.}.#endif.
1d30: 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 6e 6f 72 6d  ./*.** Do a norm
1d40: 61 6c 20 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f  al HTTP reply.*/
1d50: 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 79 28  .void cgi_reply(
1d60: 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 74 6f 74  void){.  int tot
1d70: 61 6c 5f 73 69 7a 65 20 3d 20 30 3b 0a 20 20 69  al_size = 0;.  i
1d80: 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 3c  f( iReplyStatus<
1d90: 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c 79  =0 ){.    iReply
1da0: 53 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20 20  Status = 200;.  
1db0: 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d    zReplyStatus =
1dc0: 20 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66 20   "OK";.  }..#if 
1dd0: 30 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 74  0.  if( iReplySt
1de0: 61 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68 65  atus==200 && che
1df0: 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f 6c  ck_cache_control
1e00: 28 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63 68  () ) {.    /* ch
1e10: 61 6e 67 65 20 74 68 65 20 73 74 61 74 75 73 20  ange the status 
1e20: 74 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20 61  to "unchanged" a
1e30: 6e 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20 73  nd we can skip s
1e40: 65 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20 2a  ending the.    *
1e50: 2a 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e 73  * actual respons
1e60: 65 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73 6c  e body. Obviousl
1e70: 79 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68 69  y we only do thi
1e80: 73 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65 5f  s when we _have_
1e90: 20 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20 28   a.    ** body (
1ea0: 63 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20 2a  code 200)..    *
1eb0: 2f 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 74  /.    iReplyStat
1ec0: 75 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a 52  us = 304;.    zR
1ed0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e 6f  eplyStatus = "No
1ee0: 74 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20 7d  t Modified";.  }
1ef0: 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 66  .#endif..  if( f
1f00: 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b 0a  ullHttpReply ){.
1f10: 20 20 20 20 70 72 69 6e 74 66 28 22 48 54 54 50      printf("HTTP
1f20: 2f 31 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22 2c  /1.0 %d %s\r\n",
1f30: 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a   iReplyStatus, z
1f40: 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20  ReplyStatus);.  
1f50: 20 20 63 68 61 72 20 2a 20 7a 44 61 74 65 20 3d    char * zDate =
1f60: 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65   cgi_rfc822_date
1f70: 73 74 61 6d 70 28 74 69 6d 65 28 30 29 29 3b 0a  stamp(time(0));.
1f80: 20 20 20 20 70 72 69 6e 74 66 28 22 44 61 74 65      printf("Date
1f90: 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 44 61 74 65  : %s\r\n", zDate
1fa0: 20 29 3b 0a 20 20 20 20 69 66 28 20 7a 44 61 74   );.    if( zDat
1fb0: 65 5b 30 5d 20 29 20 66 72 65 65 28 20 7a 44 61  e[0] ) free( zDa
1fc0: 74 65 20 29 3b 0a 20 20 20 20 70 72 69 6e 74 66  te );.    printf
1fd0: 28 22 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c  ("Connection: cl
1fe0: 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20 20 7d 65 6c  ose\r\n");.  }el
1ff0: 73 65 7b 0a 20 20 20 20 70 72 69 6e 74 66 28 22  se{.    printf("
2000: 53 74 61 74 75 73 3a 20 25 64 20 25 73 5c 72 5c  Status: %d %s\r\
2010: 6e 22 2c 20 69 52 65 70 6c 79 53 74 61 74 75 73  n", iReplyStatus
2020: 2c 20 7a 52 65 70 6c 79 53 74 61 74 75 73 29 3b  , zReplyStatus);
2030: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 62 6c 6f 62  .  }..  if( blob
2040: 5f 73 69 7a 65 28 26 65 78 74 72 61 48 65 61 64  _size(&extraHead
2050: 65 72 29 3e 30 20 29 7b 0a 20 20 20 20 70 72 69  er)>0 ){.    pri
2060: 6e 74 66 28 22 25 73 22 2c 20 62 6c 6f 62 5f 62  ntf("%s", blob_b
2070: 75 66 66 65 72 28 26 65 78 74 72 61 48 65 61 64  uffer(&extraHead
2080: 65 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  er));.  }..  if(
2090: 20 67 2e 69 73 43 6f 6e 73 74 20 29 7b 0a 20 20   g.isConst ){.  
20a0: 20 20 2f 2a 20 63 6f 6e 73 74 61 6e 74 20 6d 65    /* constant me
20b0: 61 6e 73 20 74 68 61 74 20 74 68 65 20 69 6e 70  ans that the inp
20c0: 75 74 20 55 52 4c 20 77 69 6c 6c 20 5f 6e 65 76  ut URL will _nev
20d0: 65 72 5f 20 67 65 6e 65 72 61 74 65 20 61 6e 79  er_ generate any
20e0: 74 68 69 6e 67 0a 20 20 20 20 2a 2a 20 65 6c 73  thing.    ** els
20f0: 65 2e 20 49 6e 20 74 68 65 20 63 61 73 65 20 6f  e. In the case o
2100: 66 20 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 74  f attachments, t
2110: 68 65 20 63 6f 6e 74 65 6e 74 73 20 77 6f 6e 27  he contents won'
2120: 74 20 63 68 61 6e 67 65 20 62 65 63 61 75 73 65  t change because
2130: 0a 20 20 20 20 2a 2a 20 61 6e 20 61 74 74 65 6d  .    ** an attem
2140: 70 74 20 74 6f 20 63 68 61 6e 67 65 20 74 68 65  pt to change the
2150: 6d 20 67 65 6e 65 72 61 74 65 73 20 61 20 6e 65  m generates a ne
2160: 77 20 61 74 74 61 63 68 6d 65 6e 74 20 6e 75 6d  w attachment num
2170: 62 65 72 2e 20 49 6e 20 74 68 65 0a 20 20 20 20  ber. In the.    
2180: 2a 2a 20 63 61 73 65 20 6f 66 20 6d 6f 73 74 20  ** case of most 
2190: 2f 67 65 74 66 69 6c 65 20 63 61 6c 6c 73 20 66  /getfile calls f
21a0: 6f 72 20 73 70 65 63 69 66 69 63 20 76 65 72 73  or specific vers
21b0: 69 6f 6e 73 2c 20 74 68 65 20 6f 6e 6c 79 20 77  ions, the only w
21c0: 61 79 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f  ay the.    ** co
21d0: 6e 74 65 6e 74 20 63 68 61 6e 67 65 73 20 69 73  ntent changes is
21e0: 20 69 66 20 73 6f 6d 65 6f 6e 65 20 62 72 65 61   if someone brea
21f0: 6b 73 20 74 68 65 20 53 43 4d 2e 20 41 6e 64 20  ks the SCM. And 
2200: 69 66 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c  if that happens,
2210: 20 61 0a 20 20 20 20 2a 2a 20 73 74 61 6c 65 20   a.    ** stale 
2220: 63 61 63 68 65 20 69 73 20 74 68 65 20 6c 65 61  cache is the lea
2230: 73 74 20 6f 66 20 74 68 65 20 70 72 6f 62 6c 65  st of the proble
2240: 6d 2e 20 53 6f 20 77 65 20 70 72 6f 76 69 64 65  m. So we provide
2250: 20 61 6e 20 45 78 70 69 72 65 73 0a 20 20 20 20   an Expires.    
2260: 2a 2a 20 68 65 61 64 65 72 20 73 65 74 20 74 6f  ** header set to
2270: 20 61 20 72 65 61 73 6f 6e 61 62 6c 65 20 70 65   a reasonable pe
2280: 72 69 6f 64 20 28 64 65 66 61 75 6c 74 3a 20 6f  riod (default: o
2290: 6e 65 20 77 65 65 6b 29 2e 0a 20 20 20 20 2a 2f  ne week)..    */
22a0: 0a 20 20 20 20 2f 2a 74 69 6d 65 5f 74 20 65 78  .    /*time_t ex
22b0: 70 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20  pires = time(0) 
22c0: 2b 20 61 74 6f 69 28 64 62 5f 63 6f 6e 66 69 67  + atoi(db_config
22d0: 28 22 63 6f 6e 73 74 61 6e 74 5f 65 78 70 69 72  ("constant_expir
22e0: 65 73 22 2c 22 36 30 34 38 30 30 22 29 29 3b 2a  es","604800"));*
22f0: 2f 0a 20 20 20 20 74 69 6d 65 5f 74 20 65 78 70  /.    time_t exp
2300: 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 2b  ires = time(0) +
2310: 20 36 30 34 38 30 30 3b 0a 20 20 20 20 63 68 61   604800;.    cha
2320: 72 20 2a 20 7a 44 61 74 65 20 3d 20 63 67 69 5f  r * zDate = cgi_
2330: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70  rfc822_datestamp
2340: 28 65 78 70 69 72 65 73 29 3b 0a 20 20 20 20 70  (expires);.    p
2350: 72 69 6e 74 66 28 20 22 45 78 70 69 72 65 73 3a  rintf( "Expires:
2360: 20 25 73 5c 72 5c 6e 22 2c 20 7a 44 61 74 65 20   %s\r\n", zDate 
2370: 29 3b 0a 20 20 20 20 69 66 28 20 7a 44 61 74 65  );.    if( zDate
2380: 5b 30 5d 20 29 20 66 72 65 65 28 20 7a 44 61 74  [0] ) free( zDat
2390: 65 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43  e );.  }..  /* C
23a0: 6f 6e 74 65 6e 74 20 69 6e 74 65 6e 64 65 64 20  ontent intended 
23b0: 66 6f 72 20 6c 6f 67 67 65 64 20 69 6e 20 75 73  for logged in us
23c0: 65 72 73 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20  ers should only 
23d0: 62 65 20 63 61 63 68 65 64 20 69 6e 0a 20 20 2a  be cached in.  *
23e0: 2a 20 74 68 65 20 62 72 6f 77 73 65 72 2c 20 6e  * the browser, n
23f0: 6f 74 20 73 6f 6d 65 20 73 68 61 72 65 64 20 6c  ot some shared l
2400: 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20  ocation..  */.  
2410: 70 72 69 6e 74 66 28 22 43 61 63 68 65 2d 63 6f  printf("Cache-co
2420: 6e 74 72 6f 6c 3a 20 70 72 69 76 61 74 65 5c 72  ntrol: private\r
2430: 5c 6e 22 29 3b 0a 0a 23 69 66 20 46 4f 53 53 49  \n");..#if FOSSI
2440: 4c 5f 49 31 38 4e 0a 20 20 70 72 69 6e 74 66 28  L_I18N.  printf(
2450: 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20   "Content-Type: 
2460: 25 73 3b 20 63 68 61 72 73 65 74 3d 25 73 5c 72  %s; charset=%s\r
2470: 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79 70  \n", zContentTyp
2480: 65 2c 20 6e 6c 5f 6c 61 6e 67 69 6e 66 6f 28 43  e, nl_langinfo(C
2490: 4f 44 45 53 45 54 29 29 3b 0a 23 65 6c 73 65 0a  ODESET));.#else.
24a0: 20 20 70 72 69 6e 74 66 28 20 22 43 6f 6e 74 65    printf( "Conte
24b0: 6e 74 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61  nt-Type: %s; cha
24c0: 72 73 65 74 3d 49 53 4f 2d 38 38 35 39 2d 31 5c  rset=ISO-8859-1\
24d0: 72 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79  r\n", zContentTy
24e0: 70 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 69 66  pe);.#endif.  if
24f0: 28 20 73 74 72 63 6d 70 28 7a 43 6f 6e 74 65 6e  ( strcmp(zConten
2500: 74 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74 69  tType,"applicati
2510: 6f 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30  on/x-fossil")==0
2520: 20 29 7b 0a 20 20 20 20 63 67 69 5f 63 6f 6d 62   ){.    cgi_comb
2530: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62  ine_header_and_b
2540: 6f 64 79 28 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  ody();.    blob_
2550: 63 6f 6d 70 72 65 73 73 28 26 63 67 69 43 6f 6e  compress(&cgiCon
2560: 74 65 6e 74 5b 30 5d 2c 20 26 63 67 69 43 6f 6e  tent[0], &cgiCon
2570: 74 65 6e 74 5b 30 5d 29 3b 0a 20 20 7d 0a 0a 20  tent[0]);.  }.. 
2580: 20 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75   if( iReplyStatu
2590: 73 20 21 3d 20 33 30 34 20 29 20 7b 0a 20 20 20  s != 304 ) {.   
25a0: 20 74 6f 74 61 6c 5f 73 69 7a 65 20 3d 20 62 6c   total_size = bl
25b0: 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e 74  ob_size(&cgiCont
25c0: 65 6e 74 5b 30 5d 29 20 2b 20 62 6c 6f 62 5f 73  ent[0]) + blob_s
25d0: 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b  ize(&cgiContent[
25e0: 31 5d 29 3b 0a 20 20 20 20 70 72 69 6e 74 66 28  1]);.    printf(
25f0: 20 22 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68   "Content-Length
2600: 3a 20 25 64 5c 72 5c 6e 22 2c 20 74 6f 74 61 6c  : %d\r\n", total
2610: 5f 73 69 7a 65 29 3b 0a 20 20 7d 0a 20 20 70 72  _size);.  }.  pr
2620: 69 6e 74 66 28 22 5c 72 5c 6e 22 29 3b 0a 20 20  intf("\r\n");.  
2630: 69 66 28 20 74 6f 74 61 6c 5f 73 69 7a 65 3e 30  if( total_size>0
2640: 20 26 26 20 69 52 65 70 6c 79 53 74 61 74 75 73   && iReplyStatus
2650: 20 21 3d 20 33 30 34 20 29 7b 0a 20 20 20 20 69   != 304 ){.    i
2660: 6e 74 20 69 2c 20 73 69 7a 65 3b 0a 20 20 20 20  nt i, size;.    
2670: 66 6f 72 28 69 3d 30 3b 20 69 3c 32 3b 20 69 2b  for(i=0; i<2; i+
2680: 2b 29 7b 0a 20 20 20 20 20 20 73 69 7a 65 20 3d  +){.      size =
2690: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43   blob_size(&cgiC
26a0: 6f 6e 74 65 6e 74 5b 69 5d 29 3b 0a 20 20 20 20  ontent[i]);.    
26b0: 20 20 69 66 28 20 73 69 7a 65 3e 30 20 29 7b 0a    if( size>0 ){.
26c0: 20 20 20 20 20 20 20 20 66 77 72 69 74 65 28 62          fwrite(b
26d0: 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 69 43  lob_buffer(&cgiC
26e0: 6f 6e 74 65 6e 74 5b 69 5d 29 2c 20 31 2c 20 73  ontent[i]), 1, s
26f0: 69 7a 65 2c 20 73 74 64 6f 75 74 29 3b 0a 20 20  ize, stdout);.  
2700: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a      }.    }.  }.
2710: 20 20 43 47 49 44 45 42 55 47 28 28 22 44 4f 4e    CGIDEBUG(("DON
2720: 45 5c 6e 22 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  E\n"));.}../*.**
2730: 20 44 6f 20 61 20 72 65 64 69 72 65 63 74 20 72   Do a redirect r
2740: 65 71 75 65 73 74 20 74 6f 20 74 68 65 20 55 52  equest to the UR
2750: 4c 20 67 69 76 65 6e 20 69 6e 20 74 68 65 20 61  L given in the a
2760: 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54  rgument..**.** T
2770: 68 65 20 55 52 4c 20 6d 75 73 74 20 62 65 20 72  he URL must be r
2780: 65 6c 61 74 69 76 65 20 74 6f 20 74 68 65 20 62  elative to the b
2790: 61 73 65 20 6f 66 20 74 68 65 20 66 6f 73 73 69  ase of the fossi
27a0: 6c 20 73 65 72 76 65 72 2e 0a 2a 2f 0a 76 6f 69  l server..*/.voi
27b0: 64 20 63 67 69 5f 72 65 64 69 72 65 63 74 28 63  d cgi_redirect(c
27c0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 52 4c 29  onst char *zURL)
27d0: 7b 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 63 61 74  {.  char *zLocat
27e0: 69 6f 6e 3b 0a 20 20 43 47 49 44 45 42 55 47 28  ion;.  CGIDEBUG(
27f0: 28 22 72 65 64 69 72 65 63 74 20 74 6f 20 25 73  ("redirect to %s
2800: 5c 6e 22 2c 20 7a 55 52 4c 29 29 3b 0a 20 20 69  \n", zURL));.  i
2810: 66 28 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c  f( strncmp(zURL,
2820: 22 68 74 74 70 3a 22 2c 35 29 3d 3d 30 20 7c 7c  "http:",5)==0 ||
2830: 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22 68   strncmp(zURL,"h
2840: 74 74 70 73 3a 22 2c 36 29 3d 3d 30 20 7c 7c 20  ttps:",6)==0 || 
2850: 2a 7a 55 52 4c 3d 3d 27 2f 27 20 29 7b 0a 20 20  *zURL=='/' ){.  
2860: 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d 70    zLocation = mp
2870: 72 69 6e 74 66 28 22 4c 6f 63 61 74 69 6f 6e 3a  rintf("Location:
2880: 20 25 73 5c 72 5c 6e 22 2c 20 7a 55 52 4c 29 3b   %s\r\n", zURL);
2890: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 4c  .  }else{.    zL
28a0: 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 72 69 6e 74  ocation = mprint
28b0: 66 28 22 4c 6f 63 61 74 69 6f 6e 3a 20 25 73 2f  f("Location: %s/
28c0: 25 73 5c 72 5c 6e 22 2c 20 67 2e 7a 42 61 73 65  %s\r\n", g.zBase
28d0: 55 52 4c 2c 20 7a 55 52 4c 29 3b 0a 20 20 7d 0a  URL, zURL);.  }.
28e0: 20 20 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 61    cgi_append_hea
28f0: 64 65 72 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a  der(zLocation);.
2900: 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74    cgi_reset_cont
2910: 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f 70 72 69  ent();.  cgi_pri
2920: 6e 74 66 28 22 3c 68 74 6d 6c 3e 5c 6e 3c 70 3e  ntf("<html>\n<p>
2930: 52 65 64 69 72 65 63 74 20 74 6f 20 25 68 3c 2f  Redirect to %h</
2940: 70 3e 5c 6e 3c 2f 68 74 6d 6c 3e 5c 6e 22 2c 20  p>\n</html>\n", 
2950: 7a 55 52 4c 29 3b 0a 20 20 63 67 69 5f 73 65 74  zURL);.  cgi_set
2960: 5f 73 74 61 74 75 73 28 33 30 32 2c 20 22 4d 6f  _status(302, "Mo
2970: 76 65 64 20 54 65 6d 70 6f 72 61 72 69 6c 79 22  ved Temporarily"
2980: 29 3b 0a 20 20 66 72 65 65 28 7a 4c 6f 63 61 74  );.  free(zLocat
2990: 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c  ion);.  cgi_repl
29a0: 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a  y();.  exit(0);.
29b0: 7d 0a 76 6f 69 64 20 63 67 69 5f 72 65 64 69 72  }.void cgi_redir
29c0: 65 63 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20  ectf(const char 
29d0: 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a  *zFormat, ...){.
29e0: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20    va_list ap;.  
29f0: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f  va_start(ap, zFo
2a00: 72 6d 61 74 29 3b 0a 20 20 63 67 69 5f 72 65 64  rmat);.  cgi_red
2a10: 69 72 65 63 74 28 76 6d 70 72 69 6e 74 66 28 7a  irect(vmprintf(z
2a20: 46 6f 72 6d 61 74 2c 20 61 70 29 29 3b 0a 20 20  Format, ap));.  
2a30: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 2f  va_end(ap);.}../
2a40: 2a 0a 2a 2a 20 49 6e 66 6f 72 6d 61 74 69 6f 6e  *.** Information
2a50: 20 61 62 6f 75 74 20 61 6c 6c 20 71 75 65 72 79   about all query
2a60: 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e 64 20   parameters and 
2a70: 63 6f 6f 6b 69 65 73 20 61 72 65 20 73 74 6f 72  cookies are stor
2a80: 65 64 0a 2a 2a 20 69 6e 20 74 68 65 73 65 20 76  ed.** in these v
2a90: 61 72 69 61 62 6c 65 73 2e 0a 2a 2f 0a 73 74 61  ariables..*/.sta
2aa0: 74 69 63 20 69 6e 74 20 6e 41 6c 6c 6f 63 51 50  tic int nAllocQP
2ab0: 20 3d 20 30 3b 20 2f 2a 20 53 70 61 63 65 20 61   = 0; /* Space a
2ac0: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 50 61  llocated for aPa
2ad0: 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 69  ramQP[] */.stati
2ae0: 63 20 69 6e 74 20 6e 55 73 65 64 51 50 20 3d 20  c int nUsedQP = 
2af0: 30 3b 20 20 2f 2a 20 53 70 61 63 65 20 61 63 74  0;  /* Space act
2b00: 75 61 6c 6c 79 20 75 73 65 64 20 69 6e 20 61 50  ually used in aP
2b10: 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74  aramQP[] */.stat
2b20: 69 63 20 69 6e 74 20 73 6f 72 74 51 50 20 3d 20  ic int sortQP = 
2b30: 30 3b 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20  0;   /* True if 
2b40: 61 50 61 72 61 6d 51 50 5b 5d 20 6e 65 65 64 73  aParamQP[] needs
2b50: 20 73 6f 72 74 69 6e 67 20 2a 2f 0a 73 74 61 74   sorting */.stat
2b60: 69 63 20 69 6e 74 20 73 65 71 51 50 20 3d 20 30  ic int seqQP = 0
2b70: 3b 20 20 20 20 2f 2a 20 53 65 71 75 65 6e 63 65  ;    /* Sequence
2b80: 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 73 74 61 74   numbers */.stat
2b90: 69 63 20 73 74 72 75 63 74 20 51 50 61 72 61 6d  ic struct QParam
2ba0: 20 7b 20 20 20 2f 2a 20 4f 6e 65 20 65 6e 74 72   {   /* One entr
2bb0: 79 20 66 6f 72 20 65 61 63 68 20 71 75 65 72 79  y for each query
2bc0: 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f   parameter or co
2bd0: 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  okie */.  const 
2be0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20  char *zName;    
2bf0: 20 20 20 20 2f 2a 20 50 61 72 61 6d 65 74 65 72      /* Parameter
2c00: 20 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 20   or cookie name 
2c10: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
2c20: 2a 7a 56 61 6c 75 65 3b 20 20 20 20 20 20 20 2f  *zValue;       /
2c30: 2a 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20 71  * Value of the q
2c40: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f  uery parameter o
2c50: 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 69 6e  r cookie */.  in
2c60: 74 20 73 65 71 3b 20 20 20 20 20 20 20 20 20 20  t seq;          
2c70: 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 64 65 72          /* Order
2c80: 20 6f 66 20 69 6e 73 65 72 74 69 6f 6e 20 2a 2f   of insertion */
2c90: 0a 7d 20 2a 61 50 61 72 61 6d 51 50 3b 20 20 20  .} *aParamQP;   
2ca0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 6e 20            /* An 
2cb0: 61 72 72 61 79 20 6f 66 20 61 6c 6c 20 70 61 72  array of all par
2cc0: 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b  ameters and cook
2cd0: 69 65 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 64  ies */../*.** Ad
2ce0: 64 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79 20  d another query 
2cf0: 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f  parameter or coo
2d00: 6b 69 65 20 74 6f 20 74 68 65 20 70 61 72 61 6d  kie to the param
2d10: 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61  eter set..** zNa
2d20: 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f  me is the name o
2d30: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  f the query para
2d40: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20  meter or cookie 
2d50: 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73  and zValue.** is
2d60: 20 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f 64   its fully decod
2d70: 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20  ed value..**.** 
2d80: 7a 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c 75 65  zName and zValue
2d90: 20 61 72 65 20 6e 6f 74 20 63 6f 70 69 65 64 20   are not copied 
2da0: 61 6e 64 20 6d 75 73 74 20 6e 6f 74 20 63 68 61  and must not cha
2db0: 6e 67 65 20 6f 72 20 62 65 0a 2a 2a 20 64 65 61  nge or be.** dea
2dc0: 6c 6c 6f 63 61 74 65 64 20 61 66 74 65 72 20 74  llocated after t
2dd0: 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75  his routine retu
2de0: 72 6e 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69  rns..*/.void cgi
2df0: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e  _set_parameter_n
2e00: 6f 63 6f 70 79 28 63 6f 6e 73 74 20 63 68 61 72  ocopy(const char
2e10: 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63   *zName, const c
2e20: 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20  har *zValue){.  
2e30: 69 66 28 20 6e 41 6c 6c 6f 63 51 50 3c 3d 6e 55  if( nAllocQP<=nU
2e40: 73 65 64 51 50 20 29 7b 0a 20 20 20 20 6e 41 6c  sedQP ){.    nAl
2e50: 6c 6f 63 51 50 20 3d 20 6e 41 6c 6c 6f 63 51 50  locQP = nAllocQP
2e60: 2a 32 20 2b 20 31 30 3b 0a 20 20 20 20 61 50 61  *2 + 10;.    aPa
2e70: 72 61 6d 51 50 20 3d 20 72 65 61 6c 6c 6f 63 28  ramQP = realloc(
2e80: 20 61 50 61 72 61 6d 51 50 2c 20 6e 41 6c 6c 6f   aParamQP, nAllo
2e90: 63 51 50 2a 73 69 7a 65 6f 66 28 61 50 61 72 61  cQP*sizeof(aPara
2ea0: 6d 51 50 5b 30 5d 29 20 29 3b 0a 20 20 20 20 69  mQP[0]) );.    i
2eb0: 66 28 20 61 50 61 72 61 6d 51 50 3d 3d 30 20 29  f( aParamQP==0 )
2ec0: 20 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a 20 20   exit(1);.  }.  
2ed0: 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51 50  aParamQP[nUsedQP
2ee0: 5d 2e 7a 4e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b  ].zName = zName;
2ef0: 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65  .  aParamQP[nUse
2f00: 64 51 50 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56  dQP].zValue = zV
2f10: 61 6c 75 65 3b 0a 20 20 61 50 61 72 61 6d 51 50  alue;.  aParamQP
2f20: 5b 6e 55 73 65 64 51 50 5d 2e 73 65 71 20 3d 20  [nUsedQP].seq = 
2f30: 73 65 71 51 50 2b 2b 3b 0a 20 20 6e 55 73 65 64  seqQP++;.  nUsed
2f40: 51 50 2b 2b 3b 0a 20 20 73 6f 72 74 51 50 20 3d  QP++;.  sortQP =
2f50: 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64   1;.}../*.** Add
2f60: 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79 20 70   another query p
2f70: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b  arameter or cook
2f80: 69 65 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65  ie to the parame
2f90: 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d  ter set..** zNam
2fa0: 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66  e is the name of
2fb0: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   the query param
2fc0: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61  eter or cookie a
2fd0: 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20  nd zValue.** is 
2fe0: 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f 64 65  its fully decode
2ff0: 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 43  d value..**.** C
3000: 6f 70 69 65 73 20 61 72 65 20 6d 61 64 65 20 6f  opies are made o
3010: 66 20 62 6f 74 68 20 74 68 65 20 7a 4e 61 6d 65  f both the zName
3020: 20 61 6e 64 20 7a 56 61 6c 75 65 20 70 61 72 61   and zValue para
3030: 6d 65 74 65 72 73 2e 0a 2a 2f 0a 76 6f 69 64 20  meters..*/.void 
3040: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65  cgi_set_paramete
3050: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  r(const char *zN
3060: 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ame, const char 
3070: 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f  *zValue){.  cgi_
3080: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
3090: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73  copy(mprintf("%s
30a0: 22 2c 7a 4e 61 6d 65 29 2c 20 6d 70 72 69 6e 74  ",zName), mprint
30b0: 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b  f("%s",zValue));
30c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 70 6c 61 63  .}../*.** Replac
30d0: 65 20 61 20 70 61 72 61 6d 65 74 65 72 20 77 69  e a parameter wi
30e0: 74 68 20 61 20 6e 65 77 20 76 61 6c 75 65 2e 0a  th a new value..
30f0: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c  */.void cgi_repl
3100: 61 63 65 5f 70 61 72 61 6d 65 74 65 72 28 63 6f  ace_parameter(co
3110: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c  nst char *zName,
3120: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61   const char *zVa
3130: 6c 75 65 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  lue){.  int i;. 
3140: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 55 73 65   for(i=0; i<nUse
3150: 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69  dQP; i++){.    i
3160: 66 28 20 73 74 72 63 6d 70 28 61 50 61 72 61 6d  f( strcmp(aParam
3170: 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 7a 4e 61 6d  QP[i].zName,zNam
3180: 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61  e)==0 ){.      a
3190: 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 56 61 6c 75  ParamQP[i].zValu
31a0: 65 20 3d 20 7a 56 61 6c 75 65 3b 0a 20 20 20 20  e = zValue;.    
31b0: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  }.  }.}../*.** A
31c0: 64 64 20 61 20 71 75 65 72 79 20 70 61 72 61 6d  dd a query param
31d0: 65 74 65 72 2e 20 20 54 68 65 20 7a 4e 61 6d 65  eter.  The zName
31e0: 20 70 6f 72 74 69 6f 6e 20 69 73 20 66 69 78 65   portion is fixe
31f0: 64 20 62 75 74 20 61 20 63 6f 70 79 0a 2a 2a 20  d but a copy.** 
3200: 6d 75 73 74 20 62 65 20 6d 61 64 65 20 6f 66 20  must be made of 
3210: 7a 56 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20  zValue..*/.void 
3220: 63 67 69 5f 73 65 74 65 6e 76 28 63 6f 6e 73 74  cgi_setenv(const
3230: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f   char *zName, co
3240: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65  nst char *zValue
3250: 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 72  ){.  cgi_set_par
3260: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e  ameter_nocopy(zN
3270: 61 6d 65 2c 20 6d 70 72 69 6e 74 66 28 22 25 73  ame, mprintf("%s
3280: 22 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a 20 0a  ",zValue));.}. .
3290: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 6c 69 73  ./*.** Add a lis
32a0: 74 20 6f 66 20 71 75 65 72 79 20 70 61 72 61 6d  t of query param
32b0: 65 74 65 72 73 20 6f 72 20 63 6f 6f 6b 69 65 73  eters or cookies
32c0: 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65   to the paramete
32d0: 72 20 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 45 61 63  r set..**.** Eac
32e0: 68 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 6f  h parameter is o
32f0: 66 20 74 68 65 20 66 6f 72 6d 20 4e 41 4d 45 3d  f the form NAME=
3300: 56 41 4c 55 45 2e 20 20 42 6f 74 68 20 74 68 65  VALUE.  Both the
3310: 20 4e 41 4d 45 20 61 6e 64 20 74 68 65 0a 2a 2a   NAME and the.**
3320: 20 56 41 4c 55 45 20 6d 61 79 20 62 65 20 75 72   VALUE may be ur
3330: 6c 2d 65 6e 63 6f 64 65 64 20 28 22 2b 22 20 66  l-encoded ("+" f
3340: 6f 72 20 73 70 61 63 65 2c 20 22 25 48 48 22 20  or space, "%HH" 
3350: 66 6f 72 20 6f 74 68 65 72 20 73 70 65 63 69 61  for other specia
3360: 6c 0a 2a 2a 20 63 68 61 72 61 63 74 65 72 73 29  l.** characters)
3370: 2e 20 20 42 75 74 20 74 68 69 73 20 72 6f 75 74  .  But this rout
3380: 69 6e 65 20 61 73 73 75 6d 65 73 20 74 68 61 74  ine assumes that
3390: 20 4e 41 4d 45 20 63 6f 6e 74 61 69 6e 73 20 6e   NAME contains n
33a0: 6f 0a 2a 2a 20 73 70 65 63 69 61 6c 20 63 68 61  o.** special cha
33b0: 72 61 63 74 65 72 20 61 6e 64 20 74 68 65 72 65  racter and there
33c0: 66 6f 72 65 20 64 6f 65 73 20 6e 6f 74 20 64 65  fore does not de
33d0: 63 6f 64 65 20 69 74 2e 0a 2a 2a 0a 2a 2a 20 49  code it..**.** I
33e0: 66 20 4e 41 4d 45 20 62 65 67 69 6e 73 20 77 69  f NAME begins wi
33f0: 74 68 20 61 6e 6f 74 68 65 72 20 6f 74 68 65 72  th another other
3400: 20 74 68 61 6e 20 61 20 6c 6f 77 65 72 2d 63 61   than a lower-ca
3410: 73 65 20 6c 65 74 74 65 72 20 74 68 65 6e 0a 2a  se letter then.*
3420: 2a 20 74 68 65 20 65 6e 74 69 72 65 20 4e 41 4d  * the entire NAM
3430: 45 3d 56 41 4c 55 45 20 74 65 72 6d 20 69 73 20  E=VALUE term is 
3440: 69 67 6e 6f 72 65 64 2e 20 20 48 65 6e 63 65 3a  ignored.  Hence:
3450: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a 20 20 63  .**.**      *  c
3460: 6f 6f 6b 69 65 73 20 61 6e 64 20 71 75 65 72 79  ookies and query
3470: 20 70 61 72 61 6d 65 74 65 72 73 20 74 68 61 74   parameters that
3480: 20 68 61 76 65 20 75 70 70 65 72 63 61 73 65 20   have uppercase 
3490: 6e 61 6d 65 73 0a 2a 2a 20 20 20 20 20 20 20 20  names.**        
34a0: 20 61 72 65 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a   are ignored..**
34b0: 0a 2a 2a 20 20 20 20 20 20 2a 20 20 69 74 20 69  .**      *  it i
34c0: 73 20 69 6d 70 6f 73 73 69 62 6c 65 20 66 6f 72  s impossible for
34d0: 20 61 20 63 6f 6f 6b 69 65 20 6f 72 20 71 75 65   a cookie or que
34e0: 72 79 20 70 61 72 61 6d 65 74 65 72 20 74 6f 0a  ry parameter to.
34f0: 2a 2a 20 20 20 20 20 20 20 20 20 6f 76 65 72 72  **         overr
3500: 69 64 65 20 74 68 65 20 76 61 6c 75 65 20 6f 66  ide the value of
3510: 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20   an environment 
3520: 76 61 72 69 61 62 6c 65 20 73 69 6e 63 65 0a 2a  variable since.*
3530: 2a 20 20 20 20 20 20 20 20 20 65 6e 76 69 72 6f  *         enviro
3540: 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 73 20  nment variables 
3550: 61 6c 77 61 79 73 20 68 61 76 65 20 75 70 70 65  always have uppe
3560: 72 63 61 73 65 20 6e 61 6d 65 73 2e 0a 2a 2a 0a  rcase names..**.
3570: 2a 2a 20 50 61 72 61 6d 65 74 65 72 73 20 61 72  ** Parameters ar
3580: 65 20 73 65 70 61 72 61 74 65 64 20 62 79 20 74  e separated by t
3590: 68 65 20 22 74 65 72 6d 69 6e 61 74 6f 72 22 20  he "terminator" 
35a0: 63 68 61 72 61 63 74 65 72 2e 20 20 57 68 69 74  character.  Whit
35b0: 65 73 70 61 63 65 0a 2a 2a 20 62 65 66 6f 72 65  espace.** before
35c0: 20 74 68 65 20 4e 41 4d 45 20 69 73 20 69 67 6e   the NAME is ign
35d0: 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  ored..**.** The 
35e0: 69 6e 70 75 74 20 73 74 72 69 6e 67 20 22 7a 22  input string "z"
35f0: 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62 75 74   is modified but
3600: 20 6e 6f 20 63 6f 70 69 65 73 20 69 73 20 6d 61   no copies is ma
3610: 64 65 2e 20 20 22 7a 22 0a 2a 2a 20 73 68 6f 75  de.  "z".** shou
3620: 6c 64 20 6e 6f 74 20 62 65 20 64 65 61 6c 6c 6f  ld not be deallo
3630: 63 61 74 65 64 20 6f 72 20 63 68 61 6e 67 65 64  cated or changed
3640: 20 61 67 61 69 6e 20 61 66 74 65 72 20 74 68 69   again after thi
3650: 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74  s routine.** ret
3660: 75 72 6e 73 20 6f 72 20 69 74 20 77 69 6c 6c 20  urns or it will 
3670: 63 6f 72 72 75 70 74 20 74 68 65 20 70 61 72 61  corrupt the para
3680: 6d 65 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2f 0a  meter table..*/.
3690: 73 74 61 74 69 63 20 76 6f 69 64 20 61 64 64 5f  static void add_
36a0: 70 61 72 61 6d 5f 6c 69 73 74 28 63 68 61 72 20  param_list(char 
36b0: 2a 7a 2c 20 69 6e 74 20 74 65 72 6d 69 6e 61 74  *z, int terminat
36c0: 6f 72 29 7b 0a 20 20 77 68 69 6c 65 28 20 2a 7a  or){.  while( *z
36d0: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e   ){.    char *zN
36e0: 61 6d 65 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a  ame;.    char *z
36f0: 56 61 6c 75 65 3b 0a 20 20 20 20 77 68 69 6c 65  Value;.    while
3700: 28 20 69 73 73 70 61 63 65 28 2a 7a 29 20 29 7b  ( isspace(*z) ){
3710: 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 7a 4e 61 6d   z++; }.    zNam
3720: 65 20 3d 20 7a 3b 0a 20 20 20 20 77 68 69 6c 65  e = z;.    while
3730: 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 3d 27 20  ( *z && *z!='=' 
3740: 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 74 6f  && *z!=terminato
3750: 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20  r ){ z++; }.    
3760: 69 66 28 20 2a 7a 3d 3d 27 3d 27 20 29 7b 0a 20  if( *z=='=' ){. 
3770: 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20       *z = 0;.   
3780: 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7a 56     z++;.      zV
3790: 61 6c 75 65 20 3d 20 7a 3b 0a 20 20 20 20 20 20  alue = z;.      
37a0: 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21  while( *z && *z!
37b0: 3d 74 65 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a  =terminator ){ z
37c0: 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 28 20  ++; }.      if( 
37d0: 2a 7a 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a  *z ){.        *z
37e0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b   = 0;.        z+
37f0: 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  +;.      }.     
3800: 20 64 65 68 74 74 70 69 7a 65 28 7a 56 61 6c 75   dehttpize(zValu
3810: 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  e);.    }else{. 
3820: 20 20 20 20 20 69 66 28 20 2a 7a 20 29 7b 20 2a       if( *z ){ *
3830: 7a 2b 2b 20 3d 20 30 3b 20 7d 0a 20 20 20 20 20  z++ = 0; }.     
3840: 20 7a 56 61 6c 75 65 20 3d 20 22 22 3b 0a 20 20   zValue = "";.  
3850: 20 20 7d 0a 20 20 20 20 69 66 28 20 69 73 6c 6f    }.    if( islo
3860: 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b  wer(zName[0]) ){
3870: 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70  .      cgi_set_p
3880: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28  arameter_nocopy(
3890: 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a  zName, zValue);.
38a0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a      }.  }.}../*.
38b0: 2a 2a 20 2a 70 7a 20 69 73 20 61 20 73 74 72 69  ** *pz is a stri
38c0: 6e 67 20 74 68 61 74 20 63 6f 6e 73 69 73 74 73  ng that consists
38d0: 20 6f 66 20 6d 75 6c 74 69 70 6c 65 20 6c 69 6e   of multiple lin
38e0: 65 73 20 6f 66 20 74 65 78 74 2e 20 20 54 68 69  es of text.  Thi
38f0: 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 66 69 6e  s.** routine fin
3900: 64 73 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68  ds the end of th
3910: 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65 20 6f  e current line o
3920: 66 20 74 65 78 74 20 61 6e 64 20 63 6f 6e 76 65  f text and conve
3930: 72 74 73 0a 2a 2a 20 74 68 65 20 22 5c 6e 22 20  rts.** the "\n" 
3940: 6f 72 20 22 5c 72 5c 6e 22 20 74 68 61 74 20 65  or "\r\n" that e
3950: 6e 64 73 20 74 68 61 74 20 6c 69 6e 65 20 69 6e  nds that line in
3960: 74 6f 20 61 20 22 5c 30 30 30 22 2e 20 20 49 74  to a "\000".  It
3970: 20 74 68 65 6e 0a 2a 2a 20 61 64 76 61 6e 63 65   then.** advance
3980: 73 20 2a 70 7a 20 74 6f 20 74 68 65 20 62 65 67  s *pz to the beg
3990: 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20 6e 65  inning of the ne
39a0: 78 74 20 6c 69 6e 65 20 61 6e 64 20 72 65 74 75  xt line and retu
39b0: 72 6e 73 20 74 68 65 0a 2a 2a 20 70 72 65 76 69  rns the.** previ
39c0: 6f 75 73 20 76 61 6c 75 65 20 6f 66 20 2a 70 7a  ous value of *pz
39d0: 20 28 77 68 69 63 68 20 69 73 20 74 68 65 20 73   (which is the s
39e0: 74 61 72 74 20 6f 66 20 74 68 65 20 63 75 72 72  tart of the curr
39f0: 65 6e 74 20 6c 69 6e 65 2e 29 0a 2a 2f 0a 73 74  ent line.).*/.st
3a00: 61 74 69 63 20 63 68 61 72 20 2a 67 65 74 5f 6c  atic char *get_l
3a10: 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28  ine_from_string(
3a20: 63 68 61 72 20 2a 2a 70 7a 2c 20 69 6e 74 20 2a  char **pz, int *
3a30: 70 4c 65 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a  pLen){.  char *z
3a40: 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e 74 20 69 3b   = *pz;.  int i;
3a50: 0a 20 20 69 66 28 20 7a 5b 30 5d 3d 3d 30 20 29  .  if( z[0]==0 )
3a60: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 66 6f 72   return 0;.  for
3a70: 28 69 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29  (i=0; z[i]; i++)
3a80: 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d  {.    if( z[i]==
3a90: 27 5c 6e 27 20 29 7b 0a 20 20 20 20 20 20 69 66  '\n' ){.      if
3aa0: 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d  ( i>0 && z[i-1]=
3ab0: 3d 27 5c 72 27 20 29 7b 0a 20 20 20 20 20 20 20  ='\r' ){.       
3ac0: 20 7a 5b 69 2d 31 5d 20 3d 20 30 3b 0a 20 20 20   z[i-1] = 0;.   
3ad0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3ae0: 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20    z[i] = 0;.    
3af0: 20 20 7d 0a 20 20 20 20 20 20 69 2b 2b 3b 0a 20    }.      i++;. 
3b00: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
3b10: 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a  }.  }.  *pz = &z
3b20: 5b 69 5d 3b 0a 20 20 2a 70 4c 65 6e 20 2d 3d 20  [i];.  *pLen -= 
3b30: 69 3b 0a 20 20 72 65 74 75 72 6e 20 7a 3b 0a 7d  i;.  return z;.}
3b40: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75  ../*.** The inpu
3b50: 74 20 2a 70 7a 20 70 6f 69 6e 74 73 20 74 6f 20  t *pz points to 
3b60: 63 6f 6e 74 65 6e 74 20 74 68 61 74 20 69 73 20  content that is 
3b70: 74 65 72 6d 69 6e 61 74 65 64 20 62 79 20 61 20  terminated by a 
3b80: 22 5c 72 5c 6e 22 0a 2a 2a 20 66 6f 6c 6c 6f 77  "\r\n".** follow
3b90: 65 64 20 62 79 20 74 68 65 20 62 6f 75 6e 64 72  ed by the boundr
3ba0: 79 20 6d 61 72 6b 65 72 20 7a 42 6f 75 6e 64 72  y marker zBoundr
3bb0: 79 2e 20 20 41 6e 20 65 78 74 72 61 20 22 2d 2d  y.  An extra "--
3bc0: 22 20 6d 61 79 20 6f 72 0a 2a 2a 20 6d 61 79 20  " may or.** may 
3bd0: 6e 6f 74 20 62 65 20 61 70 70 65 6e 64 65 64 20  not be appended 
3be0: 74 6f 20 74 68 65 20 62 6f 75 6e 64 72 79 20 6d  to the boundry m
3bf0: 61 72 6b 65 72 2e 20 20 54 68 65 72 65 20 61 72  arker.  There ar
3c00: 65 20 2a 70 4c 65 6e 20 63 68 61 72 61 63 74 65  e *pLen characte
3c10: 72 73 0a 2a 2a 20 69 6e 20 2a 70 7a 2e 0a 2a 2a  rs.** in *pz..**
3c20: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
3c30: 20 61 64 64 73 20 61 20 22 5c 30 30 30 22 20 74   adds a "\000" t
3c40: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65  o the end of the
3c50: 20 63 6f 6e 74 65 6e 74 20 28 6f 76 65 72 77 72   content (overwr
3c60: 69 74 69 6e 67 0a 2a 2a 20 74 68 65 20 22 5c 72  iting.** the "\r
3c70: 5c 6e 22 29 20 61 6e 64 20 72 65 74 75 72 6e 73  \n") and returns
3c80: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68   a pointer to th
3c90: 65 20 63 6f 6e 74 65 6e 74 2e 20 20 54 68 65 20  e content.  The 
3ca0: 2a 70 7a 20 69 6e 70 75 74 0a 2a 2a 20 69 73 20  *pz input.** is 
3cb0: 61 64 6a 75 73 74 65 64 20 74 6f 20 70 6f 69 6e  adjusted to poin
3cc0: 74 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 6c  t to the first l
3cd0: 69 6e 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68  ine following th
3ce0: 65 20 62 6f 75 6e 64 72 79 2e 0a 2a 2a 20 54 68  e boundry..** Th
3cf0: 65 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20  e length of the 
3d00: 63 6f 6e 74 65 6e 74 20 69 73 20 73 74 6f 72 65  content is store
3d10: 64 20 69 6e 20 2a 70 6e 43 6f 6e 74 65 6e 74 2e  d in *pnContent.
3d20: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20  .*/.static char 
3d30: 2a 67 65 74 5f 62 6f 75 6e 64 65 64 5f 63 6f 6e  *get_bounded_con
3d40: 74 65 6e 74 28 0a 20 20 63 68 61 72 20 2a 2a 70  tent(.  char **p
3d50: 7a 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f  z,         /* Co
3d60: 6e 74 65 6e 74 20 74 61 6b 65 6e 20 66 72 6f 6d  ntent taken from
3d70: 20 68 65 72 65 20 2a 2f 0a 20 20 69 6e 74 20 2a   here */.  int *
3d80: 70 4c 65 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a  pLen,         /*
3d90: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73   Number of bytes
3da0: 20 6f 66 20 64 61 74 61 20 69 6e 20 28 2a 70 7a   of data in (*pz
3db0: 29 5b 5d 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a  )[] */.  char *z
3dc0: 42 6f 75 6e 64 72 79 2c 20 20 20 20 2f 2a 20 42  Boundry,    /* B
3dd0: 6f 75 6e 64 72 79 20 74 65 78 74 20 6d 61 72 6b  oundry text mark
3de0: 69 6e 67 20 74 68 65 20 65 6e 64 20 6f 66 20 63  ing the end of c
3df0: 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20  ontent */.  int 
3e00: 2a 70 6e 43 6f 6e 74 65 6e 74 20 20 20 20 20 2f  *pnContent     /
3e10: 2a 20 57 72 69 74 65 20 74 68 65 20 73 69 7a 65  * Write the size
3e20: 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20   of the content 
3e30: 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 63 68 61  here */.){.  cha
3e40: 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e  r *z = *pz;.  in
3e50: 74 20 6c 65 6e 20 3d 20 2a 70 4c 65 6e 3b 0a 20  t len = *pLen;. 
3e60: 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 6e 42   int i;.  int nB
3e70: 6f 75 6e 64 72 79 20 3d 20 73 74 72 6c 65 6e 28  oundry = strlen(
3e80: 7a 42 6f 75 6e 64 72 79 29 3b 0a 20 20 2a 70 6e  zBoundry);.  *pn
3e90: 43 6f 6e 74 65 6e 74 20 3d 20 6c 65 6e 3b 0a 20  Content = len;. 
3ea0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6c 65 6e 3b   for(i=0; i<len;
3eb0: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a   i++){.    if( z
3ec0: 5b 69 5d 3d 3d 27 5c 6e 27 20 26 26 20 73 74 72  [i]=='\n' && str
3ed0: 6e 63 6d 70 28 7a 42 6f 75 6e 64 72 79 2c 20 26  ncmp(zBoundry, &
3ee0: 7a 5b 69 2b 31 5d 2c 20 6e 42 6f 75 6e 64 72 79  z[i+1], nBoundry
3ef0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66  )==0 ){.      if
3f00: 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d  ( i>0 && z[i-1]=
3f10: 3d 27 5c 72 27 20 29 20 69 2d 2d 3b 0a 20 20 20  ='\r' ) i--;.   
3f20: 20 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20 20     z[i] = 0;.   
3f30: 20 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d 20     *pnContent = 
3f40: 69 3b 0a 20 20 20 20 20 20 69 20 2b 3d 20 6e 42  i;.      i += nB
3f50: 6f 75 6e 64 72 79 3b 0a 20 20 20 20 20 20 62 72  oundry;.      br
3f60: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  eak;.    }.  }. 
3f70: 20 2a 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20   *pz = &z[i];.  
3f80: 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74  get_line_from_st
3f90: 72 69 6e 67 28 70 7a 2c 20 70 4c 65 6e 29 3b 0a  ring(pz, pLen);.
3fa0: 20 20 72 65 74 75 72 6e 20 7a 3b 20 20 20 20 20    return z;     
3fb0: 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e   .}../*.** Token
3fc0: 69 7a 65 20 61 20 6c 69 6e 65 20 6f 66 20 74 65  ize a line of te
3fd0: 78 74 20 69 6e 74 6f 20 61 73 20 6d 61 6e 79 20  xt into as many 
3fe0: 61 73 20 6e 41 72 67 20 74 6f 6b 65 6e 73 2e 20  as nArg tokens. 
3ff0: 20 4d 61 6b 65 0a 2a 2a 20 61 7a 41 72 67 5b 5d   Make.** azArg[]
4000: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74   point to the st
4010: 61 72 74 20 6f 66 20 65 61 63 68 20 74 6f 6b 65  art of each toke
4020: 6e 2e 0a 2a 2a 0a 2a 2a 20 54 6f 6b 65 6e 73 20  n..**.** Tokens 
4030: 63 6f 6e 73 69 73 74 20 6f 66 20 73 70 61 63 65  consist of space
4040: 20 6f 72 20 73 65 6d 69 2d 63 6f 6c 6f 6e 20 64   or semi-colon d
4050: 65 6c 69 6d 69 74 65 64 20 77 6f 72 64 73 20 6f  elimited words o
4060: 72 0a 2a 2a 20 73 74 72 69 6e 67 73 20 69 6e 73  r.** strings ins
4070: 69 64 65 20 64 6f 75 62 6c 65 2d 71 75 6f 74 65  ide double-quote
4080: 73 2e 20 20 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a  s.  Example:.**.
4090: 2a 2a 20 20 20 20 63 6f 6e 74 65 6e 74 2d 64 69  **    content-di
40a0: 73 70 6f 73 69 74 69 6f 6e 3a 20 66 6f 72 6d 2d  sposition: form-
40b0: 64 61 74 61 3b 20 6e 61 6d 65 3d 22 66 6e 22 3b  data; name="fn";
40c0: 20 66 69 6c 65 6e 61 6d 65 3d 22 69 6e 64 65 78   filename="index
40d0: 2e 68 74 6d 6c 22 0a 2a 2a 0a 2a 2a 20 54 68 65  .html".**.** The
40e0: 20 6c 69 6e 65 20 61 62 6f 76 65 20 69 73 20 74   line above is t
40f0: 6f 6b 65 6e 69 7a 65 64 20 61 73 20 66 6f 6c 6c  okenized as foll
4100: 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 61 7a  ows:.**.**    az
4110: 41 72 67 5b 30 5d 20 3d 20 22 63 6f 6e 74 65 6e  Arg[0] = "conten
4120: 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22 0a  t-disposition:".
4130: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 31 5d 20 3d  **    azArg[1] =
4140: 20 22 66 6f 72 6d 2d 64 61 74 61 22 0a 2a 2a 20   "form-data".** 
4150: 20 20 20 61 7a 41 72 67 5b 32 5d 20 3d 20 22 6e     azArg[2] = "n
4160: 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61 7a 41 72  ame=".**    azAr
4170: 67 5b 33 5d 20 3d 20 22 66 6e 22 0a 2a 2a 20 20  g[3] = "fn".**  
4180: 20 20 61 7a 41 72 67 5b 34 5d 20 3d 20 22 66 69    azArg[4] = "fi
4190: 6c 65 6e 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61  lename=".**    a
41a0: 7a 41 72 67 5b 35 5d 20 3d 20 22 69 6e 64 65 78  zArg[5] = "index
41b0: 2e 68 74 6d 6c 22 0a 2a 2a 20 20 20 20 61 7a 41  .html".**    azA
41c0: 72 67 5b 36 5d 20 3d 20 30 3b 0a 2a 2a 0a 2a 2a  rg[6] = 0;.**.**
41d0: 20 27 5c 30 30 30 27 20 63 68 61 72 61 63 74 65   '\000' characte
41e0: 72 73 20 61 72 65 20 69 6e 73 65 72 74 65 64 20  rs are inserted 
41f0: 69 6e 20 7a 5b 5d 20 61 74 20 74 68 65 20 65 6e  in z[] at the en
4200: 64 20 6f 66 20 65 61 63 68 20 74 6f 6b 65 6e 2e  d of each token.
4210: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
4220: 20 72 65 74 75 72 6e 73 20 74 68 65 20 74 6f 74   returns the tot
4230: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b  al number of tok
4240: 65 6e 73 20 6f 6e 20 74 68 65 20 6c 69 6e 65 2c  ens on the line,
4250: 20 36 0a 2a 2a 20 69 6e 20 74 68 65 20 65 78 61   6.** in the exa
4260: 6d 70 6c 65 20 61 62 6f 76 65 2e 0a 2a 2f 0a 73  mple above..*/.s
4270: 74 61 74 69 63 20 69 6e 74 20 74 6f 6b 65 6e 69  tatic int tokeni
4280: 7a 65 5f 6c 69 6e 65 28 63 68 61 72 20 2a 7a 2c  ze_line(char *z,
4290: 20 69 6e 74 20 6d 78 41 72 67 2c 20 63 68 61 72   int mxArg, char
42a0: 20 2a 2a 61 7a 41 72 67 29 7b 0a 20 20 69 6e 74   **azArg){.  int
42b0: 20 69 20 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28   i = 0;.  while(
42c0: 20 2a 7a 20 29 7b 0a 20 20 20 20 77 68 69 6c 65   *z ){.    while
42d0: 28 20 69 73 73 70 61 63 65 28 2a 7a 29 20 7c 7c  ( isspace(*z) ||
42e0: 20 2a 7a 3d 3d 27 3b 27 20 29 7b 20 7a 2b 2b 3b   *z==';' ){ z++;
42f0: 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27   }.    if( *z=='
4300: 22 27 20 26 26 20 7a 5b 31 5d 20 29 7b 0a 20 20  "' && z[1] ){.  
4310: 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20      *z = 0;.    
4320: 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28    z++;.      if(
4330: 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b 20 61 7a   i<mxArg-1 ){ az
4340: 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a  Arg[i++] = z; }.
4350: 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20        while( *z 
4360: 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b  && *z!='"' ){ z+
4370: 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a  +; }.      if( *
4380: 7a 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  z==0 ) break;.  
4390: 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20      *z = 0;.    
43a0: 20 20 7a 2b 2b 3b 0a 20 20 20 20 7d 65 6c 73 65    z++;.    }else
43b0: 7b 0a 20 20 20 20 20 20 69 66 28 20 69 3c 6d 78  {.      if( i<mx
43c0: 41 72 67 2d 31 20 29 7b 20 61 7a 41 72 67 5b 69  Arg-1 ){ azArg[i
43d0: 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a 20 20 20 20 20  ++] = z; }.     
43e0: 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 21 69   while( *z && !i
43f0: 73 73 70 61 63 65 28 2a 7a 29 20 26 26 20 2a 7a  sspace(*z) && *z
4400: 21 3d 27 3b 27 20 26 26 20 2a 7a 21 3d 27 22 27  !=';' && *z!='"'
4410: 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20   ){ z++; }.     
4420: 20 69 66 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27   if( *z && *z!='
4430: 22 27 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a  "' ){.        *z
4440: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b   = 0;.        z+
4450: 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  +;.      }.    }
4460: 0a 20 20 7d 0a 20 20 61 7a 41 72 67 5b 69 5d 20  .  }.  azArg[i] 
4470: 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 69 3b  = 0;.  return i;
4480: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 63 61 6e 20 74  .}../*.** Scan t
4490: 68 65 20 6d 75 6c 74 69 70 61 72 74 2d 66 6f 72  he multipart-for
44a0: 6d 20 63 6f 6e 74 65 6e 74 20 61 6e 64 20 6d 61  m content and ma
44b0: 6b 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 65  ke appropriate e
44c0: 6e 74 72 69 65 73 0a 2a 2a 20 69 6e 74 6f 20 74  ntries.** into t
44d0: 68 65 20 70 61 72 61 6d 65 74 65 72 20 74 61 62  he parameter tab
44e0: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f  le..**.** The co
44f0: 6e 74 65 6e 74 20 73 74 72 69 6e 67 20 22 7a 22  ntent string "z"
4500: 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62 79 20   is modified by 
4510: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 62 75 74  this routine but
4520: 20 69 74 20 69 73 0a 2a 2a 20 6e 6f 74 20 63 6f   it is.** not co
4530: 70 69 65 64 2e 20 20 54 68 65 20 63 61 6c 6c 69  pied.  The calli
4540: 6e 67 20 66 75 6e 63 74 69 6f 6e 20 6d 75 73 74  ng function must
4550: 20 6e 6f 74 20 64 65 61 6c 6c 6f 63 61 74 65 20   not deallocate 
4560: 6f 72 20 6d 6f 64 69 66 79 0a 2a 2a 20 22 7a 22  or modify.** "z"
4570: 20 61 66 74 65 72 20 74 68 69 73 20 72 6f 75 74   after this rout
4580: 69 6e 65 20 66 69 6e 69 73 68 65 73 20 6f 72 20  ine finishes or 
4590: 69 74 20 63 6f 75 6c 64 20 63 6f 72 72 75 70 74  it could corrupt
45a0: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 0a 2a   the parameter.*
45b0: 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74  * table..*/.stat
45c0: 69 63 20 76 6f 69 64 20 70 72 6f 63 65 73 73 5f  ic void process_
45d0: 6d 75 6c 74 69 70 61 72 74 5f 66 6f 72 6d 5f 64  multipart_form_d
45e0: 61 74 61 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74  ata(char *z, int
45f0: 20 6c 65 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a   len){.  char *z
4600: 4c 69 6e 65 3b 0a 20 20 69 6e 74 20 6e 41 72 67  Line;.  int nArg
4610: 2c 20 69 3b 0a 20 20 63 68 61 72 20 2a 7a 42 6f  , i;.  char *zBo
4620: 75 6e 64 72 79 3b 0a 20 20 63 68 61 72 20 2a 7a  undry;.  char *z
4630: 56 61 6c 75 65 3b 0a 20 20 63 68 61 72 20 2a 7a  Value;.  char *z
4640: 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20  Name = 0;.  int 
4650: 73 68 6f 77 42 79 74 65 73 20 3d 20 30 3b 0a 20  showBytes = 0;. 
4660: 20 63 68 61 72 20 2a 61 7a 41 72 67 5b 35 30 5d   char *azArg[50]
4670: 3b 0a 0a 20 20 7a 42 6f 75 6e 64 72 79 20 3d 20  ;..  zBoundry = 
4680: 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74  get_line_from_st
4690: 72 69 6e 67 28 26 7a 2c 20 26 6c 65 6e 29 3b 0a  ring(&z, &len);.
46a0: 20 20 69 66 28 20 7a 42 6f 75 6e 64 72 79 3d 3d    if( zBoundry==
46b0: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 77 68  0 ) return;.  wh
46c0: 69 6c 65 28 20 28 7a 4c 69 6e 65 20 3d 20 67 65  ile( (zLine = ge
46d0: 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69  t_line_from_stri
46e0: 6e 67 28 26 7a 2c 20 26 6c 65 6e 29 29 21 3d 30  ng(&z, &len))!=0
46f0: 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 4c 69 6e   ){.    if( zLin
4700: 65 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20  e[0]==0 ){.     
4710: 20 69 6e 74 20 6e 43 6f 6e 74 65 6e 74 20 3d 20   int nContent = 
4720: 30 3b 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20  0;.      zValue 
4730: 3d 20 67 65 74 5f 62 6f 75 6e 64 65 64 5f 63 6f  = get_bounded_co
4740: 6e 74 65 6e 74 28 26 7a 2c 20 26 6c 65 6e 2c 20  ntent(&z, &len, 
4750: 7a 42 6f 75 6e 64 72 79 2c 20 26 6e 43 6f 6e 74  zBoundry, &nCont
4760: 65 6e 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ent);.      if( 
4770: 7a 4e 61 6d 65 20 26 26 20 7a 56 61 6c 75 65 20  zName && zValue 
4780: 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65  && islower(zName
4790: 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20  [0]) ){.        
47a0: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65  cgi_set_paramete
47b0: 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20  r_nocopy(zName, 
47c0: 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 20  zValue);.       
47d0: 20 69 66 28 20 73 68 6f 77 42 79 74 65 73 20 29   if( showBytes )
47e0: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 67 69 5f  {.          cgi_
47f0: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
4800: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73  copy(mprintf("%s
4810: 3a 62 79 74 65 73 22 2c 20 7a 4e 61 6d 65 29 2c  :bytes", zName),
4820: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
4830: 6d 70 72 69 6e 74 66 28 22 25 64 22 2c 6e 43 6f  mprintf("%d",nCo
4840: 6e 74 65 6e 74 29 29 3b 0a 20 20 20 20 20 20 20  ntent));.       
4850: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20   }.      }.     
4860: 20 7a 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20   zName = 0;.    
4870: 20 20 73 68 6f 77 42 79 74 65 73 20 3d 20 30 3b    showBytes = 0;
4880: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
4890: 20 20 6e 41 72 67 20 3d 20 74 6f 6b 65 6e 69 7a    nArg = tokeniz
48a0: 65 5f 6c 69 6e 65 28 7a 4c 69 6e 65 2c 20 73 69  e_line(zLine, si
48b0: 7a 65 6f 66 28 61 7a 41 72 67 29 2f 73 69 7a 65  zeof(azArg)/size
48c0: 6f 66 28 61 7a 41 72 67 5b 30 5d 29 2c 20 61 7a  of(azArg[0]), az
48d0: 41 72 67 29 3b 0a 20 20 20 20 20 20 66 6f 72 28  Arg);.      for(
48e0: 69 3d 30 3b 20 69 3c 6e 41 72 67 3b 20 69 2b 2b  i=0; i<nArg; i++
48f0: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 63  ){.        int c
4900: 20 3d 20 74 6f 6c 6f 77 65 72 28 61 7a 41 72 67   = tolower(azArg
4910: 5b 69 5d 5b 30 5d 29 3b 0a 20 20 20 20 20 20 20  [i][0]);.       
4920: 20 69 66 28 20 63 3d 3d 27 63 27 20 26 26 20 73   if( c=='c' && s
4930: 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c  tricmp(azArg[i],
4940: 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69  "content-disposi
4950: 74 69 6f 6e 3a 22 29 3d 3d 30 20 29 7b 0a 20 20  tion:")==0 ){.  
4960: 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20          i++;.   
4970: 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63       }else if( c
4980: 3d 3d 27 6e 27 20 26 26 20 73 74 72 69 63 6d 70  =='n' && stricmp
4990: 28 61 7a 41 72 67 5b 69 5d 2c 22 6e 61 6d 65 3d  (azArg[i],"name=
49a0: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ")==0 ){.       
49b0: 20 20 20 7a 4e 61 6d 65 20 3d 20 61 7a 41 72 67     zName = azArg
49c0: 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 7d  [++i];.        }
49d0: 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 66 27 20  else if( c=='f' 
49e0: 26 26 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67  && stricmp(azArg
49f0: 5b 69 5d 2c 22 66 69 6c 65 6e 61 6d 65 3d 22 29  [i],"filename=")
4a00: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
4a10: 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a 41 72 67   char *z = azArg
4a20: 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 20  [++i];.         
4a30: 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a 20   if( zName && z 
4a40: 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65  && islower(zName
4a50: 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20  [0]) ){.        
4a60: 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61      cgi_set_para
4a70: 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72  meter_nocopy(mpr
4a80: 69 6e 74 66 28 22 25 73 3a 66 69 6c 65 6e 61 6d  intf("%s:filenam
4a90: 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a 20  e",zName), z);. 
4aa0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
4ab0: 20 20 20 20 20 73 68 6f 77 42 79 74 65 73 20 3d       showBytes =
4ac0: 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73   1;.        }els
4ad0: 65 20 69 66 28 20 63 3d 3d 27 63 27 20 26 26 20  e if( c=='c' && 
4ae0: 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d  stricmp(azArg[i]
4af0: 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 22  ,"content-type:"
4b00: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  )==0 ){.        
4b10: 20 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a 41 72    char *z = azAr
4b20: 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20  g[++i];.        
4b30: 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a    if( zName && z
4b40: 20 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d   && islower(zNam
4b50: 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 20  e[0]) ){.       
4b60: 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72       cgi_set_par
4b70: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70  ameter_nocopy(mp
4b80: 72 69 6e 74 66 28 22 25 73 3a 6d 69 6d 65 74 79  rintf("%s:mimety
4b90: 70 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a  pe",zName), z);.
4ba0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20            }.    
4bb0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
4bc0: 20 20 7d 0a 20 20 7d 20 20 20 20 20 20 20 20 0a    }.  }        .
4bd0: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c  }../*.** Initial
4be0: 69 7a 65 20 74 68 65 20 71 75 65 72 79 20 70 61  ize the query pa
4bf0: 72 61 6d 65 74 65 72 20 64 61 74 61 62 61 73 65  rameter database
4c00: 2e 20 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 69  .  Information i
4c10: 73 20 70 75 6c 6c 65 64 20 66 72 6f 6d 0a 2a 2a  s pulled from.**
4c20: 20 74 68 65 20 51 55 45 52 59 5f 53 54 52 49 4e   the QUERY_STRIN
4c30: 47 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61  G environment va
4c40: 72 69 61 62 6c 65 20 28 69 66 20 69 74 20 65 78  riable (if it ex
4c50: 69 73 74 73 29 2c 20 66 72 6f 6d 20 73 74 61 6e  ists), from stan
4c60: 64 61 72 64 0a 2a 2a 20 69 6e 70 75 74 20 69 66  dard.** input if
4c70: 20 74 68 65 72 65 20 69 73 20 50 4f 53 54 20 64   there is POST d
4c80: 61 74 61 2c 20 61 6e 64 20 66 72 6f 6d 20 48 54  ata, and from HT
4c90: 54 50 5f 43 4f 4f 4b 49 45 2e 0a 2a 2f 0a 76 6f  TP_COOKIE..*/.vo
4ca0: 69 64 20 63 67 69 5f 69 6e 69 74 28 76 6f 69 64  id cgi_init(void
4cb0: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20  ){.  char *z;.  
4cc0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 70  const char *zTyp
4cd0: 65 3b 0a 20 20 69 6e 74 20 6c 65 6e 3b 0a 20 20  e;.  int len;.  
4ce0: 63 67 69 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28  cgi_destination(
4cf0: 43 47 49 5f 42 4f 44 59 29 3b 0a 20 20 7a 20 3d  CGI_BODY);.  z =
4d00: 20 28 63 68 61 72 2a 29 50 28 22 51 55 45 52 59   (char*)P("QUERY
4d10: 5f 53 54 52 49 4e 47 22 29 3b 0a 20 20 69 66 28  _STRING");.  if(
4d20: 20 7a 20 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70   z ){.    z = mp
4d30: 72 69 6e 74 66 28 22 25 73 22 2c 7a 29 3b 0a 20  rintf("%s",z);. 
4d40: 20 20 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73     add_param_lis
4d50: 74 28 7a 2c 20 27 26 27 29 3b 0a 20 20 7d 0a 0a  t(z, '&');.  }..
4d60: 20 20 6c 65 6e 20 3d 20 61 74 6f 69 28 50 44 28    len = atoi(PD(
4d70: 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22  "CONTENT_LENGTH"
4d80: 2c 20 22 30 22 29 29 3b 0a 20 20 67 2e 7a 43 6f  , "0"));.  g.zCo
4d90: 6e 74 65 6e 74 54 79 70 65 20 3d 20 7a 54 79 70  ntentType = zTyp
4da0: 65 20 3d 20 50 28 22 43 4f 4e 54 45 4e 54 5f 54  e = P("CONTENT_T
4db0: 59 50 45 22 29 3b 0a 20 20 69 66 28 20 6c 65 6e  YPE");.  if( len
4dc0: 3e 30 20 26 26 20 7a 54 79 70 65 20 29 7b 0a 20  >0 && zType ){. 
4dd0: 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 67 2e     blob_zero(&g.
4de0: 63 67 69 49 6e 29 3b 0a 20 20 20 20 69 66 28 20  cgiIn);.    if( 
4df0: 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 22 61 70  strcmp(zType,"ap
4e00: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d  plication/x-www-
4e10: 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 22  form-urlencoded"
4e20: 29 3d 3d 30 20 0a 20 20 20 20 20 20 20 20 20 7c  )==0 .         |
4e30: 7c 20 73 74 72 6e 63 6d 70 28 7a 54 79 70 65 2c  | strncmp(zType,
4e40: 22 6d 75 6c 74 69 70 61 72 74 2f 66 6f 72 6d 2d  "multipart/form-
4e50: 64 61 74 61 22 2c 31 39 29 3d 3d 30 20 29 7b 0a  data",19)==0 ){.
4e60: 20 20 20 20 20 20 7a 20 3d 20 6d 61 6c 6c 6f 63        z = malloc
4e70: 28 20 6c 65 6e 2b 31 20 29 3b 0a 20 20 20 20 20  ( len+1 );.     
4e80: 20 69 66 28 20 7a 3d 3d 30 20 29 20 65 78 69 74   if( z==0 ) exit
4e90: 28 31 29 3b 0a 20 20 20 20 20 20 6c 65 6e 20 3d  (1);.      len =
4ea0: 20 66 72 65 61 64 28 7a 2c 20 31 2c 20 6c 65 6e   fread(z, 1, len
4eb0: 2c 20 73 74 64 69 6e 29 3b 0a 20 20 20 20 20 20  , stdin);.      
4ec0: 7a 5b 6c 65 6e 5d 20 3d 20 30 3b 0a 20 20 20 20  z[len] = 0;.    
4ed0: 20 20 69 66 28 20 7a 54 79 70 65 5b 30 5d 3d 3d    if( zType[0]==
4ee0: 27 61 27 20 29 7b 0a 20 20 20 20 20 20 20 20 61  'a' ){.        a
4ef0: 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c  dd_param_list(z,
4f00: 20 27 26 27 29 3b 0a 20 20 20 20 20 20 7d 65 6c   '&');.      }el
4f10: 73 65 7b 0a 20 20 20 20 20 20 20 20 70 72 6f 63  se{.        proc
4f20: 65 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66 6f  ess_multipart_fo
4f30: 72 6d 5f 64 61 74 61 28 7a 2c 20 6c 65 6e 29 3b  rm_data(z, len);
4f40: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c  .      }.    }el
4f50: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54  se if( strcmp(zT
4f60: 79 70 65 2c 20 22 61 70 70 6c 69 63 61 74 69 6f  ype, "applicatio
4f70: 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 20  n/x-fossil")==0 
4f80: 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65  ){.      blob_re
4f90: 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28  ad_from_channel(
4fa0: 26 67 2e 63 67 69 49 6e 2c 20 73 74 64 69 6e 2c  &g.cgiIn, stdin,
4fb0: 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 62 6c 6f   len);.      blo
4fc0: 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26 67 2e  b_uncompress(&g.
4fd0: 63 67 69 49 6e 2c 20 26 67 2e 63 67 69 49 6e 29  cgiIn, &g.cgiIn)
4fe0: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
4ff0: 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20 22 61  strcmp(zType, "a
5000: 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73  pplication/x-fos
5010: 73 69 6c 2d 64 65 62 75 67 22 29 3d 3d 30 20 29  sil-debug")==0 )
5020: 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 61  {.      blob_rea
5030: 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26  d_from_channel(&
5040: 67 2e 63 67 69 49 6e 2c 20 73 74 64 69 6e 2c 20  g.cgiIn, stdin, 
5050: 6c 65 6e 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  len);.    }.  }.
5060: 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 50 28  .  z = (char*)P(
5070: 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 29 3b 0a  "HTTP_COOKIE");.
5080: 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 20 20 7a    if( z ){.    z
5090: 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c   = mprintf("%s",
50a0: 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 61 72 61  z);.    add_para
50b0: 6d 5f 6c 69 73 74 28 7a 2c 20 27 3b 27 29 3b 0a  m_list(z, ';');.
50c0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69    }.}../*.** Thi
50d0: 73 20 69 73 20 74 68 65 20 63 6f 6d 70 61 72 69  s is the compari
50e0: 73 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 75 73 65  son function use
50f0: 64 20 74 6f 20 73 6f 72 74 20 74 68 65 20 61 50  d to sort the aP
5100: 61 72 61 6d 51 50 5b 5d 20 61 72 72 61 79 20 6f  aramQP[] array o
5110: 66 0a 2a 2a 20 71 75 65 72 79 20 70 61 72 61 6d  f.** query param
5120: 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65  eters and cookie
5130: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  s..*/.static int
5140: 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72 65 28   qparam_compare(
5150: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 61 2c 20 63  const void *a, c
5160: 6f 6e 73 74 20 76 6f 69 64 20 2a 62 29 7b 0a 20  onst void *b){. 
5170: 20 73 74 72 75 63 74 20 51 50 61 72 61 6d 20 2a   struct QParam *
5180: 70 41 20 3d 20 28 73 74 72 75 63 74 20 51 50 61  pA = (struct QPa
5190: 72 61 6d 2a 29 61 3b 0a 20 20 73 74 72 75 63 74  ram*)a;.  struct
51a0: 20 51 50 61 72 61 6d 20 2a 70 42 20 3d 20 28 73   QParam *pB = (s
51b0: 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29 62 3b  truct QParam*)b;
51c0: 0a 20 20 69 6e 74 20 63 3b 0a 20 20 63 20 3d 20  .  int c;.  c = 
51d0: 73 74 72 63 6d 70 28 70 41 2d 3e 7a 4e 61 6d 65  strcmp(pA->zName
51e0: 2c 20 70 42 2d 3e 7a 4e 61 6d 65 29 3b 0a 20 20  , pB->zName);.  
51f0: 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20  if( c==0 ){.    
5200: 63 20 3d 20 70 41 2d 3e 73 65 71 20 2d 20 70 42  c = pA->seq - pB
5210: 2d 3e 73 65 71 3b 0a 20 20 7d 0a 20 20 72 65 74  ->seq;.  }.  ret
5220: 75 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn c;.}../*.** 
5230: 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65  Return the value
5240: 20 6f 66 20 61 20 71 75 65 72 79 20 70 61 72 61   of a query para
5250: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20  meter or cookie 
5260: 77 68 6f 73 65 20 6e 61 6d 65 20 69 73 20 7a 4e  whose name is zN
5270: 61 6d 65 2e 0a 2a 2a 20 49 66 20 74 68 65 72 65  ame..** If there
5280: 20 69 73 20 6e 6f 20 71 75 65 72 79 20 70 61 72   is no query par
5290: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65  ameter or cookie
52a0: 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 61 6e 64   named zName and
52b0: 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20 63 68   the first.** ch
52c0: 61 72 61 63 74 65 72 20 6f 66 20 7a 4e 61 6d 65  aracter of zName
52d0: 20 69 73 20 75 70 70 65 72 63 61 73 65 2c 20 74   is uppercase, t
52e0: 68 65 6e 20 63 68 65 63 6b 20 74 6f 20 73 65 65  hen check to see
52f0: 20 69 66 20 74 68 65 72 65 20 69 73 20 61 6e 0a   if there is an.
5300: 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76  ** environment v
5310: 61 72 69 61 62 6c 65 20 62 79 20 74 68 61 74 20  ariable by that 
5320: 6e 61 6d 65 20 61 6e 64 20 72 65 74 75 72 6e 20  name and return 
5330: 69 74 20 69 66 20 74 68 65 72 65 20 69 73 2e 20  it if there is. 
5340: 20 41 73 0a 2a 2a 20 61 20 6c 61 73 74 20 72 65   As.** a last re
5350: 73 6f 72 74 20 77 68 65 6e 20 6e 6f 74 68 69 6e  sort when nothin
5360: 67 20 65 6c 73 65 20 6d 61 74 63 68 65 73 2c 20  g else matches, 
5370: 72 65 74 75 72 6e 20 7a 44 65 66 61 75 6c 74 2e  return zDefault.
5380: 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20 2a  .*/.const char *
5390: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 63 6f  cgi_parameter(co
53a0: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c  nst char *zName,
53b0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 65   const char *zDe
53c0: 66 61 75 6c 74 29 7b 0a 20 20 69 6e 74 20 6c 6f  fault){.  int lo
53d0: 2c 20 68 69 2c 20 6d 69 64 2c 20 63 3b 0a 0a 20  , hi, mid, c;.. 
53e0: 20 2f 2a 20 54 68 65 20 73 6f 72 74 51 50 20 66   /* The sortQP f
53f0: 6c 61 67 20 69 73 20 73 65 74 20 77 68 65 6e 65  lag is set whene
5400: 76 65 72 20 61 20 6e 65 77 20 71 75 65 72 79 20  ver a new query 
5410: 70 61 72 61 6d 65 74 65 72 20 69 73 20 69 6e 73  parameter is ins
5420: 65 72 74 65 64 2e 0a 20 20 2a 2a 20 49 74 20 69  erted..  ** It i
5430: 6e 64 69 63 61 74 65 73 20 74 68 61 74 20 77 65  ndicates that we
5440: 20 6e 65 65 64 20 74 6f 20 72 65 73 6f 72 74 20   need to resort 
5450: 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65  the query parame
5460: 74 65 72 73 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  ters..  */.  if(
5470: 20 73 6f 72 74 51 50 20 29 7b 0a 20 20 20 20 69   sortQP ){.    i
5480: 6e 74 20 69 2c 20 6a 3b 0a 20 20 20 20 71 73 6f  nt i, j;.    qso
5490: 72 74 28 61 50 61 72 61 6d 51 50 2c 20 6e 55 73  rt(aParamQP, nUs
54a0: 65 64 51 50 2c 20 73 69 7a 65 6f 66 28 61 50 61  edQP, sizeof(aPa
54b0: 72 61 6d 51 50 5b 30 5d 29 2c 20 71 70 61 72 61  ramQP[0]), qpara
54c0: 6d 5f 63 6f 6d 70 61 72 65 29 3b 0a 20 20 20 20  m_compare);.    
54d0: 73 6f 72 74 51 50 20 3d 20 30 3b 0a 20 20 20 20  sortQP = 0;.    
54e0: 2f 2a 20 41 66 74 65 72 20 73 6f 72 74 69 6e 67  /* After sorting
54f0: 2c 20 72 65 6d 6f 76 65 20 64 75 70 6c 69 63 61  , remove duplica
5500: 74 65 20 70 61 72 61 6d 65 74 65 72 73 2e 20 20  te parameters.  
5510: 54 68 65 20 73 65 63 6f 6e 64 61 72 79 20 73 6f  The secondary so
5520: 72 74 0a 20 20 20 20 2a 2a 20 6b 65 79 20 69 73  rt.    ** key is
5530: 20 61 50 61 72 61 6d 51 50 5b 5d 2e 73 65 71 20   aParamQP[].seq 
5540: 61 6e 64 20 77 65 20 6b 65 65 70 20 74 68 65 20  and we keep the 
5550: 66 69 72 73 74 20 65 6e 74 72 79 2e 20 20 54 68  first entry.  Th
5560: 61 74 20 6d 65 61 6e 73 0a 20 20 20 20 2a 2a 20  at means.    ** 
5570: 77 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 63  with duplicate c
5580: 61 6c 6c 73 20 74 6f 20 63 67 69 5f 73 65 74 5f  alls to cgi_set_
5590: 70 61 72 61 6d 65 74 65 72 28 29 20 74 68 65 20  parameter() the 
55a0: 73 65 63 6f 6e 64 20 61 6e 64 0a 20 20 20 20 2a  second and.    *
55b0: 2a 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c  * subsequent cal
55c0: 6c 73 20 61 72 65 20 65 66 66 65 63 74 69 76 65  ls are effective
55d0: 6c 79 20 6e 6f 2d 6f 70 73 2e 20 2a 2f 0a 20 20  ly no-ops. */.  
55e0: 20 20 66 6f 72 28 69 3d 6a 3d 31 3b 20 69 3c 6e    for(i=j=1; i<n
55f0: 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20  UsedQP; i++){.  
5600: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61      if( strcmp(a
5610: 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65  ParamQP[i].zName
5620: 2c 61 50 61 72 61 6d 51 50 5b 69 2d 31 5d 2e 7a  ,aParamQP[i-1].z
5630: 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20  Name)==0 ){.    
5640: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20      continue;.  
5650: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20      }.      if( 
5660: 6a 3c 69 20 29 7b 0a 20 20 20 20 20 20 20 20 6d  j<i ){.        m
5670: 65 6d 63 70 79 28 26 61 50 61 72 61 6d 51 50 5b  emcpy(&aParamQP[
5680: 6a 5d 2c 20 26 61 50 61 72 61 6d 51 50 5b 69 5d  j], &aParamQP[i]
5690: 2c 20 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51  , sizeof(aParamQ
56a0: 50 5b 6a 5d 29 29 3b 0a 20 20 20 20 20 20 7d 0a  P[j]));.      }.
56b0: 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 20 20 20 7d        j++;.    }
56c0: 0a 20 20 20 20 6e 55 73 65 64 51 50 20 3d 20 6a  .    nUsedQP = j
56d0: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 6f 20 61  ;.  }..  /* Do a
56e0: 20 62 69 6e 61 72 79 20 73 65 61 72 63 68 20 66   binary search f
56f0: 6f 72 20 61 20 6d 61 74 63 68 69 6e 67 20 71 75  or a matching qu
5700: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 2a 2f  ery parameter */
5710: 0a 20 20 6c 6f 20 3d 20 30 3b 0a 20 20 68 69 20  .  lo = 0;.  hi 
5720: 3d 20 6e 55 73 65 64 51 50 2d 31 3b 0a 20 20 77  = nUsedQP-1;.  w
5730: 68 69 6c 65 28 20 6c 6f 3c 3d 68 69 20 29 7b 0a  hile( lo<=hi ){.
5740: 20 20 20 20 6d 69 64 20 3d 20 28 6c 6f 2b 68 69      mid = (lo+hi
5750: 29 2f 32 3b 0a 20 20 20 20 63 20 3d 20 73 74 72  )/2;.    c = str
5760: 63 6d 70 28 61 50 61 72 61 6d 51 50 5b 6d 69 64  cmp(aParamQP[mid
5770: 5d 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 29 3b  ].zName, zName);
5780: 0a 20 20 20 20 69 66 28 20 63 3d 3d 30 20 29 7b  .    if( c==0 ){
5790: 0a 20 20 20 20 20 20 43 47 49 44 45 42 55 47 28  .      CGIDEBUG(
57a0: 28 22 6d 65 6d 2d 6d 61 74 63 68 20 5b 25 73 5d  ("mem-match [%s]
57b0: 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d   = [%s]\n", zNam
57c0: 65 2c 20 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d  e, aParamQP[mid]
57d0: 2e 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20 20  .zValue));.     
57e0: 20 72 65 74 75 72 6e 20 61 50 61 72 61 6d 51 50   return aParamQP
57f0: 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 3b 0a 20 20  [mid].zValue;.  
5800: 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3e 30 20    }else if( c>0 
5810: 29 7b 0a 20 20 20 20 20 20 68 69 20 3d 20 6d 69  ){.      hi = mi
5820: 64 2d 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  d-1;.    }else{.
5830: 20 20 20 20 20 20 6c 6f 20 3d 20 6d 69 64 2b 31        lo = mid+1
5840: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f  ;.    }.  }..  /
5850: 2a 20 49 66 20 6e 6f 20 6d 61 74 63 68 20 69 73  * If no match is
5860: 20 66 6f 75 6e 64 20 61 6e 64 20 74 68 65 20 6e   found and the n
5870: 61 6d 65 20 62 65 67 69 6e 73 20 77 69 74 68 20  ame begins with 
5880: 61 6e 20 75 70 70 65 72 2d 63 61 73 65 0a 20 20  an upper-case.  
5890: 2a 2a 20 6c 65 74 74 65 72 2c 20 74 68 65 6e 20  ** letter, then 
58a0: 63 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20  check to see if 
58b0: 74 68 65 72 65 20 69 73 20 61 6e 20 65 6e 76 69  there is an envi
58c0: 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65  ronment variable
58d0: 0a 20 20 2a 2a 20 77 69 74 68 20 74 68 65 20 67  .  ** with the g
58e0: 69 76 65 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a  iven name..  */.
58f0: 20 20 69 66 28 20 69 73 75 70 70 65 72 28 7a 4e    if( isupper(zN
5900: 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 63  ame[0]) ){.    c
5910: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75  onst char *zValu
5920: 65 20 3d 20 67 65 74 65 6e 76 28 7a 4e 61 6d 65  e = getenv(zName
5930: 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 75  );.    if( zValu
5940: 65 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73  e ){.      cgi_s
5950: 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63  et_parameter_noc
5960: 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75  opy(zName, zValu
5970: 65 29 3b 0a 20 20 20 20 20 20 43 47 49 44 45 42  e);.      CGIDEB
5980: 55 47 28 28 22 65 6e 76 2d 6d 61 74 63 68 20 5b  UG(("env-match [
5990: 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a  %s] = [%s]\n", z
59a0: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 29 3b 0a  Name, zValue));.
59b0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 7a 56 61        return zVa
59c0: 6c 75 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  lue;.    }.  }. 
59d0: 20 43 47 49 44 45 42 55 47 28 28 22 6e 6f 2d 6d   CGIDEBUG(("no-m
59e0: 61 74 63 68 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e  atch [%s]\n", zN
59f0: 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72 6e 20  ame));.  return 
5a00: 7a 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a  zDefault;.}../*.
5a10: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 61  ** Return the na
5a20: 6d 65 20 6f 66 20 74 68 65 20 69 2d 74 68 20 43  me of the i-th C
5a30: 47 49 20 70 61 72 61 6d 65 74 65 72 2e 20 20 52  GI parameter.  R
5a40: 65 74 75 72 6e 20 4e 55 4c 4c 20 69 66 20 74 68  eturn NULL if th
5a50: 65 72 65 0a 2a 2a 20 61 72 65 20 66 65 77 65 72  ere.** are fewer
5a60: 20 74 68 61 6e 20 69 20 72 65 67 69 73 74 65 72   than i register
5a70: 65 64 20 43 47 49 20 70 61 72 6d 61 65 74 65 72  ed CGI parmaeter
5a80: 73 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72  s..*/.const char
5a90: 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72 5f   *cgi_parameter_
5aa0: 6e 61 6d 65 28 69 6e 74 20 69 29 7b 0a 20 20 69  name(int i){.  i
5ab0: 66 28 20 69 3e 3d 30 20 26 26 20 69 3c 6e 55 73  f( i>=0 && i<nUs
5ac0: 65 64 51 50 20 29 7b 0a 20 20 20 20 72 65 74 75  edQP ){.    retu
5ad0: 72 6e 20 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a  rn aParamQP[i].z
5ae0: 4e 61 6d 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  Name;.  }else{. 
5af0: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d     return 0;.  }
5b00: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74 20  .}../*.** Print 
5b10: 43 47 49 20 64 65 62 75 67 67 69 6e 67 20 6d 65  CGI debugging me
5b20: 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20  ssages..*/.void 
5b30: 63 67 69 5f 64 65 62 75 67 28 63 6f 6e 73 74 20  cgi_debug(const 
5b40: 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e  char *zFormat, .
5b50: 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61  ..){.  va_list a
5b60: 70 3b 0a 20 20 69 66 28 20 67 2e 66 44 65 62 75  p;.  if( g.fDebu
5b70: 67 20 29 7b 0a 20 20 20 20 76 61 5f 73 74 61 72  g ){.    va_star
5b80: 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a  t(ap, zFormat);.
5b90: 20 20 20 20 76 66 70 72 69 6e 74 66 28 67 2e 66      vfprintf(g.f
5ba0: 44 65 62 75 67 2c 20 7a 46 6f 72 6d 61 74 2c 20  Debug, zFormat, 
5bb0: 61 70 29 3b 0a 20 20 20 20 76 61 5f 65 6e 64 28  ap);.    va_end(
5bc0: 61 70 29 3b 0a 20 20 20 20 66 66 6c 75 73 68 28  ap);.    fflush(
5bd0: 67 2e 66 44 65 62 75 67 29 3b 0a 20 20 7d 0a 7d  g.fDebug);.  }.}
5be0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74  ../*.** Return t
5bf0: 72 75 65 20 69 66 20 61 6e 79 20 6f 66 20 74 68  rue if any of th
5c00: 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  e query paramete
5c10: 72 73 20 69 6e 20 74 68 65 20 61 72 67 75 6d 65  rs in the argume
5c20: 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 72 65 20 64  nt.** list are d
5c30: 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20 63  efined..*/.int c
5c40: 67 69 5f 61 6e 79 28 63 6f 6e 73 74 20 63 68 61  gi_any(const cha
5c50: 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61  r *z, ...){.  va
5c60: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72  _list ap;.  char
5c70: 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 67 69 5f   *z2;.  if( cgi_
5c80: 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 29 21 3d  parameter(z,0)!=
5c90: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20  0 ) return 1;.  
5ca0: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 29 3b  va_start(ap, z);
5cb0: 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 20 3d 20  .  while( (z2 = 
5cc0: 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a  va_arg(ap, char*
5cd0: 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  ))!=0 ){.    if(
5ce0: 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a   cgi_parameter(z
5cf0: 32 2c 30 29 21 3d 30 20 29 20 72 65 74 75 72 6e  2,0)!=0 ) return
5d00: 20 31 3b 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64   1;.  }.  va_end
5d10: 28 61 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 30  (ap);.  return 0
5d20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
5d30: 6e 20 74 72 75 65 20 69 66 20 61 6c 6c 20 6f 66  n true if all of
5d40: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   the query param
5d50: 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 67  eters in the arg
5d60: 75 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a 20 61 72  ument list.** ar
5d70: 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e  e defined..*/.in
5d80: 74 20 63 67 69 5f 61 6c 6c 28 63 6f 6e 73 74 20  t cgi_all(const 
5d90: 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20  char *z, ...){. 
5da0: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63   va_list ap;.  c
5db0: 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63  har *z2;.  if( c
5dc0: 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30  gi_parameter(z,0
5dd0: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b  )==0 ) return 0;
5de0: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20  .  va_start(ap, 
5df0: 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32  z);.  while( (z2
5e00: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68   = va_arg(ap, ch
5e10: 61 72 2a 29 29 3d 3d 30 20 29 7b 0a 20 20 20 20  ar*))==0 ){.    
5e20: 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65  if( cgi_paramete
5e30: 72 28 7a 32 2c 30 29 3d 3d 30 20 29 20 72 65 74  r(z2,0)==0 ) ret
5e40: 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 76 61 5f  urn 0;.  }.  va_
5e50: 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72  end(ap);.  retur
5e60: 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72  n 1;.}../*.** Pr
5e70: 69 6e 74 20 61 6c 6c 20 71 75 65 72 79 20 70 61  int all query pa
5e80: 72 61 6d 65 74 65 72 73 20 6f 6e 20 73 74 61 6e  rameters on stan
5e90: 64 61 72 64 20 6f 75 74 70 75 74 2e 20 20 46 6f  dard output.  Fo
5ea0: 72 6d 61 74 20 74 68 65 0a 2a 2a 20 70 61 72 61  rmat the.** para
5eb0: 6d 65 74 65 72 73 20 61 73 20 48 54 4d 4c 2e 20  meters as HTML. 
5ec0: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f   This is used fo
5ed0: 72 20 74 65 73 74 69 6e 67 20 61 6e 64 20 64 65  r testing and de
5ee0: 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64  bugging..*/.void
5ef0: 20 63 67 69 5f 70 72 69 6e 74 5f 61 6c 6c 28 76   cgi_print_all(v
5f00: 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20  oid){.  int i;. 
5f10: 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 22   cgi_parameter("
5f20: 22 2c 22 22 29 3b 20 20 2f 2a 20 46 6f 72 63 65  ","");  /* Force
5f30: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 73 20   the parameters 
5f40: 69 6e 74 6f 20 73 6f 72 74 65 64 20 6f 72 64 65  into sorted orde
5f50: 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20  r */.  for(i=0; 
5f60: 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b  i<nUsedQP; i++){
5f70: 0a 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28  .    cgi_printf(
5f80: 22 25 73 20 3d 20 25 73 20 20 3c 62 72 20 2f 3e  "%s = %s  <br />
5f90: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 68 74 6d 6c  \n",.       html
5fa0: 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e  ize(aParamQP[i].
5fb0: 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 68 74 6d 6c  zName, -1), html
5fc0: 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e  ize(aParamQP[i].
5fd0: 7a 56 61 6c 75 65 2c 20 2d 31 29 29 3b 0a 20 20  zValue, -1));.  
5fe0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65  }.}../*.** Write
5ff0: 20 48 54 4d 4c 20 74 65 78 74 20 66 6f 72 20 61   HTML text for a
6000: 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 74 6f  n option menu to
6010: 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74   standard output
6020: 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a 20 69 73 20  .  zParam.** is 
6030: 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65  the query parame
6040: 74 65 72 20 74 68 61 74 20 74 68 65 20 6f 70 74  ter that the opt
6050: 69 6f 6e 20 6d 65 6e 75 20 73 65 74 73 2e 20 20  ion menu sets.  
6060: 7a 44 66 6c 74 20 69 73 20 74 68 65 0a 2a 2a 20  zDflt is the.** 
6070: 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 20 6f 66  initial value of
6080: 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65 6e 75   the option menu
6090: 2e 20 20 41 64 64 69 74 69 6f 6e 20 61 72 67 75  .  Addition argu
60a0: 6d 65 6e 74 73 20 61 72 65 20 6e 61 6d 65 2f 76  ments are name/v
60b0: 61 6c 75 65 0a 2a 2a 20 70 61 69 72 73 20 74 68  alue.** pairs th
60c0: 61 74 20 64 65 66 69 6e 65 20 76 61 6c 75 65 73  at define values
60d0: 20 6f 6e 20 74 68 65 20 6d 65 6e 75 2e 20 20 54   on the menu.  T
60e0: 68 65 20 6c 69 73 74 20 69 73 20 74 65 72 6d 69  he list is termi
60f0: 6e 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 61 20  nated with.** a 
6100: 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 61 72 67 75  single NULL argu
6110: 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  ment..*/.void cg
6120: 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 69 6e 74  i_optionmenu(int
6130: 20 69 6e 2c 20 63 6f 6e 73 74 20 63 68 61 72 20   in, const char 
6140: 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  *zP, const char 
6150: 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f  *zD, ...){.  va_
6160: 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72 20  list ap;.  char 
6170: 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c 3b 0a 20  *zName, *zVal;. 
6180: 20 69 6e 74 20 64 66 6c 74 53 65 65 6e 20 3d 20   int dfltSeen = 
6190: 30 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28  0;.  cgi_printf(
61a0: 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65  "%*s<select size
61b0: 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c  =1 name=\"%s\">\
61c0: 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b  n", in, "", zP);
61d0: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20  .  va_start(ap, 
61e0: 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a  zD);.  while( (z
61f0: 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70  Name = va_arg(ap
6200: 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20  , char*))!=0 && 
6210: 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61  (zVal = va_arg(a
6220: 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b  p, char*))!=0 ){
6230: 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28  .    if( strcmp(
6240: 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 29 7b 20 64  zVal,zD)==0 ){ d
6250: 66 6c 74 53 65 65 6e 20 3d 20 31 3b 20 62 72 65  fltSeen = 1; bre
6260: 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76 61 5f 65  ak; }.  }.  va_e
6270: 6e 64 28 61 70 29 3b 0a 20 20 69 66 28 20 21 64  nd(ap);.  if( !d
6280: 66 6c 74 53 65 65 6e 20 29 7b 0a 20 20 20 20 69  fltSeen ){.    i
6290: 66 28 20 7a 44 5b 30 5d 20 29 7b 0a 20 20 20 20  f( zD[0] ){.    
62a0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a    cgi_printf("%*
62b0: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c  s<option value=\
62c0: 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25  "%h\" selected>%
62d0: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20  h</option>\n",. 
62e0: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c         in+2, "",
62f0: 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 65   zD, zD);.    }e
6300: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70  lse{.      cgi_p
6310: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f  rintf("%*s<optio
6320: 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c  n value=\"\" sel
6330: 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70  ected>&nbsp;</op
6340: 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b 32 2c 20  tion>\n", in+2, 
6350: 22 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  "");.    }.  }. 
6360: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 44   va_start(ap, zD
6370: 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4e 61  );.  while( (zNa
6380: 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20  me = va_arg(ap, 
6390: 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20 28 7a  char*))!=0 && (z
63a0: 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c  Val = va_arg(ap,
63b0: 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20   char*))!=0 ){. 
63c0: 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 20     if( zName[0] 
63d0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  ){.      cgi_pri
63e0: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20  ntf("%*s<option 
63f0: 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25  value=\"%h\"%s>%
6400: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20  h</option>\n",. 
6410: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c         in+2, "",
6420: 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20  .        zVal,. 
6430: 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56         strcmp(zV
6440: 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22  al, zD) ? "" : "
6450: 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 20 20 20   selected",.    
6460: 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 20 20 20      zName.      
6470: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  );.    }else{.  
6480: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22      cgi_printf("
6490: 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65  %*s<option value
64a0: 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b 3c 2f  =\"\"%s>&nbsp;</
64b0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20  option>\n",.    
64c0: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20      in+2, "",.  
64d0: 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61        strcmp(zVa
64e0: 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20  l, zD) ? "" : " 
64f0: 73 65 6c 65 63 74 65 64 22 0a 20 20 20 20 20 20  selected".      
6500: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 76  );.    }.  }.  v
6510: 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63 67 69  a_end(ap);.  cgi
6520: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65  _printf("%*s</se
6530: 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22  lect>\n", in, ""
6540: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73  );.}../*.** This
6550: 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 61   routine works a
6560: 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69 5f 6f 70   lot like cgi_op
6570: 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70  tionmenu() excep
6580: 74 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 20  t that the list 
6590: 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 20 69 73 20  of.** values is 
65a0: 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 61 6e 20  contained in an 
65b0: 61 72 72 61 79 2e 20 20 41 6c 73 6f 2c 20 74 68  array.  Also, th
65c0: 65 20 76 61 6c 75 65 73 20 61 72 65 20 6a 75 73  e values are jus
65d0: 74 20 76 61 6c 75 65 73 2c 20 6e 6f 74 0a 2a 2a  t values, not.**
65e0: 20 6e 61 6d 65 2f 76 61 6c 75 65 20 70 61 69 72   name/value pair
65f0: 73 20 61 73 20 69 6e 20 63 67 69 5f 6f 70 74 69  s as in cgi_opti
6600: 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f 69 64 20  onmenu..*/.void 
6610: 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e 75  cgi_v_optionmenu
6620: 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20 20 20  (.  int in,     
6630: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65           /* Inde
6640: 6e 74 20 62 79 20 74 68 69 73 20 61 6d 6f 75 6e  nt by this amoun
6650: 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  t */.  const cha
6660: 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a 20 54  r *zP,      /* T
6670: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74  he query paramet
6680: 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e  er name */.  con
6690: 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 20 20 20  st char *zD,    
66a0: 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 76 61 6c    /* Default val
66b0: 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ue */.  const ch
66c0: 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f 2a 20  ar **az      /* 
66d0: 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 64 20  NULL-terminated 
66e0: 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65 64 20  list of allowed 
66f0: 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 20 63  values */.){.  c
6700: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b  onst char *zVal;
6710: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69 5f  .  int i;.  cgi_
6720: 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c 65  printf("%*s<sele
6730: 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c  ct size=1 name=\
6740: 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22  "%s\">\n", in, "
6750: 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28 69 3d  ", zP);.  for(i=
6760: 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a  0; az[i]; i++){.
6770: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61      if( strcmp(a
6780: 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20 62 72  z[i],zD)==0 ) br
6790: 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61  eak;.  }.  if( a
67a0: 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 69  z[i]==0 ){.    i
67b0: 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b 0a 20  f( zD[0]==0 ){. 
67c0: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28       cgi_printf(
67d0: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75  "%*s<option valu
67e0: 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64 3e  e=\"\" selected>
67f0: 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c  &nbsp;</option>\
6800: 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c  n",.       in+2,
6810: 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b   "");.    }else{
6820: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74  .      cgi_print
6830: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61  f("%*s<option va
6840: 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63  lue=\"%h\" selec
6850: 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c  ted>%h</option>\
6860: 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c  n",.       in+2,
6870: 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20   "", zD, zD);.  
6880: 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28    }.  }.  while(
6890: 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b 2b 29   (zVal = *(az++)
68a0: 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 69 66 28  )!=0  ){.    if(
68b0: 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20 20 20 20   zVal[0] ){.    
68c0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a    cgi_printf("%*
68d0: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c  s<option value=\
68e0: 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69  "%h\"%s>%h</opti
68f0: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20  on>\n",.        
6900: 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20  in+2, "",.      
6910: 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 20    zVal,.        
6920: 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29  strcmp(zVal, zD)
6930: 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74   ? "" : " select
6940: 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61  ed",.        zVa
6950: 6c 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d  l.      );.    }
6960: 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f  else{.      cgi_
6970: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69  printf("%*s<opti
6980: 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25 73 3e  on value=\"\"%s>
6990: 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c  &nbsp;</option>\
69a0: 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32  n",.        in+2
69b0: 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 73 74  , "",.        st
69c0: 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f  rcmp(zVal, zD) ?
69d0: 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64   "" : " selected
69e0: 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d  ".      );.    }
69f0: 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74  .  }.  cgi_print
6a00: 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c  f("%*s</select>\
6a10: 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a  n", in, "");.}..
6a20: 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  /*.** This routi
6a30: 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74 20 6c  ne works a lot l
6a40: 69 6b 65 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e  ike cgi_v_option
6a50: 6d 65 6e 75 28 29 20 65 78 63 65 70 74 20 74 68  menu() except th
6a60: 61 74 20 74 68 65 20 6c 69 73 74 0a 2a 2a 20 69  at the list.** i
6a70: 73 20 61 20 6c 69 73 74 20 6f 66 20 70 61 69 72  s a list of pair
6a80: 73 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 6c  s.  The first el
6a90: 65 6d 65 6e 74 20 6f 66 20 65 61 63 68 20 70 61  ement of each pa
6aa0: 69 72 20 69 73 20 74 68 65 20 76 61 6c 75 65 20  ir is the value 
6ab0: 75 73 65 64 0a 2a 2a 20 69 6e 74 65 72 6e 61 6c  used.** internal
6ac0: 6c 79 20 61 6e 64 20 74 68 65 20 73 65 63 6f 6e  ly and the secon
6ad0: 64 20 65 6c 65 6d 65 6e 74 20 69 73 20 74 68 65  d element is the
6ae0: 20 76 61 6c 75 65 20 64 69 73 70 6c 61 79 65 64   value displayed
6af0: 20 74 6f 20 74 68 65 20 75 73 65 72 2e 0a 2a 2f   to the user..*/
6b00: 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74 69  .void cgi_v_opti
6b10: 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 6e 74 20 69  onmenu2(.  int i
6b20: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
6b30: 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20 74 68 69  /* Indent by thi
6b40: 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f  s amount */.  co
6b50: 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 20 20  nst char *zP,   
6b60: 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79 20     /* The query 
6b70: 70 61 72 61 6d 65 74 65 72 20 6e 61 6d 65 20 2a  parameter name *
6b80: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
6b90: 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44 65 66 61  zD,      /* Defa
6ba0: 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20 63  ult value */.  c
6bb0: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 20 20  onst char **az  
6bc0: 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d      /* NULL-term
6bd0: 69 6e 61 74 65 64 20 6c 69 73 74 20 6f 66 20 61  inated list of a
6be0: 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 2a 2f  llowed values */
6bf0: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
6c00: 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 69 3b   *zVal;.  int i;
6c10: 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25  .  cgi_printf("%
6c20: 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 3d 31  *s<select size=1
6c30: 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22   name=\"%s\">\n"
6c40: 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a 20  , in, "", zP);. 
6c50: 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b   for(i=0; az[i];
6c60: 20 69 2b 3d 32 29 7b 0a 20 20 20 20 69 66 28 20   i+=2){.    if( 
6c70: 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a 44 29  strcmp(az[i],zD)
6c80: 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d  ==0 ) break;.  }
6c90: 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d 30 20  .  if( az[i]==0 
6ca0: 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b 30 5d  ){.    if( zD[0]
6cb0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69  ==0 ){.      cgi
6cc0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74  _printf("%*s<opt
6cd0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73  ion value=\"\" s
6ce0: 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f  elected>&nbsp;</
6cf0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20  option>\n",.    
6d00: 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20 20     in+2, "");.  
6d10: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63    }else{.      c
6d20: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f  gi_printf("%*s<o
6d30: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68  ption value=\"%h
6d40: 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 68 3c 2f  \" selected>%h</
6d50: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20  option>\n",.    
6d60: 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c     in+2, "", zD,
6d70: 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   zD);.    }.  }.
6d80: 20 20 77 68 69 6c 65 28 20 28 7a 56 61 6c 20 3d    while( (zVal =
6d90: 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20 29 7b   *(az++))!=0  ){
6da0: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20  .    const char 
6db0: 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a 2b 2b 29  *zName = *(az++)
6dc0: 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b  ;.    if( zName[
6dd0: 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  0] ){.      cgi_
6de0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69  printf("%*s<opti
6df0: 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25  on value=\"%h\"%
6e00: 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22  s>%h</option>\n"
6e10: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20  ,.        in+2, 
6e20: 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c  "",.        zVal
6e30: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70  ,.        strcmp
6e40: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20  (zVal, zD) ? "" 
6e50: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20  : " selected",. 
6e60: 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20         zName.   
6e70: 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b     );.    }else{
6e80: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74  .      cgi_print
6e90: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61  f("%*s<option va
6ea0: 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 26 6e 62  lue=\"%h\"%s>&nb
6eb0: 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c  sp;</option>\n",
6ec0: 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22  .        in+2, "
6ed0: 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c  ",.        zVal,
6ee0: 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28  .        strcmp(
6ef0: 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a  zVal, zD) ? "" :
6f00: 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20   " selected".   
6f10: 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a     );.    }.  }.
6f20: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a    cgi_printf("%*
6f30: 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69  s</select>\n", i
6f40: 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  n, "");.}../*.**
6f50: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f   This routine wo
6f60: 72 6b 73 20 6c 69 6b 65 20 22 70 72 69 6e 74 66  rks like "printf
6f70: 22 20 65 78 63 65 70 74 20 74 68 61 74 20 69 74  " except that it
6f80: 20 68 61 73 20 74 68 65 0a 2a 2a 20 65 78 74 72   has the.** extr
6f90: 61 20 66 6f 72 6d 61 74 74 69 6e 67 20 63 61 70  a formatting cap
6fa0: 61 62 69 6c 69 74 69 65 73 20 73 75 63 68 20 61  abilities such a
6fb0: 73 20 25 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a  s %h and %t..*/.
6fc0: 76 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 66 28  void cgi_printf(
6fd0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72  const char *zFor
6fe0: 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f  mat, ...){.  va_
6ff0: 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74  list ap;.  va_st
7000: 61 72 74 28 61 70 2c 7a 46 6f 72 6d 61 74 29 3b  art(ap,zFormat);
7010: 0a 20 20 76 78 70 72 69 6e 74 66 28 70 43 6f 6e  .  vxprintf(pCon
7020: 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 70 29  tent,zFormat,ap)
7030: 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a  ;.  va_end(ap);.
7040: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  }../*.** This ro
7050: 75 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69 6b 65  utine works like
7060: 20 22 76 70 72 69 6e 74 66 22 20 65 78 63 65 70   "vprintf" excep
7070: 74 20 74 68 61 74 20 69 74 20 68 61 73 20 74 68  t that it has th
7080: 65 0a 2a 2a 20 65 78 74 72 61 20 66 6f 72 6d 61  e.** extra forma
7090: 74 74 69 6e 67 20 63 61 70 61 62 69 6c 69 74 69  tting capabiliti
70a0: 65 73 20 73 75 63 68 20 61 73 20 25 68 20 61 6e  es such as %h an
70b0: 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  d %t..*/.void cg
70c0: 69 5f 76 70 72 69 6e 74 66 28 63 6f 6e 73 74 20  i_vprintf(const 
70d0: 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 76  char *zFormat, v
70e0: 61 5f 6c 69 73 74 20 61 70 29 7b 0a 20 20 76 78  a_list ap){.  vx
70f0: 70 72 69 6e 74 66 28 70 43 6f 6e 74 65 6e 74 2c  printf(pContent,
7100: 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 7d 0a 0a  zFormat,ap);.}..
7110: 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20 72 65  ./*.** Send a re
7120: 70 6c 79 20 69 6e 64 69 63 61 74 69 6e 67 20 74  ply indicating t
7130: 68 61 74 20 74 68 65 20 48 54 54 50 20 72 65 71  hat the HTTP req
7140: 75 65 73 74 20 77 61 73 20 6d 61 6c 66 6f 72 6d  uest was malform
7150: 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  ed.*/.static voi
7160: 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75  d malformed_requ
7170: 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 63 67 69  est(void){.  cgi
7180: 5f 73 65 74 5f 73 74 61 74 75 73 28 35 30 31 2c  _set_status(501,
7190: 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e 74 65   "Not Implemente
71a0: 64 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74  d");.  cgi_print
71b0: 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62  f(.    "<html><b
71c0: 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69 7a 65 64  ody>Unrecognized
71d0: 20 48 54 54 50 20 52 65 71 75 65 73 74 3c 2f 62   HTTP Request</b
71e0: 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e 22 0a 20  ody></html>\n". 
71f0: 20 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28   );.  cgi_reply(
7200: 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a  );.  exit(0);.}.
7210: 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 61 6e 64  ./*.** Panic and
7220: 20 64 69 65 20 77 68 69 6c 65 20 70 72 6f 63 65   die while proce
7230: 73 73 69 6e 67 20 61 20 77 65 62 70 61 67 65 2e  ssing a webpage.
7240: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 61 6e  .*/.void cgi_pan
7250: 69 63 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  ic(const char *z
7260: 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20  Format, ...){.  
7270: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 67  va_list ap;.  cg
7280: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28  i_reset_content(
7290: 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61  );.  cgi_set_sta
72a0: 74 75 73 28 35 30 30 2c 20 22 49 6e 74 65 72 6e  tus(500, "Intern
72b0: 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72 22  al Server Error"
72c0: 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28  );.  cgi_printf(
72d0: 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 6f 64  .    "<html><bod
72e0: 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 6c 20 53  y><h1>Internal S
72f0: 65 72 76 65 72 20 45 72 72 6f 72 3c 2f 68 31 3e  erver Error</h1>
7300: 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61 69 6e 74  \n".    "<plaint
7310: 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20 76 61 5f  ext>".  );.  va_
7320: 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61  start(ap, zForma
7330: 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 70  t);.  vxprintf(p
7340: 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c  Content,zFormat,
7350: 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  ap);.  va_end(ap
7360: 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29  );.  cgi_reply()
7370: 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a 0a  ;.  exit(1);.}..
7380: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65  /*.** Remove the
7390: 20 66 69 72 73 74 20 73 70 61 63 65 2d 64 65 6c   first space-del
73a0: 69 6d 69 74 65 64 20 74 6f 6b 65 6e 20 66 72 6f  imited token fro
73b0: 6d 20 61 20 73 74 72 69 6e 67 20 61 6e 64 20 72  m a string and r
73c0: 65 74 75 72 6e 0a 2a 2a 20 61 20 70 6f 69 6e 74  eturn.** a point
73d0: 65 72 20 74 6f 20 69 74 2e 20 20 41 64 64 20 61  er to it.  Add a
73e0: 20 4e 55 4c 4c 20 74 6f 20 74 68 65 20 73 74 72   NULL to the str
73f0: 69 6e 67 20 74 6f 20 74 65 72 6d 69 6e 61 74 65  ing to terminate
7400: 20 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 4d   the token..** M
7410: 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 72 20 70  ake *zLeftOver p
7420: 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72  oint to the star
7430: 74 20 6f 66 20 74 68 65 20 6e 65 78 74 20 74 6f  t of the next to
7440: 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63  ken..*/.static c
7450: 68 61 72 20 2a 65 78 74 72 61 63 74 5f 74 6f 6b  har *extract_tok
7460: 65 6e 28 63 68 61 72 20 2a 7a 49 6e 70 75 74 2c  en(char *zInput,
7470: 20 63 68 61 72 20 2a 2a 7a 4c 65 66 74 4f 76 65   char **zLeftOve
7480: 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65 73  r){.  char *zRes
7490: 75 6c 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 7a  ult = 0;.  if( z
74a0: 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20 20  Input==0 ){.    
74b0: 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 20 29 20  if( zLeftOver ) 
74c0: 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 30 3b 0a  *zLeftOver = 0;.
74d0: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
74e0: 7d 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70 61  }.  while( isspa
74f0: 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a  ce(*zInput) ){ z
7500: 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a 52 65  Input++; }.  zRe
7510: 73 75 6c 74 20 3d 20 7a 49 6e 70 75 74 3b 0a 20  sult = zInput;. 
7520: 20 77 68 69 6c 65 28 20 2a 7a 49 6e 70 75 74 20   while( *zInput 
7530: 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a 49 6e  && !isspace(*zIn
7540: 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b  put) ){ zInput++
7550: 3b 20 7d 0a 20 20 69 66 28 20 2a 7a 49 6e 70 75  ; }.  if( *zInpu
7560: 74 20 29 7b 0a 20 20 20 20 2a 7a 49 6e 70 75 74  t ){.    *zInput
7570: 20 3d 20 30 3b 0a 20 20 20 20 7a 49 6e 70 75 74   = 0;.    zInput
7580: 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69  ++;.    while( i
7590: 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20  sspace(*zInput) 
75a0: 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20  ){ zInput++; }. 
75b0: 20 7d 0a 20 20 69 66 28 20 7a 4c 65 66 74 4f 76   }.  if( zLeftOv
75c0: 65 72 20 29 7b 20 2a 7a 4c 65 66 74 4f 76 65 72  er ){ *zLeftOver
75d0: 20 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a 20 20 72   = zInput; }.  r
75e0: 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a 7d  eturn zResult;.}
75f0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ../*.** This rou
7600: 74 69 6e 65 20 68 61 6e 64 6c 65 73 20 61 20 73  tine handles a s
7610: 69 6e 67 6c 65 20 48 54 54 50 20 72 65 71 75 65  ingle HTTP reque
7620: 73 74 20 77 68 69 63 68 20 69 73 20 63 6f 6d 69  st which is comi
7630: 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74 61 6e  ng in on.** stan
7640: 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20 77  dard input and w
7650: 68 69 63 68 20 72 65 70 6c 69 65 73 20 6f 6e 20  hich replies on 
7660: 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e  standard output.
7670: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 54 50 20  .**.** The HTTP 
7680: 72 65 71 75 65 73 74 20 69 73 20 72 65 61 64 20  request is read 
7690: 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 20 69 6e  from standard in
76a0: 70 75 74 20 61 6e 64 20 69 73 20 75 73 65 64 20  put and is used 
76b0: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 0a 2a 2a  to initialize.**
76c0: 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72   environment var
76d0: 69 61 62 6c 65 73 20 61 73 20 70 65 72 20 43 47  iables as per CG
76e0: 49 2e 20 20 54 68 65 20 63 67 69 5f 69 6e 69 74  I.  The cgi_init
76f0: 28 29 20 72 6f 75 74 69 6e 65 20 74 6f 20 63 6f  () routine to co
7700: 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 65 20 73 65  mplete.** the se
7710: 74 75 70 2e 20 20 4f 6e 63 65 20 61 6c 6c 20 74  tup.  Once all t
7720: 68 65 20 73 65 74 75 70 20 69 73 20 66 69 6e 69  he setup is fini
7730: 73 68 65 64 2c 20 74 68 69 73 20 70 72 6f 63 65  shed, this proce
7740: 64 75 72 65 20 72 65 74 75 72 6e 73 0a 2a 2a 20  dure returns.** 
7750: 61 6e 64 20 73 75 62 73 65 71 75 65 6e 74 20 63  and subsequent c
7760: 6f 64 65 20 68 61 6e 64 6c 65 73 20 74 68 65 20  ode handles the 
7770: 61 63 74 75 61 6c 20 67 65 6e 65 72 61 74 69 6f  actual generatio
7780: 6e 20 6f 66 20 74 68 65 20 77 65 62 70 61 67 65  n of the webpage
7790: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 61  ..*/.void cgi_ha
77a0: 6e 64 6c 65 5f 68 74 74 70 5f 72 65 71 75 65 73  ndle_http_reques
77b0: 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 72 20  t(void){.  char 
77c0: 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 20 69  *z, *zToken;.  i
77d0: 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 74 20 73  nt i;.  struct s
77e0: 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 6d 6f 74  ockaddr_in remot
77f0: 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 5f 74 20  eName;.  size_t 
7800: 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 28 73 74  size = sizeof(st
7810: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e  ruct sockaddr_in
7820: 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 6e 65 5b  );.  char zLine[
7830: 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a 20 41 20  2000];     /* A 
7840: 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 69  single line of i
7850: 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 66 75 6c 6c  nput. */..  full
7860: 48 74 74 70 52 65 70 6c 79 20 3d 20 31 3b 0a 20  HttpReply = 1;. 
7870: 20 69 66 28 20 66 67 65 74 73 28 7a 4c 69 6e 65   if( fgets(zLine
7880: 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c  , sizeof(zLine),
7890: 20 73 74 64 69 6e 29 3d 3d 30 20 29 7b 0a 20 20   stdin)==0 ){.  
78a0: 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75    malformed_requ
78b0: 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 7a 54 6f  est();.  }.  zTo
78c0: 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 5f 74 6f  ken = extract_to
78d0: 6b 65 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29 3b 0a  ken(zLine, &z);.
78e0: 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 20    if( zToken==0 
78f0: 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64  ){.    malformed
7900: 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a  _request();.  }.
7910: 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54 6f    if( strcmp(zTo
7920: 6b 65 6e 2c 22 47 45 54 22 29 21 3d 30 20 26 26  ken,"GET")!=0 &&
7930: 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22   strcmp(zToken,"
7940: 50 4f 53 54 22 29 21 3d 30 0a 20 20 20 20 20 20  POST")!=0.      
7950: 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e  && strcmp(zToken
7960: 2c 22 48 45 41 44 22 29 21 3d 30 20 29 7b 0a 20  ,"HEAD")!=0 ){. 
7970: 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71     malformed_req
7980: 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 63 67  uest();.  }.  cg
7990: 69 5f 73 65 74 65 6e 76 28 22 47 41 54 45 57 41  i_setenv("GATEWA
79a0: 59 5f 49 4e 54 45 52 46 41 43 45 22 2c 22 43 47  Y_INTERFACE","CG
79b0: 49 2f 31 2e 30 22 29 3b 0a 20 20 63 67 69 5f 73  I/1.0");.  cgi_s
79c0: 65 74 65 6e 76 28 22 52 45 51 55 45 53 54 5f 4d  etenv("REQUEST_M
79d0: 45 54 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29 3b 0a  ETHOD",zToken);.
79e0: 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61    zToken = extra
79f0: 63 74 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a 29 3b  ct_token(z, &z);
7a00: 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30  .  if( zToken==0
7a10: 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65   ){.    malforme
7a20: 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d  d_request();.  }
7a30: 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52  .  cgi_setenv("R
7a40: 45 51 55 45 53 54 5f 55 52 49 22 2c 20 7a 54 6f  EQUEST_URI", zTo
7a50: 6b 65 6e 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  ken);.  for(i=0;
7a60: 20 7a 54 6f 6b 65 6e 5b 69 5d 20 26 26 20 7a 54   zToken[i] && zT
7a70: 6f 6b 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20 69 2b  oken[i]!='?'; i+
7a80: 2b 29 7b 7d 0a 20 20 69 66 28 20 7a 54 6f 6b 65  +){}.  if( zToke
7a90: 6e 5b 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b 69 2b  n[i] ) zToken[i+
7aa0: 2b 5d 20 3d 20 30 3b 0a 20 20 63 67 69 5f 73 65  +] = 0;.  cgi_se
7ab0: 74 65 6e 76 28 22 50 41 54 48 5f 49 4e 46 4f 22  tenv("PATH_INFO"
7ac0: 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63 67 69  , zToken);.  cgi
7ad0: 5f 73 65 74 65 6e 76 28 22 51 55 45 52 59 5f 53  _setenv("QUERY_S
7ae0: 54 52 49 4e 47 22 2c 20 26 7a 54 6f 6b 65 6e 5b  TRING", &zToken[
7af0: 69 5d 29 3b 0a 20 20 69 66 28 20 67 65 74 70 65  i]);.  if( getpe
7b00: 65 72 6e 61 6d 65 28 66 69 6c 65 6e 6f 28 73 74  ername(fileno(st
7b10: 64 69 6e 29 2c 20 28 73 74 72 75 63 74 20 73 6f  din), (struct so
7b20: 63 6b 61 64 64 72 2a 29 26 72 65 6d 6f 74 65 4e  ckaddr*)&remoteN
7b30: 61 6d 65 2c 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a  ame, (socklen_t*
7b40: 29 26 73 69 7a 65 29 3e 3d 30 20 29 7b 0a 20 20  )&size)>=0 ){.  
7b50: 20 20 63 68 61 72 20 2a 7a 49 70 41 64 64 72 20    char *zIpAddr 
7b60: 3d 20 69 6e 65 74 5f 6e 74 6f 61 28 72 65 6d 6f  = inet_ntoa(remo
7b70: 74 65 4e 61 6d 65 2e 73 69 6e 5f 61 64 64 72 29  teName.sin_addr)
7b80: 3b 0a 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76  ;.    cgi_setenv
7b90: 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 22 2c 20  ("REMOTE_ADDR", 
7ba0: 7a 49 70 41 64 64 72 29 3b 0a 0a 20 20 20 20 2f  zIpAddr);..    /
7bb0: 2a 20 53 65 74 20 74 68 65 20 47 6c 6f 62 61 6c  * Set the Global
7bc0: 2e 7a 49 70 41 64 64 72 20 76 61 72 69 61 62 6c  .zIpAddr variabl
7bd0: 65 20 74 6f 20 74 68 65 20 73 65 72 76 65 72 20  e to the server 
7be0: 77 65 20 61 72 65 20 74 61 6c 6b 69 6e 67 20 74  we are talking t
7bf0: 6f 2e 0a 20 20 20 20 2a 2a 20 54 68 69 73 20 69  o..    ** This i
7c00: 73 20 75 73 65 64 20 74 6f 20 70 6f 70 75 6c 61  s used to popula
7c10: 74 65 20 74 68 65 20 69 70 61 64 64 72 20 63 6f  te the ipaddr co
7c20: 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 63 76 66  lumn of the rcvf
7c30: 72 6f 6d 20 74 61 62 6c 65 2c 0a 20 20 20 20 2a  rom table,.    *
7c40: 2a 20 69 66 20 61 6e 79 20 66 69 6c 65 73 20 61  * if any files a
7c50: 72 65 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d  re received from
7c60: 20 74 68 65 20 63 6f 6e 6e 65 63 74 65 64 20 63   the connected c
7c70: 6c 69 65 6e 74 2e 0a 20 20 20 20 2a 2f 0a 20 20  lient..    */.  
7c80: 20 20 67 2e 7a 49 70 41 64 64 72 20 3d 20 6d 70    g.zIpAddr = mp
7c90: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 49 70 41  rintf("%s", zIpA
7ca0: 64 64 72 29 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a  ddr);.  }. .  /*
7cb0: 20 47 65 74 20 61 6c 6c 20 74 68 65 20 6f 70 74   Get all the opt
7cc0: 69 6f 6e 61 6c 20 66 69 65 6c 64 73 20 74 68 61  ional fields tha
7cd0: 74 20 66 6f 6c 6c 6f 77 20 74 68 65 20 66 69 72  t follow the fir
7ce0: 73 74 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20  st line..  */.  
7cf0: 77 68 69 6c 65 28 20 66 67 65 74 73 28 7a 4c 69  while( fgets(zLi
7d00: 6e 65 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29  ne,sizeof(zLine)
7d10: 2c 73 74 64 69 6e 29 20 29 7b 0a 20 20 20 20 63  ,stdin) ){.    c
7d20: 68 61 72 20 2a 7a 46 69 65 6c 64 4e 61 6d 65 3b  har *zFieldName;
7d30: 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 3b  .    char *zVal;
7d40: 0a 0a 20 20 20 20 7a 46 69 65 6c 64 4e 61 6d 65  ..    zFieldName
7d50: 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e   = extract_token
7d60: 28 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b 0a 20  (zLine,&zVal);. 
7d70: 20 20 20 69 66 28 20 7a 46 69 65 6c 64 4e 61 6d     if( zFieldNam
7d80: 65 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c 64 4e  e==0 || *zFieldN
7d90: 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a  ame==0 ) break;.
7da0: 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61      while( isspa
7db0: 63 65 28 2a 7a 56 61 6c 29 20 29 7b 20 7a 56 61  ce(*zVal) ){ zVa
7dc0: 6c 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 3d 20 73  l++; }.    i = s
7dd0: 74 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20 20 20  trlen(zVal);.   
7de0: 20 77 68 69 6c 65 28 20 69 3e 30 20 26 26 20 69   while( i>0 && i
7df0: 73 73 70 61 63 65 28 7a 56 61 6c 5b 69 2d 31 5d  sspace(zVal[i-1]
7e00: 29 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20 20 20  ) ){ i--; }.    
7e10: 7a 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 20 20  zVal[i] = 0;.   
7e20: 20 66 6f 72 28 69 3d 30 3b 20 7a 46 69 65 6c 64   for(i=0; zField
7e30: 4e 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b 20 7a  Name[i]; i++){ z
7e40: 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d 20 74  FieldName[i] = t
7e50: 6f 6c 6f 77 65 72 28 7a 46 69 65 6c 64 4e 61 6d  olower(zFieldNam
7e60: 65 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 69 66 28  e[i]); }.    if(
7e70: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61   strcmp(zFieldNa
7e80: 6d 65 2c 22 75 73 65 72 2d 61 67 65 6e 74 3a 22  me,"user-agent:"
7e90: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67  )==0 ){.      cg
7ea0: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 55  i_setenv("HTTP_U
7eb0: 53 45 52 5f 41 47 45 4e 54 22 2c 20 7a 56 61 6c  SER_AGENT", zVal
7ec0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
7ed0: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61   strcmp(zFieldNa
7ee0: 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65 6e 67  me,"content-leng
7ef0: 74 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20  th:")==0 ){.    
7f00: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f    cgi_setenv("CO
7f10: 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 7a  NTENT_LENGTH", z
7f20: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20  Val);.    }else 
7f30: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c  if( strcmp(zFiel
7f40: 64 4e 61 6d 65 2c 22 72 65 66 65 72 65 72 3a 22  dName,"referer:"
7f50: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67  )==0 ){.      cg
7f60: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 52  i_setenv("HTTP_R
7f70: 45 46 45 52 45 52 22 2c 20 7a 56 61 6c 29 3b 0a  EFERER", zVal);.
7f80: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74      }else if( st
7f90: 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c  rcmp(zFieldName,
7fa0: 22 68 6f 73 74 3a 22 29 3d 3d 30 20 29 7b 0a 20  "host:")==0 ){. 
7fb0: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28       cgi_setenv(
7fc0: 22 48 54 54 50 5f 48 4f 53 54 22 2c 20 7a 56 61  "HTTP_HOST", zVa
7fd0: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  l);.    }else if
7fe0: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e  ( strcmp(zFieldN
7ff0: 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70  ame,"content-typ
8000: 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  e:")==0 ){.     
8010: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f 4e   cgi_setenv("CON
8020: 54 45 4e 54 5f 54 59 50 45 22 2c 20 7a 56 61 6c  TENT_TYPE", zVal
8030: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
8040: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61   strcmp(zFieldNa
8050: 6d 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d 3d 30  me,"cookie:")==0
8060: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65   ){.      cgi_se
8070: 74 65 6e 76 28 22 48 54 54 50 5f 43 4f 4f 4b 49  tenv("HTTP_COOKI
8080: 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d  E", zVal);.    }
8090: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28  else if( strcmp(
80a0: 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d 6e  zFieldName,"if-n
80b0: 6f 6e 65 2d 6d 61 74 63 68 3a 22 29 3d 3d 30 20  one-match:")==0 
80c0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74  ){.      cgi_set
80d0: 65 6e 76 28 22 48 54 54 50 5f 49 46 5f 4e 4f 4e  env("HTTP_IF_NON
80e0: 45 5f 4d 41 54 43 48 22 2c 20 7a 56 61 6c 29 3b  E_MATCH", zVal);
80f0: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73  .    }else if( s
8100: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65  trcmp(zFieldName
8110: 2c 22 69 66 2d 6d 6f 64 69 66 69 65 64 2d 73 69  ,"if-modified-si
8120: 6e 63 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20  nce:")==0 ){.   
8130: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48     cgi_setenv("H
8140: 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f  TTP_IF_MODIFIED_
8150: 53 49 4e 43 45 22 2c 20 7a 56 61 6c 29 3b 0a 20  SINCE", zVal);. 
8160: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 67 69 5f     }.  }..  cgi_
8170: 69 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  init();.}../*.**
8180: 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20   Maximum number 
8190: 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73  of child process
81a0: 65 73 20 74 68 61 74 20 77 65 20 63 61 6e 20 68  es that we can h
81b0: 61 76 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20 61  ave running.** a
81c0: 74 20 6f 6e 65 20 74 69 6d 65 20 62 65 66 6f 72  t one time befor
81d0: 65 20 77 65 20 73 74 61 72 74 20 73 6c 6f 77 69  e we start slowi
81e0: 6e 67 20 74 68 69 6e 67 73 20 64 6f 77 6e 2e 0a  ng things down..
81f0: 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 41 58 5f 50  */.#define MAX_P
8200: 41 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a 2a 2a  ARALLEL 2../*.**
8210: 20 49 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 48 54   Implement an HT
8220: 54 50 20 73 65 72 76 65 72 20 64 61 65 6d 6f 6e  TP server daemon
8230: 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20 70 6f   listening on po
8240: 72 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20  rt iPort..**.** 
8250: 41 73 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f  As new connectio
8260: 6e 73 20 61 72 72 69 76 65 2c 20 66 6f 72 6b 20  ns arrive, fork 
8270: 61 20 63 68 69 6c 64 20 61 6e 64 20 6c 65 74 20  a child and let 
8280: 63 68 69 6c 64 20 72 65 74 75 72 6e 0a 2a 2a 20  child return.** 
8290: 6f 75 74 20 6f 66 20 74 68 69 73 20 70 72 6f 63  out of this proc
82a0: 65 64 75 72 65 20 63 61 6c 6c 2e 20 20 54 68 65  edure call.  The
82b0: 20 63 68 69 6c 64 20 77 69 6c 6c 20 68 61 6e 64   child will hand
82c0: 6c 65 20 74 68 65 20 72 65 71 75 65 73 74 2e 0a  le the request..
82d0: 2a 2a 20 54 68 65 20 70 61 72 65 6e 74 20 6e 65  ** The parent ne
82e0: 76 65 72 20 72 65 74 75 72 6e 73 20 66 72 6f 6d  ver returns from
82f0: 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 2e   this procedure.
8300: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 74 74  .*/.void cgi_htt
8310: 70 5f 73 65 72 76 65 72 28 69 6e 74 20 69 50 6f  p_server(int iPo
8320: 72 74 29 7b 0a 23 69 66 64 65 66 20 5f 5f 4d 49  rt){.#ifdef __MI
8330: 4e 47 57 33 32 5f 5f 0a 20 20 66 70 72 69 6e 74  NGW32__.  fprint
8340: 66 28 73 74 64 65 72 72 2c 22 73 65 72 76 65 72  f(stderr,"server
8350: 20 6e 6f 74 20 79 65 74 20 61 76 61 69 6c 61 62   not yet availab
8360: 6c 65 20 69 6e 20 77 69 6e 64 6f 77 73 20 76 65  le in windows ve
8370: 72 73 69 6f 6e 20 6f 66 20 66 6f 73 73 69 6c 5c  rsion of fossil\
8380: 6e 22 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a  n");.  exit(1);.
8390: 23 65 6c 73 65 0a 20 20 69 6e 74 20 6c 69 73 74  #else.  int list
83a0: 65 6e 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ener;           
83b0: 20 20 20 20 20 2f 2a 20 54 68 65 20 73 65 72 76       /* The serv
83c0: 65 72 20 73 6f 63 6b 65 74 20 2a 2f 0a 20 20 69  er socket */.  i
83d0: 6e 74 20 63 6f 6e 6e 65 63 74 69 6f 6e 3b 20 20  nt connection;  
83e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
83f0: 20 73 6f 63 6b 65 74 20 66 6f 72 20 65 61 63 68   socket for each
8400: 20 69 6e 64 69 76 69 64 75 61 6c 20 63 6f 6e 6e   individual conn
8410: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 64 5f 73  ection */.  fd_s
8420: 65 74 20 72 65 61 64 66 64 73 3b 20 20 20 20 20  et readfds;     
8430: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20           /* Set 
8440: 6f 66 20 66 69 6c 65 20 64 65 73 63 72 69 70 74  of file descript
8450: 6f 72 73 20 66 6f 72 20 73 65 6c 65 63 74 28 29  ors for select()
8460: 20 2a 2f 0a 20 20 73 69 7a 65 5f 74 20 6c 65 6e   */.  size_t len
8470: 61 64 64 72 3b 20 20 20 20 20 20 20 20 20 20 20  addr;           
8480: 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20     /* Length of 
8490: 74 68 65 20 69 6e 61 64 64 72 20 73 74 72 75 63  the inaddr struc
84a0: 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20 63 68  ture */.  int ch
84b0: 69 6c 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  ild;            
84c0: 20 20 20 20 20 20 20 2f 2a 20 50 49 44 20 6f 66         /* PID of
84d0: 20 74 68 65 20 63 68 69 6c 64 20 70 72 6f 63 65   the child proce
84e0: 73 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 63 68 69  ss */.  int nchi
84f0: 6c 64 72 65 6e 20 3d 20 30 3b 20 20 20 20 20 20  ldren = 0;      
8500: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
8510: 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 65  f child processe
8520: 73 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 74 69  s */.  struct ti
8530: 6d 65 76 61 6c 20 64 65 6c 61 79 3b 20 20 20 20  meval delay;    
8540: 20 20 20 20 2f 2a 20 48 6f 77 20 6c 6f 6e 67 20      /* How long 
8550: 74 6f 20 77 61 69 74 20 69 6e 73 69 64 65 20 73  to wait inside s
8560: 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 73 74 72  elect() */.  str
8570: 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20  uct sockaddr_in 
8580: 69 6e 61 64 64 72 3b 20 20 20 2f 2a 20 54 68 65  inaddr;   /* The
8590: 20 73 6f 63 6b 65 74 20 61 64 64 72 65 73 73 20   socket address 
85a0: 2a 2f 0a 20 20 69 6e 74 20 6f 70 74 20 3d 20 31  */.  int opt = 1
85b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
85c0: 20 20 2f 2a 20 73 65 74 73 6f 63 6b 6f 70 74 20    /* setsockopt 
85d0: 66 6c 61 67 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65  flag */..  memse
85e0: 74 28 26 69 6e 61 64 64 72 2c 20 30 2c 20 73 69  t(&inaddr, 0, si
85f0: 7a 65 6f 66 28 69 6e 61 64 64 72 29 29 3b 0a 20  zeof(inaddr));. 
8600: 20 69 6e 61 64 64 72 2e 73 69 6e 5f 66 61 6d 69   inaddr.sin_fami
8610: 6c 79 20 3d 20 41 46 5f 49 4e 45 54 3b 0a 20 20  ly = AF_INET;.  
8620: 69 6e 61 64 64 72 2e 73 69 6e 5f 61 64 64 72 2e  inaddr.sin_addr.
8630: 73 5f 61 64 64 72 20 3d 20 49 4e 41 44 44 52 5f  s_addr = INADDR_
8640: 41 4e 59 3b 0a 20 20 69 6e 61 64 64 72 2e 73 69  ANY;.  inaddr.si
8650: 6e 5f 70 6f 72 74 20 3d 20 68 74 6f 6e 73 28 69  n_port = htons(i
8660: 50 6f 72 74 29 3b 0a 20 20 6c 69 73 74 65 6e 65  Port);.  listene
8670: 72 20 3d 20 73 6f 63 6b 65 74 28 41 46 5f 49 4e  r = socket(AF_IN
8680: 45 54 2c 20 53 4f 43 4b 5f 53 54 52 45 41 4d 2c  ET, SOCK_STREAM,
8690: 20 30 29 3b 0a 20 20 69 66 28 20 6c 69 73 74 65   0);.  if( liste
86a0: 6e 65 72 3c 30 20 29 7b 0a 20 20 20 20 66 70 72  ner<0 ){.    fpr
86b0: 69 6e 74 66 28 73 74 64 65 72 72 2c 22 43 61 6e  intf(stderr,"Can
86c0: 27 74 20 63 72 65 61 74 65 20 61 20 73 6f 63 6b  't create a sock
86d0: 65 74 5c 6e 22 29 3b 0a 20 20 20 20 65 78 69 74  et\n");.    exit
86e0: 28 31 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 69  (1);.  }..  /* i
86f0: 66 20 77 65 20 63 61 6e 27 74 20 74 65 72 6d 69  f we can't termi
8700: 6e 61 74 65 20 6e 69 63 65 6c 79 2c 20 61 74 20  nate nicely, at 
8710: 6c 65 61 73 74 20 61 6c 6c 6f 77 20 74 68 65 20  least allow the 
8720: 73 6f 63 6b 65 74 20 74 6f 20 62 65 20 72 65 75  socket to be reu
8730: 73 65 64 20 2a 2f 0a 20 20 73 65 74 73 6f 63 6b  sed */.  setsock
8740: 6f 70 74 28 6c 69 73 74 65 6e 65 72 2c 53 4f 4c  opt(listener,SOL
8750: 5f 53 4f 43 4b 45 54 2c 53 4f 5f 52 45 55 53 45  _SOCKET,SO_REUSE
8760: 41 44 44 52 2c 26 6f 70 74 2c 73 69 7a 65 6f 66  ADDR,&opt,sizeof
8770: 28 6f 70 74 29 29 3b 0a 0a 20 20 69 66 28 20 62  (opt));..  if( b
8780: 69 6e 64 28 6c 69 73 74 65 6e 65 72 2c 20 28 73  ind(listener, (s
8790: 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29  truct sockaddr*)
87a0: 26 69 6e 61 64 64 72 2c 20 73 69 7a 65 6f 66 28  &inaddr, sizeof(
87b0: 69 6e 61 64 64 72 29 29 3c 30 20 29 7b 0a 20 20  inaddr))<0 ){.  
87c0: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72    fprintf(stderr
87d0: 2c 22 43 61 6e 27 74 20 62 69 6e 64 20 74 6f 20  ,"Can't bind to 
87e0: 70 6f 72 74 20 25 64 5c 6e 22 2c 20 69 50 6f 72  port %d\n", iPor
87f0: 74 29 3b 0a 20 20 20 20 65 78 69 74 28 31 29 3b  t);.    exit(1);
8800: 0a 20 20 7d 0a 20 20 6c 69 73 74 65 6e 28 6c 69  .  }.  listen(li
8810: 73 74 65 6e 65 72 2c 31 30 29 3b 0a 20 20 77 68  stener,10);.  wh
8820: 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 69 66  ile( 1 ){.    if
8830: 28 20 6e 63 68 69 6c 64 72 65 6e 3e 4d 41 58 5f  ( nchildren>MAX_
8840: 50 41 52 41 4c 4c 45 4c 20 29 7b 0a 20 20 20 20  PARALLEL ){.    
8850: 20 20 2f 2a 20 53 6c 6f 77 20 64 6f 77 6e 20 69    /* Slow down i
8860: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72  f connections ar
8870: 65 20 61 72 72 69 76 69 6e 67 20 74 6f 6f 20 66  e arriving too f
8880: 61 73 74 20 2a 2f 0a 20 20 20 20 20 20 73 6c 65  ast */.      sle
8890: 65 70 28 20 6e 63 68 69 6c 64 72 65 6e 2d 4d 41  ep( nchildren-MA
88a0: 58 5f 50 41 52 41 4c 4c 45 4c 20 29 3b 0a 20 20  X_PARALLEL );.  
88b0: 20 20 7d 0a 20 20 20 20 64 65 6c 61 79 2e 74 76    }.    delay.tv
88c0: 5f 73 65 63 20 3d 20 36 30 3b 0a 20 20 20 20 64  _sec = 60;.    d
88d0: 65 6c 61 79 2e 74 76 5f 75 73 65 63 20 3d 20 30  elay.tv_usec = 0
88e0: 3b 0a 20 20 20 20 46 44 5f 5a 45 52 4f 28 26 72  ;.    FD_ZERO(&r
88f0: 65 61 64 66 64 73 29 3b 0a 20 20 20 20 46 44 5f  eadfds);.    FD_
8900: 53 45 54 28 20 6c 69 73 74 65 6e 65 72 2c 20 26  SET( listener, &
8910: 72 65 61 64 66 64 73 29 3b 0a 20 20 20 20 69 66  readfds);.    if
8920: 28 20 73 65 6c 65 63 74 28 20 6c 69 73 74 65 6e  ( select( listen
8930: 65 72 2b 31 2c 20 26 72 65 61 64 66 64 73 2c 20  er+1, &readfds, 
8940: 30 2c 20 30 2c 20 26 64 65 6c 61 79 29 20 29 7b  0, 0, &delay) ){
8950: 0a 20 20 20 20 20 20 6c 65 6e 61 64 64 72 20 3d  .      lenaddr =
8960: 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 3b   sizeof(inaddr);
8970: 0a 20 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f  .      connectio
8980: 6e 20 3d 20 61 63 63 65 70 74 28 6c 69 73 74 65  n = accept(liste
8990: 6e 65 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63  ner, (struct soc
89a0: 6b 61 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 20  kaddr*)&inaddr, 
89b0: 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 20 26 6c 65  (socklen_t*) &le
89c0: 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20 69 66  naddr);.      if
89d0: 28 20 63 6f 6e 6e 65 63 74 69 6f 6e 3e 3d 30 20  ( connection>=0 
89e0: 29 7b 0a 20 20 20 20 20 20 20 20 63 68 69 6c 64  ){.        child
89f0: 20 3d 20 66 6f 72 6b 28 29 3b 0a 20 20 20 20 20   = fork();.     
8a00: 20 20 20 69 66 28 20 63 68 69 6c 64 21 3d 30 20     if( child!=0 
8a10: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
8a20: 20 63 68 69 6c 64 3e 30 20 29 20 6e 63 68 69 6c   child>0 ) nchil
8a30: 64 72 65 6e 2b 2b 3b 0a 20 20 20 20 20 20 20 20  dren++;.        
8a40: 20 20 63 6c 6f 73 65 28 63 6f 6e 6e 65 63 74 69    close(connecti
8a50: 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  on);.        }el
8a60: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 63 6c  se{.          cl
8a70: 6f 73 65 28 30 29 3b 0a 20 20 20 20 20 20 20 20  ose(0);.        
8a80: 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e    dup(connection
8a90: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f  );.          clo
8aa0: 73 65 28 31 29 3b 0a 20 20 20 20 20 20 20 20 20  se(1);.         
8ab0: 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29   dup(connection)
8ac0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
8ad0: 21 67 2e 66 48 74 74 70 54 72 61 63 65 20 29 7b  !g.fHttpTrace ){
8ae0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 6c 6f  .            clo
8af0: 73 65 28 32 29 3b 0a 20 20 20 20 20 20 20 20 20  se(2);.         
8b00: 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f     dup(connectio
8b10: 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  n);.          }.
8b20: 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28            close(
8b30: 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20  connection);.   
8b40: 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20         return;. 
8b50: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
8b60: 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75  .    }.    /* Bu
8b70: 72 79 20 64 65 61 64 20 63 68 69 6c 64 72 65 6e  ry dead children
8b80: 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 77   */.    while( w
8b90: 61 69 74 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f  aitpid(0, 0, WNO
8ba0: 48 41 4e 47 29 3e 30 20 29 7b 0a 20 20 20 20 20  HANG)>0 ){.     
8bb0: 20 6e 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20   nchildren--;.  
8bc0: 20 20 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54    }.  }.  /* NOT
8bd0: 20 52 45 41 43 48 45 44 20 2a 2f 20 20 0a 20 20   REACHED */  .  
8be0: 65 78 69 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a  exit(1);.#endif.
8bf0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66  }../*.** Name of
8c00: 20 64 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73   days and months
8c10: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73  ..*/.static cons
8c20: 74 20 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d  t char *azDays[]
8c30: 20 3d 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22   =.    {"Sun", "
8c40: 4d 6f 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65  Mon", "Tue", "We
8c50: 64 22 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22  d", "Thu", "Fri"
8c60: 2c 20 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61  , "Sat", 0};.sta
8c70: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  tic const char *
8c80: 61 7a 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20  azMonths[] =.   
8c90: 20 7b 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20   {"Jan", "Feb", 
8ca0: 22 4d 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d  "Mar", "Apr", "M
8cb0: 61 79 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20  ay", "Jun",.    
8cc0: 20 22 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22   "Jul", "Aug", "
8cd0: 53 65 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f  Sep", "Oct", "No
8ce0: 76 22 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a  v", "Dec", 0};..
8cf0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61  ./*.** Returns a
8d00: 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74  n RFC822-formatt
8d10: 65 64 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73  ed time string s
8d20: 75 69 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50  uitable for HTTP
8d30: 20 68 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a   headers, among.
8d40: 2a 2a 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e  ** other things.
8d50: 0a 2a 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d  .** Returned tim
8d60: 65 7a 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20  ezone is always 
8d70: 47 4d 54 20 61 73 20 72 65 71 75 69 72 65 64 20  GMT as required 
8d80: 62 79 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63  by HTTP/1.1 spec
8d90: 69 66 69 63 61 74 69 6f 6e 2e 0a 2a 2a 20 54 68  ification..** Th
8da0: 65 20 72 65 74 75 72 6e 65 64 20 73 74 72 69 6e  e returned strin
8db0: 67 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 77  g is allocated w
8dc0: 69 74 68 20 6d 61 6c 6c 6f 63 28 29 20 61 6e 64  ith malloc() and
8dd0: 20 6d 75 73 74 20 62 65 20 66 72 65 65 64 0a 2a   must be freed.*
8de0: 2a 20 77 69 74 68 20 66 72 65 65 28 29 2e 0a 2a  * with free()..*
8df0: 2a 0a 2a 2a 20 53 65 65 20 68 74 74 70 3a 2f 2f  *.** See http://
8e00: 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66 63  www.faqs.org/rfc
8e10: 73 2f 72 66 63 38 32 32 2e 68 74 6d 6c 2c 20 73  s/rfc822.html, s
8e20: 65 63 74 69 6f 6e 20 35 0a 2a 2a 20 61 6e 64 20  ection 5.** and 
8e30: 68 74 74 70 3a 2f 2f 77 77 77 2e 66 61 71 73 2e  http://www.faqs.
8e40: 6f 72 67 2f 72 66 63 73 2f 72 66 63 32 36 31 36  org/rfcs/rfc2616
8e50: 2e 68 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 20 33  .html, section 3
8e60: 2e 33 2e 0a 2a 2f 0a 63 68 61 72 20 2a 63 67 69  .3..*/.char *cgi
8e70: 5f 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d  _rfc822_datestam
8e80: 70 28 74 69 6d 65 5f 74 20 6e 6f 77 29 7b 0a 20  p(time_t now){. 
8e90: 20 73 74 72 75 63 74 20 74 6d 20 2a 70 54 6d 3b   struct tm *pTm;
8ea0: 0a 20 20 70 54 6d 20 3d 20 67 6d 74 69 6d 65 28  .  pTm = gmtime(
8eb0: 26 6e 6f 77 29 3b 0a 20 20 69 66 28 20 70 54 6d  &now);.  if( pTm
8ec0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 22 22 3b  ==0 ) return "";
8ed0: 0a 20 20 72 65 74 75 72 6e 20 6d 70 72 69 6e 74  .  return mprint
8ee0: 66 28 22 25 73 2c 20 25 64 20 25 73 20 25 30 32  f("%s, %d %s %02
8ef0: 64 20 25 30 32 64 3a 25 30 32 64 3a 25 30 32 64  d %02d:%02d:%02d
8f00: 20 47 4d 54 22 2c 0a 20 20 20 20 20 20 20 20 20   GMT",.         
8f10: 20 20 20 20 20 20 20 20 61 7a 44 61 79 73 5b 70          azDays[p
8f20: 54 6d 2d 3e 74 6d 5f 77 64 61 79 5d 2c 20 70 54  Tm->tm_wday], pT
8f30: 6d 2d 3e 74 6d 5f 6d 64 61 79 2c 20 61 7a 4d 6f  m->tm_mday, azMo
8f40: 6e 74 68 73 5b 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e  nths[pTm->tm_mon
8f50: 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ],.             
8f60: 20 20 20 20 70 54 6d 2d 3e 74 6d 5f 79 65 61 72      pTm->tm_year
8f70: 2b 31 39 30 30 2c 20 70 54 6d 2d 3e 74 6d 5f 68  +1900, pTm->tm_h
8f80: 6f 75 72 2c 20 70 54 6d 2d 3e 74 6d 5f 6d 69 6e  our, pTm->tm_min
8f90: 2c 20 70 54 6d 2d 3e 74 6d 5f 73 65 63 29 3b 0a  , pTm->tm_sec);.
8fa0: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65 20 61  }../*.** Parse a
8fb0: 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74  n RFC822-formatt
8fc0: 65 64 20 74 69 6d 65 73 74 61 6d 70 20 61 73 20  ed timestamp as 
8fd0: 77 65 27 64 20 65 78 70 65 63 74 20 66 72 6f 6d  we'd expect from
8fe0: 20 48 54 54 50 20 61 6e 64 20 72 65 74 75 72 6e   HTTP and return
8ff0: 0a 2a 2a 20 61 20 55 6e 69 78 20 65 70 6f 63 68  .** a Unix epoch
9000: 20 74 69 6d 65 2e 20 3c 3d 20 7a 65 72 6f 20 69   time. <= zero i
9010: 73 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 66 61  s returned on fa
9020: 69 6c 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74  ilure..**.** Not
9030: 65 20 74 68 61 74 20 74 68 69 73 20 77 6f 6e 27  e that this won'
9040: 74 20 68 61 6e 64 6c 65 20 61 6c 6c 20 74 68 65  t handle all the
9050: 20 5f 61 6c 6c 6f 77 65 64 5f 20 48 54 54 50 20   _allowed_ HTTP 
9060: 66 6f 72 6d 61 74 73 2c 20 6a 75 73 74 20 74 68  formats, just th
9070: 65 0a 2a 2a 20 6d 6f 73 74 20 70 6f 70 75 6c 61  e.** most popula
9080: 72 20 6f 6e 65 20 28 74 68 65 20 6f 6e 65 20 67  r one (the one g
9090: 65 6e 65 72 61 74 65 64 20 62 79 20 63 67 69 5f  enerated by cgi_
90a0: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70  rfc822_datestamp
90b0: 28 29 2c 20 61 63 74 75 61 6c 6c 79 29 2e 0a 2a  (), actually)..*
90c0: 2f 0a 74 69 6d 65 5f 74 20 63 67 69 5f 72 66 63  /.time_t cgi_rfc
90d0: 38 32 32 5f 70 61 72 73 65 64 61 74 65 28 63 6f  822_parsedate(co
90e0: 6e 73 74 20 63 68 61 72 20 2a 7a 44 61 74 65 29  nst char *zDate)
90f0: 7b 0a 20 20 73 74 72 75 63 74 20 74 6d 20 74 3b  {.  struct tm t;
9100: 0a 20 20 63 68 61 72 20 7a 49 67 6e 6f 72 65 5b  .  char zIgnore[
9110: 31 36 5d 3b 0a 20 20 63 68 61 72 20 7a 4d 6f 6e  16];.  char zMon
9120: 74 68 5b 31 36 5d 3b 0a 0a 20 20 6d 65 6d 73 65  th[16];..  memse
9130: 74 28 26 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28  t(&t, 0, sizeof(
9140: 74 29 29 3b 0a 20 20 69 66 28 20 37 3d 3d 73 73  t));.  if( 7==ss
9150: 63 61 6e 66 28 7a 44 61 74 65 2c 20 22 25 31 32  canf(zDate, "%12
9160: 5b 41 2d 5a 61 2d 7a 2c 5d 20 25 64 20 25 31 32  [A-Za-z,] %d %12
9170: 5b 41 2d 5a 61 2d 7a 5d 20 25 64 20 25 64 3a 25  [A-Za-z] %d %d:%
9180: 64 3a 25 64 22 2c 20 7a 49 67 6e 6f 72 65 2c 0a  d:%d", zIgnore,.
9190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
91a0: 20 20 20 20 20 20 20 26 74 2e 74 6d 5f 6d 64 61         &t.tm_mda
91b0: 79 2c 20 7a 4d 6f 6e 74 68 2c 20 26 74 2e 74 6d  y, zMonth, &t.tm
91c0: 5f 79 65 61 72 2c 20 26 74 2e 74 6d 5f 68 6f 75  _year, &t.tm_hou
91d0: 72 2c 20 26 74 2e 74 6d 5f 6d 69 6e 2c 0a 20 20  r, &t.tm_min,.  
91e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
91f0: 20 20 20 20 20 26 74 2e 74 6d 5f 73 65 63 29 29       &t.tm_sec))
9200: 7b 0a 0a 20 20 20 20 69 66 28 20 74 2e 74 6d 5f  {..    if( t.tm_
9210: 79 65 61 72 20 3e 20 31 39 30 30 20 29 20 74 2e  year > 1900 ) t.
9220: 74 6d 5f 79 65 61 72 20 2d 3d 20 31 39 30 30 3b  tm_year -= 1900;
9230: 0a 20 20 20 20 66 6f 72 28 74 2e 74 6d 5f 6d 6f  .    for(t.tm_mo
9240: 6e 3d 30 3b 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e  n=0; azMonths[t.
9250: 74 6d 5f 6d 6f 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f  tm_mon]; t.tm_mo
9260: 6e 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20  n++){.      if( 
9270: 21 73 74 72 6e 63 61 73 65 63 6d 70 28 20 61 7a  !strncasecmp( az
9280: 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d  Months[t.tm_mon]
9290: 2c 20 7a 4d 6f 6e 74 68 2c 20 33 20 29 29 7b 0a  , zMonth, 3 )){.
92a0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 6d          return m
92b0: 6b 67 6d 74 69 6d 65 28 26 74 29 3b 0a 20 20 20  kgmtime(&t);.   
92c0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a     }.    }.  }..
92d0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f    return 0;.}../
92e0: 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 20 73  *.** Convert a s
92f0: 74 72 75 63 74 20 74 6d 2a 20 74 68 61 74 20 72  truct tm* that r
9300: 65 70 72 65 73 65 6e 74 73 20 61 20 6d 6f 6d 65  epresents a mome
9310: 6e 74 20 69 6e 20 55 54 43 20 69 6e 74 6f 20 74  nt in UTC into t
9320: 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20  he number.** of 
9330: 73 65 63 6f 6e 64 73 20 69 6e 20 31 39 37 30 2c  seconds in 1970,
9340: 20 55 54 43 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20   UTC..*/.time_t 
9350: 6d 6b 67 6d 74 69 6d 65 28 73 74 72 75 63 74 20  mkgmtime(struct 
9360: 74 6d 20 2a 70 29 7b 0a 20 20 74 69 6d 65 5f 74  tm *p){.  time_t
9370: 20 74 3b 0a 20 20 69 6e 74 20 6e 44 61 79 3b 0a   t;.  int nDay;.
9380: 20 20 69 6e 74 20 69 73 4c 65 61 70 59 72 3b 0a    int isLeapYr;.
9390: 20 20 2f 2a 20 44 61 79 73 20 69 6e 20 65 61 63    /* Days in eac
93a0: 68 20 6d 6f 6e 74 68 3a 20 20 20 20 20 20 20 33  h month:       3
93b0: 31 2c 20 32 38 2c 20 33 31 2c 20 33 30 2c 20 33  1, 28, 31, 30, 3
93c0: 31 2c 20 33 30 2c 20 33 31 2c 20 33 31 2c 20 33  1, 30, 31, 31, 3
93d0: 30 2c 20 33 31 2c 20 33 30 2c 20 33 31 20 2a 2f  0, 31, 30, 31 */
93e0: 0a 20 20 73 74 61 74 69 63 20 69 6e 74 20 70 72  .  static int pr
93f0: 69 6f 72 44 61 79 73 5b 5d 20 20 20 3d 20 7b 20  iorDays[]   = { 
9400: 20 30 2c 20 33 31 2c 20 35 39 2c 20 39 30 2c 31   0, 31, 59, 90,1
9410: 32 30 2c 31 35 31 2c 31 38 31 2c 32 31 32 2c 32  20,151,181,212,2
9420: 34 33 2c 32 37 33 2c 33 30 34 2c 33 33 34 20 7d  43,273,304,334 }
9430: 3b 0a 20 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f  ;.  if( p->tm_mo
9440: 6e 3c 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e  n<0 ){.    int n
9450: 59 65 61 72 20 3d 20 28 31 31 20 2d 20 70 2d 3e  Year = (11 - p->
9460: 74 6d 5f 6d 6f 6e 29 2f 31 32 3b 0a 20 20 20 20  tm_mon)/12;.    
9470: 70 2d 3e 74 6d 5f 79 65 61 72 20 2d 3d 20 6e 59  p->tm_year -= nY
9480: 65 61 72 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d  ear;.    p->tm_m
9490: 6f 6e 20 2b 3d 20 6e 59 65 61 72 2a 31 32 3b 0a  on += nYear*12;.
94a0: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 74    }else if( p->t
94b0: 6d 5f 6d 6f 6e 3e 31 31 20 29 7b 0a 20 20 20 20  m_mon>11 ){.    
94c0: 70 2d 3e 74 6d 5f 79 65 61 72 20 2b 3d 20 70 2d  p->tm_year += p-
94d0: 3e 74 6d 5f 6d 6f 6e 2f 31 32 3b 0a 20 20 20 20  >tm_mon/12;.    
94e0: 70 2d 3e 74 6d 5f 6d 6f 6e 20 25 3d 20 31 32 3b  p->tm_mon %= 12;
94f0: 0a 20 20 7d 0a 20 20 69 73 4c 65 61 70 59 72 20  .  }.  isLeapYr 
9500: 3d 20 70 2d 3e 74 6d 5f 79 65 61 72 25 34 3d 3d  = p->tm_year%4==
9510: 30 20 26 26 20 28 70 2d 3e 74 6d 5f 79 65 61 72  0 && (p->tm_year
9520: 25 31 30 30 21 3d 30 20 7c 7c 20 28 70 2d 3e 74  %100!=0 || (p->t
9530: 6d 5f 79 65 61 72 2b 33 30 30 29 25 34 30 30 3d  m_year+300)%400=
9540: 3d 30 29 3b 0a 20 20 70 2d 3e 74 6d 5f 79 64 61  =0);.  p->tm_yda
9550: 79 20 3d 20 70 72 69 6f 72 44 61 79 73 5b 70 2d  y = priorDays[p-
9560: 3e 74 6d 5f 6d 6f 6e 5d 20 2b 20 70 2d 3e 74 6d  >tm_mon] + p->tm
9570: 5f 6d 64 61 79 20 2d 20 31 3b 0a 20 20 69 66 28  _mday - 1;.  if(
9580: 20 69 73 4c 65 61 70 59 72 20 26 26 20 70 2d 3e   isLeapYr && p->
9590: 74 6d 5f 6d 6f 6e 3e 31 20 29 20 70 2d 3e 74 6d  tm_mon>1 ) p->tm
95a0: 5f 79 64 61 79 2b 2b 3b 0a 20 20 6e 44 61 79 20  _yday++;.  nDay 
95b0: 3d 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 37 30  = (p->tm_year-70
95c0: 29 2a 33 36 35 20 2b 20 28 70 2d 3e 74 6d 5f 79  )*365 + (p->tm_y
95d0: 65 61 72 2d 36 39 29 2f 34 20 2d 70 2d 3e 74 6d  ear-69)/4 -p->tm
95e0: 5f 79 65 61 72 2f 31 30 30 20 2b 20 0a 20 20 20  _year/100 + .   
95f0: 20 20 20 20 20 20 28 70 2d 3e 74 6d 5f 79 65 61        (p->tm_yea
9600: 72 2b 33 30 30 29 2f 34 30 30 20 2b 20 70 2d 3e  r+300)/400 + p->
9610: 74 6d 5f 79 64 61 79 3b 0a 20 20 74 20 3d 20 28  tm_yday;.  t = (
9620: 28 6e 44 61 79 2a 32 34 20 2b 20 70 2d 3e 74 6d  (nDay*24 + p->tm
9630: 5f 68 6f 75 72 29 2a 36 30 20 2b 20 70 2d 3e 74  _hour)*60 + p->t
9640: 6d 5f 6d 69 6e 29 2a 36 30 20 2b 20 70 2d 3e 74  m_min)*60 + p->t
9650: 6d 5f 73 65 63 3b 0a 20 20 72 65 74 75 72 6e 20  m_sec;.  return 
9660: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63  t;.}../*.** Chec
9670: 6b 20 74 68 65 20 6f 62 6a 65 63 74 54 69 6d 65  k the objectTime
9680: 20 61 67 61 69 6e 73 74 20 74 68 65 20 49 66 2d   against the If-
9690: 4d 6f 64 69 66 69 65 64 2d 53 69 6e 63 65 20 72  Modified-Since r
96a0: 65 71 75 65 73 74 20 68 65 61 64 65 72 2e 20 49  equest header. I
96b0: 66 20 74 68 65 0a 2a 2a 20 6f 62 6a 65 63 74 20  f the.** object 
96c0: 74 69 6d 65 20 69 73 6e 27 74 20 61 6e 79 20 6e  time isn't any n
96d0: 65 77 65 72 20 74 68 61 6e 20 74 68 65 20 68 65  ewer than the he
96e0: 61 64 65 72 2c 20 77 65 20 69 6d 6d 65 64 69 61  ader, we immedia
96f0: 74 65 6c 79 20 73 65 6e 64 20 62 61 63 6b 0a 2a  tely send back.*
9700: 2a 20 61 20 33 30 34 20 72 65 70 6c 79 20 61 6e  * a 304 reply an
9710: 64 20 65 78 69 74 2e 0a 2a 2f 0a 76 6f 69 64 20  d exit..*/.void 
9720: 63 67 69 5f 6d 6f 64 69 66 69 65 64 5f 73 69 6e  cgi_modified_sin
9730: 63 65 28 74 69 6d 65 5f 74 20 6f 62 6a 65 63 74  ce(time_t object
9740: 54 69 6d 65 29 7b 0a 20 20 63 6f 6e 73 74 20 63  Time){.  const c
9750: 68 61 72 20 2a 7a 49 66 20 3d 20 50 28 22 48 54  har *zIf = P("HT
9760: 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f 53  TP_IF_MODIFIED_S
9770: 49 4e 43 45 22 29 3b 0a 20 20 69 66 28 20 7a 49  INCE");.  if( zI
9780: 66 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20  f==0 ) return;. 
9790: 20 69 66 28 20 6f 62 6a 65 63 74 54 69 6d 65 20   if( objectTime 
97a0: 3e 20 63 67 69 5f 72 66 63 38 32 32 5f 70 61 72  > cgi_rfc822_par
97b0: 73 65 64 61 74 65 28 7a 49 66 29 20 29 20 72 65  sedate(zIf) ) re
97c0: 74 75 72 6e 3b 0a 20 20 63 67 69 5f 73 65 74 5f  turn;.  cgi_set_
97d0: 73 74 61 74 75 73 28 33 30 34 2c 22 4e 6f 74 20  status(304,"Not 
97e0: 4d 6f 64 69 66 69 65 64 22 29 3b 0a 20 20 63 67  Modified");.  cg
97f0: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28  i_reset_content(
9800: 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29  );.  cgi_reply()
9810: 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a     ;.  exit(0);.}.