Hex Artifact Content
Not logged in

Artifact 90e1185c4a8fec15c31d0b5e972378c002f95cac:

File src/cgi.c part of check-in [6dab6149b1] - From the vinfo webpage, provide a hyperlink to download a ZIP archive the version. by drh on 2007-08-01 13:32: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 6e 63   "config.h".#inc
04b0: 6c 75 64 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74  lude <sys/socket
04c0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 6e 65  .h>.#include <ne
04d0: 74 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 69 6e 63  tinet/in.h>.#inc
04e0: 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74 2e  lude <arpa/inet.
04f0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74 69 6d  h>.#include <tim
0500: 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  e.h>.#include <s
0510: 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 69 6e 63  ys/times.h>.#inc
0520: 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d 65 2e 68  lude <sys/time.h
0530: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f  >.#include <sys/
0540: 77 61 69 74 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  wait.h>.#include
0550: 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c   <stdio.h>.#incl
0560: 75 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23  ude <stdlib.h>.#
0570: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c  include <sys/sel
0580: 65 63 74 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ect.h>.#include 
0590: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c  <unistd.h>.#incl
05a0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66  ude "cgi.h"..#if
05b0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a   INTERFACE./*.**
05c0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63   Shortcuts for c
05d0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50  gi_parameter.  P
05e0: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68  ("x") returns th
05f0: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79  e value of query
0600: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72   parameter.** or
0610: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20   cookie "x", or 
0620: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73  NULL if there is
0630: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74   no such paramet
0640: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50  er or cookie.  P
0650: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f  D("x","y").** do
0660: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65  es the same exce
0670: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e  pt "y" is return
0680: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e  ed in place of N
0690: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20  ULL if there is 
06a0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64  not match..*/.#d
06b0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20  efine P(x)      
06c0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28    cgi_parameter(
06d0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50  (x),0).#define P
06e0: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70  D(x,y)     cgi_p
06f0: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29  arameter((x),(y)
0700: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20  ).#define QP(x) 
0710: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73        quotable_s
0720: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65  tring(cgi_parame
0730: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66  ter((x),0)).#def
0740: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20  ine QPD(x,y)    
0750: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28  quotable_string(
0760: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78  cgi_parameter((x
0770: 29 2c 28 79 29 29 29 0a 0a 23 65 6e 64 69 66 20  ),(y)))..#endif 
0780: 2f 2a 20 49 4e 54 45 52 46 41 43 45 20 2a 2f 0a  /* INTERFACE */.
0790: 0a 2f 2a 0a 2a 2a 20 50 72 6f 76 69 64 65 20 61  ./*.** Provide a
07a0: 20 72 65 6c 69 61 62 6c 65 20 69 6d 70 6c 65 6d   reliable implem
07b0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 61 20 63 61  entation of a ca
07c0: 73 65 6c 65 73 73 20 73 74 72 69 6e 67 20 63 6f  seless string co
07d0: 6d 70 61 72 69 73 6f 6e 0a 2a 2a 20 66 75 6e 63  mparison.** func
07e0: 74 69 6f 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  tion..*/.#define
07f0: 20 73 74 72 69 63 6d 70 20 73 71 6c 69 74 65 33   stricmp sqlite3
0800: 53 74 72 49 43 6d 70 0a 65 78 74 65 72 6e 20 69  StrICmp.extern i
0810: 6e 74 20 73 71 6c 69 74 65 33 53 74 72 49 43 6d  nt sqlite3StrICm
0820: 70 28 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 63  p(const char*, c
0830: 6f 6e 73 74 20 63 68 61 72 2a 29 3b 0a 0a 2f 2a  onst char*);../*
0840: 0a 2a 2a 20 54 68 65 20 62 6f 64 79 20 6f 66 20  .** The body of 
0850: 74 68 65 20 48 54 54 50 20 72 65 70 6c 79 20 74  the HTTP reply t
0860: 65 78 74 20 69 73 20 73 74 6f 72 65 64 20 68 65  ext is stored he
0870: 72 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42 6c  re..*/.static Bl
0880: 6f 62 20 63 67 69 43 6f 6e 74 65 6e 74 20 3d 20  ob cgiContent = 
0890: 42 4c 4f 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52  BLOB_INITIALIZER
08a0: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20  ;../*.** Append 
08b0: 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 6f  reply content to
08c0: 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 65 78   what already ex
08d0: 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  ists..*/.void cg
08e0: 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e 74  i_append_content
08f0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 61  (const char *zDa
0900: 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b 0a 20  ta, int nAmt){. 
0910: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 63 67   blob_append(&cg
0920: 69 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c  iContent, zData,
0930: 20 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   nAmt);.}../*.**
0940: 20 52 65 73 65 74 20 74 68 65 20 48 54 54 50 20   Reset the HTTP 
0950: 72 65 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65  reply text to be
0960: 20 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67   an empty string
0970: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65  ..*/.void cgi_re
0980: 73 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64  set_content(void
0990: 29 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  ){.  blob_reset(
09a0: 26 63 67 69 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a  &cgiContent);.}.
09b0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  ./*.** Return a 
09c0: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 48  pointer to the H
09d0: 54 54 50 20 72 65 70 6c 79 20 74 65 78 74 2e 0a  TTP reply text..
09e0: 2a 2f 0a 63 68 61 72 20 2a 63 67 69 5f 65 78 74  */.char *cgi_ext
09f0: 72 61 63 74 5f 63 6f 6e 74 65 6e 74 28 69 6e 74  ract_content(int
0a00: 20 2a 70 6e 41 6d 74 29 7b 0a 20 20 72 65 74 75   *pnAmt){.  retu
0a10: 72 6e 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26  rn blob_buffer(&
0a20: 63 67 69 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a 0a  cgiContent);.}..
0a30: 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c  /*.** Additional
0a40: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73 65   information use
0a50: 64 20 74 6f 20 66 6f 72 6d 20 74 68 65 20 48 54  d to form the HT
0a60: 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 73 74 61 74  TP reply.*/.stat
0a70: 69 63 20 63 68 61 72 20 2a 7a 43 6f 6e 74 65 6e  ic char *zConten
0a80: 74 54 79 70 65 20 3d 20 22 74 65 78 74 2f 68 74  tType = "text/ht
0a90: 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 43 6f 6e 74  ml";     /* Cont
0aa0: 65 6e 74 20 74 79 70 65 20 6f 66 20 74 68 65 20  ent type of the 
0ab0: 72 65 70 6c 79 20 2a 2f 0a 73 74 61 74 69 63 20  reply */.static 
0ac0: 63 68 61 72 20 2a 7a 52 65 70 6c 79 53 74 61 74  char *zReplyStat
0ad0: 75 73 20 3d 20 22 4f 4b 22 3b 20 20 20 20 20 20  us = "OK";      
0ae0: 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 73        /* Reply s
0af0: 74 61 74 75 73 20 64 65 73 63 72 69 70 74 69 6f  tatus descriptio
0b00: 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  n */.static int 
0b10: 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 32  iReplyStatus = 2
0b20: 30 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  00;             
0b30: 20 20 2f 2a 20 52 65 70 6c 79 20 73 74 61 74 75    /* Reply statu
0b40: 73 20 63 6f 64 65 20 2a 2f 0a 73 74 61 74 69 63  s code */.static
0b50: 20 42 6c 6f 62 20 65 78 74 72 61 48 65 61 64 65   Blob extraHeade
0b60: 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 4c  r = BLOB_INITIAL
0b70: 49 5a 45 52 3b 20 20 2f 2a 20 45 78 74 72 61 20  IZER;  /* Extra 
0b80: 68 65 61 64 65 72 20 74 65 78 74 20 2a 2f 0a 73  header text */.s
0b90: 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 48 74  tatic int fullHt
0ba0: 74 70 52 65 70 6c 79 20 3d 20 30 3b 20 20 20 20  tpReply = 0;    
0bb0: 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 61 20    /* True for a 
0bc0: 66 75 6c 6c 2d 62 6c 6f 77 6e 20 48 54 54 50 20  full-blown HTTP 
0bd0: 68 65 61 64 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a 2a  header */../*.**
0be0: 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 20 63   Set the reply c
0bf0: 6f 6e 74 65 6e 74 20 74 79 70 65 0a 2a 2f 0a 76  ontent type.*/.v
0c00: 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74  oid cgi_set_cont
0c10: 65 6e 74 5f 74 79 70 65 28 63 6f 6e 73 74 20 63  ent_type(const c
0c20: 68 61 72 20 2a 7a 54 79 70 65 29 7b 0a 20 20 7a  har *zType){.  z
0c30: 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 6d 70  ContentType = mp
0c40: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 54 79 70  rintf("%s", zTyp
0c50: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74  e);.}../*.** Set
0c60: 20 74 68 65 20 72 65 70 6c 79 20 63 6f 6e 74 65   the reply conte
0c70: 6e 74 20 74 6f 20 74 68 65 20 73 70 65 63 69 66  nt to the specif
0c80: 69 65 64 20 42 4c 4f 42 2e 0a 2a 2f 0a 76 6f 69  ied BLOB..*/.voi
0c90: 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 65 6e  d cgi_set_conten
0ca0: 74 28 42 6c 6f 62 20 2a 70 4e 65 77 43 6f 6e 74  t(Blob *pNewCont
0cb0: 65 6e 74 29 7b 0a 20 20 62 6c 6f 62 5f 72 65 73  ent){.  blob_res
0cc0: 65 74 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 3b  et(&cgiContent);
0cd0: 0a 20 20 63 67 69 43 6f 6e 74 65 6e 74 20 3d 20  .  cgiContent = 
0ce0: 2a 70 4e 65 77 43 6f 6e 74 65 6e 74 3b 0a 20 20  *pNewContent;.  
0cf0: 62 6c 6f 62 5f 7a 65 72 6f 28 70 4e 65 77 43 6f  blob_zero(pNewCo
0d00: 6e 74 65 6e 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  ntent);.}../*.**
0d10: 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 20 73   Set the reply s
0d20: 74 61 74 75 73 20 63 6f 64 65 0a 2a 2f 0a 76 6f  tatus code.*/.vo
0d30: 69 64 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75  id cgi_set_statu
0d40: 73 28 69 6e 74 20 69 53 74 61 74 2c 20 63 6f 6e  s(int iStat, con
0d50: 73 74 20 63 68 61 72 20 2a 7a 53 74 61 74 29 7b  st char *zStat){
0d60: 0a 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20  .  zReplyStatus 
0d70: 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20  = mprintf("%s", 
0d80: 7a 53 74 61 74 29 3b 0a 20 20 69 52 65 70 6c 79  zStat);.  iReply
0d90: 53 74 61 74 75 73 20 3d 20 69 53 74 61 74 3b 0a  Status = iStat;.
0da0: 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20  }../*.** Append 
0db0: 74 65 78 74 20 74 6f 20 74 68 65 20 68 65 61 64  text to the head
0dc0: 65 72 20 6f 66 20 61 6e 20 48 54 54 50 20 72 65  er of an HTTP re
0dd0: 70 6c 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  ply.*/.void cgi_
0de0: 61 70 70 65 6e 64 5f 68 65 61 64 65 72 28 63 6f  append_header(co
0df0: 6e 73 74 20 63 68 61 72 20 2a 7a 4c 69 6e 65 29  nst char *zLine)
0e00: 7b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28  {.  blob_append(
0e10: 26 65 78 74 72 61 48 65 61 64 65 72 2c 20 7a 4c  &extraHeader, zL
0e20: 69 6e 65 2c 20 2d 31 29 3b 0a 7d 0a 0a 2f 2a 0a  ine, -1);.}../*.
0e30: 2a 2a 20 53 65 74 20 61 20 63 6f 6f 6b 69 65 2e  ** Set a cookie.
0e40: 0a 2a 2a 0a 2a 2a 20 5a 65 72 6f 20 6c 69 66 65  .**.** Zero life
0e50: 74 69 6d 65 20 69 6d 70 6c 69 65 73 20 61 20 73  time implies a s
0e60: 65 73 73 69 6f 6e 20 63 6f 6f 6b 69 65 2e 0a 2a  ession cookie..*
0e70: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 63  /.void cgi_set_c
0e80: 6f 6f 6b 69 65 28 0a 20 20 63 6f 6e 73 74 20 63  ookie(.  const c
0e90: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 2f  har *zName,    /
0ea0: 2a 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 63 6f  * Name of the co
0eb0: 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  okie */.  const 
0ec0: 63 68 61 72 20 2a 7a 56 61 6c 75 65 2c 20 20 20  char *zValue,   
0ed0: 2f 2a 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20  /* Value of the 
0ee0: 63 6f 6f 6b 69 65 2e 20 20 41 75 74 6f 6d 61 74  cookie.  Automat
0ef0: 69 63 61 6c 6c 79 20 65 73 63 61 70 65 64 20 2a  ically escaped *
0f00: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  /.  const char *
0f10: 7a 50 61 74 68 2c 20 20 20 20 2f 2a 20 50 61 74  zPath,    /* Pat
0f20: 68 20 63 6f 6f 6b 69 65 20 61 70 70 6c 69 65 73  h cookie applies
0f30: 20 74 6f 2e 20 20 4e 55 4c 4c 20 6d 65 61 6e 73   to.  NULL means
0f40: 20 22 2f 22 20 2a 2f 0a 20 20 69 6e 74 20 6c 69   "/" */.  int li
0f50: 66 65 74 69 6d 65 20 20 20 20 20 20 20 20 20 20  fetime          
0f60: 2f 2a 20 45 78 70 69 72 61 74 69 6f 6e 20 6f 66  /* Expiration of
0f70: 20 74 68 65 20 63 6f 6f 6b 69 65 20 69 6e 20 73   the cookie in s
0f80: 65 63 6f 6e 64 73 20 66 72 6f 6d 20 6e 6f 77 20  econds from now 
0f90: 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 7a 50 61 74  */.){.  if( zPat
0fa0: 68 3d 3d 30 20 29 20 7a 50 61 74 68 20 3d 20 22  h==0 ) zPath = "
0fb0: 2f 22 3b 0a 20 20 69 66 28 20 6c 69 66 65 74 69  /";.  if( lifeti
0fc0: 6d 65 3e 30 20 29 7b 0a 20 20 20 20 6c 69 66 65  me>0 ){.    life
0fd0: 74 69 6d 65 20 2b 3d 20 28 69 6e 74 29 74 69 6d  time += (int)tim
0fe0: 65 28 30 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 61  e(0);.    blob_a
0ff0: 70 70 65 6e 64 66 28 26 65 78 74 72 61 48 65 61  ppendf(&extraHea
1000: 64 65 72 2c 0a 20 20 20 20 20 20 20 22 53 65 74  der,.       "Set
1010: 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d 25 74 3b 20  -Cookie: %s=%t; 
1020: 50 61 74 68 3d 25 73 3b 20 65 78 70 69 72 65 73  Path=%s; expires
1030: 3d 25 73 3b 20 56 65 72 73 69 6f 6e 3d 31 5c 72  =%s; Version=1\r
1040: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e 61  \n",.        zNa
1050: 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50 61 74  me, zValue, zPat
1060: 68 2c 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61  h, cgi_rfc822_da
1070: 74 65 73 74 61 6d 70 28 6c 69 66 65 74 69 6d 65  testamp(lifetime
1080: 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ));.  }else{.   
1090: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65   blob_appendf(&e
10a0: 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20 20  xtraHeader,.    
10b0: 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20     "Set-Cookie: 
10c0: 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b 20  %s=%t; Path=%s; 
10d0: 56 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a  Version=1\r\n",.
10e0: 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56         zName, zV
10f0: 61 6c 75 65 2c 20 7a 50 61 74 68 29 3b 0a 20 20  alue, zPath);.  
1100: 7d 0a 7d 0a 0a 23 69 66 20 30 0a 2f 2a 0a 2a 2a  }.}..#if 0./*.**
1110: 20 41 64 64 20 61 6e 20 45 54 61 67 20 68 65 61   Add an ETag hea
1120: 64 65 72 20 6c 69 6e 65 0a 2a 2f 0a 73 74 61 74  der line.*/.stat
1130: 69 63 20 63 68 61 72 20 2a 63 67 69 5f 61 64 64  ic char *cgi_add
1140: 5f 65 74 61 67 28 63 68 61 72 20 2a 7a 54 78 74  _etag(char *zTxt
1150: 2c 20 69 6e 74 20 6e 4c 65 6e 29 7b 0a 20 20 4d  , int nLen){.  M
1160: 44 35 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20  D5Context ctx;. 
1170: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 64   unsigned char d
1180: 69 67 65 73 74 5b 31 36 5d 3b 0a 20 20 69 6e 74  igest[16];.  int
1190: 20 69 2c 20 6a 3b 0a 20 20 63 68 61 72 20 7a 45   i, j;.  char zE
11a0: 54 61 67 5b 36 34 5d 3b 0a 0a 20 20 4d 44 35 49  Tag[64];..  MD5I
11b0: 6e 69 74 28 26 63 74 78 29 3b 0a 20 20 4d 44 35  nit(&ctx);.  MD5
11c0: 55 70 64 61 74 65 28 26 63 74 78 2c 7a 54 78 74  Update(&ctx,zTxt
11d0: 2c 6e 4c 65 6e 29 3b 0a 20 20 4d 44 35 46 69 6e  ,nLen);.  MD5Fin
11e0: 61 6c 28 64 69 67 65 73 74 2c 26 63 74 78 29 3b  al(digest,&ctx);
11f0: 0a 20 20 66 6f 72 28 6a 3d 69 3d 30 3b 20 69 3c  .  for(j=i=0; i<
1200: 31 36 3b 20 69 2b 2b 2c 6a 2b 3d 32 29 7b 0a 20  16; i++,j+=2){. 
1210: 20 20 20 62 70 72 69 6e 74 66 28 26 7a 45 54 61     bprintf(&zETa
1220: 67 5b 6a 5d 2c 73 69 7a 65 6f 66 28 7a 45 54 61  g[j],sizeof(zETa
1230: 67 29 2d 6a 2c 22 25 30 32 78 22 2c 28 69 6e 74  g)-j,"%02x",(int
1240: 29 64 69 67 65 73 74 5b 69 5d 29 3b 0a 20 20 7d  )digest[i]);.  }
1250: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28  .  blob_appendf(
1260: 26 65 78 74 72 61 48 65 61 64 65 72 2c 20 22 45  &extraHeader, "E
1270: 54 61 67 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 45  Tag: %s\r\n", zE
1280: 54 61 67 29 3b 0a 20 20 72 65 74 75 72 6e 20 73  Tag);.  return s
1290: 74 72 64 75 70 28 7a 45 54 61 67 29 3b 0a 7d 0a  trdup(zETag);.}.
12a0: 0a 2f 2a 0a 2a 2a 20 44 6f 20 73 6f 6d 65 20 63  ./*.** Do some c
12b0: 61 63 68 65 20 63 6f 6e 74 72 6f 6c 20 73 74 75  ache control stu
12c0: 66 66 2e 20 46 69 72 73 74 2c 20 77 65 20 67 65  ff. First, we ge
12d0: 6e 65 72 61 74 65 20 61 6e 20 45 54 61 67 20 61  nerate an ETag a
12e0: 6e 64 20 69 6e 63 6c 75 64 65 20 69 74 20 69 6e  nd include it in
12f0: 0a 2a 2a 20 74 68 65 20 72 65 73 70 6f 6e 73 65  .** the response
1300: 20 68 65 61 64 65 72 73 2e 20 53 65 63 6f 6e 64   headers. Second
1310: 2c 20 77 65 20 64 6f 20 77 68 61 74 65 76 65 72  , we do whatever
1320: 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 74 6f   is necessary to
1330: 20 64 65 74 65 72 6d 69 6e 65 20 69 66 0a 2a 2a   determine if.**
1340: 20 74 68 65 20 72 65 71 75 65 73 74 20 77 61 73   the request was
1350: 20 61 73 6b 69 6e 67 20 61 62 6f 75 74 20 63 61   asking about ca
1360: 63 68 69 6e 67 20 61 6e 64 20 77 68 65 74 68 65  ching and whethe
1370: 72 20 77 65 20 6e 65 65 64 20 74 6f 20 73 65 6e  r we need to sen
1380: 64 20 62 61 63 6b 20 74 68 65 0a 2a 2a 20 72 65  d back the.** re
1390: 73 70 6f 6e 73 65 20 62 6f 64 79 2e 20 49 66 20  sponse body. If 
13a0: 77 65 20 73 68 6f 75 6c 64 6e 27 74 20 73 65 6e  we shouldn't sen
13b0: 64 20 61 20 62 6f 64 79 2c 20 72 65 74 75 72 6e  d a body, return
13c0: 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a   non-zero..**.**
13d0: 20 43 75 72 72 65 6e 74 6c 79 2c 20 77 65 20 6a   Currently, we j
13e0: 75 73 74 20 63 68 65 63 6b 20 74 68 65 20 45 54  ust check the ET
13f0: 61 67 20 61 67 61 69 6e 73 74 20 61 6e 79 20 49  ag against any I
1400: 66 2d 4e 6f 6e 65 2d 4d 61 74 63 68 20 68 65 61  f-None-Match hea
1410: 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 46 49 58 4d 45  der..**.** FIXME
1420: 3a 20 49 6e 20 73 6f 6d 65 20 63 61 73 65 73 20  : In some cases 
1430: 28 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 66 69  (attachments, fi
1440: 6c 65 20 63 6f 6e 74 65 6e 74 73 29 20 77 65 20  le contents) we 
1450: 63 6f 75 6c 64 20 63 68 65 63 6b 0a 2a 2a 20 49  could check.** I
1460: 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e 63 65  f-Modified-Since
1470: 20 68 65 61 64 65 72 73 20 61 6e 64 20 61 6c 77   headers and alw
1480: 61 79 73 20 69 6e 63 6c 75 64 65 20 4c 61 73 74  ays include Last
1490: 2d 4d 6f 64 69 66 69 65 64 20 69 6e 20 72 65 73  -Modified in res
14a0: 70 6f 6e 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69  ponses..*/.stati
14b0: 63 20 69 6e 74 20 63 68 65 63 6b 5f 63 61 63 68  c int check_cach
14c0: 65 5f 63 6f 6e 74 72 6f 6c 28 76 6f 69 64 29 7b  e_control(void){
14d0: 0a 20 20 2f 2a 20 46 49 58 4d 45 3a 20 74 68 65  .  /* FIXME: the
14e0: 72 65 27 73 20 73 6f 6d 65 20 67 6f 74 63 68 61  re's some gotcha
14f0: 73 20 77 74 68 20 63 6f 6f 6b 69 65 73 20 61 6e  s wth cookies an
1500: 64 20 73 6f 6d 65 20 68 65 61 64 65 72 73 2e 20  d some headers. 
1510: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 54 61 67  */.  char *zETag
1520: 20 3d 20 63 67 69 5f 61 64 64 5f 65 74 61 67 28   = cgi_add_etag(
1530: 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 69  blob_buffer(&cgi
1540: 43 6f 6e 74 65 6e 74 29 2c 62 6c 6f 62 5f 73 69  Content),blob_si
1550: 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 29  ze(&cgiContent))
1560: 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 61 74 63 68  ;.  char *zMatch
1570: 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f 4e 4f   = P("HTTP_IF_NO
1580: 4e 45 5f 4d 41 54 43 48 22 29 3b 0a 0a 20 20 69  NE_MATCH");..  i
1590: 66 28 20 7a 45 54 61 67 21 3d 30 20 26 26 20 7a  f( zETag!=0 && z
15a0: 4d 61 74 63 68 21 3d 30 20 29 20 7b 0a 20 20 20  Match!=0 ) {.   
15b0: 20 63 68 61 72 20 2a 7a 42 75 66 20 3d 20 73 74   char *zBuf = st
15c0: 72 64 75 70 28 7a 4d 61 74 63 68 29 3b 0a 20 20  rdup(zMatch);.  
15d0: 20 20 69 66 28 20 7a 42 75 66 21 3d 30 20 29 7b    if( zBuf!=0 ){
15e0: 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 54 6f  .      char *zTo
15f0: 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 63 68 61  k = 0;.      cha
1600: 72 20 2a 7a 50 6f 73 3b 0a 20 20 20 20 20 20 66  r *zPos;.      f
1610: 6f 72 28 20 7a 54 6f 6b 20 3d 20 73 74 72 74 6f  or( zTok = strto
1620: 6b 5f 72 28 7a 42 75 66 2c 20 22 2c 5c 22 22 2c  k_r(zBuf, ",\"",
1630: 26 7a 50 6f 73 29 3b 0a 20 20 20 20 20 20 20 20  &zPos);.        
1640: 20 20 20 7a 54 6f 6b 20 26 26 20 73 74 72 63 61     zTok && strca
1650: 73 65 63 6d 70 28 7a 54 6f 6b 2c 7a 45 54 61 67  secmp(zTok,zETag
1660: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 7a 54  );.           zT
1670: 6f 6b 20 3d 20 20 73 74 72 74 6f 6b 5f 72 28 30  ok =  strtok_r(0
1680: 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 29 7b  , ",\"",&zPos)){
1690: 7d 0a 20 20 20 20 20 20 66 72 65 65 28 7a 42 75  }.      free(zBu
16a0: 66 29 3b 0a 20 20 20 20 20 20 69 66 28 7a 54 6f  f);.      if(zTo
16b0: 6b 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20  k) return 1;.   
16c0: 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72 65 74 75   }.  }.  .  retu
16d0: 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a  rn 0;.}.#endif..
16e0: 2f 2a 0a 2a 2a 20 44 6f 20 61 20 6e 6f 72 6d 61  /*.** Do a norma
16f0: 6c 20 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a  l HTTP reply.*/.
1700: 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 79 28 76  void cgi_reply(v
1710: 6f 69 64 29 7b 0a 20 20 69 66 28 20 69 52 65 70  oid){.  if( iRep
1720: 6c 79 53 74 61 74 75 73 3c 3d 30 20 29 7b 0a 20  lyStatus<=0 ){. 
1730: 20 20 20 69 52 65 70 6c 79 53 74 61 74 75 73 20     iReplyStatus 
1740: 3d 20 32 30 30 3b 0a 20 20 20 20 7a 52 65 70 6c  = 200;.    zRepl
1750: 79 53 74 61 74 75 73 20 3d 20 22 4f 4b 22 3b 0a  yStatus = "OK";.
1760: 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20 69 66 28    }..#if 0.  if(
1770: 20 69 52 65 70 6c 79 53 74 61 74 75 73 3d 3d 32   iReplyStatus==2
1780: 30 30 20 26 26 20 63 68 65 63 6b 5f 63 61 63 68  00 && check_cach
1790: 65 5f 63 6f 6e 74 72 6f 6c 28 29 20 29 20 7b 0a  e_control() ) {.
17a0: 20 20 20 20 2f 2a 20 63 68 61 6e 67 65 20 74 68      /* change th
17b0: 65 20 73 74 61 74 75 73 20 74 6f 20 22 75 6e 63  e status to "unc
17c0: 68 61 6e 67 65 64 22 20 61 6e 64 20 77 65 20 63  hanged" and we c
17d0: 61 6e 20 73 6b 69 70 20 73 65 6e 64 69 6e 67 20  an skip sending 
17e0: 74 68 65 0a 20 20 20 20 2a 2a 20 61 63 74 75 61  the.    ** actua
17f0: 6c 20 72 65 73 70 6f 6e 73 65 20 62 6f 64 79 2e  l response body.
1800: 20 4f 62 76 69 6f 75 73 6c 79 20 77 65 20 6f 6e   Obviously we on
1810: 6c 79 20 64 6f 20 74 68 69 73 20 77 68 65 6e 20  ly do this when 
1820: 77 65 20 5f 68 61 76 65 5f 20 61 0a 20 20 20 20  we _have_ a.    
1830: 2a 2a 20 62 6f 64 79 20 28 63 6f 64 65 20 32 30  ** body (code 20
1840: 30 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 69  0)..    */.    i
1850: 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 33 30  ReplyStatus = 30
1860: 34 3b 0a 20 20 20 20 7a 52 65 70 6c 79 53 74 61  4;.    zReplySta
1870: 74 75 73 20 3d 20 22 4e 6f 74 20 4d 6f 64 69 66  tus = "Not Modif
1880: 69 65 64 22 3b 0a 20 20 7d 0a 23 65 6e 64 69 66  ied";.  }.#endif
1890: 0a 0a 20 20 69 66 28 20 66 75 6c 6c 48 74 74 70  ..  if( fullHttp
18a0: 52 65 70 6c 79 20 29 7b 0a 20 20 20 20 70 72 69  Reply ){.    pri
18b0: 6e 74 66 28 22 48 54 54 50 2f 31 2e 30 20 25 64  ntf("HTTP/1.0 %d
18c0: 20 25 73 5c 72 5c 6e 22 2c 20 69 52 65 70 6c 79   %s\r\n", iReply
18d0: 53 74 61 74 75 73 2c 20 7a 52 65 70 6c 79 53 74  Status, zReplySt
18e0: 61 74 75 73 29 3b 0a 20 20 20 20 70 72 69 6e 74  atus);.    print
18f0: 66 28 22 44 61 74 65 3a 20 25 73 5c 72 5c 6e 22  f("Date: %s\r\n"
1900: 2c 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74  , cgi_rfc822_dat
1910: 65 73 74 61 6d 70 28 74 69 6d 65 28 30 29 29 29  estamp(time(0)))
1920: 3b 0a 20 20 20 20 70 72 69 6e 74 66 28 22 43 6f  ;.    printf("Co
1930: 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c  nnection: close\
1940: 72 5c 6e 22 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a  r\n");.  }else{.
1950: 20 20 20 20 70 72 69 6e 74 66 28 22 53 74 61 74      printf("Stat
1960: 75 73 3a 20 25 64 20 25 73 5c 72 5c 6e 22 2c 20  us: %d %s\r\n", 
1970: 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a 52  iReplyStatus, zR
1980: 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20 7d  eplyStatus);.  }
1990: 0a 0a 20 20 69 66 28 20 62 6c 6f 62 5f 73 69 7a  ..  if( blob_siz
19a0: 65 28 26 65 78 74 72 61 48 65 61 64 65 72 29 3e  e(&extraHeader)>
19b0: 30 20 29 7b 0a 20 20 20 20 70 72 69 6e 74 66 28  0 ){.    printf(
19c0: 22 25 73 22 2c 20 62 6c 6f 62 5f 62 75 66 66 65  "%s", blob_buffe
19d0: 72 28 26 65 78 74 72 61 48 65 61 64 65 72 29 29  r(&extraHeader))
19e0: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 67 2e 69  ;.  }..  if( g.i
19f0: 73 43 6f 6e 73 74 20 29 7b 0a 20 20 20 20 2f 2a  sConst ){.    /*
1a00: 20 63 6f 6e 73 74 61 6e 74 20 6d 65 61 6e 73 20   constant means 
1a10: 74 68 61 74 20 74 68 65 20 69 6e 70 75 74 20 55  that the input U
1a20: 52 4c 20 77 69 6c 6c 20 5f 6e 65 76 65 72 5f 20  RL will _never_ 
1a30: 67 65 6e 65 72 61 74 65 20 61 6e 79 74 68 69 6e  generate anythin
1a40: 67 0a 20 20 20 20 2a 2a 20 65 6c 73 65 2e 20 49  g.    ** else. I
1a50: 6e 20 74 68 65 20 63 61 73 65 20 6f 66 20 61 74  n the case of at
1a60: 74 61 63 68 6d 65 6e 74 73 2c 20 74 68 65 20 63  tachments, the c
1a70: 6f 6e 74 65 6e 74 73 20 77 6f 6e 27 74 20 63 68  ontents won't ch
1a80: 61 6e 67 65 20 62 65 63 61 75 73 65 0a 20 20 20  ange because.   
1a90: 20 2a 2a 20 61 6e 20 61 74 74 65 6d 70 74 20 74   ** an attempt t
1aa0: 6f 20 63 68 61 6e 67 65 20 74 68 65 6d 20 67 65  o change them ge
1ab0: 6e 65 72 61 74 65 73 20 61 20 6e 65 77 20 61 74  nerates a new at
1ac0: 74 61 63 68 6d 65 6e 74 20 6e 75 6d 62 65 72 2e  tachment number.
1ad0: 20 49 6e 20 74 68 65 0a 20 20 20 20 2a 2a 20 63   In the.    ** c
1ae0: 61 73 65 20 6f 66 20 6d 6f 73 74 20 2f 67 65 74  ase of most /get
1af0: 66 69 6c 65 20 63 61 6c 6c 73 20 66 6f 72 20 73  file calls for s
1b00: 70 65 63 69 66 69 63 20 76 65 72 73 69 6f 6e 73  pecific versions
1b10: 2c 20 74 68 65 20 6f 6e 6c 79 20 77 61 79 20 74  , the only way t
1b20: 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e 74 65 6e  he.    ** conten
1b30: 74 20 63 68 61 6e 67 65 73 20 69 73 20 69 66 20  t changes is if 
1b40: 73 6f 6d 65 6f 6e 65 20 62 72 65 61 6b 73 20 74  someone breaks t
1b50: 68 65 20 53 43 4d 2e 20 41 6e 64 20 69 66 20 74  he SCM. And if t
1b60: 68 61 74 20 68 61 70 70 65 6e 73 2c 20 61 0a 20  hat happens, a. 
1b70: 20 20 20 2a 2a 20 73 74 61 6c 65 20 63 61 63 68     ** stale cach
1b80: 65 20 69 73 20 74 68 65 20 6c 65 61 73 74 20 6f  e is the least o
1b90: 66 20 74 68 65 20 70 72 6f 62 6c 65 6d 2e 20 53  f the problem. S
1ba0: 6f 20 77 65 20 70 72 6f 76 69 64 65 20 61 6e 20  o we provide an 
1bb0: 45 78 70 69 72 65 73 0a 20 20 20 20 2a 2a 20 68  Expires.    ** h
1bc0: 65 61 64 65 72 20 73 65 74 20 74 6f 20 61 20 72  eader set to a r
1bd0: 65 61 73 6f 6e 61 62 6c 65 20 70 65 72 69 6f 64  easonable period
1be0: 20 28 64 65 66 61 75 6c 74 3a 20 6f 6e 65 20 77   (default: one w
1bf0: 65 65 6b 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20  eek)..    */.   
1c00: 20 2f 2a 74 69 6d 65 5f 74 20 65 78 70 69 72 65   /*time_t expire
1c10: 73 20 3d 20 74 69 6d 65 28 30 29 20 2b 20 61 74  s = time(0) + at
1c20: 6f 69 28 64 62 5f 63 6f 6e 66 69 67 28 22 63 6f  oi(db_config("co
1c30: 6e 73 74 61 6e 74 5f 65 78 70 69 72 65 73 22 2c  nstant_expires",
1c40: 22 36 30 34 38 30 30 22 29 29 3b 2a 2f 0a 20 20  "604800"));*/.  
1c50: 20 20 74 69 6d 65 5f 74 20 65 78 70 69 72 65 73    time_t expires
1c60: 20 3d 20 74 69 6d 65 28 30 29 20 2b 20 36 30 34   = time(0) + 604
1c70: 38 30 30 3b 0a 20 20 20 20 70 72 69 6e 74 66 28  800;.    printf(
1c80: 20 22 45 78 70 69 72 65 73 3a 20 25 73 5c 72 5c   "Expires: %s\r\
1c90: 6e 22 2c 20 63 67 69 5f 72 66 63 38 32 32 5f 64  n", cgi_rfc822_d
1ca0: 61 74 65 73 74 61 6d 70 28 65 78 70 69 72 65 73  atestamp(expires
1cb0: 29 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f  ));.  }..  /* Co
1cc0: 6e 74 65 6e 74 20 69 6e 74 65 6e 64 65 64 20 66  ntent intended f
1cd0: 6f 72 20 6c 6f 67 67 65 64 20 69 6e 20 75 73 65  or logged in use
1ce0: 72 73 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 62  rs should only b
1cf0: 65 20 63 61 63 68 65 64 20 69 6e 0a 20 20 2a 2a  e cached in.  **
1d00: 20 74 68 65 20 62 72 6f 77 73 65 72 2c 20 6e 6f   the browser, no
1d10: 74 20 73 6f 6d 65 20 73 68 61 72 65 64 20 6c 6f  t some shared lo
1d20: 63 61 74 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 70  cation..  */.  p
1d30: 72 69 6e 74 66 28 22 43 61 63 68 65 2d 63 6f 6e  rintf("Cache-con
1d40: 74 72 6f 6c 3a 20 70 72 69 76 61 74 65 5c 72 5c  trol: private\r\
1d50: 6e 22 29 3b 0a 0a 23 69 66 20 46 4f 53 53 49 4c  n");..#if FOSSIL
1d60: 5f 49 31 38 4e 0a 20 20 70 72 69 6e 74 66 28 20  _I18N.  printf( 
1d70: 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 25  "Content-Type: %
1d80: 73 3b 20 63 68 61 72 73 65 74 3d 25 73 5c 72 5c  s; charset=%s\r\
1d90: 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79 70 65  n", zContentType
1da0: 2c 20 6e 6c 5f 6c 61 6e 67 69 6e 66 6f 28 43 4f  , nl_langinfo(CO
1db0: 44 45 53 45 54 29 29 3b 0a 23 65 6c 73 65 0a 20  DESET));.#else. 
1dc0: 20 70 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e   printf( "Conten
1dd0: 74 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 72  t-Type: %s; char
1de0: 73 65 74 3d 49 53 4f 2d 38 38 35 39 2d 31 5c 72  set=ISO-8859-1\r
1df0: 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79 70  \n", zContentTyp
1e00: 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 69 66 28  e);.#endif.  if(
1e10: 20 73 74 72 63 6d 70 28 7a 43 6f 6e 74 65 6e 74   strcmp(zContent
1e20: 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74 69 6f  Type,"applicatio
1e30: 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 20  n/x-fossil")==0 
1e40: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 63 6f 6d 70  ){.    blob_comp
1e50: 72 65 73 73 28 26 63 67 69 43 6f 6e 74 65 6e 74  ress(&cgiContent
1e60: 2c 20 26 63 67 69 43 6f 6e 74 65 6e 74 29 3b 0a  , &cgiContent);.
1e70: 20 20 7d 0a 0a 20 20 69 66 28 20 69 52 65 70 6c    }..  if( iRepl
1e80: 79 53 74 61 74 75 73 20 21 3d 20 33 30 34 20 29  yStatus != 304 )
1e90: 20 7b 0a 20 20 20 20 70 72 69 6e 74 66 28 20 22   {.    printf( "
1ea0: 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20  Content-Length: 
1eb0: 25 64 5c 72 5c 6e 22 2c 20 62 6c 6f 62 5f 73 69  %d\r\n", blob_si
1ec0: 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 20  ze(&cgiContent) 
1ed0: 29 3b 0a 20 20 7d 0a 20 20 70 72 69 6e 74 66 28  );.  }.  printf(
1ee0: 22 5c 72 5c 6e 22 29 3b 0a 20 20 69 66 28 20 62  "\r\n");.  if( b
1ef0: 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e  lob_size(&cgiCon
1f00: 74 65 6e 74 29 3e 30 20 26 26 20 69 52 65 70 6c  tent)>0 && iRepl
1f10: 79 53 74 61 74 75 73 20 21 3d 20 33 30 34 20 29  yStatus != 304 )
1f20: 7b 0a 20 20 20 20 66 77 72 69 74 65 28 62 6c 6f  {.    fwrite(blo
1f30: 62 5f 62 75 66 66 65 72 28 26 63 67 69 43 6f 6e  b_buffer(&cgiCon
1f40: 74 65 6e 74 29 2c 20 31 2c 20 62 6c 6f 62 5f 73  tent), 1, blob_s
1f50: 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 29  ize(&cgiContent)
1f60: 2c 20 73 74 64 6f 75 74 29 3b 0a 20 20 7d 0a 20  , stdout);.  }. 
1f70: 20 43 47 49 44 45 42 55 47 28 28 22 44 4f 4e 45   CGIDEBUG(("DONE
1f80: 5c 6e 22 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  \n"));.}../*.** 
1f90: 44 6f 20 61 20 72 65 64 69 72 65 63 74 20 72 65  Do a redirect re
1fa0: 71 75 65 73 74 20 74 6f 20 74 68 65 20 55 52 4c  quest to the URL
1fb0: 20 67 69 76 65 6e 20 69 6e 20 74 68 65 20 61 72   given in the ar
1fc0: 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68  gument..**.** Th
1fd0: 65 20 55 52 4c 20 6d 75 73 74 20 62 65 20 72 65  e URL must be re
1fe0: 6c 61 74 69 76 65 20 74 6f 20 74 68 65 20 62 61  lative to the ba
1ff0: 73 65 20 6f 66 20 74 68 65 20 66 6f 73 73 69 6c  se of the fossil
2000: 20 73 65 72 76 65 72 2e 0a 2a 2f 0a 76 6f 69 64   server..*/.void
2010: 20 63 67 69 5f 72 65 64 69 72 65 63 74 28 63 6f   cgi_redirect(co
2020: 6e 73 74 20 63 68 61 72 20 2a 7a 55 52 4c 29 7b  nst char *zURL){
2030: 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 63 61 74 69  .  char *zLocati
2040: 6f 6e 3b 0a 20 20 43 47 49 44 45 42 55 47 28 28  on;.  CGIDEBUG((
2050: 22 72 65 64 69 72 65 63 74 20 74 6f 20 25 73 5c  "redirect to %s\
2060: 6e 22 2c 20 7a 55 52 4c 29 29 3b 0a 20 20 69 66  n", zURL));.  if
2070: 28 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22  ( strncmp(zURL,"
2080: 68 74 74 70 3a 22 2c 35 29 3d 3d 30 20 7c 7c 20  http:",5)==0 || 
2090: 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22 68 74  strncmp(zURL,"ht
20a0: 74 70 73 3a 22 2c 36 29 3d 3d 30 20 7c 7c 20 2a  tps:",6)==0 || *
20b0: 7a 55 52 4c 3d 3d 27 2f 27 20 29 7b 0a 20 20 20  zURL=='/' ){.   
20c0: 20 63 67 69 5f 70 61 6e 69 63 28 22 69 6e 76 61   cgi_panic("inva
20d0: 6c 69 64 20 72 65 64 69 72 65 63 74 20 55 52 4c  lid redirect URL
20e0: 3a 20 25 73 22 2c 20 7a 55 52 4c 29 3b 0a 20 20  : %s", zURL);.  
20f0: 7d 0a 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20  }.  zLocation = 
2100: 6d 70 72 69 6e 74 66 28 22 4c 6f 63 61 74 69 6f  mprintf("Locatio
2110: 6e 3a 20 25 73 2f 25 73 5c 72 5c 6e 22 2c 20 67  n: %s/%s\r\n", g
2120: 2e 7a 42 61 73 65 55 52 4c 2c 20 7a 55 52 4c 29  .zBaseURL, zURL)
2130: 3b 0a 20 20 63 67 69 5f 61 70 70 65 6e 64 5f 68  ;.  cgi_append_h
2140: 65 61 64 65 72 28 7a 4c 6f 63 61 74 69 6f 6e 29  eader(zLocation)
2150: 3b 0a 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f  ;.  cgi_reset_co
2160: 6e 74 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f 70  ntent();.  cgi_p
2170: 72 69 6e 74 66 28 22 3c 68 74 6d 6c 3e 5c 6e 3c  rintf("<html>\n<
2180: 70 3e 52 65 64 69 72 65 63 74 20 74 6f 20 25 68  p>Redirect to %h
2190: 3c 2f 70 3e 5c 6e 3c 2f 68 74 6d 6c 3e 5c 6e 22  </p>\n</html>\n"
21a0: 2c 20 7a 55 52 4c 29 3b 0a 20 20 63 67 69 5f 73  , zURL);.  cgi_s
21b0: 65 74 5f 73 74 61 74 75 73 28 33 30 32 2c 20 22  et_status(302, "
21c0: 4d 6f 76 65 64 20 54 65 6d 70 6f 72 61 72 69 6c  Moved Temporaril
21d0: 79 22 29 3b 0a 20 20 66 72 65 65 28 7a 4c 6f 63  y");.  free(zLoc
21e0: 61 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65  ation);.  cgi_re
21f0: 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29  ply();.  exit(0)
2200: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f 72  ;.}../*.** Infor
2210: 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 61 6c 6c  mation about all
2220: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
2230: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 20 61 72  s and cookies ar
2240: 65 20 73 74 6f 72 65 64 0a 2a 2a 20 69 6e 20 74  e stored.** in t
2250: 68 65 73 65 20 76 61 72 69 61 62 6c 65 73 2e 0a  hese variables..
2260: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 41  */.static int nA
2270: 6c 6c 6f 63 51 50 20 3d 20 30 3b 20 2f 2a 20 53  llocQP = 0; /* S
2280: 70 61 63 65 20 61 6c 6c 6f 63 61 74 65 64 20 66  pace allocated f
2290: 6f 72 20 61 50 61 72 61 6d 51 50 5b 5d 20 2a 2f  or aParamQP[] */
22a0: 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 55 73 65  .static int nUse
22b0: 64 51 50 20 3d 20 30 3b 20 20 2f 2a 20 53 70 61  dQP = 0;  /* Spa
22c0: 63 65 20 61 63 74 75 61 6c 6c 79 20 75 73 65 64  ce actually used
22d0: 20 69 6e 20 61 50 61 72 61 6d 51 50 5b 5d 20 2a   in aParamQP[] *
22e0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 6f 72  /.static int sor
22f0: 74 51 50 20 3d 20 30 3b 20 20 20 2f 2a 20 54 72  tQP = 0;   /* Tr
2300: 75 65 20 69 66 20 61 50 61 72 61 6d 51 50 5b 5d  ue if aParamQP[]
2310: 20 6e 65 65 64 73 20 73 6f 72 74 69 6e 67 20 2a   needs sorting *
2320: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65 71  /.static int seq
2330: 51 50 20 3d 20 30 3b 20 20 20 20 2f 2a 20 53 65  QP = 0;    /* Se
2340: 71 75 65 6e 63 65 20 6e 75 6d 62 65 72 73 20 2a  quence numbers *
2350: 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 20  /.static struct 
2360: 51 50 61 72 61 6d 20 7b 20 20 20 2f 2a 20 4f 6e  QParam {   /* On
2370: 65 20 65 6e 74 72 79 20 66 6f 72 20 65 61 63 68  e entry for each
2380: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
2390: 20 6f 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20   or cookie */.  
23a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d  const char *zNam
23b0: 65 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61 72  e;        /* Par
23c0: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65  ameter or cookie
23d0: 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74   name */.  const
23e0: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 20 20   char *zValue;  
23f0: 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f 66       /* Value of
2400: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   the query param
2410: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 2a  eter or cookie *
2420: 2f 0a 20 20 69 6e 74 20 73 65 71 3b 20 20 20 20  /.  int seq;    
2430: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a                /*
2440: 20 4f 72 64 65 72 20 6f 66 20 69 6e 73 65 72 74   Order of insert
2450: 69 6f 6e 20 2a 2f 0a 7d 20 2a 61 50 61 72 61 6d  ion */.} *aParam
2460: 51 50 3b 20 20 20 20 20 20 20 20 20 20 20 20 20  QP;             
2470: 2f 2a 20 41 6e 20 61 72 72 61 79 20 6f 66 20 61  /* An array of a
2480: 6c 6c 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e  ll parameters an
2490: 64 20 63 6f 6f 6b 69 65 73 20 2a 2f 0a 0a 2f 2a  d cookies */../*
24a0: 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 68 65 72 20  .** Add another 
24b0: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20  query parameter 
24c0: 6f 72 20 63 6f 6f 6b 69 65 20 74 6f 20 74 68 65  or cookie to the
24d0: 20 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a   parameter set..
24e0: 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 74 68 65 20  ** zName is the 
24f0: 6e 61 6d 65 20 6f 66 20 74 68 65 20 71 75 65 72  name of the quer
2500: 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63  y parameter or c
2510: 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 61 6c 75 65  ookie and zValue
2520: 0a 2a 2a 20 69 73 20 69 74 73 20 66 75 6c 6c 79  .** is its fully
2530: 20 64 65 63 6f 64 65 64 20 76 61 6c 75 65 2e 0a   decoded value..
2540: 2a 2a 0a 2a 2a 20 7a 4e 61 6d 65 20 61 6e 64 20  **.** zName and 
2550: 7a 56 61 6c 75 65 20 61 72 65 20 6e 6f 74 20 63  zValue are not c
2560: 6f 70 69 65 64 20 61 6e 64 20 6d 75 73 74 20 6e  opied and must n
2570: 6f 74 20 63 68 61 6e 67 65 20 6f 72 20 62 65 0a  ot change or be.
2580: 2a 2a 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 61  ** deallocated a
2590: 66 74 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e  fter this routin
25a0: 65 20 72 65 74 75 72 6e 73 2e 0a 2a 2f 0a 73 74  e returns..*/.st
25b0: 61 74 69 63 20 76 6f 69 64 20 63 67 69 5f 73 65  atic void cgi_se
25c0: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f  t_parameter_noco
25d0: 70 79 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  py(const char *z
25e0: 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72  Name, const char
25f0: 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 69 66 28   *zValue){.  if(
2600: 20 6e 41 6c 6c 6f 63 51 50 3c 3d 6e 55 73 65 64   nAllocQP<=nUsed
2610: 51 50 20 29 7b 0a 20 20 20 20 6e 41 6c 6c 6f 63  QP ){.    nAlloc
2620: 51 50 20 3d 20 6e 41 6c 6c 6f 63 51 50 2a 32 20  QP = nAllocQP*2 
2630: 2b 20 31 30 3b 0a 20 20 20 20 61 50 61 72 61 6d  + 10;.    aParam
2640: 51 50 20 3d 20 72 65 61 6c 6c 6f 63 28 20 61 50  QP = realloc( aP
2650: 61 72 61 6d 51 50 2c 20 6e 41 6c 6c 6f 63 51 50  aramQP, nAllocQP
2660: 2a 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51 50  *sizeof(aParamQP
2670: 5b 30 5d 29 20 29 3b 0a 20 20 20 20 69 66 28 20  [0]) );.    if( 
2680: 61 50 61 72 61 6d 51 50 3d 3d 30 20 29 20 65 78  aParamQP==0 ) ex
2690: 69 74 28 31 29 3b 0a 20 20 7d 0a 20 20 61 50 61  it(1);.  }.  aPa
26a0: 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a  ramQP[nUsedQP].z
26b0: 4e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20  Name = zName;.  
26c0: 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51 50  aParamQP[nUsedQP
26d0: 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56 61 6c 75  ].zValue = zValu
26e0: 65 3b 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55  e;.  aParamQP[nU
26f0: 73 65 64 51 50 5d 2e 73 65 71 20 3d 20 73 65 71  sedQP].seq = seq
2700: 51 50 2b 2b 3b 0a 20 20 6e 55 73 65 64 51 50 2b  QP++;.  nUsedQP+
2710: 2b 3b 0a 20 20 73 6f 72 74 51 50 20 3d 20 31 3b  +;.  sortQP = 1;
2720: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e  .}../*.** Add an
2730: 6f 74 68 65 72 20 71 75 65 72 79 20 70 61 72 61  other query para
2740: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20  meter or cookie 
2750: 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 72  to the parameter
2760: 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 69   set..** zName i
2770: 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68  s the name of th
2780: 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  e query paramete
2790: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61 6e 64 20  r or cookie and 
27a0: 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20 69 74 73  zValue.** is its
27b0: 20 66 75 6c 6c 79 20 64 65 63 6f 64 65 64 20 76   fully decoded v
27c0: 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 43 6f 70 69  alue..**.** Copi
27d0: 65 73 20 61 72 65 20 6d 61 64 65 20 6f 66 20 62  es are made of b
27e0: 6f 74 68 20 74 68 65 20 7a 4e 61 6d 65 20 61 6e  oth the zName an
27f0: 64 20 7a 56 61 6c 75 65 20 70 61 72 61 6d 65 74  d zValue paramet
2800: 65 72 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69  ers..*/.void cgi
2810: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 28 63  _set_parameter(c
2820: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65  onst char *zName
2830: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56  , const char *zV
2840: 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f 73 65 74  alue){.  cgi_set
2850: 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70  _parameter_nocop
2860: 79 28 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a  y(mprintf("%s",z
2870: 4e 61 6d 65 29 2c 20 6d 70 72 69 6e 74 66 28 22  Name), mprintf("
2880: 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a  %s",zValue));.}.
2890: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 71 75 65  ./*.** Add a que
28a0: 72 79 20 70 61 72 61 6d 65 74 65 72 2e 20 20 54  ry parameter.  T
28b0: 68 65 20 7a 4e 61 6d 65 20 70 6f 72 74 69 6f 6e  he zName portion
28c0: 20 69 73 20 66 69 78 65 64 20 62 75 74 20 61 20   is fixed but a 
28d0: 63 6f 70 79 0a 2a 2a 20 6d 75 73 74 20 62 65 20  copy.** must be 
28e0: 6d 61 64 65 20 6f 66 20 7a 56 61 6c 75 65 2e 0a  made of zValue..
28f0: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 65  */.void cgi_sete
2900: 6e 76 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  nv(const char *z
2910: 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72  Name, const char
2920: 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69   *zValue){.  cgi
2930: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e  _set_parameter_n
2940: 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 6d 70 72  ocopy(zName, mpr
2950: 69 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65  intf("%s",zValue
2960: 29 29 3b 0a 7d 0a 20 0a 0a 2f 2a 0a 2a 2a 20 41  ));.}. ../*.** A
2970: 64 64 20 61 20 6c 69 73 74 20 6f 66 20 71 75 65  dd a list of que
2980: 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 6f 72  ry parameters or
2990: 20 63 6f 6f 6b 69 65 73 20 74 6f 20 74 68 65 20   cookies to the 
29a0: 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a  parameter set..*
29b0: 2a 0a 2a 2a 20 45 61 63 68 20 70 61 72 61 6d 65  *.** Each parame
29c0: 74 65 72 20 69 73 20 6f 66 20 74 68 65 20 66 6f  ter is of the fo
29d0: 72 6d 20 4e 41 4d 45 3d 56 41 4c 55 45 2e 20 20  rm NAME=VALUE.  
29e0: 42 6f 74 68 20 74 68 65 20 4e 41 4d 45 20 61 6e  Both the NAME an
29f0: 64 20 74 68 65 0a 2a 2a 20 56 41 4c 55 45 20 6d  d the.** VALUE m
2a00: 61 79 20 62 65 20 75 72 6c 2d 65 6e 63 6f 64 65  ay be url-encode
2a10: 64 20 28 22 2b 22 20 66 6f 72 20 73 70 61 63 65  d ("+" for space
2a20: 2c 20 22 25 48 48 22 20 66 6f 72 20 6f 74 68 65  , "%HH" for othe
2a30: 72 20 73 70 65 63 69 61 6c 0a 2a 2a 20 63 68 61  r special.** cha
2a40: 72 61 63 74 65 72 73 29 2e 20 20 42 75 74 20 74  racters).  But t
2a50: 68 69 73 20 72 6f 75 74 69 6e 65 20 61 73 73 75  his routine assu
2a60: 6d 65 73 20 74 68 61 74 20 4e 41 4d 45 20 63 6f  mes that NAME co
2a70: 6e 74 61 69 6e 73 20 6e 6f 0a 2a 2a 20 73 70 65  ntains no.** spe
2a80: 63 69 61 6c 20 63 68 61 72 61 63 74 65 72 20 61  cial character a
2a90: 6e 64 20 74 68 65 72 65 66 6f 72 65 20 64 6f 65  nd therefore doe
2aa0: 73 20 6e 6f 74 20 64 65 63 6f 64 65 20 69 74 2e  s not decode it.
2ab0: 0a 2a 2a 0a 2a 2a 20 49 66 20 4e 41 4d 45 20 62  .**.** If NAME b
2ac0: 65 67 69 6e 73 20 77 69 74 68 20 61 6e 6f 74 68  egins with anoth
2ad0: 65 72 20 6f 74 68 65 72 20 74 68 61 6e 20 61 20  er other than a 
2ae0: 6c 6f 77 65 72 2d 63 61 73 65 20 6c 65 74 74 65  lower-case lette
2af0: 72 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20 65 6e  r then.** the en
2b00: 74 69 72 65 20 4e 41 4d 45 3d 56 41 4c 55 45 20  tire NAME=VALUE 
2b10: 74 65 72 6d 20 69 73 20 69 67 6e 6f 72 65 64 2e  term is ignored.
2b20: 20 20 48 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a 20 20    Hence:.**.**  
2b30: 20 20 20 20 2a 20 20 63 6f 6f 6b 69 65 73 20 61      *  cookies a
2b40: 6e 64 20 71 75 65 72 79 20 70 61 72 61 6d 65 74  nd query paramet
2b50: 65 72 73 20 74 68 61 74 20 68 61 76 65 20 75 70  ers that have up
2b60: 70 65 72 63 61 73 65 20 6e 61 6d 65 73 0a 2a 2a  percase names.**
2b70: 20 20 20 20 20 20 20 20 20 61 72 65 20 69 67 6e           are ign
2b80: 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20  ored..**.**     
2b90: 20 2a 20 20 69 74 20 69 73 20 69 6d 70 6f 73 73   *  it is imposs
2ba0: 69 62 6c 65 20 66 6f 72 20 61 20 63 6f 6f 6b 69  ible for a cooki
2bb0: 65 20 6f 72 20 71 75 65 72 79 20 70 61 72 61 6d  e or query param
2bc0: 65 74 65 72 20 74 6f 0a 2a 2a 20 20 20 20 20 20  eter to.**      
2bd0: 20 20 20 6f 76 65 72 72 69 64 65 20 74 68 65 20     override the 
2be0: 76 61 6c 75 65 20 6f 66 20 61 6e 20 65 6e 76 69  value of an envi
2bf0: 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65  ronment variable
2c00: 20 73 69 6e 63 65 0a 2a 2a 20 20 20 20 20 20 20   since.**       
2c10: 20 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61    environment va
2c20: 72 69 61 62 6c 65 73 20 61 6c 77 61 79 73 20 68  riables always h
2c30: 61 76 65 20 75 70 70 65 72 63 61 73 65 20 6e 61  ave uppercase na
2c40: 6d 65 73 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d  mes..**.** Param
2c50: 65 74 65 72 73 20 61 72 65 20 73 65 70 61 72 61  eters are separa
2c60: 74 65 64 20 62 79 20 74 68 65 20 22 74 65 72 6d  ted by the "term
2c70: 69 6e 61 74 6f 72 22 20 63 68 61 72 61 63 74 65  inator" characte
2c80: 72 2e 20 20 57 68 69 74 65 73 70 61 63 65 0a 2a  r.  Whitespace.*
2c90: 2a 20 62 65 66 6f 72 65 20 74 68 65 20 4e 41 4d  * before the NAM
2ca0: 45 20 69 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a  E is ignored..**
2cb0: 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74 20 73 74  .** The input st
2cc0: 72 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69  ring "z" is modi
2cd0: 66 69 65 64 20 62 75 74 20 6e 6f 20 63 6f 70 69  fied but no copi
2ce0: 65 73 20 69 73 20 6d 61 64 65 2e 20 20 22 7a 22  es is made.  "z"
2cf0: 0a 2a 2a 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62  .** should not b
2d00: 65 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 6f 72  e deallocated or
2d10: 20 63 68 61 6e 67 65 64 20 61 67 61 69 6e 20 61   changed again a
2d20: 66 74 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e  fter this routin
2d30: 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 6f 72 20  e.** returns or 
2d40: 69 74 20 77 69 6c 6c 20 63 6f 72 72 75 70 74 20  it will corrupt 
2d50: 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 74 61  the parameter ta
2d60: 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76  ble..*/.static v
2d70: 6f 69 64 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69  oid add_param_li
2d80: 73 74 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20  st(char *z, int 
2d90: 74 65 72 6d 69 6e 61 74 6f 72 29 7b 0a 20 20 77  terminator){.  w
2da0: 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20  hile( *z ){.    
2db0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20  char *zName;.   
2dc0: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20   char *zValue;. 
2dd0: 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63     while( isspac
2de0: 65 28 2a 7a 29 20 29 7b 20 7a 2b 2b 3b 20 7d 0a  e(*z) ){ z++; }.
2df0: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20      zName = z;. 
2e00: 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20     while( *z && 
2e10: 2a 7a 21 3d 27 3d 27 20 26 26 20 2a 7a 21 3d 74  *z!='=' && *z!=t
2e20: 65 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b  erminator ){ z++
2e30: 3b 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d  ; }.    if( *z==
2e40: 27 3d 27 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20  '=' ){.      *z 
2e50: 3d 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a  = 0;.      z++;.
2e60: 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 7a        zValue = z
2e70: 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a  ;.      while( *
2e80: 7a 20 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61  z && *z!=termina
2e90: 74 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20  tor ){ z++; }.  
2ea0: 20 20 20 20 69 66 28 20 2a 7a 20 29 7b 0a 20 20      if( *z ){.  
2eb0: 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20        *z = 0;.  
2ec0: 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20        z++;.     
2ed0: 20 7d 0a 20 20 20 20 20 20 64 65 68 74 74 70 69   }.      dehttpi
2ee0: 7a 65 28 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20  ze(zValue);.    
2ef0: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28  }else{.      if(
2f00: 20 2a 7a 20 29 7b 20 2a 7a 2b 2b 20 3d 20 30 3b   *z ){ *z++ = 0;
2f10: 20 7d 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20   }.      zValue 
2f20: 3d 20 22 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20  = "";.    }.    
2f30: 69 66 28 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d  if( islower(zNam
2f40: 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 63  e[0]) ){.      c
2f50: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72  gi_set_parameter
2f60: 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a  _nocopy(zName, z
2f70: 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d 0a 20 20  Value);.    }.  
2f80: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 2a 70 7a 20 69  }.}../*.** *pz i
2f90: 73 20 61 20 73 74 72 69 6e 67 20 74 68 61 74 20  s a string that 
2fa0: 63 6f 6e 73 69 73 74 73 20 6f 66 20 6d 75 6c 74  consists of mult
2fb0: 69 70 6c 65 20 6c 69 6e 65 73 20 6f 66 20 74 65  iple lines of te
2fc0: 78 74 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75  xt.  This.** rou
2fd0: 74 69 6e 65 20 66 69 6e 64 73 20 74 68 65 20 65  tine finds the e
2fe0: 6e 64 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e  nd of the curren
2ff0: 74 20 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 61  t line of text a
3000: 6e 64 20 63 6f 6e 76 65 72 74 73 0a 2a 2a 20 74  nd converts.** t
3010: 68 65 20 22 5c 6e 22 20 6f 72 20 22 5c 72 5c 6e  he "\n" or "\r\n
3020: 22 20 74 68 61 74 20 65 6e 64 73 20 74 68 61 74  " that ends that
3030: 20 6c 69 6e 65 20 69 6e 74 6f 20 61 20 22 5c 30   line into a "\0
3040: 30 30 22 2e 20 20 49 74 20 74 68 65 6e 0a 2a 2a  00".  It then.**
3050: 20 61 64 76 61 6e 63 65 73 20 2a 70 7a 20 74 6f   advances *pz to
3060: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f   the beginning o
3070: 66 20 74 68 65 20 6e 65 78 74 20 6c 69 6e 65 20  f the next line 
3080: 61 6e 64 20 72 65 74 75 72 6e 73 20 74 68 65 0a  and returns the.
3090: 2a 2a 20 70 72 65 76 69 6f 75 73 20 76 61 6c 75  ** previous valu
30a0: 65 20 6f 66 20 2a 70 7a 20 28 77 68 69 63 68 20  e of *pz (which 
30b0: 69 73 20 74 68 65 20 73 74 61 72 74 20 6f 66 20  is the start of 
30c0: 74 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65  the current line
30d0: 2e 29 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61  .).*/.static cha
30e0: 72 20 2a 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d  r *get_line_from
30f0: 5f 73 74 72 69 6e 67 28 63 68 61 72 20 2a 2a 70  _string(char **p
3100: 7a 2c 20 69 6e 74 20 2a 70 4c 65 6e 29 7b 0a 20  z, int *pLen){. 
3110: 20 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a   char *z = *pz;.
3120: 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a    int i;.  if( z
3130: 5b 30 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20  [0]==0 ) return 
3140: 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 5b  0;.  for(i=0; z[
3150: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66  i]; i++){.    if
3160: 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29 7b 0a  ( z[i]=='\n' ){.
3170: 20 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26        if( i>0 &&
3180: 20 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 7b   z[i-1]=='\r' ){
3190: 0a 20 20 20 20 20 20 20 20 7a 5b 69 2d 31 5d 20  .        z[i-1] 
31a0: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65  = 0;.      }else
31b0: 7b 0a 20 20 20 20 20 20 20 20 7a 5b 69 5d 20 3d  {.        z[i] =
31c0: 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20   0;.      }.    
31d0: 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 62 72 65    i++;.      bre
31e0: 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20  ak;.    }.  }.  
31f0: 2a 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 2a  *pz = &z[i];.  *
3200: 70 4c 65 6e 20 2d 3d 20 69 3b 0a 20 20 72 65 74  pLen -= i;.  ret
3210: 75 72 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  urn z;.}../*.** 
3220: 54 68 65 20 69 6e 70 75 74 20 2a 70 7a 20 70 6f  The input *pz po
3230: 69 6e 74 73 20 74 6f 20 63 6f 6e 74 65 6e 74 20  ints to content 
3240: 74 68 61 74 20 69 73 20 74 65 72 6d 69 6e 61 74  that is terminat
3250: 65 64 20 62 79 20 61 20 22 5c 72 5c 6e 22 0a 2a  ed by a "\r\n".*
3260: 2a 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74 68  * followed by th
3270: 65 20 62 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72  e boundry marker
3280: 20 7a 42 6f 75 6e 64 72 79 2e 20 20 41 6e 20 65   zBoundry.  An e
3290: 78 74 72 61 20 22 2d 2d 22 20 6d 61 79 20 6f 72  xtra "--" may or
32a0: 0a 2a 2a 20 6d 61 79 20 6e 6f 74 20 62 65 20 61  .** may not be a
32b0: 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 62  ppended to the b
32c0: 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 2e 20 20  oundry marker.  
32d0: 54 68 65 72 65 20 61 72 65 20 2a 70 4c 65 6e 20  There are *pLen 
32e0: 63 68 61 72 61 63 74 65 72 73 0a 2a 2a 20 69 6e  characters.** in
32f0: 20 2a 70 7a 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73   *pz..**.** This
3300: 20 72 6f 75 74 69 6e 65 20 61 64 64 73 20 61 20   routine adds a 
3310: 22 5c 30 30 30 22 20 74 6f 20 74 68 65 20 65 6e  "\000" to the en
3320: 64 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74  d of the content
3330: 20 28 6f 76 65 72 77 72 69 74 69 6e 67 0a 2a 2a   (overwriting.**
3340: 20 74 68 65 20 22 5c 72 5c 6e 22 29 20 61 6e 64   the "\r\n") and
3350: 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74   returns a point
3360: 65 72 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e  er to the conten
3370: 74 2e 20 20 54 68 65 20 2a 70 7a 20 69 6e 70 75  t.  The *pz inpu
3380: 74 0a 2a 2a 20 69 73 20 61 64 6a 75 73 74 65 64  t.** is adjusted
3390: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65   to point to the
33a0: 20 66 69 72 73 74 20 6c 69 6e 65 20 66 6f 6c 6c   first line foll
33b0: 6f 77 69 6e 67 20 74 68 65 20 62 6f 75 6e 64 72  owing the boundr
33c0: 79 2e 0a 2a 2a 20 54 68 65 20 6c 65 6e 67 74 68  y..** The length
33d0: 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20   of the content 
33e0: 69 73 20 73 74 6f 72 65 64 20 69 6e 20 2a 70 6e  is stored in *pn
33f0: 43 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74  Content..*/.stat
3400: 69 63 20 63 68 61 72 20 2a 67 65 74 5f 62 6f 75  ic char *get_bou
3410: 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28 0a 20 20  nded_content(.  
3420: 63 68 61 72 20 2a 2a 70 7a 2c 20 20 20 20 20 20  char **pz,      
3430: 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 61     /* Content ta
3440: 6b 65 6e 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f  ken from here */
3450: 0a 20 20 69 6e 74 20 2a 70 4c 65 6e 2c 20 20 20  .  int *pLen,   
3460: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20        /* Number 
3470: 6f 66 20 62 79 74 65 73 20 6f 66 20 64 61 74 61  of bytes of data
3480: 20 69 6e 20 28 2a 70 7a 29 5b 5d 20 2a 2f 0a 20   in (*pz)[] */. 
3490: 20 63 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 2c   char *zBoundry,
34a0: 20 20 20 20 2f 2a 20 42 6f 75 6e 64 72 79 20 74      /* Boundry t
34b0: 65 78 74 20 6d 61 72 6b 69 6e 67 20 74 68 65 20  ext marking the 
34c0: 65 6e 64 20 6f 66 20 63 6f 6e 74 65 6e 74 20 2a  end of content *
34d0: 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6e 74 65  /.  int *pnConte
34e0: 6e 74 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20  nt     /* Write 
34f0: 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20  the size of the 
3500: 63 6f 6e 74 65 6e 74 20 68 65 72 65 20 2a 2f 0a  content here */.
3510: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 2a  ){.  char *z = *
3520: 70 7a 3b 0a 20 20 69 6e 74 20 6c 65 6e 20 3d 20  pz;.  int len = 
3530: 2a 70 4c 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a  *pLen;.  int i;.
3540: 20 20 69 6e 74 20 6e 42 6f 75 6e 64 72 79 20 3d    int nBoundry =
3550: 20 73 74 72 6c 65 6e 28 7a 42 6f 75 6e 64 72 79   strlen(zBoundry
3560: 29 3b 0a 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20  );.  *pnContent 
3570: 3d 20 6c 65 6e 3b 0a 20 20 66 6f 72 28 69 3d 30  = len;.  for(i=0
3580: 3b 20 69 3c 6c 65 6e 3b 20 69 2b 2b 29 7b 0a 20  ; i<len; i++){. 
3590: 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e     if( z[i]=='\n
35a0: 27 20 26 26 20 73 74 72 6e 63 6d 70 28 7a 42 6f  ' && strncmp(zBo
35b0: 75 6e 64 72 79 2c 20 26 7a 5b 69 2b 31 5d 2c 20  undry, &z[i+1], 
35c0: 6e 42 6f 75 6e 64 72 79 29 3d 3d 30 20 29 7b 0a  nBoundry)==0 ){.
35d0: 20 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26        if( i>0 &&
35e0: 20 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 20   z[i-1]=='\r' ) 
35f0: 69 2d 2d 3b 0a 20 20 20 20 20 20 7a 5b 69 5d 20  i--;.      z[i] 
3600: 3d 20 30 3b 0a 20 20 20 20 20 20 2a 70 6e 43 6f  = 0;.      *pnCo
3610: 6e 74 65 6e 74 20 3d 20 69 3b 0a 20 20 20 20 20  ntent = i;.     
3620: 20 69 20 2b 3d 20 6e 42 6f 75 6e 64 72 79 3b 0a   i += nBoundry;.
3630: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20        break;.   
3640: 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26   }.  }.  *pz = &
3650: 7a 5b 69 5d 3b 0a 20 20 67 65 74 5f 6c 69 6e 65  z[i];.  get_line
3660: 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 70 7a 2c  _from_string(pz,
3670: 20 70 4c 65 6e 29 3b 0a 20 20 72 65 74 75 72 6e   pLen);.  return
3680: 20 7a 3b 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a   z;      .}../*.
3690: 2a 2a 20 54 6f 6b 65 6e 69 7a 65 20 61 20 6c 69  ** Tokenize a li
36a0: 6e 65 20 6f 66 20 74 65 78 74 20 69 6e 74 6f 20  ne of text into 
36b0: 61 73 20 6d 61 6e 79 20 61 73 20 6e 41 72 67 20  as many as nArg 
36c0: 74 6f 6b 65 6e 73 2e 20 20 4d 61 6b 65 0a 2a 2a  tokens.  Make.**
36d0: 20 61 7a 41 72 67 5b 5d 20 70 6f 69 6e 74 20 74   azArg[] point t
36e0: 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 65  o the start of e
36f0: 61 63 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a  ach token..**.**
3700: 20 54 6f 6b 65 6e 73 20 63 6f 6e 73 69 73 74 20   Tokens consist 
3710: 6f 66 20 73 70 61 63 65 20 6f 72 20 73 65 6d 69  of space or semi
3720: 2d 63 6f 6c 6f 6e 20 64 65 6c 69 6d 69 74 65 64  -colon delimited
3730: 20 77 6f 72 64 73 20 6f 72 0a 2a 2a 20 73 74 72   words or.** str
3740: 69 6e 67 73 20 69 6e 73 69 64 65 20 64 6f 75 62  ings inside doub
3750: 6c 65 2d 71 75 6f 74 65 73 2e 20 20 45 78 61 6d  le-quotes.  Exam
3760: 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 63 6f  ple:.**.**    co
3770: 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f  ntent-dispositio
3780: 6e 3a 20 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61  n: form-data; na
3790: 6d 65 3d 22 66 6e 22 3b 20 66 69 6c 65 6e 61 6d  me="fn"; filenam
37a0: 65 3d 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a  e="index.html".*
37b0: 2a 0a 2a 2a 20 54 68 65 20 6c 69 6e 65 20 61 62  *.** The line ab
37c0: 6f 76 65 20 69 73 20 74 6f 6b 65 6e 69 7a 65 64  ove is tokenized
37d0: 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a   as follows:.**.
37e0: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 30 5d 20 3d  **    azArg[0] =
37f0: 20 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73   "content-dispos
3800: 69 74 69 6f 6e 3a 22 0a 2a 2a 20 20 20 20 61 7a  ition:".**    az
3810: 41 72 67 5b 31 5d 20 3d 20 22 66 6f 72 6d 2d 64  Arg[1] = "form-d
3820: 61 74 61 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67  ata".**    azArg
3830: 5b 32 5d 20 3d 20 22 6e 61 6d 65 3d 22 0a 2a 2a  [2] = "name=".**
3840: 20 20 20 20 61 7a 41 72 67 5b 33 5d 20 3d 20 22      azArg[3] = "
3850: 66 6e 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b  fn".**    azArg[
3860: 34 5d 20 3d 20 22 66 69 6c 65 6e 61 6d 65 3d 22  4] = "filename="
3870: 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 35 5d 20  .**    azArg[5] 
3880: 3d 20 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a  = "index.html".*
3890: 2a 20 20 20 20 61 7a 41 72 67 5b 36 5d 20 3d 20  *    azArg[6] = 
38a0: 30 3b 0a 2a 2a 0a 2a 2a 20 27 5c 30 30 30 27 20  0;.**.** '\000' 
38b0: 63 68 61 72 61 63 74 65 72 73 20 61 72 65 20 69  characters are i
38c0: 6e 73 65 72 74 65 64 20 69 6e 20 7a 5b 5d 20 61  nserted in z[] a
38d0: 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63  t the end of eac
38e0: 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 54 68 69 73  h token..** This
38f0: 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73   routine returns
3900: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65   the total numbe
3910: 72 20 6f 66 20 74 6f 6b 65 6e 73 20 6f 6e 20 74  r of tokens on t
3920: 68 65 20 6c 69 6e 65 2c 20 36 0a 2a 2a 20 69 6e  he line, 6.** in
3930: 20 74 68 65 20 65 78 61 6d 70 6c 65 20 61 62 6f   the example abo
3940: 76 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ve..*/.static in
3950: 74 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28  t tokenize_line(
3960: 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6d 78 41  char *z, int mxA
3970: 72 67 2c 20 63 68 61 72 20 2a 2a 61 7a 41 72 67  rg, char **azArg
3980: 29 7b 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a  ){.  int i = 0;.
3990: 20 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20    while( *z ){. 
39a0: 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63     while( isspac
39b0: 65 28 2a 7a 29 20 7c 7c 20 2a 7a 3d 3d 27 3b 27  e(*z) || *z==';'
39c0: 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69   ){ z++; }.    i
39d0: 66 28 20 2a 7a 3d 3d 27 22 27 20 26 26 20 7a 5b  f( *z=='"' && z[
39e0: 31 5d 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d  1] ){.      *z =
39f0: 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20   0;.      z++;. 
3a00: 20 20 20 20 20 69 66 28 20 69 3c 6d 78 41 72 67       if( i<mxArg
3a10: 2d 31 20 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d  -1 ){ azArg[i++]
3a20: 20 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68   = z; }.      wh
3a30: 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27  ile( *z && *z!='
3a40: 22 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20  "' ){ z++; }.   
3a50: 20 20 20 69 66 28 20 2a 7a 3d 3d 30 20 29 20 62     if( *z==0 ) b
3a60: 72 65 61 6b 3b 0a 20 20 20 20 20 20 2a 7a 20 3d  reak;.      *z =
3a70: 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20   0;.      z++;. 
3a80: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
3a90: 69 66 28 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b  if( i<mxArg-1 ){
3aa0: 20 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b   azArg[i++] = z;
3ab0: 20 7d 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20   }.      while( 
3ac0: 2a 7a 20 26 26 20 21 69 73 73 70 61 63 65 28 2a  *z && !isspace(*
3ad0: 7a 29 20 26 26 20 2a 7a 21 3d 27 3b 27 20 26 26  z) && *z!=';' &&
3ae0: 20 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b   *z!='"' ){ z++;
3af0: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20   }.      if( *z 
3b00: 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b 0a 20 20  && *z!='"' ){.  
3b10: 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20        *z = 0;.  
3b20: 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20        z++;.     
3b30: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61   }.    }.  }.  a
3b40: 7a 41 72 67 5b 69 5d 20 3d 20 30 3b 0a 20 20 72  zArg[i] = 0;.  r
3b50: 65 74 75 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn i;.}../*.*
3b60: 2a 20 53 63 61 6e 20 74 68 65 20 6d 75 6c 74 69  * Scan the multi
3b70: 70 61 72 74 2d 66 6f 72 6d 20 63 6f 6e 74 65 6e  part-form conten
3b80: 74 20 61 6e 64 20 6d 61 6b 65 20 61 70 70 72 6f  t and make appro
3b90: 70 72 69 61 74 65 20 65 6e 74 72 69 65 73 0a 2a  priate entries.*
3ba0: 2a 20 69 6e 74 6f 20 74 68 65 20 70 61 72 61 6d  * into the param
3bb0: 65 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a  eter table..**.*
3bc0: 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 73 74  * The content st
3bd0: 72 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69  ring "z" is modi
3be0: 66 69 65 64 20 62 79 20 74 68 69 73 20 72 6f 75  fied by this rou
3bf0: 74 69 6e 65 20 62 75 74 20 69 74 20 69 73 0a 2a  tine but it is.*
3c00: 2a 20 6e 6f 74 20 63 6f 70 69 65 64 2e 20 20 54  * not copied.  T
3c10: 68 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74  he calling funct
3c20: 69 6f 6e 20 6d 75 73 74 20 6e 6f 74 20 64 65 61  ion must not dea
3c30: 6c 6c 6f 63 61 74 65 20 6f 72 20 6d 6f 64 69 66  llocate or modif
3c40: 79 0a 2a 2a 20 22 7a 22 20 61 66 74 65 72 20 74  y.** "z" after t
3c50: 68 69 73 20 72 6f 75 74 69 6e 65 20 66 69 6e 69  his routine fini
3c60: 73 68 65 73 20 6f 72 20 69 74 20 63 6f 75 6c 64  shes or it could
3c70: 20 63 6f 72 72 75 70 74 20 74 68 65 20 70 61 72   corrupt the par
3c80: 61 6d 65 74 65 72 0a 2a 2a 20 74 61 62 6c 65 2e  ameter.** table.
3c90: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20  .*/.static void 
3ca0: 70 72 6f 63 65 73 73 5f 6d 75 6c 74 69 70 61 72  process_multipar
3cb0: 74 5f 66 6f 72 6d 5f 64 61 74 61 28 63 68 61 72  t_form_data(char
3cc0: 20 2a 7a 2c 20 69 6e 74 20 6c 65 6e 29 7b 0a 20   *z, int len){. 
3cd0: 20 63 68 61 72 20 2a 7a 4c 69 6e 65 3b 0a 20 20   char *zLine;.  
3ce0: 69 6e 74 20 6e 41 72 67 2c 20 69 3b 0a 20 20 63  int nArg, i;.  c
3cf0: 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 3b 0a 20  har *zBoundry;. 
3d00: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20   char *zValue;. 
3d10: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 30   char *zName = 0
3d20: 3b 0a 20 20 69 6e 74 20 73 68 6f 77 42 79 74 65  ;.  int showByte
3d30: 73 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 61  s = 0;.  char *a
3d40: 7a 41 72 67 5b 35 30 5d 3b 0a 0a 20 20 7a 42 6f  zArg[50];..  zBo
3d50: 75 6e 64 72 79 20 3d 20 67 65 74 5f 6c 69 6e 65  undry = get_line
3d60: 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c  _from_string(&z,
3d70: 20 26 6c 65 6e 29 3b 0a 20 20 69 66 28 20 7a 42   &len);.  if( zB
3d80: 6f 75 6e 64 72 79 3d 3d 30 20 29 20 72 65 74 75  oundry==0 ) retu
3d90: 72 6e 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4c  rn;.  while( (zL
3da0: 69 6e 65 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66  ine = get_line_f
3db0: 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26  rom_string(&z, &
3dc0: 6c 65 6e 29 29 21 3d 30 20 29 7b 0a 20 20 20 20  len))!=0 ){.    
3dd0: 69 66 28 20 7a 4c 69 6e 65 5b 30 5d 3d 3d 30 20  if( zLine[0]==0 
3de0: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f  ){.      int nCo
3df0: 6e 74 65 6e 74 20 3d 20 30 3b 0a 20 20 20 20 20  ntent = 0;.     
3e00: 20 7a 56 61 6c 75 65 20 3d 20 67 65 74 5f 62 6f   zValue = get_bo
3e10: 75 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28 26 7a  unded_content(&z
3e20: 2c 20 26 6c 65 6e 2c 20 7a 42 6f 75 6e 64 72 79  , &len, zBoundry
3e30: 2c 20 26 6e 43 6f 6e 74 65 6e 74 29 3b 0a 20 20  , &nContent);.  
3e40: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26      if( zName &&
3e50: 20 7a 56 61 6c 75 65 20 26 26 20 69 73 6c 6f 77   zValue && islow
3e60: 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a  er(zName[0]) ){.
3e70: 20 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f          cgi_set_
3e80: 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79  parameter_nocopy
3e90: 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b  (zName, zValue);
3ea0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 73 68 6f  .        if( sho
3eb0: 77 42 79 74 65 73 20 29 7b 0a 20 20 20 20 20 20  wBytes ){.      
3ec0: 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61      cgi_set_para
3ed0: 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72  meter_nocopy(mpr
3ee0: 69 6e 74 66 28 22 25 73 3a 62 79 74 65 73 22 2c  intf("%s:bytes",
3ef0: 20 7a 4e 61 6d 65 29 2c 0a 20 20 20 20 20 20 20   zName),.       
3f00: 20 20 20 20 20 20 20 20 6d 70 72 69 6e 74 66 28          mprintf(
3f10: 22 25 64 22 2c 6e 43 6f 6e 74 65 6e 74 29 29 3b  "%d",nContent));
3f20: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20  .        }.     
3f30: 20 7d 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d   }.      zName =
3f40: 20 30 3b 0a 20 20 20 20 20 20 73 68 6f 77 42 79   0;.      showBy
3f50: 74 65 73 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c  tes = 0;.    }el
3f60: 73 65 7b 0a 20 20 20 20 20 20 6e 41 72 67 20 3d  se{.      nArg =
3f70: 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 7a   tokenize_line(z
3f80: 4c 69 6e 65 2c 20 73 69 7a 65 6f 66 28 61 7a 41  Line, sizeof(azA
3f90: 72 67 29 2f 73 69 7a 65 6f 66 28 61 7a 41 72 67  rg)/sizeof(azArg
3fa0: 5b 30 5d 29 2c 20 61 7a 41 72 67 29 3b 0a 20 20  [0]), azArg);.  
3fb0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e      for(i=0; i<n
3fc0: 41 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20  Arg; i++){.     
3fd0: 20 20 20 69 6e 74 20 63 20 3d 20 74 6f 6c 6f 77     int c = tolow
3fe0: 65 72 28 61 7a 41 72 67 5b 69 5d 5b 30 5d 29 3b  er(azArg[i][0]);
3ff0: 0a 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d  .        if( c==
4000: 27 63 27 20 26 26 20 73 74 72 69 63 6d 70 28 61  'c' && stricmp(a
4010: 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74  zArg[i],"content
4020: 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22 29 3d  -disposition:")=
4030: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20  =0 ){.          
4040: 69 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  i++;.        }el
4050: 73 65 20 69 66 28 20 63 3d 3d 27 6e 27 20 26 26  se if( c=='n' &&
4060: 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69   stricmp(azArg[i
4070: 5d 2c 22 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b  ],"name=")==0 ){
4080: 0a 20 20 20 20 20 20 20 20 20 20 7a 4e 61 6d 65  .          zName
4090: 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20   = azArg[++i];. 
40a0: 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28         }else if(
40b0: 20 63 3d 3d 27 66 27 20 26 26 20 73 74 72 69 63   c=='f' && stric
40c0: 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 66 69 6c  mp(azArg[i],"fil
40d0: 65 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a 20  ename=")==0 ){. 
40e0: 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a           char *z
40f0: 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20   = azArg[++i];. 
4100: 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61           if( zNa
4110: 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f 77  me && z && islow
4120: 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a  er(zName[0]) ){.
4130: 20 20 20 20 20 20 20 20 20 20 20 20 63 67 69 5f              cgi_
4140: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
4150: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73  copy(mprintf("%s
4160: 3a 66 69 6c 65 6e 61 6d 65 22 2c 7a 4e 61 6d 65  :filename",zName
4170: 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 20  ), z);.         
4180: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 73 68 6f   }.          sho
4190: 77 42 79 74 65 73 20 3d 20 31 3b 0a 20 20 20 20  wBytes = 1;.    
41a0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d      }else if( c=
41b0: 3d 27 63 27 20 26 26 20 73 74 72 69 63 6d 70 28  ='c' && stricmp(
41c0: 61 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e  azArg[i],"conten
41d0: 74 2d 74 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a  t-type:")==0 ){.
41e0: 20 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a            char *
41f0: 7a 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a  z = azArg[++i];.
4200: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e            if( zN
4210: 61 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f  ame && z && islo
4220: 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b  wer(zName[0]) ){
4230: 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 67 69  .            cgi
4240: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e  _set_parameter_n
4250: 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25  ocopy(mprintf("%
4260: 73 3a 6d 69 6d 65 74 79 70 65 22 2c 7a 4e 61 6d  s:mimetype",zNam
4270: 65 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20  e), z);.        
4280: 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20    }.        }.  
4290: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20      }.    }.  } 
42a0: 20 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a         .}../*.**
42b0: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20   Initialize the 
42c0: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20  query parameter 
42d0: 64 61 74 61 62 61 73 65 2e 20 20 49 6e 66 6f 72  database.  Infor
42e0: 6d 61 74 69 6f 6e 20 69 73 20 70 75 6c 6c 65 64  mation is pulled
42f0: 20 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 51 55 45   from.** the QUE
4300: 52 59 5f 53 54 52 49 4e 47 20 65 6e 76 69 72 6f  RY_STRING enviro
4310: 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 28  nment variable (
4320: 69 66 20 69 74 20 65 78 69 73 74 73 29 2c 20 66  if it exists), f
4330: 72 6f 6d 20 73 74 61 6e 64 61 72 64 0a 2a 2a 20  rom standard.** 
4340: 69 6e 70 75 74 20 69 66 20 74 68 65 72 65 20 69  input if there i
4350: 73 20 50 4f 53 54 20 64 61 74 61 2c 20 61 6e 64  s POST data, and
4360: 20 66 72 6f 6d 20 48 54 54 50 5f 43 4f 4f 4b 49   from HTTP_COOKI
4370: 45 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 69  E..*/.void cgi_i
4380: 6e 69 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61  nit(void){.  cha
4390: 72 20 2a 7a 3b 0a 20 20 63 6f 6e 73 74 20 63 68  r *z;.  const ch
43a0: 61 72 20 2a 7a 54 79 70 65 3b 0a 20 20 69 6e 74  ar *zType;.  int
43b0: 20 6c 65 6e 3b 0a 20 20 7a 20 3d 20 28 63 68 61   len;.  z = (cha
43c0: 72 2a 29 50 28 22 51 55 45 52 59 5f 53 54 52 49  r*)P("QUERY_STRI
43d0: 4e 47 22 29 3b 0a 20 20 69 66 28 20 7a 20 29 7b  NG");.  if( z ){
43e0: 0a 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e 74 66  .    z = mprintf
43f0: 28 22 25 73 22 2c 7a 29 3b 0a 20 20 20 20 61 64  ("%s",z);.    ad
4400: 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20  d_param_list(z, 
4410: 27 26 27 29 3b 0a 20 20 7d 0a 0a 20 20 6c 65 6e  '&');.  }..  len
4420: 20 3d 20 61 74 6f 69 28 50 44 28 22 43 4f 4e 54   = atoi(PD("CONT
4430: 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 22 30 22  ENT_LENGTH", "0"
4440: 29 29 3b 0a 20 20 67 2e 7a 43 6f 6e 74 65 6e 74  ));.  g.zContent
4450: 54 79 70 65 20 3d 20 7a 54 79 70 65 20 3d 20 50  Type = zType = P
4460: 28 22 43 4f 4e 54 45 4e 54 5f 54 59 50 45 22 29  ("CONTENT_TYPE")
4470: 3b 0a 20 20 69 66 28 20 6c 65 6e 3e 30 20 26 26  ;.  if( len>0 &&
4480: 20 7a 54 79 70 65 20 29 7b 0a 20 20 20 20 62 6c   zType ){.    bl
4490: 6f 62 5f 7a 65 72 6f 28 26 67 2e 63 67 69 49 6e  ob_zero(&g.cgiIn
44a0: 29 3b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d  );.    if( strcm
44b0: 70 28 7a 54 79 70 65 2c 22 61 70 70 6c 69 63 61  p(zType,"applica
44c0: 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d  tion/x-www-form-
44d0: 75 72 6c 65 6e 63 6f 64 65 64 22 29 3d 3d 30 20  urlencoded")==0 
44e0: 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 73 74 72  .         || str
44f0: 6e 63 6d 70 28 7a 54 79 70 65 2c 22 6d 75 6c 74  ncmp(zType,"mult
4500: 69 70 61 72 74 2f 66 6f 72 6d 2d 64 61 74 61 22  ipart/form-data"
4510: 2c 31 39 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  ,19)==0 ){.     
4520: 20 7a 20 3d 20 6d 61 6c 6c 6f 63 28 20 6c 65 6e   z = malloc( len
4530: 2b 31 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20  +1 );.      if( 
4540: 7a 3d 3d 30 20 29 20 65 78 69 74 28 31 29 3b 0a  z==0 ) exit(1);.
4550: 20 20 20 20 20 20 6c 65 6e 20 3d 20 66 72 65 61        len = frea
4560: 64 28 7a 2c 20 31 2c 20 6c 65 6e 2c 20 73 74 64  d(z, 1, len, std
4570: 69 6e 29 3b 0a 20 20 20 20 20 20 7a 5b 6c 65 6e  in);.      z[len
4580: 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28  ] = 0;.      if(
4590: 20 7a 54 79 70 65 5b 30 5d 3d 3d 27 61 27 20 29   zType[0]=='a' )
45a0: 7b 0a 20 20 20 20 20 20 20 20 61 64 64 5f 70 61  {.        add_pa
45b0: 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 26 27 29  ram_list(z, '&')
45c0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20  ;.      }else{. 
45d0: 20 20 20 20 20 20 20 70 72 6f 63 65 73 73 5f 6d         process_m
45e0: 75 6c 74 69 70 61 72 74 5f 66 6f 72 6d 5f 64 61  ultipart_form_da
45f0: 74 61 28 7a 2c 20 6c 65 6e 29 3b 0a 20 20 20 20  ta(z, len);.    
4600: 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 20 69 66    }.    }else if
4610: 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20  ( strcmp(zType, 
4620: 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66  "application/x-f
4630: 6f 73 73 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20  ossil")==0 ){.  
4640: 20 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72      blob_read_fr
4650: 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26 67 2e 63 67  om_channel(&g.cg
4660: 69 49 6e 2c 20 73 74 64 69 6e 2c 20 6c 65 6e 29  iIn, stdin, len)
4670: 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 75 6e 63  ;.      blob_unc
4680: 6f 6d 70 72 65 73 73 28 26 67 2e 63 67 69 49 6e  ompress(&g.cgiIn
4690: 2c 20 26 67 2e 63 67 69 49 6e 29 3b 0a 20 20 20  , &g.cgiIn);.   
46a0: 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d   }else if( strcm
46b0: 70 28 7a 54 79 70 65 2c 20 22 61 70 70 6c 69 63  p(zType, "applic
46c0: 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 2d 64  ation/x-fossil-d
46d0: 65 62 75 67 22 29 3d 3d 30 20 29 7b 0a 20 20 20  ebug")==0 ){.   
46e0: 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f     blob_read_fro
46f0: 6d 5f 63 68 61 6e 6e 65 6c 28 26 67 2e 63 67 69  m_channel(&g.cgi
4700: 49 6e 2c 20 73 74 64 69 6e 2c 20 6c 65 6e 29 3b  In, stdin, len);
4710: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 20  .    }.  }..  z 
4720: 3d 20 28 63 68 61 72 2a 29 50 28 22 48 54 54 50  = (char*)P("HTTP
4730: 5f 43 4f 4f 4b 49 45 22 29 3b 0a 20 20 69 66 28  _COOKIE");.  if(
4740: 20 7a 20 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70   z ){.    z = mp
4750: 72 69 6e 74 66 28 22 25 73 22 2c 7a 29 3b 0a 20  rintf("%s",z);. 
4760: 20 20 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73     add_param_lis
4770: 74 28 7a 2c 20 27 3b 27 29 3b 0a 20 20 7d 0a 7d  t(z, ';');.  }.}
4780: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20  ../*.** This is 
4790: 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 20 66  the comparison f
47a0: 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 74 6f 20  unction used to 
47b0: 73 6f 72 74 20 74 68 65 20 61 50 61 72 61 6d 51  sort the aParamQ
47c0: 50 5b 5d 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20  P[] array of.** 
47d0: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73  query parameters
47e0: 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2e 0a 2a 2f   and cookies..*/
47f0: 0a 73 74 61 74 69 63 20 69 6e 74 20 71 70 61 72  .static int qpar
4800: 61 6d 5f 63 6f 6d 70 61 72 65 28 63 6f 6e 73 74  am_compare(const
4810: 20 76 6f 69 64 20 2a 61 2c 20 63 6f 6e 73 74 20   void *a, const 
4820: 76 6f 69 64 20 2a 62 29 7b 0a 20 20 73 74 72 75  void *b){.  stru
4830: 63 74 20 51 50 61 72 61 6d 20 2a 70 41 20 3d 20  ct QParam *pA = 
4840: 28 73 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29  (struct QParam*)
4850: 61 3b 0a 20 20 73 74 72 75 63 74 20 51 50 61 72  a;.  struct QPar
4860: 61 6d 20 2a 70 42 20 3d 20 28 73 74 72 75 63 74  am *pB = (struct
4870: 20 51 50 61 72 61 6d 2a 29 62 3b 0a 20 20 69 6e   QParam*)b;.  in
4880: 74 20 63 3b 0a 20 20 63 20 3d 20 73 74 72 63 6d  t c;.  c = strcm
4890: 70 28 70 41 2d 3e 7a 4e 61 6d 65 2c 20 70 42 2d  p(pA->zName, pB-
48a0: 3e 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 63  >zName);.  if( c
48b0: 3d 3d 30 20 29 7b 0a 20 20 20 20 63 20 3d 20 70  ==0 ){.    c = p
48c0: 41 2d 3e 73 65 71 20 2d 20 70 42 2d 3e 73 65 71  A->seq - pB->seq
48d0: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 63  ;.  }.  return c
48e0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  ;.}../*.** Retur
48f0: 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 61  n the value of a
4900: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
4910: 20 6f 72 20 63 6f 6f 6b 69 65 20 77 68 6f 73 65   or cookie whose
4920: 20 6e 61 6d 65 20 69 73 20 7a 4e 61 6d 65 2e 0a   name is zName..
4930: 2a 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6e  ** If there is n
4940: 6f 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  o query paramete
4950: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65  r or cookie name
4960: 64 20 7a 4e 61 6d 65 20 61 6e 64 20 74 68 65 20  d zName and the 
4970: 66 69 72 73 74 0a 2a 2a 20 63 68 61 72 61 63 74  first.** charact
4980: 65 72 20 6f 66 20 7a 4e 61 6d 65 20 69 73 20 75  er of zName is u
4990: 70 70 65 72 63 61 73 65 2c 20 74 68 65 6e 20 63  ppercase, then c
49a0: 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74  heck to see if t
49b0: 68 65 72 65 20 69 73 20 61 6e 0a 2a 2a 20 65 6e  here is an.** en
49c0: 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62  vironment variab
49d0: 6c 65 20 62 79 20 74 68 61 74 20 6e 61 6d 65 20  le by that name 
49e0: 61 6e 64 20 72 65 74 75 72 6e 20 69 74 20 69 66  and return it if
49f0: 20 74 68 65 72 65 20 69 73 2e 20 20 41 73 0a 2a   there is.  As.*
4a00: 2a 20 61 20 6c 61 73 74 20 72 65 73 6f 72 74 20  * a last resort 
4a10: 77 68 65 6e 20 6e 6f 74 68 69 6e 67 20 65 6c 73  when nothing els
4a20: 65 20 6d 61 74 63 68 65 73 2c 20 72 65 74 75 72  e matches, retur
4a30: 6e 20 7a 44 65 66 61 75 6c 74 2e 0a 2a 2f 0a 63  n zDefault..*/.c
4a40: 6f 6e 73 74 20 63 68 61 72 20 2a 63 67 69 5f 70  onst char *cgi_p
4a50: 61 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 20 63  arameter(const c
4a60: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73  har *zName, cons
4a70: 74 20 63 68 61 72 20 2a 7a 44 65 66 61 75 6c 74  t char *zDefault
4a80: 29 7b 0a 20 20 69 6e 74 20 6c 6f 2c 20 68 69 2c  ){.  int lo, hi,
4a90: 20 6d 69 64 2c 20 63 3b 0a 0a 20 20 2f 2a 20 54   mid, c;..  /* T
4aa0: 68 65 20 73 6f 72 74 51 50 20 66 6c 61 67 20 69  he sortQP flag i
4ab0: 73 20 73 65 74 20 77 68 65 6e 65 76 65 72 20 61  s set whenever a
4ac0: 20 6e 65 77 20 71 75 65 72 79 20 70 61 72 61 6d   new query param
4ad0: 65 74 65 72 20 69 73 20 69 6e 73 65 72 74 65 64  eter is inserted
4ae0: 2e 0a 20 20 2a 2a 20 49 74 20 69 6e 64 69 63 61  ..  ** It indica
4af0: 74 65 73 20 74 68 61 74 20 77 65 20 6e 65 65 64  tes that we need
4b00: 20 74 6f 20 72 65 73 6f 72 74 20 74 68 65 20 71   to resort the q
4b10: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 2e  uery parameters.
4b20: 0a 20 20 2a 2f 0a 20 20 69 66 28 20 73 6f 72 74  .  */.  if( sort
4b30: 51 50 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 2c  QP ){.    int i,
4b40: 20 6a 3b 0a 20 20 20 20 71 73 6f 72 74 28 61 50   j;.    qsort(aP
4b50: 61 72 61 6d 51 50 2c 20 6e 55 73 65 64 51 50 2c  aramQP, nUsedQP,
4b60: 20 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51 50   sizeof(aParamQP
4b70: 5b 30 5d 29 2c 20 71 70 61 72 61 6d 5f 63 6f 6d  [0]), qparam_com
4b80: 70 61 72 65 29 3b 0a 20 20 20 20 73 6f 72 74 51  pare);.    sortQ
4b90: 50 20 3d 20 30 3b 0a 20 20 20 20 2f 2a 20 41 66  P = 0;.    /* Af
4ba0: 74 65 72 20 73 6f 72 74 69 6e 67 2c 20 72 65 6d  ter sorting, rem
4bb0: 6f 76 65 20 64 75 70 6c 69 63 61 74 65 20 70 61  ove duplicate pa
4bc0: 72 61 6d 65 74 65 72 73 2e 20 20 54 68 65 20 73  rameters.  The s
4bd0: 65 63 6f 6e 64 61 72 79 20 73 6f 72 74 0a 20 20  econdary sort.  
4be0: 20 20 2a 2a 20 6b 65 79 20 69 73 20 61 50 61 72    ** key is aPar
4bf0: 61 6d 51 50 5b 5d 2e 73 65 71 20 61 6e 64 20 77  amQP[].seq and w
4c00: 65 20 6b 65 65 70 20 74 68 65 20 66 69 72 73 74  e keep the first
4c10: 20 65 6e 74 72 79 2e 20 20 54 68 61 74 20 6d 65   entry.  That me
4c20: 61 6e 73 0a 20 20 20 20 2a 2a 20 77 69 74 68 20  ans.    ** with 
4c30: 64 75 70 6c 69 63 61 74 65 20 63 61 6c 6c 73 20  duplicate calls 
4c40: 74 6f 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d  to cgi_set_param
4c50: 65 74 65 72 28 29 20 74 68 65 20 73 65 63 6f 6e  eter() the secon
4c60: 64 20 61 6e 64 0a 20 20 20 20 2a 2a 20 73 75 62  d and.    ** sub
4c70: 73 65 71 75 65 6e 74 20 63 61 6c 6c 73 20 61 72  sequent calls ar
4c80: 65 20 65 66 66 65 63 74 69 76 65 6c 79 20 6e 6f  e effectively no
4c90: 2d 6f 70 73 2e 20 2a 2f 0a 20 20 20 20 66 6f 72  -ops. */.    for
4ca0: 28 69 3d 6a 3d 31 3b 20 69 3c 6e 55 73 65 64 51  (i=j=1; i<nUsedQ
4cb0: 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69  P; i++){.      i
4cc0: 66 28 20 73 74 72 63 6d 70 28 61 50 61 72 61 6d  f( strcmp(aParam
4cd0: 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 61 50 61 72  QP[i].zName,aPar
4ce0: 61 6d 51 50 5b 69 2d 31 5d 2e 7a 4e 61 6d 65 29  amQP[i-1].zName)
4cf0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63  ==0 ){.        c
4d00: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d  ontinue;.      }
4d10: 0a 20 20 20 20 20 20 69 66 28 20 6a 3c 69 20 29  .      if( j<i )
4d20: 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79  {.        memcpy
4d30: 28 26 61 50 61 72 61 6d 51 50 5b 6a 5d 2c 20 26  (&aParamQP[j], &
4d40: 61 50 61 72 61 6d 51 50 5b 69 5d 2c 20 73 69 7a  aParamQP[i], siz
4d50: 65 6f 66 28 61 50 61 72 61 6d 51 50 5b 6a 5d 29  eof(aParamQP[j])
4d60: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  );.      }.     
4d70: 20 6a 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20   j++;.    }.    
4d80: 6e 55 73 65 64 51 50 20 3d 20 6a 3b 0a 20 20 7d  nUsedQP = j;.  }
4d90: 0a 0a 20 20 2f 2a 20 44 6f 20 61 20 62 69 6e 61  ..  /* Do a bina
4da0: 72 79 20 73 65 61 72 63 68 20 66 6f 72 20 61 20  ry search for a 
4db0: 6d 61 74 63 68 69 6e 67 20 71 75 65 72 79 20 70  matching query p
4dc0: 61 72 61 6d 65 74 65 72 20 2a 2f 0a 20 20 6c 6f  arameter */.  lo
4dd0: 20 3d 20 30 3b 0a 20 20 68 69 20 3d 20 6e 55 73   = 0;.  hi = nUs
4de0: 65 64 51 50 2d 31 3b 0a 20 20 77 68 69 6c 65 28  edQP-1;.  while(
4df0: 20 6c 6f 3c 3d 68 69 20 29 7b 0a 20 20 20 20 6d   lo<=hi ){.    m
4e00: 69 64 20 3d 20 28 6c 6f 2b 68 69 29 2f 32 3b 0a  id = (lo+hi)/2;.
4e10: 20 20 20 20 63 20 3d 20 73 74 72 63 6d 70 28 61      c = strcmp(a
4e20: 50 61 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 4e 61  ParamQP[mid].zNa
4e30: 6d 65 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20  me, zName);.    
4e40: 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20  if( c==0 ){.    
4e50: 20 20 43 47 49 44 45 42 55 47 28 28 22 6d 65 6d    CGIDEBUG(("mem
4e60: 2d 6d 61 74 63 68 20 5b 25 73 5d 20 3d 20 5b 25  -match [%s] = [%
4e70: 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c 20 61 50  s]\n", zName, aP
4e80: 61 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c  aramQP[mid].zVal
4e90: 75 65 29 29 3b 0a 20 20 20 20 20 20 72 65 74 75  ue));.      retu
4ea0: 72 6e 20 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d  rn aParamQP[mid]
4eb0: 2e 7a 56 61 6c 75 65 3b 0a 20 20 20 20 7d 65 6c  .zValue;.    }el
4ec0: 73 65 20 69 66 28 20 63 3e 30 20 29 7b 0a 20 20  se if( c>0 ){.  
4ed0: 20 20 20 20 68 69 20 3d 20 6d 69 64 2d 31 3b 0a      hi = mid-1;.
4ee0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
4ef0: 20 6c 6f 20 3d 20 6d 69 64 2b 31 3b 0a 20 20 20   lo = mid+1;.   
4f00: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20   }.  }..  /* If 
4f10: 6e 6f 20 6d 61 74 63 68 20 69 73 20 66 6f 75 6e  no match is foun
4f20: 64 20 61 6e 64 20 74 68 65 20 6e 61 6d 65 20 62  d and the name b
4f30: 65 67 69 6e 73 20 77 69 74 68 20 61 6e 20 75 70  egins with an up
4f40: 70 65 72 2d 63 61 73 65 0a 20 20 2a 2a 20 6c 65  per-case.  ** le
4f50: 74 74 65 72 2c 20 74 68 65 6e 20 63 68 65 63 6b  tter, then check
4f60: 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 72 65   to see if there
4f70: 20 69 73 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65   is an environme
4f80: 6e 74 20 76 61 72 69 61 62 6c 65 0a 20 20 2a 2a  nt variable.  **
4f90: 20 77 69 74 68 20 74 68 65 20 67 69 76 65 6e 20   with the given 
4fa0: 6e 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28  name..  */.  if(
4fb0: 20 69 73 75 70 70 65 72 28 7a 4e 61 6d 65 5b 30   isupper(zName[0
4fc0: 5d 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20  ]) ){.    const 
4fd0: 63 68 61 72 20 2a 7a 56 61 6c 75 65 20 3d 20 67  char *zValue = g
4fe0: 65 74 65 6e 76 28 7a 4e 61 6d 65 29 3b 0a 20 20  etenv(zName);.  
4ff0: 20 20 69 66 28 20 7a 56 61 6c 75 65 20 29 7b 0a    if( zValue ){.
5000: 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61        cgi_set_pa
5010: 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a  rameter_nocopy(z
5020: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20  Name, zValue);. 
5030: 20 20 20 20 20 43 47 49 44 45 42 55 47 28 28 22       CGIDEBUG(("
5040: 65 6e 76 2d 6d 61 74 63 68 20 5b 25 73 5d 20 3d  env-match [%s] =
5050: 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c   [%s]\n", zName,
5060: 20 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20 20   zValue));.     
5070: 20 72 65 74 75 72 6e 20 7a 56 61 6c 75 65 3b 0a   return zValue;.
5080: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 43 47 49 44      }.  }.  CGID
5090: 45 42 55 47 28 28 22 6e 6f 2d 6d 61 74 63 68 20  EBUG(("no-match 
50a0: 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 29 29  [%s]\n", zName))
50b0: 3b 0a 20 20 72 65 74 75 72 6e 20 7a 44 65 66 61  ;.  return zDefa
50c0: 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72  ult;.}../*.** Pr
50d0: 69 6e 74 20 43 47 49 20 64 65 62 75 67 67 69 6e  int CGI debuggin
50e0: 67 20 6d 65 73 73 61 67 65 73 2e 0a 2a 2f 0a 76  g messages..*/.v
50f0: 6f 69 64 20 63 67 69 5f 64 65 62 75 67 28 63 6f  oid cgi_debug(co
5100: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61  nst char *zForma
5110: 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69  t, ...){.  va_li
5120: 73 74 20 61 70 3b 0a 20 20 69 66 28 20 67 2e 66  st ap;.  if( g.f
5130: 44 65 62 75 67 20 29 7b 0a 20 20 20 20 76 61 5f  Debug ){.    va_
5140: 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61  start(ap, zForma
5150: 74 29 3b 0a 20 20 20 20 76 66 70 72 69 6e 74 66  t);.    vfprintf
5160: 28 67 2e 66 44 65 62 75 67 2c 20 7a 46 6f 72 6d  (g.fDebug, zForm
5170: 61 74 2c 20 61 70 29 3b 0a 20 20 20 20 76 61 5f  at, ap);.    va_
5180: 65 6e 64 28 61 70 29 3b 0a 20 20 20 20 66 66 6c  end(ap);.    ffl
5190: 75 73 68 28 67 2e 66 44 65 62 75 67 29 3b 0a 20  ush(g.fDebug);. 
51a0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75   }.}../*.** Retu
51b0: 72 6e 20 74 72 75 65 20 69 66 20 61 6e 79 20 6f  rn true if any o
51c0: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  f the query para
51d0: 6d 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72  meters in the ar
51e0: 67 75 6d 65 6e 74 0a 2a 2a 20 6c 69 73 74 20 61  gument.** list a
51f0: 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69  re defined..*/.i
5200: 6e 74 20 63 67 69 5f 61 6e 79 28 63 6f 6e 73 74  nt cgi_any(const
5210: 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a   char *z, ...){.
5220: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20    va_list ap;.  
5230: 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20  char *z2;.  if( 
5240: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c  cgi_parameter(z,
5250: 30 29 21 3d 30 20 29 20 72 65 74 75 72 6e 20 31  0)!=0 ) return 1
5260: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c  ;.  va_start(ap,
5270: 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a   z);.  while( (z
5280: 32 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63  2 = va_arg(ap, c
5290: 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20  har*))!=0 ){.   
52a0: 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74   if( cgi_paramet
52b0: 65 72 28 7a 32 2c 30 29 21 3d 30 20 29 20 72 65  er(z2,0)!=0 ) re
52c0: 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 76 61  turn 1;.  }.  va
52d0: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75  _end(ap);.  retu
52e0: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  rn 0;.}../*.** R
52f0: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 61 6c  eturn true if al
5300: 6c 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70  l of the query p
5310: 61 72 61 6d 65 74 65 72 73 20 69 6e 20 74 68 65  arameters in the
5320: 20 61 72 67 75 6d 65 6e 74 20 6c 69 73 74 0a 2a   argument list.*
5330: 2a 20 61 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a  * are defined..*
5340: 2f 0a 69 6e 74 20 63 67 69 5f 61 6c 6c 28 63 6f  /.int cgi_all(co
5350: 6e 73 74 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e  nst char *z, ...
5360: 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b  ){.  va_list ap;
5370: 0a 20 20 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69  .  char *z2;.  i
5380: 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72  f( cgi_parameter
5390: 28 7a 2c 30 29 3d 3d 30 20 29 20 72 65 74 75 72  (z,0)==0 ) retur
53a0: 6e 20 30 3b 0a 20 20 76 61 5f 73 74 61 72 74 28  n 0;.  va_start(
53b0: 61 70 2c 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28  ap, z);.  while(
53c0: 20 28 7a 32 20 3d 20 76 61 5f 61 72 67 28 61 70   (z2 = va_arg(ap
53d0: 2c 20 63 68 61 72 2a 29 29 3d 3d 30 20 29 7b 0a  , char*))==0 ){.
53e0: 20 20 20 20 69 66 28 20 63 67 69 5f 70 61 72 61      if( cgi_para
53f0: 6d 65 74 65 72 28 7a 32 2c 30 29 3d 3d 30 20 29  meter(z2,0)==0 )
5400: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20   return 0;.  }. 
5410: 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72   va_end(ap);.  r
5420: 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a  eturn 1;.}../*.*
5430: 2a 20 50 72 69 6e 74 20 61 6c 6c 20 71 75 65 72  * Print all quer
5440: 79 20 70 61 72 61 6d 65 74 65 72 73 20 6f 6e 20  y parameters on 
5450: 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e  standard output.
5460: 20 20 46 6f 72 6d 61 74 20 74 68 65 0a 2a 2a 20    Format the.** 
5470: 70 61 72 61 6d 65 74 65 72 73 20 61 73 20 48 54  parameters as HT
5480: 4d 4c 2e 20 20 54 68 69 73 20 69 73 20 75 73 65  ML.  This is use
5490: 64 20 66 6f 72 20 74 65 73 74 69 6e 67 20 61 6e  d for testing an
54a0: 64 20 64 65 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a  d debugging..*/.
54b0: 76 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 5f 61  void cgi_print_a
54c0: 6c 6c 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20  ll(void){.  int 
54d0: 69 3b 0a 20 20 63 67 69 5f 70 61 72 61 6d 65 74  i;.  cgi_paramet
54e0: 65 72 28 22 22 2c 22 22 29 3b 20 20 2f 2a 20 46  er("","");  /* F
54f0: 6f 72 63 65 20 74 68 65 20 70 61 72 61 6d 65 74  orce the paramet
5500: 65 72 73 20 69 6e 74 6f 20 73 6f 72 74 65 64 20  ers into sorted 
5510: 6f 72 64 65 72 20 2a 2f 0a 20 20 66 6f 72 28 69  order */.  for(i
5520: 3d 30 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 69  =0; i<nUsedQP; i
5530: 2b 2b 29 7b 0a 20 20 20 20 63 67 69 5f 70 72 69  ++){.    cgi_pri
5540: 6e 74 66 28 22 25 73 20 3d 20 25 73 20 20 3c 62  ntf("%s = %s  <b
5550: 72 20 2f 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20  r />\n",.       
5560: 68 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50  htmlize(aParamQP
5570: 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20  [i].zName, -1), 
5580: 68 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50  htmlize(aParamQP
5590: 5b 69 5d 2e 7a 56 61 6c 75 65 2c 20 2d 31 29 29  [i].zValue, -1))
55a0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57  ;.  }.}../*.** W
55b0: 72 69 74 65 20 48 54 4d 4c 20 74 65 78 74 20 66  rite HTML text f
55c0: 6f 72 20 61 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e  or an option men
55d0: 75 20 74 6f 20 73 74 61 6e 64 61 72 64 20 6f 75  u to standard ou
55e0: 74 70 75 74 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a  tput.  zParam.**
55f0: 20 69 73 20 74 68 65 20 71 75 65 72 79 20 70 61   is the query pa
5600: 72 61 6d 65 74 65 72 20 74 68 61 74 20 74 68 65  rameter that the
5610: 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 73 65 74   option menu set
5620: 73 2e 20 20 7a 44 66 6c 74 20 69 73 20 74 68 65  s.  zDflt is the
5630: 0a 2a 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c 75  .** initial valu
5640: 65 20 6f 66 20 74 68 65 20 6f 70 74 69 6f 6e 20  e of the option 
5650: 6d 65 6e 75 2e 20 20 41 64 64 69 74 69 6f 6e 20  menu.  Addition 
5660: 61 72 67 75 6d 65 6e 74 73 20 61 72 65 20 6e 61  arguments are na
5670: 6d 65 2f 76 61 6c 75 65 0a 2a 2a 20 70 61 69 72  me/value.** pair
5680: 73 20 74 68 61 74 20 64 65 66 69 6e 65 20 76 61  s that define va
5690: 6c 75 65 73 20 6f 6e 20 74 68 65 20 6d 65 6e 75  lues on the menu
56a0: 2e 20 20 54 68 65 20 6c 69 73 74 20 69 73 20 74  .  The list is t
56b0: 65 72 6d 69 6e 61 74 65 64 20 77 69 74 68 0a 2a  erminated with.*
56c0: 2a 20 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20  * a single NULL 
56d0: 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69  argument..*/.voi
56e0: 64 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75  d cgi_optionmenu
56f0: 28 69 6e 74 20 69 6e 2c 20 63 6f 6e 73 74 20 63  (int in, const c
5700: 68 61 72 20 2a 7a 50 2c 20 63 6f 6e 73 74 20 63  har *zP, const c
5710: 68 61 72 20 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20  har *zD, ...){. 
5720: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63   va_list ap;.  c
5730: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61  har *zName, *zVa
5740: 6c 3b 0a 20 20 69 6e 74 20 64 66 6c 74 53 65 65  l;.  int dfltSee
5750: 6e 20 3d 20 30 3b 0a 20 20 63 67 69 5f 70 72 69  n = 0;.  cgi_pri
5760: 6e 74 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20  ntf("%*s<select 
5770: 73 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73  size=1 name=\"%s
5780: 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20  \">\n", in, "", 
5790: 7a 50 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 28  zP);.  va_start(
57a0: 61 70 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65  ap, zD);.  while
57b0: 28 20 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72  ( (zName = va_ar
57c0: 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30  g(ap, char*))!=0
57d0: 20 26 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61   && (zVal = va_a
57e0: 72 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d  rg(ap, char*))!=
57f0: 30 20 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72  0 ){.    if( str
5800: 63 6d 70 28 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20  cmp(zVal,zD)==0 
5810: 29 7b 20 64 66 6c 74 53 65 65 6e 20 3d 20 31 3b  ){ dfltSeen = 1;
5820: 20 62 72 65 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20   break; }.  }.  
5830: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 69 66  va_end(ap);.  if
5840: 28 20 21 64 66 6c 74 53 65 65 6e 20 29 7b 0a 20  ( !dfltSeen ){. 
5850: 20 20 20 69 66 28 20 7a 44 5b 30 5d 20 29 7b 0a     if( zD[0] ){.
5860: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66        cgi_printf
5870: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c  ("%*s<option val
5880: 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 74  ue=\"%h\" select
5890: 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e  ed>%h</option>\n
58a0: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c  ",.        in+2,
58b0: 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20   "", zD, zD);.  
58c0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63    }else{.      c
58d0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f  gi_printf("%*s<o
58e0: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22  ption value=\"\"
58f0: 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b   selected>&nbsp;
5900: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e  </option>\n", in
5910: 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 0a 20  +2, "");.    }. 
5920: 20 7d 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70   }.  va_start(ap
5930: 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20  , zD);.  while( 
5940: 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28  (zName = va_arg(
5950: 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26  ap, char*))!=0 &
5960: 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67  & (zVal = va_arg
5970: 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20  (ap, char*))!=0 
5980: 29 7b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65  ){.    if( zName
5990: 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69  [0] ){.      cgi
59a0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74  _printf("%*s<opt
59b0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22  ion value=\"%h\"
59c0: 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e  %s>%h</option>\n
59d0: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c  ",.        in+2,
59e0: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61   "",.        zVa
59f0: 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d  l,.        strcm
5a00: 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22  p(zVal, zD) ? ""
5a10: 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a   : " selected",.
5a20: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20          zName.  
5a30: 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65      );.    }else
5a40: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e  {.      cgi_prin
5a50: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76  tf("%*s<option v
5a60: 61 6c 75 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73  alue=\"\"%s>&nbs
5a70: 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a  p;</option>\n",.
5a80: 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22          in+2, ""
5a90: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70  ,.        strcmp
5aa0: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20  (zVal, zD) ? "" 
5ab0: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20  : " selected".  
5ac0: 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d      );.    }.  }
5ad0: 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20  .  va_end(ap);. 
5ae0: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73   cgi_printf("%*s
5af0: 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e  </select>\n", in
5b00: 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20  , "");.}../*.** 
5b10: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72  This routine wor
5b20: 6b 73 20 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67  ks a lot like cg
5b30: 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65  i_optionmenu() e
5b40: 78 63 65 70 74 20 74 68 61 74 20 74 68 65 20 6c  xcept that the l
5b50: 69 73 74 20 6f 66 0a 2a 2a 20 76 61 6c 75 65 73  ist of.** values
5b60: 20 69 73 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e   is contained in
5b70: 20 61 6e 20 61 72 72 61 79 2e 20 20 41 6c 73 6f   an array.  Also
5b80: 2c 20 74 68 65 20 76 61 6c 75 65 73 20 61 72 65  , the values are
5b90: 20 6a 75 73 74 20 76 61 6c 75 65 73 2c 20 6e 6f   just values, no
5ba0: 74 0a 2a 2a 20 6e 61 6d 65 2f 76 61 6c 75 65 20  t.** name/value 
5bb0: 70 61 69 72 73 20 61 73 20 69 6e 20 63 67 69 5f  pairs as in cgi_
5bc0: 6f 70 74 69 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76  optionmenu..*/.v
5bd0: 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e  oid cgi_v_option
5be0: 6d 65 6e 75 28 0a 20 20 69 6e 74 20 69 6e 2c 20  menu(.  int in, 
5bf0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
5c00: 49 6e 64 65 6e 74 20 62 79 20 74 68 69 73 20 61  Indent by this a
5c10: 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74  mount */.  const
5c20: 20 63 68 61 72 20 2a 7a 50 2c 20 20 20 20 20 20   char *zP,      
5c30: 2f 2a 20 54 68 65 20 71 75 65 72 79 20 70 61 72  /* The query par
5c40: 61 6d 65 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20  ameter name */. 
5c50: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c   const char *zD,
5c60: 20 20 20 20 20 20 2f 2a 20 44 65 66 61 75 6c 74        /* Default
5c70: 20 76 61 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73   value */.  cons
5c80: 74 20 63 68 61 72 20 2a 2a 61 7a 20 20 20 20 20  t char **az     
5c90: 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61   /* NULL-termina
5ca0: 74 65 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f  ted list of allo
5cb0: 77 65 64 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b  wed values */.){
5cc0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a  .  const char *z
5cd0: 56 61 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20  Val;.  int i;.  
5ce0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c  cgi_printf("%*s<
5cf0: 73 65 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61  select size=1 na
5d00: 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69  me=\"%s\">\n", i
5d10: 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f  n, "", zP);.  fo
5d20: 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b  r(i=0; az[i]; i+
5d30: 2b 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63  +){.    if( strc
5d40: 6d 70 28 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20  mp(az[i],zD)==0 
5d50: 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69  ) break;.  }.  i
5d60: 66 28 20 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20  f( az[i]==0 ){. 
5d70: 20 20 20 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20     if( zD[0]==0 
5d80: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69  ){.      cgi_pri
5d90: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20  ntf("%*s<option 
5da0: 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63  value=\"\" selec
5db0: 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69  ted>&nbsp;</opti
5dc0: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69  on>\n",.       i
5dd0: 6e 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65  n+2, "");.    }e
5de0: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70  lse{.      cgi_p
5df0: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f  rintf("%*s<optio
5e00: 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73  n value=\"%h\" s
5e10: 65 6c 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69  elected>%h</opti
5e20: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69  on>\n",.       i
5e30: 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29  n+2, "", zD, zD)
5e40: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68  ;.    }.  }.  wh
5e50: 69 6c 65 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61  ile( (zVal = *(a
5e60: 7a 2b 2b 29 29 21 3d 30 20 20 29 7b 0a 20 20 20  z++))!=0  ){.   
5e70: 20 69 66 28 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a   if( zVal[0] ){.
5e80: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66        cgi_printf
5e90: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c  ("%*s<option val
5ea0: 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f  ue=\"%h\"%s>%h</
5eb0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20  option>\n",.    
5ec0: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20      in+2, "",.  
5ed0: 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20        zVal,.    
5ee0: 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c      strcmp(zVal,
5ef0: 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65   zD) ? "" : " se
5f00: 6c 65 63 74 65 64 22 2c 0a 20 20 20 20 20 20 20  lected",.       
5f10: 20 7a 56 61 6c 0a 20 20 20 20 20 20 29 3b 0a 20   zVal.      );. 
5f20: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
5f30: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c  cgi_printf("%*s<
5f40: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c  option value=\"\
5f50: 22 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69  "%s>&nbsp;</opti
5f60: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20  on>\n",.        
5f70: 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20  in+2, "",.      
5f80: 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a    strcmp(zVal, z
5f90: 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65  D) ? "" : " sele
5fa0: 63 74 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20  cted".      );. 
5fb0: 20 20 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70     }.  }.  cgi_p
5fc0: 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65  rintf("%*s</sele
5fd0: 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b  ct>\n", in, "");
5fe0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72  .}../*.** This r
5ff0: 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c  outine works a l
6000: 6f 74 20 6c 69 6b 65 20 63 67 69 5f 76 5f 6f 70  ot like cgi_v_op
6010: 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70  tionmenu() excep
6020: 74 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 0a  t that the list.
6030: 2a 2a 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20  ** is a list of 
6040: 70 61 69 72 73 2e 20 20 54 68 65 20 66 69 72 73  pairs.  The firs
6050: 74 20 65 6c 65 6d 65 6e 74 20 6f 66 20 65 61 63  t element of eac
6060: 68 20 70 61 69 72 20 69 73 20 74 68 65 20 76 61  h pair is the va
6070: 6c 75 65 20 75 73 65 64 0a 2a 2a 20 69 6e 74 65  lue used.** inte
6080: 72 6e 61 6c 6c 79 20 61 6e 64 20 74 68 65 20 73  rnally and the s
6090: 65 63 6f 6e 64 20 65 6c 65 6d 65 6e 74 20 69 73  econd element is
60a0: 20 74 68 65 20 76 61 6c 75 65 20 64 69 73 70 6c   the value displ
60b0: 61 79 65 64 20 74 6f 20 74 68 65 20 75 73 65 72  ayed to the user
60c0: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f  ..*/.void cgi_v_
60d0: 6f 70 74 69 6f 6e 6d 65 6e 75 32 28 0a 20 20 69  optionmenu2(.  i
60e0: 6e 74 20 69 6e 2c 20 20 20 20 20 20 20 20 20 20  nt in,          
60f0: 20 20 20 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79      /* Indent by
6100: 20 74 68 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a   this amount */.
6110: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50    const char *zP
6120: 2c 20 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75  ,      /* The qu
6130: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6e 61  ery parameter na
6140: 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68  me */.  const ch
6150: 61 72 20 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20  ar *zD,      /* 
6160: 44 65 66 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f  Default value */
6170: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a  .  const char **
6180: 61 7a 20 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d  az      /* NULL-
6190: 74 65 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20  terminated list 
61a0: 6f 66 20 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65  of allowed value
61b0: 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20  s */.){.  const 
61c0: 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e  char *zVal;.  in
61d0: 74 20 69 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74  t i;.  cgi_print
61e0: 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69  f("%*s<select si
61f0: 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22  ze=1 name=\"%s\"
6200: 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50  >\n", in, "", zP
6210: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a  );.  for(i=0; az
6220: 5b 69 5d 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20  [i]; i+=2){.    
6230: 69 66 28 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d  if( strcmp(az[i]
6240: 2c 7a 44 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b  ,zD)==0 ) break;
6250: 0a 20 20 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d  .  }.  if( az[i]
6260: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a  ==0 ){.    if( z
6270: 44 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20  D[0]==0 ){.     
6280: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73   cgi_printf("%*s
6290: 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22  <option value=\"
62a0: 5c 22 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73  \" selected>&nbs
62b0: 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a  p;</option>\n",.
62c0: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 29         in+2, "")
62d0: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20  ;.    }else{.   
62e0: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25     cgi_printf("%
62f0: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d  *s<option value=
6300: 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e  \"%h\" selected>
6310: 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a  %h</option>\n",.
6320: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c         in+2, "",
6330: 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a   zD, zD);.    }.
6340: 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 28 7a 56    }.  while( (zV
6350: 61 6c 20 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30  al = *(az++))!=0
6360: 20 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63    ){.    const c
6370: 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61  har *zName = *(a
6380: 7a 2b 2b 29 3b 0a 20 20 20 20 69 66 28 20 7a 4e  z++);.    if( zN
6390: 61 6d 65 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20  ame[0] ){.      
63a0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c  cgi_printf("%*s<
63b0: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25  option value=\"%
63c0: 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e  h\"%s>%h</option
63d0: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e  >\n",.        in
63e0: 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20  +2, "",.        
63f0: 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74  zVal,.        st
6400: 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f  rcmp(zVal, zD) ?
6410: 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64   "" : " selected
6420: 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d 65  ",.        zName
6430: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65  .      );.    }e
6440: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70  lse{.      cgi_p
6450: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f  rintf("%*s<optio
6460: 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73  n value=\"%h\"%s
6470: 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e  >&nbsp;</option>
6480: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b  \n",.        in+
6490: 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a  2, "",.        z
64a0: 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72  Val,.        str
64b0: 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20  cmp(zVal, zD) ? 
64c0: 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22  "" : " selected"
64d0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a  .      );.    }.
64e0: 20 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74 66    }.  cgi_printf
64f0: 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e  ("%*s</select>\n
6500: 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f  ", in, "");.}../
6510: 2a 20 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74  * .** This funct
6520: 69 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74  ion implements t
6530: 68 65 20 63 61 6c 6c 62 61 63 6b 20 66 72 6f 6d  he callback from
6540: 20 76 78 70 72 69 6e 74 66 2e 20 0a 2a 2a 0a 2a   vxprintf. .**.*
6550: 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 73  * This routine s
6560: 65 6e 64 73 20 6e 4e 65 77 43 68 61 72 20 63 68  ends nNewChar ch
6570: 61 72 61 63 74 65 72 73 20 6f 66 20 74 65 78 74  aracters of text
6580: 20 69 6e 20 7a 4e 65 77 54 65 78 74 20 74 6f 0a   in zNewText to.
6590: 2a 2a 20 43 47 49 20 72 65 70 6c 79 20 63 6f 6e  ** CGI reply con
65a0: 74 65 6e 74 20 62 75 66 66 65 72 2e 0a 2a 2f 0a  tent buffer..*/.
65b0: 73 74 61 74 69 63 20 76 6f 69 64 20 73 6f 75 74  static void sout
65c0: 28 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 2c 20  (void *NotUsed, 
65d0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 65 77  const char *zNew
65e0: 54 65 78 74 2c 20 69 6e 74 20 6e 4e 65 77 43 68  Text, int nNewCh
65f0: 61 72 29 7b 0a 20 20 63 67 69 5f 61 70 70 65 6e  ar){.  cgi_appen
6600: 64 5f 63 6f 6e 74 65 6e 74 28 7a 4e 65 77 54 65  d_content(zNewTe
6610: 78 74 2c 20 6e 4e 65 77 43 68 61 72 29 3b 0a 7d  xt, nNewChar);.}
6620: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ../*.** This rou
6630: 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69 6b 65 20  tine works like 
6640: 22 70 72 69 6e 74 66 22 20 65 78 63 65 70 74 20  "printf" except 
6650: 74 68 61 74 20 69 74 20 68 61 73 20 74 68 65 0a  that it has the.
6660: 2a 2a 20 65 78 74 72 61 20 66 6f 72 6d 61 74 74  ** extra formatt
6670: 69 6e 67 20 63 61 70 61 62 69 6c 69 74 69 65 73  ing capabilities
6680: 20 73 75 63 68 20 61 73 20 25 68 20 61 6e 64 20   such as %h and 
6690: 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  %t..*/.void cgi_
66a0: 70 72 69 6e 74 66 28 63 6f 6e 73 74 20 63 68 61  printf(const cha
66b0: 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29  r *zFormat, ...)
66c0: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  {.  va_list ap;.
66d0: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 7a 46    va_start(ap,zF
66e0: 6f 72 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e  ormat);.  vxprin
66f0: 74 66 28 73 6f 75 74 2c 30 2c 7a 46 6f 72 6d 61  tf(sout,0,zForma
6700: 74 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28  t,ap);.  va_end(
6710: 61 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68  ap);.}../*.** Th
6720: 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73  is routine works
6730: 20 6c 69 6b 65 20 22 76 70 72 69 6e 74 66 22 20   like "vprintf" 
6740: 65 78 63 65 70 74 20 74 68 61 74 20 69 74 20 68  except that it h
6750: 61 73 20 74 68 65 0a 2a 2a 20 65 78 74 72 61 20  as the.** extra 
6760: 66 6f 72 6d 61 74 74 69 6e 67 20 63 61 70 61 62  formatting capab
6770: 69 6c 69 74 69 65 73 20 73 75 63 68 20 61 73 20  ilities such as 
6780: 25 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f  %h and %t..*/.vo
6790: 69 64 20 63 67 69 5f 76 70 72 69 6e 74 66 28 63  id cgi_vprintf(c
67a0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d  onst char *zForm
67b0: 61 74 2c 20 76 61 5f 6c 69 73 74 20 61 70 29 7b  at, va_list ap){
67c0: 0a 20 20 76 78 70 72 69 6e 74 66 28 73 6f 75 74  .  vxprintf(sout
67d0: 2c 30 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a  ,0,zFormat,ap);.
67e0: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61  }.../*.** Send a
67f0: 20 72 65 70 6c 79 20 69 6e 64 69 63 61 74 69 6e   reply indicatin
6800: 67 20 74 68 61 74 20 74 68 65 20 48 54 54 50 20  g that the HTTP 
6810: 72 65 71 75 65 73 74 20 77 61 73 20 6d 61 6c 66  request was malf
6820: 6f 72 6d 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20  ormed.*/.static 
6830: 76 6f 69 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72  void malformed_r
6840: 65 71 75 65 73 74 28 76 6f 69 64 29 7b 0a 20 20  equest(void){.  
6850: 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 35  cgi_set_status(5
6860: 30 31 2c 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65  01, "Not Impleme
6870: 6e 74 65 64 22 29 3b 0a 20 20 63 67 69 5f 70 72  nted");.  cgi_pr
6880: 69 6e 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c  intf(.    "<html
6890: 3e 3c 62 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69  ><body>Unrecogni
68a0: 7a 65 64 20 48 54 54 50 20 52 65 71 75 65 73 74  zed HTTP Request
68b0: 3c 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e  </body></html>\n
68c0: 22 0a 20 20 29 3b 0a 20 20 63 67 69 5f 72 65 70  ".  );.  cgi_rep
68d0: 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b  ly();.  exit(0);
68e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20  .}../*.** Panic 
68f0: 61 6e 64 20 64 69 65 20 77 68 69 6c 65 20 70 72  and die while pr
6900: 6f 63 65 73 73 69 6e 67 20 61 20 77 65 62 70 61  ocessing a webpa
6910: 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  ge..*/.void cgi_
6920: 70 61 6e 69 63 28 63 6f 6e 73 74 20 63 68 61 72  panic(const char
6930: 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b   *zFormat, ...){
6940: 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20  .  va_list ap;. 
6950: 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65   cgi_reset_conte
6960: 6e 74 28 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f  nt();.  cgi_set_
6970: 73 74 61 74 75 73 28 35 30 30 2c 20 22 49 6e 74  status(500, "Int
6980: 65 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72  ernal Server Err
6990: 6f 72 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e  or");.  cgi_prin
69a0: 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c  tf(.    "<html><
69b0: 62 6f 64 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61  body><h1>Interna
69c0: 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72 3c 2f  l Server Error</
69d0: 68 31 3e 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61  h1>\n".    "<pla
69e0: 69 6e 74 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20  intext>".  );.  
69f0: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f  va_start(ap, zFo
6a00: 72 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74  rmat);.  vxprint
6a10: 66 28 73 6f 75 74 2c 30 2c 7a 46 6f 72 6d 61 74  f(sout,0,zFormat
6a20: 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61  ,ap);.  va_end(a
6a30: 70 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28  p);.  cgi_reply(
6a40: 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a  );.  exit(1);.}.
6a50: 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68  ./*.** Remove th
6a60: 65 20 66 69 72 73 74 20 73 70 61 63 65 2d 64 65  e first space-de
6a70: 6c 69 6d 69 74 65 64 20 74 6f 6b 65 6e 20 66 72  limited token fr
6a80: 6f 6d 20 61 20 73 74 72 69 6e 67 20 61 6e 64 20  om a string and 
6a90: 72 65 74 75 72 6e 0a 2a 2a 20 61 20 70 6f 69 6e  return.** a poin
6aa0: 74 65 72 20 74 6f 20 69 74 2e 20 20 41 64 64 20  ter to it.  Add 
6ab0: 61 20 4e 55 4c 4c 20 74 6f 20 74 68 65 20 73 74  a NULL to the st
6ac0: 72 69 6e 67 20 74 6f 20 74 65 72 6d 69 6e 61 74  ring to terminat
6ad0: 65 20 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 20  e the token..** 
6ae0: 4d 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 72 20  Make *zLeftOver 
6af0: 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61  point to the sta
6b00: 72 74 20 6f 66 20 74 68 65 20 6e 65 78 74 20 74  rt of the next t
6b10: 6f 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20  oken..*/.static 
6b20: 63 68 61 72 20 2a 65 78 74 72 61 63 74 5f 74 6f  char *extract_to
6b30: 6b 65 6e 28 63 68 61 72 20 2a 7a 49 6e 70 75 74  ken(char *zInput
6b40: 2c 20 63 68 61 72 20 2a 2a 7a 4c 65 66 74 4f 76  , char **zLeftOv
6b50: 65 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65  er){.  char *zRe
6b60: 73 75 6c 74 20 3d 20 30 3b 0a 20 20 69 66 28 20  sult = 0;.  if( 
6b70: 7a 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20  zInput==0 ){.   
6b80: 20 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 20 29   if( zLeftOver )
6b90: 20 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 30 3b   *zLeftOver = 0;
6ba0: 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20  .    return 0;. 
6bb0: 20 7d 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70   }.  while( issp
6bc0: 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20  ace(*zInput) ){ 
6bd0: 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a 52  zInput++; }.  zR
6be0: 65 73 75 6c 74 20 3d 20 7a 49 6e 70 75 74 3b 0a  esult = zInput;.
6bf0: 20 20 77 68 69 6c 65 28 20 2a 7a 49 6e 70 75 74    while( *zInput
6c00: 20 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a 49   && !isspace(*zI
6c10: 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b  nput) ){ zInput+
6c20: 2b 3b 20 7d 0a 20 20 69 66 28 20 2a 7a 49 6e 70  +; }.  if( *zInp
6c30: 75 74 20 29 7b 0a 20 20 20 20 2a 7a 49 6e 70 75  ut ){.    *zInpu
6c40: 74 20 3d 20 30 3b 0a 20 20 20 20 7a 49 6e 70 75  t = 0;.    zInpu
6c50: 74 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  t++;.    while( 
6c60: 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29  isspace(*zInput)
6c70: 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a   ){ zInput++; }.
6c80: 20 20 7d 0a 20 20 69 66 28 20 7a 4c 65 66 74 4f    }.  if( zLeftO
6c90: 76 65 72 20 29 7b 20 2a 7a 4c 65 66 74 4f 76 65  ver ){ *zLeftOve
6ca0: 72 20 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a 20 20  r = zInput; }.  
6cb0: 72 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a  return zResult;.
6cc0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  }../*.** This ro
6cd0: 75 74 69 6e 65 20 68 61 6e 64 6c 65 73 20 61 20  utine handles a 
6ce0: 73 69 6e 67 6c 65 20 48 54 54 50 20 72 65 71 75  single HTTP requ
6cf0: 65 73 74 20 77 68 69 63 68 20 69 73 20 63 6f 6d  est which is com
6d00: 69 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74 61  ing in on.** sta
6d10: 6e 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20  ndard input and 
6d20: 77 68 69 63 68 20 72 65 70 6c 69 65 73 20 6f 6e  which replies on
6d30: 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74   standard output
6d40: 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 54 50  ..**.** The HTTP
6d50: 20 72 65 71 75 65 73 74 20 69 73 20 72 65 61 64   request is read
6d60: 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 20 69   from standard i
6d70: 6e 70 75 74 20 61 6e 64 20 69 73 20 75 73 65 64  nput and is used
6d80: 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 0a 2a   to initialize.*
6d90: 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61  * environment va
6da0: 72 69 61 62 6c 65 73 20 61 73 20 70 65 72 20 43  riables as per C
6db0: 47 49 2e 20 20 54 68 65 20 63 67 69 5f 69 6e 69  GI.  The cgi_ini
6dc0: 74 28 29 20 72 6f 75 74 69 6e 65 20 74 6f 20 63  t() routine to c
6dd0: 6f 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 65 20 73  omplete.** the s
6de0: 65 74 75 70 2e 20 20 4f 6e 63 65 20 61 6c 6c 20  etup.  Once all 
6df0: 74 68 65 20 73 65 74 75 70 20 69 73 20 66 69 6e  the setup is fin
6e00: 69 73 68 65 64 2c 20 74 68 69 73 20 70 72 6f 63  ished, this proc
6e10: 65 64 75 72 65 20 72 65 74 75 72 6e 73 0a 2a 2a  edure returns.**
6e20: 20 61 6e 64 20 73 75 62 73 65 71 75 65 6e 74 20   and subsequent 
6e30: 63 6f 64 65 20 68 61 6e 64 6c 65 73 20 74 68 65  code handles the
6e40: 20 61 63 74 75 61 6c 20 67 65 6e 65 72 61 74 69   actual generati
6e50: 6f 6e 20 6f 66 20 74 68 65 20 77 65 62 70 61 67  on of the webpag
6e60: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68  e..*/.void cgi_h
6e70: 61 6e 64 6c 65 5f 68 74 74 70 5f 72 65 71 75 65  andle_http_reque
6e80: 73 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 72  st(void){.  char
6e90: 20 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 20   *z, *zToken;.  
6ea0: 69 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 74 20  int i;.  struct 
6eb0: 73 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 6d 6f  sockaddr_in remo
6ec0: 74 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 5f 74  teName;.  size_t
6ed0: 20 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 28 73   size = sizeof(s
6ee0: 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69  truct sockaddr_i
6ef0: 6e 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 6e 65  n);.  char zLine
6f00: 5b 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a 20 41  [2000];     /* A
6f10: 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20   single line of 
6f20: 69 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 66 75 6c  input. */..  ful
6f30: 6c 48 74 74 70 52 65 70 6c 79 20 3d 20 31 3b 0a  lHttpReply = 1;.
6f40: 20 20 69 66 28 20 66 67 65 74 73 28 7a 4c 69 6e    if( fgets(zLin
6f50: 65 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29  e, sizeof(zLine)
6f60: 2c 20 73 74 64 69 6e 29 3d 3d 30 20 29 7b 0a 20  , stdin)==0 ){. 
6f70: 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71     malformed_req
6f80: 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 7a 54  uest();.  }.  zT
6f90: 6f 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 5f 74  oken = extract_t
6fa0: 6f 6b 65 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29 3b  oken(zLine, &z);
6fb0: 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30  .  if( zToken==0
6fc0: 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65   ){.    malforme
6fd0: 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d  d_request();.  }
6fe0: 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54  .  if( strcmp(zT
6ff0: 6f 6b 65 6e 2c 22 47 45 54 22 29 21 3d 30 20 26  oken,"GET")!=0 &
7000: 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c  & strcmp(zToken,
7010: 22 50 4f 53 54 22 29 21 3d 30 0a 20 20 20 20 20  "POST")!=0.     
7020: 20 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65   && strcmp(zToke
7030: 6e 2c 22 48 45 41 44 22 29 21 3d 30 20 29 7b 0a  n,"HEAD")!=0 ){.
7040: 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65      malformed_re
7050: 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 63  quest();.  }.  c
7060: 67 69 5f 73 65 74 65 6e 76 28 22 47 41 54 45 57  gi_setenv("GATEW
7070: 41 59 5f 49 4e 54 45 52 46 41 43 45 22 2c 22 43  AY_INTERFACE","C
7080: 47 49 2f 31 2e 30 22 29 3b 0a 20 20 63 67 69 5f  GI/1.0");.  cgi_
7090: 73 65 74 65 6e 76 28 22 52 45 51 55 45 53 54 5f  setenv("REQUEST_
70a0: 4d 45 54 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29 3b  METHOD",zToken);
70b0: 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72  .  zToken = extr
70c0: 61 63 74 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a 29  act_token(z, &z)
70d0: 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d  ;.  if( zToken==
70e0: 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d  0 ){.    malform
70f0: 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20  ed_request();.  
7100: 7d 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22  }.  cgi_setenv("
7110: 52 45 51 55 45 53 54 5f 55 52 49 22 2c 20 7a 54  REQUEST_URI", zT
7120: 6f 6b 65 6e 29 3b 0a 20 20 66 6f 72 28 69 3d 30  oken);.  for(i=0
7130: 3b 20 7a 54 6f 6b 65 6e 5b 69 5d 20 26 26 20 7a  ; zToken[i] && z
7140: 54 6f 6b 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20 69  Token[i]!='?'; i
7150: 2b 2b 29 7b 7d 0a 20 20 69 66 28 20 7a 54 6f 6b  ++){}.  if( zTok
7160: 65 6e 5b 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b 69  en[i] ) zToken[i
7170: 2b 2b 5d 20 3d 20 30 3b 0a 20 20 63 67 69 5f 73  ++] = 0;.  cgi_s
7180: 65 74 65 6e 76 28 22 50 41 54 48 5f 49 4e 46 4f  etenv("PATH_INFO
7190: 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63 67  ", zToken);.  cg
71a0: 69 5f 73 65 74 65 6e 76 28 22 51 55 45 52 59 5f  i_setenv("QUERY_
71b0: 53 54 52 49 4e 47 22 2c 20 26 7a 54 6f 6b 65 6e  STRING", &zToken
71c0: 5b 69 5d 29 3b 0a 20 20 69 66 28 20 67 65 74 70  [i]);.  if( getp
71d0: 65 65 72 6e 61 6d 65 28 66 69 6c 65 6e 6f 28 73  eername(fileno(s
71e0: 74 64 69 6e 29 2c 20 28 73 74 72 75 63 74 20 73  tdin), (struct s
71f0: 6f 63 6b 61 64 64 72 2a 29 26 72 65 6d 6f 74 65  ockaddr*)&remote
7200: 4e 61 6d 65 2c 20 26 73 69 7a 65 29 3e 3d 30 20  Name, &size)>=0 
7210: 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 49 70  ){.    char *zIp
7220: 41 64 64 72 20 3d 20 69 6e 65 74 5f 6e 74 6f 61  Addr = inet_ntoa
7230: 28 72 65 6d 6f 74 65 4e 61 6d 65 2e 73 69 6e 5f  (remoteName.sin_
7240: 61 64 64 72 29 3b 0a 20 20 20 20 63 67 69 5f 73  addr);.    cgi_s
7250: 65 74 65 6e 76 28 22 52 45 4d 4f 54 45 5f 41 44  etenv("REMOTE_AD
7260: 44 52 22 2c 20 7a 49 70 41 64 64 72 29 3b 0a 0a  DR", zIpAddr);..
7270: 20 20 20 20 2f 2a 20 53 65 74 20 74 68 65 20 47      /* Set the G
7280: 6c 6f 62 61 6c 2e 7a 49 70 41 64 64 72 20 76 61  lobal.zIpAddr va
7290: 72 69 61 62 6c 65 20 74 6f 20 74 68 65 20 73 65  riable to the se
72a0: 72 76 65 72 20 77 65 20 61 72 65 20 74 61 6c 6b  rver we are talk
72b0: 69 6e 67 20 74 6f 2e 0a 20 20 20 20 2a 2a 20 54  ing to..    ** T
72c0: 68 69 73 20 69 73 20 75 73 65 64 20 74 6f 20 70  his is used to p
72d0: 6f 70 75 6c 61 74 65 20 74 68 65 20 69 70 61 64  opulate the ipad
72e0: 64 72 20 63 6f 6c 75 6d 6e 20 6f 66 20 74 68 65  dr column of the
72f0: 20 72 63 76 66 72 6f 6d 20 74 61 62 6c 65 2c 0a   rcvfrom table,.
7300: 20 20 20 20 2a 2a 20 69 66 20 61 6e 79 20 66 69      ** if any fi
7310: 6c 65 73 20 61 72 65 20 72 65 63 65 69 76 65 64  les are received
7320: 20 66 72 6f 6d 20 74 68 65 20 63 6f 6e 6e 65 63   from the connec
7330: 74 65 64 20 63 6c 69 65 6e 74 2e 0a 20 20 20 20  ted client..    
7340: 2a 2f 0a 20 20 20 20 67 2e 7a 49 70 41 64 64 72  */.    g.zIpAddr
7350: 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c   = mprintf("%s",
7360: 20 7a 49 70 41 64 64 72 29 3b 0a 20 20 7d 0a 20   zIpAddr);.  }. 
7370: 0a 20 20 2f 2a 20 47 65 74 20 61 6c 6c 20 74 68  .  /* Get all th
7380: 65 20 6f 70 74 69 6f 6e 61 6c 20 66 69 65 6c 64  e optional field
7390: 73 20 74 68 61 74 20 66 6f 6c 6c 6f 77 20 74 68  s that follow th
73a0: 65 20 66 69 72 73 74 20 6c 69 6e 65 2e 0a 20 20  e first line..  
73b0: 2a 2f 0a 20 20 77 68 69 6c 65 28 20 66 67 65 74  */.  while( fget
73c0: 73 28 7a 4c 69 6e 65 2c 73 69 7a 65 6f 66 28 7a  s(zLine,sizeof(z
73d0: 4c 69 6e 65 29 2c 73 74 64 69 6e 29 20 29 7b 0a  Line),stdin) ){.
73e0: 20 20 20 20 63 68 61 72 20 2a 7a 46 69 65 6c 64      char *zField
73f0: 4e 61 6d 65 3b 0a 20 20 20 20 63 68 61 72 20 2a  Name;.    char *
7400: 7a 56 61 6c 3b 0a 0a 20 20 20 20 7a 46 69 65 6c  zVal;..    zFiel
7410: 64 4e 61 6d 65 20 3d 20 65 78 74 72 61 63 74 5f  dName = extract_
7420: 74 6f 6b 65 6e 28 7a 4c 69 6e 65 2c 26 7a 56 61  token(zLine,&zVa
7430: 6c 29 3b 0a 20 20 20 20 69 66 28 20 7a 46 69 65  l);.    if( zFie
7440: 6c 64 4e 61 6d 65 3d 3d 30 20 7c 7c 20 2a 7a 46  ldName==0 || *zF
7450: 69 65 6c 64 4e 61 6d 65 3d 3d 30 20 29 20 62 72  ieldName==0 ) br
7460: 65 61 6b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20  eak;.    while( 
7470: 69 73 73 70 61 63 65 28 2a 7a 56 61 6c 29 20 29  isspace(*zVal) )
7480: 7b 20 7a 56 61 6c 2b 2b 3b 20 7d 0a 20 20 20 20  { zVal++; }.    
7490: 69 20 3d 20 73 74 72 6c 65 6e 28 7a 56 61 6c 29  i = strlen(zVal)
74a0: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 3e 30  ;.    while( i>0
74b0: 20 26 26 20 69 73 73 70 61 63 65 28 7a 56 61 6c   && isspace(zVal
74c0: 5b 69 2d 31 5d 29 20 29 7b 20 69 2d 2d 3b 20 7d  [i-1]) ){ i--; }
74d0: 0a 20 20 20 20 7a 56 61 6c 5b 69 5d 20 3d 20 30  .    zVal[i] = 0
74e0: 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 7a  ;.    for(i=0; z
74f0: 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 3b 20 69 2b  FieldName[i]; i+
7500: 2b 29 7b 20 7a 46 69 65 6c 64 4e 61 6d 65 5b 69  +){ zFieldName[i
7510: 5d 20 3d 20 74 6f 6c 6f 77 65 72 28 7a 46 69 65  ] = tolower(zFie
7520: 6c 64 4e 61 6d 65 5b 69 5d 29 3b 20 7d 0a 20 20  ldName[i]); }.  
7530: 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69    if( strcmp(zFi
7540: 65 6c 64 4e 61 6d 65 2c 22 75 73 65 72 2d 61 67  eldName,"user-ag
7550: 65 6e 74 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20  ent:")==0 ){.   
7560: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48     cgi_setenv("H
7570: 54 54 50 5f 55 53 45 52 5f 41 47 45 4e 54 22 2c  TTP_USER_AGENT",
7580: 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73   zVal);.    }els
7590: 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69  e if( strcmp(zFi
75a0: 65 6c 64 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74  eldName,"content
75b0: 2d 6c 65 6e 67 74 68 3a 22 29 3d 3d 30 20 29 7b  -length:")==0 ){
75c0: 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e  .      cgi_seten
75d0: 76 28 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54  v("CONTENT_LENGT
75e0: 48 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d  H", zVal);.    }
75f0: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28  else if( strcmp(
7600: 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 72 65 66 65  zFieldName,"refe
7610: 72 65 72 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20  rer:")==0 ){.   
7620: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48     cgi_setenv("H
7630: 54 54 50 5f 52 45 46 45 52 45 52 22 2c 20 7a 56  TTP_REFERER", zV
7640: 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69  al);.    }else i
7650: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64  f( strcmp(zField
7660: 4e 61 6d 65 2c 22 68 6f 73 74 3a 22 29 3d 3d 30  Name,"host:")==0
7670: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65   ){.      cgi_se
7680: 74 65 6e 76 28 22 48 54 54 50 5f 48 4f 53 54 22  tenv("HTTP_HOST"
7690: 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c  , zVal);.    }el
76a0: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46  se if( strcmp(zF
76b0: 69 65 6c 64 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e  ieldName,"conten
76c0: 74 2d 74 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a  t-type:")==0 ){.
76d0: 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76        cgi_setenv
76e0: 28 22 43 4f 4e 54 45 4e 54 5f 54 59 50 45 22 2c  ("CONTENT_TYPE",
76f0: 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73   zVal);.    }els
7700: 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69  e if( strcmp(zFi
7710: 65 6c 64 4e 61 6d 65 2c 22 63 6f 6f 6b 69 65 3a  eldName,"cookie:
7720: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63  ")==0 ){.      c
7730: 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f  gi_setenv("HTTP_
7740: 43 4f 4f 4b 49 45 22 2c 20 7a 56 61 6c 29 3b 0a  COOKIE", zVal);.
7750: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74      }else if( st
7760: 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c  rcmp(zFieldName,
7770: 22 69 66 2d 6e 6f 6e 65 2d 6d 61 74 63 68 3a 22  "if-none-match:"
7780: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67  )==0 ){.      cg
7790: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 49  i_setenv("HTTP_I
77a0: 46 5f 4e 4f 4e 45 5f 4d 41 54 43 48 22 2c 20 7a  F_NONE_MATCH", z
77b0: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20  Val);.    }else 
77c0: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c  if( strcmp(zFiel
77d0: 64 4e 61 6d 65 2c 22 69 66 2d 6d 6f 64 69 66 69  dName,"if-modifi
77e0: 65 64 2d 73 69 6e 63 65 3a 22 29 3d 3d 30 20 29  ed-since:")==0 )
77f0: 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65  {.      cgi_sete
7800: 6e 76 28 22 48 54 54 50 5f 49 46 5f 4d 4f 44 49  nv("HTTP_IF_MODI
7810: 46 49 45 44 5f 53 49 4e 43 45 22 2c 20 7a 56 61  FIED_SINCE", zVa
7820: 6c 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20  l);.    }.  }.. 
7830: 20 63 67 69 5f 69 6e 69 74 28 29 3b 0a 7d 0a 0a   cgi_init();.}..
7840: 2f 2a 0a 2a 2a 20 4d 61 78 69 6d 75 6d 20 6e 75  /*.** Maximum nu
7850: 6d 62 65 72 20 6f 66 20 63 68 69 6c 64 20 70 72  mber of child pr
7860: 6f 63 65 73 73 65 73 20 74 68 61 74 20 77 65 20  ocesses that we 
7870: 63 61 6e 20 68 61 76 65 20 72 75 6e 6e 69 6e 67  can have running
7880: 0a 2a 2a 20 61 74 20 6f 6e 65 20 74 69 6d 65 20  .** at one time 
7890: 62 65 66 6f 72 65 20 77 65 20 73 74 61 72 74 20  before we start 
78a0: 73 6c 6f 77 69 6e 67 20 74 68 69 6e 67 73 20 64  slowing things d
78b0: 6f 77 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20  own..*/.#define 
78c0: 4d 41 58 5f 50 41 52 41 4c 4c 45 4c 20 32 0a 0a  MAX_PARALLEL 2..
78d0: 2f 2a 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20  /*.** Implement 
78e0: 61 6e 20 48 54 54 50 20 73 65 72 76 65 72 20 64  an HTTP server d
78f0: 61 65 6d 6f 6e 20 6c 69 73 74 65 6e 69 6e 67 20  aemon listening 
7900: 6f 6e 20 70 6f 72 74 20 69 50 6f 72 74 2e 0a 2a  on port iPort..*
7910: 2a 0a 2a 2a 20 41 73 20 6e 65 77 20 63 6f 6e 6e  *.** As new conn
7920: 65 63 74 69 6f 6e 73 20 61 72 72 69 76 65 2c 20  ections arrive, 
7930: 66 6f 72 6b 20 61 20 63 68 69 6c 64 20 61 6e 64  fork a child and
7940: 20 6c 65 74 20 63 68 69 6c 64 20 72 65 74 75 72   let child retur
7950: 6e 0a 2a 2a 20 6f 75 74 20 6f 66 20 74 68 69 73  n.** out of this
7960: 20 70 72 6f 63 65 64 75 72 65 20 63 61 6c 6c 2e   procedure call.
7970: 20 20 54 68 65 20 63 68 69 6c 64 20 77 69 6c 6c    The child will
7980: 20 68 61 6e 64 6c 65 20 74 68 65 20 72 65 71 75   handle the requ
7990: 65 73 74 2e 0a 2a 2a 20 54 68 65 20 70 61 72 65  est..** The pare
79a0: 6e 74 20 6e 65 76 65 72 20 72 65 74 75 72 6e 73  nt never returns
79b0: 20 66 72 6f 6d 20 74 68 69 73 20 70 72 6f 63 65   from this proce
79c0: 64 75 72 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  dure..*/.void cg
79d0: 69 5f 68 74 74 70 5f 73 65 72 76 65 72 28 69 6e  i_http_server(in
79e0: 74 20 69 50 6f 72 74 29 7b 0a 20 20 69 6e 74 20  t iPort){.  int 
79f0: 6c 69 73 74 65 6e 65 72 3b 20 20 20 20 20 20 20  listener;       
7a00: 20 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20           /* The 
7a10: 73 65 72 76 65 72 20 73 6f 63 6b 65 74 20 2a 2f  server socket */
7a20: 0a 20 20 69 6e 74 20 63 6f 6e 6e 65 63 74 69 6f  .  int connectio
7a30: 6e 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20  n;              
7a40: 2f 2a 20 41 20 73 6f 63 6b 65 74 20 66 6f 72 20  /* A socket for 
7a50: 65 61 63 68 20 69 6e 64 69 76 69 64 75 61 6c 20  each individual 
7a60: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20  connection */.  
7a70: 66 64 5f 73 65 74 20 72 65 61 64 66 64 73 3b 20  fd_set readfds; 
7a80: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20               /* 
7a90: 53 65 74 20 6f 66 20 66 69 6c 65 20 64 65 73 63  Set of file desc
7aa0: 72 69 70 74 6f 72 73 20 66 6f 72 20 73 65 6c 65  riptors for sele
7ab0: 63 74 28 29 20 2a 2f 0a 20 20 73 69 7a 65 5f 74  ct() */.  size_t
7ac0: 20 6c 65 6e 61 64 64 72 3b 20 20 20 20 20 20 20   lenaddr;       
7ad0: 20 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68         /* Length
7ae0: 20 6f 66 20 74 68 65 20 69 6e 61 64 64 72 20 73   of the inaddr s
7af0: 74 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 69 6e  tructure */.  in
7b00: 74 20 63 68 69 6c 64 3b 20 20 20 20 20 20 20 20  t child;        
7b10: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 49             /* PI
7b20: 44 20 6f 66 20 74 68 65 20 63 68 69 6c 64 20 70  D of the child p
7b30: 72 6f 63 65 73 73 20 2a 2f 0a 20 20 69 6e 74 20  rocess */.  int 
7b40: 6e 63 68 69 6c 64 72 65 6e 20 3d 20 30 3b 20 20  nchildren = 0;  
7b50: 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62           /* Numb
7b60: 65 72 20 6f 66 20 63 68 69 6c 64 20 70 72 6f 63  er of child proc
7b70: 65 73 73 65 73 20 2a 2f 0a 20 20 73 74 72 75 63  esses */.  struc
7b80: 74 20 74 69 6d 65 76 61 6c 20 64 65 6c 61 79 3b  t timeval delay;
7b90: 20 20 20 20 20 20 20 20 2f 2a 20 48 6f 77 20 6c          /* How l
7ba0: 6f 6e 67 20 74 6f 20 77 61 69 74 20 69 6e 73 69  ong to wait insi
7bb0: 64 65 20 73 65 6c 65 63 74 28 29 20 2a 2f 0a 20  de select() */. 
7bc0: 20 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72   struct sockaddr
7bd0: 5f 69 6e 20 69 6e 61 64 64 72 3b 20 20 20 2f 2a  _in inaddr;   /*
7be0: 20 54 68 65 20 73 6f 63 6b 65 74 20 61 64 64 72   The socket addr
7bf0: 65 73 73 20 2a 2f 0a 20 20 69 6e 74 20 6f 70 74  ess */.  int opt
7c00: 20 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20   = 1;           
7c10: 20 20 20 20 20 20 2f 2a 20 73 65 74 73 6f 63 6b        /* setsock
7c20: 6f 70 74 20 66 6c 61 67 20 2a 2f 0a 0a 20 20 6d  opt flag */..  m
7c30: 65 6d 73 65 74 28 26 69 6e 61 64 64 72 2c 20 30  emset(&inaddr, 0
7c40: 2c 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29  , sizeof(inaddr)
7c50: 29 3b 0a 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f  );.  inaddr.sin_
7c60: 66 61 6d 69 6c 79 20 3d 20 41 46 5f 49 4e 45 54  family = AF_INET
7c70: 3b 0a 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f 61  ;.  inaddr.sin_a
7c80: 64 64 72 2e 73 5f 61 64 64 72 20 3d 20 49 4e 41  ddr.s_addr = INA
7c90: 44 44 52 5f 41 4e 59 3b 0a 20 20 69 6e 61 64 64  DDR_ANY;.  inadd
7ca0: 72 2e 73 69 6e 5f 70 6f 72 74 20 3d 20 68 74 6f  r.sin_port = hto
7cb0: 6e 73 28 69 50 6f 72 74 29 3b 0a 20 20 6c 69 73  ns(iPort);.  lis
7cc0: 74 65 6e 65 72 20 3d 20 73 6f 63 6b 65 74 28 41  tener = socket(A
7cd0: 46 5f 49 4e 45 54 2c 20 53 4f 43 4b 5f 53 54 52  F_INET, SOCK_STR
7ce0: 45 41 4d 2c 20 30 29 3b 0a 20 20 69 66 28 20 6c  EAM, 0);.  if( l
7cf0: 69 73 74 65 6e 65 72 3c 30 20 29 7b 0a 20 20 20  istener<0 ){.   
7d00: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c   fprintf(stderr,
7d10: 22 43 61 6e 27 74 20 63 72 65 61 74 65 20 61 20  "Can't create a 
7d20: 73 6f 63 6b 65 74 5c 6e 22 29 3b 0a 20 20 20 20  socket\n");.    
7d30: 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a 0a 20 20  exit(1);.  }..  
7d40: 2f 2a 20 69 66 20 77 65 20 63 61 6e 27 74 20 74  /* if we can't t
7d50: 65 72 6d 69 6e 61 74 65 20 6e 69 63 65 6c 79 2c  erminate nicely,
7d60: 20 61 74 20 6c 65 61 73 74 20 61 6c 6c 6f 77 20   at least allow 
7d70: 74 68 65 20 73 6f 63 6b 65 74 20 74 6f 20 62 65  the socket to be
7d80: 20 72 65 75 73 65 64 20 2a 2f 0a 20 20 73 65 74   reused */.  set
7d90: 73 6f 63 6b 6f 70 74 28 6c 69 73 74 65 6e 65 72  sockopt(listener
7da0: 2c 53 4f 4c 5f 53 4f 43 4b 45 54 2c 53 4f 5f 52  ,SOL_SOCKET,SO_R
7db0: 45 55 53 45 41 44 44 52 2c 26 6f 70 74 2c 73 69  EUSEADDR,&opt,si
7dc0: 7a 65 6f 66 28 6f 70 74 29 29 3b 0a 0a 20 20 69  zeof(opt));..  i
7dd0: 66 28 20 62 69 6e 64 28 6c 69 73 74 65 6e 65 72  f( bind(listener
7de0: 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b 61 64  , (struct sockad
7df0: 64 72 2a 29 26 69 6e 61 64 64 72 2c 20 73 69 7a  dr*)&inaddr, siz
7e00: 65 6f 66 28 69 6e 61 64 64 72 29 29 3c 30 20 29  eof(inaddr))<0 )
7e10: 7b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 73 74  {.    fprintf(st
7e20: 64 65 72 72 2c 22 43 61 6e 27 74 20 62 69 6e 64  derr,"Can't bind
7e30: 20 74 6f 20 70 6f 72 74 20 25 64 5c 6e 22 2c 20   to port %d\n", 
7e40: 69 50 6f 72 74 29 3b 0a 20 20 20 20 65 78 69 74  iPort);.    exit
7e50: 28 31 29 3b 0a 20 20 7d 0a 20 20 6c 69 73 74 65  (1);.  }.  liste
7e60: 6e 28 6c 69 73 74 65 6e 65 72 2c 31 30 29 3b 0a  n(listener,10);.
7e70: 20 20 77 68 69 6c 65 28 20 31 20 29 7b 0a 20 20    while( 1 ){.  
7e80: 20 20 69 66 28 20 6e 63 68 69 6c 64 72 65 6e 3e    if( nchildren>
7e90: 4d 41 58 5f 50 41 52 41 4c 4c 45 4c 20 29 7b 0a  MAX_PARALLEL ){.
7ea0: 20 20 20 20 20 20 2f 2a 20 53 6c 6f 77 20 64 6f        /* Slow do
7eb0: 77 6e 20 69 66 20 63 6f 6e 6e 65 63 74 69 6f 6e  wn if connection
7ec0: 73 20 61 72 65 20 61 72 72 69 76 69 6e 67 20 74  s are arriving t
7ed0: 6f 6f 20 66 61 73 74 20 2a 2f 0a 20 20 20 20 20  oo fast */.     
7ee0: 20 73 6c 65 65 70 28 20 6e 63 68 69 6c 64 72 65   sleep( nchildre
7ef0: 6e 2d 4d 41 58 5f 50 41 52 41 4c 4c 45 4c 20 29  n-MAX_PARALLEL )
7f00: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64 65 6c 61  ;.    }.    dela
7f10: 79 2e 74 76 5f 73 65 63 20 3d 20 36 30 3b 0a 20  y.tv_sec = 60;. 
7f20: 20 20 20 64 65 6c 61 79 2e 74 76 5f 75 73 65 63     delay.tv_usec
7f30: 20 3d 20 30 3b 0a 20 20 20 20 46 44 5f 5a 45 52   = 0;.    FD_ZER
7f40: 4f 28 26 72 65 61 64 66 64 73 29 3b 0a 20 20 20  O(&readfds);.   
7f50: 20 46 44 5f 53 45 54 28 20 6c 69 73 74 65 6e 65   FD_SET( listene
7f60: 72 2c 20 26 72 65 61 64 66 64 73 29 3b 0a 20 20  r, &readfds);.  
7f70: 20 20 69 66 28 20 73 65 6c 65 63 74 28 20 6c 69    if( select( li
7f80: 73 74 65 6e 65 72 2b 31 2c 20 26 72 65 61 64 66  stener+1, &readf
7f90: 64 73 2c 20 30 2c 20 30 2c 20 26 64 65 6c 61 79  ds, 0, 0, &delay
7fa0: 29 20 29 7b 0a 20 20 20 20 20 20 6c 65 6e 61 64  ) ){.      lenad
7fb0: 64 72 20 3d 20 73 69 7a 65 6f 66 28 69 6e 61 64  dr = sizeof(inad
7fc0: 64 72 29 3b 0a 20 20 20 20 20 20 63 6f 6e 6e 65  dr);.      conne
7fd0: 63 74 69 6f 6e 20 3d 20 61 63 63 65 70 74 28 6c  ction = accept(l
7fe0: 69 73 74 65 6e 65 72 2c 20 28 73 74 72 75 63 74  istener, (struct
7ff0: 20 73 6f 63 6b 61 64 64 72 2a 29 26 69 6e 61 64   sockaddr*)&inad
8000: 64 72 2c 20 26 6c 65 6e 61 64 64 72 29 3b 0a 20  dr, &lenaddr);. 
8010: 20 20 20 20 20 69 66 28 20 63 6f 6e 6e 65 63 74       if( connect
8020: 69 6f 6e 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20  ion>=0 ){.      
8030: 20 20 63 68 69 6c 64 20 3d 20 66 6f 72 6b 28 29    child = fork()
8040: 3b 0a 20 20 20 20 20 20 20 20 69 66 28 20 63 68  ;.        if( ch
8050: 69 6c 64 21 3d 30 20 29 7b 0a 20 20 20 20 20 20  ild!=0 ){.      
8060: 20 20 20 20 69 66 28 20 63 68 69 6c 64 3e 30 20      if( child>0 
8070: 29 20 6e 63 68 69 6c 64 72 65 6e 2b 2b 3b 0a 20  ) nchildren++;. 
8080: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 63           close(c
8090: 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20  onnection);.    
80a0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20      }else{.     
80b0: 20 20 20 20 20 63 6c 6f 73 65 28 30 29 3b 0a 20       close(0);. 
80c0: 20 20 20 20 20 20 20 20 20 64 75 70 28 63 6f 6e           dup(con
80d0: 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20  nection);.      
80e0: 20 20 20 20 63 6c 6f 73 65 28 31 29 3b 0a 20 20      close(1);.  
80f0: 20 20 20 20 20 20 20 20 64 75 70 28 63 6f 6e 6e          dup(conn
8100: 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20  ection);.       
8110: 20 20 20 69 66 28 20 21 67 2e 66 48 74 74 70 54     if( !g.fHttpT
8120: 72 61 63 65 20 29 7b 0a 20 20 20 20 20 20 20 20  race ){.        
8130: 20 20 20 20 63 6c 6f 73 65 28 32 29 3b 0a 20 20      close(2);.  
8140: 20 20 20 20 20 20 20 20 20 20 64 75 70 28 63 6f            dup(co
8150: 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20  nnection);.     
8160: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 20       }.         
8170: 20 63 6c 6f 73 65 28 63 6f 6e 6e 65 63 74 69 6f   close(connectio
8180: 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 72 65  n);.          re
8190: 74 75 72 6e 3b 0a 20 20 20 20 20 20 20 20 7d 0a  turn;.        }.
81a0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20        }.    }.  
81b0: 20 20 2f 2a 20 42 75 72 79 20 64 65 61 64 20 63    /* Bury dead c
81c0: 68 69 6c 64 72 65 6e 20 2a 2f 0a 20 20 20 20 77  hildren */.    w
81d0: 68 69 6c 65 28 20 77 61 69 74 70 69 64 28 30 2c  hile( waitpid(0,
81e0: 20 30 2c 20 57 4e 4f 48 41 4e 47 29 3e 30 20 29   0, WNOHANG)>0 )
81f0: 7b 0a 20 20 20 20 20 20 6e 63 68 69 6c 64 72 65  {.      nchildre
8200: 6e 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  n--;.    }.  }. 
8210: 20 2f 2a 20 4e 4f 54 20 52 45 41 43 48 45 44 20   /* NOT REACHED 
8220: 2a 2f 20 20 0a 20 20 65 78 69 74 28 31 29 3b 0a  */  .  exit(1);.
8230: 7d 0a 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66  }../*.** Name of
8240: 20 64 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73   days and months
8250: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73  ..*/.static cons
8260: 74 20 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d  t char *azDays[]
8270: 20 3d 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22   =.    {"Sun", "
8280: 4d 6f 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65  Mon", "Tue", "We
8290: 64 22 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22  d", "Thu", "Fri"
82a0: 2c 20 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61  , "Sat", 0};.sta
82b0: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  tic const char *
82c0: 61 7a 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20  azMonths[] =.   
82d0: 20 7b 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20   {"Jan", "Feb", 
82e0: 22 4d 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d  "Mar", "Apr", "M
82f0: 61 79 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20  ay", "Jun",.    
8300: 20 22 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22   "Jul", "Aug", "
8310: 53 65 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f  Sep", "Oct", "No
8320: 76 22 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a  v", "Dec", 0};..
8330: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61  ./*.** Returns a
8340: 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74  n RFC822-formatt
8350: 65 64 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73  ed time string s
8360: 75 69 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50  uitable for HTTP
8370: 20 68 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a   headers, among.
8380: 2a 2a 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e  ** other things.
8390: 0a 2a 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d  .** Returned tim
83a0: 65 7a 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20  ezone is always 
83b0: 47 4d 54 20 61 73 20 72 65 71 75 69 72 65 64 20  GMT as required 
83c0: 62 79 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63  by HTTP/1.1 spec
83d0: 69 66 69 63 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a  ification..**.**
83e0: 20 53 65 65 20 68 74 74 70 3a 2f 2f 77 77 77 2e   See http://www.
83f0: 66 61 71 73 2e 6f 72 67 2f 72 66 63 73 2f 72 66  faqs.org/rfcs/rf
8400: 63 38 32 32 2e 68 74 6d 6c 2c 20 73 65 63 74 69  c822.html, secti
8410: 6f 6e 20 35 0a 2a 2a 20 61 6e 64 20 68 74 74 70  on 5.** and http
8420: 3a 2f 2f 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f  ://www.faqs.org/
8430: 72 66 63 73 2f 72 66 63 32 36 31 36 2e 68 74 6d  rfcs/rfc2616.htm
8440: 6c 2c 20 73 65 63 74 69 6f 6e 20 33 2e 33 2e 0a  l, section 3.3..
8450: 2a 2f 0a 63 68 61 72 20 2a 63 67 69 5f 72 66 63  */.char *cgi_rfc
8460: 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 74 69  822_datestamp(ti
8470: 6d 65 5f 74 20 6e 6f 77 29 7b 0a 20 20 73 74 72  me_t now){.  str
8480: 75 63 74 20 74 6d 20 2a 70 54 6d 3b 0a 20 20 70  uct tm *pTm;.  p
8490: 54 6d 20 3d 20 67 6d 74 69 6d 65 28 26 6e 6f 77  Tm = gmtime(&now
84a0: 29 3b 0a 20 20 69 66 28 20 70 54 6d 3d 3d 30 20  );.  if( pTm==0 
84b0: 29 20 72 65 74 75 72 6e 20 22 22 3b 0a 20 20 72  ) return "";.  r
84c0: 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 28 22 25  eturn mprintf("%
84d0: 73 2c 20 25 64 20 25 73 20 25 30 32 64 20 25 30  s, %d %s %02d %0
84e0: 32 64 3a 25 30 32 64 3a 25 30 32 64 20 47 4d 54  2d:%02d:%02d GMT
84f0: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ",.             
8500: 20 20 20 20 61 7a 44 61 79 73 5b 70 54 6d 2d 3e      azDays[pTm->
8510: 74 6d 5f 77 64 61 79 5d 2c 20 70 54 6d 2d 3e 74  tm_wday], pTm->t
8520: 6d 5f 6d 64 61 79 2c 20 61 7a 4d 6f 6e 74 68 73  m_mday, azMonths
8530: 5b 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d 2c 0a 20  [pTm->tm_mon],. 
8540: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8550: 70 54 6d 2d 3e 74 6d 5f 79 65 61 72 2b 31 39 30  pTm->tm_year+190
8560: 30 2c 20 70 54 6d 2d 3e 74 6d 5f 68 6f 75 72 2c  0, pTm->tm_hour,
8570: 20 70 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c 20 70 54   pTm->tm_min, pT
8580: 6d 2d 3e 74 6d 5f 73 65 63 29 3b 0a 7d 0a 0a 2f  m->tm_sec);.}../
8590: 2a 0a 2a 2a 20 50 61 72 73 65 20 61 6e 20 52 46  *.** Parse an RF
85a0: 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 64 20 74  C822-formatted t
85b0: 69 6d 65 73 74 61 6d 70 20 61 73 20 77 65 27 64  imestamp as we'd
85c0: 20 65 78 70 65 63 74 20 66 72 6f 6d 20 48 54 54   expect from HTT
85d0: 50 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20  P and return.** 
85e0: 61 20 55 6e 69 78 20 65 70 6f 63 68 20 74 69 6d  a Unix epoch tim
85f0: 65 2e 20 3c 3d 20 7a 65 72 6f 20 69 73 20 72 65  e. <= zero is re
8600: 74 75 72 6e 65 64 20 6f 6e 20 66 61 69 6c 75 72  turned on failur
8610: 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68  e..**.** Note th
8620: 61 74 20 74 68 69 73 20 77 6f 6e 27 74 20 68 61  at this won't ha
8630: 6e 64 6c 65 20 61 6c 6c 20 74 68 65 20 5f 61 6c  ndle all the _al
8640: 6c 6f 77 65 64 5f 20 48 54 54 50 20 66 6f 72 6d  lowed_ HTTP form
8650: 61 74 73 2c 20 6a 75 73 74 20 74 68 65 0a 2a 2a  ats, just the.**
8660: 20 6d 6f 73 74 20 70 6f 70 75 6c 61 72 20 6f 6e   most popular on
8670: 65 20 28 74 68 65 20 6f 6e 65 20 67 65 6e 65 72  e (the one gener
8680: 61 74 65 64 20 62 79 20 63 67 69 5f 72 66 63 38  ated by cgi_rfc8
8690: 32 32 5f 64 61 74 65 73 74 61 6d 70 28 29 2c 20  22_datestamp(), 
86a0: 61 63 74 75 61 6c 6c 79 29 2e 0a 2a 2f 0a 74 69  actually)..*/.ti
86b0: 6d 65 5f 74 20 63 67 69 5f 72 66 63 38 32 32 5f  me_t cgi_rfc822_
86c0: 70 61 72 73 65 64 61 74 65 28 63 6f 6e 73 74 20  parsedate(const 
86d0: 63 68 61 72 20 2a 7a 44 61 74 65 29 7b 0a 20 20  char *zDate){.  
86e0: 73 74 72 75 63 74 20 74 6d 20 74 3b 0a 20 20 63  struct tm t;.  c
86f0: 68 61 72 20 7a 49 67 6e 6f 72 65 5b 31 36 5d 3b  har zIgnore[16];
8700: 0a 20 20 63 68 61 72 20 7a 4d 6f 6e 74 68 5b 31  .  char zMonth[1
8710: 36 5d 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 74  6];..  memset(&t
8720: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 74 29 29 3b  , 0, sizeof(t));
8730: 0a 20 20 69 66 28 20 37 3d 3d 73 73 63 61 6e 66  .  if( 7==sscanf
8740: 28 7a 44 61 74 65 2c 20 22 25 31 32 5b 41 2d 5a  (zDate, "%12[A-Z
8750: 61 2d 7a 2c 5d 20 25 64 20 25 31 32 5b 41 2d 5a  a-z,] %d %12[A-Z
8760: 61 2d 7a 5d 20 25 64 20 25 64 3a 25 64 3a 25 64  a-z] %d %d:%d:%d
8770: 22 2c 20 7a 49 67 6e 6f 72 65 2c 0a 20 20 20 20  ", zIgnore,.    
8780: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8790: 20 20 20 26 74 2e 74 6d 5f 6d 64 61 79 2c 20 7a     &t.tm_mday, z
87a0: 4d 6f 6e 74 68 2c 20 26 74 2e 74 6d 5f 79 65 61  Month, &t.tm_yea
87b0: 72 2c 20 26 74 2e 74 6d 5f 68 6f 75 72 2c 20 26  r, &t.tm_hour, &
87c0: 74 2e 74 6d 5f 6d 69 6e 2c 0a 20 20 20 20 20 20  t.tm_min,.      
87d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
87e0: 20 26 74 2e 74 6d 5f 73 65 63 29 29 7b 0a 0a 20   &t.tm_sec)){.. 
87f0: 20 20 20 69 66 28 20 74 2e 74 6d 5f 79 65 61 72     if( t.tm_year
8800: 20 3e 20 31 39 30 30 20 29 20 74 2e 74 6d 5f 79   > 1900 ) t.tm_y
8810: 65 61 72 20 2d 3d 20 31 39 30 30 3b 0a 20 20 20  ear -= 1900;.   
8820: 20 66 6f 72 28 74 2e 74 6d 5f 6d 6f 6e 3d 30 3b   for(t.tm_mon=0;
8830: 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d   azMonths[t.tm_m
8840: 6f 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e 2b 2b 29  on]; t.tm_mon++)
8850: 7b 0a 20 20 20 20 20 20 69 66 28 20 21 73 74 72  {.      if( !str
8860: 6e 63 61 73 65 63 6d 70 28 20 61 7a 4d 6f 6e 74  ncasecmp( azMont
8870: 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c 20 7a 4d  hs[t.tm_mon], zM
8880: 6f 6e 74 68 2c 20 33 20 29 29 7b 0a 20 20 20 20  onth, 3 )){.    
8890: 20 20 20 20 72 65 74 75 72 6e 20 6d 6b 67 6d 74      return mkgmt
88a0: 69 6d 65 28 26 74 29 3b 0a 20 20 20 20 20 20 7d  ime(&t);.      }
88b0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
88c0: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn 0;.}../*.**
88d0: 20 43 6f 6e 76 65 72 74 20 61 20 73 74 72 75 63   Convert a struc
88e0: 74 20 74 6d 2a 20 74 68 61 74 20 72 65 70 72 65  t tm* that repre
88f0: 73 65 6e 74 73 20 61 20 6d 6f 6d 65 6e 74 20 69  sents a moment i
8900: 6e 20 55 54 43 20 69 6e 74 6f 20 74 68 65 20 6e  n UTC into the n
8910: 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 73 65 63 6f  umber.** of seco
8920: 6e 64 73 20 69 6e 20 31 39 37 30 2c 20 55 54 43  nds in 1970, UTC
8930: 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 6d 6b 67 6d  ..*/.time_t mkgm
8940: 74 69 6d 65 28 73 74 72 75 63 74 20 74 6d 20 2a  time(struct tm *
8950: 70 29 7b 0a 20 20 74 69 6d 65 5f 74 20 74 3b 0a  p){.  time_t t;.
8960: 20 20 69 6e 74 20 6e 44 61 79 3b 0a 20 20 69 6e    int nDay;.  in
8970: 74 20 69 73 4c 65 61 70 59 72 3b 0a 20 20 2f 2a  t isLeapYr;.  /*
8980: 20 44 61 79 73 20 69 6e 20 65 61 63 68 20 6d 6f   Days in each mo
8990: 6e 74 68 3a 20 20 20 20 20 20 20 33 31 2c 20 32  nth:       31, 2
89a0: 38 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33  8, 31, 30, 31, 3
89b0: 30 2c 20 33 31 2c 20 33 31 2c 20 33 30 2c 20 33  0, 31, 31, 30, 3
89c0: 31 2c 20 33 30 2c 20 33 31 20 2a 2f 0a 20 20 73  1, 30, 31 */.  s
89d0: 74 61 74 69 63 20 69 6e 74 20 70 72 69 6f 72 44  tatic int priorD
89e0: 61 79 73 5b 5d 20 20 20 3d 20 7b 20 20 30 2c 20  ays[]   = {  0, 
89f0: 33 31 2c 20 35 39 2c 20 39 30 2c 31 32 30 2c 31  31, 59, 90,120,1
8a00: 35 31 2c 31 38 31 2c 32 31 32 2c 32 34 33 2c 32  51,181,212,243,2
8a10: 37 33 2c 33 30 34 2c 33 33 34 20 7d 3b 0a 20 20  73,304,334 };.  
8a20: 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3c 30 20  if( p->tm_mon<0 
8a30: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 59 65 61 72  ){.    int nYear
8a40: 20 3d 20 28 31 31 20 2d 20 70 2d 3e 74 6d 5f 6d   = (11 - p->tm_m
8a50: 6f 6e 29 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74  on)/12;.    p->t
8a60: 6d 5f 79 65 61 72 20 2d 3d 20 6e 59 65 61 72 3b  m_year -= nYear;
8a70: 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 20 2b  .    p->tm_mon +
8a80: 3d 20 6e 59 65 61 72 2a 31 32 3b 0a 20 20 7d 65  = nYear*12;.  }e
8a90: 6c 73 65 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f  lse if( p->tm_mo
8aa0: 6e 3e 31 31 20 29 7b 0a 20 20 20 20 70 2d 3e 74  n>11 ){.    p->t
8ab0: 6d 5f 79 65 61 72 20 2b 3d 20 70 2d 3e 74 6d 5f  m_year += p->tm_
8ac0: 6d 6f 6e 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74  mon/12;.    p->t
8ad0: 6d 5f 6d 6f 6e 20 25 3d 20 31 32 3b 0a 20 20 7d  m_mon %= 12;.  }
8ae0: 0a 20 20 69 73 4c 65 61 70 59 72 20 3d 20 70 2d  .  isLeapYr = p-
8af0: 3e 74 6d 5f 79 65 61 72 25 34 3d 3d 30 20 26 26  >tm_year%4==0 &&
8b00: 20 28 70 2d 3e 74 6d 5f 79 65 61 72 25 31 30 30   (p->tm_year%100
8b10: 21 3d 30 20 7c 7c 20 28 70 2d 3e 74 6d 5f 79 65  !=0 || (p->tm_ye
8b20: 61 72 2b 33 30 30 29 25 34 30 30 3d 3d 30 29 3b  ar+300)%400==0);
8b30: 0a 20 20 70 2d 3e 74 6d 5f 79 64 61 79 20 3d 20  .  p->tm_yday = 
8b40: 70 72 69 6f 72 44 61 79 73 5b 70 2d 3e 74 6d 5f  priorDays[p->tm_
8b50: 6d 6f 6e 5d 20 2b 20 70 2d 3e 74 6d 5f 6d 64 61  mon] + p->tm_mda
8b60: 79 20 2d 20 31 3b 0a 20 20 69 66 28 20 69 73 4c  y - 1;.  if( isL
8b70: 65 61 70 59 72 20 26 26 20 70 2d 3e 74 6d 5f 6d  eapYr && p->tm_m
8b80: 6f 6e 3e 31 20 29 20 70 2d 3e 74 6d 5f 79 64 61  on>1 ) p->tm_yda
8b90: 79 2b 2b 3b 0a 20 20 6e 44 61 79 20 3d 20 28 70  y++;.  nDay = (p
8ba0: 2d 3e 74 6d 5f 79 65 61 72 2d 37 30 29 2a 33 36  ->tm_year-70)*36
8bb0: 35 20 2b 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d  5 + (p->tm_year-
8bc0: 36 39 29 2f 34 20 2d 70 2d 3e 74 6d 5f 79 65 61  69)/4 -p->tm_yea
8bd0: 72 2f 31 30 30 20 2b 20 0a 20 20 20 20 20 20 20  r/100 + .       
8be0: 20 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2b 33 30    (p->tm_year+30
8bf0: 30 29 2f 34 30 30 20 2b 20 70 2d 3e 74 6d 5f 79  0)/400 + p->tm_y
8c00: 64 61 79 3b 0a 20 20 74 20 3d 20 28 28 6e 44 61  day;.  t = ((nDa
8c10: 79 2a 32 34 20 2b 20 70 2d 3e 74 6d 5f 68 6f 75  y*24 + p->tm_hou
8c20: 72 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 6d 69  r)*60 + p->tm_mi
8c30: 6e 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 73 65  n)*60 + p->tm_se
8c40: 63 3b 0a 20 20 72 65 74 75 72 6e 20 74 3b 0a 7d  c;.  return t;.}
8c50: 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68  ../*.** Check th
8c60: 65 20 6f 62 6a 65 63 74 54 69 6d 65 20 61 67 61  e objectTime aga
8c70: 69 6e 73 74 20 74 68 65 20 49 66 2d 4d 6f 64 69  inst the If-Modi
8c80: 66 69 65 64 2d 53 69 6e 63 65 20 72 65 71 75 65  fied-Since reque
8c90: 73 74 20 68 65 61 64 65 72 2e 20 49 66 20 74 68  st header. If th
8ca0: 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 74 69 6d 65  e.** object time
8cb0: 20 69 73 6e 27 74 20 61 6e 79 20 6e 65 77 65 72   isn't any newer
8cc0: 20 74 68 61 6e 20 74 68 65 20 68 65 61 64 65 72   than the header
8cd0: 2c 20 77 65 20 69 6d 6d 65 64 69 61 74 65 6c 79  , we immediately
8ce0: 20 73 65 6e 64 20 62 61 63 6b 0a 2a 2a 20 61 20   send back.** a 
8cf0: 33 30 34 20 72 65 70 6c 79 20 61 6e 64 20 65 78  304 reply and ex
8d00: 69 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  it..*/.void cgi_
8d10: 6d 6f 64 69 66 69 65 64 5f 73 69 6e 63 65 28 74  modified_since(t
8d20: 69 6d 65 5f 74 20 6f 62 6a 65 63 74 54 69 6d 65  ime_t objectTime
8d30: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
8d40: 2a 7a 49 66 20 3d 20 50 28 22 48 54 54 50 5f 49  *zIf = P("HTTP_I
8d50: 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 4e 43 45  F_MODIFIED_SINCE
8d60: 22 29 3b 0a 20 20 69 66 28 20 7a 49 66 3d 3d 30  ");.  if( zIf==0
8d70: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28   ) return;.  if(
8d80: 20 6f 62 6a 65 63 74 54 69 6d 65 20 3e 20 63 67   objectTime > cg
8d90: 69 5f 72 66 63 38 32 32 5f 70 61 72 73 65 64 61  i_rfc822_parseda
8da0: 74 65 28 7a 49 66 29 20 29 20 72 65 74 75 72 6e  te(zIf) ) return
8db0: 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74  ;.  cgi_set_stat
8dc0: 75 73 28 33 30 34 2c 22 4e 6f 74 20 4d 6f 64 69  us(304,"Not Modi
8dd0: 66 69 65 64 22 29 3b 0a 20 20 63 67 69 5f 72 65  fied");.  cgi_re
8de0: 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20  set_content();. 
8df0: 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20   cgi_reply();.  
8e00: 65 78 69 74 28 30 29 3b 0a 7d 0a                 exit(0);.}.