Hex Artifact Content
Not logged in

Artifact fb85a3385bdb28bbce74e844eadd731546c1f501:

File src/cgi.c part of check-in [555911dff5] - Render the header of every page using subscript. Add a setup page that for editing that subscript. by drh on 2007-11-21 03:01:40.

0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20  /*.** Copyright 
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68  (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54  ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66  his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f  ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75  u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20  te it and/or.** 
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20  modify it under 
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65  the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62   GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76  lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c  ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65  ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69  ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73  s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20  tributed in the 
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c  hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20  l be useful,.** 
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20  but WITHOUT ANY 
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75  WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69  t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a  ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54  * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52  Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55   A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20  RPOSE.  See the 
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50  GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f  ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a  r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c  ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20  d have received 
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e  a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63  U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e  .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72  g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69  ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65  te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64  e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20  ation, Inc., 59 
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53  Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73  uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31  ton, MA  02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20  307, USA..**.** 
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69  Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20  nformation:.**  
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a   drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68  *   http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a  waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a  ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65  .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 43 20 66 75 6e 63   contains C func
0380: 74 69 6f 6e 73 20 61 6e 64 20 70 72 6f 63 65 64  tions and proced
0390: 75 72 65 73 20 74 68 61 74 20 70 72 6f 76 69 64  ures that provid
03a0: 65 20 75 73 65 66 75 6c 0a 2a 2a 20 73 65 72 76  e useful.** serv
03b0: 69 63 65 73 20 74 6f 20 43 47 49 20 70 72 6f 67  ices to CGI prog
03c0: 72 61 6d 73 2e 20 20 54 68 65 72 65 20 61 72 65  rams.  There are
03d0: 20 70 72 6f 63 65 64 75 72 65 73 20 66 6f 72 20   procedures for 
03e0: 70 61 72 73 69 6e 67 20 61 6e 64 0a 2a 2a 20 64  parsing and.** d
03f0: 69 73 70 65 6e 73 69 6e 67 20 51 55 45 52 59 5f  ispensing QUERY_
0400: 53 54 52 49 4e 47 20 70 61 72 61 6d 65 74 65 72  STRING parameter
0410: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2c 20 74  s and cookies, t
0420: 68 65 20 22 6d 70 72 69 6e 74 66 28 29 22 0a 2a  he "mprintf()".*
0430: 2a 20 66 6f 72 6d 61 74 74 69 6e 67 20 66 75 6e  * formatting fun
0440: 63 74 69 6f 6e 20 61 6e 64 20 69 74 73 20 63 6f  ction and its co
0450: 75 73 69 6e 73 2c 20 61 6e 64 20 72 6f 75 74 69  usins, and routi
0460: 6e 65 73 20 74 6f 20 65 6e 63 6f 64 65 20 61 6e  nes to encode an
0470: 64 0a 2a 2a 20 64 65 63 6f 64 65 20 73 74 72 69  d.** decode stri
0480: 6e 67 73 20 69 6e 20 48 54 4d 4c 20 6f 72 20 48  ngs in HTML or H
0490: 54 54 50 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65  TTP..*/.#include
04a0: 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 66 64   "config.h".#ifd
04b0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 23  ef __MINGW32__.#
04c0: 20 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e 64 6f    include <windo
04d0: 77 73 2e 68 3e 20 20 20 20 20 20 20 20 20 20 20  ws.h>           
04e0: 2f 2a 20 66 6f 72 20 53 6c 65 65 70 20 6f 6e 63  /* for Sleep onc
04f0: 65 20 73 65 72 76 65 72 20 77 6f 72 6b 73 20 61  e server works a
0500: 67 61 69 6e 20 2a 2f 0a 23 20 20 69 6e 63 6c 75  gain */.#  inclu
0510: 64 65 20 3c 77 69 6e 73 6f 63 6b 32 2e 68 3e 20  de <winsock2.h> 
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 6f 63 6b           /* sock
0530: 65 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f  et operations */
0540: 0a 23 20 20 64 65 66 69 6e 65 20 73 6c 65 65 70  .#  define sleep
0550: 20 53 6c 65 65 70 20 20 20 20 20 20 20 20 20 20   Sleep          
0560: 20 20 2f 2a 20 77 69 6e 64 6f 77 73 20 64 6f 65    /* windows doe
0570: 73 20 6e 6f 74 20 68 61 76 65 20 73 6c 65 65 70  s not have sleep
0580: 2c 20 62 75 74 20 53 6c 65 65 70 20 2a 2f 0a 23  , but Sleep */.#
0590: 20 20 69 6e 63 6c 75 64 65 20 3c 77 73 32 74 63    include <ws2tc
05a0: 70 69 70 2e 68 3e 20 20 20 20 20 20 20 20 20 20  pip.h>          
05b0: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64  .#else.#  includ
05c0: 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e  e <sys/socket.h>
05d0: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74  .#  include <net
05e0: 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e  inet/in.h>.#  in
05f0: 63 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74  clude <arpa/inet
0600: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c  .h>.#  include <
0610: 73 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20  sys/times.h>.#  
0620: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d  include <sys/tim
0630: 65 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20  e.h>.#  include 
0640: 3c 73 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20  <sys/wait.h>.#  
0650: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c  include <sys/sel
0660: 65 63 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69  ect.h>.#endif.#i
0670: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a  nclude <time.h>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e  #include <stdio.
0690: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64  h>.#include <std
06a0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  lib.h>.#include 
06b0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c  <unistd.h>.#incl
06c0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66  ude "cgi.h"..#if
06d0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a   INTERFACE./*.**
06e0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63   Shortcuts for c
06f0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50  gi_parameter.  P
0700: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68  ("x") returns th
0710: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79  e value of query
0720: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72   parameter.** or
0730: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20   cookie "x", or 
0740: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73  NULL if there is
0750: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74   no such paramet
0760: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50  er or cookie.  P
0770: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f  D("x","y").** do
0780: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65  es the same exce
0790: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e  pt "y" is return
07a0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e  ed in place of N
07b0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20  ULL if there is 
07c0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64  not match..*/.#d
07d0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20  efine P(x)      
07e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28    cgi_parameter(
07f0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50  (x),0).#define P
0800: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70  D(x,y)     cgi_p
0810: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29  arameter((x),(y)
0820: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20  ).#define QP(x) 
0830: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73        quotable_s
0840: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65  tring(cgi_parame
0850: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66  ter((x),0)).#def
0860: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20  ine QPD(x,y)    
0870: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28  quotable_string(
0880: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78  cgi_parameter((x
0890: 29 2c 28 79 29 29 29 0a 0a 23 65 6e 64 69 66 20  ),(y)))..#endif 
08a0: 2f 2a 20 49 4e 54 45 52 46 41 43 45 20 2a 2f 0a  /* INTERFACE */.
08b0: 0a 2f 2a 0a 2a 2a 20 50 72 6f 76 69 64 65 20 61  ./*.** Provide a
08c0: 20 72 65 6c 69 61 62 6c 65 20 69 6d 70 6c 65 6d   reliable implem
08d0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 61 20 63 61  entation of a ca
08e0: 73 65 6c 65 73 73 20 73 74 72 69 6e 67 20 63 6f  seless string co
08f0: 6d 70 61 72 69 73 6f 6e 0a 2a 2a 20 66 75 6e 63  mparison.** func
0900: 74 69 6f 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65  tion..*/.#define
0910: 20 73 74 72 69 63 6d 70 20 73 71 6c 69 74 65 33   stricmp sqlite3
0920: 53 74 72 49 43 6d 70 0a 65 78 74 65 72 6e 20 69  StrICmp.extern i
0930: 6e 74 20 73 71 6c 69 74 65 33 53 74 72 49 43 6d  nt sqlite3StrICm
0940: 70 28 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 63  p(const char*, c
0950: 6f 6e 73 74 20 63 68 61 72 2a 29 3b 0a 0a 2f 2a  onst char*);../*
0960: 0a 2a 2a 20 54 68 65 20 62 6f 64 79 20 6f 66 20  .** The body of 
0970: 74 68 65 20 48 54 54 50 20 72 65 70 6c 79 20 74  the HTTP reply t
0980: 65 78 74 20 69 73 20 73 74 6f 72 65 64 20 68 65  ext is stored he
0990: 72 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42 6c  re..*/.static Bl
09a0: 6f 62 20 63 67 69 43 6f 6e 74 65 6e 74 20 3d 20  ob cgiContent = 
09b0: 42 4c 4f 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52  BLOB_INITIALIZER
09c0: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20  ;../*.** Append 
09d0: 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 6f  reply content to
09e0: 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 65 78   what already ex
09f0: 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67  ists..*/.void cg
0a00: 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e 74  i_append_content
0a10: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 61  (const char *zDa
0a20: 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b 0a 20  ta, int nAmt){. 
0a30: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 63 67   blob_append(&cg
0a40: 69 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c  iContent, zData,
0a50: 20 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   nAmt);.}../*.**
0a60: 20 52 65 73 65 74 20 74 68 65 20 48 54 54 50 20   Reset the HTTP 
0a70: 72 65 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65  reply text to be
0a80: 20 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67   an empty string
0a90: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65  ..*/.void cgi_re
0aa0: 73 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64  set_content(void
0ab0: 29 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28  ){.  blob_reset(
0ac0: 26 63 67 69 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a  &cgiContent);.}.
0ad0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20  ./*.** Return a 
0ae0: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43  pointer to the C
0af0: 47 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a  GI output blob..
0b00: 2a 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74  */.Blob *cgi_out
0b10: 70 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a  put_blob(void){.
0b20: 20 20 72 65 74 75 72 6e 20 26 63 67 69 43 6f 6e    return &cgiCon
0b30: 74 65 6e 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52  tent;.}../*.** R
0b40: 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20  eturn a pointer 
0b50: 74 6f 20 74 68 65 20 48 54 54 50 20 72 65 70 6c  to the HTTP repl
0b60: 79 20 74 65 78 74 2e 0a 2a 2f 0a 63 68 61 72 20  y text..*/.char 
0b70: 2a 63 67 69 5f 65 78 74 72 61 63 74 5f 63 6f 6e  *cgi_extract_con
0b80: 74 65 6e 74 28 69 6e 74 20 2a 70 6e 41 6d 74 29  tent(int *pnAmt)
0b90: 7b 0a 20 20 72 65 74 75 72 6e 20 62 6c 6f 62 5f  {.  return blob_
0ba0: 62 75 66 66 65 72 28 26 63 67 69 43 6f 6e 74 65  buffer(&cgiConte
0bb0: 6e 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64  nt);.}../*.** Ad
0bc0: 64 69 74 69 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61  ditional informa
0bd0: 74 69 6f 6e 20 75 73 65 64 20 74 6f 20 66 6f 72  tion used to for
0be0: 6d 20 74 68 65 20 48 54 54 50 20 72 65 70 6c 79  m the HTTP reply
0bf0: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20  .*/.static char 
0c00: 2a 7a 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20  *zContentType = 
0c10: 22 74 65 78 74 2f 68 74 6d 6c 22 3b 20 20 20 20  "text/html";    
0c20: 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 79 70 65   /* Content type
0c30: 20 6f 66 20 74 68 65 20 72 65 70 6c 79 20 2a 2f   of the reply */
0c40: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 7a 52  .static char *zR
0c50: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4f 4b  eplyStatus = "OK
0c60: 22 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a  ";            /*
0c70: 20 52 65 70 6c 79 20 73 74 61 74 75 73 20 64 65   Reply status de
0c80: 73 63 72 69 70 74 69 6f 6e 20 2a 2f 0a 73 74 61  scription */.sta
0c90: 74 69 63 20 69 6e 74 20 69 52 65 70 6c 79 53 74  tic int iReplySt
0ca0: 61 74 75 73 20 3d 20 32 30 30 3b 20 20 20 20 20  atus = 200;     
0cb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 70            /* Rep
0cc0: 6c 79 20 73 74 61 74 75 73 20 63 6f 64 65 20 2a  ly status code *
0cd0: 2f 0a 73 74 61 74 69 63 20 42 6c 6f 62 20 65 78  /.static Blob ex
0ce0: 74 72 61 48 65 61 64 65 72 20 3d 20 42 4c 4f 42  traHeader = BLOB
0cf0: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 20 20 2f  _INITIALIZER;  /
0d00: 2a 20 45 78 74 72 61 20 68 65 61 64 65 72 20 74  * Extra header t
0d10: 65 78 74 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ext */.static in
0d20: 74 20 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20  t fullHttpReply 
0d30: 3d 20 30 3b 20 20 20 20 20 20 2f 2a 20 54 72 75  = 0;      /* Tru
0d40: 65 20 66 6f 72 20 61 20 66 75 6c 6c 2d 62 6c 6f  e for a full-blo
0d50: 77 6e 20 48 54 54 50 20 68 65 61 64 65 72 20 2a  wn HTTP header *
0d60: 2f 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65  /../*.** Set the
0d70: 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74   reply content t
0d80: 79 70 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  ype.*/.void cgi_
0d90: 73 65 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65  set_content_type
0da0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79  (const char *zTy
0db0: 70 65 29 7b 0a 20 20 7a 43 6f 6e 74 65 6e 74 54  pe){.  zContentT
0dc0: 79 70 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25  ype = mprintf("%
0dd0: 73 22 2c 20 7a 54 79 70 65 29 3b 0a 7d 0a 0a 2f  s", zType);.}../
0de0: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70  *.** Set the rep
0df0: 6c 79 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68  ly content to th
0e00: 65 20 73 70 65 63 69 66 69 65 64 20 42 4c 4f 42  e specified BLOB
0e10: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65  ..*/.void cgi_se
0e20: 74 5f 63 6f 6e 74 65 6e 74 28 42 6c 6f 62 20 2a  t_content(Blob *
0e30: 70 4e 65 77 43 6f 6e 74 65 6e 74 29 7b 0a 20 20  pNewContent){.  
0e40: 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67 69 43  blob_reset(&cgiC
0e50: 6f 6e 74 65 6e 74 29 3b 0a 20 20 63 67 69 43 6f  ontent);.  cgiCo
0e60: 6e 74 65 6e 74 20 3d 20 2a 70 4e 65 77 43 6f 6e  ntent = *pNewCon
0e70: 74 65 6e 74 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72  tent;.  blob_zer
0e80: 6f 28 70 4e 65 77 43 6f 6e 74 65 6e 74 29 3b 0a  o(pNewContent);.
0e90: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65  }../*.** Set the
0ea0: 20 72 65 70 6c 79 20 73 74 61 74 75 73 20 63 6f   reply status co
0eb0: 64 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73  de.*/.void cgi_s
0ec0: 65 74 5f 73 74 61 74 75 73 28 69 6e 74 20 69 53  et_status(int iS
0ed0: 74 61 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  tat, const char 
0ee0: 2a 7a 53 74 61 74 29 7b 0a 20 20 7a 52 65 70 6c  *zStat){.  zRepl
0ef0: 79 53 74 61 74 75 73 20 3d 20 6d 70 72 69 6e 74  yStatus = mprint
0f00: 66 28 22 25 73 22 2c 20 7a 53 74 61 74 29 3b 0a  f("%s", zStat);.
0f10: 20 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d    iReplyStatus =
0f20: 20 69 53 74 61 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a   iStat;.}../*.**
0f30: 20 41 70 70 65 6e 64 20 74 65 78 74 20 74 6f 20   Append text to 
0f40: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 61 6e  the header of an
0f50: 20 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 76   HTTP reply.*/.v
0f60: 6f 69 64 20 63 67 69 5f 61 70 70 65 6e 64 5f 68  oid cgi_append_h
0f70: 65 61 64 65 72 28 63 6f 6e 73 74 20 63 68 61 72  eader(const char
0f80: 20 2a 7a 4c 69 6e 65 29 7b 0a 20 20 62 6c 6f 62   *zLine){.  blob
0f90: 5f 61 70 70 65 6e 64 28 26 65 78 74 72 61 48 65  _append(&extraHe
0fa0: 61 64 65 72 2c 20 7a 4c 69 6e 65 2c 20 2d 31 29  ader, zLine, -1)
0fb0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61  ;.}../*.** Set a
0fc0: 20 63 6f 6f 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 5a   cookie..**.** Z
0fd0: 65 72 6f 20 6c 69 66 65 74 69 6d 65 20 69 6d 70  ero lifetime imp
0fe0: 6c 69 65 73 20 61 20 73 65 73 73 69 6f 6e 20 63  lies a session c
0ff0: 6f 6f 6b 69 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63  ookie..*/.void c
1000: 67 69 5f 73 65 74 5f 63 6f 6f 6b 69 65 28 0a 20  gi_set_cookie(. 
1010: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
1020: 6d 65 2c 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f  me,    /* Name o
1030: 66 20 74 68 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a  f the cookie */.
1040: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56    const char *zV
1050: 61 6c 75 65 2c 20 20 20 2f 2a 20 56 61 6c 75 65  alue,   /* Value
1060: 20 6f 66 20 74 68 65 20 63 6f 6f 6b 69 65 2e 20   of the cookie. 
1070: 20 41 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 65   Automatically e
1080: 73 63 61 70 65 64 20 2a 2f 0a 20 20 63 6f 6e 73  scaped */.  cons
1090: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 20 20  t char *zPath,  
10a0: 20 20 2f 2a 20 50 61 74 68 20 63 6f 6f 6b 69 65    /* Path cookie
10b0: 20 61 70 70 6c 69 65 73 20 74 6f 2e 20 20 4e 55   applies to.  NU
10c0: 4c 4c 20 6d 65 61 6e 73 20 22 2f 22 20 2a 2f 0a  LL means "/" */.
10d0: 20 20 69 6e 74 20 6c 69 66 65 74 69 6d 65 20 20    int lifetime  
10e0: 20 20 20 20 20 20 20 20 2f 2a 20 45 78 70 69 72          /* Expir
10f0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 63 6f 6f  ation of the coo
1100: 6b 69 65 20 69 6e 20 73 65 63 6f 6e 64 73 20 66  kie in seconds f
1110: 72 6f 6d 20 6e 6f 77 20 2a 2f 0a 29 7b 0a 20 20  rom now */.){.  
1120: 69 66 28 20 7a 50 61 74 68 3d 3d 30 20 29 20 7a  if( zPath==0 ) z
1130: 50 61 74 68 20 3d 20 22 2f 22 3b 0a 20 20 69 66  Path = "/";.  if
1140: 28 20 6c 69 66 65 74 69 6d 65 3e 30 20 29 7b 0a  ( lifetime>0 ){.
1150: 20 20 20 20 6c 69 66 65 74 69 6d 65 20 2b 3d 20      lifetime += 
1160: 28 69 6e 74 29 74 69 6d 65 28 30 29 3b 0a 20 20  (int)time(0);.  
1170: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26    blob_appendf(&
1180: 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20  extraHeader,.   
1190: 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a      "Set-Cookie:
11a0: 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b   %s=%t; Path=%s;
11b0: 20 65 78 70 69 72 65 73 3d 25 73 3b 20 56 65 72   expires=%s; Ver
11c0: 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20  sion=1\r\n",.   
11d0: 20 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c       zName, zVal
11e0: 75 65 2c 20 7a 50 61 74 68 2c 20 63 67 69 5f 72  ue, zPath, cgi_r
11f0: 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28  fc822_datestamp(
1200: 6c 69 66 65 74 69 6d 65 29 29 3b 0a 20 20 7d 65  lifetime));.  }e
1210: 6c 73 65 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70  lse{.    blob_ap
1220: 70 65 6e 64 66 28 26 65 78 74 72 61 48 65 61 64  pendf(&extraHead
1230: 65 72 2c 0a 20 20 20 20 20 20 20 22 53 65 74 2d  er,.       "Set-
1240: 43 6f 6f 6b 69 65 3a 20 25 73 3d 25 74 3b 20 50  Cookie: %s=%t; P
1250: 61 74 68 3d 25 73 3b 20 56 65 72 73 69 6f 6e 3d  ath=%s; Version=
1260: 31 5c 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 7a  1\r\n",.       z
1270: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50  Name, zValue, zP
1280: 61 74 68 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66  ath);.  }.}..#if
1290: 20 30 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 20   0./*.** Add an 
12a0: 45 54 61 67 20 68 65 61 64 65 72 20 6c 69 6e 65  ETag header line
12b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20  .*/.static char 
12c0: 2a 63 67 69 5f 61 64 64 5f 65 74 61 67 28 63 68  *cgi_add_etag(ch
12d0: 61 72 20 2a 7a 54 78 74 2c 20 69 6e 74 20 6e 4c  ar *zTxt, int nL
12e0: 65 6e 29 7b 0a 20 20 4d 44 35 43 6f 6e 74 65 78  en){.  MD5Contex
12f0: 74 20 63 74 78 3b 0a 20 20 75 6e 73 69 67 6e 65  t ctx;.  unsigne
1300: 64 20 63 68 61 72 20 64 69 67 65 73 74 5b 31 36  d char digest[16
1310: 5d 3b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20  ];.  int i, j;. 
1320: 20 63 68 61 72 20 7a 45 54 61 67 5b 36 34 5d 3b   char zETag[64];
1330: 0a 0a 20 20 4d 44 35 49 6e 69 74 28 26 63 74 78  ..  MD5Init(&ctx
1340: 29 3b 0a 20 20 4d 44 35 55 70 64 61 74 65 28 26  );.  MD5Update(&
1350: 63 74 78 2c 7a 54 78 74 2c 6e 4c 65 6e 29 3b 0a  ctx,zTxt,nLen);.
1360: 20 20 4d 44 35 46 69 6e 61 6c 28 64 69 67 65 73    MD5Final(diges
1370: 74 2c 26 63 74 78 29 3b 0a 20 20 66 6f 72 28 6a  t,&ctx);.  for(j
1380: 3d 69 3d 30 3b 20 69 3c 31 36 3b 20 69 2b 2b 2c  =i=0; i<16; i++,
1390: 6a 2b 3d 32 29 7b 0a 20 20 20 20 62 70 72 69 6e  j+=2){.    bprin
13a0: 74 66 28 26 7a 45 54 61 67 5b 6a 5d 2c 73 69 7a  tf(&zETag[j],siz
13b0: 65 6f 66 28 7a 45 54 61 67 29 2d 6a 2c 22 25 30  eof(zETag)-j,"%0
13c0: 32 78 22 2c 28 69 6e 74 29 64 69 67 65 73 74 5b  2x",(int)digest[
13d0: 69 5d 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f  i]);.  }.  blob_
13e0: 61 70 70 65 6e 64 66 28 26 65 78 74 72 61 48 65  appendf(&extraHe
13f0: 61 64 65 72 2c 20 22 45 54 61 67 3a 20 25 73 5c  ader, "ETag: %s\
1400: 72 5c 6e 22 2c 20 7a 45 54 61 67 29 3b 0a 20 20  r\n", zETag);.  
1410: 72 65 74 75 72 6e 20 73 74 72 64 75 70 28 7a 45  return strdup(zE
1420: 54 61 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44  Tag);.}../*.** D
1430: 6f 20 73 6f 6d 65 20 63 61 63 68 65 20 63 6f 6e  o some cache con
1440: 74 72 6f 6c 20 73 74 75 66 66 2e 20 46 69 72 73  trol stuff. Firs
1450: 74 2c 20 77 65 20 67 65 6e 65 72 61 74 65 20 61  t, we generate a
1460: 6e 20 45 54 61 67 20 61 6e 64 20 69 6e 63 6c 75  n ETag and inclu
1470: 64 65 20 69 74 20 69 6e 0a 2a 2a 20 74 68 65 20  de it in.** the 
1480: 72 65 73 70 6f 6e 73 65 20 68 65 61 64 65 72 73  response headers
1490: 2e 20 53 65 63 6f 6e 64 2c 20 77 65 20 64 6f 20  . Second, we do 
14a0: 77 68 61 74 65 76 65 72 20 69 73 20 6e 65 63 65  whatever is nece
14b0: 73 73 61 72 79 20 74 6f 20 64 65 74 65 72 6d 69  ssary to determi
14c0: 6e 65 20 69 66 0a 2a 2a 20 74 68 65 20 72 65 71  ne if.** the req
14d0: 75 65 73 74 20 77 61 73 20 61 73 6b 69 6e 67 20  uest was asking 
14e0: 61 62 6f 75 74 20 63 61 63 68 69 6e 67 20 61 6e  about caching an
14f0: 64 20 77 68 65 74 68 65 72 20 77 65 20 6e 65 65  d whether we nee
1500: 64 20 74 6f 20 73 65 6e 64 20 62 61 63 6b 20 74  d to send back t
1510: 68 65 0a 2a 2a 20 72 65 73 70 6f 6e 73 65 20 62  he.** response b
1520: 6f 64 79 2e 20 49 66 20 77 65 20 73 68 6f 75 6c  ody. If we shoul
1530: 64 6e 27 74 20 73 65 6e 64 20 61 20 62 6f 64 79  dn't send a body
1540: 2c 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72  , return non-zer
1550: 6f 2e 0a 2a 2a 0a 2a 2a 20 43 75 72 72 65 6e 74  o..**.** Current
1560: 6c 79 2c 20 77 65 20 6a 75 73 74 20 63 68 65 63  ly, we just chec
1570: 6b 20 74 68 65 20 45 54 61 67 20 61 67 61 69 6e  k the ETag again
1580: 73 74 20 61 6e 79 20 49 66 2d 4e 6f 6e 65 2d 4d  st any If-None-M
1590: 61 74 63 68 20 68 65 61 64 65 72 2e 0a 2a 2a 0a  atch header..**.
15a0: 2a 2a 20 46 49 58 4d 45 3a 20 49 6e 20 73 6f 6d  ** FIXME: In som
15b0: 65 20 63 61 73 65 73 20 28 61 74 74 61 63 68 6d  e cases (attachm
15c0: 65 6e 74 73 2c 20 66 69 6c 65 20 63 6f 6e 74 65  ents, file conte
15d0: 6e 74 73 29 20 77 65 20 63 6f 75 6c 64 20 63 68  nts) we could ch
15e0: 65 63 6b 0a 2a 2a 20 49 66 2d 4d 6f 64 69 66 69  eck.** If-Modifi
15f0: 65 64 2d 53 69 6e 63 65 20 68 65 61 64 65 72 73  ed-Since headers
1600: 20 61 6e 64 20 61 6c 77 61 79 73 20 69 6e 63 6c   and always incl
1610: 75 64 65 20 4c 61 73 74 2d 4d 6f 64 69 66 69 65  ude Last-Modifie
1620: 64 20 69 6e 20 72 65 73 70 6f 6e 73 65 73 2e 0a  d in responses..
1630: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63 68  */.static int ch
1640: 65 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f  eck_cache_contro
1650: 6c 28 76 6f 69 64 29 7b 0a 20 20 2f 2a 20 46 49  l(void){.  /* FI
1660: 58 4d 45 3a 20 74 68 65 72 65 27 73 20 73 6f 6d  XME: there's som
1670: 65 20 67 6f 74 63 68 61 73 20 77 74 68 20 63 6f  e gotchas wth co
1680: 6f 6b 69 65 73 20 61 6e 64 20 73 6f 6d 65 20 68  okies and some h
1690: 65 61 64 65 72 73 2e 20 2a 2f 0a 20 20 63 68 61  eaders. */.  cha
16a0: 72 20 2a 7a 45 54 61 67 20 3d 20 63 67 69 5f 61  r *zETag = cgi_a
16b0: 64 64 5f 65 74 61 67 28 62 6c 6f 62 5f 62 75 66  dd_etag(blob_buf
16c0: 66 65 72 28 26 63 67 69 43 6f 6e 74 65 6e 74 29  fer(&cgiContent)
16d0: 2c 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43  ,blob_size(&cgiC
16e0: 6f 6e 74 65 6e 74 29 29 3b 0a 20 20 63 68 61 72  ontent));.  char
16f0: 20 2a 7a 4d 61 74 63 68 20 3d 20 50 28 22 48 54   *zMatch = P("HT
1700: 54 50 5f 49 46 5f 4e 4f 4e 45 5f 4d 41 54 43 48  TP_IF_NONE_MATCH
1710: 22 29 3b 0a 0a 20 20 69 66 28 20 7a 45 54 61 67  ");..  if( zETag
1720: 21 3d 30 20 26 26 20 7a 4d 61 74 63 68 21 3d 30  !=0 && zMatch!=0
1730: 20 29 20 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a   ) {.    char *z
1740: 42 75 66 20 3d 20 73 74 72 64 75 70 28 7a 4d 61  Buf = strdup(zMa
1750: 74 63 68 29 3b 0a 20 20 20 20 69 66 28 20 7a 42  tch);.    if( zB
1760: 75 66 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 63  uf!=0 ){.      c
1770: 68 61 72 20 2a 7a 54 6f 6b 20 3d 20 30 3b 0a 20  har *zTok = 0;. 
1780: 20 20 20 20 20 63 68 61 72 20 2a 7a 50 6f 73 3b       char *zPos;
1790: 0a 20 20 20 20 20 20 66 6f 72 28 20 7a 54 6f 6b  .      for( zTok
17a0: 20 3d 20 73 74 72 74 6f 6b 5f 72 28 7a 42 75 66   = strtok_r(zBuf
17b0: 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 3b 0a  , ",\"",&zPos);.
17c0: 20 20 20 20 20 20 20 20 20 20 20 7a 54 6f 6b 20             zTok 
17d0: 26 26 20 73 74 72 63 61 73 65 63 6d 70 28 7a 54  && strcasecmp(zT
17e0: 6f 6b 2c 7a 45 54 61 67 29 3b 0a 20 20 20 20 20  ok,zETag);.     
17f0: 20 20 20 20 20 20 7a 54 6f 6b 20 3d 20 20 73 74        zTok =  st
1800: 72 74 6f 6b 5f 72 28 30 2c 20 22 2c 5c 22 22 2c  rtok_r(0, ",\"",
1810: 26 7a 50 6f 73 29 29 7b 7d 0a 20 20 20 20 20 20  &zPos)){}.      
1820: 66 72 65 65 28 7a 42 75 66 29 3b 0a 20 20 20 20  free(zBuf);.    
1830: 20 20 69 66 28 7a 54 6f 6b 29 20 72 65 74 75 72    if(zTok) retur
1840: 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20  n 1;.    }.  }. 
1850: 20 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a   .  return 0;.}.
1860: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 44 6f  #endif../*.** Do
1870: 20 61 20 6e 6f 72 6d 61 6c 20 48 54 54 50 20 72   a normal HTTP r
1880: 65 70 6c 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69  eply.*/.void cgi
1890: 5f 72 65 70 6c 79 28 76 6f 69 64 29 7b 0a 20 20  _reply(void){.  
18a0: 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73  if( iReplyStatus
18b0: 3c 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c  <=0 ){.    iRepl
18c0: 79 53 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20  yStatus = 200;. 
18d0: 20 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20     zReplyStatus 
18e0: 3d 20 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66  = "OK";.  }..#if
18f0: 20 30 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53   0.  if( iReplyS
1900: 74 61 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68  tatus==200 && ch
1910: 65 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f  eck_cache_contro
1920: 6c 28 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63  l() ) {.    /* c
1930: 68 61 6e 67 65 20 74 68 65 20 73 74 61 74 75 73  hange the status
1940: 20 74 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20   to "unchanged" 
1950: 61 6e 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20  and we can skip 
1960: 73 65 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20  sending the.    
1970: 2a 2a 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e  ** actual respon
1980: 73 65 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73  se body. Obvious
1990: 6c 79 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68  ly we only do th
19a0: 69 73 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65  is when we _have
19b0: 5f 20 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20  _ a.    ** body 
19c0: 28 63 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20  (code 200)..    
19d0: 2a 2f 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61  */.    iReplySta
19e0: 74 75 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a  tus = 304;.    z
19f0: 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e  ReplyStatus = "N
1a00: 6f 74 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20  ot Modified";.  
1a10: 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20  }.#endif..  if( 
1a20: 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b  fullHttpReply ){
1a30: 0a 20 20 20 20 70 72 69 6e 74 66 28 22 48 54 54  .    printf("HTT
1a40: 50 2f 31 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22  P/1.0 %d %s\r\n"
1a50: 2c 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20  , iReplyStatus, 
1a60: 7a 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20  zReplyStatus);. 
1a70: 20 20 20 70 72 69 6e 74 66 28 22 44 61 74 65 3a     printf("Date:
1a80: 20 25 73 5c 72 5c 6e 22 2c 20 63 67 69 5f 72 66   %s\r\n", cgi_rf
1a90: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 74  c822_datestamp(t
1aa0: 69 6d 65 28 30 29 29 29 3b 0a 20 20 20 20 70 72  ime(0)));.    pr
1ab0: 69 6e 74 66 28 22 43 6f 6e 6e 65 63 74 69 6f 6e  intf("Connection
1ac0: 3a 20 63 6c 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20  : close\r\n");. 
1ad0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 72 69 6e   }else{.    prin
1ae0: 74 66 28 22 53 74 61 74 75 73 3a 20 25 64 20 25  tf("Status: %d %
1af0: 73 5c 72 5c 6e 22 2c 20 69 52 65 70 6c 79 53 74  s\r\n", iReplySt
1b00: 61 74 75 73 2c 20 7a 52 65 70 6c 79 53 74 61 74  atus, zReplyStat
1b10: 75 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20  us);.  }..  if( 
1b20: 62 6c 6f 62 5f 73 69 7a 65 28 26 65 78 74 72 61  blob_size(&extra
1b30: 48 65 61 64 65 72 29 3e 30 20 29 7b 0a 20 20 20  Header)>0 ){.   
1b40: 20 70 72 69 6e 74 66 28 22 25 73 22 2c 20 62 6c   printf("%s", bl
1b50: 6f 62 5f 62 75 66 66 65 72 28 26 65 78 74 72 61  ob_buffer(&extra
1b60: 48 65 61 64 65 72 29 29 3b 0a 20 20 7d 0a 0a 20  Header));.  }.. 
1b70: 20 69 66 28 20 67 2e 69 73 43 6f 6e 73 74 20 29   if( g.isConst )
1b80: 7b 0a 20 20 20 20 2f 2a 20 63 6f 6e 73 74 61 6e  {.    /* constan
1b90: 74 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65  t means that the
1ba0: 20 69 6e 70 75 74 20 55 52 4c 20 77 69 6c 6c 20   input URL will 
1bb0: 5f 6e 65 76 65 72 5f 20 67 65 6e 65 72 61 74 65  _never_ generate
1bc0: 20 61 6e 79 74 68 69 6e 67 0a 20 20 20 20 2a 2a   anything.    **
1bd0: 20 65 6c 73 65 2e 20 49 6e 20 74 68 65 20 63 61   else. In the ca
1be0: 73 65 20 6f 66 20 61 74 74 61 63 68 6d 65 6e 74  se of attachment
1bf0: 73 2c 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20  s, the contents 
1c00: 77 6f 6e 27 74 20 63 68 61 6e 67 65 20 62 65 63  won't change bec
1c10: 61 75 73 65 0a 20 20 20 20 2a 2a 20 61 6e 20 61  ause.    ** an a
1c20: 74 74 65 6d 70 74 20 74 6f 20 63 68 61 6e 67 65  ttempt to change
1c30: 20 74 68 65 6d 20 67 65 6e 65 72 61 74 65 73 20   them generates 
1c40: 61 20 6e 65 77 20 61 74 74 61 63 68 6d 65 6e 74  a new attachment
1c50: 20 6e 75 6d 62 65 72 2e 20 49 6e 20 74 68 65 0a   number. In the.
1c60: 20 20 20 20 2a 2a 20 63 61 73 65 20 6f 66 20 6d      ** case of m
1c70: 6f 73 74 20 2f 67 65 74 66 69 6c 65 20 63 61 6c  ost /getfile cal
1c80: 6c 73 20 66 6f 72 20 73 70 65 63 69 66 69 63 20  ls for specific 
1c90: 76 65 72 73 69 6f 6e 73 2c 20 74 68 65 20 6f 6e  versions, the on
1ca0: 6c 79 20 77 61 79 20 74 68 65 0a 20 20 20 20 2a  ly way the.    *
1cb0: 2a 20 63 6f 6e 74 65 6e 74 20 63 68 61 6e 67 65  * content change
1cc0: 73 20 69 73 20 69 66 20 73 6f 6d 65 6f 6e 65 20  s is if someone 
1cd0: 62 72 65 61 6b 73 20 74 68 65 20 53 43 4d 2e 20  breaks the SCM. 
1ce0: 41 6e 64 20 69 66 20 74 68 61 74 20 68 61 70 70  And if that happ
1cf0: 65 6e 73 2c 20 61 0a 20 20 20 20 2a 2a 20 73 74  ens, a.    ** st
1d00: 61 6c 65 20 63 61 63 68 65 20 69 73 20 74 68 65  ale cache is the
1d10: 20 6c 65 61 73 74 20 6f 66 20 74 68 65 20 70 72   least of the pr
1d20: 6f 62 6c 65 6d 2e 20 53 6f 20 77 65 20 70 72 6f  oblem. So we pro
1d30: 76 69 64 65 20 61 6e 20 45 78 70 69 72 65 73 0a  vide an Expires.
1d40: 20 20 20 20 2a 2a 20 68 65 61 64 65 72 20 73 65      ** header se
1d50: 74 20 74 6f 20 61 20 72 65 61 73 6f 6e 61 62 6c  t to a reasonabl
1d60: 65 20 70 65 72 69 6f 64 20 28 64 65 66 61 75 6c  e period (defaul
1d70: 74 3a 20 6f 6e 65 20 77 65 65 6b 29 2e 0a 20 20  t: one week)..  
1d80: 20 20 2a 2f 0a 20 20 20 20 2f 2a 74 69 6d 65 5f    */.    /*time_
1d90: 74 20 65 78 70 69 72 65 73 20 3d 20 74 69 6d 65  t expires = time
1da0: 28 30 29 20 2b 20 61 74 6f 69 28 64 62 5f 63 6f  (0) + atoi(db_co
1db0: 6e 66 69 67 28 22 63 6f 6e 73 74 61 6e 74 5f 65  nfig("constant_e
1dc0: 78 70 69 72 65 73 22 2c 22 36 30 34 38 30 30 22  xpires","604800"
1dd0: 29 29 3b 2a 2f 0a 20 20 20 20 74 69 6d 65 5f 74  ));*/.    time_t
1de0: 20 65 78 70 69 72 65 73 20 3d 20 74 69 6d 65 28   expires = time(
1df0: 30 29 20 2b 20 36 30 34 38 30 30 3b 0a 20 20 20  0) + 604800;.   
1e00: 20 70 72 69 6e 74 66 28 20 22 45 78 70 69 72 65   printf( "Expire
1e10: 73 3a 20 25 73 5c 72 5c 6e 22 2c 20 63 67 69 5f  s: %s\r\n", cgi_
1e20: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70  rfc822_datestamp
1e30: 28 65 78 70 69 72 65 73 29 29 3b 0a 20 20 7d 0a  (expires));.  }.
1e40: 0a 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 69 6e  .  /* Content in
1e50: 74 65 6e 64 65 64 20 66 6f 72 20 6c 6f 67 67 65  tended for logge
1e60: 64 20 69 6e 20 75 73 65 72 73 20 73 68 6f 75 6c  d in users shoul
1e70: 64 20 6f 6e 6c 79 20 62 65 20 63 61 63 68 65 64  d only be cached
1e80: 20 69 6e 0a 20 20 2a 2a 20 74 68 65 20 62 72 6f   in.  ** the bro
1e90: 77 73 65 72 2c 20 6e 6f 74 20 73 6f 6d 65 20 73  wser, not some s
1ea0: 68 61 72 65 64 20 6c 6f 63 61 74 69 6f 6e 2e 0a  hared location..
1eb0: 20 20 2a 2f 0a 20 20 70 72 69 6e 74 66 28 22 43    */.  printf("C
1ec0: 61 63 68 65 2d 63 6f 6e 74 72 6f 6c 3a 20 70 72  ache-control: pr
1ed0: 69 76 61 74 65 5c 72 5c 6e 22 29 3b 0a 0a 23 69  ivate\r\n");..#i
1ee0: 66 20 46 4f 53 53 49 4c 5f 49 31 38 4e 0a 20 20  f FOSSIL_I18N.  
1ef0: 70 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74  printf( "Content
1f00: 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 72 73  -Type: %s; chars
1f10: 65 74 3d 25 73 5c 72 5c 6e 22 2c 20 7a 43 6f 6e  et=%s\r\n", zCon
1f20: 74 65 6e 74 54 79 70 65 2c 20 6e 6c 5f 6c 61 6e  tentType, nl_lan
1f30: 67 69 6e 66 6f 28 43 4f 44 45 53 45 54 29 29 3b  ginfo(CODESET));
1f40: 0a 23 65 6c 73 65 0a 20 20 70 72 69 6e 74 66 28  .#else.  printf(
1f50: 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20   "Content-Type: 
1f60: 25 73 3b 20 63 68 61 72 73 65 74 3d 49 53 4f 2d  %s; charset=ISO-
1f70: 38 38 35 39 2d 31 5c 72 5c 6e 22 2c 20 7a 43 6f  8859-1\r\n", zCo
1f80: 6e 74 65 6e 74 54 79 70 65 29 3b 0a 23 65 6e 64  ntentType);.#end
1f90: 69 66 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28  if.  if( strcmp(
1fa0: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 2c 22 61 70  zContentType,"ap
1fb0: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73  plication/x-foss
1fc0: 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 62  il")==0 ){.    b
1fd0: 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 28 26 63 67  lob_compress(&cg
1fe0: 69 43 6f 6e 74 65 6e 74 2c 20 26 63 67 69 43 6f  iContent, &cgiCo
1ff0: 6e 74 65 6e 74 29 3b 0a 20 20 7d 0a 0a 20 20 69  ntent);.  }..  i
2000: 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 20  f( iReplyStatus 
2010: 21 3d 20 33 30 34 20 29 20 7b 0a 20 20 20 20 70  != 304 ) {.    p
2020: 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74 2d  rintf( "Content-
2030: 4c 65 6e 67 74 68 3a 20 25 64 5c 72 5c 6e 22 2c  Length: %d\r\n",
2040: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43   blob_size(&cgiC
2050: 6f 6e 74 65 6e 74 29 20 29 3b 0a 20 20 7d 0a 20  ontent) );.  }. 
2060: 20 70 72 69 6e 74 66 28 22 5c 72 5c 6e 22 29 3b   printf("\r\n");
2070: 0a 20 20 69 66 28 20 62 6c 6f 62 5f 73 69 7a 65  .  if( blob_size
2080: 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 3e 30 20  (&cgiContent)>0 
2090: 26 26 20 69 52 65 70 6c 79 53 74 61 74 75 73 20  && iReplyStatus 
20a0: 21 3d 20 33 30 34 20 29 7b 0a 20 20 20 20 66 77  != 304 ){.    fw
20b0: 72 69 74 65 28 62 6c 6f 62 5f 62 75 66 66 65 72  rite(blob_buffer
20c0: 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 2c 20 31  (&cgiContent), 1
20d0: 2c 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69  , blob_size(&cgi
20e0: 43 6f 6e 74 65 6e 74 29 2c 20 73 74 64 6f 75 74  Content), stdout
20f0: 29 3b 0a 20 20 7d 0a 20 20 43 47 49 44 45 42 55  );.  }.  CGIDEBU
2100: 47 28 28 22 44 4f 4e 45 5c 6e 22 29 29 3b 0a 7d  G(("DONE\n"));.}
2110: 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 72 65 64  ../*.** Do a red
2120: 69 72 65 63 74 20 72 65 71 75 65 73 74 20 74 6f  irect request to
2130: 20 74 68 65 20 55 52 4c 20 67 69 76 65 6e 20 69   the URL given i
2140: 6e 20 74 68 65 20 61 72 67 75 6d 65 6e 74 2e 0a  n the argument..
2150: 2a 2a 0a 2a 2a 20 54 68 65 20 55 52 4c 20 6d 75  **.** The URL mu
2160: 73 74 20 62 65 20 72 65 6c 61 74 69 76 65 20 74  st be relative t
2170: 6f 20 74 68 65 20 62 61 73 65 20 6f 66 20 74 68  o the base of th
2180: 65 20 66 6f 73 73 69 6c 20 73 65 72 76 65 72 2e  e fossil server.
2190: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 64  .*/.void cgi_red
21a0: 69 72 65 63 74 28 63 6f 6e 73 74 20 63 68 61 72  irect(const char
21b0: 20 2a 7a 55 52 4c 29 7b 0a 20 20 63 68 61 72 20   *zURL){.  char 
21c0: 2a 7a 4c 6f 63 61 74 69 6f 6e 3b 0a 20 20 43 47  *zLocation;.  CG
21d0: 49 44 45 42 55 47 28 28 22 72 65 64 69 72 65 63  IDEBUG(("redirec
21e0: 74 20 74 6f 20 25 73 5c 6e 22 2c 20 7a 55 52 4c  t to %s\n", zURL
21f0: 29 29 3b 0a 20 20 69 66 28 20 73 74 72 6e 63 6d  ));.  if( strncm
2200: 70 28 7a 55 52 4c 2c 22 68 74 74 70 3a 22 2c 35  p(zURL,"http:",5
2210: 29 3d 3d 30 20 7c 7c 20 73 74 72 6e 63 6d 70 28  )==0 || strncmp(
2220: 7a 55 52 4c 2c 22 68 74 74 70 73 3a 22 2c 36 29  zURL,"https:",6)
2230: 3d 3d 30 20 7c 7c 20 2a 7a 55 52 4c 3d 3d 27 2f  ==0 || *zURL=='/
2240: 27 20 29 7b 0a 20 20 20 20 7a 4c 6f 63 61 74 69  ' ){.    zLocati
2250: 6f 6e 20 3d 20 6d 70 72 69 6e 74 66 28 22 4c 6f  on = mprintf("Lo
2260: 63 61 74 69 6f 6e 3a 20 25 73 5c 72 5c 6e 22 2c  cation: %s\r\n",
2270: 20 7a 55 52 4c 29 3b 0a 20 20 7d 65 6c 73 65 7b   zURL);.  }else{
2280: 0a 20 20 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d  .    zLocation =
2290: 20 6d 70 72 69 6e 74 66 28 22 4c 6f 63 61 74 69   mprintf("Locati
22a0: 6f 6e 3a 20 25 73 2f 25 73 5c 72 5c 6e 22 2c 20  on: %s/%s\r\n", 
22b0: 67 2e 7a 42 61 73 65 55 52 4c 2c 20 7a 55 52 4c  g.zBaseURL, zURL
22c0: 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f 61 70 70  );.  }.  cgi_app
22d0: 65 6e 64 5f 68 65 61 64 65 72 28 7a 4c 6f 63 61  end_header(zLoca
22e0: 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65 73  tion);.  cgi_res
22f0: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20  et_content();.  
2300: 63 67 69 5f 70 72 69 6e 74 66 28 22 3c 68 74 6d  cgi_printf("<htm
2310: 6c 3e 5c 6e 3c 70 3e 52 65 64 69 72 65 63 74 20  l>\n<p>Redirect 
2320: 74 6f 20 25 68 3c 2f 70 3e 5c 6e 3c 2f 68 74 6d  to %h</p>\n</htm
2330: 6c 3e 5c 6e 22 2c 20 7a 55 52 4c 29 3b 0a 20 20  l>\n", zURL);.  
2340: 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 33  cgi_set_status(3
2350: 30 32 2c 20 22 4d 6f 76 65 64 20 54 65 6d 70 6f  02, "Moved Tempo
2360: 72 61 72 69 6c 79 22 29 3b 0a 20 20 66 72 65 65  rarily");.  free
2370: 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a 20 20 63  (zLocation);.  c
2380: 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 78  gi_reply();.  ex
2390: 69 74 28 30 29 3b 0a 7d 0a 76 6f 69 64 20 63 67  it(0);.}.void cg
23a0: 69 5f 72 65 64 69 72 65 63 74 66 28 63 6f 6e 73  i_redirectf(cons
23b0: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c  t char *zFormat,
23c0: 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74   ...){.  va_list
23d0: 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 72 74 28   ap;.  va_start(
23e0: 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20  ap, zFormat);.  
23f0: 63 67 69 5f 72 65 64 69 72 65 63 74 28 76 6d 70  cgi_redirect(vmp
2400: 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74 2c 20 61  rintf(zFormat, a
2410: 70 29 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  p));.  va_end(ap
2420: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f  );.}../*.** Info
2430: 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 20 61 6c  rmation about al
2440: 6c 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  l query paramete
2450: 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 20 61  rs and cookies a
2460: 72 65 20 73 74 6f 72 65 64 0a 2a 2a 20 69 6e 20  re stored.** in 
2470: 74 68 65 73 65 20 76 61 72 69 61 62 6c 65 73 2e  these variables.
2480: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6e  .*/.static int n
2490: 41 6c 6c 6f 63 51 50 20 3d 20 30 3b 20 2f 2a 20  AllocQP = 0; /* 
24a0: 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 65 64 20  Space allocated 
24b0: 66 6f 72 20 61 50 61 72 61 6d 51 50 5b 5d 20 2a  for aParamQP[] *
24c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 55 73  /.static int nUs
24d0: 65 64 51 50 20 3d 20 30 3b 20 20 2f 2a 20 53 70  edQP = 0;  /* Sp
24e0: 61 63 65 20 61 63 74 75 61 6c 6c 79 20 75 73 65  ace actually use
24f0: 64 20 69 6e 20 61 50 61 72 61 6d 51 50 5b 5d 20  d in aParamQP[] 
2500: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 6f  */.static int so
2510: 72 74 51 50 20 3d 20 30 3b 20 20 20 2f 2a 20 54  rtQP = 0;   /* T
2520: 72 75 65 20 69 66 20 61 50 61 72 61 6d 51 50 5b  rue if aParamQP[
2530: 5d 20 6e 65 65 64 73 20 73 6f 72 74 69 6e 67 20  ] needs sorting 
2540: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 73 65  */.static int se
2550: 71 51 50 20 3d 20 30 3b 20 20 20 20 2f 2a 20 53  qQP = 0;    /* S
2560: 65 71 75 65 6e 63 65 20 6e 75 6d 62 65 72 73 20  equence numbers 
2570: 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74  */.static struct
2580: 20 51 50 61 72 61 6d 20 7b 20 20 20 2f 2a 20 4f   QParam {   /* O
2590: 6e 65 20 65 6e 74 72 79 20 66 6f 72 20 65 61 63  ne entry for eac
25a0: 68 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  h query paramete
25b0: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20  r or cookie */. 
25c0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61   const char *zNa
25d0: 6d 65 3b 20 20 20 20 20 20 20 20 2f 2a 20 50 61  me;        /* Pa
25e0: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69  rameter or cooki
25f0: 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73  e name */.  cons
2600: 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 20  t char *zValue; 
2610: 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f        /* Value o
2620: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61  f the query para
2630: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20  meter or cookie 
2640: 2a 2f 0a 20 20 69 6e 74 20 73 65 71 3b 20 20 20  */.  int seq;   
2650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f                 /
2660: 2a 20 4f 72 64 65 72 20 6f 66 20 69 6e 73 65 72  * Order of inser
2670: 74 69 6f 6e 20 2a 2f 0a 7d 20 2a 61 50 61 72 61  tion */.} *aPara
2680: 6d 51 50 3b 20 20 20 20 20 20 20 20 20 20 20 20  mQP;            
2690: 20 2f 2a 20 41 6e 20 61 72 72 61 79 20 6f 66 20   /* An array of 
26a0: 61 6c 6c 20 70 61 72 61 6d 65 74 65 72 73 20 61  all parameters a
26b0: 6e 64 20 63 6f 6f 6b 69 65 73 20 2a 2f 0a 0a 2f  nd cookies */../
26c0: 2a 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 68 65 72  *.** Add another
26d0: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
26e0: 20 6f 72 20 63 6f 6f 6b 69 65 20 74 6f 20 74 68   or cookie to th
26f0: 65 20 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e  e parameter set.
2700: 0a 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 74 68 65  .** zName is the
2710: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 71 75 65   name of the que
2720: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20  ry parameter or 
2730: 63 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 61 6c 75  cookie and zValu
2740: 65 0a 2a 2a 20 69 73 20 69 74 73 20 66 75 6c 6c  e.** is its full
2750: 79 20 64 65 63 6f 64 65 64 20 76 61 6c 75 65 2e  y decoded value.
2760: 0a 2a 2a 0a 2a 2a 20 7a 4e 61 6d 65 20 61 6e 64  .**.** zName and
2770: 20 7a 56 61 6c 75 65 20 61 72 65 20 6e 6f 74 20   zValue are not 
2780: 63 6f 70 69 65 64 20 61 6e 64 20 6d 75 73 74 20  copied and must 
2790: 6e 6f 74 20 63 68 61 6e 67 65 20 6f 72 20 62 65  not change or be
27a0: 0a 2a 2a 20 64 65 61 6c 6c 6f 63 61 74 65 64 20  .** deallocated 
27b0: 61 66 74 65 72 20 74 68 69 73 20 72 6f 75 74 69  after this routi
27c0: 6e 65 20 72 65 74 75 72 6e 73 2e 0a 2a 2f 0a 76  ne returns..*/.v
27d0: 6f 69 64 20 63 67 69 5f 73 65 74 5f 70 61 72 61  oid cgi_set_para
27e0: 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 63 6f 6e  meter_nocopy(con
27f0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20  st char *zName, 
2800: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c  const char *zVal
2810: 75 65 29 7b 0a 20 20 69 66 28 20 6e 41 6c 6c 6f  ue){.  if( nAllo
2820: 63 51 50 3c 3d 6e 55 73 65 64 51 50 20 29 7b 0a  cQP<=nUsedQP ){.
2830: 20 20 20 20 6e 41 6c 6c 6f 63 51 50 20 3d 20 6e      nAllocQP = n
2840: 41 6c 6c 6f 63 51 50 2a 32 20 2b 20 31 30 3b 0a  AllocQP*2 + 10;.
2850: 20 20 20 20 61 50 61 72 61 6d 51 50 20 3d 20 72      aParamQP = r
2860: 65 61 6c 6c 6f 63 28 20 61 50 61 72 61 6d 51 50  ealloc( aParamQP
2870: 2c 20 6e 41 6c 6c 6f 63 51 50 2a 73 69 7a 65 6f  , nAllocQP*sizeo
2880: 66 28 61 50 61 72 61 6d 51 50 5b 30 5d 29 20 29  f(aParamQP[0]) )
2890: 3b 0a 20 20 20 20 69 66 28 20 61 50 61 72 61 6d  ;.    if( aParam
28a0: 51 50 3d 3d 30 20 29 20 65 78 69 74 28 31 29 3b  QP==0 ) exit(1);
28b0: 0a 20 20 7d 0a 20 20 61 50 61 72 61 6d 51 50 5b  .  }.  aParamQP[
28c0: 6e 55 73 65 64 51 50 5d 2e 7a 4e 61 6d 65 20 3d  nUsedQP].zName =
28d0: 20 7a 4e 61 6d 65 3b 0a 20 20 61 50 61 72 61 6d   zName;.  aParam
28e0: 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a 56 61 6c  QP[nUsedQP].zVal
28f0: 75 65 20 3d 20 7a 56 61 6c 75 65 3b 0a 20 20 61  ue = zValue;.  a
2900: 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d  ParamQP[nUsedQP]
2910: 2e 73 65 71 20 3d 20 73 65 71 51 50 2b 2b 3b 0a  .seq = seqQP++;.
2920: 20 20 6e 55 73 65 64 51 50 2b 2b 3b 0a 20 20 73    nUsedQP++;.  s
2930: 6f 72 74 51 50 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a  ortQP = 1;.}../*
2940: 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 68 65 72 20  .** Add another 
2950: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20  query parameter 
2960: 6f 72 20 63 6f 6f 6b 69 65 20 74 6f 20 74 68 65  or cookie to the
2970: 20 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a   parameter set..
2980: 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 74 68 65 20  ** zName is the 
2990: 6e 61 6d 65 20 6f 66 20 74 68 65 20 71 75 65 72  name of the quer
29a0: 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63  y parameter or c
29b0: 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 61 6c 75 65  ookie and zValue
29c0: 0a 2a 2a 20 69 73 20 69 74 73 20 66 75 6c 6c 79  .** is its fully
29d0: 20 64 65 63 6f 64 65 64 20 76 61 6c 75 65 2e 0a   decoded value..
29e0: 2a 2a 0a 2a 2a 20 43 6f 70 69 65 73 20 61 72 65  **.** Copies are
29f0: 20 6d 61 64 65 20 6f 66 20 62 6f 74 68 20 74 68   made of both th
2a00: 65 20 7a 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c  e zName and zVal
2a10: 75 65 20 70 61 72 61 6d 65 74 65 72 73 2e 0a 2a  ue parameters..*
2a20: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 70  /.void cgi_set_p
2a30: 61 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 20 63  arameter(const c
2a40: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73  har *zName, cons
2a50: 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b  t char *zValue){
2a60: 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d  .  cgi_set_param
2a70: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69  eter_nocopy(mpri
2a80: 6e 74 66 28 22 25 73 22 2c 7a 4e 61 6d 65 29 2c  ntf("%s",zName),
2a90: 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 56   mprintf("%s",zV
2aa0: 61 6c 75 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  alue));.}../*.**
2ab0: 20 52 65 70 6c 61 63 65 20 61 20 70 61 72 61 6d   Replace a param
2ac0: 65 74 65 72 20 77 69 74 68 20 61 20 6e 65 77 20  eter with a new 
2ad0: 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63  value..*/.void c
2ae0: 67 69 5f 72 65 70 6c 61 63 65 5f 70 61 72 61 6d  gi_replace_param
2af0: 65 74 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20  eter(const char 
2b00: 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68  *zName, const ch
2b10: 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 69  ar *zValue){.  i
2b20: 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  nt i;.  for(i=0;
2b30: 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29   i<nUsedQP; i++)
2b40: 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70  {.    if( strcmp
2b50: 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61  (aParamQP[i].zNa
2b60: 6d 65 2c 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a  me,zName)==0 ){.
2b70: 20 20 20 20 20 20 61 50 61 72 61 6d 51 50 5b 69        aParamQP[i
2b80: 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56 61 6c 75  ].zValue = zValu
2b90: 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a  e;.    }.  }.}..
2ba0: 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 71 75 65 72  /*.** Add a quer
2bb0: 79 20 70 61 72 61 6d 65 74 65 72 2e 20 20 54 68  y parameter.  Th
2bc0: 65 20 7a 4e 61 6d 65 20 70 6f 72 74 69 6f 6e 20  e zName portion 
2bd0: 69 73 20 66 69 78 65 64 20 62 75 74 20 61 20 63  is fixed but a c
2be0: 6f 70 79 0a 2a 2a 20 6d 75 73 74 20 62 65 20 6d  opy.** must be m
2bf0: 61 64 65 20 6f 66 20 7a 56 61 6c 75 65 2e 0a 2a  ade of zValue..*
2c00: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 65 6e  /.void cgi_seten
2c10: 76 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e  v(const char *zN
2c20: 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  ame, const char 
2c30: 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f  *zValue){.  cgi_
2c40: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
2c50: 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 6d 70 72 69  copy(zName, mpri
2c60: 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29  ntf("%s",zValue)
2c70: 29 3b 0a 7d 0a 20 0a 0a 2f 2a 0a 2a 2a 20 41 64  );.}. ../*.** Ad
2c80: 64 20 61 20 6c 69 73 74 20 6f 66 20 71 75 65 72  d a list of quer
2c90: 79 20 70 61 72 61 6d 65 74 65 72 73 20 6f 72 20  y parameters or 
2ca0: 63 6f 6f 6b 69 65 73 20 74 6f 20 74 68 65 20 70  cookies to the p
2cb0: 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a  arameter set..**
2cc0: 0a 2a 2a 20 45 61 63 68 20 70 61 72 61 6d 65 74  .** Each paramet
2cd0: 65 72 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72  er is of the for
2ce0: 6d 20 4e 41 4d 45 3d 56 41 4c 55 45 2e 20 20 42  m NAME=VALUE.  B
2cf0: 6f 74 68 20 74 68 65 20 4e 41 4d 45 20 61 6e 64  oth the NAME and
2d00: 20 74 68 65 0a 2a 2a 20 56 41 4c 55 45 20 6d 61   the.** VALUE ma
2d10: 79 20 62 65 20 75 72 6c 2d 65 6e 63 6f 64 65 64  y be url-encoded
2d20: 20 28 22 2b 22 20 66 6f 72 20 73 70 61 63 65 2c   ("+" for space,
2d30: 20 22 25 48 48 22 20 66 6f 72 20 6f 74 68 65 72   "%HH" for other
2d40: 20 73 70 65 63 69 61 6c 0a 2a 2a 20 63 68 61 72   special.** char
2d50: 61 63 74 65 72 73 29 2e 20 20 42 75 74 20 74 68  acters).  But th
2d60: 69 73 20 72 6f 75 74 69 6e 65 20 61 73 73 75 6d  is routine assum
2d70: 65 73 20 74 68 61 74 20 4e 41 4d 45 20 63 6f 6e  es that NAME con
2d80: 74 61 69 6e 73 20 6e 6f 0a 2a 2a 20 73 70 65 63  tains no.** spec
2d90: 69 61 6c 20 63 68 61 72 61 63 74 65 72 20 61 6e  ial character an
2da0: 64 20 74 68 65 72 65 66 6f 72 65 20 64 6f 65 73  d therefore does
2db0: 20 6e 6f 74 20 64 65 63 6f 64 65 20 69 74 2e 0a   not decode it..
2dc0: 2a 2a 0a 2a 2a 20 49 66 20 4e 41 4d 45 20 62 65  **.** If NAME be
2dd0: 67 69 6e 73 20 77 69 74 68 20 61 6e 6f 74 68 65  gins with anothe
2de0: 72 20 6f 74 68 65 72 20 74 68 61 6e 20 61 20 6c  r other than a l
2df0: 6f 77 65 72 2d 63 61 73 65 20 6c 65 74 74 65 72  ower-case letter
2e00: 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20 65 6e 74   then.** the ent
2e10: 69 72 65 20 4e 41 4d 45 3d 56 41 4c 55 45 20 74  ire NAME=VALUE t
2e20: 65 72 6d 20 69 73 20 69 67 6e 6f 72 65 64 2e 20  erm is ignored. 
2e30: 20 48 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a 20 20 20   Hence:.**.**   
2e40: 20 20 20 2a 20 20 63 6f 6f 6b 69 65 73 20 61 6e     *  cookies an
2e50: 64 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65  d query paramete
2e60: 72 73 20 74 68 61 74 20 68 61 76 65 20 75 70 70  rs that have upp
2e70: 65 72 63 61 73 65 20 6e 61 6d 65 73 0a 2a 2a 20  ercase names.** 
2e80: 20 20 20 20 20 20 20 20 61 72 65 20 69 67 6e 6f          are igno
2e90: 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20  red..**.**      
2ea0: 2a 20 20 69 74 20 69 73 20 69 6d 70 6f 73 73 69  *  it is impossi
2eb0: 62 6c 65 20 66 6f 72 20 61 20 63 6f 6f 6b 69 65  ble for a cookie
2ec0: 20 6f 72 20 71 75 65 72 79 20 70 61 72 61 6d 65   or query parame
2ed0: 74 65 72 20 74 6f 0a 2a 2a 20 20 20 20 20 20 20  ter to.**       
2ee0: 20 20 6f 76 65 72 72 69 64 65 20 74 68 65 20 76    override the v
2ef0: 61 6c 75 65 20 6f 66 20 61 6e 20 65 6e 76 69 72  alue of an envir
2f00: 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20  onment variable 
2f10: 73 69 6e 63 65 0a 2a 2a 20 20 20 20 20 20 20 20  since.**        
2f20: 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72   environment var
2f30: 69 61 62 6c 65 73 20 61 6c 77 61 79 73 20 68 61  iables always ha
2f40: 76 65 20 75 70 70 65 72 63 61 73 65 20 6e 61 6d  ve uppercase nam
2f50: 65 73 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65  es..**.** Parame
2f60: 74 65 72 73 20 61 72 65 20 73 65 70 61 72 61 74  ters are separat
2f70: 65 64 20 62 79 20 74 68 65 20 22 74 65 72 6d 69  ed by the "termi
2f80: 6e 61 74 6f 72 22 20 63 68 61 72 61 63 74 65 72  nator" character
2f90: 2e 20 20 57 68 69 74 65 73 70 61 63 65 0a 2a 2a  .  Whitespace.**
2fa0: 20 62 65 66 6f 72 65 20 74 68 65 20 4e 41 4d 45   before the NAME
2fb0: 20 69 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a   is ignored..**.
2fc0: 2a 2a 20 54 68 65 20 69 6e 70 75 74 20 73 74 72  ** The input str
2fd0: 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66  ing "z" is modif
2fe0: 69 65 64 20 62 75 74 20 6e 6f 20 63 6f 70 69 65  ied but no copie
2ff0: 73 20 69 73 20 6d 61 64 65 2e 20 20 22 7a 22 0a  s is made.  "z".
3000: 2a 2a 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62 65  ** should not be
3010: 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 6f 72 20   deallocated or 
3020: 63 68 61 6e 67 65 64 20 61 67 61 69 6e 20 61 66  changed again af
3030: 74 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e 65  ter this routine
3040: 0a 2a 2a 20 72 65 74 75 72 6e 73 20 6f 72 20 69  .** returns or i
3050: 74 20 77 69 6c 6c 20 63 6f 72 72 75 70 74 20 74  t will corrupt t
3060: 68 65 20 70 61 72 61 6d 65 74 65 72 20 74 61 62  he parameter tab
3070: 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f  le..*/.static vo
3080: 69 64 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73  id add_param_lis
3090: 74 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 74  t(char *z, int t
30a0: 65 72 6d 69 6e 61 74 6f 72 29 7b 0a 20 20 77 68  erminator){.  wh
30b0: 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 63  ile( *z ){.    c
30c0: 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20  har *zName;.    
30d0: 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20  char *zValue;.  
30e0: 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65    while( isspace
30f0: 28 2a 7a 29 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20  (*z) ){ z++; }. 
3100: 20 20 20 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20     zName = z;.  
3110: 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a    while( *z && *
3120: 7a 21 3d 27 3d 27 20 26 26 20 2a 7a 21 3d 74 65  z!='=' && *z!=te
3130: 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b 3b  rminator ){ z++;
3140: 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27   }.    if( *z=='
3150: 3d 27 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d  =' ){.      *z =
3160: 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20   0;.      z++;. 
3170: 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 7a 3b       zValue = z;
3180: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a  .      while( *z
3190: 20 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 74   && *z!=terminat
31a0: 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20  or ){ z++; }.   
31b0: 20 20 20 69 66 28 20 2a 7a 20 29 7b 0a 20 20 20     if( *z ){.   
31c0: 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20       *z = 0;.   
31d0: 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20       z++;.      
31e0: 7d 0a 20 20 20 20 20 20 64 65 68 74 74 70 69 7a  }.      dehttpiz
31f0: 65 28 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d  e(zValue);.    }
3200: 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20  else{.      if( 
3210: 2a 7a 20 29 7b 20 2a 7a 2b 2b 20 3d 20 30 3b 20  *z ){ *z++ = 0; 
3220: 7d 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d  }.      zValue =
3230: 20 22 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69   "";.    }.    i
3240: 66 28 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65  f( islower(zName
3250: 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 63 67  [0]) ){.      cg
3260: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f  i_set_parameter_
3270: 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56  nocopy(zName, zV
3280: 61 6c 75 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d  alue);.    }.  }
3290: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 2a 70 7a 20 69 73  .}../*.** *pz is
32a0: 20 61 20 73 74 72 69 6e 67 20 74 68 61 74 20 63   a string that c
32b0: 6f 6e 73 69 73 74 73 20 6f 66 20 6d 75 6c 74 69  onsists of multi
32c0: 70 6c 65 20 6c 69 6e 65 73 20 6f 66 20 74 65 78  ple lines of tex
32d0: 74 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74  t.  This.** rout
32e0: 69 6e 65 20 66 69 6e 64 73 20 74 68 65 20 65 6e  ine finds the en
32f0: 64 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e 74  d of the current
3300: 20 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 61 6e   line of text an
3310: 64 20 63 6f 6e 76 65 72 74 73 0a 2a 2a 20 74 68  d converts.** th
3320: 65 20 22 5c 6e 22 20 6f 72 20 22 5c 72 5c 6e 22  e "\n" or "\r\n"
3330: 20 74 68 61 74 20 65 6e 64 73 20 74 68 61 74 20   that ends that 
3340: 6c 69 6e 65 20 69 6e 74 6f 20 61 20 22 5c 30 30  line into a "\00
3350: 30 22 2e 20 20 49 74 20 74 68 65 6e 0a 2a 2a 20  0".  It then.** 
3360: 61 64 76 61 6e 63 65 73 20 2a 70 7a 20 74 6f 20  advances *pz to 
3370: 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66  the beginning of
3380: 20 74 68 65 20 6e 65 78 74 20 6c 69 6e 65 20 61   the next line a
3390: 6e 64 20 72 65 74 75 72 6e 73 20 74 68 65 0a 2a  nd returns the.*
33a0: 2a 20 70 72 65 76 69 6f 75 73 20 76 61 6c 75 65  * previous value
33b0: 20 6f 66 20 2a 70 7a 20 28 77 68 69 63 68 20 69   of *pz (which i
33c0: 73 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74  s the start of t
33d0: 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65 2e  he current line.
33e0: 29 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72  ).*/.static char
33f0: 20 2a 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f   *get_line_from_
3400: 73 74 72 69 6e 67 28 63 68 61 72 20 2a 2a 70 7a  string(char **pz
3410: 2c 20 69 6e 74 20 2a 70 4c 65 6e 29 7b 0a 20 20  , int *pLen){.  
3420: 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20  char *z = *pz;. 
3430: 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a 5b   int i;.  if( z[
3440: 30 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30  0]==0 ) return 0
3450: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 5b 69  ;.  for(i=0; z[i
3460: 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28  ]; i++){.    if(
3470: 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29 7b 0a 20   z[i]=='\n' ){. 
3480: 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20       if( i>0 && 
3490: 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 7b 0a  z[i-1]=='\r' ){.
34a0: 20 20 20 20 20 20 20 20 7a 5b 69 2d 31 5d 20 3d          z[i-1] =
34b0: 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b   0;.      }else{
34c0: 0a 20 20 20 20 20 20 20 20 7a 5b 69 5d 20 3d 20  .        z[i] = 
34d0: 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20  0;.      }.     
34e0: 20 69 2b 2b 3b 0a 20 20 20 20 20 20 62 72 65 61   i++;.      brea
34f0: 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a  k;.    }.  }.  *
3500: 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 2a 70  pz = &z[i];.  *p
3510: 4c 65 6e 20 2d 3d 20 69 3b 0a 20 20 72 65 74 75  Len -= i;.  retu
3520: 72 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54  rn z;.}../*.** T
3530: 68 65 20 69 6e 70 75 74 20 2a 70 7a 20 70 6f 69  he input *pz poi
3540: 6e 74 73 20 74 6f 20 63 6f 6e 74 65 6e 74 20 74  nts to content t
3550: 68 61 74 20 69 73 20 74 65 72 6d 69 6e 61 74 65  hat is terminate
3560: 64 20 62 79 20 61 20 22 5c 72 5c 6e 22 0a 2a 2a  d by a "\r\n".**
3570: 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74 68 65   followed by the
3580: 20 62 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 20   boundry marker 
3590: 7a 42 6f 75 6e 64 72 79 2e 20 20 41 6e 20 65 78  zBoundry.  An ex
35a0: 74 72 61 20 22 2d 2d 22 20 6d 61 79 20 6f 72 0a  tra "--" may or.
35b0: 2a 2a 20 6d 61 79 20 6e 6f 74 20 62 65 20 61 70  ** may not be ap
35c0: 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 62 6f  pended to the bo
35d0: 75 6e 64 72 79 20 6d 61 72 6b 65 72 2e 20 20 54  undry marker.  T
35e0: 68 65 72 65 20 61 72 65 20 2a 70 4c 65 6e 20 63  here are *pLen c
35f0: 68 61 72 61 63 74 65 72 73 0a 2a 2a 20 69 6e 20  haracters.** in 
3600: 2a 70 7a 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20  *pz..**.** This 
3610: 72 6f 75 74 69 6e 65 20 61 64 64 73 20 61 20 22  routine adds a "
3620: 5c 30 30 30 22 20 74 6f 20 74 68 65 20 65 6e 64  \000" to the end
3630: 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20   of the content 
3640: 28 6f 76 65 72 77 72 69 74 69 6e 67 0a 2a 2a 20  (overwriting.** 
3650: 74 68 65 20 22 5c 72 5c 6e 22 29 20 61 6e 64 20  the "\r\n") and 
3660: 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65  returns a pointe
3670: 72 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74  r to the content
3680: 2e 20 20 54 68 65 20 2a 70 7a 20 69 6e 70 75 74  .  The *pz input
3690: 0a 2a 2a 20 69 73 20 61 64 6a 75 73 74 65 64 20  .** is adjusted 
36a0: 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20  to point to the 
36b0: 66 69 72 73 74 20 6c 69 6e 65 20 66 6f 6c 6c 6f  first line follo
36c0: 77 69 6e 67 20 74 68 65 20 62 6f 75 6e 64 72 79  wing the boundry
36d0: 2e 0a 2a 2a 20 54 68 65 20 6c 65 6e 67 74 68 20  ..** The length 
36e0: 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 69  of the content i
36f0: 73 20 73 74 6f 72 65 64 20 69 6e 20 2a 70 6e 43  s stored in *pnC
3700: 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69  ontent..*/.stati
3710: 63 20 63 68 61 72 20 2a 67 65 74 5f 62 6f 75 6e  c char *get_boun
3720: 64 65 64 5f 63 6f 6e 74 65 6e 74 28 0a 20 20 63  ded_content(.  c
3730: 68 61 72 20 2a 2a 70 7a 2c 20 20 20 20 20 20 20  har **pz,       
3740: 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 61 6b    /* Content tak
3750: 65 6e 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f 0a  en from here */.
3760: 20 20 69 6e 74 20 2a 70 4c 65 6e 2c 20 20 20 20    int *pLen,    
3770: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
3780: 66 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20  f bytes of data 
3790: 69 6e 20 28 2a 70 7a 29 5b 5d 20 2a 2f 0a 20 20  in (*pz)[] */.  
37a0: 63 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 2c 20  char *zBoundry, 
37b0: 20 20 20 2f 2a 20 42 6f 75 6e 64 72 79 20 74 65     /* Boundry te
37c0: 78 74 20 6d 61 72 6b 69 6e 67 20 74 68 65 20 65  xt marking the e
37d0: 6e 64 20 6f 66 20 63 6f 6e 74 65 6e 74 20 2a 2f  nd of content */
37e0: 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6e 74 65 6e  .  int *pnConten
37f0: 74 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74  t     /* Write t
3800: 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63  he size of the c
3810: 6f 6e 74 65 6e 74 20 68 65 72 65 20 2a 2f 0a 29  ontent here */.)
3820: 7b 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 2a 70  {.  char *z = *p
3830: 7a 3b 0a 20 20 69 6e 74 20 6c 65 6e 20 3d 20 2a  z;.  int len = *
3840: 70 4c 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 20  pLen;.  int i;. 
3850: 20 69 6e 74 20 6e 42 6f 75 6e 64 72 79 20 3d 20   int nBoundry = 
3860: 73 74 72 6c 65 6e 28 7a 42 6f 75 6e 64 72 79 29  strlen(zBoundry)
3870: 3b 0a 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d  ;.  *pnContent =
3880: 20 6c 65 6e 3b 0a 20 20 66 6f 72 28 69 3d 30 3b   len;.  for(i=0;
3890: 20 69 3c 6c 65 6e 3b 20 69 2b 2b 29 7b 0a 20 20   i<len; i++){.  
38a0: 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27    if( z[i]=='\n'
38b0: 20 26 26 20 73 74 72 6e 63 6d 70 28 7a 42 6f 75   && strncmp(zBou
38c0: 6e 64 72 79 2c 20 26 7a 5b 69 2b 31 5d 2c 20 6e  ndry, &z[i+1], n
38d0: 42 6f 75 6e 64 72 79 29 3d 3d 30 20 29 7b 0a 20  Boundry)==0 ){. 
38e0: 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20       if( i>0 && 
38f0: 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 20 69  z[i-1]=='\r' ) i
3900: 2d 2d 3b 0a 20 20 20 20 20 20 7a 5b 69 5d 20 3d  --;.      z[i] =
3910: 20 30 3b 0a 20 20 20 20 20 20 2a 70 6e 43 6f 6e   0;.      *pnCon
3920: 74 65 6e 74 20 3d 20 69 3b 0a 20 20 20 20 20 20  tent = i;.      
3930: 69 20 2b 3d 20 6e 42 6f 75 6e 64 72 79 3b 0a 20  i += nBoundry;. 
3940: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20       break;.    
3950: 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a  }.  }.  *pz = &z
3960: 5b 69 5d 3b 0a 20 20 67 65 74 5f 6c 69 6e 65 5f  [i];.  get_line_
3970: 66 72 6f 6d 5f 73 74 72 69 6e 67 28 70 7a 2c 20  from_string(pz, 
3980: 70 4c 65 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20  pLen);.  return 
3990: 7a 3b 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a  z;      .}../*.*
39a0: 2a 20 54 6f 6b 65 6e 69 7a 65 20 61 20 6c 69 6e  * Tokenize a lin
39b0: 65 20 6f 66 20 74 65 78 74 20 69 6e 74 6f 20 61  e of text into a
39c0: 73 20 6d 61 6e 79 20 61 73 20 6e 41 72 67 20 74  s many as nArg t
39d0: 6f 6b 65 6e 73 2e 20 20 4d 61 6b 65 0a 2a 2a 20  okens.  Make.** 
39e0: 61 7a 41 72 67 5b 5d 20 70 6f 69 6e 74 20 74 6f  azArg[] point to
39f0: 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 65 61   the start of ea
3a00: 63 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20  ch token..**.** 
3a10: 54 6f 6b 65 6e 73 20 63 6f 6e 73 69 73 74 20 6f  Tokens consist o
3a20: 66 20 73 70 61 63 65 20 6f 72 20 73 65 6d 69 2d  f space or semi-
3a30: 63 6f 6c 6f 6e 20 64 65 6c 69 6d 69 74 65 64 20  colon delimited 
3a40: 77 6f 72 64 73 20 6f 72 0a 2a 2a 20 73 74 72 69  words or.** stri
3a50: 6e 67 73 20 69 6e 73 69 64 65 20 64 6f 75 62 6c  ngs inside doubl
3a60: 65 2d 71 75 6f 74 65 73 2e 20 20 45 78 61 6d 70  e-quotes.  Examp
3a70: 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 63 6f 6e  le:.**.**    con
3a80: 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e  tent-disposition
3a90: 3a 20 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 6d  : form-data; nam
3aa0: 65 3d 22 66 6e 22 3b 20 66 69 6c 65 6e 61 6d 65  e="fn"; filename
3ab0: 3d 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a  ="index.html".**
3ac0: 0a 2a 2a 20 54 68 65 20 6c 69 6e 65 20 61 62 6f  .** The line abo
3ad0: 76 65 20 69 73 20 74 6f 6b 65 6e 69 7a 65 64 20  ve is tokenized 
3ae0: 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a  as follows:.**.*
3af0: 2a 20 20 20 20 61 7a 41 72 67 5b 30 5d 20 3d 20  *    azArg[0] = 
3b00: 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69  "content-disposi
3b10: 74 69 6f 6e 3a 22 0a 2a 2a 20 20 20 20 61 7a 41  tion:".**    azA
3b20: 72 67 5b 31 5d 20 3d 20 22 66 6f 72 6d 2d 64 61  rg[1] = "form-da
3b30: 74 61 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b  ta".**    azArg[
3b40: 32 5d 20 3d 20 22 6e 61 6d 65 3d 22 0a 2a 2a 20  2] = "name=".** 
3b50: 20 20 20 61 7a 41 72 67 5b 33 5d 20 3d 20 22 66     azArg[3] = "f
3b60: 6e 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 34  n".**    azArg[4
3b70: 5d 20 3d 20 22 66 69 6c 65 6e 61 6d 65 3d 22 0a  ] = "filename=".
3b80: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 35 5d 20 3d  **    azArg[5] =
3b90: 20 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a   "index.html".**
3ba0: 20 20 20 20 61 7a 41 72 67 5b 36 5d 20 3d 20 30      azArg[6] = 0
3bb0: 3b 0a 2a 2a 0a 2a 2a 20 27 5c 30 30 30 27 20 63  ;.**.** '\000' c
3bc0: 68 61 72 61 63 74 65 72 73 20 61 72 65 20 69 6e  haracters are in
3bd0: 73 65 72 74 65 64 20 69 6e 20 7a 5b 5d 20 61 74  serted in z[] at
3be0: 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68   the end of each
3bf0: 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 54 68 69 73 20   token..** This 
3c00: 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20  routine returns 
3c10: 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72  the total number
3c20: 20 6f 66 20 74 6f 6b 65 6e 73 20 6f 6e 20 74 68   of tokens on th
3c30: 65 20 6c 69 6e 65 2c 20 36 0a 2a 2a 20 69 6e 20  e line, 6.** in 
3c40: 74 68 65 20 65 78 61 6d 70 6c 65 20 61 62 6f 76  the example abov
3c50: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74  e..*/.static int
3c60: 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 63   tokenize_line(c
3c70: 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6d 78 41 72  har *z, int mxAr
3c80: 67 2c 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 29  g, char **azArg)
3c90: 7b 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a 20  {.  int i = 0;. 
3ca0: 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20   while( *z ){.  
3cb0: 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65    while( isspace
3cc0: 28 2a 7a 29 20 7c 7c 20 2a 7a 3d 3d 27 3b 27 20  (*z) || *z==';' 
3cd0: 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69 66  ){ z++; }.    if
3ce0: 28 20 2a 7a 3d 3d 27 22 27 20 26 26 20 7a 5b 31  ( *z=='"' && z[1
3cf0: 5d 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 20  ] ){.      *z = 
3d00: 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20  0;.      z++;.  
3d10: 20 20 20 20 69 66 28 20 69 3c 6d 78 41 72 67 2d      if( i<mxArg-
3d20: 31 20 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d 20  1 ){ azArg[i++] 
3d30: 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68 69  = z; }.      whi
3d40: 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 22  le( *z && *z!='"
3d50: 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20  ' ){ z++; }.    
3d60: 20 20 69 66 28 20 2a 7a 3d 3d 30 20 29 20 62 72    if( *z==0 ) br
3d70: 65 61 6b 3b 0a 20 20 20 20 20 20 2a 7a 20 3d 20  eak;.      *z = 
3d80: 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20  0;.      z++;.  
3d90: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69    }else{.      i
3da0: 66 28 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b 20  f( i<mxArg-1 ){ 
3db0: 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20  azArg[i++] = z; 
3dc0: 7d 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a  }.      while( *
3dd0: 7a 20 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a  z && !isspace(*z
3de0: 29 20 26 26 20 2a 7a 21 3d 27 3b 27 20 26 26 20  ) && *z!=';' && 
3df0: 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b 20  *z!='"' ){ z++; 
3e00: 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20 26  }.      if( *z &
3e10: 26 20 2a 7a 21 3d 27 22 27 20 29 7b 0a 20 20 20  & *z!='"' ){.   
3e20: 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20       *z = 0;.   
3e30: 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20       z++;.      
3e40: 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 7a  }.    }.  }.  az
3e50: 41 72 67 5b 69 5d 20 3d 20 30 3b 0a 20 20 72 65  Arg[i] = 0;.  re
3e60: 74 75 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn i;.}../*.**
3e70: 20 53 63 61 6e 20 74 68 65 20 6d 75 6c 74 69 70   Scan the multip
3e80: 61 72 74 2d 66 6f 72 6d 20 63 6f 6e 74 65 6e 74  art-form content
3e90: 20 61 6e 64 20 6d 61 6b 65 20 61 70 70 72 6f 70   and make approp
3ea0: 72 69 61 74 65 20 65 6e 74 72 69 65 73 0a 2a 2a  riate entries.**
3eb0: 20 69 6e 74 6f 20 74 68 65 20 70 61 72 61 6d 65   into the parame
3ec0: 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a  ter table..**.**
3ed0: 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 73 74 72   The content str
3ee0: 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66  ing "z" is modif
3ef0: 69 65 64 20 62 79 20 74 68 69 73 20 72 6f 75 74  ied by this rout
3f00: 69 6e 65 20 62 75 74 20 69 74 20 69 73 0a 2a 2a  ine but it is.**
3f10: 20 6e 6f 74 20 63 6f 70 69 65 64 2e 20 20 54 68   not copied.  Th
3f20: 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69  e calling functi
3f30: 6f 6e 20 6d 75 73 74 20 6e 6f 74 20 64 65 61 6c  on must not deal
3f40: 6c 6f 63 61 74 65 20 6f 72 20 6d 6f 64 69 66 79  locate or modify
3f50: 0a 2a 2a 20 22 7a 22 20 61 66 74 65 72 20 74 68  .** "z" after th
3f60: 69 73 20 72 6f 75 74 69 6e 65 20 66 69 6e 69 73  is routine finis
3f70: 68 65 73 20 6f 72 20 69 74 20 63 6f 75 6c 64 20  hes or it could 
3f80: 63 6f 72 72 75 70 74 20 74 68 65 20 70 61 72 61  corrupt the para
3f90: 6d 65 74 65 72 0a 2a 2a 20 74 61 62 6c 65 2e 0a  meter.** table..
3fa0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70  */.static void p
3fb0: 72 6f 63 65 73 73 5f 6d 75 6c 74 69 70 61 72 74  rocess_multipart
3fc0: 5f 66 6f 72 6d 5f 64 61 74 61 28 63 68 61 72 20  _form_data(char 
3fd0: 2a 7a 2c 20 69 6e 74 20 6c 65 6e 29 7b 0a 20 20  *z, int len){.  
3fe0: 63 68 61 72 20 2a 7a 4c 69 6e 65 3b 0a 20 20 69  char *zLine;.  i
3ff0: 6e 74 20 6e 41 72 67 2c 20 69 3b 0a 20 20 63 68  nt nArg, i;.  ch
4000: 61 72 20 2a 7a 42 6f 75 6e 64 72 79 3b 0a 20 20  ar *zBoundry;.  
4010: 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20  char *zValue;.  
4020: 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 30 3b  char *zName = 0;
4030: 0a 20 20 69 6e 74 20 73 68 6f 77 42 79 74 65 73  .  int showBytes
4040: 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 61 7a   = 0;.  char *az
4050: 41 72 67 5b 35 30 5d 3b 0a 0a 20 20 7a 42 6f 75  Arg[50];..  zBou
4060: 6e 64 72 79 20 3d 20 67 65 74 5f 6c 69 6e 65 5f  ndry = get_line_
4070: 66 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20  from_string(&z, 
4080: 26 6c 65 6e 29 3b 0a 20 20 69 66 28 20 7a 42 6f  &len);.  if( zBo
4090: 75 6e 64 72 79 3d 3d 30 20 29 20 72 65 74 75 72  undry==0 ) retur
40a0: 6e 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4c 69  n;.  while( (zLi
40b0: 6e 65 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 72  ne = get_line_fr
40c0: 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 6c  om_string(&z, &l
40d0: 65 6e 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69  en))!=0 ){.    i
40e0: 66 28 20 7a 4c 69 6e 65 5b 30 5d 3d 3d 30 20 29  f( zLine[0]==0 )
40f0: 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 6e  {.      int nCon
4100: 74 65 6e 74 20 3d 20 30 3b 0a 20 20 20 20 20 20  tent = 0;.      
4110: 7a 56 61 6c 75 65 20 3d 20 67 65 74 5f 62 6f 75  zValue = get_bou
4120: 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28 26 7a 2c  nded_content(&z,
4130: 20 26 6c 65 6e 2c 20 7a 42 6f 75 6e 64 72 79 2c   &len, zBoundry,
4140: 20 26 6e 43 6f 6e 74 65 6e 74 29 3b 0a 20 20 20   &nContent);.   
4150: 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20     if( zName && 
4160: 7a 56 61 6c 75 65 20 26 26 20 69 73 6c 6f 77 65  zValue && islowe
4170: 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20  r(zName[0]) ){. 
4180: 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70         cgi_set_p
4190: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28  arameter_nocopy(
41a0: 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a  zName, zValue);.
41b0: 20 20 20 20 20 20 20 20 69 66 28 20 73 68 6f 77          if( show
41c0: 42 79 74 65 73 20 29 7b 0a 20 20 20 20 20 20 20  Bytes ){.       
41d0: 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d     cgi_set_param
41e0: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69  eter_nocopy(mpri
41f0: 6e 74 66 28 22 25 73 3a 62 79 74 65 73 22 2c 20  ntf("%s:bytes", 
4200: 7a 4e 61 6d 65 29 2c 0a 20 20 20 20 20 20 20 20  zName),.        
4210: 20 20 20 20 20 20 20 6d 70 72 69 6e 74 66 28 22         mprintf("
4220: 25 64 22 2c 6e 43 6f 6e 74 65 6e 74 29 29 3b 0a  %d",nContent));.
4230: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20          }.      
4240: 7d 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20  }.      zName = 
4250: 30 3b 0a 20 20 20 20 20 20 73 68 6f 77 42 79 74  0;.      showByt
4260: 65 73 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73  es = 0;.    }els
4270: 65 7b 0a 20 20 20 20 20 20 6e 41 72 67 20 3d 20  e{.      nArg = 
4280: 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 7a 4c  tokenize_line(zL
4290: 69 6e 65 2c 20 73 69 7a 65 6f 66 28 61 7a 41 72  ine, sizeof(azAr
42a0: 67 29 2f 73 69 7a 65 6f 66 28 61 7a 41 72 67 5b  g)/sizeof(azArg[
42b0: 30 5d 29 2c 20 61 7a 41 72 67 29 3b 0a 20 20 20  0]), azArg);.   
42c0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41     for(i=0; i<nA
42d0: 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20  rg; i++){.      
42e0: 20 20 69 6e 74 20 63 20 3d 20 74 6f 6c 6f 77 65    int c = tolowe
42f0: 72 28 61 7a 41 72 67 5b 69 5d 5b 30 5d 29 3b 0a  r(azArg[i][0]);.
4300: 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27          if( c=='
4310: 63 27 20 26 26 20 73 74 72 69 63 6d 70 28 61 7a  c' && stricmp(az
4320: 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d  Arg[i],"content-
4330: 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22 29 3d 3d  disposition:")==
4340: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69  0 ){.          i
4350: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73  ++;.        }els
4360: 65 20 69 66 28 20 63 3d 3d 27 6e 27 20 26 26 20  e if( c=='n' && 
4370: 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d  stricmp(azArg[i]
4380: 2c 22 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a  ,"name=")==0 ){.
4390: 20 20 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 20            zName 
43a0: 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20  = azArg[++i];.  
43b0: 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20        }else if( 
43c0: 63 3d 3d 27 66 27 20 26 26 20 73 74 72 69 63 6d  c=='f' && stricm
43d0: 70 28 61 7a 41 72 67 5b 69 5d 2c 22 66 69 6c 65  p(azArg[i],"file
43e0: 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a 20 20  name=")==0 ){.  
43f0: 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20          char *z 
4400: 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20  = azArg[++i];.  
4410: 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d          if( zNam
4420: 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f 77 65  e && z && islowe
4430: 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20  r(zName[0]) ){. 
4440: 20 20 20 20 20 20 20 20 20 20 20 63 67 69 5f 73             cgi_s
4450: 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63  et_parameter_noc
4460: 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 3a  opy(mprintf("%s:
4470: 66 69 6c 65 6e 61 6d 65 22 2c 7a 4e 61 6d 65 29  filename",zName)
4480: 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20  , z);.          
4490: 7d 0a 20 20 20 20 20 20 20 20 20 20 73 68 6f 77  }.          show
44a0: 42 79 74 65 73 20 3d 20 31 3b 0a 20 20 20 20 20  Bytes = 1;.     
44b0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d     }else if( c==
44c0: 27 63 27 20 26 26 20 73 74 72 69 63 6d 70 28 61  'c' && stricmp(a
44d0: 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74  zArg[i],"content
44e0: 2d 74 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a 20  -type:")==0 ){. 
44f0: 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a           char *z
4500: 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20   = azArg[++i];. 
4510: 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61           if( zNa
4520: 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f 77  me && z && islow
4530: 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a  er(zName[0]) ){.
4540: 20 20 20 20 20 20 20 20 20 20 20 20 63 67 69 5f              cgi_
4550: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f  set_parameter_no
4560: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73  copy(mprintf("%s
4570: 3a 6d 69 6d 65 74 79 70 65 22 2c 7a 4e 61 6d 65  :mimetype",zName
4580: 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 20  ), z);.         
4590: 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20   }.        }.   
45a0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 20     }.    }.  }  
45b0: 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20        .}../*.** 
45c0: 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 71  Initialize the q
45d0: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 64  uery parameter d
45e0: 61 74 61 62 61 73 65 2e 20 20 49 6e 66 6f 72 6d  atabase.  Inform
45f0: 61 74 69 6f 6e 20 69 73 20 70 75 6c 6c 65 64 20  ation is pulled 
4600: 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 51 55 45 52  from.** the QUER
4610: 59 5f 53 54 52 49 4e 47 20 65 6e 76 69 72 6f 6e  Y_STRING environ
4620: 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 28 69  ment variable (i
4630: 66 20 69 74 20 65 78 69 73 74 73 29 2c 20 66 72  f it exists), fr
4640: 6f 6d 20 73 74 61 6e 64 61 72 64 0a 2a 2a 20 69  om standard.** i
4650: 6e 70 75 74 20 69 66 20 74 68 65 72 65 20 69 73  nput if there is
4660: 20 50 4f 53 54 20 64 61 74 61 2c 20 61 6e 64 20   POST data, and 
4670: 66 72 6f 6d 20 48 54 54 50 5f 43 4f 4f 4b 49 45  from HTTP_COOKIE
4680: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 69 6e  ..*/.void cgi_in
4690: 69 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 72  it(void){.  char
46a0: 20 2a 7a 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61   *z;.  const cha
46b0: 72 20 2a 7a 54 79 70 65 3b 0a 20 20 69 6e 74 20  r *zType;.  int 
46c0: 6c 65 6e 3b 0a 20 20 7a 20 3d 20 28 63 68 61 72  len;.  z = (char
46d0: 2a 29 50 28 22 51 55 45 52 59 5f 53 54 52 49 4e  *)P("QUERY_STRIN
46e0: 47 22 29 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a  G");.  if( z ){.
46f0: 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28      z = mprintf(
4700: 22 25 73 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64  "%s",z);.    add
4710: 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27  _param_list(z, '
4720: 26 27 29 3b 0a 20 20 7d 0a 0a 20 20 6c 65 6e 20  &');.  }..  len 
4730: 3d 20 61 74 6f 69 28 50 44 28 22 43 4f 4e 54 45  = atoi(PD("CONTE
4740: 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 22 30 22 29  NT_LENGTH", "0")
4750: 29 3b 0a 20 20 67 2e 7a 43 6f 6e 74 65 6e 74 54  );.  g.zContentT
4760: 79 70 65 20 3d 20 7a 54 79 70 65 20 3d 20 50 28  ype = zType = P(
4770: 22 43 4f 4e 54 45 4e 54 5f 54 59 50 45 22 29 3b  "CONTENT_TYPE");
4780: 0a 20 20 69 66 28 20 6c 65 6e 3e 30 20 26 26 20  .  if( len>0 && 
4790: 7a 54 79 70 65 20 29 7b 0a 20 20 20 20 62 6c 6f  zType ){.    blo
47a0: 62 5f 7a 65 72 6f 28 26 67 2e 63 67 69 49 6e 29  b_zero(&g.cgiIn)
47b0: 3b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70  ;.    if( strcmp
47c0: 28 7a 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74  (zType,"applicat
47d0: 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75  ion/x-www-form-u
47e0: 72 6c 65 6e 63 6f 64 65 64 22 29 3d 3d 30 20 0a  rlencoded")==0 .
47f0: 20 20 20 20 20 20 20 20 20 7c 7c 20 73 74 72 6e           || strn
4800: 63 6d 70 28 7a 54 79 70 65 2c 22 6d 75 6c 74 69  cmp(zType,"multi
4810: 70 61 72 74 2f 66 6f 72 6d 2d 64 61 74 61 22 2c  part/form-data",
4820: 31 39 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  19)==0 ){.      
4830: 7a 20 3d 20 6d 61 6c 6c 6f 63 28 20 6c 65 6e 2b  z = malloc( len+
4840: 31 20 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a  1 );.      if( z
4850: 3d 3d 30 20 29 20 65 78 69 74 28 31 29 3b 0a 20  ==0 ) exit(1);. 
4860: 20 20 20 20 20 6c 65 6e 20 3d 20 66 72 65 61 64       len = fread
4870: 28 7a 2c 20 31 2c 20 6c 65 6e 2c 20 73 74 64 69  (z, 1, len, stdi
4880: 6e 29 3b 0a 20 20 20 20 20 20 7a 5b 6c 65 6e 5d  n);.      z[len]
4890: 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20   = 0;.      if( 
48a0: 7a 54 79 70 65 5b 30 5d 3d 3d 27 61 27 20 29 7b  zType[0]=='a' ){
48b0: 0a 20 20 20 20 20 20 20 20 61 64 64 5f 70 61 72  .        add_par
48c0: 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 26 27 29 3b  am_list(z, '&');
48d0: 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20  .      }else{.  
48e0: 20 20 20 20 20 20 70 72 6f 63 65 73 73 5f 6d 75        process_mu
48f0: 6c 74 69 70 61 72 74 5f 66 6f 72 6d 5f 64 61 74  ltipart_form_dat
4900: 61 28 7a 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20  a(z, len);.     
4910: 20 7d 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28   }.    }else if(
4920: 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20 22   strcmp(zType, "
4930: 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f  application/x-fo
4940: 73 73 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20  ssil")==0 ){.   
4950: 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f     blob_read_fro
4960: 6d 5f 63 68 61 6e 6e 65 6c 28 26 67 2e 63 67 69  m_channel(&g.cgi
4970: 49 6e 2c 20 73 74 64 69 6e 2c 20 6c 65 6e 29 3b  In, stdin, len);
4980: 0a 20 20 20 20 20 20 62 6c 6f 62 5f 75 6e 63 6f  .      blob_unco
4990: 6d 70 72 65 73 73 28 26 67 2e 63 67 69 49 6e 2c  mpress(&g.cgiIn,
49a0: 20 26 67 2e 63 67 69 49 6e 29 3b 0a 20 20 20 20   &g.cgiIn);.    
49b0: 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70  }else if( strcmp
49c0: 28 7a 54 79 70 65 2c 20 22 61 70 70 6c 69 63 61  (zType, "applica
49d0: 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 2d 64 65  tion/x-fossil-de
49e0: 62 75 67 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20  bug")==0 ){.    
49f0: 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d    blob_read_from
4a00: 5f 63 68 61 6e 6e 65 6c 28 26 67 2e 63 67 69 49  _channel(&g.cgiI
4a10: 6e 2c 20 73 74 64 69 6e 2c 20 6c 65 6e 29 3b 0a  n, stdin, len);.
4a20: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 20 3d      }.  }..  z =
4a30: 20 28 63 68 61 72 2a 29 50 28 22 48 54 54 50 5f   (char*)P("HTTP_
4a40: 43 4f 4f 4b 49 45 22 29 3b 0a 20 20 69 66 28 20  COOKIE");.  if( 
4a50: 7a 20 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 72  z ){.    z = mpr
4a60: 69 6e 74 66 28 22 25 73 22 2c 7a 29 3b 0a 20 20  intf("%s",z);.  
4a70: 20 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74    add_param_list
4a80: 28 7a 2c 20 27 3b 27 29 3b 0a 20 20 7d 0a 7d 0a  (z, ';');.  }.}.
4a90: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74  ./*.** This is t
4aa0: 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 20 66 75  he comparison fu
4ab0: 6e 63 74 69 6f 6e 20 75 73 65 64 20 74 6f 20 73  nction used to s
4ac0: 6f 72 74 20 74 68 65 20 61 50 61 72 61 6d 51 50  ort the aParamQP
4ad0: 5b 5d 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 71  [] array of.** q
4ae0: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 20  uery parameters 
4af0: 61 6e 64 20 63 6f 6f 6b 69 65 73 2e 0a 2a 2f 0a  and cookies..*/.
4b00: 73 74 61 74 69 63 20 69 6e 74 20 71 70 61 72 61  static int qpara
4b10: 6d 5f 63 6f 6d 70 61 72 65 28 63 6f 6e 73 74 20  m_compare(const 
4b20: 76 6f 69 64 20 2a 61 2c 20 63 6f 6e 73 74 20 76  void *a, const v
4b30: 6f 69 64 20 2a 62 29 7b 0a 20 20 73 74 72 75 63  oid *b){.  struc
4b40: 74 20 51 50 61 72 61 6d 20 2a 70 41 20 3d 20 28  t QParam *pA = (
4b50: 73 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29 61  struct QParam*)a
4b60: 3b 0a 20 20 73 74 72 75 63 74 20 51 50 61 72 61  ;.  struct QPara
4b70: 6d 20 2a 70 42 20 3d 20 28 73 74 72 75 63 74 20  m *pB = (struct 
4b80: 51 50 61 72 61 6d 2a 29 62 3b 0a 20 20 69 6e 74  QParam*)b;.  int
4b90: 20 63 3b 0a 20 20 63 20 3d 20 73 74 72 63 6d 70   c;.  c = strcmp
4ba0: 28 70 41 2d 3e 7a 4e 61 6d 65 2c 20 70 42 2d 3e  (pA->zName, pB->
4bb0: 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 63 3d  zName);.  if( c=
4bc0: 3d 30 20 29 7b 0a 20 20 20 20 63 20 3d 20 70 41  =0 ){.    c = pA
4bd0: 2d 3e 73 65 71 20 2d 20 70 42 2d 3e 73 65 71 3b  ->seq - pB->seq;
4be0: 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 63 3b  .  }.  return c;
4bf0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e  .}../*.** Return
4c00: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 61 20   the value of a 
4c10: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20  query parameter 
4c20: 6f 72 20 63 6f 6f 6b 69 65 20 77 68 6f 73 65 20  or cookie whose 
4c30: 6e 61 6d 65 20 69 73 20 7a 4e 61 6d 65 2e 0a 2a  name is zName..*
4c40: 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f  * If there is no
4c50: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72   query parameter
4c60: 20 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 64   or cookie named
4c70: 20 7a 4e 61 6d 65 20 61 6e 64 20 74 68 65 20 66   zName and the f
4c80: 69 72 73 74 0a 2a 2a 20 63 68 61 72 61 63 74 65  irst.** characte
4c90: 72 20 6f 66 20 7a 4e 61 6d 65 20 69 73 20 75 70  r of zName is up
4ca0: 70 65 72 63 61 73 65 2c 20 74 68 65 6e 20 63 68  percase, then ch
4cb0: 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74 68  eck to see if th
4cc0: 65 72 65 20 69 73 20 61 6e 0a 2a 2a 20 65 6e 76  ere is an.** env
4cd0: 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c  ironment variabl
4ce0: 65 20 62 79 20 74 68 61 74 20 6e 61 6d 65 20 61  e by that name a
4cf0: 6e 64 20 72 65 74 75 72 6e 20 69 74 20 69 66 20  nd return it if 
4d00: 74 68 65 72 65 20 69 73 2e 20 20 41 73 0a 2a 2a  there is.  As.**
4d10: 20 61 20 6c 61 73 74 20 72 65 73 6f 72 74 20 77   a last resort w
4d20: 68 65 6e 20 6e 6f 74 68 69 6e 67 20 65 6c 73 65  hen nothing else
4d30: 20 6d 61 74 63 68 65 73 2c 20 72 65 74 75 72 6e   matches, return
4d40: 20 7a 44 65 66 61 75 6c 74 2e 0a 2a 2f 0a 63 6f   zDefault..*/.co
4d50: 6e 73 74 20 63 68 61 72 20 2a 63 67 69 5f 70 61  nst char *cgi_pa
4d60: 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 20 63 68  rameter(const ch
4d70: 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74  ar *zName, const
4d80: 20 63 68 61 72 20 2a 7a 44 65 66 61 75 6c 74 29   char *zDefault)
4d90: 7b 0a 20 20 69 6e 74 20 6c 6f 2c 20 68 69 2c 20  {.  int lo, hi, 
4da0: 6d 69 64 2c 20 63 3b 0a 0a 20 20 2f 2a 20 54 68  mid, c;..  /* Th
4db0: 65 20 73 6f 72 74 51 50 20 66 6c 61 67 20 69 73  e sortQP flag is
4dc0: 20 73 65 74 20 77 68 65 6e 65 76 65 72 20 61 20   set whenever a 
4dd0: 6e 65 77 20 71 75 65 72 79 20 70 61 72 61 6d 65  new query parame
4de0: 74 65 72 20 69 73 20 69 6e 73 65 72 74 65 64 2e  ter is inserted.
4df0: 0a 20 20 2a 2a 20 49 74 20 69 6e 64 69 63 61 74  .  ** It indicat
4e00: 65 73 20 74 68 61 74 20 77 65 20 6e 65 65 64 20  es that we need 
4e10: 74 6f 20 72 65 73 6f 72 74 20 74 68 65 20 71 75  to resort the qu
4e20: 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 2e 0a  ery parameters..
4e30: 20 20 2a 2f 0a 20 20 69 66 28 20 73 6f 72 74 51    */.  if( sortQ
4e40: 50 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20  P ){.    int i, 
4e50: 6a 3b 0a 20 20 20 20 71 73 6f 72 74 28 61 50 61  j;.    qsort(aPa
4e60: 72 61 6d 51 50 2c 20 6e 55 73 65 64 51 50 2c 20  ramQP, nUsedQP, 
4e70: 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51 50 5b  sizeof(aParamQP[
4e80: 30 5d 29 2c 20 71 70 61 72 61 6d 5f 63 6f 6d 70  0]), qparam_comp
4e90: 61 72 65 29 3b 0a 20 20 20 20 73 6f 72 74 51 50  are);.    sortQP
4ea0: 20 3d 20 30 3b 0a 20 20 20 20 2f 2a 20 41 66 74   = 0;.    /* Aft
4eb0: 65 72 20 73 6f 72 74 69 6e 67 2c 20 72 65 6d 6f  er sorting, remo
4ec0: 76 65 20 64 75 70 6c 69 63 61 74 65 20 70 61 72  ve duplicate par
4ed0: 61 6d 65 74 65 72 73 2e 20 20 54 68 65 20 73 65  ameters.  The se
4ee0: 63 6f 6e 64 61 72 79 20 73 6f 72 74 0a 20 20 20  condary sort.   
4ef0: 20 2a 2a 20 6b 65 79 20 69 73 20 61 50 61 72 61   ** key is aPara
4f00: 6d 51 50 5b 5d 2e 73 65 71 20 61 6e 64 20 77 65  mQP[].seq and we
4f10: 20 6b 65 65 70 20 74 68 65 20 66 69 72 73 74 20   keep the first 
4f20: 65 6e 74 72 79 2e 20 20 54 68 61 74 20 6d 65 61  entry.  That mea
4f30: 6e 73 0a 20 20 20 20 2a 2a 20 77 69 74 68 20 64  ns.    ** with d
4f40: 75 70 6c 69 63 61 74 65 20 63 61 6c 6c 73 20 74  uplicate calls t
4f50: 6f 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65  o cgi_set_parame
4f60: 74 65 72 28 29 20 74 68 65 20 73 65 63 6f 6e 64  ter() the second
4f70: 20 61 6e 64 0a 20 20 20 20 2a 2a 20 73 75 62 73   and.    ** subs
4f80: 65 71 75 65 6e 74 20 63 61 6c 6c 73 20 61 72 65  equent calls are
4f90: 20 65 66 66 65 63 74 69 76 65 6c 79 20 6e 6f 2d   effectively no-
4fa0: 6f 70 73 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28  ops. */.    for(
4fb0: 69 3d 6a 3d 31 3b 20 69 3c 6e 55 73 65 64 51 50  i=j=1; i<nUsedQP
4fc0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66  ; i++){.      if
4fd0: 28 20 73 74 72 63 6d 70 28 61 50 61 72 61 6d 51  ( strcmp(aParamQ
4fe0: 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 61 50 61 72 61  P[i].zName,aPara
4ff0: 6d 51 50 5b 69 2d 31 5d 2e 7a 4e 61 6d 65 29 3d  mQP[i-1].zName)=
5000: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63 6f  =0 ){.        co
5010: 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d 0a  ntinue;.      }.
5020: 20 20 20 20 20 20 69 66 28 20 6a 3c 69 20 29 7b        if( j<i ){
5030: 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28  .        memcpy(
5040: 26 61 50 61 72 61 6d 51 50 5b 6a 5d 2c 20 26 61  &aParamQP[j], &a
5050: 50 61 72 61 6d 51 50 5b 69 5d 2c 20 73 69 7a 65  ParamQP[i], size
5060: 6f 66 28 61 50 61 72 61 6d 51 50 5b 6a 5d 29 29  of(aParamQP[j]))
5070: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20  ;.      }.      
5080: 6a 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e  j++;.    }.    n
5090: 55 73 65 64 51 50 20 3d 20 6a 3b 0a 20 20 7d 0a  UsedQP = j;.  }.
50a0: 0a 20 20 2f 2a 20 44 6f 20 61 20 62 69 6e 61 72  .  /* Do a binar
50b0: 79 20 73 65 61 72 63 68 20 66 6f 72 20 61 20 6d  y search for a m
50c0: 61 74 63 68 69 6e 67 20 71 75 65 72 79 20 70 61  atching query pa
50d0: 72 61 6d 65 74 65 72 20 2a 2f 0a 20 20 6c 6f 20  rameter */.  lo 
50e0: 3d 20 30 3b 0a 20 20 68 69 20 3d 20 6e 55 73 65  = 0;.  hi = nUse
50f0: 64 51 50 2d 31 3b 0a 20 20 77 68 69 6c 65 28 20  dQP-1;.  while( 
5100: 6c 6f 3c 3d 68 69 20 29 7b 0a 20 20 20 20 6d 69  lo<=hi ){.    mi
5110: 64 20 3d 20 28 6c 6f 2b 68 69 29 2f 32 3b 0a 20  d = (lo+hi)/2;. 
5120: 20 20 20 63 20 3d 20 73 74 72 63 6d 70 28 61 50     c = strcmp(aP
5130: 61 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 4e 61 6d  aramQP[mid].zNam
5140: 65 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 69  e, zName);.    i
5150: 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20  f( c==0 ){.     
5160: 20 43 47 49 44 45 42 55 47 28 28 22 6d 65 6d 2d   CGIDEBUG(("mem-
5170: 6d 61 74 63 68 20 5b 25 73 5d 20 3d 20 5b 25 73  match [%s] = [%s
5180: 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c 20 61 50 61  ]\n", zName, aPa
5190: 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75  ramQP[mid].zValu
51a0: 65 29 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72  e));.      retur
51b0: 6e 20 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d 2e  n aParamQP[mid].
51c0: 7a 56 61 6c 75 65 3b 0a 20 20 20 20 7d 65 6c 73  zValue;.    }els
51d0: 65 20 69 66 28 20 63 3e 30 20 29 7b 0a 20 20 20  e if( c>0 ){.   
51e0: 20 20 20 68 69 20 3d 20 6d 69 64 2d 31 3b 0a 20     hi = mid-1;. 
51f0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20     }else{.      
5200: 6c 6f 20 3d 20 6d 69 64 2b 31 3b 0a 20 20 20 20  lo = mid+1;.    
5210: 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 6e  }.  }..  /* If n
5220: 6f 20 6d 61 74 63 68 20 69 73 20 66 6f 75 6e 64  o match is found
5230: 20 61 6e 64 20 74 68 65 20 6e 61 6d 65 20 62 65   and the name be
5240: 67 69 6e 73 20 77 69 74 68 20 61 6e 20 75 70 70  gins with an upp
5250: 65 72 2d 63 61 73 65 0a 20 20 2a 2a 20 6c 65 74  er-case.  ** let
5260: 74 65 72 2c 20 74 68 65 6e 20 63 68 65 63 6b 20  ter, then check 
5270: 74 6f 20 73 65 65 20 69 66 20 74 68 65 72 65 20  to see if there 
5280: 69 73 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e  is an environmen
5290: 74 20 76 61 72 69 61 62 6c 65 0a 20 20 2a 2a 20  t variable.  ** 
52a0: 77 69 74 68 20 74 68 65 20 67 69 76 65 6e 20 6e  with the given n
52b0: 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20  ame..  */.  if( 
52c0: 69 73 75 70 70 65 72 28 7a 4e 61 6d 65 5b 30 5d  isupper(zName[0]
52d0: 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63  ) ){.    const c
52e0: 68 61 72 20 2a 7a 56 61 6c 75 65 20 3d 20 67 65  har *zValue = ge
52f0: 74 65 6e 76 28 7a 4e 61 6d 65 29 3b 0a 20 20 20  tenv(zName);.   
5300: 20 69 66 28 20 7a 56 61 6c 75 65 20 29 7b 0a 20   if( zValue ){. 
5310: 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72       cgi_set_par
5320: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e  ameter_nocopy(zN
5330: 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20  ame, zValue);.  
5340: 20 20 20 20 43 47 49 44 45 42 55 47 28 28 22 65      CGIDEBUG(("e
5350: 6e 76 2d 6d 61 74 63 68 20 5b 25 73 5d 20 3d 20  nv-match [%s] = 
5360: 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c 20  [%s]\n", zName, 
5370: 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20 20 20  zValue));.      
5380: 72 65 74 75 72 6e 20 7a 56 61 6c 75 65 3b 0a 20  return zValue;. 
5390: 20 20 20 7d 0a 20 20 7d 0a 20 20 43 47 49 44 45     }.  }.  CGIDE
53a0: 42 55 47 28 28 22 6e 6f 2d 6d 61 74 63 68 20 5b  BUG(("no-match [
53b0: 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 29 29 3b  %s]\n", zName));
53c0: 0a 20 20 72 65 74 75 72 6e 20 7a 44 65 66 61 75  .  return zDefau
53d0: 6c 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69  lt;.}../*.** Pri
53e0: 6e 74 20 43 47 49 20 64 65 62 75 67 67 69 6e 67  nt CGI debugging
53f0: 20 6d 65 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f   messages..*/.vo
5400: 69 64 20 63 67 69 5f 64 65 62 75 67 28 63 6f 6e  id cgi_debug(con
5410: 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74  st char *zFormat
5420: 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73  , ...){.  va_lis
5430: 74 20 61 70 3b 0a 20 20 69 66 28 20 67 2e 66 44  t ap;.  if( g.fD
5440: 65 62 75 67 20 29 7b 0a 20 20 20 20 76 61 5f 73  ebug ){.    va_s
5450: 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74  tart(ap, zFormat
5460: 29 3b 0a 20 20 20 20 76 66 70 72 69 6e 74 66 28  );.    vfprintf(
5470: 67 2e 66 44 65 62 75 67 2c 20 7a 46 6f 72 6d 61  g.fDebug, zForma
5480: 74 2c 20 61 70 29 3b 0a 20 20 20 20 76 61 5f 65  t, ap);.    va_e
5490: 6e 64 28 61 70 29 3b 0a 20 20 20 20 66 66 6c 75  nd(ap);.    fflu
54a0: 73 68 28 67 2e 66 44 65 62 75 67 29 3b 0a 20 20  sh(g.fDebug);.  
54b0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72  }.}../*.** Retur
54c0: 6e 20 74 72 75 65 20 69 66 20 61 6e 79 20 6f 66  n true if any of
54d0: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d   the query param
54e0: 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 67  eters in the arg
54f0: 75 6d 65 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 72  ument.** list ar
5500: 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e  e defined..*/.in
5510: 74 20 63 67 69 5f 61 6e 79 28 63 6f 6e 73 74 20  t cgi_any(const 
5520: 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20  char *z, ...){. 
5530: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63   va_list ap;.  c
5540: 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63  har *z2;.  if( c
5550: 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30  gi_parameter(z,0
5560: 29 21 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b  )!=0 ) return 1;
5570: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20  .  va_start(ap, 
5580: 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32  z);.  while( (z2
5590: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68   = va_arg(ap, ch
55a0: 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20  ar*))!=0 ){.    
55b0: 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65  if( cgi_paramete
55c0: 72 28 7a 32 2c 30 29 21 3d 30 20 29 20 72 65 74  r(z2,0)!=0 ) ret
55d0: 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 76 61 5f  urn 1;.  }.  va_
55e0: 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72  end(ap);.  retur
55f0: 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65  n 0;.}../*.** Re
5600: 74 75 72 6e 20 74 72 75 65 20 69 66 20 61 6c 6c  turn true if all
5610: 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 61   of the query pa
5620: 72 61 6d 65 74 65 72 73 20 69 6e 20 74 68 65 20  rameters in the 
5630: 61 72 67 75 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a  argument list.**
5640: 20 61 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f   are defined..*/
5650: 0a 69 6e 74 20 63 67 69 5f 61 6c 6c 28 63 6f 6e  .int cgi_all(con
5660: 73 74 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29  st char *z, ...)
5670: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a  {.  va_list ap;.
5680: 20 20 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66    char *z2;.  if
5690: 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28  ( cgi_parameter(
56a0: 7a 2c 30 29 3d 3d 30 20 29 20 72 65 74 75 72 6e  z,0)==0 ) return
56b0: 20 30 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61   0;.  va_start(a
56c0: 70 2c 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20  p, z);.  while( 
56d0: 28 7a 32 20 3d 20 76 61 5f 61 72 67 28 61 70 2c  (z2 = va_arg(ap,
56e0: 20 63 68 61 72 2a 29 29 3d 3d 30 20 29 7b 0a 20   char*))==0 ){. 
56f0: 20 20 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d     if( cgi_param
5700: 65 74 65 72 28 7a 32 2c 30 29 3d 3d 30 20 29 20  eter(z2,0)==0 ) 
5710: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20  return 0;.  }.  
5720: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65  va_end(ap);.  re
5730: 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn 1;.}../*.**
5740: 20 50 72 69 6e 74 20 61 6c 6c 20 71 75 65 72 79   Print all query
5750: 20 70 61 72 61 6d 65 74 65 72 73 20 6f 6e 20 73   parameters on s
5760: 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 20  tandard output. 
5770: 20 46 6f 72 6d 61 74 20 74 68 65 0a 2a 2a 20 70   Format the.** p
5780: 61 72 61 6d 65 74 65 72 73 20 61 73 20 48 54 4d  arameters as HTM
5790: 4c 2e 20 20 54 68 69 73 20 69 73 20 75 73 65 64  L.  This is used
57a0: 20 66 6f 72 20 74 65 73 74 69 6e 67 20 61 6e 64   for testing and
57b0: 20 64 65 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76   debugging..*/.v
57c0: 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 5f 61 6c  oid cgi_print_al
57d0: 6c 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69  l(void){.  int i
57e0: 3b 0a 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65  ;.  cgi_paramete
57f0: 72 28 22 22 2c 22 22 29 3b 20 20 2f 2a 20 46 6f  r("","");  /* Fo
5800: 72 63 65 20 74 68 65 20 70 61 72 61 6d 65 74 65  rce the paramete
5810: 72 73 20 69 6e 74 6f 20 73 6f 72 74 65 64 20 6f  rs into sorted o
5820: 72 64 65 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d  rder */.  for(i=
5830: 30 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b  0; i<nUsedQP; i+
5840: 2b 29 7b 0a 20 20 20 20 63 67 69 5f 70 72 69 6e  +){.    cgi_prin
5850: 74 66 28 22 25 73 20 3d 20 25 73 20 20 3c 62 72  tf("%s = %s  <br
5860: 20 2f 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 68   />\n",.       h
5870: 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b  tmlize(aParamQP[
5880: 69 5d 2e 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 68  i].zName, -1), h
5890: 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b  tmlize(aParamQP[
58a0: 69 5d 2e 7a 56 61 6c 75 65 2c 20 2d 31 29 29 3b  i].zValue, -1));
58b0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72  .  }.}../*.** Wr
58c0: 69 74 65 20 48 54 4d 4c 20 74 65 78 74 20 66 6f  ite HTML text fo
58d0: 72 20 61 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e 75  r an option menu
58e0: 20 74 6f 20 73 74 61 6e 64 61 72 64 20 6f 75 74   to standard out
58f0: 70 75 74 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a 20  put.  zParam.** 
5900: 69 73 20 74 68 65 20 71 75 65 72 79 20 70 61 72  is the query par
5910: 61 6d 65 74 65 72 20 74 68 61 74 20 74 68 65 20  ameter that the 
5920: 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 73 65 74 73  option menu sets
5930: 2e 20 20 7a 44 66 6c 74 20 69 73 20 74 68 65 0a  .  zDflt is the.
5940: 2a 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65  ** initial value
5950: 20 6f 66 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d   of the option m
5960: 65 6e 75 2e 20 20 41 64 64 69 74 69 6f 6e 20 61  enu.  Addition a
5970: 72 67 75 6d 65 6e 74 73 20 61 72 65 20 6e 61 6d  rguments are nam
5980: 65 2f 76 61 6c 75 65 0a 2a 2a 20 70 61 69 72 73  e/value.** pairs
5990: 20 74 68 61 74 20 64 65 66 69 6e 65 20 76 61 6c   that define val
59a0: 75 65 73 20 6f 6e 20 74 68 65 20 6d 65 6e 75 2e  ues on the menu.
59b0: 20 20 54 68 65 20 6c 69 73 74 20 69 73 20 74 65    The list is te
59c0: 72 6d 69 6e 61 74 65 64 20 77 69 74 68 0a 2a 2a  rminated with.**
59d0: 20 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 61   a single NULL a
59e0: 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64  rgument..*/.void
59f0: 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28   cgi_optionmenu(
5a00: 69 6e 74 20 69 6e 2c 20 63 6f 6e 73 74 20 63 68  int in, const ch
5a10: 61 72 20 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 68  ar *zP, const ch
5a20: 61 72 20 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20  ar *zD, ...){.  
5a30: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68  va_list ap;.  ch
5a40: 61 72 20 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c  ar *zName, *zVal
5a50: 3b 0a 20 20 69 6e 74 20 64 66 6c 74 53 65 65 6e  ;.  int dfltSeen
5a60: 20 3d 20 30 3b 0a 20 20 63 67 69 5f 70 72 69 6e   = 0;.  cgi_prin
5a70: 74 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73  tf("%*s<select s
5a80: 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c  ize=1 name=\"%s\
5a90: 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a  ">\n", in, "", z
5aa0: 50 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61  P);.  va_start(a
5ab0: 70 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28  p, zD);.  while(
5ac0: 20 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67   (zName = va_arg
5ad0: 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20  (ap, char*))!=0 
5ae0: 26 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72  && (zVal = va_ar
5af0: 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30  g(ap, char*))!=0
5b00: 20 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63   ){.    if( strc
5b10: 6d 70 28 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 29  mp(zVal,zD)==0 )
5b20: 7b 20 64 66 6c 74 53 65 65 6e 20 3d 20 31 3b 20  { dfltSeen = 1; 
5b30: 62 72 65 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76  break; }.  }.  v
5b40: 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 69 66 28  a_end(ap);.  if(
5b50: 20 21 64 66 6c 74 53 65 65 6e 20 29 7b 0a 20 20   !dfltSeen ){.  
5b60: 20 20 69 66 28 20 7a 44 5b 30 5d 20 29 7b 0a 20    if( zD[0] ){. 
5b70: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28       cgi_printf(
5b80: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75  "%*s<option valu
5b90: 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 65  e=\"%h\" selecte
5ba0: 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22  d>%h</option>\n"
5bb0: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20  ,.        in+2, 
5bc0: 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20  "", zD, zD);.   
5bd0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67   }else{.      cg
5be0: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70  i_printf("%*s<op
5bf0: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20  tion value=\"\" 
5c00: 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c  selected>&nbsp;<
5c10: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b  /option>\n", in+
5c20: 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 0a 20 20  2, "");.    }.  
5c30: 7d 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c  }.  va_start(ap,
5c40: 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28   zD);.  while( (
5c50: 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61  zName = va_arg(a
5c60: 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26  p, char*))!=0 &&
5c70: 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28   (zVal = va_arg(
5c80: 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29  ap, char*))!=0 )
5c90: 7b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b  {.    if( zName[
5ca0: 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f  0] ){.      cgi_
5cb0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69  printf("%*s<opti
5cc0: 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25  on value=\"%h\"%
5cd0: 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22  s>%h</option>\n"
5ce0: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20  ,.        in+2, 
5cf0: 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c  "",.        zVal
5d00: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70  ,.        strcmp
5d10: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20  (zVal, zD) ? "" 
5d20: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20  : " selected",. 
5d30: 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20         zName.   
5d40: 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b     );.    }else{
5d50: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74  .      cgi_print
5d60: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61  f("%*s<option va
5d70: 6c 75 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70  lue=\"\"%s>&nbsp
5d80: 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20  ;</option>\n",. 
5d90: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c         in+2, "",
5da0: 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28  .        strcmp(
5db0: 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a  zVal, zD) ? "" :
5dc0: 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20   " selected".   
5dd0: 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a     );.    }.  }.
5de0: 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20    va_end(ap);.  
5df0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c  cgi_printf("%*s<
5e00: 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c  /select>\n", in,
5e10: 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54   "");.}../*.** T
5e20: 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b  his routine work
5e30: 73 20 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69  s a lot like cgi
5e40: 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78  _optionmenu() ex
5e50: 63 65 70 74 20 74 68 61 74 20 74 68 65 20 6c 69  cept that the li
5e60: 73 74 20 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 20  st of.** values 
5e70: 69 73 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20  is contained in 
5e80: 61 6e 20 61 72 72 61 79 2e 20 20 41 6c 73 6f 2c  an array.  Also,
5e90: 20 74 68 65 20 76 61 6c 75 65 73 20 61 72 65 20   the values are 
5ea0: 6a 75 73 74 20 76 61 6c 75 65 73 2c 20 6e 6f 74  just values, not
5eb0: 0a 2a 2a 20 6e 61 6d 65 2f 76 61 6c 75 65 20 70  .** name/value p
5ec0: 61 69 72 73 20 61 73 20 69 6e 20 63 67 69 5f 6f  airs as in cgi_o
5ed0: 70 74 69 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f  ptionmenu..*/.vo
5ee0: 69 64 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d  id cgi_v_optionm
5ef0: 65 6e 75 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20  enu(.  int in,  
5f00: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49              /* I
5f10: 6e 64 65 6e 74 20 62 79 20 74 68 69 73 20 61 6d  ndent by this am
5f20: 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20  ount */.  const 
5f30: 63 68 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f  char *zP,      /
5f40: 2a 20 54 68 65 20 71 75 65 72 79 20 70 61 72 61  * The query para
5f50: 6d 65 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20  meter name */.  
5f60: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20  const char *zD, 
5f70: 20 20 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20       /* Default 
5f80: 76 61 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74  value */.  const
5f90: 20 63 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 20   char **az      
5fa0: 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74  /* NULL-terminat
5fb0: 65 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77  ed list of allow
5fc0: 65 64 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a  ed values */.){.
5fd0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56    const char *zV
5fe0: 61 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63  al;.  int i;.  c
5ff0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73  gi_printf("%*s<s
6000: 65 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d  elect size=1 nam
6010: 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e  e=\"%s\">\n", in
6020: 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72  , "", zP);.  for
6030: 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b  (i=0; az[i]; i++
6040: 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d  ){.    if( strcm
6050: 70 28 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29  p(az[i],zD)==0 )
6060: 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66   break;.  }.  if
6070: 28 20 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20  ( az[i]==0 ){.  
6080: 20 20 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29    if( zD[0]==0 )
6090: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e  {.      cgi_prin
60a0: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76  tf("%*s<option v
60b0: 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74  alue=\"\" select
60c0: 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f  ed>&nbsp;</optio
60d0: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e  n>\n",.       in
60e0: 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c  +2, "");.    }el
60f0: 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72  se{.      cgi_pr
6100: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e  intf("%*s<option
6110: 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65   value=\"%h\" se
6120: 6c 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f  lected>%h</optio
6130: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e  n>\n",.       in
6140: 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b  +2, "", zD, zD);
6150: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69  .    }.  }.  whi
6160: 6c 65 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a  le( (zVal = *(az
6170: 2b 2b 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 20  ++))!=0  ){.    
6180: 69 66 28 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20  if( zVal[0] ){. 
6190: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28       cgi_printf(
61a0: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75  "%*s<option valu
61b0: 65 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f  e=\"%h\"%s>%h</o
61c0: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20  ption>\n",.     
61d0: 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20     in+2, "",.   
61e0: 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20       zVal,.     
61f0: 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20     strcmp(zVal, 
6200: 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c  zD) ? "" : " sel
6210: 65 63 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20  ected",.        
6220: 7a 56 61 6c 0a 20 20 20 20 20 20 29 3b 0a 20 20  zVal.      );.  
6230: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63    }else{.      c
6240: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f  gi_printf("%*s<o
6250: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22  ption value=\"\"
6260: 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f  %s>&nbsp;</optio
6270: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69  n>\n",.        i
6280: 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20  n+2, "",.       
6290: 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44   strcmp(zVal, zD
62a0: 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63  ) ? "" : " selec
62b0: 74 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20  ted".      );.  
62c0: 20 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72    }.  }.  cgi_pr
62d0: 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63  intf("%*s</selec
62e0: 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a  t>\n", in, "");.
62f0: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f  }../*.** This ro
6300: 75 74 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f  utine works a lo
6310: 74 20 6c 69 6b 65 20 63 67 69 5f 76 5f 6f 70 74  t like cgi_v_opt
6320: 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 74  ionmenu() except
6330: 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 0a 2a   that the list.*
6340: 2a 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20 70  * is a list of p
6350: 61 69 72 73 2e 20 20 54 68 65 20 66 69 72 73 74  airs.  The first
6360: 20 65 6c 65 6d 65 6e 74 20 6f 66 20 65 61 63 68   element of each
6370: 20 70 61 69 72 20 69 73 20 74 68 65 20 76 61 6c   pair is the val
6380: 75 65 20 75 73 65 64 0a 2a 2a 20 69 6e 74 65 72  ue used.** inter
6390: 6e 61 6c 6c 79 20 61 6e 64 20 74 68 65 20 73 65  nally and the se
63a0: 63 6f 6e 64 20 65 6c 65 6d 65 6e 74 20 69 73 20  cond element is 
63b0: 74 68 65 20 76 61 6c 75 65 20 64 69 73 70 6c 61  the value displa
63c0: 79 65 64 20 74 6f 20 74 68 65 20 75 73 65 72 2e  yed to the user.
63d0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f  .*/.void cgi_v_o
63e0: 70 74 69 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 6e  ptionmenu2(.  in
63f0: 74 20 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20  t in,           
6400: 20 20 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20     /* Indent by 
6410: 74 68 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20  this amount */. 
6420: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c   const char *zP,
6430: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65        /* The que
6440: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6e 61 6d  ry parameter nam
6450: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61  e */.  const cha
6460: 72 20 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44  r *zD,      /* D
6470: 65 66 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a  efault value */.
6480: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61    const char **a
6490: 7a 20 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74  z      /* NULL-t
64a0: 65 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 6f  erminated list o
64b0: 66 20 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73  f allowed values
64c0: 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63   */.){.  const c
64d0: 68 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74  har *zVal;.  int
64e0: 20 69 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66   i;.  cgi_printf
64f0: 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a  ("%*s<select siz
6500: 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e  e=1 name=\"%s\">
6510: 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29  \n", in, "", zP)
6520: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b  ;.  for(i=0; az[
6530: 69 5d 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20 69  i]; i+=2){.    i
6540: 66 28 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c  f( strcmp(az[i],
6550: 7a 44 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a  zD)==0 ) break;.
6560: 20 20 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d    }.  if( az[i]=
6570: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44  =0 ){.    if( zD
6580: 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20  [0]==0 ){.      
6590: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c  cgi_printf("%*s<
65a0: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c  option value=\"\
65b0: 22 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70  " selected>&nbsp
65c0: 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20  ;</option>\n",. 
65d0: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b        in+2, "");
65e0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20  .    }else{.    
65f0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a    cgi_printf("%*
6600: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c  s<option value=\
6610: 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25  "%h\" selected>%
6620: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20  h</option>\n",. 
6630: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20        in+2, "", 
6640: 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20  zD, zD);.    }. 
6650: 20 7d 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 61   }.  while( (zVa
6660: 6c 20 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20  l = *(az++))!=0 
6670: 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68   ){.    const ch
6680: 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a  ar *zName = *(az
6690: 2b 2b 29 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61  ++);.    if( zNa
66a0: 6d 65 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63  me[0] ){.      c
66b0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f  gi_printf("%*s<o
66c0: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68  ption value=\"%h
66d0: 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e  \"%s>%h</option>
66e0: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b  \n",.        in+
66f0: 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a  2, "",.        z
6700: 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72  Val,.        str
6710: 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20  cmp(zVal, zD) ? 
6720: 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22  "" : " selected"
6730: 2c 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a  ,.        zName.
6740: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c        );.    }el
6750: 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72  se{.      cgi_pr
6760: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e  intf("%*s<option
6770: 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e   value=\"%h\"%s>
6780: 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c  &nbsp;</option>\
6790: 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32  n",.        in+2
67a0: 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56  , "",.        zV
67b0: 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63  al,.        strc
67c0: 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22  mp(zVal, zD) ? "
67d0: 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 0a  " : " selected".
67e0: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20        );.    }. 
67f0: 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28   }.  cgi_printf(
6800: 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22  "%*s</select>\n"
6810: 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a  , in, "");.}../*
6820: 20 0a 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69   .** This functi
6830: 6f 6e 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68  on implements th
6840: 65 20 63 61 6c 6c 62 61 63 6b 20 66 72 6f 6d 20  e callback from 
6850: 76 78 70 72 69 6e 74 66 2e 20 0a 2a 2a 0a 2a 2a  vxprintf. .**.**
6860: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 73 65   This routine se
6870: 6e 64 73 20 6e 4e 65 77 43 68 61 72 20 63 68 61  nds nNewChar cha
6880: 72 61 63 74 65 72 73 20 6f 66 20 74 65 78 74 20  racters of text 
6890: 69 6e 20 7a 4e 65 77 54 65 78 74 20 74 6f 0a 2a  in zNewText to.*
68a0: 2a 20 43 47 49 20 72 65 70 6c 79 20 63 6f 6e 74  * CGI reply cont
68b0: 65 6e 74 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73  ent buffer..*/.s
68c0: 74 61 74 69 63 20 76 6f 69 64 20 73 6f 75 74 28  tatic void sout(
68d0: 76 6f 69 64 20 2a 4e 6f 74 55 73 65 64 2c 20 63  void *NotUsed, c
68e0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 65 77 54  onst char *zNewT
68f0: 65 78 74 2c 20 69 6e 74 20 6e 4e 65 77 43 68 61  ext, int nNewCha
6900: 72 29 7b 0a 20 20 63 67 69 5f 61 70 70 65 6e 64  r){.  cgi_append
6910: 5f 63 6f 6e 74 65 6e 74 28 7a 4e 65 77 54 65 78  _content(zNewTex
6920: 74 2c 20 6e 4e 65 77 43 68 61 72 29 3b 0a 7d 0a  t, nNewChar);.}.
6930: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74  ./*.** This rout
6940: 69 6e 65 20 77 6f 72 6b 73 20 6c 69 6b 65 20 22  ine works like "
6950: 70 72 69 6e 74 66 22 20 65 78 63 65 70 74 20 74  printf" except t
6960: 68 61 74 20 69 74 20 68 61 73 20 74 68 65 0a 2a  hat it has the.*
6970: 2a 20 65 78 74 72 61 20 66 6f 72 6d 61 74 74 69  * extra formatti
6980: 6e 67 20 63 61 70 61 62 69 6c 69 74 69 65 73 20  ng capabilities 
6990: 73 75 63 68 20 61 73 20 25 68 20 61 6e 64 20 25  such as %h and %
69a0: 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70  t..*/.void cgi_p
69b0: 72 69 6e 74 66 28 63 6f 6e 73 74 20 63 68 61 72  rintf(const char
69c0: 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b   *zFormat, ...){
69d0: 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20  .  va_list ap;. 
69e0: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 7a 46 6f   va_start(ap,zFo
69f0: 72 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74  rmat);.  vxprint
6a00: 66 28 73 6f 75 74 2c 30 2c 7a 46 6f 72 6d 61 74  f(sout,0,zFormat
6a10: 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61  ,ap);.  va_end(a
6a20: 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69  p);.}../*.** Thi
6a30: 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20  s routine works 
6a40: 6c 69 6b 65 20 22 76 70 72 69 6e 74 66 22 20 65  like "vprintf" e
6a50: 78 63 65 70 74 20 74 68 61 74 20 69 74 20 68 61  xcept that it ha
6a60: 73 20 74 68 65 0a 2a 2a 20 65 78 74 72 61 20 66  s the.** extra f
6a70: 6f 72 6d 61 74 74 69 6e 67 20 63 61 70 61 62 69  ormatting capabi
6a80: 6c 69 74 69 65 73 20 73 75 63 68 20 61 73 20 25  lities such as %
6a90: 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69  h and %t..*/.voi
6aa0: 64 20 63 67 69 5f 76 70 72 69 6e 74 66 28 63 6f  d cgi_vprintf(co
6ab0: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61  nst char *zForma
6ac0: 74 2c 20 76 61 5f 6c 69 73 74 20 61 70 29 7b 0a  t, va_list ap){.
6ad0: 20 20 76 78 70 72 69 6e 74 66 28 73 6f 75 74 2c    vxprintf(sout,
6ae0: 30 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 7d  0,zFormat,ap);.}
6af0: 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20  .../*.** Send a 
6b00: 72 65 70 6c 79 20 69 6e 64 69 63 61 74 69 6e 67  reply indicating
6b10: 20 74 68 61 74 20 74 68 65 20 48 54 54 50 20 72   that the HTTP r
6b20: 65 71 75 65 73 74 20 77 61 73 20 6d 61 6c 66 6f  equest was malfo
6b30: 72 6d 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 76  rmed.*/.static v
6b40: 6f 69 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65  oid malformed_re
6b50: 71 75 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 63  quest(void){.  c
6b60: 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 35 30  gi_set_status(50
6b70: 31 2c 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e  1, "Not Implemen
6b80: 74 65 64 22 29 3b 0a 20 20 63 67 69 5f 70 72 69  ted");.  cgi_pri
6b90: 6e 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e  ntf(.    "<html>
6ba0: 3c 62 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69 7a  <body>Unrecogniz
6bb0: 65 64 20 48 54 54 50 20 52 65 71 75 65 73 74 3c  ed HTTP Request<
6bc0: 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e 22  /body></html>\n"
6bd0: 0a 20 20 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c  .  );.  cgi_repl
6be0: 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a  y();.  exit(0);.
6bf0: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 61  }../*.** Panic a
6c00: 6e 64 20 64 69 65 20 77 68 69 6c 65 20 70 72 6f  nd die while pro
6c10: 63 65 73 73 69 6e 67 20 61 20 77 65 62 70 61 67  cessing a webpag
6c20: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70  e..*/.void cgi_p
6c30: 61 6e 69 63 28 63 6f 6e 73 74 20 63 68 61 72 20  anic(const char 
6c40: 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a  *zFormat, ...){.
6c50: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20    va_list ap;.  
6c60: 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e  cgi_reset_conten
6c70: 74 28 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73  t();.  cgi_set_s
6c80: 74 61 74 75 73 28 35 30 30 2c 20 22 49 6e 74 65  tatus(500, "Inte
6c90: 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f  rnal Server Erro
6ca0: 72 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74  r");.  cgi_print
6cb0: 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62  f(.    "<html><b
6cc0: 6f 64 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 6c  ody><h1>Internal
6cd0: 20 53 65 72 76 65 72 20 45 72 72 6f 72 3c 2f 68   Server Error</h
6ce0: 31 3e 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61 69  1>\n".    "<plai
6cf0: 6e 74 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20 76  ntext>".  );.  v
6d00: 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72  a_start(ap, zFor
6d10: 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66  mat);.  vxprintf
6d20: 28 73 6f 75 74 2c 30 2c 7a 46 6f 72 6d 61 74 2c  (sout,0,zFormat,
6d30: 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70  ap);.  va_end(ap
6d40: 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29  );.  cgi_reply()
6d50: 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a 0a  ;.  exit(1);.}..
6d60: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65  /*.** Remove the
6d70: 20 66 69 72 73 74 20 73 70 61 63 65 2d 64 65 6c   first space-del
6d80: 69 6d 69 74 65 64 20 74 6f 6b 65 6e 20 66 72 6f  imited token fro
6d90: 6d 20 61 20 73 74 72 69 6e 67 20 61 6e 64 20 72  m a string and r
6da0: 65 74 75 72 6e 0a 2a 2a 20 61 20 70 6f 69 6e 74  eturn.** a point
6db0: 65 72 20 74 6f 20 69 74 2e 20 20 41 64 64 20 61  er to it.  Add a
6dc0: 20 4e 55 4c 4c 20 74 6f 20 74 68 65 20 73 74 72   NULL to the str
6dd0: 69 6e 67 20 74 6f 20 74 65 72 6d 69 6e 61 74 65  ing to terminate
6de0: 20 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 4d   the token..** M
6df0: 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 72 20 70  ake *zLeftOver p
6e00: 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72  oint to the star
6e10: 74 20 6f 66 20 74 68 65 20 6e 65 78 74 20 74 6f  t of the next to
6e20: 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63  ken..*/.static c
6e30: 68 61 72 20 2a 65 78 74 72 61 63 74 5f 74 6f 6b  har *extract_tok
6e40: 65 6e 28 63 68 61 72 20 2a 7a 49 6e 70 75 74 2c  en(char *zInput,
6e50: 20 63 68 61 72 20 2a 2a 7a 4c 65 66 74 4f 76 65   char **zLeftOve
6e60: 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65 73  r){.  char *zRes
6e70: 75 6c 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 7a  ult = 0;.  if( z
6e80: 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20 20  Input==0 ){.    
6e90: 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 20 29 20  if( zLeftOver ) 
6ea0: 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 30 3b 0a  *zLeftOver = 0;.
6eb0: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20      return 0;.  
6ec0: 7d 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70 61  }.  while( isspa
6ed0: 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a  ce(*zInput) ){ z
6ee0: 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a 52 65  Input++; }.  zRe
6ef0: 73 75 6c 74 20 3d 20 7a 49 6e 70 75 74 3b 0a 20  sult = zInput;. 
6f00: 20 77 68 69 6c 65 28 20 2a 7a 49 6e 70 75 74 20   while( *zInput 
6f10: 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a 49 6e  && !isspace(*zIn
6f20: 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b  put) ){ zInput++
6f30: 3b 20 7d 0a 20 20 69 66 28 20 2a 7a 49 6e 70 75  ; }.  if( *zInpu
6f40: 74 20 29 7b 0a 20 20 20 20 2a 7a 49 6e 70 75 74  t ){.    *zInput
6f50: 20 3d 20 30 3b 0a 20 20 20 20 7a 49 6e 70 75 74   = 0;.    zInput
6f60: 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69  ++;.    while( i
6f70: 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20  sspace(*zInput) 
6f80: 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20  ){ zInput++; }. 
6f90: 20 7d 0a 20 20 69 66 28 20 7a 4c 65 66 74 4f 76   }.  if( zLeftOv
6fa0: 65 72 20 29 7b 20 2a 7a 4c 65 66 74 4f 76 65 72  er ){ *zLeftOver
6fb0: 20 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a 20 20 72   = zInput; }.  r
6fc0: 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a 7d  eturn zResult;.}
6fd0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75  ../*.** This rou
6fe0: 74 69 6e 65 20 68 61 6e 64 6c 65 73 20 61 20 73  tine handles a s
6ff0: 69 6e 67 6c 65 20 48 54 54 50 20 72 65 71 75 65  ingle HTTP reque
7000: 73 74 20 77 68 69 63 68 20 69 73 20 63 6f 6d 69  st which is comi
7010: 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74 61 6e  ng in on.** stan
7020: 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20 77  dard input and w
7030: 68 69 63 68 20 72 65 70 6c 69 65 73 20 6f 6e 20  hich replies on 
7040: 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e  standard output.
7050: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 54 50 20  .**.** The HTTP 
7060: 72 65 71 75 65 73 74 20 69 73 20 72 65 61 64 20  request is read 
7070: 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 20 69 6e  from standard in
7080: 70 75 74 20 61 6e 64 20 69 73 20 75 73 65 64 20  put and is used 
7090: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 0a 2a 2a  to initialize.**
70a0: 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72   environment var
70b0: 69 61 62 6c 65 73 20 61 73 20 70 65 72 20 43 47  iables as per CG
70c0: 49 2e 20 20 54 68 65 20 63 67 69 5f 69 6e 69 74  I.  The cgi_init
70d0: 28 29 20 72 6f 75 74 69 6e 65 20 74 6f 20 63 6f  () routine to co
70e0: 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 65 20 73 65  mplete.** the se
70f0: 74 75 70 2e 20 20 4f 6e 63 65 20 61 6c 6c 20 74  tup.  Once all t
7100: 68 65 20 73 65 74 75 70 20 69 73 20 66 69 6e 69  he setup is fini
7110: 73 68 65 64 2c 20 74 68 69 73 20 70 72 6f 63 65  shed, this proce
7120: 64 75 72 65 20 72 65 74 75 72 6e 73 0a 2a 2a 20  dure returns.** 
7130: 61 6e 64 20 73 75 62 73 65 71 75 65 6e 74 20 63  and subsequent c
7140: 6f 64 65 20 68 61 6e 64 6c 65 73 20 74 68 65 20  ode handles the 
7150: 61 63 74 75 61 6c 20 67 65 6e 65 72 61 74 69 6f  actual generatio
7160: 6e 20 6f 66 20 74 68 65 20 77 65 62 70 61 67 65  n of the webpage
7170: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 61  ..*/.void cgi_ha
7180: 6e 64 6c 65 5f 68 74 74 70 5f 72 65 71 75 65 73  ndle_http_reques
7190: 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 72 20  t(void){.  char 
71a0: 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 20 69  *z, *zToken;.  i
71b0: 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 74 20 73  nt i;.  struct s
71c0: 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 6d 6f 74  ockaddr_in remot
71d0: 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 5f 74 20  eName;.  size_t 
71e0: 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 28 73 74  size = sizeof(st
71f0: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e  ruct sockaddr_in
7200: 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 6e 65 5b  );.  char zLine[
7210: 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a 20 41 20  2000];     /* A 
7220: 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 69  single line of i
7230: 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 66 75 6c 6c  nput. */..  full
7240: 48 74 74 70 52 65 70 6c 79 20 3d 20 31 3b 0a 20  HttpReply = 1;. 
7250: 20 69 66 28 20 66 67 65 74 73 28 7a 4c 69 6e 65   if( fgets(zLine
7260: 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c  , sizeof(zLine),
7270: 20 73 74 64 69 6e 29 3d 3d 30 20 29 7b 0a 20 20   stdin)==0 ){.  
7280: 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75    malformed_requ
7290: 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 7a 54 6f  est();.  }.  zTo
72a0: 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 5f 74 6f  ken = extract_to
72b0: 6b 65 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29 3b 0a  ken(zLine, &z);.
72c0: 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 20    if( zToken==0 
72d0: 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64  ){.    malformed
72e0: 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a  _request();.  }.
72f0: 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54 6f    if( strcmp(zTo
7300: 6b 65 6e 2c 22 47 45 54 22 29 21 3d 30 20 26 26  ken,"GET")!=0 &&
7310: 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22   strcmp(zToken,"
7320: 50 4f 53 54 22 29 21 3d 30 0a 20 20 20 20 20 20  POST")!=0.      
7330: 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e  && strcmp(zToken
7340: 2c 22 48 45 41 44 22 29 21 3d 30 20 29 7b 0a 20  ,"HEAD")!=0 ){. 
7350: 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71     malformed_req
7360: 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 63 67  uest();.  }.  cg
7370: 69 5f 73 65 74 65 6e 76 28 22 47 41 54 45 57 41  i_setenv("GATEWA
7380: 59 5f 49 4e 54 45 52 46 41 43 45 22 2c 22 43 47  Y_INTERFACE","CG
7390: 49 2f 31 2e 30 22 29 3b 0a 20 20 63 67 69 5f 73  I/1.0");.  cgi_s
73a0: 65 74 65 6e 76 28 22 52 45 51 55 45 53 54 5f 4d  etenv("REQUEST_M
73b0: 45 54 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29 3b 0a  ETHOD",zToken);.
73c0: 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61    zToken = extra
73d0: 63 74 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a 29 3b  ct_token(z, &z);
73e0: 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30  .  if( zToken==0
73f0: 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65   ){.    malforme
7400: 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d  d_request();.  }
7410: 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52  .  cgi_setenv("R
7420: 45 51 55 45 53 54 5f 55 52 49 22 2c 20 7a 54 6f  EQUEST_URI", zTo
7430: 6b 65 6e 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b  ken);.  for(i=0;
7440: 20 7a 54 6f 6b 65 6e 5b 69 5d 20 26 26 20 7a 54   zToken[i] && zT
7450: 6f 6b 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20 69 2b  oken[i]!='?'; i+
7460: 2b 29 7b 7d 0a 20 20 69 66 28 20 7a 54 6f 6b 65  +){}.  if( zToke
7470: 6e 5b 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b 69 2b  n[i] ) zToken[i+
7480: 2b 5d 20 3d 20 30 3b 0a 20 20 63 67 69 5f 73 65  +] = 0;.  cgi_se
7490: 74 65 6e 76 28 22 50 41 54 48 5f 49 4e 46 4f 22  tenv("PATH_INFO"
74a0: 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63 67 69  , zToken);.  cgi
74b0: 5f 73 65 74 65 6e 76 28 22 51 55 45 52 59 5f 53  _setenv("QUERY_S
74c0: 54 52 49 4e 47 22 2c 20 26 7a 54 6f 6b 65 6e 5b  TRING", &zToken[
74d0: 69 5d 29 3b 0a 20 20 69 66 28 20 67 65 74 70 65  i]);.  if( getpe
74e0: 65 72 6e 61 6d 65 28 66 69 6c 65 6e 6f 28 73 74  ername(fileno(st
74f0: 64 69 6e 29 2c 20 28 73 74 72 75 63 74 20 73 6f  din), (struct so
7500: 63 6b 61 64 64 72 2a 29 26 72 65 6d 6f 74 65 4e  ckaddr*)&remoteN
7510: 61 6d 65 2c 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a  ame, (socklen_t*
7520: 29 26 73 69 7a 65 29 3e 3d 30 20 29 7b 0a 20 20  )&size)>=0 ){.  
7530: 20 20 63 68 61 72 20 2a 7a 49 70 41 64 64 72 20    char *zIpAddr 
7540: 3d 20 69 6e 65 74 5f 6e 74 6f 61 28 72 65 6d 6f  = inet_ntoa(remo
7550: 74 65 4e 61 6d 65 2e 73 69 6e 5f 61 64 64 72 29  teName.sin_addr)
7560: 3b 0a 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76  ;.    cgi_setenv
7570: 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 22 2c 20  ("REMOTE_ADDR", 
7580: 7a 49 70 41 64 64 72 29 3b 0a 0a 20 20 20 20 2f  zIpAddr);..    /
7590: 2a 20 53 65 74 20 74 68 65 20 47 6c 6f 62 61 6c  * Set the Global
75a0: 2e 7a 49 70 41 64 64 72 20 76 61 72 69 61 62 6c  .zIpAddr variabl
75b0: 65 20 74 6f 20 74 68 65 20 73 65 72 76 65 72 20  e to the server 
75c0: 77 65 20 61 72 65 20 74 61 6c 6b 69 6e 67 20 74  we are talking t
75d0: 6f 2e 0a 20 20 20 20 2a 2a 20 54 68 69 73 20 69  o..    ** This i
75e0: 73 20 75 73 65 64 20 74 6f 20 70 6f 70 75 6c 61  s used to popula
75f0: 74 65 20 74 68 65 20 69 70 61 64 64 72 20 63 6f  te the ipaddr co
7600: 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 63 76 66  lumn of the rcvf
7610: 72 6f 6d 20 74 61 62 6c 65 2c 0a 20 20 20 20 2a  rom table,.    *
7620: 2a 20 69 66 20 61 6e 79 20 66 69 6c 65 73 20 61  * if any files a
7630: 72 65 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d  re received from
7640: 20 74 68 65 20 63 6f 6e 6e 65 63 74 65 64 20 63   the connected c
7650: 6c 69 65 6e 74 2e 0a 20 20 20 20 2a 2f 0a 20 20  lient..    */.  
7660: 20 20 67 2e 7a 49 70 41 64 64 72 20 3d 20 6d 70    g.zIpAddr = mp
7670: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 49 70 41  rintf("%s", zIpA
7680: 64 64 72 29 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a  ddr);.  }. .  /*
7690: 20 47 65 74 20 61 6c 6c 20 74 68 65 20 6f 70 74   Get all the opt
76a0: 69 6f 6e 61 6c 20 66 69 65 6c 64 73 20 74 68 61  ional fields tha
76b0: 74 20 66 6f 6c 6c 6f 77 20 74 68 65 20 66 69 72  t follow the fir
76c0: 73 74 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20  st line..  */.  
76d0: 77 68 69 6c 65 28 20 66 67 65 74 73 28 7a 4c 69  while( fgets(zLi
76e0: 6e 65 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29  ne,sizeof(zLine)
76f0: 2c 73 74 64 69 6e 29 20 29 7b 0a 20 20 20 20 63  ,stdin) ){.    c
7700: 68 61 72 20 2a 7a 46 69 65 6c 64 4e 61 6d 65 3b  har *zFieldName;
7710: 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 3b  .    char *zVal;
7720: 0a 0a 20 20 20 20 7a 46 69 65 6c 64 4e 61 6d 65  ..    zFieldName
7730: 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e   = extract_token
7740: 28 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b 0a 20  (zLine,&zVal);. 
7750: 20 20 20 69 66 28 20 7a 46 69 65 6c 64 4e 61 6d     if( zFieldNam
7760: 65 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c 64 4e  e==0 || *zFieldN
7770: 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a  ame==0 ) break;.
7780: 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61      while( isspa
7790: 63 65 28 2a 7a 56 61 6c 29 20 29 7b 20 7a 56 61  ce(*zVal) ){ zVa
77a0: 6c 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 3d 20 73  l++; }.    i = s
77b0: 74 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20 20 20  trlen(zVal);.   
77c0: 20 77 68 69 6c 65 28 20 69 3e 30 20 26 26 20 69   while( i>0 && i
77d0: 73 73 70 61 63 65 28 7a 56 61 6c 5b 69 2d 31 5d  sspace(zVal[i-1]
77e0: 29 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20 20 20  ) ){ i--; }.    
77f0: 7a 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 20 20  zVal[i] = 0;.   
7800: 20 66 6f 72 28 69 3d 30 3b 20 7a 46 69 65 6c 64   for(i=0; zField
7810: 4e 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b 20 7a  Name[i]; i++){ z
7820: 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d 20 74  FieldName[i] = t
7830: 6f 6c 6f 77 65 72 28 7a 46 69 65 6c 64 4e 61 6d  olower(zFieldNam
7840: 65 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 69 66 28  e[i]); }.    if(
7850: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61   strcmp(zFieldNa
7860: 6d 65 2c 22 75 73 65 72 2d 61 67 65 6e 74 3a 22  me,"user-agent:"
7870: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67  )==0 ){.      cg
7880: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 55  i_setenv("HTTP_U
7890: 53 45 52 5f 41 47 45 4e 54 22 2c 20 7a 56 61 6c  SER_AGENT", zVal
78a0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
78b0: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61   strcmp(zFieldNa
78c0: 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65 6e 67  me,"content-leng
78d0: 74 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20  th:")==0 ){.    
78e0: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f    cgi_setenv("CO
78f0: 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 7a  NTENT_LENGTH", z
7900: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20  Val);.    }else 
7910: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c  if( strcmp(zFiel
7920: 64 4e 61 6d 65 2c 22 72 65 66 65 72 65 72 3a 22  dName,"referer:"
7930: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67  )==0 ){.      cg
7940: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 52  i_setenv("HTTP_R
7950: 45 46 45 52 45 52 22 2c 20 7a 56 61 6c 29 3b 0a  EFERER", zVal);.
7960: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74      }else if( st
7970: 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c  rcmp(zFieldName,
7980: 22 68 6f 73 74 3a 22 29 3d 3d 30 20 29 7b 0a 20  "host:")==0 ){. 
7990: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28       cgi_setenv(
79a0: 22 48 54 54 50 5f 48 4f 53 54 22 2c 20 7a 56 61  "HTTP_HOST", zVa
79b0: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66  l);.    }else if
79c0: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e  ( strcmp(zFieldN
79d0: 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70  ame,"content-typ
79e0: 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20  e:")==0 ){.     
79f0: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f 4e   cgi_setenv("CON
7a00: 54 45 4e 54 5f 54 59 50 45 22 2c 20 7a 56 61 6c  TENT_TYPE", zVal
7a10: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28  );.    }else if(
7a20: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61   strcmp(zFieldNa
7a30: 6d 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d 3d 30  me,"cookie:")==0
7a40: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65   ){.      cgi_se
7a50: 74 65 6e 76 28 22 48 54 54 50 5f 43 4f 4f 4b 49  tenv("HTTP_COOKI
7a60: 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d  E", zVal);.    }
7a70: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28  else if( strcmp(
7a80: 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d 6e  zFieldName,"if-n
7a90: 6f 6e 65 2d 6d 61 74 63 68 3a 22 29 3d 3d 30 20  one-match:")==0 
7aa0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74  ){.      cgi_set
7ab0: 65 6e 76 28 22 48 54 54 50 5f 49 46 5f 4e 4f 4e  env("HTTP_IF_NON
7ac0: 45 5f 4d 41 54 43 48 22 2c 20 7a 56 61 6c 29 3b  E_MATCH", zVal);
7ad0: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73  .    }else if( s
7ae0: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65  trcmp(zFieldName
7af0: 2c 22 69 66 2d 6d 6f 64 69 66 69 65 64 2d 73 69  ,"if-modified-si
7b00: 6e 63 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20  nce:")==0 ){.   
7b10: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48     cgi_setenv("H
7b20: 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f  TTP_IF_MODIFIED_
7b30: 53 49 4e 43 45 22 2c 20 7a 56 61 6c 29 3b 0a 20  SINCE", zVal);. 
7b40: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 67 69 5f     }.  }..  cgi_
7b50: 69 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  init();.}../*.**
7b60: 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20   Maximum number 
7b70: 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73  of child process
7b80: 65 73 20 74 68 61 74 20 77 65 20 63 61 6e 20 68  es that we can h
7b90: 61 76 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20 61  ave running.** a
7ba0: 74 20 6f 6e 65 20 74 69 6d 65 20 62 65 66 6f 72  t one time befor
7bb0: 65 20 77 65 20 73 74 61 72 74 20 73 6c 6f 77 69  e we start slowi
7bc0: 6e 67 20 74 68 69 6e 67 73 20 64 6f 77 6e 2e 0a  ng things down..
7bd0: 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 41 58 5f 50  */.#define MAX_P
7be0: 41 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a 2a 2a  ARALLEL 2../*.**
7bf0: 20 49 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 48 54   Implement an HT
7c00: 54 50 20 73 65 72 76 65 72 20 64 61 65 6d 6f 6e  TP server daemon
7c10: 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20 70 6f   listening on po
7c20: 72 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20  rt iPort..**.** 
7c30: 41 73 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f  As new connectio
7c40: 6e 73 20 61 72 72 69 76 65 2c 20 66 6f 72 6b 20  ns arrive, fork 
7c50: 61 20 63 68 69 6c 64 20 61 6e 64 20 6c 65 74 20  a child and let 
7c60: 63 68 69 6c 64 20 72 65 74 75 72 6e 0a 2a 2a 20  child return.** 
7c70: 6f 75 74 20 6f 66 20 74 68 69 73 20 70 72 6f 63  out of this proc
7c80: 65 64 75 72 65 20 63 61 6c 6c 2e 20 20 54 68 65  edure call.  The
7c90: 20 63 68 69 6c 64 20 77 69 6c 6c 20 68 61 6e 64   child will hand
7ca0: 6c 65 20 74 68 65 20 72 65 71 75 65 73 74 2e 0a  le the request..
7cb0: 2a 2a 20 54 68 65 20 70 61 72 65 6e 74 20 6e 65  ** The parent ne
7cc0: 76 65 72 20 72 65 74 75 72 6e 73 20 66 72 6f 6d  ver returns from
7cd0: 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 2e   this procedure.
7ce0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 74 74  .*/.void cgi_htt
7cf0: 70 5f 73 65 72 76 65 72 28 69 6e 74 20 69 50 6f  p_server(int iPo
7d00: 72 74 29 7b 0a 23 69 66 64 65 66 20 5f 5f 4d 49  rt){.#ifdef __MI
7d10: 4e 47 57 33 32 5f 5f 0a 20 20 66 70 72 69 6e 74  NGW32__.  fprint
7d20: 66 28 73 74 64 65 72 72 2c 22 73 65 72 76 65 72  f(stderr,"server
7d30: 20 6e 6f 74 20 79 65 74 20 61 76 61 69 6c 61 62   not yet availab
7d40: 6c 65 20 69 6e 20 77 69 6e 64 6f 77 73 20 76 65  le in windows ve
7d50: 72 73 69 6f 6e 20 6f 66 20 66 6f 73 73 69 6c 5c  rsion of fossil\
7d60: 6e 22 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a  n");.  exit(1);.
7d70: 23 65 6c 73 65 0a 20 20 69 6e 74 20 6c 69 73 74  #else.  int list
7d80: 65 6e 65 72 3b 20 20 20 20 20 20 20 20 20 20 20  ener;           
7d90: 20 20 20 20 20 2f 2a 20 54 68 65 20 73 65 72 76       /* The serv
7da0: 65 72 20 73 6f 63 6b 65 74 20 2a 2f 0a 20 20 69  er socket */.  i
7db0: 6e 74 20 63 6f 6e 6e 65 63 74 69 6f 6e 3b 20 20  nt connection;  
7dc0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41              /* A
7dd0: 20 73 6f 63 6b 65 74 20 66 6f 72 20 65 61 63 68   socket for each
7de0: 20 69 6e 64 69 76 69 64 75 61 6c 20 63 6f 6e 6e   individual conn
7df0: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 64 5f 73  ection */.  fd_s
7e00: 65 74 20 72 65 61 64 66 64 73 3b 20 20 20 20 20  et readfds;     
7e10: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20           /* Set 
7e20: 6f 66 20 66 69 6c 65 20 64 65 73 63 72 69 70 74  of file descript
7e30: 6f 72 73 20 66 6f 72 20 73 65 6c 65 63 74 28 29  ors for select()
7e40: 20 2a 2f 0a 20 20 73 69 7a 65 5f 74 20 6c 65 6e   */.  size_t len
7e50: 61 64 64 72 3b 20 20 20 20 20 20 20 20 20 20 20  addr;           
7e60: 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20     /* Length of 
7e70: 74 68 65 20 69 6e 61 64 64 72 20 73 74 72 75 63  the inaddr struc
7e80: 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20 63 68  ture */.  int ch
7e90: 69 6c 64 3b 20 20 20 20 20 20 20 20 20 20 20 20  ild;            
7ea0: 20 20 20 20 20 20 20 2f 2a 20 50 49 44 20 6f 66         /* PID of
7eb0: 20 74 68 65 20 63 68 69 6c 64 20 70 72 6f 63 65   the child proce
7ec0: 73 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 63 68 69  ss */.  int nchi
7ed0: 6c 64 72 65 6e 20 3d 20 30 3b 20 20 20 20 20 20  ldren = 0;      
7ee0: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f       /* Number o
7ef0: 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 65  f child processe
7f00: 73 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 74 69  s */.  struct ti
7f10: 6d 65 76 61 6c 20 64 65 6c 61 79 3b 20 20 20 20  meval delay;    
7f20: 20 20 20 20 2f 2a 20 48 6f 77 20 6c 6f 6e 67 20      /* How long 
7f30: 74 6f 20 77 61 69 74 20 69 6e 73 69 64 65 20 73  to wait inside s
7f40: 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 73 74 72  elect() */.  str
7f50: 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20  uct sockaddr_in 
7f60: 69 6e 61 64 64 72 3b 20 20 20 2f 2a 20 54 68 65  inaddr;   /* The
7f70: 20 73 6f 63 6b 65 74 20 61 64 64 72 65 73 73 20   socket address 
7f80: 2a 2f 0a 20 20 69 6e 74 20 6f 70 74 20 3d 20 31  */.  int opt = 1
7f90: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  ;               
7fa0: 20 20 2f 2a 20 73 65 74 73 6f 63 6b 6f 70 74 20    /* setsockopt 
7fb0: 66 6c 61 67 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65  flag */..  memse
7fc0: 74 28 26 69 6e 61 64 64 72 2c 20 30 2c 20 73 69  t(&inaddr, 0, si
7fd0: 7a 65 6f 66 28 69 6e 61 64 64 72 29 29 3b 0a 20  zeof(inaddr));. 
7fe0: 20 69 6e 61 64 64 72 2e 73 69 6e 5f 66 61 6d 69   inaddr.sin_fami
7ff0: 6c 79 20 3d 20 41 46 5f 49 4e 45 54 3b 0a 20 20  ly = AF_INET;.  
8000: 69 6e 61 64 64 72 2e 73 69 6e 5f 61 64 64 72 2e  inaddr.sin_addr.
8010: 73 5f 61 64 64 72 20 3d 20 49 4e 41 44 44 52 5f  s_addr = INADDR_
8020: 41 4e 59 3b 0a 20 20 69 6e 61 64 64 72 2e 73 69  ANY;.  inaddr.si
8030: 6e 5f 70 6f 72 74 20 3d 20 68 74 6f 6e 73 28 69  n_port = htons(i
8040: 50 6f 72 74 29 3b 0a 20 20 6c 69 73 74 65 6e 65  Port);.  listene
8050: 72 20 3d 20 73 6f 63 6b 65 74 28 41 46 5f 49 4e  r = socket(AF_IN
8060: 45 54 2c 20 53 4f 43 4b 5f 53 54 52 45 41 4d 2c  ET, SOCK_STREAM,
8070: 20 30 29 3b 0a 20 20 69 66 28 20 6c 69 73 74 65   0);.  if( liste
8080: 6e 65 72 3c 30 20 29 7b 0a 20 20 20 20 66 70 72  ner<0 ){.    fpr
8090: 69 6e 74 66 28 73 74 64 65 72 72 2c 22 43 61 6e  intf(stderr,"Can
80a0: 27 74 20 63 72 65 61 74 65 20 61 20 73 6f 63 6b  't create a sock
80b0: 65 74 5c 6e 22 29 3b 0a 20 20 20 20 65 78 69 74  et\n");.    exit
80c0: 28 31 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 69  (1);.  }..  /* i
80d0: 66 20 77 65 20 63 61 6e 27 74 20 74 65 72 6d 69  f we can't termi
80e0: 6e 61 74 65 20 6e 69 63 65 6c 79 2c 20 61 74 20  nate nicely, at 
80f0: 6c 65 61 73 74 20 61 6c 6c 6f 77 20 74 68 65 20  least allow the 
8100: 73 6f 63 6b 65 74 20 74 6f 20 62 65 20 72 65 75  socket to be reu
8110: 73 65 64 20 2a 2f 0a 20 20 73 65 74 73 6f 63 6b  sed */.  setsock
8120: 6f 70 74 28 6c 69 73 74 65 6e 65 72 2c 53 4f 4c  opt(listener,SOL
8130: 5f 53 4f 43 4b 45 54 2c 53 4f 5f 52 45 55 53 45  _SOCKET,SO_REUSE
8140: 41 44 44 52 2c 26 6f 70 74 2c 73 69 7a 65 6f 66  ADDR,&opt,sizeof
8150: 28 6f 70 74 29 29 3b 0a 0a 20 20 69 66 28 20 62  (opt));..  if( b
8160: 69 6e 64 28 6c 69 73 74 65 6e 65 72 2c 20 28 73  ind(listener, (s
8170: 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29  truct sockaddr*)
8180: 26 69 6e 61 64 64 72 2c 20 73 69 7a 65 6f 66 28  &inaddr, sizeof(
8190: 69 6e 61 64 64 72 29 29 3c 30 20 29 7b 0a 20 20  inaddr))<0 ){.  
81a0: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72    fprintf(stderr
81b0: 2c 22 43 61 6e 27 74 20 62 69 6e 64 20 74 6f 20  ,"Can't bind to 
81c0: 70 6f 72 74 20 25 64 5c 6e 22 2c 20 69 50 6f 72  port %d\n", iPor
81d0: 74 29 3b 0a 20 20 20 20 65 78 69 74 28 31 29 3b  t);.    exit(1);
81e0: 0a 20 20 7d 0a 20 20 6c 69 73 74 65 6e 28 6c 69  .  }.  listen(li
81f0: 73 74 65 6e 65 72 2c 31 30 29 3b 0a 20 20 77 68  stener,10);.  wh
8200: 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 69 66  ile( 1 ){.    if
8210: 28 20 6e 63 68 69 6c 64 72 65 6e 3e 4d 41 58 5f  ( nchildren>MAX_
8220: 50 41 52 41 4c 4c 45 4c 20 29 7b 0a 20 20 20 20  PARALLEL ){.    
8230: 20 20 2f 2a 20 53 6c 6f 77 20 64 6f 77 6e 20 69    /* Slow down i
8240: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72  f connections ar
8250: 65 20 61 72 72 69 76 69 6e 67 20 74 6f 6f 20 66  e arriving too f
8260: 61 73 74 20 2a 2f 0a 20 20 20 20 20 20 73 6c 65  ast */.      sle
8270: 65 70 28 20 6e 63 68 69 6c 64 72 65 6e 2d 4d 41  ep( nchildren-MA
8280: 58 5f 50 41 52 41 4c 4c 45 4c 20 29 3b 0a 20 20  X_PARALLEL );.  
8290: 20 20 7d 0a 20 20 20 20 64 65 6c 61 79 2e 74 76    }.    delay.tv
82a0: 5f 73 65 63 20 3d 20 36 30 3b 0a 20 20 20 20 64  _sec = 60;.    d
82b0: 65 6c 61 79 2e 74 76 5f 75 73 65 63 20 3d 20 30  elay.tv_usec = 0
82c0: 3b 0a 20 20 20 20 46 44 5f 5a 45 52 4f 28 26 72  ;.    FD_ZERO(&r
82d0: 65 61 64 66 64 73 29 3b 0a 20 20 20 20 46 44 5f  eadfds);.    FD_
82e0: 53 45 54 28 20 6c 69 73 74 65 6e 65 72 2c 20 26  SET( listener, &
82f0: 72 65 61 64 66 64 73 29 3b 0a 20 20 20 20 69 66  readfds);.    if
8300: 28 20 73 65 6c 65 63 74 28 20 6c 69 73 74 65 6e  ( select( listen
8310: 65 72 2b 31 2c 20 26 72 65 61 64 66 64 73 2c 20  er+1, &readfds, 
8320: 30 2c 20 30 2c 20 26 64 65 6c 61 79 29 20 29 7b  0, 0, &delay) ){
8330: 0a 20 20 20 20 20 20 6c 65 6e 61 64 64 72 20 3d  .      lenaddr =
8340: 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 3b   sizeof(inaddr);
8350: 0a 20 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f  .      connectio
8360: 6e 20 3d 20 61 63 63 65 70 74 28 6c 69 73 74 65  n = accept(liste
8370: 6e 65 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63  ner, (struct soc
8380: 6b 61 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 20  kaddr*)&inaddr, 
8390: 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 20 26 6c 65  (socklen_t*) &le
83a0: 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20 69 66  naddr);.      if
83b0: 28 20 63 6f 6e 6e 65 63 74 69 6f 6e 3e 3d 30 20  ( connection>=0 
83c0: 29 7b 0a 20 20 20 20 20 20 20 20 63 68 69 6c 64  ){.        child
83d0: 20 3d 20 66 6f 72 6b 28 29 3b 0a 20 20 20 20 20   = fork();.     
83e0: 20 20 20 69 66 28 20 63 68 69 6c 64 21 3d 30 20     if( child!=0 
83f0: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28  ){.          if(
8400: 20 63 68 69 6c 64 3e 30 20 29 20 6e 63 68 69 6c   child>0 ) nchil
8410: 64 72 65 6e 2b 2b 3b 0a 20 20 20 20 20 20 20 20  dren++;.        
8420: 20 20 63 6c 6f 73 65 28 63 6f 6e 6e 65 63 74 69    close(connecti
8430: 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c  on);.        }el
8440: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 63 6c  se{.          cl
8450: 6f 73 65 28 30 29 3b 0a 20 20 20 20 20 20 20 20  ose(0);.        
8460: 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e    dup(connection
8470: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f  );.          clo
8480: 73 65 28 31 29 3b 0a 20 20 20 20 20 20 20 20 20  se(1);.         
8490: 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29   dup(connection)
84a0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20  ;.          if( 
84b0: 21 67 2e 66 48 74 74 70 54 72 61 63 65 20 29 7b  !g.fHttpTrace ){
84c0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 6c 6f  .            clo
84d0: 73 65 28 32 29 3b 0a 20 20 20 20 20 20 20 20 20  se(2);.         
84e0: 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f     dup(connectio
84f0: 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a  n);.          }.
8500: 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28            close(
8510: 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20  connection);.   
8520: 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20         return;. 
8530: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d         }.      }
8540: 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75  .    }.    /* Bu
8550: 72 79 20 64 65 61 64 20 63 68 69 6c 64 72 65 6e  ry dead children
8560: 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 77   */.    while( w
8570: 61 69 74 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f  aitpid(0, 0, WNO
8580: 48 41 4e 47 29 3e 30 20 29 7b 0a 20 20 20 20 20  HANG)>0 ){.     
8590: 20 6e 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20   nchildren--;.  
85a0: 20 20 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54    }.  }.  /* NOT
85b0: 20 52 45 41 43 48 45 44 20 2a 2f 20 20 0a 20 20   REACHED */  .  
85c0: 65 78 69 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a  exit(1);.#endif.
85d0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66  }../*.** Name of
85e0: 20 64 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73   days and months
85f0: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73  ..*/.static cons
8600: 74 20 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d  t char *azDays[]
8610: 20 3d 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22   =.    {"Sun", "
8620: 4d 6f 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65  Mon", "Tue", "We
8630: 64 22 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22  d", "Thu", "Fri"
8640: 2c 20 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61  , "Sat", 0};.sta
8650: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  tic const char *
8660: 61 7a 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20  azMonths[] =.   
8670: 20 7b 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20   {"Jan", "Feb", 
8680: 22 4d 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d  "Mar", "Apr", "M
8690: 61 79 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20  ay", "Jun",.    
86a0: 20 22 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22   "Jul", "Aug", "
86b0: 53 65 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f  Sep", "Oct", "No
86c0: 76 22 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a  v", "Dec", 0};..
86d0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61  ./*.** Returns a
86e0: 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74  n RFC822-formatt
86f0: 65 64 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73  ed time string s
8700: 75 69 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50  uitable for HTTP
8710: 20 68 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a   headers, among.
8720: 2a 2a 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e  ** other things.
8730: 0a 2a 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d  .** Returned tim
8740: 65 7a 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20  ezone is always 
8750: 47 4d 54 20 61 73 20 72 65 71 75 69 72 65 64 20  GMT as required 
8760: 62 79 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63  by HTTP/1.1 spec
8770: 69 66 69 63 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a  ification..**.**
8780: 20 53 65 65 20 68 74 74 70 3a 2f 2f 77 77 77 2e   See http://www.
8790: 66 61 71 73 2e 6f 72 67 2f 72 66 63 73 2f 72 66  faqs.org/rfcs/rf
87a0: 63 38 32 32 2e 68 74 6d 6c 2c 20 73 65 63 74 69  c822.html, secti
87b0: 6f 6e 20 35 0a 2a 2a 20 61 6e 64 20 68 74 74 70  on 5.** and http
87c0: 3a 2f 2f 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f  ://www.faqs.org/
87d0: 72 66 63 73 2f 72 66 63 32 36 31 36 2e 68 74 6d  rfcs/rfc2616.htm
87e0: 6c 2c 20 73 65 63 74 69 6f 6e 20 33 2e 33 2e 0a  l, section 3.3..
87f0: 2a 2f 0a 63 68 61 72 20 2a 63 67 69 5f 72 66 63  */.char *cgi_rfc
8800: 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 74 69  822_datestamp(ti
8810: 6d 65 5f 74 20 6e 6f 77 29 7b 0a 20 20 73 74 72  me_t now){.  str
8820: 75 63 74 20 74 6d 20 2a 70 54 6d 3b 0a 20 20 70  uct tm *pTm;.  p
8830: 54 6d 20 3d 20 67 6d 74 69 6d 65 28 26 6e 6f 77  Tm = gmtime(&now
8840: 29 3b 0a 20 20 69 66 28 20 70 54 6d 3d 3d 30 20  );.  if( pTm==0 
8850: 29 20 72 65 74 75 72 6e 20 22 22 3b 0a 20 20 72  ) return "";.  r
8860: 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 28 22 25  eturn mprintf("%
8870: 73 2c 20 25 64 20 25 73 20 25 30 32 64 20 25 30  s, %d %s %02d %0
8880: 32 64 3a 25 30 32 64 3a 25 30 32 64 20 47 4d 54  2d:%02d:%02d GMT
8890: 22 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20  ",.             
88a0: 20 20 20 20 61 7a 44 61 79 73 5b 70 54 6d 2d 3e      azDays[pTm->
88b0: 74 6d 5f 77 64 61 79 5d 2c 20 70 54 6d 2d 3e 74  tm_wday], pTm->t
88c0: 6d 5f 6d 64 61 79 2c 20 61 7a 4d 6f 6e 74 68 73  m_mday, azMonths
88d0: 5b 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d 2c 0a 20  [pTm->tm_mon],. 
88e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
88f0: 70 54 6d 2d 3e 74 6d 5f 79 65 61 72 2b 31 39 30  pTm->tm_year+190
8900: 30 2c 20 70 54 6d 2d 3e 74 6d 5f 68 6f 75 72 2c  0, pTm->tm_hour,
8910: 20 70 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c 20 70 54   pTm->tm_min, pT
8920: 6d 2d 3e 74 6d 5f 73 65 63 29 3b 0a 7d 0a 0a 2f  m->tm_sec);.}../
8930: 2a 0a 2a 2a 20 50 61 72 73 65 20 61 6e 20 52 46  *.** Parse an RF
8940: 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 64 20 74  C822-formatted t
8950: 69 6d 65 73 74 61 6d 70 20 61 73 20 77 65 27 64  imestamp as we'd
8960: 20 65 78 70 65 63 74 20 66 72 6f 6d 20 48 54 54   expect from HTT
8970: 50 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20  P and return.** 
8980: 61 20 55 6e 69 78 20 65 70 6f 63 68 20 74 69 6d  a Unix epoch tim
8990: 65 2e 20 3c 3d 20 7a 65 72 6f 20 69 73 20 72 65  e. <= zero is re
89a0: 74 75 72 6e 65 64 20 6f 6e 20 66 61 69 6c 75 72  turned on failur
89b0: 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68  e..**.** Note th
89c0: 61 74 20 74 68 69 73 20 77 6f 6e 27 74 20 68 61  at this won't ha
89d0: 6e 64 6c 65 20 61 6c 6c 20 74 68 65 20 5f 61 6c  ndle all the _al
89e0: 6c 6f 77 65 64 5f 20 48 54 54 50 20 66 6f 72 6d  lowed_ HTTP form
89f0: 61 74 73 2c 20 6a 75 73 74 20 74 68 65 0a 2a 2a  ats, just the.**
8a00: 20 6d 6f 73 74 20 70 6f 70 75 6c 61 72 20 6f 6e   most popular on
8a10: 65 20 28 74 68 65 20 6f 6e 65 20 67 65 6e 65 72  e (the one gener
8a20: 61 74 65 64 20 62 79 20 63 67 69 5f 72 66 63 38  ated by cgi_rfc8
8a30: 32 32 5f 64 61 74 65 73 74 61 6d 70 28 29 2c 20  22_datestamp(), 
8a40: 61 63 74 75 61 6c 6c 79 29 2e 0a 2a 2f 0a 74 69  actually)..*/.ti
8a50: 6d 65 5f 74 20 63 67 69 5f 72 66 63 38 32 32 5f  me_t cgi_rfc822_
8a60: 70 61 72 73 65 64 61 74 65 28 63 6f 6e 73 74 20  parsedate(const 
8a70: 63 68 61 72 20 2a 7a 44 61 74 65 29 7b 0a 20 20  char *zDate){.  
8a80: 73 74 72 75 63 74 20 74 6d 20 74 3b 0a 20 20 63  struct tm t;.  c
8a90: 68 61 72 20 7a 49 67 6e 6f 72 65 5b 31 36 5d 3b  har zIgnore[16];
8aa0: 0a 20 20 63 68 61 72 20 7a 4d 6f 6e 74 68 5b 31  .  char zMonth[1
8ab0: 36 5d 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 74  6];..  memset(&t
8ac0: 2c 20 30 2c 20 73 69 7a 65 6f 66 28 74 29 29 3b  , 0, sizeof(t));
8ad0: 0a 20 20 69 66 28 20 37 3d 3d 73 73 63 61 6e 66  .  if( 7==sscanf
8ae0: 28 7a 44 61 74 65 2c 20 22 25 31 32 5b 41 2d 5a  (zDate, "%12[A-Z
8af0: 61 2d 7a 2c 5d 20 25 64 20 25 31 32 5b 41 2d 5a  a-z,] %d %12[A-Z
8b00: 61 2d 7a 5d 20 25 64 20 25 64 3a 25 64 3a 25 64  a-z] %d %d:%d:%d
8b10: 22 2c 20 7a 49 67 6e 6f 72 65 2c 0a 20 20 20 20  ", zIgnore,.    
8b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b30: 20 20 20 26 74 2e 74 6d 5f 6d 64 61 79 2c 20 7a     &t.tm_mday, z
8b40: 4d 6f 6e 74 68 2c 20 26 74 2e 74 6d 5f 79 65 61  Month, &t.tm_yea
8b50: 72 2c 20 26 74 2e 74 6d 5f 68 6f 75 72 2c 20 26  r, &t.tm_hour, &
8b60: 74 2e 74 6d 5f 6d 69 6e 2c 0a 20 20 20 20 20 20  t.tm_min,.      
8b70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
8b80: 20 26 74 2e 74 6d 5f 73 65 63 29 29 7b 0a 0a 20   &t.tm_sec)){.. 
8b90: 20 20 20 69 66 28 20 74 2e 74 6d 5f 79 65 61 72     if( t.tm_year
8ba0: 20 3e 20 31 39 30 30 20 29 20 74 2e 74 6d 5f 79   > 1900 ) t.tm_y
8bb0: 65 61 72 20 2d 3d 20 31 39 30 30 3b 0a 20 20 20  ear -= 1900;.   
8bc0: 20 66 6f 72 28 74 2e 74 6d 5f 6d 6f 6e 3d 30 3b   for(t.tm_mon=0;
8bd0: 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d   azMonths[t.tm_m
8be0: 6f 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e 2b 2b 29  on]; t.tm_mon++)
8bf0: 7b 0a 20 20 20 20 20 20 69 66 28 20 21 73 74 72  {.      if( !str
8c00: 6e 63 61 73 65 63 6d 70 28 20 61 7a 4d 6f 6e 74  ncasecmp( azMont
8c10: 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c 20 7a 4d  hs[t.tm_mon], zM
8c20: 6f 6e 74 68 2c 20 33 20 29 29 7b 0a 20 20 20 20  onth, 3 )){.    
8c30: 20 20 20 20 72 65 74 75 72 6e 20 6d 6b 67 6d 74      return mkgmt
8c40: 69 6d 65 28 26 74 29 3b 0a 20 20 20 20 20 20 7d  ime(&t);.      }
8c50: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65  .    }.  }..  re
8c60: 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a  turn 0;.}../*.**
8c70: 20 43 6f 6e 76 65 72 74 20 61 20 73 74 72 75 63   Convert a struc
8c80: 74 20 74 6d 2a 20 74 68 61 74 20 72 65 70 72 65  t tm* that repre
8c90: 73 65 6e 74 73 20 61 20 6d 6f 6d 65 6e 74 20 69  sents a moment i
8ca0: 6e 20 55 54 43 20 69 6e 74 6f 20 74 68 65 20 6e  n UTC into the n
8cb0: 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 73 65 63 6f  umber.** of seco
8cc0: 6e 64 73 20 69 6e 20 31 39 37 30 2c 20 55 54 43  nds in 1970, UTC
8cd0: 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 6d 6b 67 6d  ..*/.time_t mkgm
8ce0: 74 69 6d 65 28 73 74 72 75 63 74 20 74 6d 20 2a  time(struct tm *
8cf0: 70 29 7b 0a 20 20 74 69 6d 65 5f 74 20 74 3b 0a  p){.  time_t t;.
8d00: 20 20 69 6e 74 20 6e 44 61 79 3b 0a 20 20 69 6e    int nDay;.  in
8d10: 74 20 69 73 4c 65 61 70 59 72 3b 0a 20 20 2f 2a  t isLeapYr;.  /*
8d20: 20 44 61 79 73 20 69 6e 20 65 61 63 68 20 6d 6f   Days in each mo
8d30: 6e 74 68 3a 20 20 20 20 20 20 20 33 31 2c 20 32  nth:       31, 2
8d40: 38 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33  8, 31, 30, 31, 3
8d50: 30 2c 20 33 31 2c 20 33 31 2c 20 33 30 2c 20 33  0, 31, 31, 30, 3
8d60: 31 2c 20 33 30 2c 20 33 31 20 2a 2f 0a 20 20 73  1, 30, 31 */.  s
8d70: 74 61 74 69 63 20 69 6e 74 20 70 72 69 6f 72 44  tatic int priorD
8d80: 61 79 73 5b 5d 20 20 20 3d 20 7b 20 20 30 2c 20  ays[]   = {  0, 
8d90: 33 31 2c 20 35 39 2c 20 39 30 2c 31 32 30 2c 31  31, 59, 90,120,1
8da0: 35 31 2c 31 38 31 2c 32 31 32 2c 32 34 33 2c 32  51,181,212,243,2
8db0: 37 33 2c 33 30 34 2c 33 33 34 20 7d 3b 0a 20 20  73,304,334 };.  
8dc0: 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3c 30 20  if( p->tm_mon<0 
8dd0: 29 7b 0a 20 20 20 20 69 6e 74 20 6e 59 65 61 72  ){.    int nYear
8de0: 20 3d 20 28 31 31 20 2d 20 70 2d 3e 74 6d 5f 6d   = (11 - p->tm_m
8df0: 6f 6e 29 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74  on)/12;.    p->t
8e00: 6d 5f 79 65 61 72 20 2d 3d 20 6e 59 65 61 72 3b  m_year -= nYear;
8e10: 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 20 2b  .    p->tm_mon +
8e20: 3d 20 6e 59 65 61 72 2a 31 32 3b 0a 20 20 7d 65  = nYear*12;.  }e
8e30: 6c 73 65 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f  lse if( p->tm_mo
8e40: 6e 3e 31 31 20 29 7b 0a 20 20 20 20 70 2d 3e 74  n>11 ){.    p->t
8e50: 6d 5f 79 65 61 72 20 2b 3d 20 70 2d 3e 74 6d 5f  m_year += p->tm_
8e60: 6d 6f 6e 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74  mon/12;.    p->t
8e70: 6d 5f 6d 6f 6e 20 25 3d 20 31 32 3b 0a 20 20 7d  m_mon %= 12;.  }
8e80: 0a 20 20 69 73 4c 65 61 70 59 72 20 3d 20 70 2d  .  isLeapYr = p-
8e90: 3e 74 6d 5f 79 65 61 72 25 34 3d 3d 30 20 26 26  >tm_year%4==0 &&
8ea0: 20 28 70 2d 3e 74 6d 5f 79 65 61 72 25 31 30 30   (p->tm_year%100
8eb0: 21 3d 30 20 7c 7c 20 28 70 2d 3e 74 6d 5f 79 65  !=0 || (p->tm_ye
8ec0: 61 72 2b 33 30 30 29 25 34 30 30 3d 3d 30 29 3b  ar+300)%400==0);
8ed0: 0a 20 20 70 2d 3e 74 6d 5f 79 64 61 79 20 3d 20  .  p->tm_yday = 
8ee0: 70 72 69 6f 72 44 61 79 73 5b 70 2d 3e 74 6d 5f  priorDays[p->tm_
8ef0: 6d 6f 6e 5d 20 2b 20 70 2d 3e 74 6d 5f 6d 64 61  mon] + p->tm_mda
8f00: 79 20 2d 20 31 3b 0a 20 20 69 66 28 20 69 73 4c  y - 1;.  if( isL
8f10: 65 61 70 59 72 20 26 26 20 70 2d 3e 74 6d 5f 6d  eapYr && p->tm_m
8f20: 6f 6e 3e 31 20 29 20 70 2d 3e 74 6d 5f 79 64 61  on>1 ) p->tm_yda
8f30: 79 2b 2b 3b 0a 20 20 6e 44 61 79 20 3d 20 28 70  y++;.  nDay = (p
8f40: 2d 3e 74 6d 5f 79 65 61 72 2d 37 30 29 2a 33 36  ->tm_year-70)*36
8f50: 35 20 2b 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d  5 + (p->tm_year-
8f60: 36 39 29 2f 34 20 2d 70 2d 3e 74 6d 5f 79 65 61  69)/4 -p->tm_yea
8f70: 72 2f 31 30 30 20 2b 20 0a 20 20 20 20 20 20 20  r/100 + .       
8f80: 20 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2b 33 30    (p->tm_year+30
8f90: 30 29 2f 34 30 30 20 2b 20 70 2d 3e 74 6d 5f 79  0)/400 + p->tm_y
8fa0: 64 61 79 3b 0a 20 20 74 20 3d 20 28 28 6e 44 61  day;.  t = ((nDa
8fb0: 79 2a 32 34 20 2b 20 70 2d 3e 74 6d 5f 68 6f 75  y*24 + p->tm_hou
8fc0: 72 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 6d 69  r)*60 + p->tm_mi
8fd0: 6e 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 73 65  n)*60 + p->tm_se
8fe0: 63 3b 0a 20 20 72 65 74 75 72 6e 20 74 3b 0a 7d  c;.  return t;.}
8ff0: 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68  ../*.** Check th
9000: 65 20 6f 62 6a 65 63 74 54 69 6d 65 20 61 67 61  e objectTime aga
9010: 69 6e 73 74 20 74 68 65 20 49 66 2d 4d 6f 64 69  inst the If-Modi
9020: 66 69 65 64 2d 53 69 6e 63 65 20 72 65 71 75 65  fied-Since reque
9030: 73 74 20 68 65 61 64 65 72 2e 20 49 66 20 74 68  st header. If th
9040: 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 74 69 6d 65  e.** object time
9050: 20 69 73 6e 27 74 20 61 6e 79 20 6e 65 77 65 72   isn't any newer
9060: 20 74 68 61 6e 20 74 68 65 20 68 65 61 64 65 72   than the header
9070: 2c 20 77 65 20 69 6d 6d 65 64 69 61 74 65 6c 79  , we immediately
9080: 20 73 65 6e 64 20 62 61 63 6b 0a 2a 2a 20 61 20   send back.** a 
9090: 33 30 34 20 72 65 70 6c 79 20 61 6e 64 20 65 78  304 reply and ex
90a0: 69 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f  it..*/.void cgi_
90b0: 6d 6f 64 69 66 69 65 64 5f 73 69 6e 63 65 28 74  modified_since(t
90c0: 69 6d 65 5f 74 20 6f 62 6a 65 63 74 54 69 6d 65  ime_t objectTime
90d0: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20  ){.  const char 
90e0: 2a 7a 49 66 20 3d 20 50 28 22 48 54 54 50 5f 49  *zIf = P("HTTP_I
90f0: 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 4e 43 45  F_MODIFIED_SINCE
9100: 22 29 3b 0a 20 20 69 66 28 20 7a 49 66 3d 3d 30  ");.  if( zIf==0
9110: 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28   ) return;.  if(
9120: 20 6f 62 6a 65 63 74 54 69 6d 65 20 3e 20 63 67   objectTime > cg
9130: 69 5f 72 66 63 38 32 32 5f 70 61 72 73 65 64 61  i_rfc822_parseda
9140: 74 65 28 7a 49 66 29 20 29 20 72 65 74 75 72 6e  te(zIf) ) return
9150: 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74  ;.  cgi_set_stat
9160: 75 73 28 33 30 34 2c 22 4e 6f 74 20 4d 6f 64 69  us(304,"Not Modi
9170: 66 69 65 64 22 29 3b 0a 20 20 63 67 69 5f 72 65  fied");.  cgi_re
9180: 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20  set_content();. 
9190: 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20   cgi_reply();.  
91a0: 65 78 69 74 28 30 29 3b 0a 7d 0a                 exit(0);.}.