Hex Artifact Content
Not logged in

Artifact 52f3e41396d013cadf89a89719aa52ab1eb654c8:

File src/cgi.c part of check-in [0a14f18111] - Return a proper error message if the first line of an HTTP requested handed to the "http" command is blank. by drh on 2008-05-14 12:21:23.

0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68  (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76  lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c  ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65  ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73  s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20  tributed in the 
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c  hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20  l be useful,.** 
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20  but WITHOUT ANY 
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75  WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69  t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a  ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54  * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52  Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55   A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20  RPOSE.  See the 
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50  GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f  ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a  r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c  ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20  d have received 
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e  a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63  U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e  .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72  g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69  ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65  te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20  ation, Inc., 59 
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53  Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73  uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31  ton, MA  02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20  307, USA..**.** 
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69  Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20  nformation:.**  
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a   drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68  *   http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a  waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 43 20 66 75 6e 63   contains C func
0380: 74 69 6f 6e 73 20 61 6e 64 20 70 72 6f 63 65 64  tions and proced
0390: 75 72 65 73 20 74 68 61 74 20 70 72 6f 76 69 64  ures that provid
03a0: 65 20 75 73 65 66 75 6c 0a 2a 2a 20 73 65 72 76  e useful.** serv
03b0: 69 63 65 73 20 74 6f 20 43 47 49 20 70 72 6f 67  ices to CGI prog
03c0: 72 61 6d 73 2e 20 20 54 68 65 72 65 20 61 72 65  rams.  There are
03d0: 20 70 72 6f 63 65 64 75 72 65 73 20 66 6f 72 20   procedures for 
03e0: 70 61 72 73 69 6e 67 20 61 6e 64 0a 2a 2a 20 64  parsing and.** d
03f0: 69 73 70 65 6e 73 69 6e 67 20 51 55 45 52 59 5f  ispensing QUERY_
0400: 53 54 52 49 4e 47 20 70 61 72 61 6d 65 74 65 72  STRING parameter
0410: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2c 20 74  s and cookies, t
0420: 68 65 20 22 6d 70 72 69 6e 74 66 28 29 22 0a 2a  he "mprintf()".*
0430: 2a 20 66 6f 72 6d 61 74 74 69 6e 67 20 66 75 6e  * formatting fun
0440: 63 74 69 6f 6e 20 61 6e 64 20 69 74 73 20 63 6f  ction and its co
0450: 75 73 69 6e 73 2c 20 61 6e 64 20 72 6f 75 74 69  usins, and routi
0460: 6e 65 73 20 74 6f 20 65 6e 63 6f 64 65 20 61 6e  nes to encode an
0470: 64 0a 2a 2a 20 64 65 63 6f 64 65 20 73 74 72 69  d.** decode stri
0480: 6e 67 73 20 69 6e 20 48 54 4d 4c 20 6f 72 20 48  ngs in HTML or H
0490: 54 54 50 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  TTP..*/.#include
04a0: 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 66 64   "config.h".#ifd
04b0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 23  ef __MINGW32__.#
04c0: 20 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e 64 6f    include <windo
04d0: 77 73 2e 68 3e 20 20 20 20 20 20 20 20 20 20 20  ws.h>           
04e0: 2f 2a 20 66 6f 72 20 53 6c 65 65 70 20 6f 6e 63  /* for Sleep onc
04f0: 65 20 73 65 72 76 65 72 20 77 6f 72 6b 73 20 61  e server works a
0500: 67 61 69 6e 20 2a 2f 0a 23 20 20 69 6e 63 6c 75  gain */.#  inclu
0510: 64 65 20 3c 77 69 6e 73 6f 63 6b 32 2e 68 3e 20  de <winsock2.h> 
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 6f 63 6b           /* sock
0530: 65 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f  et operations */
0540: 0a 23 20 20 64 65 66 69 6e 65 20 73 6c 65 65 70  .#  define sleep
0550: 20 53 6c 65 65 70 20 20 20 20 20 20 20 20 20 20   Sleep          
0560: 20 20 2f 2a 20 77 69 6e 64 6f 77 73 20 64 6f 65    /* windows doe
0570: 73 20 6e 6f 74 20 68 61 76 65 20 73 6c 65 65 70  s not have sleep
0580: 2c 20 62 75 74 20 53 6c 65 65 70 20 2a 2f 0a 23  , but Sleep */.#
0590: 20 20 69 6e 63 6c 75 64 65 20 3c 77 73 32 74 63    include <ws2tc
05a0: 70 69 70 2e 68 3e 20 20 20 20 20 20 20 20 20 20  pip.h>          
05b0: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64  .#else.#  includ
05c0: 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e  e <sys/socket.h>
05d0: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74  .#  include <net
05e0: 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e  inet/in.h>.#  in
05f0: 63 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74  clude <arpa/inet
0600: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c  .h>.#  include <
0610: 73 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20  sys/times.h>.#  
0620: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d  include <sys/tim
0630: 65 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20  e.h>.#  include 
0640: 3c 73 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20  <sys/wait.h>.#  
0650: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c  include <sys/sel
0660: 65 63 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69  ect.h>.#endif.#i
0670: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a  nclude <time.h>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e  #include <stdio.
0690: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h>.#include <std
06a0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  lib.h>.#include 
06b0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c  <unistd.h>.#incl
06c0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66  ude "cgi.h"..#if
06d0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a   INTERFACE./*.**
06e0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63   Shortcuts for c
06f0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50  gi_parameter.  P
0700: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68  ("x") returns th
0710: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79  e value of query
0720: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72   parameter.** or
0730: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20   cookie "x", or 
0740: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73  NULL if there is
0750: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74   no such paramet
0760: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50  er or cookie.  P
0770: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f  D("x","y").** do
0780: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65  es the same exce
0790: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e  pt "y" is return
07a0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e  ed in place of N
07b0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20  ULL if there is 
07c0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64  not match..*/.#d
07d0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20  efine P(x)      
07e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28    cgi_parameter(
07f0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50  (x),0).#define P
0800: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70  D(x,y)     cgi_p
0810: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29  arameter((x),(y)
0820: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20  ).#define QP(x) 
0830: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73        quotable_s
0840: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65  tring(cgi_parame
0850: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66  ter((x),0)).#def
0860: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20  ine QPD(x,y)    
0870: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28  quotable_string(
0880: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78  cgi_parameter((x
0890: 29 2c 28 79 29 29 29 0a 0a 0a 2f 2a 0a 2a 2a 20  ),(y))).../*.** 
08a0: 44 65 73 74 69 6e 61 74 69 6f 6e 73 20 66 6f 72  Destinations for
08b0: 20 6f 75 74 70 75 74 20 74 65 78 74 2e 0a 2a 2f   output text..*/
08c0: 0a 23 64 65 66 69 6e 65 20 43 47 49 5f 48 45 41  .#define CGI_HEA
08d0: 44 45 52 20 20 20 30 0a 23 64 65 66 69 6e 65 20  DER   0.#define 
08e0: 43 47 49 5f 42 4f 44 59 20 20 20 20 20 31 0a 0a  CGI_BODY     1..
08f0: 23 65 6e 64 69 66 20 2f 2a 20 49 4e 54 45 52 46  #endif /* INTERF
0900: 41 43 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50 72  ACE */../*.** Pr
0910: 6f 76 69 64 65 20 61 20 72 65 6c 69 61 62 6c 65  ovide a reliable
0920: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20   implementation 
0930: 6f 66 20 61 20 63 61 73 65 6c 65 73 73 20 73 74  of a caseless st
0940: 72 69 6e 67 20 63 6f 6d 70 61 72 69 73 6f 6e 0a  ring comparison.
0950: 2a 2a 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a  ** function..*/.
0960: 23 64 65 66 69 6e 65 20 73 74 72 69 63 6d 70 20  #define stricmp 
0970: 73 71 6c 69 74 65 33 53 74 72 49 43 6d 70 0a 65  sqlite3StrICmp.e
0980: 78 74 65 72 6e 20 69 6e 74 20 73 71 6c 69 74 65  xtern int sqlite
0990: 33 53 74 72 49 43 6d 70 28 63 6f 6e 73 74 20 63  3StrICmp(const c
09a0: 68 61 72 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72  har*, const char
09b0: 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 48  *);../*.** The H
09c0: 54 54 50 20 72 65 70 6c 79 20 69 73 20 67 65 6e  TTP reply is gen
09d0: 65 72 61 74 65 64 20 69 6e 20 74 77 6f 20 70 69  erated in two pi
09e0: 65 63 65 73 3a 20 74 68 65 20 68 65 61 64 65 72  eces: the header
09f0: 20 61 6e 64 20 74 68 65 20 62 6f 64 79 2e 0a 2a   and the body..*
0a00: 2a 20 54 68 65 73 65 20 70 69 65 63 65 73 20 61  * These pieces a
0a10: 72 65 20 67 65 6e 65 72 61 74 65 64 20 73 65 70  re generated sep
0a20: 61 72 61 74 65 6c 79 20 62 65 63 61 75 73 65 20  arately because 
0a30: 74 68 65 79 20 61 72 65 20 6e 6f 74 20 6e 65 63  they are not nec
0a40: 65 73 73 61 72 79 0a 2a 2a 20 70 72 6f 64 75 63  essary.** produc
0a50: 65 64 20 69 6e 20 6f 72 64 65 72 2e 20 20 50 61  ed in order.  Pa
0a60: 72 74 73 20 6f 66 20 74 68 65 20 68 65 61 64 65  rts of the heade
0a70: 72 20 6d 69 67 68 74 20 62 65 20 62 75 69 6c 74  r might be built
0a80: 20 61 66 74 65 72 20 61 6c 6c 20 6f 72 0a 2a 2a   after all or.**
0a90: 20 70 61 72 74 20 6f 66 20 74 68 65 20 62 6f 64   part of the bod
0aa0: 79 2e 20 20 54 68 65 20 68 65 61 64 65 72 20 61  y.  The header a
0ab0: 6e 64 20 62 6f 64 79 20 61 72 65 20 61 63 63 75  nd body are accu
0ac0: 6d 75 6c 61 74 65 64 20 69 6e 20 73 65 70 61 72  mulated in separ
0ad0: 61 74 65 0a 2a 2a 20 42 6c 6f 62 20 73 74 72 75  ate.** Blob stru
0ae0: 63 74 75 72 65 73 20 74 68 65 6e 20 6f 75 74 70  ctures then outp
0af0: 75 74 20 73 65 71 75 65 6e 74 69 61 6c 6c 79 20  ut sequentially 
0b00: 6f 6e 63 65 20 65 76 65 72 79 74 68 69 6e 67 20  once everything 
0b10: 68 61 73 20 62 65 65 6e 0a 2a 2a 20 62 75 69 6c  has been.** buil
0b20: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 67 69  t..**.** The cgi
0b30: 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 29 20 69  _destination() i
0b40: 6e 74 65 72 66 61 63 65 20 73 77 69 74 63 68 20  nterface switch 
0b50: 62 65 74 77 65 65 6e 20 74 68 65 20 62 75 66 66  between the buff
0b60: 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42  ers..*/.static B
0b70: 6c 6f 62 20 63 67 69 43 6f 6e 74 65 6e 74 5b 32  lob cgiContent[2
0b80: 5d 20 3d 20 7b 20 42 4c 4f 42 5f 49 4e 49 54 49  ] = { BLOB_INITI
0b90: 41 4c 49 5a 45 52 2c 20 42 4c 4f 42 5f 49 4e 49  ALIZER, BLOB_INI
0ba0: 54 49 41 4c 49 5a 45 52 20 7d 3b 0a 73 74 61 74  TIALIZER };.stat
0bb0: 69 63 20 42 6c 6f 62 20 2a 70 43 6f 6e 74 65 6e  ic Blob *pConten
0bc0: 74 20 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b  t = &cgiContent[
0bd0: 30 5d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74  0];../*.** Set t
0be0: 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 62  he destination b
0bf0: 75 66 66 65 72 20 69 6e 74 6f 20 77 68 69 63 68  uffer into which
0c00: 20 74 6f 20 61 63 63 75 6d 75 6c 61 74 65 20 43   to accumulate C
0c10: 47 49 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76  GI content..*/.v
0c20: 6f 69 64 20 63 67 69 5f 64 65 73 74 69 6e 61 74  oid cgi_destinat
0c30: 69 6f 6e 28 69 6e 74 20 64 65 73 74 29 7b 0a 20  ion(int dest){. 
0c40: 20 73 77 69 74 63 68 28 20 64 65 73 74 20 29 7b   switch( dest ){
0c50: 0a 20 20 20 20 63 61 73 65 20 43 47 49 5f 48 45  .    case CGI_HE
0c60: 41 44 45 52 3a 20 7b 0a 20 20 20 20 20 20 70 43  ADER: {.      pC
0c70: 6f 6e 74 65 6e 74 20 3d 20 26 63 67 69 43 6f 6e  ontent = &cgiCon
0c80: 74 65 6e 74 5b 30 5d 3b 0a 20 20 20 20 20 20 62  tent[0];.      b
0c90: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20  reak;.    }.    
0ca0: 63 61 73 65 20 43 47 49 5f 42 4f 44 59 3a 20 7b  case CGI_BODY: {
0cb0: 0a 20 20 20 20 20 20 70 43 6f 6e 74 65 6e 74 20  .      pContent 
0cc0: 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d  = &cgiContent[1]
0cd0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
0ce0: 20 20 20 7d 0a 20 20 20 20 64 65 66 61 75 6c 74     }.    default
0cf0: 3a 20 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 61  : {.      cgi_pa
0d00: 6e 69 63 28 22 62 61 64 20 64 65 73 74 69 6e 61  nic("bad destina
0d10: 74 69 6f 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20  tion");.    }.  
0d20: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e  }.}../*.** Appen
0d30: 64 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20  d reply content 
0d40: 74 6f 20 77 68 61 74 20 61 6c 72 65 61 64 79 20  to what already 
0d50: 65 78 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20  exists..*/.void 
0d60: 63 67 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65  cgi_append_conte
0d70: 6e 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  nt(const char *z
0d80: 44 61 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b  Data, int nAmt){
0d90: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70  .  blob_append(p
0da0: 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c 20  Content, zData, 
0db0: 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  nAmt);.}../*.** 
0dc0: 52 65 73 65 74 20 74 68 65 20 48 54 54 50 20 72  Reset the HTTP r
0dd0: 65 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 20  eply text to be 
0de0: 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 2e  an empty string.
0df0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 73  .*/.void cgi_res
0e00: 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 29  et_content(void)
0e10: 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26  {.  blob_reset(&
0e20: 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a  cgiContent[0]);.
0e30: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67    blob_reset(&cg
0e40: 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 7d 0a  iContent[1]);.}.
0e50: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  ./*.** Return a 
0e60: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43  pointer to the C
0e70: 47 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a  GI output blob..
0e80: 2a 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74  */.Blob *cgi_out
0e90: 70 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a  put_blob(void){.
0ea0: 20 20 72 65 74 75 72 6e 20 70 43 6f 6e 74 65 6e    return pConten
0eb0: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 62  t;.}../*.** Comb
0ec0: 69 6e 65 20 74 68 65 20 68 65 61 64 65 72 20 61  ine the header a
0ed0: 6e 64 20 62 6f 64 79 20 6f 66 20 74 68 65 20 43  nd body of the C
0ee0: 47 49 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65  GI into a single
0ef0: 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74   string..*/.stat
0f00: 69 63 20 76 6f 69 64 20 63 67 69 5f 63 6f 6d 62  ic void cgi_comb
0f10: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62  ine_header_and_b
0f20: 6f 64 79 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74  ody(void){.  int
0f30: 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a   size = blob_siz
0f40: 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d  e(&cgiContent[1]
0f50: 29 3b 0a 20 20 69 66 28 20 73 69 7a 65 3e 30 20  );.  if( size>0 
0f60: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65  ){.    blob_appe
0f70: 6e 64 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30  nd(&cgiContent[0
0f80: 5d 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26  ], blob_buffer(&
0f90: 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 2c 20  cgiContent[1]), 
0fa0: 73 69 7a 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f  size);.    blob_
0fb0: 72 65 73 65 74 28 26 63 67 69 43 6f 6e 74 65 6e  reset(&cgiConten
0fc0: 74 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a  t[1]);.  }.}../*
0fd0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69  .** Return a poi
0fe0: 6e 74 65 72 20 74 6f 20 74 68 65 20 48 54 54 50  nter to the HTTP
0ff0: 20 72 65 70 6c 79 20 74 65 78 74 2e 0a 2a 2f 0a   reply text..*/.
1000: 63 68 61 72 20 2a 63 67 69 5f 65 78 74 72 61 63  char *cgi_extrac
1010: 74 5f 63 6f 6e 74 65 6e 74 28 69 6e 74 20 2a 70  t_content(int *p
1020: 6e 41 6d 74 29 7b 0a 20 20 63 67 69 5f 63 6f 6d  nAmt){.  cgi_com
1030: 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f  bine_header_and_
1040: 62 6f 64 79 28 29 3b 0a 20 20 72 65 74 75 72 6e  body();.  return
1050: 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67   blob_buffer(&cg
1060: 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 7d 0a  iContent[0]);.}.
1070: 0a 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61  ./*.** Additiona
1080: 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73  l information us
1090: 65 64 20 74 6f 20 66 6f 72 6d 20 74 68 65 20 48  ed to form the H
10a0: 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 73 74 61  TTP reply.*/.sta
10b0: 74 69 63 20 63 68 61 72 20 2a 7a 43 6f 6e 74 65  tic char *zConte
10c0: 6e 74 54 79 70 65 20 3d 20 22 74 65 78 74 2f 68  ntType = "text/h
10d0: 74 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 43 6f 6e  tml";     /* Con
10e0: 74 65 6e 74 20 74 79 70 65 20 6f 66 20 74 68 65  tent type of the
10f0: 20 72 65 70 6c 79 20 2a 2f 0a 73 74 61 74 69 63   reply */.static
1100: 20 63 68 61 72 20 2a 7a 52 65 70 6c 79 53 74 61   char *zReplySta
1110: 74 75 73 20 3d 20 22 4f 4b 22 3b 20 20 20 20 20  tus = "OK";     
1120: 20 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20         /* Reply 
1130: 73 74 61 74 75 73 20 64 65 73 63 72 69 70 74 69  status descripti
1140: 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  on */.static int
1150: 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20   iReplyStatus = 
1160: 32 30 30 3b 20 20 20 20 20 20 20 20 20 20 20 20  200;            
1170: 20 20 20 2f 2a 20 52 65 70 6c 79 20 73 74 61 74     /* Reply stat
1180: 75 73 20 63 6f 64 65 20 2a 2f 0a 73 74 61 74 69  us code */.stati
1190: 63 20 42 6c 6f 62 20 65 78 74 72 61 48 65 61 64  c Blob extraHead
11a0: 65 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41  er = BLOB_INITIA
11b0: 4c 49 5a 45 52 3b 20 20 2f 2a 20 45 78 74 72 61  LIZER;  /* Extra
11c0: 20 68 65 61 64 65 72 20 74 65 78 74 20 2a 2f 0a   header text */.
11d0: 73 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 48  static int fullH
11e0: 74 74 70 52 65 70 6c 79 20 3d 20 30 3b 20 20 20  ttpReply = 0;   
11f0: 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 61     /* True for a
1200: 20 66 75 6c 6c 2d 62 6c 6f 77 6e 20 48 54 54 50   full-blown HTTP
1210: 20 68 65 61 64 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a   header */../*.*
1220: 2a 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 20  * Set the reply 
1230: 63 6f 6e 74 65 6e 74 20 74 79 70 65 0a 2a 2f 0a  content type.*/.
1240: 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e  void cgi_set_con
1250: 74 65 6e 74 5f 74 79 70 65 28 63 6f 6e 73 74 20  tent_type(const 
1260: 63 68 61 72 20 2a 7a 54 79 70 65 29 7b 0a 20 20  char *zType){.  
1270: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 6d  zContentType = m
1280: 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 54 79  printf("%s", zTy
1290: 70 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65  pe);.}../*.** Se
12a0: 74 20 74 68 65 20 72 65 70 6c 79 20 63 6f 6e 74  t the reply cont
12b0: 65 6e 74 20 74 6f 20 74 68 65 20 73 70 65 63 69  ent to the speci
12c0: 66 69 65 64 20 42 4c 4f 42 2e 0a 2a 2f 0a 76 6f  fied BLOB..*/.vo
12d0: 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 65  id cgi_set_conte
12e0: 6e 74 28 42 6c 6f 62 20 2a 70 4e 65 77 43 6f 6e  nt(Blob *pNewCon
12f0: 74 65 6e 74 29 7b 0a 20 20 63 67 69 5f 72 65 73  tent){.  cgi_res
1300: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20  et_content();.  
1310: 63 67 69 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28  cgi_destination(
1320: 43 47 49 5f 48 45 41 44 45 52 29 3b 0a 20 20 63  CGI_HEADER);.  c
1330: 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 20 3d 20 2a  giContent[0] = *
1340: 70 4e 65 77 43 6f 6e 74 65 6e 74 3b 0a 20 20 62  pNewContent;.  b
1350: 6c 6f 62 5f 7a 65 72 6f 28 70 4e 65 77 43 6f 6e  lob_zero(pNewCon
1360: 74 65 6e 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  tent);.}../*.** 
1370: 53 65 74 20 74 68 65 20 72 65 70 6c 79 20 73 74  Set the reply st
1380: 61 74 75 73 20 63 6f 64 65 0a 2a 2f 0a 76 6f 69  atus code.*/.voi
1390: 64 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73  d cgi_set_status
13a0: 28 69 6e 74 20 69 53 74 61 74 2c 20 63 6f 6e 73  (int iStat, cons
13b0: 74 20 63 68 61 72 20 2a 7a 53 74 61 74 29 7b 0a  t char *zStat){.
13c0: 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d    zReplyStatus =
13d0: 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a   mprintf("%s", z
13e0: 53 74 61 74 29 3b 0a 20 20 69 52 65 70 6c 79 53  Stat);.  iReplyS
13f0: 74 61 74 75 73 20 3d 20 69 53 74 61 74 3b 0a 7d  tatus = iStat;.}
1400: 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74  ../*.** Append t
1410: 65 78 74 20 74 6f 20 74 68 65 20 68 65 61 64 65  ext to the heade
1420: 72 20 6f 66 20 61 6e 20 48 54 54 50 20 72 65 70  r of an HTTP rep
1430: 6c 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 61  ly.*/.void cgi_a
1440: 70 70 65 6e 64 5f 68 65 61 64 65 72 28 63 6f 6e  ppend_header(con
1450: 73 74 20 63 68 61 72 20 2a 7a 4c 69 6e 65 29 7b  st char *zLine){
1460: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26  .  blob_append(&
1470: 65 78 74 72 61 48 65 61 64 65 72 2c 20 7a 4c 69  extraHeader, zLi
1480: 6e 65 2c 20 2d 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  ne, -1);.}../*.*
1490: 2a 20 53 65 74 20 61 20 63 6f 6f 6b 69 65 2e 0a  * Set a cookie..
14a0: 2a 2a 0a 2a 2a 20 5a 65 72 6f 20 6c 69 66 65 74  **.** Zero lifet
14b0: 69 6d 65 20 69 6d 70 6c 69 65 73 20 61 20 73 65  ime implies a se
14c0: 73 73 69 6f 6e 20 63 6f 6f 6b 69 65 2e 0a 2a 2f  ssion cookie..*/
14d0: 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f  .void cgi_set_co
14e0: 6f 6b 69 65 28 0a 20 20 63 6f 6e 73 74 20 63 68  okie(.  const ch
14f0: 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 2f 2a  ar *zName,    /*
1500: 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 63 6f 6f   Name of the coo
1510: 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  kie */.  const c
1520: 68 61 72 20 2a 7a 56 61 6c 75 65 2c 20 20 20 2f  har *zValue,   /
1530: 2a 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20 63  * Value of the c
1540: 6f 6f 6b 69 65 2e 20 20 41 75 74 6f 6d 61 74 69  ookie.  Automati
1550: 63 61 6c 6c 79 20 65 73 63 61 70 65 64 20 2a 2f  cally escaped */
1560: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
1570: 50 61 74 68 2c 20 20 20 20 2f 2a 20 50 61 74 68  Path,    /* Path
1580: 20 63 6f 6f 6b 69 65 20 61 70 70 6c 69 65 73 20   cookie applies 
1590: 74 6f 2e 20 20 4e 55 4c 4c 20 6d 65 61 6e 73 20  to.  NULL means 
15a0: 22 2f 22 20 2a 2f 0a 20 20 69 6e 74 20 6c 69 66  "/" */.  int lif
15b0: 65 74 69 6d 65 20 20 20 20 20 20 20 20 20 20 2f  etime          /
15c0: 2a 20 45 78 70 69 72 61 74 69 6f 6e 20 6f 66 20  * Expiration of 
15d0: 74 68 65 20 63 6f 6f 6b 69 65 20 69 6e 20 73 65  the cookie in se
15e0: 63 6f 6e 64 73 20 66 72 6f 6d 20 6e 6f 77 20 2a  conds from now *
15f0: 2f 0a 29 7b 0a 20 20 69 66 28 20 7a 50 61 74 68  /.){.  if( zPath
1600: 3d 3d 30 20 29 20 7a 50 61 74 68 20 3d 20 67 2e  ==0 ) zPath = g.
1610: 7a 54 6f 70 3b 0a 20 20 69 66 28 20 6c 69 66 65  zTop;.  if( life
1620: 74 69 6d 65 3e 30 20 29 7b 0a 20 20 20 20 6c 69  time>0 ){.    li
1630: 66 65 74 69 6d 65 20 2b 3d 20 28 69 6e 74 29 74  fetime += (int)t
1640: 69 6d 65 28 30 29 3b 0a 20 20 20 20 62 6c 6f 62  ime(0);.    blob
1650: 5f 61 70 70 65 6e 64 66 28 26 65 78 74 72 61 48  _appendf(&extraH
1660: 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 22 53  eader,.       "S
1670: 65 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d 25 74  et-Cookie: %s=%t
1680: 3b 20 50 61 74 68 3d 25 73 3b 20 65 78 70 69 72  ; Path=%s; expir
1690: 65 73 3d 25 73 3b 20 56 65 72 73 69 6f 6e 3d 31  es=%s; Version=1
16a0: 5c 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 7a  \r\n",.        z
16b0: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50  Name, zValue, zP
16c0: 61 74 68 2c 20 63 67 69 5f 72 66 63 38 32 32 5f  ath, cgi_rfc822_
16d0: 64 61 74 65 73 74 61 6d 70 28 6c 69 66 65 74 69  datestamp(lifeti
16e0: 6d 65 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20  me));.  }else{. 
16f0: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28     blob_appendf(
1700: 26 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20  &extraHeader,.  
1710: 20 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65       "Set-Cookie
1720: 3a 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73  : %s=%t; Path=%s
1730: 3b 20 56 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e 22  ; Version=1\r\n"
1740: 2c 0a 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20  ,.       zName, 
1750: 7a 56 61 6c 75 65 2c 20 7a 50 61 74 68 29 3b 0a  zValue, zPath);.
1760: 20 20 7d 0a 7d 0a 0a 23 69 66 20 30 0a 2f 2a 0a    }.}..#if 0./*.
1770: 2a 2a 20 41 64 64 20 61 6e 20 45 54 61 67 20 68  ** Add an ETag h
1780: 65 61 64 65 72 20 6c 69 6e 65 0a 2a 2f 0a 73 74  eader line.*/.st
1790: 61 74 69 63 20 63 68 61 72 20 2a 63 67 69 5f 61  atic char *cgi_a
17a0: 64 64 5f 65 74 61 67 28 63 68 61 72 20 2a 7a 54  dd_etag(char *zT
17b0: 78 74 2c 20 69 6e 74 20 6e 4c 65 6e 29 7b 0a 20  xt, int nLen){. 
17c0: 20 4d 44 35 43 6f 6e 74 65 78 74 20 63 74 78 3b   MD5Context ctx;
17d0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  .  unsigned char
17e0: 20 64 69 67 65 73 74 5b 31 36 5d 3b 0a 20 20 69   digest[16];.  i
17f0: 6e 74 20 69 2c 20 6a 3b 0a 20 20 63 68 61 72 20  nt i, j;.  char 
1800: 7a 45 54 61 67 5b 36 34 5d 3b 0a 0a 20 20 4d 44  zETag[64];..  MD
1810: 35 49 6e 69 74 28 26 63 74 78 29 3b 0a 20 20 4d  5Init(&ctx);.  M
1820: 44 35 55 70 64 61 74 65 28 26 63 74 78 2c 7a 54  D5Update(&ctx,zT
1830: 78 74 2c 6e 4c 65 6e 29 3b 0a 20 20 4d 44 35 46  xt,nLen);.  MD5F
1840: 69 6e 61 6c 28 64 69 67 65 73 74 2c 26 63 74 78  inal(digest,&ctx
1850: 29 3b 0a 20 20 66 6f 72 28 6a 3d 69 3d 30 3b 20  );.  for(j=i=0; 
1860: 69 3c 31 36 3b 20 69 2b 2b 2c 6a 2b 3d 32 29 7b  i<16; i++,j+=2){
1870: 0a 20 20 20 20 62 70 72 69 6e 74 66 28 26 7a 45  .    bprintf(&zE
1880: 54 61 67 5b 6a 5d 2c 73 69 7a 65 6f 66 28 7a 45  Tag[j],sizeof(zE
1890: 54 61 67 29 2d 6a 2c 22 25 30 32 78 22 2c 28 69  Tag)-j,"%02x",(i
18a0: 6e 74 29 64 69 67 65 73 74 5b 69 5d 29 3b 0a 20  nt)digest[i]);. 
18b0: 20 7d 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64   }.  blob_append
18c0: 66 28 26 65 78 74 72 61 48 65 61 64 65 72 2c 20  f(&extraHeader, 
18d0: 22 45 54 61 67 3a 20 25 73 5c 72 5c 6e 22 2c 20  "ETag: %s\r\n", 
18e0: 7a 45 54 61 67 29 3b 0a 20 20 72 65 74 75 72 6e  zETag);.  return
18f0: 20 73 74 72 64 75 70 28 7a 45 54 61 67 29 3b 0a   strdup(zETag);.
1900: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 73 6f 6d 65  }../*.** Do some
1910: 20 63 61 63 68 65 20 63 6f 6e 74 72 6f 6c 20 73   cache control s
1920: 74 75 66 66 2e 20 46 69 72 73 74 2c 20 77 65 20  tuff. First, we 
1930: 67 65 6e 65 72 61 74 65 20 61 6e 20 45 54 61 67  generate an ETag
1940: 20 61 6e 64 20 69 6e 63 6c 75 64 65 20 69 74 20   and include it 
1950: 69 6e 0a 2a 2a 20 74 68 65 20 72 65 73 70 6f 6e  in.** the respon
1960: 73 65 20 68 65 61 64 65 72 73 2e 20 53 65 63 6f  se headers. Seco
1970: 6e 64 2c 20 77 65 20 64 6f 20 77 68 61 74 65 76  nd, we do whatev
1980: 65 72 20 69 73 20 6e 65 63 65 73 73 61 72 79 20  er is necessary 
1990: 74 6f 20 64 65 74 65 72 6d 69 6e 65 20 69 66 0a  to determine if.
19a0: 2a 2a 20 74 68 65 20 72 65 71 75 65 73 74 20 77  ** the request w
19b0: 61 73 20 61 73 6b 69 6e 67 20 61 62 6f 75 74 20  as asking about 
19c0: 63 61 63 68 69 6e 67 20 61 6e 64 20 77 68 65 74  caching and whet
19d0: 68 65 72 20 77 65 20 6e 65 65 64 20 74 6f 20 73  her we need to s
19e0: 65 6e 64 20 62 61 63 6b 20 74 68 65 0a 2a 2a 20  end back the.** 
19f0: 72 65 73 70 6f 6e 73 65 20 62 6f 64 79 2e 20 49  response body. I
1a00: 66 20 77 65 20 73 68 6f 75 6c 64 6e 27 74 20 73  f we shouldn't s
1a10: 65 6e 64 20 61 20 62 6f 64 79 2c 20 72 65 74 75  end a body, retu
1a20: 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a  rn non-zero..**.
1a30: 2a 2a 20 43 75 72 72 65 6e 74 6c 79 2c 20 77 65  ** Currently, we
1a40: 20 6a 75 73 74 20 63 68 65 63 6b 20 74 68 65 20   just check the 
1a50: 45 54 61 67 20 61 67 61 69 6e 73 74 20 61 6e 79  ETag against any
1a60: 20 49 66 2d 4e 6f 6e 65 2d 4d 61 74 63 68 20 68   If-None-Match h
1a70: 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 46 49 58  eader..**.** FIX
1a80: 4d 45 3a 20 49 6e 20 73 6f 6d 65 20 63 61 73 65  ME: In some case
1a90: 73 20 28 61 74 74 61 63 68 6d 65 6e 74 73 2c 20  s (attachments, 
1aa0: 66 69 6c 65 20 63 6f 6e 74 65 6e 74 73 29 20 77  file contents) w
1ab0: 65 20 63 6f 75 6c 64 20 63 68 65 63 6b 0a 2a 2a  e could check.**
1ac0: 20 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e   If-Modified-Sin
1ad0: 63 65 20 68 65 61 64 65 72 73 20 61 6e 64 20 61  ce headers and a
1ae0: 6c 77 61 79 73 20 69 6e 63 6c 75 64 65 20 4c 61  lways include La
1af0: 73 74 2d 4d 6f 64 69 66 69 65 64 20 69 6e 20 72  st-Modified in r
1b00: 65 73 70 6f 6e 73 65 73 2e 0a 2a 2f 0a 73 74 61  esponses..*/.sta
1b10: 74 69 63 20 69 6e 74 20 63 68 65 63 6b 5f 63 61  tic int check_ca
1b20: 63 68 65 5f 63 6f 6e 74 72 6f 6c 28 76 6f 69 64  che_control(void
1b30: 29 7b 0a 20 20 2f 2a 20 46 49 58 4d 45 3a 20 74  ){.  /* FIXME: t
1b40: 68 65 72 65 27 73 20 73 6f 6d 65 20 67 6f 74 63  here's some gotc
1b50: 68 61 73 20 77 74 68 20 63 6f 6f 6b 69 65 73 20  has wth cookies 
1b60: 61 6e 64 20 73 6f 6d 65 20 68 65 61 64 65 72 73  and some headers
1b70: 2e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 54  . */.  char *zET
1b80: 61 67 20 3d 20 63 67 69 5f 61 64 64 5f 65 74 61  ag = cgi_add_eta
1b90: 67 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63  g(blob_buffer(&c
1ba0: 67 69 43 6f 6e 74 65 6e 74 29 2c 62 6c 6f 62 5f  giContent),blob_
1bb0: 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74  size(&cgiContent
1bc0: 29 29 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 61 74  ));.  char *zMat
1bd0: 63 68 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f  ch = P("HTTP_IF_
1be0: 4e 4f 4e 45 5f 4d 41 54 43 48 22 29 3b 0a 0a 20  NONE_MATCH");.. 
1bf0: 20 69 66 28 20 7a 45 54 61 67 21 3d 30 20 26 26   if( zETag!=0 &&
1c00: 20 7a 4d 61 74 63 68 21 3d 30 20 29 20 7b 0a 20   zMatch!=0 ) {. 
1c10: 20 20 20 63 68 61 72 20 2a 7a 42 75 66 20 3d 20     char *zBuf = 
1c20: 73 74 72 64 75 70 28 7a 4d 61 74 63 68 29 3b 0a  strdup(zMatch);.
1c30: 20 20 20 20 69 66 28 20 7a 42 75 66 21 3d 30 20      if( zBuf!=0 
1c40: 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a  ){.      char *z
1c50: 54 6f 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 63  Tok = 0;.      c
1c60: 68 61 72 20 2a 7a 50 6f 73 3b 0a 20 20 20 20 20  har *zPos;.     
1c70: 20 66 6f 72 28 20 7a 54 6f 6b 20 3d 20 73 74 72   for( zTok = str
1c80: 74 6f 6b 5f 72 28 7a 42 75 66 2c 20 22 2c 5c 22  tok_r(zBuf, ",\"
1c90: 22 2c 26 7a 50 6f 73 29 3b 0a 20 20 20 20 20 20  ",&zPos);.      
1ca0: 20 20 20 20 20 7a 54 6f 6b 20 26 26 20 73 74 72       zTok && str
1cb0: 63 61 73 65 63 6d 70 28 7a 54 6f 6b 2c 7a 45 54  casecmp(zTok,zET
1cc0: 61 67 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20  ag);.           
1cd0: 7a 54 6f 6b 20 3d 20 20 73 74 72 74 6f 6b 5f 72  zTok =  strtok_r
1ce0: 28 30 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29  (0, ",\"",&zPos)
1cf0: 29 7b 7d 0a 20 20 20 20 20 20 66 72 65 65 28 7a  ){}.      free(z
1d00: 42 75 66 29 3b 0a 20 20 20 20 20 20 69 66 28 7a  Buf);.      if(z
1d10: 54 6f 6b 29 20 72 65 74 75 72 6e 20 31 3b 0a 20  Tok) return 1;. 
1d20: 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72 65     }.  }.  .  re
1d30: 74 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69 66  turn 0;.}.#endif
1d40: 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 6e 6f 72  ../*.** Do a nor
1d50: 6d 61 6c 20 48 54 54 50 20 72 65 70 6c 79 0a 2a  mal HTTP reply.*
1d60: 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 79  /.void cgi_reply
1d70: 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 74 6f  (void){.  int to
1d80: 74 61 6c 5f 73 69 7a 65 20 3d 20 30 3b 0a 20 20  tal_size = 0;.  
1d90: 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73  if( iReplyStatus
1da0: 3c 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c  <=0 ){.    iRepl
1db0: 79 53 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20  yStatus = 200;. 
1dc0: 20 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20     zReplyStatus 
1dd0: 3d 20 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66  = "OK";.  }..#if
1de0: 20 30 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53   0.  if( iReplyS
1df0: 74 61 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68  tatus==200 && ch
1e00: 65 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f  eck_cache_contro
1e10: 6c 28 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63  l() ) {.    /* c
1e20: 68 61 6e 67 65 20 74 68 65 20 73 74 61 74 75 73  hange the status
1e30: 20 74 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20   to "unchanged" 
1e40: 61 6e 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20  and we can skip 
1e50: 73 65 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20  sending the.    
1e60: 2a 2a 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e  ** actual respon
1e70: 73 65 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73  se body. Obvious
1e80: 6c 79 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68  ly we only do th
1e90: 69 73 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65  is when we _have
1ea0: 5f 20 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20  _ a.    ** body 
1eb0: 28 63 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20  (code 200)..    
1ec0: 2a 2f 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61  */.    iReplySta
1ed0: 74 75 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a  tus = 304;.    z
1ee0: 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e  ReplyStatus = "N
1ef0: 6f 74 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20  ot Modified";.  
1f00: 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20  }.#endif..  if( 
1f10: 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b  fullHttpReply ){
1f20: 0a 20 20 20 20 70 72 69 6e 74 66 28 22 48 54 54  .    printf("HTT
1f30: 50 2f 31 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22  P/1.0 %d %s\r\n"
1f40: 2c 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20  , iReplyStatus, 
1f50: 7a 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20  zReplyStatus);. 
1f60: 20 20 20 70 72 69 6e 74 66 28 22 44 61 74 65 3a     printf("Date:
1f70: 20 25 73 5c 72 5c 6e 22 2c 20 63 67 69 5f 72 66   %s\r\n", cgi_rf
1f80: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 74  c822_datestamp(t
1f90: 69 6d 65 28 30 29 29 29 3b 0a 20 20 20 20 70 72  ime(0)));.    pr
1fa0: 69 6e 74 66 28 22 43 6f 6e 6e 65 63 74 69 6f 6e  intf("Connection
1fb0: 3a 20 63 6c 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20  : close\r\n");. 
1fc0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 72 69 6e   }else{.    prin
1fd0: 74 66 28 22 53 74 61 74 75 73 3a 20 25 64 20 25  tf("Status: %d %
1fe0: 73 5c 72 5c 6e 22 2c 20 69 52 65 70 6c 79 53 74  s\r\n", iReplySt
1ff0: 61 74 75 73 2c 20 7a 52 65 70 6c 79 53 74 61 74  atus, zReplyStat
2000: 75 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  us);.  }..  if( 
2010: 62 6c 6f 62 5f 73 69 7a 65 28 26 65 78 74 72 61  blob_size(&extra
2020: 48 65 61 64 65 72 29 3e 30 20 29 7b 0a 20 20 20  Header)>0 ){.   
2030: 20 70 72 69 6e 74 66 28 22 25 73 22 2c 20 62 6c   printf("%s", bl
2040: 6f 62 5f 62 75 66 66 65 72 28 26 65 78 74 72 61  ob_buffer(&extra
2050: 48 65 61 64 65 72 29 29 3b 0a 20 20 7d 0a 0a 20  Header));.  }.. 
2060: 20 69 66 28 20 67 2e 69 73 43 6f 6e 73 74 20 29   if( g.isConst )
2070: 7b 0a 20 20 20 20 2f 2a 20 63 6f 6e 73 74 61 6e  {.    /* constan
2080: 74 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65  t means that the
2090: 20 69 6e 70 75 74 20 55 52 4c 20 77 69 6c 6c 20   input URL will 
20a0: 5f 6e 65 76 65 72 5f 20 67 65 6e 65 72 61 74 65  _never_ generate
20b0: 20 61 6e 79 74 68 69 6e 67 0a 20 20 20 20 2a 2a   anything.    **
20c0: 20 65 6c 73 65 2e 20 49 6e 20 74 68 65 20 63 61   else. In the ca
20d0: 73 65 20 6f 66 20 61 74 74 61 63 68 6d 65 6e 74  se of attachment
20e0: 73 2c 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  s, the contents 
20f0: 77 6f 6e 27 74 20 63 68 61 6e 67 65 20 62 65 63  won't change bec
2100: 61 75 73 65 0a 20 20 20 20 2a 2a 20 61 6e 20 61  ause.    ** an a
2110: 74 74 65 6d 70 74 20 74 6f 20 63 68 61 6e 67 65  ttempt to change
2120: 20 74 68 65 6d 20 67 65 6e 65 72 61 74 65 73 20   them generates 
2130: 61 20 6e 65 77 20 61 74 74 61 63 68 6d 65 6e 74  a new attachment
2140: 20 6e 75 6d 62 65 72 2e 20 49 6e 20 74 68 65 0a   number. In the.
2150: 20 20 20 20 2a 2a 20 63 61 73 65 20 6f 66 20 6d      ** case of m
2160: 6f 73 74 20 2f 67 65 74 66 69 6c 65 20 63 61 6c  ost /getfile cal
2170: 6c 73 20 66 6f 72 20 73 70 65 63 69 66 69 63 20  ls for specific 
2180: 76 65 72 73 69 6f 6e 73 2c 20 74 68 65 20 6f 6e  versions, the on
2190: 6c 79 20 77 61 79 20 74 68 65 0a 20 20 20 20 2a  ly way the.    *
21a0: 2a 20 63 6f 6e 74 65 6e 74 20 63 68 61 6e 67 65  * content change
21b0: 73 20 69 73 20 69 66 20 73 6f 6d 65 6f 6e 65 20  s is if someone 
21c0: 62 72 65 61 6b 73 20 74 68 65 20 53 43 4d 2e 20  breaks the SCM. 
21d0: 41 6e 64 20 69 66 20 74 68 61 74 20 68 61 70 70  And if that happ
21e0: 65 6e 73 2c 20 61 0a 20 20 20 20 2a 2a 20 73 74  ens, a.    ** st
21f0: 61 6c 65 20 63 61 63 68 65 20 69 73 20 74 68 65  ale cache is the
2200: 20 6c 65 61 73 74 20 6f 66 20 74 68 65 20 70 72   least of the pr
2210: 6f 62 6c 65 6d 2e 20 53 6f 20 77 65 20 70 72 6f  oblem. So we pro
2220: 76 69 64 65 20 61 6e 20 45 78 70 69 72 65 73 0a  vide an Expires.
2230: 20 20 20 20 2a 2a 20 68 65 61 64 65 72 20 73 65      ** header se
2240: 74 20 74 6f 20 61 20 72 65 61 73 6f 6e 61 62 6c  t to a reasonabl
2250: 65 20 70 65 72 69 6f 64 20 28 64 65 66 61 75 6c  e period (defaul
2260: 74 3a 20 6f 6e 65 20 77 65 65 6b 29 2e 0a 20 20  t: one week)..  
2270: 20 20 2a 2f 0a 20 20 20 20 2f 2a 74 69 6d 65 5f    */.    /*time_
2280: 74 20 65 78 70 69 72 65 73 20 3d 20 74 69 6d 65  t expires = time
2290: 28 30 29 20 2b 20 61 74 6f 69 28 64 62 5f 63 6f  (0) + atoi(db_co
22a0: 6e 66 69 67 28 22 63 6f 6e 73 74 61 6e 74 5f 65  nfig("constant_e
22b0: 78 70 69 72 65 73 22 2c 22 36 30 34 38 30 30 22  xpires","604800"
22c0: 29 29 3b 2a 2f 0a 20 20 20 20 74 69 6d 65 5f 74  ));*/.    time_t
22d0: 20 65 78 70 69 72 65 73 20 3d 20 74 69 6d 65 28   expires = time(
22e0: 30 29 20 2b 20 36 30 34 38 30 30 3b 0a 20 20 20  0) + 604800;.   
22f0: 20 70 72 69 6e 74 66 28 20 22 45 78 70 69 72 65   printf( "Expire
2300: 73 3a 20 25 73 5c 72 5c 6e 22 2c 20 63 67 69 5f  s: %s\r\n", cgi_
2310: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70  rfc822_datestamp
2320: 28 65 78 70 69 72 65 73 29 29 3b 0a 20 20 7d 0a  (expires));.  }.
2330: 0a 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 69 6e  .  /* Content in
2340: 74 65 6e 64 65 64 20 66 6f 72 20 6c 6f 67 67 65  tended for logge
2350: 64 20 69 6e 20 75 73 65 72 73 20 73 68 6f 75 6c  d in users shoul
2360: 64 20 6f 6e 6c 79 20 62 65 20 63 61 63 68 65 64  d only be cached
2370: 20 69 6e 0a 20 20 2a 2a 20 74 68 65 20 62 72 6f   in.  ** the bro
2380: 77 73 65 72 2c 20 6e 6f 74 20 73 6f 6d 65 20 73  wser, not some s
2390: 68 61 72 65 64 20 6c 6f 63 61 74 69 6f 6e 2e 0a  hared location..
23a0: 20 20 2a 2f 0a 20 20 70 72 69 6e 74 66 28 22 43    */.  printf("C
23b0: 61 63 68 65 2d 63 6f 6e 74 72 6f 6c 3a 20 70 72  ache-control: pr
23c0: 69 76 61 74 65 5c 72 5c 6e 22 29 3b 0a 0a 23 69  ivate\r\n");..#i
23d0: 66 20 46 4f 53 53 49 4c 5f 49 31 38 4e 0a 20 20  f FOSSIL_I18N.  
23e0: 70 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74  printf( "Content
23f0: 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 72 73  -Type: %s; chars
2400: 65 74 3d 25 73 5c 72 5c 6e 22 2c 20 7a 43 6f 6e  et=%s\r\n", zCon
2410: 74 65 6e 74 54 79 70 65 2c 20 6e 6c 5f 6c 61 6e  tentType, nl_lan
2420: 67 69 6e 66 6f 28 43 4f 44 45 53 45 54 29 29 3b  ginfo(CODESET));
2430: 0a 23 65 6c 73 65 0a 20 20 70 72 69 6e 74 66 28  .#else.  printf(
2440: 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20   "Content-Type: 
2450: 25 73 3b 20 63 68 61 72 73 65 74 3d 49 53 4f 2d  %s; charset=ISO-
2460: 38 38 35 39 2d 31 5c 72 5c 6e 22 2c 20 7a 43 6f  8859-1\r\n", zCo
2470: 6e 74 65 6e 74 54 79 70 65 29 3b 0a 23 65 6e 64  ntentType);.#end
2480: 69 66 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28  if.  if( strcmp(
2490: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 2c 22 61 70  zContentType,"ap
24a0: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73  plication/x-foss
24b0: 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 63  il")==0 ){.    c
24c0: 67 69 5f 63 6f 6d 62 69 6e 65 5f 68 65 61 64 65  gi_combine_heade
24d0: 72 5f 61 6e 64 5f 62 6f 64 79 28 29 3b 0a 20 20  r_and_body();.  
24e0: 20 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 28    blob_compress(
24f0: 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 2c 20  &cgiContent[0], 
2500: 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b  &cgiContent[0]);
2510: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 52 65 70  .  }..  if( iRep
2520: 6c 79 53 74 61 74 75 73 20 21 3d 20 33 30 34 20  lyStatus != 304 
2530: 29 20 7b 0a 20 20 20 20 74 6f 74 61 6c 5f 73 69  ) {.    total_si
2540: 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26  ze = blob_size(&
2550: 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 20 2b  cgiContent[0]) +
2560: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43   blob_size(&cgiC
2570: 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 20 20 20 20  ontent[1]);.    
2580: 70 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74  printf( "Content
2590: 2d 4c 65 6e 67 74 68 3a 20 25 64 5c 72 5c 6e 22  -Length: %d\r\n"
25a0: 2c 20 74 6f 74 61 6c 5f 73 69 7a 65 29 3b 0a 20  , total_size);. 
25b0: 20 7d 0a 20 20 70 72 69 6e 74 66 28 22 5c 72 5c   }.  printf("\r\
25c0: 6e 22 29 3b 0a 20 20 69 66 28 20 74 6f 74 61 6c  n");.  if( total
25d0: 5f 73 69 7a 65 3e 30 20 26 26 20 69 52 65 70 6c  _size>0 && iRepl
25e0: 79 53 74 61 74 75 73 20 21 3d 20 33 30 34 20 29  yStatus != 304 )
25f0: 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20 73 69 7a  {.    int i, siz
2600: 65 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20  e;.    for(i=0; 
2610: 69 3c 32 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  i<2; i++){.     
2620: 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a   size = blob_siz
2630: 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 69 5d  e(&cgiContent[i]
2640: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73 69 7a  );.      if( siz
2650: 65 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 66  e>0 ){.        f
2660: 77 72 69 74 65 28 62 6c 6f 62 5f 62 75 66 66 65  write(blob_buffe
2670: 72 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 69 5d  r(&cgiContent[i]
2680: 29 2c 20 31 2c 20 73 69 7a 65 2c 20 73 74 64 6f  ), 1, size, stdo
2690: 75 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  ut);.      }.   
26a0: 20 7d 0a 20 20 7d 0a 20 20 43 47 49 44 45 42 55   }.  }.  CGIDEBU
26b0: 47 28 28 22 44 4f 4e 45 5c 6e 22 29 29 3b 0a 7d  G(("DONE\n"));.}
26c0: 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 72 65 64  ../*.** Do a red
26d0: 69 72 65 63 74 20 72 65 71 75 65 73 74 20 74 6f  irect request to
26e0: 20 74 68 65 20 55 52 4c 20 67 69 76 65 6e 20 69   the URL given i
26f0: 6e 20 74 68 65 20 61 72 67 75 6d 65 6e 74 2e 0a  n the argument..
2700: 2a 2a 0a 2a 2a 20 54 68 65 20 55 52 4c 20 6d 75  **.** The URL mu
2710: 73 74 20 62 65 20 72 65 6c 61 74 69 76 65 20 74  st be relative t
2720: 6f 20 74 68 65 20 62 61 73 65 20 6f 66 20 74 68  o the base of th
2730: 65 20 66 6f 73 73 69 6c 20 73 65 72 76 65 72 2e  e fossil server.
2740: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 64  .*/.void cgi_red
2750: 69 72 65 63 74 28 63 6f 6e 73 74 20 63 68 61 72  irect(const char
2760: 20 2a 7a 55 52 4c 29 7b 0a 20 20 63 68 61 72 20   *zURL){.  char 
2770: 2a 7a 4c 6f 63 61 74 69 6f 6e 3b 0a 20 20 43 47  *zLocation;.  CG
2780: 49 44 45 42 55 47 28 28 22 72 65 64 69 72 65 63  IDEBUG(("redirec
2790: 74 20 74 6f 20 25 73 5c 6e 22 2c 20 7a 55 52 4c  t to %s\n", zURL
27a0: 29 29 3b 0a 20 20 69 66 28 20 73 74 72 6e 63 6d  ));.  if( strncm
27b0: 70 28 7a 55 52 4c 2c 22 68 74 74 70 3a 22 2c 35  p(zURL,"http:",5
27c0: 29 3d 3d 30 20 7c 7c 20 73 74 72 6e 63 6d 70 28  )==0 || strncmp(
27d0: 7a 55 52 4c 2c 22 68 74 74 70 73 3a 22 2c 36 29  zURL,"https:",6)
27e0: 3d 3d 30 20 7c 7c 20 2a 7a 55 52 4c 3d 3d 27 2f  ==0 || *zURL=='/
27f0: 27 20 29 7b 0a 20 20 20 20 7a 4c 6f 63 61 74 69  ' ){.    zLocati
2800: 6f 6e 20 3d 20 6d 70 72 69 6e 74 66 28 22 4c 6f  on = mprintf("Lo
2810: 63 61 74 69 6f 6e 3a 20 25 73 5c 72 5c 6e 22 2c  cation: %s\r\n",
2820: 20 7a 55 52 4c 29 3b 0a 20 20 7d 65 6c 73 65 7b   zURL);.  }else{
2830: 0a 20 20 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d  .    zLocation =
2840: 20 6d 70 72 69 6e 74 66 28 22 4c 6f 63 61 74 69   mprintf("Locati
2850: 6f 6e 3a 20 25 73 2f 25 73 5c 72 5c 6e 22 2c 20  on: %s/%s\r\n", 
2860: 67 2e 7a 42 61 73 65 55 52 4c 2c 20 7a 55 52 4c  g.zBaseURL, zURL
2870: 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f 61 70 70  );.  }.  cgi_app
2880: 65 6e 64 5f 68 65 61 64 65 72 28 7a 4c 6f 63 61  end_header(zLoca
2890: 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65 73  tion);.  cgi_res
28a0: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20  et_content();.  
28b0: 63 67 69 5f 70 72 69 6e 74 66 28 22 3c 68 74 6d  cgi_printf("<htm
28c0: 6c 3e 5c 6e 3c 70 3e 52 65 64 69 72 65 63 74 20  l>\n<p>Redirect 
28d0: 74 6f 20 25 68 3c 2f 70 3e 5c 6e 3c 2f 68 74 6d  to %h</p>\n</htm
28e0: 6c 3e 5c 6e 22 2c 20 7a 55 52 4c 29 3b 0a 20 20  l>\n", zURL);.  
28f0: 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 33  cgi_set_status(3
2900: 30 32 2c 20 22 4d 6f 76 65 64 20 54 65 6d 70 6f  02, "Moved Tempo
2910: 72 61 72 69 6c 79 22 29 3b 0a 20 20 66 72 65 65  rarily");.  free
2920: 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a 20 20 63  (zLocation);.  c
2930: 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 78  gi_reply();.  ex
2940: 69 74 28 30 29 3b 0a 7d 0a 76 6f 69 64 20 63 67  it(0);.}.void cg
2950: 69 5f 72 65 64 69 72 65 63 74 66 28 63 6f 6e 73  i_redirectf(cons
2960: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c  t char *zFormat,
2970: 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74   ...){.  va_list
2980: 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 72 74 28   ap;.  va_start(
2990: 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20  ap, zFormat);.  
29a0: 63 67 69 5f 72 65 64 69 72 65 63 74 28 76 6d 70  cgi_redirect(vmp
29b0: 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74 2c 20 61  rintf(zFormat, a
29c0: 70 29 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  p));.  va_end(ap
29d0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f  );.}../*.** Info
29e0: 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 61 6c  rmation about al
29f0: 6c 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  l query paramete
2a00: 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 20 61  rs and cookies a
2a10: 72 65 20 73 74 6f 72 65 64 0a 2a 2a 20 69 6e 20  re stored.** in 
2a20: 74 68 65 73 65 20 76 61 72 69 61 62 6c 65 73 2e  these variables.
2a30: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6e  .*/.static int n
2a40: 41 6c 6c 6f 63 51 50 20 3d 20 30 3b 20 2f 2a 20  AllocQP = 0; /* 
2a50: 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 65 64 20  Space allocated 
2a60: 66 6f 72 20 61 50 61 72 61 6d 51 50 5b 5d 20 2a  for aParamQP[] *
2a70: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 55 73  /.static int nUs
2a80: 65 64 51 50 20 3d 20 30 3b 20 20 2f 2a 20 53 70  edQP = 0;  /* Sp
2a90: 61 63 65 20 61 63 74 75 61 6c 6c 79 20 75 73 65  ace actually use
2aa0: 64 20 69 6e 20 61 50 61 72 61 6d 51 50 5b 5d 20  d in aParamQP[] 
2ab0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 6f  */.static int so
2ac0: 72 74 51 50 20 3d 20 30 3b 20 20 20 2f 2a 20 54  rtQP = 0;   /* T
2ad0: 72 75 65 20 69 66 20 61 50 61 72 61 6d 51 50 5b  rue if aParamQP[
2ae0: 5d 20 6e 65 65 64 73 20 73 6f 72 74 69 6e 67 20  ] needs sorting 
2af0: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
2b00: 71 51 50 20 3d 20 30 3b 20 20 20 20 2f 2a 20 53  qQP = 0;    /* S
2b10: 65 71 75 65 6e 63 65 20 6e 75 6d 62 65 72 73 20  equence numbers 
2b20: 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74  */.static struct
2b30: 20 51 50 61 72 61 6d 20 7b 20 20 20 2f 2a 20 4f   QParam {   /* O
2b40: 6e 65 20 65 6e 74 72 79 20 66 6f 72 20 65 61 63  ne entry for eac
2b50: 68 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  h query paramete
2b60: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20  r or cookie */. 
2b70: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
2b80: 6d 65 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61  me;        /* Pa
2b90: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69  rameter or cooki
2ba0: 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73  e name */.  cons
2bb0: 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 20  t char *zValue; 
2bc0: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f        /* Value o
2bd0: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  f the query para
2be0: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20  meter or cookie 
2bf0: 2a 2f 0a 20 20 69 6e 74 20 73 65 71 3b 20 20 20  */.  int seq;   
2c00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2c10: 2a 20 4f 72 64 65 72 20 6f 66 20 69 6e 73 65 72  * Order of inser
2c20: 74 69 6f 6e 20 2a 2f 0a 7d 20 2a 61 50 61 72 61  tion */.} *aPara
2c30: 6d 51 50 3b 20 20 20 20 20 20 20 20 20 20 20 20  mQP;            
2c40: 20 2f 2a 20 41 6e 20 61 72 72 61 79 20 6f 66 20   /* An array of 
2c50: 61 6c 6c 20 70 61 72 61 6d 65 74 65 72 73 20 61  all parameters a
2c60: 6e 64 20 63 6f 6f 6b 69 65 73 20 2a 2f 0a 0a 2f  nd cookies */../
2c70: 2a 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 68 65 72  *.** Add another
2c80: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
2c90: 20 6f 72 20 63 6f 6f 6b 69 65 20 74 6f 20 74 68   or cookie to th
2ca0: 65 20 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e  e parameter set.
2cb0: 0a 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 74 68 65  .** zName is the
2cc0: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 71 75 65   name of the que
2cd0: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20  ry parameter or 
2ce0: 63 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 61 6c 75  cookie and zValu
2cf0: 65 0a 2a 2a 20 69 73 20 69 74 73 20 66 75 6c 6c  e.** is its full
2d00: 79 20 64 65 63 6f 64 65 64 20 76 61 6c 75 65 2e  y decoded value.
2d10: 0a 2a 2a 0a 2a 2a 20 7a 4e 61 6d 65 20 61 6e 64  .**.** zName and
2d20: 20 7a 56 61 6c 75 65 20 61 72 65 20 6e 6f 74 20   zValue are not 
2d30: 63 6f 70 69 65 64 20 61 6e 64 20 6d 75 73 74 20  copied and must 
2d40: 6e 6f 74 20 63 68 61 6e 67 65 20 6f 72 20 62 65  not change or be
2d50: 0a 2a 2a 20 64 65 61 6c 6c 6f 63 61 74 65 64 20  .** deallocated 
2d60: 61 66 74 65 72 20 74 68 69 73 20 72 6f 75 74 69  after this routi
2d70: 6e 65 20 72 65 74 75 72 6e 73 2e 0a 2a 2f 0a 76  ne returns..*/.v
2d80: 6f 69 64 20 63 67 69 5f 73 65 74 5f 70 61 72 61  oid cgi_set_para
2d90: 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 63 6f 6e  meter_nocopy(con
2da0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20  st char *zName, 
2db0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
2dc0: 75 65 29 7b 0a 20 20 69 66 28 20 6e 41 6c 6c 6f  ue){.  if( nAllo
2dd0: 63 51 50 3c 3d 6e 55 73 65 64 51 50 20 29 7b 0a  cQP<=nUsedQP ){.
2de0: 20 20 20 20 6e 41 6c 6c 6f 63 51 50 20 3d 20 6e      nAllocQP = n
2df0: 41 6c 6c 6f 63 51 50 2a 32 20 2b 20 31 30 3b 0a  AllocQP*2 + 10;.
2e00: 20 20 20 20 61 50 61 72 61 6d 51 50 20 3d 20 72      aParamQP = r
2e10: 65 61 6c 6c 6f 63 28 20 61 50 61 72 61 6d 51 50  ealloc( aParamQP
2e20: 2c 20 6e 41 6c 6c 6f 63 51 50 2a 73 69 7a 65 6f  , nAllocQP*sizeo
2e30: 66 28 61 50 61 72 61 6d 51 50 5b 30 5d 29 20 29  f(aParamQP[0]) )
2e40: 3b 0a 20 20 20 20 69 66 28 20 61 50 61 72 61 6d  ;.    if( aParam
2e50: 51 50 3d 3d 30 20 29 20 65 78 69 74 28 31 29 3b  QP==0 ) exit(1);
2e60: 0a 20 20 7d 0a 20 20 61 50 61 72 61 6d 51 50 5b  .  }.  aParamQP[
2e70: 6e 55 73 65 64 51 50 5d 2e 7a 4e 61 6d 65 20 3d  nUsedQP].zName =
2e80: 20 7a 4e 61 6d 65 3b 0a 20 20 61 50 61 72 61 6d   zName;.  aParam
2e90: 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a 56 61 6c  QP[nUsedQP].zVal
2ea0: 75 65 20 3d 20 7a 56 61 6c 75 65 3b 0a 20 20 61  ue = zValue;.  a
2eb0: 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d  ParamQP[nUsedQP]
2ec0: 2e 73 65 71 20 3d 20 73 65 71 51 50 2b 2b 3b 0a  .seq = seqQP++;.
2ed0: 20 20 6e 55 73 65 64 51 50 2b 2b 3b 0a 20 20 73    nUsedQP++;.  s
2ee0: 6f 72 74 51 50 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a  ortQP = 1;.}../*
2ef0: 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 68 65 72 20  .** Add another 
2f00: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20  query parameter 
2f10: 6f 72 20 63 6f 6f 6b 69 65 20 74 6f 20 74 68 65  or cookie to the
2f20: 20 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a   parameter set..
2f30: 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 74 68 65 20  ** zName is the 
2f40: 6e 61 6d 65 20 6f 66 20 74 68 65 20 71 75 65 72  name of the quer
2f50: 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63  y parameter or c
2f60: 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 61 6c 75 65  ookie and zValue
2f70: 0a 2a 2a 20 69 73 20 69 74 73 20 66 75 6c 6c 79  .** is its fully
2f80: 20 64 65 63 6f 64 65 64 20 76 61 6c 75 65 2e 0a   decoded value..
2f90: 2a 2a 0a 2a 2a 20 43 6f 70 69 65 73 20 61 72 65  **.** Copies are
2fa0: 20 6d 61 64 65 20 6f 66 20 62 6f 74 68 20 74 68   made of both th
2fb0: 65 20 7a 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c  e zName and zVal
2fc0: 75 65 20 70 61 72 61 6d 65 74 65 72 73 2e 0a 2a  ue parameters..*
2fd0: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 70  /.void cgi_set_p
2fe0: 61 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 20 63  arameter(const c
2ff0: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73  har *zName, cons
3000: 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b  t char *zValue){
3010: 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d  .  cgi_set_param
3020: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69  eter_nocopy(mpri
3030: 6e 74 66 28 22 25 73 22 2c 7a 4e 61 6d 65 29 2c  ntf("%s",zName),
3040: 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 56   mprintf("%s",zV
3050: 61 6c 75 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  alue));.}../*.**
3060: 20 52 65 70 6c 61 63 65 20 61 20 70 61 72 61 6d   Replace a param
3070: 65 74 65 72 20 77 69 74 68 20 61 20 6e 65 77 20  eter with a new 
3080: 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63  value..*/.void c
3090: 67 69 5f 72 65 70 6c 61 63 65 5f 70 61 72 61 6d  gi_replace_param
30a0: 65 74 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20  eter(const char 
30b0: 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68  *zName, const ch
30c0: 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 69  ar *zValue){.  i
30d0: 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  nt i;.  for(i=0;
30e0: 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29   i<nUsedQP; i++)
30f0: 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70  {.    if( strcmp
3100: 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61  (aParamQP[i].zNa
3110: 6d 65 2c 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a  me,zName)==0 ){.
3120: 20 20 20 20 20 20 61 50 61 72 61 6d 51 50 5b 69        aParamQP[i
3130: 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56 61 6c 75  ].zValue = zValu
3140: 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  e;.    }.  }.}..
3150: 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 71 75 65 72  /*.** Add a quer
3160: 79 20 70 61 72 61 6d 65 74 65 72 2e 20 20 54 68  y parameter.  Th
3170: 65 20 7a 4e 61 6d 65 20 70 6f 72 74 69 6f 6e 20  e zName portion 
3180: 69 73 20 66 69 78 65 64 20 62 75 74 20 61 20 63  is fixed but a c
3190: 6f 70 79 0a 2a 2a 20 6d 75 73 74 20 62 65 20 6d  opy.** must be m
31a0: 61 64 65 20 6f 66 20 7a 56 61 6c 75 65 2e 0a 2a  ade of zValue..*
31b0: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 65 6e  /.void cgi_seten
31c0: 76 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  v(const char *zN
31d0: 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ame, const char 
31e0: 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f  *zValue){.  cgi_
31f0: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
3200: 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 6d 70 72 69  copy(zName, mpri
3210: 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29  ntf("%s",zValue)
3220: 29 3b 0a 7d 0a 20 0a 0a 2f 2a 0a 2a 2a 20 41 64  );.}. ../*.** Ad
3230: 64 20 61 20 6c 69 73 74 20 6f 66 20 71 75 65 72  d a list of quer
3240: 79 20 70 61 72 61 6d 65 74 65 72 73 20 6f 72 20  y parameters or 
3250: 63 6f 6f 6b 69 65 73 20 74 6f 20 74 68 65 20 70  cookies to the p
3260: 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a  arameter set..**
3270: 0a 2a 2a 20 45 61 63 68 20 70 61 72 61 6d 65 74  .** Each paramet
3280: 65 72 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72  er is of the for
3290: 6d 20 4e 41 4d 45 3d 56 41 4c 55 45 2e 20 20 42  m NAME=VALUE.  B
32a0: 6f 74 68 20 74 68 65 20 4e 41 4d 45 20 61 6e 64  oth the NAME and
32b0: 20 74 68 65 0a 2a 2a 20 56 41 4c 55 45 20 6d 61   the.** VALUE ma
32c0: 79 20 62 65 20 75 72 6c 2d 65 6e 63 6f 64 65 64  y be url-encoded
32d0: 20 28 22 2b 22 20 66 6f 72 20 73 70 61 63 65 2c   ("+" for space,
32e0: 20 22 25 48 48 22 20 66 6f 72 20 6f 74 68 65 72   "%HH" for other
32f0: 20 73 70 65 63 69 61 6c 0a 2a 2a 20 63 68 61 72   special.** char
3300: 61 63 74 65 72 73 29 2e 20 20 42 75 74 20 74 68  acters).  But th
3310: 69 73 20 72 6f 75 74 69 6e 65 20 61 73 73 75 6d  is routine assum
3320: 65 73 20 74 68 61 74 20 4e 41 4d 45 20 63 6f 6e  es that NAME con
3330: 74 61 69 6e 73 20 6e 6f 0a 2a 2a 20 73 70 65 63  tains no.** spec
3340: 69 61 6c 20 63 68 61 72 61 63 74 65 72 20 61 6e  ial character an
3350: 64 20 74 68 65 72 65 66 6f 72 65 20 64 6f 65 73  d therefore does
3360: 20 6e 6f 74 20 64 65 63 6f 64 65 20 69 74 2e 0a   not decode it..
3370: 2a 2a 0a 2a 2a 20 49 66 20 4e 41 4d 45 20 62 65  **.** If NAME be
3380: 67 69 6e 73 20 77 69 74 68 20 61 6e 6f 74 68 65  gins with anothe
3390: 72 20 6f 74 68 65 72 20 74 68 61 6e 20 61 20 6c  r other than a l
33a0: 6f 77 65 72 2d 63 61 73 65 20 6c 65 74 74 65 72  ower-case letter
33b0: 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20 65 6e 74   then.** the ent
33c0: 69 72 65 20 4e 41 4d 45 3d 56 41 4c 55 45 20 74  ire NAME=VALUE t
33d0: 65 72 6d 20 69 73 20 69 67 6e 6f 72 65 64 2e 20  erm is ignored. 
33e0: 20 48 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a 20 20 20   Hence:.**.**   
33f0: 20 20 20 2a 20 20 63 6f 6f 6b 69 65 73 20 61 6e     *  cookies an
3400: 64 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  d query paramete
3410: 72 73 20 74 68 61 74 20 68 61 76 65 20 75 70 70  rs that have upp
3420: 65 72 63 61 73 65 20 6e 61 6d 65 73 0a 2a 2a 20  ercase names.** 
3430: 20 20 20 20 20 20 20 20 61 72 65 20 69 67 6e 6f          are igno
3440: 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  red..**.**      
3450: 2a 20 20 69 74 20 69 73 20 69 6d 70 6f 73 73 69  *  it is impossi
3460: 62 6c 65 20 66 6f 72 20 61 20 63 6f 6f 6b 69 65  ble for a cookie
3470: 20 6f 72 20 71 75 65 72 79 20 70 61 72 61 6d 65   or query parame
3480: 74 65 72 20 74 6f 0a 2a 2a 20 20 20 20 20 20 20  ter to.**       
3490: 20 20 6f 76 65 72 72 69 64 65 20 74 68 65 20 76    override the v
34a0: 61 6c 75 65 20 6f 66 20 61 6e 20 65 6e 76 69 72  alue of an envir
34b0: 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20  onment variable 
34c0: 73 69 6e 63 65 0a 2a 2a 20 20 20 20 20 20 20 20  since.**        
34d0: 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72   environment var
34e0: 69 61 62 6c 65 73 20 61 6c 77 61 79 73 20 68 61  iables always ha
34f0: 76 65 20 75 70 70 65 72 63 61 73 65 20 6e 61 6d  ve uppercase nam
3500: 65 73 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65  es..**.** Parame
3510: 74 65 72 73 20 61 72 65 20 73 65 70 61 72 61 74  ters are separat
3520: 65 64 20 62 79 20 74 68 65 20 22 74 65 72 6d 69  ed by the "termi
3530: 6e 61 74 6f 72 22 20 63 68 61 72 61 63 74 65 72  nator" character
3540: 2e 20 20 57 68 69 74 65 73 70 61 63 65 0a 2a 2a  .  Whitespace.**
3550: 20 62 65 66 6f 72 65 20 74 68 65 20 4e 41 4d 45   before the NAME
3560: 20 69 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a   is ignored..**.
3570: 2a 2a 20 54 68 65 20 69 6e 70 75 74 20 73 74 72  ** The input str
3580: 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66  ing "z" is modif
3590: 69 65 64 20 62 75 74 20 6e 6f 20 63 6f 70 69 65  ied but no copie
35a0: 73 20 69 73 20 6d 61 64 65 2e 20 20 22 7a 22 0a  s is made.  "z".
35b0: 2a 2a 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62 65  ** should not be
35c0: 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 6f 72 20   deallocated or 
35d0: 63 68 61 6e 67 65 64 20 61 67 61 69 6e 20 61 66  changed again af
35e0: 74 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e 65  ter this routine
35f0: 0a 2a 2a 20 72 65 74 75 72 6e 73 20 6f 72 20 69  .** returns or i
3600: 74 20 77 69 6c 6c 20 63 6f 72 72 75 70 74 20 74  t will corrupt t
3610: 68 65 20 70 61 72 61 6d 65 74 65 72 20 74 61 62  he parameter tab
3620: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
3630: 69 64 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73  id add_param_lis
3640: 74 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 74  t(char *z, int t
3650: 65 72 6d 69 6e 61 74 6f 72 29 7b 0a 20 20 77 68  erminator){.  wh
3660: 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 63  ile( *z ){.    c
3670: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
3680: 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20  char *zValue;.  
3690: 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65    while( isspace
36a0: 28 2a 7a 29 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20  (*z) ){ z++; }. 
36b0: 20 20 20 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20     zName = z;.  
36c0: 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a    while( *z && *
36d0: 7a 21 3d 27 3d 27 20 26 26 20 2a 7a 21 3d 74 65  z!='=' && *z!=te
36e0: 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b 3b  rminator ){ z++;
36f0: 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27   }.    if( *z=='
3700: 3d 27 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d  =' ){.      *z =
3710: 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20   0;.      z++;. 
3720: 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 7a 3b       zValue = z;
3730: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a  .      while( *z
3740: 20 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 74   && *z!=terminat
3750: 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20  or ){ z++; }.   
3760: 20 20 20 69 66 28 20 2a 7a 20 29 7b 0a 20 20 20     if( *z ){.   
3770: 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20       *z = 0;.   
3780: 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20       z++;.      
3790: 7d 0a 20 20 20 20 20 20 64 65 68 74 74 70 69 7a  }.      dehttpiz
37a0: 65 28 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d  e(zValue);.    }
37b0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20  else{.      if( 
37c0: 2a 7a 20 29 7b 20 2a 7a 2b 2b 20 3d 20 30 3b 20  *z ){ *z++ = 0; 
37d0: 7d 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d  }.      zValue =
37e0: 20 22 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69   "";.    }.    i
37f0: 66 28 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65  f( islower(zName
3800: 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 63 67  [0]) ){.      cg
3810: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f  i_set_parameter_
3820: 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56  nocopy(zName, zV
3830: 61 6c 75 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  alue);.    }.  }
3840: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 2a 70 7a 20 69 73  .}../*.** *pz is
3850: 20 61 20 73 74 72 69 6e 67 20 74 68 61 74 20 63   a string that c
3860: 6f 6e 73 69 73 74 73 20 6f 66 20 6d 75 6c 74 69  onsists of multi
3870: 70 6c 65 20 6c 69 6e 65 73 20 6f 66 20 74 65 78  ple lines of tex
3880: 74 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74  t.  This.** rout
3890: 69 6e 65 20 66 69 6e 64 73 20 74 68 65 20 65 6e  ine finds the en
38a0: 64 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e 74  d of the current
38b0: 20 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 61 6e   line of text an
38c0: 64 20 63 6f 6e 76 65 72 74 73 0a 2a 2a 20 74 68  d converts.** th
38d0: 65 20 22 5c 6e 22 20 6f 72 20 22 5c 72 5c 6e 22  e "\n" or "\r\n"
38e0: 20 74 68 61 74 20 65 6e 64 73 20 74 68 61 74 20   that ends that 
38f0: 6c 69 6e 65 20 69 6e 74 6f 20 61 20 22 5c 30 30  line into a "\00
3900: 30 22 2e 20 20 49 74 20 74 68 65 6e 0a 2a 2a 20  0".  It then.** 
3910: 61 64 76 61 6e 63 65 73 20 2a 70 7a 20 74 6f 20  advances *pz to 
3920: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66  the beginning of
3930: 20 74 68 65 20 6e 65 78 74 20 6c 69 6e 65 20 61   the next line a
3940: 6e 64 20 72 65 74 75 72 6e 73 20 74 68 65 0a 2a  nd returns the.*
3950: 2a 20 70 72 65 76 69 6f 75 73 20 76 61 6c 75 65  * previous value
3960: 20 6f 66 20 2a 70 7a 20 28 77 68 69 63 68 20 69   of *pz (which i
3970: 73 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74  s the start of t
3980: 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65 2e  he current line.
3990: 29 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72  ).*/.static char
39a0: 20 2a 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f   *get_line_from_
39b0: 73 74 72 69 6e 67 28 63 68 61 72 20 2a 2a 70 7a  string(char **pz
39c0: 2c 20 69 6e 74 20 2a 70 4c 65 6e 29 7b 0a 20 20  , int *pLen){.  
39d0: 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20  char *z = *pz;. 
39e0: 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a 5b   int i;.  if( z[
39f0: 30 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30  0]==0 ) return 0
3a00: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 5b 69  ;.  for(i=0; z[i
3a10: 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  ]; i++){.    if(
3a20: 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29 7b 0a 20   z[i]=='\n' ){. 
3a30: 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20       if( i>0 && 
3a40: 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 7b 0a  z[i-1]=='\r' ){.
3a50: 20 20 20 20 20 20 20 20 7a 5b 69 2d 31 5d 20 3d          z[i-1] =
3a60: 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b   0;.      }else{
3a70: 0a 20 20 20 20 20 20 20 20 7a 5b 69 5d 20 3d 20  .        z[i] = 
3a80: 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  0;.      }.     
3a90: 20 69 2b 2b 3b 0a 20 20 20 20 20 20 62 72 65 61   i++;.      brea
3aa0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  k;.    }.  }.  *
3ab0: 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 2a 70  pz = &z[i];.  *p
3ac0: 4c 65 6e 20 2d 3d 20 69 3b 0a 20 20 72 65 74 75  Len -= i;.  retu
3ad0: 72 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  rn z;.}../*.** T
3ae0: 68 65 20 69 6e 70 75 74 20 2a 70 7a 20 70 6f 69  he input *pz poi
3af0: 6e 74 73 20 74 6f 20 63 6f 6e 74 65 6e 74 20 74  nts to content t
3b00: 68 61 74 20 69 73 20 74 65 72 6d 69 6e 61 74 65  hat is terminate
3b10: 64 20 62 79 20 61 20 22 5c 72 5c 6e 22 0a 2a 2a  d by a "\r\n".**
3b20: 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74 68 65   followed by the
3b30: 20 62 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 20   boundry marker 
3b40: 7a 42 6f 75 6e 64 72 79 2e 20 20 41 6e 20 65 78  zBoundry.  An ex
3b50: 74 72 61 20 22 2d 2d 22 20 6d 61 79 20 6f 72 0a  tra "--" may or.
3b60: 2a 2a 20 6d 61 79 20 6e 6f 74 20 62 65 20 61 70  ** may not be ap
3b70: 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 62 6f  pended to the bo
3b80: 75 6e 64 72 79 20 6d 61 72 6b 65 72 2e 20 20 54  undry marker.  T
3b90: 68 65 72 65 20 61 72 65 20 2a 70 4c 65 6e 20 63  here are *pLen c
3ba0: 68 61 72 61 63 74 65 72 73 0a 2a 2a 20 69 6e 20  haracters.** in 
3bb0: 2a 70 7a 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  *pz..**.** This 
3bc0: 72 6f 75 74 69 6e 65 20 61 64 64 73 20 61 20 22  routine adds a "
3bd0: 5c 30 30 30 22 20 74 6f 20 74 68 65 20 65 6e 64  \000" to the end
3be0: 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20   of the content 
3bf0: 28 6f 76 65 72 77 72 69 74 69 6e 67 0a 2a 2a 20  (overwriting.** 
3c00: 74 68 65 20 22 5c 72 5c 6e 22 29 20 61 6e 64 20  the "\r\n") and 
3c10: 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65  returns a pointe
3c20: 72 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74  r to the content
3c30: 2e 20 20 54 68 65 20 2a 70 7a 20 69 6e 70 75 74  .  The *pz input
3c40: 0a 2a 2a 20 69 73 20 61 64 6a 75 73 74 65 64 20  .** is adjusted 
3c50: 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  to point to the 
3c60: 66 69 72 73 74 20 6c 69 6e 65 20 66 6f 6c 6c 6f  first line follo
3c70: 77 69 6e 67 20 74 68 65 20 62 6f 75 6e 64 72 79  wing the boundry
3c80: 2e 0a 2a 2a 20 54 68 65 20 6c 65 6e 67 74 68 20  ..** The length 
3c90: 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 69  of the content i
3ca0: 73 20 73 74 6f 72 65 64 20 69 6e 20 2a 70 6e 43  s stored in *pnC
3cb0: 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  ontent..*/.stati
3cc0: 63 20 63 68 61 72 20 2a 67 65 74 5f 62 6f 75 6e  c char *get_boun
3cd0: 64 65 64 5f 63 6f 6e 74 65 6e 74 28 0a 20 20 63  ded_content(.  c
3ce0: 68 61 72 20 2a 2a 70 7a 2c 20 20 20 20 20 20 20  har **pz,       
3cf0: 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 61 6b    /* Content tak
3d00: 65 6e 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f 0a  en from here */.
3d10: 20 20 69 6e 74 20 2a 70 4c 65 6e 2c 20 20 20 20    int *pLen,    
3d20: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
3d30: 66 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20  f bytes of data 
3d40: 69 6e 20 28 2a 70 7a 29 5b 5d 20 2a 2f 0a 20 20  in (*pz)[] */.  
3d50: 63 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 2c 20  char *zBoundry, 
3d60: 20 20 20 2f 2a 20 42 6f 75 6e 64 72 79 20 74 65     /* Boundry te
3d70: 78 74 20 6d 61 72 6b 69 6e 67 20 74 68 65 20 65  xt marking the e
3d80: 6e 64 20 6f 66 20 63 6f 6e 74 65 6e 74 20 2a 2f  nd of content */
3d90: 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6e 74 65 6e  .  int *pnConten
3da0: 74 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74  t     /* Write t
3db0: 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63  he size of the c
3dc0: 6f 6e 74 65 6e 74 20 68 65 72 65 20 2a 2f 0a 29  ontent here */.)
3dd0: 7b 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 2a 70  {.  char *z = *p
3de0: 7a 3b 0a 20 20 69 6e 74 20 6c 65 6e 20 3d 20 2a  z;.  int len = *
3df0: 70 4c 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  pLen;.  int i;. 
3e00: 20 69 6e 74 20 6e 42 6f 75 6e 64 72 79 20 3d 20   int nBoundry = 
3e10: 73 74 72 6c 65 6e 28 7a 42 6f 75 6e 64 72 79 29  strlen(zBoundry)
3e20: 3b 0a 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d  ;.  *pnContent =
3e30: 20 6c 65 6e 3b 0a 20 20 66 6f 72 28 69 3d 30 3b   len;.  for(i=0;
3e40: 20 69 3c 6c 65 6e 3b 20 69 2b 2b 29 7b 0a 20 20   i<len; i++){.  
3e50: 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27    if( z[i]=='\n'
3e60: 20 26 26 20 73 74 72 6e 63 6d 70 28 7a 42 6f 75   && strncmp(zBou
3e70: 6e 64 72 79 2c 20 26 7a 5b 69 2b 31 5d 2c 20 6e  ndry, &z[i+1], n
3e80: 42 6f 75 6e 64 72 79 29 3d 3d 30 20 29 7b 0a 20  Boundry)==0 ){. 
3e90: 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20       if( i>0 && 
3ea0: 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 20 69  z[i-1]=='\r' ) i
3eb0: 2d 2d 3b 0a 20 20 20 20 20 20 7a 5b 69 5d 20 3d  --;.      z[i] =
3ec0: 20 30 3b 0a 20 20 20 20 20 20 2a 70 6e 43 6f 6e   0;.      *pnCon
3ed0: 74 65 6e 74 20 3d 20 69 3b 0a 20 20 20 20 20 20  tent = i;.      
3ee0: 69 20 2b 3d 20 6e 42 6f 75 6e 64 72 79 3b 0a 20  i += nBoundry;. 
3ef0: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
3f00: 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a  }.  }.  *pz = &z
3f10: 5b 69 5d 3b 0a 20 20 67 65 74 5f 6c 69 6e 65 5f  [i];.  get_line_
3f20: 66 72 6f 6d 5f 73 74 72 69 6e 67 28 70 7a 2c 20  from_string(pz, 
3f30: 70 4c 65 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20  pLen);.  return 
3f40: 7a 3b 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a  z;      .}../*.*
3f50: 2a 20 54 6f 6b 65 6e 69 7a 65 20 61 20 6c 69 6e  * Tokenize a lin
3f60: 65 20 6f 66 20 74 65 78 74 20 69 6e 74 6f 20 61  e of text into a
3f70: 73 20 6d 61 6e 79 20 61 73 20 6e 41 72 67 20 74  s many as nArg t
3f80: 6f 6b 65 6e 73 2e 20 20 4d 61 6b 65 0a 2a 2a 20  okens.  Make.** 
3f90: 61 7a 41 72 67 5b 5d 20 70 6f 69 6e 74 20 74 6f  azArg[] point to
3fa0: 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 65 61   the start of ea
3fb0: 63 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20  ch token..**.** 
3fc0: 54 6f 6b 65 6e 73 20 63 6f 6e 73 69 73 74 20 6f  Tokens consist o
3fd0: 66 20 73 70 61 63 65 20 6f 72 20 73 65 6d 69 2d  f space or semi-
3fe0: 63 6f 6c 6f 6e 20 64 65 6c 69 6d 69 74 65 64 20  colon delimited 
3ff0: 77 6f 72 64 73 20 6f 72 0a 2a 2a 20 73 74 72 69  words or.** stri
4000: 6e 67 73 20 69 6e 73 69 64 65 20 64 6f 75 62 6c  ngs inside doubl
4010: 65 2d 71 75 6f 74 65 73 2e 20 20 45 78 61 6d 70  e-quotes.  Examp
4020: 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 63 6f 6e  le:.**.**    con
4030: 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e  tent-disposition
4040: 3a 20 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 6d  : form-data; nam
4050: 65 3d 22 66 6e 22 3b 20 66 69 6c 65 6e 61 6d 65  e="fn"; filename
4060: 3d 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a  ="index.html".**
4070: 0a 2a 2a 20 54 68 65 20 6c 69 6e 65 20 61 62 6f  .** The line abo
4080: 76 65 20 69 73 20 74 6f 6b 65 6e 69 7a 65 64 20  ve is tokenized 
4090: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
40a0: 2a 20 20 20 20 61 7a 41 72 67 5b 30 5d 20 3d 20  *    azArg[0] = 
40b0: 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69  "content-disposi
40c0: 74 69 6f 6e 3a 22 0a 2a 2a 20 20 20 20 61 7a 41  tion:".**    azA
40d0: 72 67 5b 31 5d 20 3d 20 22 66 6f 72 6d 2d 64 61  rg[1] = "form-da
40e0: 74 61 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b  ta".**    azArg[
40f0: 32 5d 20 3d 20 22 6e 61 6d 65 3d 22 0a 2a 2a 20  2] = "name=".** 
4100: 20 20 20 61 7a 41 72 67 5b 33 5d 20 3d 20 22 66     azArg[3] = "f
4110: 6e 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 34  n".**    azArg[4
4120: 5d 20 3d 20 22 66 69 6c 65 6e 61 6d 65 3d 22 0a  ] = "filename=".
4130: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 35 5d 20 3d  **    azArg[5] =
4140: 20 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a   "index.html".**
4150: 20 20 20 20 61 7a 41 72 67 5b 36 5d 20 3d 20 30      azArg[6] = 0
4160: 3b 0a 2a 2a 0a 2a 2a 20 27 5c 30 30 30 27 20 63  ;.**.** '\000' c
4170: 68 61 72 61 63 74 65 72 73 20 61 72 65 20 69 6e  haracters are in
4180: 73 65 72 74 65 64 20 69 6e 20 7a 5b 5d 20 61 74  serted in z[] at
4190: 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68   the end of each
41a0: 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 54 68 69 73 20   token..** This 
41b0: 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20  routine returns 
41c0: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
41d0: 20 6f 66 20 74 6f 6b 65 6e 73 20 6f 6e 20 74 68   of tokens on th
41e0: 65 20 6c 69 6e 65 2c 20 36 0a 2a 2a 20 69 6e 20  e line, 6.** in 
41f0: 74 68 65 20 65 78 61 6d 70 6c 65 20 61 62 6f 76  the example abov
4200: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
4210: 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 63   tokenize_line(c
4220: 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6d 78 41 72  har *z, int mxAr
4230: 67 2c 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 29  g, char **azArg)
4240: 7b 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a 20  {.  int i = 0;. 
4250: 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20   while( *z ){.  
4260: 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65    while( isspace
4270: 28 2a 7a 29 20 7c 7c 20 2a 7a 3d 3d 27 3b 27 20  (*z) || *z==';' 
4280: 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69 66  ){ z++; }.    if
4290: 28 20 2a 7a 3d 3d 27 22 27 20 26 26 20 7a 5b 31  ( *z=='"' && z[1
42a0: 5d 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 20  ] ){.      *z = 
42b0: 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20  0;.      z++;.  
42c0: 20 20 20 20 69 66 28 20 69 3c 6d 78 41 72 67 2d      if( i<mxArg-
42d0: 31 20 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d 20  1 ){ azArg[i++] 
42e0: 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68 69  = z; }.      whi
42f0: 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 22  le( *z && *z!='"
4300: 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20  ' ){ z++; }.    
4310: 20 20 69 66 28 20 2a 7a 3d 3d 30 20 29 20 62 72    if( *z==0 ) br
4320: 65 61 6b 3b 0a 20 20 20 20 20 20 2a 7a 20 3d 20  eak;.      *z = 
4330: 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20  0;.      z++;.  
4340: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
4350: 66 28 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b 20  f( i<mxArg-1 ){ 
4360: 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20  azArg[i++] = z; 
4370: 7d 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a  }.      while( *
4380: 7a 20 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a  z && !isspace(*z
4390: 29 20 26 26 20 2a 7a 21 3d 27 3b 27 20 26 26 20  ) && *z!=';' && 
43a0: 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b 20  *z!='"' ){ z++; 
43b0: 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20 26  }.      if( *z &
43c0: 26 20 2a 7a 21 3d 27 22 27 20 29 7b 0a 20 20 20  & *z!='"' ){.   
43d0: 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20       *z = 0;.   
43e0: 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20       z++;.      
43f0: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 7a  }.    }.  }.  az
4400: 41 72 67 5b 69 5d 20 3d 20 30 3b 0a 20 20 72 65  Arg[i] = 0;.  re
4410: 74 75 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn i;.}../*.**
4420: 20 53 63 61 6e 20 74 68 65 20 6d 75 6c 74 69 70   Scan the multip
4430: 61 72 74 2d 66 6f 72 6d 20 63 6f 6e 74 65 6e 74  art-form content
4440: 20 61 6e 64 20 6d 61 6b 65 20 61 70 70 72 6f 70   and make approp
4450: 72 69 61 74 65 20 65 6e 74 72 69 65 73 0a 2a 2a  riate entries.**
4460: 20 69 6e 74 6f 20 74 68 65 20 70 61 72 61 6d 65   into the parame
4470: 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a  ter table..**.**
4480: 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 73 74 72   The content str
4490: 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66  ing "z" is modif
44a0: 69 65 64 20 62 79 20 74 68 69 73 20 72 6f 75 74  ied by this rout
44b0: 69 6e 65 20 62 75 74 20 69 74 20 69 73 0a 2a 2a  ine but it is.**
44c0: 20 6e 6f 74 20 63 6f 70 69 65 64 2e 20 20 54 68   not copied.  Th
44d0: 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69  e calling functi
44e0: 6f 6e 20 6d 75 73 74 20 6e 6f 74 20 64 65 61 6c  on must not deal
44f0: 6c 6f 63 61 74 65 20 6f 72 20 6d 6f 64 69 66 79  locate or modify
4500: 0a 2a 2a 20 22 7a 22 20 61 66 74 65 72 20 74 68  .** "z" after th
4510: 69 73 20 72 6f 75 74 69 6e 65 20 66 69 6e 69 73  is routine finis
4520: 68 65 73 20 6f 72 20 69 74 20 63 6f 75 6c 64 20  hes or it could 
4530: 63 6f 72 72 75 70 74 20 74 68 65 20 70 61 72 61  corrupt the para
4540: 6d 65 74 65 72 0a 2a 2a 20 74 61 62 6c 65 2e 0a  meter.** table..
4550: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
4560: 72 6f 63 65 73 73 5f 6d 75 6c 74 69 70 61 72 74  rocess_multipart
4570: 5f 66 6f 72 6d 5f 64 61 74 61 28 63 68 61 72 20  _form_data(char 
4580: 2a 7a 2c 20 69 6e 74 20 6c 65 6e 29 7b 0a 20 20  *z, int len){.  
4590: 63 68 61 72 20 2a 7a 4c 69 6e 65 3b 0a 20 20 69  char *zLine;.  i
45a0: 6e 74 20 6e 41 72 67 2c 20 69 3b 0a 20 20 63 68  nt nArg, i;.  ch
45b0: 61 72 20 2a 7a 42 6f 75 6e 64 72 79 3b 0a 20 20  ar *zBoundry;.  
45c0: 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20  char *zValue;.  
45d0: 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 30 3b  char *zName = 0;
45e0: 0a 20 20 69 6e 74 20 73 68 6f 77 42 79 74 65 73  .  int showBytes
45f0: 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 61 7a   = 0;.  char *az
4600: 41 72 67 5b 35 30 5d 3b 0a 0a 20 20 7a 42 6f 75  Arg[50];..  zBou
4610: 6e 64 72 79 20 3d 20 67 65 74 5f 6c 69 6e 65 5f  ndry = get_line_
4620: 66 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20  from_string(&z, 
4630: 26 6c 65 6e 29 3b 0a 20 20 69 66 28 20 7a 42 6f  &len);.  if( zBo
4640: 75 6e 64 72 79 3d 3d 30 20 29 20 72 65 74 75 72  undry==0 ) retur
4650: 6e 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4c 69  n;.  while( (zLi
4660: 6e 65 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 72  ne = get_line_fr
4670: 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 6c  om_string(&z, &l
4680: 65 6e 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69  en))!=0 ){.    i
4690: 66 28 20 7a 4c 69 6e 65 5b 30 5d 3d 3d 30 20 29  f( zLine[0]==0 )
46a0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 6e  {.      int nCon
46b0: 74 65 6e 74 20 3d 20 30 3b 0a 20 20 20 20 20 20  tent = 0;.      
46c0: 7a 56 61 6c 75 65 20 3d 20 67 65 74 5f 62 6f 75  zValue = get_bou
46d0: 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28 26 7a 2c  nded_content(&z,
46e0: 20 26 6c 65 6e 2c 20 7a 42 6f 75 6e 64 72 79 2c   &len, zBoundry,
46f0: 20 26 6e 43 6f 6e 74 65 6e 74 29 3b 0a 20 20 20   &nContent);.   
4700: 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20     if( zName && 
4710: 7a 56 61 6c 75 65 20 26 26 20 69 73 6c 6f 77 65  zValue && islowe
4720: 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20  r(zName[0]) ){. 
4730: 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70         cgi_set_p
4740: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28  arameter_nocopy(
4750: 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a  zName, zValue);.
4760: 20 20 20 20 20 20 20 20 69 66 28 20 73 68 6f 77          if( show
4770: 42 79 74 65 73 20 29 7b 0a 20 20 20 20 20 20 20  Bytes ){.       
4780: 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d     cgi_set_param
4790: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69  eter_nocopy(mpri
47a0: 6e 74 66 28 22 25 73 3a 62 79 74 65 73 22 2c 20  ntf("%s:bytes", 
47b0: 7a 4e 61 6d 65 29 2c 0a 20 20 20 20 20 20 20 20  zName),.        
47c0: 20 20 20 20 20 20 20 6d 70 72 69 6e 74 66 28 22         mprintf("
47d0: 25 64 22 2c 6e 43 6f 6e 74 65 6e 74 29 29 3b 0a  %d",nContent));.
47e0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
47f0: 7d 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20  }.      zName = 
4800: 30 3b 0a 20 20 20 20 20 20 73 68 6f 77 42 79 74  0;.      showByt
4810: 65 73 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73  es = 0;.    }els
4820: 65 7b 0a 20 20 20 20 20 20 6e 41 72 67 20 3d 20  e{.      nArg = 
4830: 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 7a 4c  tokenize_line(zL
4840: 69 6e 65 2c 20 73 69 7a 65 6f 66 28 61 7a 41 72  ine, sizeof(azAr
4850: 67 29 2f 73 69 7a 65 6f 66 28 61 7a 41 72 67 5b  g)/sizeof(azArg[
4860: 30 5d 29 2c 20 61 7a 41 72 67 29 3b 0a 20 20 20  0]), azArg);.   
4870: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41     for(i=0; i<nA
4880: 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  rg; i++){.      
4890: 20 20 69 6e 74 20 63 20 3d 20 74 6f 6c 6f 77 65    int c = tolowe
48a0: 72 28 61 7a 41 72 67 5b 69 5d 5b 30 5d 29 3b 0a  r(azArg[i][0]);.
48b0: 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27          if( c=='
48c0: 63 27 20 26 26 20 73 74 72 69 63 6d 70 28 61 7a  c' && stricmp(az
48d0: 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d  Arg[i],"content-
48e0: 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22 29 3d 3d  disposition:")==
48f0: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  0 ){.          i
4900: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  ++;.        }els
4910: 65 20 69 66 28 20 63 3d 3d 27 6e 27 20 26 26 20  e if( c=='n' && 
4920: 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d  stricmp(azArg[i]
4930: 2c 22 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a  ,"name=")==0 ){.
4940: 20 20 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 20            zName 
4950: 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20  = azArg[++i];.  
4960: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
4970: 63 3d 3d 27 66 27 20 26 26 20 73 74 72 69 63 6d  c=='f' && stricm
4980: 70 28 61 7a 41 72 67 5b 69 5d 2c 22 66 69 6c 65  p(azArg[i],"file
4990: 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a 20 20  name=")==0 ){.  
49a0: 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20          char *z 
49b0: 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20  = azArg[++i];.  
49c0: 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d          if( zNam
49d0: 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f 77 65  e && z && islowe
49e0: 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20  r(zName[0]) ){. 
49f0: 20 20 20 20 20 20 20 20 20 20 20 63 67 69 5f 73             cgi_s
4a00: 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63  et_parameter_noc
4a10: 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 3a  opy(mprintf("%s:
4a20: 66 69 6c 65 6e 61 6d 65 22 2c 7a 4e 61 6d 65 29  filename",zName)
4a30: 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20  , z);.          
4a40: 7d 0a 20 20 20 20 20 20 20 20 20 20 73 68 6f 77  }.          show
4a50: 42 79 74 65 73 20 3d 20 31 3b 0a 20 20 20 20 20  Bytes = 1;.     
4a60: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d     }else if( c==
4a70: 27 63 27 20 26 26 20 73 74 72 69 63 6d 70 28 61  'c' && stricmp(a
4a80: 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74  zArg[i],"content
4a90: 2d 74 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a 20  -type:")==0 ){. 
4aa0: 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a           char *z
4ab0: 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20   = azArg[++i];. 
4ac0: 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61           if( zNa
4ad0: 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f 77  me && z && islow
4ae0: 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a  er(zName[0]) ){.
4af0: 20 20 20 20 20 20 20 20 20 20 20 20 63 67 69 5f              cgi_
4b00: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
4b10: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73  copy(mprintf("%s
4b20: 3a 6d 69 6d 65 74 79 70 65 22 2c 7a 4e 61 6d 65  :mimetype",zName
4b30: 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 20  ), z);.         
4b40: 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
4b50: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 20     }.    }.  }  
4b60: 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20        .}../*.** 
4b70: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 71  Initialize the q
4b80: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 64  uery parameter d
4b90: 61 74 61 62 61 73 65 2e 20 20 49 6e 66 6f 72 6d  atabase.  Inform
4ba0: 61 74 69 6f 6e 20 69 73 20 70 75 6c 6c 65 64 20  ation is pulled 
4bb0: 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 51 55 45 52  from.** the QUER
4bc0: 59 5f 53 54 52 49 4e 47 20 65 6e 76 69 72 6f 6e  Y_STRING environ
4bd0: 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 28 69  ment variable (i
4be0: 66 20 69 74 20 65 78 69 73 74 73 29 2c 20 66 72  f it exists), fr
4bf0: 6f 6d 20 73 74 61 6e 64 61 72 64 0a 2a 2a 20 69  om standard.** i
4c00: 6e 70 75 74 20 69 66 20 74 68 65 72 65 20 69 73  nput if there is
4c10: 20 50 4f 53 54 20 64 61 74 61 2c 20 61 6e 64 20   POST data, and 
4c20: 66 72 6f 6d 20 48 54 54 50 5f 43 4f 4f 4b 49 45  from HTTP_COOKIE
4c30: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 69 6e  ..*/.void cgi_in
4c40: 69 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 72  it(void){.  char
4c50: 20 2a 7a 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61   *z;.  const cha
4c60: 72 20 2a 7a 54 79 70 65 3b 0a 20 20 69 6e 74 20  r *zType;.  int 
4c70: 6c 65 6e 3b 0a 20 20 63 67 69 5f 64 65 73 74 69  len;.  cgi_desti
4c80: 6e 61 74 69 6f 6e 28 43 47 49 5f 42 4f 44 59 29  nation(CGI_BODY)
4c90: 3b 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 50  ;.  z = (char*)P
4ca0: 28 22 51 55 45 52 59 5f 53 54 52 49 4e 47 22 29  ("QUERY_STRING")
4cb0: 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 20  ;.  if( z ){.   
4cc0: 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73   z = mprintf("%s
4cd0: 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 61  ",z);.    add_pa
4ce0: 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 26 27 29  ram_list(z, '&')
4cf0: 3b 0a 20 20 7d 0a 0a 20 20 6c 65 6e 20 3d 20 61  ;.  }..  len = a
4d00: 74 6f 69 28 50 44 28 22 43 4f 4e 54 45 4e 54 5f  toi(PD("CONTENT_
4d10: 4c 45 4e 47 54 48 22 2c 20 22 30 22 29 29 3b 0a  LENGTH", "0"));.
4d20: 20 20 67 2e 7a 43 6f 6e 74 65 6e 74 54 79 70 65    g.zContentType
4d30: 20 3d 20 7a 54 79 70 65 20 3d 20 50 28 22 43 4f   = zType = P("CO
4d40: 4e 54 45 4e 54 5f 54 59 50 45 22 29 3b 0a 20 20  NTENT_TYPE");.  
4d50: 69 66 28 20 6c 65 6e 3e 30 20 26 26 20 7a 54 79  if( len>0 && zTy
4d60: 70 65 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a  pe ){.    blob_z
4d70: 65 72 6f 28 26 67 2e 63 67 69 49 6e 29 3b 0a 20  ero(&g.cgiIn);. 
4d80: 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54     if( strcmp(zT
4d90: 79 70 65 2c 22 61 70 70 6c 69 63 61 74 69 6f 6e  ype,"application
4da0: 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c 65  /x-www-form-urle
4db0: 6e 63 6f 64 65 64 22 29 3d 3d 30 20 0a 20 20 20  ncoded")==0 .   
4dc0: 20 20 20 20 20 20 7c 7c 20 73 74 72 6e 63 6d 70        || strncmp
4dd0: 28 7a 54 79 70 65 2c 22 6d 75 6c 74 69 70 61 72  (zType,"multipar
4de0: 74 2f 66 6f 72 6d 2d 64 61 74 61 22 2c 31 39 29  t/form-data",19)
4df0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 7a 20 3d  ==0 ){.      z =
4e00: 20 6d 61 6c 6c 6f 63 28 20 6c 65 6e 2b 31 20 29   malloc( len+1 )
4e10: 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 3d 3d 30  ;.      if( z==0
4e20: 20 29 20 65 78 69 74 28 31 29 3b 0a 20 20 20 20   ) exit(1);.    
4e30: 20 20 6c 65 6e 20 3d 20 66 72 65 61 64 28 7a 2c    len = fread(z,
4e40: 20 31 2c 20 6c 65 6e 2c 20 73 74 64 69 6e 29 3b   1, len, stdin);
4e50: 0a 20 20 20 20 20 20 7a 5b 6c 65 6e 5d 20 3d 20  .      z[len] = 
4e60: 30 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 54 79  0;.      if( zTy
4e70: 70 65 5b 30 5d 3d 3d 27 61 27 20 29 7b 0a 20 20  pe[0]=='a' ){.  
4e80: 20 20 20 20 20 20 61 64 64 5f 70 61 72 61 6d 5f        add_param_
4e90: 6c 69 73 74 28 7a 2c 20 27 26 27 29 3b 0a 20 20  list(z, '&');.  
4ea0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4eb0: 20 20 20 70 72 6f 63 65 73 73 5f 6d 75 6c 74 69     process_multi
4ec0: 70 61 72 74 5f 66 6f 72 6d 5f 64 61 74 61 28 7a  part_form_data(z
4ed0: 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 7d 0a  , len);.      }.
4ee0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74      }else if( st
4ef0: 72 63 6d 70 28 7a 54 79 70 65 2c 20 22 61 70 70  rcmp(zType, "app
4f00: 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69  lication/x-fossi
4f10: 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  l")==0 ){.      
4f20: 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 63  blob_read_from_c
4f30: 68 61 6e 6e 65 6c 28 26 67 2e 63 67 69 49 6e 2c  hannel(&g.cgiIn,
4f40: 20 73 74 64 69 6e 2c 20 6c 65 6e 29 3b 0a 20 20   stdin, len);.  
4f50: 20 20 20 20 62 6c 6f 62 5f 75 6e 63 6f 6d 70 72      blob_uncompr
4f60: 65 73 73 28 26 67 2e 63 67 69 49 6e 2c 20 26 67  ess(&g.cgiIn, &g
4f70: 2e 63 67 69 49 6e 29 3b 0a 20 20 20 20 7d 65 6c  .cgiIn);.    }el
4f80: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54  se if( strcmp(zT
4f90: 79 70 65 2c 20 22 61 70 70 6c 69 63 61 74 69 6f  ype, "applicatio
4fa0: 6e 2f 78 2d 66 6f 73 73 69 6c 2d 64 65 62 75 67  n/x-fossil-debug
4fb0: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 62  ")==0 ){.      b
4fc0: 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 63 68  lob_read_from_ch
4fd0: 61 6e 6e 65 6c 28 26 67 2e 63 67 69 49 6e 2c 20  annel(&g.cgiIn, 
4fe0: 73 74 64 69 6e 2c 20 6c 65 6e 29 3b 0a 20 20 20  stdin, len);.   
4ff0: 20 7d 0a 20 20 7d 0a 0a 20 20 7a 20 3d 20 28 63   }.  }..  z = (c
5000: 68 61 72 2a 29 50 28 22 48 54 54 50 5f 43 4f 4f  har*)P("HTTP_COO
5010: 4b 49 45 22 29 3b 0a 20 20 69 66 28 20 7a 20 29  KIE");.  if( z )
5020: 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e 74  {.    z = mprint
5030: 66 28 22 25 73 22 2c 7a 29 3b 0a 20 20 20 20 61  f("%s",z);.    a
5040: 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c  dd_param_list(z,
5050: 20 27 3b 27 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a   ';');.  }.}../*
5060: 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 20  .** This is the 
5070: 63 6f 6d 70 61 72 69 73 6f 6e 20 66 75 6e 63 74  comparison funct
5080: 69 6f 6e 20 75 73 65 64 20 74 6f 20 73 6f 72 74  ion used to sort
5090: 20 74 68 65 20 61 50 61 72 61 6d 51 50 5b 5d 20   the aParamQP[] 
50a0: 61 72 72 61 79 20 6f 66 0a 2a 2a 20 71 75 65 72  array of.** quer
50b0: 79 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e 64  y parameters and
50c0: 20 63 6f 6f 6b 69 65 73 2e 0a 2a 2f 0a 73 74 61   cookies..*/.sta
50d0: 74 69 63 20 69 6e 74 20 71 70 61 72 61 6d 5f 63  tic int qparam_c
50e0: 6f 6d 70 61 72 65 28 63 6f 6e 73 74 20 76 6f 69  ompare(const voi
50f0: 64 20 2a 61 2c 20 63 6f 6e 73 74 20 76 6f 69 64  d *a, const void
5100: 20 2a 62 29 7b 0a 20 20 73 74 72 75 63 74 20 51   *b){.  struct Q
5110: 50 61 72 61 6d 20 2a 70 41 20 3d 20 28 73 74 72  Param *pA = (str
5120: 75 63 74 20 51 50 61 72 61 6d 2a 29 61 3b 0a 20  uct QParam*)a;. 
5130: 20 73 74 72 75 63 74 20 51 50 61 72 61 6d 20 2a   struct QParam *
5140: 70 42 20 3d 20 28 73 74 72 75 63 74 20 51 50 61  pB = (struct QPa
5150: 72 61 6d 2a 29 62 3b 0a 20 20 69 6e 74 20 63 3b  ram*)b;.  int c;
5160: 0a 20 20 63 20 3d 20 73 74 72 63 6d 70 28 70 41  .  c = strcmp(pA
5170: 2d 3e 7a 4e 61 6d 65 2c 20 70 42 2d 3e 7a 4e 61  ->zName, pB->zNa
5180: 6d 65 29 3b 0a 20 20 69 66 28 20 63 3d 3d 30 20  me);.  if( c==0 
5190: 29 7b 0a 20 20 20 20 63 20 3d 20 70 41 2d 3e 73  ){.    c = pA->s
51a0: 65 71 20 2d 20 70 42 2d 3e 73 65 71 3b 0a 20 20  eq - pB->seq;.  
51b0: 7d 0a 20 20 72 65 74 75 72 6e 20 63 3b 0a 7d 0a  }.  return c;.}.
51c0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68  ./*.** Return th
51d0: 65 20 76 61 6c 75 65 20 6f 66 20 61 20 71 75 65  e value of a que
51e0: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20  ry parameter or 
51f0: 63 6f 6f 6b 69 65 20 77 68 6f 73 65 20 6e 61 6d  cookie whose nam
5200: 65 20 69 73 20 7a 4e 61 6d 65 2e 0a 2a 2a 20 49  e is zName..** I
5210: 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 71 75  f there is no qu
5220: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72  ery parameter or
5230: 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 64 20 7a 4e   cookie named zN
5240: 61 6d 65 20 61 6e 64 20 74 68 65 20 66 69 72 73  ame and the firs
5250: 74 0a 2a 2a 20 63 68 61 72 61 63 74 65 72 20 6f  t.** character o
5260: 66 20 7a 4e 61 6d 65 20 69 73 20 75 70 70 65 72  f zName is upper
5270: 63 61 73 65 2c 20 74 68 65 6e 20 63 68 65 63 6b  case, then check
5280: 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 72 65   to see if there
5290: 20 69 73 20 61 6e 0a 2a 2a 20 65 6e 76 69 72 6f   is an.** enviro
52a0: 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 62  nment variable b
52b0: 79 20 74 68 61 74 20 6e 61 6d 65 20 61 6e 64 20  y that name and 
52c0: 72 65 74 75 72 6e 20 69 74 20 69 66 20 74 68 65  return it if the
52d0: 72 65 20 69 73 2e 20 20 41 73 0a 2a 2a 20 61 20  re is.  As.** a 
52e0: 6c 61 73 74 20 72 65 73 6f 72 74 20 77 68 65 6e  last resort when
52f0: 20 6e 6f 74 68 69 6e 67 20 65 6c 73 65 20 6d 61   nothing else ma
5300: 74 63 68 65 73 2c 20 72 65 74 75 72 6e 20 7a 44  tches, return zD
5310: 65 66 61 75 6c 74 2e 0a 2a 2f 0a 63 6f 6e 73 74  efault..*/.const
5320: 20 63 68 61 72 20 2a 63 67 69 5f 70 61 72 61 6d   char *cgi_param
5330: 65 74 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20  eter(const char 
5340: 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68  *zName, const ch
5350: 61 72 20 2a 7a 44 65 66 61 75 6c 74 29 7b 0a 20  ar *zDefault){. 
5360: 20 69 6e 74 20 6c 6f 2c 20 68 69 2c 20 6d 69 64   int lo, hi, mid
5370: 2c 20 63 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 73  , c;..  /* The s
5380: 6f 72 74 51 50 20 66 6c 61 67 20 69 73 20 73 65  ortQP flag is se
5390: 74 20 77 68 65 6e 65 76 65 72 20 61 20 6e 65 77  t whenever a new
53a0: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
53b0: 20 69 73 20 69 6e 73 65 72 74 65 64 2e 0a 20 20   is inserted..  
53c0: 2a 2a 20 49 74 20 69 6e 64 69 63 61 74 65 73 20  ** It indicates 
53d0: 74 68 61 74 20 77 65 20 6e 65 65 64 20 74 6f 20  that we need to 
53e0: 72 65 73 6f 72 74 20 74 68 65 20 71 75 65 72 79  resort the query
53f0: 20 70 61 72 61 6d 65 74 65 72 73 2e 0a 20 20 2a   parameters..  *
5400: 2f 0a 20 20 69 66 28 20 73 6f 72 74 51 50 20 29  /.  if( sortQP )
5410: 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20 6a 3b 0a  {.    int i, j;.
5420: 20 20 20 20 71 73 6f 72 74 28 61 50 61 72 61 6d      qsort(aParam
5430: 51 50 2c 20 6e 55 73 65 64 51 50 2c 20 73 69 7a  QP, nUsedQP, siz
5440: 65 6f 66 28 61 50 61 72 61 6d 51 50 5b 30 5d 29  eof(aParamQP[0])
5450: 2c 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72 65  , qparam_compare
5460: 29 3b 0a 20 20 20 20 73 6f 72 74 51 50 20 3d 20  );.    sortQP = 
5470: 30 3b 0a 20 20 20 20 2f 2a 20 41 66 74 65 72 20  0;.    /* After 
5480: 73 6f 72 74 69 6e 67 2c 20 72 65 6d 6f 76 65 20  sorting, remove 
5490: 64 75 70 6c 69 63 61 74 65 20 70 61 72 61 6d 65  duplicate parame
54a0: 74 65 72 73 2e 20 20 54 68 65 20 73 65 63 6f 6e  ters.  The secon
54b0: 64 61 72 79 20 73 6f 72 74 0a 20 20 20 20 2a 2a  dary sort.    **
54c0: 20 6b 65 79 20 69 73 20 61 50 61 72 61 6d 51 50   key is aParamQP
54d0: 5b 5d 2e 73 65 71 20 61 6e 64 20 77 65 20 6b 65  [].seq and we ke
54e0: 65 70 20 74 68 65 20 66 69 72 73 74 20 65 6e 74  ep the first ent
54f0: 72 79 2e 20 20 54 68 61 74 20 6d 65 61 6e 73 0a  ry.  That means.
5500: 20 20 20 20 2a 2a 20 77 69 74 68 20 64 75 70 6c      ** with dupl
5510: 69 63 61 74 65 20 63 61 6c 6c 73 20 74 6f 20 63  icate calls to c
5520: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72  gi_set_parameter
5530: 28 29 20 74 68 65 20 73 65 63 6f 6e 64 20 61 6e  () the second an
5540: 64 0a 20 20 20 20 2a 2a 20 73 75 62 73 65 71 75  d.    ** subsequ
5550: 65 6e 74 20 63 61 6c 6c 73 20 61 72 65 20 65 66  ent calls are ef
5560: 66 65 63 74 69 76 65 6c 79 20 6e 6f 2d 6f 70 73  fectively no-ops
5570: 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d 6a  . */.    for(i=j
5580: 3d 31 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 69  =1; i<nUsedQP; i
5590: 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 73  ++){.      if( s
55a0: 74 72 63 6d 70 28 61 50 61 72 61 6d 51 50 5b 69  trcmp(aParamQP[i
55b0: 5d 2e 7a 4e 61 6d 65 2c 61 50 61 72 61 6d 51 50  ].zName,aParamQP
55c0: 5b 69 2d 31 5d 2e 7a 4e 61 6d 65 29 3d 3d 30 20  [i-1].zName)==0 
55d0: 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 74 69  ){.        conti
55e0: 6e 75 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20  nue;.      }.   
55f0: 20 20 20 69 66 28 20 6a 3c 69 20 29 7b 0a 20 20     if( j<i ){.  
5600: 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61 50        memcpy(&aP
5610: 61 72 61 6d 51 50 5b 6a 5d 2c 20 26 61 50 61 72  aramQP[j], &aPar
5620: 61 6d 51 50 5b 69 5d 2c 20 73 69 7a 65 6f 66 28  amQP[i], sizeof(
5630: 61 50 61 72 61 6d 51 50 5b 6a 5d 29 29 3b 0a 20  aParamQP[j]));. 
5640: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6a 2b 2b       }.      j++
5650: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 55 73 65  ;.    }.    nUse
5660: 64 51 50 20 3d 20 6a 3b 0a 20 20 7d 0a 0a 20 20  dQP = j;.  }..  
5670: 2f 2a 20 44 6f 20 61 20 62 69 6e 61 72 79 20 73  /* Do a binary s
5680: 65 61 72 63 68 20 66 6f 72 20 61 20 6d 61 74 63  earch for a matc
5690: 68 69 6e 67 20 71 75 65 72 79 20 70 61 72 61 6d  hing query param
56a0: 65 74 65 72 20 2a 2f 0a 20 20 6c 6f 20 3d 20 30  eter */.  lo = 0
56b0: 3b 0a 20 20 68 69 20 3d 20 6e 55 73 65 64 51 50  ;.  hi = nUsedQP
56c0: 2d 31 3b 0a 20 20 77 68 69 6c 65 28 20 6c 6f 3c  -1;.  while( lo<
56d0: 3d 68 69 20 29 7b 0a 20 20 20 20 6d 69 64 20 3d  =hi ){.    mid =
56e0: 20 28 6c 6f 2b 68 69 29 2f 32 3b 0a 20 20 20 20   (lo+hi)/2;.    
56f0: 63 20 3d 20 73 74 72 63 6d 70 28 61 50 61 72 61  c = strcmp(aPara
5700: 6d 51 50 5b 6d 69 64 5d 2e 7a 4e 61 6d 65 2c 20  mQP[mid].zName, 
5710: 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20  zName);.    if( 
5720: 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 43 47  c==0 ){.      CG
5730: 49 44 45 42 55 47 28 28 22 6d 65 6d 2d 6d 61 74  IDEBUG(("mem-mat
5740: 63 68 20 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e  ch [%s] = [%s]\n
5750: 22 2c 20 7a 4e 61 6d 65 2c 20 61 50 61 72 61 6d  ", zName, aParam
5760: 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 29 29  QP[mid].zValue))
5770: 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 61  ;.      return a
5780: 50 61 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 56 61  ParamQP[mid].zVa
5790: 6c 75 65 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  lue;.    }else i
57a0: 66 28 20 63 3e 30 20 29 7b 0a 20 20 20 20 20 20  f( c>0 ){.      
57b0: 68 69 20 3d 20 6d 69 64 2d 31 3b 0a 20 20 20 20  hi = mid-1;.    
57c0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6c 6f 20  }else{.      lo 
57d0: 3d 20 6d 69 64 2b 31 3b 0a 20 20 20 20 7d 0a 20  = mid+1;.    }. 
57e0: 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 6d   }..  /* If no m
57f0: 61 74 63 68 20 69 73 20 66 6f 75 6e 64 20 61 6e  atch is found an
5800: 64 20 74 68 65 20 6e 61 6d 65 20 62 65 67 69 6e  d the name begin
5810: 73 20 77 69 74 68 20 61 6e 20 75 70 70 65 72 2d  s with an upper-
5820: 63 61 73 65 0a 20 20 2a 2a 20 6c 65 74 74 65 72  case.  ** letter
5830: 2c 20 74 68 65 6e 20 63 68 65 63 6b 20 74 6f 20  , then check to 
5840: 73 65 65 20 69 66 20 74 68 65 72 65 20 69 73 20  see if there is 
5850: 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76  an environment v
5860: 61 72 69 61 62 6c 65 0a 20 20 2a 2a 20 77 69 74  ariable.  ** wit
5870: 68 20 74 68 65 20 67 69 76 65 6e 20 6e 61 6d 65  h the given name
5880: 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 73 75  ..  */.  if( isu
5890: 70 70 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29  pper(zName[0]) )
58a0: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
58b0: 20 2a 7a 56 61 6c 75 65 20 3d 20 67 65 74 65 6e   *zValue = geten
58c0: 76 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66  v(zName);.    if
58d0: 28 20 7a 56 61 6c 75 65 20 29 7b 0a 20 20 20 20  ( zValue ){.    
58e0: 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65    cgi_set_parame
58f0: 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65  ter_nocopy(zName
5900: 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 20  , zValue);.     
5910: 20 43 47 49 44 45 42 55 47 28 28 22 65 6e 76 2d   CGIDEBUG(("env-
5920: 6d 61 74 63 68 20 5b 25 73 5d 20 3d 20 5b 25 73  match [%s] = [%s
5930: 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c 20 7a 56 61  ]\n", zName, zVa
5940: 6c 75 65 29 29 3b 0a 20 20 20 20 20 20 72 65 74  lue));.      ret
5950: 75 72 6e 20 7a 56 61 6c 75 65 3b 0a 20 20 20 20  urn zValue;.    
5960: 7d 0a 20 20 7d 0a 20 20 43 47 49 44 45 42 55 47  }.  }.  CGIDEBUG
5970: 28 28 22 6e 6f 2d 6d 61 74 63 68 20 5b 25 73 5d  (("no-match [%s]
5980: 5c 6e 22 2c 20 7a 4e 61 6d 65 29 29 3b 0a 20 20  \n", zName));.  
5990: 72 65 74 75 72 6e 20 7a 44 65 66 61 75 6c 74 3b  return zDefault;
59a0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
59b0: 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65   the name of the
59c0: 20 69 2d 74 68 20 43 47 49 20 70 61 72 61 6d 65   i-th CGI parame
59d0: 74 65 72 2e 20 20 52 65 74 75 72 6e 20 4e 55 4c  ter.  Return NUL
59e0: 4c 20 69 66 20 74 68 65 72 65 0a 2a 2a 20 61 72  L if there.** ar
59f0: 65 20 66 65 77 65 72 20 74 68 61 6e 20 69 20 72  e fewer than i r
5a00: 65 67 69 73 74 65 72 65 64 20 43 47 49 20 70 61  egistered CGI pa
5a10: 72 6d 61 65 74 65 72 73 2e 0a 2a 2f 0a 63 6f 6e  rmaeters..*/.con
5a20: 73 74 20 63 68 61 72 20 2a 63 67 69 5f 70 61 72  st char *cgi_par
5a30: 61 6d 65 74 65 72 5f 6e 61 6d 65 28 69 6e 74 20  ameter_name(int 
5a40: 69 29 7b 0a 20 20 69 66 28 20 69 3e 3d 30 20 26  i){.  if( i>=0 &
5a50: 26 20 69 3c 6e 55 73 65 64 51 50 20 29 7b 0a 20  & i<nUsedQP ){. 
5a60: 20 20 20 72 65 74 75 72 6e 20 61 50 61 72 61 6d     return aParam
5a70: 51 50 5b 69 5d 2e 7a 4e 61 6d 65 3b 0a 20 20 7d  QP[i].zName;.  }
5a80: 65 6c 73 65 7b 0a 20 20 20 20 72 65 74 75 72 6e  else{.    return
5a90: 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a   0;.  }.}../*.**
5aa0: 20 50 72 69 6e 74 20 43 47 49 20 64 65 62 75 67   Print CGI debug
5ab0: 67 69 6e 67 20 6d 65 73 73 61 67 65 73 2e 0a 2a  ging messages..*
5ac0: 2f 0a 76 6f 69 64 20 63 67 69 5f 64 65 62 75 67  /.void cgi_debug
5ad0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f  (const char *zFo
5ae0: 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61  rmat, ...){.  va
5af0: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 69 66 28 20  _list ap;.  if( 
5b00: 67 2e 66 44 65 62 75 67 20 29 7b 0a 20 20 20 20  g.fDebug ){.    
5b10: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f  va_start(ap, zFo
5b20: 72 6d 61 74 29 3b 0a 20 20 20 20 76 66 70 72 69  rmat);.    vfpri
5b30: 6e 74 66 28 67 2e 66 44 65 62 75 67 2c 20 7a 46  ntf(g.fDebug, zF
5b40: 6f 72 6d 61 74 2c 20 61 70 29 3b 0a 20 20 20 20  ormat, ap);.    
5b50: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 20 20  va_end(ap);.    
5b60: 66 66 6c 75 73 68 28 67 2e 66 44 65 62 75 67 29  fflush(g.fDebug)
5b70: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  ;.  }.}../*.** R
5b80: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 61 6e  eturn true if an
5b90: 79 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70  y of the query p
5ba0: 61 72 61 6d 65 74 65 72 73 20 69 6e 20 74 68 65  arameters in the
5bb0: 20 61 72 67 75 6d 65 6e 74 0a 2a 2a 20 6c 69 73   argument.** lis
5bc0: 74 20 61 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a  t are defined..*
5bd0: 2f 0a 69 6e 74 20 63 67 69 5f 61 6e 79 28 63 6f  /.int cgi_any(co
5be0: 6e 73 74 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e  nst char *z, ...
5bf0: 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b  ){.  va_list ap;
5c00: 0a 20 20 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69  .  char *z2;.  i
5c10: 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72  f( cgi_parameter
5c20: 28 7a 2c 30 29 21 3d 30 20 29 20 72 65 74 75 72  (z,0)!=0 ) retur
5c30: 6e 20 31 3b 0a 20 20 76 61 5f 73 74 61 72 74 28  n 1;.  va_start(
5c40: 61 70 2c 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28  ap, z);.  while(
5c50: 20 28 7a 32 20 3d 20 76 61 5f 61 72 67 28 61 70   (z2 = va_arg(ap
5c60: 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a  , char*))!=0 ){.
5c70: 20 20 20 20 69 66 28 20 63 67 69 5f 70 61 72 61      if( cgi_para
5c80: 6d 65 74 65 72 28 7a 32 2c 30 29 21 3d 30 20 29  meter(z2,0)!=0 )
5c90: 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 20   return 1;.  }. 
5ca0: 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72   va_end(ap);.  r
5cb0: 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn 0;.}../*.*
5cc0: 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 66  * Return true if
5cd0: 20 61 6c 6c 20 6f 66 20 74 68 65 20 71 75 65 72   all of the quer
5ce0: 79 20 70 61 72 61 6d 65 74 65 72 73 20 69 6e 20  y parameters in 
5cf0: 74 68 65 20 61 72 67 75 6d 65 6e 74 20 6c 69 73  the argument lis
5d00: 74 0a 2a 2a 20 61 72 65 20 64 65 66 69 6e 65 64  t.** are defined
5d10: 2e 0a 2a 2f 0a 69 6e 74 20 63 67 69 5f 61 6c 6c  ..*/.int cgi_all
5d20: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 2c 20  (const char *z, 
5d30: 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20  ...){.  va_list 
5d40: 61 70 3b 0a 20 20 63 68 61 72 20 2a 7a 32 3b 0a  ap;.  char *z2;.
5d50: 20 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65    if( cgi_parame
5d60: 74 65 72 28 7a 2c 30 29 3d 3d 30 20 29 20 72 65  ter(z,0)==0 ) re
5d70: 74 75 72 6e 20 30 3b 0a 20 20 76 61 5f 73 74 61  turn 0;.  va_sta
5d80: 72 74 28 61 70 2c 20 7a 29 3b 0a 20 20 77 68 69  rt(ap, z);.  whi
5d90: 6c 65 28 20 28 7a 32 20 3d 20 76 61 5f 61 72 67  le( (z2 = va_arg
5da0: 28 61 70 2c 20 63 68 61 72 2a 29 29 3d 3d 30 20  (ap, char*))==0 
5db0: 29 7b 0a 20 20 20 20 69 66 28 20 63 67 69 5f 70  ){.    if( cgi_p
5dc0: 61 72 61 6d 65 74 65 72 28 7a 32 2c 30 29 3d 3d  arameter(z2,0)==
5dd0: 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20  0 ) return 0;.  
5de0: 7d 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a  }.  va_end(ap);.
5df0: 20 20 72 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f    return 1;.}../
5e00: 2a 0a 2a 2a 20 50 72 69 6e 74 20 61 6c 6c 20 71  *.** Print all q
5e10: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 20  uery parameters 
5e20: 6f 6e 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70  on standard outp
5e30: 75 74 2e 20 20 46 6f 72 6d 61 74 20 74 68 65 0a  ut.  Format the.
5e40: 2a 2a 20 70 61 72 61 6d 65 74 65 72 73 20 61 73  ** parameters as
5e50: 20 48 54 4d 4c 2e 20 20 54 68 69 73 20 69 73 20   HTML.  This is 
5e60: 75 73 65 64 20 66 6f 72 20 74 65 73 74 69 6e 67  used for testing
5e70: 20 61 6e 64 20 64 65 62 75 67 67 69 6e 67 2e 0a   and debugging..
5e80: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 72 69 6e  */.void cgi_prin
5e90: 74 5f 61 6c 6c 28 76 6f 69 64 29 7b 0a 20 20 69  t_all(void){.  i
5ea0: 6e 74 20 69 3b 0a 20 20 63 67 69 5f 70 61 72 61  nt i;.  cgi_para
5eb0: 6d 65 74 65 72 28 22 22 2c 22 22 29 3b 20 20 2f  meter("","");  /
5ec0: 2a 20 46 6f 72 63 65 20 74 68 65 20 70 61 72 61  * Force the para
5ed0: 6d 65 74 65 72 73 20 69 6e 74 6f 20 73 6f 72 74  meters into sort
5ee0: 65 64 20 6f 72 64 65 72 20 2a 2f 0a 20 20 66 6f  ed order */.  fo
5ef0: 72 28 69 3d 30 3b 20 69 3c 6e 55 73 65 64 51 50  r(i=0; i<nUsedQP
5f00: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 63 67 69 5f  ; i++){.    cgi_
5f10: 70 72 69 6e 74 66 28 22 25 73 20 3d 20 25 73 20  printf("%s = %s 
5f20: 20 3c 62 72 20 2f 3e 5c 6e 22 2c 0a 20 20 20 20   <br />\n",.    
5f30: 20 20 20 68 74 6d 6c 69 7a 65 28 61 50 61 72 61     htmlize(aPara
5f40: 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 2d 31  mQP[i].zName, -1
5f50: 29 2c 20 68 74 6d 6c 69 7a 65 28 61 50 61 72 61  ), htmlize(aPara
5f60: 6d 51 50 5b 69 5d 2e 7a 56 61 6c 75 65 2c 20 2d  mQP[i].zValue, -
5f70: 31 29 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a  1));.  }.}../*.*
5f80: 2a 20 57 72 69 74 65 20 48 54 4d 4c 20 74 65 78  * Write HTML tex
5f90: 74 20 66 6f 72 20 61 6e 20 6f 70 74 69 6f 6e 20  t for an option 
5fa0: 6d 65 6e 75 20 74 6f 20 73 74 61 6e 64 61 72 64  menu to standard
5fb0: 20 6f 75 74 70 75 74 2e 20 20 7a 50 61 72 61 6d   output.  zParam
5fc0: 0a 2a 2a 20 69 73 20 74 68 65 20 71 75 65 72 79  .** is the query
5fd0: 20 70 61 72 61 6d 65 74 65 72 20 74 68 61 74 20   parameter that 
5fe0: 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20  the option menu 
5ff0: 73 65 74 73 2e 20 20 7a 44 66 6c 74 20 69 73 20  sets.  zDflt is 
6000: 74 68 65 0a 2a 2a 20 69 6e 69 74 69 61 6c 20 76  the.** initial v
6010: 61 6c 75 65 20 6f 66 20 74 68 65 20 6f 70 74 69  alue of the opti
6020: 6f 6e 20 6d 65 6e 75 2e 20 20 41 64 64 69 74 69  on menu.  Additi
6030: 6f 6e 20 61 72 67 75 6d 65 6e 74 73 20 61 72 65  on arguments are
6040: 20 6e 61 6d 65 2f 76 61 6c 75 65 0a 2a 2a 20 70   name/value.** p
6050: 61 69 72 73 20 74 68 61 74 20 64 65 66 69 6e 65  airs that define
6060: 20 76 61 6c 75 65 73 20 6f 6e 20 74 68 65 20 6d   values on the m
6070: 65 6e 75 2e 20 20 54 68 65 20 6c 69 73 74 20 69  enu.  The list i
6080: 73 20 74 65 72 6d 69 6e 61 74 65 64 20 77 69 74  s terminated wit
6090: 68 0a 2a 2a 20 61 20 73 69 6e 67 6c 65 20 4e 55  h.** a single NU
60a0: 4c 4c 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a  LL argument..*/.
60b0: 76 6f 69 64 20 63 67 69 5f 6f 70 74 69 6f 6e 6d  void cgi_optionm
60c0: 65 6e 75 28 69 6e 74 20 69 6e 2c 20 63 6f 6e 73  enu(int in, cons
60d0: 74 20 63 68 61 72 20 2a 7a 50 2c 20 63 6f 6e 73  t char *zP, cons
60e0: 74 20 63 68 61 72 20 2a 7a 44 2c 20 2e 2e 2e 29  t char *zD, ...)
60f0: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  {.  va_list ap;.
6100: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 2a    char *zName, *
6110: 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 64 66 6c 74  zVal;.  int dflt
6120: 53 65 65 6e 20 3d 20 30 3b 0a 20 20 63 67 69 5f  Seen = 0;.  cgi_
6130: 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c 65  printf("%*s<sele
6140: 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c  ct size=1 name=\
6150: 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22  "%s\">\n", in, "
6160: 22 2c 20 7a 50 29 3b 0a 20 20 76 61 5f 73 74 61  ", zP);.  va_sta
6170: 72 74 28 61 70 2c 20 7a 44 29 3b 0a 20 20 77 68  rt(ap, zD);.  wh
6180: 69 6c 65 28 20 28 7a 4e 61 6d 65 20 3d 20 76 61  ile( (zName = va
6190: 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a 29 29  _arg(ap, char*))
61a0: 21 3d 30 20 26 26 20 28 7a 56 61 6c 20 3d 20 76  !=0 && (zVal = v
61b0: 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a 29  a_arg(ap, char*)
61c0: 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20  )!=0 ){.    if( 
61d0: 73 74 72 63 6d 70 28 7a 56 61 6c 2c 7a 44 29 3d  strcmp(zVal,zD)=
61e0: 3d 30 20 29 7b 20 64 66 6c 74 53 65 65 6e 20 3d  =0 ){ dfltSeen =
61f0: 20 31 3b 20 62 72 65 61 6b 3b 20 7d 0a 20 20 7d   1; break; }.  }
6200: 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20  .  va_end(ap);. 
6210: 20 69 66 28 20 21 64 66 6c 74 53 65 65 6e 20 29   if( !dfltSeen )
6220: 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b 30 5d 20  {.    if( zD[0] 
6230: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  ){.      cgi_pri
6240: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20  ntf("%*s<option 
6250: 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c  value=\"%h\" sel
6260: 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e  ected>%h</option
6270: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e  >\n",.        in
6280: 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b  +2, "", zD, zD);
6290: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
62a0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a    cgi_printf("%*
62b0: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c  s<option value=\
62c0: 22 5c 22 20 73 65 6c 65 63 74 65 64 3e 26 6e 62  "\" selected>&nb
62d0: 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c  sp;</option>\n",
62e0: 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20   in+2, "");.    
62f0: 7d 0a 20 20 7d 0a 20 20 76 61 5f 73 74 61 72 74  }.  }.  va_start
6300: 28 61 70 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c  (ap, zD);.  whil
6310: 65 28 20 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61  e( (zName = va_a
6320: 72 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d  rg(ap, char*))!=
6330: 30 20 26 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f  0 && (zVal = va_
6340: 61 72 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21  arg(ap, char*))!
6350: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 4e  =0 ){.    if( zN
6360: 61 6d 65 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20  ame[0] ){.      
6370: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c  cgi_printf("%*s<
6380: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25  option value=\"%
6390: 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e  h\"%s>%h</option
63a0: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e  >\n",.        in
63b0: 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20  +2, "",.        
63c0: 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74  zVal,.        st
63d0: 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f  rcmp(zVal, zD) ?
63e0: 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64   "" : " selected
63f0: 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d 65  ",.        zName
6400: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65  .      );.    }e
6410: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70  lse{.      cgi_p
6420: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f  rintf("%*s<optio
6430: 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25 73 3e 26  n value=\"\"%s>&
6440: 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e  nbsp;</option>\n
6450: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c  ",.        in+2,
6460: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 73 74 72   "",.        str
6470: 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20  cmp(zVal, zD) ? 
6480: 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22  "" : " selected"
6490: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
64a0: 20 20 7d 0a 20 20 76 61 5f 65 6e 64 28 61 70 29    }.  va_end(ap)
64b0: 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22  ;.  cgi_printf("
64c0: 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c  %*s</select>\n",
64d0: 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a   in, "");.}../*.
64e0: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20  ** This routine 
64f0: 77 6f 72 6b 73 20 61 20 6c 6f 74 20 6c 69 6b 65  works a lot like
6500: 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28   cgi_optionmenu(
6510: 29 20 65 78 63 65 70 74 20 74 68 61 74 20 74 68  ) except that th
6520: 65 20 6c 69 73 74 20 6f 66 0a 2a 2a 20 76 61 6c  e list of.** val
6530: 75 65 73 20 69 73 20 63 6f 6e 74 61 69 6e 65 64  ues is contained
6540: 20 69 6e 20 61 6e 20 61 72 72 61 79 2e 20 20 41   in an array.  A
6550: 6c 73 6f 2c 20 74 68 65 20 76 61 6c 75 65 73 20  lso, the values 
6560: 61 72 65 20 6a 75 73 74 20 76 61 6c 75 65 73 2c  are just values,
6570: 20 6e 6f 74 0a 2a 2a 20 6e 61 6d 65 2f 76 61 6c   not.** name/val
6580: 75 65 20 70 61 69 72 73 20 61 73 20 69 6e 20 63  ue pairs as in c
6590: 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 2e 0a 2a  gi_optionmenu..*
65a0: 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74  /.void cgi_v_opt
65b0: 69 6f 6e 6d 65 6e 75 28 0a 20 20 69 6e 74 20 69  ionmenu(.  int i
65c0: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n,              
65d0: 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20 74 68 69  /* Indent by thi
65e0: 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f  s amount */.  co
65f0: 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 20 20  nst char *zP,   
6600: 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79 20     /* The query 
6610: 70 61 72 61 6d 65 74 65 72 20 6e 61 6d 65 20 2a  parameter name *
6620: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
6630: 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44 65 66 61  zD,      /* Defa
6640: 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20 63  ult value */.  c
6650: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 20 20  onst char **az  
6660: 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d      /* NULL-term
6670: 69 6e 61 74 65 64 20 6c 69 73 74 20 6f 66 20 61  inated list of a
6680: 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 2a 2f  llowed values */
6690: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72  .){.  const char
66a0: 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 69 3b   *zVal;.  int i;
66b0: 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25  .  cgi_printf("%
66c0: 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 3d 31  *s<select size=1
66d0: 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22   name=\"%s\">\n"
66e0: 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a 20  , in, "", zP);. 
66f0: 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b   for(i=0; az[i];
6700: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 73   i++){.    if( s
6710: 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a 44 29 3d  trcmp(az[i],zD)=
6720: 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a  =0 ) break;.  }.
6730: 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d 30 20 29    if( az[i]==0 )
6740: 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b 30 5d 3d  {.    if( zD[0]=
6750: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  =0 ){.      cgi_
6760: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69  printf("%*s<opti
6770: 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65  on value=\"\" se
6780: 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f  lected>&nbsp;</o
6790: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20  ption>\n",.     
67a0: 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20 20 20    in+2, "");.   
67b0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67   }else{.      cg
67c0: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70  i_printf("%*s<op
67d0: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c  tion value=\"%h\
67e0: 22 20 73 65 6c 65 63 74 65 64 3e 25 68 3c 2f 6f  " selected>%h</o
67f0: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20  ption>\n",.     
6800: 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c 20    in+2, "", zD, 
6810: 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  zD);.    }.  }. 
6820: 20 77 68 69 6c 65 28 20 28 7a 56 61 6c 20 3d 20   while( (zVal = 
6830: 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20 29 7b 0a  *(az++))!=0  ){.
6840: 20 20 20 20 69 66 28 20 7a 56 61 6c 5b 30 5d 20      if( zVal[0] 
6850: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  ){.      cgi_pri
6860: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20  ntf("%*s<option 
6870: 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25  value=\"%h\"%s>%
6880: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20  h</option>\n",. 
6890: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c         in+2, "",
68a0: 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20  .        zVal,. 
68b0: 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56         strcmp(zV
68c0: 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22  al, zD) ? "" : "
68d0: 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 20 20 20   selected",.    
68e0: 20 20 20 20 7a 56 61 6c 0a 20 20 20 20 20 20 29      zVal.      )
68f0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
6900: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25     cgi_printf("%
6910: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d  *s<option value=
6920: 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f  \"\"%s>&nbsp;</o
6930: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20  ption>\n",.     
6940: 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20     in+2, "",.   
6950: 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c       strcmp(zVal
6960: 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73  , zD) ? "" : " s
6970: 65 6c 65 63 74 65 64 22 0a 20 20 20 20 20 20 29  elected".      )
6980: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 63 67  ;.    }.  }.  cg
6990: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73  i_printf("%*s</s
69a0: 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22  elect>\n", in, "
69b0: 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  ");.}../*.** Thi
69c0: 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20  s routine works 
69d0: 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69 5f 76  a lot like cgi_v
69e0: 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78  _optionmenu() ex
69f0: 63 65 70 74 20 74 68 61 74 20 74 68 65 20 6c 69  cept that the li
6a00: 73 74 0a 2a 2a 20 69 73 20 61 20 6c 69 73 74 20  st.** is a list 
6a10: 6f 66 20 70 61 69 72 73 2e 20 20 54 68 65 20 66  of pairs.  The f
6a20: 69 72 73 74 20 65 6c 65 6d 65 6e 74 20 6f 66 20  irst element of 
6a30: 65 61 63 68 20 70 61 69 72 20 69 73 20 74 68 65  each pair is the
6a40: 20 76 61 6c 75 65 20 75 73 65 64 0a 2a 2a 20 69   value used.** i
6a50: 6e 74 65 72 6e 61 6c 6c 79 20 61 6e 64 20 74 68  nternally and th
6a60: 65 20 73 65 63 6f 6e 64 20 65 6c 65 6d 65 6e 74  e second element
6a70: 20 69 73 20 74 68 65 20 76 61 6c 75 65 20 64 69   is the value di
6a80: 73 70 6c 61 79 65 64 20 74 6f 20 74 68 65 20 75  splayed to the u
6a90: 73 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69  ser..*/.void cgi
6aa0: 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e 75 32 28 0a  _v_optionmenu2(.
6ab0: 20 20 69 6e 74 20 69 6e 2c 20 20 20 20 20 20 20    int in,       
6ac0: 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 6e 74         /* Indent
6ad0: 20 62 79 20 74 68 69 73 20 61 6d 6f 75 6e 74 20   by this amount 
6ae0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
6af0: 2a 7a 50 2c 20 20 20 20 20 20 2f 2a 20 54 68 65  *zP,      /* The
6b00: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
6b10: 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74   name */.  const
6b20: 20 63 68 61 72 20 2a 7a 44 2c 20 20 20 20 20 20   char *zD,      
6b30: 2f 2a 20 44 65 66 61 75 6c 74 20 76 61 6c 75 65  /* Default value
6b40: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
6b50: 20 2a 2a 61 7a 20 20 20 20 20 20 2f 2a 20 4e 55   **az      /* NU
6b60: 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 64 20 6c 69  LL-terminated li
6b70: 73 74 20 6f 66 20 61 6c 6c 6f 77 65 64 20 76 61  st of allowed va
6b80: 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e  lues */.){.  con
6b90: 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 20  st char *zVal;. 
6ba0: 20 69 6e 74 20 69 3b 0a 20 20 63 67 69 5f 70 72   int i;.  cgi_pr
6bb0: 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c 65 63 74  intf("%*s<select
6bc0: 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25   size=1 name=\"%
6bd0: 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c  s\">\n", in, "",
6be0: 20 7a 50 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b   zP);.  for(i=0;
6bf0: 20 61 7a 5b 69 5d 3b 20 69 2b 3d 32 29 7b 0a 20   az[i]; i+=2){. 
6c00: 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61 7a     if( strcmp(az
6c10: 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20 62 72 65  [i],zD)==0 ) bre
6c20: 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61 7a  ak;.  }.  if( az
6c30: 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66  [i]==0 ){.    if
6c40: 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20  ( zD[0]==0 ){.  
6c50: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22      cgi_printf("
6c60: 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65  %*s<option value
6c70: 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64 3e 26  =\"\" selected>&
6c80: 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e  nbsp;</option>\n
6c90: 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c 20  ",.       in+2, 
6ca0: 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a  "");.    }else{.
6cb0: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66        cgi_printf
6cc0: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c  ("%*s<option val
6cd0: 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 74  ue=\"%h\" select
6ce0: 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e  ed>%h</option>\n
6cf0: 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c 20  ",.       in+2, 
6d00: 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20  "", zD, zD);.   
6d10: 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20   }.  }.  while( 
6d20: 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b 2b 29 29  (zVal = *(az++))
6d30: 21 3d 30 20 20 29 7b 0a 20 20 20 20 63 6f 6e 73  !=0  ){.    cons
6d40: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20  t char *zName = 
6d50: 2a 28 61 7a 2b 2b 29 3b 0a 20 20 20 20 69 66 28  *(az++);.    if(
6d60: 20 7a 4e 61 6d 65 5b 30 5d 20 29 7b 0a 20 20 20   zName[0] ){.   
6d70: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25     cgi_printf("%
6d80: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d  *s<option value=
6d90: 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74  \"%h\"%s>%h</opt
6da0: 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20  ion>\n",.       
6db0: 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20   in+2, "",.     
6dc0: 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20     zVal,.       
6dd0: 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44   strcmp(zVal, zD
6de0: 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63  ) ? "" : " selec
6df0: 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e  ted",.        zN
6e00: 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ame.      );.   
6e10: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67   }else{.      cg
6e20: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70  i_printf("%*s<op
6e30: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c  tion value=\"%h\
6e40: 22 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69  "%s>&nbsp;</opti
6e50: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20  on>\n",.        
6e60: 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20  in+2, "",.      
6e70: 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 20    zVal,.        
6e80: 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29  strcmp(zVal, zD)
6e90: 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74   ? "" : " select
6ea0: 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20  ed".      );.   
6eb0: 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72 69   }.  }.  cgi_pri
6ec0: 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74  ntf("%*s</select
6ed0: 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d  >\n", in, "");.}
6ee0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ../*.** This rou
6ef0: 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69 6b 65 20  tine works like 
6f00: 22 70 72 69 6e 74 66 22 20 65 78 63 65 70 74 20  "printf" except 
6f10: 74 68 61 74 20 69 74 20 68 61 73 20 74 68 65 0a  that it has the.
6f20: 2a 2a 20 65 78 74 72 61 20 66 6f 72 6d 61 74 74  ** extra formatt
6f30: 69 6e 67 20 63 61 70 61 62 69 6c 69 74 69 65 73  ing capabilities
6f40: 20 73 75 63 68 20 61 73 20 25 68 20 61 6e 64 20   such as %h and 
6f50: 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  %t..*/.void cgi_
6f60: 70 72 69 6e 74 66 28 63 6f 6e 73 74 20 63 68 61  printf(const cha
6f70: 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29  r *zFormat, ...)
6f80: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  {.  va_list ap;.
6f90: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 7a 46    va_start(ap,zF
6fa0: 6f 72 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e  ormat);.  vxprin
6fb0: 74 66 28 70 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72  tf(pContent,zFor
6fc0: 6d 61 74 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e  mat,ap);.  va_en
6fd0: 64 28 61 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  d(ap);.}../*.** 
6fe0: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72  This routine wor
6ff0: 6b 73 20 6c 69 6b 65 20 22 76 70 72 69 6e 74 66  ks like "vprintf
7000: 22 20 65 78 63 65 70 74 20 74 68 61 74 20 69 74  " except that it
7010: 20 68 61 73 20 74 68 65 0a 2a 2a 20 65 78 74 72   has the.** extr
7020: 61 20 66 6f 72 6d 61 74 74 69 6e 67 20 63 61 70  a formatting cap
7030: 61 62 69 6c 69 74 69 65 73 20 73 75 63 68 20 61  abilities such a
7040: 73 20 25 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a  s %h and %t..*/.
7050: 76 6f 69 64 20 63 67 69 5f 76 70 72 69 6e 74 66  void cgi_vprintf
7060: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f  (const char *zFo
7070: 72 6d 61 74 2c 20 76 61 5f 6c 69 73 74 20 61 70  rmat, va_list ap
7080: 29 7b 0a 20 20 76 78 70 72 69 6e 74 66 28 70 43  ){.  vxprintf(pC
7090: 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61  ontent,zFormat,a
70a0: 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65  p);.}.../*.** Se
70b0: 6e 64 20 61 20 72 65 70 6c 79 20 69 6e 64 69 63  nd a reply indic
70c0: 61 74 69 6e 67 20 74 68 61 74 20 74 68 65 20 48  ating that the H
70d0: 54 54 50 20 72 65 71 75 65 73 74 20 77 61 73 20  TTP request was 
70e0: 6d 61 6c 66 6f 72 6d 65 64 0a 2a 2f 0a 73 74 61  malformed.*/.sta
70f0: 74 69 63 20 76 6f 69 64 20 6d 61 6c 66 6f 72 6d  tic void malform
7100: 65 64 5f 72 65 71 75 65 73 74 28 76 6f 69 64 29  ed_request(void)
7110: 7b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74  {.  cgi_set_stat
7120: 75 73 28 35 30 31 2c 20 22 4e 6f 74 20 49 6d 70  us(501, "Not Imp
7130: 6c 65 6d 65 6e 74 65 64 22 29 3b 0a 20 20 63 67  lemented");.  cg
7140: 69 5f 70 72 69 6e 74 66 28 0a 20 20 20 20 22 3c  i_printf(.    "<
7150: 68 74 6d 6c 3e 3c 62 6f 64 79 3e 55 6e 72 65 63  html><body>Unrec
7160: 6f 67 6e 69 7a 65 64 20 48 54 54 50 20 52 65 71  ognized HTTP Req
7170: 75 65 73 74 3c 2f 62 6f 64 79 3e 3c 2f 68 74 6d  uest</body></htm
7180: 6c 3e 5c 6e 22 0a 20 20 29 3b 0a 20 20 63 67 69  l>\n".  );.  cgi
7190: 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 78 69 74  _reply();.  exit
71a0: 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61  (0);.}../*.** Pa
71b0: 6e 69 63 20 61 6e 64 20 64 69 65 20 77 68 69 6c  nic and die whil
71c0: 65 20 70 72 6f 63 65 73 73 69 6e 67 20 61 20 77  e processing a w
71d0: 65 62 70 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20  ebpage..*/.void 
71e0: 63 67 69 5f 70 61 6e 69 63 28 63 6f 6e 73 74 20  cgi_panic(const 
71f0: 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e  char *zFormat, .
7200: 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61  ..){.  va_list a
7210: 70 3b 0a 20 20 63 67 69 5f 72 65 73 65 74 5f 63  p;.  cgi_reset_c
7220: 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f  ontent();.  cgi_
7230: 73 65 74 5f 73 74 61 74 75 73 28 35 30 30 2c 20  set_status(500, 
7240: 22 49 6e 74 65 72 6e 61 6c 20 53 65 72 76 65 72  "Internal Server
7250: 20 45 72 72 6f 72 22 29 3b 0a 20 20 63 67 69 5f   Error");.  cgi_
7260: 70 72 69 6e 74 66 28 0a 20 20 20 20 22 3c 68 74  printf(.    "<ht
7270: 6d 6c 3e 3c 62 6f 64 79 3e 3c 68 31 3e 49 6e 74  ml><body><h1>Int
7280: 65 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72  ernal Server Err
7290: 6f 72 3c 2f 68 31 3e 5c 6e 22 0a 20 20 20 20 22  or</h1>\n".    "
72a0: 3c 70 6c 61 69 6e 74 65 78 74 3e 22 0a 20 20 29  <plaintext>".  )
72b0: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c  ;.  va_start(ap,
72c0: 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 76 78 70   zFormat);.  vxp
72d0: 72 69 6e 74 66 28 70 43 6f 6e 74 65 6e 74 2c 7a  rintf(pContent,z
72e0: 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 20 20 76 61  Format,ap);.  va
72f0: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63 67 69 5f  _end(ap);.  cgi_
7300: 72 65 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28  reply();.  exit(
7310: 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d  1);.}../*.** Rem
7320: 6f 76 65 20 74 68 65 20 66 69 72 73 74 20 73 70  ove the first sp
7330: 61 63 65 2d 64 65 6c 69 6d 69 74 65 64 20 74 6f  ace-delimited to
7340: 6b 65 6e 20 66 72 6f 6d 20 61 20 73 74 72 69 6e  ken from a strin
7350: 67 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20  g and return.** 
7360: 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 69 74 2e  a pointer to it.
7370: 20 20 41 64 64 20 61 20 4e 55 4c 4c 20 74 6f 20    Add a NULL to 
7380: 74 68 65 20 73 74 72 69 6e 67 20 74 6f 20 74 65  the string to te
7390: 72 6d 69 6e 61 74 65 20 74 68 65 20 74 6f 6b 65  rminate the toke
73a0: 6e 2e 0a 2a 2a 20 4d 61 6b 65 20 2a 7a 4c 65 66  n..** Make *zLef
73b0: 74 4f 76 65 72 20 70 6f 69 6e 74 20 74 6f 20 74  tOver point to t
73c0: 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20  he start of the 
73d0: 6e 65 78 74 20 74 6f 6b 65 6e 2e 0a 2a 2f 0a 73  next token..*/.s
73e0: 74 61 74 69 63 20 63 68 61 72 20 2a 65 78 74 72  tatic char *extr
73f0: 61 63 74 5f 74 6f 6b 65 6e 28 63 68 61 72 20 2a  act_token(char *
7400: 7a 49 6e 70 75 74 2c 20 63 68 61 72 20 2a 2a 7a  zInput, char **z
7410: 4c 65 66 74 4f 76 65 72 29 7b 0a 20 20 63 68 61  LeftOver){.  cha
7420: 72 20 2a 7a 52 65 73 75 6c 74 20 3d 20 30 3b 0a  r *zResult = 0;.
7430: 20 20 69 66 28 20 7a 49 6e 70 75 74 3d 3d 30 20    if( zInput==0 
7440: 29 7b 0a 20 20 20 20 69 66 28 20 7a 4c 65 66 74  ){.    if( zLeft
7450: 4f 76 65 72 20 29 20 2a 7a 4c 65 66 74 4f 76 65  Over ) *zLeftOve
7460: 72 20 3d 20 30 3b 0a 20 20 20 20 72 65 74 75 72  r = 0;.    retur
7470: 6e 20 30 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65  n 0;.  }.  while
7480: 28 20 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 75  ( isspace(*zInpu
7490: 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20  t) ){ zInput++; 
74a0: 7d 0a 20 20 7a 52 65 73 75 6c 74 20 3d 20 7a 49  }.  zResult = zI
74b0: 6e 70 75 74 3b 0a 20 20 77 68 69 6c 65 28 20 2a  nput;.  while( *
74c0: 7a 49 6e 70 75 74 20 26 26 20 21 69 73 73 70 61  zInput && !isspa
74d0: 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a  ce(*zInput) ){ z
74e0: 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 69 66 28  Input++; }.  if(
74f0: 20 2a 7a 49 6e 70 75 74 20 29 7b 0a 20 20 20 20   *zInput ){.    
7500: 2a 7a 49 6e 70 75 74 20 3d 20 30 3b 0a 20 20 20  *zInput = 0;.   
7510: 20 7a 49 6e 70 75 74 2b 2b 3b 0a 20 20 20 20 77   zInput++;.    w
7520: 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a  hile( isspace(*z
7530: 49 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74  Input) ){ zInput
7540: 2b 2b 3b 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20  ++; }.  }.  if( 
7550: 7a 4c 65 66 74 4f 76 65 72 20 29 7b 20 2a 7a 4c  zLeftOver ){ *zL
7560: 65 66 74 4f 76 65 72 20 3d 20 7a 49 6e 70 75 74  eftOver = zInput
7570: 3b 20 7d 0a 20 20 72 65 74 75 72 6e 20 7a 52 65  ; }.  return zRe
7580: 73 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  sult;.}../*.** T
7590: 68 69 73 20 72 6f 75 74 69 6e 65 20 68 61 6e 64  his routine hand
75a0: 6c 65 73 20 61 20 73 69 6e 67 6c 65 20 48 54 54  les a single HTT
75b0: 50 20 72 65 71 75 65 73 74 20 77 68 69 63 68 20  P request which 
75c0: 69 73 20 63 6f 6d 69 6e 67 20 69 6e 20 6f 6e 0a  is coming in on.
75d0: 2a 2a 20 73 74 61 6e 64 61 72 64 20 69 6e 70 75  ** standard inpu
75e0: 74 20 61 6e 64 20 77 68 69 63 68 20 72 65 70 6c  t and which repl
75f0: 69 65 73 20 6f 6e 20 73 74 61 6e 64 61 72 64 20  ies on standard 
7600: 6f 75 74 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 54 68  output..**.** Th
7610: 65 20 48 54 54 50 20 72 65 71 75 65 73 74 20 69  e HTTP request i
7620: 73 20 72 65 61 64 20 66 72 6f 6d 20 73 74 61 6e  s read from stan
7630: 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20 69  dard input and i
7640: 73 20 75 73 65 64 20 74 6f 20 69 6e 69 74 69 61  s used to initia
7650: 6c 69 7a 65 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d  lize.** environm
7660: 65 6e 74 20 76 61 72 69 61 62 6c 65 73 20 61 73  ent variables as
7670: 20 70 65 72 20 43 47 49 2e 20 20 54 68 65 20 63   per CGI.  The c
7680: 67 69 5f 69 6e 69 74 28 29 20 72 6f 75 74 69 6e  gi_init() routin
7690: 65 20 74 6f 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a  e to complete.**
76a0: 20 74 68 65 20 73 65 74 75 70 2e 20 20 4f 6e 63   the setup.  Onc
76b0: 65 20 61 6c 6c 20 74 68 65 20 73 65 74 75 70 20  e all the setup 
76c0: 69 73 20 66 69 6e 69 73 68 65 64 2c 20 74 68 69  is finished, thi
76d0: 73 20 70 72 6f 63 65 64 75 72 65 20 72 65 74 75  s procedure retu
76e0: 72 6e 73 0a 2a 2a 20 61 6e 64 20 73 75 62 73 65  rns.** and subse
76f0: 71 75 65 6e 74 20 63 6f 64 65 20 68 61 6e 64 6c  quent code handl
7700: 65 73 20 74 68 65 20 61 63 74 75 61 6c 20 67 65  es the actual ge
7710: 6e 65 72 61 74 69 6f 6e 20 6f 66 20 74 68 65 20  neration of the 
7720: 77 65 62 70 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64  webpage..*/.void
7730: 20 63 67 69 5f 68 61 6e 64 6c 65 5f 68 74 74 70   cgi_handle_http
7740: 5f 72 65 71 75 65 73 74 28 76 6f 69 64 29 7b 0a  _request(void){.
7750: 20 20 63 68 61 72 20 2a 7a 2c 20 2a 7a 54 6f 6b    char *z, *zTok
7760: 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 73  en;.  int i;.  s
7770: 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69  truct sockaddr_i
7780: 6e 20 72 65 6d 6f 74 65 4e 61 6d 65 3b 0a 20 20  n remoteName;.  
7790: 73 69 7a 65 5f 74 20 73 69 7a 65 20 3d 20 73 69  size_t size = si
77a0: 7a 65 6f 66 28 73 74 72 75 63 74 20 73 6f 63 6b  zeof(struct sock
77b0: 61 64 64 72 5f 69 6e 29 3b 0a 20 20 63 68 61 72  addr_in);.  char
77c0: 20 7a 4c 69 6e 65 5b 32 30 30 30 5d 3b 20 20 20   zLine[2000];   
77d0: 20 20 2f 2a 20 41 20 73 69 6e 67 6c 65 20 6c 69    /* A single li
77e0: 6e 65 20 6f 66 20 69 6e 70 75 74 2e 20 2a 2f 0a  ne of input. */.
77f0: 0a 20 20 66 75 6c 6c 48 74 74 70 52 65 70 6c 79  .  fullHttpReply
7800: 20 3d 20 31 3b 0a 20 20 69 66 28 20 66 67 65 74   = 1;.  if( fget
7810: 73 28 7a 4c 69 6e 65 2c 20 73 69 7a 65 6f 66 28  s(zLine, sizeof(
7820: 7a 4c 69 6e 65 29 2c 20 73 74 64 69 6e 29 3d 3d  zLine), stdin)==
7830: 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d  0 ){.    malform
7840: 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20  ed_request();.  
7850: 7d 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74  }.  zToken = ext
7860: 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e 65  ract_token(zLine
7870: 2c 20 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f  , &z);.  if( zTo
7880: 6b 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61  ken==0 ){.    ma
7890: 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28  lformed_request(
78a0: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73 74 72  );.  }.  if( str
78b0: 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22 47 45 54 22  cmp(zToken,"GET"
78c0: 29 21 3d 30 20 26 26 20 73 74 72 63 6d 70 28 7a  )!=0 && strcmp(z
78d0: 54 6f 6b 65 6e 2c 22 50 4f 53 54 22 29 21 3d 30  Token,"POST")!=0
78e0: 0a 20 20 20 20 20 20 26 26 20 73 74 72 63 6d 70  .      && strcmp
78f0: 28 7a 54 6f 6b 65 6e 2c 22 48 45 41 44 22 29 21  (zToken,"HEAD")!
7900: 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72  =0 ){.    malfor
7910: 6d 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20  med_request();. 
7920: 20 7d 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28   }.  cgi_setenv(
7930: 22 47 41 54 45 57 41 59 5f 49 4e 54 45 52 46 41  "GATEWAY_INTERFA
7940: 43 45 22 2c 22 43 47 49 2f 31 2e 30 22 29 3b 0a  CE","CGI/1.0");.
7950: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45    cgi_setenv("RE
7960: 51 55 45 53 54 5f 4d 45 54 48 4f 44 22 2c 7a 54  QUEST_METHOD",zT
7970: 6f 6b 65 6e 29 3b 0a 20 20 7a 54 6f 6b 65 6e 20  oken);.  zToken 
7980: 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28  = extract_token(
7990: 7a 2c 20 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54  z, &z);.  if( zT
79a0: 6f 6b 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d  oken==0 ){.    m
79b0: 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74  alformed_request
79c0: 28 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f 73 65  ();.  }.  cgi_se
79d0: 74 65 6e 76 28 22 52 45 51 55 45 53 54 5f 55 52  tenv("REQUEST_UR
79e0: 49 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 66  I", zToken);.  f
79f0: 6f 72 28 69 3d 30 3b 20 7a 54 6f 6b 65 6e 5b 69  or(i=0; zToken[i
7a00: 5d 20 26 26 20 7a 54 6f 6b 65 6e 5b 69 5d 21 3d  ] && zToken[i]!=
7a10: 27 3f 27 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69 66  '?'; i++){}.  if
7a20: 28 20 7a 54 6f 6b 65 6e 5b 69 5d 20 29 20 7a 54  ( zToken[i] ) zT
7a30: 6f 6b 65 6e 5b 69 2b 2b 5d 20 3d 20 30 3b 0a 20  oken[i++] = 0;. 
7a40: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 50 41 54   cgi_setenv("PAT
7a50: 48 5f 49 4e 46 4f 22 2c 20 7a 54 6f 6b 65 6e 29  H_INFO", zToken)
7a60: 3b 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22  ;.  cgi_setenv("
7a70: 51 55 45 52 59 5f 53 54 52 49 4e 47 22 2c 20 26  QUERY_STRING", &
7a80: 7a 54 6f 6b 65 6e 5b 69 5d 29 3b 0a 20 20 69 66  zToken[i]);.  if
7a90: 28 20 67 65 74 70 65 65 72 6e 61 6d 65 28 66 69  ( getpeername(fi
7aa0: 6c 65 6e 6f 28 73 74 64 69 6e 29 2c 20 28 73 74  leno(stdin), (st
7ab0: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26  ruct sockaddr*)&
7ac0: 72 65 6d 6f 74 65 4e 61 6d 65 2c 20 28 73 6f 63  remoteName, (soc
7ad0: 6b 6c 65 6e 5f 74 2a 29 26 73 69 7a 65 29 3e 3d  klen_t*)&size)>=
7ae0: 30 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a  0 ){.    char *z
7af0: 49 70 41 64 64 72 20 3d 20 69 6e 65 74 5f 6e 74  IpAddr = inet_nt
7b00: 6f 61 28 72 65 6d 6f 74 65 4e 61 6d 65 2e 73 69  oa(remoteName.si
7b10: 6e 5f 61 64 64 72 29 3b 0a 20 20 20 20 63 67 69  n_addr);.    cgi
7b20: 5f 73 65 74 65 6e 76 28 22 52 45 4d 4f 54 45 5f  _setenv("REMOTE_
7b30: 41 44 44 52 22 2c 20 7a 49 70 41 64 64 72 29 3b  ADDR", zIpAddr);
7b40: 0a 0a 20 20 20 20 2f 2a 20 53 65 74 20 74 68 65  ..    /* Set the
7b50: 20 47 6c 6f 62 61 6c 2e 7a 49 70 41 64 64 72 20   Global.zIpAddr 
7b60: 76 61 72 69 61 62 6c 65 20 74 6f 20 74 68 65 20  variable to the 
7b70: 73 65 72 76 65 72 20 77 65 20 61 72 65 20 74 61  server we are ta
7b80: 6c 6b 69 6e 67 20 74 6f 2e 0a 20 20 20 20 2a 2a  lking to..    **
7b90: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 74 6f   This is used to
7ba0: 20 70 6f 70 75 6c 61 74 65 20 74 68 65 20 69 70   populate the ip
7bb0: 61 64 64 72 20 63 6f 6c 75 6d 6e 20 6f 66 20 74  addr column of t
7bc0: 68 65 20 72 63 76 66 72 6f 6d 20 74 61 62 6c 65  he rcvfrom table
7bd0: 2c 0a 20 20 20 20 2a 2a 20 69 66 20 61 6e 79 20  ,.    ** if any 
7be0: 66 69 6c 65 73 20 61 72 65 20 72 65 63 65 69 76  files are receiv
7bf0: 65 64 20 66 72 6f 6d 20 74 68 65 20 63 6f 6e 6e  ed from the conn
7c00: 65 63 74 65 64 20 63 6c 69 65 6e 74 2e 0a 20 20  ected client..  
7c10: 20 20 2a 2f 0a 20 20 20 20 67 2e 7a 49 70 41 64    */.    g.zIpAd
7c20: 64 72 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73  dr = mprintf("%s
7c30: 22 2c 20 7a 49 70 41 64 64 72 29 3b 0a 20 20 7d  ", zIpAddr);.  }
7c40: 0a 20 0a 20 20 2f 2a 20 47 65 74 20 61 6c 6c 20  . .  /* Get all 
7c50: 74 68 65 20 6f 70 74 69 6f 6e 61 6c 20 66 69 65  the optional fie
7c60: 6c 64 73 20 74 68 61 74 20 66 6f 6c 6c 6f 77 20  lds that follow 
7c70: 74 68 65 20 66 69 72 73 74 20 6c 69 6e 65 2e 0a  the first line..
7c80: 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 66 67    */.  while( fg
7c90: 65 74 73 28 7a 4c 69 6e 65 2c 73 69 7a 65 6f 66  ets(zLine,sizeof
7ca0: 28 7a 4c 69 6e 65 29 2c 73 74 64 69 6e 29 20 29  (zLine),stdin) )
7cb0: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 46 69 65  {.    char *zFie
7cc0: 6c 64 4e 61 6d 65 3b 0a 20 20 20 20 63 68 61 72  ldName;.    char
7cd0: 20 2a 7a 56 61 6c 3b 0a 0a 20 20 20 20 7a 46 69   *zVal;..    zFi
7ce0: 65 6c 64 4e 61 6d 65 20 3d 20 65 78 74 72 61 63  eldName = extrac
7cf0: 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e 65 2c 26 7a  t_token(zLine,&z
7d00: 56 61 6c 29 3b 0a 20 20 20 20 69 66 28 20 7a 46  Val);.    if( zF
7d10: 69 65 6c 64 4e 61 6d 65 3d 3d 30 20 7c 7c 20 2a  ieldName==0 || *
7d20: 7a 46 69 65 6c 64 4e 61 6d 65 3d 3d 30 20 29 20  zFieldName==0 ) 
7d30: 62 72 65 61 6b 3b 0a 20 20 20 20 77 68 69 6c 65  break;.    while
7d40: 28 20 69 73 73 70 61 63 65 28 2a 7a 56 61 6c 29  ( isspace(*zVal)
7d50: 20 29 7b 20 7a 56 61 6c 2b 2b 3b 20 7d 0a 20 20   ){ zVal++; }.  
7d60: 20 20 69 20 3d 20 73 74 72 6c 65 6e 28 7a 56 61    i = strlen(zVa
7d70: 6c 29 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69  l);.    while( i
7d80: 3e 30 20 26 26 20 69 73 73 70 61 63 65 28 7a 56  >0 && isspace(zV
7d90: 61 6c 5b 69 2d 31 5d 29 20 29 7b 20 69 2d 2d 3b  al[i-1]) ){ i--;
7da0: 20 7d 0a 20 20 20 20 7a 56 61 6c 5b 69 5d 20 3d   }.    zVal[i] =
7db0: 20 30 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b   0;.    for(i=0;
7dc0: 20 7a 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 3b 20   zFieldName[i]; 
7dd0: 69 2b 2b 29 7b 20 7a 46 69 65 6c 64 4e 61 6d 65  i++){ zFieldName
7de0: 5b 69 5d 20 3d 20 74 6f 6c 6f 77 65 72 28 7a 46  [i] = tolower(zF
7df0: 69 65 6c 64 4e 61 6d 65 5b 69 5d 29 3b 20 7d 0a  ieldName[i]); }.
7e00: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a      if( strcmp(z
7e10: 46 69 65 6c 64 4e 61 6d 65 2c 22 75 73 65 72 2d  FieldName,"user-
7e20: 61 67 65 6e 74 3a 22 29 3d 3d 30 20 29 7b 0a 20  agent:")==0 ){. 
7e30: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28       cgi_setenv(
7e40: 22 48 54 54 50 5f 55 53 45 52 5f 41 47 45 4e 54  "HTTP_USER_AGENT
7e50: 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65  ", zVal);.    }e
7e60: 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a  lse if( strcmp(z
7e70: 46 69 65 6c 64 4e 61 6d 65 2c 22 63 6f 6e 74 65  FieldName,"conte
7e80: 6e 74 2d 6c 65 6e 67 74 68 3a 22 29 3d 3d 30 20  nt-length:")==0 
7e90: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74  ){.      cgi_set
7ea0: 65 6e 76 28 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e  env("CONTENT_LEN
7eb0: 47 54 48 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20  GTH", zVal);.   
7ec0: 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d   }else if( strcm
7ed0: 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 72 65  p(zFieldName,"re
7ee0: 66 65 72 65 72 3a 22 29 3d 3d 30 20 29 7b 0a 20  ferer:")==0 ){. 
7ef0: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28       cgi_setenv(
7f00: 22 48 54 54 50 5f 52 45 46 45 52 45 52 22 2c 20  "HTTP_REFERER", 
7f10: 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65  zVal);.    }else
7f20: 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65   if( strcmp(zFie
7f30: 6c 64 4e 61 6d 65 2c 22 68 6f 73 74 3a 22 29 3d  ldName,"host:")=
7f40: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  =0 ){.      cgi_
7f50: 73 65 74 65 6e 76 28 22 48 54 54 50 5f 48 4f 53  setenv("HTTP_HOS
7f60: 54 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d  T", zVal);.    }
7f70: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28  else if( strcmp(
7f80: 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 63 6f 6e 74  zFieldName,"cont
7f90: 65 6e 74 2d 74 79 70 65 3a 22 29 3d 3d 30 20 29  ent-type:")==0 )
7fa0: 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65  {.      cgi_sete
7fb0: 6e 76 28 22 43 4f 4e 54 45 4e 54 5f 54 59 50 45  nv("CONTENT_TYPE
7fc0: 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65  ", zVal);.    }e
7fd0: 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a  lse if( strcmp(z
7fe0: 46 69 65 6c 64 4e 61 6d 65 2c 22 63 6f 6f 6b 69  FieldName,"cooki
7ff0: 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  e:")==0 ){.     
8000: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54   cgi_setenv("HTT
8010: 50 5f 43 4f 4f 4b 49 45 22 2c 20 7a 56 61 6c 29  P_COOKIE", zVal)
8020: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
8030: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d  strcmp(zFieldNam
8040: 65 2c 22 69 66 2d 6e 6f 6e 65 2d 6d 61 74 63 68  e,"if-none-match
8050: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  :")==0 ){.      
8060: 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50  cgi_setenv("HTTP
8070: 5f 49 46 5f 4e 4f 4e 45 5f 4d 41 54 43 48 22 2c  _IF_NONE_MATCH",
8080: 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73   zVal);.    }els
8090: 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69  e if( strcmp(zFi
80a0: 65 6c 64 4e 61 6d 65 2c 22 69 66 2d 6d 6f 64 69  eldName,"if-modi
80b0: 66 69 65 64 2d 73 69 6e 63 65 3a 22 29 3d 3d 30  fied-since:")==0
80c0: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65   ){.      cgi_se
80d0: 74 65 6e 76 28 22 48 54 54 50 5f 49 46 5f 4d 4f  tenv("HTTP_IF_MO
80e0: 44 49 46 49 45 44 5f 53 49 4e 43 45 22 2c 20 7a  DIFIED_SINCE", z
80f0: 56 61 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  Val);.    }.  }.
8100: 0a 20 20 63 67 69 5f 69 6e 69 74 28 29 3b 0a 7d  .  cgi_init();.}
8110: 0a 0a 2f 2a 0a 2a 2a 20 4d 61 78 69 6d 75 6d 20  ../*.** Maximum 
8120: 6e 75 6d 62 65 72 20 6f 66 20 63 68 69 6c 64 20  number of child 
8130: 70 72 6f 63 65 73 73 65 73 20 74 68 61 74 20 77  processes that w
8140: 65 20 63 61 6e 20 68 61 76 65 20 72 75 6e 6e 69  e can have runni
8150: 6e 67 0a 2a 2a 20 61 74 20 6f 6e 65 20 74 69 6d  ng.** at one tim
8160: 65 20 62 65 66 6f 72 65 20 77 65 20 73 74 61 72  e before we star
8170: 74 20 73 6c 6f 77 69 6e 67 20 74 68 69 6e 67 73  t slowing things
8180: 20 64 6f 77 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e   down..*/.#defin
8190: 65 20 4d 41 58 5f 50 41 52 41 4c 4c 45 4c 20 32  e MAX_PARALLEL 2
81a0: 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e  ../*.** Implemen
81b0: 74 20 61 6e 20 48 54 54 50 20 73 65 72 76 65 72  t an HTTP server
81c0: 20 64 61 65 6d 6f 6e 20 6c 69 73 74 65 6e 69 6e   daemon listenin
81d0: 67 20 6f 6e 20 70 6f 72 74 20 69 50 6f 72 74 2e  g on port iPort.
81e0: 0a 2a 2a 0a 2a 2a 20 41 73 20 6e 65 77 20 63 6f  .**.** As new co
81f0: 6e 6e 65 63 74 69 6f 6e 73 20 61 72 72 69 76 65  nnections arrive
8200: 2c 20 66 6f 72 6b 20 61 20 63 68 69 6c 64 20 61  , fork a child a
8210: 6e 64 20 6c 65 74 20 63 68 69 6c 64 20 72 65 74  nd let child ret
8220: 75 72 6e 0a 2a 2a 20 6f 75 74 20 6f 66 20 74 68  urn.** out of th
8230: 69 73 20 70 72 6f 63 65 64 75 72 65 20 63 61 6c  is procedure cal
8240: 6c 2e 20 20 54 68 65 20 63 68 69 6c 64 20 77 69  l.  The child wi
8250: 6c 6c 20 68 61 6e 64 6c 65 20 74 68 65 20 72 65  ll handle the re
8260: 71 75 65 73 74 2e 0a 2a 2a 20 54 68 65 20 70 61  quest..** The pa
8270: 72 65 6e 74 20 6e 65 76 65 72 20 72 65 74 75 72  rent never retur
8280: 6e 73 20 66 72 6f 6d 20 74 68 69 73 20 70 72 6f  ns from this pro
8290: 63 65 64 75 72 65 2e 0a 2a 2f 0a 76 6f 69 64 20  cedure..*/.void 
82a0: 63 67 69 5f 68 74 74 70 5f 73 65 72 76 65 72 28  cgi_http_server(
82b0: 69 6e 74 20 69 50 6f 72 74 29 7b 0a 23 69 66 64  int iPort){.#ifd
82c0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 20  ef __MINGW32__. 
82d0: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
82e0: 22 73 65 72 76 65 72 20 6e 6f 74 20 79 65 74 20  "server not yet 
82f0: 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 77 69 6e  available in win
8300: 64 6f 77 73 20 76 65 72 73 69 6f 6e 20 6f 66 20  dows version of 
8310: 66 6f 73 73 69 6c 5c 6e 22 29 3b 0a 20 20 65 78  fossil\n");.  ex
8320: 69 74 28 31 29 3b 0a 23 65 6c 73 65 0a 20 20 69  it(1);.#else.  i
8330: 6e 74 20 6c 69 73 74 65 6e 65 72 3b 20 20 20 20  nt listener;    
8340: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 54              /* T
8350: 68 65 20 73 65 72 76 65 72 20 73 6f 63 6b 65 74  he server socket
8360: 20 2a 2f 0a 20 20 69 6e 74 20 63 6f 6e 6e 65 63   */.  int connec
8370: 74 69 6f 6e 3b 20 20 20 20 20 20 20 20 20 20 20  tion;           
8380: 20 20 20 2f 2a 20 41 20 73 6f 63 6b 65 74 20 66     /* A socket f
8390: 6f 72 20 65 61 63 68 20 69 6e 64 69 76 69 64 75  or each individu
83a0: 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f  al connection */
83b0: 0a 20 20 66 64 5f 73 65 74 20 72 65 61 64 66 64  .  fd_set readfd
83c0: 73 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  s;              
83d0: 2f 2a 20 53 65 74 20 6f 66 20 66 69 6c 65 20 64  /* Set of file d
83e0: 65 73 63 72 69 70 74 6f 72 73 20 66 6f 72 20 73  escriptors for s
83f0: 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 73 69 7a  elect() */.  siz
8400: 65 5f 74 20 6c 65 6e 61 64 64 72 3b 20 20 20 20  e_t lenaddr;    
8410: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e            /* Len
8420: 67 74 68 20 6f 66 20 74 68 65 20 69 6e 61 64 64  gth of the inadd
8430: 72 20 73 74 72 75 63 74 75 72 65 20 2a 2f 0a 20  r structure */. 
8440: 20 69 6e 74 20 63 68 69 6c 64 3b 20 20 20 20 20   int child;     
8450: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8460: 20 50 49 44 20 6f 66 20 74 68 65 20 63 68 69 6c   PID of the chil
8470: 64 20 70 72 6f 63 65 73 73 20 2a 2f 0a 20 20 69  d process */.  i
8480: 6e 74 20 6e 63 68 69 6c 64 72 65 6e 20 3d 20 30  nt nchildren = 0
8490: 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4e  ;           /* N
84a0: 75 6d 62 65 72 20 6f 66 20 63 68 69 6c 64 20 70  umber of child p
84b0: 72 6f 63 65 73 73 65 73 20 2a 2f 0a 20 20 73 74  rocesses */.  st
84c0: 72 75 63 74 20 74 69 6d 65 76 61 6c 20 64 65 6c  ruct timeval del
84d0: 61 79 3b 20 20 20 20 20 20 20 20 2f 2a 20 48 6f  ay;        /* Ho
84e0: 77 20 6c 6f 6e 67 20 74 6f 20 77 61 69 74 20 69  w long to wait i
84f0: 6e 73 69 64 65 20 73 65 6c 65 63 74 28 29 20 2a  nside select() *
8500: 2f 0a 20 20 73 74 72 75 63 74 20 73 6f 63 6b 61  /.  struct socka
8510: 64 64 72 5f 69 6e 20 69 6e 61 64 64 72 3b 20 20  ddr_in inaddr;  
8520: 20 2f 2a 20 54 68 65 20 73 6f 63 6b 65 74 20 61   /* The socket a
8530: 64 64 72 65 73 73 20 2a 2f 0a 20 20 69 6e 74 20  ddress */.  int 
8540: 6f 70 74 20 3d 20 31 3b 20 20 20 20 20 20 20 20  opt = 1;        
8550: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 65 74 73           /* sets
8560: 6f 63 6b 6f 70 74 20 66 6c 61 67 20 2a 2f 0a 0a  ockopt flag */..
8570: 20 20 6d 65 6d 73 65 74 28 26 69 6e 61 64 64 72    memset(&inaddr
8580: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 69 6e 61 64  , 0, sizeof(inad
8590: 64 72 29 29 3b 0a 20 20 69 6e 61 64 64 72 2e 73  dr));.  inaddr.s
85a0: 69 6e 5f 66 61 6d 69 6c 79 20 3d 20 41 46 5f 49  in_family = AF_I
85b0: 4e 45 54 3b 0a 20 20 69 6e 61 64 64 72 2e 73 69  NET;.  inaddr.si
85c0: 6e 5f 61 64 64 72 2e 73 5f 61 64 64 72 20 3d 20  n_addr.s_addr = 
85d0: 49 4e 41 44 44 52 5f 41 4e 59 3b 0a 20 20 69 6e  INADDR_ANY;.  in
85e0: 61 64 64 72 2e 73 69 6e 5f 70 6f 72 74 20 3d 20  addr.sin_port = 
85f0: 68 74 6f 6e 73 28 69 50 6f 72 74 29 3b 0a 20 20  htons(iPort);.  
8600: 6c 69 73 74 65 6e 65 72 20 3d 20 73 6f 63 6b 65  listener = socke
8610: 74 28 41 46 5f 49 4e 45 54 2c 20 53 4f 43 4b 5f  t(AF_INET, SOCK_
8620: 53 54 52 45 41 4d 2c 20 30 29 3b 0a 20 20 69 66  STREAM, 0);.  if
8630: 28 20 6c 69 73 74 65 6e 65 72 3c 30 20 29 7b 0a  ( listener<0 ){.
8640: 20 20 20 20 66 70 72 69 6e 74 66 28 73 74 64 65      fprintf(stde
8650: 72 72 2c 22 43 61 6e 27 74 20 63 72 65 61 74 65  rr,"Can't create
8660: 20 61 20 73 6f 63 6b 65 74 5c 6e 22 29 3b 0a 20   a socket\n");. 
8670: 20 20 20 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a     exit(1);.  }.
8680: 0a 20 20 2f 2a 20 69 66 20 77 65 20 63 61 6e 27  .  /* if we can'
8690: 74 20 74 65 72 6d 69 6e 61 74 65 20 6e 69 63 65  t terminate nice
86a0: 6c 79 2c 20 61 74 20 6c 65 61 73 74 20 61 6c 6c  ly, at least all
86b0: 6f 77 20 74 68 65 20 73 6f 63 6b 65 74 20 74 6f  ow the socket to
86c0: 20 62 65 20 72 65 75 73 65 64 20 2a 2f 0a 20 20   be reused */.  
86d0: 73 65 74 73 6f 63 6b 6f 70 74 28 6c 69 73 74 65  setsockopt(liste
86e0: 6e 65 72 2c 53 4f 4c 5f 53 4f 43 4b 45 54 2c 53  ner,SOL_SOCKET,S
86f0: 4f 5f 52 45 55 53 45 41 44 44 52 2c 26 6f 70 74  O_REUSEADDR,&opt
8700: 2c 73 69 7a 65 6f 66 28 6f 70 74 29 29 3b 0a 0a  ,sizeof(opt));..
8710: 20 20 69 66 28 20 62 69 6e 64 28 6c 69 73 74 65    if( bind(liste
8720: 6e 65 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63  ner, (struct soc
8730: 6b 61 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 20  kaddr*)&inaddr, 
8740: 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 29 3c  sizeof(inaddr))<
8750: 30 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 66  0 ){.    fprintf
8760: 28 73 74 64 65 72 72 2c 22 43 61 6e 27 74 20 62  (stderr,"Can't b
8770: 69 6e 64 20 74 6f 20 70 6f 72 74 20 25 64 5c 6e  ind to port %d\n
8780: 22 2c 20 69 50 6f 72 74 29 3b 0a 20 20 20 20 65  ", iPort);.    e
8790: 78 69 74 28 31 29 3b 0a 20 20 7d 0a 20 20 6c 69  xit(1);.  }.  li
87a0: 73 74 65 6e 28 6c 69 73 74 65 6e 65 72 2c 31 30  sten(listener,10
87b0: 29 3b 0a 20 20 77 68 69 6c 65 28 20 31 20 29 7b  );.  while( 1 ){
87c0: 0a 20 20 20 20 69 66 28 20 6e 63 68 69 6c 64 72  .    if( nchildr
87d0: 65 6e 3e 4d 41 58 5f 50 41 52 41 4c 4c 45 4c 20  en>MAX_PARALLEL 
87e0: 29 7b 0a 20 20 20 20 20 20 2f 2a 20 53 6c 6f 77  ){.      /* Slow
87f0: 20 64 6f 77 6e 20 69 66 20 63 6f 6e 6e 65 63 74   down if connect
8800: 69 6f 6e 73 20 61 72 65 20 61 72 72 69 76 69 6e  ions are arrivin
8810: 67 20 74 6f 6f 20 66 61 73 74 20 2a 2f 0a 20 20  g too fast */.  
8820: 20 20 20 20 73 6c 65 65 70 28 20 6e 63 68 69 6c      sleep( nchil
8830: 64 72 65 6e 2d 4d 41 58 5f 50 41 52 41 4c 4c 45  dren-MAX_PARALLE
8840: 4c 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64  L );.    }.    d
8850: 65 6c 61 79 2e 74 76 5f 73 65 63 20 3d 20 36 30  elay.tv_sec = 60
8860: 3b 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 5f 75  ;.    delay.tv_u
8870: 73 65 63 20 3d 20 30 3b 0a 20 20 20 20 46 44 5f  sec = 0;.    FD_
8880: 5a 45 52 4f 28 26 72 65 61 64 66 64 73 29 3b 0a  ZERO(&readfds);.
8890: 20 20 20 20 46 44 5f 53 45 54 28 20 6c 69 73 74      FD_SET( list
88a0: 65 6e 65 72 2c 20 26 72 65 61 64 66 64 73 29 3b  ener, &readfds);
88b0: 0a 20 20 20 20 69 66 28 20 73 65 6c 65 63 74 28  .    if( select(
88c0: 20 6c 69 73 74 65 6e 65 72 2b 31 2c 20 26 72 65   listener+1, &re
88d0: 61 64 66 64 73 2c 20 30 2c 20 30 2c 20 26 64 65  adfds, 0, 0, &de
88e0: 6c 61 79 29 20 29 7b 0a 20 20 20 20 20 20 6c 65  lay) ){.      le
88f0: 6e 61 64 64 72 20 3d 20 73 69 7a 65 6f 66 28 69  naddr = sizeof(i
8900: 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20 63 6f  naddr);.      co
8910: 6e 6e 65 63 74 69 6f 6e 20 3d 20 61 63 63 65 70  nnection = accep
8920: 74 28 6c 69 73 74 65 6e 65 72 2c 20 28 73 74 72  t(listener, (str
8930: 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26 69  uct sockaddr*)&i
8940: 6e 61 64 64 72 2c 20 28 73 6f 63 6b 6c 65 6e 5f  naddr, (socklen_
8950: 74 2a 29 20 26 6c 65 6e 61 64 64 72 29 3b 0a 20  t*) &lenaddr);. 
8960: 20 20 20 20 20 69 66 28 20 63 6f 6e 6e 65 63 74       if( connect
8970: 69 6f 6e 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20  ion>=0 ){.      
8980: 20 20 63 68 69 6c 64 20 3d 20 66 6f 72 6b 28 29    child = fork()
8990: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 63 68  ;.        if( ch
89a0: 69 6c 64 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  ild!=0 ){.      
89b0: 20 20 20 20 69 66 28 20 63 68 69 6c 64 3e 30 20      if( child>0 
89c0: 29 20 6e 63 68 69 6c 64 72 65 6e 2b 2b 3b 0a 20  ) nchildren++;. 
89d0: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 63           close(c
89e0: 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20  onnection);.    
89f0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
8a00: 20 20 20 20 20 63 6c 6f 73 65 28 30 29 3b 0a 20       close(0);. 
8a10: 20 20 20 20 20 20 20 20 20 64 75 70 28 63 6f 6e           dup(con
8a20: 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20  nection);.      
8a30: 20 20 20 20 63 6c 6f 73 65 28 31 29 3b 0a 20 20      close(1);.  
8a40: 20 20 20 20 20 20 20 20 64 75 70 28 63 6f 6e 6e          dup(conn
8a50: 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20  ection);.       
8a60: 20 20 20 69 66 28 20 21 67 2e 66 48 74 74 70 54     if( !g.fHttpT
8a70: 72 61 63 65 20 29 7b 0a 20 20 20 20 20 20 20 20  race ){.        
8a80: 20 20 20 20 63 6c 6f 73 65 28 32 29 3b 0a 20 20      close(2);.  
8a90: 20 20 20 20 20 20 20 20 20 20 64 75 70 28 63 6f            dup(co
8aa0: 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20  nnection);.     
8ab0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
8ac0: 20 63 6c 6f 73 65 28 63 6f 6e 6e 65 63 74 69 6f   close(connectio
8ad0: 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 65  n);.          re
8ae0: 74 75 72 6e 3b 0a 20 20 20 20 20 20 20 20 7d 0a  turn;.        }.
8af0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
8b00: 20 20 2f 2a 20 42 75 72 79 20 64 65 61 64 20 63    /* Bury dead c
8b10: 68 69 6c 64 72 65 6e 20 2a 2f 0a 20 20 20 20 77  hildren */.    w
8b20: 68 69 6c 65 28 20 77 61 69 74 70 69 64 28 30 2c  hile( waitpid(0,
8b30: 20 30 2c 20 57 4e 4f 48 41 4e 47 29 3e 30 20 29   0, WNOHANG)>0 )
8b40: 7b 0a 20 20 20 20 20 20 6e 63 68 69 6c 64 72 65  {.      nchildre
8b50: 6e 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  n--;.    }.  }. 
8b60: 20 2f 2a 20 4e 4f 54 20 52 45 41 43 48 45 44 20   /* NOT REACHED 
8b70: 2a 2f 20 20 0a 20 20 65 78 69 74 28 31 29 3b 0a  */  .  exit(1);.
8b80: 23 65 6e 64 69 66 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  #endif.}../*.** 
8b90: 4e 61 6d 65 20 6f 66 20 64 61 79 73 20 61 6e 64  Name of days and
8ba0: 20 6d 6f 6e 74 68 73 2e 0a 2a 2f 0a 73 74 61 74   months..*/.stat
8bb0: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61  ic const char *a
8bc0: 7a 44 61 79 73 5b 5d 20 3d 0a 20 20 20 20 7b 22  zDays[] =.    {"
8bd0: 53 75 6e 22 2c 20 22 4d 6f 6e 22 2c 20 22 54 75  Sun", "Mon", "Tu
8be0: 65 22 2c 20 22 57 65 64 22 2c 20 22 54 68 75 22  e", "Wed", "Thu"
8bf0: 2c 20 22 46 72 69 22 2c 20 22 53 61 74 22 2c 20  , "Fri", "Sat", 
8c00: 30 7d 3b 0a 73 74 61 74 69 63 20 63 6f 6e 73 74  0};.static const
8c10: 20 63 68 61 72 20 2a 61 7a 4d 6f 6e 74 68 73 5b   char *azMonths[
8c20: 5d 20 3d 0a 20 20 20 20 7b 22 4a 61 6e 22 2c 20  ] =.    {"Jan", 
8c30: 22 46 65 62 22 2c 20 22 4d 61 72 22 2c 20 22 41  "Feb", "Mar", "A
8c40: 70 72 22 2c 20 22 4d 61 79 22 2c 20 22 4a 75 6e  pr", "May", "Jun
8c50: 22 2c 0a 20 20 20 20 20 22 4a 75 6c 22 2c 20 22  ",.     "Jul", "
8c60: 41 75 67 22 2c 20 22 53 65 70 22 2c 20 22 4f 63  Aug", "Sep", "Oc
8c70: 74 22 2c 20 22 4e 6f 76 22 2c 20 22 44 65 63 22  t", "Nov", "Dec"
8c80: 2c 20 30 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65  , 0};.../*.** Re
8c90: 74 75 72 6e 73 20 61 6e 20 52 46 43 38 32 32 2d  turns an RFC822-
8ca0: 66 6f 72 6d 61 74 74 65 64 20 74 69 6d 65 20 73  formatted time s
8cb0: 74 72 69 6e 67 20 73 75 69 74 61 62 6c 65 20 66  tring suitable f
8cc0: 6f 72 20 48 54 54 50 20 68 65 61 64 65 72 73 2c  or HTTP headers,
8cd0: 20 61 6d 6f 6e 67 0a 2a 2a 20 6f 74 68 65 72 20   among.** other 
8ce0: 74 68 69 6e 67 73 2e 0a 2a 2a 20 52 65 74 75 72  things..** Retur
8cf0: 6e 65 64 20 74 69 6d 65 7a 6f 6e 65 20 69 73 20  ned timezone is 
8d00: 61 6c 77 61 79 73 20 47 4d 54 20 61 73 20 72 65  always GMT as re
8d10: 71 75 69 72 65 64 20 62 79 20 48 54 54 50 2f 31  quired by HTTP/1
8d20: 2e 31 20 73 70 65 63 69 66 69 63 61 74 69 6f 6e  .1 specification
8d30: 2e 0a 2a 2a 0a 2a 2a 20 53 65 65 20 68 74 74 70  ..**.** See http
8d40: 3a 2f 2f 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f  ://www.faqs.org/
8d50: 72 66 63 73 2f 72 66 63 38 32 32 2e 68 74 6d 6c  rfcs/rfc822.html
8d60: 2c 20 73 65 63 74 69 6f 6e 20 35 0a 2a 2a 20 61  , section 5.** a
8d70: 6e 64 20 68 74 74 70 3a 2f 2f 77 77 77 2e 66 61  nd http://www.fa
8d80: 71 73 2e 6f 72 67 2f 72 66 63 73 2f 72 66 63 32  qs.org/rfcs/rfc2
8d90: 36 31 36 2e 68 74 6d 6c 2c 20 73 65 63 74 69 6f  616.html, sectio
8da0: 6e 20 33 2e 33 2e 0a 2a 2f 0a 63 68 61 72 20 2a  n 3.3..*/.char *
8db0: 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65 73  cgi_rfc822_dates
8dc0: 74 61 6d 70 28 74 69 6d 65 5f 74 20 6e 6f 77 29  tamp(time_t now)
8dd0: 7b 0a 20 20 73 74 72 75 63 74 20 74 6d 20 2a 70  {.  struct tm *p
8de0: 54 6d 3b 0a 20 20 70 54 6d 20 3d 20 67 6d 74 69  Tm;.  pTm = gmti
8df0: 6d 65 28 26 6e 6f 77 29 3b 0a 20 20 69 66 28 20  me(&now);.  if( 
8e00: 70 54 6d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  pTm==0 ) return 
8e10: 22 22 3b 0a 20 20 72 65 74 75 72 6e 20 6d 70 72  "";.  return mpr
8e20: 69 6e 74 66 28 22 25 73 2c 20 25 64 20 25 73 20  intf("%s, %d %s 
8e30: 25 30 32 64 20 25 30 32 64 3a 25 30 32 64 3a 25  %02d %02d:%02d:%
8e40: 30 32 64 20 47 4d 54 22 2c 0a 20 20 20 20 20 20  02d GMT",.      
8e50: 20 20 20 20 20 20 20 20 20 20 20 61 7a 44 61 79             azDay
8e60: 73 5b 70 54 6d 2d 3e 74 6d 5f 77 64 61 79 5d 2c  s[pTm->tm_wday],
8e70: 20 70 54 6d 2d 3e 74 6d 5f 6d 64 61 79 2c 20 61   pTm->tm_mday, a
8e80: 7a 4d 6f 6e 74 68 73 5b 70 54 6d 2d 3e 74 6d 5f  zMonths[pTm->tm_
8e90: 6d 6f 6e 5d 2c 0a 20 20 20 20 20 20 20 20 20 20  mon],.          
8ea0: 20 20 20 20 20 20 20 70 54 6d 2d 3e 74 6d 5f 79         pTm->tm_y
8eb0: 65 61 72 2b 31 39 30 30 2c 20 70 54 6d 2d 3e 74  ear+1900, pTm->t
8ec0: 6d 5f 68 6f 75 72 2c 20 70 54 6d 2d 3e 74 6d 5f  m_hour, pTm->tm_
8ed0: 6d 69 6e 2c 20 70 54 6d 2d 3e 74 6d 5f 73 65 63  min, pTm->tm_sec
8ee0: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 73  );.}../*.** Pars
8ef0: 65 20 61 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d  e an RFC822-form
8f00: 61 74 74 65 64 20 74 69 6d 65 73 74 61 6d 70 20  atted timestamp 
8f10: 61 73 20 77 65 27 64 20 65 78 70 65 63 74 20 66  as we'd expect f
8f20: 72 6f 6d 20 48 54 54 50 20 61 6e 64 20 72 65 74  rom HTTP and ret
8f30: 75 72 6e 0a 2a 2a 20 61 20 55 6e 69 78 20 65 70  urn.** a Unix ep
8f40: 6f 63 68 20 74 69 6d 65 2e 20 3c 3d 20 7a 65 72  och time. <= zer
8f50: 6f 20 69 73 20 72 65 74 75 72 6e 65 64 20 6f 6e  o is returned on
8f60: 20 66 61 69 6c 75 72 65 2e 0a 2a 2a 0a 2a 2a 20   failure..**.** 
8f70: 4e 6f 74 65 20 74 68 61 74 20 74 68 69 73 20 77  Note that this w
8f80: 6f 6e 27 74 20 68 61 6e 64 6c 65 20 61 6c 6c 20  on't handle all 
8f90: 74 68 65 20 5f 61 6c 6c 6f 77 65 64 5f 20 48 54  the _allowed_ HT
8fa0: 54 50 20 66 6f 72 6d 61 74 73 2c 20 6a 75 73 74  TP formats, just
8fb0: 20 74 68 65 0a 2a 2a 20 6d 6f 73 74 20 70 6f 70   the.** most pop
8fc0: 75 6c 61 72 20 6f 6e 65 20 28 74 68 65 20 6f 6e  ular one (the on
8fd0: 65 20 67 65 6e 65 72 61 74 65 64 20 62 79 20 63  e generated by c
8fe0: 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65 73 74  gi_rfc822_datest
8ff0: 61 6d 70 28 29 2c 20 61 63 74 75 61 6c 6c 79 29  amp(), actually)
9000: 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 63 67 69 5f  ..*/.time_t cgi_
9010: 72 66 63 38 32 32 5f 70 61 72 73 65 64 61 74 65  rfc822_parsedate
9020: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 61  (const char *zDa
9030: 74 65 29 7b 0a 20 20 73 74 72 75 63 74 20 74 6d  te){.  struct tm
9040: 20 74 3b 0a 20 20 63 68 61 72 20 7a 49 67 6e 6f   t;.  char zIgno
9050: 72 65 5b 31 36 5d 3b 0a 20 20 63 68 61 72 20 7a  re[16];.  char z
9060: 4d 6f 6e 74 68 5b 31 36 5d 3b 0a 0a 20 20 6d 65  Month[16];..  me
9070: 6d 73 65 74 28 26 74 2c 20 30 2c 20 73 69 7a 65  mset(&t, 0, size
9080: 6f 66 28 74 29 29 3b 0a 20 20 69 66 28 20 37 3d  of(t));.  if( 7=
9090: 3d 73 73 63 61 6e 66 28 7a 44 61 74 65 2c 20 22  =sscanf(zDate, "
90a0: 25 31 32 5b 41 2d 5a 61 2d 7a 2c 5d 20 25 64 20  %12[A-Za-z,] %d 
90b0: 25 31 32 5b 41 2d 5a 61 2d 7a 5d 20 25 64 20 25  %12[A-Za-z] %d %
90c0: 64 3a 25 64 3a 25 64 22 2c 20 7a 49 67 6e 6f 72  d:%d:%d", zIgnor
90d0: 65 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  e,.             
90e0: 20 20 20 20 20 20 20 20 20 20 26 74 2e 74 6d 5f            &t.tm_
90f0: 6d 64 61 79 2c 20 7a 4d 6f 6e 74 68 2c 20 26 74  mday, zMonth, &t
9100: 2e 74 6d 5f 79 65 61 72 2c 20 26 74 2e 74 6d 5f  .tm_year, &t.tm_
9110: 68 6f 75 72 2c 20 26 74 2e 74 6d 5f 6d 69 6e 2c  hour, &t.tm_min,
9120: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
9130: 20 20 20 20 20 20 20 20 26 74 2e 74 6d 5f 73 65          &t.tm_se
9140: 63 29 29 7b 0a 0a 20 20 20 20 69 66 28 20 74 2e  c)){..    if( t.
9150: 74 6d 5f 79 65 61 72 20 3e 20 31 39 30 30 20 29  tm_year > 1900 )
9160: 20 74 2e 74 6d 5f 79 65 61 72 20 2d 3d 20 31 39   t.tm_year -= 19
9170: 30 30 3b 0a 20 20 20 20 66 6f 72 28 74 2e 74 6d  00;.    for(t.tm
9180: 5f 6d 6f 6e 3d 30 3b 20 61 7a 4d 6f 6e 74 68 73  _mon=0; azMonths
9190: 5b 74 2e 74 6d 5f 6d 6f 6e 5d 3b 20 74 2e 74 6d  [t.tm_mon]; t.tm
91a0: 5f 6d 6f 6e 2b 2b 29 7b 0a 20 20 20 20 20 20 69  _mon++){.      i
91b0: 66 28 20 21 73 74 72 6e 63 61 73 65 63 6d 70 28  f( !strncasecmp(
91c0: 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d   azMonths[t.tm_m
91d0: 6f 6e 5d 2c 20 7a 4d 6f 6e 74 68 2c 20 33 20 29  on], zMonth, 3 )
91e0: 29 7b 0a 20 20 20 20 20 20 20 20 72 65 74 75 72  ){.        retur
91f0: 6e 20 6d 6b 67 6d 74 69 6d 65 28 26 74 29 3b 0a  n mkgmtime(&t);.
9200: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
9210: 7d 0a 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d  }..  return 0;.}
9220: 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20  ../*.** Convert 
9230: 61 20 73 74 72 75 63 74 20 74 6d 2a 20 74 68 61  a struct tm* tha
9240: 74 20 72 65 70 72 65 73 65 6e 74 73 20 61 20 6d  t represents a m
9250: 6f 6d 65 6e 74 20 69 6e 20 55 54 43 20 69 6e 74  oment in UTC int
9260: 6f 20 74 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20  o the number.** 
9270: 6f 66 20 73 65 63 6f 6e 64 73 20 69 6e 20 31 39  of seconds in 19
9280: 37 30 2c 20 55 54 43 2e 0a 2a 2f 0a 74 69 6d 65  70, UTC..*/.time
9290: 5f 74 20 6d 6b 67 6d 74 69 6d 65 28 73 74 72 75  _t mkgmtime(stru
92a0: 63 74 20 74 6d 20 2a 70 29 7b 0a 20 20 74 69 6d  ct tm *p){.  tim
92b0: 65 5f 74 20 74 3b 0a 20 20 69 6e 74 20 6e 44 61  e_t t;.  int nDa
92c0: 79 3b 0a 20 20 69 6e 74 20 69 73 4c 65 61 70 59  y;.  int isLeapY
92d0: 72 3b 0a 20 20 2f 2a 20 44 61 79 73 20 69 6e 20  r;.  /* Days in 
92e0: 65 61 63 68 20 6d 6f 6e 74 68 3a 20 20 20 20 20  each month:     
92f0: 20 20 33 31 2c 20 32 38 2c 20 33 31 2c 20 33 30    31, 28, 31, 30
9300: 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33 31  , 31, 30, 31, 31
9310: 2c 20 33 30 2c 20 33 31 2c 20 33 30 2c 20 33 31  , 30, 31, 30, 31
9320: 20 2a 2f 0a 20 20 73 74 61 74 69 63 20 69 6e 74   */.  static int
9330: 20 70 72 69 6f 72 44 61 79 73 5b 5d 20 20 20 3d   priorDays[]   =
9340: 20 7b 20 20 30 2c 20 33 31 2c 20 35 39 2c 20 39   {  0, 31, 59, 9
9350: 30 2c 31 32 30 2c 31 35 31 2c 31 38 31 2c 32 31  0,120,151,181,21
9360: 32 2c 32 34 33 2c 32 37 33 2c 33 30 34 2c 33 33  2,243,273,304,33
9370: 34 20 7d 3b 0a 20 20 69 66 28 20 70 2d 3e 74 6d  4 };.  if( p->tm
9380: 5f 6d 6f 6e 3c 30 20 29 7b 0a 20 20 20 20 69 6e  _mon<0 ){.    in
9390: 74 20 6e 59 65 61 72 20 3d 20 28 31 31 20 2d 20  t nYear = (11 - 
93a0: 70 2d 3e 74 6d 5f 6d 6f 6e 29 2f 31 32 3b 0a 20  p->tm_mon)/12;. 
93b0: 20 20 20 70 2d 3e 74 6d 5f 79 65 61 72 20 2d 3d     p->tm_year -=
93c0: 20 6e 59 65 61 72 3b 0a 20 20 20 20 70 2d 3e 74   nYear;.    p->t
93d0: 6d 5f 6d 6f 6e 20 2b 3d 20 6e 59 65 61 72 2a 31  m_mon += nYear*1
93e0: 32 3b 0a 20 20 7d 65 6c 73 65 20 69 66 28 20 70  2;.  }else if( p
93f0: 2d 3e 74 6d 5f 6d 6f 6e 3e 31 31 20 29 7b 0a 20  ->tm_mon>11 ){. 
9400: 20 20 20 70 2d 3e 74 6d 5f 79 65 61 72 20 2b 3d     p->tm_year +=
9410: 20 70 2d 3e 74 6d 5f 6d 6f 6e 2f 31 32 3b 0a 20   p->tm_mon/12;. 
9420: 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 20 25 3d 20     p->tm_mon %= 
9430: 31 32 3b 0a 20 20 7d 0a 20 20 69 73 4c 65 61 70  12;.  }.  isLeap
9440: 59 72 20 3d 20 70 2d 3e 74 6d 5f 79 65 61 72 25  Yr = p->tm_year%
9450: 34 3d 3d 30 20 26 26 20 28 70 2d 3e 74 6d 5f 79  4==0 && (p->tm_y
9460: 65 61 72 25 31 30 30 21 3d 30 20 7c 7c 20 28 70  ear%100!=0 || (p
9470: 2d 3e 74 6d 5f 79 65 61 72 2b 33 30 30 29 25 34  ->tm_year+300)%4
9480: 30 30 3d 3d 30 29 3b 0a 20 20 70 2d 3e 74 6d 5f  00==0);.  p->tm_
9490: 79 64 61 79 20 3d 20 70 72 69 6f 72 44 61 79 73  yday = priorDays
94a0: 5b 70 2d 3e 74 6d 5f 6d 6f 6e 5d 20 2b 20 70 2d  [p->tm_mon] + p-
94b0: 3e 74 6d 5f 6d 64 61 79 20 2d 20 31 3b 0a 20 20  >tm_mday - 1;.  
94c0: 69 66 28 20 69 73 4c 65 61 70 59 72 20 26 26 20  if( isLeapYr && 
94d0: 70 2d 3e 74 6d 5f 6d 6f 6e 3e 31 20 29 20 70 2d  p->tm_mon>1 ) p-
94e0: 3e 74 6d 5f 79 64 61 79 2b 2b 3b 0a 20 20 6e 44  >tm_yday++;.  nD
94f0: 61 79 20 3d 20 28 70 2d 3e 74 6d 5f 79 65 61 72  ay = (p->tm_year
9500: 2d 37 30 29 2a 33 36 35 20 2b 20 28 70 2d 3e 74  -70)*365 + (p->t
9510: 6d 5f 79 65 61 72 2d 36 39 29 2f 34 20 2d 70 2d  m_year-69)/4 -p-
9520: 3e 74 6d 5f 79 65 61 72 2f 31 30 30 20 2b 20 0a  >tm_year/100 + .
9530: 20 20 20 20 20 20 20 20 20 28 70 2d 3e 74 6d 5f           (p->tm_
9540: 79 65 61 72 2b 33 30 30 29 2f 34 30 30 20 2b 20  year+300)/400 + 
9550: 70 2d 3e 74 6d 5f 79 64 61 79 3b 0a 20 20 74 20  p->tm_yday;.  t 
9560: 3d 20 28 28 6e 44 61 79 2a 32 34 20 2b 20 70 2d  = ((nDay*24 + p-
9570: 3e 74 6d 5f 68 6f 75 72 29 2a 36 30 20 2b 20 70  >tm_hour)*60 + p
9580: 2d 3e 74 6d 5f 6d 69 6e 29 2a 36 30 20 2b 20 70  ->tm_min)*60 + p
9590: 2d 3e 74 6d 5f 73 65 63 3b 0a 20 20 72 65 74 75  ->tm_sec;.  retu
95a0: 72 6e 20 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43  rn t;.}../*.** C
95b0: 68 65 63 6b 20 74 68 65 20 6f 62 6a 65 63 74 54  heck the objectT
95c0: 69 6d 65 20 61 67 61 69 6e 73 74 20 74 68 65 20  ime against the 
95d0: 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e 63  If-Modified-Sinc
95e0: 65 20 72 65 71 75 65 73 74 20 68 65 61 64 65 72  e request header
95f0: 2e 20 49 66 20 74 68 65 0a 2a 2a 20 6f 62 6a 65  . If the.** obje
9600: 63 74 20 74 69 6d 65 20 69 73 6e 27 74 20 61 6e  ct time isn't an
9610: 79 20 6e 65 77 65 72 20 74 68 61 6e 20 74 68 65  y newer than the
9620: 20 68 65 61 64 65 72 2c 20 77 65 20 69 6d 6d 65   header, we imme
9630: 64 69 61 74 65 6c 79 20 73 65 6e 64 20 62 61 63  diately send bac
9640: 6b 0a 2a 2a 20 61 20 33 30 34 20 72 65 70 6c 79  k.** a 304 reply
9650: 20 61 6e 64 20 65 78 69 74 2e 0a 2a 2f 0a 76 6f   and exit..*/.vo
9660: 69 64 20 63 67 69 5f 6d 6f 64 69 66 69 65 64 5f  id cgi_modified_
9670: 73 69 6e 63 65 28 74 69 6d 65 5f 74 20 6f 62 6a  since(time_t obj
9680: 65 63 74 54 69 6d 65 29 7b 0a 20 20 63 6f 6e 73  ectTime){.  cons
9690: 74 20 63 68 61 72 20 2a 7a 49 66 20 3d 20 50 28  t char *zIf = P(
96a0: 22 48 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45  "HTTP_IF_MODIFIE
96b0: 44 5f 53 49 4e 43 45 22 29 3b 0a 20 20 69 66 28  D_SINCE");.  if(
96c0: 20 7a 49 66 3d 3d 30 20 29 20 72 65 74 75 72 6e   zIf==0 ) return
96d0: 3b 0a 20 20 69 66 28 20 6f 62 6a 65 63 74 54 69  ;.  if( objectTi
96e0: 6d 65 20 3e 20 63 67 69 5f 72 66 63 38 32 32 5f  me > cgi_rfc822_
96f0: 70 61 72 73 65 64 61 74 65 28 7a 49 66 29 20 29  parsedate(zIf) )
9700: 20 72 65 74 75 72 6e 3b 0a 20 20 63 67 69 5f 73   return;.  cgi_s
9710: 65 74 5f 73 74 61 74 75 73 28 33 30 34 2c 22 4e  et_status(304,"N
9720: 6f 74 20 4d 6f 64 69 66 69 65 64 22 29 3b 0a 20  ot Modified");. 
9730: 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65   cgi_reset_conte
9740: 6e 74 28 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c  nt();.  cgi_repl
9750: 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a  y();.  exit(0);.
9760: 7d 0a                                            }.