Hex Artifact Content
Not logged in

Artifact a795dc49f1ddae659feef0e7218c756bb71ba41d:

File src/cgi.c part of check-in [6af8fdc230] - Generate CGI replies as separate header and body so that the header can be extended during the construction of the body. by drh on 2007-12-04 13:05:35. Also file src/cgi.c part of check-in [b312f5ff5b] - Merge in some changes to the CGI reply generator that we made back in early December but got lost on an abandoned branch. Distributed version control is nice, but it also leaves open the real danger of losing changes this way. We need to work on interface features to minimize the risk of losing changes like this, and to identify lost changes quickly. by drh on 2008-02-03 02:41:50.

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 73 3b 20 56 65 72 73 69 6f 6e 3d 31 5c  s=%s; 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 3b 0a 20 20 69 66 28 20 69  al_size;.  if( i
1d80: 52 65 70 6c 79 53 74 61 74 75 73 3c 3d 30 20 29  ReplyStatus<=0 )
1d90: 7b 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 74  {.    iReplyStat
1da0: 75 73 20 3d 20 32 30 30 3b 0a 20 20 20 20 7a 52  us = 200;.    zR
1db0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4f 4b  eplyStatus = "OK
1dc0: 22 3b 0a 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20  ";.  }..#if 0.  
1dd0: 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73  if( iReplyStatus
1de0: 3d 3d 32 30 30 20 26 26 20 63 68 65 63 6b 5f 63  ==200 && check_c
1df0: 61 63 68 65 5f 63 6f 6e 74 72 6f 6c 28 29 20 29  ache_control() )
1e00: 20 7b 0a 20 20 20 20 2f 2a 20 63 68 61 6e 67 65   {.    /* change
1e10: 20 74 68 65 20 73 74 61 74 75 73 20 74 6f 20 22   the status to "
1e20: 75 6e 63 68 61 6e 67 65 64 22 20 61 6e 64 20 77  unchanged" and w
1e30: 65 20 63 61 6e 20 73 6b 69 70 20 73 65 6e 64 69  e can skip sendi
1e40: 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a 20 61 63  ng the.    ** ac
1e50: 74 75 61 6c 20 72 65 73 70 6f 6e 73 65 20 62 6f  tual response bo
1e60: 64 79 2e 20 4f 62 76 69 6f 75 73 6c 79 20 77 65  dy. Obviously we
1e70: 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73 20 77 68   only do this wh
1e80: 65 6e 20 77 65 20 5f 68 61 76 65 5f 20 61 0a 20  en we _have_ a. 
1e90: 20 20 20 2a 2a 20 62 6f 64 79 20 28 63 6f 64 65     ** body (code
1ea0: 20 32 30 30 29 2e 0a 20 20 20 20 2a 2f 0a 20 20   200)..    */.  
1eb0: 20 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d    iReplyStatus =
1ec0: 20 33 30 34 3b 0a 20 20 20 20 7a 52 65 70 6c 79   304;.    zReply
1ed0: 53 74 61 74 75 73 20 3d 20 22 4e 6f 74 20 4d 6f  Status = "Not Mo
1ee0: 64 69 66 69 65 64 22 3b 0a 20 20 7d 0a 23 65 6e  dified";.  }.#en
1ef0: 64 69 66 0a 0a 20 20 69 66 28 20 66 75 6c 6c 48  dif..  if( fullH
1f00: 74 74 70 52 65 70 6c 79 20 29 7b 0a 20 20 20 20  ttpReply ){.    
1f10: 70 72 69 6e 74 66 28 22 48 54 54 50 2f 31 2e 30  printf("HTTP/1.0
1f20: 20 25 64 20 25 73 5c 72 5c 6e 22 2c 20 69 52 65   %d %s\r\n", iRe
1f30: 70 6c 79 53 74 61 74 75 73 2c 20 7a 52 65 70 6c  plyStatus, zRepl
1f40: 79 53 74 61 74 75 73 29 3b 0a 20 20 20 20 70 72  yStatus);.    pr
1f50: 69 6e 74 66 28 22 44 61 74 65 3a 20 25 73 5c 72  intf("Date: %s\r
1f60: 5c 6e 22 2c 20 63 67 69 5f 72 66 63 38 32 32 5f  \n", cgi_rfc822_
1f70: 64 61 74 65 73 74 61 6d 70 28 74 69 6d 65 28 30  datestamp(time(0
1f80: 29 29 29 3b 0a 20 20 20 20 70 72 69 6e 74 66 28  )));.    printf(
1f90: 22 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f  "Connection: clo
1fa0: 73 65 5c 72 5c 6e 22 29 3b 0a 20 20 7d 65 6c 73  se\r\n");.  }els
1fb0: 65 7b 0a 20 20 20 20 70 72 69 6e 74 66 28 22 53  e{.    printf("S
1fc0: 74 61 74 75 73 3a 20 25 64 20 25 73 5c 72 5c 6e  tatus: %d %s\r\n
1fd0: 22 2c 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c  ", iReplyStatus,
1fe0: 20 7a 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a   zReplyStatus);.
1ff0: 20 20 7d 0a 0a 20 20 69 66 28 20 62 6c 6f 62 5f    }..  if( blob_
2000: 73 69 7a 65 28 26 65 78 74 72 61 48 65 61 64 65  size(&extraHeade
2010: 72 29 3e 30 20 29 7b 0a 20 20 20 20 70 72 69 6e  r)>0 ){.    prin
2020: 74 66 28 22 25 73 22 2c 20 62 6c 6f 62 5f 62 75  tf("%s", blob_bu
2030: 66 66 65 72 28 26 65 78 74 72 61 48 65 61 64 65  ffer(&extraHeade
2040: 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  r));.  }..  if( 
2050: 67 2e 69 73 43 6f 6e 73 74 20 29 7b 0a 20 20 20  g.isConst ){.   
2060: 20 2f 2a 20 63 6f 6e 73 74 61 6e 74 20 6d 65 61   /* constant mea
2070: 6e 73 20 74 68 61 74 20 74 68 65 20 69 6e 70 75  ns that the inpu
2080: 74 20 55 52 4c 20 77 69 6c 6c 20 5f 6e 65 76 65  t URL will _neve
2090: 72 5f 20 67 65 6e 65 72 61 74 65 20 61 6e 79 74  r_ generate anyt
20a0: 68 69 6e 67 0a 20 20 20 20 2a 2a 20 65 6c 73 65  hing.    ** else
20b0: 2e 20 49 6e 20 74 68 65 20 63 61 73 65 20 6f 66  . In the case of
20c0: 20 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 74 68   attachments, th
20d0: 65 20 63 6f 6e 74 65 6e 74 73 20 77 6f 6e 27 74  e contents won't
20e0: 20 63 68 61 6e 67 65 20 62 65 63 61 75 73 65 0a   change because.
20f0: 20 20 20 20 2a 2a 20 61 6e 20 61 74 74 65 6d 70      ** an attemp
2100: 74 20 74 6f 20 63 68 61 6e 67 65 20 74 68 65 6d  t to change them
2110: 20 67 65 6e 65 72 61 74 65 73 20 61 20 6e 65 77   generates a new
2120: 20 61 74 74 61 63 68 6d 65 6e 74 20 6e 75 6d 62   attachment numb
2130: 65 72 2e 20 49 6e 20 74 68 65 0a 20 20 20 20 2a  er. In the.    *
2140: 2a 20 63 61 73 65 20 6f 66 20 6d 6f 73 74 20 2f  * case of most /
2150: 67 65 74 66 69 6c 65 20 63 61 6c 6c 73 20 66 6f  getfile calls fo
2160: 72 20 73 70 65 63 69 66 69 63 20 76 65 72 73 69  r specific versi
2170: 6f 6e 73 2c 20 74 68 65 20 6f 6e 6c 79 20 77 61  ons, the only wa
2180: 79 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e  y the.    ** con
2190: 74 65 6e 74 20 63 68 61 6e 67 65 73 20 69 73 20  tent changes is 
21a0: 69 66 20 73 6f 6d 65 6f 6e 65 20 62 72 65 61 6b  if someone break
21b0: 73 20 74 68 65 20 53 43 4d 2e 20 41 6e 64 20 69  s the SCM. And i
21c0: 66 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c 20  f that happens, 
21d0: 61 0a 20 20 20 20 2a 2a 20 73 74 61 6c 65 20 63  a.    ** stale c
21e0: 61 63 68 65 20 69 73 20 74 68 65 20 6c 65 61 73  ache is the leas
21f0: 74 20 6f 66 20 74 68 65 20 70 72 6f 62 6c 65 6d  t of the problem
2200: 2e 20 53 6f 20 77 65 20 70 72 6f 76 69 64 65 20  . So we provide 
2210: 61 6e 20 45 78 70 69 72 65 73 0a 20 20 20 20 2a  an Expires.    *
2220: 2a 20 68 65 61 64 65 72 20 73 65 74 20 74 6f 20  * header set to 
2230: 61 20 72 65 61 73 6f 6e 61 62 6c 65 20 70 65 72  a reasonable per
2240: 69 6f 64 20 28 64 65 66 61 75 6c 74 3a 20 6f 6e  iod (default: on
2250: 65 20 77 65 65 6b 29 2e 0a 20 20 20 20 2a 2f 0a  e week)..    */.
2260: 20 20 20 20 2f 2a 74 69 6d 65 5f 74 20 65 78 70      /*time_t exp
2270: 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 2b  ires = time(0) +
2280: 20 61 74 6f 69 28 64 62 5f 63 6f 6e 66 69 67 28   atoi(db_config(
2290: 22 63 6f 6e 73 74 61 6e 74 5f 65 78 70 69 72 65  "constant_expire
22a0: 73 22 2c 22 36 30 34 38 30 30 22 29 29 3b 2a 2f  s","604800"));*/
22b0: 0a 20 20 20 20 74 69 6d 65 5f 74 20 65 78 70 69  .    time_t expi
22c0: 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 2b 20  res = time(0) + 
22d0: 36 30 34 38 30 30 3b 0a 20 20 20 20 70 72 69 6e  604800;.    prin
22e0: 74 66 28 20 22 45 78 70 69 72 65 73 3a 20 25 73  tf( "Expires: %s
22f0: 5c 72 5c 6e 22 2c 20 63 67 69 5f 72 66 63 38 32  \r\n", cgi_rfc82
2300: 32 5f 64 61 74 65 73 74 61 6d 70 28 65 78 70 69  2_datestamp(expi
2310: 72 65 73 29 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  res));.  }..  /*
2320: 20 43 6f 6e 74 65 6e 74 20 69 6e 74 65 6e 64 65   Content intende
2330: 64 20 66 6f 72 20 6c 6f 67 67 65 64 20 69 6e 20  d for logged in 
2340: 75 73 65 72 73 20 73 68 6f 75 6c 64 20 6f 6e 6c  users should onl
2350: 79 20 62 65 20 63 61 63 68 65 64 20 69 6e 0a 20  y be cached in. 
2360: 20 2a 2a 20 74 68 65 20 62 72 6f 77 73 65 72 2c   ** the browser,
2370: 20 6e 6f 74 20 73 6f 6d 65 20 73 68 61 72 65 64   not some shared
2380: 20 6c 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a 2f 0a   location..  */.
2390: 20 20 70 72 69 6e 74 66 28 22 43 61 63 68 65 2d    printf("Cache-
23a0: 63 6f 6e 74 72 6f 6c 3a 20 70 72 69 76 61 74 65  control: private
23b0: 5c 72 5c 6e 22 29 3b 0a 0a 23 69 66 20 46 4f 53  \r\n");..#if FOS
23c0: 53 49 4c 5f 49 31 38 4e 0a 20 20 70 72 69 6e 74  SIL_I18N.  print
23d0: 66 28 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65  f( "Content-Type
23e0: 3a 20 25 73 3b 20 63 68 61 72 73 65 74 3d 25 73  : %s; charset=%s
23f0: 5c 72 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54  \r\n", zContentT
2400: 79 70 65 2c 20 6e 6c 5f 6c 61 6e 67 69 6e 66 6f  ype, nl_langinfo
2410: 28 43 4f 44 45 53 45 54 29 29 3b 0a 23 65 6c 73  (CODESET));.#els
2420: 65 0a 20 20 70 72 69 6e 74 66 28 20 22 43 6f 6e  e.  printf( "Con
2430: 74 65 6e 74 2d 54 79 70 65 3a 20 25 73 3b 20 63  tent-Type: %s; c
2440: 68 61 72 73 65 74 3d 49 53 4f 2d 38 38 35 39 2d  harset=ISO-8859-
2450: 31 5c 72 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74  1\r\n", zContent
2460: 54 79 70 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20  Type);.#endif.  
2470: 69 66 28 20 73 74 72 63 6d 70 28 7a 43 6f 6e 74  if( strcmp(zCont
2480: 65 6e 74 54 79 70 65 2c 22 61 70 70 6c 69 63 61  entType,"applica
2490: 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d  tion/x-fossil")=
24a0: 3d 30 20 29 7b 0a 20 20 20 20 63 67 69 5f 63 6f  =0 ){.    cgi_co
24b0: 6d 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64  mbine_header_and
24c0: 5f 62 6f 64 79 28 29 3b 0a 20 20 20 20 62 6c 6f  _body();.    blo
24d0: 62 5f 63 6f 6d 70 72 65 73 73 28 26 63 67 69 43  b_compress(&cgiC
24e0: 6f 6e 74 65 6e 74 5b 30 5d 2c 20 26 63 67 69 43  ontent[0], &cgiC
24f0: 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 20 20 7d 0a  ontent[0]);.  }.
2500: 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 74 61  .  if( iReplySta
2510: 74 75 73 20 21 3d 20 33 30 34 20 29 20 7b 0a 20  tus != 304 ) {. 
2520: 20 20 20 74 6f 74 61 6c 5f 73 69 7a 65 20 3d 20     total_size = 
2530: 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f  blob_size(&cgiCo
2540: 6e 74 65 6e 74 5b 30 5d 29 20 2b 20 62 6c 6f 62  ntent[0]) + blob
2550: 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e  _size(&cgiConten
2560: 74 5b 31 5d 29 3b 0a 20 20 20 20 70 72 69 6e 74  t[1]);.    print
2570: 66 28 20 22 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67  f( "Content-Leng
2580: 74 68 3a 20 25 64 5c 72 5c 6e 22 2c 20 74 6f 74  th: %d\r\n", tot
2590: 61 6c 5f 73 69 7a 65 29 3b 0a 20 20 7d 0a 20 20  al_size);.  }.  
25a0: 70 72 69 6e 74 66 28 22 5c 72 5c 6e 22 29 3b 0a  printf("\r\n");.
25b0: 20 20 69 66 28 20 74 6f 74 61 6c 5f 73 69 7a 65    if( total_size
25c0: 3e 30 20 26 26 20 69 52 65 70 6c 79 53 74 61 74  >0 && iReplyStat
25d0: 75 73 20 21 3d 20 33 30 34 20 29 7b 0a 20 20 20  us != 304 ){.   
25e0: 20 69 6e 74 20 69 2c 20 73 69 7a 65 3b 0a 20 20   int i, size;.  
25f0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 32 3b 20    for(i=0; i<2; 
2600: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 73 69 7a 65  i++){.      size
2610: 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67   = blob_size(&cg
2620: 69 43 6f 6e 74 65 6e 74 5b 69 5d 29 3b 0a 20 20  iContent[i]);.  
2630: 20 20 20 20 69 66 28 20 73 69 7a 65 3e 30 20 29      if( size>0 )
2640: 7b 0a 20 20 20 20 20 20 20 20 66 77 72 69 74 65  {.        fwrite
2650: 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67  (blob_buffer(&cg
2660: 69 43 6f 6e 74 65 6e 74 5b 69 5d 29 2c 20 31 2c  iContent[i]), 1,
2670: 20 73 69 7a 65 2c 20 73 74 64 6f 75 74 29 3b 0a   size, stdout);.
2680: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
2690: 7d 0a 20 20 43 47 49 44 45 42 55 47 28 28 22 44  }.  CGIDEBUG(("D
26a0: 4f 4e 45 5c 6e 22 29 29 3b 0a 7d 0a 0a 2f 2a 0a  ONE\n"));.}../*.
26b0: 2a 2a 20 44 6f 20 61 20 72 65 64 69 72 65 63 74  ** Do a redirect
26c0: 20 72 65 71 75 65 73 74 20 74 6f 20 74 68 65 20   request to the 
26d0: 55 52 4c 20 67 69 76 65 6e 20 69 6e 20 74 68 65  URL given in the
26e0: 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a   argument..**.**
26f0: 20 54 68 65 20 55 52 4c 20 6d 75 73 74 20 62 65   The URL must be
2700: 20 72 65 6c 61 74 69 76 65 20 74 6f 20 74 68 65   relative to the
2710: 20 62 61 73 65 20 6f 66 20 74 68 65 20 66 6f 73   base of the fos
2720: 73 69 6c 20 73 65 72 76 65 72 2e 0a 2a 2f 0a 76  sil server..*/.v
2730: 6f 69 64 20 63 67 69 5f 72 65 64 69 72 65 63 74  oid cgi_redirect
2740: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 52  (const char *zUR
2750: 4c 29 7b 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 63  L){.  char *zLoc
2760: 61 74 69 6f 6e 3b 0a 20 20 43 47 49 44 45 42 55  ation;.  CGIDEBU
2770: 47 28 28 22 72 65 64 69 72 65 63 74 20 74 6f 20  G(("redirect to 
2780: 25 73 5c 6e 22 2c 20 7a 55 52 4c 29 29 3b 0a 20  %s\n", zURL));. 
2790: 20 69 66 28 20 73 74 72 6e 63 6d 70 28 7a 55 52   if( strncmp(zUR
27a0: 4c 2c 22 68 74 74 70 3a 22 2c 35 29 3d 3d 30 20  L,"http:",5)==0 
27b0: 7c 7c 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c  || strncmp(zURL,
27c0: 22 68 74 74 70 73 3a 22 2c 36 29 3d 3d 30 20 7c  "https:",6)==0 |
27d0: 7c 20 2a 7a 55 52 4c 3d 3d 27 2f 27 20 29 7b 0a  | *zURL=='/' ){.
27e0: 20 20 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20      zLocation = 
27f0: 6d 70 72 69 6e 74 66 28 22 4c 6f 63 61 74 69 6f  mprintf("Locatio
2800: 6e 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 55 52 4c  n: %s\r\n", zURL
2810: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
2820: 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 72 69  zLocation = mpri
2830: 6e 74 66 28 22 4c 6f 63 61 74 69 6f 6e 3a 20 25  ntf("Location: %
2840: 73 2f 25 73 5c 72 5c 6e 22 2c 20 67 2e 7a 42 61  s/%s\r\n", g.zBa
2850: 73 65 55 52 4c 2c 20 7a 55 52 4c 29 3b 0a 20 20  seURL, zURL);.  
2860: 7d 0a 20 20 63 67 69 5f 61 70 70 65 6e 64 5f 68  }.  cgi_append_h
2870: 65 61 64 65 72 28 7a 4c 6f 63 61 74 69 6f 6e 29  eader(zLocation)
2880: 3b 0a 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f  ;.  cgi_reset_co
2890: 6e 74 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f 70  ntent();.  cgi_p
28a0: 72 69 6e 74 66 28 22 3c 68 74 6d 6c 3e 5c 6e 3c  rintf("<html>\n<
28b0: 70 3e 52 65 64 69 72 65 63 74 20 74 6f 20 25 68  p>Redirect to %h
28c0: 3c 2f 70 3e 5c 6e 3c 2f 68 74 6d 6c 3e 5c 6e 22  </p>\n</html>\n"
28d0: 2c 20 7a 55 52 4c 29 3b 0a 20 20 63 67 69 5f 73  , zURL);.  cgi_s
28e0: 65 74 5f 73 74 61 74 75 73 28 33 30 32 2c 20 22  et_status(302, "
28f0: 4d 6f 76 65 64 20 54 65 6d 70 6f 72 61 72 69 6c  Moved Temporaril
2900: 79 22 29 3b 0a 20 20 66 72 65 65 28 7a 4c 6f 63  y");.  free(zLoc
2910: 61 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65  ation);.  cgi_re
2920: 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29  ply();.  exit(0)
2930: 3b 0a 7d 0a 76 6f 69 64 20 63 67 69 5f 72 65 64  ;.}.void cgi_red
2940: 69 72 65 63 74 66 28 63 6f 6e 73 74 20 63 68 61  irectf(const cha
2950: 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29  r *zFormat, ...)
2960: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  {.  va_list ap;.
2970: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a    va_start(ap, z
2980: 46 6f 72 6d 61 74 29 3b 0a 20 20 63 67 69 5f 72  Format);.  cgi_r
2990: 65 64 69 72 65 63 74 28 76 6d 70 72 69 6e 74 66  edirect(vmprintf
29a0: 28 7a 46 6f 72 6d 61 74 2c 20 61 70 29 29 3b 0a  (zFormat, ap));.
29b0: 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a    va_end(ap);.}.
29c0: 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f 72 6d 61 74 69  ./*.** Informati
29d0: 6f 6e 20 61 62 6f 75 74 20 61 6c 6c 20 71 75 65  on about all que
29e0: 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e  ry parameters an
29f0: 64 20 63 6f 6f 6b 69 65 73 20 61 72 65 20 73 74  d cookies are st
2a00: 6f 72 65 64 0a 2a 2a 20 69 6e 20 74 68 65 73 65  ored.** in these
2a10: 20 76 61 72 69 61 62 6c 65 73 2e 0a 2a 2f 0a 73   variables..*/.s
2a20: 74 61 74 69 63 20 69 6e 74 20 6e 41 6c 6c 6f 63  tatic int nAlloc
2a30: 51 50 20 3d 20 30 3b 20 2f 2a 20 53 70 61 63 65  QP = 0; /* Space
2a40: 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61   allocated for a
2a50: 50 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61  ParamQP[] */.sta
2a60: 74 69 63 20 69 6e 74 20 6e 55 73 65 64 51 50 20  tic int nUsedQP 
2a70: 3d 20 30 3b 20 20 2f 2a 20 53 70 61 63 65 20 61  = 0;  /* Space a
2a80: 63 74 75 61 6c 6c 79 20 75 73 65 64 20 69 6e 20  ctually used in 
2a90: 61 50 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74  aParamQP[] */.st
2aa0: 61 74 69 63 20 69 6e 74 20 73 6f 72 74 51 50 20  atic int sortQP 
2ab0: 3d 20 30 3b 20 20 20 2f 2a 20 54 72 75 65 20 69  = 0;   /* True i
2ac0: 66 20 61 50 61 72 61 6d 51 50 5b 5d 20 6e 65 65  f aParamQP[] nee
2ad0: 64 73 20 73 6f 72 74 69 6e 67 20 2a 2f 0a 73 74  ds sorting */.st
2ae0: 61 74 69 63 20 69 6e 74 20 73 65 71 51 50 20 3d  atic int seqQP =
2af0: 20 30 3b 20 20 20 20 2f 2a 20 53 65 71 75 65 6e   0;    /* Sequen
2b00: 63 65 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 73 74  ce numbers */.st
2b10: 61 74 69 63 20 73 74 72 75 63 74 20 51 50 61 72  atic struct QPar
2b20: 61 6d 20 7b 20 20 20 2f 2a 20 4f 6e 65 20 65 6e  am {   /* One en
2b30: 74 72 79 20 66 6f 72 20 65 61 63 68 20 71 75 65  try for each que
2b40: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20  ry parameter or 
2b50: 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73  cookie */.  cons
2b60: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20  t char *zName;  
2b70: 20 20 20 20 20 20 2f 2a 20 50 61 72 61 6d 65 74        /* Paramet
2b80: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d  er or cookie nam
2b90: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
2ba0: 72 20 2a 7a 56 61 6c 75 65 3b 20 20 20 20 20 20  r *zValue;      
2bb0: 20 2f 2a 20 56 61 6c 75 65 20 6f 66 20 74 68 65   /* Value of the
2bc0: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
2bd0: 20 6f 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20   or cookie */.  
2be0: 69 6e 74 20 73 65 71 3b 20 20 20 20 20 20 20 20  int seq;        
2bf0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 64            /* Ord
2c00: 65 72 20 6f 66 20 69 6e 73 65 72 74 69 6f 6e 20  er of insertion 
2c10: 2a 2f 0a 7d 20 2a 61 50 61 72 61 6d 51 50 3b 20  */.} *aParamQP; 
2c20: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
2c30: 6e 20 61 72 72 61 79 20 6f 66 20 61 6c 6c 20 70  n array of all p
2c40: 61 72 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f  arameters and co
2c50: 6f 6b 69 65 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20  okies */../*.** 
2c60: 41 64 64 20 61 6e 6f 74 68 65 72 20 71 75 65 72  Add another quer
2c70: 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63  y parameter or c
2c80: 6f 6f 6b 69 65 20 74 6f 20 74 68 65 20 70 61 72  ookie to the par
2c90: 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a  ameter set..** z
2ca0: 4e 61 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65  Name is the name
2cb0: 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 61   of the query pa
2cc0: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69  rameter or cooki
2cd0: 65 20 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20  e and zValue.** 
2ce0: 69 73 20 69 74 73 20 66 75 6c 6c 79 20 64 65 63  is its fully dec
2cf0: 6f 64 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a  oded value..**.*
2d00: 2a 20 7a 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c  * zName and zVal
2d10: 75 65 20 61 72 65 20 6e 6f 74 20 63 6f 70 69 65  ue are not copie
2d20: 64 20 61 6e 64 20 6d 75 73 74 20 6e 6f 74 20 63  d and must not c
2d30: 68 61 6e 67 65 20 6f 72 20 62 65 0a 2a 2a 20 64  hange or be.** d
2d40: 65 61 6c 6c 6f 63 61 74 65 64 20 61 66 74 65 72  eallocated after
2d50: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65   this routine re
2d60: 74 75 72 6e 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63  turns..*/.void c
2d70: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72  gi_set_parameter
2d80: 5f 6e 6f 63 6f 70 79 28 63 6f 6e 73 74 20 63 68  _nocopy(const ch
2d90: 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74  ar *zName, const
2da0: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a   char *zValue){.
2db0: 20 20 69 66 28 20 6e 41 6c 6c 6f 63 51 50 3c 3d    if( nAllocQP<=
2dc0: 6e 55 73 65 64 51 50 20 29 7b 0a 20 20 20 20 6e  nUsedQP ){.    n
2dd0: 41 6c 6c 6f 63 51 50 20 3d 20 6e 41 6c 6c 6f 63  AllocQP = nAlloc
2de0: 51 50 2a 32 20 2b 20 31 30 3b 0a 20 20 20 20 61  QP*2 + 10;.    a
2df0: 50 61 72 61 6d 51 50 20 3d 20 72 65 61 6c 6c 6f  ParamQP = reallo
2e00: 63 28 20 61 50 61 72 61 6d 51 50 2c 20 6e 41 6c  c( aParamQP, nAl
2e10: 6c 6f 63 51 50 2a 73 69 7a 65 6f 66 28 61 50 61  locQP*sizeof(aPa
2e20: 72 61 6d 51 50 5b 30 5d 29 20 29 3b 0a 20 20 20  ramQP[0]) );.   
2e30: 20 69 66 28 20 61 50 61 72 61 6d 51 50 3d 3d 30   if( aParamQP==0
2e40: 20 29 20 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a   ) exit(1);.  }.
2e50: 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64    aParamQP[nUsed
2e60: 51 50 5d 2e 7a 4e 61 6d 65 20 3d 20 7a 4e 61 6d  QP].zName = zNam
2e70: 65 3b 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55  e;.  aParamQP[nU
2e80: 73 65 64 51 50 5d 2e 7a 56 61 6c 75 65 20 3d 20  sedQP].zValue = 
2e90: 7a 56 61 6c 75 65 3b 0a 20 20 61 50 61 72 61 6d  zValue;.  aParam
2ea0: 51 50 5b 6e 55 73 65 64 51 50 5d 2e 73 65 71 20  QP[nUsedQP].seq 
2eb0: 3d 20 73 65 71 51 50 2b 2b 3b 0a 20 20 6e 55 73  = seqQP++;.  nUs
2ec0: 65 64 51 50 2b 2b 3b 0a 20 20 73 6f 72 74 51 50  edQP++;.  sortQP
2ed0: 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41   = 1;.}../*.** A
2ee0: 64 64 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79  dd another query
2ef0: 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f   parameter or co
2f00: 6f 6b 69 65 20 74 6f 20 74 68 65 20 70 61 72 61  okie to the para
2f10: 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e  meter set..** zN
2f20: 61 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20  ame is the name 
2f30: 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72  of the query par
2f40: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65  ameter or cookie
2f50: 20 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69   and zValue.** i
2f60: 73 20 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f  s its fully deco
2f70: 64 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a  ded value..**.**
2f80: 20 43 6f 70 69 65 73 20 61 72 65 20 6d 61 64 65   Copies are made
2f90: 20 6f 66 20 62 6f 74 68 20 74 68 65 20 7a 4e 61   of both the zNa
2fa0: 6d 65 20 61 6e 64 20 7a 56 61 6c 75 65 20 70 61  me and zValue pa
2fb0: 72 61 6d 65 74 65 72 73 2e 0a 2a 2f 0a 76 6f 69  rameters..*/.voi
2fc0: 64 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65  d cgi_set_parame
2fd0: 74 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ter(const char *
2fe0: 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61  zName, const cha
2ff0: 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67  r *zValue){.  cg
3000: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f  i_set_parameter_
3010: 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22  nocopy(mprintf("
3020: 25 73 22 2c 7a 4e 61 6d 65 29 2c 20 6d 70 72 69  %s",zName), mpri
3030: 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29  ntf("%s",zValue)
3040: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 70 6c  );.}../*.** Repl
3050: 61 63 65 20 61 20 70 61 72 61 6d 65 74 65 72 20  ace a parameter 
3060: 77 69 74 68 20 61 20 6e 65 77 20 76 61 6c 75 65  with a new value
3070: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65  ..*/.void cgi_re
3080: 70 6c 61 63 65 5f 70 61 72 61 6d 65 74 65 72 28  place_parameter(
3090: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
30a0: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  e, const char *z
30b0: 56 61 6c 75 65 29 7b 0a 20 20 69 6e 74 20 69 3b  Value){.  int i;
30c0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 55  .  for(i=0; i<nU
30d0: 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20  sedQP; i++){.   
30e0: 20 69 66 28 20 73 74 72 63 6d 70 28 61 50 61 72   if( strcmp(aPar
30f0: 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 7a 4e  amQP[i].zName,zN
3100: 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ame)==0 ){.     
3110: 20 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 56 61   aParamQP[i].zVa
3120: 6c 75 65 20 3d 20 7a 56 61 6c 75 65 3b 0a 20 20  lue = zValue;.  
3130: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
3140: 20 41 64 64 20 61 20 71 75 65 72 79 20 70 61 72   Add a query par
3150: 61 6d 65 74 65 72 2e 20 20 54 68 65 20 7a 4e 61  ameter.  The zNa
3160: 6d 65 20 70 6f 72 74 69 6f 6e 20 69 73 20 66 69  me portion is fi
3170: 78 65 64 20 62 75 74 20 61 20 63 6f 70 79 0a 2a  xed but a copy.*
3180: 2a 20 6d 75 73 74 20 62 65 20 6d 61 64 65 20 6f  * must be made o
3190: 66 20 7a 56 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69  f zValue..*/.voi
31a0: 64 20 63 67 69 5f 73 65 74 65 6e 76 28 63 6f 6e  d cgi_setenv(con
31b0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20  st char *zName, 
31c0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
31d0: 75 65 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f 70  ue){.  cgi_set_p
31e0: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28  arameter_nocopy(
31f0: 7a 4e 61 6d 65 2c 20 6d 70 72 69 6e 74 66 28 22  zName, mprintf("
3200: 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a  %s",zValue));.}.
3210: 20 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 6c   ../*.** Add a l
3220: 69 73 74 20 6f 66 20 71 75 65 72 79 20 70 61 72  ist of query par
3230: 61 6d 65 74 65 72 73 20 6f 72 20 63 6f 6f 6b 69  ameters or cooki
3240: 65 73 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65  es to the parame
3250: 74 65 72 20 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 45  ter set..**.** E
3260: 61 63 68 20 70 61 72 61 6d 65 74 65 72 20 69 73  ach parameter is
3270: 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 4e 41 4d   of the form NAM
3280: 45 3d 56 41 4c 55 45 2e 20 20 42 6f 74 68 20 74  E=VALUE.  Both t
3290: 68 65 20 4e 41 4d 45 20 61 6e 64 20 74 68 65 0a  he NAME and the.
32a0: 2a 2a 20 56 41 4c 55 45 20 6d 61 79 20 62 65 20  ** VALUE may be 
32b0: 75 72 6c 2d 65 6e 63 6f 64 65 64 20 28 22 2b 22  url-encoded ("+"
32c0: 20 66 6f 72 20 73 70 61 63 65 2c 20 22 25 48 48   for space, "%HH
32d0: 22 20 66 6f 72 20 6f 74 68 65 72 20 73 70 65 63  " for other spec
32e0: 69 61 6c 0a 2a 2a 20 63 68 61 72 61 63 74 65 72  ial.** character
32f0: 73 29 2e 20 20 42 75 74 20 74 68 69 73 20 72 6f  s).  But this ro
3300: 75 74 69 6e 65 20 61 73 73 75 6d 65 73 20 74 68  utine assumes th
3310: 61 74 20 4e 41 4d 45 20 63 6f 6e 74 61 69 6e 73  at NAME contains
3320: 20 6e 6f 0a 2a 2a 20 73 70 65 63 69 61 6c 20 63   no.** special c
3330: 68 61 72 61 63 74 65 72 20 61 6e 64 20 74 68 65  haracter and the
3340: 72 65 66 6f 72 65 20 64 6f 65 73 20 6e 6f 74 20  refore does not 
3350: 64 65 63 6f 64 65 20 69 74 2e 0a 2a 2a 0a 2a 2a  decode it..**.**
3360: 20 49 66 20 4e 41 4d 45 20 62 65 67 69 6e 73 20   If NAME begins 
3370: 77 69 74 68 20 61 6e 6f 74 68 65 72 20 6f 74 68  with another oth
3380: 65 72 20 74 68 61 6e 20 61 20 6c 6f 77 65 72 2d  er than a lower-
3390: 63 61 73 65 20 6c 65 74 74 65 72 20 74 68 65 6e  case letter then
33a0: 0a 2a 2a 20 74 68 65 20 65 6e 74 69 72 65 20 4e  .** the entire N
33b0: 41 4d 45 3d 56 41 4c 55 45 20 74 65 72 6d 20 69  AME=VALUE term i
33c0: 73 20 69 67 6e 6f 72 65 64 2e 20 20 48 65 6e 63  s ignored.  Henc
33d0: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a 20  e:.**.**      * 
33e0: 20 63 6f 6f 6b 69 65 73 20 61 6e 64 20 71 75 65   cookies and que
33f0: 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 74 68  ry parameters th
3400: 61 74 20 68 61 76 65 20 75 70 70 65 72 63 61 73  at have uppercas
3410: 65 20 6e 61 6d 65 73 0a 2a 2a 20 20 20 20 20 20  e names.**      
3420: 20 20 20 61 72 65 20 69 67 6e 6f 72 65 64 2e 0a     are ignored..
3430: 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a 20 20 69 74  **.**      *  it
3440: 20 69 73 20 69 6d 70 6f 73 73 69 62 6c 65 20 66   is impossible f
3450: 6f 72 20 61 20 63 6f 6f 6b 69 65 20 6f 72 20 71  or a cookie or q
3460: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 74  uery parameter t
3470: 6f 0a 2a 2a 20 20 20 20 20 20 20 20 20 6f 76 65  o.**         ove
3480: 72 72 69 64 65 20 74 68 65 20 76 61 6c 75 65 20  rride the value 
3490: 6f 66 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e  of an environmen
34a0: 74 20 76 61 72 69 61 62 6c 65 20 73 69 6e 63 65  t variable since
34b0: 0a 2a 2a 20 20 20 20 20 20 20 20 20 65 6e 76 69  .**         envi
34c0: 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65  ronment variable
34d0: 73 20 61 6c 77 61 79 73 20 68 61 76 65 20 75 70  s always have up
34e0: 70 65 72 63 61 73 65 20 6e 61 6d 65 73 2e 0a 2a  percase names..*
34f0: 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 73 20  *.** Parameters 
3500: 61 72 65 20 73 65 70 61 72 61 74 65 64 20 62 79  are separated by
3510: 20 74 68 65 20 22 74 65 72 6d 69 6e 61 74 6f 72   the "terminator
3520: 22 20 63 68 61 72 61 63 74 65 72 2e 20 20 57 68  " character.  Wh
3530: 69 74 65 73 70 61 63 65 0a 2a 2a 20 62 65 66 6f  itespace.** befo
3540: 72 65 20 74 68 65 20 4e 41 4d 45 20 69 73 20 69  re the NAME is i
3550: 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68  gnored..**.** Th
3560: 65 20 69 6e 70 75 74 20 73 74 72 69 6e 67 20 22  e input string "
3570: 7a 22 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62  z" is modified b
3580: 75 74 20 6e 6f 20 63 6f 70 69 65 73 20 69 73 20  ut no copies is 
3590: 6d 61 64 65 2e 20 20 22 7a 22 0a 2a 2a 20 73 68  made.  "z".** sh
35a0: 6f 75 6c 64 20 6e 6f 74 20 62 65 20 64 65 61 6c  ould not be deal
35b0: 6c 6f 63 61 74 65 64 20 6f 72 20 63 68 61 6e 67  located or chang
35c0: 65 64 20 61 67 61 69 6e 20 61 66 74 65 72 20 74  ed again after t
35d0: 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72  his routine.** r
35e0: 65 74 75 72 6e 73 20 6f 72 20 69 74 20 77 69 6c  eturns or it wil
35f0: 6c 20 63 6f 72 72 75 70 74 20 74 68 65 20 70 61  l corrupt the pa
3600: 72 61 6d 65 74 65 72 20 74 61 62 6c 65 2e 0a 2a  rameter table..*
3610: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 64  /.static void ad
3620: 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 63 68 61  d_param_list(cha
3630: 72 20 2a 7a 2c 20 69 6e 74 20 74 65 72 6d 69 6e  r *z, int termin
3640: 61 74 6f 72 29 7b 0a 20 20 77 68 69 6c 65 28 20  ator){.  while( 
3650: 2a 7a 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  *z ){.    char *
3660: 7a 4e 61 6d 65 3b 0a 20 20 20 20 63 68 61 72 20  zName;.    char 
3670: 2a 7a 56 61 6c 75 65 3b 0a 20 20 20 20 77 68 69  *zValue;.    whi
3680: 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a 29 20  le( isspace(*z) 
3690: 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 7a 4e  ){ z++; }.    zN
36a0: 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 20 77 68 69  ame = z;.    whi
36b0: 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 3d  le( *z && *z!='=
36c0: 27 20 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61  ' && *z!=termina
36d0: 74 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20  tor ){ z++; }.  
36e0: 20 20 69 66 28 20 2a 7a 3d 3d 27 3d 27 20 29 7b    if( *z=='=' ){
36f0: 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20  .      *z = 0;. 
3700: 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20       z++;.      
3710: 7a 56 61 6c 75 65 20 3d 20 7a 3b 0a 20 20 20 20  zValue = z;.    
3720: 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a    while( *z && *
3730: 7a 21 3d 74 65 72 6d 69 6e 61 74 6f 72 20 29 7b  z!=terminator ){
3740: 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66   z++; }.      if
3750: 28 20 2a 7a 20 29 7b 0a 20 20 20 20 20 20 20 20  ( *z ){.        
3760: 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  *z = 0;.        
3770: 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  z++;.      }.   
3780: 20 20 20 64 65 68 74 74 70 69 7a 65 28 7a 56 61     dehttpize(zVa
3790: 6c 75 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  lue);.    }else{
37a0: 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20 29 7b  .      if( *z ){
37b0: 20 2a 7a 2b 2b 20 3d 20 30 3b 20 7d 0a 20 20 20   *z++ = 0; }.   
37c0: 20 20 20 7a 56 61 6c 75 65 20 3d 20 22 22 3b 0a     zValue = "";.
37d0: 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 73      }.    if( is
37e0: 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20  lower(zName[0]) 
37f0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74  ){.      cgi_set
3800: 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70  _parameter_nocop
3810: 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29  y(zName, zValue)
3820: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f  ;.    }.  }.}../
3830: 2a 0a 2a 2a 20 2a 70 7a 20 69 73 20 61 20 73 74  *.** *pz is a st
3840: 72 69 6e 67 20 74 68 61 74 20 63 6f 6e 73 69 73  ring that consis
3850: 74 73 20 6f 66 20 6d 75 6c 74 69 70 6c 65 20 6c  ts of multiple l
3860: 69 6e 65 73 20 6f 66 20 74 65 78 74 2e 20 20 54  ines of text.  T
3870: 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 66  his.** routine f
3880: 69 6e 64 73 20 74 68 65 20 65 6e 64 20 6f 66 20  inds the end of 
3890: 74 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65  the current line
38a0: 20 6f 66 20 74 65 78 74 20 61 6e 64 20 63 6f 6e   of text and con
38b0: 76 65 72 74 73 0a 2a 2a 20 74 68 65 20 22 5c 6e  verts.** the "\n
38c0: 22 20 6f 72 20 22 5c 72 5c 6e 22 20 74 68 61 74  " or "\r\n" that
38d0: 20 65 6e 64 73 20 74 68 61 74 20 6c 69 6e 65 20   ends that line 
38e0: 69 6e 74 6f 20 61 20 22 5c 30 30 30 22 2e 20 20  into a "\000".  
38f0: 49 74 20 74 68 65 6e 0a 2a 2a 20 61 64 76 61 6e  It then.** advan
3900: 63 65 73 20 2a 70 7a 20 74 6f 20 74 68 65 20 62  ces *pz to the b
3910: 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20  eginning of the 
3920: 6e 65 78 74 20 6c 69 6e 65 20 61 6e 64 20 72 65  next line and re
3930: 74 75 72 6e 73 20 74 68 65 0a 2a 2a 20 70 72 65  turns the.** pre
3940: 76 69 6f 75 73 20 76 61 6c 75 65 20 6f 66 20 2a  vious value of *
3950: 70 7a 20 28 77 68 69 63 68 20 69 73 20 74 68 65  pz (which is the
3960: 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 63 75   start of the cu
3970: 72 72 65 6e 74 20 6c 69 6e 65 2e 29 0a 2a 2f 0a  rrent line.).*/.
3980: 73 74 61 74 69 63 20 63 68 61 72 20 2a 67 65 74  static char *get
3990: 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e  _line_from_strin
39a0: 67 28 63 68 61 72 20 2a 2a 70 7a 2c 20 69 6e 74  g(char **pz, int
39b0: 20 2a 70 4c 65 6e 29 7b 0a 20 20 63 68 61 72 20   *pLen){.  char 
39c0: 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e 74 20  *z = *pz;.  int 
39d0: 69 3b 0a 20 20 69 66 28 20 7a 5b 30 5d 3d 3d 30  i;.  if( z[0]==0
39e0: 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 66   ) return 0;.  f
39f0: 6f 72 28 69 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b  or(i=0; z[i]; i+
3a00: 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d  +){.    if( z[i]
3a10: 3d 3d 27 5c 6e 27 20 29 7b 0a 20 20 20 20 20 20  =='\n' ){.      
3a20: 69 66 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d 31  if( i>0 && z[i-1
3a30: 5d 3d 3d 27 5c 72 27 20 29 7b 0a 20 20 20 20 20  ]=='\r' ){.     
3a40: 20 20 20 7a 5b 69 2d 31 5d 20 3d 20 30 3b 0a 20     z[i-1] = 0;. 
3a50: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20       }else{.    
3a60: 20 20 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20      z[i] = 0;.  
3a70: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 2b 2b 3b      }.      i++;
3a80: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20  .      break;.  
3a90: 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20    }.  }.  *pz = 
3aa0: 26 7a 5b 69 5d 3b 0a 20 20 2a 70 4c 65 6e 20 2d  &z[i];.  *pLen -
3ab0: 3d 20 69 3b 0a 20 20 72 65 74 75 72 6e 20 7a 3b  = i;.  return z;
3ac0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e  .}../*.** The in
3ad0: 70 75 74 20 2a 70 7a 20 70 6f 69 6e 74 73 20 74  put *pz points t
3ae0: 6f 20 63 6f 6e 74 65 6e 74 20 74 68 61 74 20 69  o content that i
3af0: 73 20 74 65 72 6d 69 6e 61 74 65 64 20 62 79 20  s terminated by 
3b00: 61 20 22 5c 72 5c 6e 22 0a 2a 2a 20 66 6f 6c 6c  a "\r\n".** foll
3b10: 6f 77 65 64 20 62 79 20 74 68 65 20 62 6f 75 6e  owed by the boun
3b20: 64 72 79 20 6d 61 72 6b 65 72 20 7a 42 6f 75 6e  dry marker zBoun
3b30: 64 72 79 2e 20 20 41 6e 20 65 78 74 72 61 20 22  dry.  An extra "
3b40: 2d 2d 22 20 6d 61 79 20 6f 72 0a 2a 2a 20 6d 61  --" may or.** ma
3b50: 79 20 6e 6f 74 20 62 65 20 61 70 70 65 6e 64 65  y not be appende
3b60: 64 20 74 6f 20 74 68 65 20 62 6f 75 6e 64 72 79  d to the boundry
3b70: 20 6d 61 72 6b 65 72 2e 20 20 54 68 65 72 65 20   marker.  There 
3b80: 61 72 65 20 2a 70 4c 65 6e 20 63 68 61 72 61 63  are *pLen charac
3b90: 74 65 72 73 0a 2a 2a 20 69 6e 20 2a 70 7a 2e 0a  ters.** in *pz..
3ba0: 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  **.** This routi
3bb0: 6e 65 20 61 64 64 73 20 61 20 22 5c 30 30 30 22  ne adds a "\000"
3bc0: 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74   to the end of t
3bd0: 68 65 20 63 6f 6e 74 65 6e 74 20 28 6f 76 65 72  he content (over
3be0: 77 72 69 74 69 6e 67 0a 2a 2a 20 74 68 65 20 22  writing.** the "
3bf0: 5c 72 5c 6e 22 29 20 61 6e 64 20 72 65 74 75 72  \r\n") and retur
3c00: 6e 73 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20  ns a pointer to 
3c10: 74 68 65 20 63 6f 6e 74 65 6e 74 2e 20 20 54 68  the content.  Th
3c20: 65 20 2a 70 7a 20 69 6e 70 75 74 0a 2a 2a 20 69  e *pz input.** i
3c30: 73 20 61 64 6a 75 73 74 65 64 20 74 6f 20 70 6f  s adjusted to po
3c40: 69 6e 74 20 74 6f 20 74 68 65 20 66 69 72 73 74  int to the first
3c50: 20 6c 69 6e 65 20 66 6f 6c 6c 6f 77 69 6e 67 20   line following 
3c60: 74 68 65 20 62 6f 75 6e 64 72 79 2e 0a 2a 2a 20  the boundry..** 
3c70: 54 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 74 68  The length of th
3c80: 65 20 63 6f 6e 74 65 6e 74 20 69 73 20 73 74 6f  e content is sto
3c90: 72 65 64 20 69 6e 20 2a 70 6e 43 6f 6e 74 65 6e  red in *pnConten
3ca0: 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61  t..*/.static cha
3cb0: 72 20 2a 67 65 74 5f 62 6f 75 6e 64 65 64 5f 63  r *get_bounded_c
3cc0: 6f 6e 74 65 6e 74 28 0a 20 20 63 68 61 72 20 2a  ontent(.  char *
3cd0: 2a 70 7a 2c 20 20 20 20 20 20 20 20 20 2f 2a 20  *pz,         /* 
3ce0: 43 6f 6e 74 65 6e 74 20 74 61 6b 65 6e 20 66 72  Content taken fr
3cf0: 6f 6d 20 68 65 72 65 20 2a 2f 0a 20 20 69 6e 74  om here */.  int
3d00: 20 2a 70 4c 65 6e 2c 20 20 20 20 20 20 20 20 20   *pLen,         
3d10: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74  /* Number of byt
3d20: 65 73 20 6f 66 20 64 61 74 61 20 69 6e 20 28 2a  es of data in (*
3d30: 70 7a 29 5b 5d 20 2a 2f 0a 20 20 63 68 61 72 20  pz)[] */.  char 
3d40: 2a 7a 42 6f 75 6e 64 72 79 2c 20 20 20 20 2f 2a  *zBoundry,    /*
3d50: 20 42 6f 75 6e 64 72 79 20 74 65 78 74 20 6d 61   Boundry text ma
3d60: 72 6b 69 6e 67 20 74 68 65 20 65 6e 64 20 6f 66  rking the end of
3d70: 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 69 6e   content */.  in
3d80: 74 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 20 20 20  t *pnContent    
3d90: 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 73 69   /* Write the si
3da0: 7a 65 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e  ze of the conten
3db0: 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 63  t here */.){.  c
3dc0: 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20  har *z = *pz;.  
3dd0: 69 6e 74 20 6c 65 6e 20 3d 20 2a 70 4c 65 6e 3b  int len = *pLen;
3de0: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20  .  int i;.  int 
3df0: 6e 42 6f 75 6e 64 72 79 20 3d 20 73 74 72 6c 65  nBoundry = strle
3e00: 6e 28 7a 42 6f 75 6e 64 72 79 29 3b 0a 20 20 2a  n(zBoundry);.  *
3e10: 70 6e 43 6f 6e 74 65 6e 74 20 3d 20 6c 65 6e 3b  pnContent = len;
3e20: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6c 65  .  for(i=0; i<le
3e30: 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  n; i++){.    if(
3e40: 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 26 26 20 73   z[i]=='\n' && s
3e50: 74 72 6e 63 6d 70 28 7a 42 6f 75 6e 64 72 79 2c  trncmp(zBoundry,
3e60: 20 26 7a 5b 69 2b 31 5d 2c 20 6e 42 6f 75 6e 64   &z[i+1], nBound
3e70: 72 79 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  ry)==0 ){.      
3e80: 69 66 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d 31  if( i>0 && z[i-1
3e90: 5d 3d 3d 27 5c 72 27 20 29 20 69 2d 2d 3b 0a 20  ]=='\r' ) i--;. 
3ea0: 20 20 20 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20       z[i] = 0;. 
3eb0: 20 20 20 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20       *pnContent 
3ec0: 3d 20 69 3b 0a 20 20 20 20 20 20 69 20 2b 3d 20  = i;.      i += 
3ed0: 6e 42 6f 75 6e 64 72 79 3b 0a 20 20 20 20 20 20  nBoundry;.      
3ee0: 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d  break;.    }.  }
3ef0: 0a 20 20 2a 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a  .  *pz = &z[i];.
3f00: 20 20 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f    get_line_from_
3f10: 73 74 72 69 6e 67 28 70 7a 2c 20 70 4c 65 6e 29  string(pz, pLen)
3f20: 3b 0a 20 20 72 65 74 75 72 6e 20 7a 3b 20 20 20  ;.  return z;   
3f30: 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b     .}../*.** Tok
3f40: 65 6e 69 7a 65 20 61 20 6c 69 6e 65 20 6f 66 20  enize a line of 
3f50: 74 65 78 74 20 69 6e 74 6f 20 61 73 20 6d 61 6e  text into as man
3f60: 79 20 61 73 20 6e 41 72 67 20 74 6f 6b 65 6e 73  y as nArg tokens
3f70: 2e 20 20 4d 61 6b 65 0a 2a 2a 20 61 7a 41 72 67  .  Make.** azArg
3f80: 5b 5d 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  [] point to the 
3f90: 73 74 61 72 74 20 6f 66 20 65 61 63 68 20 74 6f  start of each to
3fa0: 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 54 6f 6b 65 6e  ken..**.** Token
3fb0: 73 20 63 6f 6e 73 69 73 74 20 6f 66 20 73 70 61  s consist of spa
3fc0: 63 65 20 6f 72 20 73 65 6d 69 2d 63 6f 6c 6f 6e  ce or semi-colon
3fd0: 20 64 65 6c 69 6d 69 74 65 64 20 77 6f 72 64 73   delimited words
3fe0: 20 6f 72 0a 2a 2a 20 73 74 72 69 6e 67 73 20 69   or.** strings i
3ff0: 6e 73 69 64 65 20 64 6f 75 62 6c 65 2d 71 75 6f  nside double-quo
4000: 74 65 73 2e 20 20 45 78 61 6d 70 6c 65 3a 0a 2a  tes.  Example:.*
4010: 2a 0a 2a 2a 20 20 20 20 63 6f 6e 74 65 6e 74 2d  *.**    content-
4020: 64 69 73 70 6f 73 69 74 69 6f 6e 3a 20 66 6f 72  disposition: for
4030: 6d 2d 64 61 74 61 3b 20 6e 61 6d 65 3d 22 66 6e  m-data; name="fn
4040: 22 3b 20 66 69 6c 65 6e 61 6d 65 3d 22 69 6e 64  "; filename="ind
4050: 65 78 2e 68 74 6d 6c 22 0a 2a 2a 0a 2a 2a 20 54  ex.html".**.** T
4060: 68 65 20 6c 69 6e 65 20 61 62 6f 76 65 20 69 73  he line above is
4070: 20 74 6f 6b 65 6e 69 7a 65 64 20 61 73 20 66 6f   tokenized as fo
4080: 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  llows:.**.**    
4090: 61 7a 41 72 67 5b 30 5d 20 3d 20 22 63 6f 6e 74  azArg[0] = "cont
40a0: 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a  ent-disposition:
40b0: 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 31 5d  ".**    azArg[1]
40c0: 20 3d 20 22 66 6f 72 6d 2d 64 61 74 61 22 0a 2a   = "form-data".*
40d0: 2a 20 20 20 20 61 7a 41 72 67 5b 32 5d 20 3d 20  *    azArg[2] = 
40e0: 22 6e 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61 7a  "name=".**    az
40f0: 41 72 67 5b 33 5d 20 3d 20 22 66 6e 22 0a 2a 2a  Arg[3] = "fn".**
4100: 20 20 20 20 61 7a 41 72 67 5b 34 5d 20 3d 20 22      azArg[4] = "
4110: 66 69 6c 65 6e 61 6d 65 3d 22 0a 2a 2a 20 20 20  filename=".**   
4120: 20 61 7a 41 72 67 5b 35 5d 20 3d 20 22 69 6e 64   azArg[5] = "ind
4130: 65 78 2e 68 74 6d 6c 22 0a 2a 2a 20 20 20 20 61  ex.html".**    a
4140: 7a 41 72 67 5b 36 5d 20 3d 20 30 3b 0a 2a 2a 0a  zArg[6] = 0;.**.
4150: 2a 2a 20 27 5c 30 30 30 27 20 63 68 61 72 61 63  ** '\000' charac
4160: 74 65 72 73 20 61 72 65 20 69 6e 73 65 72 74 65  ters are inserte
4170: 64 20 69 6e 20 7a 5b 5d 20 61 74 20 74 68 65 20  d in z[] at the 
4180: 65 6e 64 20 6f 66 20 65 61 63 68 20 74 6f 6b 65  end of each toke
4190: 6e 2e 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  n..** This routi
41a0: 6e 65 20 72 65 74 75 72 6e 73 20 74 68 65 20 74  ne returns the t
41b0: 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 74  otal number of t
41c0: 6f 6b 65 6e 73 20 6f 6e 20 74 68 65 20 6c 69 6e  okens on the lin
41d0: 65 2c 20 36 0a 2a 2a 20 69 6e 20 74 68 65 20 65  e, 6.** in the e
41e0: 78 61 6d 70 6c 65 20 61 62 6f 76 65 2e 0a 2a 2f  xample above..*/
41f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 74 6f 6b 65  .static int toke
4200: 6e 69 7a 65 5f 6c 69 6e 65 28 63 68 61 72 20 2a  nize_line(char *
4210: 7a 2c 20 69 6e 74 20 6d 78 41 72 67 2c 20 63 68  z, int mxArg, ch
4220: 61 72 20 2a 2a 61 7a 41 72 67 29 7b 0a 20 20 69  ar **azArg){.  i
4230: 6e 74 20 69 20 3d 20 30 3b 0a 20 20 77 68 69 6c  nt i = 0;.  whil
4240: 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 77 68 69  e( *z ){.    whi
4250: 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a 29 20  le( isspace(*z) 
4260: 7c 7c 20 2a 7a 3d 3d 27 3b 27 20 29 7b 20 7a 2b  || *z==';' ){ z+
4270: 2b 3b 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d  +; }.    if( *z=
4280: 3d 27 22 27 20 26 26 20 7a 5b 31 5d 20 29 7b 0a  ='"' && z[1] ){.
4290: 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20        *z = 0;.  
42a0: 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 69      z++;.      i
42b0: 66 28 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b 20  f( i<mxArg-1 ){ 
42c0: 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20  azArg[i++] = z; 
42d0: 7d 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a  }.      while( *
42e0: 7a 20 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b 20  z && *z!='"' ){ 
42f0: 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 28  z++; }.      if(
4300: 20 2a 7a 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a   *z==0 ) break;.
4310: 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20        *z = 0;.  
4320: 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 7d 65 6c      z++;.    }el
4330: 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 69 3c  se{.      if( i<
4340: 6d 78 41 72 67 2d 31 20 29 7b 20 61 7a 41 72 67  mxArg-1 ){ azArg
4350: 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a 20 20 20  [i++] = z; }.   
4360: 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20     while( *z && 
4370: 21 69 73 73 70 61 63 65 28 2a 7a 29 20 26 26 20  !isspace(*z) && 
4380: 2a 7a 21 3d 27 3b 27 20 26 26 20 2a 7a 21 3d 27  *z!=';' && *z!='
4390: 22 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20  "' ){ z++; }.   
43a0: 20 20 20 69 66 28 20 2a 7a 20 26 26 20 2a 7a 21     if( *z && *z!
43b0: 3d 27 22 27 20 29 7b 0a 20 20 20 20 20 20 20 20  ='"' ){.        
43c0: 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20  *z = 0;.        
43d0: 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  z++;.      }.   
43e0: 20 7d 0a 20 20 7d 0a 20 20 61 7a 41 72 67 5b 69   }.  }.  azArg[i
43f0: 5d 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20  ] = 0;.  return 
4400: 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 63 61 6e  i;.}../*.** Scan
4410: 20 74 68 65 20 6d 75 6c 74 69 70 61 72 74 2d 66   the multipart-f
4420: 6f 72 6d 20 63 6f 6e 74 65 6e 74 20 61 6e 64 20  orm content and 
4430: 6d 61 6b 65 20 61 70 70 72 6f 70 72 69 61 74 65  make appropriate
4440: 20 65 6e 74 72 69 65 73 0a 2a 2a 20 69 6e 74 6f   entries.** into
4450: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 74   the parameter t
4460: 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20  able..**.** The 
4470: 63 6f 6e 74 65 6e 74 20 73 74 72 69 6e 67 20 22  content string "
4480: 7a 22 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62  z" is modified b
4490: 79 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 62  y this routine b
44a0: 75 74 20 69 74 20 69 73 0a 2a 2a 20 6e 6f 74 20  ut it is.** not 
44b0: 63 6f 70 69 65 64 2e 20 20 54 68 65 20 63 61 6c  copied.  The cal
44c0: 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e 20 6d 75  ling function mu
44d0: 73 74 20 6e 6f 74 20 64 65 61 6c 6c 6f 63 61 74  st not deallocat
44e0: 65 20 6f 72 20 6d 6f 64 69 66 79 0a 2a 2a 20 22  e or modify.** "
44f0: 7a 22 20 61 66 74 65 72 20 74 68 69 73 20 72 6f  z" after this ro
4500: 75 74 69 6e 65 20 66 69 6e 69 73 68 65 73 20 6f  utine finishes o
4510: 72 20 69 74 20 63 6f 75 6c 64 20 63 6f 72 72 75  r it could corru
4520: 70 74 20 74 68 65 20 70 61 72 61 6d 65 74 65 72  pt the parameter
4530: 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74  .** table..*/.st
4540: 61 74 69 63 20 76 6f 69 64 20 70 72 6f 63 65 73  atic void proces
4550: 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66 6f 72 6d  s_multipart_form
4560: 5f 64 61 74 61 28 63 68 61 72 20 2a 7a 2c 20 69  _data(char *z, i
4570: 6e 74 20 6c 65 6e 29 7b 0a 20 20 63 68 61 72 20  nt len){.  char 
4580: 2a 7a 4c 69 6e 65 3b 0a 20 20 69 6e 74 20 6e 41  *zLine;.  int nA
4590: 72 67 2c 20 69 3b 0a 20 20 63 68 61 72 20 2a 7a  rg, i;.  char *z
45a0: 42 6f 75 6e 64 72 79 3b 0a 20 20 63 68 61 72 20  Boundry;.  char 
45b0: 2a 7a 56 61 6c 75 65 3b 0a 20 20 63 68 61 72 20  *zValue;.  char 
45c0: 2a 7a 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 69 6e  *zName = 0;.  in
45d0: 74 20 73 68 6f 77 42 79 74 65 73 20 3d 20 30 3b  t showBytes = 0;
45e0: 0a 20 20 63 68 61 72 20 2a 61 7a 41 72 67 5b 35  .  char *azArg[5
45f0: 30 5d 3b 0a 0a 20 20 7a 42 6f 75 6e 64 72 79 20  0];..  zBoundry 
4600: 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f  = get_line_from_
4610: 73 74 72 69 6e 67 28 26 7a 2c 20 26 6c 65 6e 29  string(&z, &len)
4620: 3b 0a 20 20 69 66 28 20 7a 42 6f 75 6e 64 72 79  ;.  if( zBoundry
4630: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20  ==0 ) return;.  
4640: 77 68 69 6c 65 28 20 28 7a 4c 69 6e 65 20 3d 20  while( (zLine = 
4650: 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74  get_line_from_st
4660: 72 69 6e 67 28 26 7a 2c 20 26 6c 65 6e 29 29 21  ring(&z, &len))!
4670: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 4c  =0 ){.    if( zL
4680: 69 6e 65 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20  ine[0]==0 ){.   
4690: 20 20 20 69 6e 74 20 6e 43 6f 6e 74 65 6e 74 20     int nContent 
46a0: 3d 20 30 3b 0a 20 20 20 20 20 20 7a 56 61 6c 75  = 0;.      zValu
46b0: 65 20 3d 20 67 65 74 5f 62 6f 75 6e 64 65 64 5f  e = get_bounded_
46c0: 63 6f 6e 74 65 6e 74 28 26 7a 2c 20 26 6c 65 6e  content(&z, &len
46d0: 2c 20 7a 42 6f 75 6e 64 72 79 2c 20 26 6e 43 6f  , zBoundry, &nCo
46e0: 6e 74 65 6e 74 29 3b 0a 20 20 20 20 20 20 69 66  ntent);.      if
46f0: 28 20 7a 4e 61 6d 65 20 26 26 20 7a 56 61 6c 75  ( zName && zValu
4700: 65 20 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61  e && islower(zNa
4710: 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20  me[0]) ){.      
4720: 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65    cgi_set_parame
4730: 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65  ter_nocopy(zName
4740: 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 20  , zValue);.     
4750: 20 20 20 69 66 28 20 73 68 6f 77 42 79 74 65 73     if( showBytes
4760: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63 67   ){.          cg
4770: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f  i_set_parameter_
4780: 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22  nocopy(mprintf("
4790: 25 73 3a 62 79 74 65 73 22 2c 20 7a 4e 61 6d 65  %s:bytes", zName
47a0: 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ),.             
47b0: 20 20 6d 70 72 69 6e 74 66 28 22 25 64 22 2c 6e    mprintf("%d",n
47c0: 43 6f 6e 74 65 6e 74 29 29 3b 0a 20 20 20 20 20  Content));.     
47d0: 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20     }.      }.   
47e0: 20 20 20 7a 4e 61 6d 65 20 3d 20 30 3b 0a 20 20     zName = 0;.  
47f0: 20 20 20 20 73 68 6f 77 42 79 74 65 73 20 3d 20      showBytes = 
4800: 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  0;.    }else{.  
4810: 20 20 20 20 6e 41 72 67 20 3d 20 74 6f 6b 65 6e      nArg = token
4820: 69 7a 65 5f 6c 69 6e 65 28 7a 4c 69 6e 65 2c 20  ize_line(zLine, 
4830: 73 69 7a 65 6f 66 28 61 7a 41 72 67 29 2f 73 69  sizeof(azArg)/si
4840: 7a 65 6f 66 28 61 7a 41 72 67 5b 30 5d 29 2c 20  zeof(azArg[0]), 
4850: 61 7a 41 72 67 29 3b 0a 20 20 20 20 20 20 66 6f  azArg);.      fo
4860: 72 28 69 3d 30 3b 20 69 3c 6e 41 72 67 3b 20 69  r(i=0; i<nArg; i
4870: 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74  ++){.        int
4880: 20 63 20 3d 20 74 6f 6c 6f 77 65 72 28 61 7a 41   c = tolower(azA
4890: 72 67 5b 69 5d 5b 30 5d 29 3b 0a 20 20 20 20 20  rg[i][0]);.     
48a0: 20 20 20 69 66 28 20 63 3d 3d 27 63 27 20 26 26     if( c=='c' &&
48b0: 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69   stricmp(azArg[i
48c0: 5d 2c 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f  ],"content-dispo
48d0: 73 69 74 69 6f 6e 3a 22 29 3d 3d 30 20 29 7b 0a  sition:")==0 ){.
48e0: 20 20 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a 20            i++;. 
48f0: 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28         }else if(
4900: 20 63 3d 3d 27 6e 27 20 26 26 20 73 74 72 69 63   c=='n' && stric
4910: 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 6e 61 6d  mp(azArg[i],"nam
4920: 65 3d 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  e=")==0 ){.     
4930: 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 61 7a 41       zName = azA
4940: 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20  rg[++i];.       
4950: 20 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 66   }else if( c=='f
4960: 27 20 26 26 20 73 74 72 69 63 6d 70 28 61 7a 41  ' && stricmp(azA
4970: 72 67 5b 69 5d 2c 22 66 69 6c 65 6e 61 6d 65 3d  rg[i],"filename=
4980: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20  ")==0 ){.       
4990: 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a 41     char *z = azA
49a0: 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20  rg[++i];.       
49b0: 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20     if( zName && 
49c0: 7a 20 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61  z && islower(zNa
49d0: 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20  me[0]) ){.      
49e0: 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61        cgi_set_pa
49f0: 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d  rameter_nocopy(m
4a00: 70 72 69 6e 74 66 28 22 25 73 3a 66 69 6c 65 6e  printf("%s:filen
4a10: 61 6d 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b  ame",zName), z);
4a20: 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20  .          }.   
4a30: 20 20 20 20 20 20 20 73 68 6f 77 42 79 74 65 73         showBytes
4a40: 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65   = 1;.        }e
4a50: 6c 73 65 20 69 66 28 20 63 3d 3d 27 63 27 20 26  lse if( c=='c' &
4a60: 26 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b  & stricmp(azArg[
4a70: 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 65  i],"content-type
4a80: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  :")==0 ){.      
4a90: 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a      char *z = az
4aa0: 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20  Arg[++i];.      
4ab0: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26      if( zName &&
4ac0: 20 7a 20 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e   z && islower(zN
4ad0: 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20  ame[0]) ){.     
4ae0: 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70         cgi_set_p
4af0: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28  arameter_nocopy(
4b00: 6d 70 72 69 6e 74 66 28 22 25 73 3a 6d 69 6d 65  mprintf("%s:mime
4b10: 74 79 70 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29  type",zName), z)
4b20: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
4b30: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a        }.      }.
4b40: 20 20 20 20 7d 0a 20 20 7d 20 20 20 20 20 20 20      }.  }       
4b50: 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69   .}../*.** Initi
4b60: 61 6c 69 7a 65 20 74 68 65 20 71 75 65 72 79 20  alize the query 
4b70: 70 61 72 61 6d 65 74 65 72 20 64 61 74 61 62 61  parameter databa
4b80: 73 65 2e 20 20 49 6e 66 6f 72 6d 61 74 69 6f 6e  se.  Information
4b90: 20 69 73 20 70 75 6c 6c 65 64 20 66 72 6f 6d 0a   is pulled from.
4ba0: 2a 2a 20 74 68 65 20 51 55 45 52 59 5f 53 54 52  ** the QUERY_STR
4bb0: 49 4e 47 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20  ING environment 
4bc0: 76 61 72 69 61 62 6c 65 20 28 69 66 20 69 74 20  variable (if it 
4bd0: 65 78 69 73 74 73 29 2c 20 66 72 6f 6d 20 73 74  exists), from st
4be0: 61 6e 64 61 72 64 0a 2a 2a 20 69 6e 70 75 74 20  andard.** input 
4bf0: 69 66 20 74 68 65 72 65 20 69 73 20 50 4f 53 54  if there is POST
4c00: 20 64 61 74 61 2c 20 61 6e 64 20 66 72 6f 6d 20   data, and from 
4c10: 48 54 54 50 5f 43 4f 4f 4b 49 45 2e 0a 2a 2f 0a  HTTP_COOKIE..*/.
4c20: 76 6f 69 64 20 63 67 69 5f 69 6e 69 74 28 76 6f  void cgi_init(vo
4c30: 69 64 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a  id){.  char *z;.
4c40: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54    const char *zT
4c50: 79 70 65 3b 0a 20 20 69 6e 74 20 6c 65 6e 3b 0a  ype;.  int len;.
4c60: 20 20 63 67 69 5f 64 65 73 74 69 6e 61 74 69 6f    cgi_destinatio
4c70: 6e 28 43 47 49 5f 42 4f 44 59 29 3b 0a 20 20 7a  n(CGI_BODY);.  z
4c80: 20 3d 20 28 63 68 61 72 2a 29 50 28 22 51 55 45   = (char*)P("QUE
4c90: 52 59 5f 53 54 52 49 4e 47 22 29 3b 0a 20 20 69  RY_STRING");.  i
4ca0: 66 28 20 7a 20 29 7b 0a 20 20 20 20 7a 20 3d 20  f( z ){.    z = 
4cb0: 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 29 3b  mprintf("%s",z);
4cc0: 0a 20 20 20 20 61 64 64 5f 70 61 72 61 6d 5f 6c  .    add_param_l
4cd0: 69 73 74 28 7a 2c 20 27 26 27 29 3b 0a 20 20 7d  ist(z, '&');.  }
4ce0: 0a 0a 20 20 6c 65 6e 20 3d 20 61 74 6f 69 28 50  ..  len = atoi(P
4cf0: 44 28 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54  D("CONTENT_LENGT
4d00: 48 22 2c 20 22 30 22 29 29 3b 0a 20 20 67 2e 7a  H", "0"));.  g.z
4d10: 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 7a 54  ContentType = zT
4d20: 79 70 65 20 3d 20 50 28 22 43 4f 4e 54 45 4e 54  ype = P("CONTENT
4d30: 5f 54 59 50 45 22 29 3b 0a 20 20 69 66 28 20 6c  _TYPE");.  if( l
4d40: 65 6e 3e 30 20 26 26 20 7a 54 79 70 65 20 29 7b  en>0 && zType ){
4d50: 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26  .    blob_zero(&
4d60: 67 2e 63 67 69 49 6e 29 3b 0a 20 20 20 20 69 66  g.cgiIn);.    if
4d70: 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 22  ( strcmp(zType,"
4d80: 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77  application/x-ww
4d90: 77 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65  w-form-urlencode
4da0: 64 22 29 3d 3d 30 20 0a 20 20 20 20 20 20 20 20  d")==0 .        
4db0: 20 7c 7c 20 73 74 72 6e 63 6d 70 28 7a 54 79 70   || strncmp(zTyp
4dc0: 65 2c 22 6d 75 6c 74 69 70 61 72 74 2f 66 6f 72  e,"multipart/for
4dd0: 6d 2d 64 61 74 61 22 2c 31 39 29 3d 3d 30 20 29  m-data",19)==0 )
4de0: 7b 0a 20 20 20 20 20 20 7a 20 3d 20 6d 61 6c 6c  {.      z = mall
4df0: 6f 63 28 20 6c 65 6e 2b 31 20 29 3b 0a 20 20 20  oc( len+1 );.   
4e00: 20 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 65 78     if( z==0 ) ex
4e10: 69 74 28 31 29 3b 0a 20 20 20 20 20 20 6c 65 6e  it(1);.      len
4e20: 20 3d 20 66 72 65 61 64 28 7a 2c 20 31 2c 20 6c   = fread(z, 1, l
4e30: 65 6e 2c 20 73 74 64 69 6e 29 3b 0a 20 20 20 20  en, stdin);.    
4e40: 20 20 7a 5b 6c 65 6e 5d 20 3d 20 30 3b 0a 20 20    z[len] = 0;.  
4e50: 20 20 20 20 69 66 28 20 7a 54 79 70 65 5b 30 5d      if( zType[0]
4e60: 3d 3d 27 61 27 20 29 7b 0a 20 20 20 20 20 20 20  =='a' ){.       
4e70: 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28   add_param_list(
4e80: 7a 2c 20 27 26 27 29 3b 0a 20 20 20 20 20 20 7d  z, '&');.      }
4e90: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 72  else{.        pr
4ea0: 6f 63 65 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f  ocess_multipart_
4eb0: 66 6f 72 6d 5f 64 61 74 61 28 7a 2c 20 6c 65 6e  form_data(z, len
4ec0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d  );.      }.    }
4ed0: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28  else if( strcmp(
4ee0: 7a 54 79 70 65 2c 20 22 61 70 70 6c 69 63 61 74  zType, "applicat
4ef0: 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d  ion/x-fossil")==
4f00: 30 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f  0 ){.      blob_
4f10: 72 65 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65  read_from_channe
4f20: 6c 28 26 67 2e 63 67 69 49 6e 2c 20 73 74 64 69  l(&g.cgiIn, stdi
4f30: 6e 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 62  n, len);.      b
4f40: 6c 6f 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26  lob_uncompress(&
4f50: 67 2e 63 67 69 49 6e 2c 20 26 67 2e 63 67 69 49  g.cgiIn, &g.cgiI
4f60: 6e 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  n);.    }else if
4f70: 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20  ( strcmp(zType, 
4f80: 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66  "application/x-f
4f90: 6f 73 73 69 6c 2d 64 65 62 75 67 22 29 3d 3d 30  ossil-debug")==0
4fa0: 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72   ){.      blob_r
4fb0: 65 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c  ead_from_channel
4fc0: 28 26 67 2e 63 67 69 49 6e 2c 20 73 74 64 69 6e  (&g.cgiIn, stdin
4fd0: 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 7d 0a 20 20  , len);.    }.  
4fe0: 7d 0a 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29  }..  z = (char*)
4ff0: 50 28 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 29  P("HTTP_COOKIE")
5000: 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 20  ;.  if( z ){.   
5010: 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73   z = mprintf("%s
5020: 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 61  ",z);.    add_pa
5030: 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 3b 27 29  ram_list(z, ';')
5040: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  ;.  }.}../*.** T
5050: 68 69 73 20 69 73 20 74 68 65 20 63 6f 6d 70 61  his is the compa
5060: 72 69 73 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 75  rison function u
5070: 73 65 64 20 74 6f 20 73 6f 72 74 20 74 68 65 20  sed to sort the 
5080: 61 50 61 72 61 6d 51 50 5b 5d 20 61 72 72 61 79  aParamQP[] array
5090: 20 6f 66 0a 2a 2a 20 71 75 65 72 79 20 70 61 72   of.** query par
50a0: 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b  ameters and cook
50b0: 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69  ies..*/.static i
50c0: 6e 74 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72  nt qparam_compar
50d0: 65 28 63 6f 6e 73 74 20 76 6f 69 64 20 2a 61 2c  e(const void *a,
50e0: 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 62 29 7b   const void *b){
50f0: 0a 20 20 73 74 72 75 63 74 20 51 50 61 72 61 6d  .  struct QParam
5100: 20 2a 70 41 20 3d 20 28 73 74 72 75 63 74 20 51   *pA = (struct Q
5110: 50 61 72 61 6d 2a 29 61 3b 0a 20 20 73 74 72 75  Param*)a;.  stru
5120: 63 74 20 51 50 61 72 61 6d 20 2a 70 42 20 3d 20  ct QParam *pB = 
5130: 28 73 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29  (struct QParam*)
5140: 62 3b 0a 20 20 69 6e 74 20 63 3b 0a 20 20 63 20  b;.  int c;.  c 
5150: 3d 20 73 74 72 63 6d 70 28 70 41 2d 3e 7a 4e 61  = strcmp(pA->zNa
5160: 6d 65 2c 20 70 42 2d 3e 7a 4e 61 6d 65 29 3b 0a  me, pB->zName);.
5170: 20 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20    if( c==0 ){.  
5180: 20 20 63 20 3d 20 70 41 2d 3e 73 65 71 20 2d 20    c = pA->seq - 
5190: 70 42 2d 3e 73 65 71 3b 0a 20 20 7d 0a 20 20 72  pB->seq;.  }.  r
51a0: 65 74 75 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn c;.}../*.*
51b0: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c  * Return the val
51c0: 75 65 20 6f 66 20 61 20 71 75 65 72 79 20 70 61  ue of a query pa
51d0: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69  rameter or cooki
51e0: 65 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 73 20  e whose name is 
51f0: 7a 4e 61 6d 65 2e 0a 2a 2a 20 49 66 20 74 68 65  zName..** If the
5200: 72 65 20 69 73 20 6e 6f 20 71 75 65 72 79 20 70  re is no query p
5210: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b  arameter or cook
5220: 69 65 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 61  ie named zName a
5230: 6e 64 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20  nd the first.** 
5240: 63 68 61 72 61 63 74 65 72 20 6f 66 20 7a 4e 61  character of zNa
5250: 6d 65 20 69 73 20 75 70 70 65 72 63 61 73 65 2c  me is uppercase,
5260: 20 74 68 65 6e 20 63 68 65 63 6b 20 74 6f 20 73   then check to s
5270: 65 65 20 69 66 20 74 68 65 72 65 20 69 73 20 61  ee if there is a
5280: 6e 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74  n.** environment
5290: 20 76 61 72 69 61 62 6c 65 20 62 79 20 74 68 61   variable by tha
52a0: 74 20 6e 61 6d 65 20 61 6e 64 20 72 65 74 75 72  t name and retur
52b0: 6e 20 69 74 20 69 66 20 74 68 65 72 65 20 69 73  n it if there is
52c0: 2e 20 20 41 73 0a 2a 2a 20 61 20 6c 61 73 74 20  .  As.** a last 
52d0: 72 65 73 6f 72 74 20 77 68 65 6e 20 6e 6f 74 68  resort when noth
52e0: 69 6e 67 20 65 6c 73 65 20 6d 61 74 63 68 65 73  ing else matches
52f0: 2c 20 72 65 74 75 72 6e 20 7a 44 65 66 61 75 6c  , return zDefaul
5300: 74 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72  t..*/.const char
5310: 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28   *cgi_parameter(
5320: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
5330: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  e, const char *z
5340: 44 65 66 61 75 6c 74 29 7b 0a 20 20 69 6e 74 20  Default){.  int 
5350: 6c 6f 2c 20 68 69 2c 20 6d 69 64 2c 20 63 3b 0a  lo, hi, mid, c;.
5360: 0a 20 20 2f 2a 20 54 68 65 20 73 6f 72 74 51 50  .  /* The sortQP
5370: 20 66 6c 61 67 20 69 73 20 73 65 74 20 77 68 65   flag is set whe
5380: 6e 65 76 65 72 20 61 20 6e 65 77 20 71 75 65 72  never a new quer
5390: 79 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 69  y parameter is i
53a0: 6e 73 65 72 74 65 64 2e 0a 20 20 2a 2a 20 49 74  nserted..  ** It
53b0: 20 69 6e 64 69 63 61 74 65 73 20 74 68 61 74 20   indicates that 
53c0: 77 65 20 6e 65 65 64 20 74 6f 20 72 65 73 6f 72  we need to resor
53d0: 74 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  t the query para
53e0: 6d 65 74 65 72 73 2e 0a 20 20 2a 2f 0a 20 20 69  meters..  */.  i
53f0: 66 28 20 73 6f 72 74 51 50 20 29 7b 0a 20 20 20  f( sortQP ){.   
5400: 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 20 20 71   int i, j;.    q
5410: 73 6f 72 74 28 61 50 61 72 61 6d 51 50 2c 20 6e  sort(aParamQP, n
5420: 55 73 65 64 51 50 2c 20 73 69 7a 65 6f 66 28 61  UsedQP, sizeof(a
5430: 50 61 72 61 6d 51 50 5b 30 5d 29 2c 20 71 70 61  ParamQP[0]), qpa
5440: 72 61 6d 5f 63 6f 6d 70 61 72 65 29 3b 0a 20 20  ram_compare);.  
5450: 20 20 73 6f 72 74 51 50 20 3d 20 30 3b 0a 20 20    sortQP = 0;.  
5460: 20 20 2f 2a 20 41 66 74 65 72 20 73 6f 72 74 69    /* After sorti
5470: 6e 67 2c 20 72 65 6d 6f 76 65 20 64 75 70 6c 69  ng, remove dupli
5480: 63 61 74 65 20 70 61 72 61 6d 65 74 65 72 73 2e  cate parameters.
5490: 20 20 54 68 65 20 73 65 63 6f 6e 64 61 72 79 20    The secondary 
54a0: 73 6f 72 74 0a 20 20 20 20 2a 2a 20 6b 65 79 20  sort.    ** key 
54b0: 69 73 20 61 50 61 72 61 6d 51 50 5b 5d 2e 73 65  is aParamQP[].se
54c0: 71 20 61 6e 64 20 77 65 20 6b 65 65 70 20 74 68  q and we keep th
54d0: 65 20 66 69 72 73 74 20 65 6e 74 72 79 2e 20 20  e first entry.  
54e0: 54 68 61 74 20 6d 65 61 6e 73 0a 20 20 20 20 2a  That means.    *
54f0: 2a 20 77 69 74 68 20 64 75 70 6c 69 63 61 74 65  * with duplicate
5500: 20 63 61 6c 6c 73 20 74 6f 20 63 67 69 5f 73 65   calls to cgi_se
5510: 74 5f 70 61 72 61 6d 65 74 65 72 28 29 20 74 68  t_parameter() th
5520: 65 20 73 65 63 6f 6e 64 20 61 6e 64 0a 20 20 20  e second and.   
5530: 20 2a 2a 20 73 75 62 73 65 71 75 65 6e 74 20 63   ** subsequent c
5540: 61 6c 6c 73 20 61 72 65 20 65 66 66 65 63 74 69  alls are effecti
5550: 76 65 6c 79 20 6e 6f 2d 6f 70 73 2e 20 2a 2f 0a  vely no-ops. */.
5560: 20 20 20 20 66 6f 72 28 69 3d 6a 3d 31 3b 20 69      for(i=j=1; i
5570: 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a  <nUsedQP; i++){.
5580: 20 20 20 20 20 20 69 66 28 20 73 74 72 63 6d 70        if( strcmp
5590: 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61  (aParamQP[i].zNa
55a0: 6d 65 2c 61 50 61 72 61 6d 51 50 5b 69 2d 31 5d  me,aParamQP[i-1]
55b0: 2e 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20  .zName)==0 ){.  
55c0: 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a        continue;.
55d0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66        }.      if
55e0: 28 20 6a 3c 69 20 29 7b 0a 20 20 20 20 20 20 20  ( j<i ){.       
55f0: 20 6d 65 6d 63 70 79 28 26 61 50 61 72 61 6d 51   memcpy(&aParamQ
5600: 50 5b 6a 5d 2c 20 26 61 50 61 72 61 6d 51 50 5b  P[j], &aParamQP[
5610: 69 5d 2c 20 73 69 7a 65 6f 66 28 61 50 61 72 61  i], sizeof(aPara
5620: 6d 51 50 5b 6a 5d 29 29 3b 0a 20 20 20 20 20 20  mQP[j]));.      
5630: 7d 0a 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 20 20  }.      j++;.   
5640: 20 7d 0a 20 20 20 20 6e 55 73 65 64 51 50 20 3d   }.    nUsedQP =
5650: 20 6a 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 6f   j;.  }..  /* Do
5660: 20 61 20 62 69 6e 61 72 79 20 73 65 61 72 63 68   a binary search
5670: 20 66 6f 72 20 61 20 6d 61 74 63 68 69 6e 67 20   for a matching 
5680: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20  query parameter 
5690: 2a 2f 0a 20 20 6c 6f 20 3d 20 30 3b 0a 20 20 68  */.  lo = 0;.  h
56a0: 69 20 3d 20 6e 55 73 65 64 51 50 2d 31 3b 0a 20  i = nUsedQP-1;. 
56b0: 20 77 68 69 6c 65 28 20 6c 6f 3c 3d 68 69 20 29   while( lo<=hi )
56c0: 7b 0a 20 20 20 20 6d 69 64 20 3d 20 28 6c 6f 2b  {.    mid = (lo+
56d0: 68 69 29 2f 32 3b 0a 20 20 20 20 63 20 3d 20 73  hi)/2;.    c = s
56e0: 74 72 63 6d 70 28 61 50 61 72 61 6d 51 50 5b 6d  trcmp(aParamQP[m
56f0: 69 64 5d 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65  id].zName, zName
5700: 29 3b 0a 20 20 20 20 69 66 28 20 63 3d 3d 30 20  );.    if( c==0 
5710: 29 7b 0a 20 20 20 20 20 20 43 47 49 44 45 42 55  ){.      CGIDEBU
5720: 47 28 28 22 6d 65 6d 2d 6d 61 74 63 68 20 5b 25  G(("mem-match [%
5730: 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e  s] = [%s]\n", zN
5740: 61 6d 65 2c 20 61 50 61 72 61 6d 51 50 5b 6d 69  ame, aParamQP[mi
5750: 64 5d 2e 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20  d].zValue));.   
5760: 20 20 20 72 65 74 75 72 6e 20 61 50 61 72 61 6d     return aParam
5770: 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 3b 0a  QP[mid].zValue;.
5780: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3e      }else if( c>
5790: 30 20 29 7b 0a 20 20 20 20 20 20 68 69 20 3d 20  0 ){.      hi = 
57a0: 6d 69 64 2d 31 3b 0a 20 20 20 20 7d 65 6c 73 65  mid-1;.    }else
57b0: 7b 0a 20 20 20 20 20 20 6c 6f 20 3d 20 6d 69 64  {.      lo = mid
57c0: 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  +1;.    }.  }.. 
57d0: 20 2f 2a 20 49 66 20 6e 6f 20 6d 61 74 63 68 20   /* If no match 
57e0: 69 73 20 66 6f 75 6e 64 20 61 6e 64 20 74 68 65  is found and the
57f0: 20 6e 61 6d 65 20 62 65 67 69 6e 73 20 77 69 74   name begins wit
5800: 68 20 61 6e 20 75 70 70 65 72 2d 63 61 73 65 0a  h an upper-case.
5810: 20 20 2a 2a 20 6c 65 74 74 65 72 2c 20 74 68 65    ** letter, the
5820: 6e 20 63 68 65 63 6b 20 74 6f 20 73 65 65 20 69  n check to see i
5830: 66 20 74 68 65 72 65 20 69 73 20 61 6e 20 65 6e  f there is an en
5840: 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62  vironment variab
5850: 6c 65 0a 20 20 2a 2a 20 77 69 74 68 20 74 68 65  le.  ** with the
5860: 20 67 69 76 65 6e 20 6e 61 6d 65 2e 0a 20 20 2a   given name..  *
5870: 2f 0a 20 20 69 66 28 20 69 73 75 70 70 65 72 28  /.  if( isupper(
5880: 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20  zName[0]) ){.   
5890: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61   const char *zVa
58a0: 6c 75 65 20 3d 20 67 65 74 65 6e 76 28 7a 4e 61  lue = getenv(zNa
58b0: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61  me);.    if( zVa
58c0: 6c 75 65 20 29 7b 0a 20 20 20 20 20 20 63 67 69  lue ){.      cgi
58d0: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e  _set_parameter_n
58e0: 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61  ocopy(zName, zVa
58f0: 6c 75 65 29 3b 0a 20 20 20 20 20 20 43 47 49 44  lue);.      CGID
5900: 45 42 55 47 28 28 22 65 6e 76 2d 6d 61 74 63 68  EBUG(("env-match
5910: 20 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c   [%s] = [%s]\n",
5920: 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 29   zName, zValue))
5930: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 7a  ;.      return z
5940: 56 61 6c 75 65 3b 0a 20 20 20 20 7d 0a 20 20 7d  Value;.    }.  }
5950: 0a 20 20 43 47 49 44 45 42 55 47 28 28 22 6e 6f  .  CGIDEBUG(("no
5960: 2d 6d 61 74 63 68 20 5b 25 73 5d 5c 6e 22 2c 20  -match [%s]\n", 
5970: 7a 4e 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72  zName));.  retur
5980: 6e 20 7a 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a 2f  n zDefault;.}../
5990: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20  *.** Return the 
59a0: 6e 61 6d 65 20 6f 66 20 74 68 65 20 69 2d 74 68  name of the i-th
59b0: 20 43 47 49 20 70 61 72 61 6d 65 74 65 72 2e 20   CGI parameter. 
59c0: 20 52 65 74 75 72 6e 20 4e 55 4c 4c 20 69 66 20   Return NULL if 
59d0: 74 68 65 72 65 0a 2a 2a 20 61 72 65 20 66 65 77  there.** are few
59e0: 65 72 20 74 68 61 6e 20 69 20 72 65 67 69 73 74  er than i regist
59f0: 65 72 65 64 20 43 47 49 20 70 61 72 6d 61 65 74  ered CGI parmaet
5a00: 65 72 73 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68  ers..*/.const ch
5a10: 61 72 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 65  ar *cgi_paramete
5a20: 72 5f 6e 61 6d 65 28 69 6e 74 20 69 29 7b 0a 20  r_name(int i){. 
5a30: 20 69 66 28 20 69 3e 3d 30 20 26 26 20 69 3c 6e   if( i>=0 && i<n
5a40: 55 73 65 64 51 50 20 29 7b 0a 20 20 20 20 72 65  UsedQP ){.    re
5a50: 74 75 72 6e 20 61 50 61 72 61 6d 51 50 5b 69 5d  turn aParamQP[i]
5a60: 2e 7a 4e 61 6d 65 3b 0a 20 20 7d 65 6c 73 65 7b  .zName;.  }else{
5a70: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
5a80: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e   }.}../*.** Prin
5a90: 74 20 43 47 49 20 64 65 62 75 67 67 69 6e 67 20  t CGI debugging 
5aa0: 6d 65 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69  messages..*/.voi
5ab0: 64 20 63 67 69 5f 64 65 62 75 67 28 63 6f 6e 73  d cgi_debug(cons
5ac0: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c  t char *zFormat,
5ad0: 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74   ...){.  va_list
5ae0: 20 61 70 3b 0a 20 20 69 66 28 20 67 2e 66 44 65   ap;.  if( g.fDe
5af0: 62 75 67 20 29 7b 0a 20 20 20 20 76 61 5f 73 74  bug ){.    va_st
5b00: 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29  art(ap, zFormat)
5b10: 3b 0a 20 20 20 20 76 66 70 72 69 6e 74 66 28 67  ;.    vfprintf(g
5b20: 2e 66 44 65 62 75 67 2c 20 7a 46 6f 72 6d 61 74  .fDebug, zFormat
5b30: 2c 20 61 70 29 3b 0a 20 20 20 20 76 61 5f 65 6e  , ap);.    va_en
5b40: 64 28 61 70 29 3b 0a 20 20 20 20 66 66 6c 75 73  d(ap);.    fflus
5b50: 68 28 67 2e 66 44 65 62 75 67 29 3b 0a 20 20 7d  h(g.fDebug);.  }
5b60: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
5b70: 20 74 72 75 65 20 69 66 20 61 6e 79 20 6f 66 20   true if any of 
5b80: 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65  the query parame
5b90: 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 67 75  ters in the argu
5ba0: 6d 65 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 72 65  ment.** list are
5bb0: 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74   defined..*/.int
5bc0: 20 63 67 69 5f 61 6e 79 28 63 6f 6e 73 74 20 63   cgi_any(const c
5bd0: 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20  har *z, ...){.  
5be0: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68  va_list ap;.  ch
5bf0: 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 67  ar *z2;.  if( cg
5c00: 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 29  i_parameter(z,0)
5c10: 21 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a  !=0 ) return 1;.
5c20: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a    va_start(ap, z
5c30: 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 20  );.  while( (z2 
5c40: 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61  = va_arg(ap, cha
5c50: 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69  r*))!=0 ){.    i
5c60: 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72  f( cgi_parameter
5c70: 28 7a 32 2c 30 29 21 3d 30 20 29 20 72 65 74 75  (z2,0)!=0 ) retu
5c80: 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 76 61 5f 65  rn 1;.  }.  va_e
5c90: 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72 6e  nd(ap);.  return
5ca0: 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74   0;.}../*.** Ret
5cb0: 75 72 6e 20 74 72 75 65 20 69 66 20 61 6c 6c 20  urn true if all 
5cc0: 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72  of the query par
5cd0: 61 6d 65 74 65 72 73 20 69 6e 20 74 68 65 20 61  ameters in the a
5ce0: 72 67 75 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a 20  rgument list.** 
5cf0: 61 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a  are defined..*/.
5d00: 69 6e 74 20 63 67 69 5f 61 6c 6c 28 63 6f 6e 73  int cgi_all(cons
5d10: 74 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b  t char *z, ...){
5d20: 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20  .  va_list ap;. 
5d30: 20 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28   char *z2;.  if(
5d40: 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a   cgi_parameter(z
5d50: 2c 30 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  ,0)==0 ) return 
5d60: 30 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70  0;.  va_start(ap
5d70: 2c 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28  , z);.  while( (
5d80: 7a 32 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20  z2 = va_arg(ap, 
5d90: 63 68 61 72 2a 29 29 3d 3d 30 20 29 7b 0a 20 20  char*))==0 ){.  
5da0: 20 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65    if( cgi_parame
5db0: 74 65 72 28 7a 32 2c 30 29 3d 3d 30 20 29 20 72  ter(z2,0)==0 ) r
5dc0: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 76  eturn 0;.  }.  v
5dd0: 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74  a_end(ap);.  ret
5de0: 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn 1;.}../*.** 
5df0: 50 72 69 6e 74 20 61 6c 6c 20 71 75 65 72 79 20  Print all query 
5e00: 70 61 72 61 6d 65 74 65 72 73 20 6f 6e 20 73 74  parameters on st
5e10: 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 20 20  andard output.  
5e20: 46 6f 72 6d 61 74 20 74 68 65 0a 2a 2a 20 70 61  Format the.** pa
5e30: 72 61 6d 65 74 65 72 73 20 61 73 20 48 54 4d 4c  rameters as HTML
5e40: 2e 20 20 54 68 69 73 20 69 73 20 75 73 65 64 20  .  This is used 
5e50: 66 6f 72 20 74 65 73 74 69 6e 67 20 61 6e 64 20  for testing and 
5e60: 64 65 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76 6f  debugging..*/.vo
5e70: 69 64 20 63 67 69 5f 70 72 69 6e 74 5f 61 6c 6c  id cgi_print_all
5e80: 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b  (void){.  int i;
5e90: 0a 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72  .  cgi_parameter
5ea0: 28 22 22 2c 22 22 29 3b 20 20 2f 2a 20 46 6f 72  ("","");  /* For
5eb0: 63 65 20 74 68 65 20 70 61 72 61 6d 65 74 65 72  ce the parameter
5ec0: 73 20 69 6e 74 6f 20 73 6f 72 74 65 64 20 6f 72  s into sorted or
5ed0: 64 65 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30  der */.  for(i=0
5ee0: 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b  ; i<nUsedQP; i++
5ef0: 29 7b 0a 20 20 20 20 63 67 69 5f 70 72 69 6e 74  ){.    cgi_print
5f00: 66 28 22 25 73 20 3d 20 25 73 20 20 3c 62 72 20  f("%s = %s  <br 
5f10: 2f 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 68 74  />\n",.       ht
5f20: 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69  mlize(aParamQP[i
5f30: 5d 2e 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 68 74  ].zName, -1), ht
5f40: 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69  mlize(aParamQP[i
5f50: 5d 2e 7a 56 61 6c 75 65 2c 20 2d 31 29 29 3b 0a  ].zValue, -1));.
5f60: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69    }.}../*.** Wri
5f70: 74 65 20 48 54 4d 4c 20 74 65 78 74 20 66 6f 72  te HTML text for
5f80: 20 61 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20   an option menu 
5f90: 74 6f 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70  to standard outp
5fa0: 75 74 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a 20 69  ut.  zParam.** i
5fb0: 73 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  s the query para
5fc0: 6d 65 74 65 72 20 74 68 61 74 20 74 68 65 20 6f  meter that the o
5fd0: 70 74 69 6f 6e 20 6d 65 6e 75 20 73 65 74 73 2e  ption menu sets.
5fe0: 20 20 7a 44 66 6c 74 20 69 73 20 74 68 65 0a 2a    zDflt is the.*
5ff0: 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 20  * initial value 
6000: 6f 66 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65  of the option me
6010: 6e 75 2e 20 20 41 64 64 69 74 69 6f 6e 20 61 72  nu.  Addition ar
6020: 67 75 6d 65 6e 74 73 20 61 72 65 20 6e 61 6d 65  guments are name
6030: 2f 76 61 6c 75 65 0a 2a 2a 20 70 61 69 72 73 20  /value.** pairs 
6040: 74 68 61 74 20 64 65 66 69 6e 65 20 76 61 6c 75  that define valu
6050: 65 73 20 6f 6e 20 74 68 65 20 6d 65 6e 75 2e 20  es on the menu. 
6060: 20 54 68 65 20 6c 69 73 74 20 69 73 20 74 65 72   The list is ter
6070: 6d 69 6e 61 74 65 64 20 77 69 74 68 0a 2a 2a 20  minated with.** 
6080: 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 61 72  a single NULL ar
6090: 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20  gument..*/.void 
60a0: 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 69  cgi_optionmenu(i
60b0: 6e 74 20 69 6e 2c 20 63 6f 6e 73 74 20 63 68 61  nt in, const cha
60c0: 72 20 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 68 61  r *zP, const cha
60d0: 72 20 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20 76  r *zD, ...){.  v
60e0: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61  a_list ap;.  cha
60f0: 72 20 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c 3b  r *zName, *zVal;
6100: 0a 20 20 69 6e 74 20 64 66 6c 74 53 65 65 6e 20  .  int dfltSeen 
6110: 3d 20 30 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74  = 0;.  cgi_print
6120: 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69  f("%*s<select si
6130: 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22  ze=1 name=\"%s\"
6140: 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50  >\n", in, "", zP
6150: 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70  );.  va_start(ap
6160: 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20  , zD);.  while( 
6170: 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28  (zName = va_arg(
6180: 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26  ap, char*))!=0 &
6190: 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67  & (zVal = va_arg
61a0: 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20  (ap, char*))!=0 
61b0: 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d  ){.    if( strcm
61c0: 70 28 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 29 7b  p(zVal,zD)==0 ){
61d0: 20 64 66 6c 74 53 65 65 6e 20 3d 20 31 3b 20 62   dfltSeen = 1; b
61e0: 72 65 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76 61  reak; }.  }.  va
61f0: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 69 66 28 20  _end(ap);.  if( 
6200: 21 64 66 6c 74 53 65 65 6e 20 29 7b 0a 20 20 20  !dfltSeen ){.   
6210: 20 69 66 28 20 7a 44 5b 30 5d 20 29 7b 0a 20 20   if( zD[0] ){.  
6220: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22      cgi_printf("
6230: 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65  %*s<option value
6240: 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64  =\"%h\" selected
6250: 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c  >%h</option>\n",
6260: 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22  .        in+2, "
6270: 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20  ", zD, zD);.    
6280: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69  }else{.      cgi
6290: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74  _printf("%*s<opt
62a0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73  ion value=\"\" s
62b0: 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f  elected>&nbsp;</
62c0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b 32  option>\n", in+2
62d0: 2c 20 22 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  , "");.    }.  }
62e0: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20  .  va_start(ap, 
62f0: 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a  zD);.  while( (z
6300: 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70  Name = va_arg(ap
6310: 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20  , char*))!=0 && 
6320: 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61  (zVal = va_arg(a
6330: 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b  p, char*))!=0 ){
6340: 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30  .    if( zName[0
6350: 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70  ] ){.      cgi_p
6360: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f  rintf("%*s<optio
6370: 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73  n value=\"%h\"%s
6380: 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c  >%h</option>\n",
6390: 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22  .        in+2, "
63a0: 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c  ",.        zVal,
63b0: 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28  .        strcmp(
63c0: 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a  zVal, zD) ? "" :
63d0: 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 20   " selected",.  
63e0: 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 20        zName.    
63f0: 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a    );.    }else{.
6400: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66        cgi_printf
6410: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c  ("%*s<option val
6420: 75 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b  ue=\"\"%s>&nbsp;
6430: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20  </option>\n",.  
6440: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a        in+2, "",.
6450: 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a          strcmp(z
6460: 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20  Val, zD) ? "" : 
6470: 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 20  " selected".    
6480: 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20    );.    }.  }. 
6490: 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63   va_end(ap);.  c
64a0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f  gi_printf("%*s</
64b0: 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20  select>\n", in, 
64c0: 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  "");.}../*.** Th
64d0: 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73  is routine works
64e0: 20 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69 5f   a lot like cgi_
64f0: 6f 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63  optionmenu() exc
6500: 65 70 74 20 74 68 61 74 20 74 68 65 20 6c 69 73  ept that the lis
6510: 74 20 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 20 69  t of.** values i
6520: 73 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 61  s contained in a
6530: 6e 20 61 72 72 61 79 2e 20 20 41 6c 73 6f 2c 20  n array.  Also, 
6540: 74 68 65 20 76 61 6c 75 65 73 20 61 72 65 20 6a  the values are j
6550: 75 73 74 20 76 61 6c 75 65 73 2c 20 6e 6f 74 0a  ust values, not.
6560: 2a 2a 20 6e 61 6d 65 2f 76 61 6c 75 65 20 70 61  ** name/value pa
6570: 69 72 73 20 61 73 20 69 6e 20 63 67 69 5f 6f 70  irs as in cgi_op
6580: 74 69 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f 69  tionmenu..*/.voi
6590: 64 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65  d cgi_v_optionme
65a0: 6e 75 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20  nu(.  int in,   
65b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e             /* In
65c0: 64 65 6e 74 20 62 79 20 74 68 69 73 20 61 6d 6f  dent by this amo
65d0: 75 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  unt */.  const c
65e0: 68 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a  har *zP,      /*
65f0: 20 54 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   The query param
6600: 65 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63  eter name */.  c
6610: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 20  onst char *zD,  
6620: 20 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 76      /* Default v
6630: 61 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  alue */.  const 
6640: 63 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f  char **az      /
6650: 2a 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65  * NULL-terminate
6660: 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65  d list of allowe
6670: 64 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20  d values */.){. 
6680: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61   const char *zVa
6690: 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67  l;.  int i;.  cg
66a0: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65  i_printf("%*s<se
66b0: 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65  lect size=1 name
66c0: 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c  =\"%s\">\n", in,
66d0: 20 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28   "", zP);.  for(
66e0: 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b 29  i=0; az[i]; i++)
66f0: 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70  {.    if( strcmp
6700: 28 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20  (az[i],zD)==0 ) 
6710: 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28  break;.  }.  if(
6720: 20 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20   az[i]==0 ){.   
6730: 20 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b   if( zD[0]==0 ){
6740: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74  .      cgi_print
6750: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61  f("%*s<option va
6760: 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65  lue=\"\" selecte
6770: 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e  d>&nbsp;</option
6780: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b  >\n",.       in+
6790: 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73  2, "");.    }els
67a0: 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  e{.      cgi_pri
67b0: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20  ntf("%*s<option 
67c0: 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c  value=\"%h\" sel
67d0: 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e  ected>%h</option
67e0: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b  >\n",.       in+
67f0: 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a  2, "", zD, zD);.
6800: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c      }.  }.  whil
6810: 65 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b  e( (zVal = *(az+
6820: 2b 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 69  +))!=0  ){.    i
6830: 66 28 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20 20  f( zVal[0] ){.  
6840: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22      cgi_printf("
6850: 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65  %*s<option value
6860: 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70  =\"%h\"%s>%h</op
6870: 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20  tion>\n",.      
6880: 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20    in+2, "",.    
6890: 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20      zVal,.      
68a0: 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a    strcmp(zVal, z
68b0: 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65  D) ? "" : " sele
68c0: 63 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a  cted",.        z
68d0: 56 61 6c 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  Val.      );.   
68e0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67   }else{.      cg
68f0: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70  i_printf("%*s<op
6900: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25  tion value=\"\"%
6910: 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e  s>&nbsp;</option
6920: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e  >\n",.        in
6930: 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20  +2, "",.        
6940: 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29  strcmp(zVal, zD)
6950: 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74   ? "" : " select
6960: 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ed".      );.   
6970: 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72 69   }.  }.  cgi_pri
6980: 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74  ntf("%*s</select
6990: 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d  >\n", in, "");.}
69a0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ../*.** This rou
69b0: 74 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74  tine works a lot
69c0: 20 6c 69 6b 65 20 63 67 69 5f 76 5f 6f 70 74 69   like cgi_v_opti
69d0: 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 74 20  onmenu() except 
69e0: 74 68 61 74 20 74 68 65 20 6c 69 73 74 0a 2a 2a  that the list.**
69f0: 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20 70 61   is a list of pa
6a00: 69 72 73 2e 20 20 54 68 65 20 66 69 72 73 74 20  irs.  The first 
6a10: 65 6c 65 6d 65 6e 74 20 6f 66 20 65 61 63 68 20  element of each 
6a20: 70 61 69 72 20 69 73 20 74 68 65 20 76 61 6c 75  pair is the valu
6a30: 65 20 75 73 65 64 0a 2a 2a 20 69 6e 74 65 72 6e  e used.** intern
6a40: 61 6c 6c 79 20 61 6e 64 20 74 68 65 20 73 65 63  ally and the sec
6a50: 6f 6e 64 20 65 6c 65 6d 65 6e 74 20 69 73 20 74  ond element is t
6a60: 68 65 20 76 61 6c 75 65 20 64 69 73 70 6c 61 79  he value display
6a70: 65 64 20 74 6f 20 74 68 65 20 75 73 65 72 2e 0a  ed to the user..
6a80: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f 70  */.void cgi_v_op
6a90: 74 69 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 6e 74  tionmenu2(.  int
6aa0: 20 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20   in,            
6ab0: 20 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20 74    /* Indent by t
6ac0: 68 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 20  his amount */.  
6ad0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20  const char *zP, 
6ae0: 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72       /* The quer
6af0: 79 20 70 61 72 61 6d 65 74 65 72 20 6e 61 6d 65  y parameter name
6b00: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
6b10: 20 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44 65   *zD,      /* De
6b20: 66 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a 20  fault value */. 
6b30: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a   const char **az
6b40: 20 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 65        /* NULL-te
6b50: 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 6f 66  rminated list of
6b60: 20 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20   allowed values 
6b70: 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68  */.){.  const ch
6b80: 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20  ar *zVal;.  int 
6b90: 69 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28  i;.  cgi_printf(
6ba0: 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65  "%*s<select size
6bb0: 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c  =1 name=\"%s\">\
6bc0: 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b  n", in, "", zP);
6bd0: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69  .  for(i=0; az[i
6be0: 5d 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20 69 66  ]; i+=2){.    if
6bf0: 28 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a  ( strcmp(az[i],z
6c00: 44 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20  D)==0 ) break;. 
6c10: 20 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d   }.  if( az[i]==
6c20: 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b  0 ){.    if( zD[
6c30: 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63  0]==0 ){.      c
6c40: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f  gi_printf("%*s<o
6c50: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22  ption value=\"\"
6c60: 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b   selected>&nbsp;
6c70: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20  </option>\n",.  
6c80: 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a       in+2, "");.
6c90: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
6ca0: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73   cgi_printf("%*s
6cb0: 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22  <option value=\"
6cc0: 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 68  %h\" selected>%h
6cd0: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20  </option>\n",.  
6ce0: 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a       in+2, "", z
6cf0: 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20  D, zD);.    }.  
6d00: 7d 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 61 6c  }.  while( (zVal
6d10: 20 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20   = *(az++))!=0  
6d20: 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61  ){.    const cha
6d30: 72 20 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a 2b  r *zName = *(az+
6d40: 2b 29 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d  +);.    if( zNam
6d50: 65 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67  e[0] ){.      cg
6d60: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70  i_printf("%*s<op
6d70: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c  tion value=\"%h\
6d80: 22 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c  "%s>%h</option>\
6d90: 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32  n",.        in+2
6da0: 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56  , "",.        zV
6db0: 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63  al,.        strc
6dc0: 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22  mp(zVal, zD) ? "
6dd0: 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c  " : " selected",
6de0: 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20  .        zName. 
6df0: 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73       );.    }els
6e00: 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  e{.      cgi_pri
6e10: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20  ntf("%*s<option 
6e20: 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 26  value=\"%h\"%s>&
6e30: 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e  nbsp;</option>\n
6e40: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c  ",.        in+2,
6e50: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61   "",.        zVa
6e60: 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d  l,.        strcm
6e70: 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22  p(zVal, zD) ? ""
6e80: 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20   : " selected". 
6e90: 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20       );.    }.  
6ea0: 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22  }.  cgi_printf("
6eb0: 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c  %*s</select>\n",
6ec0: 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a   in, "");.}../*.
6ed0: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
6ee0: 77 6f 72 6b 73 20 6c 69 6b 65 20 22 70 72 69 6e  works like "prin
6ef0: 74 66 22 20 65 78 63 65 70 74 20 74 68 61 74 20  tf" except that 
6f00: 69 74 20 68 61 73 20 74 68 65 0a 2a 2a 20 65 78  it has the.** ex
6f10: 74 72 61 20 66 6f 72 6d 61 74 74 69 6e 67 20 63  tra formatting c
6f20: 61 70 61 62 69 6c 69 74 69 65 73 20 73 75 63 68  apabilities such
6f30: 20 61 73 20 25 68 20 61 6e 64 20 25 74 2e 0a 2a   as %h and %t..*
6f40: 2f 0a 76 6f 69 64 20 63 67 69 5f 70 72 69 6e 74  /.void cgi_print
6f50: 66 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46  f(const char *zF
6f60: 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76  ormat, ...){.  v
6f70: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f  a_list ap;.  va_
6f80: 73 74 61 72 74 28 61 70 2c 7a 46 6f 72 6d 61 74  start(ap,zFormat
6f90: 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 70 43  );.  vxprintf(pC
6fa0: 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61  ontent,zFormat,a
6fb0: 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29  p);.  va_end(ap)
6fc0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20  ;.}../*.** This 
6fd0: 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69  routine works li
6fe0: 6b 65 20 22 76 70 72 69 6e 74 66 22 20 65 78 63  ke "vprintf" exc
6ff0: 65 70 74 20 74 68 61 74 20 69 74 20 68 61 73 20  ept that it has 
7000: 74 68 65 0a 2a 2a 20 65 78 74 72 61 20 66 6f 72  the.** extra for
7010: 6d 61 74 74 69 6e 67 20 63 61 70 61 62 69 6c 69  matting capabili
7020: 74 69 65 73 20 73 75 63 68 20 61 73 20 25 68 20  ties such as %h 
7030: 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20  and %t..*/.void 
7040: 63 67 69 5f 76 70 72 69 6e 74 66 28 63 6f 6e 73  cgi_vprintf(cons
7050: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c  t char *zFormat,
7060: 20 76 61 5f 6c 69 73 74 20 61 70 29 7b 0a 20 20   va_list ap){.  
7070: 76 78 70 72 69 6e 74 66 28 70 43 6f 6e 74 65 6e  vxprintf(pConten
7080: 74 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 7d  t,zFormat,ap);.}
7090: 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20  .../*.** Send a 
70a0: 72 65 70 6c 79 20 69 6e 64 69 63 61 74 69 6e 67  reply indicating
70b0: 20 74 68 61 74 20 74 68 65 20 48 54 54 50 20 72   that the HTTP r
70c0: 65 71 75 65 73 74 20 77 61 73 20 6d 61 6c 66 6f  equest was malfo
70d0: 72 6d 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 76  rmed.*/.static v
70e0: 6f 69 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65  oid malformed_re
70f0: 71 75 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 63  quest(void){.  c
7100: 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 35 30  gi_set_status(50
7110: 31 2c 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e  1, "Not Implemen
7120: 74 65 64 22 29 3b 0a 20 20 63 67 69 5f 70 72 69  ted");.  cgi_pri
7130: 6e 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e  ntf(.    "<html>
7140: 3c 62 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69 7a  <body>Unrecogniz
7150: 65 64 20 48 54 54 50 20 52 65 71 75 65 73 74 3c  ed HTTP Request<
7160: 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e 22  /body></html>\n"
7170: 0a 20 20 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c  .  );.  cgi_repl
7180: 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a  y();.  exit(0);.
7190: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 61  }../*.** Panic a
71a0: 6e 64 20 64 69 65 20 77 68 69 6c 65 20 70 72 6f  nd die while pro
71b0: 63 65 73 73 69 6e 67 20 61 20 77 65 62 70 61 67  cessing a webpag
71c0: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70  e..*/.void cgi_p
71d0: 61 6e 69 63 28 63 6f 6e 73 74 20 63 68 61 72 20  anic(const char 
71e0: 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a  *zFormat, ...){.
71f0: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20    va_list ap;.  
7200: 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e  cgi_reset_conten
7210: 74 28 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73  t();.  cgi_set_s
7220: 74 61 74 75 73 28 35 30 30 2c 20 22 49 6e 74 65  tatus(500, "Inte
7230: 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f  rnal Server Erro
7240: 72 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74  r");.  cgi_print
7250: 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62  f(.    "<html><b
7260: 6f 64 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 6c  ody><h1>Internal
7270: 20 53 65 72 76 65 72 20 45 72 72 6f 72 3c 2f 68   Server Error</h
7280: 31 3e 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61 69  1>\n".    "<plai
7290: 6e 74 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20 76  ntext>".  );.  v
72a0: 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72  a_start(ap, zFor
72b0: 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66  mat);.  vxprintf
72c0: 28 70 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61  (pContent,zForma
72d0: 74 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28  t,ap);.  va_end(
72e0: 61 70 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79  ap);.  cgi_reply
72f0: 28 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d  ();.  exit(1);.}
7300: 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74  ../*.** Remove t
7310: 68 65 20 66 69 72 73 74 20 73 70 61 63 65 2d 64  he first space-d
7320: 65 6c 69 6d 69 74 65 64 20 74 6f 6b 65 6e 20 66  elimited token f
7330: 72 6f 6d 20 61 20 73 74 72 69 6e 67 20 61 6e 64  rom a string and
7340: 20 72 65 74 75 72 6e 0a 2a 2a 20 61 20 70 6f 69   return.** a poi
7350: 6e 74 65 72 20 74 6f 20 69 74 2e 20 20 41 64 64  nter to it.  Add
7360: 20 61 20 4e 55 4c 4c 20 74 6f 20 74 68 65 20 73   a NULL to the s
7370: 74 72 69 6e 67 20 74 6f 20 74 65 72 6d 69 6e 61  tring to termina
7380: 74 65 20 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a  te the token..**
7390: 20 4d 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 72   Make *zLeftOver
73a0: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74   point to the st
73b0: 61 72 74 20 6f 66 20 74 68 65 20 6e 65 78 74 20  art of the next 
73c0: 74 6f 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63  token..*/.static
73d0: 20 63 68 61 72 20 2a 65 78 74 72 61 63 74 5f 74   char *extract_t
73e0: 6f 6b 65 6e 28 63 68 61 72 20 2a 7a 49 6e 70 75  oken(char *zInpu
73f0: 74 2c 20 63 68 61 72 20 2a 2a 7a 4c 65 66 74 4f  t, char **zLeftO
7400: 76 65 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52  ver){.  char *zR
7410: 65 73 75 6c 74 20 3d 20 30 3b 0a 20 20 69 66 28  esult = 0;.  if(
7420: 20 7a 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20   zInput==0 ){.  
7430: 20 20 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 20    if( zLeftOver 
7440: 29 20 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 30  ) *zLeftOver = 0
7450: 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a  ;.    return 0;.
7460: 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 69 73 73    }.  while( iss
7470: 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b  pace(*zInput) ){
7480: 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a   zInput++; }.  z
7490: 52 65 73 75 6c 74 20 3d 20 7a 49 6e 70 75 74 3b  Result = zInput;
74a0: 0a 20 20 77 68 69 6c 65 28 20 2a 7a 49 6e 70 75  .  while( *zInpu
74b0: 74 20 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a  t && !isspace(*z
74c0: 49 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74  Input) ){ zInput
74d0: 2b 2b 3b 20 7d 0a 20 20 69 66 28 20 2a 7a 49 6e  ++; }.  if( *zIn
74e0: 70 75 74 20 29 7b 0a 20 20 20 20 2a 7a 49 6e 70  put ){.    *zInp
74f0: 75 74 20 3d 20 30 3b 0a 20 20 20 20 7a 49 6e 70  ut = 0;.    zInp
7500: 75 74 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28  ut++;.    while(
7510: 20 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74   isspace(*zInput
7520: 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d  ) ){ zInput++; }
7530: 0a 20 20 7d 0a 20 20 69 66 28 20 7a 4c 65 66 74  .  }.  if( zLeft
7540: 4f 76 65 72 20 29 7b 20 2a 7a 4c 65 66 74 4f 76  Over ){ *zLeftOv
7550: 65 72 20 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a 20  er = zInput; }. 
7560: 20 72 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b   return zResult;
7570: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72  .}../*.** This r
7580: 6f 75 74 69 6e 65 20 68 61 6e 64 6c 65 73 20 61  outine handles a
7590: 20 73 69 6e 67 6c 65 20 48 54 54 50 20 72 65 71   single HTTP req
75a0: 75 65 73 74 20 77 68 69 63 68 20 69 73 20 63 6f  uest which is co
75b0: 6d 69 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74  ming in on.** st
75c0: 61 6e 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64  andard input and
75d0: 20 77 68 69 63 68 20 72 65 70 6c 69 65 73 20 6f   which replies o
75e0: 6e 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75  n standard outpu
75f0: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 54  t..**.** The HTT
7600: 50 20 72 65 71 75 65 73 74 20 69 73 20 72 65 61  P request is rea
7610: 64 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 20  d from standard 
7620: 69 6e 70 75 74 20 61 6e 64 20 69 73 20 75 73 65  input and is use
7630: 64 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 0a  d to initialize.
7640: 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76  ** environment v
7650: 61 72 69 61 62 6c 65 73 20 61 73 20 70 65 72 20  ariables as per 
7660: 43 47 49 2e 20 20 54 68 65 20 63 67 69 5f 69 6e  CGI.  The cgi_in
7670: 69 74 28 29 20 72 6f 75 74 69 6e 65 20 74 6f 20  it() routine to 
7680: 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 65 20  complete.** the 
7690: 73 65 74 75 70 2e 20 20 4f 6e 63 65 20 61 6c 6c  setup.  Once all
76a0: 20 74 68 65 20 73 65 74 75 70 20 69 73 20 66 69   the setup is fi
76b0: 6e 69 73 68 65 64 2c 20 74 68 69 73 20 70 72 6f  nished, this pro
76c0: 63 65 64 75 72 65 20 72 65 74 75 72 6e 73 0a 2a  cedure returns.*
76d0: 2a 20 61 6e 64 20 73 75 62 73 65 71 75 65 6e 74  * and subsequent
76e0: 20 63 6f 64 65 20 68 61 6e 64 6c 65 73 20 74 68   code handles th
76f0: 65 20 61 63 74 75 61 6c 20 67 65 6e 65 72 61 74  e actual generat
7700: 69 6f 6e 20 6f 66 20 74 68 65 20 77 65 62 70 61  ion of the webpa
7710: 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  ge..*/.void cgi_
7720: 68 61 6e 64 6c 65 5f 68 74 74 70 5f 72 65 71 75  handle_http_requ
7730: 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61  est(void){.  cha
7740: 72 20 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20  r *z, *zToken;. 
7750: 20 69 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 74   int i;.  struct
7760: 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 6d   sockaddr_in rem
7770: 6f 74 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 5f  oteName;.  size_
7780: 74 20 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 28  t size = sizeof(
7790: 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f  struct sockaddr_
77a0: 69 6e 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 6e  in);.  char zLin
77b0: 65 5b 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a 20  e[2000];     /* 
77c0: 41 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66  A single line of
77d0: 20 69 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 66 75   input. */..  fu
77e0: 6c 6c 48 74 74 70 52 65 70 6c 79 20 3d 20 31 3b  llHttpReply = 1;
77f0: 0a 20 20 69 66 28 20 66 67 65 74 73 28 7a 4c 69  .  if( fgets(zLi
7800: 6e 65 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e 65  ne, sizeof(zLine
7810: 29 2c 20 73 74 64 69 6e 29 3d 3d 30 20 29 7b 0a  ), stdin)==0 ){.
7820: 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65      malformed_re
7830: 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 7a  quest();.  }.  z
7840: 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 5f  Token = extract_
7850: 74 6f 6b 65 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29  token(zLine, &z)
7860: 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d  ;.  if( zToken==
7870: 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d  0 ){.    malform
7880: 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20  ed_request();.  
7890: 7d 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a  }.  if( strcmp(z
78a0: 54 6f 6b 65 6e 2c 22 47 45 54 22 29 21 3d 30 20  Token,"GET")!=0 
78b0: 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e  && strcmp(zToken
78c0: 2c 22 50 4f 53 54 22 29 21 3d 30 0a 20 20 20 20  ,"POST")!=0.    
78d0: 20 20 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b    && strcmp(zTok
78e0: 65 6e 2c 22 48 45 41 44 22 29 21 3d 30 20 29 7b  en,"HEAD")!=0 ){
78f0: 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72  .    malformed_r
7900: 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20  equest();.  }.  
7910: 63 67 69 5f 73 65 74 65 6e 76 28 22 47 41 54 45  cgi_setenv("GATE
7920: 57 41 59 5f 49 4e 54 45 52 46 41 43 45 22 2c 22  WAY_INTERFACE","
7930: 43 47 49 2f 31 2e 30 22 29 3b 0a 20 20 63 67 69  CGI/1.0");.  cgi
7940: 5f 73 65 74 65 6e 76 28 22 52 45 51 55 45 53 54  _setenv("REQUEST
7950: 5f 4d 45 54 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29  _METHOD",zToken)
7960: 3b 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74  ;.  zToken = ext
7970: 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a  ract_token(z, &z
7980: 29 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d  );.  if( zToken=
7990: 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72  =0 ){.    malfor
79a0: 6d 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20  med_request();. 
79b0: 20 7d 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28   }.  cgi_setenv(
79c0: 22 52 45 51 55 45 53 54 5f 55 52 49 22 2c 20 7a  "REQUEST_URI", z
79d0: 54 6f 6b 65 6e 29 3b 0a 20 20 66 6f 72 28 69 3d  Token);.  for(i=
79e0: 30 3b 20 7a 54 6f 6b 65 6e 5b 69 5d 20 26 26 20  0; zToken[i] && 
79f0: 7a 54 6f 6b 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20  zToken[i]!='?'; 
7a00: 69 2b 2b 29 7b 7d 0a 20 20 69 66 28 20 7a 54 6f  i++){}.  if( zTo
7a10: 6b 65 6e 5b 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b  ken[i] ) zToken[
7a20: 69 2b 2b 5d 20 3d 20 30 3b 0a 20 20 63 67 69 5f  i++] = 0;.  cgi_
7a30: 73 65 74 65 6e 76 28 22 50 41 54 48 5f 49 4e 46  setenv("PATH_INF
7a40: 4f 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63  O", zToken);.  c
7a50: 67 69 5f 73 65 74 65 6e 76 28 22 51 55 45 52 59  gi_setenv("QUERY
7a60: 5f 53 54 52 49 4e 47 22 2c 20 26 7a 54 6f 6b 65  _STRING", &zToke
7a70: 6e 5b 69 5d 29 3b 0a 20 20 69 66 28 20 67 65 74  n[i]);.  if( get
7a80: 70 65 65 72 6e 61 6d 65 28 66 69 6c 65 6e 6f 28  peername(fileno(
7a90: 73 74 64 69 6e 29 2c 20 28 73 74 72 75 63 74 20  stdin), (struct 
7aa0: 73 6f 63 6b 61 64 64 72 2a 29 26 72 65 6d 6f 74  sockaddr*)&remot
7ab0: 65 4e 61 6d 65 2c 20 28 73 6f 63 6b 6c 65 6e 5f  eName, (socklen_
7ac0: 74 2a 29 26 73 69 7a 65 29 3e 3d 30 20 29 7b 0a  t*)&size)>=0 ){.
7ad0: 20 20 20 20 63 68 61 72 20 2a 7a 49 70 41 64 64      char *zIpAdd
7ae0: 72 20 3d 20 69 6e 65 74 5f 6e 74 6f 61 28 72 65  r = inet_ntoa(re
7af0: 6d 6f 74 65 4e 61 6d 65 2e 73 69 6e 5f 61 64 64  moteName.sin_add
7b00: 72 29 3b 0a 20 20 20 20 63 67 69 5f 73 65 74 65  r);.    cgi_sete
7b10: 6e 76 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 22  nv("REMOTE_ADDR"
7b20: 2c 20 7a 49 70 41 64 64 72 29 3b 0a 0a 20 20 20  , zIpAddr);..   
7b30: 20 2f 2a 20 53 65 74 20 74 68 65 20 47 6c 6f 62   /* Set the Glob
7b40: 61 6c 2e 7a 49 70 41 64 64 72 20 76 61 72 69 61  al.zIpAddr varia
7b50: 62 6c 65 20 74 6f 20 74 68 65 20 73 65 72 76 65  ble to the serve
7b60: 72 20 77 65 20 61 72 65 20 74 61 6c 6b 69 6e 67  r we are talking
7b70: 20 74 6f 2e 0a 20 20 20 20 2a 2a 20 54 68 69 73   to..    ** This
7b80: 20 69 73 20 75 73 65 64 20 74 6f 20 70 6f 70 75   is used to popu
7b90: 6c 61 74 65 20 74 68 65 20 69 70 61 64 64 72 20  late the ipaddr 
7ba0: 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 63  column of the rc
7bb0: 76 66 72 6f 6d 20 74 61 62 6c 65 2c 0a 20 20 20  vfrom table,.   
7bc0: 20 2a 2a 20 69 66 20 61 6e 79 20 66 69 6c 65 73   ** if any files
7bd0: 20 61 72 65 20 72 65 63 65 69 76 65 64 20 66 72   are received fr
7be0: 6f 6d 20 74 68 65 20 63 6f 6e 6e 65 63 74 65 64  om the connected
7bf0: 20 63 6c 69 65 6e 74 2e 0a 20 20 20 20 2a 2f 0a   client..    */.
7c00: 20 20 20 20 67 2e 7a 49 70 41 64 64 72 20 3d 20      g.zIpAddr = 
7c10: 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 49  mprintf("%s", zI
7c20: 70 41 64 64 72 29 3b 0a 20 20 7d 0a 20 0a 20 20  pAddr);.  }. .  
7c30: 2f 2a 20 47 65 74 20 61 6c 6c 20 74 68 65 20 6f  /* Get all the o
7c40: 70 74 69 6f 6e 61 6c 20 66 69 65 6c 64 73 20 74  ptional fields t
7c50: 68 61 74 20 66 6f 6c 6c 6f 77 20 74 68 65 20 66  hat follow the f
7c60: 69 72 73 74 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a  irst line..  */.
7c70: 20 20 77 68 69 6c 65 28 20 66 67 65 74 73 28 7a    while( fgets(z
7c80: 4c 69 6e 65 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e  Line,sizeof(zLin
7c90: 65 29 2c 73 74 64 69 6e 29 20 29 7b 0a 20 20 20  e),stdin) ){.   
7ca0: 20 63 68 61 72 20 2a 7a 46 69 65 6c 64 4e 61 6d   char *zFieldNam
7cb0: 65 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61  e;.    char *zVa
7cc0: 6c 3b 0a 0a 20 20 20 20 7a 46 69 65 6c 64 4e 61  l;..    zFieldNa
7cd0: 6d 65 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b  me = extract_tok
7ce0: 65 6e 28 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b  en(zLine,&zVal);
7cf0: 0a 20 20 20 20 69 66 28 20 7a 46 69 65 6c 64 4e  .    if( zFieldN
7d00: 61 6d 65 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c  ame==0 || *zFiel
7d10: 64 4e 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b  dName==0 ) break
7d20: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 73  ;.    while( iss
7d30: 70 61 63 65 28 2a 7a 56 61 6c 29 20 29 7b 20 7a  pace(*zVal) ){ z
7d40: 56 61 6c 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 3d  Val++; }.    i =
7d50: 20 73 74 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20   strlen(zVal);. 
7d60: 20 20 20 77 68 69 6c 65 28 20 69 3e 30 20 26 26     while( i>0 &&
7d70: 20 69 73 73 70 61 63 65 28 7a 56 61 6c 5b 69 2d   isspace(zVal[i-
7d80: 31 5d 29 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20  1]) ){ i--; }.  
7d90: 20 20 7a 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20    zVal[i] = 0;. 
7da0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 7a 46 69 65     for(i=0; zFie
7db0: 6c 64 4e 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b  ldName[i]; i++){
7dc0: 20 7a 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d   zFieldName[i] =
7dd0: 20 74 6f 6c 6f 77 65 72 28 7a 46 69 65 6c 64 4e   tolower(zFieldN
7de0: 61 6d 65 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 69  ame[i]); }.    i
7df0: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64  f( strcmp(zField
7e00: 4e 61 6d 65 2c 22 75 73 65 72 2d 61 67 65 6e 74  Name,"user-agent
7e10: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  :")==0 ){.      
7e20: 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50  cgi_setenv("HTTP
7e30: 5f 55 53 45 52 5f 41 47 45 4e 54 22 2c 20 7a 56  _USER_AGENT", zV
7e40: 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  al);.    }else i
7e50: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64  f( strcmp(zField
7e60: 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65  Name,"content-le
7e70: 6e 67 74 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20  ngth:")==0 ){.  
7e80: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22      cgi_setenv("
7e90: 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c  CONTENT_LENGTH",
7ea0: 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73   zVal);.    }els
7eb0: 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69  e if( strcmp(zFi
7ec0: 65 6c 64 4e 61 6d 65 2c 22 72 65 66 65 72 65 72  eldName,"referer
7ed0: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  :")==0 ){.      
7ee0: 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50  cgi_setenv("HTTP
7ef0: 5f 52 45 46 45 52 45 52 22 2c 20 7a 56 61 6c 29  _REFERER", zVal)
7f00: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
7f10: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d  strcmp(zFieldNam
7f20: 65 2c 22 68 6f 73 74 3a 22 29 3d 3d 30 20 29 7b  e,"host:")==0 ){
7f30: 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e  .      cgi_seten
7f40: 76 28 22 48 54 54 50 5f 48 4f 53 54 22 2c 20 7a  v("HTTP_HOST", z
7f50: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20  Val);.    }else 
7f60: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c  if( strcmp(zFiel
7f70: 64 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 74  dName,"content-t
7f80: 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20  ype:")==0 ){.   
7f90: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43     cgi_setenv("C
7fa0: 4f 4e 54 45 4e 54 5f 54 59 50 45 22 2c 20 7a 56  ONTENT_TYPE", zV
7fb0: 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  al);.    }else i
7fc0: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64  f( strcmp(zField
7fd0: 4e 61 6d 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d  Name,"cookie:")=
7fe0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  =0 ){.      cgi_
7ff0: 73 65 74 65 6e 76 28 22 48 54 54 50 5f 43 4f 4f  setenv("HTTP_COO
8000: 4b 49 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20  KIE", zVal);.   
8010: 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d   }else if( strcm
8020: 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66  p(zFieldName,"if
8030: 2d 6e 6f 6e 65 2d 6d 61 74 63 68 3a 22 29 3d 3d  -none-match:")==
8040: 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73  0 ){.      cgi_s
8050: 65 74 65 6e 76 28 22 48 54 54 50 5f 49 46 5f 4e  etenv("HTTP_IF_N
8060: 4f 4e 45 5f 4d 41 54 43 48 22 2c 20 7a 56 61 6c  ONE_MATCH", zVal
8070: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
8080: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61   strcmp(zFieldNa
8090: 6d 65 2c 22 69 66 2d 6d 6f 64 69 66 69 65 64 2d  me,"if-modified-
80a0: 73 69 6e 63 65 3a 22 29 3d 3d 30 20 29 7b 0a 20  since:")==0 ){. 
80b0: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28       cgi_setenv(
80c0: 22 48 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45  "HTTP_IF_MODIFIE
80d0: 44 5f 53 49 4e 43 45 22 2c 20 7a 56 61 6c 29 3b  D_SINCE", zVal);
80e0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 67  .    }.  }..  cg
80f0: 69 5f 69 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a  i_init();.}../*.
8100: 2a 2a 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65  ** Maximum numbe
8110: 72 20 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65  r of child proce
8120: 73 73 65 73 20 74 68 61 74 20 77 65 20 63 61 6e  sses that we can
8130: 20 68 61 76 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a   have running.**
8140: 20 61 74 20 6f 6e 65 20 74 69 6d 65 20 62 65 66   at one time bef
8150: 6f 72 65 20 77 65 20 73 74 61 72 74 20 73 6c 6f  ore we start slo
8160: 77 69 6e 67 20 74 68 69 6e 67 73 20 64 6f 77 6e  wing things down
8170: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 41 58  ..*/.#define MAX
8180: 5f 50 41 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a  _PARALLEL 2../*.
8190: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 61 6e 20  ** Implement an 
81a0: 48 54 54 50 20 73 65 72 76 65 72 20 64 61 65 6d  HTTP server daem
81b0: 6f 6e 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20  on listening on 
81c0: 70 6f 72 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a  port iPort..**.*
81d0: 2a 20 41 73 20 6e 65 77 20 63 6f 6e 6e 65 63 74  * As new connect
81e0: 69 6f 6e 73 20 61 72 72 69 76 65 2c 20 66 6f 72  ions arrive, for
81f0: 6b 20 61 20 63 68 69 6c 64 20 61 6e 64 20 6c 65  k a child and le
8200: 74 20 63 68 69 6c 64 20 72 65 74 75 72 6e 0a 2a  t child return.*
8210: 2a 20 6f 75 74 20 6f 66 20 74 68 69 73 20 70 72  * out of this pr
8220: 6f 63 65 64 75 72 65 20 63 61 6c 6c 2e 20 20 54  ocedure call.  T
8230: 68 65 20 63 68 69 6c 64 20 77 69 6c 6c 20 68 61  he child will ha
8240: 6e 64 6c 65 20 74 68 65 20 72 65 71 75 65 73 74  ndle the request
8250: 2e 0a 2a 2a 20 54 68 65 20 70 61 72 65 6e 74 20  ..** The parent 
8260: 6e 65 76 65 72 20 72 65 74 75 72 6e 73 20 66 72  never returns fr
8270: 6f 6d 20 74 68 69 73 20 70 72 6f 63 65 64 75 72  om this procedur
8280: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68  e..*/.void cgi_h
8290: 74 74 70 5f 73 65 72 76 65 72 28 69 6e 74 20 69  ttp_server(int i
82a0: 50 6f 72 74 29 7b 0a 23 69 66 64 65 66 20 5f 5f  Port){.#ifdef __
82b0: 4d 49 4e 47 57 33 32 5f 5f 0a 20 20 66 70 72 69  MINGW32__.  fpri
82c0: 6e 74 66 28 73 74 64 65 72 72 2c 22 73 65 72 76  ntf(stderr,"serv
82d0: 65 72 20 6e 6f 74 20 79 65 74 20 61 76 61 69 6c  er not yet avail
82e0: 61 62 6c 65 20 69 6e 20 77 69 6e 64 6f 77 73 20  able in windows 
82f0: 76 65 72 73 69 6f 6e 20 6f 66 20 66 6f 73 73 69  version of fossi
8300: 6c 5c 6e 22 29 3b 0a 20 20 65 78 69 74 28 31 29  l\n");.  exit(1)
8310: 3b 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 6c 69  ;.#else.  int li
8320: 73 74 65 6e 65 72 3b 20 20 20 20 20 20 20 20 20  stener;         
8330: 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 73 65         /* The se
8340: 72 76 65 72 20 73 6f 63 6b 65 74 20 2a 2f 0a 20  rver socket */. 
8350: 20 69 6e 74 20 63 6f 6e 6e 65 63 74 69 6f 6e 3b   int connection;
8360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8370: 20 41 20 73 6f 63 6b 65 74 20 66 6f 72 20 65 61   A socket for ea
8380: 63 68 20 69 6e 64 69 76 69 64 75 61 6c 20 63 6f  ch individual co
8390: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 64  nnection */.  fd
83a0: 5f 73 65 74 20 72 65 61 64 66 64 73 3b 20 20 20  _set readfds;   
83b0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65             /* Se
83c0: 74 20 6f 66 20 66 69 6c 65 20 64 65 73 63 72 69  t of file descri
83d0: 70 74 6f 72 73 20 66 6f 72 20 73 65 6c 65 63 74  ptors for select
83e0: 28 29 20 2a 2f 0a 20 20 73 69 7a 65 5f 74 20 6c  () */.  size_t l
83f0: 65 6e 61 64 64 72 3b 20 20 20 20 20 20 20 20 20  enaddr;         
8400: 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f       /* Length o
8410: 66 20 74 68 65 20 69 6e 61 64 64 72 20 73 74 72  f the inaddr str
8420: 75 63 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20  ucture */.  int 
8430: 63 68 69 6c 64 3b 20 20 20 20 20 20 20 20 20 20  child;          
8440: 20 20 20 20 20 20 20 20 20 2f 2a 20 50 49 44 20           /* PID 
8450: 6f 66 20 74 68 65 20 63 68 69 6c 64 20 70 72 6f  of the child pro
8460: 63 65 73 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 63  cess */.  int nc
8470: 68 69 6c 64 72 65 6e 20 3d 20 30 3b 20 20 20 20  hildren = 0;    
8480: 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72         /* Number
8490: 20 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73   of child proces
84a0: 73 65 73 20 2a 2f 0a 20 20 73 74 72 75 63 74 20  ses */.  struct 
84b0: 74 69 6d 65 76 61 6c 20 64 65 6c 61 79 3b 20 20  timeval delay;  
84c0: 20 20 20 20 20 20 2f 2a 20 48 6f 77 20 6c 6f 6e        /* How lon
84d0: 67 20 74 6f 20 77 61 69 74 20 69 6e 73 69 64 65  g to wait inside
84e0: 20 73 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 73   select() */.  s
84f0: 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69  truct sockaddr_i
8500: 6e 20 69 6e 61 64 64 72 3b 20 20 20 2f 2a 20 54  n inaddr;   /* T
8510: 68 65 20 73 6f 63 6b 65 74 20 61 64 64 72 65 73  he socket addres
8520: 73 20 2a 2f 0a 20 20 69 6e 74 20 6f 70 74 20 3d  s */.  int opt =
8530: 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 20   1;             
8540: 20 20 20 20 2f 2a 20 73 65 74 73 6f 63 6b 6f 70      /* setsockop
8550: 74 20 66 6c 61 67 20 2a 2f 0a 0a 20 20 6d 65 6d  t flag */..  mem
8560: 73 65 74 28 26 69 6e 61 64 64 72 2c 20 30 2c 20  set(&inaddr, 0, 
8570: 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 29 3b  sizeof(inaddr));
8580: 0a 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f 66 61  .  inaddr.sin_fa
8590: 6d 69 6c 79 20 3d 20 41 46 5f 49 4e 45 54 3b 0a  mily = AF_INET;.
85a0: 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f 61 64 64    inaddr.sin_add
85b0: 72 2e 73 5f 61 64 64 72 20 3d 20 49 4e 41 44 44  r.s_addr = INADD
85c0: 52 5f 41 4e 59 3b 0a 20 20 69 6e 61 64 64 72 2e  R_ANY;.  inaddr.
85d0: 73 69 6e 5f 70 6f 72 74 20 3d 20 68 74 6f 6e 73  sin_port = htons
85e0: 28 69 50 6f 72 74 29 3b 0a 20 20 6c 69 73 74 65  (iPort);.  liste
85f0: 6e 65 72 20 3d 20 73 6f 63 6b 65 74 28 41 46 5f  ner = socket(AF_
8600: 49 4e 45 54 2c 20 53 4f 43 4b 5f 53 54 52 45 41  INET, SOCK_STREA
8610: 4d 2c 20 30 29 3b 0a 20 20 69 66 28 20 6c 69 73  M, 0);.  if( lis
8620: 74 65 6e 65 72 3c 30 20 29 7b 0a 20 20 20 20 66  tener<0 ){.    f
8630: 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 22 43  printf(stderr,"C
8640: 61 6e 27 74 20 63 72 65 61 74 65 20 61 20 73 6f  an't create a so
8650: 63 6b 65 74 5c 6e 22 29 3b 0a 20 20 20 20 65 78  cket\n");.    ex
8660: 69 74 28 31 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a  it(1);.  }..  /*
8670: 20 69 66 20 77 65 20 63 61 6e 27 74 20 74 65 72   if we can't ter
8680: 6d 69 6e 61 74 65 20 6e 69 63 65 6c 79 2c 20 61  minate nicely, a
8690: 74 20 6c 65 61 73 74 20 61 6c 6c 6f 77 20 74 68  t least allow th
86a0: 65 20 73 6f 63 6b 65 74 20 74 6f 20 62 65 20 72  e socket to be r
86b0: 65 75 73 65 64 20 2a 2f 0a 20 20 73 65 74 73 6f  eused */.  setso
86c0: 63 6b 6f 70 74 28 6c 69 73 74 65 6e 65 72 2c 53  ckopt(listener,S
86d0: 4f 4c 5f 53 4f 43 4b 45 54 2c 53 4f 5f 52 45 55  OL_SOCKET,SO_REU
86e0: 53 45 41 44 44 52 2c 26 6f 70 74 2c 73 69 7a 65  SEADDR,&opt,size
86f0: 6f 66 28 6f 70 74 29 29 3b 0a 0a 20 20 69 66 28  of(opt));..  if(
8700: 20 62 69 6e 64 28 6c 69 73 74 65 6e 65 72 2c 20   bind(listener, 
8710: 28 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72  (struct sockaddr
8720: 2a 29 26 69 6e 61 64 64 72 2c 20 73 69 7a 65 6f  *)&inaddr, sizeo
8730: 66 28 69 6e 61 64 64 72 29 29 3c 30 20 29 7b 0a  f(inaddr))<0 ){.
8740: 20 20 20 20 66 70 72 69 6e 74 66 28 73 74 64 65      fprintf(stde
8750: 72 72 2c 22 43 61 6e 27 74 20 62 69 6e 64 20 74  rr,"Can't bind t
8760: 6f 20 70 6f 72 74 20 25 64 5c 6e 22 2c 20 69 50  o port %d\n", iP
8770: 6f 72 74 29 3b 0a 20 20 20 20 65 78 69 74 28 31  ort);.    exit(1
8780: 29 3b 0a 20 20 7d 0a 20 20 6c 69 73 74 65 6e 28  );.  }.  listen(
8790: 6c 69 73 74 65 6e 65 72 2c 31 30 29 3b 0a 20 20  listener,10);.  
87a0: 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20  while( 1 ){.    
87b0: 69 66 28 20 6e 63 68 69 6c 64 72 65 6e 3e 4d 41  if( nchildren>MA
87c0: 58 5f 50 41 52 41 4c 4c 45 4c 20 29 7b 0a 20 20  X_PARALLEL ){.  
87d0: 20 20 20 20 2f 2a 20 53 6c 6f 77 20 64 6f 77 6e      /* Slow down
87e0: 20 69 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20   if connections 
87f0: 61 72 65 20 61 72 72 69 76 69 6e 67 20 74 6f 6f  are arriving too
8800: 20 66 61 73 74 20 2a 2f 0a 20 20 20 20 20 20 73   fast */.      s
8810: 6c 65 65 70 28 20 6e 63 68 69 6c 64 72 65 6e 2d  leep( nchildren-
8820: 4d 41 58 5f 50 41 52 41 4c 4c 45 4c 20 29 3b 0a  MAX_PARALLEL );.
8830: 20 20 20 20 7d 0a 20 20 20 20 64 65 6c 61 79 2e      }.    delay.
8840: 74 76 5f 73 65 63 20 3d 20 36 30 3b 0a 20 20 20  tv_sec = 60;.   
8850: 20 64 65 6c 61 79 2e 74 76 5f 75 73 65 63 20 3d   delay.tv_usec =
8860: 20 30 3b 0a 20 20 20 20 46 44 5f 5a 45 52 4f 28   0;.    FD_ZERO(
8870: 26 72 65 61 64 66 64 73 29 3b 0a 20 20 20 20 46  &readfds);.    F
8880: 44 5f 53 45 54 28 20 6c 69 73 74 65 6e 65 72 2c  D_SET( listener,
8890: 20 26 72 65 61 64 66 64 73 29 3b 0a 20 20 20 20   &readfds);.    
88a0: 69 66 28 20 73 65 6c 65 63 74 28 20 6c 69 73 74  if( select( list
88b0: 65 6e 65 72 2b 31 2c 20 26 72 65 61 64 66 64 73  ener+1, &readfds
88c0: 2c 20 30 2c 20 30 2c 20 26 64 65 6c 61 79 29 20  , 0, 0, &delay) 
88d0: 29 7b 0a 20 20 20 20 20 20 6c 65 6e 61 64 64 72  ){.      lenaddr
88e0: 20 3d 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72   = sizeof(inaddr
88f0: 29 3b 0a 20 20 20 20 20 20 63 6f 6e 6e 65 63 74  );.      connect
8900: 69 6f 6e 20 3d 20 61 63 63 65 70 74 28 6c 69 73  ion = accept(lis
8910: 74 65 6e 65 72 2c 20 28 73 74 72 75 63 74 20 73  tener, (struct s
8920: 6f 63 6b 61 64 64 72 2a 29 26 69 6e 61 64 64 72  ockaddr*)&inaddr
8930: 2c 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 20 26  , (socklen_t*) &
8940: 6c 65 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20  lenaddr);.      
8950: 69 66 28 20 63 6f 6e 6e 65 63 74 69 6f 6e 3e 3d  if( connection>=
8960: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63 68 69  0 ){.        chi
8970: 6c 64 20 3d 20 66 6f 72 6b 28 29 3b 0a 20 20 20  ld = fork();.   
8980: 20 20 20 20 20 69 66 28 20 63 68 69 6c 64 21 3d       if( child!=
8990: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  0 ){.          i
89a0: 66 28 20 63 68 69 6c 64 3e 30 20 29 20 6e 63 68  f( child>0 ) nch
89b0: 69 6c 64 72 65 6e 2b 2b 3b 0a 20 20 20 20 20 20  ildren++;.      
89c0: 20 20 20 20 63 6c 6f 73 65 28 63 6f 6e 6e 65 63      close(connec
89d0: 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 7d  tion);.        }
89e0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20  else{.          
89f0: 63 6c 6f 73 65 28 30 29 3b 0a 20 20 20 20 20 20  close(0);.      
8a00: 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69      dup(connecti
8a10: 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 63  on);.          c
8a20: 6c 6f 73 65 28 31 29 3b 0a 20 20 20 20 20 20 20  lose(1);.       
8a30: 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f     dup(connectio
8a40: 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66  n);.          if
8a50: 28 20 21 67 2e 66 48 74 74 70 54 72 61 63 65 20  ( !g.fHttpTrace 
8a60: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 63  ){.            c
8a70: 6c 6f 73 65 28 32 29 3b 0a 20 20 20 20 20 20 20  lose(2);.       
8a80: 20 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74       dup(connect
8a90: 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20  ion);.          
8aa0: 7d 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73  }.          clos
8ab0: 65 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20  e(connection);. 
8ac0: 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b           return;
8ad0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
8ae0: 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20   }.    }.    /* 
8af0: 42 75 72 79 20 64 65 61 64 20 63 68 69 6c 64 72  Bury dead childr
8b00: 65 6e 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28  en */.    while(
8b10: 20 77 61 69 74 70 69 64 28 30 2c 20 30 2c 20 57   waitpid(0, 0, W
8b20: 4e 4f 48 41 4e 47 29 3e 30 20 29 7b 0a 20 20 20  NOHANG)>0 ){.   
8b30: 20 20 20 6e 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a     nchildren--;.
8b40: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e      }.  }.  /* N
8b50: 4f 54 20 52 45 41 43 48 45 44 20 2a 2f 20 20 0a  OT REACHED */  .
8b60: 20 20 65 78 69 74 28 31 29 3b 0a 23 65 6e 64 69    exit(1);.#endi
8b70: 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20  f.}../*.** Name 
8b80: 6f 66 20 64 61 79 73 20 61 6e 64 20 6d 6f 6e 74  of days and mont
8b90: 68 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f  hs..*/.static co
8ba0: 6e 73 74 20 63 68 61 72 20 2a 61 7a 44 61 79 73  nst char *azDays
8bb0: 5b 5d 20 3d 0a 20 20 20 20 7b 22 53 75 6e 22 2c  [] =.    {"Sun",
8bc0: 20 22 4d 6f 6e 22 2c 20 22 54 75 65 22 2c 20 22   "Mon", "Tue", "
8bd0: 57 65 64 22 2c 20 22 54 68 75 22 2c 20 22 46 72  Wed", "Thu", "Fr
8be0: 69 22 2c 20 22 53 61 74 22 2c 20 30 7d 3b 0a 73  i", "Sat", 0};.s
8bf0: 74 61 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72  tatic const char
8c00: 20 2a 61 7a 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20   *azMonths[] =. 
8c10: 20 20 20 7b 22 4a 61 6e 22 2c 20 22 46 65 62 22     {"Jan", "Feb"
8c20: 2c 20 22 4d 61 72 22 2c 20 22 41 70 72 22 2c 20  , "Mar", "Apr", 
8c30: 22 4d 61 79 22 2c 20 22 4a 75 6e 22 2c 0a 20 20  "May", "Jun",.  
8c40: 20 20 20 22 4a 75 6c 22 2c 20 22 41 75 67 22 2c     "Jul", "Aug",
8c50: 20 22 53 65 70 22 2c 20 22 4f 63 74 22 2c 20 22   "Sep", "Oct", "
8c60: 4e 6f 76 22 2c 20 22 44 65 63 22 2c 20 30 7d 3b  Nov", "Dec", 0};
8c70: 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 73  .../*.** Returns
8c80: 20 61 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d 61   an RFC822-forma
8c90: 74 74 65 64 20 74 69 6d 65 20 73 74 72 69 6e 67  tted time string
8ca0: 20 73 75 69 74 61 62 6c 65 20 66 6f 72 20 48 54   suitable for HT
8cb0: 54 50 20 68 65 61 64 65 72 73 2c 20 61 6d 6f 6e  TP headers, amon
8cc0: 67 0a 2a 2a 20 6f 74 68 65 72 20 74 68 69 6e 67  g.** other thing
8cd0: 73 2e 0a 2a 2a 20 52 65 74 75 72 6e 65 64 20 74  s..** Returned t
8ce0: 69 6d 65 7a 6f 6e 65 20 69 73 20 61 6c 77 61 79  imezone is alway
8cf0: 73 20 47 4d 54 20 61 73 20 72 65 71 75 69 72 65  s GMT as require
8d00: 64 20 62 79 20 48 54 54 50 2f 31 2e 31 20 73 70  d by HTTP/1.1 sp
8d10: 65 63 69 66 69 63 61 74 69 6f 6e 2e 0a 2a 2a 0a  ecification..**.
8d20: 2a 2a 20 53 65 65 20 68 74 74 70 3a 2f 2f 77 77  ** See http://ww
8d30: 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66 63 73 2f  w.faqs.org/rfcs/
8d40: 72 66 63 38 32 32 2e 68 74 6d 6c 2c 20 73 65 63  rfc822.html, sec
8d50: 74 69 6f 6e 20 35 0a 2a 2a 20 61 6e 64 20 68 74  tion 5.** and ht
8d60: 74 70 3a 2f 2f 77 77 77 2e 66 61 71 73 2e 6f 72  tp://www.faqs.or
8d70: 67 2f 72 66 63 73 2f 72 66 63 32 36 31 36 2e 68  g/rfcs/rfc2616.h
8d80: 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 20 33 2e 33  tml, section 3.3
8d90: 2e 0a 2a 2f 0a 63 68 61 72 20 2a 63 67 69 5f 72  ..*/.char *cgi_r
8da0: 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28  fc822_datestamp(
8db0: 74 69 6d 65 5f 74 20 6e 6f 77 29 7b 0a 20 20 73  time_t now){.  s
8dc0: 74 72 75 63 74 20 74 6d 20 2a 70 54 6d 3b 0a 20  truct tm *pTm;. 
8dd0: 20 70 54 6d 20 3d 20 67 6d 74 69 6d 65 28 26 6e   pTm = gmtime(&n
8de0: 6f 77 29 3b 0a 20 20 69 66 28 20 70 54 6d 3d 3d  ow);.  if( pTm==
8df0: 30 20 29 20 72 65 74 75 72 6e 20 22 22 3b 0a 20  0 ) return "";. 
8e00: 20 72 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 28   return mprintf(
8e10: 22 25 73 2c 20 25 64 20 25 73 20 25 30 32 64 20  "%s, %d %s %02d 
8e20: 25 30 32 64 3a 25 30 32 64 3a 25 30 32 64 20 47  %02d:%02d:%02d G
8e30: 4d 54 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  MT",.           
8e40: 20 20 20 20 20 20 61 7a 44 61 79 73 5b 70 54 6d        azDays[pTm
8e50: 2d 3e 74 6d 5f 77 64 61 79 5d 2c 20 70 54 6d 2d  ->tm_wday], pTm-
8e60: 3e 74 6d 5f 6d 64 61 79 2c 20 61 7a 4d 6f 6e 74  >tm_mday, azMont
8e70: 68 73 5b 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d 2c  hs[pTm->tm_mon],
8e80: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
8e90: 20 20 70 54 6d 2d 3e 74 6d 5f 79 65 61 72 2b 31    pTm->tm_year+1
8ea0: 39 30 30 2c 20 70 54 6d 2d 3e 74 6d 5f 68 6f 75  900, pTm->tm_hou
8eb0: 72 2c 20 70 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c 20  r, pTm->tm_min, 
8ec0: 70 54 6d 2d 3e 74 6d 5f 73 65 63 29 3b 0a 7d 0a  pTm->tm_sec);.}.
8ed0: 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65 20 61 6e 20  ./*.** Parse an 
8ee0: 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 64  RFC822-formatted
8ef0: 20 74 69 6d 65 73 74 61 6d 70 20 61 73 20 77 65   timestamp as we
8f00: 27 64 20 65 78 70 65 63 74 20 66 72 6f 6d 20 48  'd expect from H
8f10: 54 54 50 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a  TTP and return.*
8f20: 2a 20 61 20 55 6e 69 78 20 65 70 6f 63 68 20 74  * a Unix epoch t
8f30: 69 6d 65 2e 20 3c 3d 20 7a 65 72 6f 20 69 73 20  ime. <= zero is 
8f40: 72 65 74 75 72 6e 65 64 20 6f 6e 20 66 61 69 6c  returned on fail
8f50: 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20  ure..**.** Note 
8f60: 74 68 61 74 20 74 68 69 73 20 77 6f 6e 27 74 20  that this won't 
8f70: 68 61 6e 64 6c 65 20 61 6c 6c 20 74 68 65 20 5f  handle all the _
8f80: 61 6c 6c 6f 77 65 64 5f 20 48 54 54 50 20 66 6f  allowed_ HTTP fo
8f90: 72 6d 61 74 73 2c 20 6a 75 73 74 20 74 68 65 0a  rmats, just the.
8fa0: 2a 2a 20 6d 6f 73 74 20 70 6f 70 75 6c 61 72 20  ** most popular 
8fb0: 6f 6e 65 20 28 74 68 65 20 6f 6e 65 20 67 65 6e  one (the one gen
8fc0: 65 72 61 74 65 64 20 62 79 20 63 67 69 5f 72 66  erated by cgi_rf
8fd0: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 29  c822_datestamp()
8fe0: 2c 20 61 63 74 75 61 6c 6c 79 29 2e 0a 2a 2f 0a  , actually)..*/.
8ff0: 74 69 6d 65 5f 74 20 63 67 69 5f 72 66 63 38 32  time_t cgi_rfc82
9000: 32 5f 70 61 72 73 65 64 61 74 65 28 63 6f 6e 73  2_parsedate(cons
9010: 74 20 63 68 61 72 20 2a 7a 44 61 74 65 29 7b 0a  t char *zDate){.
9020: 20 20 73 74 72 75 63 74 20 74 6d 20 74 3b 0a 20    struct tm t;. 
9030: 20 63 68 61 72 20 7a 49 67 6e 6f 72 65 5b 31 36   char zIgnore[16
9040: 5d 3b 0a 20 20 63 68 61 72 20 7a 4d 6f 6e 74 68  ];.  char zMonth
9050: 5b 31 36 5d 3b 0a 0a 20 20 6d 65 6d 73 65 74 28  [16];..  memset(
9060: 26 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 74 29  &t, 0, sizeof(t)
9070: 29 3b 0a 20 20 69 66 28 20 37 3d 3d 73 73 63 61  );.  if( 7==ssca
9080: 6e 66 28 7a 44 61 74 65 2c 20 22 25 31 32 5b 41  nf(zDate, "%12[A
9090: 2d 5a 61 2d 7a 2c 5d 20 25 64 20 25 31 32 5b 41  -Za-z,] %d %12[A
90a0: 2d 5a 61 2d 7a 5d 20 25 64 20 25 64 3a 25 64 3a  -Za-z] %d %d:%d:
90b0: 25 64 22 2c 20 7a 49 67 6e 6f 72 65 2c 0a 20 20  %d", zIgnore,.  
90c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
90d0: 20 20 20 20 20 26 74 2e 74 6d 5f 6d 64 61 79 2c       &t.tm_mday,
90e0: 20 7a 4d 6f 6e 74 68 2c 20 26 74 2e 74 6d 5f 79   zMonth, &t.tm_y
90f0: 65 61 72 2c 20 26 74 2e 74 6d 5f 68 6f 75 72 2c  ear, &t.tm_hour,
9100: 20 26 74 2e 74 6d 5f 6d 69 6e 2c 0a 20 20 20 20   &t.tm_min,.    
9110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9120: 20 20 20 26 74 2e 74 6d 5f 73 65 63 29 29 7b 0a     &t.tm_sec)){.
9130: 0a 20 20 20 20 69 66 28 20 74 2e 74 6d 5f 79 65  .    if( t.tm_ye
9140: 61 72 20 3e 20 31 39 30 30 20 29 20 74 2e 74 6d  ar > 1900 ) t.tm
9150: 5f 79 65 61 72 20 2d 3d 20 31 39 30 30 3b 0a 20  _year -= 1900;. 
9160: 20 20 20 66 6f 72 28 74 2e 74 6d 5f 6d 6f 6e 3d     for(t.tm_mon=
9170: 30 3b 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d  0; azMonths[t.tm
9180: 5f 6d 6f 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e 2b  _mon]; t.tm_mon+
9190: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 21 73  +){.      if( !s
91a0: 74 72 6e 63 61 73 65 63 6d 70 28 20 61 7a 4d 6f  trncasecmp( azMo
91b0: 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c 20  nths[t.tm_mon], 
91c0: 7a 4d 6f 6e 74 68 2c 20 33 20 29 29 7b 0a 20 20  zMonth, 3 )){.  
91d0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 6d 6b 67        return mkg
91e0: 6d 74 69 6d 65 28 26 74 29 3b 0a 20 20 20 20 20  mtime(&t);.     
91f0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
9200: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a  return 0;.}../*.
9210: 2a 2a 20 43 6f 6e 76 65 72 74 20 61 20 73 74 72  ** Convert a str
9220: 75 63 74 20 74 6d 2a 20 74 68 61 74 20 72 65 70  uct tm* that rep
9230: 72 65 73 65 6e 74 73 20 61 20 6d 6f 6d 65 6e 74  resents a moment
9240: 20 69 6e 20 55 54 43 20 69 6e 74 6f 20 74 68 65   in UTC into the
9250: 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 73 65   number.** of se
9260: 63 6f 6e 64 73 20 69 6e 20 31 39 37 30 2c 20 55  conds in 1970, U
9270: 54 43 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 6d 6b  TC..*/.time_t mk
9280: 67 6d 74 69 6d 65 28 73 74 72 75 63 74 20 74 6d  gmtime(struct tm
9290: 20 2a 70 29 7b 0a 20 20 74 69 6d 65 5f 74 20 74   *p){.  time_t t
92a0: 3b 0a 20 20 69 6e 74 20 6e 44 61 79 3b 0a 20 20  ;.  int nDay;.  
92b0: 69 6e 74 20 69 73 4c 65 61 70 59 72 3b 0a 20 20  int isLeapYr;.  
92c0: 2f 2a 20 44 61 79 73 20 69 6e 20 65 61 63 68 20  /* Days in each 
92d0: 6d 6f 6e 74 68 3a 20 20 20 20 20 20 20 33 31 2c  month:       31,
92e0: 20 32 38 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c   28, 31, 30, 31,
92f0: 20 33 30 2c 20 33 31 2c 20 33 31 2c 20 33 30 2c   30, 31, 31, 30,
9300: 20 33 31 2c 20 33 30 2c 20 33 31 20 2a 2f 0a 20   31, 30, 31 */. 
9310: 20 73 74 61 74 69 63 20 69 6e 74 20 70 72 69 6f   static int prio
9320: 72 44 61 79 73 5b 5d 20 20 20 3d 20 7b 20 20 30  rDays[]   = {  0
9330: 2c 20 33 31 2c 20 35 39 2c 20 39 30 2c 31 32 30  , 31, 59, 90,120
9340: 2c 31 35 31 2c 31 38 31 2c 32 31 32 2c 32 34 33  ,151,181,212,243
9350: 2c 32 37 33 2c 33 30 34 2c 33 33 34 20 7d 3b 0a  ,273,304,334 };.
9360: 20 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3c    if( p->tm_mon<
9370: 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 59 65  0 ){.    int nYe
9380: 61 72 20 3d 20 28 31 31 20 2d 20 70 2d 3e 74 6d  ar = (11 - p->tm
9390: 5f 6d 6f 6e 29 2f 31 32 3b 0a 20 20 20 20 70 2d  _mon)/12;.    p-
93a0: 3e 74 6d 5f 79 65 61 72 20 2d 3d 20 6e 59 65 61  >tm_year -= nYea
93b0: 72 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e  r;.    p->tm_mon
93c0: 20 2b 3d 20 6e 59 65 61 72 2a 31 32 3b 0a 20 20   += nYear*12;.  
93d0: 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 74 6d 5f  }else if( p->tm_
93e0: 6d 6f 6e 3e 31 31 20 29 7b 0a 20 20 20 20 70 2d  mon>11 ){.    p-
93f0: 3e 74 6d 5f 79 65 61 72 20 2b 3d 20 70 2d 3e 74  >tm_year += p->t
9400: 6d 5f 6d 6f 6e 2f 31 32 3b 0a 20 20 20 20 70 2d  m_mon/12;.    p-
9410: 3e 74 6d 5f 6d 6f 6e 20 25 3d 20 31 32 3b 0a 20  >tm_mon %= 12;. 
9420: 20 7d 0a 20 20 69 73 4c 65 61 70 59 72 20 3d 20   }.  isLeapYr = 
9430: 70 2d 3e 74 6d 5f 79 65 61 72 25 34 3d 3d 30 20  p->tm_year%4==0 
9440: 26 26 20 28 70 2d 3e 74 6d 5f 79 65 61 72 25 31  && (p->tm_year%1
9450: 30 30 21 3d 30 20 7c 7c 20 28 70 2d 3e 74 6d 5f  00!=0 || (p->tm_
9460: 79 65 61 72 2b 33 30 30 29 25 34 30 30 3d 3d 30  year+300)%400==0
9470: 29 3b 0a 20 20 70 2d 3e 74 6d 5f 79 64 61 79 20  );.  p->tm_yday 
9480: 3d 20 70 72 69 6f 72 44 61 79 73 5b 70 2d 3e 74  = priorDays[p->t
9490: 6d 5f 6d 6f 6e 5d 20 2b 20 70 2d 3e 74 6d 5f 6d  m_mon] + p->tm_m
94a0: 64 61 79 20 2d 20 31 3b 0a 20 20 69 66 28 20 69  day - 1;.  if( i
94b0: 73 4c 65 61 70 59 72 20 26 26 20 70 2d 3e 74 6d  sLeapYr && p->tm
94c0: 5f 6d 6f 6e 3e 31 20 29 20 70 2d 3e 74 6d 5f 79  _mon>1 ) p->tm_y
94d0: 64 61 79 2b 2b 3b 0a 20 20 6e 44 61 79 20 3d 20  day++;.  nDay = 
94e0: 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 37 30 29 2a  (p->tm_year-70)*
94f0: 33 36 35 20 2b 20 28 70 2d 3e 74 6d 5f 79 65 61  365 + (p->tm_yea
9500: 72 2d 36 39 29 2f 34 20 2d 70 2d 3e 74 6d 5f 79  r-69)/4 -p->tm_y
9510: 65 61 72 2f 31 30 30 20 2b 20 0a 20 20 20 20 20  ear/100 + .     
9520: 20 20 20 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2b      (p->tm_year+
9530: 33 30 30 29 2f 34 30 30 20 2b 20 70 2d 3e 74 6d  300)/400 + p->tm
9540: 5f 79 64 61 79 3b 0a 20 20 74 20 3d 20 28 28 6e  _yday;.  t = ((n
9550: 44 61 79 2a 32 34 20 2b 20 70 2d 3e 74 6d 5f 68  Day*24 + p->tm_h
9560: 6f 75 72 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f  our)*60 + p->tm_
9570: 6d 69 6e 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f  min)*60 + p->tm_
9580: 73 65 63 3b 0a 20 20 72 65 74 75 72 6e 20 74 3b  sec;.  return t;
9590: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20  .}../*.** Check 
95a0: 74 68 65 20 6f 62 6a 65 63 74 54 69 6d 65 20 61  the objectTime a
95b0: 67 61 69 6e 73 74 20 74 68 65 20 49 66 2d 4d 6f  gainst the If-Mo
95c0: 64 69 66 69 65 64 2d 53 69 6e 63 65 20 72 65 71  dified-Since req
95d0: 75 65 73 74 20 68 65 61 64 65 72 2e 20 49 66 20  uest header. If 
95e0: 74 68 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 74 69  the.** object ti
95f0: 6d 65 20 69 73 6e 27 74 20 61 6e 79 20 6e 65 77  me isn't any new
9600: 65 72 20 74 68 61 6e 20 74 68 65 20 68 65 61 64  er than the head
9610: 65 72 2c 20 77 65 20 69 6d 6d 65 64 69 61 74 65  er, we immediate
9620: 6c 79 20 73 65 6e 64 20 62 61 63 6b 0a 2a 2a 20  ly send back.** 
9630: 61 20 33 30 34 20 72 65 70 6c 79 20 61 6e 64 20  a 304 reply and 
9640: 65 78 69 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  exit..*/.void cg
9650: 69 5f 6d 6f 64 69 66 69 65 64 5f 73 69 6e 63 65  i_modified_since
9660: 28 74 69 6d 65 5f 74 20 6f 62 6a 65 63 74 54 69  (time_t objectTi
9670: 6d 65 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  me){.  const cha
9680: 72 20 2a 7a 49 66 20 3d 20 50 28 22 48 54 54 50  r *zIf = P("HTTP
9690: 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 4e  _IF_MODIFIED_SIN
96a0: 43 45 22 29 3b 0a 20 20 69 66 28 20 7a 49 66 3d  CE");.  if( zIf=
96b0: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69  =0 ) return;.  i
96c0: 66 28 20 6f 62 6a 65 63 74 54 69 6d 65 20 3e 20  f( objectTime > 
96d0: 63 67 69 5f 72 66 63 38 32 32 5f 70 61 72 73 65  cgi_rfc822_parse
96e0: 64 61 74 65 28 7a 49 66 29 20 29 20 72 65 74 75  date(zIf) ) retu
96f0: 72 6e 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74  rn;.  cgi_set_st
9700: 61 74 75 73 28 33 30 34 2c 22 4e 6f 74 20 4d 6f  atus(304,"Not Mo
9710: 64 69 66 69 65 64 22 29 3b 0a 20 20 63 67 69 5f  dified");.  cgi_
9720: 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b  reset_content();
9730: 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a  .  cgi_reply();.
9740: 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a             exit(0);.}.