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 2a 70 43 6f 6e 74 65 6e 74 3b 0a 73 lob *pContent;.s
0b80: 74 61 74 69 63 20 42 6c 6f 62 20 63 67 69 43 6f tatic Blob cgiCo
0b90: 6e 74 65 6e 74 5b 32 5d 20 3d 20 7b 20 42 4c 4f ntent[2] = { BLO
0ba0: 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52 2c 20 42 B_INITIALIZER, B
0bb0: 4c 4f 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52 20 LOB_INITIALIZER
0bc0: 7d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 };../*.** Set th
0bd0: 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 62 75 e destination bu
0be0: 66 66 65 72 20 69 6e 74 6f 20 77 68 69 63 68 20 ffer into which
0bf0: 74 6f 20 61 63 63 75 6d 75 6c 61 74 65 20 43 47 to accumulate CG
0c00: 49 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76 6f I content..*/.vo
0c10: 69 64 20 63 67 69 5f 64 65 73 74 69 6e 61 74 69 id cgi_destinati
0c20: 6f 6e 28 69 6e 74 20 64 65 73 74 29 7b 0a 20 20 on(int dest){.
0c30: 73 77 69 74 63 68 28 20 64 65 73 74 20 29 7b 0a switch( dest ){.
0c40: 20 20 20 20 63 61 73 65 20 43 47 49 5f 48 45 41 case CGI_HEA
0c50: 44 45 52 3a 20 7b 0a 20 20 20 20 20 20 70 43 6f DER: {. pCo
0c60: 6e 74 65 6e 74 20 3d 20 26 63 67 69 43 6f 6e 74 ntent = &cgiCont
0c70: 65 6e 74 5b 30 5d 3b 0a 20 20 20 20 20 20 62 72 ent[0];. br
0c80: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 63 eak;. }. c
0c90: 61 73 65 20 43 47 49 5f 42 4f 44 59 3a 20 7b 0a ase CGI_BODY: {.
0ca0: 20 20 20 20 20 20 70 43 6f 6e 74 65 6e 74 20 3d pContent =
0cb0: 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 3b &cgiContent[1];
0cc0: 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 . break;.
0cd0: 20 20 7d 0a 20 20 20 20 64 65 66 61 75 6c 74 3a }. default:
0ce0: 20 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 61 6e {. cgi_pan
0cf0: 69 63 28 22 62 61 64 20 64 65 73 74 69 6e 61 74 ic("bad destinat
0d00: 69 6f 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d ion");. }. }
0d10: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 .}../*.** Append
0d20: 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 reply content t
0d30: 6f 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 65 o what already e
0d40: 78 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 xists..*/.void c
0d50: 67 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e gi_append_conten
0d60: 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 t(const char *zD
0d70: 61 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b 0a ata, int nAmt){.
0d80: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 43 blob_append(pC
0d90: 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c 20 6e ontent, zData, n
0da0: 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 Amt);.}../*.** R
0db0: 65 73 65 74 20 74 68 65 20 48 54 54 50 20 72 65 eset the HTTP re
0dc0: 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 20 61 ply text to be a
0dd0: 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 2e 0a n empty string..
0de0: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 73 65 */.void cgi_rese
0df0: 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 29 7b t_content(void){
0e00: 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 . blob_reset(&c
0e10: 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 20 giContent[0]);.
0e20: 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67 69 blob_reset(&cgi
0e30: 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 7d 0a 0a Content[1]);.}..
0e40: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 /*.** Return a p
0e50: 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43 47 ointer to the CG
0e60: 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a 2a I output blob..*
0e70: 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74 70 /.Blob *cgi_outp
0e80: 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a 20 ut_blob(void){.
0e90: 20 72 65 74 75 72 6e 20 70 43 6f 6e 74 65 6e 74 return pContent
0ea0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 62 69 ;.}../*.** Combi
0eb0: 6e 65 20 74 68 65 20 68 65 61 64 65 72 20 61 6e ne the header an
0ec0: 64 20 62 6f 64 79 20 6f 66 20 74 68 65 20 43 47 d body of the CG
0ed0: 49 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 20 I into a single
0ee0: 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 69 string..*/.stati
0ef0: 63 20 76 6f 69 64 20 63 67 69 5f 63 6f 6d 62 69 c void cgi_combi
0f00: 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 6f ne_header_and_bo
0f10: 64 79 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 dy(void){. int
0f20: 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a 65 size = blob_size
0f30: 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 (&cgiContent[1])
0f40: 3b 0a 20 20 69 66 28 20 73 69 7a 65 3e 30 20 29 ;. if( size>0 )
0f50: 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e {. blob_appen
0f60: 64 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d d(&cgiContent[0]
0f70: 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 , blob_buffer(&c
0f80: 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 2c 20 73 giContent[1]), s
0f90: 69 7a 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f 72 ize);. blob_r
0fa0: 65 73 65 74 28 26 63 67 69 43 6f 6e 74 65 6e 74 eset(&cgiContent
0fb0: 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a [1]);. }.}../*.
0fc0: 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 6e ** Return a poin
0fd0: 74 65 72 20 74 6f 20 74 68 65 20 48 54 54 50 20 ter to the HTTP
0fe0: 72 65 70 6c 79 20 74 65 78 74 2e 0a 2a 2f 0a 63 reply text..*/.c
0ff0: 68 61 72 20 2a 63 67 69 5f 65 78 74 72 61 63 74 har *cgi_extract
1000: 5f 63 6f 6e 74 65 6e 74 28 69 6e 74 20 2a 70 6e _content(int *pn
1010: 41 6d 74 29 7b 0a 20 20 63 67 69 5f 63 6f 6d 62 Amt){. cgi_comb
1020: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 ine_header_and_b
1030: 6f 64 79 28 29 3b 0a 20 20 72 65 74 75 72 6e 20 ody();. return
1040: 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 69 blob_buffer(&cgi
1050: 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 7d 0a 0a Content[0]);.}..
1060: 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 6c /*.** Additional
1070: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73 65 information use
1080: 64 20 74 6f 20 66 6f 72 6d 20 74 68 65 20 48 54 d to form the HT
1090: 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 73 74 61 74 TP reply.*/.stat
10a0: 69 63 20 63 68 61 72 20 2a 7a 43 6f 6e 74 65 6e ic char *zConten
10b0: 74 54 79 70 65 20 3d 20 22 74 65 78 74 2f 68 74 tType = "text/ht
10c0: 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 43 6f 6e 74 ml"; /* Cont
10d0: 65 6e 74 20 74 79 70 65 20 6f 66 20 74 68 65 20 ent type of the
10e0: 72 65 70 6c 79 20 2a 2f 0a 73 74 61 74 69 63 20 reply */.static
10f0: 63 68 61 72 20 2a 7a 52 65 70 6c 79 53 74 61 74 char *zReplyStat
1100: 75 73 20 3d 20 22 4f 4b 22 3b 20 20 20 20 20 20 us = "OK";
1110: 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 73 /* Reply s
1120: 74 61 74 75 73 20 64 65 73 63 72 69 70 74 69 6f tatus descriptio
1130: 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 n */.static int
1140: 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 32 iReplyStatus = 2
1150: 30 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 00;
1160: 20 20 2f 2a 20 52 65 70 6c 79 20 73 74 61 74 75 /* Reply statu
1170: 73 20 63 6f 64 65 20 2a 2f 0a 73 74 61 74 69 63 s code */.static
1180: 20 42 6c 6f 62 20 65 78 74 72 61 48 65 61 64 65 Blob extraHeade
1190: 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 4c r = BLOB_INITIAL
11a0: 49 5a 45 52 3b 20 20 2f 2a 20 45 78 74 72 61 20 IZER; /* Extra
11b0: 68 65 61 64 65 72 20 74 65 78 74 20 2a 2f 0a 73 header text */.s
11c0: 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 48 74 tatic int fullHt
11d0: 74 70 52 65 70 6c 79 20 3d 20 30 3b 20 20 20 20 tpReply = 0;
11e0: 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 61 20 /* True for a
11f0: 66 75 6c 6c 2d 62 6c 6f 77 6e 20 48 54 54 50 20 full-blown HTTP
1200: 68 65 61 64 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a 2a header */../*.**
1210: 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 20 63 Set the reply c
1220: 6f 6e 74 65 6e 74 20 74 79 70 65 0a 2a 2f 0a 76 ontent type.*/.v
1230: 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 oid cgi_set_cont
1240: 65 6e 74 5f 74 79 70 65 28 63 6f 6e 73 74 20 63 ent_type(const c
1250: 68 61 72 20 2a 7a 54 79 70 65 29 7b 0a 20 20 7a har *zType){. z
1260: 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 6d 70 ContentType = mp
1270: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 54 79 70 rintf("%s", zTyp
1280: 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 e);.}../*.** Set
1290: 20 74 68 65 20 72 65 70 6c 79 20 63 6f 6e 74 65 the reply conte
12a0: 6e 74 20 74 6f 20 74 68 65 20 73 70 65 63 69 66 nt to the specif
12b0: 69 65 64 20 42 4c 4f 42 2e 0a 2a 2f 0a 76 6f 69 ied BLOB..*/.voi
12c0: 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 65 6e d cgi_set_conten
12d0: 74 28 42 6c 6f 62 20 2a 70 4e 65 77 43 6f 6e 74 t(Blob *pNewCont
12e0: 65 6e 74 29 7b 0a 20 20 63 67 69 5f 72 65 73 65 ent){. cgi_rese
12f0: 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63 t_content();. c
1300: 67 69 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 43 gi_destination(C
1310: 47 49 5f 48 45 41 44 45 52 29 3b 0a 20 20 63 67 GI_HEADER);. cg
1320: 69 43 6f 6e 74 65 6e 74 5b 30 5d 20 3d 20 2a 70 iContent[0] = *p
1330: 4e 65 77 43 6f 6e 74 65 6e 74 3b 0a 20 20 62 6c NewContent;. bl
1340: 6f 62 5f 7a 65 72 6f 28 70 4e 65 77 43 6f 6e 74 ob_zero(pNewCont
1350: 65 6e 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 ent);.}../*.** S
1360: 65 74 20 74 68 65 20 72 65 70 6c 79 20 73 74 61 et the reply sta
1370: 74 75 73 20 63 6f 64 65 0a 2a 2f 0a 76 6f 69 64 tus code.*/.void
1380: 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 cgi_set_status(
1390: 69 6e 74 20 69 53 74 61 74 2c 20 63 6f 6e 73 74 int iStat, const
13a0: 20 63 68 61 72 20 2a 7a 53 74 61 74 29 7b 0a 20 char *zStat){.
13b0: 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 zReplyStatus =
13c0: 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 53 mprintf("%s", zS
13d0: 74 61 74 29 3b 0a 20 20 69 52 65 70 6c 79 53 74 tat);. iReplySt
13e0: 61 74 75 73 20 3d 20 69 53 74 61 74 3b 0a 7d 0a atus = iStat;.}.
13f0: 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 65 ./*.** Append te
1400: 78 74 20 74 6f 20 74 68 65 20 68 65 61 64 65 72 xt to the header
1410: 20 6f 66 20 61 6e 20 48 54 54 50 20 72 65 70 6c of an HTTP repl
1420: 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 61 70 y.*/.void cgi_ap
1430: 70 65 6e 64 5f 68 65 61 64 65 72 28 63 6f 6e 73 pend_header(cons
1440: 74 20 63 68 61 72 20 2a 7a 4c 69 6e 65 29 7b 0a t char *zLine){.
1450: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 65 blob_append(&e
1460: 78 74 72 61 48 65 61 64 65 72 2c 20 7a 4c 69 6e xtraHeader, zLin
1470: 65 2c 20 2d 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a e, -1);.}../*.**
1480: 20 53 65 74 20 61 20 63 6f 6f 6b 69 65 2e 0a 2a Set a cookie..*
1490: 2a 0a 2a 2a 20 5a 65 72 6f 20 6c 69 66 65 74 69 *.** Zero lifeti
14a0: 6d 65 20 69 6d 70 6c 69 65 73 20 61 20 73 65 73 me implies a ses
14b0: 73 69 6f 6e 20 63 6f 6f 6b 69 65 2e 0a 2a 2f 0a sion cookie..*/.
14c0: 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6f void cgi_set_coo
14d0: 6b 69 65 28 0a 20 20 63 6f 6e 73 74 20 63 68 61 kie(. const cha
14e0: 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 2f 2a 20 r *zName, /*
14f0: 4e 61 6d 65 20 6f 66 20 74 68 65 20 63 6f 6f 6b Name of the cook
1500: 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 ie */. const ch
1510: 61 72 20 2a 7a 56 61 6c 75 65 2c 20 20 20 2f 2a ar *zValue, /*
1520: 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20 63 6f Value of the co
1530: 6f 6b 69 65 2e 20 20 41 75 74 6f 6d 61 74 69 63 okie. Automatic
1540: 61 6c 6c 79 20 65 73 63 61 70 65 64 20 2a 2f 0a ally escaped */.
1550: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 const char *zP
1560: 61 74 68 2c 20 20 20 20 2f 2a 20 50 61 74 68 20 ath, /* Path
1570: 63 6f 6f 6b 69 65 20 61 70 70 6c 69 65 73 20 74 cookie applies t
1580: 6f 2e 20 20 4e 55 4c 4c 20 6d 65 61 6e 73 20 22 o. NULL means "
1590: 2f 22 20 2a 2f 0a 20 20 69 6e 74 20 6c 69 66 65 /" */. int life
15a0: 74 69 6d 65 20 20 20 20 20 20 20 20 20 20 2f 2a time /*
15b0: 20 45 78 70 69 72 61 74 69 6f 6e 20 6f 66 20 74 Expiration of t
15c0: 68 65 20 63 6f 6f 6b 69 65 20 69 6e 20 73 65 63 he cookie in sec
15d0: 6f 6e 64 73 20 66 72 6f 6d 20 6e 6f 77 20 2a 2f onds from now */
15e0: 0a 29 7b 0a 20 20 69 66 28 20 7a 50 61 74 68 3d .){. if( zPath=
15f0: 3d 30 20 29 20 7a 50 61 74 68 20 3d 20 67 2e 7a =0 ) zPath = g.z
1600: 54 6f 70 3b 0a 20 20 69 66 28 20 6c 69 66 65 74 Top;. if( lifet
1610: 69 6d 65 3e 30 20 29 7b 0a 20 20 20 20 6c 69 66 ime>0 ){. lif
1620: 65 74 69 6d 65 20 2b 3d 20 28 69 6e 74 29 74 69 etime += (int)ti
1630: 6d 65 28 30 29 3b 0a 20 20 20 20 62 6c 6f 62 5f me(0);. blob_
1640: 61 70 70 65 6e 64 66 28 26 65 78 74 72 61 48 65 appendf(&extraHe
1650: 61 64 65 72 2c 0a 20 20 20 20 20 20 20 22 53 65 ader,. "Se
1660: 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d 25 74 3b t-Cookie: %s=%t;
1670: 20 50 61 74 68 3d 25 73 3b 20 65 78 70 69 72 65 Path=%s; expire
1680: 73 3d 25 7a 3b 20 56 65 72 73 69 6f 6e 3d 31 5c s=%z; Version=1\
1690: 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e r\n",. zN
16a0: 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50 61 ame, zValue, zPa
16b0: 74 68 2c 20 63 67 69 5f 72 66 63 38 32 32 5f 64 th, cgi_rfc822_d
16c0: 61 74 65 73 74 61 6d 70 28 6c 69 66 65 74 69 6d atestamp(lifetim
16d0: 65 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 e));. }else{.
16e0: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 blob_appendf(&
16f0: 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20 extraHeader,.
1700: 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a "Set-Cookie:
1710: 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b %s=%t; Path=%s;
1720: 20 56 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c Version=1\r\n",
1730: 0a 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 7a . zName, z
1740: 56 61 6c 75 65 2c 20 7a 50 61 74 68 29 3b 0a 20 Value, zPath);.
1750: 20 7d 0a 7d 0a 0a 23 69 66 20 30 0a 2f 2a 0a 2a }.}..#if 0./*.*
1760: 2a 20 41 64 64 20 61 6e 20 45 54 61 67 20 68 65 * Add an ETag he
1770: 61 64 65 72 20 6c 69 6e 65 0a 2a 2f 0a 73 74 61 ader line.*/.sta
1780: 74 69 63 20 63 68 61 72 20 2a 63 67 69 5f 61 64 tic char *cgi_ad
1790: 64 5f 65 74 61 67 28 63 68 61 72 20 2a 7a 54 78 d_etag(char *zTx
17a0: 74 2c 20 69 6e 74 20 6e 4c 65 6e 29 7b 0a 20 20 t, int nLen){.
17b0: 4d 44 35 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a MD5Context ctx;.
17c0: 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 unsigned char
17d0: 64 69 67 65 73 74 5b 31 36 5d 3b 0a 20 20 69 6e digest[16];. in
17e0: 74 20 69 2c 20 6a 3b 0a 20 20 63 68 61 72 20 7a t i, j;. char z
17f0: 45 54 61 67 5b 36 34 5d 3b 0a 0a 20 20 4d 44 35 ETag[64];.. MD5
1800: 49 6e 69 74 28 26 63 74 78 29 3b 0a 20 20 4d 44 Init(&ctx);. MD
1810: 35 55 70 64 61 74 65 28 26 63 74 78 2c 7a 54 78 5Update(&ctx,zTx
1820: 74 2c 6e 4c 65 6e 29 3b 0a 20 20 4d 44 35 46 69 t,nLen);. MD5Fi
1830: 6e 61 6c 28 64 69 67 65 73 74 2c 26 63 74 78 29 nal(digest,&ctx)
1840: 3b 0a 20 20 66 6f 72 28 6a 3d 69 3d 30 3b 20 69 ;. for(j=i=0; i
1850: 3c 31 36 3b 20 69 2b 2b 2c 6a 2b 3d 32 29 7b 0a <16; i++,j+=2){.
1860: 20 20 20 20 62 70 72 69 6e 74 66 28 26 7a 45 54 bprintf(&zET
1870: 61 67 5b 6a 5d 2c 73 69 7a 65 6f 66 28 7a 45 54 ag[j],sizeof(zET
1880: 61 67 29 2d 6a 2c 22 25 30 32 78 22 2c 28 69 6e ag)-j,"%02x",(in
1890: 74 29 64 69 67 65 73 74 5b 69 5d 29 3b 0a 20 20 t)digest[i]);.
18a0: 7d 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 }. blob_appendf
18b0: 28 26 65 78 74 72 61 48 65 61 64 65 72 2c 20 22 (&extraHeader, "
18c0: 45 54 61 67 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a ETag: %s\r\n", z
18d0: 45 54 61 67 29 3b 0a 20 20 72 65 74 75 72 6e 20 ETag);. return
18e0: 73 74 72 64 75 70 28 7a 45 54 61 67 29 3b 0a 7d strdup(zETag);.}
18f0: 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 73 6f 6d 65 20 ../*.** Do some
1900: 63 61 63 68 65 20 63 6f 6e 74 72 6f 6c 20 73 74 cache control st
1910: 75 66 66 2e 20 46 69 72 73 74 2c 20 77 65 20 67 uff. First, we g
1920: 65 6e 65 72 61 74 65 20 61 6e 20 45 54 61 67 20 enerate an ETag
1930: 61 6e 64 20 69 6e 63 6c 75 64 65 20 69 74 20 69 and include it i
1940: 6e 0a 2a 2a 20 74 68 65 20 72 65 73 70 6f 6e 73 n.** the respons
1950: 65 20 68 65 61 64 65 72 73 2e 20 53 65 63 6f 6e e headers. Secon
1960: 64 2c 20 77 65 20 64 6f 20 77 68 61 74 65 76 65 d, we do whateve
1970: 72 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 74 r is necessary t
1980: 6f 20 64 65 74 65 72 6d 69 6e 65 20 69 66 0a 2a o determine if.*
1990: 2a 20 74 68 65 20 72 65 71 75 65 73 74 20 77 61 * the request wa
19a0: 73 20 61 73 6b 69 6e 67 20 61 62 6f 75 74 20 63 s asking about c
19b0: 61 63 68 69 6e 67 20 61 6e 64 20 77 68 65 74 68 aching and wheth
19c0: 65 72 20 77 65 20 6e 65 65 64 20 74 6f 20 73 65 er we need to se
19d0: 6e 64 20 62 61 63 6b 20 74 68 65 0a 2a 2a 20 72 nd back the.** r
19e0: 65 73 70 6f 6e 73 65 20 62 6f 64 79 2e 20 49 66 esponse body. If
19f0: 20 77 65 20 73 68 6f 75 6c 64 6e 27 74 20 73 65 we shouldn't se
1a00: 6e 64 20 61 20 62 6f 64 79 2c 20 72 65 74 75 72 nd a body, retur
1a10: 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a n non-zero..**.*
1a20: 2a 20 43 75 72 72 65 6e 74 6c 79 2c 20 77 65 20 * Currently, we
1a30: 6a 75 73 74 20 63 68 65 63 6b 20 74 68 65 20 45 just check the E
1a40: 54 61 67 20 61 67 61 69 6e 73 74 20 61 6e 79 20 Tag against any
1a50: 49 66 2d 4e 6f 6e 65 2d 4d 61 74 63 68 20 68 65 If-None-Match he
1a60: 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 46 49 58 4d ader..**.** FIXM
1a70: 45 3a 20 49 6e 20 73 6f 6d 65 20 63 61 73 65 73 E: In some cases
1a80: 20 28 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 66 (attachments, f
1a90: 69 6c 65 20 63 6f 6e 74 65 6e 74 73 29 20 77 65 ile contents) we
1aa0: 20 63 6f 75 6c 64 20 63 68 65 63 6b 0a 2a 2a 20 could check.**
1ab0: 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e 63 If-Modified-Sinc
1ac0: 65 20 68 65 61 64 65 72 73 20 61 6e 64 20 61 6c e headers and al
1ad0: 77 61 79 73 20 69 6e 63 6c 75 64 65 20 4c 61 73 ways include Las
1ae0: 74 2d 4d 6f 64 69 66 69 65 64 20 69 6e 20 72 65 t-Modified in re
1af0: 73 70 6f 6e 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 sponses..*/.stat
1b00: 69 63 20 69 6e 74 20 63 68 65 63 6b 5f 63 61 63 ic int check_cac
1b10: 68 65 5f 63 6f 6e 74 72 6f 6c 28 76 6f 69 64 29 he_control(void)
1b20: 7b 0a 20 20 2f 2a 20 46 49 58 4d 45 3a 20 74 68 {. /* FIXME: th
1b30: 65 72 65 27 73 20 73 6f 6d 65 20 67 6f 74 63 68 ere's some gotch
1b40: 61 73 20 77 74 68 20 63 6f 6f 6b 69 65 73 20 61 as wth cookies a
1b50: 6e 64 20 73 6f 6d 65 20 68 65 61 64 65 72 73 2e nd some headers.
1b60: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 54 61 */. char *zETa
1b70: 67 20 3d 20 63 67 69 5f 61 64 64 5f 65 74 61 67 g = cgi_add_etag
1b80: 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 (blob_buffer(&cg
1b90: 69 43 6f 6e 74 65 6e 74 29 2c 62 6c 6f 62 5f 73 iContent),blob_s
1ba0: 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 ize(&cgiContent)
1bb0: 29 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 61 74 63 );. char *zMatc
1bc0: 68 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f 4e h = P("HTTP_IF_N
1bd0: 4f 4e 45 5f 4d 41 54 43 48 22 29 3b 0a 0a 20 20 ONE_MATCH");..
1be0: 69 66 28 20 7a 45 54 61 67 21 3d 30 20 26 26 20 if( zETag!=0 &&
1bf0: 7a 4d 61 74 63 68 21 3d 30 20 29 20 7b 0a 20 20 zMatch!=0 ) {.
1c00: 20 20 63 68 61 72 20 2a 7a 42 75 66 20 3d 20 73 char *zBuf = s
1c10: 74 72 64 75 70 28 7a 4d 61 74 63 68 29 3b 0a 20 trdup(zMatch);.
1c20: 20 20 20 69 66 28 20 7a 42 75 66 21 3d 30 20 29 if( zBuf!=0 )
1c30: 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 54 {. char *zT
1c40: 6f 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 63 68 ok = 0;. ch
1c50: 61 72 20 2a 7a 50 6f 73 3b 0a 20 20 20 20 20 20 ar *zPos;.
1c60: 66 6f 72 28 20 7a 54 6f 6b 20 3d 20 73 74 72 74 for( zTok = strt
1c70: 6f 6b 5f 72 28 7a 42 75 66 2c 20 22 2c 5c 22 22 ok_r(zBuf, ",\""
1c80: 2c 26 7a 50 6f 73 29 3b 0a 20 20 20 20 20 20 20 ,&zPos);.
1c90: 20 20 20 20 7a 54 6f 6b 20 26 26 20 73 74 72 63 zTok && strc
1ca0: 61 73 65 63 6d 70 28 7a 54 6f 6b 2c 7a 45 54 61 asecmp(zTok,zETa
1cb0: 67 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 7a g);. z
1cc0: 54 6f 6b 20 3d 20 20 73 74 72 74 6f 6b 5f 72 28 Tok = strtok_r(
1cd0: 30 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 29 0, ",\"",&zPos))
1ce0: 7b 7d 0a 20 20 20 20 20 20 66 72 65 65 28 7a 42 {}. free(zB
1cf0: 75 66 29 3b 0a 20 20 20 20 20 20 69 66 28 7a 54 uf);. if(zT
1d00: 6f 6b 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 ok) return 1;.
1d10: 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72 65 74 }. }. . ret
1d20: 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69 66 0a urn 0;.}.#endif.
1d30: 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 6e 6f 72 6d ./*.** Do a norm
1d40: 61 6c 20 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f al HTTP reply.*/
1d50: 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 79 28 .void cgi_reply(
1d60: 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 74 6f 74 void){. int tot
1d70: 61 6c 5f 73 69 7a 65 20 3d 20 30 3b 0a 20 20 69 al_size = 0;. i
1d80: 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 3c f( iReplyStatus<
1d90: 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c 79 =0 ){. iReply
1da0: 53 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20 20 Status = 200;.
1db0: 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d zReplyStatus =
1dc0: 20 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66 20 "OK";. }..#if
1dd0: 30 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 74 0. if( iReplySt
1de0: 61 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68 65 atus==200 && che
1df0: 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f 6c ck_cache_control
1e00: 28 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63 68 () ) {. /* ch
1e10: 61 6e 67 65 20 74 68 65 20 73 74 61 74 75 73 20 ange the status
1e20: 74 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20 61 to "unchanged" a
1e30: 6e 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20 73 nd we can skip s
1e40: 65 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20 2a ending the. *
1e50: 2a 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e 73 * actual respons
1e60: 65 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73 6c e body. Obviousl
1e70: 79 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68 69 y we only do thi
1e80: 73 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65 5f s when we _have_
1e90: 20 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20 28 a. ** body (
1ea0: 63 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20 2a code 200).. *
1eb0: 2f 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 74 /. iReplyStat
1ec0: 75 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a 52 us = 304;. zR
1ed0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e 6f eplyStatus = "No
1ee0: 74 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20 7d t Modified";. }
1ef0: 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 66 .#endif.. if( f
1f00: 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b 0a ullHttpReply ){.
1f10: 20 20 20 20 70 72 69 6e 74 66 28 22 48 54 54 50 printf("HTTP
1f20: 2f 31 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22 2c /1.0 %d %s\r\n",
1f30: 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a iReplyStatus, z
1f40: 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20 ReplyStatus);.
1f50: 20 20 63 68 61 72 20 2a 20 7a 44 61 74 65 20 3d char * zDate =
1f60: 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65 cgi_rfc822_date
1f70: 73 74 61 6d 70 28 74 69 6d 65 28 30 29 29 3b 0a stamp(time(0));.
1f80: 20 20 20 20 70 72 69 6e 74 66 28 22 44 61 74 65 printf("Date
1f90: 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 44 61 74 65 : %s\r\n", zDate
1fa0: 20 29 3b 0a 20 20 20 20 69 66 28 20 7a 44 61 74 );. if( zDat
1fb0: 65 5b 30 5d 20 29 20 66 72 65 65 28 20 7a 44 61 e[0] ) free( zDa
1fc0: 74 65 20 29 3b 0a 20 20 20 20 70 72 69 6e 74 66 te );. printf
1fd0: 28 22 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c ("Connection: cl
1fe0: 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20 20 7d 65 6c ose\r\n");. }el
1ff0: 73 65 7b 0a 20 20 20 20 70 72 69 6e 74 66 28 22 se{. printf("
2000: 53 74 61 74 75 73 3a 20 25 64 20 25 73 5c 72 5c Status: %d %s\r\
2010: 6e 22 2c 20 69 52 65 70 6c 79 53 74 61 74 75 73 n", iReplyStatus
2020: 2c 20 7a 52 65 70 6c 79 53 74 61 74 75 73 29 3b , zReplyStatus);
2030: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 62 6c 6f 62 . }.. if( blob
2040: 5f 73 69 7a 65 28 26 65 78 74 72 61 48 65 61 64 _size(&extraHead
2050: 65 72 29 3e 30 20 29 7b 0a 20 20 20 20 70 72 69 er)>0 ){. pri
2060: 6e 74 66 28 22 25 73 22 2c 20 62 6c 6f 62 5f 62 ntf("%s", blob_b
2070: 75 66 66 65 72 28 26 65 78 74 72 61 48 65 61 64 uffer(&extraHead
2080: 65 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 er));. }.. if(
2090: 20 67 2e 69 73 43 6f 6e 73 74 20 29 7b 0a 20 20 g.isConst ){.
20a0: 20 20 2f 2a 20 63 6f 6e 73 74 61 6e 74 20 6d 65 /* constant me
20b0: 61 6e 73 20 74 68 61 74 20 74 68 65 20 69 6e 70 ans that the inp
20c0: 75 74 20 55 52 4c 20 77 69 6c 6c 20 5f 6e 65 76 ut URL will _nev
20d0: 65 72 5f 20 67 65 6e 65 72 61 74 65 20 61 6e 79 er_ generate any
20e0: 74 68 69 6e 67 0a 20 20 20 20 2a 2a 20 65 6c 73 thing. ** els
20f0: 65 2e 20 49 6e 20 74 68 65 20 63 61 73 65 20 6f e. In the case o
2100: 66 20 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 74 f attachments, t
2110: 68 65 20 63 6f 6e 74 65 6e 74 73 20 77 6f 6e 27 he contents won'
2120: 74 20 63 68 61 6e 67 65 20 62 65 63 61 75 73 65 t change because
2130: 0a 20 20 20 20 2a 2a 20 61 6e 20 61 74 74 65 6d . ** an attem
2140: 70 74 20 74 6f 20 63 68 61 6e 67 65 20 74 68 65 pt to change the
2150: 6d 20 67 65 6e 65 72 61 74 65 73 20 61 20 6e 65 m generates a ne
2160: 77 20 61 74 74 61 63 68 6d 65 6e 74 20 6e 75 6d w attachment num
2170: 62 65 72 2e 20 49 6e 20 74 68 65 0a 20 20 20 20 ber. In the.
2180: 2a 2a 20 63 61 73 65 20 6f 66 20 6d 6f 73 74 20 ** case of most
2190: 2f 67 65 74 66 69 6c 65 20 63 61 6c 6c 73 20 66 /getfile calls f
21a0: 6f 72 20 73 70 65 63 69 66 69 63 20 76 65 72 73 or specific vers
21b0: 69 6f 6e 73 2c 20 74 68 65 20 6f 6e 6c 79 20 77 ions, the only w
21c0: 61 79 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f ay the. ** co
21d0: 6e 74 65 6e 74 20 63 68 61 6e 67 65 73 20 69 73 ntent changes is
21e0: 20 69 66 20 73 6f 6d 65 6f 6e 65 20 62 72 65 61 if someone brea
21f0: 6b 73 20 74 68 65 20 53 43 4d 2e 20 41 6e 64 20 ks the SCM. And
2200: 69 66 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c if that happens,
2210: 20 61 0a 20 20 20 20 2a 2a 20 73 74 61 6c 65 20 a. ** stale
2220: 63 61 63 68 65 20 69 73 20 74 68 65 20 6c 65 61 cache is the lea
2230: 73 74 20 6f 66 20 74 68 65 20 70 72 6f 62 6c 65 st of the proble
2240: 6d 2e 20 53 6f 20 77 65 20 70 72 6f 76 69 64 65 m. So we provide
2250: 20 61 6e 20 45 78 70 69 72 65 73 0a 20 20 20 20 an Expires.
2260: 2a 2a 20 68 65 61 64 65 72 20 73 65 74 20 74 6f ** header set to
2270: 20 61 20 72 65 61 73 6f 6e 61 62 6c 65 20 70 65 a reasonable pe
2280: 72 69 6f 64 20 28 64 65 66 61 75 6c 74 3a 20 6f riod (default: o
2290: 6e 65 20 77 65 65 6b 29 2e 0a 20 20 20 20 2a 2f ne week).. */
22a0: 0a 20 20 20 20 2f 2a 74 69 6d 65 5f 74 20 65 78 . /*time_t ex
22b0: 70 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 pires = time(0)
22c0: 2b 20 61 74 6f 69 28 64 62 5f 63 6f 6e 66 69 67 + atoi(db_config
22d0: 28 22 63 6f 6e 73 74 61 6e 74 5f 65 78 70 69 72 ("constant_expir
22e0: 65 73 22 2c 22 36 30 34 38 30 30 22 29 29 3b 2a es","604800"));*
22f0: 2f 0a 20 20 20 20 74 69 6d 65 5f 74 20 65 78 70 /. time_t exp
2300: 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 2b ires = time(0) +
2310: 20 36 30 34 38 30 30 3b 0a 20 20 20 20 63 68 61 604800;. cha
2320: 72 20 2a 20 7a 44 61 74 65 20 3d 20 63 67 69 5f r * zDate = cgi_
2330: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 rfc822_datestamp
2340: 28 65 78 70 69 72 65 73 29 3b 0a 20 20 20 20 70 (expires);. p
2350: 72 69 6e 74 66 28 20 22 45 78 70 69 72 65 73 3a rintf( "Expires:
2360: 20 25 73 5c 72 5c 6e 22 2c 20 7a 44 61 74 65 20 %s\r\n", zDate
2370: 29 3b 0a 20 20 20 20 69 66 28 20 7a 44 61 74 65 );. if( zDate
2380: 5b 30 5d 20 29 20 66 72 65 65 28 20 7a 44 61 74 [0] ) free( zDat
2390: 65 20 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 e );. }.. /* C
23a0: 6f 6e 74 65 6e 74 20 69 6e 74 65 6e 64 65 64 20 ontent intended
23b0: 66 6f 72 20 6c 6f 67 67 65 64 20 69 6e 20 75 73 for logged in us
23c0: 65 72 73 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 ers should only
23d0: 62 65 20 63 61 63 68 65 64 20 69 6e 0a 20 20 2a be cached in. *
23e0: 2a 20 74 68 65 20 62 72 6f 77 73 65 72 2c 20 6e * the browser, n
23f0: 6f 74 20 73 6f 6d 65 20 73 68 61 72 65 64 20 6c ot some shared l
2400: 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 ocation.. */.
2410: 70 72 69 6e 74 66 28 22 43 61 63 68 65 2d 63 6f printf("Cache-co
2420: 6e 74 72 6f 6c 3a 20 70 72 69 76 61 74 65 5c 72 ntrol: private\r
2430: 5c 6e 22 29 3b 0a 0a 23 69 66 20 46 4f 53 53 49 \n");..#if FOSSI
2440: 4c 5f 49 31 38 4e 0a 20 20 70 72 69 6e 74 66 28 L_I18N. printf(
2450: 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 "Content-Type:
2460: 25 73 3b 20 63 68 61 72 73 65 74 3d 25 73 5c 72 %s; charset=%s\r
2470: 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79 70 \n", zContentTyp
2480: 65 2c 20 6e 6c 5f 6c 61 6e 67 69 6e 66 6f 28 43 e, nl_langinfo(C
2490: 4f 44 45 53 45 54 29 29 3b 0a 23 65 6c 73 65 0a ODESET));.#else.
24a0: 20 20 70 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 printf( "Conte
24b0: 6e 74 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 nt-Type: %s; cha
24c0: 72 73 65 74 3d 49 53 4f 2d 38 38 35 39 2d 31 5c rset=ISO-8859-1\
24d0: 72 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79 r\n", zContentTy
24e0: 70 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 69 66 pe);.#endif. 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 70 72 69 6e 74 66 28 1]);. printf(
25f0: 20 22 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 "Content-Length
2600: 3a 20 25 64 5c 72 5c 6e 22 2c 20 74 6f 74 61 6c : %d\r\n", total
2610: 5f 73 69 7a 65 29 3b 0a 20 20 7d 0a 20 20 70 72 _size);. }. pr
2620: 69 6e 74 66 28 22 5c 72 5c 6e 22 29 3b 0a 20 20 intf("\r\n");.
2630: 69 66 28 20 74 6f 74 61 6c 5f 73 69 7a 65 3e 30 if( total_size>0
2640: 20 26 26 20 69 52 65 70 6c 79 53 74 61 74 75 73 && iReplyStatus
2650: 20 21 3d 20 33 30 34 20 29 7b 0a 20 20 20 20 69 != 304 ){. i
2660: 6e 74 20 69 2c 20 73 69 7a 65 3b 0a 20 20 20 20 nt i, size;.
2670: 66 6f 72 28 69 3d 30 3b 20 69 3c 32 3b 20 69 2b for(i=0; i<2; i+
2680: 2b 29 7b 0a 20 20 20 20 20 20 73 69 7a 65 20 3d +){. size =
2690: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 blob_size(&cgiC
26a0: 6f 6e 74 65 6e 74 5b 69 5d 29 3b 0a 20 20 20 20 ontent[i]);.
26b0: 20 20 69 66 28 20 73 69 7a 65 3e 30 20 29 7b 0a if( size>0 ){.
26c0: 20 20 20 20 20 20 20 20 66 77 72 69 74 65 28 62 fwrite(b
26d0: 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 69 43 lob_buffer(&cgiC
26e0: 6f 6e 74 65 6e 74 5b 69 5d 29 2c 20 31 2c 20 73 ontent[i]), 1, s
26f0: 69 7a 65 2c 20 73 74 64 6f 75 74 29 3b 0a 20 20 ize, stdout);.
2700: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a }. }. }.
2710: 20 20 43 47 49 44 45 42 55 47 28 28 22 44 4f 4e CGIDEBUG(("DON
2720: 45 5c 6e 22 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a E\n"));.}../*.**
2730: 20 44 6f 20 61 20 72 65 64 69 72 65 63 74 20 72 Do a redirect r
2740: 65 71 75 65 73 74 20 74 6f 20 74 68 65 20 55 52 equest to the UR
2750: 4c 20 67 69 76 65 6e 20 69 6e 20 74 68 65 20 61 L given in the a
2760: 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 rgument..**.** T
2770: 68 65 20 55 52 4c 20 6d 75 73 74 20 62 65 20 72 he URL must be r
2780: 65 6c 61 74 69 76 65 20 74 6f 20 74 68 65 20 62 elative to the b
2790: 61 73 65 20 6f 66 20 74 68 65 20 66 6f 73 73 69 ase of the fossi
27a0: 6c 20 73 65 72 76 65 72 2e 0a 2a 2f 0a 76 6f 69 l server..*/.voi
27b0: 64 20 63 67 69 5f 72 65 64 69 72 65 63 74 28 63 d cgi_redirect(c
27c0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 55 52 4c 29 onst char *zURL)
27d0: 7b 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 63 61 74 {. char *zLocat
27e0: 69 6f 6e 3b 0a 20 20 43 47 49 44 45 42 55 47 28 ion;. CGIDEBUG(
27f0: 28 22 72 65 64 69 72 65 63 74 20 74 6f 20 25 73 ("redirect to %s
2800: 5c 6e 22 2c 20 7a 55 52 4c 29 29 3b 0a 20 20 69 \n", zURL));. i
2810: 66 28 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c f( strncmp(zURL,
2820: 22 68 74 74 70 3a 22 2c 35 29 3d 3d 30 20 7c 7c "http:",5)==0 ||
2830: 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22 68 strncmp(zURL,"h
2840: 74 74 70 73 3a 22 2c 36 29 3d 3d 30 20 7c 7c 20 ttps:",6)==0 ||
2850: 2a 7a 55 52 4c 3d 3d 27 2f 27 20 29 7b 0a 20 20 *zURL=='/' ){.
2860: 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 zLocation = mp
2870: 72 69 6e 74 66 28 22 4c 6f 63 61 74 69 6f 6e 3a rintf("Location:
2880: 20 25 73 5c 72 5c 6e 22 2c 20 7a 55 52 4c 29 3b %s\r\n", zURL);
2890: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 4c . }else{. zL
28a0: 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 72 69 6e 74 ocation = mprint
28b0: 66 28 22 4c 6f 63 61 74 69 6f 6e 3a 20 25 73 2f f("Location: %s/
28c0: 25 73 5c 72 5c 6e 22 2c 20 67 2e 7a 42 61 73 65 %s\r\n", g.zBase
28d0: 55 52 4c 2c 20 7a 55 52 4c 29 3b 0a 20 20 7d 0a URL, zURL);. }.
28e0: 20 20 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 61 cgi_append_hea
28f0: 64 65 72 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a der(zLocation);.
2900: 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 cgi_reset_cont
2910: 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f 70 72 69 ent();. cgi_pri
2920: 6e 74 66 28 22 3c 68 74 6d 6c 3e 5c 6e 3c 70 3e ntf("<html>\n<p>
2930: 52 65 64 69 72 65 63 74 20 74 6f 20 25 68 3c 2f Redirect to %h</
2940: 70 3e 5c 6e 3c 2f 68 74 6d 6c 3e 5c 6e 22 2c 20 p>\n</html>\n",
2950: 7a 55 52 4c 29 3b 0a 20 20 63 67 69 5f 73 65 74 zURL);. cgi_set
2960: 5f 73 74 61 74 75 73 28 33 30 32 2c 20 22 4d 6f _status(302, "Mo
2970: 76 65 64 20 54 65 6d 70 6f 72 61 72 69 6c 79 22 ved Temporarily"
2980: 29 3b 0a 20 20 66 72 65 65 28 7a 4c 6f 63 61 74 );. free(zLocat
2990: 69 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c ion);. cgi_repl
29a0: 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a y();. exit(0);.
29b0: 7d 0a 76 6f 69 64 20 63 67 69 5f 72 65 64 69 72 }.void cgi_redir
29c0: 65 63 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20 ectf(const char
29d0: 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a *zFormat, ...){.
29e0: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 va_list ap;.
29f0: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f va_start(ap, zFo
2a00: 72 6d 61 74 29 3b 0a 20 20 63 67 69 5f 72 65 64 rmat);. cgi_red
2a10: 69 72 65 63 74 28 76 6d 70 72 69 6e 74 66 28 7a irect(vmprintf(z
2a20: 46 6f 72 6d 61 74 2c 20 61 70 29 29 3b 0a 20 20 Format, ap));.
2a30: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 2f va_end(ap);.}../
2a40: 2a 0a 2a 2a 20 49 6e 66 6f 72 6d 61 74 69 6f 6e *.** Information
2a50: 20 61 62 6f 75 74 20 61 6c 6c 20 71 75 65 72 79 about all query
2a60: 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e 64 20 parameters and
2a70: 63 6f 6f 6b 69 65 73 20 61 72 65 20 73 74 6f 72 cookies are stor
2a80: 65 64 0a 2a 2a 20 69 6e 20 74 68 65 73 65 20 76 ed.** in these v
2a90: 61 72 69 61 62 6c 65 73 2e 0a 2a 2f 0a 73 74 61 ariables..*/.sta
2aa0: 74 69 63 20 69 6e 74 20 6e 41 6c 6c 6f 63 51 50 tic int nAllocQP
2ab0: 20 3d 20 30 3b 20 2f 2a 20 53 70 61 63 65 20 61 = 0; /* Space a
2ac0: 6c 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 50 61 llocated for aPa
2ad0: 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 69 ramQP[] */.stati
2ae0: 63 20 69 6e 74 20 6e 55 73 65 64 51 50 20 3d 20 c int nUsedQP =
2af0: 30 3b 20 20 2f 2a 20 53 70 61 63 65 20 61 63 74 0; /* Space act
2b00: 75 61 6c 6c 79 20 75 73 65 64 20 69 6e 20 61 50 ually used in aP
2b10: 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 aramQP[] */.stat
2b20: 69 63 20 69 6e 74 20 73 6f 72 74 51 50 20 3d 20 ic int sortQP =
2b30: 30 3b 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 0; /* True if
2b40: 61 50 61 72 61 6d 51 50 5b 5d 20 6e 65 65 64 73 aParamQP[] needs
2b50: 20 73 6f 72 74 69 6e 67 20 2a 2f 0a 73 74 61 74 sorting */.stat
2b60: 69 63 20 69 6e 74 20 73 65 71 51 50 20 3d 20 30 ic int seqQP = 0
2b70: 3b 20 20 20 20 2f 2a 20 53 65 71 75 65 6e 63 65 ; /* Sequence
2b80: 20 6e 75 6d 62 65 72 73 20 2a 2f 0a 73 74 61 74 numbers */.stat
2b90: 69 63 20 73 74 72 75 63 74 20 51 50 61 72 61 6d ic struct QParam
2ba0: 20 7b 20 20 20 2f 2a 20 4f 6e 65 20 65 6e 74 72 { /* One entr
2bb0: 79 20 66 6f 72 20 65 61 63 68 20 71 75 65 72 79 y for each query
2bc0: 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f parameter or co
2bd0: 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 okie */. const
2be0: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 char *zName;
2bf0: 20 20 20 20 2f 2a 20 50 61 72 61 6d 65 74 65 72 /* Parameter
2c00: 20 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 20 or cookie name
2c10: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 */. const char
2c20: 2a 7a 56 61 6c 75 65 3b 20 20 20 20 20 20 20 2f *zValue; /
2c30: 2a 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20 71 * Value of the q
2c40: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f uery parameter o
2c50: 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 69 6e r cookie */. in
2c60: 74 20 73 65 71 3b 20 20 20 20 20 20 20 20 20 20 t seq;
2c70: 20 20 20 20 20 20 20 20 2f 2a 20 4f 72 64 65 72 /* Order
2c80: 20 6f 66 20 69 6e 73 65 72 74 69 6f 6e 20 2a 2f of insertion */
2c90: 0a 7d 20 2a 61 50 61 72 61 6d 51 50 3b 20 20 20 .} *aParamQP;
2ca0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 6e 20 /* An
2cb0: 61 72 72 61 79 20 6f 66 20 61 6c 6c 20 70 61 72 array of all par
2cc0: 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b ameters and cook
2cd0: 69 65 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 64 ies */../*.** Ad
2ce0: 64 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79 20 d another query
2cf0: 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f parameter or coo
2d00: 6b 69 65 20 74 6f 20 74 68 65 20 70 61 72 61 6d kie to the param
2d10: 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 eter set..** zNa
2d20: 6d 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f me is the name o
2d30: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 f the query para
2d40: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 meter or cookie
2d50: 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 and zValue.** is
2d60: 20 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f 64 its fully decod
2d70: 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 ed value..**.**
2d80: 7a 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c 75 65 zName and zValue
2d90: 20 61 72 65 20 6e 6f 74 20 63 6f 70 69 65 64 20 are not copied
2da0: 61 6e 64 20 6d 75 73 74 20 6e 6f 74 20 63 68 61 and must not cha
2db0: 6e 67 65 20 6f 72 20 62 65 0a 2a 2a 20 64 65 61 nge or be.** dea
2dc0: 6c 6c 6f 63 61 74 65 64 20 61 66 74 65 72 20 74 llocated after t
2dd0: 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75 his routine retu
2de0: 72 6e 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 rns..*/.void cgi
2df0: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e _set_parameter_n
2e00: 6f 63 6f 70 79 28 63 6f 6e 73 74 20 63 68 61 72 ocopy(const char
2e10: 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 *zName, const c
2e20: 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 har *zValue){.
2e30: 69 66 28 20 6e 41 6c 6c 6f 63 51 50 3c 3d 6e 55 if( nAllocQP<=nU
2e40: 73 65 64 51 50 20 29 7b 0a 20 20 20 20 6e 41 6c sedQP ){. nAl
2e50: 6c 6f 63 51 50 20 3d 20 6e 41 6c 6c 6f 63 51 50 locQP = nAllocQP
2e60: 2a 32 20 2b 20 31 30 3b 0a 20 20 20 20 61 50 61 *2 + 10;. aPa
2e70: 72 61 6d 51 50 20 3d 20 72 65 61 6c 6c 6f 63 28 ramQP = realloc(
2e80: 20 61 50 61 72 61 6d 51 50 2c 20 6e 41 6c 6c 6f aParamQP, nAllo
2e90: 63 51 50 2a 73 69 7a 65 6f 66 28 61 50 61 72 61 cQP*sizeof(aPara
2ea0: 6d 51 50 5b 30 5d 29 20 29 3b 0a 20 20 20 20 69 mQP[0]) );. i
2eb0: 66 28 20 61 50 61 72 61 6d 51 50 3d 3d 30 20 29 f( aParamQP==0 )
2ec0: 20 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a 20 20 exit(1);. }.
2ed0: 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 aParamQP[nUsedQP
2ee0: 5d 2e 7a 4e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b ].zName = zName;
2ef0: 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 . aParamQP[nUse
2f00: 64 51 50 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56 dQP].zValue = zV
2f10: 61 6c 75 65 3b 0a 20 20 61 50 61 72 61 6d 51 50 alue;. aParamQP
2f20: 5b 6e 55 73 65 64 51 50 5d 2e 73 65 71 20 3d 20 [nUsedQP].seq =
2f30: 73 65 71 51 50 2b 2b 3b 0a 20 20 6e 55 73 65 64 seqQP++;. nUsed
2f40: 51 50 2b 2b 3b 0a 20 20 73 6f 72 74 51 50 20 3d QP++;. sortQP =
2f50: 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 1;.}../*.** Add
2f60: 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79 20 70 another query p
2f70: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b arameter or cook
2f80: 69 65 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65 ie to the parame
2f90: 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d ter set..** zNam
2fa0: 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 e is the name of
2fb0: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d the query param
2fc0: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61 eter or cookie a
2fd0: 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20 nd zValue.** is
2fe0: 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f 64 65 its fully decode
2ff0: 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 43 d value..**.** C
3000: 6f 70 69 65 73 20 61 72 65 20 6d 61 64 65 20 6f opies are made o
3010: 66 20 62 6f 74 68 20 74 68 65 20 7a 4e 61 6d 65 f both the zName
3020: 20 61 6e 64 20 7a 56 61 6c 75 65 20 70 61 72 61 and zValue para
3030: 6d 65 74 65 72 73 2e 0a 2a 2f 0a 76 6f 69 64 20 meters..*/.void
3040: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 cgi_set_paramete
3050: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e r(const char *zN
3060: 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 ame, const char
3070: 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f *zValue){. cgi_
3080: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f set_parameter_no
3090: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 copy(mprintf("%s
30a0: 22 2c 7a 4e 61 6d 65 29 2c 20 6d 70 72 69 6e 74 ",zName), mprint
30b0: 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b f("%s",zValue));
30c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 70 6c 61 63 .}../*.** Replac
30d0: 65 20 61 20 70 61 72 61 6d 65 74 65 72 20 77 69 e a parameter wi
30e0: 74 68 20 61 20 6e 65 77 20 76 61 6c 75 65 2e 0a th a new value..
30f0: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c */.void cgi_repl
3100: 61 63 65 5f 70 61 72 61 6d 65 74 65 72 28 63 6f ace_parameter(co
3110: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c nst char *zName,
3120: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 const char *zVa
3130: 6c 75 65 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 lue){. int i;.
3140: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 55 73 65 for(i=0; i<nUse
3150: 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 dQP; i++){. i
3160: 66 28 20 73 74 72 63 6d 70 28 61 50 61 72 61 6d f( strcmp(aParam
3170: 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 7a 4e 61 6d QP[i].zName,zNam
3180: 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 e)==0 ){. a
3190: 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 56 61 6c 75 ParamQP[i].zValu
31a0: 65 20 3d 20 7a 56 61 6c 75 65 3b 0a 20 20 20 20 e = zValue;.
31b0: 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 }. }.}../*.** A
31c0: 64 64 20 61 20 71 75 65 72 79 20 70 61 72 61 6d dd a query param
31d0: 65 74 65 72 2e 20 20 54 68 65 20 7a 4e 61 6d 65 eter. The zName
31e0: 20 70 6f 72 74 69 6f 6e 20 69 73 20 66 69 78 65 portion is fixe
31f0: 64 20 62 75 74 20 61 20 63 6f 70 79 0a 2a 2a 20 d but a copy.**
3200: 6d 75 73 74 20 62 65 20 6d 61 64 65 20 6f 66 20 must be made of
3210: 7a 56 61 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 zValue..*/.void
3220: 63 67 69 5f 73 65 74 65 6e 76 28 63 6f 6e 73 74 cgi_setenv(const
3230: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f char *zName, co
3240: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 nst char *zValue
3250: 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 72 ){. cgi_set_par
3260: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e ameter_nocopy(zN
3270: 61 6d 65 2c 20 6d 70 72 69 6e 74 66 28 22 25 73 ame, mprintf("%s
3280: 22 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a 20 0a ",zValue));.}. .
3290: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 6c 69 73 ./*.** Add a lis
32a0: 74 20 6f 66 20 71 75 65 72 79 20 70 61 72 61 6d t of query param
32b0: 65 74 65 72 73 20 6f 72 20 63 6f 6f 6b 69 65 73 eters or cookies
32c0: 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 to the paramete
32d0: 72 20 73 65 74 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 r set..**.** Eac
32e0: 68 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 6f h parameter is o
32f0: 66 20 74 68 65 20 66 6f 72 6d 20 4e 41 4d 45 3d f the form NAME=
3300: 56 41 4c 55 45 2e 20 20 42 6f 74 68 20 74 68 65 VALUE. Both the
3310: 20 4e 41 4d 45 20 61 6e 64 20 74 68 65 0a 2a 2a NAME and the.**
3320: 20 56 41 4c 55 45 20 6d 61 79 20 62 65 20 75 72 VALUE may be ur
3330: 6c 2d 65 6e 63 6f 64 65 64 20 28 22 2b 22 20 66 l-encoded ("+" f
3340: 6f 72 20 73 70 61 63 65 2c 20 22 25 48 48 22 20 or space, "%HH"
3350: 66 6f 72 20 6f 74 68 65 72 20 73 70 65 63 69 61 for other specia
3360: 6c 0a 2a 2a 20 63 68 61 72 61 63 74 65 72 73 29 l.** characters)
3370: 2e 20 20 42 75 74 20 74 68 69 73 20 72 6f 75 74 . But this rout
3380: 69 6e 65 20 61 73 73 75 6d 65 73 20 74 68 61 74 ine assumes that
3390: 20 4e 41 4d 45 20 63 6f 6e 74 61 69 6e 73 20 6e NAME contains n
33a0: 6f 0a 2a 2a 20 73 70 65 63 69 61 6c 20 63 68 61 o.** special cha
33b0: 72 61 63 74 65 72 20 61 6e 64 20 74 68 65 72 65 racter and there
33c0: 66 6f 72 65 20 64 6f 65 73 20 6e 6f 74 20 64 65 fore does not de
33d0: 63 6f 64 65 20 69 74 2e 0a 2a 2a 0a 2a 2a 20 49 code it..**.** I
33e0: 66 20 4e 41 4d 45 20 62 65 67 69 6e 73 20 77 69 f NAME begins wi
33f0: 74 68 20 61 6e 6f 74 68 65 72 20 6f 74 68 65 72 th another other
3400: 20 74 68 61 6e 20 61 20 6c 6f 77 65 72 2d 63 61 than a lower-ca
3410: 73 65 20 6c 65 74 74 65 72 20 74 68 65 6e 0a 2a se letter then.*
3420: 2a 20 74 68 65 20 65 6e 74 69 72 65 20 4e 41 4d * the entire NAM
3430: 45 3d 56 41 4c 55 45 20 74 65 72 6d 20 69 73 20 E=VALUE term is
3440: 69 67 6e 6f 72 65 64 2e 20 20 48 65 6e 63 65 3a ignored. Hence:
3450: 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a 20 20 63 .**.** * c
3460: 6f 6f 6b 69 65 73 20 61 6e 64 20 71 75 65 72 79 ookies and query
3470: 20 70 61 72 61 6d 65 74 65 72 73 20 74 68 61 74 parameters that
3480: 20 68 61 76 65 20 75 70 70 65 72 63 61 73 65 20 have uppercase
3490: 6e 61 6d 65 73 0a 2a 2a 20 20 20 20 20 20 20 20 names.**
34a0: 20 61 72 65 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a are ignored..**
34b0: 0a 2a 2a 20 20 20 20 20 20 2a 20 20 69 74 20 69 .** * it i
34c0: 73 20 69 6d 70 6f 73 73 69 62 6c 65 20 66 6f 72 s impossible for
34d0: 20 61 20 63 6f 6f 6b 69 65 20 6f 72 20 71 75 65 a cookie or que
34e0: 72 79 20 70 61 72 61 6d 65 74 65 72 20 74 6f 0a ry parameter to.
34f0: 2a 2a 20 20 20 20 20 20 20 20 20 6f 76 65 72 72 ** overr
3500: 69 64 65 20 74 68 65 20 76 61 6c 75 65 20 6f 66 ide the value of
3510: 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 an environment
3520: 76 61 72 69 61 62 6c 65 20 73 69 6e 63 65 0a 2a variable since.*
3530: 2a 20 20 20 20 20 20 20 20 20 65 6e 76 69 72 6f * enviro
3540: 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 73 20 nment variables
3550: 61 6c 77 61 79 73 20 68 61 76 65 20 75 70 70 65 always have uppe
3560: 72 63 61 73 65 20 6e 61 6d 65 73 2e 0a 2a 2a 0a rcase names..**.
3570: 2a 2a 20 50 61 72 61 6d 65 74 65 72 73 20 61 72 ** Parameters ar
3580: 65 20 73 65 70 61 72 61 74 65 64 20 62 79 20 74 e separated by t
3590: 68 65 20 22 74 65 72 6d 69 6e 61 74 6f 72 22 20 he "terminator"
35a0: 63 68 61 72 61 63 74 65 72 2e 20 20 57 68 69 74 character. Whit
35b0: 65 73 70 61 63 65 0a 2a 2a 20 62 65 66 6f 72 65 espace.** before
35c0: 20 74 68 65 20 4e 41 4d 45 20 69 73 20 69 67 6e the NAME is ign
35d0: 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 ored..**.** The
35e0: 69 6e 70 75 74 20 73 74 72 69 6e 67 20 22 7a 22 input string "z"
35f0: 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62 75 74 is modified but
3600: 20 6e 6f 20 63 6f 70 69 65 73 20 69 73 20 6d 61 no copies is ma
3610: 64 65 2e 20 20 22 7a 22 0a 2a 2a 20 73 68 6f 75 de. "z".** shou
3620: 6c 64 20 6e 6f 74 20 62 65 20 64 65 61 6c 6c 6f ld not be deallo
3630: 63 61 74 65 64 20 6f 72 20 63 68 61 6e 67 65 64 cated or changed
3640: 20 61 67 61 69 6e 20 61 66 74 65 72 20 74 68 69 again after thi
3650: 73 20 72 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74 s routine.** ret
3660: 75 72 6e 73 20 6f 72 20 69 74 20 77 69 6c 6c 20 urns or it will
3670: 63 6f 72 72 75 70 74 20 74 68 65 20 70 61 72 61 corrupt the para
3680: 6d 65 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2f 0a meter table..*/.
3690: 73 74 61 74 69 63 20 76 6f 69 64 20 61 64 64 5f static void add_
36a0: 70 61 72 61 6d 5f 6c 69 73 74 28 63 68 61 72 20 param_list(char
36b0: 2a 7a 2c 20 69 6e 74 20 74 65 72 6d 69 6e 61 74 *z, int terminat
36c0: 6f 72 29 7b 0a 20 20 77 68 69 6c 65 28 20 2a 7a or){. while( *z
36d0: 20 29 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e ){. char *zN
36e0: 61 6d 65 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a ame;. char *z
36f0: 56 61 6c 75 65 3b 0a 20 20 20 20 77 68 69 6c 65 Value;. while
3700: 28 20 69 73 73 70 61 63 65 28 2a 7a 29 20 29 7b ( isspace(*z) ){
3710: 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 7a 4e 61 6d z++; }. zNam
3720: 65 20 3d 20 7a 3b 0a 20 20 20 20 77 68 69 6c 65 e = z;. while
3730: 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 3d 27 20 ( *z && *z!='='
3740: 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 74 6f && *z!=terminato
3750: 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 r ){ z++; }.
3760: 69 66 28 20 2a 7a 3d 3d 27 3d 27 20 29 7b 0a 20 if( *z=='=' ){.
3770: 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 *z = 0;.
3780: 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7a 56 z++;. zV
3790: 61 6c 75 65 20 3d 20 7a 3b 0a 20 20 20 20 20 20 alue = z;.
37a0: 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 while( *z && *z!
37b0: 3d 74 65 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a =terminator ){ z
37c0: 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 28 20 ++; }. if(
37d0: 2a 7a 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a *z ){. *z
37e0: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b = 0;. z+
37f0: 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 +;. }.
3800: 20 64 65 68 74 74 70 69 7a 65 28 7a 56 61 6c 75 dehttpize(zValu
3810: 65 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 e);. }else{.
3820: 20 20 20 20 20 69 66 28 20 2a 7a 20 29 7b 20 2a if( *z ){ *
3830: 7a 2b 2b 20 3d 20 30 3b 20 7d 0a 20 20 20 20 20 z++ = 0; }.
3840: 20 7a 56 61 6c 75 65 20 3d 20 22 22 3b 0a 20 20 zValue = "";.
3850: 20 20 7d 0a 20 20 20 20 69 66 28 20 69 73 6c 6f }. if( islo
3860: 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b wer(zName[0]) ){
3870: 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 . cgi_set_p
3880: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 arameter_nocopy(
3890: 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a zName, zValue);.
38a0: 20 20 20 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a }. }.}../*.
38b0: 2a 2a 20 2a 70 7a 20 69 73 20 61 20 73 74 72 69 ** *pz is a stri
38c0: 6e 67 20 74 68 61 74 20 63 6f 6e 73 69 73 74 73 ng that consists
38d0: 20 6f 66 20 6d 75 6c 74 69 70 6c 65 20 6c 69 6e of multiple lin
38e0: 65 73 20 6f 66 20 74 65 78 74 2e 20 20 54 68 69 es of text. Thi
38f0: 73 0a 2a 2a 20 72 6f 75 74 69 6e 65 20 66 69 6e s.** routine fin
3900: 64 73 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 ds the end of th
3910: 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65 20 6f e current line o
3920: 66 20 74 65 78 74 20 61 6e 64 20 63 6f 6e 76 65 f text and conve
3930: 72 74 73 0a 2a 2a 20 74 68 65 20 22 5c 6e 22 20 rts.** the "\n"
3940: 6f 72 20 22 5c 72 5c 6e 22 20 74 68 61 74 20 65 or "\r\n" that e
3950: 6e 64 73 20 74 68 61 74 20 6c 69 6e 65 20 69 6e nds that line in
3960: 74 6f 20 61 20 22 5c 30 30 30 22 2e 20 20 49 74 to a "\000". It
3970: 20 74 68 65 6e 0a 2a 2a 20 61 64 76 61 6e 63 65 then.** advance
3980: 73 20 2a 70 7a 20 74 6f 20 74 68 65 20 62 65 67 s *pz to the beg
3990: 69 6e 6e 69 6e 67 20 6f 66 20 74 68 65 20 6e 65 inning of the ne
39a0: 78 74 20 6c 69 6e 65 20 61 6e 64 20 72 65 74 75 xt line and retu
39b0: 72 6e 73 20 74 68 65 0a 2a 2a 20 70 72 65 76 69 rns the.** previ
39c0: 6f 75 73 20 76 61 6c 75 65 20 6f 66 20 2a 70 7a ous value of *pz
39d0: 20 28 77 68 69 63 68 20 69 73 20 74 68 65 20 73 (which is the s
39e0: 74 61 72 74 20 6f 66 20 74 68 65 20 63 75 72 72 tart of the curr
39f0: 65 6e 74 20 6c 69 6e 65 2e 29 0a 2a 2f 0a 73 74 ent line.).*/.st
3a00: 61 74 69 63 20 63 68 61 72 20 2a 67 65 74 5f 6c atic char *get_l
3a10: 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 ine_from_string(
3a20: 63 68 61 72 20 2a 2a 70 7a 2c 20 69 6e 74 20 2a char **pz, int *
3a30: 70 4c 65 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a pLen){. char *z
3a40: 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e 74 20 69 3b = *pz;. int i;
3a50: 0a 20 20 69 66 28 20 7a 5b 30 5d 3d 3d 30 20 29 . if( z[0]==0 )
3a60: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 66 6f 72 return 0;. for
3a70: 28 69 3d 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 (i=0; z[i]; i++)
3a80: 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d {. if( z[i]==
3a90: 27 5c 6e 27 20 29 7b 0a 20 20 20 20 20 20 69 66 '\n' ){. if
3aa0: 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d ( i>0 && z[i-1]=
3ab0: 3d 27 5c 72 27 20 29 7b 0a 20 20 20 20 20 20 20 ='\r' ){.
3ac0: 20 7a 5b 69 2d 31 5d 20 3d 20 30 3b 0a 20 20 20 z[i-1] = 0;.
3ad0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
3ae0: 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 z[i] = 0;.
3af0: 20 20 7d 0a 20 20 20 20 20 20 69 2b 2b 3b 0a 20 }. i++;.
3b00: 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 break;.
3b10: 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a }. }. *pz = &z
3b20: 5b 69 5d 3b 0a 20 20 2a 70 4c 65 6e 20 2d 3d 20 [i];. *pLen -=
3b30: 69 3b 0a 20 20 72 65 74 75 72 6e 20 7a 3b 0a 7d i;. return z;.}
3b40: 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 ../*.** The inpu
3b50: 74 20 2a 70 7a 20 70 6f 69 6e 74 73 20 74 6f 20 t *pz points to
3b60: 63 6f 6e 74 65 6e 74 20 74 68 61 74 20 69 73 20 content that is
3b70: 74 65 72 6d 69 6e 61 74 65 64 20 62 79 20 61 20 terminated by a
3b80: 22 5c 72 5c 6e 22 0a 2a 2a 20 66 6f 6c 6c 6f 77 "\r\n".** follow
3b90: 65 64 20 62 79 20 74 68 65 20 62 6f 75 6e 64 72 ed by the boundr
3ba0: 79 20 6d 61 72 6b 65 72 20 7a 42 6f 75 6e 64 72 y marker zBoundr
3bb0: 79 2e 20 20 41 6e 20 65 78 74 72 61 20 22 2d 2d y. An extra "--
3bc0: 22 20 6d 61 79 20 6f 72 0a 2a 2a 20 6d 61 79 20 " may or.** may
3bd0: 6e 6f 74 20 62 65 20 61 70 70 65 6e 64 65 64 20 not be appended
3be0: 74 6f 20 74 68 65 20 62 6f 75 6e 64 72 79 20 6d to the boundry m
3bf0: 61 72 6b 65 72 2e 20 20 54 68 65 72 65 20 61 72 arker. There ar
3c00: 65 20 2a 70 4c 65 6e 20 63 68 61 72 61 63 74 65 e *pLen characte
3c10: 72 73 0a 2a 2a 20 69 6e 20 2a 70 7a 2e 0a 2a 2a rs.** in *pz..**
3c20: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 .** This routine
3c30: 20 61 64 64 73 20 61 20 22 5c 30 30 30 22 20 74 adds a "\000" t
3c40: 6f 20 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 o the end of the
3c50: 20 63 6f 6e 74 65 6e 74 20 28 6f 76 65 72 77 72 content (overwr
3c60: 69 74 69 6e 67 0a 2a 2a 20 74 68 65 20 22 5c 72 iting.** the "\r
3c70: 5c 6e 22 29 20 61 6e 64 20 72 65 74 75 72 6e 73 \n") and returns
3c80: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 a pointer to th
3c90: 65 20 63 6f 6e 74 65 6e 74 2e 20 20 54 68 65 20 e content. The
3ca0: 2a 70 7a 20 69 6e 70 75 74 0a 2a 2a 20 69 73 20 *pz input.** is
3cb0: 61 64 6a 75 73 74 65 64 20 74 6f 20 70 6f 69 6e adjusted to poin
3cc0: 74 20 74 6f 20 74 68 65 20 66 69 72 73 74 20 6c t to the first l
3cd0: 69 6e 65 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 ine following th
3ce0: 65 20 62 6f 75 6e 64 72 79 2e 0a 2a 2a 20 54 68 e boundry..** Th
3cf0: 65 20 6c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 e length of the
3d00: 63 6f 6e 74 65 6e 74 20 69 73 20 73 74 6f 72 65 content is store
3d10: 64 20 69 6e 20 2a 70 6e 43 6f 6e 74 65 6e 74 2e d in *pnContent.
3d20: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 .*/.static char
3d30: 2a 67 65 74 5f 62 6f 75 6e 64 65 64 5f 63 6f 6e *get_bounded_con
3d40: 74 65 6e 74 28 0a 20 20 63 68 61 72 20 2a 2a 70 tent(. char **p
3d50: 7a 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 43 6f z, /* Co
3d60: 6e 74 65 6e 74 20 74 61 6b 65 6e 20 66 72 6f 6d ntent taken from
3d70: 20 68 65 72 65 20 2a 2f 0a 20 20 69 6e 74 20 2a here */. int *
3d80: 70 4c 65 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a pLen, /*
3d90: 20 4e 75 6d 62 65 72 20 6f 66 20 62 79 74 65 73 Number of bytes
3da0: 20 6f 66 20 64 61 74 61 20 69 6e 20 28 2a 70 7a of data in (*pz
3db0: 29 5b 5d 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a )[] */. char *z
3dc0: 42 6f 75 6e 64 72 79 2c 20 20 20 20 2f 2a 20 42 Boundry, /* B
3dd0: 6f 75 6e 64 72 79 20 74 65 78 74 20 6d 61 72 6b oundry text mark
3de0: 69 6e 67 20 74 68 65 20 65 6e 64 20 6f 66 20 63 ing the end of c
3df0: 6f 6e 74 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 ontent */. int
3e00: 2a 70 6e 43 6f 6e 74 65 6e 74 20 20 20 20 20 2f *pnContent /
3e10: 2a 20 57 72 69 74 65 20 74 68 65 20 73 69 7a 65 * Write the size
3e20: 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 of the content
3e30: 68 65 72 65 20 2a 2f 0a 29 7b 0a 20 20 63 68 61 here */.){. cha
3e40: 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e r *z = *pz;. in
3e50: 74 20 6c 65 6e 20 3d 20 2a 70 4c 65 6e 3b 0a 20 t len = *pLen;.
3e60: 20 69 6e 74 20 69 3b 0a 20 20 69 6e 74 20 6e 42 int i;. int nB
3e70: 6f 75 6e 64 72 79 20 3d 20 73 74 72 6c 65 6e 28 oundry = strlen(
3e80: 7a 42 6f 75 6e 64 72 79 29 3b 0a 20 20 2a 70 6e zBoundry);. *pn
3e90: 43 6f 6e 74 65 6e 74 20 3d 20 6c 65 6e 3b 0a 20 Content = len;.
3ea0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6c 65 6e 3b for(i=0; i<len;
3eb0: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a i++){. if( z
3ec0: 5b 69 5d 3d 3d 27 5c 6e 27 20 26 26 20 73 74 72 [i]=='\n' && str
3ed0: 6e 63 6d 70 28 7a 42 6f 75 6e 64 72 79 2c 20 26 ncmp(zBoundry, &
3ee0: 7a 5b 69 2b 31 5d 2c 20 6e 42 6f 75 6e 64 72 79 z[i+1], nBoundry
3ef0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 66 )==0 ){. if
3f00: 28 20 69 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d ( i>0 && z[i-1]=
3f10: 3d 27 5c 72 27 20 29 20 69 2d 2d 3b 0a 20 20 20 ='\r' ) i--;.
3f20: 20 20 20 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 z[i] = 0;.
3f30: 20 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d 20 *pnContent =
3f40: 69 3b 0a 20 20 20 20 20 20 69 20 2b 3d 20 6e 42 i;. i += nB
3f50: 6f 75 6e 64 72 79 3b 0a 20 20 20 20 20 20 62 72 oundry;. br
3f60: 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 eak;. }. }.
3f70: 20 2a 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 *pz = &z[i];.
3f80: 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 get_line_from_st
3f90: 72 69 6e 67 28 70 7a 2c 20 70 4c 65 6e 29 3b 0a ring(pz, pLen);.
3fa0: 20 20 72 65 74 75 72 6e 20 7a 3b 20 20 20 20 20 return z;
3fb0: 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e .}../*.** Token
3fc0: 69 7a 65 20 61 20 6c 69 6e 65 20 6f 66 20 74 65 ize a line of te
3fd0: 78 74 20 69 6e 74 6f 20 61 73 20 6d 61 6e 79 20 xt into as many
3fe0: 61 73 20 6e 41 72 67 20 74 6f 6b 65 6e 73 2e 20 as nArg tokens.
3ff0: 20 4d 61 6b 65 0a 2a 2a 20 61 7a 41 72 67 5b 5d Make.** azArg[]
4000: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 point to the st
4010: 61 72 74 20 6f 66 20 65 61 63 68 20 74 6f 6b 65 art of each toke
4020: 6e 2e 0a 2a 2a 0a 2a 2a 20 54 6f 6b 65 6e 73 20 n..**.** Tokens
4030: 63 6f 6e 73 69 73 74 20 6f 66 20 73 70 61 63 65 consist of space
4040: 20 6f 72 20 73 65 6d 69 2d 63 6f 6c 6f 6e 20 64 or semi-colon d
4050: 65 6c 69 6d 69 74 65 64 20 77 6f 72 64 73 20 6f elimited words o
4060: 72 0a 2a 2a 20 73 74 72 69 6e 67 73 20 69 6e 73 r.** strings ins
4070: 69 64 65 20 64 6f 75 62 6c 65 2d 71 75 6f 74 65 ide double-quote
4080: 73 2e 20 20 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a s. Example:.**.
4090: 2a 2a 20 20 20 20 63 6f 6e 74 65 6e 74 2d 64 69 ** content-di
40a0: 73 70 6f 73 69 74 69 6f 6e 3a 20 66 6f 72 6d 2d sposition: form-
40b0: 64 61 74 61 3b 20 6e 61 6d 65 3d 22 66 6e 22 3b data; name="fn";
40c0: 20 66 69 6c 65 6e 61 6d 65 3d 22 69 6e 64 65 78 filename="index
40d0: 2e 68 74 6d 6c 22 0a 2a 2a 0a 2a 2a 20 54 68 65 .html".**.** The
40e0: 20 6c 69 6e 65 20 61 62 6f 76 65 20 69 73 20 74 line above is t
40f0: 6f 6b 65 6e 69 7a 65 64 20 61 73 20 66 6f 6c 6c okenized as foll
4100: 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 61 7a ows:.**.** az
4110: 41 72 67 5b 30 5d 20 3d 20 22 63 6f 6e 74 65 6e Arg[0] = "conten
4120: 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22 0a t-disposition:".
4130: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 31 5d 20 3d ** azArg[1] =
4140: 20 22 66 6f 72 6d 2d 64 61 74 61 22 0a 2a 2a 20 "form-data".**
4150: 20 20 20 61 7a 41 72 67 5b 32 5d 20 3d 20 22 6e azArg[2] = "n
4160: 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61 7a 41 72 ame=".** azAr
4170: 67 5b 33 5d 20 3d 20 22 66 6e 22 0a 2a 2a 20 20 g[3] = "fn".**
4180: 20 20 61 7a 41 72 67 5b 34 5d 20 3d 20 22 66 69 azArg[4] = "fi
4190: 6c 65 6e 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61 lename=".** a
41a0: 7a 41 72 67 5b 35 5d 20 3d 20 22 69 6e 64 65 78 zArg[5] = "index
41b0: 2e 68 74 6d 6c 22 0a 2a 2a 20 20 20 20 61 7a 41 .html".** azA
41c0: 72 67 5b 36 5d 20 3d 20 30 3b 0a 2a 2a 0a 2a 2a rg[6] = 0;.**.**
41d0: 20 27 5c 30 30 30 27 20 63 68 61 72 61 63 74 65 '\000' characte
41e0: 72 73 20 61 72 65 20 69 6e 73 65 72 74 65 64 20 rs are inserted
41f0: 69 6e 20 7a 5b 5d 20 61 74 20 74 68 65 20 65 6e in z[] at the en
4200: 64 20 6f 66 20 65 61 63 68 20 74 6f 6b 65 6e 2e d of each token.
4210: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 .** This routine
4220: 20 72 65 74 75 72 6e 73 20 74 68 65 20 74 6f 74 returns the tot
4230: 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b al number of tok
4240: 65 6e 73 20 6f 6e 20 74 68 65 20 6c 69 6e 65 2c ens on the line,
4250: 20 36 0a 2a 2a 20 69 6e 20 74 68 65 20 65 78 61 6.** in the exa
4260: 6d 70 6c 65 20 61 62 6f 76 65 2e 0a 2a 2f 0a 73 mple above..*/.s
4270: 74 61 74 69 63 20 69 6e 74 20 74 6f 6b 65 6e 69 tatic int tokeni
4280: 7a 65 5f 6c 69 6e 65 28 63 68 61 72 20 2a 7a 2c ze_line(char *z,
4290: 20 69 6e 74 20 6d 78 41 72 67 2c 20 63 68 61 72 int mxArg, char
42a0: 20 2a 2a 61 7a 41 72 67 29 7b 0a 20 20 69 6e 74 **azArg){. int
42b0: 20 69 20 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28 i = 0;. while(
42c0: 20 2a 7a 20 29 7b 0a 20 20 20 20 77 68 69 6c 65 *z ){. while
42d0: 28 20 69 73 73 70 61 63 65 28 2a 7a 29 20 7c 7c ( isspace(*z) ||
42e0: 20 2a 7a 3d 3d 27 3b 27 20 29 7b 20 7a 2b 2b 3b *z==';' ){ z++;
42f0: 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27 }. if( *z=='
4300: 22 27 20 26 26 20 7a 5b 31 5d 20 29 7b 0a 20 20 "' && z[1] ){.
4310: 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 *z = 0;.
4320: 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28 z++;. if(
4330: 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b 20 61 7a i<mxArg-1 ){ az
4340: 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a Arg[i++] = z; }.
4350: 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 while( *z
4360: 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b && *z!='"' ){ z+
4370: 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a +; }. if( *
4380: 7a 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 z==0 ) break;.
4390: 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 *z = 0;.
43a0: 20 20 7a 2b 2b 3b 0a 20 20 20 20 7d 65 6c 73 65 z++;. }else
43b0: 7b 0a 20 20 20 20 20 20 69 66 28 20 69 3c 6d 78 {. if( i<mx
43c0: 41 72 67 2d 31 20 29 7b 20 61 7a 41 72 67 5b 69 Arg-1 ){ azArg[i
43d0: 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 ++] = z; }.
43e0: 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 21 69 while( *z && !i
43f0: 73 73 70 61 63 65 28 2a 7a 29 20 26 26 20 2a 7a sspace(*z) && *z
4400: 21 3d 27 3b 27 20 26 26 20 2a 7a 21 3d 27 22 27 !=';' && *z!='"'
4410: 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 ){ z++; }.
4420: 20 69 66 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 if( *z && *z!='
4430: 22 27 20 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a "' ){. *z
4440: 20 3d 20 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b = 0;. z+
4450: 2b 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d +;. }. }
4460: 0a 20 20 7d 0a 20 20 61 7a 41 72 67 5b 69 5d 20 . }. azArg[i]
4470: 3d 20 30 3b 0a 20 20 72 65 74 75 72 6e 20 69 3b = 0;. return i;
4480: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 63 61 6e 20 74 .}../*.** Scan t
4490: 68 65 20 6d 75 6c 74 69 70 61 72 74 2d 66 6f 72 he multipart-for
44a0: 6d 20 63 6f 6e 74 65 6e 74 20 61 6e 64 20 6d 61 m content and ma
44b0: 6b 65 20 61 70 70 72 6f 70 72 69 61 74 65 20 65 ke appropriate e
44c0: 6e 74 72 69 65 73 0a 2a 2a 20 69 6e 74 6f 20 74 ntries.** into t
44d0: 68 65 20 70 61 72 61 6d 65 74 65 72 20 74 61 62 he parameter tab
44e0: 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f le..**.** The co
44f0: 6e 74 65 6e 74 20 73 74 72 69 6e 67 20 22 7a 22 ntent string "z"
4500: 20 69 73 20 6d 6f 64 69 66 69 65 64 20 62 79 20 is modified by
4510: 74 68 69 73 20 72 6f 75 74 69 6e 65 20 62 75 74 this routine but
4520: 20 69 74 20 69 73 0a 2a 2a 20 6e 6f 74 20 63 6f it is.** not co
4530: 70 69 65 64 2e 20 20 54 68 65 20 63 61 6c 6c 69 pied. The calli
4540: 6e 67 20 66 75 6e 63 74 69 6f 6e 20 6d 75 73 74 ng function must
4550: 20 6e 6f 74 20 64 65 61 6c 6c 6f 63 61 74 65 20 not deallocate
4560: 6f 72 20 6d 6f 64 69 66 79 0a 2a 2a 20 22 7a 22 or modify.** "z"
4570: 20 61 66 74 65 72 20 74 68 69 73 20 72 6f 75 74 after this rout
4580: 69 6e 65 20 66 69 6e 69 73 68 65 73 20 6f 72 20 ine finishes or
4590: 69 74 20 63 6f 75 6c 64 20 63 6f 72 72 75 70 74 it could corrupt
45a0: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 0a 2a the parameter.*
45b0: 2a 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 * table..*/.stat
45c0: 69 63 20 76 6f 69 64 20 70 72 6f 63 65 73 73 5f ic void process_
45d0: 6d 75 6c 74 69 70 61 72 74 5f 66 6f 72 6d 5f 64 multipart_form_d
45e0: 61 74 61 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 ata(char *z, int
45f0: 20 6c 65 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a len){. char *z
4600: 4c 69 6e 65 3b 0a 20 20 69 6e 74 20 6e 41 72 67 Line;. int nArg
4610: 2c 20 69 3b 0a 20 20 63 68 61 72 20 2a 7a 42 6f , i;. char *zBo
4620: 75 6e 64 72 79 3b 0a 20 20 63 68 61 72 20 2a 7a undry;. char *z
4630: 56 61 6c 75 65 3b 0a 20 20 63 68 61 72 20 2a 7a Value;. char *z
4640: 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 Name = 0;. int
4650: 73 68 6f 77 42 79 74 65 73 20 3d 20 30 3b 0a 20 showBytes = 0;.
4660: 20 63 68 61 72 20 2a 61 7a 41 72 67 5b 35 30 5d char *azArg[50]
4670: 3b 0a 0a 20 20 7a 42 6f 75 6e 64 72 79 20 3d 20 ;.. zBoundry =
4680: 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 get_line_from_st
4690: 72 69 6e 67 28 26 7a 2c 20 26 6c 65 6e 29 3b 0a ring(&z, &len);.
46a0: 20 20 69 66 28 20 7a 42 6f 75 6e 64 72 79 3d 3d if( zBoundry==
46b0: 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 77 68 0 ) return;. wh
46c0: 69 6c 65 28 20 28 7a 4c 69 6e 65 20 3d 20 67 65 ile( (zLine = ge
46d0: 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 t_line_from_stri
46e0: 6e 67 28 26 7a 2c 20 26 6c 65 6e 29 29 21 3d 30 ng(&z, &len))!=0
46f0: 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 4c 69 6e ){. if( zLin
4700: 65 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 e[0]==0 ){.
4710: 20 69 6e 74 20 6e 43 6f 6e 74 65 6e 74 20 3d 20 int nContent =
4720: 30 3b 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20 0;. zValue
4730: 3d 20 67 65 74 5f 62 6f 75 6e 64 65 64 5f 63 6f = get_bounded_co
4740: 6e 74 65 6e 74 28 26 7a 2c 20 26 6c 65 6e 2c 20 ntent(&z, &len,
4750: 7a 42 6f 75 6e 64 72 79 2c 20 26 6e 43 6f 6e 74 zBoundry, &nCont
4760: 65 6e 74 29 3b 0a 20 20 20 20 20 20 69 66 28 20 ent);. if(
4770: 7a 4e 61 6d 65 20 26 26 20 7a 56 61 6c 75 65 20 zName && zValue
4780: 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 && islower(zName
4790: 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 [0]) ){.
47a0: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 cgi_set_paramete
47b0: 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 r_nocopy(zName,
47c0: 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 20 zValue);.
47d0: 20 69 66 28 20 73 68 6f 77 42 79 74 65 73 20 29 if( showBytes )
47e0: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 67 69 5f {. cgi_
47f0: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f set_parameter_no
4800: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 copy(mprintf("%s
4810: 3a 62 79 74 65 73 22 2c 20 7a 4e 61 6d 65 29 2c :bytes", zName),
4820: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
4830: 6d 70 72 69 6e 74 66 28 22 25 64 22 2c 6e 43 6f mprintf("%d",nCo
4840: 6e 74 65 6e 74 29 29 3b 0a 20 20 20 20 20 20 20 ntent));.
4850: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 }. }.
4860: 20 7a 4e 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 zName = 0;.
4870: 20 20 73 68 6f 77 42 79 74 65 73 20 3d 20 30 3b showBytes = 0;
4880: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 . }else{.
4890: 20 20 6e 41 72 67 20 3d 20 74 6f 6b 65 6e 69 7a nArg = tokeniz
48a0: 65 5f 6c 69 6e 65 28 7a 4c 69 6e 65 2c 20 73 69 e_line(zLine, si
48b0: 7a 65 6f 66 28 61 7a 41 72 67 29 2f 73 69 7a 65 zeof(azArg)/size
48c0: 6f 66 28 61 7a 41 72 67 5b 30 5d 29 2c 20 61 7a of(azArg[0]), az
48d0: 41 72 67 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 Arg);. for(
48e0: 69 3d 30 3b 20 69 3c 6e 41 72 67 3b 20 69 2b 2b i=0; i<nArg; i++
48f0: 29 7b 0a 20 20 20 20 20 20 20 20 69 6e 74 20 63 ){. int c
4900: 20 3d 20 74 6f 6c 6f 77 65 72 28 61 7a 41 72 67 = tolower(azArg
4910: 5b 69 5d 5b 30 5d 29 3b 0a 20 20 20 20 20 20 20 [i][0]);.
4920: 20 69 66 28 20 63 3d 3d 27 63 27 20 26 26 20 73 if( c=='c' && s
4930: 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c tricmp(azArg[i],
4940: 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 "content-disposi
4950: 74 69 6f 6e 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 tion:")==0 ){.
4960: 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 i++;.
4970: 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 }else if( c
4980: 3d 3d 27 6e 27 20 26 26 20 73 74 72 69 63 6d 70 =='n' && stricmp
4990: 28 61 7a 41 72 67 5b 69 5d 2c 22 6e 61 6d 65 3d (azArg[i],"name=
49a0: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 ")==0 ){.
49b0: 20 20 20 7a 4e 61 6d 65 20 3d 20 61 7a 41 72 67 zName = azArg
49c0: 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 7d [++i];. }
49d0: 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 66 27 20 else if( c=='f'
49e0: 26 26 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 && stricmp(azArg
49f0: 5b 69 5d 2c 22 66 69 6c 65 6e 61 6d 65 3d 22 29 [i],"filename=")
4a00: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 ==0 ){.
4a10: 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a 41 72 67 char *z = azArg
4a20: 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 20 [++i];.
4a30: 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a 20 if( zName && z
4a40: 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 && islower(zName
4a50: 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 [0]) ){.
4a60: 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 cgi_set_para
4a70: 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 meter_nocopy(mpr
4a80: 69 6e 74 66 28 22 25 73 3a 66 69 6c 65 6e 61 6d intf("%s:filenam
4a90: 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a 20 e",zName), z);.
4aa0: 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 }.
4ab0: 20 20 20 20 20 73 68 6f 77 42 79 74 65 73 20 3d showBytes =
4ac0: 20 31 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 1;. }els
4ad0: 65 20 69 66 28 20 63 3d 3d 27 63 27 20 26 26 20 e if( c=='c' &&
4ae0: 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d stricmp(azArg[i]
4af0: 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 22 ,"content-type:"
4b00: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 )==0 ){.
4b10: 20 20 63 68 61 72 20 2a 7a 20 3d 20 61 7a 41 72 char *z = azAr
4b20: 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 g[++i];.
4b30: 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a if( zName && z
4b40: 20 26 26 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d && islower(zNam
4b50: 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 e[0]) ){.
4b60: 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 cgi_set_par
4b70: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 ameter_nocopy(mp
4b80: 72 69 6e 74 66 28 22 25 73 3a 6d 69 6d 65 74 79 rintf("%s:mimety
4b90: 70 65 22 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a pe",zName), z);.
4ba0: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 }.
4bb0: 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 }. }.
4bc0: 20 20 7d 0a 20 20 7d 20 20 20 20 20 20 20 20 0a }. } .
4bd0: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c }../*.** Initial
4be0: 69 7a 65 20 74 68 65 20 71 75 65 72 79 20 70 61 ize the query pa
4bf0: 72 61 6d 65 74 65 72 20 64 61 74 61 62 61 73 65 rameter database
4c00: 2e 20 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 . Information i
4c10: 73 20 70 75 6c 6c 65 64 20 66 72 6f 6d 0a 2a 2a s pulled from.**
4c20: 20 74 68 65 20 51 55 45 52 59 5f 53 54 52 49 4e the QUERY_STRIN
4c30: 47 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 G environment va
4c40: 72 69 61 62 6c 65 20 28 69 66 20 69 74 20 65 78 riable (if it ex
4c50: 69 73 74 73 29 2c 20 66 72 6f 6d 20 73 74 61 6e ists), from stan
4c60: 64 61 72 64 0a 2a 2a 20 69 6e 70 75 74 20 69 66 dard.** input if
4c70: 20 74 68 65 72 65 20 69 73 20 50 4f 53 54 20 64 there is POST d
4c80: 61 74 61 2c 20 61 6e 64 20 66 72 6f 6d 20 48 54 ata, and from HT
4c90: 54 50 5f 43 4f 4f 4b 49 45 2e 0a 2a 2f 0a 76 6f TP_COOKIE..*/.vo
4ca0: 69 64 20 63 67 69 5f 69 6e 69 74 28 76 6f 69 64 id cgi_init(void
4cb0: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 ){. char *z;.
4cc0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 70 const char *zTyp
4cd0: 65 3b 0a 20 20 69 6e 74 20 6c 65 6e 3b 0a 20 20 e;. int len;.
4ce0: 63 67 69 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 cgi_destination(
4cf0: 43 47 49 5f 42 4f 44 59 29 3b 0a 20 20 7a 20 3d CGI_BODY);. z =
4d00: 20 28 63 68 61 72 2a 29 50 28 22 51 55 45 52 59 (char*)P("QUERY
4d10: 5f 53 54 52 49 4e 47 22 29 3b 0a 20 20 69 66 28 _STRING");. if(
4d20: 20 7a 20 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 z ){. z = mp
4d30: 72 69 6e 74 66 28 22 25 73 22 2c 7a 29 3b 0a 20 rintf("%s",z);.
4d40: 20 20 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 add_param_lis
4d50: 74 28 7a 2c 20 27 26 27 29 3b 0a 20 20 7d 0a 0a t(z, '&');. }..
4d60: 20 20 6c 65 6e 20 3d 20 61 74 6f 69 28 50 44 28 len = atoi(PD(
4d70: 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 "CONTENT_LENGTH"
4d80: 2c 20 22 30 22 29 29 3b 0a 20 20 67 2e 7a 43 6f , "0"));. g.zCo
4d90: 6e 74 65 6e 74 54 79 70 65 20 3d 20 7a 54 79 70 ntentType = zTyp
4da0: 65 20 3d 20 50 28 22 43 4f 4e 54 45 4e 54 5f 54 e = P("CONTENT_T
4db0: 59 50 45 22 29 3b 0a 20 20 69 66 28 20 6c 65 6e YPE");. if( len
4dc0: 3e 30 20 26 26 20 7a 54 79 70 65 20 29 7b 0a 20 >0 && zType ){.
4dd0: 20 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 26 67 2e blob_zero(&g.
4de0: 63 67 69 49 6e 29 3b 0a 20 20 20 20 69 66 28 20 cgiIn);. if(
4df0: 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 22 61 70 strcmp(zType,"ap
4e00: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d plication/x-www-
4e10: 66 6f 72 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 22 form-urlencoded"
4e20: 29 3d 3d 30 20 0a 20 20 20 20 20 20 20 20 20 7c )==0 . |
4e30: 7c 20 73 74 72 6e 63 6d 70 28 7a 54 79 70 65 2c | strncmp(zType,
4e40: 22 6d 75 6c 74 69 70 61 72 74 2f 66 6f 72 6d 2d "multipart/form-
4e50: 64 61 74 61 22 2c 31 39 29 3d 3d 30 20 29 7b 0a data",19)==0 ){.
4e60: 20 20 20 20 20 20 7a 20 3d 20 6d 61 6c 6c 6f 63 z = malloc
4e70: 28 20 6c 65 6e 2b 31 20 29 3b 0a 20 20 20 20 20 ( len+1 );.
4e80: 20 69 66 28 20 7a 3d 3d 30 20 29 20 65 78 69 74 if( z==0 ) exit
4e90: 28 31 29 3b 0a 20 20 20 20 20 20 6c 65 6e 20 3d (1);. len =
4ea0: 20 66 72 65 61 64 28 7a 2c 20 31 2c 20 6c 65 6e fread(z, 1, len
4eb0: 2c 20 73 74 64 69 6e 29 3b 0a 20 20 20 20 20 20 , stdin);.
4ec0: 7a 5b 6c 65 6e 5d 20 3d 20 30 3b 0a 20 20 20 20 z[len] = 0;.
4ed0: 20 20 69 66 28 20 7a 54 79 70 65 5b 30 5d 3d 3d if( zType[0]==
4ee0: 27 61 27 20 29 7b 0a 20 20 20 20 20 20 20 20 61 'a' ){. a
4ef0: 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c dd_param_list(z,
4f00: 20 27 26 27 29 3b 0a 20 20 20 20 20 20 7d 65 6c '&');. }el
4f10: 73 65 7b 0a 20 20 20 20 20 20 20 20 70 72 6f 63 se{. proc
4f20: 65 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66 6f ess_multipart_fo
4f30: 72 6d 5f 64 61 74 61 28 7a 2c 20 6c 65 6e 29 3b rm_data(z, len);
4f40: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c . }. }el
4f50: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54 se if( strcmp(zT
4f60: 79 70 65 2c 20 22 61 70 70 6c 69 63 61 74 69 6f ype, "applicatio
4f70: 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 20 n/x-fossil")==0
4f80: 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 ){. blob_re
4f90: 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 ad_from_channel(
4fa0: 26 67 2e 63 67 69 49 6e 2c 20 73 74 64 69 6e 2c &g.cgiIn, stdin,
4fb0: 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 62 6c 6f len);. blo
4fc0: 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26 67 2e b_uncompress(&g.
4fd0: 63 67 69 49 6e 2c 20 26 67 2e 63 67 69 49 6e 29 cgiIn, &g.cgiIn)
4fe0: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 ;. }else if(
4ff0: 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20 22 61 strcmp(zType, "a
5000: 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 pplication/x-fos
5010: 73 69 6c 2d 64 65 62 75 67 22 29 3d 3d 30 20 29 sil-debug")==0 )
5020: 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 61 {. blob_rea
5030: 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26 d_from_channel(&
5040: 67 2e 63 67 69 49 6e 2c 20 73 74 64 69 6e 2c 20 g.cgiIn, stdin,
5050: 6c 65 6e 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a len);. }. }.
5060: 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 50 28 . z = (char*)P(
5070: 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 29 3b 0a "HTTP_COOKIE");.
5080: 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 20 20 7a if( z ){. z
5090: 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c = mprintf("%s",
50a0: 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 61 72 61 z);. add_para
50b0: 6d 5f 6c 69 73 74 28 7a 2c 20 27 3b 27 29 3b 0a m_list(z, ';');.
50c0: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 }.}../*.** Thi
50d0: 73 20 69 73 20 74 68 65 20 63 6f 6d 70 61 72 69 s is the compari
50e0: 73 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 son function use
50f0: 64 20 74 6f 20 73 6f 72 74 20 74 68 65 20 61 50 d to sort the aP
5100: 61 72 61 6d 51 50 5b 5d 20 61 72 72 61 79 20 6f aramQP[] array o
5110: 66 0a 2a 2a 20 71 75 65 72 79 20 70 61 72 61 6d f.** query param
5120: 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 eters and cookie
5130: 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 s..*/.static int
5140: 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72 65 28 qparam_compare(
5150: 63 6f 6e 73 74 20 76 6f 69 64 20 2a 61 2c 20 63 const void *a, c
5160: 6f 6e 73 74 20 76 6f 69 64 20 2a 62 29 7b 0a 20 onst void *b){.
5170: 20 73 74 72 75 63 74 20 51 50 61 72 61 6d 20 2a struct QParam *
5180: 70 41 20 3d 20 28 73 74 72 75 63 74 20 51 50 61 pA = (struct QPa
5190: 72 61 6d 2a 29 61 3b 0a 20 20 73 74 72 75 63 74 ram*)a;. struct
51a0: 20 51 50 61 72 61 6d 20 2a 70 42 20 3d 20 28 73 QParam *pB = (s
51b0: 74 72 75 63 74 20 51 50 61 72 61 6d 2a 29 62 3b truct QParam*)b;
51c0: 0a 20 20 69 6e 74 20 63 3b 0a 20 20 63 20 3d 20 . int c;. c =
51d0: 73 74 72 63 6d 70 28 70 41 2d 3e 7a 4e 61 6d 65 strcmp(pA->zName
51e0: 2c 20 70 42 2d 3e 7a 4e 61 6d 65 29 3b 0a 20 20 , pB->zName);.
51f0: 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20 if( c==0 ){.
5200: 63 20 3d 20 70 41 2d 3e 73 65 71 20 2d 20 70 42 c = pA->seq - pB
5210: 2d 3e 73 65 71 3b 0a 20 20 7d 0a 20 20 72 65 74 ->seq;. }. ret
5220: 75 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 urn c;.}../*.**
5230: 52 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65 Return the value
5240: 20 6f 66 20 61 20 71 75 65 72 79 20 70 61 72 61 of a query para
5250: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 meter or cookie
5260: 77 68 6f 73 65 20 6e 61 6d 65 20 69 73 20 7a 4e whose name is zN
5270: 61 6d 65 2e 0a 2a 2a 20 49 66 20 74 68 65 72 65 ame..** If there
5280: 20 69 73 20 6e 6f 20 71 75 65 72 79 20 70 61 72 is no query par
5290: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 ameter or cookie
52a0: 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 61 6e 64 named zName and
52b0: 20 74 68 65 20 66 69 72 73 74 0a 2a 2a 20 63 68 the first.** ch
52c0: 61 72 61 63 74 65 72 20 6f 66 20 7a 4e 61 6d 65 aracter of zName
52d0: 20 69 73 20 75 70 70 65 72 63 61 73 65 2c 20 74 is uppercase, t
52e0: 68 65 6e 20 63 68 65 63 6b 20 74 6f 20 73 65 65 hen check to see
52f0: 20 69 66 20 74 68 65 72 65 20 69 73 20 61 6e 0a if there is an.
5300: 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 ** environment v
5310: 61 72 69 61 62 6c 65 20 62 79 20 74 68 61 74 20 ariable by that
5320: 6e 61 6d 65 20 61 6e 64 20 72 65 74 75 72 6e 20 name and return
5330: 69 74 20 69 66 20 74 68 65 72 65 20 69 73 2e 20 it if there is.
5340: 20 41 73 0a 2a 2a 20 61 20 6c 61 73 74 20 72 65 As.** a last re
5350: 73 6f 72 74 20 77 68 65 6e 20 6e 6f 74 68 69 6e sort when nothin
5360: 67 20 65 6c 73 65 20 6d 61 74 63 68 65 73 2c 20 g else matches,
5370: 72 65 74 75 72 6e 20 7a 44 65 66 61 75 6c 74 2e return zDefault.
5380: 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20 2a .*/.const char *
5390: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 63 6f cgi_parameter(co
53a0: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c nst char *zName,
53b0: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 65 const char *zDe
53c0: 66 61 75 6c 74 29 7b 0a 20 20 69 6e 74 20 6c 6f fault){. int lo
53d0: 2c 20 68 69 2c 20 6d 69 64 2c 20 63 3b 0a 0a 20 , hi, mid, c;..
53e0: 20 2f 2a 20 54 68 65 20 73 6f 72 74 51 50 20 66 /* The sortQP f
53f0: 6c 61 67 20 69 73 20 73 65 74 20 77 68 65 6e 65 lag is set whene
5400: 76 65 72 20 61 20 6e 65 77 20 71 75 65 72 79 20 ver a new query
5410: 70 61 72 61 6d 65 74 65 72 20 69 73 20 69 6e 73 parameter is ins
5420: 65 72 74 65 64 2e 0a 20 20 2a 2a 20 49 74 20 69 erted.. ** It i
5430: 6e 64 69 63 61 74 65 73 20 74 68 61 74 20 77 65 ndicates that we
5440: 20 6e 65 65 64 20 74 6f 20 72 65 73 6f 72 74 20 need to resort
5450: 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 the query parame
5460: 74 65 72 73 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 ters.. */. if(
5470: 20 73 6f 72 74 51 50 20 29 7b 0a 20 20 20 20 69 sortQP ){. i
5480: 6e 74 20 69 2c 20 6a 3b 0a 20 20 20 20 71 73 6f nt i, j;. qso
5490: 72 74 28 61 50 61 72 61 6d 51 50 2c 20 6e 55 73 rt(aParamQP, nUs
54a0: 65 64 51 50 2c 20 73 69 7a 65 6f 66 28 61 50 61 edQP, sizeof(aPa
54b0: 72 61 6d 51 50 5b 30 5d 29 2c 20 71 70 61 72 61 ramQP[0]), qpara
54c0: 6d 5f 63 6f 6d 70 61 72 65 29 3b 0a 20 20 20 20 m_compare);.
54d0: 73 6f 72 74 51 50 20 3d 20 30 3b 0a 20 20 20 20 sortQP = 0;.
54e0: 2f 2a 20 41 66 74 65 72 20 73 6f 72 74 69 6e 67 /* After sorting
54f0: 2c 20 72 65 6d 6f 76 65 20 64 75 70 6c 69 63 61 , remove duplica
5500: 74 65 20 70 61 72 61 6d 65 74 65 72 73 2e 20 20 te parameters.
5510: 54 68 65 20 73 65 63 6f 6e 64 61 72 79 20 73 6f The secondary so
5520: 72 74 0a 20 20 20 20 2a 2a 20 6b 65 79 20 69 73 rt. ** key is
5530: 20 61 50 61 72 61 6d 51 50 5b 5d 2e 73 65 71 20 aParamQP[].seq
5540: 61 6e 64 20 77 65 20 6b 65 65 70 20 74 68 65 20 and we keep the
5550: 66 69 72 73 74 20 65 6e 74 72 79 2e 20 20 54 68 first entry. Th
5560: 61 74 20 6d 65 61 6e 73 0a 20 20 20 20 2a 2a 20 at means. **
5570: 77 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 63 with duplicate c
5580: 61 6c 6c 73 20 74 6f 20 63 67 69 5f 73 65 74 5f alls to cgi_set_
5590: 70 61 72 61 6d 65 74 65 72 28 29 20 74 68 65 20 parameter() the
55a0: 73 65 63 6f 6e 64 20 61 6e 64 0a 20 20 20 20 2a second and. *
55b0: 2a 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c * subsequent cal
55c0: 6c 73 20 61 72 65 20 65 66 66 65 63 74 69 76 65 ls are effective
55d0: 6c 79 20 6e 6f 2d 6f 70 73 2e 20 2a 2f 0a 20 20 ly no-ops. */.
55e0: 20 20 66 6f 72 28 69 3d 6a 3d 31 3b 20 69 3c 6e for(i=j=1; i<n
55f0: 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 UsedQP; i++){.
5600: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61 if( strcmp(a
5610: 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 ParamQP[i].zName
5620: 2c 61 50 61 72 61 6d 51 50 5b 69 2d 31 5d 2e 7a ,aParamQP[i-1].z
5630: 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 Name)==0 ){.
5640: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 continue;.
5650: 20 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 }. if(
5660: 6a 3c 69 20 29 7b 0a 20 20 20 20 20 20 20 20 6d j<i ){. m
5670: 65 6d 63 70 79 28 26 61 50 61 72 61 6d 51 50 5b emcpy(&aParamQP[
5680: 6a 5d 2c 20 26 61 50 61 72 61 6d 51 50 5b 69 5d j], &aParamQP[i]
5690: 2c 20 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51 , sizeof(aParamQ
56a0: 50 5b 6a 5d 29 29 3b 0a 20 20 20 20 20 20 7d 0a P[j]));. }.
56b0: 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 20 20 20 7d j++;. }
56c0: 0a 20 20 20 20 6e 55 73 65 64 51 50 20 3d 20 6a . nUsedQP = j
56d0: 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 6f 20 61 ;. }.. /* Do a
56e0: 20 62 69 6e 61 72 79 20 73 65 61 72 63 68 20 66 binary search f
56f0: 6f 72 20 61 20 6d 61 74 63 68 69 6e 67 20 71 75 or a matching qu
5700: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 2a 2f ery parameter */
5710: 0a 20 20 6c 6f 20 3d 20 30 3b 0a 20 20 68 69 20 . lo = 0;. hi
5720: 3d 20 6e 55 73 65 64 51 50 2d 31 3b 0a 20 20 77 = nUsedQP-1;. w
5730: 68 69 6c 65 28 20 6c 6f 3c 3d 68 69 20 29 7b 0a hile( lo<=hi ){.
5740: 20 20 20 20 6d 69 64 20 3d 20 28 6c 6f 2b 68 69 mid = (lo+hi
5750: 29 2f 32 3b 0a 20 20 20 20 63 20 3d 20 73 74 72 )/2;. c = str
5760: 63 6d 70 28 61 50 61 72 61 6d 51 50 5b 6d 69 64 cmp(aParamQP[mid
5770: 5d 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 29 3b ].zName, zName);
5780: 0a 20 20 20 20 69 66 28 20 63 3d 3d 30 20 29 7b . if( c==0 ){
5790: 0a 20 20 20 20 20 20 43 47 49 44 45 42 55 47 28 . CGIDEBUG(
57a0: 28 22 6d 65 6d 2d 6d 61 74 63 68 20 5b 25 73 5d ("mem-match [%s]
57b0: 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d = [%s]\n", zNam
57c0: 65 2c 20 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d e, aParamQP[mid]
57d0: 2e 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20 20 .zValue));.
57e0: 20 72 65 74 75 72 6e 20 61 50 61 72 61 6d 51 50 return aParamQP
57f0: 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 3b 0a 20 20 [mid].zValue;.
5800: 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3e 30 20 }else if( c>0
5810: 29 7b 0a 20 20 20 20 20 20 68 69 20 3d 20 6d 69 ){. hi = mi
5820: 64 2d 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a d-1;. }else{.
5830: 20 20 20 20 20 20 6c 6f 20 3d 20 6d 69 64 2b 31 lo = mid+1
5840: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f ;. }. }.. /
5850: 2a 20 49 66 20 6e 6f 20 6d 61 74 63 68 20 69 73 * If no match is
5860: 20 66 6f 75 6e 64 20 61 6e 64 20 74 68 65 20 6e found and the n
5870: 61 6d 65 20 62 65 67 69 6e 73 20 77 69 74 68 20 ame begins with
5880: 61 6e 20 75 70 70 65 72 2d 63 61 73 65 0a 20 20 an upper-case.
5890: 2a 2a 20 6c 65 74 74 65 72 2c 20 74 68 65 6e 20 ** letter, then
58a0: 63 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 check to see if
58b0: 74 68 65 72 65 20 69 73 20 61 6e 20 65 6e 76 69 there is an envi
58c0: 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 ronment variable
58d0: 0a 20 20 2a 2a 20 77 69 74 68 20 74 68 65 20 67 . ** with the g
58e0: 69 76 65 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a iven name.. */.
58f0: 20 20 69 66 28 20 69 73 75 70 70 65 72 28 7a 4e if( isupper(zN
5900: 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 63 ame[0]) ){. c
5910: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 onst char *zValu
5920: 65 20 3d 20 67 65 74 65 6e 76 28 7a 4e 61 6d 65 e = getenv(zName
5930: 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 75 );. if( zValu
5940: 65 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 e ){. cgi_s
5950: 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 et_parameter_noc
5960: 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 opy(zName, zValu
5970: 65 29 3b 0a 20 20 20 20 20 20 43 47 49 44 45 42 e);. CGIDEB
5980: 55 47 28 28 22 65 6e 76 2d 6d 61 74 63 68 20 5b UG(("env-match [
5990: 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a %s] = [%s]\n", z
59a0: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 29 3b 0a Name, zValue));.
59b0: 20 20 20 20 20 20 72 65 74 75 72 6e 20 7a 56 61 return zVa
59c0: 6c 75 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 lue;. }. }.
59d0: 20 43 47 49 44 45 42 55 47 28 28 22 6e 6f 2d 6d CGIDEBUG(("no-m
59e0: 61 74 63 68 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e atch [%s]\n", zN
59f0: 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 ame));. return
5a00: 7a 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a zDefault;.}../*.
5a10: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 61 ** Return the na
5a20: 6d 65 20 6f 66 20 74 68 65 20 69 2d 74 68 20 43 me of the i-th C
5a30: 47 49 20 70 61 72 61 6d 65 74 65 72 2e 20 20 52 GI parameter. R
5a40: 65 74 75 72 6e 20 4e 55 4c 4c 20 69 66 20 74 68 eturn NULL if th
5a50: 65 72 65 0a 2a 2a 20 61 72 65 20 66 65 77 65 72 ere.** are fewer
5a60: 20 74 68 61 6e 20 69 20 72 65 67 69 73 74 65 72 than i register
5a70: 65 64 20 43 47 49 20 70 61 72 6d 61 65 74 65 72 ed CGI parmaeter
5a80: 73 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 s..*/.const char
5a90: 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72 5f *cgi_parameter_
5aa0: 6e 61 6d 65 28 69 6e 74 20 69 29 7b 0a 20 20 69 name(int i){. i
5ab0: 66 28 20 69 3e 3d 30 20 26 26 20 69 3c 6e 55 73 f( i>=0 && i<nUs
5ac0: 65 64 51 50 20 29 7b 0a 20 20 20 20 72 65 74 75 edQP ){. retu
5ad0: 72 6e 20 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a rn aParamQP[i].z
5ae0: 4e 61 6d 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 Name;. }else{.
5af0: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d return 0;. }
5b00: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74 20 .}../*.** Print
5b10: 43 47 49 20 64 65 62 75 67 67 69 6e 67 20 6d 65 CGI debugging me
5b20: 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20 ssages..*/.void
5b30: 63 67 69 5f 64 65 62 75 67 28 63 6f 6e 73 74 20 cgi_debug(const
5b40: 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e char *zFormat, .
5b50: 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 ..){. va_list a
5b60: 70 3b 0a 20 20 69 66 28 20 67 2e 66 44 65 62 75 p;. if( g.fDebu
5b70: 67 20 29 7b 0a 20 20 20 20 76 61 5f 73 74 61 72 g ){. va_star
5b80: 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a t(ap, zFormat);.
5b90: 20 20 20 20 76 66 70 72 69 6e 74 66 28 67 2e 66 vfprintf(g.f
5ba0: 44 65 62 75 67 2c 20 7a 46 6f 72 6d 61 74 2c 20 Debug, zFormat,
5bb0: 61 70 29 3b 0a 20 20 20 20 76 61 5f 65 6e 64 28 ap);. va_end(
5bc0: 61 70 29 3b 0a 20 20 20 20 66 66 6c 75 73 68 28 ap);. fflush(
5bd0: 67 2e 66 44 65 62 75 67 29 3b 0a 20 20 7d 0a 7d g.fDebug);. }.}
5be0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 ../*.** Return t
5bf0: 72 75 65 20 69 66 20 61 6e 79 20 6f 66 20 74 68 rue if any of th
5c00: 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 e query paramete
5c10: 72 73 20 69 6e 20 74 68 65 20 61 72 67 75 6d 65 rs in the argume
5c20: 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 72 65 20 64 nt.** list are d
5c30: 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20 63 efined..*/.int c
5c40: 67 69 5f 61 6e 79 28 63 6f 6e 73 74 20 63 68 61 gi_any(const cha
5c50: 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 r *z, ...){. va
5c60: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72 _list ap;. char
5c70: 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 67 69 5f *z2;. if( cgi_
5c80: 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 29 21 3d parameter(z,0)!=
5c90: 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 0 ) return 1;.
5ca0: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 29 3b va_start(ap, z);
5cb0: 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 20 3d 20 . while( (z2 =
5cc0: 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a va_arg(ap, char*
5cd0: 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 ))!=0 ){. if(
5ce0: 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a cgi_parameter(z
5cf0: 32 2c 30 29 21 3d 30 20 29 20 72 65 74 75 72 6e 2,0)!=0 ) return
5d00: 20 31 3b 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64 1;. }. va_end
5d10: 28 61 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 (ap);. return 0
5d20: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 ;.}../*.** Retur
5d30: 6e 20 74 72 75 65 20 69 66 20 61 6c 6c 20 6f 66 n true if all of
5d40: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d the query param
5d50: 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 67 eters in the arg
5d60: 75 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a 20 61 72 ument list.** ar
5d70: 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e e defined..*/.in
5d80: 74 20 63 67 69 5f 61 6c 6c 28 63 6f 6e 73 74 20 t cgi_all(const
5d90: 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 char *z, ...){.
5da0: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 va_list ap;. c
5db0: 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 har *z2;. if( c
5dc0: 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 gi_parameter(z,0
5dd0: 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b )==0 ) return 0;
5de0: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 . va_start(ap,
5df0: 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 z);. while( (z2
5e00: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 = va_arg(ap, ch
5e10: 61 72 2a 29 29 3d 3d 30 20 29 7b 0a 20 20 20 20 ar*))==0 ){.
5e20: 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 if( cgi_paramete
5e30: 72 28 7a 32 2c 30 29 3d 3d 30 20 29 20 72 65 74 r(z2,0)==0 ) ret
5e40: 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 76 61 5f urn 0;. }. va_
5e50: 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72 end(ap);. retur
5e60: 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 n 1;.}../*.** Pr
5e70: 69 6e 74 20 61 6c 6c 20 71 75 65 72 79 20 70 61 int all query pa
5e80: 72 61 6d 65 74 65 72 73 20 6f 6e 20 73 74 61 6e rameters on stan
5e90: 64 61 72 64 20 6f 75 74 70 75 74 2e 20 20 46 6f dard output. Fo
5ea0: 72 6d 61 74 20 74 68 65 0a 2a 2a 20 70 61 72 61 rmat the.** para
5eb0: 6d 65 74 65 72 73 20 61 73 20 48 54 4d 4c 2e 20 meters as HTML.
5ec0: 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f This is used fo
5ed0: 72 20 74 65 73 74 69 6e 67 20 61 6e 64 20 64 65 r testing and de
5ee0: 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 bugging..*/.void
5ef0: 20 63 67 69 5f 70 72 69 6e 74 5f 61 6c 6c 28 76 cgi_print_all(v
5f00: 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 oid){. int i;.
5f10: 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 22 cgi_parameter("
5f20: 22 2c 22 22 29 3b 20 20 2f 2a 20 46 6f 72 63 65 ",""); /* Force
5f30: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 73 20 the parameters
5f40: 69 6e 74 6f 20 73 6f 72 74 65 64 20 6f 72 64 65 into sorted orde
5f50: 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 r */. for(i=0;
5f60: 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b i<nUsedQP; i++){
5f70: 0a 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 . cgi_printf(
5f80: 22 25 73 20 3d 20 25 73 20 20 3c 62 72 20 2f 3e "%s = %s <br />
5f90: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 68 74 6d 6c \n",. html
5fa0: 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e ize(aParamQP[i].
5fb0: 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 68 74 6d 6c zName, -1), html
5fc0: 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e ize(aParamQP[i].
5fd0: 7a 56 61 6c 75 65 2c 20 2d 31 29 29 3b 0a 20 20 zValue, -1));.
5fe0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 }.}../*.** Write
5ff0: 20 48 54 4d 4c 20 74 65 78 74 20 66 6f 72 20 61 HTML text for a
6000: 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 74 6f n option menu to
6010: 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 standard output
6020: 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a 20 69 73 20 . zParam.** is
6030: 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 the query parame
6040: 74 65 72 20 74 68 61 74 20 74 68 65 20 6f 70 74 ter that the opt
6050: 69 6f 6e 20 6d 65 6e 75 20 73 65 74 73 2e 20 20 ion menu sets.
6060: 7a 44 66 6c 74 20 69 73 20 74 68 65 0a 2a 2a 20 zDflt is the.**
6070: 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 20 6f 66 initial value of
6080: 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 the option menu
6090: 2e 20 20 41 64 64 69 74 69 6f 6e 20 61 72 67 75 . Addition argu
60a0: 6d 65 6e 74 73 20 61 72 65 20 6e 61 6d 65 2f 76 ments are name/v
60b0: 61 6c 75 65 0a 2a 2a 20 70 61 69 72 73 20 74 68 alue.** pairs th
60c0: 61 74 20 64 65 66 69 6e 65 20 76 61 6c 75 65 73 at define values
60d0: 20 6f 6e 20 74 68 65 20 6d 65 6e 75 2e 20 20 54 on the menu. T
60e0: 68 65 20 6c 69 73 74 20 69 73 20 74 65 72 6d 69 he list is termi
60f0: 6e 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 61 20 nated with.** a
6100: 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 61 72 67 75 single NULL argu
6110: 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 ment..*/.void cg
6120: 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 69 6e 74 i_optionmenu(int
6130: 20 69 6e 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 in, const char
6140: 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 *zP, const char
6150: 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f *zD, ...){. va_
6160: 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72 20 list ap;. char
6170: 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c 3b 0a 20 *zName, *zVal;.
6180: 20 69 6e 74 20 64 66 6c 74 53 65 65 6e 20 3d 20 int dfltSeen =
6190: 30 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 0;. cgi_printf(
61a0: 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 "%*s<select size
61b0: 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c =1 name=\"%s\">\
61c0: 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b n", in, "", zP);
61d0: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 . va_start(ap,
61e0: 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a zD);. while( (z
61f0: 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70 Name = va_arg(ap
6200: 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20 , char*))!=0 &&
6210: 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 (zVal = va_arg(a
6220: 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b p, char*))!=0 ){
6230: 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 . if( strcmp(
6240: 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 29 7b 20 64 zVal,zD)==0 ){ d
6250: 66 6c 74 53 65 65 6e 20 3d 20 31 3b 20 62 72 65 fltSeen = 1; bre
6260: 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76 61 5f 65 ak; }. }. va_e
6270: 6e 64 28 61 70 29 3b 0a 20 20 69 66 28 20 21 64 nd(ap);. if( !d
6280: 66 6c 74 53 65 65 6e 20 29 7b 0a 20 20 20 20 69 fltSeen ){. i
6290: 66 28 20 7a 44 5b 30 5d 20 29 7b 0a 20 20 20 20 f( zD[0] ){.
62a0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
62b0: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c s<option value=\
62c0: 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 "%h\" selected>%
62d0: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 h</option>\n",.
62e0: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c in+2, "",
62f0: 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 65 zD, zD);. }e
6300: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 lse{. cgi_p
6310: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f rintf("%*s<optio
6320: 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c n value=\"\" sel
6330: 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 ected> </op
6340: 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b 32 2c 20 tion>\n", in+2,
6350: 22 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 "");. }. }.
6360: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 44 va_start(ap, zD
6370: 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4e 61 );. while( (zNa
6380: 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 me = va_arg(ap,
6390: 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20 28 7a char*))!=0 && (z
63a0: 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c Val = va_arg(ap,
63b0: 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20 char*))!=0 ){.
63c0: 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 20 if( zName[0]
63d0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 ){. cgi_pri
63e0: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 ntf("%*s<option
63f0: 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25 value=\"%h\"%s>%
6400: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 h</option>\n",.
6410: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c in+2, "",
6420: 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20 . zVal,.
6430: 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 strcmp(zV
6440: 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 al, zD) ? "" : "
6450: 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 20 20 20 selected",.
6460: 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 20 20 20 zName.
6470: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 );. }else{.
6480: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 cgi_printf("
6490: 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 %*s<option value
64a0: 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b 3c 2f =\"\"%s> </
64b0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 option>\n",.
64c0: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 in+2, "",.
64d0: 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 strcmp(zVa
64e0: 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 l, zD) ? "" : "
64f0: 73 65 6c 65 63 74 65 64 22 0a 20 20 20 20 20 20 selected".
6500: 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 76 );. }. }. v
6510: 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63 67 69 a_end(ap);. cgi
6520: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 _printf("%*s</se
6530: 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 lect>\n", in, ""
6540: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 );.}../*.** This
6550: 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 61 routine works a
6560: 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69 5f 6f 70 lot like cgi_op
6570: 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 tionmenu() excep
6580: 74 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 20 t that the list
6590: 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 20 69 73 20 of.** values is
65a0: 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 61 6e 20 contained in an
65b0: 61 72 72 61 79 2e 20 20 41 6c 73 6f 2c 20 74 68 array. Also, th
65c0: 65 20 76 61 6c 75 65 73 20 61 72 65 20 6a 75 73 e values are jus
65d0: 74 20 76 61 6c 75 65 73 2c 20 6e 6f 74 0a 2a 2a t values, not.**
65e0: 20 6e 61 6d 65 2f 76 61 6c 75 65 20 70 61 69 72 name/value pair
65f0: 73 20 61 73 20 69 6e 20 63 67 69 5f 6f 70 74 69 s as in cgi_opti
6600: 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f 69 64 20 onmenu..*/.void
6610: 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e 75 cgi_v_optionmenu
6620: 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20 20 20 (. int in,
6630: 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 /* Inde
6640: 6e 74 20 62 79 20 74 68 69 73 20 61 6d 6f 75 6e nt by this amoun
6650: 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 t */. const cha
6660: 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a 20 54 r *zP, /* T
6670: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 he query paramet
6680: 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e er name */. con
6690: 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 20 20 20 st char *zD,
66a0: 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 76 61 6c /* Default val
66b0: 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 ue */. const ch
66c0: 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f 2a 20 ar **az /*
66d0: 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 64 20 NULL-terminated
66e0: 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65 64 20 list of allowed
66f0: 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 20 63 values */.){. c
6700: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b onst char *zVal;
6710: 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69 5f . int i;. cgi_
6720: 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c 65 printf("%*s<sele
6730: 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c ct size=1 name=\
6740: 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22 "%s\">\n", in, "
6750: 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28 69 3d ", zP);. for(i=
6760: 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 0; az[i]; i++){.
6770: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61 if( strcmp(a
6780: 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20 62 72 z[i],zD)==0 ) br
6790: 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61 eak;. }. if( a
67a0: 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 69 z[i]==0 ){. i
67b0: 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b 0a 20 f( zD[0]==0 ){.
67c0: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 cgi_printf(
67d0: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 "%*s<option valu
67e0: 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64 3e e=\"\" selected>
67f0: 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c </option>\
6800: 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c n",. in+2,
6810: 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b "");. }else{
6820: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 . cgi_print
6830: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 f("%*s<option va
6840: 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 lue=\"%h\" selec
6850: 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c ted>%h</option>\
6860: 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c n",. in+2,
6870: 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 "", zD, zD);.
6880: 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 }. }. while(
6890: 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b 2b 29 (zVal = *(az++)
68a0: 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 69 66 28 )!=0 ){. if(
68b0: 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20 20 20 20 zVal[0] ){.
68c0: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
68d0: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c s<option value=\
68e0: 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69 "%h\"%s>%h</opti
68f0: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 on>\n",.
6900: 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 in+2, "",.
6910: 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 zVal,.
6920: 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 strcmp(zVal, zD)
6930: 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 ? "" : " select
6940: 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 ed",. zVa
6950: 6c 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d l. );. }
6960: 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f else{. cgi_
6970: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 printf("%*s<opti
6980: 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25 73 3e on value=\"\"%s>
6990: 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c </option>\
69a0: 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 n",. in+2
69b0: 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 73 74 , "",. st
69c0: 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f rcmp(zVal, zD) ?
69d0: 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 "" : " selected
69e0: 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d ". );. }
69f0: 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74 . }. cgi_print
6a00: 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c f("%*s</select>\
6a10: 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a n", in, "");.}..
6a20: 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 /*.** This routi
6a30: 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74 20 6c ne works a lot l
6a40: 69 6b 65 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e ike cgi_v_option
6a50: 6d 65 6e 75 28 29 20 65 78 63 65 70 74 20 74 68 menu() except th
6a60: 61 74 20 74 68 65 20 6c 69 73 74 0a 2a 2a 20 69 at the list.** i
6a70: 73 20 61 20 6c 69 73 74 20 6f 66 20 70 61 69 72 s a list of pair
6a80: 73 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 6c s. The first el
6a90: 65 6d 65 6e 74 20 6f 66 20 65 61 63 68 20 70 61 ement of each pa
6aa0: 69 72 20 69 73 20 74 68 65 20 76 61 6c 75 65 20 ir is the value
6ab0: 75 73 65 64 0a 2a 2a 20 69 6e 74 65 72 6e 61 6c used.** internal
6ac0: 6c 79 20 61 6e 64 20 74 68 65 20 73 65 63 6f 6e ly and the secon
6ad0: 64 20 65 6c 65 6d 65 6e 74 20 69 73 20 74 68 65 d element is the
6ae0: 20 76 61 6c 75 65 20 64 69 73 70 6c 61 79 65 64 value displayed
6af0: 20 74 6f 20 74 68 65 20 75 73 65 72 2e 0a 2a 2f to the user..*/
6b00: 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74 69 .void cgi_v_opti
6b10: 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 6e 74 20 69 onmenu2(. int i
6b20: 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 n,
6b30: 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20 74 68 69 /* Indent by thi
6b40: 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f s amount */. co
6b50: 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 20 20 nst char *zP,
6b60: 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79 20 /* The query
6b70: 70 61 72 61 6d 65 74 65 72 20 6e 61 6d 65 20 2a parameter name *
6b80: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a /. const char *
6b90: 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44 65 66 61 zD, /* Defa
6ba0: 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20 63 ult value */. c
6bb0: 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 20 20 onst char **az
6bc0: 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d /* NULL-term
6bd0: 69 6e 61 74 65 64 20 6c 69 73 74 20 6f 66 20 61 inated list of a
6be0: 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 2a 2f llowed values */
6bf0: 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 .){. const char
6c00: 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 69 3b *zVal;. int i;
6c10: 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 . cgi_printf("%
6c20: 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 3d 31 *s<select size=1
6c30: 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 name=\"%s\">\n"
6c40: 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 , in, "", zP);.
6c50: 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b for(i=0; az[i];
6c60: 20 69 2b 3d 32 29 7b 0a 20 20 20 20 69 66 28 20 i+=2){. if(
6c70: 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a 44 29 strcmp(az[i],zD)
6c80: 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d ==0 ) break;. }
6c90: 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d 30 20 . if( az[i]==0
6ca0: 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b 30 5d ){. if( zD[0]
6cb0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 ==0 ){. cgi
6cc0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 _printf("%*s<opt
6cd0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 ion value=\"\" s
6ce0: 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f elected> </
6cf0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 option>\n",.
6d00: 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20 20 in+2, "");.
6d10: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 }else{. c
6d20: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f gi_printf("%*s<o
6d30: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 ption value=\"%h
6d40: 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 68 3c 2f \" selected>%h</
6d50: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 option>\n",.
6d60: 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c in+2, "", zD,
6d70: 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a zD);. }. }.
6d80: 20 20 77 68 69 6c 65 28 20 28 7a 56 61 6c 20 3d while( (zVal =
6d90: 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20 29 7b *(az++))!=0 ){
6da0: 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 . const char
6db0: 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a 2b 2b 29 *zName = *(az++)
6dc0: 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b ;. if( zName[
6dd0: 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 0] ){. cgi_
6de0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 printf("%*s<opti
6df0: 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 on value=\"%h\"%
6e00: 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 s>%h</option>\n"
6e10: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 ,. in+2,
6e20: 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c "",. zVal
6e30: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 ,. strcmp
6e40: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 (zVal, zD) ? ""
6e50: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 : " selected",.
6e60: 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 zName.
6e70: 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b );. }else{
6e80: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 . cgi_print
6e90: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 f("%*s<option va
6ea0: 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 26 6e 62 lue=\"%h\"%s>&nb
6eb0: 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c sp;</option>\n",
6ec0: 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 . in+2, "
6ed0: 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c ",. zVal,
6ee0: 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 . strcmp(
6ef0: 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a zVal, zD) ? "" :
6f00: 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 " selected".
6f10: 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a );. }. }.
6f20: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
6f30: 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 s</select>\n", i
6f40: 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a n, "");.}../*.**
6f50: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f This routine wo
6f60: 72 6b 73 20 6c 69 6b 65 20 22 70 72 69 6e 74 66 rks like "printf
6f70: 22 20 65 78 63 65 70 74 20 74 68 61 74 20 69 74 " except that it
6f80: 20 68 61 73 20 74 68 65 0a 2a 2a 20 65 78 74 72 has the.** extr
6f90: 61 20 66 6f 72 6d 61 74 74 69 6e 67 20 63 61 70 a formatting cap
6fa0: 61 62 69 6c 69 74 69 65 73 20 73 75 63 68 20 61 abilities such a
6fb0: 73 20 25 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a s %h and %t..*/.
6fc0: 76 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 66 28 void cgi_printf(
6fd0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 const char *zFor
6fe0: 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f mat, ...){. va_
6ff0: 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 list ap;. va_st
7000: 61 72 74 28 61 70 2c 7a 46 6f 72 6d 61 74 29 3b art(ap,zFormat);
7010: 0a 20 20 76 78 70 72 69 6e 74 66 28 70 43 6f 6e . vxprintf(pCon
7020: 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 tent,zFormat,ap)
7030: 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a ;. va_end(ap);.
7040: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f }../*.** This ro
7050: 75 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69 6b 65 utine works like
7060: 20 22 76 70 72 69 6e 74 66 22 20 65 78 63 65 70 "vprintf" excep
7070: 74 20 74 68 61 74 20 69 74 20 68 61 73 20 74 68 t that it has th
7080: 65 0a 2a 2a 20 65 78 74 72 61 20 66 6f 72 6d 61 e.** extra forma
7090: 74 74 69 6e 67 20 63 61 70 61 62 69 6c 69 74 69 tting capabiliti
70a0: 65 73 20 73 75 63 68 20 61 73 20 25 68 20 61 6e es such as %h an
70b0: 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 d %t..*/.void cg
70c0: 69 5f 76 70 72 69 6e 74 66 28 63 6f 6e 73 74 20 i_vprintf(const
70d0: 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 76 char *zFormat, v
70e0: 61 5f 6c 69 73 74 20 61 70 29 7b 0a 20 20 76 78 a_list ap){. vx
70f0: 70 72 69 6e 74 66 28 70 43 6f 6e 74 65 6e 74 2c printf(pContent,
7100: 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 7d 0a 0a zFormat,ap);.}..
7110: 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20 72 65 ./*.** Send a re
7120: 70 6c 79 20 69 6e 64 69 63 61 74 69 6e 67 20 74 ply indicating t
7130: 68 61 74 20 74 68 65 20 48 54 54 50 20 72 65 71 hat the HTTP req
7140: 75 65 73 74 20 77 61 73 20 6d 61 6c 66 6f 72 6d uest was malform
7150: 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 ed.*/.static voi
7160: 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 d malformed_requ
7170: 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 63 67 69 est(void){. cgi
7180: 5f 73 65 74 5f 73 74 61 74 75 73 28 35 30 31 2c _set_status(501,
7190: 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e 74 65 "Not Implemente
71a0: 64 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 d");. cgi_print
71b0: 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 f(. "<html><b
71c0: 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69 7a 65 64 ody>Unrecognized
71d0: 20 48 54 54 50 20 52 65 71 75 65 73 74 3c 2f 62 HTTP Request</b
71e0: 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e 22 0a 20 ody></html>\n".
71f0: 20 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 );. cgi_reply(
7200: 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a );. exit(0);.}.
7210: 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 61 6e 64 ./*.** Panic and
7220: 20 64 69 65 20 77 68 69 6c 65 20 70 72 6f 63 65 die while proce
7230: 73 73 69 6e 67 20 61 20 77 65 62 70 61 67 65 2e ssing a webpage.
7240: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 61 6e .*/.void cgi_pan
7250: 69 63 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a ic(const char *z
7260: 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 Format, ...){.
7270: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 67 va_list ap;. cg
7280: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 i_reset_content(
7290: 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 );. cgi_set_sta
72a0: 74 75 73 28 35 30 30 2c 20 22 49 6e 74 65 72 6e tus(500, "Intern
72b0: 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72 22 al Server Error"
72c0: 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 );. cgi_printf(
72d0: 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 6f 64 . "<html><bod
72e0: 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 6c 20 53 y><h1>Internal S
72f0: 65 72 76 65 72 20 45 72 72 6f 72 3c 2f 68 31 3e erver Error</h1>
7300: 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61 69 6e 74 \n". "<plaint
7310: 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20 76 61 5f ext>". );. va_
7320: 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 start(ap, zForma
7330: 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 70 t);. vxprintf(p
7340: 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c Content,zFormat,
7350: 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 ap);. va_end(ap
7360: 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 );. cgi_reply()
7370: 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a 0a ;. exit(1);.}..
7380: 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 /*.** Remove the
7390: 20 66 69 72 73 74 20 73 70 61 63 65 2d 64 65 6c first space-del
73a0: 69 6d 69 74 65 64 20 74 6f 6b 65 6e 20 66 72 6f imited token fro
73b0: 6d 20 61 20 73 74 72 69 6e 67 20 61 6e 64 20 72 m a string and r
73c0: 65 74 75 72 6e 0a 2a 2a 20 61 20 70 6f 69 6e 74 eturn.** a point
73d0: 65 72 20 74 6f 20 69 74 2e 20 20 41 64 64 20 61 er to it. Add a
73e0: 20 4e 55 4c 4c 20 74 6f 20 74 68 65 20 73 74 72 NULL to the str
73f0: 69 6e 67 20 74 6f 20 74 65 72 6d 69 6e 61 74 65 ing to terminate
7400: 20 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 4d the token..** M
7410: 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 72 20 70 ake *zLeftOver p
7420: 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72 oint to the star
7430: 74 20 6f 66 20 74 68 65 20 6e 65 78 74 20 74 6f t of the next to
7440: 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 ken..*/.static c
7450: 68 61 72 20 2a 65 78 74 72 61 63 74 5f 74 6f 6b har *extract_tok
7460: 65 6e 28 63 68 61 72 20 2a 7a 49 6e 70 75 74 2c en(char *zInput,
7470: 20 63 68 61 72 20 2a 2a 7a 4c 65 66 74 4f 76 65 char **zLeftOve
7480: 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65 73 r){. char *zRes
7490: 75 6c 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 7a ult = 0;. if( z
74a0: 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20 20 Input==0 ){.
74b0: 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 20 29 20 if( zLeftOver )
74c0: 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 30 3b 0a *zLeftOver = 0;.
74d0: 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 return 0;.
74e0: 7d 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 }. while( isspa
74f0: 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a ce(*zInput) ){ z
7500: 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a 52 65 Input++; }. zRe
7510: 73 75 6c 74 20 3d 20 7a 49 6e 70 75 74 3b 0a 20 sult = zInput;.
7520: 20 77 68 69 6c 65 28 20 2a 7a 49 6e 70 75 74 20 while( *zInput
7530: 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a 49 6e && !isspace(*zIn
7540: 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b put) ){ zInput++
7550: 3b 20 7d 0a 20 20 69 66 28 20 2a 7a 49 6e 70 75 ; }. if( *zInpu
7560: 74 20 29 7b 0a 20 20 20 20 2a 7a 49 6e 70 75 74 t ){. *zInput
7570: 20 3d 20 30 3b 0a 20 20 20 20 7a 49 6e 70 75 74 = 0;. zInput
7580: 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 ++;. while( i
7590: 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 sspace(*zInput)
75a0: 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 ){ zInput++; }.
75b0: 20 7d 0a 20 20 69 66 28 20 7a 4c 65 66 74 4f 76 }. if( zLeftOv
75c0: 65 72 20 29 7b 20 2a 7a 4c 65 66 74 4f 76 65 72 er ){ *zLeftOver
75d0: 20 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a 20 20 72 = zInput; }. r
75e0: 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a 7d eturn zResult;.}
75f0: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 ../*.** This rou
7600: 74 69 6e 65 20 68 61 6e 64 6c 65 73 20 61 20 73 tine handles a s
7610: 69 6e 67 6c 65 20 48 54 54 50 20 72 65 71 75 65 ingle HTTP reque
7620: 73 74 20 77 68 69 63 68 20 69 73 20 63 6f 6d 69 st which is comi
7630: 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74 61 6e ng in on.** stan
7640: 64 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20 77 dard input and w
7650: 68 69 63 68 20 72 65 70 6c 69 65 73 20 6f 6e 20 hich replies on
7660: 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e standard output.
7670: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 54 50 20 .**.** The HTTP
7680: 72 65 71 75 65 73 74 20 69 73 20 72 65 61 64 20 request is read
7690: 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 20 69 6e from standard in
76a0: 70 75 74 20 61 6e 64 20 69 73 20 75 73 65 64 20 put and is used
76b0: 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 0a 2a 2a to initialize.**
76c0: 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 environment var
76d0: 69 61 62 6c 65 73 20 61 73 20 70 65 72 20 43 47 iables as per CG
76e0: 49 2e 20 20 54 68 65 20 63 67 69 5f 69 6e 69 74 I. The cgi_init
76f0: 28 29 20 72 6f 75 74 69 6e 65 20 74 6f 20 63 6f () routine to co
7700: 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 65 20 73 65 mplete.** the se
7710: 74 75 70 2e 20 20 4f 6e 63 65 20 61 6c 6c 20 74 tup. Once all t
7720: 68 65 20 73 65 74 75 70 20 69 73 20 66 69 6e 69 he setup is fini
7730: 73 68 65 64 2c 20 74 68 69 73 20 70 72 6f 63 65 shed, this proce
7740: 64 75 72 65 20 72 65 74 75 72 6e 73 0a 2a 2a 20 dure returns.**
7750: 61 6e 64 20 73 75 62 73 65 71 75 65 6e 74 20 63 and subsequent c
7760: 6f 64 65 20 68 61 6e 64 6c 65 73 20 74 68 65 20 ode handles the
7770: 61 63 74 75 61 6c 20 67 65 6e 65 72 61 74 69 6f actual generatio
7780: 6e 20 6f 66 20 74 68 65 20 77 65 62 70 61 67 65 n of the webpage
7790: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 61 ..*/.void cgi_ha
77a0: 6e 64 6c 65 5f 68 74 74 70 5f 72 65 71 75 65 73 ndle_http_reques
77b0: 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 72 20 t(void){. char
77c0: 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 20 69 *z, *zToken;. i
77d0: 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 74 20 73 nt i;. struct s
77e0: 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 6d 6f 74 ockaddr_in remot
77f0: 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 5f 74 20 eName;. size_t
7800: 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 28 73 74 size = sizeof(st
7810: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e ruct sockaddr_in
7820: 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 6e 65 5b );. char zLine[
7830: 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a 20 41 20 2000]; /* A
7840: 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 69 single line of i
7850: 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 66 75 6c 6c nput. */.. full
7860: 48 74 74 70 52 65 70 6c 79 20 3d 20 31 3b 0a 20 HttpReply = 1;.
7870: 20 69 66 28 20 66 67 65 74 73 28 7a 4c 69 6e 65 if( fgets(zLine
7880: 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c , sizeof(zLine),
7890: 20 73 74 64 69 6e 29 3d 3d 30 20 29 7b 0a 20 20 stdin)==0 ){.
78a0: 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 malformed_requ
78b0: 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 7a 54 6f est();. }. zTo
78c0: 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 5f 74 6f ken = extract_to
78d0: 6b 65 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29 3b 0a ken(zLine, &z);.
78e0: 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 20 if( zToken==0
78f0: 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 ){. malformed
7900: 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a _request();. }.
7910: 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54 6f if( strcmp(zTo
7920: 6b 65 6e 2c 22 47 45 54 22 29 21 3d 30 20 26 26 ken,"GET")!=0 &&
7930: 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22 strcmp(zToken,"
7940: 50 4f 53 54 22 29 21 3d 30 0a 20 20 20 20 20 20 POST")!=0.
7950: 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e && strcmp(zToken
7960: 2c 22 48 45 41 44 22 29 21 3d 30 20 29 7b 0a 20 ,"HEAD")!=0 ){.
7970: 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 malformed_req
7980: 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 63 67 uest();. }. cg
7990: 69 5f 73 65 74 65 6e 76 28 22 47 41 54 45 57 41 i_setenv("GATEWA
79a0: 59 5f 49 4e 54 45 52 46 41 43 45 22 2c 22 43 47 Y_INTERFACE","CG
79b0: 49 2f 31 2e 30 22 29 3b 0a 20 20 63 67 69 5f 73 I/1.0");. cgi_s
79c0: 65 74 65 6e 76 28 22 52 45 51 55 45 53 54 5f 4d etenv("REQUEST_M
79d0: 45 54 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29 3b 0a ETHOD",zToken);.
79e0: 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61 zToken = extra
79f0: 63 74 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a 29 3b ct_token(z, &z);
7a00: 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 . if( zToken==0
7a10: 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 ){. malforme
7a20: 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d d_request();. }
7a30: 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 . cgi_setenv("R
7a40: 45 51 55 45 53 54 5f 55 52 49 22 2c 20 7a 54 6f EQUEST_URI", zTo
7a50: 6b 65 6e 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b ken);. for(i=0;
7a60: 20 7a 54 6f 6b 65 6e 5b 69 5d 20 26 26 20 7a 54 zToken[i] && zT
7a70: 6f 6b 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20 69 2b oken[i]!='?'; i+
7a80: 2b 29 7b 7d 0a 20 20 69 66 28 20 7a 54 6f 6b 65 +){}. if( zToke
7a90: 6e 5b 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b 69 2b n[i] ) zToken[i+
7aa0: 2b 5d 20 3d 20 30 3b 0a 20 20 63 67 69 5f 73 65 +] = 0;. cgi_se
7ab0: 74 65 6e 76 28 22 50 41 54 48 5f 49 4e 46 4f 22 tenv("PATH_INFO"
7ac0: 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63 67 69 , zToken);. cgi
7ad0: 5f 73 65 74 65 6e 76 28 22 51 55 45 52 59 5f 53 _setenv("QUERY_S
7ae0: 54 52 49 4e 47 22 2c 20 26 7a 54 6f 6b 65 6e 5b TRING", &zToken[
7af0: 69 5d 29 3b 0a 20 20 69 66 28 20 67 65 74 70 65 i]);. if( getpe
7b00: 65 72 6e 61 6d 65 28 66 69 6c 65 6e 6f 28 73 74 ername(fileno(st
7b10: 64 69 6e 29 2c 20 28 73 74 72 75 63 74 20 73 6f din), (struct so
7b20: 63 6b 61 64 64 72 2a 29 26 72 65 6d 6f 74 65 4e ckaddr*)&remoteN
7b30: 61 6d 65 2c 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a ame, (socklen_t*
7b40: 29 26 73 69 7a 65 29 3e 3d 30 20 29 7b 0a 20 20 )&size)>=0 ){.
7b50: 20 20 63 68 61 72 20 2a 7a 49 70 41 64 64 72 20 char *zIpAddr
7b60: 3d 20 69 6e 65 74 5f 6e 74 6f 61 28 72 65 6d 6f = inet_ntoa(remo
7b70: 74 65 4e 61 6d 65 2e 73 69 6e 5f 61 64 64 72 29 teName.sin_addr)
7b80: 3b 0a 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 ;. cgi_setenv
7b90: 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 22 2c 20 ("REMOTE_ADDR",
7ba0: 7a 49 70 41 64 64 72 29 3b 0a 0a 20 20 20 20 2f zIpAddr);.. /
7bb0: 2a 20 53 65 74 20 74 68 65 20 47 6c 6f 62 61 6c * Set the Global
7bc0: 2e 7a 49 70 41 64 64 72 20 76 61 72 69 61 62 6c .zIpAddr variabl
7bd0: 65 20 74 6f 20 74 68 65 20 73 65 72 76 65 72 20 e to the server
7be0: 77 65 20 61 72 65 20 74 61 6c 6b 69 6e 67 20 74 we are talking t
7bf0: 6f 2e 0a 20 20 20 20 2a 2a 20 54 68 69 73 20 69 o.. ** This i
7c00: 73 20 75 73 65 64 20 74 6f 20 70 6f 70 75 6c 61 s used to popula
7c10: 74 65 20 74 68 65 20 69 70 61 64 64 72 20 63 6f te the ipaddr co
7c20: 6c 75 6d 6e 20 6f 66 20 74 68 65 20 72 63 76 66 lumn of the rcvf
7c30: 72 6f 6d 20 74 61 62 6c 65 2c 0a 20 20 20 20 2a rom table,. *
7c40: 2a 20 69 66 20 61 6e 79 20 66 69 6c 65 73 20 61 * if any files a
7c50: 72 65 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d re received from
7c60: 20 74 68 65 20 63 6f 6e 6e 65 63 74 65 64 20 63 the connected c
7c70: 6c 69 65 6e 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 lient.. */.
7c80: 20 20 67 2e 7a 49 70 41 64 64 72 20 3d 20 6d 70 g.zIpAddr = mp
7c90: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 49 70 41 rintf("%s", zIpA
7ca0: 64 64 72 29 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a ddr);. }. . /*
7cb0: 20 47 65 74 20 61 6c 6c 20 74 68 65 20 6f 70 74 Get all the opt
7cc0: 69 6f 6e 61 6c 20 66 69 65 6c 64 73 20 74 68 61 ional fields tha
7cd0: 74 20 66 6f 6c 6c 6f 77 20 74 68 65 20 66 69 72 t follow the fir
7ce0: 73 74 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20 st line.. */.
7cf0: 77 68 69 6c 65 28 20 66 67 65 74 73 28 7a 4c 69 while( fgets(zLi
7d00: 6e 65 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 ne,sizeof(zLine)
7d10: 2c 73 74 64 69 6e 29 20 29 7b 0a 20 20 20 20 63 ,stdin) ){. c
7d20: 68 61 72 20 2a 7a 46 69 65 6c 64 4e 61 6d 65 3b har *zFieldName;
7d30: 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 3b . char *zVal;
7d40: 0a 0a 20 20 20 20 7a 46 69 65 6c 64 4e 61 6d 65 .. zFieldName
7d50: 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e = extract_token
7d60: 28 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b 0a 20 (zLine,&zVal);.
7d70: 20 20 20 69 66 28 20 7a 46 69 65 6c 64 4e 61 6d if( zFieldNam
7d80: 65 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c 64 4e e==0 || *zFieldN
7d90: 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a ame==0 ) break;.
7da0: 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 while( isspa
7db0: 63 65 28 2a 7a 56 61 6c 29 20 29 7b 20 7a 56 61 ce(*zVal) ){ zVa
7dc0: 6c 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 3d 20 73 l++; }. i = s
7dd0: 74 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20 20 20 trlen(zVal);.
7de0: 20 77 68 69 6c 65 28 20 69 3e 30 20 26 26 20 69 while( i>0 && i
7df0: 73 73 70 61 63 65 28 7a 56 61 6c 5b 69 2d 31 5d sspace(zVal[i-1]
7e00: 29 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20 20 20 ) ){ i--; }.
7e10: 7a 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 zVal[i] = 0;.
7e20: 20 66 6f 72 28 69 3d 30 3b 20 7a 46 69 65 6c 64 for(i=0; zField
7e30: 4e 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b 20 7a Name[i]; i++){ z
7e40: 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d 20 74 FieldName[i] = t
7e50: 6f 6c 6f 77 65 72 28 7a 46 69 65 6c 64 4e 61 6d olower(zFieldNam
7e60: 65 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 69 66 28 e[i]); }. if(
7e70: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 strcmp(zFieldNa
7e80: 6d 65 2c 22 75 73 65 72 2d 61 67 65 6e 74 3a 22 me,"user-agent:"
7e90: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 )==0 ){. cg
7ea0: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 55 i_setenv("HTTP_U
7eb0: 53 45 52 5f 41 47 45 4e 54 22 2c 20 7a 56 61 6c SER_AGENT", zVal
7ec0: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 );. }else if(
7ed0: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 strcmp(zFieldNa
7ee0: 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65 6e 67 me,"content-leng
7ef0: 74 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 th:")==0 ){.
7f00: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f cgi_setenv("CO
7f10: 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 7a NTENT_LENGTH", z
7f20: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 Val);. }else
7f30: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c if( strcmp(zFiel
7f40: 64 4e 61 6d 65 2c 22 72 65 66 65 72 65 72 3a 22 dName,"referer:"
7f50: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 )==0 ){. cg
7f60: 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 52 i_setenv("HTTP_R
7f70: 45 46 45 52 45 52 22 2c 20 7a 56 61 6c 29 3b 0a EFERER", zVal);.
7f80: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 }else if( st
7f90: 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c rcmp(zFieldName,
7fa0: 22 68 6f 73 74 3a 22 29 3d 3d 30 20 29 7b 0a 20 "host:")==0 ){.
7fb0: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 cgi_setenv(
7fc0: 22 48 54 54 50 5f 48 4f 53 54 22 2c 20 7a 56 61 "HTTP_HOST", zVa
7fd0: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 l);. }else if
7fe0: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e ( strcmp(zFieldN
7ff0: 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 ame,"content-typ
8000: 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 e:")==0 ){.
8010: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f 4e cgi_setenv("CON
8020: 54 45 4e 54 5f 54 59 50 45 22 2c 20 7a 56 61 6c TENT_TYPE", zVal
8030: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 );. }else if(
8040: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 strcmp(zFieldNa
8050: 6d 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d 3d 30 me,"cookie:")==0
8060: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 ){. cgi_se
8070: 74 65 6e 76 28 22 48 54 54 50 5f 43 4f 4f 4b 49 tenv("HTTP_COOKI
8080: 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d E", zVal);. }
8090: 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 else if( strcmp(
80a0: 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d 6e zFieldName,"if-n
80b0: 6f 6e 65 2d 6d 61 74 63 68 3a 22 29 3d 3d 30 20 one-match:")==0
80c0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 ){. cgi_set
80d0: 65 6e 76 28 22 48 54 54 50 5f 49 46 5f 4e 4f 4e env("HTTP_IF_NON
80e0: 45 5f 4d 41 54 43 48 22 2c 20 7a 56 61 6c 29 3b E_MATCH", 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 69 66 2d 6d 6f 64 69 66 69 65 64 2d 73 69 ,"if-modified-si
8120: 6e 63 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 nce:")==0 ){.
8130: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48 cgi_setenv("H
8140: 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f TTP_IF_MODIFIED_
8150: 53 49 4e 43 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 SINCE", zVal);.
8160: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 67 69 5f }. }.. cgi_
8170: 69 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a init();.}../*.**
8180: 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 Maximum number
8190: 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 of child process
81a0: 65 73 20 74 68 61 74 20 77 65 20 63 61 6e 20 68 es that we can h
81b0: 61 76 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20 61 ave running.** a
81c0: 74 20 6f 6e 65 20 74 69 6d 65 20 62 65 66 6f 72 t one time befor
81d0: 65 20 77 65 20 73 74 61 72 74 20 73 6c 6f 77 69 e we start slowi
81e0: 6e 67 20 74 68 69 6e 67 73 20 64 6f 77 6e 2e 0a ng things down..
81f0: 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 41 58 5f 50 */.#define MAX_P
8200: 41 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a 2a 2a ARALLEL 2../*.**
8210: 20 49 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 48 54 Implement an HT
8220: 54 50 20 73 65 72 76 65 72 20 64 61 65 6d 6f 6e TP server daemon
8230: 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20 70 6f listening on po
8240: 72 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 rt iPort..**.**
8250: 41 73 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f As new connectio
8260: 6e 73 20 61 72 72 69 76 65 2c 20 66 6f 72 6b 20 ns arrive, fork
8270: 61 20 63 68 69 6c 64 20 61 6e 64 20 6c 65 74 20 a child and let
8280: 63 68 69 6c 64 20 72 65 74 75 72 6e 0a 2a 2a 20 child return.**
8290: 6f 75 74 20 6f 66 20 74 68 69 73 20 70 72 6f 63 out of this proc
82a0: 65 64 75 72 65 20 63 61 6c 6c 2e 20 20 54 68 65 edure call. The
82b0: 20 63 68 69 6c 64 20 77 69 6c 6c 20 68 61 6e 64 child will hand
82c0: 6c 65 20 74 68 65 20 72 65 71 75 65 73 74 2e 0a le the request..
82d0: 2a 2a 20 54 68 65 20 70 61 72 65 6e 74 20 6e 65 ** The parent ne
82e0: 76 65 72 20 72 65 74 75 72 6e 73 20 66 72 6f 6d ver returns from
82f0: 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 2e this procedure.
8300: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 74 74 .*/.void cgi_htt
8310: 70 5f 73 65 72 76 65 72 28 69 6e 74 20 69 50 6f p_server(int iPo
8320: 72 74 29 7b 0a 23 69 66 64 65 66 20 5f 5f 4d 49 rt){.#ifdef __MI
8330: 4e 47 57 33 32 5f 5f 0a 20 20 66 70 72 69 6e 74 NGW32__. fprint
8340: 66 28 73 74 64 65 72 72 2c 22 73 65 72 76 65 72 f(stderr,"server
8350: 20 6e 6f 74 20 79 65 74 20 61 76 61 69 6c 61 62 not yet availab
8360: 6c 65 20 69 6e 20 77 69 6e 64 6f 77 73 20 76 65 le in windows ve
8370: 72 73 69 6f 6e 20 6f 66 20 66 6f 73 73 69 6c 5c rsion of fossil\
8380: 6e 22 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a n");. exit(1);.
8390: 23 65 6c 73 65 0a 20 20 69 6e 74 20 6c 69 73 74 #else. int list
83a0: 65 6e 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 ener;
83b0: 20 20 20 20 20 2f 2a 20 54 68 65 20 73 65 72 76 /* The serv
83c0: 65 72 20 73 6f 63 6b 65 74 20 2a 2f 0a 20 20 69 er socket */. i
83d0: 6e 74 20 63 6f 6e 6e 65 63 74 69 6f 6e 3b 20 20 nt connection;
83e0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 /* A
83f0: 20 73 6f 63 6b 65 74 20 66 6f 72 20 65 61 63 68 socket for each
8400: 20 69 6e 64 69 76 69 64 75 61 6c 20 63 6f 6e 6e individual conn
8410: 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 64 5f 73 ection */. fd_s
8420: 65 74 20 72 65 61 64 66 64 73 3b 20 20 20 20 20 et readfds;
8430: 20 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20 /* Set
8440: 6f 66 20 66 69 6c 65 20 64 65 73 63 72 69 70 74 of file descript
8450: 6f 72 73 20 66 6f 72 20 73 65 6c 65 63 74 28 29 ors for select()
8460: 20 2a 2f 0a 20 20 73 69 7a 65 5f 74 20 6c 65 6e */. size_t len
8470: 61 64 64 72 3b 20 20 20 20 20 20 20 20 20 20 20 addr;
8480: 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 /* Length of
8490: 74 68 65 20 69 6e 61 64 64 72 20 73 74 72 75 63 the inaddr struc
84a0: 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20 63 68 ture */. int ch
84b0: 69 6c 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 ild;
84c0: 20 20 20 20 20 20 20 2f 2a 20 50 49 44 20 6f 66 /* PID of
84d0: 20 74 68 65 20 63 68 69 6c 64 20 70 72 6f 63 65 the child proce
84e0: 73 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 63 68 69 ss */. int nchi
84f0: 6c 64 72 65 6e 20 3d 20 30 3b 20 20 20 20 20 20 ldren = 0;
8500: 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f /* Number o
8510: 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 65 f child processe
8520: 73 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 74 69 s */. struct ti
8530: 6d 65 76 61 6c 20 64 65 6c 61 79 3b 20 20 20 20 meval delay;
8540: 20 20 20 20 2f 2a 20 48 6f 77 20 6c 6f 6e 67 20 /* How long
8550: 74 6f 20 77 61 69 74 20 69 6e 73 69 64 65 20 73 to wait inside s
8560: 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 73 74 72 elect() */. str
8570: 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20 uct sockaddr_in
8580: 69 6e 61 64 64 72 3b 20 20 20 2f 2a 20 54 68 65 inaddr; /* The
8590: 20 73 6f 63 6b 65 74 20 61 64 64 72 65 73 73 20 socket address
85a0: 2a 2f 0a 20 20 69 6e 74 20 6f 70 74 20 3d 20 31 */. int opt = 1
85b0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ;
85c0: 20 20 2f 2a 20 73 65 74 73 6f 63 6b 6f 70 74 20 /* setsockopt
85d0: 66 6c 61 67 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 flag */.. memse
85e0: 74 28 26 69 6e 61 64 64 72 2c 20 30 2c 20 73 69 t(&inaddr, 0, si
85f0: 7a 65 6f 66 28 69 6e 61 64 64 72 29 29 3b 0a 20 zeof(inaddr));.
8600: 20 69 6e 61 64 64 72 2e 73 69 6e 5f 66 61 6d 69 inaddr.sin_fami
8610: 6c 79 20 3d 20 41 46 5f 49 4e 45 54 3b 0a 20 20 ly = AF_INET;.
8620: 69 6e 61 64 64 72 2e 73 69 6e 5f 61 64 64 72 2e inaddr.sin_addr.
8630: 73 5f 61 64 64 72 20 3d 20 49 4e 41 44 44 52 5f s_addr = INADDR_
8640: 41 4e 59 3b 0a 20 20 69 6e 61 64 64 72 2e 73 69 ANY;. inaddr.si
8650: 6e 5f 70 6f 72 74 20 3d 20 68 74 6f 6e 73 28 69 n_port = htons(i
8660: 50 6f 72 74 29 3b 0a 20 20 6c 69 73 74 65 6e 65 Port);. listene
8670: 72 20 3d 20 73 6f 63 6b 65 74 28 41 46 5f 49 4e r = socket(AF_IN
8680: 45 54 2c 20 53 4f 43 4b 5f 53 54 52 45 41 4d 2c ET, SOCK_STREAM,
8690: 20 30 29 3b 0a 20 20 69 66 28 20 6c 69 73 74 65 0);. if( liste
86a0: 6e 65 72 3c 30 20 29 7b 0a 20 20 20 20 66 70 72 ner<0 ){. fpr
86b0: 69 6e 74 66 28 73 74 64 65 72 72 2c 22 43 61 6e intf(stderr,"Can
86c0: 27 74 20 63 72 65 61 74 65 20 61 20 73 6f 63 6b 't create a sock
86d0: 65 74 5c 6e 22 29 3b 0a 20 20 20 20 65 78 69 74 et\n");. exit
86e0: 28 31 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 69 (1);. }.. /* i
86f0: 66 20 77 65 20 63 61 6e 27 74 20 74 65 72 6d 69 f we can't termi
8700: 6e 61 74 65 20 6e 69 63 65 6c 79 2c 20 61 74 20 nate nicely, at
8710: 6c 65 61 73 74 20 61 6c 6c 6f 77 20 74 68 65 20 least allow the
8720: 73 6f 63 6b 65 74 20 74 6f 20 62 65 20 72 65 75 socket to be reu
8730: 73 65 64 20 2a 2f 0a 20 20 73 65 74 73 6f 63 6b sed */. setsock
8740: 6f 70 74 28 6c 69 73 74 65 6e 65 72 2c 53 4f 4c opt(listener,SOL
8750: 5f 53 4f 43 4b 45 54 2c 53 4f 5f 52 45 55 53 45 _SOCKET,SO_REUSE
8760: 41 44 44 52 2c 26 6f 70 74 2c 73 69 7a 65 6f 66 ADDR,&opt,sizeof
8770: 28 6f 70 74 29 29 3b 0a 0a 20 20 69 66 28 20 62 (opt));.. if( b
8780: 69 6e 64 28 6c 69 73 74 65 6e 65 72 2c 20 28 73 ind(listener, (s
8790: 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 truct sockaddr*)
87a0: 26 69 6e 61 64 64 72 2c 20 73 69 7a 65 6f 66 28 &inaddr, sizeof(
87b0: 69 6e 61 64 64 72 29 29 3c 30 20 29 7b 0a 20 20 inaddr))<0 ){.
87c0: 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 fprintf(stderr
87d0: 2c 22 43 61 6e 27 74 20 62 69 6e 64 20 74 6f 20 ,"Can't bind to
87e0: 70 6f 72 74 20 25 64 5c 6e 22 2c 20 69 50 6f 72 port %d\n", iPor
87f0: 74 29 3b 0a 20 20 20 20 65 78 69 74 28 31 29 3b t);. exit(1);
8800: 0a 20 20 7d 0a 20 20 6c 69 73 74 65 6e 28 6c 69 . }. listen(li
8810: 73 74 65 6e 65 72 2c 31 30 29 3b 0a 20 20 77 68 stener,10);. wh
8820: 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 69 66 ile( 1 ){. if
8830: 28 20 6e 63 68 69 6c 64 72 65 6e 3e 4d 41 58 5f ( nchildren>MAX_
8840: 50 41 52 41 4c 4c 45 4c 20 29 7b 0a 20 20 20 20 PARALLEL ){.
8850: 20 20 2f 2a 20 53 6c 6f 77 20 64 6f 77 6e 20 69 /* Slow down i
8860: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72 f connections ar
8870: 65 20 61 72 72 69 76 69 6e 67 20 74 6f 6f 20 66 e arriving too f
8880: 61 73 74 20 2a 2f 0a 20 20 20 20 20 20 73 6c 65 ast */. sle
8890: 65 70 28 20 6e 63 68 69 6c 64 72 65 6e 2d 4d 41 ep( nchildren-MA
88a0: 58 5f 50 41 52 41 4c 4c 45 4c 20 29 3b 0a 20 20 X_PARALLEL );.
88b0: 20 20 7d 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 }. delay.tv
88c0: 5f 73 65 63 20 3d 20 36 30 3b 0a 20 20 20 20 64 _sec = 60;. d
88d0: 65 6c 61 79 2e 74 76 5f 75 73 65 63 20 3d 20 30 elay.tv_usec = 0
88e0: 3b 0a 20 20 20 20 46 44 5f 5a 45 52 4f 28 26 72 ;. FD_ZERO(&r
88f0: 65 61 64 66 64 73 29 3b 0a 20 20 20 20 46 44 5f eadfds);. FD_
8900: 53 45 54 28 20 6c 69 73 74 65 6e 65 72 2c 20 26 SET( listener, &
8910: 72 65 61 64 66 64 73 29 3b 0a 20 20 20 20 69 66 readfds);. if
8920: 28 20 73 65 6c 65 63 74 28 20 6c 69 73 74 65 6e ( select( listen
8930: 65 72 2b 31 2c 20 26 72 65 61 64 66 64 73 2c 20 er+1, &readfds,
8940: 30 2c 20 30 2c 20 26 64 65 6c 61 79 29 20 29 7b 0, 0, &delay) ){
8950: 0a 20 20 20 20 20 20 6c 65 6e 61 64 64 72 20 3d . lenaddr =
8960: 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 3b sizeof(inaddr);
8970: 0a 20 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f . connectio
8980: 6e 20 3d 20 61 63 63 65 70 74 28 6c 69 73 74 65 n = accept(liste
8990: 6e 65 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63 ner, (struct soc
89a0: 6b 61 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 20 kaddr*)&inaddr,
89b0: 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 20 26 6c 65 (socklen_t*) &le
89c0: 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20 69 66 naddr);. if
89d0: 28 20 63 6f 6e 6e 65 63 74 69 6f 6e 3e 3d 30 20 ( connection>=0
89e0: 29 7b 0a 20 20 20 20 20 20 20 20 63 68 69 6c 64 ){. child
89f0: 20 3d 20 66 6f 72 6b 28 29 3b 0a 20 20 20 20 20 = fork();.
8a00: 20 20 20 69 66 28 20 63 68 69 6c 64 21 3d 30 20 if( child!=0
8a10: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 ){. if(
8a20: 20 63 68 69 6c 64 3e 30 20 29 20 6e 63 68 69 6c child>0 ) nchil
8a30: 64 72 65 6e 2b 2b 3b 0a 20 20 20 20 20 20 20 20 dren++;.
8a40: 20 20 63 6c 6f 73 65 28 63 6f 6e 6e 65 63 74 69 close(connecti
8a50: 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c on);. }el
8a60: 73 65 7b 0a 20 20 20 20 20 20 20 20 20 20 63 6c se{. cl
8a70: 6f 73 65 28 30 29 3b 0a 20 20 20 20 20 20 20 20 ose(0);.
8a80: 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e dup(connection
8a90: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f );. clo
8aa0: 73 65 28 31 29 3b 0a 20 20 20 20 20 20 20 20 20 se(1);.
8ab0: 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 dup(connection)
8ac0: 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 ;. if(
8ad0: 21 67 2e 66 48 74 74 70 54 72 61 63 65 20 29 7b !g.fHttpTrace ){
8ae0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 6c 6f . clo
8af0: 73 65 28 32 29 3b 0a 20 20 20 20 20 20 20 20 20 se(2);.
8b00: 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f dup(connectio
8b10: 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a n);. }.
8b20: 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 close(
8b30: 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 connection);.
8b40: 20 20 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 return;.
8b50: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d }. }
8b60: 0a 20 20 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75 . }. /* Bu
8b70: 72 79 20 64 65 61 64 20 63 68 69 6c 64 72 65 6e ry dead children
8b80: 20 2a 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 77 */. while( w
8b90: 61 69 74 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f aitpid(0, 0, WNO
8ba0: 48 41 4e 47 29 3e 30 20 29 7b 0a 20 20 20 20 20 HANG)>0 ){.
8bb0: 20 6e 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20 nchildren--;.
8bc0: 20 20 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54 }. }. /* NOT
8bd0: 20 52 45 41 43 48 45 44 20 2a 2f 20 20 0a 20 20 REACHED */ .
8be0: 65 78 69 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a exit(1);.#endif.
8bf0: 7d 0a 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66 }../*.** Name of
8c00: 20 64 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73 days and months
8c10: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 ..*/.static cons
8c20: 74 20 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d t char *azDays[]
8c30: 20 3d 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22 =. {"Sun", "
8c40: 4d 6f 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65 Mon", "Tue", "We
8c50: 64 22 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22 d", "Thu", "Fri"
8c60: 2c 20 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61 , "Sat", 0};.sta
8c70: 74 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a tic const char *
8c80: 61 7a 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20 azMonths[] =.
8c90: 20 7b 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20 {"Jan", "Feb",
8ca0: 22 4d 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d "Mar", "Apr", "M
8cb0: 61 79 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20 ay", "Jun",.
8cc0: 20 22 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22 "Jul", "Aug", "
8cd0: 53 65 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f Sep", "Oct", "No
8ce0: 76 22 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a v", "Dec", 0};..
8cf0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61 ./*.** Returns a
8d00: 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 n RFC822-formatt
8d10: 65 64 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73 ed time string s
8d20: 75 69 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50 uitable for HTTP
8d30: 20 68 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a headers, among.
8d40: 2a 2a 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e ** other things.
8d50: 0a 2a 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d .** Returned tim
8d60: 65 7a 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20 ezone is always
8d70: 47 4d 54 20 61 73 20 72 65 71 75 69 72 65 64 20 GMT as required
8d80: 62 79 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63 by HTTP/1.1 spec
8d90: 69 66 69 63 61 74 69 6f 6e 2e 0a 2a 2a 20 54 68 ification..** Th
8da0: 65 20 72 65 74 75 72 6e 65 64 20 73 74 72 69 6e e returned strin
8db0: 67 20 69 73 20 61 6c 6c 6f 63 61 74 65 64 20 77 g is allocated w
8dc0: 69 74 68 20 6d 61 6c 6c 6f 63 28 29 20 61 6e 64 ith malloc() and
8dd0: 20 6d 75 73 74 20 62 65 20 66 72 65 65 64 0a 2a must be freed.*
8de0: 2a 20 77 69 74 68 20 66 72 65 65 28 29 2e 0a 2a * with free()..*
8df0: 2a 0a 2a 2a 20 53 65 65 20 68 74 74 70 3a 2f 2f *.** See http://
8e00: 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66 63 www.faqs.org/rfc
8e10: 73 2f 72 66 63 38 32 32 2e 68 74 6d 6c 2c 20 73 s/rfc822.html, s
8e20: 65 63 74 69 6f 6e 20 35 0a 2a 2a 20 61 6e 64 20 ection 5.** and
8e30: 68 74 74 70 3a 2f 2f 77 77 77 2e 66 61 71 73 2e http://www.faqs.
8e40: 6f 72 67 2f 72 66 63 73 2f 72 66 63 32 36 31 36 org/rfcs/rfc2616
8e50: 2e 68 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 20 33 .html, section 3
8e60: 2e 33 2e 0a 2a 2f 0a 63 68 61 72 20 2a 63 67 69 .3..*/.char *cgi
8e70: 5f 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d _rfc822_datestam
8e80: 70 28 74 69 6d 65 5f 74 20 6e 6f 77 29 7b 0a 20 p(time_t now){.
8e90: 20 73 74 72 75 63 74 20 74 6d 20 2a 70 54 6d 3b struct tm *pTm;
8ea0: 0a 20 20 70 54 6d 20 3d 20 67 6d 74 69 6d 65 28 . pTm = gmtime(
8eb0: 26 6e 6f 77 29 3b 0a 20 20 69 66 28 20 70 54 6d &now);. if( pTm
8ec0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 22 22 3b ==0 ) return "";
8ed0: 0a 20 20 72 65 74 75 72 6e 20 6d 70 72 69 6e 74 . return mprint
8ee0: 66 28 22 25 73 2c 20 25 64 20 25 73 20 25 30 32 f("%s, %d %s %02
8ef0: 64 20 25 30 32 64 3a 25 30 32 64 3a 25 30 32 64 d %02d:%02d:%02d
8f00: 20 47 4d 54 22 2c 0a 20 20 20 20 20 20 20 20 20 GMT",.
8f10: 20 20 20 20 20 20 20 20 61 7a 44 61 79 73 5b 70 azDays[p
8f20: 54 6d 2d 3e 74 6d 5f 77 64 61 79 5d 2c 20 70 54 Tm->tm_wday], pT
8f30: 6d 2d 3e 74 6d 5f 6d 64 61 79 2c 20 61 7a 4d 6f m->tm_mday, azMo
8f40: 6e 74 68 73 5b 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e nths[pTm->tm_mon
8f50: 5d 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 ],.
8f60: 20 20 20 20 70 54 6d 2d 3e 74 6d 5f 79 65 61 72 pTm->tm_year
8f70: 2b 31 39 30 30 2c 20 70 54 6d 2d 3e 74 6d 5f 68 +1900, pTm->tm_h
8f80: 6f 75 72 2c 20 70 54 6d 2d 3e 74 6d 5f 6d 69 6e our, pTm->tm_min
8f90: 2c 20 70 54 6d 2d 3e 74 6d 5f 73 65 63 29 3b 0a , pTm->tm_sec);.
8fa0: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 72 73 65 20 61 }../*.** Parse a
8fb0: 6e 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 n RFC822-formatt
8fc0: 65 64 20 74 69 6d 65 73 74 61 6d 70 20 61 73 20 ed timestamp as
8fd0: 77 65 27 64 20 65 78 70 65 63 74 20 66 72 6f 6d we'd expect from
8fe0: 20 48 54 54 50 20 61 6e 64 20 72 65 74 75 72 6e HTTP and return
8ff0: 0a 2a 2a 20 61 20 55 6e 69 78 20 65 70 6f 63 68 .** a Unix epoch
9000: 20 74 69 6d 65 2e 20 3c 3d 20 7a 65 72 6f 20 69 time. <= zero i
9010: 73 20 72 65 74 75 72 6e 65 64 20 6f 6e 20 66 61 s returned on fa
9020: 69 6c 75 72 65 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 ilure..**.** Not
9030: 65 20 74 68 61 74 20 74 68 69 73 20 77 6f 6e 27 e that this won'
9040: 74 20 68 61 6e 64 6c 65 20 61 6c 6c 20 74 68 65 t handle all the
9050: 20 5f 61 6c 6c 6f 77 65 64 5f 20 48 54 54 50 20 _allowed_ HTTP
9060: 66 6f 72 6d 61 74 73 2c 20 6a 75 73 74 20 74 68 formats, just th
9070: 65 0a 2a 2a 20 6d 6f 73 74 20 70 6f 70 75 6c 61 e.** most popula
9080: 72 20 6f 6e 65 20 28 74 68 65 20 6f 6e 65 20 67 r one (the one g
9090: 65 6e 65 72 61 74 65 64 20 62 79 20 63 67 69 5f enerated by cgi_
90a0: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 rfc822_datestamp
90b0: 28 29 2c 20 61 63 74 75 61 6c 6c 79 29 2e 0a 2a (), actually)..*
90c0: 2f 0a 74 69 6d 65 5f 74 20 63 67 69 5f 72 66 63 /.time_t cgi_rfc
90d0: 38 32 32 5f 70 61 72 73 65 64 61 74 65 28 63 6f 822_parsedate(co
90e0: 6e 73 74 20 63 68 61 72 20 2a 7a 44 61 74 65 29 nst char *zDate)
90f0: 7b 0a 20 20 73 74 72 75 63 74 20 74 6d 20 74 3b {. struct tm t;
9100: 0a 20 20 63 68 61 72 20 7a 49 67 6e 6f 72 65 5b . char zIgnore[
9110: 31 36 5d 3b 0a 20 20 63 68 61 72 20 7a 4d 6f 6e 16];. char zMon
9120: 74 68 5b 31 36 5d 3b 0a 0a 20 20 6d 65 6d 73 65 th[16];.. memse
9130: 74 28 26 74 2c 20 30 2c 20 73 69 7a 65 6f 66 28 t(&t, 0, sizeof(
9140: 74 29 29 3b 0a 20 20 69 66 28 20 37 3d 3d 73 73 t));. if( 7==ss
9150: 63 61 6e 66 28 7a 44 61 74 65 2c 20 22 25 31 32 canf(zDate, "%12
9160: 5b 41 2d 5a 61 2d 7a 2c 5d 20 25 64 20 25 31 32 [A-Za-z,] %d %12
9170: 5b 41 2d 5a 61 2d 7a 5d 20 25 64 20 25 64 3a 25 [A-Za-z] %d %d:%
9180: 64 3a 25 64 22 2c 20 7a 49 67 6e 6f 72 65 2c 0a d:%d", zIgnore,.
9190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
91a0: 20 20 20 20 20 20 20 26 74 2e 74 6d 5f 6d 64 61 &t.tm_mda
91b0: 79 2c 20 7a 4d 6f 6e 74 68 2c 20 26 74 2e 74 6d y, zMonth, &t.tm
91c0: 5f 79 65 61 72 2c 20 26 74 2e 74 6d 5f 68 6f 75 _year, &t.tm_hou
91d0: 72 2c 20 26 74 2e 74 6d 5f 6d 69 6e 2c 0a 20 20 r, &t.tm_min,.
91e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
91f0: 20 20 20 20 20 26 74 2e 74 6d 5f 73 65 63 29 29 &t.tm_sec))
9200: 7b 0a 0a 20 20 20 20 69 66 28 20 74 2e 74 6d 5f {.. if( t.tm_
9210: 79 65 61 72 20 3e 20 31 39 30 30 20 29 20 74 2e year > 1900 ) t.
9220: 74 6d 5f 79 65 61 72 20 2d 3d 20 31 39 30 30 3b tm_year -= 1900;
9230: 0a 20 20 20 20 66 6f 72 28 74 2e 74 6d 5f 6d 6f . for(t.tm_mo
9240: 6e 3d 30 3b 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e n=0; azMonths[t.
9250: 74 6d 5f 6d 6f 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f tm_mon]; t.tm_mo
9260: 6e 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 n++){. if(
9270: 21 73 74 72 6e 63 61 73 65 63 6d 70 28 20 61 7a !strncasecmp( az
9280: 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d Months[t.tm_mon]
9290: 2c 20 7a 4d 6f 6e 74 68 2c 20 33 20 29 29 7b 0a , zMonth, 3 )){.
92a0: 20 20 20 20 20 20 20 20 72 65 74 75 72 6e 20 6d return m
92b0: 6b 67 6d 74 69 6d 65 28 26 74 29 3b 0a 20 20 20 kgmtime(&t);.
92c0: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a }. }. }..
92d0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a 0a 2f return 0;.}../
92e0: 2a 0a 2a 2a 20 43 6f 6e 76 65 72 74 20 61 20 73 *.** Convert a s
92f0: 74 72 75 63 74 20 74 6d 2a 20 74 68 61 74 20 72 truct tm* that r
9300: 65 70 72 65 73 65 6e 74 73 20 61 20 6d 6f 6d 65 epresents a mome
9310: 6e 74 20 69 6e 20 55 54 43 20 69 6e 74 6f 20 74 nt in UTC into t
9320: 68 65 20 6e 75 6d 62 65 72 0a 2a 2a 20 6f 66 20 he number.** of
9330: 73 65 63 6f 6e 64 73 20 69 6e 20 31 39 37 30 2c seconds in 1970,
9340: 20 55 54 43 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 UTC..*/.time_t
9350: 6d 6b 67 6d 74 69 6d 65 28 73 74 72 75 63 74 20 mkgmtime(struct
9360: 74 6d 20 2a 70 29 7b 0a 20 20 74 69 6d 65 5f 74 tm *p){. time_t
9370: 20 74 3b 0a 20 20 69 6e 74 20 6e 44 61 79 3b 0a t;. int nDay;.
9380: 20 20 69 6e 74 20 69 73 4c 65 61 70 59 72 3b 0a int isLeapYr;.
9390: 20 20 2f 2a 20 44 61 79 73 20 69 6e 20 65 61 63 /* Days in eac
93a0: 68 20 6d 6f 6e 74 68 3a 20 20 20 20 20 20 20 33 h month: 3
93b0: 31 2c 20 32 38 2c 20 33 31 2c 20 33 30 2c 20 33 1, 28, 31, 30, 3
93c0: 31 2c 20 33 30 2c 20 33 31 2c 20 33 31 2c 20 33 1, 30, 31, 31, 3
93d0: 30 2c 20 33 31 2c 20 33 30 2c 20 33 31 20 2a 2f 0, 31, 30, 31 */
93e0: 0a 20 20 73 74 61 74 69 63 20 69 6e 74 20 70 72 . static int pr
93f0: 69 6f 72 44 61 79 73 5b 5d 20 20 20 3d 20 7b 20 iorDays[] = {
9400: 20 30 2c 20 33 31 2c 20 35 39 2c 20 39 30 2c 31 0, 31, 59, 90,1
9410: 32 30 2c 31 35 31 2c 31 38 31 2c 32 31 32 2c 32 20,151,181,212,2
9420: 34 33 2c 32 37 33 2c 33 30 34 2c 33 33 34 20 7d 43,273,304,334 }
9430: 3b 0a 20 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f ;. if( p->tm_mo
9440: 6e 3c 30 20 29 7b 0a 20 20 20 20 69 6e 74 20 6e n<0 ){. int n
9450: 59 65 61 72 20 3d 20 28 31 31 20 2d 20 70 2d 3e Year = (11 - p->
9460: 74 6d 5f 6d 6f 6e 29 2f 31 32 3b 0a 20 20 20 20 tm_mon)/12;.
9470: 70 2d 3e 74 6d 5f 79 65 61 72 20 2d 3d 20 6e 59 p->tm_year -= nY
9480: 65 61 72 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d ear;. p->tm_m
9490: 6f 6e 20 2b 3d 20 6e 59 65 61 72 2a 31 32 3b 0a on += nYear*12;.
94a0: 20 20 7d 65 6c 73 65 20 69 66 28 20 70 2d 3e 74 }else if( p->t
94b0: 6d 5f 6d 6f 6e 3e 31 31 20 29 7b 0a 20 20 20 20 m_mon>11 ){.
94c0: 70 2d 3e 74 6d 5f 79 65 61 72 20 2b 3d 20 70 2d p->tm_year += p-
94d0: 3e 74 6d 5f 6d 6f 6e 2f 31 32 3b 0a 20 20 20 20 >tm_mon/12;.
94e0: 70 2d 3e 74 6d 5f 6d 6f 6e 20 25 3d 20 31 32 3b p->tm_mon %= 12;
94f0: 0a 20 20 7d 0a 20 20 69 73 4c 65 61 70 59 72 20 . }. isLeapYr
9500: 3d 20 70 2d 3e 74 6d 5f 79 65 61 72 25 34 3d 3d = p->tm_year%4==
9510: 30 20 26 26 20 28 70 2d 3e 74 6d 5f 79 65 61 72 0 && (p->tm_year
9520: 25 31 30 30 21 3d 30 20 7c 7c 20 28 70 2d 3e 74 %100!=0 || (p->t
9530: 6d 5f 79 65 61 72 2b 33 30 30 29 25 34 30 30 3d m_year+300)%400=
9540: 3d 30 29 3b 0a 20 20 70 2d 3e 74 6d 5f 79 64 61 =0);. p->tm_yda
9550: 79 20 3d 20 70 72 69 6f 72 44 61 79 73 5b 70 2d y = priorDays[p-
9560: 3e 74 6d 5f 6d 6f 6e 5d 20 2b 20 70 2d 3e 74 6d >tm_mon] + p->tm
9570: 5f 6d 64 61 79 20 2d 20 31 3b 0a 20 20 69 66 28 _mday - 1;. if(
9580: 20 69 73 4c 65 61 70 59 72 20 26 26 20 70 2d 3e isLeapYr && p->
9590: 74 6d 5f 6d 6f 6e 3e 31 20 29 20 70 2d 3e 74 6d tm_mon>1 ) p->tm
95a0: 5f 79 64 61 79 2b 2b 3b 0a 20 20 6e 44 61 79 20 _yday++;. nDay
95b0: 3d 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 37 30 = (p->tm_year-70
95c0: 29 2a 33 36 35 20 2b 20 28 70 2d 3e 74 6d 5f 79 )*365 + (p->tm_y
95d0: 65 61 72 2d 36 39 29 2f 34 20 2d 70 2d 3e 74 6d ear-69)/4 -p->tm
95e0: 5f 79 65 61 72 2f 31 30 30 20 2b 20 0a 20 20 20 _year/100 + .
95f0: 20 20 20 20 20 20 28 70 2d 3e 74 6d 5f 79 65 61 (p->tm_yea
9600: 72 2b 33 30 30 29 2f 34 30 30 20 2b 20 70 2d 3e r+300)/400 + p->
9610: 74 6d 5f 79 64 61 79 3b 0a 20 20 74 20 3d 20 28 tm_yday;. t = (
9620: 28 6e 44 61 79 2a 32 34 20 2b 20 70 2d 3e 74 6d (nDay*24 + p->tm
9630: 5f 68 6f 75 72 29 2a 36 30 20 2b 20 70 2d 3e 74 _hour)*60 + p->t
9640: 6d 5f 6d 69 6e 29 2a 36 30 20 2b 20 70 2d 3e 74 m_min)*60 + p->t
9650: 6d 5f 73 65 63 3b 0a 20 20 72 65 74 75 72 6e 20 m_sec;. return
9660: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 68 65 63 t;.}../*.** Chec
9670: 6b 20 74 68 65 20 6f 62 6a 65 63 74 54 69 6d 65 k the objectTime
9680: 20 61 67 61 69 6e 73 74 20 74 68 65 20 49 66 2d against the If-
9690: 4d 6f 64 69 66 69 65 64 2d 53 69 6e 63 65 20 72 Modified-Since r
96a0: 65 71 75 65 73 74 20 68 65 61 64 65 72 2e 20 49 equest header. I
96b0: 66 20 74 68 65 0a 2a 2a 20 6f 62 6a 65 63 74 20 f the.** object
96c0: 74 69 6d 65 20 69 73 6e 27 74 20 61 6e 79 20 6e time isn't any n
96d0: 65 77 65 72 20 74 68 61 6e 20 74 68 65 20 68 65 ewer than the he
96e0: 61 64 65 72 2c 20 77 65 20 69 6d 6d 65 64 69 61 ader, we immedia
96f0: 74 65 6c 79 20 73 65 6e 64 20 62 61 63 6b 0a 2a tely send back.*
9700: 2a 20 61 20 33 30 34 20 72 65 70 6c 79 20 61 6e * a 304 reply an
9710: 64 20 65 78 69 74 2e 0a 2a 2f 0a 76 6f 69 64 20 d exit..*/.void
9720: 63 67 69 5f 6d 6f 64 69 66 69 65 64 5f 73 69 6e cgi_modified_sin
9730: 63 65 28 74 69 6d 65 5f 74 20 6f 62 6a 65 63 74 ce(time_t object
9740: 54 69 6d 65 29 7b 0a 20 20 63 6f 6e 73 74 20 63 Time){. const c
9750: 68 61 72 20 2a 7a 49 66 20 3d 20 50 28 22 48 54 har *zIf = P("HT
9760: 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f 53 TP_IF_MODIFIED_S
9770: 49 4e 43 45 22 29 3b 0a 20 20 69 66 28 20 7a 49 INCE");. if( zI
9780: 66 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b 0a 20 f==0 ) return;.
9790: 20 69 66 28 20 6f 62 6a 65 63 74 54 69 6d 65 20 if( objectTime
97a0: 3e 20 63 67 69 5f 72 66 63 38 32 32 5f 70 61 72 > cgi_rfc822_par
97b0: 73 65 64 61 74 65 28 7a 49 66 29 20 29 20 72 65 sedate(zIf) ) re
97c0: 74 75 72 6e 3b 0a 20 20 63 67 69 5f 73 65 74 5f turn;. cgi_set_
97d0: 73 74 61 74 75 73 28 33 30 34 2c 22 4e 6f 74 20 status(304,"Not
97e0: 4d 6f 64 69 66 69 65 64 22 29 3b 0a 20 20 63 67 Modified");. cg
97f0: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 i_reset_content(
9800: 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 );. cgi_reply()
9810: 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a ;. exit(0);.}.