Hex Artifact Content
Not logged in

Artifact 48957219a226838c7bb509fc89f4317ad7013d52:

File src/cgi.c part of check-in [aeeba751c4] - Fix a memory double-free'd problem.

In function cgi_set_cookie the zDate was allocated via usage of cgi_rfc822_datestamp. But as it was appended to the blob extraHeader via the format specifier %z the memory was free'd by blob_appendf. As cgi_rfc822_datestamp might return both a dynamic allocated empty string as well as a dynamic allocated string containing the time stamp, blob_appendf should not try to free the zDate. So now the format specifier is changed to %s to let us decide, if we want to free the memory or not.

by cle on 2008-09-11 17:12:11.

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: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72  ./*.** Set the r
11e0: 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 79 70  eply content typ
11f0: 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65  e.*/.void cgi_se
1200: 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65 28 63  t_content_type(c
1210: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 70 65  onst char *zType
1220: 29 7b 0a 20 20 7a 43 6f 6e 74 65 6e 74 54 79 70  ){.  zContentTyp
1230: 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22  e = mprintf("%s"
1240: 2c 20 7a 54 79 70 65 29 3b 0a 7d 0a 0a 2f 2a 0a  , zType);.}../*.
1250: 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70 6c 79  ** Set the reply
1260: 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65 20   content to the 
1270: 73 70 65 63 69 66 69 65 64 20 42 4c 4f 42 2e 0a  specified BLOB..
1280: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f  */.void cgi_set_
1290: 63 6f 6e 74 65 6e 74 28 42 6c 6f 62 20 2a 70 4e  content(Blob *pN
12a0: 65 77 43 6f 6e 74 65 6e 74 29 7b 0a 20 20 63 67  ewContent){.  cg
12b0: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28  i_reset_content(
12c0: 29 3b 0a 20 20 63 67 69 5f 64 65 73 74 69 6e 61  );.  cgi_destina
12d0: 74 69 6f 6e 28 43 47 49 5f 48 45 41 44 45 52 29  tion(CGI_HEADER)
12e0: 3b 0a 20 20 63 67 69 43 6f 6e 74 65 6e 74 5b 30  ;.  cgiContent[0
12f0: 5d 20 3d 20 2a 70 4e 65 77 43 6f 6e 74 65 6e 74  ] = *pNewContent
1300: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70 4e  ;.  blob_zero(pN
1310: 65 77 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a 0a 2f  ewContent);.}../
1320: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70  *.** Set the rep
1330: 6c 79 20 73 74 61 74 75 73 20 63 6f 64 65 0a 2a  ly status code.*
1340: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 73  /.void cgi_set_s
1350: 74 61 74 75 73 28 69 6e 74 20 69 53 74 61 74 2c  tatus(int iStat,
1360: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74   const char *zSt
1370: 61 74 29 7b 0a 20 20 7a 52 65 70 6c 79 53 74 61  at){.  zReplySta
1380: 74 75 73 20 3d 20 6d 70 72 69 6e 74 66 28 22 25  tus = mprintf("%
1390: 73 22 2c 20 7a 53 74 61 74 29 3b 0a 20 20 69 52  s", zStat);.  iR
13a0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 69 53 74  eplyStatus = iSt
13b0: 61 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70  at;.}../*.** App
13c0: 65 6e 64 20 74 65 78 74 20 74 6f 20 74 68 65 20  end text to the 
13d0: 68 65 61 64 65 72 20 6f 66 20 61 6e 20 48 54 54  header of an HTT
13e0: 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 6f 69 64 20  P reply.*/.void 
13f0: 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 61 64 65  cgi_append_heade
1400: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4c  r(const char *zL
1410: 69 6e 65 29 7b 0a 20 20 62 6c 6f 62 5f 61 70 70  ine){.  blob_app
1420: 65 6e 64 28 26 65 78 74 72 61 48 65 61 64 65 72  end(&extraHeader
1430: 2c 20 7a 4c 69 6e 65 2c 20 2d 31 29 3b 0a 7d 0a  , zLine, -1);.}.
1440: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 20 63 6f 6f  ./*.** Set a coo
1450: 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 5a 65 72 6f 20  kie..**.** Zero 
1460: 6c 69 66 65 74 69 6d 65 20 69 6d 70 6c 69 65 73  lifetime implies
1470: 20 61 20 73 65 73 73 69 6f 6e 20 63 6f 6f 6b 69   a session cooki
1480: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73  e..*/.void cgi_s
1490: 65 74 5f 63 6f 6f 6b 69 65 28 0a 20 20 63 6f 6e  et_cookie(.  con
14a0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20  st char *zName, 
14b0: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68     /* Name of th
14c0: 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f  e cookie */.  co
14d0: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65  nst char *zValue
14e0: 2c 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f 66 20  ,   /* Value of 
14f0: 74 68 65 20 63 6f 6f 6b 69 65 2e 20 20 41 75 74  the cookie.  Aut
1500: 6f 6d 61 74 69 63 61 6c 6c 79 20 65 73 63 61 70  omatically escap
1510: 65 64 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  ed */.  const ch
1520: 61 72 20 2a 7a 50 61 74 68 2c 20 20 20 20 2f 2a  ar *zPath,    /*
1530: 20 50 61 74 68 20 63 6f 6f 6b 69 65 20 61 70 70   Path cookie app
1540: 6c 69 65 73 20 74 6f 2e 20 20 4e 55 4c 4c 20 6d  lies to.  NULL m
1550: 65 61 6e 73 20 22 2f 22 20 2a 2f 0a 20 20 69 6e  eans "/" */.  in
1560: 74 20 6c 69 66 65 74 69 6d 65 20 20 20 20 20 20  t lifetime      
1570: 20 20 20 20 2f 2a 20 45 78 70 69 72 61 74 69 6f      /* Expiratio
1580: 6e 20 6f 66 20 74 68 65 20 63 6f 6f 6b 69 65 20  n of the cookie 
1590: 69 6e 20 73 65 63 6f 6e 64 73 20 66 72 6f 6d 20  in seconds from 
15a0: 6e 6f 77 20 2a 2f 0a 29 7b 0a 20 20 69 66 28 20  now */.){.  if( 
15b0: 7a 50 61 74 68 3d 3d 30 20 29 20 7a 50 61 74 68  zPath==0 ) zPath
15c0: 20 3d 20 67 2e 7a 54 6f 70 3b 0a 20 20 69 66 28   = g.zTop;.  if(
15d0: 20 6c 69 66 65 74 69 6d 65 3e 30 20 29 7b 0a 20   lifetime>0 ){. 
15e0: 20 20 20 6c 69 66 65 74 69 6d 65 20 2b 3d 20 28     lifetime += (
15f0: 69 6e 74 29 74 69 6d 65 28 30 29 3b 0a 20 20 20  int)time(0);.   
1600: 20 63 68 61 72 20 2a 20 7a 44 61 74 65 20 3d 20   char * zDate = 
1610: 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65 73  cgi_rfc822_dates
1620: 74 61 6d 70 28 6c 69 66 65 74 69 6d 65 29 3b 0a  tamp(lifetime);.
1630: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
1640: 28 26 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20  (&extraHeader,. 
1650: 20 20 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69        "Set-Cooki
1660: 65 3a 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25  e: %s=%t; Path=%
1670: 73 3b 20 65 78 70 69 72 65 73 3d 25 73 3b 20 56  s; expires=%s; V
1680: 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a 20  ersion=1\r\n",. 
1690: 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56         zName, zV
16a0: 61 6c 75 65 2c 20 7a 50 61 74 68 2c 20 7a 44 61  alue, zPath, zDa
16b0: 74 65 29 3b 0a 20 20 20 20 69 66 28 20 7a 44 61  te);.    if( zDa
16c0: 74 65 5b 30 5d 20 29 20 66 72 65 65 28 20 7a 44  te[0] ) free( zD
16d0: 61 74 65 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  ate );.  }else{.
16e0: 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66      blob_appendf
16f0: 28 26 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20  (&extraHeader,. 
1700: 20 20 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69        "Set-Cooki
1710: 65 3a 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25  e: %s=%t; Path=%
1720: 73 3b 20 56 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e  s; Version=1\r\n
1730: 22 2c 0a 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c  ",.       zName,
1740: 20 7a 56 61 6c 75 65 2c 20 7a 50 61 74 68 29 3b   zValue, zPath);
1750: 0a 20 20 7d 0a 7d 0a 0a 23 69 66 20 30 0a 2f 2a  .  }.}..#if 0./*
1760: 0a 2a 2a 20 41 64 64 20 61 6e 20 45 54 61 67 20  .** Add an ETag 
1770: 68 65 61 64 65 72 20 6c 69 6e 65 0a 2a 2f 0a 73  header line.*/.s
1780: 74 61 74 69 63 20 63 68 61 72 20 2a 63 67 69 5f  tatic char *cgi_
1790: 61 64 64 5f 65 74 61 67 28 63 68 61 72 20 2a 7a  add_etag(char *z
17a0: 54 78 74 2c 20 69 6e 74 20 6e 4c 65 6e 29 7b 0a  Txt, int nLen){.
17b0: 20 20 4d 44 35 43 6f 6e 74 65 78 74 20 63 74 78    MD5Context ctx
17c0: 3b 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61  ;.  unsigned cha
17d0: 72 20 64 69 67 65 73 74 5b 31 36 5d 3b 0a 20 20  r digest[16];.  
17e0: 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 63 68 61 72  int i, j;.  char
17f0: 20 7a 45 54 61 67 5b 36 34 5d 3b 0a 0a 20 20 4d   zETag[64];..  M
1800: 44 35 49 6e 69 74 28 26 63 74 78 29 3b 0a 20 20  D5Init(&ctx);.  
1810: 4d 44 35 55 70 64 61 74 65 28 26 63 74 78 2c 7a  MD5Update(&ctx,z
1820: 54 78 74 2c 6e 4c 65 6e 29 3b 0a 20 20 4d 44 35  Txt,nLen);.  MD5
1830: 46 69 6e 61 6c 28 64 69 67 65 73 74 2c 26 63 74  Final(digest,&ct
1840: 78 29 3b 0a 20 20 66 6f 72 28 6a 3d 69 3d 30 3b  x);.  for(j=i=0;
1850: 20 69 3c 31 36 3b 20 69 2b 2b 2c 6a 2b 3d 32 29   i<16; i++,j+=2)
1860: 7b 0a 20 20 20 20 62 70 72 69 6e 74 66 28 26 7a  {.    bprintf(&z
1870: 45 54 61 67 5b 6a 5d 2c 73 69 7a 65 6f 66 28 7a  ETag[j],sizeof(z
1880: 45 54 61 67 29 2d 6a 2c 22 25 30 32 78 22 2c 28  ETag)-j,"%02x",(
1890: 69 6e 74 29 64 69 67 65 73 74 5b 69 5d 29 3b 0a  int)digest[i]);.
18a0: 20 20 7d 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e    }.  blob_appen
18b0: 64 66 28 26 65 78 74 72 61 48 65 61 64 65 72 2c  df(&extraHeader,
18c0: 20 22 45 54 61 67 3a 20 25 73 5c 72 5c 6e 22 2c   "ETag: %s\r\n",
18d0: 20 7a 45 54 61 67 29 3b 0a 20 20 72 65 74 75 72   zETag);.  retur
18e0: 6e 20 73 74 72 64 75 70 28 7a 45 54 61 67 29 3b  n strdup(zETag);
18f0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 73 6f 6d  .}../*.** Do som
1900: 65 20 63 61 63 68 65 20 63 6f 6e 74 72 6f 6c 20  e cache control 
1910: 73 74 75 66 66 2e 20 46 69 72 73 74 2c 20 77 65  stuff. First, we
1920: 20 67 65 6e 65 72 61 74 65 20 61 6e 20 45 54 61   generate an ETa
1930: 67 20 61 6e 64 20 69 6e 63 6c 75 64 65 20 69 74  g and include it
1940: 20 69 6e 0a 2a 2a 20 74 68 65 20 72 65 73 70 6f   in.** the respo
1950: 6e 73 65 20 68 65 61 64 65 72 73 2e 20 53 65 63  nse headers. Sec
1960: 6f 6e 64 2c 20 77 65 20 64 6f 20 77 68 61 74 65  ond, we do whate
1970: 76 65 72 20 69 73 20 6e 65 63 65 73 73 61 72 79  ver is necessary
1980: 20 74 6f 20 64 65 74 65 72 6d 69 6e 65 20 69 66   to determine if
1990: 0a 2a 2a 20 74 68 65 20 72 65 71 75 65 73 74 20  .** the request 
19a0: 77 61 73 20 61 73 6b 69 6e 67 20 61 62 6f 75 74  was asking about
19b0: 20 63 61 63 68 69 6e 67 20 61 6e 64 20 77 68 65   caching and whe
19c0: 74 68 65 72 20 77 65 20 6e 65 65 64 20 74 6f 20  ther we need to 
19d0: 73 65 6e 64 20 62 61 63 6b 20 74 68 65 0a 2a 2a  send back the.**
19e0: 20 72 65 73 70 6f 6e 73 65 20 62 6f 64 79 2e 20   response body. 
19f0: 49 66 20 77 65 20 73 68 6f 75 6c 64 6e 27 74 20  If we shouldn't 
1a00: 73 65 6e 64 20 61 20 62 6f 64 79 2c 20 72 65 74  send a body, ret
1a10: 75 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a  urn non-zero..**
1a20: 0a 2a 2a 20 43 75 72 72 65 6e 74 6c 79 2c 20 77  .** Currently, w
1a30: 65 20 6a 75 73 74 20 63 68 65 63 6b 20 74 68 65  e just check the
1a40: 20 45 54 61 67 20 61 67 61 69 6e 73 74 20 61 6e   ETag against an
1a50: 79 20 49 66 2d 4e 6f 6e 65 2d 4d 61 74 63 68 20  y If-None-Match 
1a60: 68 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 46 49  header..**.** FI
1a70: 58 4d 45 3a 20 49 6e 20 73 6f 6d 65 20 63 61 73  XME: In some cas
1a80: 65 73 20 28 61 74 74 61 63 68 6d 65 6e 74 73 2c  es (attachments,
1a90: 20 66 69 6c 65 20 63 6f 6e 74 65 6e 74 73 29 20   file contents) 
1aa0: 77 65 20 63 6f 75 6c 64 20 63 68 65 63 6b 0a 2a  we could check.*
1ab0: 2a 20 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69  * If-Modified-Si
1ac0: 6e 63 65 20 68 65 61 64 65 72 73 20 61 6e 64 20  nce headers and 
1ad0: 61 6c 77 61 79 73 20 69 6e 63 6c 75 64 65 20 4c  always include L
1ae0: 61 73 74 2d 4d 6f 64 69 66 69 65 64 20 69 6e 20  ast-Modified in 
1af0: 72 65 73 70 6f 6e 73 65 73 2e 0a 2a 2f 0a 73 74  responses..*/.st
1b00: 61 74 69 63 20 69 6e 74 20 63 68 65 63 6b 5f 63  atic int check_c
1b10: 61 63 68 65 5f 63 6f 6e 74 72 6f 6c 28 76 6f 69  ache_control(voi
1b20: 64 29 7b 0a 20 20 2f 2a 20 46 49 58 4d 45 3a 20  d){.  /* FIXME: 
1b30: 74 68 65 72 65 27 73 20 73 6f 6d 65 20 67 6f 74  there's some got
1b40: 63 68 61 73 20 77 74 68 20 63 6f 6f 6b 69 65 73  chas wth cookies
1b50: 20 61 6e 64 20 73 6f 6d 65 20 68 65 61 64 65 72   and some header
1b60: 73 2e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45  s. */.  char *zE
1b70: 54 61 67 20 3d 20 63 67 69 5f 61 64 64 5f 65 74  Tag = cgi_add_et
1b80: 61 67 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 26  ag(blob_buffer(&
1b90: 63 67 69 43 6f 6e 74 65 6e 74 29 2c 62 6c 6f 62  cgiContent),blob
1ba0: 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e  _size(&cgiConten
1bb0: 74 29 29 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 61  t));.  char *zMa
1bc0: 74 63 68 20 3d 20 50 28 22 48 54 54 50 5f 49 46  tch = P("HTTP_IF
1bd0: 5f 4e 4f 4e 45 5f 4d 41 54 43 48 22 29 3b 0a 0a  _NONE_MATCH");..
1be0: 20 20 69 66 28 20 7a 45 54 61 67 21 3d 30 20 26    if( zETag!=0 &
1bf0: 26 20 7a 4d 61 74 63 68 21 3d 30 20 29 20 7b 0a  & zMatch!=0 ) {.
1c00: 20 20 20 20 63 68 61 72 20 2a 7a 42 75 66 20 3d      char *zBuf =
1c10: 20 73 74 72 64 75 70 28 7a 4d 61 74 63 68 29 3b   strdup(zMatch);
1c20: 0a 20 20 20 20 69 66 28 20 7a 42 75 66 21 3d 30  .    if( zBuf!=0
1c30: 20 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a   ){.      char *
1c40: 7a 54 6f 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20  zTok = 0;.      
1c50: 63 68 61 72 20 2a 7a 50 6f 73 3b 0a 20 20 20 20  char *zPos;.    
1c60: 20 20 66 6f 72 28 20 7a 54 6f 6b 20 3d 20 73 74    for( zTok = st
1c70: 72 74 6f 6b 5f 72 28 7a 42 75 66 2c 20 22 2c 5c  rtok_r(zBuf, ",\
1c80: 22 22 2c 26 7a 50 6f 73 29 3b 0a 20 20 20 20 20  "",&zPos);.     
1c90: 20 20 20 20 20 20 7a 54 6f 6b 20 26 26 20 73 74        zTok && st
1ca0: 72 63 61 73 65 63 6d 70 28 7a 54 6f 6b 2c 7a 45  rcasecmp(zTok,zE
1cb0: 54 61 67 29 3b 0a 20 20 20 20 20 20 20 20 20 20  Tag);.          
1cc0: 20 7a 54 6f 6b 20 3d 20 20 73 74 72 74 6f 6b 5f   zTok =  strtok_
1cd0: 72 28 30 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73  r(0, ",\"",&zPos
1ce0: 29 29 7b 7d 0a 20 20 20 20 20 20 66 72 65 65 28  )){}.      free(
1cf0: 7a 42 75 66 29 3b 0a 20 20 20 20 20 20 69 66 28  zBuf);.      if(
1d00: 7a 54 6f 6b 29 20 72 65 74 75 72 6e 20 31 3b 0a  zTok) return 1;.
1d10: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72      }.  }.  .  r
1d20: 65 74 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69  eturn 0;.}.#endi
1d30: 66 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 6e 6f  f../*.** Do a no
1d40: 72 6d 61 6c 20 48 54 54 50 20 72 65 70 6c 79 0a  rmal HTTP reply.
1d50: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c  */.void cgi_repl
1d60: 79 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 74  y(void){.  int t
1d70: 6f 74 61 6c 5f 73 69 7a 65 20 3d 20 30 3b 0a 20  otal_size = 0;. 
1d80: 20 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75   if( iReplyStatu
1d90: 73 3c 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 70  s<=0 ){.    iRep
1da0: 6c 79 53 74 61 74 75 73 20 3d 20 32 30 30 3b 0a  lyStatus = 200;.
1db0: 20 20 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73      zReplyStatus
1dc0: 20 3d 20 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69   = "OK";.  }..#i
1dd0: 66 20 30 0a 20 20 69 66 28 20 69 52 65 70 6c 79  f 0.  if( iReply
1de0: 53 74 61 74 75 73 3d 3d 32 30 30 20 26 26 20 63  Status==200 && c
1df0: 68 65 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72  heck_cache_contr
1e00: 6f 6c 28 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20  ol() ) {.    /* 
1e10: 63 68 61 6e 67 65 20 74 68 65 20 73 74 61 74 75  change the statu
1e20: 73 20 74 6f 20 22 75 6e 63 68 61 6e 67 65 64 22  s to "unchanged"
1e30: 20 61 6e 64 20 77 65 20 63 61 6e 20 73 6b 69 70   and we can skip
1e40: 20 73 65 6e 64 69 6e 67 20 74 68 65 0a 20 20 20   sending the.   
1e50: 20 2a 2a 20 61 63 74 75 61 6c 20 72 65 73 70 6f   ** actual respo
1e60: 6e 73 65 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75  nse body. Obviou
1e70: 73 6c 79 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74  sly we only do t
1e80: 68 69 73 20 77 68 65 6e 20 77 65 20 5f 68 61 76  his when we _hav
1e90: 65 5f 20 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79  e_ a.    ** body
1ea0: 20 28 63 6f 64 65 20 32 30 30 29 2e 0a 20 20 20   (code 200)..   
1eb0: 20 2a 2f 0a 20 20 20 20 69 52 65 70 6c 79 53 74   */.    iReplySt
1ec0: 61 74 75 73 20 3d 20 33 30 34 3b 0a 20 20 20 20  atus = 304;.    
1ed0: 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22  zReplyStatus = "
1ee0: 4e 6f 74 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20  Not Modified";. 
1ef0: 20 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28   }.#endif..  if(
1f00: 20 67 2e 66 75 6c 6c 48 74 74 70 52 65 70 6c 79   g.fullHttpReply
1f10: 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 66 28   ){.    fprintf(
1f20: 67 2e 68 74 74 70 4f 75 74 2c 20 22 48 54 54 50  g.httpOut, "HTTP
1f30: 2f 31 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22 2c  /1.0 %d %s\r\n",
1f40: 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a   iReplyStatus, z
1f50: 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20  ReplyStatus);.  
1f60: 20 20 63 68 61 72 20 2a 20 7a 44 61 74 65 20 3d    char * zDate =
1f70: 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65   cgi_rfc822_date
1f80: 73 74 61 6d 70 28 74 69 6d 65 28 30 29 29 3b 0a  stamp(time(0));.
1f90: 20 20 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74      fprintf(g.ht
1fa0: 74 70 4f 75 74 2c 20 22 44 61 74 65 3a 20 25 73  tpOut, "Date: %s
1fb0: 5c 72 5c 6e 22 2c 20 7a 44 61 74 65 20 29 3b 0a  \r\n", zDate );.
1fc0: 20 20 20 20 69 66 28 20 7a 44 61 74 65 5b 30 5d      if( zDate[0]
1fd0: 20 29 20 66 72 65 65 28 20 7a 44 61 74 65 20 29   ) free( zDate )
1fe0: 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 67 2e  ;.    fprintf(g.
1ff0: 68 74 74 70 4f 75 74 2c 20 22 43 6f 6e 6e 65 63  httpOut, "Connec
2000: 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e 22  tion: close\r\n"
2010: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  );.  }else{.    
2020: 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75  fprintf(g.httpOu
2030: 74 2c 20 22 53 74 61 74 75 73 3a 20 25 64 20 25  t, "Status: %d %
2040: 73 5c 72 5c 6e 22 2c 20 69 52 65 70 6c 79 53 74  s\r\n", iReplySt
2050: 61 74 75 73 2c 20 7a 52 65 70 6c 79 53 74 61 74  atus, zReplyStat
2060: 75 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  us);.  }..  if( 
2070: 62 6c 6f 62 5f 73 69 7a 65 28 26 65 78 74 72 61  blob_size(&extra
2080: 48 65 61 64 65 72 29 3e 30 20 29 7b 0a 20 20 20  Header)>0 ){.   
2090: 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f   fprintf(g.httpO
20a0: 75 74 2c 20 22 25 73 22 2c 20 62 6c 6f 62 5f 62  ut, "%s", blob_b
20b0: 75 66 66 65 72 28 26 65 78 74 72 61 48 65 61 64  uffer(&extraHead
20c0: 65 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28  er));.  }..  if(
20d0: 20 67 2e 69 73 43 6f 6e 73 74 20 29 7b 0a 20 20   g.isConst ){.  
20e0: 20 20 2f 2a 20 63 6f 6e 73 74 61 6e 74 20 6d 65    /* constant me
20f0: 61 6e 73 20 74 68 61 74 20 74 68 65 20 69 6e 70  ans that the inp
2100: 75 74 20 55 52 4c 20 77 69 6c 6c 20 5f 6e 65 76  ut URL will _nev
2110: 65 72 5f 20 67 65 6e 65 72 61 74 65 20 61 6e 79  er_ generate any
2120: 74 68 69 6e 67 0a 20 20 20 20 2a 2a 20 65 6c 73  thing.    ** els
2130: 65 2e 20 49 6e 20 74 68 65 20 63 61 73 65 20 6f  e. In the case o
2140: 66 20 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 74  f attachments, t
2150: 68 65 20 63 6f 6e 74 65 6e 74 73 20 77 6f 6e 27  he contents won'
2160: 74 20 63 68 61 6e 67 65 20 62 65 63 61 75 73 65  t change because
2170: 0a 20 20 20 20 2a 2a 20 61 6e 20 61 74 74 65 6d  .    ** an attem
2180: 70 74 20 74 6f 20 63 68 61 6e 67 65 20 74 68 65  pt to change the
2190: 6d 20 67 65 6e 65 72 61 74 65 73 20 61 20 6e 65  m generates a ne
21a0: 77 20 61 74 74 61 63 68 6d 65 6e 74 20 6e 75 6d  w attachment num
21b0: 62 65 72 2e 20 49 6e 20 74 68 65 0a 20 20 20 20  ber. In the.    
21c0: 2a 2a 20 63 61 73 65 20 6f 66 20 6d 6f 73 74 20  ** case of most 
21d0: 2f 67 65 74 66 69 6c 65 20 63 61 6c 6c 73 20 66  /getfile calls f
21e0: 6f 72 20 73 70 65 63 69 66 69 63 20 76 65 72 73  or specific vers
21f0: 69 6f 6e 73 2c 20 74 68 65 20 6f 6e 6c 79 20 77  ions, the only w
2200: 61 79 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f  ay the.    ** co
2210: 6e 74 65 6e 74 20 63 68 61 6e 67 65 73 20 69 73  ntent changes is
2220: 20 69 66 20 73 6f 6d 65 6f 6e 65 20 62 72 65 61   if someone brea
2230: 6b 73 20 74 68 65 20 53 43 4d 2e 20 41 6e 64 20  ks the SCM. And 
2240: 69 66 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c  if that happens,
2250: 20 61 0a 20 20 20 20 2a 2a 20 73 74 61 6c 65 20   a.    ** stale 
2260: 63 61 63 68 65 20 69 73 20 74 68 65 20 6c 65 61  cache is the lea
2270: 73 74 20 6f 66 20 74 68 65 20 70 72 6f 62 6c 65  st of the proble
2280: 6d 2e 20 53 6f 20 77 65 20 70 72 6f 76 69 64 65  m. So we provide
2290: 20 61 6e 20 45 78 70 69 72 65 73 0a 20 20 20 20   an Expires.    
22a0: 2a 2a 20 68 65 61 64 65 72 20 73 65 74 20 74 6f  ** header set to
22b0: 20 61 20 72 65 61 73 6f 6e 61 62 6c 65 20 70 65   a reasonable pe
22c0: 72 69 6f 64 20 28 64 65 66 61 75 6c 74 3a 20 6f  riod (default: o
22d0: 6e 65 20 77 65 65 6b 29 2e 0a 20 20 20 20 2a 2f  ne week)..    */
22e0: 0a 20 20 20 20 2f 2a 74 69 6d 65 5f 74 20 65 78  .    /*time_t ex
22f0: 70 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20  pires = time(0) 
2300: 2b 20 61 74 6f 69 28 64 62 5f 63 6f 6e 66 69 67  + atoi(db_config
2310: 28 22 63 6f 6e 73 74 61 6e 74 5f 65 78 70 69 72  ("constant_expir
2320: 65 73 22 2c 22 36 30 34 38 30 30 22 29 29 3b 2a  es","604800"));*
2330: 2f 0a 20 20 20 20 74 69 6d 65 5f 74 20 65 78 70  /.    time_t exp
2340: 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 2b  ires = time(0) +
2350: 20 36 30 34 38 30 30 3b 0a 20 20 20 20 63 68 61   604800;.    cha
2360: 72 20 2a 20 7a 44 61 74 65 20 3d 20 63 67 69 5f  r * zDate = cgi_
2370: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70  rfc822_datestamp
2380: 28 65 78 70 69 72 65 73 29 3b 0a 20 20 20 20 66  (expires);.    f
2390: 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74  printf(g.httpOut
23a0: 2c 20 22 45 78 70 69 72 65 73 3a 20 25 73 5c 72  , "Expires: %s\r
23b0: 5c 6e 22 2c 20 7a 44 61 74 65 20 29 3b 0a 20 20  \n", zDate );.  
23c0: 20 20 69 66 28 20 7a 44 61 74 65 5b 30 5d 20 29    if( zDate[0] )
23d0: 20 66 72 65 65 28 20 7a 44 61 74 65 20 29 3b 0a   free( zDate );.
23e0: 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6e 74 65 6e    }..  /* Conten
23f0: 74 20 69 6e 74 65 6e 64 65 64 20 66 6f 72 20 6c  t intended for l
2400: 6f 67 67 65 64 20 69 6e 20 75 73 65 72 73 20 73  ogged in users s
2410: 68 6f 75 6c 64 20 6f 6e 6c 79 20 62 65 20 63 61  hould only be ca
2420: 63 68 65 64 20 69 6e 0a 20 20 2a 2a 20 74 68 65  ched in.  ** the
2430: 20 62 72 6f 77 73 65 72 2c 20 6e 6f 74 20 73 6f   browser, not so
2440: 6d 65 20 73 68 61 72 65 64 20 6c 6f 63 61 74 69  me shared locati
2450: 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 66 70 72 69 6e  on..  */.  fprin
2460: 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 43  tf(g.httpOut, "C
2470: 61 63 68 65 2d 63 6f 6e 74 72 6f 6c 3a 20 70 72  ache-control: pr
2480: 69 76 61 74 65 5c 72 5c 6e 22 29 3b 0a 0a 23 69  ivate\r\n");..#i
2490: 66 20 46 4f 53 53 49 4c 5f 49 31 38 4e 0a 20 20  f FOSSIL_I18N.  
24a0: 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75  fprintf(g.httpOu
24b0: 74 2c 0a 20 20 20 20 20 22 43 6f 6e 74 65 6e 74  t,.     "Content
24c0: 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 72 73  -Type: %s; chars
24d0: 65 74 3d 25 73 5c 72 5c 6e 22 2c 20 7a 43 6f 6e  et=%s\r\n", zCon
24e0: 74 65 6e 74 54 79 70 65 2c 20 6e 6c 5f 6c 61 6e  tentType, nl_lan
24f0: 67 69 6e 66 6f 28 43 4f 44 45 53 45 54 29 29 3b  ginfo(CODESET));
2500: 0a 23 65 6c 73 65 0a 20 20 66 70 72 69 6e 74 66  .#else.  fprintf
2510: 28 67 2e 68 74 74 70 4f 75 74 2c 0a 20 20 20 20  (g.httpOut,.    
2520: 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20   "Content-Type: 
2530: 25 73 3b 20 63 68 61 72 73 65 74 3d 49 53 4f 2d  %s; charset=ISO-
2540: 38 38 35 39 2d 31 5c 72 5c 6e 22 2c 20 7a 43 6f  8859-1\r\n", zCo
2550: 6e 74 65 6e 74 54 79 70 65 29 3b 0a 23 65 6e 64  ntentType);.#end
2560: 69 66 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28  if.  if( strcmp(
2570: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 2c 22 61 70  zContentType,"ap
2580: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73  plication/x-foss
2590: 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 63  il")==0 ){.    c
25a0: 67 69 5f 63 6f 6d 62 69 6e 65 5f 68 65 61 64 65  gi_combine_heade
25b0: 72 5f 61 6e 64 5f 62 6f 64 79 28 29 3b 0a 20 20  r_and_body();.  
25c0: 20 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 28    blob_compress(
25d0: 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 2c 20  &cgiContent[0], 
25e0: 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b  &cgiContent[0]);
25f0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 52 65 70  .  }..  if( iRep
2600: 6c 79 53 74 61 74 75 73 20 21 3d 20 33 30 34 20  lyStatus != 304 
2610: 29 20 7b 0a 20 20 20 20 74 6f 74 61 6c 5f 73 69  ) {.    total_si
2620: 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26  ze = blob_size(&
2630: 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 20 2b  cgiContent[0]) +
2640: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43   blob_size(&cgiC
2650: 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 20 20 20 20  ontent[1]);.    
2660: 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75  fprintf(g.httpOu
2670: 74 2c 20 22 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67  t, "Content-Leng
2680: 74 68 3a 20 25 64 5c 72 5c 6e 22 2c 20 74 6f 74  th: %d\r\n", tot
2690: 61 6c 5f 73 69 7a 65 29 3b 0a 20 20 7d 0a 20 20  al_size);.  }.  
26a0: 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75  fprintf(g.httpOu
26b0: 74 2c 20 22 5c 72 5c 6e 22 29 3b 0a 20 20 69 66  t, "\r\n");.  if
26c0: 28 20 74 6f 74 61 6c 5f 73 69 7a 65 3e 30 20 26  ( total_size>0 &
26d0: 26 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 21  & iReplyStatus !
26e0: 3d 20 33 30 34 20 29 7b 0a 20 20 20 20 69 6e 74  = 304 ){.    int
26f0: 20 69 2c 20 73 69 7a 65 3b 0a 20 20 20 20 66 6f   i, size;.    fo
2700: 72 28 69 3d 30 3b 20 69 3c 32 3b 20 69 2b 2b 29  r(i=0; i<2; i++)
2710: 7b 0a 20 20 20 20 20 20 73 69 7a 65 20 3d 20 62  {.      size = b
2720: 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e  lob_size(&cgiCon
2730: 74 65 6e 74 5b 69 5d 29 3b 0a 20 20 20 20 20 20  tent[i]);.      
2740: 69 66 28 20 73 69 7a 65 3e 30 20 29 7b 0a 20 20  if( size>0 ){.  
2750: 20 20 20 20 20 20 66 77 72 69 74 65 28 62 6c 6f        fwrite(blo
2760: 62 5f 62 75 66 66 65 72 28 26 63 67 69 43 6f 6e  b_buffer(&cgiCon
2770: 74 65 6e 74 5b 69 5d 29 2c 20 31 2c 20 73 69 7a  tent[i]), 1, siz
2780: 65 2c 20 67 2e 68 74 74 70 4f 75 74 29 3b 0a 20  e, g.httpOut);. 
2790: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d       }.    }.  }
27a0: 0a 20 20 43 47 49 44 45 42 55 47 28 28 22 44 4f  .  CGIDEBUG(("DO
27b0: 4e 45 5c 6e 22 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  NE\n"));.}../*.*
27c0: 2a 20 44 6f 20 61 20 72 65 64 69 72 65 63 74 20  * Do a redirect 
27d0: 72 65 71 75 65 73 74 20 74 6f 20 74 68 65 20 55  request to the U
27e0: 52 4c 20 67 69 76 65 6e 20 69 6e 20 74 68 65 20  RL given in the 
27f0: 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20  argument..**.** 
2800: 54 68 65 20 55 52 4c 20 6d 75 73 74 20 62 65 20  The URL must be 
2810: 72 65 6c 61 74 69 76 65 20 74 6f 20 74 68 65 20  relative to the 
2820: 62 61 73 65 20 6f 66 20 74 68 65 20 66 6f 73 73  base of the foss
2830: 69 6c 20 73 65 72 76 65 72 2e 0a 2a 2f 0a 76 6f  il server..*/.vo
2840: 69 64 20 63 67 69 5f 72 65 64 69 72 65 63 74 28  id cgi_redirect(
2850: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 52 4c  const char *zURL
2860: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 63 61  ){.  char *zLoca
2870: 74 69 6f 6e 3b 0a 20 20 43 47 49 44 45 42 55 47  tion;.  CGIDEBUG
2880: 28 28 22 72 65 64 69 72 65 63 74 20 74 6f 20 25  (("redirect to %
2890: 73 5c 6e 22 2c 20 7a 55 52 4c 29 29 3b 0a 20 20  s\n", zURL));.  
28a0: 69 66 28 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c  if( strncmp(zURL
28b0: 2c 22 68 74 74 70 3a 22 2c 35 29 3d 3d 30 20 7c  ,"http:",5)==0 |
28c0: 7c 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22  | strncmp(zURL,"
28d0: 68 74 74 70 73 3a 22 2c 36 29 3d 3d 30 20 7c 7c  https:",6)==0 ||
28e0: 20 2a 7a 55 52 4c 3d 3d 27 2f 27 20 29 7b 0a 20   *zURL=='/' ){. 
28f0: 20 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d     zLocation = m
2900: 70 72 69 6e 74 66 28 22 4c 6f 63 61 74 69 6f 6e  printf("Location
2910: 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 55 52 4c 29  : %s\r\n", zURL)
2920: 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a  ;.  }else{.    z
2930: 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 72 69 6e  Location = mprin
2940: 74 66 28 22 4c 6f 63 61 74 69 6f 6e 3a 20 25 73  tf("Location: %s
2950: 2f 25 73 5c 72 5c 6e 22 2c 20 67 2e 7a 42 61 73  /%s\r\n", g.zBas
2960: 65 55 52 4c 2c 20 7a 55 52 4c 29 3b 0a 20 20 7d  eURL, zURL);.  }
2970: 0a 20 20 63 67 69 5f 61 70 70 65 6e 64 5f 68 65  .  cgi_append_he
2980: 61 64 65 72 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b  ader(zLocation);
2990: 0a 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e  .  cgi_reset_con
29a0: 74 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f 70 72  tent();.  cgi_pr
29b0: 69 6e 74 66 28 22 3c 68 74 6d 6c 3e 5c 6e 3c 70  intf("<html>\n<p
29c0: 3e 52 65 64 69 72 65 63 74 20 74 6f 20 25 68 3c  >Redirect to %h<
29d0: 2f 70 3e 5c 6e 3c 2f 68 74 6d 6c 3e 5c 6e 22 2c  /p>\n</html>\n",
29e0: 20 7a 55 52 4c 29 3b 0a 20 20 63 67 69 5f 73 65   zURL);.  cgi_se
29f0: 74 5f 73 74 61 74 75 73 28 33 30 32 2c 20 22 4d  t_status(302, "M
2a00: 6f 76 65 64 20 54 65 6d 70 6f 72 61 72 69 6c 79  oved Temporarily
2a10: 22 29 3b 0a 20 20 66 72 65 65 28 7a 4c 6f 63 61  ");.  free(zLoca
2a20: 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65 70  tion);.  cgi_rep
2a30: 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b  ly();.  exit(0);
2a40: 0a 7d 0a 76 6f 69 64 20 63 67 69 5f 72 65 64 69  .}.void cgi_redi
2a50: 72 65 63 74 66 28 63 6f 6e 73 74 20 63 68 61 72  rectf(const char
2a60: 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b   *zFormat, ...){
2a70: 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20  .  va_list ap;. 
2a80: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46   va_start(ap, zF
2a90: 6f 72 6d 61 74 29 3b 0a 20 20 63 67 69 5f 72 65  ormat);.  cgi_re
2aa0: 64 69 72 65 63 74 28 76 6d 70 72 69 6e 74 66 28  direct(vmprintf(
2ab0: 7a 46 6f 72 6d 61 74 2c 20 61 70 29 29 3b 0a 20  zFormat, ap));. 
2ac0: 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a   va_end(ap);.}..
2ad0: 2f 2a 0a 2a 2a 20 49 6e 66 6f 72 6d 61 74 69 6f  /*.** Informatio
2ae0: 6e 20 61 62 6f 75 74 20 61 6c 6c 20 71 75 65 72  n about all quer
2af0: 79 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e 64  y parameters and
2b00: 20 63 6f 6f 6b 69 65 73 20 61 72 65 20 73 74 6f   cookies are sto
2b10: 72 65 64 0a 2a 2a 20 69 6e 20 74 68 65 73 65 20  red.** in these 
2b20: 76 61 72 69 61 62 6c 65 73 2e 0a 2a 2f 0a 73 74  variables..*/.st
2b30: 61 74 69 63 20 69 6e 74 20 6e 41 6c 6c 6f 63 51  atic int nAllocQ
2b40: 50 20 3d 20 30 3b 20 2f 2a 20 53 70 61 63 65 20  P = 0; /* Space 
2b50: 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 50  allocated for aP
2b60: 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74  aramQP[] */.stat
2b70: 69 63 20 69 6e 74 20 6e 55 73 65 64 51 50 20 3d  ic int nUsedQP =
2b80: 20 30 3b 20 20 2f 2a 20 53 70 61 63 65 20 61 63   0;  /* Space ac
2b90: 74 75 61 6c 6c 79 20 75 73 65 64 20 69 6e 20 61  tually used in a
2ba0: 50 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61  ParamQP[] */.sta
2bb0: 74 69 63 20 69 6e 74 20 73 6f 72 74 51 50 20 3d  tic int sortQP =
2bc0: 20 30 3b 20 20 20 2f 2a 20 54 72 75 65 20 69 66   0;   /* True if
2bd0: 20 61 50 61 72 61 6d 51 50 5b 5d 20 6e 65 65 64   aParamQP[] need
2be0: 73 20 73 6f 72 74 69 6e 67 20 2a 2f 0a 73 74 61  s sorting */.sta
2bf0: 74 69 63 20 69 6e 74 20 73 65 71 51 50 20 3d 20  tic int seqQP = 
2c00: 30 3b 20 20 20 20 2f 2a 20 53 65 71 75 65 6e 63  0;    /* Sequenc
2c10: 65 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 73 74 61  e numbers */.sta
2c20: 74 69 63 20 73 74 72 75 63 74 20 51 50 61 72 61  tic struct QPara
2c30: 6d 20 7b 20 20 20 2f 2a 20 4f 6e 65 20 65 6e 74  m {   /* One ent
2c40: 72 79 20 66 6f 72 20 65 61 63 68 20 71 75 65 72  ry for each quer
2c50: 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63  y parameter or c
2c60: 6f 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74  ookie */.  const
2c70: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20   char *zName;   
2c80: 20 20 20 20 20 2f 2a 20 50 61 72 61 6d 65 74 65       /* Paramete
2c90: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65  r or cookie name
2ca0: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72   */.  const char
2cb0: 20 2a 7a 56 61 6c 75 65 3b 20 20 20 20 20 20 20   *zValue;       
2cc0: 2f 2a 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20  /* Value of the 
2cd0: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20  query parameter 
2ce0: 6f 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 69  or cookie */.  i
2cf0: 6e 74 20 73 65 71 3b 20 20 20 20 20 20 20 20 20  nt seq;         
2d00: 20 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 64 65           /* Orde
2d10: 72 20 6f 66 20 69 6e 73 65 72 74 69 6f 6e 20 2a  r of insertion *
2d20: 2f 0a 7d 20 2a 61 50 61 72 61 6d 51 50 3b 20 20  /.} *aParamQP;  
2d30: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 6e             /* An
2d40: 20 61 72 72 61 79 20 6f 66 20 61 6c 6c 20 70 61   array of all pa
2d50: 72 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f  rameters and coo
2d60: 6b 69 65 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41  kies */../*.** A
2d70: 64 64 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79  dd another query
2d80: 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f   parameter or co
2d90: 6f 6b 69 65 20 74 6f 20 74 68 65 20 70 61 72 61  okie to the para
2da0: 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e  meter set..** zN
2db0: 61 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20  ame is the name 
2dc0: 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72  of the query par
2dd0: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65  ameter or cookie
2de0: 20 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69   and zValue.** i
2df0: 73 20 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f  s its fully deco
2e00: 64 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a  ded value..**.**
2e10: 20 7a 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c 75   zName and zValu
2e20: 65 20 61 72 65 20 6e 6f 74 20 63 6f 70 69 65 64  e are not copied
2e30: 20 61 6e 64 20 6d 75 73 74 20 6e 6f 74 20 63 68   and must not ch
2e40: 61 6e 67 65 20 6f 72 20 62 65 0a 2a 2a 20 64 65  ange or be.** de
2e50: 61 6c 6c 6f 63 61 74 65 64 20 61 66 74 65 72 20  allocated after 
2e60: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74  this routine ret
2e70: 75 72 6e 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  urns..*/.void cg
2e80: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f  i_set_parameter_
2e90: 6e 6f 63 6f 70 79 28 63 6f 6e 73 74 20 63 68 61  nocopy(const cha
2ea0: 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20  r *zName, const 
2eb0: 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20  char *zValue){. 
2ec0: 20 69 66 28 20 6e 41 6c 6c 6f 63 51 50 3c 3d 6e   if( nAllocQP<=n
2ed0: 55 73 65 64 51 50 20 29 7b 0a 20 20 20 20 6e 41  UsedQP ){.    nA
2ee0: 6c 6c 6f 63 51 50 20 3d 20 6e 41 6c 6c 6f 63 51  llocQP = nAllocQ
2ef0: 50 2a 32 20 2b 20 31 30 3b 0a 20 20 20 20 61 50  P*2 + 10;.    aP
2f00: 61 72 61 6d 51 50 20 3d 20 72 65 61 6c 6c 6f 63  aramQP = realloc
2f10: 28 20 61 50 61 72 61 6d 51 50 2c 20 6e 41 6c 6c  ( aParamQP, nAll
2f20: 6f 63 51 50 2a 73 69 7a 65 6f 66 28 61 50 61 72  ocQP*sizeof(aPar
2f30: 61 6d 51 50 5b 30 5d 29 20 29 3b 0a 20 20 20 20  amQP[0]) );.    
2f40: 69 66 28 20 61 50 61 72 61 6d 51 50 3d 3d 30 20  if( aParamQP==0 
2f50: 29 20 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a 20  ) exit(1);.  }. 
2f60: 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51   aParamQP[nUsedQ
2f70: 50 5d 2e 7a 4e 61 6d 65 20 3d 20 7a 4e 61 6d 65  P].zName = zName
2f80: 3b 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73  ;.  aParamQP[nUs
2f90: 65 64 51 50 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a  edQP].zValue = z
2fa0: 56 61 6c 75 65 3b 0a 20 20 61 50 61 72 61 6d 51  Value;.  aParamQ
2fb0: 50 5b 6e 55 73 65 64 51 50 5d 2e 73 65 71 20 3d  P[nUsedQP].seq =
2fc0: 20 73 65 71 51 50 2b 2b 3b 0a 20 20 6e 55 73 65   seqQP++;.  nUse
2fd0: 64 51 50 2b 2b 3b 0a 20 20 73 6f 72 74 51 50 20  dQP++;.  sortQP 
2fe0: 3d 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64  = 1;.}../*.** Ad
2ff0: 64 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79 20  d another query 
3000: 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f  parameter or coo
3010: 6b 69 65 20 74 6f 20 74 68 65 20 70 61 72 61 6d  kie to the param
3020: 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61  eter set..** zNa
3030: 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f  me is the name o
3040: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  f the query para
3050: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20  meter or cookie 
3060: 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73  and zValue.** is
3070: 20 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f 64   its fully decod
3080: 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20  ed value..**.** 
3090: 43 6f 70 69 65 73 20 61 72 65 20 6d 61 64 65 20  Copies are made 
30a0: 6f 66 20 62 6f 74 68 20 74 68 65 20 7a 4e 61 6d  of both the zNam
30b0: 65 20 61 6e 64 20 7a 56 61 6c 75 65 20 70 61 72  e and zValue par
30c0: 61 6d 65 74 65 72 73 2e 0a 2a 2f 0a 76 6f 69 64  ameters..*/.void
30d0: 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74   cgi_set_paramet
30e0: 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  er(const char *z
30f0: 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72  Name, const char
3100: 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69   *zValue){.  cgi
3110: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e  _set_parameter_n
3120: 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25  ocopy(mprintf("%
3130: 73 22 2c 7a 4e 61 6d 65 29 2c 20 6d 70 72 69 6e  s",zName), mprin
3140: 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29 29  tf("%s",zValue))
3150: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 70 6c 61  ;.}../*.** Repla
3160: 63 65 20 61 20 70 61 72 61 6d 65 74 65 72 20 77  ce a parameter w
3170: 69 74 68 20 61 20 6e 65 77 20 76 61 6c 75 65 2e  ith a new value.
3180: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 70  .*/.void cgi_rep
3190: 6c 61 63 65 5f 70 61 72 61 6d 65 74 65 72 28 63  lace_parameter(c
31a0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
31b0: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56  , const char *zV
31c0: 61 6c 75 65 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  alue){.  int i;.
31d0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 55 73    for(i=0; i<nUs
31e0: 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  edQP; i++){.    
31f0: 69 66 28 20 73 74 72 63 6d 70 28 61 50 61 72 61  if( strcmp(aPara
3200: 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 7a 4e 61  mQP[i].zName,zNa
3210: 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  me)==0 ){.      
3220: 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 56 61 6c  aParamQP[i].zVal
3230: 75 65 20 3d 20 7a 56 61 6c 75 65 3b 0a 20 20 20  ue = zValue;.   
3240: 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d     return;.    }
3250: 0a 20 20 7d 0a 20 20 63 67 69 5f 73 65 74 5f 70  .  }.  cgi_set_p
3260: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28  arameter_nocopy(
3270: 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a  zName, zValue);.
3280: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 71  }../*.** Add a q
3290: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 2e 20  uery parameter. 
32a0: 20 54 68 65 20 7a 4e 61 6d 65 20 70 6f 72 74 69   The zName porti
32b0: 6f 6e 20 69 73 20 66 69 78 65 64 20 62 75 74 20  on is fixed but 
32c0: 61 20 63 6f 70 79 0a 2a 2a 20 6d 75 73 74 20 62  a copy.** must b
32d0: 65 20 6d 61 64 65 20 6f 66 20 7a 56 61 6c 75 65  e made of zValue
32e0: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65  ..*/.void cgi_se
32f0: 74 65 6e 76 28 63 6f 6e 73 74 20 63 68 61 72 20  tenv(const char 
3300: 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68  *zName, const ch
3310: 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63  ar *zValue){.  c
3320: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72  gi_set_parameter
3330: 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 6d  _nocopy(zName, m
3340: 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c  printf("%s",zVal
3350: 75 65 29 29 3b 0a 7d 0a 20 0a 0a 2f 2a 0a 2a 2a  ue));.}. ../*.**
3360: 20 41 64 64 20 61 20 6c 69 73 74 20 6f 66 20 71   Add a list of q
3370: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 20  uery parameters 
3380: 6f 72 20 63 6f 6f 6b 69 65 73 20 74 6f 20 74 68  or cookies to th
3390: 65 20 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e  e parameter set.
33a0: 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 70 61 72 61  .**.** Each para
33b0: 6d 65 74 65 72 20 69 73 20 6f 66 20 74 68 65 20  meter is of the 
33c0: 66 6f 72 6d 20 4e 41 4d 45 3d 56 41 4c 55 45 2e  form NAME=VALUE.
33d0: 20 20 42 6f 74 68 20 74 68 65 20 4e 41 4d 45 20    Both the NAME 
33e0: 61 6e 64 20 74 68 65 0a 2a 2a 20 56 41 4c 55 45  and the.** VALUE
33f0: 20 6d 61 79 20 62 65 20 75 72 6c 2d 65 6e 63 6f   may be url-enco
3400: 64 65 64 20 28 22 2b 22 20 66 6f 72 20 73 70 61  ded ("+" for spa
3410: 63 65 2c 20 22 25 48 48 22 20 66 6f 72 20 6f 74  ce, "%HH" for ot
3420: 68 65 72 20 73 70 65 63 69 61 6c 0a 2a 2a 20 63  her special.** c
3430: 68 61 72 61 63 74 65 72 73 29 2e 20 20 42 75 74  haracters).  But
3440: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 61 73   this routine as
3450: 73 75 6d 65 73 20 74 68 61 74 20 4e 41 4d 45 20  sumes that NAME 
3460: 63 6f 6e 74 61 69 6e 73 20 6e 6f 0a 2a 2a 20 73  contains no.** s
3470: 70 65 63 69 61 6c 20 63 68 61 72 61 63 74 65 72  pecial character
3480: 20 61 6e 64 20 74 68 65 72 65 66 6f 72 65 20 64   and therefore d
3490: 6f 65 73 20 6e 6f 74 20 64 65 63 6f 64 65 20 69  oes not decode i
34a0: 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 4e 41 4d 45  t..**.** If NAME
34b0: 20 62 65 67 69 6e 73 20 77 69 74 68 20 61 6e 6f   begins with ano
34c0: 74 68 65 72 20 6f 74 68 65 72 20 74 68 61 6e 20  ther other than 
34d0: 61 20 6c 6f 77 65 72 2d 63 61 73 65 20 6c 65 74  a lower-case let
34e0: 74 65 72 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20  ter then.** the 
34f0: 65 6e 74 69 72 65 20 4e 41 4d 45 3d 56 41 4c 55  entire NAME=VALU
3500: 45 20 74 65 72 6d 20 69 73 20 69 67 6e 6f 72 65  E term is ignore
3510: 64 2e 20 20 48 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a  d.  Hence:.**.**
3520: 20 20 20 20 20 20 2a 20 20 63 6f 6f 6b 69 65 73        *  cookies
3530: 20 61 6e 64 20 71 75 65 72 79 20 70 61 72 61 6d   and query param
3540: 65 74 65 72 73 20 74 68 61 74 20 68 61 76 65 20  eters that have 
3550: 75 70 70 65 72 63 61 73 65 20 6e 61 6d 65 73 0a  uppercase names.
3560: 2a 2a 20 20 20 20 20 20 20 20 20 61 72 65 20 69  **         are i
3570: 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20  gnored..**.**   
3580: 20 20 20 2a 20 20 69 74 20 69 73 20 69 6d 70 6f     *  it is impo
3590: 73 73 69 62 6c 65 20 66 6f 72 20 61 20 63 6f 6f  ssible for a coo
35a0: 6b 69 65 20 6f 72 20 71 75 65 72 79 20 70 61 72  kie or query par
35b0: 61 6d 65 74 65 72 20 74 6f 0a 2a 2a 20 20 20 20  ameter to.**    
35c0: 20 20 20 20 20 6f 76 65 72 72 69 64 65 20 74 68       override th
35d0: 65 20 76 61 6c 75 65 20 6f 66 20 61 6e 20 65 6e  e value of an en
35e0: 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62  vironment variab
35f0: 6c 65 20 73 69 6e 63 65 0a 2a 2a 20 20 20 20 20  le since.**     
3600: 20 20 20 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20      environment 
3610: 76 61 72 69 61 62 6c 65 73 20 61 6c 77 61 79 73  variables always
3620: 20 68 61 76 65 20 75 70 70 65 72 63 61 73 65 20   have uppercase 
3630: 6e 61 6d 65 73 2e 0a 2a 2a 0a 2a 2a 20 50 61 72  names..**.** Par
3640: 61 6d 65 74 65 72 73 20 61 72 65 20 73 65 70 61  ameters are sepa
3650: 72 61 74 65 64 20 62 79 20 74 68 65 20 22 74 65  rated by the "te
3660: 72 6d 69 6e 61 74 6f 72 22 20 63 68 61 72 61 63  rminator" charac
3670: 74 65 72 2e 20 20 57 68 69 74 65 73 70 61 63 65  ter.  Whitespace
3680: 0a 2a 2a 20 62 65 66 6f 72 65 20 74 68 65 20 4e  .** before the N
3690: 41 4d 45 20 69 73 20 69 67 6e 6f 72 65 64 2e 0a  AME is ignored..
36a0: 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74 20  **.** The input 
36b0: 73 74 72 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f  string "z" is mo
36c0: 64 69 66 69 65 64 20 62 75 74 20 6e 6f 20 63 6f  dified but no co
36d0: 70 69 65 73 20 69 73 20 6d 61 64 65 2e 20 20 22  pies is made.  "
36e0: 7a 22 0a 2a 2a 20 73 68 6f 75 6c 64 20 6e 6f 74  z".** should not
36f0: 20 62 65 20 64 65 61 6c 6c 6f 63 61 74 65 64 20   be deallocated 
3700: 6f 72 20 63 68 61 6e 67 65 64 20 61 67 61 69 6e  or changed again
3710: 20 61 66 74 65 72 20 74 68 69 73 20 72 6f 75 74   after this rout
3720: 69 6e 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 6f  ine.** returns o
3730: 72 20 69 74 20 77 69 6c 6c 20 63 6f 72 72 75 70  r it will corrup
3740: 74 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 20  t the parameter 
3750: 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63  table..*/.static
3760: 20 76 6f 69 64 20 61 64 64 5f 70 61 72 61 6d 5f   void add_param_
3770: 6c 69 73 74 28 63 68 61 72 20 2a 7a 2c 20 69 6e  list(char *z, in
3780: 74 20 74 65 72 6d 69 6e 61 74 6f 72 29 7b 0a 20  t terminator){. 
3790: 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20   while( *z ){.  
37a0: 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20    char *zName;. 
37b0: 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b     char *zValue;
37c0: 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 70  .    while( issp
37d0: 61 63 65 28 2a 7a 29 20 29 7b 20 7a 2b 2b 3b 20  ace(*z) ){ z++; 
37e0: 7d 0a 20 20 20 20 7a 4e 61 6d 65 20 3d 20 7a 3b  }.    zName = z;
37f0: 0a 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26  .    while( *z &
3800: 26 20 2a 7a 21 3d 27 3d 27 20 26 26 20 2a 7a 21  & *z!='=' && *z!
3810: 3d 74 65 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a  =terminator ){ z
3820: 2b 2b 3b 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a  ++; }.    if( *z
3830: 3d 3d 27 3d 27 20 29 7b 0a 20 20 20 20 20 20 2a  =='=' ){.      *
3840: 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b  z = 0;.      z++
3850: 3b 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d  ;.      zValue =
3860: 20 7a 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28   z;.      while(
3870: 20 2a 7a 20 26 26 20 2a 7a 21 3d 74 65 72 6d 69   *z && *z!=termi
3880: 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a  nator ){ z++; }.
3890: 20 20 20 20 20 20 69 66 28 20 2a 7a 20 29 7b 0a        if( *z ){.
38a0: 20 20 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a          *z = 0;.
38b0: 20 20 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20          z++;.   
38c0: 20 20 20 7d 0a 20 20 20 20 20 20 64 65 68 74 74     }.      dehtt
38d0: 70 69 7a 65 28 7a 56 61 6c 75 65 29 3b 0a 20 20  pize(zValue);.  
38e0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
38f0: 66 28 20 2a 7a 20 29 7b 20 2a 7a 2b 2b 20 3d 20  f( *z ){ *z++ = 
3900: 30 3b 20 7d 0a 20 20 20 20 20 20 7a 56 61 6c 75  0; }.      zValu
3910: 65 20 3d 20 22 22 3b 0a 20 20 20 20 7d 0a 20 20  e = "";.    }.  
3920: 20 20 69 66 28 20 69 73 6c 6f 77 65 72 28 7a 4e    if( islower(zN
3930: 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20  ame[0]) ){.     
3940: 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74   cgi_set_paramet
3950: 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c  er_nocopy(zName,
3960: 20 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d 0a   zValue);.    }.
3970: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 2a 70 7a    }.}../*.** *pz
3980: 20 69 73 20 61 20 73 74 72 69 6e 67 20 74 68 61   is a string tha
3990: 74 20 63 6f 6e 73 69 73 74 73 20 6f 66 20 6d 75  t consists of mu
39a0: 6c 74 69 70 6c 65 20 6c 69 6e 65 73 20 6f 66 20  ltiple lines of 
39b0: 74 65 78 74 2e 20 20 54 68 69 73 0a 2a 2a 20 72  text.  This.** r
39c0: 6f 75 74 69 6e 65 20 66 69 6e 64 73 20 74 68 65  outine finds the
39d0: 20 65 6e 64 20 6f 66 20 74 68 65 20 63 75 72 72   end of the curr
39e0: 65 6e 74 20 6c 69 6e 65 20 6f 66 20 74 65 78 74  ent line of text
39f0: 20 61 6e 64 20 63 6f 6e 76 65 72 74 73 0a 2a 2a   and converts.**
3a00: 20 74 68 65 20 22 5c 6e 22 20 6f 72 20 22 5c 72   the "\n" or "\r
3a10: 5c 6e 22 20 74 68 61 74 20 65 6e 64 73 20 74 68  \n" that ends th
3a20: 61 74 20 6c 69 6e 65 20 69 6e 74 6f 20 61 20 22  at line into a "
3a30: 5c 30 30 30 22 2e 20 20 49 74 20 74 68 65 6e 0a  \000".  It then.
3a40: 2a 2a 20 61 64 76 61 6e 63 65 73 20 2a 70 7a 20  ** advances *pz 
3a50: 74 6f 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67  to the beginning
3a60: 20 6f 66 20 74 68 65 20 6e 65 78 74 20 6c 69 6e   of the next lin
3a70: 65 20 61 6e 64 20 72 65 74 75 72 6e 73 20 74 68  e and returns th
3a80: 65 0a 2a 2a 20 70 72 65 76 69 6f 75 73 20 76 61  e.** previous va
3a90: 6c 75 65 20 6f 66 20 2a 70 7a 20 28 77 68 69 63  lue of *pz (whic
3aa0: 68 20 69 73 20 74 68 65 20 73 74 61 72 74 20 6f  h is the start o
3ab0: 66 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 69  f the current li
3ac0: 6e 65 2e 29 0a 2a 2f 0a 73 74 61 74 69 63 20 63  ne.).*/.static c
3ad0: 68 61 72 20 2a 67 65 74 5f 6c 69 6e 65 5f 66 72  har *get_line_fr
3ae0: 6f 6d 5f 73 74 72 69 6e 67 28 63 68 61 72 20 2a  om_string(char *
3af0: 2a 70 7a 2c 20 69 6e 74 20 2a 70 4c 65 6e 29 7b  *pz, int *pLen){
3b00: 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a  .  char *z = *pz
3b10: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28  ;.  int i;.  if(
3b20: 20 7a 5b 30 5d 3d 3d 30 20 29 20 72 65 74 75 72   z[0]==0 ) retur
3b30: 6e 20 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20  n 0;.  for(i=0; 
3b40: 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20  z[i]; i++){.    
3b50: 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29  if( z[i]=='\n' )
3b60: 7b 0a 20 20 20 20 20 20 69 66 28 20 69 3e 30 20  {.      if( i>0 
3b70: 26 26 20 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20  && z[i-1]=='\r' 
3b80: 29 7b 0a 20 20 20 20 20 20 20 20 7a 5b 69 2d 31  ){.        z[i-1
3b90: 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c  ] = 0;.      }el
3ba0: 73 65 7b 0a 20 20 20 20 20 20 20 20 7a 5b 69 5d  se{.        z[i]
3bb0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20   = 0;.      }.  
3bc0: 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 62      i++;.      b
3bd0: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  reak;.    }.  }.
3be0: 20 20 2a 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20    *pz = &z[i];. 
3bf0: 20 2a 70 4c 65 6e 20 2d 3d 20 69 3b 0a 20 20 72   *pLen -= i;.  r
3c00: 65 74 75 72 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn z;.}../*.*
3c10: 2a 20 54 68 65 20 69 6e 70 75 74 20 2a 70 7a 20  * The input *pz 
3c20: 70 6f 69 6e 74 73 20 74 6f 20 63 6f 6e 74 65 6e  points to conten
3c30: 74 20 74 68 61 74 20 69 73 20 74 65 72 6d 69 6e  t that is termin
3c40: 61 74 65 64 20 62 79 20 61 20 22 5c 72 5c 6e 22  ated by a "\r\n"
3c50: 0a 2a 2a 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20  .** followed by 
3c60: 74 68 65 20 62 6f 75 6e 64 72 79 20 6d 61 72 6b  the boundry mark
3c70: 65 72 20 7a 42 6f 75 6e 64 72 79 2e 20 20 41 6e  er zBoundry.  An
3c80: 20 65 78 74 72 61 20 22 2d 2d 22 20 6d 61 79 20   extra "--" may 
3c90: 6f 72 0a 2a 2a 20 6d 61 79 20 6e 6f 74 20 62 65  or.** may not be
3ca0: 20 61 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65   appended to the
3cb0: 20 62 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 2e   boundry marker.
3cc0: 20 20 54 68 65 72 65 20 61 72 65 20 2a 70 4c 65    There are *pLe
3cd0: 6e 20 63 68 61 72 61 63 74 65 72 73 0a 2a 2a 20  n characters.** 
3ce0: 69 6e 20 2a 70 7a 2e 0a 2a 2a 0a 2a 2a 20 54 68  in *pz..**.** Th
3cf0: 69 73 20 72 6f 75 74 69 6e 65 20 61 64 64 73 20  is routine adds 
3d00: 61 20 22 5c 30 30 30 22 20 74 6f 20 74 68 65 20  a "\000" to the 
3d10: 65 6e 64 20 6f 66 20 74 68 65 20 63 6f 6e 74 65  end of the conte
3d20: 6e 74 20 28 6f 76 65 72 77 72 69 74 69 6e 67 0a  nt (overwriting.
3d30: 2a 2a 20 74 68 65 20 22 5c 72 5c 6e 22 29 20 61  ** the "\r\n") a
3d40: 6e 64 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69  nd returns a poi
3d50: 6e 74 65 72 20 74 6f 20 74 68 65 20 63 6f 6e 74  nter to the cont
3d60: 65 6e 74 2e 20 20 54 68 65 20 2a 70 7a 20 69 6e  ent.  The *pz in
3d70: 70 75 74 0a 2a 2a 20 69 73 20 61 64 6a 75 73 74  put.** is adjust
3d80: 65 64 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74  ed to point to t
3d90: 68 65 20 66 69 72 73 74 20 6c 69 6e 65 20 66 6f  he first line fo
3da0: 6c 6c 6f 77 69 6e 67 20 74 68 65 20 62 6f 75 6e  llowing the boun
3db0: 64 72 79 2e 0a 2a 2a 20 54 68 65 20 6c 65 6e 67  dry..** The leng
3dc0: 74 68 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e  th of the conten
3dd0: 74 20 69 73 20 73 74 6f 72 65 64 20 69 6e 20 2a  t is stored in *
3de0: 70 6e 43 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 73 74  pnContent..*/.st
3df0: 61 74 69 63 20 63 68 61 72 20 2a 67 65 74 5f 62  atic char *get_b
3e00: 6f 75 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28 0a  ounded_content(.
3e10: 20 20 63 68 61 72 20 2a 2a 70 7a 2c 20 20 20 20    char **pz,    
3e20: 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20       /* Content 
3e30: 74 61 6b 65 6e 20 66 72 6f 6d 20 68 65 72 65 20  taken from here 
3e40: 2a 2f 0a 20 20 69 6e 74 20 2a 70 4c 65 6e 2c 20  */.  int *pLen, 
3e50: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65          /* Numbe
3e60: 72 20 6f 66 20 62 79 74 65 73 20 6f 66 20 64 61  r of bytes of da
3e70: 74 61 20 69 6e 20 28 2a 70 7a 29 5b 5d 20 2a 2f  ta in (*pz)[] */
3e80: 0a 20 20 63 68 61 72 20 2a 7a 42 6f 75 6e 64 72  .  char *zBoundr
3e90: 79 2c 20 20 20 20 2f 2a 20 42 6f 75 6e 64 72 79  y,    /* Boundry
3ea0: 20 74 65 78 74 20 6d 61 72 6b 69 6e 67 20 74 68   text marking th
3eb0: 65 20 65 6e 64 20 6f 66 20 63 6f 6e 74 65 6e 74  e end of content
3ec0: 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6e   */.  int *pnCon
3ed0: 74 65 6e 74 20 20 20 20 20 2f 2a 20 57 72 69 74  tent     /* Writ
3ee0: 65 20 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68  e the size of th
3ef0: 65 20 63 6f 6e 74 65 6e 74 20 68 65 72 65 20 2a  e content here *
3f00: 2f 0a 29 7b 0a 20 20 63 68 61 72 20 2a 7a 20 3d  /.){.  char *z =
3f10: 20 2a 70 7a 3b 0a 20 20 69 6e 74 20 6c 65 6e 20   *pz;.  int len 
3f20: 3d 20 2a 70 4c 65 6e 3b 0a 20 20 69 6e 74 20 69  = *pLen;.  int i
3f30: 3b 0a 20 20 69 6e 74 20 6e 42 6f 75 6e 64 72 79  ;.  int nBoundry
3f40: 20 3d 20 73 74 72 6c 65 6e 28 7a 42 6f 75 6e 64   = strlen(zBound
3f50: 72 79 29 3b 0a 20 20 2a 70 6e 43 6f 6e 74 65 6e  ry);.  *pnConten
3f60: 74 20 3d 20 6c 65 6e 3b 0a 20 20 66 6f 72 28 69  t = len;.  for(i
3f70: 3d 30 3b 20 69 3c 6c 65 6e 3b 20 69 2b 2b 29 7b  =0; i<len; i++){
3f80: 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27  .    if( z[i]=='
3f90: 5c 6e 27 20 26 26 20 73 74 72 6e 63 6d 70 28 7a  \n' && strncmp(z
3fa0: 42 6f 75 6e 64 72 79 2c 20 26 7a 5b 69 2b 31 5d  Boundry, &z[i+1]
3fb0: 2c 20 6e 42 6f 75 6e 64 72 79 29 3d 3d 30 20 29  , nBoundry)==0 )
3fc0: 7b 0a 20 20 20 20 20 20 69 66 28 20 69 3e 30 20  {.      if( i>0 
3fd0: 26 26 20 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20  && z[i-1]=='\r' 
3fe0: 29 20 69 2d 2d 3b 0a 20 20 20 20 20 20 7a 5b 69  ) i--;.      z[i
3ff0: 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 2a 70 6e  ] = 0;.      *pn
4000: 43 6f 6e 74 65 6e 74 20 3d 20 69 3b 0a 20 20 20  Content = i;.   
4010: 20 20 20 69 20 2b 3d 20 6e 42 6f 75 6e 64 72 79     i += nBoundry
4020: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20  ;.      break;. 
4030: 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d     }.  }.  *pz =
4040: 20 26 7a 5b 69 5d 3b 0a 20 20 67 65 74 5f 6c 69   &z[i];.  get_li
4050: 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 70  ne_from_string(p
4060: 7a 2c 20 70 4c 65 6e 29 3b 0a 20 20 72 65 74 75  z, pLen);.  retu
4070: 72 6e 20 7a 3b 20 20 20 20 20 20 0a 7d 0a 0a 2f  rn z;      .}../
4080: 2a 0a 2a 2a 20 54 6f 6b 65 6e 69 7a 65 20 61 20  *.** Tokenize a 
4090: 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 69 6e 74  line of text int
40a0: 6f 20 61 73 20 6d 61 6e 79 20 61 73 20 6e 41 72  o as many as nAr
40b0: 67 20 74 6f 6b 65 6e 73 2e 20 20 4d 61 6b 65 0a  g tokens.  Make.
40c0: 2a 2a 20 61 7a 41 72 67 5b 5d 20 70 6f 69 6e 74  ** azArg[] point
40d0: 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66   to the start of
40e0: 20 65 61 63 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a   each token..**.
40f0: 2a 2a 20 54 6f 6b 65 6e 73 20 63 6f 6e 73 69 73  ** Tokens consis
4100: 74 20 6f 66 20 73 70 61 63 65 20 6f 72 20 73 65  t of space or se
4110: 6d 69 2d 63 6f 6c 6f 6e 20 64 65 6c 69 6d 69 74  mi-colon delimit
4120: 65 64 20 77 6f 72 64 73 20 6f 72 0a 2a 2a 20 73  ed words or.** s
4130: 74 72 69 6e 67 73 20 69 6e 73 69 64 65 20 64 6f  trings inside do
4140: 75 62 6c 65 2d 71 75 6f 74 65 73 2e 20 20 45 78  uble-quotes.  Ex
4150: 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20  ample:.**.**    
4160: 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 74  content-disposit
4170: 69 6f 6e 3a 20 66 6f 72 6d 2d 64 61 74 61 3b 20  ion: form-data; 
4180: 6e 61 6d 65 3d 22 66 6e 22 3b 20 66 69 6c 65 6e  name="fn"; filen
4190: 61 6d 65 3d 22 69 6e 64 65 78 2e 68 74 6d 6c 22  ame="index.html"
41a0: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c 69 6e 65 20  .**.** The line 
41b0: 61 62 6f 76 65 20 69 73 20 74 6f 6b 65 6e 69 7a  above is tokeniz
41c0: 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a  ed as follows:.*
41d0: 2a 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 30 5d  *.**    azArg[0]
41e0: 20 3d 20 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70   = "content-disp
41f0: 6f 73 69 74 69 6f 6e 3a 22 0a 2a 2a 20 20 20 20  osition:".**    
4200: 61 7a 41 72 67 5b 31 5d 20 3d 20 22 66 6f 72 6d  azArg[1] = "form
4210: 2d 64 61 74 61 22 0a 2a 2a 20 20 20 20 61 7a 41  -data".**    azA
4220: 72 67 5b 32 5d 20 3d 20 22 6e 61 6d 65 3d 22 0a  rg[2] = "name=".
4230: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 33 5d 20 3d  **    azArg[3] =
4240: 20 22 66 6e 22 0a 2a 2a 20 20 20 20 61 7a 41 72   "fn".**    azAr
4250: 67 5b 34 5d 20 3d 20 22 66 69 6c 65 6e 61 6d 65  g[4] = "filename
4260: 3d 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 35  =".**    azArg[5
4270: 5d 20 3d 20 22 69 6e 64 65 78 2e 68 74 6d 6c 22  ] = "index.html"
4280: 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 36 5d 20  .**    azArg[6] 
4290: 3d 20 30 3b 0a 2a 2a 0a 2a 2a 20 27 5c 30 30 30  = 0;.**.** '\000
42a0: 27 20 63 68 61 72 61 63 74 65 72 73 20 61 72 65  ' characters are
42b0: 20 69 6e 73 65 72 74 65 64 20 69 6e 20 7a 5b 5d   inserted in z[]
42c0: 20 61 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65   at the end of e
42d0: 61 63 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 54 68  ach token..** Th
42e0: 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72  is routine retur
42f0: 6e 73 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d  ns the total num
4300: 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 20 6f 6e  ber of tokens on
4310: 20 74 68 65 20 6c 69 6e 65 2c 20 36 0a 2a 2a 20   the line, 6.** 
4320: 69 6e 20 74 68 65 20 65 78 61 6d 70 6c 65 20 61  in the example a
4330: 62 6f 76 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  bove..*/.static 
4340: 69 6e 74 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e  int tokenize_lin
4350: 65 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6d  e(char *z, int m
4360: 78 41 72 67 2c 20 63 68 61 72 20 2a 2a 61 7a 41  xArg, char **azA
4370: 72 67 29 7b 0a 20 20 69 6e 74 20 69 20 3d 20 30  rg){.  int i = 0
4380: 3b 0a 20 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b  ;.  while( *z ){
4390: 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 70  .    while( issp
43a0: 61 63 65 28 2a 7a 29 20 7c 7c 20 2a 7a 3d 3d 27  ace(*z) || *z=='
43b0: 3b 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20  ;' ){ z++; }.   
43c0: 20 69 66 28 20 2a 7a 3d 3d 27 22 27 20 26 26 20   if( *z=='"' && 
43d0: 7a 5b 31 5d 20 29 7b 0a 20 20 20 20 20 20 2a 7a  z[1] ){.      *z
43e0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b   = 0;.      z++;
43f0: 0a 20 20 20 20 20 20 69 66 28 20 69 3c 6d 78 41  .      if( i<mxA
4400: 72 67 2d 31 20 29 7b 20 61 7a 41 72 67 5b 69 2b  rg-1 ){ azArg[i+
4410: 2b 5d 20 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 20  +] = z; }.      
4420: 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21  while( *z && *z!
4430: 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20  ='"' ){ z++; }. 
4440: 20 20 20 20 20 69 66 28 20 2a 7a 3d 3d 30 20 29       if( *z==0 )
4450: 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 20 2a 7a   break;.      *z
4460: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b   = 0;.      z++;
4470: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
4480: 20 20 69 66 28 20 69 3c 6d 78 41 72 67 2d 31 20    if( i<mxArg-1 
4490: 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20  ){ azArg[i++] = 
44a0: 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68 69 6c 65  z; }.      while
44b0: 28 20 2a 7a 20 26 26 20 21 69 73 73 70 61 63 65  ( *z && !isspace
44c0: 28 2a 7a 29 20 26 26 20 2a 7a 21 3d 27 3b 27 20  (*z) && *z!=';' 
44d0: 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b  && *z!='"' ){ z+
44e0: 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a  +; }.      if( *
44f0: 7a 20 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b 0a  z && *z!='"' ){.
4500: 20 20 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a          *z = 0;.
4510: 20 20 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20          z++;.   
4520: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20     }.    }.  }. 
4530: 20 61 7a 41 72 67 5b 69 5d 20 3d 20 30 3b 0a 20   azArg[i] = 0;. 
4540: 20 72 65 74 75 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a   return i;.}../*
4550: 0a 2a 2a 20 53 63 61 6e 20 74 68 65 20 6d 75 6c  .** Scan the mul
4560: 74 69 70 61 72 74 2d 66 6f 72 6d 20 63 6f 6e 74  tipart-form cont
4570: 65 6e 74 20 61 6e 64 20 6d 61 6b 65 20 61 70 70  ent and make app
4580: 72 6f 70 72 69 61 74 65 20 65 6e 74 72 69 65 73  ropriate entries
4590: 0a 2a 2a 20 69 6e 74 6f 20 74 68 65 20 70 61 72  .** into the par
45a0: 61 6d 65 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2a  ameter table..**
45b0: 0a 2a 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 20  .** The content 
45c0: 73 74 72 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f  string "z" is mo
45d0: 64 69 66 69 65 64 20 62 79 20 74 68 69 73 20 72  dified by this r
45e0: 6f 75 74 69 6e 65 20 62 75 74 20 69 74 20 69 73  outine but it is
45f0: 0a 2a 2a 20 6e 6f 74 20 63 6f 70 69 65 64 2e 20  .** not copied. 
4600: 20 54 68 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e   The calling fun
4610: 63 74 69 6f 6e 20 6d 75 73 74 20 6e 6f 74 20 64  ction must not d
4620: 65 61 6c 6c 6f 63 61 74 65 20 6f 72 20 6d 6f 64  eallocate or mod
4630: 69 66 79 0a 2a 2a 20 22 7a 22 20 61 66 74 65 72  ify.** "z" after
4640: 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 66 69   this routine fi
4650: 6e 69 73 68 65 73 20 6f 72 20 69 74 20 63 6f 75  nishes or it cou
4660: 6c 64 20 63 6f 72 72 75 70 74 20 74 68 65 20 70  ld corrupt the p
4670: 61 72 61 6d 65 74 65 72 0a 2a 2a 20 74 61 62 6c  arameter.** tabl
4680: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  e..*/.static voi
4690: 64 20 70 72 6f 63 65 73 73 5f 6d 75 6c 74 69 70  d process_multip
46a0: 61 72 74 5f 66 6f 72 6d 5f 64 61 74 61 28 63 68  art_form_data(ch
46b0: 61 72 20 2a 7a 2c 20 69 6e 74 20 6c 65 6e 29 7b  ar *z, int len){
46c0: 0a 20 20 63 68 61 72 20 2a 7a 4c 69 6e 65 3b 0a  .  char *zLine;.
46d0: 20 20 69 6e 74 20 6e 41 72 67 2c 20 69 3b 0a 20    int nArg, i;. 
46e0: 20 63 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 3b   char *zBoundry;
46f0: 0a 20 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b  .  char *zValue;
4700: 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d  .  char *zName =
4710: 20 30 3b 0a 20 20 69 6e 74 20 73 68 6f 77 42 79   0;.  int showBy
4720: 74 65 73 20 3d 20 30 3b 0a 20 20 63 68 61 72 20  tes = 0;.  char 
4730: 2a 61 7a 41 72 67 5b 35 30 5d 3b 0a 0a 20 20 7a  *azArg[50];..  z
4740: 42 6f 75 6e 64 72 79 20 3d 20 67 65 74 5f 6c 69  Boundry = get_li
4750: 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 26  ne_from_string(&
4760: 7a 2c 20 26 6c 65 6e 29 3b 0a 20 20 69 66 28 20  z, &len);.  if( 
4770: 7a 42 6f 75 6e 64 72 79 3d 3d 30 20 29 20 72 65  zBoundry==0 ) re
4780: 74 75 72 6e 3b 0a 20 20 77 68 69 6c 65 28 20 28  turn;.  while( (
4790: 7a 4c 69 6e 65 20 3d 20 67 65 74 5f 6c 69 6e 65  zLine = get_line
47a0: 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c  _from_string(&z,
47b0: 20 26 6c 65 6e 29 29 21 3d 30 20 29 7b 0a 20 20   &len))!=0 ){.  
47c0: 20 20 69 66 28 20 7a 4c 69 6e 65 5b 30 5d 3d 3d    if( zLine[0]==
47d0: 30 20 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e  0 ){.      int n
47e0: 43 6f 6e 74 65 6e 74 20 3d 20 30 3b 0a 20 20 20  Content = 0;.   
47f0: 20 20 20 7a 56 61 6c 75 65 20 3d 20 67 65 74 5f     zValue = get_
4800: 62 6f 75 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28  bounded_content(
4810: 26 7a 2c 20 26 6c 65 6e 2c 20 7a 42 6f 75 6e 64  &z, &len, zBound
4820: 72 79 2c 20 26 6e 43 6f 6e 74 65 6e 74 29 3b 0a  ry, &nContent);.
4830: 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20        if( zName 
4840: 26 26 20 7a 56 61 6c 75 65 20 26 26 20 69 73 6c  && zValue && isl
4850: 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29  ower(zName[0]) )
4860: 7b 0a 20 20 20 20 20 20 20 20 63 67 69 5f 73 65  {.        cgi_se
4870: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f  t_parameter_noco
4880: 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65  py(zName, zValue
4890: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 73  );.        if( s
48a0: 68 6f 77 42 79 74 65 73 20 29 7b 0a 20 20 20 20  howBytes ){.    
48b0: 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61        cgi_set_pa
48c0: 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d  rameter_nocopy(m
48d0: 70 72 69 6e 74 66 28 22 25 73 3a 62 79 74 65 73  printf("%s:bytes
48e0: 22 2c 20 7a 4e 61 6d 65 29 2c 0a 20 20 20 20 20  ", zName),.     
48f0: 20 20 20 20 20 20 20 20 20 20 6d 70 72 69 6e 74            mprint
4900: 66 28 22 25 64 22 2c 6e 43 6f 6e 74 65 6e 74 29  f("%d",nContent)
4910: 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20  );.        }.   
4920: 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e 61 6d 65     }.      zName
4930: 20 3d 20 30 3b 0a 20 20 20 20 20 20 73 68 6f 77   = 0;.      show
4940: 42 79 74 65 73 20 3d 20 30 3b 0a 20 20 20 20 7d  Bytes = 0;.    }
4950: 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e 41 72 67  else{.      nArg
4960: 20 3d 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65   = tokenize_line
4970: 28 7a 4c 69 6e 65 2c 20 73 69 7a 65 6f 66 28 61  (zLine, sizeof(a
4980: 7a 41 72 67 29 2f 73 69 7a 65 6f 66 28 61 7a 41  zArg)/sizeof(azA
4990: 72 67 5b 30 5d 29 2c 20 61 7a 41 72 67 29 3b 0a  rg[0]), azArg);.
49a0: 20 20 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69        for(i=0; i
49b0: 3c 6e 41 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20  <nArg; i++){.   
49c0: 20 20 20 20 20 69 6e 74 20 63 20 3d 20 74 6f 6c       int c = tol
49d0: 6f 77 65 72 28 61 7a 41 72 67 5b 69 5d 5b 30 5d  ower(azArg[i][0]
49e0: 29 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 63  );.        if( c
49f0: 3d 3d 27 63 27 20 26 26 20 73 74 72 69 63 6d 70  =='c' && stricmp
4a00: 28 61 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65  (azArg[i],"conte
4a10: 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22  nt-disposition:"
4a20: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20  )==0 ){.        
4a30: 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d    i++;.        }
4a40: 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 6e 27 20  else if( c=='n' 
4a50: 26 26 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67  && stricmp(azArg
4a60: 5b 69 5d 2c 22 6e 61 6d 65 3d 22 29 3d 3d 30 20  [i],"name=")==0 
4a70: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 7a 4e 61  ){.          zNa
4a80: 6d 65 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b  me = azArg[++i];
4a90: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69  .        }else i
4aa0: 66 28 20 63 3d 3d 27 66 27 20 26 26 20 73 74 72  f( c=='f' && str
4ab0: 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 66  icmp(azArg[i],"f
4ac0: 69 6c 65 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b  ilename=")==0 ){
4ad0: 0a 20 20 20 20 20 20 20 20 20 20 63 68 61 72 20  .          char 
4ae0: 2a 7a 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b  *z = azArg[++i];
4af0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 7a  .          if( z
4b00: 4e 61 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c  Name && z && isl
4b10: 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29  ower(zName[0]) )
4b20: 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 67  {.            cg
4b30: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f  i_set_parameter_
4b40: 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22  nocopy(mprintf("
4b50: 25 73 3a 66 69 6c 65 6e 61 6d 65 22 2c 7a 4e 61  %s:filename",zNa
4b60: 6d 65 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20  me), z);.       
4b70: 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 73     }.          s
4b80: 68 6f 77 42 79 74 65 73 20 3d 20 31 3b 0a 20 20  howBytes = 1;.  
4b90: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
4ba0: 63 3d 3d 27 63 27 20 26 26 20 73 74 72 69 63 6d  c=='c' && stricm
4bb0: 70 28 61 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74  p(azArg[i],"cont
4bc0: 65 6e 74 2d 74 79 70 65 3a 22 29 3d 3d 30 20 29  ent-type:")==0 )
4bd0: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 68 61 72  {.          char
4be0: 20 2a 7a 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d   *z = azArg[++i]
4bf0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
4c00: 7a 4e 61 6d 65 20 26 26 20 7a 20 26 26 20 69 73  zName && z && is
4c10: 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20  lower(zName[0]) 
4c20: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 63  ){.            c
4c30: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72  gi_set_parameter
4c40: 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28  _nocopy(mprintf(
4c50: 22 25 73 3a 6d 69 6d 65 74 79 70 65 22 2c 7a 4e  "%s:mimetype",zN
4c60: 61 6d 65 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20  ame), z);.      
4c70: 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a      }.        }.
4c80: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
4c90: 7d 20 20 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a  }        .}../*.
4ca0: 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68  ** Initialize th
4cb0: 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  e query paramete
4cc0: 72 20 64 61 74 61 62 61 73 65 2e 20 20 49 6e 66  r database.  Inf
4cd0: 6f 72 6d 61 74 69 6f 6e 20 69 73 20 70 75 6c 6c  ormation is pull
4ce0: 65 64 20 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 51  ed from.** the Q
4cf0: 55 45 52 59 5f 53 54 52 49 4e 47 20 65 6e 76 69  UERY_STRING envi
4d00: 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65  ronment variable
4d10: 20 28 69 66 20 69 74 20 65 78 69 73 74 73 29 2c   (if it exists),
4d20: 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 0a 2a   from standard.*
4d30: 2a 20 69 6e 70 75 74 20 69 66 20 74 68 65 72 65  * input if there
4d40: 20 69 73 20 50 4f 53 54 20 64 61 74 61 2c 20 61   is POST data, a
4d50: 6e 64 20 66 72 6f 6d 20 48 54 54 50 5f 43 4f 4f  nd from HTTP_COO
4d60: 4b 49 45 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69  KIE..*/.void cgi
4d70: 5f 69 6e 69 74 28 76 6f 69 64 29 7b 0a 20 20 63  _init(void){.  c
4d80: 68 61 72 20 2a 7a 3b 0a 20 20 63 6f 6e 73 74 20  har *z;.  const 
4d90: 63 68 61 72 20 2a 7a 54 79 70 65 3b 0a 20 20 69  char *zType;.  i
4da0: 6e 74 20 6c 65 6e 3b 0a 20 20 63 67 69 5f 64 65  nt len;.  cgi_de
4db0: 73 74 69 6e 61 74 69 6f 6e 28 43 47 49 5f 42 4f  stination(CGI_BO
4dc0: 44 59 29 3b 0a 20 20 7a 20 3d 20 28 63 68 61 72  DY);.  z = (char
4dd0: 2a 29 50 28 22 51 55 45 52 59 5f 53 54 52 49 4e  *)P("QUERY_STRIN
4de0: 47 22 29 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a  G");.  if( z ){.
4df0: 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28      z = mprintf(
4e00: 22 25 73 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64  "%s",z);.    add
4e10: 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27  _param_list(z, '
4e20: 26 27 29 3b 0a 20 20 7d 0a 0a 20 20 6c 65 6e 20  &');.  }..  len 
4e30: 3d 20 61 74 6f 69 28 50 44 28 22 43 4f 4e 54 45  = atoi(PD("CONTE
4e40: 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 22 30 22 29  NT_LENGTH", "0")
4e50: 29 3b 0a 20 20 67 2e 7a 43 6f 6e 74 65 6e 74 54  );.  g.zContentT
4e60: 79 70 65 20 3d 20 7a 54 79 70 65 20 3d 20 50 28  ype = zType = P(
4e70: 22 43 4f 4e 54 45 4e 54 5f 54 59 50 45 22 29 3b  "CONTENT_TYPE");
4e80: 0a 20 20 69 66 28 20 6c 65 6e 3e 30 20 26 26 20  .  if( len>0 && 
4e90: 7a 54 79 70 65 20 29 7b 0a 20 20 20 20 62 6c 6f  zType ){.    blo
4ea0: 62 5f 7a 65 72 6f 28 26 67 2e 63 67 69 49 6e 29  b_zero(&g.cgiIn)
4eb0: 3b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70  ;.    if( strcmp
4ec0: 28 7a 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74  (zType,"applicat
4ed0: 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75  ion/x-www-form-u
4ee0: 72 6c 65 6e 63 6f 64 65 64 22 29 3d 3d 30 20 0a  rlencoded")==0 .
4ef0: 20 20 20 20 20 20 20 20 20 7c 7c 20 73 74 72 6e           || strn
4f00: 63 6d 70 28 7a 54 79 70 65 2c 22 6d 75 6c 74 69  cmp(zType,"multi
4f10: 70 61 72 74 2f 66 6f 72 6d 2d 64 61 74 61 22 2c  part/form-data",
4f20: 31 39 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  19)==0 ){.      
4f30: 7a 20 3d 20 6d 61 6c 6c 6f 63 28 20 6c 65 6e 2b  z = malloc( len+
4f40: 31 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a  1 );.      if( z
4f50: 3d 3d 30 20 29 20 65 78 69 74 28 31 29 3b 0a 20  ==0 ) exit(1);. 
4f60: 20 20 20 20 20 6c 65 6e 20 3d 20 66 72 65 61 64       len = fread
4f70: 28 7a 2c 20 31 2c 20 6c 65 6e 2c 20 67 2e 68 74  (z, 1, len, g.ht
4f80: 74 70 49 6e 29 3b 0a 20 20 20 20 20 20 7a 5b 6c  tpIn);.      z[l
4f90: 65 6e 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69  en] = 0;.      i
4fa0: 66 28 20 7a 54 79 70 65 5b 30 5d 3d 3d 27 61 27  f( zType[0]=='a'
4fb0: 20 29 7b 0a 20 20 20 20 20 20 20 20 61 64 64 5f   ){.        add_
4fc0: 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 26  param_list(z, '&
4fd0: 27 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b  ');.      }else{
4fe0: 0a 20 20 20 20 20 20 20 20 70 72 6f 63 65 73 73  .        process
4ff0: 5f 6d 75 6c 74 69 70 61 72 74 5f 66 6f 72 6d 5f  _multipart_form_
5000: 64 61 74 61 28 7a 2c 20 6c 65 6e 29 3b 0a 20 20  data(z, len);.  
5010: 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 20      }.    }else 
5020: 69 66 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65  if( strcmp(zType
5030: 2c 20 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78  , "application/x
5040: 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 20 29 7b 0a  -fossil")==0 ){.
5050: 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f        blob_read_
5060: 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26 67 2e  from_channel(&g.
5070: 63 67 69 49 6e 2c 20 67 2e 68 74 74 70 49 6e 2c  cgiIn, g.httpIn,
5080: 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 62 6c 6f   len);.      blo
5090: 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26 67 2e  b_uncompress(&g.
50a0: 63 67 69 49 6e 2c 20 26 67 2e 63 67 69 49 6e 29  cgiIn, &g.cgiIn)
50b0: 3b 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68  ;.      /* If th
50c0: 65 20 63 6f 6e 74 65 6e 74 20 74 79 70 65 20 69  e content type i
50d0: 73 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d  s application/x-
50e0: 66 6f 73 73 69 6c 2c 20 74 68 65 6e 20 69 67 6e  fossil, then ign
50f0: 6f 72 65 0a 20 20 20 20 20 20 2a 2a 20 74 68 65  ore.      ** the
5100: 20 70 61 74 68 20 69 6e 20 74 68 65 20 66 69 72   path in the fir
5110: 73 74 20 6c 69 6e 65 20 6f 66 20 74 68 65 20 48  st line of the H
5120: 54 54 50 20 68 65 61 64 65 72 20 61 6e 64 20 61  TTP header and a
5130: 6c 77 61 79 73 0a 20 20 20 20 20 20 2a 2a 20 75  lways.      ** u
5140: 73 65 20 74 68 65 20 2f 78 66 65 72 20 6d 65 74  se the /xfer met
5150: 68 6f 64 20 73 69 6e 63 65 20 74 68 65 20 2f 78  hod since the /x
5160: 66 65 72 20 6d 65 74 68 6f 64 20 69 73 20 74 68  fer method is th
5170: 65 20 6f 6e 6c 79 0a 20 20 20 20 20 20 2a 2a 20  e only.      ** 
5180: 6d 65 74 68 6f 64 20 74 68 61 74 20 75 6e 64 65  method that unde
5190: 72 73 74 61 6e 64 73 20 74 68 65 20 61 70 70 6c  rstands the appl
51a0: 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c  ication/x-fossil
51b0: 20 63 6f 6e 74 65 6e 74 0a 20 20 20 20 20 20 2a   content.      *
51c0: 2a 20 74 79 70 65 2e 0a 20 20 20 20 20 20 2a 2f  * type..      */
51d0: 0a 20 20 20 20 20 20 63 67 69 5f 72 65 70 6c 61  .      cgi_repla
51e0: 63 65 5f 70 61 72 61 6d 65 74 65 72 28 22 50 41  ce_parameter("PA
51f0: 54 48 5f 49 4e 46 4f 22 2c 20 22 2f 78 66 65 72  TH_INFO", "/xfer
5200: 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  ");.    }else if
5210: 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20  ( strcmp(zType, 
5220: 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66  "application/x-f
5230: 6f 73 73 69 6c 2d 64 65 62 75 67 22 29 3d 3d 30  ossil-debug")==0
5240: 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72   ){.      blob_r
5250: 65 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c  ead_from_channel
5260: 28 26 67 2e 63 67 69 49 6e 2c 20 67 2e 68 74 74  (&g.cgiIn, g.htt
5270: 70 49 6e 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20  pIn, len);.     
5280: 20 63 67 69 5f 72 65 70 6c 61 63 65 5f 70 61 72   cgi_replace_par
5290: 61 6d 65 74 65 72 28 22 50 41 54 48 5f 49 4e 46  ameter("PATH_INF
52a0: 4f 22 2c 20 22 2f 78 66 65 72 22 29 3b 20 20 2f  O", "/xfer");  /
52b0: 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74 20 61 62  * See comment ab
52c0: 6f 76 65 20 2a 2f 0a 20 20 20 20 7d 0a 20 20 7d  ove */.    }.  }
52d0: 0a 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 50  ..  z = (char*)P
52e0: 28 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 29 3b  ("HTTP_COOKIE");
52f0: 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 20 20  .  if( z ){.    
5300: 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22  z = mprintf("%s"
5310: 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 61 72  ,z);.    add_par
5320: 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 3b 27 29 3b  am_list(z, ';');
5330: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  .  }.}../*.** Th
5340: 69 73 20 69 73 20 74 68 65 20 63 6f 6d 70 61 72  is is the compar
5350: 69 73 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 75 73  ison function us
5360: 65 64 20 74 6f 20 73 6f 72 74 20 74 68 65 20 61  ed to sort the a
5370: 50 61 72 61 6d 51 50 5b 5d 20 61 72 72 61 79 20  ParamQP[] array 
5380: 6f 66 0a 2a 2a 20 71 75 65 72 79 20 70 61 72 61  of.** query para
5390: 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69  meters and cooki
53a0: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  es..*/.static in
53b0: 74 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72 65  t qparam_compare
53c0: 28 63 6f 6e 73 74 20 76 6f 69 64 20 2a 61 2c 20  (const void *a, 
53d0: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 62 29 7b 0a  const void *b){.
53e0: 20 20 73 74 72 75 63 74 20 51 50 61 72 61 6d 20    struct QParam 
53f0: 2a 70 41 20 3d 20 28 73 74 72 75 63 74 20 51 50  *pA = (struct QP
5400: 61 72 61 6d 2a 29 61 3b 0a 20 20 73 74 72 75 63  aram*)a;.  struc
5410: 74 20 51 50 61 72 61 6d 20 2a 70 42 20 3d 20 28  t QParam *pB = (
5420: 73 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29 62  struct QParam*)b
5430: 3b 0a 20 20 69 6e 74 20 63 3b 0a 20 20 63 20 3d  ;.  int c;.  c =
5440: 20 73 74 72 63 6d 70 28 70 41 2d 3e 7a 4e 61 6d   strcmp(pA->zNam
5450: 65 2c 20 70 42 2d 3e 7a 4e 61 6d 65 29 3b 0a 20  e, pB->zName);. 
5460: 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20   if( c==0 ){.   
5470: 20 63 20 3d 20 70 41 2d 3e 73 65 71 20 2d 20 70   c = pA->seq - p
5480: 42 2d 3e 73 65 71 3b 0a 20 20 7d 0a 20 20 72 65  B->seq;.  }.  re
5490: 74 75 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn c;.}../*.**
54a0: 20 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75   Return the valu
54b0: 65 20 6f 66 20 61 20 71 75 65 72 79 20 70 61 72  e of a query par
54c0: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65  ameter or cookie
54d0: 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 73 20 7a   whose name is z
54e0: 4e 61 6d 65 2e 0a 2a 2a 20 49 66 20 74 68 65 72  Name..** If ther
54f0: 65 20 69 73 20 6e 6f 20 71 75 65 72 79 20 70 61  e is no query pa
5500: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69  rameter or cooki
5510: 65 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 61 6e  e named zName an
5520: 64 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20 63  d the first.** c
5530: 68 61 72 61 63 74 65 72 20 6f 66 20 7a 4e 61 6d  haracter of zNam
5540: 65 20 69 73 20 75 70 70 65 72 63 61 73 65 2c 20  e is uppercase, 
5550: 74 68 65 6e 20 63 68 65 63 6b 20 74 6f 20 73 65  then check to se
5560: 65 20 69 66 20 74 68 65 72 65 20 69 73 20 61 6e  e if there is an
5570: 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20  .** environment 
5580: 76 61 72 69 61 62 6c 65 20 62 79 20 74 68 61 74  variable by that
5590: 20 6e 61 6d 65 20 61 6e 64 20 72 65 74 75 72 6e   name and return
55a0: 20 69 74 20 69 66 20 74 68 65 72 65 20 69 73 2e   it if there is.
55b0: 20 20 41 73 0a 2a 2a 20 61 20 6c 61 73 74 20 72    As.** a last r
55c0: 65 73 6f 72 74 20 77 68 65 6e 20 6e 6f 74 68 69  esort when nothi
55d0: 6e 67 20 65 6c 73 65 20 6d 61 74 63 68 65 73 2c  ng else matches,
55e0: 20 72 65 74 75 72 6e 20 7a 44 65 66 61 75 6c 74   return zDefault
55f0: 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20  ..*/.const char 
5600: 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 63  *cgi_parameter(c
5610: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
5620: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44  , const char *zD
5630: 65 66 61 75 6c 74 29 7b 0a 20 20 69 6e 74 20 6c  efault){.  int l
5640: 6f 2c 20 68 69 2c 20 6d 69 64 2c 20 63 3b 0a 0a  o, hi, mid, c;..
5650: 20 20 2f 2a 20 54 68 65 20 73 6f 72 74 51 50 20    /* The sortQP 
5660: 66 6c 61 67 20 69 73 20 73 65 74 20 77 68 65 6e  flag is set when
5670: 65 76 65 72 20 61 20 6e 65 77 20 71 75 65 72 79  ever a new query
5680: 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 69 6e   parameter is in
5690: 73 65 72 74 65 64 2e 0a 20 20 2a 2a 20 49 74 20  serted..  ** It 
56a0: 69 6e 64 69 63 61 74 65 73 20 74 68 61 74 20 77  indicates that w
56b0: 65 20 6e 65 65 64 20 74 6f 20 72 65 73 6f 72 74  e need to resort
56c0: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   the query param
56d0: 65 74 65 72 73 2e 0a 20 20 2a 2f 0a 20 20 69 66  eters..  */.  if
56e0: 28 20 73 6f 72 74 51 50 20 29 7b 0a 20 20 20 20  ( sortQP ){.    
56f0: 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 20 20 71 73  int i, j;.    qs
5700: 6f 72 74 28 61 50 61 72 61 6d 51 50 2c 20 6e 55  ort(aParamQP, nU
5710: 73 65 64 51 50 2c 20 73 69 7a 65 6f 66 28 61 50  sedQP, sizeof(aP
5720: 61 72 61 6d 51 50 5b 30 5d 29 2c 20 71 70 61 72  aramQP[0]), qpar
5730: 61 6d 5f 63 6f 6d 70 61 72 65 29 3b 0a 20 20 20  am_compare);.   
5740: 20 73 6f 72 74 51 50 20 3d 20 30 3b 0a 20 20 20   sortQP = 0;.   
5750: 20 2f 2a 20 41 66 74 65 72 20 73 6f 72 74 69 6e   /* After sortin
5760: 67 2c 20 72 65 6d 6f 76 65 20 64 75 70 6c 69 63  g, remove duplic
5770: 61 74 65 20 70 61 72 61 6d 65 74 65 72 73 2e 20  ate parameters. 
5780: 20 54 68 65 20 73 65 63 6f 6e 64 61 72 79 20 73   The secondary s
5790: 6f 72 74 0a 20 20 20 20 2a 2a 20 6b 65 79 20 69  ort.    ** key i
57a0: 73 20 61 50 61 72 61 6d 51 50 5b 5d 2e 73 65 71  s aParamQP[].seq
57b0: 20 61 6e 64 20 77 65 20 6b 65 65 70 20 74 68 65   and we keep the
57c0: 20 66 69 72 73 74 20 65 6e 74 72 79 2e 20 20 54   first entry.  T
57d0: 68 61 74 20 6d 65 61 6e 73 0a 20 20 20 20 2a 2a  hat means.    **
57e0: 20 77 69 74 68 20 64 75 70 6c 69 63 61 74 65 20   with duplicate 
57f0: 63 61 6c 6c 73 20 74 6f 20 63 67 69 5f 73 65 74  calls to cgi_set
5800: 5f 70 61 72 61 6d 65 74 65 72 28 29 20 74 68 65  _parameter() the
5810: 20 73 65 63 6f 6e 64 20 61 6e 64 0a 20 20 20 20   second and.    
5820: 2a 2a 20 73 75 62 73 65 71 75 65 6e 74 20 63 61  ** subsequent ca
5830: 6c 6c 73 20 61 72 65 20 65 66 66 65 63 74 69 76  lls are effectiv
5840: 65 6c 79 20 6e 6f 2d 6f 70 73 2e 20 2a 2f 0a 20  ely no-ops. */. 
5850: 20 20 20 66 6f 72 28 69 3d 6a 3d 31 3b 20 69 3c     for(i=j=1; i<
5860: 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20  nUsedQP; i++){. 
5870: 20 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28       if( strcmp(
5880: 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d  aParamQP[i].zNam
5890: 65 2c 61 50 61 72 61 6d 51 50 5b 69 2d 31 5d 2e  e,aParamQP[i-1].
58a0: 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20  zName)==0 ){.   
58b0: 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20       continue;. 
58c0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28       }.      if(
58d0: 20 6a 3c 69 20 29 7b 0a 20 20 20 20 20 20 20 20   j<i ){.        
58e0: 6d 65 6d 63 70 79 28 26 61 50 61 72 61 6d 51 50  memcpy(&aParamQP
58f0: 5b 6a 5d 2c 20 26 61 50 61 72 61 6d 51 50 5b 69  [j], &aParamQP[i
5900: 5d 2c 20 73 69 7a 65 6f 66 28 61 50 61 72 61 6d  ], sizeof(aParam
5910: 51 50 5b 6a 5d 29 29 3b 0a 20 20 20 20 20 20 7d  QP[j]));.      }
5920: 0a 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 20 20 20  .      j++;.    
5930: 7d 0a 20 20 20 20 6e 55 73 65 64 51 50 20 3d 20  }.    nUsedQP = 
5940: 6a 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 6f 20  j;.  }..  /* Do 
5950: 61 20 62 69 6e 61 72 79 20 73 65 61 72 63 68 20  a binary search 
5960: 66 6f 72 20 61 20 6d 61 74 63 68 69 6e 67 20 71  for a matching q
5970: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 2a  uery parameter *
5980: 2f 0a 20 20 6c 6f 20 3d 20 30 3b 0a 20 20 68 69  /.  lo = 0;.  hi
5990: 20 3d 20 6e 55 73 65 64 51 50 2d 31 3b 0a 20 20   = nUsedQP-1;.  
59a0: 77 68 69 6c 65 28 20 6c 6f 3c 3d 68 69 20 29 7b  while( lo<=hi ){
59b0: 0a 20 20 20 20 6d 69 64 20 3d 20 28 6c 6f 2b 68  .    mid = (lo+h
59c0: 69 29 2f 32 3b 0a 20 20 20 20 63 20 3d 20 73 74  i)/2;.    c = st
59d0: 72 63 6d 70 28 61 50 61 72 61 6d 51 50 5b 6d 69  rcmp(aParamQP[mi
59e0: 64 5d 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 29  d].zName, zName)
59f0: 3b 0a 20 20 20 20 69 66 28 20 63 3d 3d 30 20 29  ;.    if( c==0 )
5a00: 7b 0a 20 20 20 20 20 20 43 47 49 44 45 42 55 47  {.      CGIDEBUG
5a10: 28 28 22 6d 65 6d 2d 6d 61 74 63 68 20 5b 25 73  (("mem-match [%s
5a20: 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61  ] = [%s]\n", zNa
5a30: 6d 65 2c 20 61 50 61 72 61 6d 51 50 5b 6d 69 64  me, aParamQP[mid
5a40: 5d 2e 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20  ].zValue));.    
5a50: 20 20 72 65 74 75 72 6e 20 61 50 61 72 61 6d 51    return aParamQ
5a60: 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 3b 0a 20  P[mid].zValue;. 
5a70: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3e 30     }else if( c>0
5a80: 20 29 7b 0a 20 20 20 20 20 20 68 69 20 3d 20 6d   ){.      hi = m
5a90: 69 64 2d 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b  id-1;.    }else{
5aa0: 0a 20 20 20 20 20 20 6c 6f 20 3d 20 6d 69 64 2b  .      lo = mid+
5ab0: 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20  1;.    }.  }..  
5ac0: 2f 2a 20 49 66 20 6e 6f 20 6d 61 74 63 68 20 69  /* If no match i
5ad0: 73 20 66 6f 75 6e 64 20 61 6e 64 20 74 68 65 20  s found and the 
5ae0: 6e 61 6d 65 20 62 65 67 69 6e 73 20 77 69 74 68  name begins with
5af0: 20 61 6e 20 75 70 70 65 72 2d 63 61 73 65 0a 20   an upper-case. 
5b00: 20 2a 2a 20 6c 65 74 74 65 72 2c 20 74 68 65 6e   ** letter, then
5b10: 20 63 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66   check to see if
5b20: 20 74 68 65 72 65 20 69 73 20 61 6e 20 65 6e 76   there is an env
5b30: 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c  ironment variabl
5b40: 65 0a 20 20 2a 2a 20 77 69 74 68 20 74 68 65 20  e.  ** with the 
5b50: 67 69 76 65 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f  given name..  */
5b60: 0a 20 20 69 66 28 20 69 73 75 70 70 65 72 28 7a  .  if( isupper(z
5b70: 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20  Name[0]) ){.    
5b80: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
5b90: 75 65 20 3d 20 67 65 74 65 6e 76 28 7a 4e 61 6d  ue = getenv(zNam
5ba0: 65 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c  e);.    if( zVal
5bb0: 75 65 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  ue ){.      cgi_
5bc0: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
5bd0: 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c  copy(zName, zVal
5be0: 75 65 29 3b 0a 20 20 20 20 20 20 43 47 49 44 45  ue);.      CGIDE
5bf0: 42 55 47 28 28 22 65 6e 76 2d 6d 61 74 63 68 20  BUG(("env-match 
5c00: 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20  [%s] = [%s]\n", 
5c10: 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 29 3b  zName, zValue));
5c20: 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 7a 56  .      return zV
5c30: 61 6c 75 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a  alue;.    }.  }.
5c40: 20 20 43 47 49 44 45 42 55 47 28 28 22 6e 6f 2d    CGIDEBUG(("no-
5c50: 6d 61 74 63 68 20 5b 25 73 5d 5c 6e 22 2c 20 7a  match [%s]\n", z
5c60: 4e 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72 6e  Name));.  return
5c70: 20 7a 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a 2f 2a   zDefault;.}../*
5c80: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e  .** Return the n
5c90: 61 6d 65 20 6f 66 20 74 68 65 20 69 2d 74 68 20  ame of the i-th 
5ca0: 43 47 49 20 70 61 72 61 6d 65 74 65 72 2e 20 20  CGI parameter.  
5cb0: 52 65 74 75 72 6e 20 4e 55 4c 4c 20 69 66 20 74  Return NULL if t
5cc0: 68 65 72 65 0a 2a 2a 20 61 72 65 20 66 65 77 65  here.** are fewe
5cd0: 72 20 74 68 61 6e 20 69 20 72 65 67 69 73 74 65  r than i registe
5ce0: 72 65 64 20 43 47 49 20 70 61 72 6d 61 65 74 65  red CGI parmaete
5cf0: 72 73 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61  rs..*/.const cha
5d00: 72 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72  r *cgi_parameter
5d10: 5f 6e 61 6d 65 28 69 6e 74 20 69 29 7b 0a 20 20  _name(int i){.  
5d20: 69 66 28 20 69 3e 3d 30 20 26 26 20 69 3c 6e 55  if( i>=0 && i<nU
5d30: 73 65 64 51 50 20 29 7b 0a 20 20 20 20 72 65 74  sedQP ){.    ret
5d40: 75 72 6e 20 61 50 61 72 61 6d 51 50 5b 69 5d 2e  urn aParamQP[i].
5d50: 7a 4e 61 6d 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a  zName;.  }else{.
5d60: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
5d70: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74  }.}../*.** Print
5d80: 20 43 47 49 20 64 65 62 75 67 67 69 6e 67 20 6d   CGI debugging m
5d90: 65 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64  essages..*/.void
5da0: 20 63 67 69 5f 64 65 62 75 67 28 63 6f 6e 73 74   cgi_debug(const
5db0: 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20   char *zFormat, 
5dc0: 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20  ...){.  va_list 
5dd0: 61 70 3b 0a 20 20 69 66 28 20 67 2e 66 44 65 62  ap;.  if( g.fDeb
5de0: 75 67 20 29 7b 0a 20 20 20 20 76 61 5f 73 74 61  ug ){.    va_sta
5df0: 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b  rt(ap, zFormat);
5e00: 0a 20 20 20 20 76 66 70 72 69 6e 74 66 28 67 2e  .    vfprintf(g.
5e10: 66 44 65 62 75 67 2c 20 7a 46 6f 72 6d 61 74 2c  fDebug, zFormat,
5e20: 20 61 70 29 3b 0a 20 20 20 20 76 61 5f 65 6e 64   ap);.    va_end
5e30: 28 61 70 29 3b 0a 20 20 20 20 66 66 6c 75 73 68  (ap);.    fflush
5e40: 28 67 2e 66 44 65 62 75 67 29 3b 0a 20 20 7d 0a  (g.fDebug);.  }.
5e50: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20  }../*.** Return 
5e60: 74 72 75 65 20 69 66 20 61 6e 79 20 6f 66 20 74  true if any of t
5e70: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74  he query paramet
5e80: 65 72 73 20 69 6e 20 74 68 65 20 61 72 67 75 6d  ers in the argum
5e90: 65 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 72 65 20  ent.** list are 
5ea0: 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20  defined..*/.int 
5eb0: 63 67 69 5f 61 6e 79 28 63 6f 6e 73 74 20 63 68  cgi_any(const ch
5ec0: 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 76  ar *z, ...){.  v
5ed0: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61  a_list ap;.  cha
5ee0: 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 67 69  r *z2;.  if( cgi
5ef0: 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 29 21  _parameter(z,0)!
5f00: 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20  =0 ) return 1;. 
5f10: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 29   va_start(ap, z)
5f20: 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 20 3d  ;.  while( (z2 =
5f30: 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72   va_arg(ap, char
5f40: 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66  *))!=0 ){.    if
5f50: 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28  ( cgi_parameter(
5f60: 7a 32 2c 30 29 21 3d 30 20 29 20 72 65 74 75 72  z2,0)!=0 ) retur
5f70: 6e 20 31 3b 0a 20 20 7d 0a 20 20 76 61 5f 65 6e  n 1;.  }.  va_en
5f80: 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72 6e 20  d(ap);.  return 
5f90: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75  0;.}../*.** Retu
5fa0: 72 6e 20 74 72 75 65 20 69 66 20 61 6c 6c 20 6f  rn true if all o
5fb0: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  f the query para
5fc0: 6d 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72  meters in the ar
5fd0: 67 75 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a 20 61  gument list.** a
5fe0: 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69  re defined..*/.i
5ff0: 6e 74 20 63 67 69 5f 61 6c 6c 28 63 6f 6e 73 74  nt cgi_all(const
6000: 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a   char *z, ...){.
6010: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20    va_list ap;.  
6020: 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20  char *z2;.  if( 
6030: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c  cgi_parameter(z,
6040: 30 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30  0)==0 ) return 0
6050: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c  ;.  va_start(ap,
6060: 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a   z);.  while( (z
6070: 32 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63  2 = va_arg(ap, c
6080: 68 61 72 2a 29 29 3d 3d 30 20 29 7b 0a 20 20 20  har*))==0 ){.   
6090: 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74   if( cgi_paramet
60a0: 65 72 28 7a 32 2c 30 29 3d 3d 30 20 29 20 72 65  er(z2,0)==0 ) re
60b0: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 76 61  turn 0;.  }.  va
60c0: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75  _end(ap);.  retu
60d0: 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50  rn 1;.}../*.** P
60e0: 72 69 6e 74 20 61 6c 6c 20 71 75 65 72 79 20 70  rint all query p
60f0: 61 72 61 6d 65 74 65 72 73 20 6f 6e 20 73 74 61  arameters on sta
6100: 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 20 20 46  ndard output.  F
6110: 6f 72 6d 61 74 20 74 68 65 0a 2a 2a 20 70 61 72  ormat the.** par
6120: 61 6d 65 74 65 72 73 20 61 73 20 48 54 4d 4c 2e  ameters as HTML.
6130: 20 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66    This is used f
6140: 6f 72 20 74 65 73 74 69 6e 67 20 61 6e 64 20 64  or testing and d
6150: 65 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76 6f 69  ebugging..*/.voi
6160: 64 20 63 67 69 5f 70 72 69 6e 74 5f 61 6c 6c 28  d cgi_print_all(
6170: 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a  void){.  int i;.
6180: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28    cgi_parameter(
6190: 22 22 2c 22 22 29 3b 20 20 2f 2a 20 46 6f 72 63  "","");  /* Forc
61a0: 65 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 73  e the parameters
61b0: 20 69 6e 74 6f 20 73 6f 72 74 65 64 20 6f 72 64   into sorted ord
61c0: 65 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b  er */.  for(i=0;
61d0: 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29   i<nUsedQP; i++)
61e0: 7b 0a 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66  {.    cgi_printf
61f0: 28 22 25 73 20 3d 20 25 73 20 20 3c 62 72 20 2f  ("%s = %s  <br /
6200: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 68 74 6d  >\n",.       htm
6210: 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d  lize(aParamQP[i]
6220: 2e 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 68 74 6d  .zName, -1), htm
6230: 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d  lize(aParamQP[i]
6240: 2e 7a 56 61 6c 75 65 2c 20 2d 31 29 29 3b 0a 20  .zValue, -1));. 
6250: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74   }.}../*.** Writ
6260: 65 20 48 54 4d 4c 20 74 65 78 74 20 66 6f 72 20  e HTML text for 
6270: 61 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 74  an option menu t
6280: 6f 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75  o standard outpu
6290: 74 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a 20 69 73  t.  zParam.** is
62a0: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   the query param
62b0: 65 74 65 72 20 74 68 61 74 20 74 68 65 20 6f 70  eter that the op
62c0: 74 69 6f 6e 20 6d 65 6e 75 20 73 65 74 73 2e 20  tion menu sets. 
62d0: 20 7a 44 66 6c 74 20 69 73 20 74 68 65 0a 2a 2a   zDflt is the.**
62e0: 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 20 6f   initial value o
62f0: 66 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65 6e  f the option men
6300: 75 2e 20 20 41 64 64 69 74 69 6f 6e 20 61 72 67  u.  Addition arg
6310: 75 6d 65 6e 74 73 20 61 72 65 20 6e 61 6d 65 2f  uments are name/
6320: 76 61 6c 75 65 0a 2a 2a 20 70 61 69 72 73 20 74  value.** pairs t
6330: 68 61 74 20 64 65 66 69 6e 65 20 76 61 6c 75 65  hat define value
6340: 73 20 6f 6e 20 74 68 65 20 6d 65 6e 75 2e 20 20  s on the menu.  
6350: 54 68 65 20 6c 69 73 74 20 69 73 20 74 65 72 6d  The list is term
6360: 69 6e 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 61  inated with.** a
6370: 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 61 72 67   single NULL arg
6380: 75 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63  ument..*/.void c
6390: 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 69 6e  gi_optionmenu(in
63a0: 74 20 69 6e 2c 20 63 6f 6e 73 74 20 63 68 61 72  t in, const char
63b0: 20 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 68 61 72   *zP, const char
63c0: 20 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61   *zD, ...){.  va
63d0: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72  _list ap;.  char
63e0: 20 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c 3b 0a   *zName, *zVal;.
63f0: 20 20 69 6e 74 20 64 66 6c 74 53 65 65 6e 20 3d    int dfltSeen =
6400: 20 30 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66   0;.  cgi_printf
6410: 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a  ("%*s<select siz
6420: 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e  e=1 name=\"%s\">
6430: 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29  \n", in, "", zP)
6440: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c  ;.  va_start(ap,
6450: 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28   zD);.  while( (
6460: 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61  zName = va_arg(a
6470: 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26  p, char*))!=0 &&
6480: 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28   (zVal = va_arg(
6490: 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29  ap, char*))!=0 )
64a0: 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70  {.    if( strcmp
64b0: 28 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 29 7b 20  (zVal,zD)==0 ){ 
64c0: 64 66 6c 74 53 65 65 6e 20 3d 20 31 3b 20 62 72  dfltSeen = 1; br
64d0: 65 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76 61 5f  eak; }.  }.  va_
64e0: 65 6e 64 28 61 70 29 3b 0a 20 20 69 66 28 20 21  end(ap);.  if( !
64f0: 64 66 6c 74 53 65 65 6e 20 29 7b 0a 20 20 20 20  dfltSeen ){.    
6500: 69 66 28 20 7a 44 5b 30 5d 20 29 7b 0a 20 20 20  if( zD[0] ){.   
6510: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25     cgi_printf("%
6520: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d  *s<option value=
6530: 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e  \"%h\" selected>
6540: 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a  %h</option>\n",.
6550: 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22          in+2, ""
6560: 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d  , zD, zD);.    }
6570: 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f  else{.      cgi_
6580: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69  printf("%*s<opti
6590: 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65  on value=\"\" se
65a0: 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f  lected>&nbsp;</o
65b0: 70 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b 32 2c  ption>\n", in+2,
65c0: 20 22 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a   "");.    }.  }.
65d0: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a    va_start(ap, z
65e0: 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4e  D);.  while( (zN
65f0: 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70 2c  ame = va_arg(ap,
6600: 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20 28   char*))!=0 && (
6610: 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70  zVal = va_arg(ap
6620: 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a  , char*))!=0 ){.
6630: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d      if( zName[0]
6640: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72   ){.      cgi_pr
6650: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e  intf("%*s<option
6660: 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e   value=\"%h\"%s>
6670: 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a  %h</option>\n",.
6680: 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22          in+2, ""
6690: 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a  ,.        zVal,.
66a0: 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a          strcmp(z
66b0: 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20  Val, zD) ? "" : 
66c0: 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 20 20  " selected",.   
66d0: 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 20 20       zName.     
66e0: 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20   );.    }else{. 
66f0: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28       cgi_printf(
6700: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75  "%*s<option valu
6710: 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b 3c  e=\"\"%s>&nbsp;<
6720: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20  /option>\n",.   
6730: 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20       in+2, "",. 
6740: 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56         strcmp(zV
6750: 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22  al, zD) ? "" : "
6760: 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 20 20   selected".     
6770: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20   );.    }.  }.  
6780: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63 67  va_end(ap);.  cg
6790: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73  i_printf("%*s</s
67a0: 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22  elect>\n", in, "
67b0: 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  ");.}../*.** Thi
67c0: 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20  s routine works 
67d0: 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69 5f 6f  a lot like cgi_o
67e0: 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65  ptionmenu() exce
67f0: 70 74 20 74 68 61 74 20 74 68 65 20 6c 69 73 74  pt that the list
6800: 20 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 20 69 73   of.** values is
6810: 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 61 6e   contained in an
6820: 20 61 72 72 61 79 2e 20 20 41 6c 73 6f 2c 20 74   array.  Also, t
6830: 68 65 20 76 61 6c 75 65 73 20 61 72 65 20 6a 75  he values are ju
6840: 73 74 20 76 61 6c 75 65 73 2c 20 6e 6f 74 0a 2a  st values, not.*
6850: 2a 20 6e 61 6d 65 2f 76 61 6c 75 65 20 70 61 69  * name/value pai
6860: 72 73 20 61 73 20 69 6e 20 63 67 69 5f 6f 70 74  rs as in cgi_opt
6870: 69 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f 69 64  ionmenu..*/.void
6880: 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e   cgi_v_optionmen
6890: 75 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20 20  u(.  int in,    
68a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64            /* Ind
68b0: 65 6e 74 20 62 79 20 74 68 69 73 20 61 6d 6f 75  ent by this amou
68c0: 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  nt */.  const ch
68d0: 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a 20  ar *zP,      /* 
68e0: 54 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65  The query parame
68f0: 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f  ter name */.  co
6900: 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 20 20  nst char *zD,   
6910: 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 76 61     /* Default va
6920: 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63  lue */.  const c
6930: 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f 2a  har **az      /*
6940: 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 64   NULL-terminated
6950: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65 64   list of allowed
6960: 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 20   values */.){.  
6970: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
6980: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69  ;.  int i;.  cgi
6990: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c  _printf("%*s<sel
69a0: 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d  ect size=1 name=
69b0: 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20  \"%s\">\n", in, 
69c0: 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28 69  "", zP);.  for(i
69d0: 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b 29 7b  =0; az[i]; i++){
69e0: 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28  .    if( strcmp(
69f0: 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20 62  az[i],zD)==0 ) b
6a00: 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20  reak;.  }.  if( 
6a10: 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20  az[i]==0 ){.    
6a20: 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b 0a  if( zD[0]==0 ){.
6a30: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66        cgi_printf
6a40: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c  ("%*s<option val
6a50: 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64  ue=\"\" selected
6a60: 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e  >&nbsp;</option>
6a70: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32  \n",.       in+2
6a80: 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65  , "");.    }else
6a90: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e  {.      cgi_prin
6aa0: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76  tf("%*s<option v
6ab0: 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65  alue=\"%h\" sele
6ac0: 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e  cted>%h</option>
6ad0: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32  \n",.       in+2
6ae0: 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20  , "", zD, zD);. 
6af0: 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65     }.  }.  while
6b00: 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b 2b  ( (zVal = *(az++
6b10: 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 69 66  ))!=0  ){.    if
6b20: 28 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20 20 20  ( zVal[0] ){.   
6b30: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25     cgi_printf("%
6b40: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d  *s<option value=
6b50: 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74  \"%h\"%s>%h</opt
6b60: 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20  ion>\n",.       
6b70: 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20   in+2, "",.     
6b80: 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20     zVal,.       
6b90: 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44   strcmp(zVal, zD
6ba0: 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63  ) ? "" : " selec
6bb0: 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a 56  ted",.        zV
6bc0: 61 6c 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  al.      );.    
6bd0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69  }else{.      cgi
6be0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74  _printf("%*s<opt
6bf0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25 73  ion value=\"\"%s
6c00: 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e  >&nbsp;</option>
6c10: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b  \n",.        in+
6c20: 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 73  2, "",.        s
6c30: 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20  trcmp(zVal, zD) 
6c40: 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65  ? "" : " selecte
6c50: 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20  d".      );.    
6c60: 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e  }.  }.  cgi_prin
6c70: 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e  tf("%*s</select>
6c80: 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a  \n", in, "");.}.
6c90: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  ./*.** This rout
6ca0: 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74 20  ine works a lot 
6cb0: 6c 69 6b 65 20 63 67 69 5f 76 5f 6f 70 74 69 6f  like cgi_v_optio
6cc0: 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 74 20 74  nmenu() except t
6cd0: 68 61 74 20 74 68 65 20 6c 69 73 74 0a 2a 2a 20  hat the list.** 
6ce0: 69 73 20 61 20 6c 69 73 74 20 6f 66 20 70 61 69  is a list of pai
6cf0: 72 73 2e 20 20 54 68 65 20 66 69 72 73 74 20 65  rs.  The first e
6d00: 6c 65 6d 65 6e 74 20 6f 66 20 65 61 63 68 20 70  lement of each p
6d10: 61 69 72 20 69 73 20 74 68 65 20 76 61 6c 75 65  air is the value
6d20: 20 75 73 65 64 0a 2a 2a 20 69 6e 74 65 72 6e 61   used.** interna
6d30: 6c 6c 79 20 61 6e 64 20 74 68 65 20 73 65 63 6f  lly and the seco
6d40: 6e 64 20 65 6c 65 6d 65 6e 74 20 69 73 20 74 68  nd element is th
6d50: 65 20 76 61 6c 75 65 20 64 69 73 70 6c 61 79 65  e value displaye
6d60: 64 20 74 6f 20 74 68 65 20 75 73 65 72 2e 0a 2a  d to the user..*
6d70: 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74  /.void cgi_v_opt
6d80: 69 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 6e 74 20  ionmenu2(.  int 
6d90: 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20  in,             
6da0: 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20 74 68   /* Indent by th
6db0: 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63  is amount */.  c
6dc0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 20  onst char *zP,  
6dd0: 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79      /* The query
6de0: 20 70 61 72 61 6d 65 74 65 72 20 6e 61 6d 65 20   parameter name 
6df0: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  */.  const char 
6e00: 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44 65 66  *zD,      /* Def
6e10: 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20  ault value */.  
6e20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 20  const char **az 
6e30: 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72       /* NULL-ter
6e40: 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 6f 66 20  minated list of 
6e50: 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 2a  allowed values *
6e60: 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  /.){.  const cha
6e70: 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 69  r *zVal;.  int i
6e80: 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22  ;.  cgi_printf("
6e90: 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 3d  %*s<select size=
6ea0: 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e  1 name=\"%s\">\n
6eb0: 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a  ", in, "", zP);.
6ec0: 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d    for(i=0; az[i]
6ed0: 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20 69 66 28  ; i+=2){.    if(
6ee0: 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a 44   strcmp(az[i],zD
6ef0: 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20  )==0 ) break;.  
6f00: 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d 30  }.  if( az[i]==0
6f10: 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b 30   ){.    if( zD[0
6f20: 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67  ]==0 ){.      cg
6f30: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70  i_printf("%*s<op
6f40: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20  tion value=\"\" 
6f50: 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c  selected>&nbsp;<
6f60: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20  /option>\n",.   
6f70: 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20      in+2, "");. 
6f80: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
6f90: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c  cgi_printf("%*s<
6fa0: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25  option value=\"%
6fb0: 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 68 3c  h\" selected>%h<
6fc0: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20  /option>\n",.   
6fd0: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44      in+2, "", zD
6fe0: 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  , zD);.    }.  }
6ff0: 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 61 6c 20  .  while( (zVal 
7000: 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20 29  = *(az++))!=0  )
7010: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72  {.    const char
7020: 20 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a 2b 2b   *zName = *(az++
7030: 29 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65  );.    if( zName
7040: 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69  [0] ){.      cgi
7050: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74  _printf("%*s<opt
7060: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22  ion value=\"%h\"
7070: 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e  %s>%h</option>\n
7080: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c  ",.        in+2,
7090: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61   "",.        zVa
70a0: 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d  l,.        strcm
70b0: 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22  p(zVal, zD) ? ""
70c0: 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a   : " selected",.
70d0: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20          zName.  
70e0: 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65      );.    }else
70f0: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e  {.      cgi_prin
7100: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76  tf("%*s<option v
7110: 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 26 6e  alue=\"%h\"%s>&n
7120: 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22  bsp;</option>\n"
7130: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20  ,.        in+2, 
7140: 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c  "",.        zVal
7150: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70  ,.        strcmp
7160: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20  (zVal, zD) ? "" 
7170: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20  : " selected".  
7180: 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d      );.    }.  }
7190: 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25  .  cgi_printf("%
71a0: 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20  *s</select>\n", 
71b0: 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  in, "");.}../*.*
71c0: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77  * This routine w
71d0: 6f 72 6b 73 20 6c 69 6b 65 20 22 70 72 69 6e 74  orks like "print
71e0: 66 22 20 65 78 63 65 70 74 20 74 68 61 74 20 69  f" except that i
71f0: 74 20 68 61 73 20 74 68 65 0a 2a 2a 20 65 78 74  t has the.** ext
7200: 72 61 20 66 6f 72 6d 61 74 74 69 6e 67 20 63 61  ra formatting ca
7210: 70 61 62 69 6c 69 74 69 65 73 20 73 75 63 68 20  pabilities such 
7220: 61 73 20 25 68 20 61 6e 64 20 25 74 2e 0a 2a 2f  as %h and %t..*/
7230: 0a 76 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 66  .void cgi_printf
7240: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f  (const char *zFo
7250: 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61  rmat, ...){.  va
7260: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73  _list ap;.  va_s
7270: 74 61 72 74 28 61 70 2c 7a 46 6f 72 6d 61 74 29  tart(ap,zFormat)
7280: 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 70 43 6f  ;.  vxprintf(pCo
7290: 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 70  ntent,zFormat,ap
72a0: 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b  );.  va_end(ap);
72b0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72  .}../*.** This r
72c0: 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69 6b  outine works lik
72d0: 65 20 22 76 70 72 69 6e 74 66 22 20 65 78 63 65  e "vprintf" exce
72e0: 70 74 20 74 68 61 74 20 69 74 20 68 61 73 20 74  pt that it has t
72f0: 68 65 0a 2a 2a 20 65 78 74 72 61 20 66 6f 72 6d  he.** extra form
7300: 61 74 74 69 6e 67 20 63 61 70 61 62 69 6c 69 74  atting capabilit
7310: 69 65 73 20 73 75 63 68 20 61 73 20 25 68 20 61  ies such as %h a
7320: 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63  nd %t..*/.void c
7330: 67 69 5f 76 70 72 69 6e 74 66 28 63 6f 6e 73 74  gi_vprintf(const
7340: 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20   char *zFormat, 
7350: 76 61 5f 6c 69 73 74 20 61 70 29 7b 0a 20 20 76  va_list ap){.  v
7360: 78 70 72 69 6e 74 66 28 70 43 6f 6e 74 65 6e 74  xprintf(pContent
7370: 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 7d 0a  ,zFormat,ap);.}.
7380: 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20 72  ../*.** Send a r
7390: 65 70 6c 79 20 69 6e 64 69 63 61 74 69 6e 67 20  eply indicating 
73a0: 74 68 61 74 20 74 68 65 20 48 54 54 50 20 72 65  that the HTTP re
73b0: 71 75 65 73 74 20 77 61 73 20 6d 61 6c 66 6f 72  quest was malfor
73c0: 6d 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  med.*/.static vo
73d0: 69 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71  id malformed_req
73e0: 75 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 63 67  uest(void){.  cg
73f0: 69 5f 73 65 74 5f 73 74 61 74 75 73 28 35 30 31  i_set_status(501
7400: 2c 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e 74  , "Not Implement
7410: 65 64 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e  ed");.  cgi_prin
7420: 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c  tf(.    "<html><
7430: 62 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69 7a 65  body>Unrecognize
7440: 64 20 48 54 54 50 20 52 65 71 75 65 73 74 3c 2f  d HTTP Request</
7450: 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e 22 0a  body></html>\n".
7460: 20 20 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79    );.  cgi_reply
7470: 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d  ();.  exit(0);.}
7480: 0a 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 61 6e  ../*.** Panic an
7490: 64 20 64 69 65 20 77 68 69 6c 65 20 70 72 6f 63  d die while proc
74a0: 65 73 73 69 6e 67 20 61 20 77 65 62 70 61 67 65  essing a webpage
74b0: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 61  ..*/.void cgi_pa
74c0: 6e 69 63 28 63 6f 6e 73 74 20 63 68 61 72 20 2a  nic(const char *
74d0: 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20  zFormat, ...){. 
74e0: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63   va_list ap;.  c
74f0: 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74  gi_reset_content
7500: 28 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74  ();.  cgi_set_st
7510: 61 74 75 73 28 35 30 30 2c 20 22 49 6e 74 65 72  atus(500, "Inter
7520: 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72  nal Server Error
7530: 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66  ");.  cgi_printf
7540: 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 6f  (.    "<html><bo
7550: 64 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 6c 20  dy><h1>Internal 
7560: 53 65 72 76 65 72 20 45 72 72 6f 72 3c 2f 68 31  Server Error</h1
7570: 3e 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61 69 6e  >\n".    "<plain
7580: 74 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20 76 61  text>".  );.  va
7590: 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d  _start(ap, zForm
75a0: 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28  at);.  vxprintf(
75b0: 70 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74  pContent,zFormat
75c0: 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61  ,ap);.  va_end(a
75d0: 70 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28  p);.  cgi_reply(
75e0: 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a  );.  exit(1);.}.
75f0: 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68  ./*.** Remove th
7600: 65 20 66 69 72 73 74 20 73 70 61 63 65 2d 64 65  e first space-de
7610: 6c 69 6d 69 74 65 64 20 74 6f 6b 65 6e 20 66 72  limited token fr
7620: 6f 6d 20 61 20 73 74 72 69 6e 67 20 61 6e 64 20  om a string and 
7630: 72 65 74 75 72 6e 0a 2a 2a 20 61 20 70 6f 69 6e  return.** a poin
7640: 74 65 72 20 74 6f 20 69 74 2e 20 20 41 64 64 20  ter to it.  Add 
7650: 61 20 4e 55 4c 4c 20 74 6f 20 74 68 65 20 73 74  a NULL to the st
7660: 72 69 6e 67 20 74 6f 20 74 65 72 6d 69 6e 61 74  ring to terminat
7670: 65 20 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 20  e the token..** 
7680: 4d 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 72 20  Make *zLeftOver 
7690: 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61  point to the sta
76a0: 72 74 20 6f 66 20 74 68 65 20 6e 65 78 74 20 74  rt of the next t
76b0: 6f 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  oken..*/.static 
76c0: 63 68 61 72 20 2a 65 78 74 72 61 63 74 5f 74 6f  char *extract_to
76d0: 6b 65 6e 28 63 68 61 72 20 2a 7a 49 6e 70 75 74  ken(char *zInput
76e0: 2c 20 63 68 61 72 20 2a 2a 7a 4c 65 66 74 4f 76  , char **zLeftOv
76f0: 65 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65  er){.  char *zRe
7700: 73 75 6c 74 20 3d 20 30 3b 0a 20 20 69 66 28 20  sult = 0;.  if( 
7710: 7a 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20  zInput==0 ){.   
7720: 20 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 20 29   if( zLeftOver )
7730: 20 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 30 3b   *zLeftOver = 0;
7740: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
7750: 20 7d 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70   }.  while( issp
7760: 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20  ace(*zInput) ){ 
7770: 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a 52  zInput++; }.  zR
7780: 65 73 75 6c 74 20 3d 20 7a 49 6e 70 75 74 3b 0a  esult = zInput;.
7790: 20 20 77 68 69 6c 65 28 20 2a 7a 49 6e 70 75 74    while( *zInput
77a0: 20 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a 49   && !isspace(*zI
77b0: 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b  nput) ){ zInput+
77c0: 2b 3b 20 7d 0a 20 20 69 66 28 20 2a 7a 49 6e 70  +; }.  if( *zInp
77d0: 75 74 20 29 7b 0a 20 20 20 20 2a 7a 49 6e 70 75  ut ){.    *zInpu
77e0: 74 20 3d 20 30 3b 0a 20 20 20 20 7a 49 6e 70 75  t = 0;.    zInpu
77f0: 74 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  t++;.    while( 
7800: 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29  isspace(*zInput)
7810: 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a   ){ zInput++; }.
7820: 20 20 7d 0a 20 20 69 66 28 20 7a 4c 65 66 74 4f    }.  if( zLeftO
7830: 76 65 72 20 29 7b 20 2a 7a 4c 65 66 74 4f 76 65  ver ){ *zLeftOve
7840: 72 20 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a 20 20  r = zInput; }.  
7850: 72 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a  return zResult;.
7860: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  }../*.** This ro
7870: 75 74 69 6e 65 20 68 61 6e 64 6c 65 73 20 61 20  utine handles a 
7880: 73 69 6e 67 6c 65 20 48 54 54 50 20 72 65 71 75  single HTTP requ
7890: 65 73 74 20 77 68 69 63 68 20 69 73 20 63 6f 6d  est which is com
78a0: 69 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74 61  ing in on.** sta
78b0: 6e 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20  ndard input and 
78c0: 77 68 69 63 68 20 72 65 70 6c 69 65 73 20 6f 6e  which replies on
78d0: 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74   standard output
78e0: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 54 50  ..**.** The HTTP
78f0: 20 72 65 71 75 65 73 74 20 69 73 20 72 65 61 64   request is read
7900: 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 20 69   from standard i
7910: 6e 70 75 74 20 61 6e 64 20 69 73 20 75 73 65 64  nput and is used
7920: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 0a 2a   to initialize.*
7930: 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61  * environment va
7940: 72 69 61 62 6c 65 73 20 61 73 20 70 65 72 20 43  riables as per C
7950: 47 49 2e 20 20 54 68 65 20 63 67 69 5f 69 6e 69  GI.  The cgi_ini
7960: 74 28 29 20 72 6f 75 74 69 6e 65 20 74 6f 20 63  t() routine to c
7970: 6f 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 65 20 73  omplete.** the s
7980: 65 74 75 70 2e 20 20 4f 6e 63 65 20 61 6c 6c 20  etup.  Once all 
7990: 74 68 65 20 73 65 74 75 70 20 69 73 20 66 69 6e  the setup is fin
79a0: 69 73 68 65 64 2c 20 74 68 69 73 20 70 72 6f 63  ished, this proc
79b0: 65 64 75 72 65 20 72 65 74 75 72 6e 73 0a 2a 2a  edure returns.**
79c0: 20 61 6e 64 20 73 75 62 73 65 71 75 65 6e 74 20   and subsequent 
79d0: 63 6f 64 65 20 68 61 6e 64 6c 65 73 20 74 68 65  code handles the
79e0: 20 61 63 74 75 61 6c 20 67 65 6e 65 72 61 74 69   actual generati
79f0: 6f 6e 20 6f 66 20 74 68 65 20 77 65 62 70 61 67  on of the webpag
7a00: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68  e..*/.void cgi_h
7a10: 61 6e 64 6c 65 5f 68 74 74 70 5f 72 65 71 75 65  andle_http_reque
7a20: 73 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  st(const char *z
7a30: 49 70 41 64 64 72 29 7b 0a 20 20 63 68 61 72 20  IpAddr){.  char 
7a40: 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 20 69  *z, *zToken;.  i
7a50: 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 74 20 73  nt i;.  struct s
7a60: 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 6d 6f 74  ockaddr_in remot
7a70: 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 5f 74 20  eName;.  size_t 
7a80: 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 28 73 74  size = sizeof(st
7a90: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e  ruct sockaddr_in
7aa0: 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 6e 65 5b  );.  char zLine[
7ab0: 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a 20 41 20  2000];     /* A 
7ac0: 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 69  single line of i
7ad0: 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 67 2e 66 75  nput. */..  g.fu
7ae0: 6c 6c 48 74 74 70 52 65 70 6c 79 20 3d 20 31 3b  llHttpReply = 1;
7af0: 0a 20 20 69 66 28 20 66 67 65 74 73 28 7a 4c 69  .  if( fgets(zLi
7b00: 6e 65 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e 65  ne, sizeof(zLine
7b10: 29 2c 67 2e 68 74 74 70 49 6e 29 3d 3d 30 20 29  ),g.httpIn)==0 )
7b20: 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f  {.    malformed_
7b30: 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20  request();.  }. 
7b40: 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61 63   zToken = extrac
7b50: 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e 65 2c 20 26  t_token(zLine, &
7b60: 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e  z);.  if( zToken
7b70: 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f  ==0 ){.    malfo
7b80: 72 6d 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a  rmed_request();.
7b90: 20 20 7d 0a 20 20 69 66 28 20 73 74 72 63 6d 70    }.  if( strcmp
7ba0: 28 7a 54 6f 6b 65 6e 2c 22 47 45 54 22 29 21 3d  (zToken,"GET")!=
7bb0: 30 20 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b  0 && strcmp(zTok
7bc0: 65 6e 2c 22 50 4f 53 54 22 29 21 3d 30 0a 20 20  en,"POST")!=0.  
7bd0: 20 20 20 20 26 26 20 73 74 72 63 6d 70 28 7a 54      && strcmp(zT
7be0: 6f 6b 65 6e 2c 22 48 45 41 44 22 29 21 3d 30 20  oken,"HEAD")!=0 
7bf0: 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64  ){.    malformed
7c00: 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a  _request();.  }.
7c10: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 47 41    cgi_setenv("GA
7c20: 54 45 57 41 59 5f 49 4e 54 45 52 46 41 43 45 22  TEWAY_INTERFACE"
7c30: 2c 22 43 47 49 2f 31 2e 30 22 29 3b 0a 20 20 63  ,"CGI/1.0");.  c
7c40: 67 69 5f 73 65 74 65 6e 76 28 22 52 45 51 55 45  gi_setenv("REQUE
7c50: 53 54 5f 4d 45 54 48 4f 44 22 2c 7a 54 6f 6b 65  ST_METHOD",zToke
7c60: 6e 29 3b 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 65  n);.  zToken = e
7c70: 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 2c 20  xtract_token(z, 
7c80: 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65  &z);.  if( zToke
7c90: 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66  n==0 ){.    malf
7ca0: 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28 29 3b  ormed_request();
7cb0: 0a 20 20 7d 0a 20 20 63 67 69 5f 73 65 74 65 6e  .  }.  cgi_seten
7cc0: 76 28 22 52 45 51 55 45 53 54 5f 55 52 49 22 2c  v("REQUEST_URI",
7cd0: 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 66 6f 72 28   zToken);.  for(
7ce0: 69 3d 30 3b 20 7a 54 6f 6b 65 6e 5b 69 5d 20 26  i=0; zToken[i] &
7cf0: 26 20 7a 54 6f 6b 65 6e 5b 69 5d 21 3d 27 3f 27  & zToken[i]!='?'
7d00: 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69 66 28 20 7a  ; i++){}.  if( z
7d10: 54 6f 6b 65 6e 5b 69 5d 20 29 20 7a 54 6f 6b 65  Token[i] ) zToke
7d20: 6e 5b 69 2b 2b 5d 20 3d 20 30 3b 0a 20 20 63 67  n[i++] = 0;.  cg
7d30: 69 5f 73 65 74 65 6e 76 28 22 50 41 54 48 5f 49  i_setenv("PATH_I
7d40: 4e 46 4f 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20  NFO", zToken);. 
7d50: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 51 55 45   cgi_setenv("QUE
7d60: 52 59 5f 53 54 52 49 4e 47 22 2c 20 26 7a 54 6f  RY_STRING", &zTo
7d70: 6b 65 6e 5b 69 5d 29 3b 0a 20 20 69 66 28 20 7a  ken[i]);.  if( z
7d80: 49 70 41 64 64 72 3d 3d 30 20 26 26 0a 20 20 20  IpAddr==0 &&.   
7d90: 20 20 20 20 20 67 65 74 70 65 65 72 6e 61 6d 65       getpeername
7da0: 28 66 69 6c 65 6e 6f 28 67 2e 68 74 74 70 49 6e  (fileno(g.httpIn
7db0: 29 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b 61  ), (struct socka
7dc0: 64 64 72 2a 29 26 72 65 6d 6f 74 65 4e 61 6d 65  ddr*)&remoteName
7dd0: 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  , .             
7de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
7df0: 20 20 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 26     (socklen_t*)&
7e00: 73 69 7a 65 29 3e 3d 30 0a 20 20 29 7b 0a 20 20  size)>=0.  ){.  
7e10: 20 20 7a 49 70 41 64 64 72 20 3d 20 69 6e 65 74    zIpAddr = inet
7e20: 5f 6e 74 6f 61 28 72 65 6d 6f 74 65 4e 61 6d 65  _ntoa(remoteName
7e30: 2e 73 69 6e 5f 61 64 64 72 29 3b 0a 20 20 7d 0a  .sin_addr);.  }.
7e40: 20 20 69 66 28 20 7a 49 70 41 64 64 72 20 29 7b    if( zIpAddr ){
7e50: 20 20 20 0a 20 20 20 20 63 67 69 5f 73 65 74 65     .    cgi_sete
7e60: 6e 76 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 22  nv("REMOTE_ADDR"
7e70: 2c 20 7a 49 70 41 64 64 72 29 3b 0a 20 20 20 20  , zIpAddr);.    
7e80: 67 2e 7a 49 70 41 64 64 72 20 3d 20 6d 70 72 69  g.zIpAddr = mpri
7e90: 6e 74 66 28 22 25 73 22 2c 20 7a 49 70 41 64 64  ntf("%s", zIpAdd
7ea0: 72 29 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a 20 47  r);.  }. .  /* G
7eb0: 65 74 20 61 6c 6c 20 74 68 65 20 6f 70 74 69 6f  et all the optio
7ec0: 6e 61 6c 20 66 69 65 6c 64 73 20 74 68 61 74 20  nal fields that 
7ed0: 66 6f 6c 6c 6f 77 20 74 68 65 20 66 69 72 73 74  follow the first
7ee0: 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20 77 68   line..  */.  wh
7ef0: 69 6c 65 28 20 66 67 65 74 73 28 7a 4c 69 6e 65  ile( fgets(zLine
7f00: 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c 67  ,sizeof(zLine),g
7f10: 2e 68 74 74 70 49 6e 29 20 29 7b 0a 20 20 20 20  .httpIn) ){.    
7f20: 63 68 61 72 20 2a 7a 46 69 65 6c 64 4e 61 6d 65  char *zFieldName
7f30: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c  ;.    char *zVal
7f40: 3b 0a 0a 20 20 20 20 7a 46 69 65 6c 64 4e 61 6d  ;..    zFieldNam
7f50: 65 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65  e = extract_toke
7f60: 6e 28 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b 0a  n(zLine,&zVal);.
7f70: 20 20 20 20 69 66 28 20 7a 46 69 65 6c 64 4e 61      if( zFieldNa
7f80: 6d 65 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c 64  me==0 || *zField
7f90: 4e 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b 3b  Name==0 ) break;
7fa0: 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 70  .    while( issp
7fb0: 61 63 65 28 2a 7a 56 61 6c 29 20 29 7b 20 7a 56  ace(*zVal) ){ zV
7fc0: 61 6c 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 3d 20  al++; }.    i = 
7fd0: 73 74 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20 20  strlen(zVal);.  
7fe0: 20 20 77 68 69 6c 65 28 20 69 3e 30 20 26 26 20    while( i>0 && 
7ff0: 69 73 73 70 61 63 65 28 7a 56 61 6c 5b 69 2d 31  isspace(zVal[i-1
8000: 5d 29 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20 20  ]) ){ i--; }.   
8010: 20 7a 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 20   zVal[i] = 0;.  
8020: 20 20 66 6f 72 28 69 3d 30 3b 20 7a 46 69 65 6c    for(i=0; zFiel
8030: 64 4e 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b 20  dName[i]; i++){ 
8040: 7a 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d 20  zFieldName[i] = 
8050: 74 6f 6c 6f 77 65 72 28 7a 46 69 65 6c 64 4e 61  tolower(zFieldNa
8060: 6d 65 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 69 66  me[i]); }.    if
8070: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e  ( strcmp(zFieldN
8080: 61 6d 65 2c 22 75 73 65 72 2d 61 67 65 6e 74 3a  ame,"user-agent:
8090: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63  ")==0 ){.      c
80a0: 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f  gi_setenv("HTTP_
80b0: 55 53 45 52 5f 41 47 45 4e 54 22 2c 20 7a 56 61  USER_AGENT", zVa
80c0: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  l);.    }else if
80d0: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e  ( strcmp(zFieldN
80e0: 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65 6e  ame,"content-len
80f0: 67 74 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20  gth:")==0 ){.   
8100: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43     cgi_setenv("C
8110: 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20  ONTENT_LENGTH", 
8120: 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65  zVal);.    }else
8130: 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65   if( strcmp(zFie
8140: 6c 64 4e 61 6d 65 2c 22 72 65 66 65 72 65 72 3a  ldName,"referer:
8150: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63  ")==0 ){.      c
8160: 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f  gi_setenv("HTTP_
8170: 52 45 46 45 52 45 52 22 2c 20 7a 56 61 6c 29 3b  REFERER", zVal);
8180: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73  .    }else if( s
8190: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65  trcmp(zFieldName
81a0: 2c 22 68 6f 73 74 3a 22 29 3d 3d 30 20 29 7b 0a  ,"host:")==0 ){.
81b0: 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76        cgi_setenv
81c0: 28 22 48 54 54 50 5f 48 4f 53 54 22 2c 20 7a 56  ("HTTP_HOST", zV
81d0: 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  al);.    }else i
81e0: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64  f( strcmp(zField
81f0: 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 74 79  Name,"content-ty
8200: 70 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20  pe:")==0 ){.    
8210: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f    cgi_setenv("CO
8220: 4e 54 45 4e 54 5f 54 59 50 45 22 2c 20 7a 56 61  NTENT_TYPE", zVa
8230: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  l);.    }else if
8240: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e  ( strcmp(zFieldN
8250: 61 6d 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d 3d  ame,"cookie:")==
8260: 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73  0 ){.      cgi_s
8270: 65 74 65 6e 76 28 22 48 54 54 50 5f 43 4f 4f 4b  etenv("HTTP_COOK
8280: 49 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20  IE", zVal);.    
8290: 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70  }else if( strcmp
82a0: 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d  (zFieldName,"if-
82b0: 6e 6f 6e 65 2d 6d 61 74 63 68 3a 22 29 3d 3d 30  none-match:")==0
82c0: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65   ){.      cgi_se
82d0: 74 65 6e 76 28 22 48 54 54 50 5f 49 46 5f 4e 4f  tenv("HTTP_IF_NO
82e0: 4e 45 5f 4d 41 54 43 48 22 2c 20 7a 56 61 6c 29  NE_MATCH", zVal)
82f0: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20  ;.    }else if( 
8300: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d  strcmp(zFieldNam
8310: 65 2c 22 69 66 2d 6d 6f 64 69 66 69 65 64 2d 73  e,"if-modified-s
8320: 69 6e 63 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20  ince:")==0 ){.  
8330: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22      cgi_setenv("
8340: 48 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44  HTTP_IF_MODIFIED
8350: 5f 53 49 4e 43 45 22 2c 20 7a 56 61 6c 29 3b 0a  _SINCE", zVal);.
8360: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 67 69      }.  }..  cgi
8370: 5f 69 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a  _init();.}../*.*
8380: 2a 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72  * Maximum number
8390: 20 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73   of child proces
83a0: 73 65 73 20 74 68 61 74 20 77 65 20 63 61 6e 20  ses that we can 
83b0: 68 61 76 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20  have running.** 
83c0: 61 74 20 6f 6e 65 20 74 69 6d 65 20 62 65 66 6f  at one time befo
83d0: 72 65 20 77 65 20 73 74 61 72 74 20 73 6c 6f 77  re we start slow
83e0: 69 6e 67 20 74 68 69 6e 67 73 20 64 6f 77 6e 2e  ing things down.
83f0: 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 41 58 5f  .*/.#define MAX_
8400: 50 41 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a 2a  PARALLEL 2../*.*
8410: 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 48  * Implement an H
8420: 54 54 50 20 73 65 72 76 65 72 20 64 61 65 6d 6f  TTP server daemo
8430: 6e 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20 70  n listening on p
8440: 6f 72 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a 2a  ort iPort..**.**
8450: 20 41 73 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69   As new connecti
8460: 6f 6e 73 20 61 72 72 69 76 65 2c 20 66 6f 72 6b  ons arrive, fork
8470: 20 61 20 63 68 69 6c 64 20 61 6e 64 20 6c 65 74   a child and let
8480: 20 63 68 69 6c 64 20 72 65 74 75 72 6e 0a 2a 2a   child return.**
8490: 20 6f 75 74 20 6f 66 20 74 68 69 73 20 70 72 6f   out of this pro
84a0: 63 65 64 75 72 65 20 63 61 6c 6c 2e 20 20 54 68  cedure call.  Th
84b0: 65 20 63 68 69 6c 64 20 77 69 6c 6c 20 68 61 6e  e child will han
84c0: 64 6c 65 20 74 68 65 20 72 65 71 75 65 73 74 2e  dle the request.
84d0: 0a 2a 2a 20 54 68 65 20 70 61 72 65 6e 74 20 6e  .** The parent n
84e0: 65 76 65 72 20 72 65 74 75 72 6e 73 20 66 72 6f  ever returns fro
84f0: 6d 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65  m this procedure
8500: 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 30  ..**.** Return 0
8510: 20 74 6f 20 65 61 63 68 20 63 68 69 6c 64 20 61   to each child a
8520: 73 20 69 74 20 72 75 6e 73 2e 20 20 49 66 20 75  s it runs.  If u
8530: 6e 61 62 6c 65 20 74 6f 20 65 73 74 61 62 6c 69  nable to establi
8540: 73 68 20 61 0a 2a 2a 20 6c 69 73 74 65 6e 69 6e  sh a.** listenin
8550: 67 20 73 6f 63 6b 65 74 2c 20 72 65 74 75 72 6e  g socket, return
8560: 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2f 0a 69 6e   non-zero..*/.in
8570: 74 20 63 67 69 5f 68 74 74 70 5f 73 65 72 76 65  t cgi_http_serve
8580: 72 28 69 6e 74 20 69 50 6f 72 74 2c 20 63 68 61  r(int iPort, cha
8590: 72 20 2a 7a 42 72 6f 77 73 65 72 29 7b 0a 23 69  r *zBrowser){.#i
85a0: 66 64 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f  fdef __MINGW32__
85b0: 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72  .  fprintf(stder
85c0: 72 2c 22 73 65 72 76 65 72 20 6e 6f 74 20 79 65  r,"server not ye
85d0: 74 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 77  t available in w
85e0: 69 6e 64 6f 77 73 20 76 65 72 73 69 6f 6e 20 6f  indows version o
85f0: 66 20 66 6f 73 73 69 6c 5c 6e 22 29 3b 0a 20 20  f fossil\n");.  
8600: 65 78 69 74 28 31 29 3b 0a 23 65 6c 73 65 0a 20  exit(1);.#else. 
8610: 20 69 6e 74 20 6c 69 73 74 65 6e 65 72 3b 20 20   int listener;  
8620: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
8630: 20 54 68 65 20 73 65 72 76 65 72 20 73 6f 63 6b   The server sock
8640: 65 74 20 2a 2f 0a 20 20 69 6e 74 20 63 6f 6e 6e  et */.  int conn
8650: 65 63 74 69 6f 6e 3b 20 20 20 20 20 20 20 20 20  ection;         
8660: 20 20 20 20 20 2f 2a 20 41 20 73 6f 63 6b 65 74       /* A socket
8670: 20 66 6f 72 20 65 61 63 68 20 69 6e 64 69 76 69   for each indivi
8680: 64 75 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e 20  dual connection 
8690: 2a 2f 0a 20 20 66 64 5f 73 65 74 20 72 65 61 64  */.  fd_set read
86a0: 66 64 73 3b 20 20 20 20 20 20 20 20 20 20 20 20  fds;            
86b0: 20 20 2f 2a 20 53 65 74 20 6f 66 20 66 69 6c 65    /* Set of file
86c0: 20 64 65 73 63 72 69 70 74 6f 72 73 20 66 6f 72   descriptors for
86d0: 20 73 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 73   select() */.  s
86e0: 69 7a 65 5f 74 20 6c 65 6e 61 64 64 72 3b 20 20  ize_t lenaddr;  
86f0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4c              /* L
8700: 65 6e 67 74 68 20 6f 66 20 74 68 65 20 69 6e 61  ength of the ina
8710: 64 64 72 20 73 74 72 75 63 74 75 72 65 20 2a 2f  ddr structure */
8720: 0a 20 20 69 6e 74 20 63 68 69 6c 64 3b 20 20 20  .  int child;   
8730: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8740: 2f 2a 20 50 49 44 20 6f 66 20 74 68 65 20 63 68  /* PID of the ch
8750: 69 6c 64 20 70 72 6f 63 65 73 73 20 2a 2f 0a 20  ild process */. 
8760: 20 69 6e 74 20 6e 63 68 69 6c 64 72 65 6e 20 3d   int nchildren =
8770: 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 2f 2a   0;           /*
8780: 20 4e 75 6d 62 65 72 20 6f 66 20 63 68 69 6c 64   Number of child
8790: 20 70 72 6f 63 65 73 73 65 73 20 2a 2f 0a 20 20   processes */.  
87a0: 73 74 72 75 63 74 20 74 69 6d 65 76 61 6c 20 64  struct timeval d
87b0: 65 6c 61 79 3b 20 20 20 20 20 20 20 20 2f 2a 20  elay;        /* 
87c0: 48 6f 77 20 6c 6f 6e 67 20 74 6f 20 77 61 69 74  How long to wait
87d0: 20 69 6e 73 69 64 65 20 73 65 6c 65 63 74 28 29   inside select()
87e0: 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 73 6f 63   */.  struct soc
87f0: 6b 61 64 64 72 5f 69 6e 20 69 6e 61 64 64 72 3b  kaddr_in inaddr;
8800: 20 20 20 2f 2a 20 54 68 65 20 73 6f 63 6b 65 74     /* The socket
8810: 20 61 64 64 72 65 73 73 20 2a 2f 0a 20 20 69 6e   address */.  in
8820: 74 20 6f 70 74 20 3d 20 31 3b 20 20 20 20 20 20  t opt = 1;      
8830: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 65             /* se
8840: 74 73 6f 63 6b 6f 70 74 20 66 6c 61 67 20 2a 2f  tsockopt flag */
8850: 0a 0a 20 20 6d 65 6d 73 65 74 28 26 69 6e 61 64  ..  memset(&inad
8860: 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 69 6e  dr, 0, sizeof(in
8870: 61 64 64 72 29 29 3b 0a 20 20 69 6e 61 64 64 72  addr));.  inaddr
8880: 2e 73 69 6e 5f 66 61 6d 69 6c 79 20 3d 20 41 46  .sin_family = AF
8890: 5f 49 4e 45 54 3b 0a 20 20 69 6e 61 64 64 72 2e  _INET;.  inaddr.
88a0: 73 69 6e 5f 61 64 64 72 2e 73 5f 61 64 64 72 20  sin_addr.s_addr 
88b0: 3d 20 49 4e 41 44 44 52 5f 41 4e 59 3b 0a 20 20  = INADDR_ANY;.  
88c0: 69 6e 61 64 64 72 2e 73 69 6e 5f 70 6f 72 74 20  inaddr.sin_port 
88d0: 3d 20 68 74 6f 6e 73 28 69 50 6f 72 74 29 3b 0a  = htons(iPort);.
88e0: 20 20 6c 69 73 74 65 6e 65 72 20 3d 20 73 6f 63    listener = soc
88f0: 6b 65 74 28 41 46 5f 49 4e 45 54 2c 20 53 4f 43  ket(AF_INET, SOC
8900: 4b 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a 20 20  K_STREAM, 0);.  
8910: 69 66 28 20 6c 69 73 74 65 6e 65 72 3c 30 20 29  if( listener<0 )
8920: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b 0a  {.    return 1;.
8930: 20 20 7d 0a 0a 20 20 2f 2a 20 69 66 20 77 65 20    }..  /* if we 
8940: 63 61 6e 27 74 20 74 65 72 6d 69 6e 61 74 65 20  can't terminate 
8950: 6e 69 63 65 6c 79 2c 20 61 74 20 6c 65 61 73 74  nicely, at least
8960: 20 61 6c 6c 6f 77 20 74 68 65 20 73 6f 63 6b 65   allow the socke
8970: 74 20 74 6f 20 62 65 20 72 65 75 73 65 64 20 2a  t to be reused *
8980: 2f 0a 20 20 73 65 74 73 6f 63 6b 6f 70 74 28 6c  /.  setsockopt(l
8990: 69 73 74 65 6e 65 72 2c 53 4f 4c 5f 53 4f 43 4b  istener,SOL_SOCK
89a0: 45 54 2c 53 4f 5f 52 45 55 53 45 41 44 44 52 2c  ET,SO_REUSEADDR,
89b0: 26 6f 70 74 2c 73 69 7a 65 6f 66 28 6f 70 74 29  &opt,sizeof(opt)
89c0: 29 3b 0a 0a 20 20 69 66 28 20 62 69 6e 64 28 6c  );..  if( bind(l
89d0: 69 73 74 65 6e 65 72 2c 20 28 73 74 72 75 63 74  istener, (struct
89e0: 20 73 6f 63 6b 61 64 64 72 2a 29 26 69 6e 61 64   sockaddr*)&inad
89f0: 64 72 2c 20 73 69 7a 65 6f 66 28 69 6e 61 64 64  dr, sizeof(inadd
8a00: 72 29 29 3c 30 20 29 7b 0a 20 20 20 20 63 6c 6f  r))<0 ){.    clo
8a10: 73 65 28 6c 69 73 74 65 6e 65 72 29 3b 0a 20 20  se(listener);.  
8a20: 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d 0a    return 1;.  }.
8a30: 20 20 6c 69 73 74 65 6e 28 6c 69 73 74 65 6e 65    listen(listene
8a40: 72 2c 31 30 29 3b 0a 20 20 69 66 28 20 7a 42 72  r,10);.  if( zBr
8a50: 6f 77 73 65 72 20 29 7b 0a 20 20 20 20 73 79 73  owser ){.    sys
8a60: 74 65 6d 28 7a 42 72 6f 77 73 65 72 29 3b 0a 20  tem(zBrowser);. 
8a70: 20 7d 0a 20 20 77 68 69 6c 65 28 20 31 20 29 7b   }.  while( 1 ){
8a80: 0a 20 20 20 20 69 66 28 20 6e 63 68 69 6c 64 72  .    if( nchildr
8a90: 65 6e 3e 4d 41 58 5f 50 41 52 41 4c 4c 45 4c 20  en>MAX_PARALLEL 
8aa0: 29 7b 0a 20 20 20 20 20 20 2f 2a 20 53 6c 6f 77  ){.      /* Slow
8ab0: 20 64 6f 77 6e 20 69 66 20 63 6f 6e 6e 65 63 74   down if connect
8ac0: 69 6f 6e 73 20 61 72 65 20 61 72 72 69 76 69 6e  ions are arrivin
8ad0: 67 20 74 6f 6f 20 66 61 73 74 20 2a 2f 0a 20 20  g too fast */.  
8ae0: 20 20 20 20 73 6c 65 65 70 28 20 6e 63 68 69 6c      sleep( nchil
8af0: 64 72 65 6e 2d 4d 41 58 5f 50 41 52 41 4c 4c 45  dren-MAX_PARALLE
8b00: 4c 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64  L );.    }.    d
8b10: 65 6c 61 79 2e 74 76 5f 73 65 63 20 3d 20 36 30  elay.tv_sec = 60
8b20: 3b 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 5f 75  ;.    delay.tv_u
8b30: 73 65 63 20 3d 20 30 3b 0a 20 20 20 20 46 44 5f  sec = 0;.    FD_
8b40: 5a 45 52 4f 28 26 72 65 61 64 66 64 73 29 3b 0a  ZERO(&readfds);.
8b50: 20 20 20 20 46 44 5f 53 45 54 28 20 6c 69 73 74      FD_SET( list
8b60: 65 6e 65 72 2c 20 26 72 65 61 64 66 64 73 29 3b  ener, &readfds);
8b70: 0a 20 20 20 20 69 66 28 20 73 65 6c 65 63 74 28  .    if( select(
8b80: 20 6c 69 73 74 65 6e 65 72 2b 31 2c 20 26 72 65   listener+1, &re
8b90: 61 64 66 64 73 2c 20 30 2c 20 30 2c 20 26 64 65  adfds, 0, 0, &de
8ba0: 6c 61 79 29 20 29 7b 0a 20 20 20 20 20 20 6c 65  lay) ){.      le
8bb0: 6e 61 64 64 72 20 3d 20 73 69 7a 65 6f 66 28 69  naddr = sizeof(i
8bc0: 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20 63 6f  naddr);.      co
8bd0: 6e 6e 65 63 74 69 6f 6e 20 3d 20 61 63 63 65 70  nnection = accep
8be0: 74 28 6c 69 73 74 65 6e 65 72 2c 20 28 73 74 72  t(listener, (str
8bf0: 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26 69  uct sockaddr*)&i
8c00: 6e 61 64 64 72 2c 0a 20 20 20 20 20 20 20 20 20  naddr,.         
8c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8c20: 20 20 20 20 20 20 20 20 20 20 20 28 73 6f 63 6b             (sock
8c30: 6c 65 6e 5f 74 2a 29 20 26 6c 65 6e 61 64 64 72  len_t*) &lenaddr
8c40: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 63 6f 6e  );.      if( con
8c50: 6e 65 63 74 69 6f 6e 3e 3d 30 20 29 7b 0a 20 20  nection>=0 ){.  
8c60: 20 20 20 20 20 20 63 68 69 6c 64 20 3d 20 66 6f        child = fo
8c70: 72 6b 28 29 3b 0a 20 20 20 20 20 20 20 20 69 66  rk();.        if
8c80: 28 20 63 68 69 6c 64 21 3d 30 20 29 7b 0a 20 20  ( child!=0 ){.  
8c90: 20 20 20 20 20 20 20 20 69 66 28 20 63 68 69 6c          if( chil
8ca0: 64 3e 30 20 29 20 6e 63 68 69 6c 64 72 65 6e 2b  d>0 ) nchildren+
8cb0: 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f  +;.          clo
8cc0: 73 65 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a  se(connection);.
8cd0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20          }else{. 
8ce0: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 30           close(0
8cf0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 75 70  );.          dup
8d00: 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20  (connection);.  
8d10: 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 31 29          close(1)
8d20: 3b 0a 20 20 20 20 20 20 20 20 20 20 64 75 70 28  ;.          dup(
8d30: 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20  connection);.   
8d40: 20 20 20 20 20 20 20 69 66 28 20 21 67 2e 66 48         if( !g.fH
8d50: 74 74 70 54 72 61 63 65 20 29 7b 0a 20 20 20 20  ttpTrace ){.    
8d60: 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 32 29          close(2)
8d70: 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 75  ;.            du
8d80: 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20  p(connection);. 
8d90: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20           }.     
8da0: 20 20 20 20 20 63 6c 6f 73 65 28 63 6f 6e 6e 65       close(conne
8db0: 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20  ction);.        
8dc0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 20    return 0;.    
8dd0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20      }.      }.  
8de0: 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75 72 79 20    }.    /* Bury 
8df0: 64 65 61 64 20 63 68 69 6c 64 72 65 6e 20 2a 2f  dead children */
8e00: 0a 20 20 20 20 77 68 69 6c 65 28 20 77 61 69 74  .    while( wait
8e10: 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f 48 41 4e  pid(0, 0, WNOHAN
8e20: 47 29 3e 30 20 29 7b 0a 20 20 20 20 20 20 6e 63  G)>0 ){.      nc
8e30: 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20 20 20 7d  hildren--;.    }
8e40: 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54 20 52 45  .  }.  /* NOT RE
8e50: 41 43 48 45 44 20 2a 2f 20 20 0a 20 20 65 78 69  ACHED */  .  exi
8e60: 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a 0a  t(1);.#endif.}..
8e70: 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66 20 64  ./*.** Name of d
8e80: 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73 2e 0a  ays and months..
8e90: 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20  */.static const 
8ea0: 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d 20 3d  char *azDays[] =
8eb0: 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22 4d 6f  .    {"Sun", "Mo
8ec0: 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65 64 22  n", "Tue", "Wed"
8ed0: 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22 2c 20  , "Thu", "Fri", 
8ee0: 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61 74 69  "Sat", 0};.stati
8ef0: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a  c const char *az
8f00: 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20 20 7b  Months[] =.    {
8f10: 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20 22 4d  "Jan", "Feb", "M
8f20: 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d 61 79  ar", "Apr", "May
8f30: 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20 20 22  ", "Jun",.     "
8f40: 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22 53 65  Jul", "Aug", "Se
8f50: 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f 76 22  p", "Oct", "Nov"
8f60: 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a 0a 2f  , "Dec", 0};.../
8f70: 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61 6e 20  *.** Returns an 
8f80: 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 64  RFC822-formatted
8f90: 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73 75 69   time string sui
8fa0: 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50 20 68  table for HTTP h
8fb0: 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a 2a 2a  eaders, among.**
8fc0: 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e 0a 2a   other things..*
8fd0: 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d 65 7a  * Returned timez
8fe0: 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20 47 4d  one is always GM
8ff0: 54 20 61 73 20 72 65 71 75 69 72 65 64 20 62 79  T as required by
9000: 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63 69 66   HTTP/1.1 specif
9010: 69 63 61 74 69 6f 6e 2e 0a 2a 2a 20 54 68 65 20  ication..** The 
9020: 72 65 74 75 72 6e 65 64 20 73 74 72 69 6e 67 20  returned string 
9030: 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 77 69 74  is allocated wit
9040: 68 20 6d 61 6c 6c 6f 63 28 29 20 61 6e 64 20 6d  h malloc() and m
9050: 75 73 74 20 62 65 20 66 72 65 65 64 0a 2a 2a 20  ust be freed.** 
9060: 77 69 74 68 20 66 72 65 65 28 29 2e 0a 2a 2a 0a  with free()..**.
9070: 2a 2a 20 53 65 65 20 68 74 74 70 3a 2f 2f 77 77  ** See http://ww
9080: 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66 63 73 2f  w.faqs.org/rfcs/
9090: 72 66 63 38 32 32 2e 68 74 6d 6c 2c 20 73 65 63  rfc822.html, sec
90a0: 74 69 6f 6e 20 35 0a 2a 2a 20 61 6e 64 20 68 74  tion 5.** and ht
90b0: 74 70 3a 2f 2f 77 77 77 2e 66 61 71 73 2e 6f 72  tp://www.faqs.or
90c0: 67 2f 72 66 63 73 2f 72 66 63 32 36 31 36 2e 68  g/rfcs/rfc2616.h
90d0: 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 20 33 2e 33  tml, section 3.3
90e0: 2e 0a 2a 2f 0a 63 68 61 72 20 2a 63 67 69 5f 72  ..*/.char *cgi_r
90f0: 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28  fc822_datestamp(
9100: 74 69 6d 65 5f 74 20 6e 6f 77 29 7b 0a 20 20 73  time_t now){.  s
9110: 74 72 75 63 74 20 74 6d 20 2a 70 54 6d 3b 0a 20  truct tm *pTm;. 
9120: 20 70 54 6d 20 3d 20 67 6d 74 69 6d 65 28 26 6e   pTm = gmtime(&n
9130: 6f 77 29 3b 0a 20 20 69 66 28 20 70 54 6d 3d 3d  ow);.  if( pTm==
9140: 30 20 29 20 72 65 74 75 72 6e 20 22 22 3b 0a 20  0 ) return "";. 
9150: 20 72 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 28   return mprintf(
9160: 22 25 73 2c 20 25 64 20 25 73 20 25 30 32 64 20  "%s, %d %s %02d 
9170: 25 30 32 64 3a 25 30 32 64 3a 25 30 32 64 20 47  %02d:%02d:%02d G
9180: 4d 54 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20  MT",.           
9190: 20 20 20 20 20 20 61 7a 44 61 79 73 5b 70 54 6d        azDays[pTm
91a0: 2d 3e 74 6d 5f 77 64 61 79 5d 2c 20 70 54 6d 2d  ->tm_wday], pTm-
91b0: 3e 74 6d 5f 6d 64 61 79 2c 20 61 7a 4d 6f 6e 74  >tm_mday, azMont
91c0: 68 73 5b 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d 2c  hs[pTm->tm_mon],
91d0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  .               
91e0: 20 20 70 54 6d 2d 3e 74 6d 5f 79 65 61 72 2b 31    pTm->tm_year+1
91f0: 39 30 30 2c 20 70 54 6d 2d 3e 74 6d 5f 68 6f 75  900, pTm->tm_hou
9200: 72 2c 20 70 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c 20  r, pTm->tm_min, 
9210: 70 54 6d 2d 3e 74 6d 5f 73 65 63 29 3b 0a 7d 0a  pTm->tm_sec);.}.
9220: 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65 20 61 6e 20  ./*.** Parse an 
9230: 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 64  RFC822-formatted
9240: 20 74 69 6d 65 73 74 61 6d 70 20 61 73 20 77 65   timestamp as we
9250: 27 64 20 65 78 70 65 63 74 20 66 72 6f 6d 20 48  'd expect from H
9260: 54 54 50 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a  TTP and return.*
9270: 2a 20 61 20 55 6e 69 78 20 65 70 6f 63 68 20 74  * a Unix epoch t
9280: 69 6d 65 2e 20 3c 3d 20 7a 65 72 6f 20 69 73 20  ime. <= zero is 
9290: 72 65 74 75 72 6e 65 64 20 6f 6e 20 66 61 69 6c  returned on fail
92a0: 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20  ure..**.** Note 
92b0: 74 68 61 74 20 74 68 69 73 20 77 6f 6e 27 74 20  that this won't 
92c0: 68 61 6e 64 6c 65 20 61 6c 6c 20 74 68 65 20 5f  handle all the _
92d0: 61 6c 6c 6f 77 65 64 5f 20 48 54 54 50 20 66 6f  allowed_ HTTP fo
92e0: 72 6d 61 74 73 2c 20 6a 75 73 74 20 74 68 65 0a  rmats, just the.
92f0: 2a 2a 20 6d 6f 73 74 20 70 6f 70 75 6c 61 72 20  ** most popular 
9300: 6f 6e 65 20 28 74 68 65 20 6f 6e 65 20 67 65 6e  one (the one gen
9310: 65 72 61 74 65 64 20 62 79 20 63 67 69 5f 72 66  erated by cgi_rf
9320: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 29  c822_datestamp()
9330: 2c 20 61 63 74 75 61 6c 6c 79 29 2e 0a 2a 2f 0a  , actually)..*/.
9340: 74 69 6d 65 5f 74 20 63 67 69 5f 72 66 63 38 32  time_t cgi_rfc82
9350: 32 5f 70 61 72 73 65 64 61 74 65 28 63 6f 6e 73  2_parsedate(cons
9360: 74 20 63 68 61 72 20 2a 7a 44 61 74 65 29 7b 0a  t char *zDate){.
9370: 20 20 73 74 72 75 63 74 20 74 6d 20 74 3b 0a 20    struct tm t;. 
9380: 20 63 68 61 72 20 7a 49 67 6e 6f 72 65 5b 31 36   char zIgnore[16
9390: 5d 3b 0a 20 20 63 68 61 72 20 7a 4d 6f 6e 74 68  ];.  char zMonth
93a0: 5b 31 36 5d 3b 0a 0a 20 20 6d 65 6d 73 65 74 28  [16];..  memset(
93b0: 26 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 74 29  &t, 0, sizeof(t)
93c0: 29 3b 0a 20 20 69 66 28 20 37 3d 3d 73 73 63 61  );.  if( 7==ssca
93d0: 6e 66 28 7a 44 61 74 65 2c 20 22 25 31 32 5b 41  nf(zDate, "%12[A
93e0: 2d 5a 61 2d 7a 2c 5d 20 25 64 20 25 31 32 5b 41  -Za-z,] %d %12[A
93f0: 2d 5a 61 2d 7a 5d 20 25 64 20 25 64 3a 25 64 3a  -Za-z] %d %d:%d:
9400: 25 64 22 2c 20 7a 49 67 6e 6f 72 65 2c 0a 20 20  %d", zIgnore,.  
9410: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9420: 20 20 20 20 20 26 74 2e 74 6d 5f 6d 64 61 79 2c       &t.tm_mday,
9430: 20 7a 4d 6f 6e 74 68 2c 20 26 74 2e 74 6d 5f 79   zMonth, &t.tm_y
9440: 65 61 72 2c 20 26 74 2e 74 6d 5f 68 6f 75 72 2c  ear, &t.tm_hour,
9450: 20 26 74 2e 74 6d 5f 6d 69 6e 2c 0a 20 20 20 20   &t.tm_min,.    
9460: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
9470: 20 20 20 26 74 2e 74 6d 5f 73 65 63 29 29 7b 0a     &t.tm_sec)){.
9480: 0a 20 20 20 20 69 66 28 20 74 2e 74 6d 5f 79 65  .    if( t.tm_ye
9490: 61 72 20 3e 20 31 39 30 30 20 29 20 74 2e 74 6d  ar > 1900 ) t.tm
94a0: 5f 79 65 61 72 20 2d 3d 20 31 39 30 30 3b 0a 20  _year -= 1900;. 
94b0: 20 20 20 66 6f 72 28 74 2e 74 6d 5f 6d 6f 6e 3d     for(t.tm_mon=
94c0: 30 3b 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d  0; azMonths[t.tm
94d0: 5f 6d 6f 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e 2b  _mon]; t.tm_mon+
94e0: 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 21 73  +){.      if( !s
94f0: 74 72 6e 63 61 73 65 63 6d 70 28 20 61 7a 4d 6f  trncasecmp( azMo
9500: 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c 20  nths[t.tm_mon], 
9510: 7a 4d 6f 6e 74 68 2c 20 33 20 29 29 7b 0a 20 20  zMonth, 3 )){.  
9520: 20 20 20 20 20 20 72 65 74 75 72 6e 20 6d 6b 67        return mkg
9530: 6d 74 69 6d 65 28 26 74 29 3b 0a 20 20 20 20 20  mtime(&t);.     
9540: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20   }.    }.  }..  
9550: 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a  return 0;.}../*.
9560: 2a 2a 20 43 6f 6e 76 65 72 74 20 61 20 73 74 72  ** Convert a str
9570: 75 63 74 20 74 6d 2a 20 74 68 61 74 20 72 65 70  uct tm* that rep
9580: 72 65 73 65 6e 74 73 20 61 20 6d 6f 6d 65 6e 74  resents a moment
9590: 20 69 6e 20 55 54 43 20 69 6e 74 6f 20 74 68 65   in UTC into the
95a0: 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 73 65   number.** of se
95b0: 63 6f 6e 64 73 20 69 6e 20 31 39 37 30 2c 20 55  conds in 1970, U
95c0: 54 43 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 6d 6b  TC..*/.time_t mk
95d0: 67 6d 74 69 6d 65 28 73 74 72 75 63 74 20 74 6d  gmtime(struct tm
95e0: 20 2a 70 29 7b 0a 20 20 74 69 6d 65 5f 74 20 74   *p){.  time_t t
95f0: 3b 0a 20 20 69 6e 74 20 6e 44 61 79 3b 0a 20 20  ;.  int nDay;.  
9600: 69 6e 74 20 69 73 4c 65 61 70 59 72 3b 0a 20 20  int isLeapYr;.  
9610: 2f 2a 20 44 61 79 73 20 69 6e 20 65 61 63 68 20  /* Days in each 
9620: 6d 6f 6e 74 68 3a 20 20 20 20 20 20 20 33 31 2c  month:       31,
9630: 20 32 38 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c   28, 31, 30, 31,
9640: 20 33 30 2c 20 33 31 2c 20 33 31 2c 20 33 30 2c   30, 31, 31, 30,
9650: 20 33 31 2c 20 33 30 2c 20 33 31 20 2a 2f 0a 20   31, 30, 31 */. 
9660: 20 73 74 61 74 69 63 20 69 6e 74 20 70 72 69 6f   static int prio
9670: 72 44 61 79 73 5b 5d 20 20 20 3d 20 7b 20 20 30  rDays[]   = {  0
9680: 2c 20 33 31 2c 20 35 39 2c 20 39 30 2c 31 32 30  , 31, 59, 90,120
9690: 2c 31 35 31 2c 31 38 31 2c 32 31 32 2c 32 34 33  ,151,181,212,243
96a0: 2c 32 37 33 2c 33 30 34 2c 33 33 34 20 7d 3b 0a  ,273,304,334 };.
96b0: 20 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3c    if( p->tm_mon<
96c0: 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 59 65  0 ){.    int nYe
96d0: 61 72 20 3d 20 28 31 31 20 2d 20 70 2d 3e 74 6d  ar = (11 - p->tm
96e0: 5f 6d 6f 6e 29 2f 31 32 3b 0a 20 20 20 20 70 2d  _mon)/12;.    p-
96f0: 3e 74 6d 5f 79 65 61 72 20 2d 3d 20 6e 59 65 61  >tm_year -= nYea
9700: 72 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e  r;.    p->tm_mon
9710: 20 2b 3d 20 6e 59 65 61 72 2a 31 32 3b 0a 20 20   += nYear*12;.  
9720: 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 74 6d 5f  }else if( p->tm_
9730: 6d 6f 6e 3e 31 31 20 29 7b 0a 20 20 20 20 70 2d  mon>11 ){.    p-
9740: 3e 74 6d 5f 79 65 61 72 20 2b 3d 20 70 2d 3e 74  >tm_year += p->t
9750: 6d 5f 6d 6f 6e 2f 31 32 3b 0a 20 20 20 20 70 2d  m_mon/12;.    p-
9760: 3e 74 6d 5f 6d 6f 6e 20 25 3d 20 31 32 3b 0a 20  >tm_mon %= 12;. 
9770: 20 7d 0a 20 20 69 73 4c 65 61 70 59 72 20 3d 20   }.  isLeapYr = 
9780: 70 2d 3e 74 6d 5f 79 65 61 72 25 34 3d 3d 30 20  p->tm_year%4==0 
9790: 26 26 20 28 70 2d 3e 74 6d 5f 79 65 61 72 25 31  && (p->tm_year%1
97a0: 30 30 21 3d 30 20 7c 7c 20 28 70 2d 3e 74 6d 5f  00!=0 || (p->tm_
97b0: 79 65 61 72 2b 33 30 30 29 25 34 30 30 3d 3d 30  year+300)%400==0
97c0: 29 3b 0a 20 20 70 2d 3e 74 6d 5f 79 64 61 79 20  );.  p->tm_yday 
97d0: 3d 20 70 72 69 6f 72 44 61 79 73 5b 70 2d 3e 74  = priorDays[p->t
97e0: 6d 5f 6d 6f 6e 5d 20 2b 20 70 2d 3e 74 6d 5f 6d  m_mon] + p->tm_m
97f0: 64 61 79 20 2d 20 31 3b 0a 20 20 69 66 28 20 69  day - 1;.  if( i
9800: 73 4c 65 61 70 59 72 20 26 26 20 70 2d 3e 74 6d  sLeapYr && p->tm
9810: 5f 6d 6f 6e 3e 31 20 29 20 70 2d 3e 74 6d 5f 79  _mon>1 ) p->tm_y
9820: 64 61 79 2b 2b 3b 0a 20 20 6e 44 61 79 20 3d 20  day++;.  nDay = 
9830: 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 37 30 29 2a  (p->tm_year-70)*
9840: 33 36 35 20 2b 20 28 70 2d 3e 74 6d 5f 79 65 61  365 + (p->tm_yea
9850: 72 2d 36 39 29 2f 34 20 2d 70 2d 3e 74 6d 5f 79  r-69)/4 -p->tm_y
9860: 65 61 72 2f 31 30 30 20 2b 20 0a 20 20 20 20 20  ear/100 + .     
9870: 20 20 20 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2b      (p->tm_year+
9880: 33 30 30 29 2f 34 30 30 20 2b 20 70 2d 3e 74 6d  300)/400 + p->tm
9890: 5f 79 64 61 79 3b 0a 20 20 74 20 3d 20 28 28 6e  _yday;.  t = ((n
98a0: 44 61 79 2a 32 34 20 2b 20 70 2d 3e 74 6d 5f 68  Day*24 + p->tm_h
98b0: 6f 75 72 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f  our)*60 + p->tm_
98c0: 6d 69 6e 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f  min)*60 + p->tm_
98d0: 73 65 63 3b 0a 20 20 72 65 74 75 72 6e 20 74 3b  sec;.  return t;
98e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20  .}../*.** Check 
98f0: 74 68 65 20 6f 62 6a 65 63 74 54 69 6d 65 20 61  the objectTime a
9900: 67 61 69 6e 73 74 20 74 68 65 20 49 66 2d 4d 6f  gainst the If-Mo
9910: 64 69 66 69 65 64 2d 53 69 6e 63 65 20 72 65 71  dified-Since req
9920: 75 65 73 74 20 68 65 61 64 65 72 2e 20 49 66 20  uest header. If 
9930: 74 68 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 74 69  the.** object ti
9940: 6d 65 20 69 73 6e 27 74 20 61 6e 79 20 6e 65 77  me isn't any new
9950: 65 72 20 74 68 61 6e 20 74 68 65 20 68 65 61 64  er than the head
9960: 65 72 2c 20 77 65 20 69 6d 6d 65 64 69 61 74 65  er, we immediate
9970: 6c 79 20 73 65 6e 64 20 62 61 63 6b 0a 2a 2a 20  ly send back.** 
9980: 61 20 33 30 34 20 72 65 70 6c 79 20 61 6e 64 20  a 304 reply and 
9990: 65 78 69 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  exit..*/.void cg
99a0: 69 5f 6d 6f 64 69 66 69 65 64 5f 73 69 6e 63 65  i_modified_since
99b0: 28 74 69 6d 65 5f 74 20 6f 62 6a 65 63 74 54 69  (time_t objectTi
99c0: 6d 65 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61  me){.  const cha
99d0: 72 20 2a 7a 49 66 20 3d 20 50 28 22 48 54 54 50  r *zIf = P("HTTP
99e0: 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 4e  _IF_MODIFIED_SIN
99f0: 43 45 22 29 3b 0a 20 20 69 66 28 20 7a 49 66 3d  CE");.  if( zIf=
9a00: 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69  =0 ) return;.  i
9a10: 66 28 20 6f 62 6a 65 63 74 54 69 6d 65 20 3e 20  f( objectTime > 
9a20: 63 67 69 5f 72 66 63 38 32 32 5f 70 61 72 73 65  cgi_rfc822_parse
9a30: 64 61 74 65 28 7a 49 66 29 20 29 20 72 65 74 75  date(zIf) ) retu
9a40: 72 6e 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74  rn;.  cgi_set_st
9a50: 61 74 75 73 28 33 30 34 2c 22 4e 6f 74 20 4d 6f  atus(304,"Not Mo
9a60: 64 69 66 69 65 64 22 29 3b 0a 20 20 63 67 69 5f  dified");.  cgi_
9a70: 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b  reset_content();
9a80: 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a  .  cgi_reply();.
9a90: 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a             exit(0);.}.