0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20 /*.** Copyright
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68 (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54 ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66 his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75 u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20 te it and/or.**
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20 modify it under
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65 the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62 GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76 lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65 ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73 s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20 tributed in the
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20 l be useful,.**
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20 but WITHOUT ANY
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75 WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54 * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52 Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55 A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20 RPOSE. See the
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50 GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20 d have received
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63 U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72 g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69 ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65 te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20 ation, Inc., 59
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53 Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73 uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31 ton, MA 02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20 307, USA..**.**
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69 Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20 nformation:.**
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68 * http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 43 20 66 75 6e 63 contains C func
0380: 74 69 6f 6e 73 20 61 6e 64 20 70 72 6f 63 65 64 tions and proced
0390: 75 72 65 73 20 74 68 61 74 20 70 72 6f 76 69 64 ures that provid
03a0: 65 20 75 73 65 66 75 6c 0a 2a 2a 20 73 65 72 76 e useful.** serv
03b0: 69 63 65 73 20 74 6f 20 43 47 49 20 70 72 6f 67 ices to CGI prog
03c0: 72 61 6d 73 2e 20 20 54 68 65 72 65 20 61 72 65 rams. There are
03d0: 20 70 72 6f 63 65 64 75 72 65 73 20 66 6f 72 20 procedures for
03e0: 70 61 72 73 69 6e 67 20 61 6e 64 0a 2a 2a 20 64 parsing and.** d
03f0: 69 73 70 65 6e 73 69 6e 67 20 51 55 45 52 59 5f ispensing QUERY_
0400: 53 54 52 49 4e 47 20 70 61 72 61 6d 65 74 65 72 STRING parameter
0410: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2c 20 74 s and cookies, t
0420: 68 65 20 22 6d 70 72 69 6e 74 66 28 29 22 0a 2a he "mprintf()".*
0430: 2a 20 66 6f 72 6d 61 74 74 69 6e 67 20 66 75 6e * formatting fun
0440: 63 74 69 6f 6e 20 61 6e 64 20 69 74 73 20 63 6f ction and its co
0450: 75 73 69 6e 73 2c 20 61 6e 64 20 72 6f 75 74 69 usins, and routi
0460: 6e 65 73 20 74 6f 20 65 6e 63 6f 64 65 20 61 6e nes to encode an
0470: 64 0a 2a 2a 20 64 65 63 6f 64 65 20 73 74 72 69 d.** decode stri
0480: 6e 67 73 20 69 6e 20 48 54 4d 4c 20 6f 72 20 48 ngs in HTML or H
0490: 54 54 50 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 TTP..*/.#include
04a0: 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 66 64 "config.h".#ifd
04b0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 23 ef __MINGW32__.#
04c0: 20 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e 64 6f include <windo
04d0: 77 73 2e 68 3e 20 20 20 20 20 20 20 20 20 20 20 ws.h>
04e0: 2f 2a 20 66 6f 72 20 53 6c 65 65 70 20 6f 6e 63 /* for Sleep onc
04f0: 65 20 73 65 72 76 65 72 20 77 6f 72 6b 73 20 61 e server works a
0500: 67 61 69 6e 20 2a 2f 0a 23 20 20 69 6e 63 6c 75 gain */.# inclu
0510: 64 65 20 3c 77 69 6e 73 6f 63 6b 32 2e 68 3e 20 de <winsock2.h>
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 6f 63 6b /* sock
0530: 65 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f et operations */
0540: 0a 23 20 20 64 65 66 69 6e 65 20 73 6c 65 65 70 .# define sleep
0550: 20 53 6c 65 65 70 20 20 20 20 20 20 20 20 20 20 Sleep
0560: 20 20 2f 2a 20 77 69 6e 64 6f 77 73 20 64 6f 65 /* windows doe
0570: 73 20 6e 6f 74 20 68 61 76 65 20 73 6c 65 65 70 s not have sleep
0580: 2c 20 62 75 74 20 53 6c 65 65 70 20 2a 2f 0a 23 , but Sleep */.#
0590: 20 20 69 6e 63 6c 75 64 65 20 3c 77 73 32 74 63 include <ws2tc
05a0: 70 69 70 2e 68 3e 20 20 20 20 20 20 20 20 20 20 pip.h>
05b0: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64 .#else.# includ
05c0: 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e e <sys/socket.h>
05d0: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74 .# include <net
05e0: 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e inet/in.h>.# in
05f0: 63 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74 clude <arpa/inet
0600: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c .h>.# include <
0610: 73 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20 sys/times.h>.#
0620: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d include <sys/tim
0630: 65 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 e.h>.# include
0640: 3c 73 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20 <sys/wait.h>.#
0650: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c include <sys/sel
0660: 65 63 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69 ect.h>.#endif.#i
0670: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a nclude <time.h>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e #include <stdio.
0690: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 h>.#include <std
06a0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 lib.h>.#include
06b0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c <unistd.h>.#incl
06c0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66 ude "cgi.h"..#if
06d0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a INTERFACE./*.**
06e0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63 Shortcuts for c
06f0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50 gi_parameter. P
0700: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68 ("x") returns th
0710: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79 e value of query
0720: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72 parameter.** or
0730: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20 cookie "x", or
0740: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 NULL if there is
0750: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74 no such paramet
0760: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50 er or cookie. P
0770: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f D("x","y").** do
0780: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65 es the same exce
0790: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e pt "y" is return
07a0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e ed in place of N
07b0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 ULL if there is
07c0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64 not match..*/.#d
07d0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20 efine P(x)
07e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 cgi_parameter(
07f0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50 (x),0).#define P
0800: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70 D(x,y) cgi_p
0810: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29 arameter((x),(y)
0820: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20 ).#define QP(x)
0830: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73 quotable_s
0840: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65 tring(cgi_parame
0850: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66 ter((x),0)).#def
0860: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20 ine QPD(x,y)
0870: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28 quotable_string(
0880: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78 cgi_parameter((x
0890: 29 2c 28 79 29 29 29 0a 0a 0a 2f 2a 0a 2a 2a 20 ),(y))).../*.**
08a0: 44 65 73 74 69 6e 61 74 69 6f 6e 73 20 66 6f 72 Destinations for
08b0: 20 6f 75 74 70 75 74 20 74 65 78 74 2e 0a 2a 2f output text..*/
08c0: 0a 23 64 65 66 69 6e 65 20 43 47 49 5f 48 45 41 .#define CGI_HEA
08d0: 44 45 52 20 20 20 30 0a 23 64 65 66 69 6e 65 20 DER 0.#define
08e0: 43 47 49 5f 42 4f 44 59 20 20 20 20 20 31 0a 0a CGI_BODY 1..
08f0: 23 65 6e 64 69 66 20 2f 2a 20 49 4e 54 45 52 46 #endif /* INTERF
0900: 41 43 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50 72 ACE */../*.** Pr
0910: 6f 76 69 64 65 20 61 20 72 65 6c 69 61 62 6c 65 ovide a reliable
0920: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 implementation
0930: 6f 66 20 61 20 63 61 73 65 6c 65 73 73 20 73 74 of a caseless st
0940: 72 69 6e 67 20 63 6f 6d 70 61 72 69 73 6f 6e 0a ring comparison.
0950: 2a 2a 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a ** function..*/.
0960: 23 64 65 66 69 6e 65 20 73 74 72 69 63 6d 70 20 #define stricmp
0970: 73 71 6c 69 74 65 33 53 74 72 49 43 6d 70 0a 65 sqlite3StrICmp.e
0980: 78 74 65 72 6e 20 69 6e 74 20 73 71 6c 69 74 65 xtern int sqlite
0990: 33 53 74 72 49 43 6d 70 28 63 6f 6e 73 74 20 63 3StrICmp(const c
09a0: 68 61 72 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 har*, const char
09b0: 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 48 *);../*.** The H
09c0: 54 54 50 20 72 65 70 6c 79 20 69 73 20 67 65 6e TTP reply is gen
09d0: 65 72 61 74 65 64 20 69 6e 20 74 77 6f 20 70 69 erated in two pi
09e0: 65 63 65 73 3a 20 74 68 65 20 68 65 61 64 65 72 eces: the header
09f0: 20 61 6e 64 20 74 68 65 20 62 6f 64 79 2e 0a 2a and the body..*
0a00: 2a 20 54 68 65 73 65 20 70 69 65 63 65 73 20 61 * These pieces a
0a10: 72 65 20 67 65 6e 65 72 61 74 65 64 20 73 65 70 re generated sep
0a20: 61 72 61 74 65 6c 79 20 62 65 63 61 75 73 65 20 arately because
0a30: 74 68 65 79 20 61 72 65 20 6e 6f 74 20 6e 65 63 they are not nec
0a40: 65 73 73 61 72 79 0a 2a 2a 20 70 72 6f 64 75 63 essary.** produc
0a50: 65 64 20 69 6e 20 6f 72 64 65 72 2e 20 20 50 61 ed in order. Pa
0a60: 72 74 73 20 6f 66 20 74 68 65 20 68 65 61 64 65 rts of the heade
0a70: 72 20 6d 69 67 68 74 20 62 65 20 62 75 69 6c 74 r might be built
0a80: 20 61 66 74 65 72 20 61 6c 6c 20 6f 72 0a 2a 2a after all or.**
0a90: 20 70 61 72 74 20 6f 66 20 74 68 65 20 62 6f 64 part of the bod
0aa0: 79 2e 20 20 54 68 65 20 68 65 61 64 65 72 20 61 y. The header a
0ab0: 6e 64 20 62 6f 64 79 20 61 72 65 20 61 63 63 75 nd body are accu
0ac0: 6d 75 6c 61 74 65 64 20 69 6e 20 73 65 70 61 72 mulated in separ
0ad0: 61 74 65 0a 2a 2a 20 42 6c 6f 62 20 73 74 72 75 ate.** Blob stru
0ae0: 63 74 75 72 65 73 20 74 68 65 6e 20 6f 75 74 70 ctures then outp
0af0: 75 74 20 73 65 71 75 65 6e 74 69 61 6c 6c 79 20 ut sequentially
0b00: 6f 6e 63 65 20 65 76 65 72 79 74 68 69 6e 67 20 once everything
0b10: 68 61 73 20 62 65 65 6e 0a 2a 2a 20 62 75 69 6c has been.** buil
0b20: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 67 69 t..**.** The cgi
0b30: 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 29 20 69 _destination() i
0b40: 6e 74 65 72 66 61 63 65 20 73 77 69 74 63 68 20 nterface switch
0b50: 62 65 74 77 65 65 6e 20 74 68 65 20 62 75 66 66 between the buff
0b60: 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42 ers..*/.static B
0b70: 6c 6f 62 20 63 67 69 43 6f 6e 74 65 6e 74 5b 32 lob cgiContent[2
0b80: 5d 20 3d 20 7b 20 42 4c 4f 42 5f 49 4e 49 54 49 ] = { BLOB_INITI
0b90: 41 4c 49 5a 45 52 2c 20 42 4c 4f 42 5f 49 4e 49 ALIZER, BLOB_INI
0ba0: 54 49 41 4c 49 5a 45 52 20 7d 3b 0a 73 74 61 74 TIALIZER };.stat
0bb0: 69 63 20 42 6c 6f 62 20 2a 70 43 6f 6e 74 65 6e ic Blob *pConten
0bc0: 74 20 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b t = &cgiContent[
0bd0: 30 5d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 0];../*.** Set t
0be0: 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 62 he destination b
0bf0: 75 66 66 65 72 20 69 6e 74 6f 20 77 68 69 63 68 uffer into which
0c00: 20 74 6f 20 61 63 63 75 6d 75 6c 61 74 65 20 43 to accumulate C
0c10: 47 49 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76 GI content..*/.v
0c20: 6f 69 64 20 63 67 69 5f 64 65 73 74 69 6e 61 74 oid cgi_destinat
0c30: 69 6f 6e 28 69 6e 74 20 64 65 73 74 29 7b 0a 20 ion(int dest){.
0c40: 20 73 77 69 74 63 68 28 20 64 65 73 74 20 29 7b switch( dest ){
0c50: 0a 20 20 20 20 63 61 73 65 20 43 47 49 5f 48 45 . case CGI_HE
0c60: 41 44 45 52 3a 20 7b 0a 20 20 20 20 20 20 70 43 ADER: {. pC
0c70: 6f 6e 74 65 6e 74 20 3d 20 26 63 67 69 43 6f 6e ontent = &cgiCon
0c80: 74 65 6e 74 5b 30 5d 3b 0a 20 20 20 20 20 20 62 tent[0];. b
0c90: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 reak;. }.
0ca0: 63 61 73 65 20 43 47 49 5f 42 4f 44 59 3a 20 7b case CGI_BODY: {
0cb0: 0a 20 20 20 20 20 20 70 43 6f 6e 74 65 6e 74 20 . pContent
0cc0: 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d = &cgiContent[1]
0cd0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 ;. break;.
0ce0: 20 20 20 7d 0a 20 20 20 20 64 65 66 61 75 6c 74 }. default
0cf0: 3a 20 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 61 : {. cgi_pa
0d00: 6e 69 63 28 22 62 61 64 20 64 65 73 74 69 6e 61 nic("bad destina
0d10: 74 69 6f 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20 tion");. }.
0d20: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e }.}../*.** Appen
0d30: 64 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 d reply content
0d40: 74 6f 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 to what already
0d50: 65 78 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 exists..*/.void
0d60: 63 67 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 cgi_append_conte
0d70: 6e 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a nt(const char *z
0d80: 44 61 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b Data, int nAmt){
0d90: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 . blob_append(p
0da0: 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c 20 Content, zData,
0db0: 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 nAmt);.}../*.**
0dc0: 52 65 73 65 74 20 74 68 65 20 48 54 54 50 20 72 Reset the HTTP r
0dd0: 65 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 20 eply text to be
0de0: 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 2e an empty string.
0df0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 73 .*/.void cgi_res
0e00: 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 29 et_content(void)
0e10: 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 {. blob_reset(&
0e20: 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a cgiContent[0]);.
0e30: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67 blob_reset(&cg
0e40: 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 7d 0a iContent[1]);.}.
0e50: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 ./*.** Return a
0e60: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43 pointer to the C
0e70: 47 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a GI output blob..
0e80: 2a 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74 */.Blob *cgi_out
0e90: 70 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a put_blob(void){.
0ea0: 20 20 72 65 74 75 72 6e 20 70 43 6f 6e 74 65 6e return pConten
0eb0: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 62 t;.}../*.** Comb
0ec0: 69 6e 65 20 74 68 65 20 68 65 61 64 65 72 20 61 ine the header a
0ed0: 6e 64 20 62 6f 64 79 20 6f 66 20 74 68 65 20 43 nd body of the C
0ee0: 47 49 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 GI into a single
0ef0: 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 string..*/.stat
0f00: 69 63 20 76 6f 69 64 20 63 67 69 5f 63 6f 6d 62 ic void cgi_comb
0f10: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 ine_header_and_b
0f20: 6f 64 79 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 ody(void){. int
0f30: 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a size = blob_siz
0f40: 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d e(&cgiContent[1]
0f50: 29 3b 0a 20 20 69 66 28 20 73 69 7a 65 3e 30 20 );. if( size>0
0f60: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 ){. blob_appe
0f70: 6e 64 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 nd(&cgiContent[0
0f80: 5d 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 ], blob_buffer(&
0f90: 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 2c 20 cgiContent[1]),
0fa0: 73 69 7a 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f size);. blob_
0fb0: 72 65 73 65 74 28 26 63 67 69 43 6f 6e 74 65 6e reset(&cgiConten
0fc0: 74 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a t[1]);. }.}../*
0fd0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 .** Return a poi
0fe0: 6e 74 65 72 20 74 6f 20 74 68 65 20 48 54 54 50 nter to the HTTP
0ff0: 20 72 65 70 6c 79 20 74 65 78 74 2e 0a 2a 2f 0a reply text..*/.
1000: 63 68 61 72 20 2a 63 67 69 5f 65 78 74 72 61 63 char *cgi_extrac
1010: 74 5f 63 6f 6e 74 65 6e 74 28 69 6e 74 20 2a 70 t_content(int *p
1020: 6e 41 6d 74 29 7b 0a 20 20 63 67 69 5f 63 6f 6d nAmt){. cgi_com
1030: 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f bine_header_and_
1040: 62 6f 64 79 28 29 3b 0a 20 20 72 65 74 75 72 6e body();. return
1050: 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 blob_buffer(&cg
1060: 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 7d 0a iContent[0]);.}.
1070: 0a 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 ./*.** Additiona
1080: 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73 l information us
1090: 65 64 20 74 6f 20 66 6f 72 6d 20 74 68 65 20 48 ed to form the H
10a0: 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 73 74 61 TTP reply.*/.sta
10b0: 74 69 63 20 63 68 61 72 20 2a 7a 43 6f 6e 74 65 tic char *zConte
10c0: 6e 74 54 79 70 65 20 3d 20 22 74 65 78 74 2f 68 ntType = "text/h
10d0: 74 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 43 6f 6e tml"; /* Con
10e0: 74 65 6e 74 20 74 79 70 65 20 6f 66 20 74 68 65 tent type of the
10f0: 20 72 65 70 6c 79 20 2a 2f 0a 73 74 61 74 69 63 reply */.static
1100: 20 63 68 61 72 20 2a 7a 52 65 70 6c 79 53 74 61 char *zReplySta
1110: 74 75 73 20 3d 20 22 4f 4b 22 3b 20 20 20 20 20 tus = "OK";
1120: 20 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 /* Reply
1130: 73 74 61 74 75 73 20 64 65 73 63 72 69 70 74 69 status descripti
1140: 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 on */.static int
1150: 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 iReplyStatus =
1160: 32 30 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 200;
1170: 20 20 20 2f 2a 20 52 65 70 6c 79 20 73 74 61 74 /* Reply stat
1180: 75 73 20 63 6f 64 65 20 2a 2f 0a 73 74 61 74 69 us code */.stati
1190: 63 20 42 6c 6f 62 20 65 78 74 72 61 48 65 61 64 c Blob extraHead
11a0: 65 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 er = BLOB_INITIA
11b0: 4c 49 5a 45 52 3b 20 20 2f 2a 20 45 78 74 72 61 LIZER; /* Extra
11c0: 20 68 65 61 64 65 72 20 74 65 78 74 20 2a 2f 0a header text */.
11d0: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 ./*.** Set the r
11e0: 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 79 70 eply content typ
11f0: 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 e.*/.void cgi_se
1200: 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65 28 63 t_content_type(c
1210: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 70 65 onst char *zType
1220: 29 7b 0a 20 20 7a 43 6f 6e 74 65 6e 74 54 79 70 ){. zContentTyp
1230: 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 e = mprintf("%s"
1240: 2c 20 7a 54 79 70 65 29 3b 0a 7d 0a 0a 2f 2a 0a , zType);.}../*.
1250: 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 ** Set the reply
1260: 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65 20 content to the
1270: 73 70 65 63 69 66 69 65 64 20 42 4c 4f 42 2e 0a specified BLOB..
1280: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f */.void cgi_set_
1290: 63 6f 6e 74 65 6e 74 28 42 6c 6f 62 20 2a 70 4e content(Blob *pN
12a0: 65 77 43 6f 6e 74 65 6e 74 29 7b 0a 20 20 63 67 ewContent){. cg
12b0: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 i_reset_content(
12c0: 29 3b 0a 20 20 63 67 69 5f 64 65 73 74 69 6e 61 );. cgi_destina
12d0: 74 69 6f 6e 28 43 47 49 5f 48 45 41 44 45 52 29 tion(CGI_HEADER)
12e0: 3b 0a 20 20 63 67 69 43 6f 6e 74 65 6e 74 5b 30 ;. cgiContent[0
12f0: 5d 20 3d 20 2a 70 4e 65 77 43 6f 6e 74 65 6e 74 ] = *pNewContent
1300: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70 4e ;. blob_zero(pN
1310: 65 77 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a 0a 2f ewContent);.}../
1320: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70 *.** Set the rep
1330: 6c 79 20 73 74 61 74 75 73 20 63 6f 64 65 0a 2a ly status code.*
1340: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 73 /.void cgi_set_s
1350: 74 61 74 75 73 28 69 6e 74 20 69 53 74 61 74 2c tatus(int iStat,
1360: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 const char *zSt
1370: 61 74 29 7b 0a 20 20 7a 52 65 70 6c 79 53 74 61 at){. zReplySta
1380: 74 75 73 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 tus = mprintf("%
1390: 73 22 2c 20 7a 53 74 61 74 29 3b 0a 20 20 69 52 s", zStat);. iR
13a0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 69 53 74 eplyStatus = iSt
13b0: 61 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 at;.}../*.** App
13c0: 65 6e 64 20 74 65 78 74 20 74 6f 20 74 68 65 20 end text to the
13d0: 68 65 61 64 65 72 20 6f 66 20 61 6e 20 48 54 54 header of an HTT
13e0: 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 6f 69 64 20 P reply.*/.void
13f0: 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 61 64 65 cgi_append_heade
1400: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4c r(const char *zL
1410: 69 6e 65 29 7b 0a 20 20 62 6c 6f 62 5f 61 70 70 ine){. blob_app
1420: 65 6e 64 28 26 65 78 74 72 61 48 65 61 64 65 72 end(&extraHeader
1430: 2c 20 7a 4c 69 6e 65 2c 20 2d 31 29 3b 0a 7d 0a , zLine, -1);.}.
1440: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 20 63 6f 6f ./*.** Set a coo
1450: 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 5a 65 72 6f 20 kie..**.** Zero
1460: 6c 69 66 65 74 69 6d 65 20 69 6d 70 6c 69 65 73 lifetime implies
1470: 20 61 20 73 65 73 73 69 6f 6e 20 63 6f 6f 6b 69 a session cooki
1480: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 e..*/.void cgi_s
1490: 65 74 5f 63 6f 6f 6b 69 65 28 0a 20 20 63 6f 6e et_cookie(. con
14a0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 st char *zName,
14b0: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 /* Name of th
14c0: 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f e cookie */. co
14d0: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 nst char *zValue
14e0: 2c 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f 66 20 , /* Value of
14f0: 74 68 65 20 63 6f 6f 6b 69 65 2e 20 20 41 75 74 the cookie. Aut
1500: 6f 6d 61 74 69 63 61 6c 6c 79 20 65 73 63 61 70 omatically escap
1510: 65 64 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 ed */. const ch
1520: 61 72 20 2a 7a 50 61 74 68 2c 20 20 20 20 2f 2a ar *zPath, /*
1530: 20 50 61 74 68 20 63 6f 6f 6b 69 65 20 61 70 70 Path cookie app
1540: 6c 69 65 73 20 74 6f 2e 20 20 4e 55 4c 4c 20 6d lies to. NULL m
1550: 65 61 6e 73 20 22 2f 22 20 2a 2f 0a 20 20 69 6e eans "/" */. in
1560: 74 20 6c 69 66 65 74 69 6d 65 20 20 20 20 20 20 t lifetime
1570: 20 20 20 20 2f 2a 20 45 78 70 69 72 61 74 69 6f /* Expiratio
1580: 6e 20 6f 66 20 74 68 65 20 63 6f 6f 6b 69 65 20 n of the cookie
1590: 69 6e 20 73 65 63 6f 6e 64 73 20 66 72 6f 6d 20 in seconds from
15a0: 6e 6f 77 20 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 now */.){. if(
15b0: 7a 50 61 74 68 3d 3d 30 20 29 20 7a 50 61 74 68 zPath==0 ) zPath
15c0: 20 3d 20 67 2e 7a 54 6f 70 3b 0a 20 20 69 66 28 = g.zTop;. if(
15d0: 20 6c 69 66 65 74 69 6d 65 3e 30 20 29 7b 0a 20 lifetime>0 ){.
15e0: 20 20 20 63 68 61 72 20 2a 7a 44 61 74 65 3b 0a char *zDate;.
15f0: 20 20 20 20 6c 69 66 65 74 69 6d 65 20 2b 3d 20 lifetime +=
1600: 28 69 6e 74 29 74 69 6d 65 28 30 29 3b 0a 20 20 (int)time(0);.
1610: 20 20 7a 44 61 74 65 20 3d 20 63 67 69 5f 72 66 zDate = cgi_rf
1620: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 6c c822_datestamp(l
1630: 69 66 65 74 69 6d 65 29 3b 0a 20 20 20 20 62 6c ifetime);. bl
1640: 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 78 74 72 ob_appendf(&extr
1650: 61 48 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 aHeader,.
1660: 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d "Set-Cookie: %s=
1670: 25 74 3b 20 50 61 74 68 3d 25 73 3b 20 65 78 70 %t; Path=%s; exp
1680: 69 72 65 73 3d 25 73 3b 20 56 65 72 73 69 6f 6e ires=%s; Version
1690: 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 =1\r\n",.
16a0: 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 zName, zValue,
16b0: 7a 50 61 74 68 2c 20 7a 44 61 74 65 29 3b 0a 20 zPath, zDate);.
16c0: 20 20 20 69 66 28 20 7a 44 61 74 65 5b 30 5d 20 if( zDate[0]
16d0: 29 20 66 72 65 65 28 20 7a 44 61 74 65 20 29 3b ) free( zDate );
16e0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 62 6c . }else{. bl
16f0: 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 78 74 72 ob_appendf(&extr
1700: 61 48 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 aHeader,.
1710: 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d "Set-Cookie: %s=
1720: 25 74 3b 20 50 61 74 68 3d 25 73 3b 20 56 65 72 %t; Path=%s; Ver
1730: 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20 sion=1\r\n",.
1740: 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 zName, zValu
1750: 65 2c 20 7a 50 61 74 68 29 3b 0a 20 20 7d 0a 7d e, zPath);. }.}
1760: 0a 0a 23 69 66 20 30 0a 2f 2a 0a 2a 2a 20 41 64 ..#if 0./*.** Ad
1770: 64 20 61 6e 20 45 54 61 67 20 68 65 61 64 65 72 d an ETag header
1780: 20 6c 69 6e 65 0a 2a 2f 0a 73 74 61 74 69 63 20 line.*/.static
1790: 63 68 61 72 20 2a 63 67 69 5f 61 64 64 5f 65 74 char *cgi_add_et
17a0: 61 67 28 63 68 61 72 20 2a 7a 54 78 74 2c 20 69 ag(char *zTxt, i
17b0: 6e 74 20 6e 4c 65 6e 29 7b 0a 20 20 4d 44 35 43 nt nLen){. MD5C
17c0: 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20 20 75 6e ontext ctx;. un
17d0: 73 69 67 6e 65 64 20 63 68 61 72 20 64 69 67 65 signed char dige
17e0: 73 74 5b 31 36 5d 3b 0a 20 20 69 6e 74 20 69 2c st[16];. int i,
17f0: 20 6a 3b 0a 20 20 63 68 61 72 20 7a 45 54 61 67 j;. char zETag
1800: 5b 36 34 5d 3b 0a 0a 20 20 4d 44 35 49 6e 69 74 [64];.. MD5Init
1810: 28 26 63 74 78 29 3b 0a 20 20 4d 44 35 55 70 64 (&ctx);. MD5Upd
1820: 61 74 65 28 26 63 74 78 2c 7a 54 78 74 2c 6e 4c ate(&ctx,zTxt,nL
1830: 65 6e 29 3b 0a 20 20 4d 44 35 46 69 6e 61 6c 28 en);. MD5Final(
1840: 64 69 67 65 73 74 2c 26 63 74 78 29 3b 0a 20 20 digest,&ctx);.
1850: 66 6f 72 28 6a 3d 69 3d 30 3b 20 69 3c 31 36 3b for(j=i=0; i<16;
1860: 20 69 2b 2b 2c 6a 2b 3d 32 29 7b 0a 20 20 20 20 i++,j+=2){.
1870: 62 70 72 69 6e 74 66 28 26 7a 45 54 61 67 5b 6a bprintf(&zETag[j
1880: 5d 2c 73 69 7a 65 6f 66 28 7a 45 54 61 67 29 2d ],sizeof(zETag)-
1890: 6a 2c 22 25 30 32 78 22 2c 28 69 6e 74 29 64 69 j,"%02x",(int)di
18a0: 67 65 73 74 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 gest[i]);. }.
18b0: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 78 blob_appendf(&ex
18c0: 74 72 61 48 65 61 64 65 72 2c 20 22 45 54 61 67 traHeader, "ETag
18d0: 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 45 54 61 67 : %s\r\n", zETag
18e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 74 72 64 );. return strd
18f0: 75 70 28 7a 45 54 61 67 29 3b 0a 7d 0a 0a 2f 2a up(zETag);.}../*
1900: 0a 2a 2a 20 44 6f 20 73 6f 6d 65 20 63 61 63 68 .** Do some cach
1910: 65 20 63 6f 6e 74 72 6f 6c 20 73 74 75 66 66 2e e control stuff.
1920: 20 46 69 72 73 74 2c 20 77 65 20 67 65 6e 65 72 First, we gener
1930: 61 74 65 20 61 6e 20 45 54 61 67 20 61 6e 64 20 ate an ETag and
1940: 69 6e 63 6c 75 64 65 20 69 74 20 69 6e 0a 2a 2a include it in.**
1950: 20 74 68 65 20 72 65 73 70 6f 6e 73 65 20 68 65 the response he
1960: 61 64 65 72 73 2e 20 53 65 63 6f 6e 64 2c 20 77 aders. Second, w
1970: 65 20 64 6f 20 77 68 61 74 65 76 65 72 20 69 73 e do whatever is
1980: 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 64 65 necessary to de
1990: 74 65 72 6d 69 6e 65 20 69 66 0a 2a 2a 20 74 68 termine if.** th
19a0: 65 20 72 65 71 75 65 73 74 20 77 61 73 20 61 73 e request was as
19b0: 6b 69 6e 67 20 61 62 6f 75 74 20 63 61 63 68 69 king about cachi
19c0: 6e 67 20 61 6e 64 20 77 68 65 74 68 65 72 20 77 ng and whether w
19d0: 65 20 6e 65 65 64 20 74 6f 20 73 65 6e 64 20 62 e need to send b
19e0: 61 63 6b 20 74 68 65 0a 2a 2a 20 72 65 73 70 6f ack the.** respo
19f0: 6e 73 65 20 62 6f 64 79 2e 20 49 66 20 77 65 20 nse body. If we
1a00: 73 68 6f 75 6c 64 6e 27 74 20 73 65 6e 64 20 61 shouldn't send a
1a10: 20 62 6f 64 79 2c 20 72 65 74 75 72 6e 20 6e 6f body, return no
1a20: 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 43 75 n-zero..**.** Cu
1a30: 72 72 65 6e 74 6c 79 2c 20 77 65 20 6a 75 73 74 rrently, we just
1a40: 20 63 68 65 63 6b 20 74 68 65 20 45 54 61 67 20 check the ETag
1a50: 61 67 61 69 6e 73 74 20 61 6e 79 20 49 66 2d 4e against any If-N
1a60: 6f 6e 65 2d 4d 61 74 63 68 20 68 65 61 64 65 72 one-Match header
1a70: 2e 0a 2a 2a 0a 2a 2a 20 46 49 58 4d 45 3a 20 49 ..**.** FIXME: I
1a80: 6e 20 73 6f 6d 65 20 63 61 73 65 73 20 28 61 74 n some cases (at
1a90: 74 61 63 68 6d 65 6e 74 73 2c 20 66 69 6c 65 20 tachments, file
1aa0: 63 6f 6e 74 65 6e 74 73 29 20 77 65 20 63 6f 75 contents) we cou
1ab0: 6c 64 20 63 68 65 63 6b 0a 2a 2a 20 49 66 2d 4d ld check.** If-M
1ac0: 6f 64 69 66 69 65 64 2d 53 69 6e 63 65 20 68 65 odified-Since he
1ad0: 61 64 65 72 73 20 61 6e 64 20 61 6c 77 61 79 73 aders and always
1ae0: 20 69 6e 63 6c 75 64 65 20 4c 61 73 74 2d 4d 6f include Last-Mo
1af0: 64 69 66 69 65 64 20 69 6e 20 72 65 73 70 6f 6e dified in respon
1b00: 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 ses..*/.static i
1b10: 6e 74 20 63 68 65 63 6b 5f 63 61 63 68 65 5f 63 nt check_cache_c
1b20: 6f 6e 74 72 6f 6c 28 76 6f 69 64 29 7b 0a 20 20 ontrol(void){.
1b30: 2f 2a 20 46 49 58 4d 45 3a 20 74 68 65 72 65 27 /* FIXME: there'
1b40: 73 20 73 6f 6d 65 20 67 6f 74 63 68 61 73 20 77 s some gotchas w
1b50: 74 68 20 63 6f 6f 6b 69 65 73 20 61 6e 64 20 73 th cookies and s
1b60: 6f 6d 65 20 68 65 61 64 65 72 73 2e 20 2a 2f 0a ome headers. */.
1b70: 20 20 63 68 61 72 20 2a 7a 45 54 61 67 20 3d 20 char *zETag =
1b80: 63 67 69 5f 61 64 64 5f 65 74 61 67 28 62 6c 6f cgi_add_etag(blo
1b90: 62 5f 62 75 66 66 65 72 28 26 63 67 69 43 6f 6e b_buffer(&cgiCon
1ba0: 74 65 6e 74 29 2c 62 6c 6f 62 5f 73 69 7a 65 28 tent),blob_size(
1bb0: 26 63 67 69 43 6f 6e 74 65 6e 74 29 29 3b 0a 20 &cgiContent));.
1bc0: 20 63 68 61 72 20 2a 7a 4d 61 74 63 68 20 3d 20 char *zMatch =
1bd0: 50 28 22 48 54 54 50 5f 49 46 5f 4e 4f 4e 45 5f P("HTTP_IF_NONE_
1be0: 4d 41 54 43 48 22 29 3b 0a 0a 20 20 69 66 28 20 MATCH");.. if(
1bf0: 7a 45 54 61 67 21 3d 30 20 26 26 20 7a 4d 61 74 zETag!=0 && zMat
1c00: 63 68 21 3d 30 20 29 20 7b 0a 20 20 20 20 63 68 ch!=0 ) {. ch
1c10: 61 72 20 2a 7a 42 75 66 20 3d 20 73 74 72 64 75 ar *zBuf = strdu
1c20: 70 28 7a 4d 61 74 63 68 29 3b 0a 20 20 20 20 69 p(zMatch);. i
1c30: 66 28 20 7a 42 75 66 21 3d 30 20 29 7b 0a 20 20 f( zBuf!=0 ){.
1c40: 20 20 20 20 63 68 61 72 20 2a 7a 54 6f 6b 20 3d char *zTok =
1c50: 20 30 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 0;. char *
1c60: 7a 50 6f 73 3b 0a 20 20 20 20 20 20 66 6f 72 28 zPos;. for(
1c70: 20 7a 54 6f 6b 20 3d 20 73 74 72 74 6f 6b 5f 72 zTok = strtok_r
1c80: 28 7a 42 75 66 2c 20 22 2c 5c 22 22 2c 26 7a 50 (zBuf, ",\"",&zP
1c90: 6f 73 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 os);.
1ca0: 7a 54 6f 6b 20 26 26 20 73 74 72 63 61 73 65 63 zTok && strcasec
1cb0: 6d 70 28 7a 54 6f 6b 2c 7a 45 54 61 67 29 3b 0a mp(zTok,zETag);.
1cc0: 20 20 20 20 20 20 20 20 20 20 20 7a 54 6f 6b 20 zTok
1cd0: 3d 20 20 73 74 72 74 6f 6b 5f 72 28 30 2c 20 22 = strtok_r(0, "
1ce0: 2c 5c 22 22 2c 26 7a 50 6f 73 29 29 7b 7d 0a 20 ,\"",&zPos)){}.
1cf0: 20 20 20 20 20 66 72 65 65 28 7a 42 75 66 29 3b free(zBuf);
1d00: 0a 20 20 20 20 20 20 69 66 28 7a 54 6f 6b 29 20 . if(zTok)
1d10: 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a return 1;. }.
1d20: 20 20 7d 0a 20 20 0a 20 20 72 65 74 75 72 6e 20 }. . return
1d30: 30 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 0;.}.#endif../*.
1d40: 2a 2a 20 44 6f 20 61 20 6e 6f 72 6d 61 6c 20 48 ** Do a normal H
1d50: 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 6f 69 TTP reply.*/.voi
1d60: 64 20 63 67 69 5f 72 65 70 6c 79 28 76 6f 69 64 d cgi_reply(void
1d70: 29 7b 0a 20 20 69 6e 74 20 74 6f 74 61 6c 5f 73 ){. int total_s
1d80: 69 7a 65 20 3d 20 30 3b 0a 20 20 69 66 28 20 69 ize = 0;. if( i
1d90: 52 65 70 6c 79 53 74 61 74 75 73 3c 3d 30 20 29 ReplyStatus<=0 )
1da0: 7b 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 74 {. iReplyStat
1db0: 75 73 20 3d 20 32 30 30 3b 0a 20 20 20 20 7a 52 us = 200;. zR
1dc0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4f 4b eplyStatus = "OK
1dd0: 22 3b 0a 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20 ";. }..#if 0.
1de0: 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 if( iReplyStatus
1df0: 3d 3d 32 30 30 20 26 26 20 63 68 65 63 6b 5f 63 ==200 && check_c
1e00: 61 63 68 65 5f 63 6f 6e 74 72 6f 6c 28 29 20 29 ache_control() )
1e10: 20 7b 0a 20 20 20 20 2f 2a 20 63 68 61 6e 67 65 {. /* change
1e20: 20 74 68 65 20 73 74 61 74 75 73 20 74 6f 20 22 the status to "
1e30: 75 6e 63 68 61 6e 67 65 64 22 20 61 6e 64 20 77 unchanged" and w
1e40: 65 20 63 61 6e 20 73 6b 69 70 20 73 65 6e 64 69 e can skip sendi
1e50: 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a 20 61 63 ng the. ** ac
1e60: 74 75 61 6c 20 72 65 73 70 6f 6e 73 65 20 62 6f tual response bo
1e70: 64 79 2e 20 4f 62 76 69 6f 75 73 6c 79 20 77 65 dy. Obviously we
1e80: 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73 20 77 68 only do this wh
1e90: 65 6e 20 77 65 20 5f 68 61 76 65 5f 20 61 0a 20 en we _have_ a.
1ea0: 20 20 20 2a 2a 20 62 6f 64 79 20 28 63 6f 64 65 ** body (code
1eb0: 20 32 30 30 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 200).. */.
1ec0: 20 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d iReplyStatus =
1ed0: 20 33 30 34 3b 0a 20 20 20 20 7a 52 65 70 6c 79 304;. zReply
1ee0: 53 74 61 74 75 73 20 3d 20 22 4e 6f 74 20 4d 6f Status = "Not Mo
1ef0: 64 69 66 69 65 64 22 3b 0a 20 20 7d 0a 23 65 6e dified";. }.#en
1f00: 64 69 66 0a 0a 20 20 69 66 28 20 67 2e 66 75 6c dif.. if( g.ful
1f10: 6c 48 74 74 70 52 65 70 6c 79 20 29 7b 0a 20 20 lHttpReply ){.
1f20: 20 20 63 68 61 72 20 2a 7a 44 61 74 65 20 3d 20 char *zDate =
1f30: 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65 73 cgi_rfc822_dates
1f40: 74 61 6d 70 28 74 69 6d 65 28 30 29 29 3b 0a 20 tamp(time(0));.
1f50: 20 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 fprintf(g.htt
1f60: 70 4f 75 74 2c 20 22 48 54 54 50 2f 31 2e 30 20 pOut, "HTTP/1.0
1f70: 25 64 20 25 73 5c 72 5c 6e 22 2c 20 69 52 65 70 %d %s\r\n", iRep
1f80: 6c 79 53 74 61 74 75 73 2c 20 7a 52 65 70 6c 79 lyStatus, zReply
1f90: 53 74 61 74 75 73 29 3b 0a 20 20 20 20 66 70 72 Status);. fpr
1fa0: 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 intf(g.httpOut,
1fb0: 22 44 61 74 65 3a 20 25 73 5c 72 5c 6e 22 2c 20 "Date: %s\r\n",
1fc0: 7a 44 61 74 65 20 29 3b 0a 20 20 20 20 69 66 28 zDate );. if(
1fd0: 20 7a 44 61 74 65 5b 30 5d 20 29 20 66 72 65 65 zDate[0] ) free
1fe0: 28 20 7a 44 61 74 65 20 29 3b 0a 20 20 20 20 66 ( zDate );. f
1ff0: 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 printf(g.httpOut
2000: 2c 20 22 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 , "Connection: c
2010: 6c 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20 20 7d 65 lose\r\n");. }e
2020: 6c 73 65 7b 0a 20 20 20 20 66 70 72 69 6e 74 66 lse{. fprintf
2030: 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 53 74 61 (g.httpOut, "Sta
2040: 74 75 73 3a 20 25 64 20 25 73 5c 72 5c 6e 22 2c tus: %d %s\r\n",
2050: 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a iReplyStatus, z
2060: 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20 ReplyStatus);.
2070: 7d 0a 0a 20 20 69 66 28 20 62 6c 6f 62 5f 73 69 }.. if( blob_si
2080: 7a 65 28 26 65 78 74 72 61 48 65 61 64 65 72 29 ze(&extraHeader)
2090: 3e 30 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 >0 ){. fprint
20a0: 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 25 73 f(g.httpOut, "%s
20b0: 22 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 ", blob_buffer(&
20c0: 65 78 74 72 61 48 65 61 64 65 72 29 29 3b 0a 20 extraHeader));.
20d0: 20 7d 0a 0a 20 20 69 66 28 20 67 2e 69 73 43 6f }.. if( g.isCo
20e0: 6e 73 74 20 29 7b 0a 20 20 20 20 2f 2a 20 63 6f nst ){. /* co
20f0: 6e 73 74 61 6e 74 20 6d 65 61 6e 73 20 74 68 61 nstant means tha
2100: 74 20 74 68 65 20 69 6e 70 75 74 20 55 52 4c 20 t the input URL
2110: 77 69 6c 6c 20 5f 6e 65 76 65 72 5f 20 67 65 6e will _never_ gen
2120: 65 72 61 74 65 20 61 6e 79 74 68 69 6e 67 0a 20 erate anything.
2130: 20 20 20 2a 2a 20 65 6c 73 65 2e 20 49 6e 20 74 ** else. In t
2140: 68 65 20 63 61 73 65 20 6f 66 20 61 74 74 61 63 he case of attac
2150: 68 6d 65 6e 74 73 2c 20 74 68 65 20 63 6f 6e 74 hments, the cont
2160: 65 6e 74 73 20 77 6f 6e 27 74 20 63 68 61 6e 67 ents won't chang
2170: 65 20 62 65 63 61 75 73 65 0a 20 20 20 20 2a 2a e because. **
2180: 20 61 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 63 an attempt to c
2190: 68 61 6e 67 65 20 74 68 65 6d 20 67 65 6e 65 72 hange them gener
21a0: 61 74 65 73 20 61 20 6e 65 77 20 61 74 74 61 63 ates a new attac
21b0: 68 6d 65 6e 74 20 6e 75 6d 62 65 72 2e 20 49 6e hment number. In
21c0: 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 61 73 65 the. ** case
21d0: 20 6f 66 20 6d 6f 73 74 20 2f 67 65 74 66 69 6c of most /getfil
21e0: 65 20 63 61 6c 6c 73 20 66 6f 72 20 73 70 65 63 e calls for spec
21f0: 69 66 69 63 20 76 65 72 73 69 6f 6e 73 2c 20 74 ific versions, t
2200: 68 65 20 6f 6e 6c 79 20 77 61 79 20 74 68 65 0a he only way the.
2210: 20 20 20 20 2a 2a 20 63 6f 6e 74 65 6e 74 20 63 ** content c
2220: 68 61 6e 67 65 73 20 69 73 20 69 66 20 73 6f 6d hanges is if som
2230: 65 6f 6e 65 20 62 72 65 61 6b 73 20 74 68 65 20 eone breaks the
2240: 53 43 4d 2e 20 41 6e 64 20 69 66 20 74 68 61 74 SCM. And if that
2250: 20 68 61 70 70 65 6e 73 2c 20 61 0a 20 20 20 20 happens, a.
2260: 2a 2a 20 73 74 61 6c 65 20 63 61 63 68 65 20 69 ** stale cache i
2270: 73 20 74 68 65 20 6c 65 61 73 74 20 6f 66 20 74 s the least of t
2280: 68 65 20 70 72 6f 62 6c 65 6d 2e 20 53 6f 20 77 he problem. So w
2290: 65 20 70 72 6f 76 69 64 65 20 61 6e 20 45 78 70 e provide an Exp
22a0: 69 72 65 73 0a 20 20 20 20 2a 2a 20 68 65 61 64 ires. ** head
22b0: 65 72 20 73 65 74 20 74 6f 20 61 20 72 65 61 73 er set to a reas
22c0: 6f 6e 61 62 6c 65 20 70 65 72 69 6f 64 20 28 64 onable period (d
22d0: 65 66 61 75 6c 74 3a 20 6f 6e 65 20 77 65 65 6b efault: one week
22e0: 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 2f 2a ).. */. /*
22f0: 74 69 6d 65 5f 74 20 65 78 70 69 72 65 73 20 3d time_t expires =
2300: 20 74 69 6d 65 28 30 29 20 2b 20 61 74 6f 69 28 time(0) + atoi(
2310: 64 62 5f 63 6f 6e 66 69 67 28 22 63 6f 6e 73 74 db_config("const
2320: 61 6e 74 5f 65 78 70 69 72 65 73 22 2c 22 36 30 ant_expires","60
2330: 34 38 30 30 22 29 29 3b 2a 2f 0a 20 20 20 20 74 4800"));*/. t
2340: 69 6d 65 5f 74 20 65 78 70 69 72 65 73 20 3d 20 ime_t expires =
2350: 74 69 6d 65 28 30 29 20 2b 20 36 30 34 38 30 30 time(0) + 604800
2360: 3b 0a 20 20 20 20 63 68 61 72 20 2a 20 7a 44 61 ;. char * zDa
2370: 74 65 20 3d 20 63 67 69 5f 72 66 63 38 32 32 5f te = cgi_rfc822_
2380: 64 61 74 65 73 74 61 6d 70 28 65 78 70 69 72 65 datestamp(expire
2390: 73 29 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 s);. fprintf(
23a0: 67 2e 68 74 74 70 4f 75 74 2c 20 22 45 78 70 69 g.httpOut, "Expi
23b0: 72 65 73 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 44 res: %s\r\n", zD
23c0: 61 74 65 20 29 3b 0a 20 20 20 20 69 66 28 20 7a ate );. if( z
23d0: 44 61 74 65 5b 30 5d 20 29 20 66 72 65 65 28 20 Date[0] ) free(
23e0: 7a 44 61 74 65 20 29 3b 0a 20 20 7d 0a 0a 20 20 zDate );. }..
23f0: 2f 2a 20 43 6f 6e 74 65 6e 74 20 69 6e 74 65 6e /* Content inten
2400: 64 65 64 20 66 6f 72 20 6c 6f 67 67 65 64 20 69 ded for logged i
2410: 6e 20 75 73 65 72 73 20 73 68 6f 75 6c 64 20 6f n users should o
2420: 6e 6c 79 20 62 65 20 63 61 63 68 65 64 20 69 6e nly be cached in
2430: 0a 20 20 2a 2a 20 74 68 65 20 62 72 6f 77 73 65 . ** the browse
2440: 72 2c 20 6e 6f 74 20 73 6f 6d 65 20 73 68 61 72 r, not some shar
2450: 65 64 20 6c 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a ed location.. *
2460: 2f 0a 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 /. fprintf(g.ht
2470: 74 70 4f 75 74 2c 20 22 43 61 63 68 65 2d 63 6f tpOut, "Cache-co
2480: 6e 74 72 6f 6c 3a 20 6e 6f 2d 63 61 63 68 65 2c ntrol: no-cache,
2490: 20 6e 6f 2d 73 74 6f 72 65 5c 72 5c 6e 22 29 3b no-store\r\n");
24a0: 0a 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 . fprintf(g.htt
24b0: 70 4f 75 74 2c 20 22 43 6f 6e 74 65 6e 74 2d 54 pOut, "Content-T
24c0: 79 70 65 3a 20 25 73 3b 20 63 68 61 72 73 65 74 ype: %s; charset
24d0: 3d 75 74 66 2d 38 5c 72 5c 6e 22 2c 20 7a 43 6f =utf-8\r\n", zCo
24e0: 6e 74 65 6e 74 54 79 70 65 29 3b 0a 20 20 69 66 ntentType);. if
24f0: 28 20 73 74 72 63 6d 70 28 7a 43 6f 6e 74 65 6e ( strcmp(zConten
2500: 74 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74 69 tType,"applicati
2510: 6f 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 on/x-fossil")==0
2520: 20 29 7b 0a 20 20 20 20 63 67 69 5f 63 6f 6d 62 ){. cgi_comb
2530: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 ine_header_and_b
2540: 6f 64 79 28 29 3b 0a 20 20 20 20 62 6c 6f 62 5f ody();. blob_
2550: 63 6f 6d 70 72 65 73 73 28 26 63 67 69 43 6f 6e compress(&cgiCon
2560: 74 65 6e 74 5b 30 5d 2c 20 26 63 67 69 43 6f 6e tent[0], &cgiCon
2570: 74 65 6e 74 5b 30 5d 29 3b 0a 20 20 7d 0a 0a 20 tent[0]);. }..
2580: 20 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 if( iReplyStatu
2590: 73 20 21 3d 20 33 30 34 20 29 20 7b 0a 20 20 20 s != 304 ) {.
25a0: 20 74 6f 74 61 6c 5f 73 69 7a 65 20 3d 20 62 6c total_size = bl
25b0: 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 ob_size(&cgiCont
25c0: 65 6e 74 5b 30 5d 29 20 2b 20 62 6c 6f 62 5f 73 ent[0]) + blob_s
25d0: 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b ize(&cgiContent[
25e0: 31 5d 29 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 1]);. fprintf
25f0: 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 43 6f 6e (g.httpOut, "Con
2600: 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 64 5c tent-Length: %d\
2610: 72 5c 6e 22 2c 20 74 6f 74 61 6c 5f 73 69 7a 65 r\n", total_size
2620: 29 3b 0a 20 20 7d 0a 20 20 66 70 72 69 6e 74 66 );. }. fprintf
2630: 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 5c 72 5c (g.httpOut, "\r\
2640: 6e 22 29 3b 0a 20 20 69 66 28 20 74 6f 74 61 6c n");. if( total
2650: 5f 73 69 7a 65 3e 30 20 26 26 20 69 52 65 70 6c _size>0 && iRepl
2660: 79 53 74 61 74 75 73 20 21 3d 20 33 30 34 20 29 yStatus != 304 )
2670: 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20 73 69 7a {. int i, siz
2680: 65 3b 0a 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 e;. for(i=0;
2690: 69 3c 32 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 i<2; i++){.
26a0: 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a size = blob_siz
26b0: 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 69 5d e(&cgiContent[i]
26c0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 73 69 7a );. if( siz
26d0: 65 3e 30 20 29 7b 0a 20 20 20 20 20 20 20 20 66 e>0 ){. f
26e0: 77 72 69 74 65 28 62 6c 6f 62 5f 62 75 66 66 65 write(blob_buffe
26f0: 72 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 69 5d r(&cgiContent[i]
2700: 29 2c 20 31 2c 20 73 69 7a 65 2c 20 67 2e 68 74 ), 1, size, g.ht
2710: 74 70 4f 75 74 29 3b 0a 20 20 20 20 20 20 7d 0a tpOut);. }.
2720: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 43 47 49 44 }. }. CGID
2730: 45 42 55 47 28 28 22 44 4f 4e 45 5c 6e 22 29 29 EBUG(("DONE\n"))
2740: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 ;.}../*.** Do a
2750: 72 65 64 69 72 65 63 74 20 72 65 71 75 65 73 74 redirect request
2760: 20 74 6f 20 74 68 65 20 55 52 4c 20 67 69 76 65 to the URL give
2770: 6e 20 69 6e 20 74 68 65 20 61 72 67 75 6d 65 6e n in the argumen
2780: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 55 52 4c t..**.** The URL
2790: 20 6d 75 73 74 20 62 65 20 72 65 6c 61 74 69 76 must be relativ
27a0: 65 20 74 6f 20 74 68 65 20 62 61 73 65 20 6f 66 e to the base of
27b0: 20 74 68 65 20 66 6f 73 73 69 6c 20 73 65 72 76 the fossil serv
27c0: 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f er..*/.void cgi_
27d0: 72 65 64 69 72 65 63 74 28 63 6f 6e 73 74 20 63 redirect(const c
27e0: 68 61 72 20 2a 7a 55 52 4c 29 7b 0a 20 20 63 68 har *zURL){. ch
27f0: 61 72 20 2a 7a 4c 6f 63 61 74 69 6f 6e 3b 0a 20 ar *zLocation;.
2800: 20 43 47 49 44 45 42 55 47 28 28 22 72 65 64 69 CGIDEBUG(("redi
2810: 72 65 63 74 20 74 6f 20 25 73 5c 6e 22 2c 20 7a rect to %s\n", z
2820: 55 52 4c 29 29 3b 0a 20 20 69 66 28 20 73 74 72 URL));. if( str
2830: 6e 63 6d 70 28 7a 55 52 4c 2c 22 68 74 74 70 3a ncmp(zURL,"http:
2840: 22 2c 35 29 3d 3d 30 20 7c 7c 20 73 74 72 6e 63 ",5)==0 || strnc
2850: 6d 70 28 7a 55 52 4c 2c 22 68 74 74 70 73 3a 22 mp(zURL,"https:"
2860: 2c 36 29 3d 3d 30 20 7c 7c 20 2a 7a 55 52 4c 3d ,6)==0 || *zURL=
2870: 3d 27 2f 27 20 29 7b 0a 20 20 20 20 7a 4c 6f 63 ='/' ){. zLoc
2880: 61 74 69 6f 6e 20 3d 20 6d 70 72 69 6e 74 66 28 ation = mprintf(
2890: 22 4c 6f 63 61 74 69 6f 6e 3a 20 25 73 5c 72 5c "Location: %s\r\
28a0: 6e 22 2c 20 7a 55 52 4c 29 3b 0a 20 20 7d 65 6c n", zURL);. }el
28b0: 73 65 7b 0a 20 20 20 20 7a 4c 6f 63 61 74 69 6f se{. zLocatio
28c0: 6e 20 3d 20 6d 70 72 69 6e 74 66 28 22 4c 6f 63 n = mprintf("Loc
28d0: 61 74 69 6f 6e 3a 20 25 73 2f 25 73 5c 72 5c 6e ation: %s/%s\r\n
28e0: 22 2c 20 67 2e 7a 42 61 73 65 55 52 4c 2c 20 7a ", g.zBaseURL, z
28f0: 55 52 4c 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f URL);. }. cgi_
2900: 61 70 70 65 6e 64 5f 68 65 61 64 65 72 28 7a 4c append_header(zL
2910: 6f 63 61 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f ocation);. cgi_
2920: 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b reset_content();
2930: 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 3c . cgi_printf("<
2940: 68 74 6d 6c 3e 5c 6e 3c 70 3e 52 65 64 69 72 65 html>\n<p>Redire
2950: 63 74 20 74 6f 20 25 68 3c 2f 70 3e 5c 6e 3c 2f ct to %h</p>\n</
2960: 68 74 6d 6c 3e 5c 6e 22 2c 20 7a 55 52 4c 29 3b html>\n", zURL);
2970: 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 . cgi_set_statu
2980: 73 28 33 30 32 2c 20 22 4d 6f 76 65 64 20 54 65 s(302, "Moved Te
2990: 6d 70 6f 72 61 72 69 6c 79 22 29 3b 0a 20 20 66 mporarily");. f
29a0: 72 65 65 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a ree(zLocation);.
29b0: 20 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 cgi_reply();.
29c0: 20 65 78 69 74 28 30 29 3b 0a 7d 0a 76 6f 69 64 exit(0);.}.void
29d0: 20 63 67 69 5f 72 65 64 69 72 65 63 74 66 28 63 cgi_redirectf(c
29e0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d onst char *zForm
29f0: 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c at, ...){. va_l
2a00: 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 ist ap;. va_sta
2a10: 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b rt(ap, zFormat);
2a20: 0a 20 20 63 67 69 5f 72 65 64 69 72 65 63 74 28 . cgi_redirect(
2a30: 76 6d 70 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74 vmprintf(zFormat
2a40: 2c 20 61 70 29 29 3b 0a 20 20 76 61 5f 65 6e 64 , ap));. va_end
2a50: 28 61 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 (ap);.}../*.** I
2a60: 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 nformation about
2a70: 20 61 6c 6c 20 71 75 65 72 79 20 70 61 72 61 6d all query param
2a80: 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 eters and cookie
2a90: 73 20 61 72 65 20 73 74 6f 72 65 64 0a 2a 2a 20 s are stored.**
2aa0: 69 6e 20 74 68 65 73 65 20 76 61 72 69 61 62 6c in these variabl
2ab0: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e es..*/.static in
2ac0: 74 20 6e 41 6c 6c 6f 63 51 50 20 3d 20 30 3b 20 t nAllocQP = 0;
2ad0: 2f 2a 20 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 /* Space allocat
2ae0: 65 64 20 66 6f 72 20 61 50 61 72 61 6d 51 50 5b ed for aParamQP[
2af0: 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ] */.static int
2b00: 6e 55 73 65 64 51 50 20 3d 20 30 3b 20 20 2f 2a nUsedQP = 0; /*
2b10: 20 53 70 61 63 65 20 61 63 74 75 61 6c 6c 79 20 Space actually
2b20: 75 73 65 64 20 69 6e 20 61 50 61 72 61 6d 51 50 used in aParamQP
2b30: 5b 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 [] */.static int
2b40: 20 73 6f 72 74 51 50 20 3d 20 30 3b 20 20 20 2f sortQP = 0; /
2b50: 2a 20 54 72 75 65 20 69 66 20 61 50 61 72 61 6d * True if aParam
2b60: 51 50 5b 5d 20 6e 65 65 64 73 20 73 6f 72 74 69 QP[] needs sorti
2b70: 6e 67 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 ng */.static int
2b80: 20 73 65 71 51 50 20 3d 20 30 3b 20 20 20 20 2f seqQP = 0; /
2b90: 2a 20 53 65 71 75 65 6e 63 65 20 6e 75 6d 62 65 * Sequence numbe
2ba0: 72 73 20 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 rs */.static str
2bb0: 75 63 74 20 51 50 61 72 61 6d 20 7b 20 20 20 2f uct QParam { /
2bc0: 2a 20 4f 6e 65 20 65 6e 74 72 79 20 66 6f 72 20 * One entry for
2bd0: 65 61 63 68 20 71 75 65 72 79 20 70 61 72 61 6d each query param
2be0: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 2a eter or cookie *
2bf0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a /. const char *
2c00: 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 2f 2a zName; /*
2c10: 20 50 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f Parameter or co
2c20: 6f 6b 69 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 okie name */. c
2c30: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 onst char *zValu
2c40: 65 3b 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 e; /* Valu
2c50: 65 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 e of the query p
2c60: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b arameter or cook
2c70: 69 65 20 2a 2f 0a 20 20 69 6e 74 20 73 65 71 3b ie */. int seq;
2c80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2c90: 20 20 2f 2a 20 4f 72 64 65 72 20 6f 66 20 69 6e /* Order of in
2ca0: 73 65 72 74 69 6f 6e 20 2a 2f 0a 7d 20 2a 61 50 sertion */.} *aP
2cb0: 61 72 61 6d 51 50 3b 20 20 20 20 20 20 20 20 20 aramQP;
2cc0: 20 20 20 20 2f 2a 20 41 6e 20 61 72 72 61 79 20 /* An array
2cd0: 6f 66 20 61 6c 6c 20 70 61 72 61 6d 65 74 65 72 of all parameter
2ce0: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 20 2a 2f s and cookies */
2cf0: 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 ../*.** Add anot
2d00: 68 65 72 20 71 75 65 72 79 20 70 61 72 61 6d 65 her query parame
2d10: 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 74 6f ter or cookie to
2d20: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 73 the parameter s
2d30: 65 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 et..** zName is
2d40: 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 the name of the
2d50: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 query parameter
2d60: 6f 72 20 63 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 or cookie and zV
2d70: 61 6c 75 65 0a 2a 2a 20 69 73 20 69 74 73 20 66 alue.** is its f
2d80: 75 6c 6c 79 20 64 65 63 6f 64 65 64 20 76 61 6c ully decoded val
2d90: 75 65 2e 0a 2a 2a 0a 2a 2a 20 7a 4e 61 6d 65 20 ue..**.** zName
2da0: 61 6e 64 20 7a 56 61 6c 75 65 20 61 72 65 20 6e and zValue are n
2db0: 6f 74 20 63 6f 70 69 65 64 20 61 6e 64 20 6d 75 ot copied and mu
2dc0: 73 74 20 6e 6f 74 20 63 68 61 6e 67 65 20 6f 72 st not change or
2dd0: 20 62 65 0a 2a 2a 20 64 65 61 6c 6c 6f 63 61 74 be.** deallocat
2de0: 65 64 20 61 66 74 65 72 20 74 68 69 73 20 72 6f ed after this ro
2df0: 75 74 69 6e 65 20 72 65 74 75 72 6e 73 2e 0a 2a utine returns..*
2e00: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 70 /.void cgi_set_p
2e10: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 arameter_nocopy(
2e20: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d const char *zNam
2e30: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a e, const char *z
2e40: 56 61 6c 75 65 29 7b 0a 20 20 69 66 28 20 6e 41 Value){. if( nA
2e50: 6c 6c 6f 63 51 50 3c 3d 6e 55 73 65 64 51 50 20 llocQP<=nUsedQP
2e60: 29 7b 0a 20 20 20 20 6e 41 6c 6c 6f 63 51 50 20 ){. nAllocQP
2e70: 3d 20 6e 41 6c 6c 6f 63 51 50 2a 32 20 2b 20 31 = nAllocQP*2 + 1
2e80: 30 3b 0a 20 20 20 20 61 50 61 72 61 6d 51 50 20 0;. aParamQP
2e90: 3d 20 72 65 61 6c 6c 6f 63 28 20 61 50 61 72 61 = realloc( aPara
2ea0: 6d 51 50 2c 20 6e 41 6c 6c 6f 63 51 50 2a 73 69 mQP, nAllocQP*si
2eb0: 7a 65 6f 66 28 61 50 61 72 61 6d 51 50 5b 30 5d zeof(aParamQP[0]
2ec0: 29 20 29 3b 0a 20 20 20 20 69 66 28 20 61 50 61 ) );. if( aPa
2ed0: 72 61 6d 51 50 3d 3d 30 20 29 20 65 78 69 74 28 ramQP==0 ) exit(
2ee0: 31 29 3b 0a 20 20 7d 0a 20 20 61 50 61 72 61 6d 1);. }. aParam
2ef0: 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a 4e 61 6d QP[nUsedQP].zNam
2f00: 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20 61 50 61 e = zName;. aPa
2f10: 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a ramQP[nUsedQP].z
2f20: 56 61 6c 75 65 20 3d 20 7a 56 61 6c 75 65 3b 0a Value = zValue;.
2f30: 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 aParamQP[nUsed
2f40: 51 50 5d 2e 73 65 71 20 3d 20 73 65 71 51 50 2b QP].seq = seqQP+
2f50: 2b 3b 0a 20 20 6e 55 73 65 64 51 50 2b 2b 3b 0a +;. nUsedQP++;.
2f60: 20 20 73 6f 72 74 51 50 20 3d 20 31 3b 0a 7d 0a sortQP = 1;.}.
2f70: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 68 ./*.** Add anoth
2f80: 65 72 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 er query paramet
2f90: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 74 6f 20 er or cookie to
2fa0: 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 73 65 the parameter se
2fb0: 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 74 t..** zName is t
2fc0: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 71 he name of the q
2fd0: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f uery parameter o
2fe0: 72 20 63 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 61 r cookie and zVa
2ff0: 6c 75 65 0a 2a 2a 20 69 73 20 69 74 73 20 66 75 lue.** is its fu
3000: 6c 6c 79 20 64 65 63 6f 64 65 64 20 76 61 6c 75 lly decoded valu
3010: 65 2e 0a 2a 2a 0a 2a 2a 20 43 6f 70 69 65 73 20 e..**.** Copies
3020: 61 72 65 20 6d 61 64 65 20 6f 66 20 62 6f 74 68 are made of both
3030: 20 74 68 65 20 7a 4e 61 6d 65 20 61 6e 64 20 7a the zName and z
3040: 56 61 6c 75 65 20 70 61 72 61 6d 65 74 65 72 73 Value parameters
3050: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 ..*/.void cgi_se
3060: 74 5f 70 61 72 61 6d 65 74 65 72 28 63 6f 6e 73 t_parameter(cons
3070: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 t char *zName, c
3080: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 onst char *zValu
3090: 65 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 e){. cgi_set_pa
30a0: 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d rameter_nocopy(m
30b0: 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 4e 61 6d printf("%s",zNam
30c0: 65 29 2c 20 6d 70 72 69 6e 74 66 28 22 25 73 22 e), mprintf("%s"
30d0: 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a 0a 2f 2a ,zValue));.}../*
30e0: 0a 2a 2a 20 52 65 70 6c 61 63 65 20 61 20 70 61 .** Replace a pa
30f0: 72 61 6d 65 74 65 72 20 77 69 74 68 20 61 20 6e rameter with a n
3100: 65 77 20 76 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 ew value..*/.voi
3110: 64 20 63 67 69 5f 72 65 70 6c 61 63 65 5f 70 61 d cgi_replace_pa
3120: 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 20 63 68 rameter(const ch
3130: 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 ar *zName, const
3140: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a char *zValue){.
3150: 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f 72 28 69 int i;. for(i
3160: 3d 30 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 =0; i<nUsedQP; i
3170: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 ++){. if( str
3180: 63 6d 70 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e cmp(aParamQP[i].
3190: 7a 4e 61 6d 65 2c 7a 4e 61 6d 65 29 3d 3d 30 20 zName,zName)==0
31a0: 29 7b 0a 20 20 20 20 20 20 61 50 61 72 61 6d 51 ){. aParamQ
31b0: 50 5b 69 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56 P[i].zValue = zV
31c0: 61 6c 75 65 3b 0a 20 20 20 20 20 20 72 65 74 75 alue;. retu
31d0: 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 rn;. }. }.
31e0: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 cgi_set_paramete
31f0: 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 r_nocopy(zName,
3200: 7a 56 61 6c 75 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a zValue);.}../*.*
3210: 2a 20 41 64 64 20 61 20 71 75 65 72 79 20 70 61 * Add a query pa
3220: 72 61 6d 65 74 65 72 2e 20 20 54 68 65 20 7a 4e rameter. The zN
3230: 61 6d 65 20 70 6f 72 74 69 6f 6e 20 69 73 20 66 ame portion is f
3240: 69 78 65 64 20 62 75 74 20 61 20 63 6f 70 79 0a ixed but a copy.
3250: 2a 2a 20 6d 75 73 74 20 62 65 20 6d 61 64 65 20 ** must be made
3260: 6f 66 20 7a 56 61 6c 75 65 2e 0a 2a 2f 0a 76 6f of zValue..*/.vo
3270: 69 64 20 63 67 69 5f 73 65 74 65 6e 76 28 63 6f id cgi_setenv(co
3280: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c nst char *zName,
3290: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 const char *zVa
32a0: 6c 75 65 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f lue){. cgi_set_
32b0: 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 parameter_nocopy
32c0: 28 7a 4e 61 6d 65 2c 20 6d 70 72 69 6e 74 66 28 (zName, mprintf(
32d0: 22 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d "%s",zValue));.}
32e0: 0a 20 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 . ../*.** Add a
32f0: 6c 69 73 74 20 6f 66 20 71 75 65 72 79 20 70 61 list of query pa
3300: 72 61 6d 65 74 65 72 73 20 6f 72 20 63 6f 6f 6b rameters or cook
3310: 69 65 73 20 74 6f 20 74 68 65 20 70 61 72 61 6d ies to the param
3320: 65 74 65 72 20 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 eter set..**.**
3330: 45 61 63 68 20 70 61 72 61 6d 65 74 65 72 20 69 Each parameter i
3340: 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 4e 41 s of the form NA
3350: 4d 45 3d 56 41 4c 55 45 2e 20 20 42 6f 74 68 20 ME=VALUE. Both
3360: 74 68 65 20 4e 41 4d 45 20 61 6e 64 20 74 68 65 the NAME and the
3370: 0a 2a 2a 20 56 41 4c 55 45 20 6d 61 79 20 62 65 .** VALUE may be
3380: 20 75 72 6c 2d 65 6e 63 6f 64 65 64 20 28 22 2b url-encoded ("+
3390: 22 20 66 6f 72 20 73 70 61 63 65 2c 20 22 25 48 " for space, "%H
33a0: 48 22 20 66 6f 72 20 6f 74 68 65 72 20 73 70 65 H" for other spe
33b0: 63 69 61 6c 0a 2a 2a 20 63 68 61 72 61 63 74 65 cial.** characte
33c0: 72 73 29 2e 20 20 42 75 74 20 74 68 69 73 20 72 rs). But this r
33d0: 6f 75 74 69 6e 65 20 61 73 73 75 6d 65 73 20 74 outine assumes t
33e0: 68 61 74 20 4e 41 4d 45 20 63 6f 6e 74 61 69 6e hat NAME contain
33f0: 73 20 6e 6f 0a 2a 2a 20 73 70 65 63 69 61 6c 20 s no.** special
3400: 63 68 61 72 61 63 74 65 72 20 61 6e 64 20 74 68 character and th
3410: 65 72 65 66 6f 72 65 20 64 6f 65 73 20 6e 6f 74 erefore does not
3420: 20 64 65 63 6f 64 65 20 69 74 2e 0a 2a 2a 0a 2a decode it..**.*
3430: 2a 20 49 66 20 4e 41 4d 45 20 62 65 67 69 6e 73 * If NAME begins
3440: 20 77 69 74 68 20 61 6e 6f 74 68 65 72 20 6f 74 with another ot
3450: 68 65 72 20 74 68 61 6e 20 61 20 6c 6f 77 65 72 her than a lower
3460: 2d 63 61 73 65 20 6c 65 74 74 65 72 20 74 68 65 -case letter the
3470: 6e 0a 2a 2a 20 74 68 65 20 65 6e 74 69 72 65 20 n.** the entire
3480: 4e 41 4d 45 3d 56 41 4c 55 45 20 74 65 72 6d 20 NAME=VALUE term
3490: 69 73 20 69 67 6e 6f 72 65 64 2e 20 20 48 65 6e is ignored. Hen
34a0: 63 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a ce:.**.** *
34b0: 20 20 63 6f 6f 6b 69 65 73 20 61 6e 64 20 71 75 cookies and qu
34c0: 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 74 ery parameters t
34d0: 68 61 74 20 68 61 76 65 20 75 70 70 65 72 63 61 hat have upperca
34e0: 73 65 20 6e 61 6d 65 73 0a 2a 2a 20 20 20 20 20 se names.**
34f0: 20 20 20 20 61 72 65 20 69 67 6e 6f 72 65 64 2e are ignored.
3500: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a 20 20 69 .**.** * i
3510: 74 20 69 73 20 69 6d 70 6f 73 73 69 62 6c 65 20 t is impossible
3520: 66 6f 72 20 61 20 63 6f 6f 6b 69 65 20 6f 72 20 for a cookie or
3530: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 query parameter
3540: 74 6f 0a 2a 2a 20 20 20 20 20 20 20 20 20 6f 76 to.** ov
3550: 65 72 72 69 64 65 20 74 68 65 20 76 61 6c 75 65 erride the value
3560: 20 6f 66 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 of an environme
3570: 6e 74 20 76 61 72 69 61 62 6c 65 20 73 69 6e 63 nt variable sinc
3580: 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 65 6e 76 e.** env
3590: 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c ironment variabl
35a0: 65 73 20 61 6c 77 61 79 73 20 68 61 76 65 20 75 es always have u
35b0: 70 70 65 72 63 61 73 65 20 6e 61 6d 65 73 2e 0a ppercase names..
35c0: 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 72 73 **.** Parameters
35d0: 20 61 72 65 20 73 65 70 61 72 61 74 65 64 20 62 are separated b
35e0: 79 20 74 68 65 20 22 74 65 72 6d 69 6e 61 74 6f y the "terminato
35f0: 72 22 20 63 68 61 72 61 63 74 65 72 2e 20 20 57 r" character. W
3600: 68 69 74 65 73 70 61 63 65 0a 2a 2a 20 62 65 66 hitespace.** bef
3610: 6f 72 65 20 74 68 65 20 4e 41 4d 45 20 69 73 20 ore the NAME is
3620: 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 ignored..**.** T
3630: 68 65 20 69 6e 70 75 74 20 73 74 72 69 6e 67 20 he input string
3640: 22 7a 22 20 69 73 20 6d 6f 64 69 66 69 65 64 20 "z" is modified
3650: 62 75 74 20 6e 6f 20 63 6f 70 69 65 73 20 69 73 but no copies is
3660: 20 6d 61 64 65 2e 20 20 22 7a 22 0a 2a 2a 20 73 made. "z".** s
3670: 68 6f 75 6c 64 20 6e 6f 74 20 62 65 20 64 65 61 hould not be dea
3680: 6c 6c 6f 63 61 74 65 64 20 6f 72 20 63 68 61 6e llocated or chan
3690: 67 65 64 20 61 67 61 69 6e 20 61 66 74 65 72 20 ged again after
36a0: 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 this routine.**
36b0: 72 65 74 75 72 6e 73 20 6f 72 20 69 74 20 77 69 returns or it wi
36c0: 6c 6c 20 63 6f 72 72 75 70 74 20 74 68 65 20 70 ll corrupt the p
36d0: 61 72 61 6d 65 74 65 72 20 74 61 62 6c 65 2e 0a arameter table..
36e0: 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 61 */.static void a
36f0: 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 63 68 dd_param_list(ch
3700: 61 72 20 2a 7a 2c 20 69 6e 74 20 74 65 72 6d 69 ar *z, int termi
3710: 6e 61 74 6f 72 29 7b 0a 20 20 77 68 69 6c 65 28 nator){. while(
3720: 20 2a 7a 20 29 7b 0a 20 20 20 20 63 68 61 72 20 *z ){. char
3730: 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 63 68 61 72 *zName;. char
3740: 20 2a 7a 56 61 6c 75 65 3b 0a 20 20 20 20 77 68 *zValue;. wh
3750: 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a 29 ile( isspace(*z)
3760: 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 7a ){ z++; }. z
3770: 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 20 77 68 Name = z;. wh
3780: 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 ile( *z && *z!='
3790: 3d 27 20 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e =' && *z!=termin
37a0: 61 74 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 ator ){ z++; }.
37b0: 20 20 20 69 66 28 20 2a 7a 3d 3d 27 3d 27 20 29 if( *z=='=' )
37c0: 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a {. *z = 0;.
37d0: 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 z++;.
37e0: 20 7a 56 61 6c 75 65 20 3d 20 7a 3b 0a 20 20 20 zValue = z;.
37f0: 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 while( *z &&
3800: 2a 7a 21 3d 74 65 72 6d 69 6e 61 74 6f 72 20 29 *z!=terminator )
3810: 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69 { z++; }. i
3820: 66 28 20 2a 7a 20 29 7b 0a 20 20 20 20 20 20 20 f( *z ){.
3830: 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 *z = 0;.
3840: 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 z++;. }.
3850: 20 20 20 20 64 65 68 74 74 70 69 7a 65 28 7a 56 dehttpize(zV
3860: 61 6c 75 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 alue);. }else
3870: 7b 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20 29 {. if( *z )
3880: 7b 20 2a 7a 2b 2b 20 3d 20 30 3b 20 7d 0a 20 20 { *z++ = 0; }.
3890: 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 22 22 3b zValue = "";
38a0: 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 20 69 . }. if( i
38b0: 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 slower(zName[0])
38c0: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 ){. cgi_se
38d0: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f t_parameter_noco
38e0: 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 py(zName, zValue
38f0: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a );. }. }.}..
3900: 2f 2a 0a 2a 2a 20 2a 70 7a 20 69 73 20 61 20 73 /*.** *pz is a s
3910: 74 72 69 6e 67 20 74 68 61 74 20 63 6f 6e 73 69 tring that consi
3920: 73 74 73 20 6f 66 20 6d 75 6c 74 69 70 6c 65 20 sts of multiple
3930: 6c 69 6e 65 73 20 6f 66 20 74 65 78 74 2e 20 20 lines of text.
3940: 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 This.** routine
3950: 66 69 6e 64 73 20 74 68 65 20 65 6e 64 20 6f 66 finds the end of
3960: 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6e the current lin
3970: 65 20 6f 66 20 74 65 78 74 20 61 6e 64 20 63 6f e of text and co
3980: 6e 76 65 72 74 73 0a 2a 2a 20 74 68 65 20 22 5c nverts.** the "\
3990: 6e 22 20 6f 72 20 22 5c 72 5c 6e 22 20 74 68 61 n" or "\r\n" tha
39a0: 74 20 65 6e 64 73 20 74 68 61 74 20 6c 69 6e 65 t ends that line
39b0: 20 69 6e 74 6f 20 61 20 22 5c 30 30 30 22 2e 20 into a "\000".
39c0: 20 49 74 20 74 68 65 6e 0a 2a 2a 20 61 64 76 61 It then.** adva
39d0: 6e 63 65 73 20 2a 70 7a 20 74 6f 20 74 68 65 20 nces *pz to the
39e0: 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 beginning of the
39f0: 20 6e 65 78 74 20 6c 69 6e 65 20 61 6e 64 20 72 next line and r
3a00: 65 74 75 72 6e 73 20 74 68 65 0a 2a 2a 20 70 72 eturns the.** pr
3a10: 65 76 69 6f 75 73 20 76 61 6c 75 65 20 6f 66 20 evious value of
3a20: 2a 70 7a 20 28 77 68 69 63 68 20 69 73 20 74 68 *pz (which is th
3a30: 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 20 63 e start of the c
3a40: 75 72 72 65 6e 74 20 6c 69 6e 65 2e 29 0a 2a 2f urrent line.).*/
3a50: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 67 65 .static char *ge
3a60: 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 t_line_from_stri
3a70: 6e 67 28 63 68 61 72 20 2a 2a 70 7a 2c 20 69 6e ng(char **pz, in
3a80: 74 20 2a 70 4c 65 6e 29 7b 0a 20 20 63 68 61 72 t *pLen){. char
3a90: 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e 74 *z = *pz;. int
3aa0: 20 69 3b 0a 20 20 69 66 28 20 7a 5b 30 5d 3d 3d i;. if( z[0]==
3ab0: 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 0 ) return 0;.
3ac0: 66 6f 72 28 69 3d 30 3b 20 7a 5b 69 5d 3b 20 69 for(i=0; z[i]; i
3ad0: 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 ++){. if( z[i
3ae0: 5d 3d 3d 27 5c 6e 27 20 29 7b 0a 20 20 20 20 20 ]=='\n' ){.
3af0: 20 69 66 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d if( i>0 && z[i-
3b00: 31 5d 3d 3d 27 5c 72 27 20 29 7b 0a 20 20 20 20 1]=='\r' ){.
3b10: 20 20 20 20 7a 5b 69 2d 31 5d 20 3d 20 30 3b 0a z[i-1] = 0;.
3b20: 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 }else{.
3b30: 20 20 20 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20 z[i] = 0;.
3b40: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 2b 2b }. i++
3b50: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 ;. break;.
3b60: 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d }. }. *pz =
3b70: 20 26 7a 5b 69 5d 3b 0a 20 20 2a 70 4c 65 6e 20 &z[i];. *pLen
3b80: 2d 3d 20 69 3b 0a 20 20 72 65 74 75 72 6e 20 7a -= i;. return z
3b90: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 ;.}../*.** The i
3ba0: 6e 70 75 74 20 2a 70 7a 20 70 6f 69 6e 74 73 20 nput *pz points
3bb0: 74 6f 20 63 6f 6e 74 65 6e 74 20 74 68 61 74 20 to content that
3bc0: 69 73 20 74 65 72 6d 69 6e 61 74 65 64 20 62 79 is terminated by
3bd0: 20 61 20 22 5c 72 5c 6e 22 0a 2a 2a 20 66 6f 6c a "\r\n".** fol
3be0: 6c 6f 77 65 64 20 62 79 20 74 68 65 20 62 6f 75 lowed by the bou
3bf0: 6e 64 72 79 20 6d 61 72 6b 65 72 20 7a 42 6f 75 ndry marker zBou
3c00: 6e 64 72 79 2e 20 20 41 6e 20 65 78 74 72 61 20 ndry. An extra
3c10: 22 2d 2d 22 20 6d 61 79 20 6f 72 0a 2a 2a 20 6d "--" may or.** m
3c20: 61 79 20 6e 6f 74 20 62 65 20 61 70 70 65 6e 64 ay not be append
3c30: 65 64 20 74 6f 20 74 68 65 20 62 6f 75 6e 64 72 ed to the boundr
3c40: 79 20 6d 61 72 6b 65 72 2e 20 20 54 68 65 72 65 y marker. There
3c50: 20 61 72 65 20 2a 70 4c 65 6e 20 63 68 61 72 61 are *pLen chara
3c60: 63 74 65 72 73 0a 2a 2a 20 69 6e 20 2a 70 7a 2e cters.** in *pz.
3c70: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 .**.** This rout
3c80: 69 6e 65 20 61 64 64 73 20 61 20 22 5c 30 30 30 ine adds a "\000
3c90: 22 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 " to the end of
3ca0: 74 68 65 20 63 6f 6e 74 65 6e 74 20 28 6f 76 65 the content (ove
3cb0: 72 77 72 69 74 69 6e 67 0a 2a 2a 20 74 68 65 20 rwriting.** the
3cc0: 22 5c 72 5c 6e 22 29 20 61 6e 64 20 72 65 74 75 "\r\n") and retu
3cd0: 72 6e 73 20 61 20 70 6f 69 6e 74 65 72 20 74 6f rns a pointer to
3ce0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 2e 20 20 54 the content. T
3cf0: 68 65 20 2a 70 7a 20 69 6e 70 75 74 0a 2a 2a 20 he *pz input.**
3d00: 69 73 20 61 64 6a 75 73 74 65 64 20 74 6f 20 70 is adjusted to p
3d10: 6f 69 6e 74 20 74 6f 20 74 68 65 20 66 69 72 73 oint to the firs
3d20: 74 20 6c 69 6e 65 20 66 6f 6c 6c 6f 77 69 6e 67 t line following
3d30: 20 74 68 65 20 62 6f 75 6e 64 72 79 2e 0a 2a 2a the boundry..**
3d40: 20 54 68 65 20 6c 65 6e 67 74 68 20 6f 66 20 74 The length of t
3d50: 68 65 20 63 6f 6e 74 65 6e 74 20 69 73 20 73 74 he content is st
3d60: 6f 72 65 64 20 69 6e 20 2a 70 6e 43 6f 6e 74 65 ored in *pnConte
3d70: 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 nt..*/.static ch
3d80: 61 72 20 2a 67 65 74 5f 62 6f 75 6e 64 65 64 5f ar *get_bounded_
3d90: 63 6f 6e 74 65 6e 74 28 0a 20 20 63 68 61 72 20 content(. char
3da0: 2a 2a 70 7a 2c 20 20 20 20 20 20 20 20 20 2f 2a **pz, /*
3db0: 20 43 6f 6e 74 65 6e 74 20 74 61 6b 65 6e 20 66 Content taken f
3dc0: 72 6f 6d 20 68 65 72 65 20 2a 2f 0a 20 20 69 6e rom here */. in
3dd0: 74 20 2a 70 4c 65 6e 2c 20 20 20 20 20 20 20 20 t *pLen,
3de0: 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 /* Number of by
3df0: 74 65 73 20 6f 66 20 64 61 74 61 20 69 6e 20 28 tes of data in (
3e00: 2a 70 7a 29 5b 5d 20 2a 2f 0a 20 20 63 68 61 72 *pz)[] */. char
3e10: 20 2a 7a 42 6f 75 6e 64 72 79 2c 20 20 20 20 2f *zBoundry, /
3e20: 2a 20 42 6f 75 6e 64 72 79 20 74 65 78 74 20 6d * Boundry text m
3e30: 61 72 6b 69 6e 67 20 74 68 65 20 65 6e 64 20 6f arking the end o
3e40: 66 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 69 f content */. i
3e50: 6e 74 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 20 20 nt *pnContent
3e60: 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 20 73 /* Write the s
3e70: 69 7a 65 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 ize of the conte
3e80: 6e 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 nt here */.){.
3e90: 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 char *z = *pz;.
3ea0: 20 69 6e 74 20 6c 65 6e 20 3d 20 2a 70 4c 65 6e int len = *pLen
3eb0: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 ;. int i;. int
3ec0: 20 6e 42 6f 75 6e 64 72 79 20 3d 20 73 74 72 6c nBoundry = strl
3ed0: 65 6e 28 7a 42 6f 75 6e 64 72 79 29 3b 0a 20 20 en(zBoundry);.
3ee0: 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d 20 6c 65 6e *pnContent = len
3ef0: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6c ;. for(i=0; i<l
3f00: 65 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 en; i++){. if
3f10: 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 26 26 20 ( z[i]=='\n' &&
3f20: 73 74 72 6e 63 6d 70 28 7a 42 6f 75 6e 64 72 79 strncmp(zBoundry
3f30: 2c 20 26 7a 5b 69 2b 31 5d 2c 20 6e 42 6f 75 6e , &z[i+1], nBoun
3f40: 64 72 79 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 dry)==0 ){.
3f50: 20 69 66 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d if( i>0 && z[i-
3f60: 31 5d 3d 3d 27 5c 72 27 20 29 20 69 2d 2d 3b 0a 1]=='\r' ) i--;.
3f70: 20 20 20 20 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a z[i] = 0;.
3f80: 20 20 20 20 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 *pnContent
3f90: 20 3d 20 69 3b 0a 20 20 20 20 20 20 69 20 2b 3d = i;. i +=
3fa0: 20 6e 42 6f 75 6e 64 72 79 3b 0a 20 20 20 20 20 nBoundry;.
3fb0: 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 break;. }.
3fc0: 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a 5b 69 5d 3b }. *pz = &z[i];
3fd0: 0a 20 20 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d . get_line_from
3fe0: 5f 73 74 72 69 6e 67 28 70 7a 2c 20 70 4c 65 6e _string(pz, pLen
3ff0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a 3b 20 20 );. return z;
4000: 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f .}../*.** To
4010: 6b 65 6e 69 7a 65 20 61 20 6c 69 6e 65 20 6f 66 kenize a line of
4020: 20 74 65 78 74 20 69 6e 74 6f 20 61 73 20 6d 61 text into as ma
4030: 6e 79 20 61 73 20 6e 41 72 67 20 74 6f 6b 65 6e ny as nArg token
4040: 73 2e 20 20 4d 61 6b 65 0a 2a 2a 20 61 7a 41 72 s. Make.** azAr
4050: 67 5b 5d 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 g[] point to the
4060: 20 73 74 61 72 74 20 6f 66 20 65 61 63 68 20 74 start of each t
4070: 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 54 6f 6b 65 oken..**.** Toke
4080: 6e 73 20 63 6f 6e 73 69 73 74 20 6f 66 20 73 70 ns consist of sp
4090: 61 63 65 20 6f 72 20 73 65 6d 69 2d 63 6f 6c 6f ace or semi-colo
40a0: 6e 20 64 65 6c 69 6d 69 74 65 64 20 77 6f 72 64 n delimited word
40b0: 73 20 6f 72 0a 2a 2a 20 73 74 72 69 6e 67 73 20 s or.** strings
40c0: 69 6e 73 69 64 65 20 64 6f 75 62 6c 65 2d 71 75 inside double-qu
40d0: 6f 74 65 73 2e 20 20 45 78 61 6d 70 6c 65 3a 0a otes. Example:.
40e0: 2a 2a 0a 2a 2a 20 20 20 20 63 6f 6e 74 65 6e 74 **.** content
40f0: 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a 20 66 6f -disposition: fo
4100: 72 6d 2d 64 61 74 61 3b 20 6e 61 6d 65 3d 22 66 rm-data; name="f
4110: 6e 22 3b 20 66 69 6c 65 6e 61 6d 65 3d 22 69 6e n"; filename="in
4120: 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a 0a 2a 2a 20 dex.html".**.**
4130: 54 68 65 20 6c 69 6e 65 20 61 62 6f 76 65 20 69 The line above i
4140: 73 20 74 6f 6b 65 6e 69 7a 65 64 20 61 73 20 66 s tokenized as f
4150: 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 ollows:.**.**
4160: 20 61 7a 41 72 67 5b 30 5d 20 3d 20 22 63 6f 6e azArg[0] = "con
4170: 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e tent-disposition
4180: 3a 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 31 :".** azArg[1
4190: 5d 20 3d 20 22 66 6f 72 6d 2d 64 61 74 61 22 0a ] = "form-data".
41a0: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 32 5d 20 3d ** azArg[2] =
41b0: 20 22 6e 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61 "name=".** a
41c0: 7a 41 72 67 5b 33 5d 20 3d 20 22 66 6e 22 0a 2a zArg[3] = "fn".*
41d0: 2a 20 20 20 20 61 7a 41 72 67 5b 34 5d 20 3d 20 * azArg[4] =
41e0: 22 66 69 6c 65 6e 61 6d 65 3d 22 0a 2a 2a 20 20 "filename=".**
41f0: 20 20 61 7a 41 72 67 5b 35 5d 20 3d 20 22 69 6e azArg[5] = "in
4200: 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a 20 20 20 20 dex.html".**
4210: 61 7a 41 72 67 5b 36 5d 20 3d 20 30 3b 0a 2a 2a azArg[6] = 0;.**
4220: 0a 2a 2a 20 27 5c 30 30 30 27 20 63 68 61 72 61 .** '\000' chara
4230: 63 74 65 72 73 20 61 72 65 20 69 6e 73 65 72 74 cters are insert
4240: 65 64 20 69 6e 20 7a 5b 5d 20 61 74 20 74 68 65 ed in z[] at the
4250: 20 65 6e 64 20 6f 66 20 65 61 63 68 20 74 6f 6b end of each tok
4260: 65 6e 2e 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 en..** This rout
4270: 69 6e 65 20 72 65 74 75 72 6e 73 20 74 68 65 20 ine returns the
4280: 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 total number of
4290: 74 6f 6b 65 6e 73 20 6f 6e 20 74 68 65 20 6c 69 tokens on the li
42a0: 6e 65 2c 20 36 0a 2a 2a 20 69 6e 20 74 68 65 20 ne, 6.** in the
42b0: 65 78 61 6d 70 6c 65 20 61 62 6f 76 65 2e 0a 2a example above..*
42c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 6f 6b /.static int tok
42d0: 65 6e 69 7a 65 5f 6c 69 6e 65 28 63 68 61 72 20 enize_line(char
42e0: 2a 7a 2c 20 69 6e 74 20 6d 78 41 72 67 2c 20 63 *z, int mxArg, c
42f0: 68 61 72 20 2a 2a 61 7a 41 72 67 29 7b 0a 20 20 har **azArg){.
4300: 69 6e 74 20 69 20 3d 20 30 3b 0a 20 20 77 68 69 int i = 0;. whi
4310: 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 77 68 le( *z ){. wh
4320: 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a 29 ile( isspace(*z)
4330: 20 7c 7c 20 2a 7a 3d 3d 27 3b 27 20 29 7b 20 7a || *z==';' ){ z
4340: 2b 2b 3b 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a ++; }. if( *z
4350: 3d 3d 27 22 27 20 26 26 20 7a 5b 31 5d 20 29 7b =='"' && z[1] ){
4360: 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 . *z = 0;.
4370: 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 z++;.
4380: 69 66 28 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b if( i<mxArg-1 ){
4390: 20 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b azArg[i++] = z;
43a0: 20 7d 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 }. while(
43b0: 2a 7a 20 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b *z && *z!='"' ){
43c0: 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 z++; }. if
43d0: 28 20 2a 7a 3d 3d 30 20 29 20 62 72 65 61 6b 3b ( *z==0 ) break;
43e0: 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 . *z = 0;.
43f0: 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 7d 65 z++;. }e
4400: 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 69 lse{. if( i
4410: 3c 6d 78 41 72 67 2d 31 20 29 7b 20 61 7a 41 72 <mxArg-1 ){ azAr
4420: 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a 20 20 g[i++] = z; }.
4430: 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 while( *z &&
4440: 20 21 69 73 73 70 61 63 65 28 2a 7a 29 20 26 26 !isspace(*z) &&
4450: 20 2a 7a 21 3d 27 3b 27 20 26 26 20 2a 7a 21 3d *z!=';' && *z!=
4460: 27 22 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 '"' ){ z++; }.
4470: 20 20 20 20 69 66 28 20 2a 7a 20 26 26 20 2a 7a if( *z && *z
4480: 21 3d 27 22 27 20 29 7b 0a 20 20 20 20 20 20 20 !='"' ){.
4490: 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 *z = 0;.
44a0: 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 z++;. }.
44b0: 20 20 7d 0a 20 20 7d 0a 20 20 61 7a 41 72 67 5b }. }. azArg[
44c0: 69 5d 20 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e i] = 0;. return
44d0: 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 63 61 i;.}../*.** Sca
44e0: 6e 20 74 68 65 20 6d 75 6c 74 69 70 61 72 74 2d n the multipart-
44f0: 66 6f 72 6d 20 63 6f 6e 74 65 6e 74 20 61 6e 64 form content and
4500: 20 6d 61 6b 65 20 61 70 70 72 6f 70 72 69 61 74 make appropriat
4510: 65 20 65 6e 74 72 69 65 73 0a 2a 2a 20 69 6e 74 e entries.** int
4520: 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 o the parameter
4530: 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 table..**.** The
4540: 20 63 6f 6e 74 65 6e 74 20 73 74 72 69 6e 67 20 content string
4550: 22 7a 22 20 69 73 20 6d 6f 64 69 66 69 65 64 20 "z" is modified
4560: 62 79 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 by this routine
4570: 62 75 74 20 69 74 20 69 73 0a 2a 2a 20 6e 6f 74 but it is.** not
4580: 20 63 6f 70 69 65 64 2e 20 20 54 68 65 20 63 61 copied. The ca
4590: 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e 20 6d lling function m
45a0: 75 73 74 20 6e 6f 74 20 64 65 61 6c 6c 6f 63 61 ust not dealloca
45b0: 74 65 20 6f 72 20 6d 6f 64 69 66 79 0a 2a 2a 20 te or modify.**
45c0: 22 7a 22 20 61 66 74 65 72 20 74 68 69 73 20 72 "z" after this r
45d0: 6f 75 74 69 6e 65 20 66 69 6e 69 73 68 65 73 20 outine finishes
45e0: 6f 72 20 69 74 20 63 6f 75 6c 64 20 63 6f 72 72 or it could corr
45f0: 75 70 74 20 74 68 65 20 70 61 72 61 6d 65 74 65 upt the paramete
4600: 72 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 r.** table..*/.s
4610: 74 61 74 69 63 20 76 6f 69 64 20 70 72 6f 63 65 tatic void proce
4620: 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66 6f 72 ss_multipart_for
4630: 6d 5f 64 61 74 61 28 63 68 61 72 20 2a 7a 2c 20 m_data(char *z,
4640: 69 6e 74 20 6c 65 6e 29 7b 0a 20 20 63 68 61 72 int len){. char
4650: 20 2a 7a 4c 69 6e 65 3b 0a 20 20 69 6e 74 20 6e *zLine;. int n
4660: 41 72 67 2c 20 69 3b 0a 20 20 63 68 61 72 20 2a Arg, i;. char *
4670: 7a 42 6f 75 6e 64 72 79 3b 0a 20 20 63 68 61 72 zBoundry;. char
4680: 20 2a 7a 56 61 6c 75 65 3b 0a 20 20 63 68 61 72 *zValue;. char
4690: 20 2a 7a 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 69 *zName = 0;. i
46a0: 6e 74 20 73 68 6f 77 42 79 74 65 73 20 3d 20 30 nt showBytes = 0
46b0: 3b 0a 20 20 63 68 61 72 20 2a 61 7a 41 72 67 5b ;. char *azArg[
46c0: 35 30 5d 3b 0a 0a 20 20 7a 42 6f 75 6e 64 72 79 50];.. zBoundry
46d0: 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d = get_line_from
46e0: 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 6c 65 6e _string(&z, &len
46f0: 29 3b 0a 20 20 69 66 28 20 7a 42 6f 75 6e 64 72 );. if( zBoundr
4700: 79 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 y==0 ) return;.
4710: 20 77 68 69 6c 65 28 20 28 7a 4c 69 6e 65 20 3d while( (zLine =
4720: 20 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 get_line_from_s
4730: 74 72 69 6e 67 28 26 7a 2c 20 26 6c 65 6e 29 29 tring(&z, &len))
4740: 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a !=0 ){. if( z
4750: 4c 69 6e 65 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 Line[0]==0 ){.
4760: 20 20 20 20 69 6e 74 20 6e 43 6f 6e 74 65 6e 74 int nContent
4770: 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a 56 61 6c = 0;. zVal
4780: 75 65 20 3d 20 67 65 74 5f 62 6f 75 6e 64 65 64 ue = get_bounded
4790: 5f 63 6f 6e 74 65 6e 74 28 26 7a 2c 20 26 6c 65 _content(&z, &le
47a0: 6e 2c 20 7a 42 6f 75 6e 64 72 79 2c 20 26 6e 43 n, zBoundry, &nC
47b0: 6f 6e 74 65 6e 74 29 3b 0a 20 20 20 20 20 20 69 ontent);. i
47c0: 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a 56 61 6c f( zName && zVal
47d0: 75 65 20 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e ue && islower(zN
47e0: 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 ame[0]) ){.
47f0: 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d cgi_set_param
4800: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d eter_nocopy(zNam
4810: 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 e, zValue);.
4820: 20 20 20 20 69 66 28 20 73 68 6f 77 42 79 74 65 if( showByte
4830: 73 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63 s ){. c
4840: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 gi_set_parameter
4850: 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 _nocopy(mprintf(
4860: 22 25 73 3a 62 79 74 65 73 22 2c 20 7a 4e 61 6d "%s:bytes", zNam
4870: 65 29 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 e),.
4880: 20 20 20 6d 70 72 69 6e 74 66 28 22 25 64 22 2c mprintf("%d",
4890: 6e 43 6f 6e 74 65 6e 74 29 29 3b 0a 20 20 20 20 nContent));.
48a0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 }. }.
48b0: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 30 3b 0a 20 zName = 0;.
48c0: 20 20 20 20 20 73 68 6f 77 42 79 74 65 73 20 3d showBytes =
48d0: 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 0;. }else{.
48e0: 20 20 20 20 20 6e 41 72 67 20 3d 20 74 6f 6b 65 nArg = toke
48f0: 6e 69 7a 65 5f 6c 69 6e 65 28 7a 4c 69 6e 65 2c nize_line(zLine,
4900: 20 73 69 7a 65 6f 66 28 61 7a 41 72 67 29 2f 73 sizeof(azArg)/s
4910: 69 7a 65 6f 66 28 61 7a 41 72 67 5b 30 5d 29 2c izeof(azArg[0]),
4920: 20 61 7a 41 72 67 29 3b 0a 20 20 20 20 20 20 66 azArg);. f
4930: 6f 72 28 69 3d 30 3b 20 69 3c 6e 41 72 67 3b 20 or(i=0; i<nArg;
4940: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 69 6e i++){. in
4950: 74 20 63 20 3d 20 74 6f 6c 6f 77 65 72 28 61 7a t c = tolower(az
4960: 41 72 67 5b 69 5d 5b 30 5d 29 3b 0a 20 20 20 20 Arg[i][0]);.
4970: 20 20 20 20 69 66 28 20 63 3d 3d 27 63 27 20 26 if( c=='c' &
4980: 26 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b & stricmp(azArg[
4990: 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 i],"content-disp
49a0: 6f 73 69 74 69 6f 6e 3a 22 29 3d 3d 30 20 29 7b osition:")==0 ){
49b0: 0a 20 20 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a . i++;.
49c0: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 }else if
49d0: 28 20 63 3d 3d 27 6e 27 20 26 26 20 73 74 72 69 ( c=='n' && stri
49e0: 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 6e 61 cmp(azArg[i],"na
49f0: 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 me=")==0 ){.
4a00: 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 61 7a zName = az
4a10: 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 Arg[++i];.
4a20: 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 }else if( c=='
4a30: 66 27 20 26 26 20 73 74 72 69 63 6d 70 28 61 7a f' && stricmp(az
4a40: 41 72 67 5b 69 5d 2c 22 66 69 6c 65 6e 61 6d 65 Arg[i],"filename
4a50: 3d 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 =")==0 ){.
4a60: 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a char *z = az
4a70: 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 Arg[++i];.
4a80: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 if( zName &&
4a90: 20 7a 20 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e z && islower(zN
4aa0: 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 ame[0]) ){.
4ab0: 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 cgi_set_p
4ac0: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 arameter_nocopy(
4ad0: 6d 70 72 69 6e 74 66 28 22 25 73 3a 66 69 6c 65 mprintf("%s:file
4ae0: 6e 61 6d 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29 name",zName), z)
4af0: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 ;. }.
4b00: 20 20 20 20 20 20 20 20 73 68 6f 77 42 79 74 65 showByte
4b10: 73 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 20 7d s = 1;. }
4b20: 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 63 27 20 else if( c=='c'
4b30: 26 26 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 && stricmp(azArg
4b40: 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 [i],"content-typ
4b50: 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 e:")==0 ){.
4b60: 20 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 61 char *z = a
4b70: 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 zArg[++i];.
4b80: 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 if( zName &
4b90: 26 20 7a 20 26 26 20 69 73 6c 6f 77 65 72 28 7a & z && islower(z
4ba0: 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 Name[0]) ){.
4bb0: 20 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f cgi_set_
4bc0: 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 parameter_nocopy
4bd0: 28 6d 70 72 69 6e 74 66 28 22 25 73 3a 6d 69 6d (mprintf("%s:mim
4be0: 65 74 79 70 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a etype",zName), z
4bf0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 );. }.
4c00: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d }. }
4c10: 0a 20 20 20 20 7d 0a 20 20 7d 20 20 20 20 20 20 . }. }
4c20: 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 .}../*.** Init
4c30: 69 61 6c 69 7a 65 20 74 68 65 20 71 75 65 72 79 ialize the query
4c40: 20 70 61 72 61 6d 65 74 65 72 20 64 61 74 61 62 parameter datab
4c50: 61 73 65 2e 20 20 49 6e 66 6f 72 6d 61 74 69 6f ase. Informatio
4c60: 6e 20 69 73 20 70 75 6c 6c 65 64 20 66 72 6f 6d n is pulled from
4c70: 0a 2a 2a 20 74 68 65 20 51 55 45 52 59 5f 53 54 .** the QUERY_ST
4c80: 52 49 4e 47 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 RING environment
4c90: 20 76 61 72 69 61 62 6c 65 20 28 69 66 20 69 74 variable (if it
4ca0: 20 65 78 69 73 74 73 29 2c 20 66 72 6f 6d 20 73 exists), from s
4cb0: 74 61 6e 64 61 72 64 0a 2a 2a 20 69 6e 70 75 74 tandard.** input
4cc0: 20 69 66 20 74 68 65 72 65 20 69 73 20 50 4f 53 if there is POS
4cd0: 54 20 64 61 74 61 2c 20 61 6e 64 20 66 72 6f 6d T data, and from
4ce0: 20 48 54 54 50 5f 43 4f 4f 4b 49 45 2e 0a 2a 2f HTTP_COOKIE..*/
4cf0: 0a 76 6f 69 64 20 63 67 69 5f 69 6e 69 74 28 76 .void cgi_init(v
4d00: 6f 69 64 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b oid){. char *z;
4d10: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a . const char *z
4d20: 54 79 70 65 3b 0a 20 20 69 6e 74 20 6c 65 6e 3b Type;. int len;
4d30: 0a 20 20 63 67 69 5f 64 65 73 74 69 6e 61 74 69 . cgi_destinati
4d40: 6f 6e 28 43 47 49 5f 42 4f 44 59 29 3b 0a 20 20 on(CGI_BODY);.
4d50: 7a 20 3d 20 28 63 68 61 72 2a 29 50 28 22 51 55 z = (char*)P("QU
4d60: 45 52 59 5f 53 54 52 49 4e 47 22 29 3b 0a 20 20 ERY_STRING");.
4d70: 69 66 28 20 7a 20 29 7b 0a 20 20 20 20 7a 20 3d if( z ){. z =
4d80: 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 29 mprintf("%s",z)
4d90: 3b 0a 20 20 20 20 61 64 64 5f 70 61 72 61 6d 5f ;. add_param_
4da0: 6c 69 73 74 28 7a 2c 20 27 26 27 29 3b 0a 20 20 list(z, '&');.
4db0: 7d 0a 0a 20 20 7a 20 3d 20 50 28 22 52 45 4d 4f }.. z = P("REMO
4dc0: 54 45 5f 41 44 44 52 22 29 3b 0a 20 20 69 66 28 TE_ADDR");. if(
4dd0: 20 7a 20 29 20 67 2e 7a 49 70 41 64 64 72 20 3d z ) g.zIpAddr =
4de0: 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a mprintf("%s", z
4df0: 29 3b 0a 0a 20 20 6c 65 6e 20 3d 20 61 74 6f 69 );.. len = atoi
4e00: 28 50 44 28 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e (PD("CONTENT_LEN
4e10: 47 54 48 22 2c 20 22 30 22 29 29 3b 0a 20 20 67 GTH", "0"));. g
4e20: 2e 7a 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 .zContentType =
4e30: 7a 54 79 70 65 20 3d 20 50 28 22 43 4f 4e 54 45 zType = P("CONTE
4e40: 4e 54 5f 54 59 50 45 22 29 3b 0a 20 20 69 66 28 NT_TYPE");. if(
4e50: 20 6c 65 6e 3e 30 20 26 26 20 7a 54 79 70 65 20 len>0 && zType
4e60: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 7a 65 72 6f ){. blob_zero
4e70: 28 26 67 2e 63 67 69 49 6e 29 3b 0a 20 20 20 20 (&g.cgiIn);.
4e80: 69 66 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65 if( strcmp(zType
4e90: 2c 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d ,"application/x-
4ea0: 77 77 77 2d 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f www-form-urlenco
4eb0: 64 65 64 22 29 3d 3d 30 20 0a 20 20 20 20 20 20 ded")==0 .
4ec0: 20 20 20 7c 7c 20 73 74 72 6e 63 6d 70 28 7a 54 || strncmp(zT
4ed0: 79 70 65 2c 22 6d 75 6c 74 69 70 61 72 74 2f 66 ype,"multipart/f
4ee0: 6f 72 6d 2d 64 61 74 61 22 2c 31 39 29 3d 3d 30 orm-data",19)==0
4ef0: 20 29 7b 0a 20 20 20 20 20 20 7a 20 3d 20 6d 61 ){. z = ma
4f00: 6c 6c 6f 63 28 20 6c 65 6e 2b 31 20 29 3b 0a 20 lloc( len+1 );.
4f10: 20 20 20 20 20 69 66 28 20 7a 3d 3d 30 20 29 20 if( z==0 )
4f20: 65 78 69 74 28 31 29 3b 0a 20 20 20 20 20 20 6c exit(1);. l
4f30: 65 6e 20 3d 20 66 72 65 61 64 28 7a 2c 20 31 2c en = fread(z, 1,
4f40: 20 6c 65 6e 2c 20 67 2e 68 74 74 70 49 6e 29 3b len, g.httpIn);
4f50: 0a 20 20 20 20 20 20 7a 5b 6c 65 6e 5d 20 3d 20 . z[len] =
4f60: 30 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 54 79 0;. if( zTy
4f70: 70 65 5b 30 5d 3d 3d 27 61 27 20 29 7b 0a 20 20 pe[0]=='a' ){.
4f80: 20 20 20 20 20 20 61 64 64 5f 70 61 72 61 6d 5f add_param_
4f90: 6c 69 73 74 28 7a 2c 20 27 26 27 29 3b 0a 20 20 list(z, '&');.
4fa0: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 }else{.
4fb0: 20 20 20 70 72 6f 63 65 73 73 5f 6d 75 6c 74 69 process_multi
4fc0: 70 61 72 74 5f 66 6f 72 6d 5f 64 61 74 61 28 7a part_form_data(z
4fd0: 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 7d 0a , len);. }.
4fe0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 }else if( st
4ff0: 72 63 6d 70 28 7a 54 79 70 65 2c 20 22 61 70 70 rcmp(zType, "app
5000: 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 lication/x-fossi
5010: 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 l")==0 ){.
5020: 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 63 blob_read_from_c
5030: 68 61 6e 6e 65 6c 28 26 67 2e 63 67 69 49 6e 2c hannel(&g.cgiIn,
5040: 20 67 2e 68 74 74 70 49 6e 2c 20 6c 65 6e 29 3b g.httpIn, len);
5050: 0a 20 20 20 20 20 20 62 6c 6f 62 5f 75 6e 63 6f . blob_unco
5060: 6d 70 72 65 73 73 28 26 67 2e 63 67 69 49 6e 2c mpress(&g.cgiIn,
5070: 20 26 67 2e 63 67 69 49 6e 29 3b 0a 20 20 20 20 &g.cgiIn);.
5080: 20 20 2f 2a 20 49 66 20 74 68 65 20 63 6f 6e 74 /* If the cont
5090: 65 6e 74 20 74 79 70 65 20 69 73 20 61 70 70 6c ent type is appl
50a0: 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c ication/x-fossil
50b0: 2c 20 74 68 65 6e 20 69 67 6e 6f 72 65 0a 20 20 , then ignore.
50c0: 20 20 20 20 2a 2a 20 74 68 65 20 70 61 74 68 20 ** the path
50d0: 69 6e 20 74 68 65 20 66 69 72 73 74 20 6c 69 6e in the first lin
50e0: 65 20 6f 66 20 74 68 65 20 48 54 54 50 20 68 65 e of the HTTP he
50f0: 61 64 65 72 20 61 6e 64 20 61 6c 77 61 79 73 0a ader and always.
5100: 20 20 20 20 20 20 2a 2a 20 75 73 65 20 74 68 65 ** use the
5110: 20 2f 78 66 65 72 20 6d 65 74 68 6f 64 20 73 69 /xfer method si
5120: 6e 63 65 20 74 68 65 20 2f 78 66 65 72 20 6d 65 nce the /xfer me
5130: 74 68 6f 64 20 69 73 20 74 68 65 20 6f 6e 6c 79 thod is the only
5140: 0a 20 20 20 20 20 20 2a 2a 20 6d 65 74 68 6f 64 . ** method
5150: 20 74 68 61 74 20 75 6e 64 65 72 73 74 61 6e 64 that understand
5160: 73 20 74 68 65 20 61 70 70 6c 69 63 61 74 69 6f s the applicatio
5170: 6e 2f 78 2d 66 6f 73 73 69 6c 20 63 6f 6e 74 65 n/x-fossil conte
5180: 6e 74 0a 20 20 20 20 20 20 2a 2a 20 74 79 70 65 nt. ** type
5190: 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 20 20 20 20 .. */.
51a0: 20 63 67 69 5f 72 65 70 6c 61 63 65 5f 70 61 72 cgi_replace_par
51b0: 61 6d 65 74 65 72 28 22 50 41 54 48 5f 49 4e 46 ameter("PATH_INF
51c0: 4f 22 2c 20 22 2f 78 66 65 72 22 29 3b 0a 20 20 O", "/xfer");.
51d0: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 }else if( strc
51e0: 6d 70 28 7a 54 79 70 65 2c 20 22 61 70 70 6c 69 mp(zType, "appli
51f0: 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 2d cation/x-fossil-
5200: 64 65 62 75 67 22 29 3d 3d 30 20 29 7b 0a 20 20 debug")==0 ){.
5210: 20 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 blob_read_fr
5220: 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26 67 2e 63 67 om_channel(&g.cg
5230: 69 49 6e 2c 20 67 2e 68 74 74 70 49 6e 2c 20 6c iIn, g.httpIn, l
5240: 65 6e 29 3b 0a 20 20 20 20 20 20 63 67 69 5f 72 en);. cgi_r
5250: 65 70 6c 61 63 65 5f 70 61 72 61 6d 65 74 65 72 eplace_parameter
5260: 28 22 50 41 54 48 5f 49 4e 46 4f 22 2c 20 22 2f ("PATH_INFO", "/
5270: 78 66 65 72 22 29 3b 20 20 2f 2a 20 53 65 65 20 xfer"); /* See
5280: 63 6f 6d 6d 65 6e 74 20 61 62 6f 76 65 20 2a 2f comment above */
5290: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 20 . }. }.. z
52a0: 3d 20 28 63 68 61 72 2a 29 50 28 22 48 54 54 50 = (char*)P("HTTP
52b0: 5f 43 4f 4f 4b 49 45 22 29 3b 0a 20 20 69 66 28 _COOKIE");. if(
52c0: 20 7a 20 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 z ){. z = mp
52d0: 72 69 6e 74 66 28 22 25 73 22 2c 7a 29 3b 0a 20 rintf("%s",z);.
52e0: 20 20 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 add_param_lis
52f0: 74 28 7a 2c 20 27 3b 27 29 3b 0a 20 20 7d 0a 7d t(z, ';');. }.}
5300: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 ../*.** This is
5310: 74 68 65 20 63 6f 6d 70 61 72 69 73 6f 6e 20 66 the comparison f
5320: 75 6e 63 74 69 6f 6e 20 75 73 65 64 20 74 6f 20 unction used to
5330: 73 6f 72 74 20 74 68 65 20 61 50 61 72 61 6d 51 sort the aParamQ
5340: 50 5b 5d 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 P[] array of.**
5350: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 query parameters
5360: 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2e 0a 2a 2f and cookies..*/
5370: 0a 73 74 61 74 69 63 20 69 6e 74 20 71 70 61 72 .static int qpar
5380: 61 6d 5f 63 6f 6d 70 61 72 65 28 63 6f 6e 73 74 am_compare(const
5390: 20 76 6f 69 64 20 2a 61 2c 20 63 6f 6e 73 74 20 void *a, const
53a0: 76 6f 69 64 20 2a 62 29 7b 0a 20 20 73 74 72 75 void *b){. stru
53b0: 63 74 20 51 50 61 72 61 6d 20 2a 70 41 20 3d 20 ct QParam *pA =
53c0: 28 73 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29 (struct QParam*)
53d0: 61 3b 0a 20 20 73 74 72 75 63 74 20 51 50 61 72 a;. struct QPar
53e0: 61 6d 20 2a 70 42 20 3d 20 28 73 74 72 75 63 74 am *pB = (struct
53f0: 20 51 50 61 72 61 6d 2a 29 62 3b 0a 20 20 69 6e QParam*)b;. in
5400: 74 20 63 3b 0a 20 20 63 20 3d 20 73 74 72 63 6d t c;. c = strcm
5410: 70 28 70 41 2d 3e 7a 4e 61 6d 65 2c 20 70 42 2d p(pA->zName, pB-
5420: 3e 7a 4e 61 6d 65 29 3b 0a 20 20 69 66 28 20 63 >zName);. if( c
5430: 3d 3d 30 20 29 7b 0a 20 20 20 20 63 20 3d 20 70 ==0 ){. c = p
5440: 41 2d 3e 73 65 71 20 2d 20 70 42 2d 3e 73 65 71 A->seq - pB->seq
5450: 3b 0a 20 20 7d 0a 20 20 72 65 74 75 72 6e 20 63 ;. }. return c
5460: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 ;.}../*.** Retur
5470: 6e 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 61 n the value of a
5480: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 query parameter
5490: 20 6f 72 20 63 6f 6f 6b 69 65 20 77 68 6f 73 65 or cookie whose
54a0: 20 6e 61 6d 65 20 69 73 20 7a 4e 61 6d 65 2e 0a name is zName..
54b0: 2a 2a 20 49 66 20 74 68 65 72 65 20 69 73 20 6e ** If there is n
54c0: 6f 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 o query paramete
54d0: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 r or cookie name
54e0: 64 20 7a 4e 61 6d 65 20 61 6e 64 20 74 68 65 20 d zName and the
54f0: 66 69 72 73 74 0a 2a 2a 20 63 68 61 72 61 63 74 first.** charact
5500: 65 72 20 6f 66 20 7a 4e 61 6d 65 20 69 73 20 75 er of zName is u
5510: 70 70 65 72 63 61 73 65 2c 20 74 68 65 6e 20 63 ppercase, then c
5520: 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74 heck to see if t
5530: 68 65 72 65 20 69 73 20 61 6e 0a 2a 2a 20 65 6e here is an.** en
5540: 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 vironment variab
5550: 6c 65 20 62 79 20 74 68 61 74 20 6e 61 6d 65 20 le by that name
5560: 61 6e 64 20 72 65 74 75 72 6e 20 69 74 20 69 66 and return it if
5570: 20 74 68 65 72 65 20 69 73 2e 20 20 41 73 0a 2a there is. As.*
5580: 2a 20 61 20 6c 61 73 74 20 72 65 73 6f 72 74 20 * a last resort
5590: 77 68 65 6e 20 6e 6f 74 68 69 6e 67 20 65 6c 73 when nothing els
55a0: 65 20 6d 61 74 63 68 65 73 2c 20 72 65 74 75 72 e matches, retur
55b0: 6e 20 7a 44 65 66 61 75 6c 74 2e 0a 2a 2f 0a 63 n zDefault..*/.c
55c0: 6f 6e 73 74 20 63 68 61 72 20 2a 63 67 69 5f 70 onst char *cgi_p
55d0: 61 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 20 63 arameter(const c
55e0: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 har *zName, cons
55f0: 74 20 63 68 61 72 20 2a 7a 44 65 66 61 75 6c 74 t char *zDefault
5600: 29 7b 0a 20 20 69 6e 74 20 6c 6f 2c 20 68 69 2c ){. int lo, hi,
5610: 20 6d 69 64 2c 20 63 3b 0a 0a 20 20 2f 2a 20 54 mid, c;.. /* T
5620: 68 65 20 73 6f 72 74 51 50 20 66 6c 61 67 20 69 he sortQP flag i
5630: 73 20 73 65 74 20 77 68 65 6e 65 76 65 72 20 61 s set whenever a
5640: 20 6e 65 77 20 71 75 65 72 79 20 70 61 72 61 6d new query param
5650: 65 74 65 72 20 69 73 20 69 6e 73 65 72 74 65 64 eter is inserted
5660: 2e 0a 20 20 2a 2a 20 49 74 20 69 6e 64 69 63 61 .. ** It indica
5670: 74 65 73 20 74 68 61 74 20 77 65 20 6e 65 65 64 tes that we need
5680: 20 74 6f 20 72 65 73 6f 72 74 20 74 68 65 20 71 to resort the q
5690: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 2e uery parameters.
56a0: 0a 20 20 2a 2f 0a 20 20 69 66 28 20 73 6f 72 74 . */. if( sort
56b0: 51 50 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 2c QP ){. int i,
56c0: 20 6a 3b 0a 20 20 20 20 71 73 6f 72 74 28 61 50 j;. qsort(aP
56d0: 61 72 61 6d 51 50 2c 20 6e 55 73 65 64 51 50 2c aramQP, nUsedQP,
56e0: 20 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51 50 sizeof(aParamQP
56f0: 5b 30 5d 29 2c 20 71 70 61 72 61 6d 5f 63 6f 6d [0]), qparam_com
5700: 70 61 72 65 29 3b 0a 20 20 20 20 73 6f 72 74 51 pare);. sortQ
5710: 50 20 3d 20 30 3b 0a 20 20 20 20 2f 2a 20 41 66 P = 0;. /* Af
5720: 74 65 72 20 73 6f 72 74 69 6e 67 2c 20 72 65 6d ter sorting, rem
5730: 6f 76 65 20 64 75 70 6c 69 63 61 74 65 20 70 61 ove duplicate pa
5740: 72 61 6d 65 74 65 72 73 2e 20 20 54 68 65 20 73 rameters. The s
5750: 65 63 6f 6e 64 61 72 79 20 73 6f 72 74 0a 20 20 econdary sort.
5760: 20 20 2a 2a 20 6b 65 79 20 69 73 20 61 50 61 72 ** key is aPar
5770: 61 6d 51 50 5b 5d 2e 73 65 71 20 61 6e 64 20 77 amQP[].seq and w
5780: 65 20 6b 65 65 70 20 74 68 65 20 66 69 72 73 74 e keep the first
5790: 20 65 6e 74 72 79 2e 20 20 54 68 61 74 20 6d 65 entry. That me
57a0: 61 6e 73 0a 20 20 20 20 2a 2a 20 77 69 74 68 20 ans. ** with
57b0: 64 75 70 6c 69 63 61 74 65 20 63 61 6c 6c 73 20 duplicate calls
57c0: 74 6f 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d to cgi_set_param
57d0: 65 74 65 72 28 29 20 74 68 65 20 73 65 63 6f 6e eter() the secon
57e0: 64 20 61 6e 64 0a 20 20 20 20 2a 2a 20 73 75 62 d and. ** sub
57f0: 73 65 71 75 65 6e 74 20 63 61 6c 6c 73 20 61 72 sequent calls ar
5800: 65 20 65 66 66 65 63 74 69 76 65 6c 79 20 6e 6f e effectively no
5810: 2d 6f 70 73 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 -ops. */. for
5820: 28 69 3d 6a 3d 31 3b 20 69 3c 6e 55 73 65 64 51 (i=j=1; i<nUsedQ
5830: 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 P; i++){. i
5840: 66 28 20 73 74 72 63 6d 70 28 61 50 61 72 61 6d f( strcmp(aParam
5850: 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 61 50 61 72 QP[i].zName,aPar
5860: 61 6d 51 50 5b 69 2d 31 5d 2e 7a 4e 61 6d 65 29 amQP[i-1].zName)
5870: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63 ==0 ){. c
5880: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d ontinue;. }
5890: 0a 20 20 20 20 20 20 69 66 28 20 6a 3c 69 20 29 . if( j<i )
58a0: 7b 0a 20 20 20 20 20 20 20 20 6d 65 6d 63 70 79 {. memcpy
58b0: 28 26 61 50 61 72 61 6d 51 50 5b 6a 5d 2c 20 26 (&aParamQP[j], &
58c0: 61 50 61 72 61 6d 51 50 5b 69 5d 2c 20 73 69 7a aParamQP[i], siz
58d0: 65 6f 66 28 61 50 61 72 61 6d 51 50 5b 6a 5d 29 eof(aParamQP[j])
58e0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 );. }.
58f0: 20 6a 2b 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 j++;. }.
5900: 6e 55 73 65 64 51 50 20 3d 20 6a 3b 0a 20 20 7d nUsedQP = j;. }
5910: 0a 0a 20 20 2f 2a 20 44 6f 20 61 20 62 69 6e 61 .. /* Do a bina
5920: 72 79 20 73 65 61 72 63 68 20 66 6f 72 20 61 20 ry search for a
5930: 6d 61 74 63 68 69 6e 67 20 71 75 65 72 79 20 70 matching query p
5940: 61 72 61 6d 65 74 65 72 20 2a 2f 0a 20 20 6c 6f arameter */. lo
5950: 20 3d 20 30 3b 0a 20 20 68 69 20 3d 20 6e 55 73 = 0;. hi = nUs
5960: 65 64 51 50 2d 31 3b 0a 20 20 77 68 69 6c 65 28 edQP-1;. while(
5970: 20 6c 6f 3c 3d 68 69 20 29 7b 0a 20 20 20 20 6d lo<=hi ){. m
5980: 69 64 20 3d 20 28 6c 6f 2b 68 69 29 2f 32 3b 0a id = (lo+hi)/2;.
5990: 20 20 20 20 63 20 3d 20 73 74 72 63 6d 70 28 61 c = strcmp(a
59a0: 50 61 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 4e 61 ParamQP[mid].zNa
59b0: 6d 65 2c 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 me, zName);.
59c0: 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20 if( c==0 ){.
59d0: 20 20 43 47 49 44 45 42 55 47 28 28 22 6d 65 6d CGIDEBUG(("mem
59e0: 2d 6d 61 74 63 68 20 5b 25 73 5d 20 3d 20 5b 25 -match [%s] = [%
59f0: 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c 20 61 50 s]\n", zName, aP
5a00: 61 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c aramQP[mid].zVal
5a10: 75 65 29 29 3b 0a 20 20 20 20 20 20 72 65 74 75 ue));. retu
5a20: 72 6e 20 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d rn aParamQP[mid]
5a30: 2e 7a 56 61 6c 75 65 3b 0a 20 20 20 20 7d 65 6c .zValue;. }el
5a40: 73 65 20 69 66 28 20 63 3e 30 20 29 7b 0a 20 20 se if( c>0 ){.
5a50: 20 20 20 20 68 69 20 3d 20 6d 69 64 2d 31 3b 0a hi = mid-1;.
5a60: 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 }else{.
5a70: 20 6c 6f 20 3d 20 6d 69 64 2b 31 3b 0a 20 20 20 lo = mid+1;.
5a80: 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 }. }.. /* If
5a90: 6e 6f 20 6d 61 74 63 68 20 69 73 20 66 6f 75 6e no match is foun
5aa0: 64 20 61 6e 64 20 74 68 65 20 6e 61 6d 65 20 62 d and the name b
5ab0: 65 67 69 6e 73 20 77 69 74 68 20 61 6e 20 75 70 egins with an up
5ac0: 70 65 72 2d 63 61 73 65 0a 20 20 2a 2a 20 6c 65 per-case. ** le
5ad0: 74 74 65 72 2c 20 74 68 65 6e 20 63 68 65 63 6b tter, then check
5ae0: 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 72 65 to see if there
5af0: 20 69 73 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 is an environme
5b00: 6e 74 20 76 61 72 69 61 62 6c 65 0a 20 20 2a 2a nt variable. **
5b10: 20 77 69 74 68 20 74 68 65 20 67 69 76 65 6e 20 with the given
5b20: 6e 61 6d 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 name.. */. if(
5b30: 20 69 73 75 70 70 65 72 28 7a 4e 61 6d 65 5b 30 isupper(zName[0
5b40: 5d 29 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 ]) ){. const
5b50: 63 68 61 72 20 2a 7a 56 61 6c 75 65 20 3d 20 67 char *zValue = g
5b60: 65 74 65 6e 76 28 7a 4e 61 6d 65 29 3b 0a 20 20 etenv(zName);.
5b70: 20 20 69 66 28 20 7a 56 61 6c 75 65 20 29 7b 0a if( zValue ){.
5b80: 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 cgi_set_pa
5b90: 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a rameter_nocopy(z
5ba0: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 Name, zValue);.
5bb0: 20 20 20 20 20 43 47 49 44 45 42 55 47 28 28 22 CGIDEBUG(("
5bc0: 65 6e 76 2d 6d 61 74 63 68 20 5b 25 73 5d 20 3d env-match [%s] =
5bd0: 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c [%s]\n", zName,
5be0: 20 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20 20 zValue));.
5bf0: 20 72 65 74 75 72 6e 20 7a 56 61 6c 75 65 3b 0a return zValue;.
5c00: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 43 47 49 44 }. }. CGID
5c10: 45 42 55 47 28 28 22 6e 6f 2d 6d 61 74 63 68 20 EBUG(("no-match
5c20: 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 29 29 [%s]\n", zName))
5c30: 3b 0a 20 20 72 65 74 75 72 6e 20 7a 44 65 66 61 ;. return zDefa
5c40: 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 ult;.}../*.** Re
5c50: 74 75 72 6e 20 74 68 65 20 6e 61 6d 65 20 6f 66 turn the name of
5c60: 20 74 68 65 20 69 2d 74 68 20 43 47 49 20 70 61 the i-th CGI pa
5c70: 72 61 6d 65 74 65 72 2e 20 20 52 65 74 75 72 6e rameter. Return
5c80: 20 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 0a 2a NULL if there.*
5c90: 2a 20 61 72 65 20 66 65 77 65 72 20 74 68 61 6e * are fewer than
5ca0: 20 69 20 72 65 67 69 73 74 65 72 65 64 20 43 47 i registered CG
5cb0: 49 20 70 61 72 6d 61 65 74 65 72 73 2e 0a 2a 2f I parmaeters..*/
5cc0: 0a 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 67 69 .const char *cgi
5cd0: 5f 70 61 72 61 6d 65 74 65 72 5f 6e 61 6d 65 28 _parameter_name(
5ce0: 69 6e 74 20 69 29 7b 0a 20 20 69 66 28 20 69 3e int i){. if( i>
5cf0: 3d 30 20 26 26 20 69 3c 6e 55 73 65 64 51 50 20 =0 && i<nUsedQP
5d00: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 61 50 ){. return aP
5d10: 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 3b aramQP[i].zName;
5d20: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 72 65 . }else{. re
5d30: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 7d 0a 0a 2f turn 0;. }.}../
5d40: 2a 0a 2a 2a 20 50 72 69 6e 74 20 43 47 49 20 64 *.** Print CGI d
5d50: 65 62 75 67 67 69 6e 67 20 6d 65 73 73 61 67 65 ebugging message
5d60: 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 64 s..*/.void cgi_d
5d70: 65 62 75 67 28 63 6f 6e 73 74 20 63 68 61 72 20 ebug(const char
5d80: 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a *zFormat, ...){.
5d90: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 va_list ap;.
5da0: 69 66 28 20 67 2e 66 44 65 62 75 67 20 29 7b 0a if( g.fDebug ){.
5db0: 20 20 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c va_start(ap,
5dc0: 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 20 20 76 zFormat);. v
5dd0: 66 70 72 69 6e 74 66 28 67 2e 66 44 65 62 75 67 fprintf(g.fDebug
5de0: 2c 20 7a 46 6f 72 6d 61 74 2c 20 61 70 29 3b 0a , zFormat, ap);.
5df0: 20 20 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a va_end(ap);.
5e00: 20 20 20 20 66 66 6c 75 73 68 28 67 2e 66 44 65 fflush(g.fDe
5e10: 62 75 67 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a bug);. }.}../*.
5e20: 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 65 20 69 ** Return true i
5e30: 66 20 61 6e 79 20 6f 66 20 74 68 65 20 71 75 65 f any of the que
5e40: 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 69 6e ry parameters in
5e50: 20 74 68 65 20 61 72 67 75 6d 65 6e 74 0a 2a 2a the argument.**
5e60: 20 6c 69 73 74 20 61 72 65 20 64 65 66 69 6e 65 list are define
5e70: 64 2e 0a 2a 2f 0a 69 6e 74 20 63 67 69 5f 61 6e d..*/.int cgi_an
5e80: 79 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 2c y(const char *z,
5e90: 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 ...){. va_list
5ea0: 20 61 70 3b 0a 20 20 63 68 61 72 20 2a 7a 32 3b ap;. char *z2;
5eb0: 0a 20 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d . if( cgi_param
5ec0: 65 74 65 72 28 7a 2c 30 29 21 3d 30 20 29 20 72 eter(z,0)!=0 ) r
5ed0: 65 74 75 72 6e 20 31 3b 0a 20 20 76 61 5f 73 74 eturn 1;. va_st
5ee0: 61 72 74 28 61 70 2c 20 7a 29 3b 0a 20 20 77 68 art(ap, z);. wh
5ef0: 69 6c 65 28 20 28 7a 32 20 3d 20 76 61 5f 61 72 ile( (z2 = va_ar
5f00: 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 g(ap, char*))!=0
5f10: 20 29 7b 0a 20 20 20 20 69 66 28 20 63 67 69 5f ){. if( cgi_
5f20: 70 61 72 61 6d 65 74 65 72 28 7a 32 2c 30 29 21 parameter(z2,0)!
5f30: 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 =0 ) return 1;.
5f40: 20 7d 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b }. va_end(ap);
5f50: 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a . return 0;.}..
5f60: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 75 /*.** Return tru
5f70: 65 20 69 66 20 61 6c 6c 20 6f 66 20 74 68 65 20 e if all of the
5f80: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 query parameters
5f90: 20 69 6e 20 74 68 65 20 61 72 67 75 6d 65 6e 74 in the argument
5fa0: 20 6c 69 73 74 0a 2a 2a 20 61 72 65 20 64 65 66 list.** are def
5fb0: 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20 63 67 69 ined..*/.int cgi
5fc0: 5f 61 6c 6c 28 63 6f 6e 73 74 20 63 68 61 72 20 _all(const char
5fd0: 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c *z, ...){. va_l
5fe0: 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72 20 2a ist ap;. char *
5ff0: 7a 32 3b 0a 20 20 69 66 28 20 63 67 69 5f 70 61 z2;. if( cgi_pa
6000: 72 61 6d 65 74 65 72 28 7a 2c 30 29 3d 3d 30 20 rameter(z,0)==0
6010: 29 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 76 61 ) return 0;. va
6020: 5f 73 74 61 72 74 28 61 70 2c 20 7a 29 3b 0a 20 _start(ap, z);.
6030: 20 77 68 69 6c 65 28 20 28 7a 32 20 3d 20 76 61 while( (z2 = va
6040: 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a 29 29 _arg(ap, char*))
6050: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 63 ==0 ){. if( c
6060: 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 32 2c gi_parameter(z2,
6070: 30 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 0)==0 ) return 0
6080: 3b 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64 28 61 ;. }. va_end(a
6090: 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 31 3b 0a p);. return 1;.
60a0: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74 20 61 }../*.** Print a
60b0: 6c 6c 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 ll query paramet
60c0: 65 72 73 20 6f 6e 20 73 74 61 6e 64 61 72 64 20 ers on standard
60d0: 6f 75 74 70 75 74 2e 20 20 46 6f 72 6d 61 74 20 output. Format
60e0: 74 68 65 0a 2a 2a 20 70 61 72 61 6d 65 74 65 72 the.** parameter
60f0: 73 20 61 73 20 48 54 4d 4c 2e 20 20 54 68 69 73 s as HTML. This
6100: 20 69 73 20 75 73 65 64 20 66 6f 72 20 74 65 73 is used for tes
6110: 74 69 6e 67 20 61 6e 64 20 64 65 62 75 67 67 69 ting and debuggi
6120: 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f ng..*/.void cgi_
6130: 70 72 69 6e 74 5f 61 6c 6c 28 76 6f 69 64 29 7b print_all(void){
6140: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69 5f . int i;. cgi_
6150: 70 61 72 61 6d 65 74 65 72 28 22 22 2c 22 22 29 parameter("","")
6160: 3b 20 20 2f 2a 20 46 6f 72 63 65 20 74 68 65 20 ; /* Force the
6170: 70 61 72 61 6d 65 74 65 72 73 20 69 6e 74 6f 20 parameters into
6180: 73 6f 72 74 65 64 20 6f 72 64 65 72 20 2a 2f 0a sorted order */.
6190: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 55 73 for(i=0; i<nUs
61a0: 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 edQP; i++){.
61b0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 73 20 3d cgi_printf("%s =
61c0: 20 25 73 20 20 3c 62 72 20 2f 3e 5c 6e 22 2c 0a %s <br />\n",.
61d0: 20 20 20 20 20 20 20 68 74 6d 6c 69 7a 65 28 61 htmlize(a
61e0: 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 ParamQP[i].zName
61f0: 2c 20 2d 31 29 2c 20 68 74 6d 6c 69 7a 65 28 61 , -1), htmlize(a
6200: 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 56 61 6c 75 ParamQP[i].zValu
6210: 65 2c 20 2d 31 29 29 3b 0a 20 20 7d 0a 7d 0a 0a e, -1));. }.}..
6220: 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 48 54 4d 4c /*.** Write HTML
6230: 20 74 65 78 74 20 66 6f 72 20 61 6e 20 6f 70 74 text for an opt
6240: 69 6f 6e 20 6d 65 6e 75 20 74 6f 20 73 74 61 6e ion menu to stan
6250: 64 61 72 64 20 6f 75 74 70 75 74 2e 20 20 7a 50 dard output. zP
6260: 61 72 61 6d 0a 2a 2a 20 69 73 20 74 68 65 20 71 aram.** is the q
6270: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 74 uery parameter t
6280: 68 61 74 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d hat the option m
6290: 65 6e 75 20 73 65 74 73 2e 20 20 7a 44 66 6c 74 enu sets. zDflt
62a0: 20 69 73 20 74 68 65 0a 2a 2a 20 69 6e 69 74 69 is the.** initi
62b0: 61 6c 20 76 61 6c 75 65 20 6f 66 20 74 68 65 20 al value of the
62c0: 6f 70 74 69 6f 6e 20 6d 65 6e 75 2e 20 20 41 64 option menu. Ad
62d0: 64 69 74 69 6f 6e 20 61 72 67 75 6d 65 6e 74 73 dition arguments
62e0: 20 61 72 65 20 6e 61 6d 65 2f 76 61 6c 75 65 0a are name/value.
62f0: 2a 2a 20 70 61 69 72 73 20 74 68 61 74 20 64 65 ** pairs that de
6300: 66 69 6e 65 20 76 61 6c 75 65 73 20 6f 6e 20 74 fine values on t
6310: 68 65 20 6d 65 6e 75 2e 20 20 54 68 65 20 6c 69 he menu. The li
6320: 73 74 20 69 73 20 74 65 72 6d 69 6e 61 74 65 64 st is terminated
6330: 20 77 69 74 68 0a 2a 2a 20 61 20 73 69 6e 67 6c with.** a singl
6340: 65 20 4e 55 4c 4c 20 61 72 67 75 6d 65 6e 74 2e e NULL argument.
6350: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 6f 70 74 .*/.void cgi_opt
6360: 69 6f 6e 6d 65 6e 75 28 69 6e 74 20 69 6e 2c 20 ionmenu(int in,
6370: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 const char *zP,
6380: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 const char *zD,
6390: 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 ...){. va_list
63a0: 61 70 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d ap;. char *zNam
63b0: 65 2c 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 e, *zVal;. int
63c0: 64 66 6c 74 53 65 65 6e 20 3d 20 30 3b 0a 20 20 dfltSeen = 0;.
63d0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
63e0: 73 65 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 select size=1 na
63f0: 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 me=\"%s\">\n", i
6400: 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 20 76 61 n, "", zP);. va
6410: 5f 73 74 61 72 74 28 61 70 2c 20 7a 44 29 3b 0a _start(ap, zD);.
6420: 20 20 77 68 69 6c 65 28 20 28 7a 4e 61 6d 65 20 while( (zName
6430: 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 = va_arg(ap, cha
6440: 72 2a 29 29 21 3d 30 20 26 26 20 28 7a 56 61 6c r*))!=0 && (zVal
6450: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 = va_arg(ap, ch
6460: 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 ar*))!=0 ){.
6470: 69 66 28 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c if( strcmp(zVal,
6480: 7a 44 29 3d 3d 30 20 29 7b 20 64 66 6c 74 53 65 zD)==0 ){ dfltSe
6490: 65 6e 20 3d 20 31 3b 20 62 72 65 61 6b 3b 20 7d en = 1; break; }
64a0: 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64 28 61 70 . }. va_end(ap
64b0: 29 3b 0a 20 20 69 66 28 20 21 64 66 6c 74 53 65 );. if( !dfltSe
64c0: 65 6e 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 en ){. if( zD
64d0: 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 [0] ){. cgi
64e0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 _printf("%*s<opt
64f0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 ion value=\"%h\"
6500: 20 73 65 6c 65 63 74 65 64 3e 25 68 3c 2f 6f 70 selected>%h</op
6510: 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 tion>\n",.
6520: 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 in+2, "", zD,
6530: 7a 44 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a zD);. }else{.
6540: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 cgi_printf
6550: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c ("%*s<option val
6560: 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64 ue=\"\" selected
6570: 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e > </option>
6580: 5c 6e 22 2c 20 69 6e 2b 32 2c 20 22 22 29 3b 0a \n", in+2, "");.
6590: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 76 61 5f 73 }. }. va_s
65a0: 74 61 72 74 28 61 70 2c 20 7a 44 29 3b 0a 20 20 tart(ap, zD);.
65b0: 77 68 69 6c 65 28 20 28 7a 4e 61 6d 65 20 3d 20 while( (zName =
65c0: 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a va_arg(ap, char*
65d0: 29 29 21 3d 30 20 26 26 20 28 7a 56 61 6c 20 3d ))!=0 && (zVal =
65e0: 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 va_arg(ap, char
65f0: 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 *))!=0 ){. if
6600: 28 20 7a 4e 61 6d 65 5b 30 5d 20 29 7b 0a 20 20 ( zName[0] ){.
6610: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 cgi_printf("
6620: 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 %*s<option value
6630: 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 =\"%h\"%s>%h</op
6640: 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 tion>\n",.
6650: 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 in+2, "",.
6660: 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 zVal,.
6670: 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a strcmp(zVal, z
6680: 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 D) ? "" : " sele
6690: 63 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a cted",. z
66a0: 4e 61 6d 65 0a 20 20 20 20 20 20 29 3b 0a 20 20 Name. );.
66b0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 }else{. c
66c0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f gi_printf("%*s<o
66d0: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 ption value=\"\"
66e0: 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f %s> </optio
66f0: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 n>\n",. i
6700: 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 n+2, "",.
6710: 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 strcmp(zVal, zD
6720: 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 ) ? "" : " selec
6730: 74 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 ted". );.
6740: 20 20 7d 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64 }. }. va_end
6750: 28 61 70 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e (ap);. cgi_prin
6760: 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e tf("%*s</select>
6770: 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a \n", in, "");.}.
6780: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 ./*.** This rout
6790: 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74 20 ine works a lot
67a0: 6c 69 6b 65 20 63 67 69 5f 6f 70 74 69 6f 6e 6d like cgi_optionm
67b0: 65 6e 75 28 29 20 65 78 63 65 70 74 20 74 68 61 enu() except tha
67c0: 74 20 74 68 65 20 6c 69 73 74 20 6f 66 0a 2a 2a t the list of.**
67d0: 20 76 61 6c 75 65 73 20 69 73 20 63 6f 6e 74 61 values is conta
67e0: 69 6e 65 64 20 69 6e 20 61 6e 20 61 72 72 61 79 ined in an array
67f0: 2e 20 20 41 6c 73 6f 2c 20 74 68 65 20 76 61 6c . Also, the val
6800: 75 65 73 20 61 72 65 20 6a 75 73 74 20 76 61 6c ues are just val
6810: 75 65 73 2c 20 6e 6f 74 0a 2a 2a 20 6e 61 6d 65 ues, not.** name
6820: 2f 76 61 6c 75 65 20 70 61 69 72 73 20 61 73 20 /value pairs as
6830: 69 6e 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e in cgi_optionmen
6840: 75 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 u..*/.void cgi_v
6850: 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 0a 20 20 69 _optionmenu(. i
6860: 6e 74 20 69 6e 2c 20 20 20 20 20 20 20 20 20 20 nt in,
6870: 20 20 20 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 /* Indent by
6880: 20 74 68 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a this amount */.
6890: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 const char *zP
68a0: 2c 20 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75 , /* The qu
68b0: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6e 61 ery parameter na
68c0: 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 me */. const ch
68d0: 61 72 20 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 ar *zD, /*
68e0: 44 65 66 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f Default value */
68f0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a . const char **
6900: 61 7a 20 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d az /* NULL-
6910: 74 65 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 terminated list
6920: 6f 66 20 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 of allowed value
6930: 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 s */.){. const
6940: 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e char *zVal;. in
6950: 74 20 69 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 t i;. cgi_print
6960: 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 f("%*s<select si
6970: 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 ze=1 name=\"%s\"
6980: 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 >\n", in, "", zP
6990: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a );. for(i=0; az
69a0: 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 [i]; i++){. i
69b0: 66 28 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c f( strcmp(az[i],
69c0: 7a 44 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a zD)==0 ) break;.
69d0: 20 20 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d }. if( az[i]=
69e0: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 =0 ){. if( zD
69f0: 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 [0]==0 ){.
6a00: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
6a10: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c option value=\"\
6a20: 22 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 " selected> 
6a30: 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 ;</option>\n",.
6a40: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b in+2, "");
6a50: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 . }else{.
6a60: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
6a70: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c s<option value=\
6a80: 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 "%h\" selected>%
6a90: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 h</option>\n",.
6aa0: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 in+2, "",
6ab0: 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 zD, zD);. }.
6ac0: 20 7d 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 61 }. while( (zVa
6ad0: 6c 20 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 l = *(az++))!=0
6ae0: 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c ){. if( zVal
6af0: 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 [0] ){. cgi
6b00: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 _printf("%*s<opt
6b10: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 ion value=\"%h\"
6b20: 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e %s>%h</option>\n
6b30: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c ",. in+2,
6b40: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 "",. zVa
6b50: 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d l,. strcm
6b60: 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 p(zVal, zD) ? ""
6b70: 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a : " selected",.
6b80: 20 20 20 20 20 20 20 20 7a 56 61 6c 0a 20 20 20 zVal.
6b90: 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b );. }else{
6ba0: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 . cgi_print
6bb0: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 f("%*s<option va
6bc0: 6c 75 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 lue=\"\"%s> 
6bd0: 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 ;</option>\n",.
6be0: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c in+2, "",
6bf0: 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 . strcmp(
6c00: 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a zVal, zD) ? "" :
6c10: 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 " selected".
6c20: 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a );. }. }.
6c30: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
6c40: 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 s</select>\n", i
6c50: 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a n, "");.}../*.**
6c60: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f This routine wo
6c70: 72 6b 73 20 61 20 6c 6f 74 20 6c 69 6b 65 20 63 rks a lot like c
6c80: 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 gi_v_optionmenu(
6c90: 29 20 65 78 63 65 70 74 20 74 68 61 74 20 74 68 ) except that th
6ca0: 65 20 6c 69 73 74 0a 2a 2a 20 69 73 20 61 20 6c e list.** is a l
6cb0: 69 73 74 20 6f 66 20 70 61 69 72 73 2e 20 20 54 ist of pairs. T
6cc0: 68 65 20 66 69 72 73 74 20 65 6c 65 6d 65 6e 74 he first element
6cd0: 20 6f 66 20 65 61 63 68 20 70 61 69 72 20 69 73 of each pair is
6ce0: 20 74 68 65 20 76 61 6c 75 65 20 75 73 65 64 0a the value used.
6cf0: 2a 2a 20 69 6e 74 65 72 6e 61 6c 6c 79 20 61 6e ** internally an
6d00: 64 20 74 68 65 20 73 65 63 6f 6e 64 20 65 6c 65 d the second ele
6d10: 6d 65 6e 74 20 69 73 20 74 68 65 20 76 61 6c 75 ment is the valu
6d20: 65 20 64 69 73 70 6c 61 79 65 64 20 74 6f 20 74 e displayed to t
6d30: 68 65 20 75 73 65 72 2e 0a 2a 2f 0a 76 6f 69 64 he user..*/.void
6d40: 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e cgi_v_optionmen
6d50: 75 32 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20 u2(. int in,
6d60: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e /* In
6d70: 64 65 6e 74 20 62 79 20 74 68 69 73 20 61 6d 6f dent by this amo
6d80: 75 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 unt */. const c
6d90: 68 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a har *zP, /*
6da0: 20 54 68 65 20 71 75 65 72 79 20 70 61 72 61 6d The query param
6db0: 65 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 eter name */. c
6dc0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 20 onst char *zD,
6dd0: 20 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 76 /* Default v
6de0: 61 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 alue */. const
6df0: 63 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f char **az /
6e00: 2a 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 * NULL-terminate
6e10: 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65 d list of allowe
6e20: 64 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 d values */.){.
6e30: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 const char *zVa
6e40: 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 l;. int i;. cg
6e50: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 i_printf("%*s<se
6e60: 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 lect size=1 name
6e70: 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c =\"%s\">\n", in,
6e80: 20 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28 "", zP);. for(
6e90: 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 3d 32 i=0; az[i]; i+=2
6ea0: 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d ){. if( strcm
6eb0: 70 28 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 p(az[i],zD)==0 )
6ec0: 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 break;. }. if
6ed0: 28 20 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 ( az[i]==0 ){.
6ee0: 20 20 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 if( zD[0]==0 )
6ef0: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e {. cgi_prin
6f00: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 tf("%*s<option v
6f10: 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 alue=\"\" select
6f20: 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f ed> </optio
6f30: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e n>\n",. in
6f40: 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c +2, "");. }el
6f50: 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 se{. cgi_pr
6f60: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e intf("%*s<option
6f70: 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 value=\"%h\" se
6f80: 6c 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f lected>%h</optio
6f90: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e n>\n",. in
6fa0: 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b +2, "", zD, zD);
6fb0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 . }. }. whi
6fc0: 6c 65 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a le( (zVal = *(az
6fd0: 2b 2b 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 ++))!=0 ){.
6fe0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d const char *zNam
6ff0: 65 20 3d 20 2a 28 61 7a 2b 2b 29 3b 0a 20 20 20 e = *(az++);.
7000: 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 20 29 7b if( zName[0] ){
7010: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 . cgi_print
7020: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 f("%*s<option va
7030: 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c lue=\"%h\"%s>%h<
7040: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 /option>\n",.
7050: 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 in+2, "",.
7060: 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 zVal,.
7070: 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c strcmp(zVal
7080: 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 , zD) ? "" : " s
7090: 65 6c 65 63 74 65 64 22 2c 0a 20 20 20 20 20 20 elected",.
70a0: 20 20 7a 4e 61 6d 65 0a 20 20 20 20 20 20 29 3b zName. );
70b0: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 . }else{.
70c0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
70d0: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c s<option value=\
70e0: 22 25 68 5c 22 25 73 3e 26 6e 62 73 70 3b 3c 2f "%h\"%s> </
70f0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 option>\n",.
7100: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 in+2, "",.
7110: 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 zVal,.
7120: 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c strcmp(zVal,
7130: 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 zD) ? "" : " se
7140: 6c 65 63 74 65 64 22 0a 20 20 20 20 20 20 29 3b lected". );
7150: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 63 67 69 . }. }. cgi
7160: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 _printf("%*s</se
7170: 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 lect>\n", in, ""
7180: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 );.}../*.** This
7190: 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 6c routine works l
71a0: 69 6b 65 20 22 70 72 69 6e 74 66 22 20 65 78 63 ike "printf" exc
71b0: 65 70 74 20 74 68 61 74 20 69 74 20 68 61 73 20 ept that it has
71c0: 74 68 65 0a 2a 2a 20 65 78 74 72 61 20 66 6f 72 the.** extra for
71d0: 6d 61 74 74 69 6e 67 20 63 61 70 61 62 69 6c 69 matting capabili
71e0: 74 69 65 73 20 73 75 63 68 20 61 73 20 25 68 20 ties such as %h
71f0: 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 and %t..*/.void
7200: 63 67 69 5f 70 72 69 6e 74 66 28 63 6f 6e 73 74 cgi_printf(const
7210: 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 char *zFormat,
7220: 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 ...){. va_list
7230: 61 70 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 ap;. va_start(a
7240: 70 2c 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 76 78 p,zFormat);. vx
7250: 70 72 69 6e 74 66 28 70 43 6f 6e 74 65 6e 74 2c printf(pContent,
7260: 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 20 20 76 zFormat,ap);. v
7270: 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 2f 2a a_end(ap);.}../*
7280: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 .** This routine
7290: 20 77 6f 72 6b 73 20 6c 69 6b 65 20 22 76 70 72 works like "vpr
72a0: 69 6e 74 66 22 20 65 78 63 65 70 74 20 74 68 61 intf" except tha
72b0: 74 20 69 74 20 68 61 73 20 74 68 65 0a 2a 2a 20 t it has the.**
72c0: 65 78 74 72 61 20 66 6f 72 6d 61 74 74 69 6e 67 extra formatting
72d0: 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 73 75 capabilities su
72e0: 63 68 20 61 73 20 25 68 20 61 6e 64 20 25 74 2e ch as %h and %t.
72f0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 70 72 .*/.void cgi_vpr
7300: 69 6e 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20 intf(const char
7310: 2a 7a 46 6f 72 6d 61 74 2c 20 76 61 5f 6c 69 73 *zFormat, va_lis
7320: 74 20 61 70 29 7b 0a 20 20 76 78 70 72 69 6e 74 t ap){. vxprint
7330: 66 28 70 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d f(pContent,zForm
7340: 61 74 2c 61 70 29 3b 0a 7d 0a 0a 0a 2f 2a 0a 2a at,ap);.}.../*.*
7350: 2a 20 53 65 6e 64 20 61 20 72 65 70 6c 79 20 69 * Send a reply i
7360: 6e 64 69 63 61 74 69 6e 67 20 74 68 61 74 20 74 ndicating that t
7370: 68 65 20 48 54 54 50 20 72 65 71 75 65 73 74 20 he HTTP request
7380: 77 61 73 20 6d 61 6c 66 6f 72 6d 65 64 0a 2a 2f was malformed.*/
7390: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 6d 61 6c .static void mal
73a0: 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28 76 formed_request(v
73b0: 6f 69 64 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f oid){. cgi_set_
73c0: 73 74 61 74 75 73 28 35 30 31 2c 20 22 4e 6f 74 status(501, "Not
73d0: 20 49 6d 70 6c 65 6d 65 6e 74 65 64 22 29 3b 0a Implemented");.
73e0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 0a 20 20 cgi_printf(.
73f0: 20 20 22 3c 68 74 6d 6c 3e 3c 62 6f 64 79 3e 55 "<html><body>U
7400: 6e 72 65 63 6f 67 6e 69 7a 65 64 20 48 54 54 50 nrecognized HTTP
7410: 20 52 65 71 75 65 73 74 3c 2f 62 6f 64 79 3e 3c Request</body><
7420: 2f 68 74 6d 6c 3e 5c 6e 22 0a 20 20 29 3b 0a 20 /html>\n". );.
7430: 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 cgi_reply();.
7440: 65 78 69 74 28 30 29 3b 0a 7d 0a 0a 2f 2a 0a 2a exit(0);.}../*.*
7450: 2a 20 50 61 6e 69 63 20 61 6e 64 20 64 69 65 20 * Panic and die
7460: 77 68 69 6c 65 20 70 72 6f 63 65 73 73 69 6e 67 while processing
7470: 20 61 20 77 65 62 70 61 67 65 2e 0a 2a 2f 0a 76 a webpage..*/.v
7480: 6f 69 64 20 63 67 69 5f 70 61 6e 69 63 28 63 6f oid cgi_panic(co
7490: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 nst char *zForma
74a0: 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 t, ...){. va_li
74b0: 73 74 20 61 70 3b 0a 20 20 63 67 69 5f 72 65 73 st ap;. cgi_res
74c0: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 et_content();.
74d0: 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 35 cgi_set_status(5
74e0: 30 30 2c 20 22 49 6e 74 65 72 6e 61 6c 20 53 65 00, "Internal Se
74f0: 72 76 65 72 20 45 72 72 6f 72 22 29 3b 0a 20 20 rver Error");.
7500: 63 67 69 5f 70 72 69 6e 74 66 28 0a 20 20 20 20 cgi_printf(.
7510: 22 3c 68 74 6d 6c 3e 3c 62 6f 64 79 3e 3c 68 31 "<html><body><h1
7520: 3e 49 6e 74 65 72 6e 61 6c 20 53 65 72 76 65 72 >Internal Server
7530: 20 45 72 72 6f 72 3c 2f 68 31 3e 5c 6e 22 0a 20 Error</h1>\n".
7540: 20 20 20 22 3c 70 6c 61 69 6e 74 65 78 74 3e 22 "<plaintext>"
7550: 0a 20 20 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 . );. va_start
7560: 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 (ap, zFormat);.
7570: 20 76 78 70 72 69 6e 74 66 28 70 43 6f 6e 74 65 vxprintf(pConte
7580: 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a nt,zFormat,ap);.
7590: 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 va_end(ap);.
75a0: 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 cgi_reply();. e
75b0: 78 69 74 28 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a xit(1);.}../*.**
75c0: 20 52 65 6d 6f 76 65 20 74 68 65 20 66 69 72 73 Remove the firs
75d0: 74 20 73 70 61 63 65 2d 64 65 6c 69 6d 69 74 65 t space-delimite
75e0: 64 20 74 6f 6b 65 6e 20 66 72 6f 6d 20 61 20 73 d token from a s
75f0: 74 72 69 6e 67 20 61 6e 64 20 72 65 74 75 72 6e tring and return
7600: 0a 2a 2a 20 61 20 70 6f 69 6e 74 65 72 20 74 6f .** a pointer to
7610: 20 69 74 2e 20 20 41 64 64 20 61 20 4e 55 4c 4c it. Add a NULL
7620: 20 74 6f 20 74 68 65 20 73 74 72 69 6e 67 20 74 to the string t
7630: 6f 20 74 65 72 6d 69 6e 61 74 65 20 74 68 65 20 o terminate the
7640: 74 6f 6b 65 6e 2e 0a 2a 2a 20 4d 61 6b 65 20 2a token..** Make *
7650: 7a 4c 65 66 74 4f 76 65 72 20 70 6f 69 6e 74 20 zLeftOver point
7660: 74 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 to the start of
7670: 74 68 65 20 6e 65 78 74 20 74 6f 6b 65 6e 2e 0a the next token..
7680: 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a */.static char *
7690: 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28 63 68 extract_token(ch
76a0: 61 72 20 2a 7a 49 6e 70 75 74 2c 20 63 68 61 72 ar *zInput, char
76b0: 20 2a 2a 7a 4c 65 66 74 4f 76 65 72 29 7b 0a 20 **zLeftOver){.
76c0: 20 63 68 61 72 20 2a 7a 52 65 73 75 6c 74 20 3d char *zResult =
76d0: 20 30 3b 0a 20 20 69 66 28 20 7a 49 6e 70 75 74 0;. if( zInput
76e0: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a ==0 ){. if( z
76f0: 4c 65 66 74 4f 76 65 72 20 29 20 2a 7a 4c 65 66 LeftOver ) *zLef
7700: 74 4f 76 65 72 20 3d 20 30 3b 0a 20 20 20 20 72 tOver = 0;. r
7710: 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 77 eturn 0;. }. w
7720: 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a hile( isspace(*z
7730: 49 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 Input) ){ zInput
7740: 2b 2b 3b 20 7d 0a 20 20 7a 52 65 73 75 6c 74 20 ++; }. zResult
7750: 3d 20 7a 49 6e 70 75 74 3b 0a 20 20 77 68 69 6c = zInput;. whil
7760: 65 28 20 2a 7a 49 6e 70 75 74 20 26 26 20 21 69 e( *zInput && !i
7770: 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 sspace(*zInput)
7780: 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 ){ zInput++; }.
7790: 20 69 66 28 20 2a 7a 49 6e 70 75 74 20 29 7b 0a if( *zInput ){.
77a0: 20 20 20 20 2a 7a 49 6e 70 75 74 20 3d 20 30 3b *zInput = 0;
77b0: 0a 20 20 20 20 7a 49 6e 70 75 74 2b 2b 3b 0a 20 . zInput++;.
77c0: 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 while( isspac
77d0: 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a 49 e(*zInput) ){ zI
77e0: 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7d 0a 20 20 nput++; }. }.
77f0: 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 20 29 7b if( zLeftOver ){
7800: 20 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 7a 49 *zLeftOver = zI
7810: 6e 70 75 74 3b 20 7d 0a 20 20 72 65 74 75 72 6e nput; }. return
7820: 20 7a 52 65 73 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a zResult;.}../*.
7830: 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 ** This routine
7840: 68 61 6e 64 6c 65 73 20 61 20 73 69 6e 67 6c 65 handles a single
7850: 20 48 54 54 50 20 72 65 71 75 65 73 74 20 77 68 HTTP request wh
7860: 69 63 68 20 69 73 20 63 6f 6d 69 6e 67 20 69 6e ich is coming in
7870: 20 6f 6e 0a 2a 2a 20 73 74 61 6e 64 61 72 64 20 on.** standard
7880: 69 6e 70 75 74 20 61 6e 64 20 77 68 69 63 68 20 input and which
7890: 72 65 70 6c 69 65 73 20 6f 6e 20 73 74 61 6e 64 replies on stand
78a0: 61 72 64 20 6f 75 74 70 75 74 2e 0a 2a 2a 0a 2a ard output..**.*
78b0: 2a 20 54 68 65 20 48 54 54 50 20 72 65 71 75 65 * The HTTP reque
78c0: 73 74 20 69 73 20 72 65 61 64 20 66 72 6f 6d 20 st is read from
78d0: 73 74 61 6e 64 61 72 64 20 69 6e 70 75 74 20 61 standard input a
78e0: 6e 64 20 69 73 20 75 73 65 64 20 74 6f 20 69 6e nd is used to in
78f0: 69 74 69 61 6c 69 7a 65 0a 2a 2a 20 65 6e 76 69 itialize.** envi
7900: 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 ronment variable
7910: 73 20 61 73 20 70 65 72 20 43 47 49 2e 20 20 54 s as per CGI. T
7920: 68 65 20 63 67 69 5f 69 6e 69 74 28 29 20 72 6f he cgi_init() ro
7930: 75 74 69 6e 65 20 74 6f 20 63 6f 6d 70 6c 65 74 utine to complet
7940: 65 0a 2a 2a 20 74 68 65 20 73 65 74 75 70 2e 20 e.** the setup.
7950: 20 4f 6e 63 65 20 61 6c 6c 20 74 68 65 20 73 65 Once all the se
7960: 74 75 70 20 69 73 20 66 69 6e 69 73 68 65 64 2c tup is finished,
7970: 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 20 this procedure
7980: 72 65 74 75 72 6e 73 0a 2a 2a 20 61 6e 64 20 73 returns.** and s
7990: 75 62 73 65 71 75 65 6e 74 20 63 6f 64 65 20 68 ubsequent code h
79a0: 61 6e 64 6c 65 73 20 74 68 65 20 61 63 74 75 61 andles the actua
79b0: 6c 20 67 65 6e 65 72 61 74 69 6f 6e 20 6f 66 20 l generation of
79c0: 74 68 65 20 77 65 62 70 61 67 65 2e 0a 2a 2f 0a the webpage..*/.
79d0: 76 6f 69 64 20 63 67 69 5f 68 61 6e 64 6c 65 5f void cgi_handle_
79e0: 68 74 74 70 5f 72 65 71 75 65 73 74 28 63 6f 6e http_request(con
79f0: 73 74 20 63 68 61 72 20 2a 7a 49 70 41 64 64 72 st char *zIpAddr
7a00: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 2c 20 2a 7a ){. char *z, *z
7a10: 54 6f 6b 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a Token;. int i;.
7a20: 20 20 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 struct sockadd
7a30: 72 5f 69 6e 20 72 65 6d 6f 74 65 4e 61 6d 65 3b r_in remoteName;
7a40: 0a 20 20 73 69 7a 65 5f 74 20 73 69 7a 65 20 3d . size_t size =
7a50: 20 73 69 7a 65 6f 66 28 73 74 72 75 63 74 20 73 sizeof(struct s
7a60: 6f 63 6b 61 64 64 72 5f 69 6e 29 3b 0a 20 20 63 ockaddr_in);. c
7a70: 68 61 72 20 7a 4c 69 6e 65 5b 32 30 30 30 5d 3b har zLine[2000];
7a80: 20 20 20 20 20 2f 2a 20 41 20 73 69 6e 67 6c 65 /* A single
7a90: 20 6c 69 6e 65 20 6f 66 20 69 6e 70 75 74 2e 20 line of input.
7aa0: 2a 2f 0a 0a 20 20 67 2e 66 75 6c 6c 48 74 74 70 */.. g.fullHttp
7ab0: 52 65 70 6c 79 20 3d 20 31 3b 0a 20 20 69 66 28 Reply = 1;. if(
7ac0: 20 66 67 65 74 73 28 7a 4c 69 6e 65 2c 20 73 69 fgets(zLine, si
7ad0: 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c 67 2e 68 74 zeof(zLine),g.ht
7ae0: 74 70 49 6e 29 3d 3d 30 20 29 7b 0a 20 20 20 20 tpIn)==0 ){.
7af0: 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 malformed_reques
7b00: 74 28 29 3b 0a 20 20 7d 0a 20 20 7a 54 6f 6b 65 t();. }. zToke
7b10: 6e 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 n = extract_toke
7b20: 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29 3b 0a 20 20 n(zLine, &z);.
7b30: 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 20 29 7b if( zToken==0 ){
7b40: 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 . malformed_r
7b50: 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 equest();. }.
7b60: 69 66 28 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 if( strcmp(zToke
7b70: 6e 2c 22 47 45 54 22 29 21 3d 30 20 26 26 20 73 n,"GET")!=0 && s
7b80: 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22 50 4f trcmp(zToken,"PO
7b90: 53 54 22 29 21 3d 30 0a 20 20 20 20 20 20 26 26 ST")!=0. &&
7ba0: 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22 strcmp(zToken,"
7bb0: 48 45 41 44 22 29 21 3d 30 20 29 7b 0a 20 20 20 HEAD")!=0 ){.
7bc0: 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 malformed_reque
7bd0: 73 74 28 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f st();. }. cgi_
7be0: 73 65 74 65 6e 76 28 22 47 41 54 45 57 41 59 5f setenv("GATEWAY_
7bf0: 49 4e 54 45 52 46 41 43 45 22 2c 22 43 47 49 2f INTERFACE","CGI/
7c00: 31 2e 30 22 29 3b 0a 20 20 63 67 69 5f 73 65 74 1.0");. cgi_set
7c10: 65 6e 76 28 22 52 45 51 55 45 53 54 5f 4d 45 54 env("REQUEST_MET
7c20: 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29 3b 0a 20 20 HOD",zToken);.
7c30: 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 zToken = extract
7c40: 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a 29 3b 0a 20 _token(z, &z);.
7c50: 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 20 29 if( zToken==0 )
7c60: 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f {. malformed_
7c70: 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 request();. }.
7c80: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45 51 cgi_setenv("REQ
7c90: 55 45 53 54 5f 55 52 49 22 2c 20 7a 54 6f 6b 65 UEST_URI", zToke
7ca0: 6e 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a n);. for(i=0; z
7cb0: 54 6f 6b 65 6e 5b 69 5d 20 26 26 20 7a 54 6f 6b Token[i] && zTok
7cc0: 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20 69 2b 2b 29 en[i]!='?'; i++)
7cd0: 7b 7d 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 5b {}. if( zToken[
7ce0: 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b 69 2b 2b 5d i] ) zToken[i++]
7cf0: 20 3d 20 30 3b 0a 20 20 63 67 69 5f 73 65 74 65 = 0;. cgi_sete
7d00: 6e 76 28 22 50 41 54 48 5f 49 4e 46 4f 22 2c 20 nv("PATH_INFO",
7d10: 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63 67 69 5f 73 zToken);. cgi_s
7d20: 65 74 65 6e 76 28 22 51 55 45 52 59 5f 53 54 52 etenv("QUERY_STR
7d30: 49 4e 47 22 2c 20 26 7a 54 6f 6b 65 6e 5b 69 5d ING", &zToken[i]
7d40: 29 3b 0a 20 20 69 66 28 20 7a 49 70 41 64 64 72 );. if( zIpAddr
7d50: 3d 3d 30 20 26 26 0a 20 20 20 20 20 20 20 20 67 ==0 &&. g
7d60: 65 74 70 65 65 72 6e 61 6d 65 28 66 69 6c 65 6e etpeername(filen
7d70: 6f 28 67 2e 68 74 74 70 49 6e 29 2c 20 28 73 74 o(g.httpIn), (st
7d80: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26 ruct sockaddr*)&
7d90: 72 65 6d 6f 74 65 4e 61 6d 65 2c 20 0a 20 20 20 remoteName, .
7da0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
7db0: 20 20 20 20 20 20 20 20 20 20 20 20 20 28 73 6f (so
7dc0: 63 6b 6c 65 6e 5f 74 2a 29 26 73 69 7a 65 29 3e cklen_t*)&size)>
7dd0: 3d 30 0a 20 20 29 7b 0a 20 20 20 20 7a 49 70 41 =0. ){. zIpA
7de0: 64 64 72 20 3d 20 69 6e 65 74 5f 6e 74 6f 61 28 ddr = inet_ntoa(
7df0: 72 65 6d 6f 74 65 4e 61 6d 65 2e 73 69 6e 5f 61 remoteName.sin_a
7e00: 64 64 72 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 ddr);. }. if(
7e10: 7a 49 70 41 64 64 72 20 29 7b 20 20 20 0a 20 20 zIpAddr ){ .
7e20: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45 cgi_setenv("RE
7e30: 4d 4f 54 45 5f 41 44 44 52 22 2c 20 7a 49 70 41 MOTE_ADDR", zIpA
7e40: 64 64 72 29 3b 0a 20 20 20 20 67 2e 7a 49 70 41 ddr);. g.zIpA
7e50: 64 64 72 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 ddr = mprintf("%
7e60: 73 22 2c 20 7a 49 70 41 64 64 72 29 3b 0a 20 20 s", zIpAddr);.
7e70: 7d 0a 20 0a 20 20 2f 2a 20 47 65 74 20 61 6c 6c }. . /* Get all
7e80: 20 74 68 65 20 6f 70 74 69 6f 6e 61 6c 20 66 69 the optional fi
7e90: 65 6c 64 73 20 74 68 61 74 20 66 6f 6c 6c 6f 77 elds that follow
7ea0: 20 74 68 65 20 66 69 72 73 74 20 6c 69 6e 65 2e the first line.
7eb0: 0a 20 20 2a 2f 0a 20 20 77 68 69 6c 65 28 20 66 . */. while( f
7ec0: 67 65 74 73 28 7a 4c 69 6e 65 2c 73 69 7a 65 6f gets(zLine,sizeo
7ed0: 66 28 7a 4c 69 6e 65 29 2c 67 2e 68 74 74 70 49 f(zLine),g.httpI
7ee0: 6e 29 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a n) ){. char *
7ef0: 7a 46 69 65 6c 64 4e 61 6d 65 3b 0a 20 20 20 20 zFieldName;.
7f00: 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 0a 20 20 20 char *zVal;..
7f10: 20 7a 46 69 65 6c 64 4e 61 6d 65 20 3d 20 65 78 zFieldName = ex
7f20: 74 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e tract_token(zLin
7f30: 65 2c 26 7a 56 61 6c 29 3b 0a 20 20 20 20 69 66 e,&zVal);. if
7f40: 28 20 7a 46 69 65 6c 64 4e 61 6d 65 3d 3d 30 20 ( zFieldName==0
7f50: 7c 7c 20 2a 7a 46 69 65 6c 64 4e 61 6d 65 3d 3d || *zFieldName==
7f60: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 77 0 ) break;. w
7f70: 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a 7a hile( isspace(*z
7f80: 56 61 6c 29 20 29 7b 20 7a 56 61 6c 2b 2b 3b 20 Val) ){ zVal++;
7f90: 7d 0a 20 20 20 20 69 20 3d 20 73 74 72 6c 65 6e }. i = strlen
7fa0: 28 7a 56 61 6c 29 3b 0a 20 20 20 20 77 68 69 6c (zVal);. whil
7fb0: 65 28 20 69 3e 30 20 26 26 20 69 73 73 70 61 63 e( i>0 && isspac
7fc0: 65 28 7a 56 61 6c 5b 69 2d 31 5d 29 20 29 7b 20 e(zVal[i-1]) ){
7fd0: 69 2d 2d 3b 20 7d 0a 20 20 20 20 7a 56 61 6c 5b i--; }. zVal[
7fe0: 69 5d 20 3d 20 30 3b 0a 20 20 20 20 66 6f 72 28 i] = 0;. for(
7ff0: 69 3d 30 3b 20 7a 46 69 65 6c 64 4e 61 6d 65 5b i=0; zFieldName[
8000: 69 5d 3b 20 69 2b 2b 29 7b 20 7a 46 69 65 6c 64 i]; i++){ zField
8010: 4e 61 6d 65 5b 69 5d 20 3d 20 74 6f 6c 6f 77 65 Name[i] = tolowe
8020: 72 28 7a 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 29 r(zFieldName[i])
8030: 3b 20 7d 0a 20 20 20 20 69 66 28 20 73 74 72 63 ; }. if( strc
8040: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 75 mp(zFieldName,"u
8050: 73 65 72 2d 61 67 65 6e 74 3a 22 29 3d 3d 30 20 ser-agent:")==0
8060: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 ){. cgi_set
8070: 65 6e 76 28 22 48 54 54 50 5f 55 53 45 52 5f 41 env("HTTP_USER_A
8080: 47 45 4e 54 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 GENT", zVal);.
8090: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 }else if( strc
80a0: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 63 mp(zFieldName,"c
80b0: 6f 6e 74 65 6e 74 2d 6c 65 6e 67 74 68 3a 22 29 ontent-length:")
80c0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 ==0 ){. cgi
80d0: 5f 73 65 74 65 6e 76 28 22 43 4f 4e 54 45 4e 54 _setenv("CONTENT
80e0: 5f 4c 45 4e 47 54 48 22 2c 20 7a 56 61 6c 29 3b _LENGTH", zVal);
80f0: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 . }else if( s
8100: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 trcmp(zFieldName
8110: 2c 22 72 65 66 65 72 65 72 3a 22 29 3d 3d 30 20 ,"referer:")==0
8120: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 ){. cgi_set
8130: 65 6e 76 28 22 48 54 54 50 5f 52 45 46 45 52 45 env("HTTP_REFERE
8140: 52 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d R", zVal);. }
8150: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 else if( strcmp(
8160: 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 68 6f 73 74 zFieldName,"host
8170: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 :")==0 ){.
8180: 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 cgi_setenv("HTTP
8190: 5f 48 4f 53 54 22 2c 20 7a 56 61 6c 29 3b 0a 20 _HOST", zVal);.
81a0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 }else if( str
81b0: 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 cmp(zFieldName,"
81c0: 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 22 29 3d content-type:")=
81d0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f =0 ){. cgi_
81e0: 73 65 74 65 6e 76 28 22 43 4f 4e 54 45 4e 54 5f setenv("CONTENT_
81f0: 54 59 50 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 TYPE", zVal);.
8200: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 }else if( strc
8210: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 63 mp(zFieldName,"c
8220: 6f 6f 6b 69 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 ookie:")==0 ){.
8230: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 cgi_setenv(
8240: 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 2c 20 7a "HTTP_COOKIE", z
8250: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 Val);. }else
8260: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c if( strcmp(zFiel
8270: 64 4e 61 6d 65 2c 22 69 66 2d 6e 6f 6e 65 2d 6d dName,"if-none-m
8280: 61 74 63 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 atch:")==0 ){.
8290: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 cgi_setenv("
82a0: 48 54 54 50 5f 49 46 5f 4e 4f 4e 45 5f 4d 41 54 HTTP_IF_NONE_MAT
82b0: 43 48 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 CH", zVal);.
82c0: 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 }else if( strcmp
82d0: 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d (zFieldName,"if-
82e0: 6d 6f 64 69 66 69 65 64 2d 73 69 6e 63 65 3a 22 modified-since:"
82f0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 )==0 ){. cg
8300: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 49 i_setenv("HTTP_I
8310: 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 4e 43 45 F_MODIFIED_SINCE
8320: 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 0a ", zVal);. }.
8330: 20 20 7d 0a 0a 20 20 63 67 69 5f 69 6e 69 74 28 }.. cgi_init(
8340: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d 61 78 69 );.}../*.** Maxi
8350: 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 20 63 68 mum number of ch
8360: 69 6c 64 20 70 72 6f 63 65 73 73 65 73 20 74 68 ild processes th
8370: 61 74 20 77 65 20 63 61 6e 20 68 61 76 65 20 72 at we can have r
8380: 75 6e 6e 69 6e 67 0a 2a 2a 20 61 74 20 6f 6e 65 unning.** at one
8390: 20 74 69 6d 65 20 62 65 66 6f 72 65 20 77 65 20 time before we
83a0: 73 74 61 72 74 20 73 6c 6f 77 69 6e 67 20 74 68 start slowing th
83b0: 69 6e 67 73 20 64 6f 77 6e 2e 0a 2a 2f 0a 23 64 ings down..*/.#d
83c0: 65 66 69 6e 65 20 4d 41 58 5f 50 41 52 41 4c 4c efine MAX_PARALL
83d0: 45 4c 20 32 0a 0a 2f 2a 0a 2a 2a 20 49 6d 70 6c EL 2../*.** Impl
83e0: 65 6d 65 6e 74 20 61 6e 20 48 54 54 50 20 73 65 ement an HTTP se
83f0: 72 76 65 72 20 64 61 65 6d 6f 6e 20 6c 69 73 74 rver daemon list
8400: 65 6e 69 6e 67 20 6f 6e 20 70 6f 72 74 20 69 50 ening on port iP
8410: 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 41 73 20 6e 65 ort..**.** As ne
8420: 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72 w connections ar
8430: 72 69 76 65 2c 20 66 6f 72 6b 20 61 20 63 68 69 rive, fork a chi
8440: 6c 64 20 61 6e 64 20 6c 65 74 20 63 68 69 6c 64 ld and let child
8450: 20 72 65 74 75 72 6e 0a 2a 2a 20 6f 75 74 20 6f return.** out o
8460: 66 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 f this procedure
8470: 20 63 61 6c 6c 2e 20 20 54 68 65 20 63 68 69 6c call. The chil
8480: 64 20 77 69 6c 6c 20 68 61 6e 64 6c 65 20 74 68 d will handle th
8490: 65 20 72 65 71 75 65 73 74 2e 0a 2a 2a 20 54 68 e request..** Th
84a0: 65 20 70 61 72 65 6e 74 20 6e 65 76 65 72 20 72 e parent never r
84b0: 65 74 75 72 6e 73 20 66 72 6f 6d 20 74 68 69 73 eturns from this
84c0: 20 70 72 6f 63 65 64 75 72 65 2e 0a 2a 2a 0a 2a procedure..**.*
84d0: 2a 20 52 65 74 75 72 6e 20 30 20 74 6f 20 65 61 * Return 0 to ea
84e0: 63 68 20 63 68 69 6c 64 20 61 73 20 69 74 20 72 ch child as it r
84f0: 75 6e 73 2e 20 20 49 66 20 75 6e 61 62 6c 65 20 uns. If unable
8500: 74 6f 20 65 73 74 61 62 6c 69 73 68 20 61 0a 2a to establish a.*
8510: 2a 20 6c 69 73 74 65 6e 69 6e 67 20 73 6f 63 6b * listening sock
8520: 65 74 2c 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a et, return non-z
8530: 65 72 6f 2e 0a 2a 2f 0a 69 6e 74 20 63 67 69 5f ero..*/.int cgi_
8540: 68 74 74 70 5f 73 65 72 76 65 72 28 69 6e 74 20 http_server(int
8550: 6d 6e 50 6f 72 74 2c 20 69 6e 74 20 6d 78 50 6f mnPort, int mxPo
8560: 72 74 2c 20 63 68 61 72 20 2a 7a 42 72 6f 77 73 rt, char *zBrows
8570: 65 72 29 7b 0a 23 69 66 64 65 66 20 5f 5f 4d 49 er){.#ifdef __MI
8580: 4e 47 57 33 32 5f 5f 0a 20 20 2f 2a 20 55 73 65 NGW32__. /* Use
8590: 20 77 69 6e 33 32 5f 68 74 74 70 5f 73 65 72 76 win32_http_serv
85a0: 65 72 28 29 20 69 6e 73 74 65 61 64 20 2a 2f 0a er() instead */.
85b0: 20 20 65 78 69 74 28 31 29 3b 0a 23 65 6c 73 65 exit(1);.#else
85c0: 0a 20 20 69 6e 74 20 6c 69 73 74 65 6e 65 72 20 . int listener
85d0: 3d 20 2d 31 3b 20 20 20 20 20 20 20 20 20 20 20 = -1;
85e0: 2f 2a 20 54 68 65 20 73 65 72 76 65 72 20 73 6f /* The server so
85f0: 63 6b 65 74 20 2a 2f 0a 20 20 69 6e 74 20 63 6f cket */. int co
8600: 6e 6e 65 63 74 69 6f 6e 3b 20 20 20 20 20 20 20 nnection;
8610: 20 20 20 20 20 20 20 2f 2a 20 41 20 73 6f 63 6b /* A sock
8620: 65 74 20 66 6f 72 20 65 61 63 68 20 69 6e 64 69 et for each indi
8630: 76 69 64 75 61 6c 20 63 6f 6e 6e 65 63 74 69 6f vidual connectio
8640: 6e 20 2a 2f 0a 20 20 66 64 5f 73 65 74 20 72 65 n */. fd_set re
8650: 61 64 66 64 73 3b 20 20 20 20 20 20 20 20 20 20 adfds;
8660: 20 20 20 20 2f 2a 20 53 65 74 20 6f 66 20 66 69 /* Set of fi
8670: 6c 65 20 64 65 73 63 72 69 70 74 6f 72 73 20 66 le descriptors f
8680: 6f 72 20 73 65 6c 65 63 74 28 29 20 2a 2f 0a 20 or select() */.
8690: 20 73 69 7a 65 5f 74 20 6c 65 6e 61 64 64 72 3b size_t lenaddr;
86a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a /*
86b0: 20 4c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 69 Length of the i
86c0: 6e 61 64 64 72 20 73 74 72 75 63 74 75 72 65 20 naddr structure
86d0: 2a 2f 0a 20 20 69 6e 74 20 63 68 69 6c 64 3b 20 */. int child;
86e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
86f0: 20 20 2f 2a 20 50 49 44 20 6f 66 20 74 68 65 20 /* PID of the
8700: 63 68 69 6c 64 20 70 72 6f 63 65 73 73 20 2a 2f child process */
8710: 0a 20 20 69 6e 74 20 6e 63 68 69 6c 64 72 65 6e . int nchildren
8720: 20 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 = 0;
8730: 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 68 69 /* Number of chi
8740: 6c 64 20 70 72 6f 63 65 73 73 65 73 20 2a 2f 0a ld processes */.
8750: 20 20 73 74 72 75 63 74 20 74 69 6d 65 76 61 6c struct timeval
8760: 20 64 65 6c 61 79 3b 20 20 20 20 20 20 20 20 2f delay; /
8770: 2a 20 48 6f 77 20 6c 6f 6e 67 20 74 6f 20 77 61 * How long to wa
8780: 69 74 20 69 6e 73 69 64 65 20 73 65 6c 65 63 74 it inside select
8790: 28 29 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 73 () */. struct s
87a0: 6f 63 6b 61 64 64 72 5f 69 6e 20 69 6e 61 64 64 ockaddr_in inadd
87b0: 72 3b 20 20 20 2f 2a 20 54 68 65 20 73 6f 63 6b r; /* The sock
87c0: 65 74 20 61 64 64 72 65 73 73 20 2a 2f 0a 20 20 et address */.
87d0: 69 6e 74 20 6f 70 74 20 3d 20 31 3b 20 20 20 20 int opt = 1;
87e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
87f0: 73 65 74 73 6f 63 6b 6f 70 74 20 66 6c 61 67 20 setsockopt flag
8800: 2a 2f 0a 20 20 69 6e 74 20 69 50 6f 72 74 20 3d */. int iPort =
8810: 20 6d 6e 50 6f 72 74 3b 0a 0a 20 20 77 68 69 6c mnPort;.. whil
8820: 65 28 20 69 50 6f 72 74 3c 3d 6d 78 50 6f 72 74 e( iPort<=mxPort
8830: 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 74 28 26 ){. memset(&
8840: 69 6e 61 64 64 72 2c 20 30 2c 20 73 69 7a 65 6f inaddr, 0, sizeo
8850: 66 28 69 6e 61 64 64 72 29 29 3b 0a 20 20 20 20 f(inaddr));.
8860: 69 6e 61 64 64 72 2e 73 69 6e 5f 66 61 6d 69 6c inaddr.sin_famil
8870: 79 20 3d 20 41 46 5f 49 4e 45 54 3b 0a 20 20 20 y = AF_INET;.
8880: 20 69 6e 61 64 64 72 2e 73 69 6e 5f 61 64 64 72 inaddr.sin_addr
8890: 2e 73 5f 61 64 64 72 20 3d 20 49 4e 41 44 44 52 .s_addr = INADDR
88a0: 5f 41 4e 59 3b 0a 20 20 20 20 69 6e 61 64 64 72 _ANY;. inaddr
88b0: 2e 73 69 6e 5f 70 6f 72 74 20 3d 20 68 74 6f 6e .sin_port = hton
88c0: 73 28 69 50 6f 72 74 29 3b 0a 20 20 20 20 6c 69 s(iPort);. li
88d0: 73 74 65 6e 65 72 20 3d 20 73 6f 63 6b 65 74 28 stener = socket(
88e0: 41 46 5f 49 4e 45 54 2c 20 53 4f 43 4b 5f 53 54 AF_INET, SOCK_ST
88f0: 52 45 41 4d 2c 20 30 29 3b 0a 20 20 20 20 69 66 REAM, 0);. if
8900: 28 20 6c 69 73 74 65 6e 65 72 3c 30 20 29 7b 0a ( listener<0 ){.
8910: 20 20 20 20 20 20 69 50 6f 72 74 2b 2b 3b 0a 20 iPort++;.
8920: 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 continue;.
8930: 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 69 66 20 }.. /* if
8940: 77 65 20 63 61 6e 27 74 20 74 65 72 6d 69 6e 61 we can't termina
8950: 74 65 20 6e 69 63 65 6c 79 2c 20 61 74 20 6c 65 te nicely, at le
8960: 61 73 74 20 61 6c 6c 6f 77 20 74 68 65 20 73 6f ast allow the so
8970: 63 6b 65 74 20 74 6f 20 62 65 20 72 65 75 73 65 cket to be reuse
8980: 64 20 2a 2f 0a 20 20 20 20 73 65 74 73 6f 63 6b d */. setsock
8990: 6f 70 74 28 6c 69 73 74 65 6e 65 72 2c 53 4f 4c opt(listener,SOL
89a0: 5f 53 4f 43 4b 45 54 2c 53 4f 5f 52 45 55 53 45 _SOCKET,SO_REUSE
89b0: 41 44 44 52 2c 26 6f 70 74 2c 73 69 7a 65 6f 66 ADDR,&opt,sizeof
89c0: 28 6f 70 74 29 29 3b 0a 0a 20 20 20 20 69 66 28 (opt));.. if(
89d0: 20 62 69 6e 64 28 6c 69 73 74 65 6e 65 72 2c 20 bind(listener,
89e0: 28 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 (struct sockaddr
89f0: 2a 29 26 69 6e 61 64 64 72 2c 20 73 69 7a 65 6f *)&inaddr, sizeo
8a00: 66 28 69 6e 61 64 64 72 29 29 3c 30 20 29 7b 0a f(inaddr))<0 ){.
8a10: 20 20 20 20 20 20 63 6c 6f 73 65 28 6c 69 73 74 close(list
8a20: 65 6e 65 72 29 3b 0a 20 20 20 20 20 20 69 50 6f ener);. iPo
8a30: 72 74 2b 2b 3b 0a 20 20 20 20 20 20 63 6f 6e 74 rt++;. cont
8a40: 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 20 20 20 inue;. }.
8a50: 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 break;. }. if(
8a60: 20 69 50 6f 72 74 3e 6d 78 50 6f 72 74 20 29 7b iPort>mxPort ){
8a70: 0a 20 20 20 20 69 66 28 20 6d 6e 50 6f 72 74 3d . if( mnPort=
8a80: 3d 6d 78 50 6f 72 74 20 29 7b 0a 20 20 20 20 20 =mxPort ){.
8a90: 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c 28 22 75 fossil_fatal("u
8aa0: 6e 61 62 6c 65 20 74 6f 20 6f 70 65 6e 20 6c 69 nable to open li
8ab0: 73 74 65 6e 69 6e 67 20 73 6f 63 6b 65 74 20 6f stening socket o
8ac0: 6e 20 70 6f 72 74 73 20 25 64 22 2c 20 6d 6e 50 n ports %d", mnP
8ad0: 6f 72 74 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b ort);. }else{
8ae0: 0a 20 20 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 . fossil_fa
8af0: 74 61 6c 28 22 75 6e 61 62 6c 65 20 74 6f 20 6f tal("unable to o
8b00: 70 65 6e 20 6c 69 73 74 65 6e 69 6e 67 20 73 6f pen listening so
8b10: 63 6b 65 74 20 6f 6e 20 61 6e 79 22 0a 20 20 20 cket on any".
8b20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8b30: 22 20 70 6f 72 74 20 69 6e 20 74 68 65 20 72 61 " port in the ra
8b40: 6e 67 65 20 25 64 2e 2e 25 64 22 2c 20 6d 6e 50 nge %d..%d", mnP
8b50: 6f 72 74 2c 20 6d 78 50 6f 72 74 29 3b 0a 20 20 ort, mxPort);.
8b60: 20 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 69 50 }. }. if( iP
8b70: 6f 72 74 3e 6d 78 50 6f 72 74 20 29 20 72 65 74 ort>mxPort ) ret
8b80: 75 72 6e 20 31 3b 0a 20 20 6c 69 73 74 65 6e 28 urn 1;. listen(
8b90: 6c 69 73 74 65 6e 65 72 2c 31 30 29 3b 0a 20 20 listener,10);.
8ba0: 69 66 28 20 69 50 6f 72 74 3e 6d 6e 50 6f 72 74 if( iPort>mnPort
8bb0: 20 29 7b 0a 20 20 20 20 70 72 69 6e 74 66 28 22 ){. printf("
8bc0: 4c 69 73 74 65 6e 69 6e 67 20 66 6f 72 20 48 54 Listening for HT
8bd0: 54 50 20 72 65 71 75 65 73 74 73 20 6f 6e 20 54 TP requests on T
8be0: 43 50 20 70 6f 72 74 20 25 64 5c 6e 22 2c 20 69 CP port %d\n", i
8bf0: 50 6f 72 74 29 3b 0a 20 20 20 20 66 66 6c 75 73 Port);. fflus
8c00: 68 28 73 74 64 6f 75 74 29 3b 0a 20 20 7d 0a 20 h(stdout);. }.
8c10: 20 69 66 28 20 7a 42 72 6f 77 73 65 72 20 29 7b if( zBrowser ){
8c20: 0a 20 20 20 20 7a 42 72 6f 77 73 65 72 20 3d 20 . zBrowser =
8c30: 6d 70 72 69 6e 74 66 28 7a 42 72 6f 77 73 65 72 mprintf(zBrowser
8c40: 2c 20 69 50 6f 72 74 29 3b 0a 20 20 20 20 73 79 , iPort);. sy
8c50: 73 74 65 6d 28 7a 42 72 6f 77 73 65 72 29 3b 0a stem(zBrowser);.
8c60: 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 31 20 29 }. while( 1 )
8c70: 7b 0a 20 20 20 20 69 66 28 20 6e 63 68 69 6c 64 {. if( nchild
8c80: 72 65 6e 3e 4d 41 58 5f 50 41 52 41 4c 4c 45 4c ren>MAX_PARALLEL
8c90: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 53 6c 6f ){. /* Slo
8ca0: 77 20 64 6f 77 6e 20 69 66 20 63 6f 6e 6e 65 63 w down if connec
8cb0: 74 69 6f 6e 73 20 61 72 65 20 61 72 72 69 76 69 tions are arrivi
8cc0: 6e 67 20 74 6f 6f 20 66 61 73 74 20 2a 2f 0a 20 ng too fast */.
8cd0: 20 20 20 20 20 73 6c 65 65 70 28 20 6e 63 68 69 sleep( nchi
8ce0: 6c 64 72 65 6e 2d 4d 41 58 5f 50 41 52 41 4c 4c ldren-MAX_PARALL
8cf0: 45 4c 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 EL );. }.
8d00: 64 65 6c 61 79 2e 74 76 5f 73 65 63 20 3d 20 36 delay.tv_sec = 6
8d10: 30 3b 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 5f 0;. delay.tv_
8d20: 75 73 65 63 20 3d 20 30 3b 0a 20 20 20 20 46 44 usec = 0;. FD
8d30: 5f 5a 45 52 4f 28 26 72 65 61 64 66 64 73 29 3b _ZERO(&readfds);
8d40: 0a 20 20 20 20 46 44 5f 53 45 54 28 20 6c 69 73 . FD_SET( lis
8d50: 74 65 6e 65 72 2c 20 26 72 65 61 64 66 64 73 29 tener, &readfds)
8d60: 3b 0a 20 20 20 20 69 66 28 20 73 65 6c 65 63 74 ;. if( select
8d70: 28 20 6c 69 73 74 65 6e 65 72 2b 31 2c 20 26 72 ( listener+1, &r
8d80: 65 61 64 66 64 73 2c 20 30 2c 20 30 2c 20 26 64 eadfds, 0, 0, &d
8d90: 65 6c 61 79 29 20 29 7b 0a 20 20 20 20 20 20 6c elay) ){. l
8da0: 65 6e 61 64 64 72 20 3d 20 73 69 7a 65 6f 66 28 enaddr = sizeof(
8db0: 69 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20 63 inaddr);. c
8dc0: 6f 6e 6e 65 63 74 69 6f 6e 20 3d 20 61 63 63 65 onnection = acce
8dd0: 70 74 28 6c 69 73 74 65 6e 65 72 2c 20 28 73 74 pt(listener, (st
8de0: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26 ruct sockaddr*)&
8df0: 69 6e 61 64 64 72 2c 0a 20 20 20 20 20 20 20 20 inaddr,.
8e00: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8e10: 20 20 20 20 20 20 20 20 20 20 20 20 28 73 6f 63 (soc
8e20: 6b 6c 65 6e 5f 74 2a 29 20 26 6c 65 6e 61 64 64 klen_t*) &lenadd
8e30: 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20 63 6f r);. if( co
8e40: 6e 6e 65 63 74 69 6f 6e 3e 3d 30 20 29 7b 0a 20 nnection>=0 ){.
8e50: 20 20 20 20 20 20 20 63 68 69 6c 64 20 3d 20 66 child = f
8e60: 6f 72 6b 28 29 3b 0a 20 20 20 20 20 20 20 20 69 ork();. i
8e70: 66 28 20 63 68 69 6c 64 21 3d 30 20 29 7b 0a 20 f( child!=0 ){.
8e80: 20 20 20 20 20 20 20 20 20 69 66 28 20 63 68 69 if( chi
8e90: 6c 64 3e 30 20 29 20 6e 63 68 69 6c 64 72 65 6e ld>0 ) nchildren
8ea0: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 63 6c ++;. cl
8eb0: 6f 73 65 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b ose(connection);
8ec0: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a . }else{.
8ed0: 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 close(
8ee0: 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 75 0);. du
8ef0: 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 p(connection);.
8f00: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 31 close(1
8f10: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 75 70 );. dup
8f20: 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 (connection);.
8f30: 20 20 20 20 20 20 20 20 69 66 28 20 21 67 2e 66 if( !g.f
8f40: 48 74 74 70 54 72 61 63 65 20 29 7b 0a 20 20 20 HttpTrace ){.
8f50: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 32 close(2
8f60: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 );. d
8f70: 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a up(connection);.
8f80: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 }.
8f90: 20 20 20 20 20 20 63 6c 6f 73 65 28 63 6f 6e 6e close(conn
8fa0: 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 ection);.
8fb0: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 return 0;.
8fc0: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 }. }.
8fd0: 20 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75 72 79 }. /* Bury
8fe0: 20 64 65 61 64 20 63 68 69 6c 64 72 65 6e 20 2a dead children *
8ff0: 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 77 61 69 /. while( wai
9000: 74 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f 48 41 tpid(0, 0, WNOHA
9010: 4e 47 29 3e 30 20 29 7b 0a 20 20 20 20 20 20 6e NG)>0 ){. n
9020: 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20 20 20 children--;.
9030: 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54 20 52 }. }. /* NOT R
9040: 45 41 43 48 45 44 20 2a 2f 20 20 0a 20 20 65 78 EACHED */ . ex
9050: 69 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a it(1);.#endif.}.
9060: 0a 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66 20 ../*.** Name of
9070: 64 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73 2e days and months.
9080: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 .*/.static const
9090: 20 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d 20 char *azDays[]
90a0: 3d 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22 4d =. {"Sun", "M
90b0: 6f 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65 64 on", "Tue", "Wed
90c0: 22 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22 2c ", "Thu", "Fri",
90d0: 20 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61 74 "Sat", 0};.stat
90e0: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 ic const char *a
90f0: 7a 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20 20 zMonths[] =.
9100: 7b 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20 22 {"Jan", "Feb", "
9110: 4d 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d 61 Mar", "Apr", "Ma
9120: 79 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20 20 y", "Jun",.
9130: 22 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22 53 "Jul", "Aug", "S
9140: 65 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f 76 ep", "Oct", "Nov
9150: 22 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a 0a ", "Dec", 0};...
9160: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61 6e /*.** Returns an
9170: 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 RFC822-formatte
9180: 64 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73 75 d time string su
9190: 69 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50 20 itable for HTTP
91a0: 68 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a 2a headers, among.*
91b0: 2a 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e 0a * other things..
91c0: 2a 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d 65 ** Returned time
91d0: 7a 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20 47 zone is always G
91e0: 4d 54 20 61 73 20 72 65 71 75 69 72 65 64 20 62 MT as required b
91f0: 79 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63 69 y HTTP/1.1 speci
9200: 66 69 63 61 74 69 6f 6e 2e 0a 2a 2a 20 54 68 65 fication..** The
9210: 20 72 65 74 75 72 6e 65 64 20 73 74 72 69 6e 67 returned string
9220: 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 77 69 is allocated wi
9230: 74 68 20 6d 61 6c 6c 6f 63 28 29 20 61 6e 64 20 th malloc() and
9240: 6d 75 73 74 20 62 65 20 66 72 65 65 64 0a 2a 2a must be freed.**
9250: 20 77 69 74 68 20 66 72 65 65 28 29 2e 0a 2a 2a with free()..**
9260: 0a 2a 2a 20 53 65 65 20 68 74 74 70 3a 2f 2f 77 .** See http://w
9270: 77 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66 63 73 ww.faqs.org/rfcs
9280: 2f 72 66 63 38 32 32 2e 68 74 6d 6c 2c 20 73 65 /rfc822.html, se
9290: 63 74 69 6f 6e 20 35 0a 2a 2a 20 61 6e 64 20 68 ction 5.** and h
92a0: 74 74 70 3a 2f 2f 77 77 77 2e 66 61 71 73 2e 6f ttp://www.faqs.o
92b0: 72 67 2f 72 66 63 73 2f 72 66 63 32 36 31 36 2e rg/rfcs/rfc2616.
92c0: 68 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 20 33 2e html, section 3.
92d0: 33 2e 0a 2a 2f 0a 63 68 61 72 20 2a 63 67 69 5f 3..*/.char *cgi_
92e0: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 rfc822_datestamp
92f0: 28 74 69 6d 65 5f 74 20 6e 6f 77 29 7b 0a 20 20 (time_t now){.
9300: 73 74 72 75 63 74 20 74 6d 20 2a 70 54 6d 3b 0a struct tm *pTm;.
9310: 20 20 70 54 6d 20 3d 20 67 6d 74 69 6d 65 28 26 pTm = gmtime(&
9320: 6e 6f 77 29 3b 0a 20 20 69 66 28 20 70 54 6d 3d now);. if( pTm=
9330: 3d 30 20 29 20 72 65 74 75 72 6e 20 22 22 3b 0a =0 ) return "";.
9340: 20 20 72 65 74 75 72 6e 20 6d 70 72 69 6e 74 66 return mprintf
9350: 28 22 25 73 2c 20 25 64 20 25 73 20 25 30 32 64 ("%s, %d %s %02d
9360: 20 25 30 32 64 3a 25 30 32 64 3a 25 30 32 64 20 %02d:%02d:%02d
9370: 47 4d 54 22 2c 0a 20 20 20 20 20 20 20 20 20 20 GMT",.
9380: 20 20 20 20 20 20 20 61 7a 44 61 79 73 5b 70 54 azDays[pT
9390: 6d 2d 3e 74 6d 5f 77 64 61 79 5d 2c 20 70 54 6d m->tm_wday], pTm
93a0: 2d 3e 74 6d 5f 6d 64 61 79 2c 20 61 7a 4d 6f 6e ->tm_mday, azMon
93b0: 74 68 73 5b 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d ths[pTm->tm_mon]
93c0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ,.
93d0: 20 20 20 70 54 6d 2d 3e 74 6d 5f 79 65 61 72 2b pTm->tm_year+
93e0: 31 39 30 30 2c 20 70 54 6d 2d 3e 74 6d 5f 68 6f 1900, pTm->tm_ho
93f0: 75 72 2c 20 70 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c ur, pTm->tm_min,
9400: 20 70 54 6d 2d 3e 74 6d 5f 73 65 63 29 3b 0a 7d pTm->tm_sec);.}
9410: 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65 20 61 6e ../*.** Parse an
9420: 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 RFC822-formatte
9430: 64 20 74 69 6d 65 73 74 61 6d 70 20 61 73 20 77 d timestamp as w
9440: 65 27 64 20 65 78 70 65 63 74 20 66 72 6f 6d 20 e'd expect from
9450: 48 54 54 50 20 61 6e 64 20 72 65 74 75 72 6e 0a HTTP and return.
9460: 2a 2a 20 61 20 55 6e 69 78 20 65 70 6f 63 68 20 ** a Unix epoch
9470: 74 69 6d 65 2e 20 3c 3d 20 7a 65 72 6f 20 69 73 time. <= zero is
9480: 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 66 61 69 returned on fai
9490: 6c 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 lure..**.** Note
94a0: 20 74 68 61 74 20 74 68 69 73 20 77 6f 6e 27 74 that this won't
94b0: 20 68 61 6e 64 6c 65 20 61 6c 6c 20 74 68 65 20 handle all the
94c0: 5f 61 6c 6c 6f 77 65 64 5f 20 48 54 54 50 20 66 _allowed_ HTTP f
94d0: 6f 72 6d 61 74 73 2c 20 6a 75 73 74 20 74 68 65 ormats, just the
94e0: 0a 2a 2a 20 6d 6f 73 74 20 70 6f 70 75 6c 61 72 .** most popular
94f0: 20 6f 6e 65 20 28 74 68 65 20 6f 6e 65 20 67 65 one (the one ge
9500: 6e 65 72 61 74 65 64 20 62 79 20 63 67 69 5f 72 nerated by cgi_r
9510: 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 fc822_datestamp(
9520: 29 2c 20 61 63 74 75 61 6c 6c 79 29 2e 0a 2a 2f ), actually)..*/
9530: 0a 74 69 6d 65 5f 74 20 63 67 69 5f 72 66 63 38 .time_t cgi_rfc8
9540: 32 32 5f 70 61 72 73 65 64 61 74 65 28 63 6f 6e 22_parsedate(con
9550: 73 74 20 63 68 61 72 20 2a 7a 44 61 74 65 29 7b st char *zDate){
9560: 0a 20 20 73 74 72 75 63 74 20 74 6d 20 74 3b 0a . struct tm t;.
9570: 20 20 63 68 61 72 20 7a 49 67 6e 6f 72 65 5b 31 char zIgnore[1
9580: 36 5d 3b 0a 20 20 63 68 61 72 20 7a 4d 6f 6e 74 6];. char zMont
9590: 68 5b 31 36 5d 3b 0a 0a 20 20 6d 65 6d 73 65 74 h[16];.. memset
95a0: 28 26 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 74 (&t, 0, sizeof(t
95b0: 29 29 3b 0a 20 20 69 66 28 20 37 3d 3d 73 73 63 ));. if( 7==ssc
95c0: 61 6e 66 28 7a 44 61 74 65 2c 20 22 25 31 32 5b anf(zDate, "%12[
95d0: 41 2d 5a 61 2d 7a 2c 5d 20 25 64 20 25 31 32 5b A-Za-z,] %d %12[
95e0: 41 2d 5a 61 2d 7a 5d 20 25 64 20 25 64 3a 25 64 A-Za-z] %d %d:%d
95f0: 3a 25 64 22 2c 20 7a 49 67 6e 6f 72 65 2c 0a 20 :%d", zIgnore,.
9600: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
9610: 20 20 20 20 20 20 26 74 2e 74 6d 5f 6d 64 61 79 &t.tm_mday
9620: 2c 20 7a 4d 6f 6e 74 68 2c 20 26 74 2e 74 6d 5f , zMonth, &t.tm_
9630: 79 65 61 72 2c 20 26 74 2e 74 6d 5f 68 6f 75 72 year, &t.tm_hour
9640: 2c 20 26 74 2e 74 6d 5f 6d 69 6e 2c 0a 20 20 20 , &t.tm_min,.
9650: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
9660: 20 20 20 20 26 74 2e 74 6d 5f 73 65 63 29 29 7b &t.tm_sec)){
9670: 0a 0a 20 20 20 20 69 66 28 20 74 2e 74 6d 5f 79 .. if( t.tm_y
9680: 65 61 72 20 3e 20 31 39 30 30 20 29 20 74 2e 74 ear > 1900 ) t.t
9690: 6d 5f 79 65 61 72 20 2d 3d 20 31 39 30 30 3b 0a m_year -= 1900;.
96a0: 20 20 20 20 66 6f 72 28 74 2e 74 6d 5f 6d 6f 6e for(t.tm_mon
96b0: 3d 30 3b 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 =0; azMonths[t.t
96c0: 6d 5f 6d 6f 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e m_mon]; t.tm_mon
96d0: 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 21 ++){. if( !
96e0: 73 74 72 6e 63 61 73 65 63 6d 70 28 20 61 7a 4d strncasecmp( azM
96f0: 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c onths[t.tm_mon],
9700: 20 7a 4d 6f 6e 74 68 2c 20 33 20 29 29 7b 0a 20 zMonth, 3 )){.
9710: 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 6d 6b return mk
9720: 67 6d 74 69 6d 65 28 26 74 29 3b 0a 20 20 20 20 gmtime(&t);.
9730: 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 }. }. }..
9740: 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a return 0;.}../*
9750: 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 20 73 74 .** Convert a st
9760: 72 75 63 74 20 74 6d 2a 20 74 68 61 74 20 72 65 ruct tm* that re
9770: 70 72 65 73 65 6e 74 73 20 61 20 6d 6f 6d 65 6e presents a momen
9780: 74 20 69 6e 20 55 54 43 20 69 6e 74 6f 20 74 68 t in UTC into th
9790: 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 73 e number.** of s
97a0: 65 63 6f 6e 64 73 20 69 6e 20 31 39 37 30 2c 20 econds in 1970,
97b0: 55 54 43 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 6d UTC..*/.time_t m
97c0: 6b 67 6d 74 69 6d 65 28 73 74 72 75 63 74 20 74 kgmtime(struct t
97d0: 6d 20 2a 70 29 7b 0a 20 20 74 69 6d 65 5f 74 20 m *p){. time_t
97e0: 74 3b 0a 20 20 69 6e 74 20 6e 44 61 79 3b 0a 20 t;. int nDay;.
97f0: 20 69 6e 74 20 69 73 4c 65 61 70 59 72 3b 0a 20 int isLeapYr;.
9800: 20 2f 2a 20 44 61 79 73 20 69 6e 20 65 61 63 68 /* Days in each
9810: 20 6d 6f 6e 74 68 3a 20 20 20 20 20 20 20 33 31 month: 31
9820: 2c 20 32 38 2c 20 33 31 2c 20 33 30 2c 20 33 31 , 28, 31, 30, 31
9830: 2c 20 33 30 2c 20 33 31 2c 20 33 31 2c 20 33 30 , 30, 31, 31, 30
9840: 2c 20 33 31 2c 20 33 30 2c 20 33 31 20 2a 2f 0a , 31, 30, 31 */.
9850: 20 20 73 74 61 74 69 63 20 69 6e 74 20 70 72 69 static int pri
9860: 6f 72 44 61 79 73 5b 5d 20 20 20 3d 20 7b 20 20 orDays[] = {
9870: 30 2c 20 33 31 2c 20 35 39 2c 20 39 30 2c 31 32 0, 31, 59, 90,12
9880: 30 2c 31 35 31 2c 31 38 31 2c 32 31 32 2c 32 34 0,151,181,212,24
9890: 33 2c 32 37 33 2c 33 30 34 2c 33 33 34 20 7d 3b 3,273,304,334 };
98a0: 0a 20 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e . if( p->tm_mon
98b0: 3c 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e 59 <0 ){. int nY
98c0: 65 61 72 20 3d 20 28 31 31 20 2d 20 70 2d 3e 74 ear = (11 - p->t
98d0: 6d 5f 6d 6f 6e 29 2f 31 32 3b 0a 20 20 20 20 70 m_mon)/12;. p
98e0: 2d 3e 74 6d 5f 79 65 61 72 20 2d 3d 20 6e 59 65 ->tm_year -= nYe
98f0: 61 72 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f ar;. p->tm_mo
9900: 6e 20 2b 3d 20 6e 59 65 61 72 2a 31 32 3b 0a 20 n += nYear*12;.
9910: 20 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 74 6d }else if( p->tm
9920: 5f 6d 6f 6e 3e 31 31 20 29 7b 0a 20 20 20 20 70 _mon>11 ){. p
9930: 2d 3e 74 6d 5f 79 65 61 72 20 2b 3d 20 70 2d 3e ->tm_year += p->
9940: 74 6d 5f 6d 6f 6e 2f 31 32 3b 0a 20 20 20 20 70 tm_mon/12;. p
9950: 2d 3e 74 6d 5f 6d 6f 6e 20 25 3d 20 31 32 3b 0a ->tm_mon %= 12;.
9960: 20 20 7d 0a 20 20 69 73 4c 65 61 70 59 72 20 3d }. isLeapYr =
9970: 20 70 2d 3e 74 6d 5f 79 65 61 72 25 34 3d 3d 30 p->tm_year%4==0
9980: 20 26 26 20 28 70 2d 3e 74 6d 5f 79 65 61 72 25 && (p->tm_year%
9990: 31 30 30 21 3d 30 20 7c 7c 20 28 70 2d 3e 74 6d 100!=0 || (p->tm
99a0: 5f 79 65 61 72 2b 33 30 30 29 25 34 30 30 3d 3d _year+300)%400==
99b0: 30 29 3b 0a 20 20 70 2d 3e 74 6d 5f 79 64 61 79 0);. p->tm_yday
99c0: 20 3d 20 70 72 69 6f 72 44 61 79 73 5b 70 2d 3e = priorDays[p->
99d0: 74 6d 5f 6d 6f 6e 5d 20 2b 20 70 2d 3e 74 6d 5f tm_mon] + p->tm_
99e0: 6d 64 61 79 20 2d 20 31 3b 0a 20 20 69 66 28 20 mday - 1;. if(
99f0: 69 73 4c 65 61 70 59 72 20 26 26 20 70 2d 3e 74 isLeapYr && p->t
9a00: 6d 5f 6d 6f 6e 3e 31 20 29 20 70 2d 3e 74 6d 5f m_mon>1 ) p->tm_
9a10: 79 64 61 79 2b 2b 3b 0a 20 20 6e 44 61 79 20 3d yday++;. nDay =
9a20: 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 37 30 29 (p->tm_year-70)
9a30: 2a 33 36 35 20 2b 20 28 70 2d 3e 74 6d 5f 79 65 *365 + (p->tm_ye
9a40: 61 72 2d 36 39 29 2f 34 20 2d 70 2d 3e 74 6d 5f ar-69)/4 -p->tm_
9a50: 79 65 61 72 2f 31 30 30 20 2b 20 0a 20 20 20 20 year/100 + .
9a60: 20 20 20 20 20 28 70 2d 3e 74 6d 5f 79 65 61 72 (p->tm_year
9a70: 2b 33 30 30 29 2f 34 30 30 20 2b 20 70 2d 3e 74 +300)/400 + p->t
9a80: 6d 5f 79 64 61 79 3b 0a 20 20 74 20 3d 20 28 28 m_yday;. t = ((
9a90: 6e 44 61 79 2a 32 34 20 2b 20 70 2d 3e 74 6d 5f nDay*24 + p->tm_
9aa0: 68 6f 75 72 29 2a 36 30 20 2b 20 70 2d 3e 74 6d hour)*60 + p->tm
9ab0: 5f 6d 69 6e 29 2a 36 30 20 2b 20 70 2d 3e 74 6d _min)*60 + p->tm
9ac0: 5f 73 65 63 3b 0a 20 20 72 65 74 75 72 6e 20 74 _sec;. return t
9ad0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b ;.}../*.** Check
9ae0: 20 74 68 65 20 6f 62 6a 65 63 74 54 69 6d 65 20 the objectTime
9af0: 61 67 61 69 6e 73 74 20 74 68 65 20 49 66 2d 4d against the If-M
9b00: 6f 64 69 66 69 65 64 2d 53 69 6e 63 65 20 72 65 odified-Since re
9b10: 71 75 65 73 74 20 68 65 61 64 65 72 2e 20 49 66 quest header. If
9b20: 20 74 68 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 74 the.** object t
9b30: 69 6d 65 20 69 73 6e 27 74 20 61 6e 79 20 6e 65 ime isn't any ne
9b40: 77 65 72 20 74 68 61 6e 20 74 68 65 20 68 65 61 wer than the hea
9b50: 64 65 72 2c 20 77 65 20 69 6d 6d 65 64 69 61 74 der, we immediat
9b60: 65 6c 79 20 73 65 6e 64 20 62 61 63 6b 0a 2a 2a ely send back.**
9b70: 20 61 20 33 30 34 20 72 65 70 6c 79 20 61 6e 64 a 304 reply and
9b80: 20 65 78 69 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 exit..*/.void c
9b90: 67 69 5f 6d 6f 64 69 66 69 65 64 5f 73 69 6e 63 gi_modified_sinc
9ba0: 65 28 74 69 6d 65 5f 74 20 6f 62 6a 65 63 74 54 e(time_t objectT
9bb0: 69 6d 65 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 ime){. const ch
9bc0: 61 72 20 2a 7a 49 66 20 3d 20 50 28 22 48 54 54 ar *zIf = P("HTT
9bd0: 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 P_IF_MODIFIED_SI
9be0: 4e 43 45 22 29 3b 0a 20 20 69 66 28 20 7a 49 66 NCE");. if( zIf
9bf0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 ==0 ) return;.
9c00: 69 66 28 20 6f 62 6a 65 63 74 54 69 6d 65 20 3e if( objectTime >
9c10: 20 63 67 69 5f 72 66 63 38 32 32 5f 70 61 72 73 cgi_rfc822_pars
9c20: 65 64 61 74 65 28 7a 49 66 29 20 29 20 72 65 74 edate(zIf) ) ret
9c30: 75 72 6e 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 urn;. cgi_set_s
9c40: 74 61 74 75 73 28 33 30 34 2c 22 4e 6f 74 20 4d tatus(304,"Not M
9c50: 6f 64 69 66 69 65 64 22 29 3b 0a 20 20 63 67 69 odified");. cgi
9c60: 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 _reset_content()
9c70: 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 3b ;. cgi_reply();
9c80: 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a . exit(0);.}.