Hex Artifact Content
Not logged in

Artifact 57f4d7daa35b4be43195e297695fe9e430e34521:

File src/cgi.c part of check-in [8372cc0b81] - Socket operations now functional in Win32 port. Added quotes around the filename portion of the command to edit thus working of windows in paths where the temp directory contains spaces. Added -all flag to clean command. If not specified each file is prompted for before removing. by jnc on 2007-09-22 18:34:49. Also file src/cgi.c part of check-in [3c5482959c] - Merge in the w32 changes. by drh on 2007-09-22 19:43:55.

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: 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64 65 20  else.#  include 
05a0: 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e 0a 23  <sys/socket.h>.#
05b0: 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74 69 6e    include <netin
05c0: 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e 63 6c  et/in.h>.#  incl
05d0: 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74 2e 68  ude <arpa/inet.h
05e0: 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 73 79  >.#  include <sy
05f0: 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20 69 6e  s/times.h>.#  in
0600: 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d 65 2e  clude <sys/time.
0610: 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 73  h>.#  include <s
0620: 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20 69 6e  ys/wait.h>.#  in
0630: 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c 65 63  clude <sys/selec
0640: 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69 6e 63  t.h>.#endif.#inc
0650: 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a 23 69  lude <time.h>.#i
0660: 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e  nclude <stdio.h>
0670: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69  .#include <stdli
0680: 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75  b.h>.#include <u
0690: 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64  nistd.h>.#includ
06a0: 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66 20 49  e "cgi.h"..#if I
06b0: 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a 20 53  NTERFACE./*.** S
06c0: 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63 67 69  hortcuts for cgi
06d0: 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50 28 22  _parameter.  P("
06e0: 78 22 29 20 72 65 74 75 72 6e 73 20 74 68 65 20  x") returns the 
06f0: 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79 20 70  value of query p
0700: 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72 20 63  arameter.** or c
0710: 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20 4e 55  ookie "x", or NU
0720: 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 6e  LL if there is n
0730: 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74 65 72  o such parameter
0740: 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50 44 28   or cookie.  PD(
0750: 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f 65 73  "x","y").** does
0760: 20 74 68 65 20 73 61 6d 65 20 65 78 63 65 70 74   the same except
0770: 20 22 79 22 20 69 73 20 72 65 74 75 72 6e 65 64   "y" is returned
0780: 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e 55 4c   in place of NUL
0790: 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 6e 6f  L if there is no
07a0: 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64 65 66  t match..*/.#def
07b0: 69 6e 65 20 50 28 78 29 20 20 20 20 20 20 20 20  ine P(x)        
07c0: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78  cgi_parameter((x
07d0: 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50 44 28  ),0).#define PD(
07e0: 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70 61 72  x,y)     cgi_par
07f0: 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29 29 0a  ameter((x),(y)).
0800: 23 64 65 66 69 6e 65 20 51 50 28 78 29 20 20 20  #define QP(x)   
0810: 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73 74 72      quotable_str
0820: 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65 74 65  ing(cgi_paramete
0830: 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66 69 6e  r((x),0)).#defin
0840: 65 20 51 50 44 28 78 2c 79 29 20 20 20 20 71 75  e QPD(x,y)    qu
0850: 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28 63 67  otable_string(cg
0860: 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78 29 2c  i_parameter((x),
0870: 28 79 29 29 29 0a 0a 23 65 6e 64 69 66 20 2f 2a  (y)))..#endif /*
0880: 20 49 4e 54 45 52 46 41 43 45 20 2a 2f 0a 0a 2f   INTERFACE */../
0890: 2a 0a 2a 2a 20 50 72 6f 76 69 64 65 20 61 20 72  *.** Provide a r
08a0: 65 6c 69 61 62 6c 65 20 69 6d 70 6c 65 6d 65 6e  eliable implemen
08b0: 74 61 74 69 6f 6e 20 6f 66 20 61 20 63 61 73 65  tation of a case
08c0: 6c 65 73 73 20 73 74 72 69 6e 67 20 63 6f 6d 70  less string comp
08d0: 61 72 69 73 6f 6e 0a 2a 2a 20 66 75 6e 63 74 69  arison.** functi
08e0: 6f 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 73  on..*/.#define s
08f0: 74 72 69 63 6d 70 20 73 71 6c 69 74 65 33 53 74  tricmp sqlite3St
0900: 72 49 43 6d 70 0a 65 78 74 65 72 6e 20 69 6e 74  rICmp.extern int
0910: 20 73 71 6c 69 74 65 33 53 74 72 49 43 6d 70 28   sqlite3StrICmp(
0920: 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 63 6f 6e  const char*, con
0930: 73 74 20 63 68 61 72 2a 29 3b 0a 0a 2f 2a 0a 2a  st char*);../*.*
0940: 2a 20 54 68 65 20 62 6f 64 79 20 6f 66 20 74 68  * The body of th
0950: 65 20 48 54 54 50 20 72 65 70 6c 79 20 74 65 78  e HTTP reply tex
0960: 74 20 69 73 20 73 74 6f 72 65 64 20 68 65 72 65  t is stored here
0970: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42 6c 6f 62  ..*/.static Blob
0980: 20 63 67 69 43 6f 6e 74 65 6e 74 20 3d 20 42 4c   cgiContent = BL
0990: 4f 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 0a  OB_INITIALIZER;.
09a0: 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 72 65  ./*.** Append re
09b0: 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 6f 20 77  ply content to w
09c0: 68 61 74 20 61 6c 72 65 61 64 79 20 65 78 69 73  hat already exis
09d0: 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  ts..*/.void cgi_
09e0: 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e 74 28 63  append_content(c
09f0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 61 74 61  onst char *zData
0a00: 2c 20 69 6e 74 20 6e 41 6d 74 29 7b 0a 20 20 62  , int nAmt){.  b
0a10: 6c 6f 62 5f 61 70 70 65 6e 64 28 26 63 67 69 43  lob_append(&cgiC
0a20: 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c 20 6e  ontent, zData, n
0a30: 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  Amt);.}../*.** R
0a40: 65 73 65 74 20 74 68 65 20 48 54 54 50 20 72 65  eset the HTTP re
0a50: 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 20 61  ply text to be a
0a60: 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 2e 0a  n empty string..
0a70: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 73 65  */.void cgi_rese
0a80: 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 29 7b  t_content(void){
0a90: 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63  .  blob_reset(&c
0aa0: 67 69 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a 0a 2f  giContent);.}../
0ab0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f  *.** Return a po
0ac0: 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43 47 49  inter to the CGI
0ad0: 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a 2a 2f   output blob..*/
0ae0: 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74 70 75  .Blob *cgi_outpu
0af0: 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a 20 20  t_blob(void){.  
0b00: 72 65 74 75 72 6e 20 26 63 67 69 43 6f 6e 74 65  return &cgiConte
0b10: 6e 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74  nt;.}../*.** Ret
0b20: 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 74 6f  urn a pointer to
0b30: 20 74 68 65 20 48 54 54 50 20 72 65 70 6c 79 20   the HTTP reply 
0b40: 74 65 78 74 2e 0a 2a 2f 0a 63 68 61 72 20 2a 63  text..*/.char *c
0b50: 67 69 5f 65 78 74 72 61 63 74 5f 63 6f 6e 74 65  gi_extract_conte
0b60: 6e 74 28 69 6e 74 20 2a 70 6e 41 6d 74 29 7b 0a  nt(int *pnAmt){.
0b70: 20 20 72 65 74 75 72 6e 20 62 6c 6f 62 5f 62 75    return blob_bu
0b80: 66 66 65 72 28 26 63 67 69 43 6f 6e 74 65 6e 74  ffer(&cgiContent
0b90: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 69  );.}../*.** Addi
0ba0: 74 69 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61 74 69  tional informati
0bb0: 6f 6e 20 75 73 65 64 20 74 6f 20 66 6f 72 6d 20  on used to form 
0bc0: 74 68 65 20 48 54 54 50 20 72 65 70 6c 79 0a 2a  the HTTP reply.*
0bd0: 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 7a  /.static char *z
0be0: 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 22 74  ContentType = "t
0bf0: 65 78 74 2f 68 74 6d 6c 22 3b 20 20 20 20 20 2f  ext/html";     /
0c00: 2a 20 43 6f 6e 74 65 6e 74 20 74 79 70 65 20 6f  * Content type o
0c10: 66 20 74 68 65 20 72 65 70 6c 79 20 2a 2f 0a 73  f the reply */.s
0c20: 74 61 74 69 63 20 63 68 61 72 20 2a 7a 52 65 70  tatic char *zRep
0c30: 6c 79 53 74 61 74 75 73 20 3d 20 22 4f 4b 22 3b  lyStatus = "OK";
0c40: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52              /* R
0c50: 65 70 6c 79 20 73 74 61 74 75 73 20 64 65 73 63  eply status desc
0c60: 72 69 70 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69  ription */.stati
0c70: 63 20 69 6e 74 20 69 52 65 70 6c 79 53 74 61 74  c int iReplyStat
0c80: 75 73 20 3d 20 32 30 30 3b 20 20 20 20 20 20 20  us = 200;       
0c90: 20 20 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79          /* Reply
0ca0: 20 73 74 61 74 75 73 20 63 6f 64 65 20 2a 2f 0a   status code */.
0cb0: 73 74 61 74 69 63 20 42 6c 6f 62 20 65 78 74 72  static Blob extr
0cc0: 61 48 65 61 64 65 72 20 3d 20 42 4c 4f 42 5f 49  aHeader = BLOB_I
0cd0: 4e 49 54 49 41 4c 49 5a 45 52 3b 20 20 2f 2a 20  NITIALIZER;  /* 
0ce0: 45 78 74 72 61 20 68 65 61 64 65 72 20 74 65 78  Extra header tex
0cf0: 74 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  t */.static int 
0d00: 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 3d 20  fullHttpReply = 
0d10: 30 3b 20 20 20 20 20 20 2f 2a 20 54 72 75 65 20  0;      /* True 
0d20: 66 6f 72 20 61 20 66 75 6c 6c 2d 62 6c 6f 77 6e  for a full-blown
0d30: 20 48 54 54 50 20 68 65 61 64 65 72 20 2a 2f 0a   HTTP header */.
0d40: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72  ./*.** Set the r
0d50: 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 79 70  eply content typ
0d60: 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65  e.*/.void cgi_se
0d70: 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65 28 63  t_content_type(c
0d80: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 70 65  onst char *zType
0d90: 29 7b 0a 20 20 7a 43 6f 6e 74 65 6e 74 54 79 70  ){.  zContentTyp
0da0: 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22  e = mprintf("%s"
0db0: 2c 20 7a 54 79 70 65 29 3b 0a 7d 0a 0a 2f 2a 0a  , zType);.}../*.
0dc0: 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70 6c 79  ** Set the reply
0dd0: 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65 20   content to the 
0de0: 73 70 65 63 69 66 69 65 64 20 42 4c 4f 42 2e 0a  specified BLOB..
0df0: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f  */.void cgi_set_
0e00: 63 6f 6e 74 65 6e 74 28 42 6c 6f 62 20 2a 70 4e  content(Blob *pN
0e10: 65 77 43 6f 6e 74 65 6e 74 29 7b 0a 20 20 62 6c  ewContent){.  bl
0e20: 6f 62 5f 72 65 73 65 74 28 26 63 67 69 43 6f 6e  ob_reset(&cgiCon
0e30: 74 65 6e 74 29 3b 0a 20 20 63 67 69 43 6f 6e 74  tent);.  cgiCont
0e40: 65 6e 74 20 3d 20 2a 70 4e 65 77 43 6f 6e 74 65  ent = *pNewConte
0e50: 6e 74 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28  nt;.  blob_zero(
0e60: 70 4e 65 77 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a  pNewContent);.}.
0e70: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72  ./*.** Set the r
0e80: 65 70 6c 79 20 73 74 61 74 75 73 20 63 6f 64 65  eply status code
0e90: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74  .*/.void cgi_set
0ea0: 5f 73 74 61 74 75 73 28 69 6e 74 20 69 53 74 61  _status(int iSta
0eb0: 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  t, const char *z
0ec0: 53 74 61 74 29 7b 0a 20 20 7a 52 65 70 6c 79 53  Stat){.  zReplyS
0ed0: 74 61 74 75 73 20 3d 20 6d 70 72 69 6e 74 66 28  tatus = mprintf(
0ee0: 22 25 73 22 2c 20 7a 53 74 61 74 29 3b 0a 20 20  "%s", zStat);.  
0ef0: 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 69  iReplyStatus = i
0f00: 53 74 61 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41  Stat;.}../*.** A
0f10: 70 70 65 6e 64 20 74 65 78 74 20 74 6f 20 74 68  ppend text to th
0f20: 65 20 68 65 61 64 65 72 20 6f 66 20 61 6e 20 48  e header of an H
0f30: 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 6f 69  TTP reply.*/.voi
0f40: 64 20 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 61  d cgi_append_hea
0f50: 64 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  der(const char *
0f60: 7a 4c 69 6e 65 29 7b 0a 20 20 62 6c 6f 62 5f 61  zLine){.  blob_a
0f70: 70 70 65 6e 64 28 26 65 78 74 72 61 48 65 61 64  ppend(&extraHead
0f80: 65 72 2c 20 7a 4c 69 6e 65 2c 20 2d 31 29 3b 0a  er, zLine, -1);.
0f90: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 20 63  }../*.** Set a c
0fa0: 6f 6f 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 5a 65 72  ookie..**.** Zer
0fb0: 6f 20 6c 69 66 65 74 69 6d 65 20 69 6d 70 6c 69  o lifetime impli
0fc0: 65 73 20 61 20 73 65 73 73 69 6f 6e 20 63 6f 6f  es a session coo
0fd0: 6b 69 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69  kie..*/.void cgi
0fe0: 5f 73 65 74 5f 63 6f 6f 6b 69 65 28 0a 20 20 63  _set_cookie(.  c
0ff0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
1000: 2c 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20  ,    /* Name of 
1010: 74 68 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20  the cookie */.  
1020: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
1030: 75 65 2c 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f  ue,   /* Value o
1040: 66 20 74 68 65 20 63 6f 6f 6b 69 65 2e 20 20 41  f the cookie.  A
1050: 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 65 73 63  utomatically esc
1060: 61 70 65 64 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  aped */.  const 
1070: 63 68 61 72 20 2a 7a 50 61 74 68 2c 20 20 20 20  char *zPath,    
1080: 2f 2a 20 50 61 74 68 20 63 6f 6f 6b 69 65 20 61  /* Path cookie a
1090: 70 70 6c 69 65 73 20 74 6f 2e 20 20 4e 55 4c 4c  pplies to.  NULL
10a0: 20 6d 65 61 6e 73 20 22 2f 22 20 2a 2f 0a 20 20   means "/" */.  
10b0: 69 6e 74 20 6c 69 66 65 74 69 6d 65 20 20 20 20  int lifetime    
10c0: 20 20 20 20 20 20 2f 2a 20 45 78 70 69 72 61 74        /* Expirat
10d0: 69 6f 6e 20 6f 66 20 74 68 65 20 63 6f 6f 6b 69  ion of the cooki
10e0: 65 20 69 6e 20 73 65 63 6f 6e 64 73 20 66 72 6f  e in seconds fro
10f0: 6d 20 6e 6f 77 20 2a 2f 0a 29 7b 0a 20 20 69 66  m now */.){.  if
1100: 28 20 7a 50 61 74 68 3d 3d 30 20 29 20 7a 50 61  ( zPath==0 ) zPa
1110: 74 68 20 3d 20 22 2f 22 3b 0a 20 20 69 66 28 20  th = "/";.  if( 
1120: 6c 69 66 65 74 69 6d 65 3e 30 20 29 7b 0a 20 20  lifetime>0 ){.  
1130: 20 20 6c 69 66 65 74 69 6d 65 20 2b 3d 20 28 69    lifetime += (i
1140: 6e 74 29 74 69 6d 65 28 30 29 3b 0a 20 20 20 20  nt)time(0);.    
1150: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 78  blob_appendf(&ex
1160: 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20 20 20  traHeader,.     
1170: 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 25    "Set-Cookie: %
1180: 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b 20 65  s=%t; Path=%s; e
1190: 78 70 69 72 65 73 3d 25 73 3b 20 56 65 72 73 69  xpires=%s; Versi
11a0: 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20 20 20  on=1\r\n",.     
11b0: 20 20 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65     zName, zValue
11c0: 2c 20 7a 50 61 74 68 2c 20 63 67 69 5f 72 66 63  , zPath, cgi_rfc
11d0: 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 6c 69  822_datestamp(li
11e0: 66 65 74 69 6d 65 29 29 3b 0a 20 20 7d 65 6c 73  fetime));.  }els
11f0: 65 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65  e{.    blob_appe
1200: 6e 64 66 28 26 65 78 74 72 61 48 65 61 64 65 72  ndf(&extraHeader
1210: 2c 0a 20 20 20 20 20 20 20 22 53 65 74 2d 43 6f  ,.       "Set-Co
1220: 6f 6b 69 65 3a 20 25 73 3d 25 74 3b 20 50 61 74  okie: %s=%t; Pat
1230: 68 3d 25 73 3b 20 56 65 72 73 69 6f 6e 3d 31 5c  h=%s; Version=1\
1240: 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 7a 4e 61  r\n",.       zNa
1250: 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50 61 74  me, zValue, zPat
1260: 68 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 20 30  h);.  }.}..#if 0
1270: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 20 45 54  ./*.** Add an ET
1280: 61 67 20 68 65 61 64 65 72 20 6c 69 6e 65 0a 2a  ag header line.*
1290: 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 63  /.static char *c
12a0: 67 69 5f 61 64 64 5f 65 74 61 67 28 63 68 61 72  gi_add_etag(char
12b0: 20 2a 7a 54 78 74 2c 20 69 6e 74 20 6e 4c 65 6e   *zTxt, int nLen
12c0: 29 7b 0a 20 20 4d 44 35 43 6f 6e 74 65 78 74 20  ){.  MD5Context 
12d0: 63 74 78 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20  ctx;.  unsigned 
12e0: 63 68 61 72 20 64 69 67 65 73 74 5b 31 36 5d 3b  char digest[16];
12f0: 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 63  .  int i, j;.  c
1300: 68 61 72 20 7a 45 54 61 67 5b 36 34 5d 3b 0a 0a  har zETag[64];..
1310: 20 20 4d 44 35 49 6e 69 74 28 26 63 74 78 29 3b    MD5Init(&ctx);
1320: 0a 20 20 4d 44 35 55 70 64 61 74 65 28 26 63 74  .  MD5Update(&ct
1330: 78 2c 7a 54 78 74 2c 6e 4c 65 6e 29 3b 0a 20 20  x,zTxt,nLen);.  
1340: 4d 44 35 46 69 6e 61 6c 28 64 69 67 65 73 74 2c  MD5Final(digest,
1350: 26 63 74 78 29 3b 0a 20 20 66 6f 72 28 6a 3d 69  &ctx);.  for(j=i
1360: 3d 30 3b 20 69 3c 31 36 3b 20 69 2b 2b 2c 6a 2b  =0; i<16; i++,j+
1370: 3d 32 29 7b 0a 20 20 20 20 62 70 72 69 6e 74 66  =2){.    bprintf
1380: 28 26 7a 45 54 61 67 5b 6a 5d 2c 73 69 7a 65 6f  (&zETag[j],sizeo
1390: 66 28 7a 45 54 61 67 29 2d 6a 2c 22 25 30 32 78  f(zETag)-j,"%02x
13a0: 22 2c 28 69 6e 74 29 64 69 67 65 73 74 5b 69 5d  ",(int)digest[i]
13b0: 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f 61 70  );.  }.  blob_ap
13c0: 70 65 6e 64 66 28 26 65 78 74 72 61 48 65 61 64  pendf(&extraHead
13d0: 65 72 2c 20 22 45 54 61 67 3a 20 25 73 5c 72 5c  er, "ETag: %s\r\
13e0: 6e 22 2c 20 7a 45 54 61 67 29 3b 0a 20 20 72 65  n", zETag);.  re
13f0: 74 75 72 6e 20 73 74 72 64 75 70 28 7a 45 54 61  turn strdup(zETa
1400: 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20  g);.}../*.** Do 
1410: 73 6f 6d 65 20 63 61 63 68 65 20 63 6f 6e 74 72  some cache contr
1420: 6f 6c 20 73 74 75 66 66 2e 20 46 69 72 73 74 2c  ol stuff. First,
1430: 20 77 65 20 67 65 6e 65 72 61 74 65 20 61 6e 20   we generate an 
1440: 45 54 61 67 20 61 6e 64 20 69 6e 63 6c 75 64 65  ETag and include
1450: 20 69 74 20 69 6e 0a 2a 2a 20 74 68 65 20 72 65   it in.** the re
1460: 73 70 6f 6e 73 65 20 68 65 61 64 65 72 73 2e 20  sponse headers. 
1470: 53 65 63 6f 6e 64 2c 20 77 65 20 64 6f 20 77 68  Second, we do wh
1480: 61 74 65 76 65 72 20 69 73 20 6e 65 63 65 73 73  atever is necess
1490: 61 72 79 20 74 6f 20 64 65 74 65 72 6d 69 6e 65  ary to determine
14a0: 20 69 66 0a 2a 2a 20 74 68 65 20 72 65 71 75 65   if.** the reque
14b0: 73 74 20 77 61 73 20 61 73 6b 69 6e 67 20 61 62  st was asking ab
14c0: 6f 75 74 20 63 61 63 68 69 6e 67 20 61 6e 64 20  out caching and 
14d0: 77 68 65 74 68 65 72 20 77 65 20 6e 65 65 64 20  whether we need 
14e0: 74 6f 20 73 65 6e 64 20 62 61 63 6b 20 74 68 65  to send back the
14f0: 0a 2a 2a 20 72 65 73 70 6f 6e 73 65 20 62 6f 64  .** response bod
1500: 79 2e 20 49 66 20 77 65 20 73 68 6f 75 6c 64 6e  y. If we shouldn
1510: 27 74 20 73 65 6e 64 20 61 20 62 6f 64 79 2c 20  't send a body, 
1520: 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e  return non-zero.
1530: 0a 2a 2a 0a 2a 2a 20 43 75 72 72 65 6e 74 6c 79  .**.** Currently
1540: 2c 20 77 65 20 6a 75 73 74 20 63 68 65 63 6b 20  , we just check 
1550: 74 68 65 20 45 54 61 67 20 61 67 61 69 6e 73 74  the ETag against
1560: 20 61 6e 79 20 49 66 2d 4e 6f 6e 65 2d 4d 61 74   any If-None-Mat
1570: 63 68 20 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a  ch header..**.**
1580: 20 46 49 58 4d 45 3a 20 49 6e 20 73 6f 6d 65 20   FIXME: In some 
1590: 63 61 73 65 73 20 28 61 74 74 61 63 68 6d 65 6e  cases (attachmen
15a0: 74 73 2c 20 66 69 6c 65 20 63 6f 6e 74 65 6e 74  ts, file content
15b0: 73 29 20 77 65 20 63 6f 75 6c 64 20 63 68 65 63  s) we could chec
15c0: 6b 0a 2a 2a 20 49 66 2d 4d 6f 64 69 66 69 65 64  k.** If-Modified
15d0: 2d 53 69 6e 63 65 20 68 65 61 64 65 72 73 20 61  -Since headers a
15e0: 6e 64 20 61 6c 77 61 79 73 20 69 6e 63 6c 75 64  nd always includ
15f0: 65 20 4c 61 73 74 2d 4d 6f 64 69 66 69 65 64 20  e Last-Modified 
1600: 69 6e 20 72 65 73 70 6f 6e 73 65 73 2e 0a 2a 2f  in responses..*/
1610: 0a 73 74 61 74 69 63 20 69 6e 74 20 63 68 65 63  .static int chec
1620: 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f 6c 28  k_cache_control(
1630: 76 6f 69 64 29 7b 0a 20 20 2f 2a 20 46 49 58 4d  void){.  /* FIXM
1640: 45 3a 20 74 68 65 72 65 27 73 20 73 6f 6d 65 20  E: there's some 
1650: 67 6f 74 63 68 61 73 20 77 74 68 20 63 6f 6f 6b  gotchas wth cook
1660: 69 65 73 20 61 6e 64 20 73 6f 6d 65 20 68 65 61  ies and some hea
1670: 64 65 72 73 2e 20 2a 2f 0a 20 20 63 68 61 72 20  ders. */.  char 
1680: 2a 7a 45 54 61 67 20 3d 20 63 67 69 5f 61 64 64  *zETag = cgi_add
1690: 5f 65 74 61 67 28 62 6c 6f 62 5f 62 75 66 66 65  _etag(blob_buffe
16a0: 72 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 2c 62  r(&cgiContent),b
16b0: 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e  lob_size(&cgiCon
16c0: 74 65 6e 74 29 29 3b 0a 20 20 63 68 61 72 20 2a  tent));.  char *
16d0: 7a 4d 61 74 63 68 20 3d 20 50 28 22 48 54 54 50  zMatch = P("HTTP
16e0: 5f 49 46 5f 4e 4f 4e 45 5f 4d 41 54 43 48 22 29  _IF_NONE_MATCH")
16f0: 3b 0a 0a 20 20 69 66 28 20 7a 45 54 61 67 21 3d  ;..  if( zETag!=
1700: 30 20 26 26 20 7a 4d 61 74 63 68 21 3d 30 20 29  0 && zMatch!=0 )
1710: 20 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 42 75   {.    char *zBu
1720: 66 20 3d 20 73 74 72 64 75 70 28 7a 4d 61 74 63  f = strdup(zMatc
1730: 68 29 3b 0a 20 20 20 20 69 66 28 20 7a 42 75 66  h);.    if( zBuf
1740: 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 68 61  !=0 ){.      cha
1750: 72 20 2a 7a 54 6f 6b 20 3d 20 30 3b 0a 20 20 20  r *zTok = 0;.   
1760: 20 20 20 63 68 61 72 20 2a 7a 50 6f 73 3b 0a 20     char *zPos;. 
1770: 20 20 20 20 20 66 6f 72 28 20 7a 54 6f 6b 20 3d       for( zTok =
1780: 20 73 74 72 74 6f 6b 5f 72 28 7a 42 75 66 2c 20   strtok_r(zBuf, 
1790: 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 3b 0a 20 20  ",\"",&zPos);.  
17a0: 20 20 20 20 20 20 20 20 20 7a 54 6f 6b 20 26 26           zTok &&
17b0: 20 73 74 72 63 61 73 65 63 6d 70 28 7a 54 6f 6b   strcasecmp(zTok
17c0: 2c 7a 45 54 61 67 29 3b 0a 20 20 20 20 20 20 20  ,zETag);.       
17d0: 20 20 20 20 7a 54 6f 6b 20 3d 20 20 73 74 72 74      zTok =  strt
17e0: 6f 6b 5f 72 28 30 2c 20 22 2c 5c 22 22 2c 26 7a  ok_r(0, ",\"",&z
17f0: 50 6f 73 29 29 7b 7d 0a 20 20 20 20 20 20 66 72  Pos)){}.      fr
1800: 65 65 28 7a 42 75 66 29 3b 0a 20 20 20 20 20 20  ee(zBuf);.      
1810: 69 66 28 7a 54 6f 6b 29 20 72 65 74 75 72 6e 20  if(zTok) return 
1820: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a  1;.    }.  }.  .
1830: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 23 65    return 0;.}.#e
1840: 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61  ndif../*.** Do a
1850: 20 6e 6f 72 6d 61 6c 20 48 54 54 50 20 72 65 70   normal HTTP rep
1860: 6c 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72  ly.*/.void cgi_r
1870: 65 70 6c 79 28 76 6f 69 64 29 7b 0a 20 20 69 66  eply(void){.  if
1880: 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 3c 3d  ( iReplyStatus<=
1890: 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c 79 53  0 ){.    iReplyS
18a0: 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20 20 20  tatus = 200;.   
18b0: 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20   zReplyStatus = 
18c0: 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66 20 30  "OK";.  }..#if 0
18d0: 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 74 61  .  if( iReplySta
18e0: 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68 65 63  tus==200 && chec
18f0: 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f 6c 28  k_cache_control(
1900: 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63 68 61  ) ) {.    /* cha
1910: 6e 67 65 20 74 68 65 20 73 74 61 74 75 73 20 74  nge the status t
1920: 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20 61 6e  o "unchanged" an
1930: 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20 73 65  d we can skip se
1940: 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a  nding the.    **
1950: 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e 73 65   actual response
1960: 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73 6c 79   body. Obviously
1970: 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73   we only do this
1980: 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65 5f 20   when we _have_ 
1990: 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20 28 63  a.    ** body (c
19a0: 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20 2a 2f  ode 200)..    */
19b0: 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 74 75  .    iReplyStatu
19c0: 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a 52 65  s = 304;.    zRe
19d0: 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e 6f 74  plyStatus = "Not
19e0: 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20 7d 0a   Modified";.  }.
19f0: 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 66 75  #endif..  if( fu
1a00: 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b 0a 20  llHttpReply ){. 
1a10: 20 20 20 70 72 69 6e 74 66 28 22 48 54 54 50 2f     printf("HTTP/
1a20: 31 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22 2c 20  1.0 %d %s\r\n", 
1a30: 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a 52  iReplyStatus, zR
1a40: 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20 20  eplyStatus);.   
1a50: 20 70 72 69 6e 74 66 28 22 44 61 74 65 3a 20 25   printf("Date: %
1a60: 73 5c 72 5c 6e 22 2c 20 63 67 69 5f 72 66 63 38  s\r\n", cgi_rfc8
1a70: 32 32 5f 64 61 74 65 73 74 61 6d 70 28 74 69 6d  22_datestamp(tim
1a80: 65 28 30 29 29 29 3b 0a 20 20 20 20 70 72 69 6e  e(0)));.    prin
1a90: 74 66 28 22 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20  tf("Connection: 
1aa0: 63 6c 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20 20 7d  close\r\n");.  }
1ab0: 65 6c 73 65 7b 0a 20 20 20 20 70 72 69 6e 74 66  else{.    printf
1ac0: 28 22 53 74 61 74 75 73 3a 20 25 64 20 25 73 5c  ("Status: %d %s\
1ad0: 72 5c 6e 22 2c 20 69 52 65 70 6c 79 53 74 61 74  r\n", iReplyStat
1ae0: 75 73 2c 20 7a 52 65 70 6c 79 53 74 61 74 75 73  us, zReplyStatus
1af0: 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 62 6c  );.  }..  if( bl
1b00: 6f 62 5f 73 69 7a 65 28 26 65 78 74 72 61 48 65  ob_size(&extraHe
1b10: 61 64 65 72 29 3e 30 20 29 7b 0a 20 20 20 20 70  ader)>0 ){.    p
1b20: 72 69 6e 74 66 28 22 25 73 22 2c 20 62 6c 6f 62  rintf("%s", blob
1b30: 5f 62 75 66 66 65 72 28 26 65 78 74 72 61 48 65  _buffer(&extraHe
1b40: 61 64 65 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 69  ader));.  }..  i
1b50: 66 28 20 67 2e 69 73 43 6f 6e 73 74 20 29 7b 0a  f( g.isConst ){.
1b60: 20 20 20 20 2f 2a 20 63 6f 6e 73 74 61 6e 74 20      /* constant 
1b70: 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65 20 69  means that the i
1b80: 6e 70 75 74 20 55 52 4c 20 77 69 6c 6c 20 5f 6e  nput URL will _n
1b90: 65 76 65 72 5f 20 67 65 6e 65 72 61 74 65 20 61  ever_ generate a
1ba0: 6e 79 74 68 69 6e 67 0a 20 20 20 20 2a 2a 20 65  nything.    ** e
1bb0: 6c 73 65 2e 20 49 6e 20 74 68 65 20 63 61 73 65  lse. In the case
1bc0: 20 6f 66 20 61 74 74 61 63 68 6d 65 6e 74 73 2c   of attachments,
1bd0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 77 6f   the contents wo
1be0: 6e 27 74 20 63 68 61 6e 67 65 20 62 65 63 61 75  n't change becau
1bf0: 73 65 0a 20 20 20 20 2a 2a 20 61 6e 20 61 74 74  se.    ** an att
1c00: 65 6d 70 74 20 74 6f 20 63 68 61 6e 67 65 20 74  empt to change t
1c10: 68 65 6d 20 67 65 6e 65 72 61 74 65 73 20 61 20  hem generates a 
1c20: 6e 65 77 20 61 74 74 61 63 68 6d 65 6e 74 20 6e  new attachment n
1c30: 75 6d 62 65 72 2e 20 49 6e 20 74 68 65 0a 20 20  umber. In the.  
1c40: 20 20 2a 2a 20 63 61 73 65 20 6f 66 20 6d 6f 73    ** case of mos
1c50: 74 20 2f 67 65 74 66 69 6c 65 20 63 61 6c 6c 73  t /getfile calls
1c60: 20 66 6f 72 20 73 70 65 63 69 66 69 63 20 76 65   for specific ve
1c70: 72 73 69 6f 6e 73 2c 20 74 68 65 20 6f 6e 6c 79  rsions, the only
1c80: 20 77 61 79 20 74 68 65 0a 20 20 20 20 2a 2a 20   way the.    ** 
1c90: 63 6f 6e 74 65 6e 74 20 63 68 61 6e 67 65 73 20  content changes 
1ca0: 69 73 20 69 66 20 73 6f 6d 65 6f 6e 65 20 62 72  is if someone br
1cb0: 65 61 6b 73 20 74 68 65 20 53 43 4d 2e 20 41 6e  eaks the SCM. An
1cc0: 64 20 69 66 20 74 68 61 74 20 68 61 70 70 65 6e  d if that happen
1cd0: 73 2c 20 61 0a 20 20 20 20 2a 2a 20 73 74 61 6c  s, a.    ** stal
1ce0: 65 20 63 61 63 68 65 20 69 73 20 74 68 65 20 6c  e cache is the l
1cf0: 65 61 73 74 20 6f 66 20 74 68 65 20 70 72 6f 62  east of the prob
1d00: 6c 65 6d 2e 20 53 6f 20 77 65 20 70 72 6f 76 69  lem. So we provi
1d10: 64 65 20 61 6e 20 45 78 70 69 72 65 73 0a 20 20  de an Expires.  
1d20: 20 20 2a 2a 20 68 65 61 64 65 72 20 73 65 74 20    ** header set 
1d30: 74 6f 20 61 20 72 65 61 73 6f 6e 61 62 6c 65 20  to a reasonable 
1d40: 70 65 72 69 6f 64 20 28 64 65 66 61 75 6c 74 3a  period (default:
1d50: 20 6f 6e 65 20 77 65 65 6b 29 2e 0a 20 20 20 20   one week)..    
1d60: 2a 2f 0a 20 20 20 20 2f 2a 74 69 6d 65 5f 74 20  */.    /*time_t 
1d70: 65 78 70 69 72 65 73 20 3d 20 74 69 6d 65 28 30  expires = time(0
1d80: 29 20 2b 20 61 74 6f 69 28 64 62 5f 63 6f 6e 66  ) + atoi(db_conf
1d90: 69 67 28 22 63 6f 6e 73 74 61 6e 74 5f 65 78 70  ig("constant_exp
1da0: 69 72 65 73 22 2c 22 36 30 34 38 30 30 22 29 29  ires","604800"))
1db0: 3b 2a 2f 0a 20 20 20 20 74 69 6d 65 5f 74 20 65  ;*/.    time_t e
1dc0: 78 70 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29  xpires = time(0)
1dd0: 20 2b 20 36 30 34 38 30 30 3b 0a 20 20 20 20 70   + 604800;.    p
1de0: 72 69 6e 74 66 28 20 22 45 78 70 69 72 65 73 3a  rintf( "Expires:
1df0: 20 25 73 5c 72 5c 6e 22 2c 20 63 67 69 5f 72 66   %s\r\n", cgi_rf
1e00: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 65  c822_datestamp(e
1e10: 78 70 69 72 65 73 29 29 3b 0a 20 20 7d 0a 0a 20  xpires));.  }.. 
1e20: 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 69 6e 74 65   /* Content inte
1e30: 6e 64 65 64 20 66 6f 72 20 6c 6f 67 67 65 64 20  nded for logged 
1e40: 69 6e 20 75 73 65 72 73 20 73 68 6f 75 6c 64 20  in users should 
1e50: 6f 6e 6c 79 20 62 65 20 63 61 63 68 65 64 20 69  only be cached i
1e60: 6e 0a 20 20 2a 2a 20 74 68 65 20 62 72 6f 77 73  n.  ** the brows
1e70: 65 72 2c 20 6e 6f 74 20 73 6f 6d 65 20 73 68 61  er, not some sha
1e80: 72 65 64 20 6c 6f 63 61 74 69 6f 6e 2e 0a 20 20  red location..  
1e90: 2a 2f 0a 20 20 70 72 69 6e 74 66 28 22 43 61 63  */.  printf("Cac
1ea0: 68 65 2d 63 6f 6e 74 72 6f 6c 3a 20 70 72 69 76  he-control: priv
1eb0: 61 74 65 5c 72 5c 6e 22 29 3b 0a 0a 23 69 66 20  ate\r\n");..#if 
1ec0: 46 4f 53 53 49 4c 5f 49 31 38 4e 0a 20 20 70 72  FOSSIL_I18N.  pr
1ed0: 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74 2d 54  intf( "Content-T
1ee0: 79 70 65 3a 20 25 73 3b 20 63 68 61 72 73 65 74  ype: %s; charset
1ef0: 3d 25 73 5c 72 5c 6e 22 2c 20 7a 43 6f 6e 74 65  =%s\r\n", zConte
1f00: 6e 74 54 79 70 65 2c 20 6e 6c 5f 6c 61 6e 67 69  ntType, nl_langi
1f10: 6e 66 6f 28 43 4f 44 45 53 45 54 29 29 3b 0a 23  nfo(CODESET));.#
1f20: 65 6c 73 65 0a 20 20 70 72 69 6e 74 66 28 20 22  else.  printf( "
1f30: 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 25 73  Content-Type: %s
1f40: 3b 20 63 68 61 72 73 65 74 3d 49 53 4f 2d 38 38  ; charset=ISO-88
1f50: 35 39 2d 31 5c 72 5c 6e 22 2c 20 7a 43 6f 6e 74  59-1\r\n", zCont
1f60: 65 6e 74 54 79 70 65 29 3b 0a 23 65 6e 64 69 66  entType);.#endif
1f70: 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 43  .  if( strcmp(zC
1f80: 6f 6e 74 65 6e 74 54 79 70 65 2c 22 61 70 70 6c  ontentType,"appl
1f90: 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c  ication/x-fossil
1fa0: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 62 6c 6f  ")==0 ){.    blo
1fb0: 62 5f 63 6f 6d 70 72 65 73 73 28 26 63 67 69 43  b_compress(&cgiC
1fc0: 6f 6e 74 65 6e 74 2c 20 26 63 67 69 43 6f 6e 74  ontent, &cgiCont
1fd0: 65 6e 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  ent);.  }..  if(
1fe0: 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 21 3d   iReplyStatus !=
1ff0: 20 33 30 34 20 29 20 7b 0a 20 20 20 20 70 72 69   304 ) {.    pri
2000: 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74 2d 4c 65  ntf( "Content-Le
2010: 6e 67 74 68 3a 20 25 64 5c 72 5c 6e 22 2c 20 62  ngth: %d\r\n", b
2020: 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e  lob_size(&cgiCon
2030: 74 65 6e 74 29 20 29 3b 0a 20 20 7d 0a 20 20 70  tent) );.  }.  p
2040: 72 69 6e 74 66 28 22 5c 72 5c 6e 22 29 3b 0a 20  rintf("\r\n");. 
2050: 20 69 66 28 20 62 6c 6f 62 5f 73 69 7a 65 28 26   if( blob_size(&
2060: 63 67 69 43 6f 6e 74 65 6e 74 29 3e 30 20 26 26  cgiContent)>0 &&
2070: 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 21 3d   iReplyStatus !=
2080: 20 33 30 34 20 29 7b 0a 20 20 20 20 66 77 72 69   304 ){.    fwri
2090: 74 65 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 26  te(blob_buffer(&
20a0: 63 67 69 43 6f 6e 74 65 6e 74 29 2c 20 31 2c 20  cgiContent), 1, 
20b0: 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f  blob_size(&cgiCo
20c0: 6e 74 65 6e 74 29 2c 20 73 74 64 6f 75 74 29 3b  ntent), stdout);
20d0: 0a 20 20 7d 0a 20 20 43 47 49 44 45 42 55 47 28  .  }.  CGIDEBUG(
20e0: 28 22 44 4f 4e 45 5c 6e 22 29 29 3b 0a 7d 0a 0a  ("DONE\n"));.}..
20f0: 2f 2a 0a 2a 2a 20 44 6f 20 61 20 72 65 64 69 72  /*.** Do a redir
2100: 65 63 74 20 72 65 71 75 65 73 74 20 74 6f 20 74  ect request to t
2110: 68 65 20 55 52 4c 20 67 69 76 65 6e 20 69 6e 20  he URL given in 
2120: 74 68 65 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a  the argument..**
2130: 0a 2a 2a 20 54 68 65 20 55 52 4c 20 6d 75 73 74  .** The URL must
2140: 20 62 65 20 72 65 6c 61 74 69 76 65 20 74 6f 20   be relative to 
2150: 74 68 65 20 62 61 73 65 20 6f 66 20 74 68 65 20  the base of the 
2160: 66 6f 73 73 69 6c 20 73 65 72 76 65 72 2e 0a 2a  fossil server..*
2170: 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 64 69 72  /.void cgi_redir
2180: 65 63 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  ect(const char *
2190: 7a 55 52 4c 29 7b 0a 20 20 63 68 61 72 20 2a 7a  zURL){.  char *z
21a0: 4c 6f 63 61 74 69 6f 6e 3b 0a 20 20 43 47 49 44  Location;.  CGID
21b0: 45 42 55 47 28 28 22 72 65 64 69 72 65 63 74 20  EBUG(("redirect 
21c0: 74 6f 20 25 73 5c 6e 22 2c 20 7a 55 52 4c 29 29  to %s\n", zURL))
21d0: 3b 0a 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28  ;.  if( strncmp(
21e0: 7a 55 52 4c 2c 22 68 74 74 70 3a 22 2c 35 29 3d  zURL,"http:",5)=
21f0: 3d 30 20 7c 7c 20 73 74 72 6e 63 6d 70 28 7a 55  =0 || strncmp(zU
2200: 52 4c 2c 22 68 74 74 70 73 3a 22 2c 36 29 3d 3d  RL,"https:",6)==
2210: 30 20 7c 7c 20 2a 7a 55 52 4c 3d 3d 27 2f 27 20  0 || *zURL=='/' 
2220: 29 7b 0a 20 20 20 20 63 67 69 5f 70 61 6e 69 63  ){.    cgi_panic
2230: 28 22 69 6e 76 61 6c 69 64 20 72 65 64 69 72 65  ("invalid redire
2240: 63 74 20 55 52 4c 3a 20 25 73 22 2c 20 7a 55 52  ct URL: %s", zUR
2250: 4c 29 3b 0a 20 20 7d 0a 20 20 7a 4c 6f 63 61 74  L);.  }.  zLocat
2260: 69 6f 6e 20 3d 20 6d 70 72 69 6e 74 66 28 22 4c  ion = mprintf("L
2270: 6f 63 61 74 69 6f 6e 3a 20 25 73 2f 25 73 5c 72  ocation: %s/%s\r
2280: 5c 6e 22 2c 20 67 2e 7a 42 61 73 65 55 52 4c 2c  \n", g.zBaseURL,
2290: 20 7a 55 52 4c 29 3b 0a 20 20 63 67 69 5f 61 70   zURL);.  cgi_ap
22a0: 70 65 6e 64 5f 68 65 61 64 65 72 28 7a 4c 6f 63  pend_header(zLoc
22b0: 61 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65  ation);.  cgi_re
22c0: 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20  set_content();. 
22d0: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 3c 68 74   cgi_printf("<ht
22e0: 6d 6c 3e 5c 6e 3c 70 3e 52 65 64 69 72 65 63 74  ml>\n<p>Redirect
22f0: 20 74 6f 20 25 68 3c 2f 70 3e 5c 6e 3c 2f 68 74   to %h</p>\n</ht
2300: 6d 6c 3e 5c 6e 22 2c 20 7a 55 52 4c 29 3b 0a 20  ml>\n", zURL);. 
2310: 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28   cgi_set_status(
2320: 33 30 32 2c 20 22 4d 6f 76 65 64 20 54 65 6d 70  302, "Moved Temp
2330: 6f 72 61 72 69 6c 79 22 29 3b 0a 20 20 66 72 65  orarily");.  fre
2340: 65 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a 20 20  e(zLocation);.  
2350: 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65  cgi_reply();.  e
2360: 78 69 74 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  xit(0);.}../*.**
2370: 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f   Information abo
2380: 75 74 20 61 6c 6c 20 71 75 65 72 79 20 70 61 72  ut all query par
2390: 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b  ameters and cook
23a0: 69 65 73 20 61 72 65 20 73 74 6f 72 65 64 0a 2a  ies are stored.*
23b0: 2a 20 69 6e 20 74 68 65 73 65 20 76 61 72 69 61  * in these varia
23c0: 62 6c 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  bles..*/.static 
23d0: 69 6e 74 20 6e 41 6c 6c 6f 63 51 50 20 3d 20 30  int nAllocQP = 0
23e0: 3b 20 2f 2a 20 53 70 61 63 65 20 61 6c 6c 6f 63  ; /* Space alloc
23f0: 61 74 65 64 20 66 6f 72 20 61 50 61 72 61 6d 51  ated for aParamQ
2400: 50 5b 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  P[] */.static in
2410: 74 20 6e 55 73 65 64 51 50 20 3d 20 30 3b 20 20  t nUsedQP = 0;  
2420: 2f 2a 20 53 70 61 63 65 20 61 63 74 75 61 6c 6c  /* Space actuall
2430: 79 20 75 73 65 64 20 69 6e 20 61 50 61 72 61 6d  y used in aParam
2440: 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69  QP[] */.static i
2450: 6e 74 20 73 6f 72 74 51 50 20 3d 20 30 3b 20 20  nt sortQP = 0;  
2460: 20 2f 2a 20 54 72 75 65 20 69 66 20 61 50 61 72   /* True if aPar
2470: 61 6d 51 50 5b 5d 20 6e 65 65 64 73 20 73 6f 72  amQP[] needs sor
2480: 74 69 6e 67 20 2a 2f 0a 73 74 61 74 69 63 20 69  ting */.static i
2490: 6e 74 20 73 65 71 51 50 20 3d 20 30 3b 20 20 20  nt seqQP = 0;   
24a0: 20 2f 2a 20 53 65 71 75 65 6e 63 65 20 6e 75 6d   /* Sequence num
24b0: 62 65 72 73 20 2a 2f 0a 73 74 61 74 69 63 20 73  bers */.static s
24c0: 74 72 75 63 74 20 51 50 61 72 61 6d 20 7b 20 20  truct QParam {  
24d0: 20 2f 2a 20 4f 6e 65 20 65 6e 74 72 79 20 66 6f   /* One entry fo
24e0: 72 20 65 61 63 68 20 71 75 65 72 79 20 70 61 72  r each query par
24f0: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65  ameter or cookie
2500: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
2510: 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20   *zName;        
2520: 2f 2a 20 50 61 72 61 6d 65 74 65 72 20 6f 72 20  /* Parameter or 
2530: 63 6f 6f 6b 69 65 20 6e 61 6d 65 20 2a 2f 0a 20  cookie name */. 
2540: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61   const char *zVa
2550: 6c 75 65 3b 20 20 20 20 20 20 20 2f 2a 20 56 61  lue;       /* Va
2560: 6c 75 65 20 6f 66 20 74 68 65 20 71 75 65 72 79  lue of the query
2570: 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f   parameter or co
2580: 6f 6b 69 65 20 2a 2f 0a 20 20 69 6e 74 20 73 65  okie */.  int se
2590: 71 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  q;              
25a0: 20 20 20 20 2f 2a 20 4f 72 64 65 72 20 6f 66 20      /* Order of 
25b0: 69 6e 73 65 72 74 69 6f 6e 20 2a 2f 0a 7d 20 2a  insertion */.} *
25c0: 61 50 61 72 61 6d 51 50 3b 20 20 20 20 20 20 20  aParamQP;       
25d0: 20 20 20 20 20 20 2f 2a 20 41 6e 20 61 72 72 61        /* An arra
25e0: 79 20 6f 66 20 61 6c 6c 20 70 61 72 61 6d 65 74  y of all paramet
25f0: 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 20  ers and cookies 
2600: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e  */../*.** Add an
2610: 6f 74 68 65 72 20 71 75 65 72 79 20 70 61 72 61  other query para
2620: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20  meter or cookie 
2630: 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 72  to the parameter
2640: 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 69   set..** zName i
2650: 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68  s the name of th
2660: 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  e query paramete
2670: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61 6e 64 20  r or cookie and 
2680: 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20 69 74 73  zValue.** is its
2690: 20 66 75 6c 6c 79 20 64 65 63 6f 64 65 64 20 76   fully decoded v
26a0: 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 7a 4e 61 6d  alue..**.** zNam
26b0: 65 20 61 6e 64 20 7a 56 61 6c 75 65 20 61 72 65  e and zValue are
26c0: 20 6e 6f 74 20 63 6f 70 69 65 64 20 61 6e 64 20   not copied and 
26d0: 6d 75 73 74 20 6e 6f 74 20 63 68 61 6e 67 65 20  must not change 
26e0: 6f 72 20 62 65 0a 2a 2a 20 64 65 61 6c 6c 6f 63  or be.** dealloc
26f0: 61 74 65 64 20 61 66 74 65 72 20 74 68 69 73 20  ated after this 
2700: 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 2e  routine returns.
2710: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
2720: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65  cgi_set_paramete
2730: 72 5f 6e 6f 63 6f 70 79 28 63 6f 6e 73 74 20 63  r_nocopy(const c
2740: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73  har *zName, cons
2750: 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b  t char *zValue){
2760: 0a 20 20 69 66 28 20 6e 41 6c 6c 6f 63 51 50 3c  .  if( nAllocQP<
2770: 3d 6e 55 73 65 64 51 50 20 29 7b 0a 20 20 20 20  =nUsedQP ){.    
2780: 6e 41 6c 6c 6f 63 51 50 20 3d 20 6e 41 6c 6c 6f  nAllocQP = nAllo
2790: 63 51 50 2a 32 20 2b 20 31 30 3b 0a 20 20 20 20  cQP*2 + 10;.    
27a0: 61 50 61 72 61 6d 51 50 20 3d 20 72 65 61 6c 6c  aParamQP = reall
27b0: 6f 63 28 20 61 50 61 72 61 6d 51 50 2c 20 6e 41  oc( aParamQP, nA
27c0: 6c 6c 6f 63 51 50 2a 73 69 7a 65 6f 66 28 61 50  llocQP*sizeof(aP
27d0: 61 72 61 6d 51 50 5b 30 5d 29 20 29 3b 0a 20 20  aramQP[0]) );.  
27e0: 20 20 69 66 28 20 61 50 61 72 61 6d 51 50 3d 3d    if( aParamQP==
27f0: 30 20 29 20 65 78 69 74 28 31 29 3b 0a 20 20 7d  0 ) exit(1);.  }
2800: 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65  .  aParamQP[nUse
2810: 64 51 50 5d 2e 7a 4e 61 6d 65 20 3d 20 7a 4e 61  dQP].zName = zNa
2820: 6d 65 3b 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e  me;.  aParamQP[n
2830: 55 73 65 64 51 50 5d 2e 7a 56 61 6c 75 65 20 3d  UsedQP].zValue =
2840: 20 7a 56 61 6c 75 65 3b 0a 20 20 61 50 61 72 61   zValue;.  aPara
2850: 6d 51 50 5b 6e 55 73 65 64 51 50 5d 2e 73 65 71  mQP[nUsedQP].seq
2860: 20 3d 20 73 65 71 51 50 2b 2b 3b 0a 20 20 6e 55   = seqQP++;.  nU
2870: 73 65 64 51 50 2b 2b 3b 0a 20 20 73 6f 72 74 51  sedQP++;.  sortQ
2880: 50 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  P = 1;.}../*.** 
2890: 41 64 64 20 61 6e 6f 74 68 65 72 20 71 75 65 72  Add another quer
28a0: 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63  y parameter or c
28b0: 6f 6f 6b 69 65 20 74 6f 20 74 68 65 20 70 61 72  ookie to the par
28c0: 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a  ameter set..** z
28d0: 4e 61 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65  Name is the name
28e0: 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 61   of the query pa
28f0: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69  rameter or cooki
2900: 65 20 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20  e and zValue.** 
2910: 69 73 20 69 74 73 20 66 75 6c 6c 79 20 64 65 63  is its fully dec
2920: 6f 64 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a  oded value..**.*
2930: 2a 20 43 6f 70 69 65 73 20 61 72 65 20 6d 61 64  * Copies are mad
2940: 65 20 6f 66 20 62 6f 74 68 20 74 68 65 20 7a 4e  e of both the zN
2950: 61 6d 65 20 61 6e 64 20 7a 56 61 6c 75 65 20 70  ame and zValue p
2960: 61 72 61 6d 65 74 65 72 73 2e 0a 2a 2f 0a 76 6f  arameters..*/.vo
2970: 69 64 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d  id cgi_set_param
2980: 65 74 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20  eter(const char 
2990: 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68  *zName, const ch
29a0: 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63  ar *zValue){.  c
29b0: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72  gi_set_parameter
29c0: 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28  _nocopy(mprintf(
29d0: 22 25 73 22 2c 7a 4e 61 6d 65 29 2c 20 6d 70 72  "%s",zName), mpr
29e0: 69 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65  intf("%s",zValue
29f0: 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64  ));.}../*.** Add
2a00: 20 61 20 71 75 65 72 79 20 70 61 72 61 6d 65 74   a query paramet
2a10: 65 72 2e 20 20 54 68 65 20 7a 4e 61 6d 65 20 70  er.  The zName p
2a20: 6f 72 74 69 6f 6e 20 69 73 20 66 69 78 65 64 20  ortion is fixed 
2a30: 62 75 74 20 61 20 63 6f 70 79 0a 2a 2a 20 6d 75  but a copy.** mu
2a40: 73 74 20 62 65 20 6d 61 64 65 20 6f 66 20 7a 56  st be made of zV
2a50: 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  alue..*/.void cg
2a60: 69 5f 73 65 74 65 6e 76 28 63 6f 6e 73 74 20 63  i_setenv(const c
2a70: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73  har *zName, cons
2a80: 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b  t char *zValue){
2a90: 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d  .  cgi_set_param
2aa0: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d  eter_nocopy(zNam
2ab0: 65 2c 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c  e, mprintf("%s",
2ac0: 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a 20 0a 0a 2f  zValue));.}. ../
2ad0: 2a 0a 2a 2a 20 41 64 64 20 61 20 6c 69 73 74 20  *.** Add a list 
2ae0: 6f 66 20 71 75 65 72 79 20 70 61 72 61 6d 65 74  of query paramet
2af0: 65 72 73 20 6f 72 20 63 6f 6f 6b 69 65 73 20 74  ers or cookies t
2b00: 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 20  o the parameter 
2b10: 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20  set..**.** Each 
2b20: 70 61 72 61 6d 65 74 65 72 20 69 73 20 6f 66 20  parameter is of 
2b30: 74 68 65 20 66 6f 72 6d 20 4e 41 4d 45 3d 56 41  the form NAME=VA
2b40: 4c 55 45 2e 20 20 42 6f 74 68 20 74 68 65 20 4e  LUE.  Both the N
2b50: 41 4d 45 20 61 6e 64 20 74 68 65 0a 2a 2a 20 56  AME and the.** V
2b60: 41 4c 55 45 20 6d 61 79 20 62 65 20 75 72 6c 2d  ALUE may be url-
2b70: 65 6e 63 6f 64 65 64 20 28 22 2b 22 20 66 6f 72  encoded ("+" for
2b80: 20 73 70 61 63 65 2c 20 22 25 48 48 22 20 66 6f   space, "%HH" fo
2b90: 72 20 6f 74 68 65 72 20 73 70 65 63 69 61 6c 0a  r other special.
2ba0: 2a 2a 20 63 68 61 72 61 63 74 65 72 73 29 2e 20  ** characters). 
2bb0: 20 42 75 74 20 74 68 69 73 20 72 6f 75 74 69 6e   But this routin
2bc0: 65 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 4e  e assumes that N
2bd0: 41 4d 45 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 0a  AME contains no.
2be0: 2a 2a 20 73 70 65 63 69 61 6c 20 63 68 61 72 61  ** special chara
2bf0: 63 74 65 72 20 61 6e 64 20 74 68 65 72 65 66 6f  cter and therefo
2c00: 72 65 20 64 6f 65 73 20 6e 6f 74 20 64 65 63 6f  re does not deco
2c10: 64 65 20 69 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20  de it..**.** If 
2c20: 4e 41 4d 45 20 62 65 67 69 6e 73 20 77 69 74 68  NAME begins with
2c30: 20 61 6e 6f 74 68 65 72 20 6f 74 68 65 72 20 74   another other t
2c40: 68 61 6e 20 61 20 6c 6f 77 65 72 2d 63 61 73 65  han a lower-case
2c50: 20 6c 65 74 74 65 72 20 74 68 65 6e 0a 2a 2a 20   letter then.** 
2c60: 74 68 65 20 65 6e 74 69 72 65 20 4e 41 4d 45 3d  the entire NAME=
2c70: 56 41 4c 55 45 20 74 65 72 6d 20 69 73 20 69 67  VALUE term is ig
2c80: 6e 6f 72 65 64 2e 20 20 48 65 6e 63 65 3a 0a 2a  nored.  Hence:.*
2c90: 2a 0a 2a 2a 20 20 20 20 20 20 2a 20 20 63 6f 6f  *.**      *  coo
2ca0: 6b 69 65 73 20 61 6e 64 20 71 75 65 72 79 20 70  kies and query p
2cb0: 61 72 61 6d 65 74 65 72 73 20 74 68 61 74 20 68  arameters that h
2cc0: 61 76 65 20 75 70 70 65 72 63 61 73 65 20 6e 61  ave uppercase na
2cd0: 6d 65 73 0a 2a 2a 20 20 20 20 20 20 20 20 20 61  mes.**         a
2ce0: 72 65 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a  re ignored..**.*
2cf0: 2a 20 20 20 20 20 20 2a 20 20 69 74 20 69 73 20  *      *  it is 
2d00: 69 6d 70 6f 73 73 69 62 6c 65 20 66 6f 72 20 61  impossible for a
2d10: 20 63 6f 6f 6b 69 65 20 6f 72 20 71 75 65 72 79   cookie or query
2d20: 20 70 61 72 61 6d 65 74 65 72 20 74 6f 0a 2a 2a   parameter to.**
2d30: 20 20 20 20 20 20 20 20 20 6f 76 65 72 72 69 64           overrid
2d40: 65 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 61  e the value of a
2d50: 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61  n environment va
2d60: 72 69 61 62 6c 65 20 73 69 6e 63 65 0a 2a 2a 20  riable since.** 
2d70: 20 20 20 20 20 20 20 20 65 6e 76 69 72 6f 6e 6d          environm
2d80: 65 6e 74 20 76 61 72 69 61 62 6c 65 73 20 61 6c  ent variables al
2d90: 77 61 79 73 20 68 61 76 65 20 75 70 70 65 72 63  ways have upperc
2da0: 61 73 65 20 6e 61 6d 65 73 2e 0a 2a 2a 0a 2a 2a  ase names..**.**
2db0: 20 50 61 72 61 6d 65 74 65 72 73 20 61 72 65 20   Parameters are 
2dc0: 73 65 70 61 72 61 74 65 64 20 62 79 20 74 68 65  separated by the
2dd0: 20 22 74 65 72 6d 69 6e 61 74 6f 72 22 20 63 68   "terminator" ch
2de0: 61 72 61 63 74 65 72 2e 20 20 57 68 69 74 65 73  aracter.  Whites
2df0: 70 61 63 65 0a 2a 2a 20 62 65 66 6f 72 65 20 74  pace.** before t
2e00: 68 65 20 4e 41 4d 45 20 69 73 20 69 67 6e 6f 72  he NAME is ignor
2e10: 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e  ed..**.** The in
2e20: 70 75 74 20 73 74 72 69 6e 67 20 22 7a 22 20 69  put string "z" i
2e30: 73 20 6d 6f 64 69 66 69 65 64 20 62 75 74 20 6e  s modified but n
2e40: 6f 20 63 6f 70 69 65 73 20 69 73 20 6d 61 64 65  o copies is made
2e50: 2e 20 20 22 7a 22 0a 2a 2a 20 73 68 6f 75 6c 64  .  "z".** should
2e60: 20 6e 6f 74 20 62 65 20 64 65 61 6c 6c 6f 63 61   not be dealloca
2e70: 74 65 64 20 6f 72 20 63 68 61 6e 67 65 64 20 61  ted or changed a
2e80: 67 61 69 6e 20 61 66 74 65 72 20 74 68 69 73 20  gain after this 
2e90: 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74 75 72  routine.** retur
2ea0: 6e 73 20 6f 72 20 69 74 20 77 69 6c 6c 20 63 6f  ns or it will co
2eb0: 72 72 75 70 74 20 74 68 65 20 70 61 72 61 6d 65  rrupt the parame
2ec0: 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74  ter table..*/.st
2ed0: 61 74 69 63 20 76 6f 69 64 20 61 64 64 5f 70 61  atic void add_pa
2ee0: 72 61 6d 5f 6c 69 73 74 28 63 68 61 72 20 2a 7a  ram_list(char *z
2ef0: 2c 20 69 6e 74 20 74 65 72 6d 69 6e 61 74 6f 72  , int terminator
2f00: 29 7b 0a 20 20 77 68 69 6c 65 28 20 2a 7a 20 29  ){.  while( *z )
2f10: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d  {.    char *zNam
2f20: 65 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61  e;.    char *zVa
2f30: 6c 75 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  lue;.    while( 
2f40: 69 73 73 70 61 63 65 28 2a 7a 29 20 29 7b 20 7a  isspace(*z) ){ z
2f50: 2b 2b 3b 20 7d 0a 20 20 20 20 7a 4e 61 6d 65 20  ++; }.    zName 
2f60: 3d 20 7a 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  = z;.    while( 
2f70: 2a 7a 20 26 26 20 2a 7a 21 3d 27 3d 27 20 26 26  *z && *z!='=' &&
2f80: 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 74 6f 72 20   *z!=terminator 
2f90: 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69 66  ){ z++; }.    if
2fa0: 28 20 2a 7a 3d 3d 27 3d 27 20 29 7b 0a 20 20 20  ( *z=='=' ){.   
2fb0: 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20     *z = 0;.     
2fc0: 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7a 56 61 6c   z++;.      zVal
2fd0: 75 65 20 3d 20 7a 3b 0a 20 20 20 20 20 20 77 68  ue = z;.      wh
2fe0: 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 74  ile( *z && *z!=t
2ff0: 65 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b  erminator ){ z++
3000: 3b 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a  ; }.      if( *z
3010: 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a 20 3d   ){.        *z =
3020: 20 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b 2b 3b   0;.        z++;
3030: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 64  .      }.      d
3040: 65 68 74 74 70 69 7a 65 28 7a 56 61 6c 75 65 29  ehttpize(zValue)
3050: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
3060: 20 20 20 69 66 28 20 2a 7a 20 29 7b 20 2a 7a 2b     if( *z ){ *z+
3070: 2b 20 3d 20 30 3b 20 7d 0a 20 20 20 20 20 20 7a  + = 0; }.      z
3080: 56 61 6c 75 65 20 3d 20 22 22 3b 0a 20 20 20 20  Value = "";.    
3090: 7d 0a 20 20 20 20 69 66 28 20 69 73 6c 6f 77 65  }.    if( islowe
30a0: 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20  r(zName[0]) ){. 
30b0: 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72       cgi_set_par
30c0: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e  ameter_nocopy(zN
30d0: 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20  ame, zValue);.  
30e0: 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a    }.  }.}../*.**
30f0: 20 2a 70 7a 20 69 73 20 61 20 73 74 72 69 6e 67   *pz is a string
3100: 20 74 68 61 74 20 63 6f 6e 73 69 73 74 73 20 6f   that consists o
3110: 66 20 6d 75 6c 74 69 70 6c 65 20 6c 69 6e 65 73  f multiple lines
3120: 20 6f 66 20 74 65 78 74 2e 20 20 54 68 69 73 0a   of text.  This.
3130: 2a 2a 20 72 6f 75 74 69 6e 65 20 66 69 6e 64 73  ** routine finds
3140: 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20   the end of the 
3150: 63 75 72 72 65 6e 74 20 6c 69 6e 65 20 6f 66 20  current line of 
3160: 74 65 78 74 20 61 6e 64 20 63 6f 6e 76 65 72 74  text and convert
3170: 73 0a 2a 2a 20 74 68 65 20 22 5c 6e 22 20 6f 72  s.** the "\n" or
3180: 20 22 5c 72 5c 6e 22 20 74 68 61 74 20 65 6e 64   "\r\n" that end
3190: 73 20 74 68 61 74 20 6c 69 6e 65 20 69 6e 74 6f  s that line into
31a0: 20 61 20 22 5c 30 30 30 22 2e 20 20 49 74 20 74   a "\000".  It t
31b0: 68 65 6e 0a 2a 2a 20 61 64 76 61 6e 63 65 73 20  hen.** advances 
31c0: 2a 70 7a 20 74 6f 20 74 68 65 20 62 65 67 69 6e  *pz to the begin
31d0: 6e 69 6e 67 20 6f 66 20 74 68 65 20 6e 65 78 74  ning of the next
31e0: 20 6c 69 6e 65 20 61 6e 64 20 72 65 74 75 72 6e   line and return
31f0: 73 20 74 68 65 0a 2a 2a 20 70 72 65 76 69 6f 75  s the.** previou
3200: 73 20 76 61 6c 75 65 20 6f 66 20 2a 70 7a 20 28  s value of *pz (
3210: 77 68 69 63 68 20 69 73 20 74 68 65 20 73 74 61  which is the sta
3220: 72 74 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e  rt of the curren
3230: 74 20 6c 69 6e 65 2e 29 0a 2a 2f 0a 73 74 61 74  t line.).*/.stat
3240: 69 63 20 63 68 61 72 20 2a 67 65 74 5f 6c 69 6e  ic char *get_lin
3250: 65 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 63 68  e_from_string(ch
3260: 61 72 20 2a 2a 70 7a 2c 20 69 6e 74 20 2a 70 4c  ar **pz, int *pL
3270: 65 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a 20 3d  en){.  char *z =
3280: 20 2a 70 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 20   *pz;.  int i;. 
3290: 20 69 66 28 20 7a 5b 30 5d 3d 3d 30 20 29 20 72   if( z[0]==0 ) r
32a0: 65 74 75 72 6e 20 30 3b 0a 20 20 66 6f 72 28 69  eturn 0;.  for(i
32b0: 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a  =0; z[i]; i++){.
32c0: 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c      if( z[i]=='\
32d0: 6e 27 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  n' ){.      if( 
32e0: 69 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d 3d 27  i>0 && z[i-1]=='
32f0: 5c 72 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a  \r' ){.        z
3300: 5b 69 2d 31 5d 20 3d 20 30 3b 0a 20 20 20 20 20  [i-1] = 0;.     
3310: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20   }else{.        
3320: 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20  z[i] = 0;.      
3330: 7d 0a 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20  }.      i++;.   
3340: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a     break;.    }.
3350: 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a 5b 69    }.  *pz = &z[i
3360: 5d 3b 0a 20 20 2a 70 4c 65 6e 20 2d 3d 20 69 3b  ];.  *pLen -= i;
3370: 0a 20 20 72 65 74 75 72 6e 20 7a 3b 0a 7d 0a 0a  .  return z;.}..
3380: 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74 20  /*.** The input 
3390: 2a 70 7a 20 70 6f 69 6e 74 73 20 74 6f 20 63 6f  *pz points to co
33a0: 6e 74 65 6e 74 20 74 68 61 74 20 69 73 20 74 65  ntent that is te
33b0: 72 6d 69 6e 61 74 65 64 20 62 79 20 61 20 22 5c  rminated by a "\
33c0: 72 5c 6e 22 0a 2a 2a 20 66 6f 6c 6c 6f 77 65 64  r\n".** followed
33d0: 20 62 79 20 74 68 65 20 62 6f 75 6e 64 72 79 20   by the boundry 
33e0: 6d 61 72 6b 65 72 20 7a 42 6f 75 6e 64 72 79 2e  marker zBoundry.
33f0: 20 20 41 6e 20 65 78 74 72 61 20 22 2d 2d 22 20    An extra "--" 
3400: 6d 61 79 20 6f 72 0a 2a 2a 20 6d 61 79 20 6e 6f  may or.** may no
3410: 74 20 62 65 20 61 70 70 65 6e 64 65 64 20 74 6f  t be appended to
3420: 20 74 68 65 20 62 6f 75 6e 64 72 79 20 6d 61 72   the boundry mar
3430: 6b 65 72 2e 20 20 54 68 65 72 65 20 61 72 65 20  ker.  There are 
3440: 2a 70 4c 65 6e 20 63 68 61 72 61 63 74 65 72 73  *pLen characters
3450: 0a 2a 2a 20 69 6e 20 2a 70 7a 2e 0a 2a 2a 0a 2a  .** in *pz..**.*
3460: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61  * This routine a
3470: 64 64 73 20 61 20 22 5c 30 30 30 22 20 74 6f 20  dds a "\000" to 
3480: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 63  the end of the c
3490: 6f 6e 74 65 6e 74 20 28 6f 76 65 72 77 72 69 74  ontent (overwrit
34a0: 69 6e 67 0a 2a 2a 20 74 68 65 20 22 5c 72 5c 6e  ing.** the "\r\n
34b0: 22 29 20 61 6e 64 20 72 65 74 75 72 6e 73 20 61  ") and returns a
34c0: 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20   pointer to the 
34d0: 63 6f 6e 74 65 6e 74 2e 20 20 54 68 65 20 2a 70  content.  The *p
34e0: 7a 20 69 6e 70 75 74 0a 2a 2a 20 69 73 20 61 64  z input.** is ad
34f0: 6a 75 73 74 65 64 20 74 6f 20 70 6f 69 6e 74 20  justed to point 
3500: 74 6f 20 74 68 65 20 66 69 72 73 74 20 6c 69 6e  to the first lin
3510: 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20  e following the 
3520: 62 6f 75 6e 64 72 79 2e 0a 2a 2a 20 54 68 65 20  boundry..** The 
3530: 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 63 6f  length of the co
3540: 6e 74 65 6e 74 20 69 73 20 73 74 6f 72 65 64 20  ntent is stored 
3550: 69 6e 20 2a 70 6e 43 6f 6e 74 65 6e 74 2e 0a 2a  in *pnContent..*
3560: 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 67  /.static char *g
3570: 65 74 5f 62 6f 75 6e 64 65 64 5f 63 6f 6e 74 65  et_bounded_conte
3580: 6e 74 28 0a 20 20 63 68 61 72 20 2a 2a 70 7a 2c  nt(.  char **pz,
3590: 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74           /* Cont
35a0: 65 6e 74 20 74 61 6b 65 6e 20 66 72 6f 6d 20 68  ent taken from h
35b0: 65 72 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 4c  ere */.  int *pL
35c0: 65 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  en,         /* N
35d0: 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f  umber of bytes o
35e0: 66 20 64 61 74 61 20 69 6e 20 28 2a 70 7a 29 5b  f data in (*pz)[
35f0: 5d 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 42 6f  ] */.  char *zBo
3600: 75 6e 64 72 79 2c 20 20 20 20 2f 2a 20 42 6f 75  undry,    /* Bou
3610: 6e 64 72 79 20 74 65 78 74 20 6d 61 72 6b 69 6e  ndry text markin
3620: 67 20 74 68 65 20 65 6e 64 20 6f 66 20 63 6f 6e  g the end of con
3630: 74 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70  tent */.  int *p
3640: 6e 43 6f 6e 74 65 6e 74 20 20 20 20 20 2f 2a 20  nContent     /* 
3650: 57 72 69 74 65 20 74 68 65 20 73 69 7a 65 20 6f  Write the size o
3660: 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 68 65  f the content he
3670: 72 65 20 2a 2f 0a 29 7b 0a 20 20 63 68 61 72 20  re */.){.  char 
3680: 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e 74 20  *z = *pz;.  int 
3690: 6c 65 6e 20 3d 20 2a 70 4c 65 6e 3b 0a 20 20 69  len = *pLen;.  i
36a0: 6e 74 20 69 3b 0a 20 20 69 6e 74 20 6e 42 6f 75  nt i;.  int nBou
36b0: 6e 64 72 79 20 3d 20 73 74 72 6c 65 6e 28 7a 42  ndry = strlen(zB
36c0: 6f 75 6e 64 72 79 29 3b 0a 20 20 2a 70 6e 43 6f  oundry);.  *pnCo
36d0: 6e 74 65 6e 74 20 3d 20 6c 65 6e 3b 0a 20 20 66  ntent = len;.  f
36e0: 6f 72 28 69 3d 30 3b 20 69 3c 6c 65 6e 3b 20 69  or(i=0; i<len; i
36f0: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69  ++){.    if( z[i
3700: 5d 3d 3d 27 5c 6e 27 20 26 26 20 73 74 72 6e 63  ]=='\n' && strnc
3710: 6d 70 28 7a 42 6f 75 6e 64 72 79 2c 20 26 7a 5b  mp(zBoundry, &z[
3720: 69 2b 31 5d 2c 20 6e 42 6f 75 6e 64 72 79 29 3d  i+1], nBoundry)=
3730: 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20  =0 ){.      if( 
3740: 69 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d 3d 27  i>0 && z[i-1]=='
3750: 5c 72 27 20 29 20 69 2d 2d 3b 0a 20 20 20 20 20  \r' ) i--;.     
3760: 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20   z[i] = 0;.     
3770: 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d 20 69 3b   *pnContent = i;
3780: 0a 20 20 20 20 20 20 69 20 2b 3d 20 6e 42 6f 75  .      i += nBou
3790: 6e 64 72 79 3b 0a 20 20 20 20 20 20 62 72 65 61  ndry;.      brea
37a0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  k;.    }.  }.  *
37b0: 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 67 65  pz = &z[i];.  ge
37c0: 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69  t_line_from_stri
37d0: 6e 67 28 70 7a 2c 20 70 4c 65 6e 29 3b 0a 20 20  ng(pz, pLen);.  
37e0: 72 65 74 75 72 6e 20 7a 3b 20 20 20 20 20 20 0a  return z;      .
37f0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 69 7a  }../*.** Tokeniz
3800: 65 20 61 20 6c 69 6e 65 20 6f 66 20 74 65 78 74  e a line of text
3810: 20 69 6e 74 6f 20 61 73 20 6d 61 6e 79 20 61 73   into as many as
3820: 20 6e 41 72 67 20 74 6f 6b 65 6e 73 2e 20 20 4d   nArg tokens.  M
3830: 61 6b 65 0a 2a 2a 20 61 7a 41 72 67 5b 5d 20 70  ake.** azArg[] p
3840: 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72  oint to the star
3850: 74 20 6f 66 20 65 61 63 68 20 74 6f 6b 65 6e 2e  t of each token.
3860: 0a 2a 2a 0a 2a 2a 20 54 6f 6b 65 6e 73 20 63 6f  .**.** Tokens co
3870: 6e 73 69 73 74 20 6f 66 20 73 70 61 63 65 20 6f  nsist of space o
3880: 72 20 73 65 6d 69 2d 63 6f 6c 6f 6e 20 64 65 6c  r semi-colon del
3890: 69 6d 69 74 65 64 20 77 6f 72 64 73 20 6f 72 0a  imited words or.
38a0: 2a 2a 20 73 74 72 69 6e 67 73 20 69 6e 73 69 64  ** strings insid
38b0: 65 20 64 6f 75 62 6c 65 2d 71 75 6f 74 65 73 2e  e double-quotes.
38c0: 20 20 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a    Example:.**.**
38d0: 20 20 20 20 63 6f 6e 74 65 6e 74 2d 64 69 73 70      content-disp
38e0: 6f 73 69 74 69 6f 6e 3a 20 66 6f 72 6d 2d 64 61  osition: form-da
38f0: 74 61 3b 20 6e 61 6d 65 3d 22 66 6e 22 3b 20 66  ta; name="fn"; f
3900: 69 6c 65 6e 61 6d 65 3d 22 69 6e 64 65 78 2e 68  ilename="index.h
3910: 74 6d 6c 22 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c  tml".**.** The l
3920: 69 6e 65 20 61 62 6f 76 65 20 69 73 20 74 6f 6b  ine above is tok
3930: 65 6e 69 7a 65 64 20 61 73 20 66 6f 6c 6c 6f 77  enized as follow
3940: 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 61 7a 41 72  s:.**.**    azAr
3950: 67 5b 30 5d 20 3d 20 22 63 6f 6e 74 65 6e 74 2d  g[0] = "content-
3960: 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22 0a 2a 2a  disposition:".**
3970: 20 20 20 20 61 7a 41 72 67 5b 31 5d 20 3d 20 22      azArg[1] = "
3980: 66 6f 72 6d 2d 64 61 74 61 22 0a 2a 2a 20 20 20  form-data".**   
3990: 20 61 7a 41 72 67 5b 32 5d 20 3d 20 22 6e 61 6d   azArg[2] = "nam
39a0: 65 3d 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b  e=".**    azArg[
39b0: 33 5d 20 3d 20 22 66 6e 22 0a 2a 2a 20 20 20 20  3] = "fn".**    
39c0: 61 7a 41 72 67 5b 34 5d 20 3d 20 22 66 69 6c 65  azArg[4] = "file
39d0: 6e 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61 7a 41  name=".**    azA
39e0: 72 67 5b 35 5d 20 3d 20 22 69 6e 64 65 78 2e 68  rg[5] = "index.h
39f0: 74 6d 6c 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67  tml".**    azArg
3a00: 5b 36 5d 20 3d 20 30 3b 0a 2a 2a 0a 2a 2a 20 27  [6] = 0;.**.** '
3a10: 5c 30 30 30 27 20 63 68 61 72 61 63 74 65 72 73  \000' characters
3a20: 20 61 72 65 20 69 6e 73 65 72 74 65 64 20 69 6e   are inserted in
3a30: 20 7a 5b 5d 20 61 74 20 74 68 65 20 65 6e 64 20   z[] at the end 
3a40: 6f 66 20 65 61 63 68 20 74 6f 6b 65 6e 2e 0a 2a  of each token..*
3a50: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 72  * This routine r
3a60: 65 74 75 72 6e 73 20 74 68 65 20 74 6f 74 61 6c  eturns the total
3a70: 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e   number of token
3a80: 73 20 6f 6e 20 74 68 65 20 6c 69 6e 65 2c 20 36  s on the line, 6
3a90: 0a 2a 2a 20 69 6e 20 74 68 65 20 65 78 61 6d 70  .** in the examp
3aa0: 6c 65 20 61 62 6f 76 65 2e 0a 2a 2f 0a 73 74 61  le above..*/.sta
3ab0: 74 69 63 20 69 6e 74 20 74 6f 6b 65 6e 69 7a 65  tic int tokenize
3ac0: 5f 6c 69 6e 65 28 63 68 61 72 20 2a 7a 2c 20 69  _line(char *z, i
3ad0: 6e 74 20 6d 78 41 72 67 2c 20 63 68 61 72 20 2a  nt mxArg, char *
3ae0: 2a 61 7a 41 72 67 29 7b 0a 20 20 69 6e 74 20 69  *azArg){.  int i
3af0: 20 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 2a   = 0;.  while( *
3b00: 7a 20 29 7b 0a 20 20 20 20 77 68 69 6c 65 28 20  z ){.    while( 
3b10: 69 73 73 70 61 63 65 28 2a 7a 29 20 7c 7c 20 2a  isspace(*z) || *
3b20: 7a 3d 3d 27 3b 27 20 29 7b 20 7a 2b 2b 3b 20 7d  z==';' ){ z++; }
3b30: 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27 22 27  .    if( *z=='"'
3b40: 20 26 26 20 7a 5b 31 5d 20 29 7b 0a 20 20 20 20   && z[1] ){.    
3b50: 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20    *z = 0;.      
3b60: 7a 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28 20 69  z++;.      if( i
3b70: 3c 6d 78 41 72 67 2d 31 20 29 7b 20 61 7a 41 72  <mxArg-1 ){ azAr
3b80: 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a 20 20  g[i++] = z; }.  
3b90: 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26      while( *z &&
3ba0: 20 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b   *z!='"' ){ z++;
3bb0: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 3d   }.      if( *z=
3bc0: 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20  =0 ) break;.    
3bd0: 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20    *z = 0;.      
3be0: 7a 2b 2b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  z++;.    }else{.
3bf0: 20 20 20 20 20 20 69 66 28 20 69 3c 6d 78 41 72        if( i<mxAr
3c00: 67 2d 31 20 29 7b 20 61 7a 41 72 67 5b 69 2b 2b  g-1 ){ azArg[i++
3c10: 5d 20 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 20 77  ] = z; }.      w
3c20: 68 69 6c 65 28 20 2a 7a 20 26 26 20 21 69 73 73  hile( *z && !iss
3c30: 70 61 63 65 28 2a 7a 29 20 26 26 20 2a 7a 21 3d  pace(*z) && *z!=
3c40: 27 3b 27 20 26 26 20 2a 7a 21 3d 27 22 27 20 29  ';' && *z!='"' )
3c50: 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69  { z++; }.      i
3c60: 66 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 22 27  f( *z && *z!='"'
3c70: 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a 20 3d   ){.        *z =
3c80: 20 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b 2b 3b   0;.        z++;
3c90: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20  .      }.    }. 
3ca0: 20 7d 0a 20 20 61 7a 41 72 67 5b 69 5d 20 3d 20   }.  azArg[i] = 
3cb0: 30 3b 0a 20 20 72 65 74 75 72 6e 20 69 3b 0a 7d  0;.  return i;.}
3cc0: 0a 0a 2f 2a 0a 2a 2a 20 53 63 61 6e 20 74 68 65  ../*.** Scan the
3cd0: 20 6d 75 6c 74 69 70 61 72 74 2d 66 6f 72 6d 20   multipart-form 
3ce0: 63 6f 6e 74 65 6e 74 20 61 6e 64 20 6d 61 6b 65  content and make
3cf0: 20 61 70 70 72 6f 70 72 69 61 74 65 20 65 6e 74   appropriate ent
3d00: 72 69 65 73 0a 2a 2a 20 69 6e 74 6f 20 74 68 65  ries.** into the
3d10: 20 70 61 72 61 6d 65 74 65 72 20 74 61 62 6c 65   parameter table
3d20: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6e 74  ..**.** The cont
3d30: 65 6e 74 20 73 74 72 69 6e 67 20 22 7a 22 20 69  ent string "z" i
3d40: 73 20 6d 6f 64 69 66 69 65 64 20 62 79 20 74 68  s modified by th
3d50: 69 73 20 72 6f 75 74 69 6e 65 20 62 75 74 20 69  is routine but i
3d60: 74 20 69 73 0a 2a 2a 20 6e 6f 74 20 63 6f 70 69  t is.** not copi
3d70: 65 64 2e 20 20 54 68 65 20 63 61 6c 6c 69 6e 67  ed.  The calling
3d80: 20 66 75 6e 63 74 69 6f 6e 20 6d 75 73 74 20 6e   function must n
3d90: 6f 74 20 64 65 61 6c 6c 6f 63 61 74 65 20 6f 72  ot deallocate or
3da0: 20 6d 6f 64 69 66 79 0a 2a 2a 20 22 7a 22 20 61   modify.** "z" a
3db0: 66 74 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e  fter this routin
3dc0: 65 20 66 69 6e 69 73 68 65 73 20 6f 72 20 69 74  e finishes or it
3dd0: 20 63 6f 75 6c 64 20 63 6f 72 72 75 70 74 20 74   could corrupt t
3de0: 68 65 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20  he parameter.** 
3df0: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  table..*/.static
3e00: 20 76 6f 69 64 20 70 72 6f 63 65 73 73 5f 6d 75   void process_mu
3e10: 6c 74 69 70 61 72 74 5f 66 6f 72 6d 5f 64 61 74  ltipart_form_dat
3e20: 61 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6c  a(char *z, int l
3e30: 65 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a 4c 69  en){.  char *zLi
3e40: 6e 65 3b 0a 20 20 69 6e 74 20 6e 41 72 67 2c 20  ne;.  int nArg, 
3e50: 69 3b 0a 20 20 63 68 61 72 20 2a 7a 42 6f 75 6e  i;.  char *zBoun
3e60: 64 72 79 3b 0a 20 20 63 68 61 72 20 2a 7a 56 61  dry;.  char *zVa
3e70: 6c 75 65 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61  lue;.  char *zNa
3e80: 6d 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 73 68  me = 0;.  int sh
3e90: 6f 77 42 79 74 65 73 20 3d 20 30 3b 0a 20 20 63  owBytes = 0;.  c
3ea0: 68 61 72 20 2a 61 7a 41 72 67 5b 35 30 5d 3b 0a  har *azArg[50];.
3eb0: 0a 20 20 7a 42 6f 75 6e 64 72 79 20 3d 20 67 65  .  zBoundry = ge
3ec0: 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69  t_line_from_stri
3ed0: 6e 67 28 26 7a 2c 20 26 6c 65 6e 29 3b 0a 20 20  ng(&z, &len);.  
3ee0: 69 66 28 20 7a 42 6f 75 6e 64 72 79 3d 3d 30 20  if( zBoundry==0 
3ef0: 29 20 72 65 74 75 72 6e 3b 0a 20 20 77 68 69 6c  ) return;.  whil
3f00: 65 28 20 28 7a 4c 69 6e 65 20 3d 20 67 65 74 5f  e( (zLine = get_
3f10: 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e 67  line_from_string
3f20: 28 26 7a 2c 20 26 6c 65 6e 29 29 21 3d 30 20 29  (&z, &len))!=0 )
3f30: 7b 0a 20 20 20 20 69 66 28 20 7a 4c 69 6e 65 5b  {.    if( zLine[
3f40: 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 69  0]==0 ){.      i
3f50: 6e 74 20 6e 43 6f 6e 74 65 6e 74 20 3d 20 30 3b  nt nContent = 0;
3f60: 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20  .      zValue = 
3f70: 67 65 74 5f 62 6f 75 6e 64 65 64 5f 63 6f 6e 74  get_bounded_cont
3f80: 65 6e 74 28 26 7a 2c 20 26 6c 65 6e 2c 20 7a 42  ent(&z, &len, zB
3f90: 6f 75 6e 64 72 79 2c 20 26 6e 43 6f 6e 74 65 6e  oundry, &nConten
3fa0: 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 4e  t);.      if( zN
3fb0: 61 6d 65 20 26 26 20 7a 56 61 6c 75 65 20 26 26  ame && zValue &&
3fc0: 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30   islower(zName[0
3fd0: 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 63 67  ]) ){.        cg
3fe0: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f  i_set_parameter_
3ff0: 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56  nocopy(zName, zV
4000: 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 20 20 69  alue);.        i
4010: 66 28 20 73 68 6f 77 42 79 74 65 73 20 29 7b 0a  f( showBytes ){.
4020: 20 20 20 20 20 20 20 20 20 20 63 67 69 5f 73 65            cgi_se
4030: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f  t_parameter_noco
4040: 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 3a 62  py(mprintf("%s:b
4050: 79 74 65 73 22 2c 20 7a 4e 61 6d 65 29 2c 0a 20  ytes", zName),. 
4060: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6d 70                mp
4070: 72 69 6e 74 66 28 22 25 64 22 2c 6e 43 6f 6e 74  rintf("%d",nCont
4080: 65 6e 74 29 29 3b 0a 20 20 20 20 20 20 20 20 7d  ent));.        }
4090: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a  .      }.      z
40a0: 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 20 20  Name = 0;.      
40b0: 73 68 6f 77 42 79 74 65 73 20 3d 20 30 3b 0a 20  showBytes = 0;. 
40c0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
40d0: 6e 41 72 67 20 3d 20 74 6f 6b 65 6e 69 7a 65 5f  nArg = tokenize_
40e0: 6c 69 6e 65 28 7a 4c 69 6e 65 2c 20 73 69 7a 65  line(zLine, size
40f0: 6f 66 28 61 7a 41 72 67 29 2f 73 69 7a 65 6f 66  of(azArg)/sizeof
4100: 28 61 7a 41 72 67 5b 30 5d 29 2c 20 61 7a 41 72  (azArg[0]), azAr
4110: 67 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d  g);.      for(i=
4120: 30 3b 20 69 3c 6e 41 72 67 3b 20 69 2b 2b 29 7b  0; i<nArg; i++){
4130: 0a 20 20 20 20 20 20 20 20 69 6e 74 20 63 20 3d  .        int c =
4140: 20 74 6f 6c 6f 77 65 72 28 61 7a 41 72 67 5b 69   tolower(azArg[i
4150: 5d 5b 30 5d 29 3b 0a 20 20 20 20 20 20 20 20 69  ][0]);.        i
4160: 66 28 20 63 3d 3d 27 63 27 20 26 26 20 73 74 72  f( c=='c' && str
4170: 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 63  icmp(azArg[i],"c
4180: 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69  ontent-dispositi
4190: 6f 6e 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20  on:")==0 ){.    
41a0: 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20        i++;.     
41b0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d     }else if( c==
41c0: 27 6e 27 20 26 26 20 73 74 72 69 63 6d 70 28 61  'n' && stricmp(a
41d0: 7a 41 72 67 5b 69 5d 2c 22 6e 61 6d 65 3d 22 29  zArg[i],"name=")
41e0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20  ==0 ){.         
41f0: 20 7a 4e 61 6d 65 20 3d 20 61 7a 41 72 67 5b 2b   zName = azArg[+
4200: 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  +i];.        }el
4210: 73 65 20 69 66 28 20 63 3d 3d 27 66 27 20 26 26  se if( c=='f' &&
4220: 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69   stricmp(azArg[i
4230: 5d 2c 22 66 69 6c 65 6e 61 6d 65 3d 22 29 3d 3d  ],"filename=")==
4240: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63  0 ){.          c
4250: 68 61 72 20 2a 7a 20 3d 20 61 7a 41 72 67 5b 2b  har *z = azArg[+
4260: 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 69  +i];.          i
4270: 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a 20 26 26  f( zName && z &&
4280: 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30   islower(zName[0
4290: 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  ]) ){.          
42a0: 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65    cgi_set_parame
42b0: 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e  ter_nocopy(mprin
42c0: 74 66 28 22 25 73 3a 66 69 6c 65 6e 61 6d 65 22  tf("%s:filename"
42d0: 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a 20 20 20  ,zName), z);.   
42e0: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20         }.       
42f0: 20 20 20 73 68 6f 77 42 79 74 65 73 20 3d 20 31     showBytes = 1
4300: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20  ;.        }else 
4310: 69 66 28 20 63 3d 3d 27 63 27 20 26 26 20 73 74  if( c=='c' && st
4320: 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22  ricmp(azArg[i],"
4330: 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 22 29 3d  content-type:")=
4340: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
4350: 63 68 61 72 20 2a 7a 20 3d 20 61 7a 41 72 67 5b  char *z = azArg[
4360: 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 20 20  ++i];.          
4370: 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a 20 26  if( zName && z &
4380: 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b  & islower(zName[
4390: 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20  0]) ){.         
43a0: 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d     cgi_set_param
43b0: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69  eter_nocopy(mpri
43c0: 6e 74 66 28 22 25 73 3a 6d 69 6d 65 74 79 70 65  ntf("%s:mimetype
43d0: 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a 20 20  ",zName), z);.  
43e0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
43f0: 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20    }.      }.    
4400: 7d 0a 20 20 7d 20 20 20 20 20 20 20 20 0a 7d 0a  }.  }        .}.
4410: 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a  ./*.** Initializ
4420: 65 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  e the query para
4430: 6d 65 74 65 72 20 64 61 74 61 62 61 73 65 2e 20  meter database. 
4440: 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 73 20   Information is 
4450: 70 75 6c 6c 65 64 20 66 72 6f 6d 0a 2a 2a 20 74  pulled from.** t
4460: 68 65 20 51 55 45 52 59 5f 53 54 52 49 4e 47 20  he QUERY_STRING 
4470: 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69  environment vari
4480: 61 62 6c 65 20 28 69 66 20 69 74 20 65 78 69 73  able (if it exis
4490: 74 73 29 2c 20 66 72 6f 6d 20 73 74 61 6e 64 61  ts), from standa
44a0: 72 64 0a 2a 2a 20 69 6e 70 75 74 20 69 66 20 74  rd.** input if t
44b0: 68 65 72 65 20 69 73 20 50 4f 53 54 20 64 61 74  here is POST dat
44c0: 61 2c 20 61 6e 64 20 66 72 6f 6d 20 48 54 54 50  a, and from HTTP
44d0: 5f 43 4f 4f 4b 49 45 2e 0a 2a 2f 0a 76 6f 69 64  _COOKIE..*/.void
44e0: 20 63 67 69 5f 69 6e 69 74 28 76 6f 69 64 29 7b   cgi_init(void){
44f0: 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 63 6f  .  char *z;.  co
4500: 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 70 65 3b  nst char *zType;
4510: 0a 20 20 69 6e 74 20 6c 65 6e 3b 0a 20 20 7a 20  .  int len;.  z 
4520: 3d 20 28 63 68 61 72 2a 29 50 28 22 51 55 45 52  = (char*)P("QUER
4530: 59 5f 53 54 52 49 4e 47 22 29 3b 0a 20 20 69 66  Y_STRING");.  if
4540: 28 20 7a 20 29 7b 0a 20 20 20 20 7a 20 3d 20 6d  ( z ){.    z = m
4550: 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 29 3b 0a  printf("%s",z);.
4560: 20 20 20 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69      add_param_li
4570: 73 74 28 7a 2c 20 27 26 27 29 3b 0a 20 20 7d 0a  st(z, '&');.  }.
4580: 0a 20 20 6c 65 6e 20 3d 20 61 74 6f 69 28 50 44  .  len = atoi(PD
4590: 28 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54 48  ("CONTENT_LENGTH
45a0: 22 2c 20 22 30 22 29 29 3b 0a 20 20 67 2e 7a 43  ", "0"));.  g.zC
45b0: 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 7a 54 79  ontentType = zTy
45c0: 70 65 20 3d 20 50 28 22 43 4f 4e 54 45 4e 54 5f  pe = P("CONTENT_
45d0: 54 59 50 45 22 29 3b 0a 20 20 69 66 28 20 6c 65  TYPE");.  if( le
45e0: 6e 3e 30 20 26 26 20 7a 54 79 70 65 20 29 7b 0a  n>0 && zType ){.
45f0: 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 67      blob_zero(&g
4600: 2e 63 67 69 49 6e 29 3b 0a 20 20 20 20 69 66 28  .cgiIn);.    if(
4610: 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 22 61   strcmp(zType,"a
4620: 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77  pplication/x-www
4630: 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64  -form-urlencoded
4640: 22 29 3d 3d 30 20 0a 20 20 20 20 20 20 20 20 20  ")==0 .         
4650: 7c 7c 20 73 74 72 6e 63 6d 70 28 7a 54 79 70 65  || strncmp(zType
4660: 2c 22 6d 75 6c 74 69 70 61 72 74 2f 66 6f 72 6d  ,"multipart/form
4670: 2d 64 61 74 61 22 2c 31 39 29 3d 3d 30 20 29 7b  -data",19)==0 ){
4680: 0a 20 20 20 20 20 20 7a 20 3d 20 6d 61 6c 6c 6f  .      z = mallo
4690: 63 28 20 6c 65 6e 2b 31 20 29 3b 0a 20 20 20 20  c( len+1 );.    
46a0: 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 65 78 69    if( z==0 ) exi
46b0: 74 28 31 29 3b 0a 20 20 20 20 20 20 6c 65 6e 20  t(1);.      len 
46c0: 3d 20 66 72 65 61 64 28 7a 2c 20 31 2c 20 6c 65  = fread(z, 1, le
46d0: 6e 2c 20 73 74 64 69 6e 29 3b 0a 20 20 20 20 20  n, stdin);.     
46e0: 20 7a 5b 6c 65 6e 5d 20 3d 20 30 3b 0a 20 20 20   z[len] = 0;.   
46f0: 20 20 20 69 66 28 20 7a 54 79 70 65 5b 30 5d 3d     if( zType[0]=
4700: 3d 27 61 27 20 29 7b 0a 20 20 20 20 20 20 20 20  ='a' ){.        
4710: 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a  add_param_list(z
4720: 2c 20 27 26 27 29 3b 0a 20 20 20 20 20 20 7d 65  , '&');.      }e
4730: 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 70 72 6f  lse{.        pro
4740: 63 65 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66  cess_multipart_f
4750: 6f 72 6d 5f 64 61 74 61 28 7a 2c 20 6c 65 6e 29  orm_data(z, len)
4760: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65  ;.      }.    }e
4770: 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a  lse if( strcmp(z
4780: 54 79 70 65 2c 20 22 61 70 70 6c 69 63 61 74 69  Type, "applicati
4790: 6f 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30  on/x-fossil")==0
47a0: 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72   ){.      blob_r
47b0: 65 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c  ead_from_channel
47c0: 28 26 67 2e 63 67 69 49 6e 2c 20 73 74 64 69 6e  (&g.cgiIn, stdin
47d0: 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 62 6c  , len);.      bl
47e0: 6f 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26 67  ob_uncompress(&g
47f0: 2e 63 67 69 49 6e 2c 20 26 67 2e 63 67 69 49 6e  .cgiIn, &g.cgiIn
4800: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
4810: 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20 22   strcmp(zType, "
4820: 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f  application/x-fo
4830: 73 73 69 6c 2d 64 65 62 75 67 22 29 3d 3d 30 20  ssil-debug")==0 
4840: 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65  ){.      blob_re
4850: 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28  ad_from_channel(
4860: 26 67 2e 63 67 69 49 6e 2c 20 73 74 64 69 6e 2c  &g.cgiIn, stdin,
4870: 20 6c 65 6e 29 3b 0a 20 20 20 20 7d 0a 20 20 7d   len);.    }.  }
4880: 0a 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 50  ..  z = (char*)P
4890: 28 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 29 3b  ("HTTP_COOKIE");
48a0: 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 20 20  .  if( z ){.    
48b0: 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22  z = mprintf("%s"
48c0: 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 61 72  ,z);.    add_par
48d0: 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 3b 27 29 3b  am_list(z, ';');
48e0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  .  }.}../*.** Th
48f0: 69 73 20 69 73 20 74 68 65 20 63 6f 6d 70 61 72  is is the compar
4900: 69 73 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 75 73  ison function us
4910: 65 64 20 74 6f 20 73 6f 72 74 20 74 68 65 20 61  ed to sort the a
4920: 50 61 72 61 6d 51 50 5b 5d 20 61 72 72 61 79 20  ParamQP[] array 
4930: 6f 66 0a 2a 2a 20 71 75 65 72 79 20 70 61 72 61  of.** query para
4940: 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69  meters and cooki
4950: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
4960: 74 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72 65  t qparam_compare
4970: 28 63 6f 6e 73 74 20 76 6f 69 64 20 2a 61 2c 20  (const void *a, 
4980: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 62 29 7b 0a  const void *b){.
4990: 20 20 73 74 72 75 63 74 20 51 50 61 72 61 6d 20    struct QParam 
49a0: 2a 70 41 20 3d 20 28 73 74 72 75 63 74 20 51 50  *pA = (struct QP
49b0: 61 72 61 6d 2a 29 61 3b 0a 20 20 73 74 72 75 63  aram*)a;.  struc
49c0: 74 20 51 50 61 72 61 6d 20 2a 70 42 20 3d 20 28  t QParam *pB = (
49d0: 73 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29 62  struct QParam*)b
49e0: 3b 0a 20 20 69 6e 74 20 63 3b 0a 20 20 63 20 3d  ;.  int c;.  c =
49f0: 20 73 74 72 63 6d 70 28 70 41 2d 3e 7a 4e 61 6d   strcmp(pA->zNam
4a00: 65 2c 20 70 42 2d 3e 7a 4e 61 6d 65 29 3b 0a 20  e, pB->zName);. 
4a10: 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20   if( c==0 ){.   
4a20: 20 63 20 3d 20 70 41 2d 3e 73 65 71 20 2d 20 70   c = pA->seq - p
4a30: 42 2d 3e 73 65 71 3b 0a 20 20 7d 0a 20 20 72 65  B->seq;.  }.  re
4a40: 74 75 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn c;.}../*.**
4a50: 20 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75   Return the valu
4a60: 65 20 6f 66 20 61 20 71 75 65 72 79 20 70 61 72  e of a query par
4a70: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65  ameter or cookie
4a80: 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 73 20 7a   whose name is z
4a90: 4e 61 6d 65 2e 0a 2a 2a 20 49 66 20 74 68 65 72  Name..** If ther
4aa0: 65 20 69 73 20 6e 6f 20 71 75 65 72 79 20 70 61  e is no query pa
4ab0: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69  rameter or cooki
4ac0: 65 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 61 6e  e named zName an
4ad0: 64 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20 63  d the first.** c
4ae0: 68 61 72 61 63 74 65 72 20 6f 66 20 7a 4e 61 6d  haracter of zNam
4af0: 65 20 69 73 20 75 70 70 65 72 63 61 73 65 2c 20  e is uppercase, 
4b00: 74 68 65 6e 20 63 68 65 63 6b 20 74 6f 20 73 65  then check to se
4b10: 65 20 69 66 20 74 68 65 72 65 20 69 73 20 61 6e  e if there is an
4b20: 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20  .** environment 
4b30: 76 61 72 69 61 62 6c 65 20 62 79 20 74 68 61 74  variable by that
4b40: 20 6e 61 6d 65 20 61 6e 64 20 72 65 74 75 72 6e   name and return
4b50: 20 69 74 20 69 66 20 74 68 65 72 65 20 69 73 2e   it if there is.
4b60: 20 20 41 73 0a 2a 2a 20 61 20 6c 61 73 74 20 72    As.** a last r
4b70: 65 73 6f 72 74 20 77 68 65 6e 20 6e 6f 74 68 69  esort when nothi
4b80: 6e 67 20 65 6c 73 65 20 6d 61 74 63 68 65 73 2c  ng else matches,
4b90: 20 72 65 74 75 72 6e 20 7a 44 65 66 61 75 6c 74   return zDefault
4ba0: 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20  ..*/.const char 
4bb0: 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 63  *cgi_parameter(c
4bc0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
4bd0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44  , const char *zD
4be0: 65 66 61 75 6c 74 29 7b 0a 20 20 69 6e 74 20 6c  efault){.  int l
4bf0: 6f 2c 20 68 69 2c 20 6d 69 64 2c 20 63 3b 0a 0a  o, hi, mid, c;..
4c00: 20 20 2f 2a 20 54 68 65 20 73 6f 72 74 51 50 20    /* The sortQP 
4c10: 66 6c 61 67 20 69 73 20 73 65 74 20 77 68 65 6e  flag is set when
4c20: 65 76 65 72 20 61 20 6e 65 77 20 71 75 65 72 79  ever a new query
4c30: 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 69 6e   parameter is in
4c40: 73 65 72 74 65 64 2e 0a 20 20 2a 2a 20 49 74 20  serted..  ** It 
4c50: 69 6e 64 69 63 61 74 65 73 20 74 68 61 74 20 77  indicates that w
4c60: 65 20 6e 65 65 64 20 74 6f 20 72 65 73 6f 72 74  e need to resort
4c70: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   the query param
4c80: 65 74 65 72 73 2e 0a 20 20 2a 2f 0a 20 20 69 66  eters..  */.  if
4c90: 28 20 73 6f 72 74 51 50 20 29 7b 0a 20 20 20 20  ( sortQP ){.    
4ca0: 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 20 20 71 73  int i, j;.    qs
4cb0: 6f 72 74 28 61 50 61 72 61 6d 51 50 2c 20 6e 55  ort(aParamQP, nU
4cc0: 73 65 64 51 50 2c 20 73 69 7a 65 6f 66 28 61 50  sedQP, sizeof(aP
4cd0: 61 72 61 6d 51 50 5b 30 5d 29 2c 20 71 70 61 72  aramQP[0]), qpar
4ce0: 61 6d 5f 63 6f 6d 70 61 72 65 29 3b 0a 20 20 20  am_compare);.   
4cf0: 20 73 6f 72 74 51 50 20 3d 20 30 3b 0a 20 20 20   sortQP = 0;.   
4d00: 20 2f 2a 20 41 66 74 65 72 20 73 6f 72 74 69 6e   /* After sortin
4d10: 67 2c 20 72 65 6d 6f 76 65 20 64 75 70 6c 69 63  g, remove duplic
4d20: 61 74 65 20 70 61 72 61 6d 65 74 65 72 73 2e 20  ate parameters. 
4d30: 20 54 68 65 20 73 65 63 6f 6e 64 61 72 79 20 73   The secondary s
4d40: 6f 72 74 0a 20 20 20 20 2a 2a 20 6b 65 79 20 69  ort.    ** key i
4d50: 73 20 61 50 61 72 61 6d 51 50 5b 5d 2e 73 65 71  s aParamQP[].seq
4d60: 20 61 6e 64 20 77 65 20 6b 65 65 70 20 74 68 65   and we keep the
4d70: 20 66 69 72 73 74 20 65 6e 74 72 79 2e 20 20 54   first entry.  T
4d80: 68 61 74 20 6d 65 61 6e 73 0a 20 20 20 20 2a 2a  hat means.    **
4d90: 20 77 69 74 68 20 64 75 70 6c 69 63 61 74 65 20   with duplicate 
4da0: 63 61 6c 6c 73 20 74 6f 20 63 67 69 5f 73 65 74  calls to cgi_set
4db0: 5f 70 61 72 61 6d 65 74 65 72 28 29 20 74 68 65  _parameter() the
4dc0: 20 73 65 63 6f 6e 64 20 61 6e 64 0a 20 20 20 20   second and.    
4dd0: 2a 2a 20 73 75 62 73 65 71 75 65 6e 74 20 63 61  ** subsequent ca
4de0: 6c 6c 73 20 61 72 65 20 65 66 66 65 63 74 69 76  lls are effectiv
4df0: 65 6c 79 20 6e 6f 2d 6f 70 73 2e 20 2a 2f 0a 20  ely no-ops. */. 
4e00: 20 20 20 66 6f 72 28 69 3d 6a 3d 31 3b 20 69 3c     for(i=j=1; i<
4e10: 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20  nUsedQP; i++){. 
4e20: 20 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28       if( strcmp(
4e30: 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d  aParamQP[i].zNam
4e40: 65 2c 61 50 61 72 61 6d 51 50 5b 69 2d 31 5d 2e  e,aParamQP[i-1].
4e50: 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20  zName)==0 ){.   
4e60: 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20       continue;. 
4e70: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
4e80: 20 6a 3c 69 20 29 7b 0a 20 20 20 20 20 20 20 20   j<i ){.        
4e90: 6d 65 6d 63 70 79 28 26 61 50 61 72 61 6d 51 50  memcpy(&aParamQP
4ea0: 5b 6a 5d 2c 20 26 61 50 61 72 61 6d 51 50 5b 69  [j], &aParamQP[i
4eb0: 5d 2c 20 73 69 7a 65 6f 66 28 61 50 61 72 61 6d  ], sizeof(aParam
4ec0: 51 50 5b 6a 5d 29 29 3b 0a 20 20 20 20 20 20 7d  QP[j]));.      }
4ed0: 0a 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 20 20 20  .      j++;.    
4ee0: 7d 0a 20 20 20 20 6e 55 73 65 64 51 50 20 3d 20  }.    nUsedQP = 
4ef0: 6a 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 6f 20  j;.  }..  /* Do 
4f00: 61 20 62 69 6e 61 72 79 20 73 65 61 72 63 68 20  a binary search 
4f10: 66 6f 72 20 61 20 6d 61 74 63 68 69 6e 67 20 71  for a matching q
4f20: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 2a  uery parameter *
4f30: 2f 0a 20 20 6c 6f 20 3d 20 30 3b 0a 20 20 68 69  /.  lo = 0;.  hi
4f40: 20 3d 20 6e 55 73 65 64 51 50 2d 31 3b 0a 20 20   = nUsedQP-1;.  
4f50: 77 68 69 6c 65 28 20 6c 6f 3c 3d 68 69 20 29 7b  while( lo<=hi ){
4f60: 0a 20 20 20 20 6d 69 64 20 3d 20 28 6c 6f 2b 68  .    mid = (lo+h
4f70: 69 29 2f 32 3b 0a 20 20 20 20 63 20 3d 20 73 74  i)/2;.    c = st
4f80: 72 63 6d 70 28 61 50 61 72 61 6d 51 50 5b 6d 69  rcmp(aParamQP[mi
4f90: 64 5d 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 29  d].zName, zName)
4fa0: 3b 0a 20 20 20 20 69 66 28 20 63 3d 3d 30 20 29  ;.    if( c==0 )
4fb0: 7b 0a 20 20 20 20 20 20 43 47 49 44 45 42 55 47  {.      CGIDEBUG
4fc0: 28 28 22 6d 65 6d 2d 6d 61 74 63 68 20 5b 25 73  (("mem-match [%s
4fd0: 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61  ] = [%s]\n", zNa
4fe0: 6d 65 2c 20 61 50 61 72 61 6d 51 50 5b 6d 69 64  me, aParamQP[mid
4ff0: 5d 2e 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20  ].zValue));.    
5000: 20 20 72 65 74 75 72 6e 20 61 50 61 72 61 6d 51    return aParamQ
5010: 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 3b 0a 20  P[mid].zValue;. 
5020: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3e 30     }else if( c>0
5030: 20 29 7b 0a 20 20 20 20 20 20 68 69 20 3d 20 6d   ){.      hi = m
5040: 69 64 2d 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  id-1;.    }else{
5050: 0a 20 20 20 20 20 20 6c 6f 20 3d 20 6d 69 64 2b  .      lo = mid+
5060: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  1;.    }.  }..  
5070: 2f 2a 20 49 66 20 6e 6f 20 6d 61 74 63 68 20 69  /* If no match i
5080: 73 20 66 6f 75 6e 64 20 61 6e 64 20 74 68 65 20  s found and the 
5090: 6e 61 6d 65 20 62 65 67 69 6e 73 20 77 69 74 68  name begins with
50a0: 20 61 6e 20 75 70 70 65 72 2d 63 61 73 65 0a 20   an upper-case. 
50b0: 20 2a 2a 20 6c 65 74 74 65 72 2c 20 74 68 65 6e   ** letter, then
50c0: 20 63 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66   check to see if
50d0: 20 74 68 65 72 65 20 69 73 20 61 6e 20 65 6e 76   there is an env
50e0: 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c  ironment variabl
50f0: 65 0a 20 20 2a 2a 20 77 69 74 68 20 74 68 65 20  e.  ** with the 
5100: 67 69 76 65 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f  given name..  */
5110: 0a 20 20 69 66 28 20 69 73 75 70 70 65 72 28 7a  .  if( isupper(z
5120: 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20  Name[0]) ){.    
5130: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
5140: 75 65 20 3d 20 67 65 74 65 6e 76 28 7a 4e 61 6d  ue = getenv(zNam
5150: 65 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c  e);.    if( zVal
5160: 75 65 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  ue ){.      cgi_
5170: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
5180: 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c  copy(zName, zVal
5190: 75 65 29 3b 0a 20 20 20 20 20 20 43 47 49 44 45  ue);.      CGIDE
51a0: 42 55 47 28 28 22 65 6e 76 2d 6d 61 74 63 68 20  BUG(("env-match 
51b0: 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20  [%s] = [%s]\n", 
51c0: 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 29 3b  zName, zValue));
51d0: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 7a 56  .      return zV
51e0: 61 6c 75 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  alue;.    }.  }.
51f0: 20 20 43 47 49 44 45 42 55 47 28 28 22 6e 6f 2d    CGIDEBUG(("no-
5200: 6d 61 74 63 68 20 5b 25 73 5d 5c 6e 22 2c 20 7a  match [%s]\n", z
5210: 4e 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72 6e  Name));.  return
5220: 20 7a 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a 2f 2a   zDefault;.}../*
5230: 0a 2a 2a 20 50 72 69 6e 74 20 43 47 49 20 64 65  .** Print CGI de
5240: 62 75 67 67 69 6e 67 20 6d 65 73 73 61 67 65 73  bugging messages
5250: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 64 65  ..*/.void cgi_de
5260: 62 75 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  bug(const char *
5270: 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20  zFormat, ...){. 
5280: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 69   va_list ap;.  i
5290: 66 28 20 67 2e 66 44 65 62 75 67 20 29 7b 0a 20  f( g.fDebug ){. 
52a0: 20 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20     va_start(ap, 
52b0: 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 20 20 76 66  zFormat);.    vf
52c0: 70 72 69 6e 74 66 28 67 2e 66 44 65 62 75 67 2c  printf(g.fDebug,
52d0: 20 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 20   zFormat, ap);. 
52e0: 20 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20     va_end(ap);. 
52f0: 20 20 20 66 66 6c 75 73 68 28 67 2e 66 44 65 62     fflush(g.fDeb
5300: 75 67 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  ug);.  }.}../*.*
5310: 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66  * Return true if
5320: 20 61 6e 79 20 6f 66 20 74 68 65 20 71 75 65 72   any of the quer
5330: 79 20 70 61 72 61 6d 65 74 65 72 73 20 69 6e 20  y parameters in 
5340: 74 68 65 20 61 72 67 75 6d 65 6e 74 0a 2a 2a 20  the argument.** 
5350: 6c 69 73 74 20 61 72 65 20 64 65 66 69 6e 65 64  list are defined
5360: 2e 0a 2a 2f 0a 69 6e 74 20 63 67 69 5f 61 6e 79  ..*/.int cgi_any
5370: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 2c 20  (const char *z, 
5380: 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20  ...){.  va_list 
5390: 61 70 3b 0a 20 20 63 68 61 72 20 2a 7a 32 3b 0a  ap;.  char *z2;.
53a0: 20 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65    if( cgi_parame
53b0: 74 65 72 28 7a 2c 30 29 21 3d 30 20 29 20 72 65  ter(z,0)!=0 ) re
53c0: 74 75 72 6e 20 31 3b 0a 20 20 76 61 5f 73 74 61  turn 1;.  va_sta
53d0: 72 74 28 61 70 2c 20 7a 29 3b 0a 20 20 77 68 69  rt(ap, z);.  whi
53e0: 6c 65 28 20 28 7a 32 20 3d 20 76 61 5f 61 72 67  le( (z2 = va_arg
53f0: 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20  (ap, char*))!=0 
5400: 29 7b 0a 20 20 20 20 69 66 28 20 63 67 69 5f 70  ){.    if( cgi_p
5410: 61 72 61 6d 65 74 65 72 28 7a 32 2c 30 29 21 3d  arameter(z2,0)!=
5420: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20  0 ) return 1;.  
5430: 7d 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a  }.  va_end(ap);.
5440: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f    return 0;.}../
5450: 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65  *.** Return true
5460: 20 69 66 20 61 6c 6c 20 6f 66 20 74 68 65 20 71   if all of the q
5470: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 20  uery parameters 
5480: 69 6e 20 74 68 65 20 61 72 67 75 6d 65 6e 74 20  in the argument 
5490: 6c 69 73 74 0a 2a 2a 20 61 72 65 20 64 65 66 69  list.** are defi
54a0: 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20 63 67 69 5f  ned..*/.int cgi_
54b0: 61 6c 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  all(const char *
54c0: 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69  z, ...){.  va_li
54d0: 73 74 20 61 70 3b 0a 20 20 63 68 61 72 20 2a 7a  st ap;.  char *z
54e0: 32 3b 0a 20 20 69 66 28 20 63 67 69 5f 70 61 72  2;.  if( cgi_par
54f0: 61 6d 65 74 65 72 28 7a 2c 30 29 3d 3d 30 20 29  ameter(z,0)==0 )
5500: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 76 61 5f   return 0;.  va_
5510: 73 74 61 72 74 28 61 70 2c 20 7a 29 3b 0a 20 20  start(ap, z);.  
5520: 77 68 69 6c 65 28 20 28 7a 32 20 3d 20 76 61 5f  while( (z2 = va_
5530: 61 72 67 28 61 70 2c 20 63 68 61 72 2a 29 29 3d  arg(ap, char*))=
5540: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 63 67  =0 ){.    if( cg
5550: 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 32 2c 30  i_parameter(z2,0
5560: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b  )==0 ) return 0;
5570: 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64 28 61 70  .  }.  va_end(ap
5580: 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d  );.  return 1;.}
5590: 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74 20 61 6c  ../*.** Print al
55a0: 6c 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  l query paramete
55b0: 72 73 20 6f 6e 20 73 74 61 6e 64 61 72 64 20 6f  rs on standard o
55c0: 75 74 70 75 74 2e 20 20 46 6f 72 6d 61 74 20 74  utput.  Format t
55d0: 68 65 0a 2a 2a 20 70 61 72 61 6d 65 74 65 72 73  he.** parameters
55e0: 20 61 73 20 48 54 4d 4c 2e 20 20 54 68 69 73 20   as HTML.  This 
55f0: 69 73 20 75 73 65 64 20 66 6f 72 20 74 65 73 74  is used for test
5600: 69 6e 67 20 61 6e 64 20 64 65 62 75 67 67 69 6e  ing and debuggin
5610: 67 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70  g..*/.void cgi_p
5620: 72 69 6e 74 5f 61 6c 6c 28 76 6f 69 64 29 7b 0a  rint_all(void){.
5630: 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69 5f 70    int i;.  cgi_p
5640: 61 72 61 6d 65 74 65 72 28 22 22 2c 22 22 29 3b  arameter("","");
5650: 20 20 2f 2a 20 46 6f 72 63 65 20 74 68 65 20 70    /* Force the p
5660: 61 72 61 6d 65 74 65 72 73 20 69 6e 74 6f 20 73  arameters into s
5670: 6f 72 74 65 64 20 6f 72 64 65 72 20 2a 2f 0a 20  orted order */. 
5680: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 55 73 65   for(i=0; i<nUse
5690: 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63  dQP; i++){.    c
56a0: 67 69 5f 70 72 69 6e 74 66 28 22 25 73 20 3d 20  gi_printf("%s = 
56b0: 25 73 20 20 3c 62 72 20 2f 3e 5c 6e 22 2c 0a 20  %s  <br />\n",. 
56c0: 20 20 20 20 20 20 68 74 6d 6c 69 7a 65 28 61 50        htmlize(aP
56d0: 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c  aramQP[i].zName,
56e0: 20 2d 31 29 2c 20 68 74 6d 6c 69 7a 65 28 61 50   -1), htmlize(aP
56f0: 61 72 61 6d 51 50 5b 69 5d 2e 7a 56 61 6c 75 65  aramQP[i].zValue
5700: 2c 20 2d 31 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f  , -1));.  }.}../
5710: 2a 0a 2a 2a 20 57 72 69 74 65 20 48 54 4d 4c 20  *.** Write HTML 
5720: 74 65 78 74 20 66 6f 72 20 61 6e 20 6f 70 74 69  text for an opti
5730: 6f 6e 20 6d 65 6e 75 20 74 6f 20 73 74 61 6e 64  on menu to stand
5740: 61 72 64 20 6f 75 74 70 75 74 2e 20 20 7a 50 61  ard output.  zPa
5750: 72 61 6d 0a 2a 2a 20 69 73 20 74 68 65 20 71 75  ram.** is the qu
5760: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 74 68  ery parameter th
5770: 61 74 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65  at the option me
5780: 6e 75 20 73 65 74 73 2e 20 20 7a 44 66 6c 74 20  nu sets.  zDflt 
5790: 69 73 20 74 68 65 0a 2a 2a 20 69 6e 69 74 69 61  is the.** initia
57a0: 6c 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 6f  l value of the o
57b0: 70 74 69 6f 6e 20 6d 65 6e 75 2e 20 20 41 64 64  ption menu.  Add
57c0: 69 74 69 6f 6e 20 61 72 67 75 6d 65 6e 74 73 20  ition arguments 
57d0: 61 72 65 20 6e 61 6d 65 2f 76 61 6c 75 65 0a 2a  are name/value.*
57e0: 2a 20 70 61 69 72 73 20 74 68 61 74 20 64 65 66  * pairs that def
57f0: 69 6e 65 20 76 61 6c 75 65 73 20 6f 6e 20 74 68  ine values on th
5800: 65 20 6d 65 6e 75 2e 20 20 54 68 65 20 6c 69 73  e menu.  The lis
5810: 74 20 69 73 20 74 65 72 6d 69 6e 61 74 65 64 20  t is terminated 
5820: 77 69 74 68 0a 2a 2a 20 61 20 73 69 6e 67 6c 65  with.** a single
5830: 20 4e 55 4c 4c 20 61 72 67 75 6d 65 6e 74 2e 0a   NULL argument..
5840: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 6f 70 74 69  */.void cgi_opti
5850: 6f 6e 6d 65 6e 75 28 69 6e 74 20 69 6e 2c 20 63  onmenu(int in, c
5860: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 63  onst char *zP, c
5870: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 2e  onst char *zD, .
5880: 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61  ..){.  va_list a
5890: 70 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65  p;.  char *zName
58a0: 2c 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 64  , *zVal;.  int d
58b0: 66 6c 74 53 65 65 6e 20 3d 20 30 3b 0a 20 20 63  fltSeen = 0;.  c
58c0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73  gi_printf("%*s<s
58d0: 65 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d  elect size=1 nam
58e0: 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e  e=\"%s\">\n", in
58f0: 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 20 76 61 5f  , "", zP);.  va_
5900: 73 74 61 72 74 28 61 70 2c 20 7a 44 29 3b 0a 20  start(ap, zD);. 
5910: 20 77 68 69 6c 65 28 20 28 7a 4e 61 6d 65 20 3d   while( (zName =
5920: 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72   va_arg(ap, char
5930: 2a 29 29 21 3d 30 20 26 26 20 28 7a 56 61 6c 20  *))!=0 && (zVal 
5940: 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61  = va_arg(ap, cha
5950: 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69  r*))!=0 ){.    i
5960: 66 28 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 7a  f( strcmp(zVal,z
5970: 44 29 3d 3d 30 20 29 7b 20 64 66 6c 74 53 65 65  D)==0 ){ dfltSee
5980: 6e 20 3d 20 31 3b 20 62 72 65 61 6b 3b 20 7d 0a  n = 1; break; }.
5990: 20 20 7d 0a 20 20 76 61 5f 65 6e 64 28 61 70 29    }.  va_end(ap)
59a0: 3b 0a 20 20 69 66 28 20 21 64 66 6c 74 53 65 65  ;.  if( !dfltSee
59b0: 6e 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b  n ){.    if( zD[
59c0: 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  0] ){.      cgi_
59d0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69  printf("%*s<opti
59e0: 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20  on value=\"%h\" 
59f0: 73 65 6c 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74  selected>%h</opt
5a00: 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20  ion>\n",.       
5a10: 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 7a   in+2, "", zD, z
5a20: 44 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20  D);.    }else{. 
5a30: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28       cgi_printf(
5a40: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75  "%*s<option valu
5a50: 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64 3e  e=\"\" selected>
5a60: 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c  &nbsp;</option>\
5a70: 6e 22 2c 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20  n", in+2, "");. 
5a80: 20 20 20 7d 0a 20 20 7d 0a 20 20 76 61 5f 73 74     }.  }.  va_st
5a90: 61 72 74 28 61 70 2c 20 7a 44 29 3b 0a 20 20 77  art(ap, zD);.  w
5aa0: 68 69 6c 65 28 20 28 7a 4e 61 6d 65 20 3d 20 76  hile( (zName = v
5ab0: 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a 29  a_arg(ap, char*)
5ac0: 29 21 3d 30 20 26 26 20 28 7a 56 61 6c 20 3d 20  )!=0 && (zVal = 
5ad0: 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a  va_arg(ap, char*
5ae0: 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28  ))!=0 ){.    if(
5af0: 20 7a 4e 61 6d 65 5b 30 5d 20 29 7b 0a 20 20 20   zName[0] ){.   
5b00: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25     cgi_printf("%
5b10: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d  *s<option value=
5b20: 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74  \"%h\"%s>%h</opt
5b30: 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20  ion>\n",.       
5b40: 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20   in+2, "",.     
5b50: 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20     zVal,.       
5b60: 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44   strcmp(zVal, zD
5b70: 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63  ) ? "" : " selec
5b80: 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e  ted",.        zN
5b90: 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ame.      );.   
5ba0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67   }else{.      cg
5bb0: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70  i_printf("%*s<op
5bc0: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25  tion value=\"\"%
5bd0: 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e  s>&nbsp;</option
5be0: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e  >\n",.        in
5bf0: 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20  +2, "",.        
5c00: 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29  strcmp(zVal, zD)
5c10: 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74   ? "" : " select
5c20: 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ed".      );.   
5c30: 20 7d 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64 28   }.  }.  va_end(
5c40: 61 70 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74  ap);.  cgi_print
5c50: 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c  f("%*s</select>\
5c60: 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a  n", in, "");.}..
5c70: 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69  /*.** This routi
5c80: 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74 20 6c  ne works a lot l
5c90: 69 6b 65 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65  ike cgi_optionme
5ca0: 6e 75 28 29 20 65 78 63 65 70 74 20 74 68 61 74  nu() except that
5cb0: 20 74 68 65 20 6c 69 73 74 20 6f 66 0a 2a 2a 20   the list of.** 
5cc0: 76 61 6c 75 65 73 20 69 73 20 63 6f 6e 74 61 69  values is contai
5cd0: 6e 65 64 20 69 6e 20 61 6e 20 61 72 72 61 79 2e  ned in an array.
5ce0: 20 20 41 6c 73 6f 2c 20 74 68 65 20 76 61 6c 75    Also, the valu
5cf0: 65 73 20 61 72 65 20 6a 75 73 74 20 76 61 6c 75  es are just valu
5d00: 65 73 2c 20 6e 6f 74 0a 2a 2a 20 6e 61 6d 65 2f  es, not.** name/
5d10: 76 61 6c 75 65 20 70 61 69 72 73 20 61 73 20 69  value pairs as i
5d20: 6e 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75  n cgi_optionmenu
5d30: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f  ..*/.void cgi_v_
5d40: 6f 70 74 69 6f 6e 6d 65 6e 75 28 0a 20 20 69 6e  optionmenu(.  in
5d50: 74 20 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20  t in,           
5d60: 20 20 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20     /* Indent by 
5d70: 74 68 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20  this amount */. 
5d80: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c   const char *zP,
5d90: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65        /* The que
5da0: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6e 61 6d  ry parameter nam
5db0: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
5dc0: 72 20 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44  r *zD,      /* D
5dd0: 65 66 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a  efault value */.
5de0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61    const char **a
5df0: 7a 20 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74  z      /* NULL-t
5e00: 65 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 6f  erminated list o
5e10: 66 20 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73  f allowed values
5e20: 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63   */.){.  const c
5e30: 68 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74  har *zVal;.  int
5e40: 20 69 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66   i;.  cgi_printf
5e50: 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a  ("%*s<select siz
5e60: 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e  e=1 name=\"%s\">
5e70: 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29  \n", in, "", zP)
5e80: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b  ;.  for(i=0; az[
5e90: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  i]; i++){.    if
5ea0: 28 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a  ( strcmp(az[i],z
5eb0: 44 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20  D)==0 ) break;. 
5ec0: 20 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d   }.  if( az[i]==
5ed0: 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b  0 ){.    if( zD[
5ee0: 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63  0]==0 ){.      c
5ef0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f  gi_printf("%*s<o
5f00: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22  ption value=\"\"
5f10: 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b   selected>&nbsp;
5f20: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20  </option>\n",.  
5f30: 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a       in+2, "");.
5f40: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
5f50: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73   cgi_printf("%*s
5f60: 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22  <option value=\"
5f70: 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 68  %h\" selected>%h
5f80: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20  </option>\n",.  
5f90: 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a       in+2, "", z
5fa0: 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20  D, zD);.    }.  
5fb0: 7d 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 61 6c  }.  while( (zVal
5fc0: 20 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20   = *(az++))!=0  
5fd0: 29 7b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 5b  ){.    if( zVal[
5fe0: 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  0] ){.      cgi_
5ff0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69  printf("%*s<opti
6000: 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25  on value=\"%h\"%
6010: 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22  s>%h</option>\n"
6020: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20  ,.        in+2, 
6030: 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c  "",.        zVal
6040: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70  ,.        strcmp
6050: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20  (zVal, zD) ? "" 
6060: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20  : " selected",. 
6070: 20 20 20 20 20 20 20 7a 56 61 6c 0a 20 20 20 20         zVal.    
6080: 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a    );.    }else{.
6090: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66        cgi_printf
60a0: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c  ("%*s<option val
60b0: 75 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b  ue=\"\"%s>&nbsp;
60c0: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20  </option>\n",.  
60d0: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a        in+2, "",.
60e0: 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a          strcmp(z
60f0: 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20  Val, zD) ? "" : 
6100: 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 20  " selected".    
6110: 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20    );.    }.  }. 
6120: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73   cgi_printf("%*s
6130: 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e  </select>\n", in
6140: 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  , "");.}../*.** 
6150: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72  This routine wor
6160: 6b 73 20 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67  ks a lot like cg
6170: 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 29  i_v_optionmenu()
6180: 20 65 78 63 65 70 74 20 74 68 61 74 20 74 68 65   except that the
6190: 20 6c 69 73 74 0a 2a 2a 20 69 73 20 61 20 6c 69   list.** is a li
61a0: 73 74 20 6f 66 20 70 61 69 72 73 2e 20 20 54 68  st of pairs.  Th
61b0: 65 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 20  e first element 
61c0: 6f 66 20 65 61 63 68 20 70 61 69 72 20 69 73 20  of each pair is 
61d0: 74 68 65 20 76 61 6c 75 65 20 75 73 65 64 0a 2a  the value used.*
61e0: 2a 20 69 6e 74 65 72 6e 61 6c 6c 79 20 61 6e 64  * internally and
61f0: 20 74 68 65 20 73 65 63 6f 6e 64 20 65 6c 65 6d   the second elem
6200: 65 6e 74 20 69 73 20 74 68 65 20 76 61 6c 75 65  ent is the value
6210: 20 64 69 73 70 6c 61 79 65 64 20 74 6f 20 74 68   displayed to th
6220: 65 20 75 73 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20  e user..*/.void 
6230: 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e 75  cgi_v_optionmenu
6240: 32 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20 20  2(.  int in,    
6250: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
6260: 65 6e 74 20 62 79 20 74 68 69 73 20 61 6d 6f 75  ent by this amou
6270: 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  nt */.  const ch
6280: 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a 20  ar *zP,      /* 
6290: 54 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65  The query parame
62a0: 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f  ter name */.  co
62b0: 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 20 20  nst char *zD,   
62c0: 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 76 61     /* Default va
62d0: 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  lue */.  const c
62e0: 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f 2a  har **az      /*
62f0: 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 64   NULL-terminated
6300: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65 64   list of allowed
6310: 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 20   values */.){.  
6320: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
6330: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69  ;.  int i;.  cgi
6340: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c  _printf("%*s<sel
6350: 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d  ect size=1 name=
6360: 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20  \"%s\">\n", in, 
6370: 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28 69  "", zP);.  for(i
6380: 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 3d 32 29  =0; az[i]; i+=2)
6390: 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70  {.    if( strcmp
63a0: 28 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20  (az[i],zD)==0 ) 
63b0: 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28  break;.  }.  if(
63c0: 20 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20   az[i]==0 ){.   
63d0: 20 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b   if( zD[0]==0 ){
63e0: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74  .      cgi_print
63f0: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61  f("%*s<option va
6400: 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65  lue=\"\" selecte
6410: 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e  d>&nbsp;</option
6420: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b  >\n",.       in+
6430: 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73  2, "");.    }els
6440: 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  e{.      cgi_pri
6450: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20  ntf("%*s<option 
6460: 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c  value=\"%h\" sel
6470: 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e  ected>%h</option
6480: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b  >\n",.       in+
6490: 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a  2, "", zD, zD);.
64a0: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c      }.  }.  whil
64b0: 65 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b  e( (zVal = *(az+
64c0: 2b 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 63  +))!=0  ){.    c
64d0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
64e0: 20 3d 20 2a 28 61 7a 2b 2b 29 3b 0a 20 20 20 20   = *(az++);.    
64f0: 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 20 29 7b 0a  if( zName[0] ){.
6500: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66        cgi_printf
6510: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c  ("%*s<option val
6520: 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f  ue=\"%h\"%s>%h</
6530: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20  option>\n",.    
6540: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20      in+2, "",.  
6550: 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20        zVal,.    
6560: 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c      strcmp(zVal,
6570: 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65   zD) ? "" : " se
6580: 6c 65 63 74 65 64 22 2c 0a 20 20 20 20 20 20 20  lected",.       
6590: 20 7a 4e 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a   zName.      );.
65a0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
65b0: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73   cgi_printf("%*s
65c0: 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22  <option value=\"
65d0: 25 68 5c 22 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f  %h\"%s>&nbsp;</o
65e0: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20  ption>\n",.     
65f0: 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20     in+2, "",.   
6600: 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20       zVal,.     
6610: 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20     strcmp(zVal, 
6620: 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c  zD) ? "" : " sel
6630: 65 63 74 65 64 22 0a 20 20 20 20 20 20 29 3b 0a  ected".      );.
6640: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f      }.  }.  cgi_
6650: 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c  printf("%*s</sel
6660: 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29  ect>\n", in, "")
6670: 3b 0a 7d 0a 0a 2f 2a 20 0a 2a 2a 20 54 68 69 73  ;.}../* .** This
6680: 20 66 75 6e 63 74 69 6f 6e 20 69 6d 70 6c 65 6d   function implem
6690: 65 6e 74 73 20 74 68 65 20 63 61 6c 6c 62 61 63  ents the callbac
66a0: 6b 20 66 72 6f 6d 20 76 78 70 72 69 6e 74 66 2e  k from vxprintf.
66b0: 20 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75   .**.** This rou
66c0: 74 69 6e 65 20 73 65 6e 64 73 20 6e 4e 65 77 43  tine sends nNewC
66d0: 68 61 72 20 63 68 61 72 61 63 74 65 72 73 20 6f  har characters o
66e0: 66 20 74 65 78 74 20 69 6e 20 7a 4e 65 77 54 65  f text in zNewTe
66f0: 78 74 20 74 6f 0a 2a 2a 20 43 47 49 20 72 65 70  xt to.** CGI rep
6700: 6c 79 20 63 6f 6e 74 65 6e 74 20 62 75 66 66 65  ly content buffe
6710: 72 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  r..*/.static voi
6720: 64 20 73 6f 75 74 28 76 6f 69 64 20 2a 4e 6f 74  d sout(void *Not
6730: 55 73 65 64 2c 20 63 6f 6e 73 74 20 63 68 61 72  Used, const char
6740: 20 2a 7a 4e 65 77 54 65 78 74 2c 20 69 6e 74 20   *zNewText, int 
6750: 6e 4e 65 77 43 68 61 72 29 7b 0a 20 20 63 67 69  nNewChar){.  cgi
6760: 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e 74 28  _append_content(
6770: 7a 4e 65 77 54 65 78 74 2c 20 6e 4e 65 77 43 68  zNewText, nNewCh
6780: 61 72 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  ar);.}../*.** Th
6790: 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73  is routine works
67a0: 20 6c 69 6b 65 20 22 70 72 69 6e 74 66 22 20 65   like "printf" e
67b0: 78 63 65 70 74 20 74 68 61 74 20 69 74 20 68 61  xcept that it ha
67c0: 73 20 74 68 65 0a 2a 2a 20 65 78 74 72 61 20 66  s the.** extra f
67d0: 6f 72 6d 61 74 74 69 6e 67 20 63 61 70 61 62 69  ormatting capabi
67e0: 6c 69 74 69 65 73 20 73 75 63 68 20 61 73 20 25  lities such as %
67f0: 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69  h and %t..*/.voi
6800: 64 20 63 67 69 5f 70 72 69 6e 74 66 28 63 6f 6e  d cgi_printf(con
6810: 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74  st char *zFormat
6820: 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73  , ...){.  va_lis
6830: 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 72 74  t ap;.  va_start
6840: 28 61 70 2c 7a 46 6f 72 6d 61 74 29 3b 0a 20 20  (ap,zFormat);.  
6850: 76 78 70 72 69 6e 74 66 28 73 6f 75 74 2c 30 2c  vxprintf(sout,0,
6860: 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 20 20 76  zFormat,ap);.  v
6870: 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 2f 2a  a_end(ap);.}../*
6880: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65  .** This routine
6890: 20 77 6f 72 6b 73 20 6c 69 6b 65 20 22 76 70 72   works like "vpr
68a0: 69 6e 74 66 22 20 65 78 63 65 70 74 20 74 68 61  intf" except tha
68b0: 74 20 69 74 20 68 61 73 20 74 68 65 0a 2a 2a 20  t it has the.** 
68c0: 65 78 74 72 61 20 66 6f 72 6d 61 74 74 69 6e 67  extra formatting
68d0: 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 73 75   capabilities su
68e0: 63 68 20 61 73 20 25 68 20 61 6e 64 20 25 74 2e  ch as %h and %t.
68f0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 70 72  .*/.void cgi_vpr
6900: 69 6e 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20  intf(const char 
6910: 2a 7a 46 6f 72 6d 61 74 2c 20 76 61 5f 6c 69 73  *zFormat, va_lis
6920: 74 20 61 70 29 7b 0a 20 20 76 78 70 72 69 6e 74  t ap){.  vxprint
6930: 66 28 73 6f 75 74 2c 30 2c 7a 46 6f 72 6d 61 74  f(sout,0,zFormat
6940: 2c 61 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20  ,ap);.}.../*.** 
6950: 53 65 6e 64 20 61 20 72 65 70 6c 79 20 69 6e 64  Send a reply ind
6960: 69 63 61 74 69 6e 67 20 74 68 61 74 20 74 68 65  icating that the
6970: 20 48 54 54 50 20 72 65 71 75 65 73 74 20 77 61   HTTP request wa
6980: 73 20 6d 61 6c 66 6f 72 6d 65 64 0a 2a 2f 0a 73  s malformed.*/.s
6990: 74 61 74 69 63 20 76 6f 69 64 20 6d 61 6c 66 6f  tatic void malfo
69a0: 72 6d 65 64 5f 72 65 71 75 65 73 74 28 76 6f 69  rmed_request(voi
69b0: 64 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74  d){.  cgi_set_st
69c0: 61 74 75 73 28 35 30 31 2c 20 22 4e 6f 74 20 49  atus(501, "Not I
69d0: 6d 70 6c 65 6d 65 6e 74 65 64 22 29 3b 0a 20 20  mplemented");.  
69e0: 63 67 69 5f 70 72 69 6e 74 66 28 0a 20 20 20 20  cgi_printf(.    
69f0: 22 3c 68 74 6d 6c 3e 3c 62 6f 64 79 3e 55 6e 72  "<html><body>Unr
6a00: 65 63 6f 67 6e 69 7a 65 64 20 48 54 54 50 20 52  ecognized HTTP R
6a10: 65 71 75 65 73 74 3c 2f 62 6f 64 79 3e 3c 2f 68  equest</body></h
6a20: 74 6d 6c 3e 5c 6e 22 0a 20 20 29 3b 0a 20 20 63  tml>\n".  );.  c
6a30: 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 78  gi_reply();.  ex
6a40: 69 74 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  it(0);.}../*.** 
6a50: 50 61 6e 69 63 20 61 6e 64 20 64 69 65 20 77 68  Panic and die wh
6a60: 69 6c 65 20 70 72 6f 63 65 73 73 69 6e 67 20 61  ile processing a
6a70: 20 77 65 62 70 61 67 65 2e 0a 2a 2f 0a 76 6f 69   webpage..*/.voi
6a80: 64 20 63 67 69 5f 70 61 6e 69 63 28 63 6f 6e 73  d cgi_panic(cons
6a90: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c  t char *zFormat,
6aa0: 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74   ...){.  va_list
6ab0: 20 61 70 3b 0a 20 20 63 67 69 5f 72 65 73 65 74   ap;.  cgi_reset
6ac0: 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63 67  _content();.  cg
6ad0: 69 5f 73 65 74 5f 73 74 61 74 75 73 28 35 30 30  i_set_status(500
6ae0: 2c 20 22 49 6e 74 65 72 6e 61 6c 20 53 65 72 76  , "Internal Serv
6af0: 65 72 20 45 72 72 6f 72 22 29 3b 0a 20 20 63 67  er Error");.  cg
6b00: 69 5f 70 72 69 6e 74 66 28 0a 20 20 20 20 22 3c  i_printf(.    "<
6b10: 68 74 6d 6c 3e 3c 62 6f 64 79 3e 3c 68 31 3e 49  html><body><h1>I
6b20: 6e 74 65 72 6e 61 6c 20 53 65 72 76 65 72 20 45  nternal Server E
6b30: 72 72 6f 72 3c 2f 68 31 3e 5c 6e 22 0a 20 20 20  rror</h1>\n".   
6b40: 20 22 3c 70 6c 61 69 6e 74 65 78 74 3e 22 0a 20   "<plaintext>". 
6b50: 20 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61   );.  va_start(a
6b60: 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 76  p, zFormat);.  v
6b70: 78 70 72 69 6e 74 66 28 73 6f 75 74 2c 30 2c 7a  xprintf(sout,0,z
6b80: 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 20 20 76 61  Format,ap);.  va
6b90: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63 67 69 5f  _end(ap);.  cgi_
6ba0: 72 65 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28  reply();.  exit(
6bb0: 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d  1);.}../*.** Rem
6bc0: 6f 76 65 20 74 68 65 20 66 69 72 73 74 20 73 70  ove the first sp
6bd0: 61 63 65 2d 64 65 6c 69 6d 69 74 65 64 20 74 6f  ace-delimited to
6be0: 6b 65 6e 20 66 72 6f 6d 20 61 20 73 74 72 69 6e  ken from a strin
6bf0: 67 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20  g and return.** 
6c00: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 69 74 2e  a pointer to it.
6c10: 20 20 41 64 64 20 61 20 4e 55 4c 4c 20 74 6f 20    Add a NULL to 
6c20: 74 68 65 20 73 74 72 69 6e 67 20 74 6f 20 74 65  the string to te
6c30: 72 6d 69 6e 61 74 65 20 74 68 65 20 74 6f 6b 65  rminate the toke
6c40: 6e 2e 0a 2a 2a 20 4d 61 6b 65 20 2a 7a 4c 65 66  n..** Make *zLef
6c50: 74 4f 76 65 72 20 70 6f 69 6e 74 20 74 6f 20 74  tOver point to t
6c60: 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
6c70: 6e 65 78 74 20 74 6f 6b 65 6e 2e 0a 2a 2f 0a 73  next token..*/.s
6c80: 74 61 74 69 63 20 63 68 61 72 20 2a 65 78 74 72  tatic char *extr
6c90: 61 63 74 5f 74 6f 6b 65 6e 28 63 68 61 72 20 2a  act_token(char *
6ca0: 7a 49 6e 70 75 74 2c 20 63 68 61 72 20 2a 2a 7a  zInput, char **z
6cb0: 4c 65 66 74 4f 76 65 72 29 7b 0a 20 20 63 68 61  LeftOver){.  cha
6cc0: 72 20 2a 7a 52 65 73 75 6c 74 20 3d 20 30 3b 0a  r *zResult = 0;.
6cd0: 20 20 69 66 28 20 7a 49 6e 70 75 74 3d 3d 30 20    if( zInput==0 
6ce0: 29 7b 0a 20 20 20 20 69 66 28 20 7a 4c 65 66 74  ){.    if( zLeft
6cf0: 4f 76 65 72 20 29 20 2a 7a 4c 65 66 74 4f 76 65  Over ) *zLeftOve
6d00: 72 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72  r = 0;.    retur
6d10: 6e 20 30 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65  n 0;.  }.  while
6d20: 28 20 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 75  ( isspace(*zInpu
6d30: 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20  t) ){ zInput++; 
6d40: 7d 0a 20 20 7a 52 65 73 75 6c 74 20 3d 20 7a 49  }.  zResult = zI
6d50: 6e 70 75 74 3b 0a 20 20 77 68 69 6c 65 28 20 2a  nput;.  while( *
6d60: 7a 49 6e 70 75 74 20 26 26 20 21 69 73 73 70 61  zInput && !isspa
6d70: 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a  ce(*zInput) ){ z
6d80: 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 69 66 28  Input++; }.  if(
6d90: 20 2a 7a 49 6e 70 75 74 20 29 7b 0a 20 20 20 20   *zInput ){.    
6da0: 2a 7a 49 6e 70 75 74 20 3d 20 30 3b 0a 20 20 20  *zInput = 0;.   
6db0: 20 7a 49 6e 70 75 74 2b 2b 3b 0a 20 20 20 20 77   zInput++;.    w
6dc0: 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a  hile( isspace(*z
6dd0: 49 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74  Input) ){ zInput
6de0: 2b 2b 3b 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20  ++; }.  }.  if( 
6df0: 7a 4c 65 66 74 4f 76 65 72 20 29 7b 20 2a 7a 4c  zLeftOver ){ *zL
6e00: 65 66 74 4f 76 65 72 20 3d 20 7a 49 6e 70 75 74  eftOver = zInput
6e10: 3b 20 7d 0a 20 20 72 65 74 75 72 6e 20 7a 52 65  ; }.  return zRe
6e20: 73 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  sult;.}../*.** T
6e30: 68 69 73 20 72 6f 75 74 69 6e 65 20 68 61 6e 64  his routine hand
6e40: 6c 65 73 20 61 20 73 69 6e 67 6c 65 20 48 54 54  les a single HTT
6e50: 50 20 72 65 71 75 65 73 74 20 77 68 69 63 68 20  P request which 
6e60: 69 73 20 63 6f 6d 69 6e 67 20 69 6e 20 6f 6e 0a  is coming in on.
6e70: 2a 2a 20 73 74 61 6e 64 61 72 64 20 69 6e 70 75  ** standard inpu
6e80: 74 20 61 6e 64 20 77 68 69 63 68 20 72 65 70 6c  t and which repl
6e90: 69 65 73 20 6f 6e 20 73 74 61 6e 64 61 72 64 20  ies on standard 
6ea0: 6f 75 74 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 54 68  output..**.** Th
6eb0: 65 20 48 54 54 50 20 72 65 71 75 65 73 74 20 69  e HTTP request i
6ec0: 73 20 72 65 61 64 20 66 72 6f 6d 20 73 74 61 6e  s read from stan
6ed0: 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20 69  dard input and i
6ee0: 73 20 75 73 65 64 20 74 6f 20 69 6e 69 74 69 61  s used to initia
6ef0: 6c 69 7a 65 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d  lize.** environm
6f00: 65 6e 74 20 76 61 72 69 61 62 6c 65 73 20 61 73  ent variables as
6f10: 20 70 65 72 20 43 47 49 2e 20 20 54 68 65 20 63   per CGI.  The c
6f20: 67 69 5f 69 6e 69 74 28 29 20 72 6f 75 74 69 6e  gi_init() routin
6f30: 65 20 74 6f 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a  e to complete.**
6f40: 20 74 68 65 20 73 65 74 75 70 2e 20 20 4f 6e 63   the setup.  Onc
6f50: 65 20 61 6c 6c 20 74 68 65 20 73 65 74 75 70 20  e all the setup 
6f60: 69 73 20 66 69 6e 69 73 68 65 64 2c 20 74 68 69  is finished, thi
6f70: 73 20 70 72 6f 63 65 64 75 72 65 20 72 65 74 75  s procedure retu
6f80: 72 6e 73 0a 2a 2a 20 61 6e 64 20 73 75 62 73 65  rns.** and subse
6f90: 71 75 65 6e 74 20 63 6f 64 65 20 68 61 6e 64 6c  quent code handl
6fa0: 65 73 20 74 68 65 20 61 63 74 75 61 6c 20 67 65  es the actual ge
6fb0: 6e 65 72 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  neration of the 
6fc0: 77 65 62 70 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64  webpage..*/.void
6fd0: 20 63 67 69 5f 68 61 6e 64 6c 65 5f 68 74 74 70   cgi_handle_http
6fe0: 5f 72 65 71 75 65 73 74 28 76 6f 69 64 29 7b 0a  _request(void){.
6ff0: 20 20 63 68 61 72 20 2a 7a 2c 20 2a 7a 54 6f 6b    char *z, *zTok
7000: 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 73  en;.  int i;.  s
7010: 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69  truct sockaddr_i
7020: 6e 20 72 65 6d 6f 74 65 4e 61 6d 65 3b 0a 20 20  n remoteName;.  
7030: 73 69 7a 65 5f 74 20 73 69 7a 65 20 3d 20 73 69  size_t size = si
7040: 7a 65 6f 66 28 73 74 72 75 63 74 20 73 6f 63 6b  zeof(struct sock
7050: 61 64 64 72 5f 69 6e 29 3b 0a 20 20 63 68 61 72  addr_in);.  char
7060: 20 7a 4c 69 6e 65 5b 32 30 30 30 5d 3b 20 20 20   zLine[2000];   
7070: 20 20 2f 2a 20 41 20 73 69 6e 67 6c 65 20 6c 69    /* A single li
7080: 6e 65 20 6f 66 20 69 6e 70 75 74 2e 20 2a 2f 0a  ne of input. */.
7090: 0a 20 20 66 75 6c 6c 48 74 74 70 52 65 70 6c 79  .  fullHttpReply
70a0: 20 3d 20 31 3b 0a 20 20 69 66 28 20 66 67 65 74   = 1;.  if( fget
70b0: 73 28 7a 4c 69 6e 65 2c 20 73 69 7a 65 6f 66 28  s(zLine, sizeof(
70c0: 7a 4c 69 6e 65 29 2c 20 73 74 64 69 6e 29 3d 3d  zLine), stdin)==
70d0: 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d  0 ){.    malform
70e0: 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20  ed_request();.  
70f0: 7d 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74  }.  zToken = ext
7100: 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e 65  ract_token(zLine
7110: 2c 20 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f  , &z);.  if( zTo
7120: 6b 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61  ken==0 ){.    ma
7130: 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28  lformed_request(
7140: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73 74 72  );.  }.  if( str
7150: 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22 47 45 54 22  cmp(zToken,"GET"
7160: 29 21 3d 30 20 26 26 20 73 74 72 63 6d 70 28 7a  )!=0 && strcmp(z
7170: 54 6f 6b 65 6e 2c 22 50 4f 53 54 22 29 21 3d 30  Token,"POST")!=0
7180: 0a 20 20 20 20 20 20 26 26 20 73 74 72 63 6d 70  .      && strcmp
7190: 28 7a 54 6f 6b 65 6e 2c 22 48 45 41 44 22 29 21  (zToken,"HEAD")!
71a0: 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72  =0 ){.    malfor
71b0: 6d 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20  med_request();. 
71c0: 20 7d 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28   }.  cgi_setenv(
71d0: 22 47 41 54 45 57 41 59 5f 49 4e 54 45 52 46 41  "GATEWAY_INTERFA
71e0: 43 45 22 2c 22 43 47 49 2f 31 2e 30 22 29 3b 0a  CE","CGI/1.0");.
71f0: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45    cgi_setenv("RE
7200: 51 55 45 53 54 5f 4d 45 54 48 4f 44 22 2c 7a 54  QUEST_METHOD",zT
7210: 6f 6b 65 6e 29 3b 0a 20 20 7a 54 6f 6b 65 6e 20  oken);.  zToken 
7220: 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28  = extract_token(
7230: 7a 2c 20 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54  z, &z);.  if( zT
7240: 6f 6b 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d  oken==0 ){.    m
7250: 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74  alformed_request
7260: 28 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f 73 65  ();.  }.  cgi_se
7270: 74 65 6e 76 28 22 52 45 51 55 45 53 54 5f 55 52  tenv("REQUEST_UR
7280: 49 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 66  I", zToken);.  f
7290: 6f 72 28 69 3d 30 3b 20 7a 54 6f 6b 65 6e 5b 69  or(i=0; zToken[i
72a0: 5d 20 26 26 20 7a 54 6f 6b 65 6e 5b 69 5d 21 3d  ] && zToken[i]!=
72b0: 27 3f 27 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69 66  '?'; i++){}.  if
72c0: 28 20 7a 54 6f 6b 65 6e 5b 69 5d 20 29 20 7a 54  ( zToken[i] ) zT
72d0: 6f 6b 65 6e 5b 69 2b 2b 5d 20 3d 20 30 3b 0a 20  oken[i++] = 0;. 
72e0: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 50 41 54   cgi_setenv("PAT
72f0: 48 5f 49 4e 46 4f 22 2c 20 7a 54 6f 6b 65 6e 29  H_INFO", zToken)
7300: 3b 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22  ;.  cgi_setenv("
7310: 51 55 45 52 59 5f 53 54 52 49 4e 47 22 2c 20 26  QUERY_STRING", &
7320: 7a 54 6f 6b 65 6e 5b 69 5d 29 3b 0a 20 20 69 66  zToken[i]);.  if
7330: 28 20 67 65 74 70 65 65 72 6e 61 6d 65 28 66 69  ( getpeername(fi
7340: 6c 65 6e 6f 28 73 74 64 69 6e 29 2c 20 28 73 74  leno(stdin), (st
7350: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26  ruct sockaddr*)&
7360: 72 65 6d 6f 74 65 4e 61 6d 65 2c 20 26 73 69 7a  remoteName, &siz
7370: 65 29 3e 3d 30 20 29 7b 0a 20 20 20 20 63 68 61  e)>=0 ){.    cha
7380: 72 20 2a 7a 49 70 41 64 64 72 20 3d 20 69 6e 65  r *zIpAddr = ine
7390: 74 5f 6e 74 6f 61 28 72 65 6d 6f 74 65 4e 61 6d  t_ntoa(remoteNam
73a0: 65 2e 73 69 6e 5f 61 64 64 72 29 3b 0a 20 20 20  e.sin_addr);.   
73b0: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45 4d   cgi_setenv("REM
73c0: 4f 54 45 5f 41 44 44 52 22 2c 20 7a 49 70 41 64  OTE_ADDR", zIpAd
73d0: 64 72 29 3b 0a 0a 20 20 20 20 2f 2a 20 53 65 74  dr);..    /* Set
73e0: 20 74 68 65 20 47 6c 6f 62 61 6c 2e 7a 49 70 41   the Global.zIpA
73f0: 64 64 72 20 76 61 72 69 61 62 6c 65 20 74 6f 20  ddr variable to 
7400: 74 68 65 20 73 65 72 76 65 72 20 77 65 20 61 72  the server we ar
7410: 65 20 74 61 6c 6b 69 6e 67 20 74 6f 2e 0a 20 20  e talking to..  
7420: 20 20 2a 2a 20 54 68 69 73 20 69 73 20 75 73 65    ** This is use
7430: 64 20 74 6f 20 70 6f 70 75 6c 61 74 65 20 74 68  d to populate th
7440: 65 20 69 70 61 64 64 72 20 63 6f 6c 75 6d 6e 20  e ipaddr column 
7450: 6f 66 20 74 68 65 20 72 63 76 66 72 6f 6d 20 74  of the rcvfrom t
7460: 61 62 6c 65 2c 0a 20 20 20 20 2a 2a 20 69 66 20  able,.    ** if 
7470: 61 6e 79 20 66 69 6c 65 73 20 61 72 65 20 72 65  any files are re
7480: 63 65 69 76 65 64 20 66 72 6f 6d 20 74 68 65 20  ceived from the 
7490: 63 6f 6e 6e 65 63 74 65 64 20 63 6c 69 65 6e 74  connected client
74a0: 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 67 2e 7a  ..    */.    g.z
74b0: 49 70 41 64 64 72 20 3d 20 6d 70 72 69 6e 74 66  IpAddr = mprintf
74c0: 28 22 25 73 22 2c 20 7a 49 70 41 64 64 72 29 3b  ("%s", zIpAddr);
74d0: 0a 20 20 7d 0a 20 0a 20 20 2f 2a 20 47 65 74 20  .  }. .  /* Get 
74e0: 61 6c 6c 20 74 68 65 20 6f 70 74 69 6f 6e 61 6c  all the optional
74f0: 20 66 69 65 6c 64 73 20 74 68 61 74 20 66 6f 6c   fields that fol
7500: 6c 6f 77 20 74 68 65 20 66 69 72 73 74 20 6c 69  low the first li
7510: 6e 65 2e 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65  ne..  */.  while
7520: 28 20 66 67 65 74 73 28 7a 4c 69 6e 65 2c 73 69  ( fgets(zLine,si
7530: 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c 73 74 64 69  zeof(zLine),stdi
7540: 6e 29 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a  n) ){.    char *
7550: 7a 46 69 65 6c 64 4e 61 6d 65 3b 0a 20 20 20 20  zFieldName;.    
7560: 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 0a 20 20 20  char *zVal;..   
7570: 20 7a 46 69 65 6c 64 4e 61 6d 65 20 3d 20 65 78   zFieldName = ex
7580: 74 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e  tract_token(zLin
7590: 65 2c 26 7a 56 61 6c 29 3b 0a 20 20 20 20 69 66  e,&zVal);.    if
75a0: 28 20 7a 46 69 65 6c 64 4e 61 6d 65 3d 3d 30 20  ( zFieldName==0 
75b0: 7c 7c 20 2a 7a 46 69 65 6c 64 4e 61 6d 65 3d 3d  || *zFieldName==
75c0: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 77  0 ) break;.    w
75d0: 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a  hile( isspace(*z
75e0: 56 61 6c 29 20 29 7b 20 7a 56 61 6c 2b 2b 3b 20  Val) ){ zVal++; 
75f0: 7d 0a 20 20 20 20 69 20 3d 20 73 74 72 6c 65 6e  }.    i = strlen
7600: 28 7a 56 61 6c 29 3b 0a 20 20 20 20 77 68 69 6c  (zVal);.    whil
7610: 65 28 20 69 3e 30 20 26 26 20 69 73 73 70 61 63  e( i>0 && isspac
7620: 65 28 7a 56 61 6c 5b 69 2d 31 5d 29 20 29 7b 20  e(zVal[i-1]) ){ 
7630: 69 2d 2d 3b 20 7d 0a 20 20 20 20 7a 56 61 6c 5b  i--; }.    zVal[
7640: 69 5d 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28  i] = 0;.    for(
7650: 69 3d 30 3b 20 7a 46 69 65 6c 64 4e 61 6d 65 5b  i=0; zFieldName[
7660: 69 5d 3b 20 69 2b 2b 29 7b 20 7a 46 69 65 6c 64  i]; i++){ zField
7670: 4e 61 6d 65 5b 69 5d 20 3d 20 74 6f 6c 6f 77 65  Name[i] = tolowe
7680: 72 28 7a 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 29  r(zFieldName[i])
7690: 3b 20 7d 0a 20 20 20 20 69 66 28 20 73 74 72 63  ; }.    if( strc
76a0: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 75  mp(zFieldName,"u
76b0: 73 65 72 2d 61 67 65 6e 74 3a 22 29 3d 3d 30 20  ser-agent:")==0 
76c0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74  ){.      cgi_set
76d0: 65 6e 76 28 22 48 54 54 50 5f 55 53 45 52 5f 41  env("HTTP_USER_A
76e0: 47 45 4e 54 22 2c 20 7a 56 61 6c 29 3b 0a 20 20  GENT", zVal);.  
76f0: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63    }else if( strc
7700: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 63  mp(zFieldName,"c
7710: 6f 6e 74 65 6e 74 2d 6c 65 6e 67 74 68 3a 22 29  ontent-length:")
7720: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69  ==0 ){.      cgi
7730: 5f 73 65 74 65 6e 76 28 22 43 4f 4e 54 45 4e 54  _setenv("CONTENT
7740: 5f 4c 45 4e 47 54 48 22 2c 20 7a 56 61 6c 29 3b  _LENGTH", zVal);
7750: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73  .    }else if( s
7760: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65  trcmp(zFieldName
7770: 2c 22 72 65 66 65 72 65 72 3a 22 29 3d 3d 30 20  ,"referer:")==0 
7780: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74  ){.      cgi_set
7790: 65 6e 76 28 22 48 54 54 50 5f 52 45 46 45 52 45  env("HTTP_REFERE
77a0: 52 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d  R", zVal);.    }
77b0: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28  else if( strcmp(
77c0: 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 68 6f 73 74  zFieldName,"host
77d0: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  :")==0 ){.      
77e0: 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50  cgi_setenv("HTTP
77f0: 5f 48 4f 53 54 22 2c 20 7a 56 61 6c 29 3b 0a 20  _HOST", zVal);. 
7800: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72     }else if( str
7810: 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22  cmp(zFieldName,"
7820: 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 22 29 3d  content-type:")=
7830: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  =0 ){.      cgi_
7840: 73 65 74 65 6e 76 28 22 43 4f 4e 54 45 4e 54 5f  setenv("CONTENT_
7850: 54 59 50 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20  TYPE", zVal);.  
7860: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63    }else if( strc
7870: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 63  mp(zFieldName,"c
7880: 6f 6f 6b 69 65 3a 22 29 3d 3d 30 20 29 7b 0a 20  ookie:")==0 ){. 
7890: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28       cgi_setenv(
78a0: 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 2c 20 7a  "HTTP_COOKIE", z
78b0: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20  Val);.    }else 
78c0: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c  if( strcmp(zFiel
78d0: 64 4e 61 6d 65 2c 22 69 66 2d 6e 6f 6e 65 2d 6d  dName,"if-none-m
78e0: 61 74 63 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20  atch:")==0 ){.  
78f0: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22      cgi_setenv("
7900: 48 54 54 50 5f 49 46 5f 4e 4f 4e 45 5f 4d 41 54  HTTP_IF_NONE_MAT
7910: 43 48 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20  CH", zVal);.    
7920: 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70  }else if( strcmp
7930: 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d  (zFieldName,"if-
7940: 6d 6f 64 69 66 69 65 64 2d 73 69 6e 63 65 3a 22  modified-since:"
7950: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67  )==0 ){.      cg
7960: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 49  i_setenv("HTTP_I
7970: 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 4e 43 45  F_MODIFIED_SINCE
7980: 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 0a  ", zVal);.    }.
7990: 20 20 7d 0a 0a 20 20 63 67 69 5f 69 6e 69 74 28    }..  cgi_init(
79a0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 78 69  );.}../*.** Maxi
79b0: 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 63 68  mum number of ch
79c0: 69 6c 64 20 70 72 6f 63 65 73 73 65 73 20 74 68  ild processes th
79d0: 61 74 20 77 65 20 63 61 6e 20 68 61 76 65 20 72  at we can have r
79e0: 75 6e 6e 69 6e 67 0a 2a 2a 20 61 74 20 6f 6e 65  unning.** at one
79f0: 20 74 69 6d 65 20 62 65 66 6f 72 65 20 77 65 20   time before we 
7a00: 73 74 61 72 74 20 73 6c 6f 77 69 6e 67 20 74 68  start slowing th
7a10: 69 6e 67 73 20 64 6f 77 6e 2e 0a 2a 2f 0a 23 64  ings down..*/.#d
7a20: 65 66 69 6e 65 20 4d 41 58 5f 50 41 52 41 4c 4c  efine MAX_PARALL
7a30: 45 4c 20 32 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c  EL 2../*.** Impl
7a40: 65 6d 65 6e 74 20 61 6e 20 48 54 54 50 20 73 65  ement an HTTP se
7a50: 72 76 65 72 20 64 61 65 6d 6f 6e 20 6c 69 73 74  rver daemon list
7a60: 65 6e 69 6e 67 20 6f 6e 20 70 6f 72 74 20 69 50  ening on port iP
7a70: 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 41 73 20 6e 65  ort..**.** As ne
7a80: 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72  w connections ar
7a90: 72 69 76 65 2c 20 66 6f 72 6b 20 61 20 63 68 69  rive, fork a chi
7aa0: 6c 64 20 61 6e 64 20 6c 65 74 20 63 68 69 6c 64  ld and let child
7ab0: 20 72 65 74 75 72 6e 0a 2a 2a 20 6f 75 74 20 6f   return.** out o
7ac0: 66 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65  f this procedure
7ad0: 20 63 61 6c 6c 2e 20 20 54 68 65 20 63 68 69 6c   call.  The chil
7ae0: 64 20 77 69 6c 6c 20 68 61 6e 64 6c 65 20 74 68  d will handle th
7af0: 65 20 72 65 71 75 65 73 74 2e 0a 2a 2a 20 54 68  e request..** Th
7b00: 65 20 70 61 72 65 6e 74 20 6e 65 76 65 72 20 72  e parent never r
7b10: 65 74 75 72 6e 73 20 66 72 6f 6d 20 74 68 69 73  eturns from this
7b20: 20 70 72 6f 63 65 64 75 72 65 2e 0a 2a 2f 0a 76   procedure..*/.v
7b30: 6f 69 64 20 63 67 69 5f 68 74 74 70 5f 73 65 72  oid cgi_http_ser
7b40: 76 65 72 28 69 6e 74 20 69 50 6f 72 74 29 7b 0a  ver(int iPort){.
7b50: 23 69 66 64 65 66 20 5f 5f 4d 49 4e 47 57 33 32  #ifdef __MINGW32
7b60: 5f 5f 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64  __.  fprintf(std
7b70: 65 72 72 2c 22 73 65 72 76 65 72 20 6e 6f 74 20  err,"server not 
7b80: 79 65 74 20 61 76 61 69 6c 61 62 6c 65 20 69 6e  yet available in
7b90: 20 77 69 6e 64 6f 77 73 20 76 65 72 73 69 6f 6e   windows version
7ba0: 20 6f 66 20 66 6f 73 73 69 6c 5c 6e 22 29 3b 0a   of fossil\n");.
7bb0: 20 20 65 78 69 74 28 31 29 3b 0a 23 65 6c 73 65    exit(1);.#else
7bc0: 0a 20 20 69 6e 74 20 6c 69 73 74 65 6e 65 72 3b  .  int listener;
7bd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7be0: 2f 2a 20 54 68 65 20 73 65 72 76 65 72 20 73 6f  /* The server so
7bf0: 63 6b 65 74 20 2a 2f 0a 20 20 69 6e 74 20 63 6f  cket */.  int co
7c00: 6e 6e 65 63 74 69 6f 6e 3b 20 20 20 20 20 20 20  nnection;       
7c10: 20 20 20 20 20 20 20 2f 2a 20 41 20 73 6f 63 6b         /* A sock
7c20: 65 74 20 66 6f 72 20 65 61 63 68 20 69 6e 64 69  et for each indi
7c30: 76 69 64 75 61 6c 20 63 6f 6e 6e 65 63 74 69 6f  vidual connectio
7c40: 6e 20 2a 2f 0a 20 20 66 64 5f 73 65 74 20 72 65  n */.  fd_set re
7c50: 61 64 66 64 73 3b 20 20 20 20 20 20 20 20 20 20  adfds;          
7c60: 20 20 20 20 2f 2a 20 53 65 74 20 6f 66 20 66 69      /* Set of fi
7c70: 6c 65 20 64 65 73 63 72 69 70 74 6f 72 73 20 66  le descriptors f
7c80: 6f 72 20 73 65 6c 65 63 74 28 29 20 2a 2f 0a 20  or select() */. 
7c90: 20 73 69 7a 65 5f 74 20 6c 65 6e 61 64 64 72 3b   size_t lenaddr;
7ca0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
7cb0: 20 4c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 69   Length of the i
7cc0: 6e 61 64 64 72 20 73 74 72 75 63 74 75 72 65 20  naddr structure 
7cd0: 2a 2f 0a 20 20 69 6e 74 20 63 68 69 6c 64 3b 20  */.  int child; 
7ce0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7cf0: 20 20 2f 2a 20 50 49 44 20 6f 66 20 74 68 65 20    /* PID of the 
7d00: 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 2a 2f  child process */
7d10: 0a 20 20 69 6e 74 20 6e 63 68 69 6c 64 72 65 6e  .  int nchildren
7d20: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20   = 0;           
7d30: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 68 69  /* Number of chi
7d40: 6c 64 20 70 72 6f 63 65 73 73 65 73 20 2a 2f 0a  ld processes */.
7d50: 20 20 73 74 72 75 63 74 20 74 69 6d 65 76 61 6c    struct timeval
7d60: 20 64 65 6c 61 79 3b 20 20 20 20 20 20 20 20 2f   delay;        /
7d70: 2a 20 48 6f 77 20 6c 6f 6e 67 20 74 6f 20 77 61  * How long to wa
7d80: 69 74 20 69 6e 73 69 64 65 20 73 65 6c 65 63 74  it inside select
7d90: 28 29 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 73  () */.  struct s
7da0: 6f 63 6b 61 64 64 72 5f 69 6e 20 69 6e 61 64 64  ockaddr_in inadd
7db0: 72 3b 20 20 20 2f 2a 20 54 68 65 20 73 6f 63 6b  r;   /* The sock
7dc0: 65 74 20 61 64 64 72 65 73 73 20 2a 2f 0a 20 20  et address */.  
7dd0: 69 6e 74 20 6f 70 74 20 3d 20 31 3b 20 20 20 20  int opt = 1;    
7de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7df0: 73 65 74 73 6f 63 6b 6f 70 74 20 66 6c 61 67 20  setsockopt flag 
7e00: 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 26 69 6e  */..  memset(&in
7e10: 61 64 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28  addr, 0, sizeof(
7e20: 69 6e 61 64 64 72 29 29 3b 0a 20 20 69 6e 61 64  inaddr));.  inad
7e30: 64 72 2e 73 69 6e 5f 66 61 6d 69 6c 79 20 3d 20  dr.sin_family = 
7e40: 41 46 5f 49 4e 45 54 3b 0a 20 20 69 6e 61 64 64  AF_INET;.  inadd
7e50: 72 2e 73 69 6e 5f 61 64 64 72 2e 73 5f 61 64 64  r.sin_addr.s_add
7e60: 72 20 3d 20 49 4e 41 44 44 52 5f 41 4e 59 3b 0a  r = INADDR_ANY;.
7e70: 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f 70 6f 72    inaddr.sin_por
7e80: 74 20 3d 20 68 74 6f 6e 73 28 69 50 6f 72 74 29  t = htons(iPort)
7e90: 3b 0a 20 20 6c 69 73 74 65 6e 65 72 20 3d 20 73  ;.  listener = s
7ea0: 6f 63 6b 65 74 28 41 46 5f 49 4e 45 54 2c 20 53  ocket(AF_INET, S
7eb0: 4f 43 4b 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a  OCK_STREAM, 0);.
7ec0: 20 20 69 66 28 20 6c 69 73 74 65 6e 65 72 3c 30    if( listener<0
7ed0: 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 66 28   ){.    fprintf(
7ee0: 73 74 64 65 72 72 2c 22 43 61 6e 27 74 20 63 72  stderr,"Can't cr
7ef0: 65 61 74 65 20 61 20 73 6f 63 6b 65 74 5c 6e 22  eate a socket\n"
7f00: 29 3b 0a 20 20 20 20 65 78 69 74 28 31 29 3b 0a  );.    exit(1);.
7f10: 20 20 7d 0a 0a 20 20 2f 2a 20 69 66 20 77 65 20    }..  /* if we 
7f20: 63 61 6e 27 74 20 74 65 72 6d 69 6e 61 74 65 20  can't terminate 
7f30: 6e 69 63 65 6c 79 2c 20 61 74 20 6c 65 61 73 74  nicely, at least
7f40: 20 61 6c 6c 6f 77 20 74 68 65 20 73 6f 63 6b 65   allow the socke
7f50: 74 20 74 6f 20 62 65 20 72 65 75 73 65 64 20 2a  t to be reused *
7f60: 2f 0a 20 20 73 65 74 73 6f 63 6b 6f 70 74 28 6c  /.  setsockopt(l
7f70: 69 73 74 65 6e 65 72 2c 53 4f 4c 5f 53 4f 43 4b  istener,SOL_SOCK
7f80: 45 54 2c 53 4f 5f 52 45 55 53 45 41 44 44 52 2c  ET,SO_REUSEADDR,
7f90: 26 6f 70 74 2c 73 69 7a 65 6f 66 28 6f 70 74 29  &opt,sizeof(opt)
7fa0: 29 3b 0a 0a 20 20 69 66 28 20 62 69 6e 64 28 6c  );..  if( bind(l
7fb0: 69 73 74 65 6e 65 72 2c 20 28 73 74 72 75 63 74  istener, (struct
7fc0: 20 73 6f 63 6b 61 64 64 72 2a 29 26 69 6e 61 64   sockaddr*)&inad
7fd0: 64 72 2c 20 73 69 7a 65 6f 66 28 69 6e 61 64 64  dr, sizeof(inadd
7fe0: 72 29 29 3c 30 20 29 7b 0a 20 20 20 20 66 70 72  r))<0 ){.    fpr
7ff0: 69 6e 74 66 28 73 74 64 65 72 72 2c 22 43 61 6e  intf(stderr,"Can
8000: 27 74 20 62 69 6e 64 20 74 6f 20 70 6f 72 74 20  't bind to port 
8010: 25 64 5c 6e 22 2c 20 69 50 6f 72 74 29 3b 0a 20  %d\n", iPort);. 
8020: 20 20 20 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a     exit(1);.  }.
8030: 20 20 6c 69 73 74 65 6e 28 6c 69 73 74 65 6e 65    listen(listene
8040: 72 2c 31 30 29 3b 0a 20 20 77 68 69 6c 65 28 20  r,10);.  while( 
8050: 31 20 29 7b 0a 20 20 20 20 69 66 28 20 6e 63 68  1 ){.    if( nch
8060: 69 6c 64 72 65 6e 3e 4d 41 58 5f 50 41 52 41 4c  ildren>MAX_PARAL
8070: 4c 45 4c 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20  LEL ){.      /* 
8080: 53 6c 6f 77 20 64 6f 77 6e 20 69 66 20 63 6f 6e  Slow down if con
8090: 6e 65 63 74 69 6f 6e 73 20 61 72 65 20 61 72 72  nections are arr
80a0: 69 76 69 6e 67 20 74 6f 6f 20 66 61 73 74 20 2a  iving too fast *
80b0: 2f 0a 20 20 20 20 20 20 73 6c 65 65 70 28 20 6e  /.      sleep( n
80c0: 63 68 69 6c 64 72 65 6e 2d 4d 41 58 5f 50 41 52  children-MAX_PAR
80d0: 41 4c 4c 45 4c 20 29 3b 0a 20 20 20 20 7d 0a 20  ALLEL );.    }. 
80e0: 20 20 20 64 65 6c 61 79 2e 74 76 5f 73 65 63 20     delay.tv_sec 
80f0: 3d 20 36 30 3b 0a 20 20 20 20 64 65 6c 61 79 2e  = 60;.    delay.
8100: 74 76 5f 75 73 65 63 20 3d 20 30 3b 0a 20 20 20  tv_usec = 0;.   
8110: 20 46 44 5f 5a 45 52 4f 28 26 72 65 61 64 66 64   FD_ZERO(&readfd
8120: 73 29 3b 0a 20 20 20 20 46 44 5f 53 45 54 28 20  s);.    FD_SET( 
8130: 6c 69 73 74 65 6e 65 72 2c 20 26 72 65 61 64 66  listener, &readf
8140: 64 73 29 3b 0a 20 20 20 20 69 66 28 20 73 65 6c  ds);.    if( sel
8150: 65 63 74 28 20 6c 69 73 74 65 6e 65 72 2b 31 2c  ect( listener+1,
8160: 20 26 72 65 61 64 66 64 73 2c 20 30 2c 20 30 2c   &readfds, 0, 0,
8170: 20 26 64 65 6c 61 79 29 20 29 7b 0a 20 20 20 20   &delay) ){.    
8180: 20 20 6c 65 6e 61 64 64 72 20 3d 20 73 69 7a 65    lenaddr = size
8190: 6f 66 28 69 6e 61 64 64 72 29 3b 0a 20 20 20 20  of(inaddr);.    
81a0: 20 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 3d 20 61    connection = a
81b0: 63 63 65 70 74 28 6c 69 73 74 65 6e 65 72 2c 20  ccept(listener, 
81c0: 28 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72  (struct sockaddr
81d0: 2a 29 26 69 6e 61 64 64 72 2c 20 26 6c 65 6e 61  *)&inaddr, &lena
81e0: 64 64 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20  ddr);.      if( 
81f0: 63 6f 6e 6e 65 63 74 69 6f 6e 3e 3d 30 20 29 7b  connection>=0 ){
8200: 0a 20 20 20 20 20 20 20 20 63 68 69 6c 64 20 3d  .        child =
8210: 20 66 6f 72 6b 28 29 3b 0a 20 20 20 20 20 20 20   fork();.       
8220: 20 69 66 28 20 63 68 69 6c 64 21 3d 30 20 29 7b   if( child!=0 ){
8230: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 63  .          if( c
8240: 68 69 6c 64 3e 30 20 29 20 6e 63 68 69 6c 64 72  hild>0 ) nchildr
8250: 65 6e 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20  en++;.          
8260: 63 6c 6f 73 65 28 63 6f 6e 6e 65 63 74 69 6f 6e  close(connection
8270: 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65  );.        }else
8280: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73  {.          clos
8290: 65 28 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20  e(0);.          
82a0: 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b  dup(connection);
82b0: 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65  .          close
82c0: 28 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64  (1);.          d
82d0: 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a  up(connection);.
82e0: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 21 67            if( !g
82f0: 2e 66 48 74 74 70 54 72 61 63 65 20 29 7b 0a 20  .fHttpTrace ){. 
8300: 20 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65             close
8310: 28 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  (2);.           
8320: 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29   dup(connection)
8330: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20  ;.          }.  
8340: 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 63 6f          close(co
8350: 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20  nnection);.     
8360: 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20       return;.   
8370: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20       }.      }. 
8380: 20 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75 72 79     }.    /* Bury
8390: 20 64 65 61 64 20 63 68 69 6c 64 72 65 6e 20 2a   dead children *
83a0: 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 77 61 69  /.    while( wai
83b0: 74 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f 48 41  tpid(0, 0, WNOHA
83c0: 4e 47 29 3e 30 20 29 7b 0a 20 20 20 20 20 20 6e  NG)>0 ){.      n
83d0: 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20 20 20  children--;.    
83e0: 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54 20 52  }.  }.  /* NOT R
83f0: 45 41 43 48 45 44 20 2a 2f 20 20 0a 20 20 65 78  EACHED */  .  ex
8400: 69 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a  it(1);.#endif.}.
8410: 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66 20 64  ./*.** Name of d
8420: 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73 2e 0a  ays and months..
8430: 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20  */.static const 
8440: 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d 20 3d  char *azDays[] =
8450: 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22 4d 6f  .    {"Sun", "Mo
8460: 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65 64 22  n", "Tue", "Wed"
8470: 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22 2c 20  , "Thu", "Fri", 
8480: 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61 74 69  "Sat", 0};.stati
8490: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a  c const char *az
84a0: 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20 20 7b  Months[] =.    {
84b0: 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20 22 4d  "Jan", "Feb", "M
84c0: 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d 61 79  ar", "Apr", "May
84d0: 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20 20 22  ", "Jun",.     "
84e0: 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22 53 65  Jul", "Aug", "Se
84f0: 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f 76 22  p", "Oct", "Nov"
8500: 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a 0a 2f  , "Dec", 0};.../
8510: 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61 6e 20  *.** Returns an 
8520: 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 64  RFC822-formatted
8530: 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73 75 69   time string sui
8540: 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50 20 68  table for HTTP h
8550: 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a 2a 2a  eaders, among.**
8560: 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e 0a 2a   other things..*
8570: 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d 65 7a  * Returned timez
8580: 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20 47 4d  one is always GM
8590: 54 20 61 73 20 72 65 71 75 69 72 65 64 20 62 79  T as required by
85a0: 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63 69 66   HTTP/1.1 specif
85b0: 69 63 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 53  ication..**.** S
85c0: 65 65 20 68 74 74 70 3a 2f 2f 77 77 77 2e 66 61  ee http://www.fa
85d0: 71 73 2e 6f 72 67 2f 72 66 63 73 2f 72 66 63 38  qs.org/rfcs/rfc8
85e0: 32 32 2e 68 74 6d 6c 2c 20 73 65 63 74 69 6f 6e  22.html, section
85f0: 20 35 0a 2a 2a 20 61 6e 64 20 68 74 74 70 3a 2f   5.** and http:/
8600: 2f 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66  /www.faqs.org/rf
8610: 63 73 2f 72 66 63 32 36 31 36 2e 68 74 6d 6c 2c  cs/rfc2616.html,
8620: 20 73 65 63 74 69 6f 6e 20 33 2e 33 2e 0a 2a 2f   section 3.3..*/
8630: 0a 63 68 61 72 20 2a 63 67 69 5f 72 66 63 38 32  .char *cgi_rfc82
8640: 32 5f 64 61 74 65 73 74 61 6d 70 28 74 69 6d 65  2_datestamp(time
8650: 5f 74 20 6e 6f 77 29 7b 0a 20 20 73 74 72 75 63  _t now){.  struc
8660: 74 20 74 6d 20 2a 70 54 6d 3b 0a 20 20 70 54 6d  t tm *pTm;.  pTm
8670: 20 3d 20 67 6d 74 69 6d 65 28 26 6e 6f 77 29 3b   = gmtime(&now);
8680: 0a 20 20 69 66 28 20 70 54 6d 3d 3d 30 20 29 20  .  if( pTm==0 ) 
8690: 72 65 74 75 72 6e 20 22 22 3b 0a 20 20 72 65 74  return "";.  ret
86a0: 75 72 6e 20 6d 70 72 69 6e 74 66 28 22 25 73 2c  urn mprintf("%s,
86b0: 20 25 64 20 25 73 20 25 30 32 64 20 25 30 32 64   %d %s %02d %02d
86c0: 3a 25 30 32 64 3a 25 30 32 64 20 47 4d 54 22 2c  :%02d:%02d GMT",
86d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
86e0: 20 20 61 7a 44 61 79 73 5b 70 54 6d 2d 3e 74 6d    azDays[pTm->tm
86f0: 5f 77 64 61 79 5d 2c 20 70 54 6d 2d 3e 74 6d 5f  _wday], pTm->tm_
8700: 6d 64 61 79 2c 20 61 7a 4d 6f 6e 74 68 73 5b 70  mday, azMonths[p
8710: 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d 2c 0a 20 20 20  Tm->tm_mon],.   
8720: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 54                pT
8730: 6d 2d 3e 74 6d 5f 79 65 61 72 2b 31 39 30 30 2c  m->tm_year+1900,
8740: 20 70 54 6d 2d 3e 74 6d 5f 68 6f 75 72 2c 20 70   pTm->tm_hour, p
8750: 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c 20 70 54 6d 2d  Tm->tm_min, pTm-
8760: 3e 74 6d 5f 73 65 63 29 3b 0a 7d 0a 0a 2f 2a 0a  >tm_sec);.}../*.
8770: 2a 2a 20 50 61 72 73 65 20 61 6e 20 52 46 43 38  ** Parse an RFC8
8780: 32 32 2d 66 6f 72 6d 61 74 74 65 64 20 74 69 6d  22-formatted tim
8790: 65 73 74 61 6d 70 20 61 73 20 77 65 27 64 20 65  estamp as we'd e
87a0: 78 70 65 63 74 20 66 72 6f 6d 20 48 54 54 50 20  xpect from HTTP 
87b0: 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20 61 20  and return.** a 
87c0: 55 6e 69 78 20 65 70 6f 63 68 20 74 69 6d 65 2e  Unix epoch time.
87d0: 20 3c 3d 20 7a 65 72 6f 20 69 73 20 72 65 74 75   <= zero is retu
87e0: 72 6e 65 64 20 6f 6e 20 66 61 69 6c 75 72 65 2e  rned on failure.
87f0: 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74  .**.** Note that
8800: 20 74 68 69 73 20 77 6f 6e 27 74 20 68 61 6e 64   this won't hand
8810: 6c 65 20 61 6c 6c 20 74 68 65 20 5f 61 6c 6c 6f  le all the _allo
8820: 77 65 64 5f 20 48 54 54 50 20 66 6f 72 6d 61 74  wed_ HTTP format
8830: 73 2c 20 6a 75 73 74 20 74 68 65 0a 2a 2a 20 6d  s, just the.** m
8840: 6f 73 74 20 70 6f 70 75 6c 61 72 20 6f 6e 65 20  ost popular one 
8850: 28 74 68 65 20 6f 6e 65 20 67 65 6e 65 72 61 74  (the one generat
8860: 65 64 20 62 79 20 63 67 69 5f 72 66 63 38 32 32  ed by cgi_rfc822
8870: 5f 64 61 74 65 73 74 61 6d 70 28 29 2c 20 61 63  _datestamp(), ac
8880: 74 75 61 6c 6c 79 29 2e 0a 2a 2f 0a 74 69 6d 65  tually)..*/.time
8890: 5f 74 20 63 67 69 5f 72 66 63 38 32 32 5f 70 61  _t cgi_rfc822_pa
88a0: 72 73 65 64 61 74 65 28 63 6f 6e 73 74 20 63 68  rsedate(const ch
88b0: 61 72 20 2a 7a 44 61 74 65 29 7b 0a 20 20 73 74  ar *zDate){.  st
88c0: 72 75 63 74 20 74 6d 20 74 3b 0a 20 20 63 68 61  ruct tm t;.  cha
88d0: 72 20 7a 49 67 6e 6f 72 65 5b 31 36 5d 3b 0a 20  r zIgnore[16];. 
88e0: 20 63 68 61 72 20 7a 4d 6f 6e 74 68 5b 31 36 5d   char zMonth[16]
88f0: 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 74 2c 20  ;..  memset(&t, 
8900: 30 2c 20 73 69 7a 65 6f 66 28 74 29 29 3b 0a 20  0, sizeof(t));. 
8910: 20 69 66 28 20 37 3d 3d 73 73 63 61 6e 66 28 7a   if( 7==sscanf(z
8920: 44 61 74 65 2c 20 22 25 31 32 5b 41 2d 5a 61 2d  Date, "%12[A-Za-
8930: 7a 2c 5d 20 25 64 20 25 31 32 5b 41 2d 5a 61 2d  z,] %d %12[A-Za-
8940: 7a 5d 20 25 64 20 25 64 3a 25 64 3a 25 64 22 2c  z] %d %d:%d:%d",
8950: 20 7a 49 67 6e 6f 72 65 2c 0a 20 20 20 20 20 20   zIgnore,.      
8960: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8970: 20 26 74 2e 74 6d 5f 6d 64 61 79 2c 20 7a 4d 6f   &t.tm_mday, zMo
8980: 6e 74 68 2c 20 26 74 2e 74 6d 5f 79 65 61 72 2c  nth, &t.tm_year,
8990: 20 26 74 2e 74 6d 5f 68 6f 75 72 2c 20 26 74 2e   &t.tm_hour, &t.
89a0: 74 6d 5f 6d 69 6e 2c 0a 20 20 20 20 20 20 20 20  tm_min,.        
89b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26                 &
89c0: 74 2e 74 6d 5f 73 65 63 29 29 7b 0a 0a 20 20 20  t.tm_sec)){..   
89d0: 20 69 66 28 20 74 2e 74 6d 5f 79 65 61 72 20 3e   if( t.tm_year >
89e0: 20 31 39 30 30 20 29 20 74 2e 74 6d 5f 79 65 61   1900 ) t.tm_yea
89f0: 72 20 2d 3d 20 31 39 30 30 3b 0a 20 20 20 20 66  r -= 1900;.    f
8a00: 6f 72 28 74 2e 74 6d 5f 6d 6f 6e 3d 30 3b 20 61  or(t.tm_mon=0; a
8a10: 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e  zMonths[t.tm_mon
8a20: 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e 2b 2b 29 7b 0a  ]; t.tm_mon++){.
8a30: 20 20 20 20 20 20 69 66 28 20 21 73 74 72 6e 63        if( !strnc
8a40: 61 73 65 63 6d 70 28 20 61 7a 4d 6f 6e 74 68 73  asecmp( azMonths
8a50: 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c 20 7a 4d 6f 6e  [t.tm_mon], zMon
8a60: 74 68 2c 20 33 20 29 29 7b 0a 20 20 20 20 20 20  th, 3 )){.      
8a70: 20 20 72 65 74 75 72 6e 20 6d 6b 67 6d 74 69 6d    return mkgmtim
8a80: 65 28 26 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20  e(&t);.      }. 
8a90: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75     }.  }..  retu
8aa0: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  rn 0;.}../*.** C
8ab0: 6f 6e 76 65 72 74 20 61 20 73 74 72 75 63 74 20  onvert a struct 
8ac0: 74 6d 2a 20 74 68 61 74 20 72 65 70 72 65 73 65  tm* that represe
8ad0: 6e 74 73 20 61 20 6d 6f 6d 65 6e 74 20 69 6e 20  nts a moment in 
8ae0: 55 54 43 20 69 6e 74 6f 20 74 68 65 20 6e 75 6d  UTC into the num
8af0: 62 65 72 0a 2a 2a 20 6f 66 20 73 65 63 6f 6e 64  ber.** of second
8b00: 73 20 69 6e 20 31 39 37 30 2c 20 55 54 43 2e 0a  s in 1970, UTC..
8b10: 2a 2f 0a 74 69 6d 65 5f 74 20 6d 6b 67 6d 74 69  */.time_t mkgmti
8b20: 6d 65 28 73 74 72 75 63 74 20 74 6d 20 2a 70 29  me(struct tm *p)
8b30: 7b 0a 20 20 74 69 6d 65 5f 74 20 74 3b 0a 20 20  {.  time_t t;.  
8b40: 69 6e 74 20 6e 44 61 79 3b 0a 20 20 69 6e 74 20  int nDay;.  int 
8b50: 69 73 4c 65 61 70 59 72 3b 0a 20 20 2f 2a 20 44  isLeapYr;.  /* D
8b60: 61 79 73 20 69 6e 20 65 61 63 68 20 6d 6f 6e 74  ays in each mont
8b70: 68 3a 20 20 20 20 20 20 20 33 31 2c 20 32 38 2c  h:       31, 28,
8b80: 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33 30 2c   31, 30, 31, 30,
8b90: 20 33 31 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c   31, 31, 30, 31,
8ba0: 20 33 30 2c 20 33 31 20 2a 2f 0a 20 20 73 74 61   30, 31 */.  sta
8bb0: 74 69 63 20 69 6e 74 20 70 72 69 6f 72 44 61 79  tic int priorDay
8bc0: 73 5b 5d 20 20 20 3d 20 7b 20 20 30 2c 20 33 31  s[]   = {  0, 31
8bd0: 2c 20 35 39 2c 20 39 30 2c 31 32 30 2c 31 35 31  , 59, 90,120,151
8be0: 2c 31 38 31 2c 32 31 32 2c 32 34 33 2c 32 37 33  ,181,212,243,273
8bf0: 2c 33 30 34 2c 33 33 34 20 7d 3b 0a 20 20 69 66  ,304,334 };.  if
8c00: 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3c 30 20 29 7b  ( p->tm_mon<0 ){
8c10: 0a 20 20 20 20 69 6e 74 20 6e 59 65 61 72 20 3d  .    int nYear =
8c20: 20 28 31 31 20 2d 20 70 2d 3e 74 6d 5f 6d 6f 6e   (11 - p->tm_mon
8c30: 29 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f  )/12;.    p->tm_
8c40: 79 65 61 72 20 2d 3d 20 6e 59 65 61 72 3b 0a 20  year -= nYear;. 
8c50: 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 20 2b 3d 20     p->tm_mon += 
8c60: 6e 59 65 61 72 2a 31 32 3b 0a 20 20 7d 65 6c 73  nYear*12;.  }els
8c70: 65 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3e  e if( p->tm_mon>
8c80: 31 31 20 29 7b 0a 20 20 20 20 70 2d 3e 74 6d 5f  11 ){.    p->tm_
8c90: 79 65 61 72 20 2b 3d 20 70 2d 3e 74 6d 5f 6d 6f  year += p->tm_mo
8ca0: 6e 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f  n/12;.    p->tm_
8cb0: 6d 6f 6e 20 25 3d 20 31 32 3b 0a 20 20 7d 0a 20  mon %= 12;.  }. 
8cc0: 20 69 73 4c 65 61 70 59 72 20 3d 20 70 2d 3e 74   isLeapYr = p->t
8cd0: 6d 5f 79 65 61 72 25 34 3d 3d 30 20 26 26 20 28  m_year%4==0 && (
8ce0: 70 2d 3e 74 6d 5f 79 65 61 72 25 31 30 30 21 3d  p->tm_year%100!=
8cf0: 30 20 7c 7c 20 28 70 2d 3e 74 6d 5f 79 65 61 72  0 || (p->tm_year
8d00: 2b 33 30 30 29 25 34 30 30 3d 3d 30 29 3b 0a 20  +300)%400==0);. 
8d10: 20 70 2d 3e 74 6d 5f 79 64 61 79 20 3d 20 70 72   p->tm_yday = pr
8d20: 69 6f 72 44 61 79 73 5b 70 2d 3e 74 6d 5f 6d 6f  iorDays[p->tm_mo
8d30: 6e 5d 20 2b 20 70 2d 3e 74 6d 5f 6d 64 61 79 20  n] + p->tm_mday 
8d40: 2d 20 31 3b 0a 20 20 69 66 28 20 69 73 4c 65 61  - 1;.  if( isLea
8d50: 70 59 72 20 26 26 20 70 2d 3e 74 6d 5f 6d 6f 6e  pYr && p->tm_mon
8d60: 3e 31 20 29 20 70 2d 3e 74 6d 5f 79 64 61 79 2b  >1 ) p->tm_yday+
8d70: 2b 3b 0a 20 20 6e 44 61 79 20 3d 20 28 70 2d 3e  +;.  nDay = (p->
8d80: 74 6d 5f 79 65 61 72 2d 37 30 29 2a 33 36 35 20  tm_year-70)*365 
8d90: 2b 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 36 39  + (p->tm_year-69
8da0: 29 2f 34 20 2d 70 2d 3e 74 6d 5f 79 65 61 72 2f  )/4 -p->tm_year/
8db0: 31 30 30 20 2b 20 0a 20 20 20 20 20 20 20 20 20  100 + .         
8dc0: 28 70 2d 3e 74 6d 5f 79 65 61 72 2b 33 30 30 29  (p->tm_year+300)
8dd0: 2f 34 30 30 20 2b 20 70 2d 3e 74 6d 5f 79 64 61  /400 + p->tm_yda
8de0: 79 3b 0a 20 20 74 20 3d 20 28 28 6e 44 61 79 2a  y;.  t = ((nDay*
8df0: 32 34 20 2b 20 70 2d 3e 74 6d 5f 68 6f 75 72 29  24 + p->tm_hour)
8e00: 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 6d 69 6e 29  *60 + p->tm_min)
8e10: 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 73 65 63 3b  *60 + p->tm_sec;
8e20: 0a 20 20 72 65 74 75 72 6e 20 74 3b 0a 7d 0a 0a  .  return t;.}..
8e30: 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 65 20  /*.** Check the 
8e40: 6f 62 6a 65 63 74 54 69 6d 65 20 61 67 61 69 6e  objectTime again
8e50: 73 74 20 74 68 65 20 49 66 2d 4d 6f 64 69 66 69  st the If-Modifi
8e60: 65 64 2d 53 69 6e 63 65 20 72 65 71 75 65 73 74  ed-Since request
8e70: 20 68 65 61 64 65 72 2e 20 49 66 20 74 68 65 0a   header. If the.
8e80: 2a 2a 20 6f 62 6a 65 63 74 20 74 69 6d 65 20 69  ** object time i
8e90: 73 6e 27 74 20 61 6e 79 20 6e 65 77 65 72 20 74  sn't any newer t
8ea0: 68 61 6e 20 74 68 65 20 68 65 61 64 65 72 2c 20  han the header, 
8eb0: 77 65 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 73  we immediately s
8ec0: 65 6e 64 20 62 61 63 6b 0a 2a 2a 20 61 20 33 30  end back.** a 30
8ed0: 34 20 72 65 70 6c 79 20 61 6e 64 20 65 78 69 74  4 reply and exit
8ee0: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 6d 6f  ..*/.void cgi_mo
8ef0: 64 69 66 69 65 64 5f 73 69 6e 63 65 28 74 69 6d  dified_since(tim
8f00: 65 5f 74 20 6f 62 6a 65 63 74 54 69 6d 65 29 7b  e_t objectTime){
8f10: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
8f20: 49 66 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f  If = P("HTTP_IF_
8f30: 4d 4f 44 49 46 49 45 44 5f 53 49 4e 43 45 22 29  MODIFIED_SINCE")
8f40: 3b 0a 20 20 69 66 28 20 7a 49 66 3d 3d 30 20 29  ;.  if( zIf==0 )
8f50: 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 6f   return;.  if( o
8f60: 62 6a 65 63 74 54 69 6d 65 20 3e 20 63 67 69 5f  bjectTime > cgi_
8f70: 72 66 63 38 32 32 5f 70 61 72 73 65 64 61 74 65  rfc822_parsedate
8f80: 28 7a 49 66 29 20 29 20 72 65 74 75 72 6e 3b 0a  (zIf) ) return;.
8f90: 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73    cgi_set_status
8fa0: 28 33 30 34 2c 22 4e 6f 74 20 4d 6f 64 69 66 69  (304,"Not Modifi
8fb0: 65 64 22 29 3b 0a 20 20 63 67 69 5f 72 65 73 65  ed");.  cgi_rese
8fc0: 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63  t_content();.  c
8fd0: 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 78  gi_reply();.  ex
8fe0: 69 74 28 30 29 3b 0a 7d 0a                       it(0);.}.