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