0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20 /*.** Copyright
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68 (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54 ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66 his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75 u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20 te it and/or.**
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20 modify it under
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65 the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62 GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76 lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65 ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73 s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20 tributed in the
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20 l be useful,.**
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20 but WITHOUT ANY
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75 WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54 * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52 Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55 A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20 RPOSE. See the
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50 GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20 d have received
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63 U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72 g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69 ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65 te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20 ation, Inc., 59
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53 Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73 uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31 ton, MA 02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20 307, USA..**.**
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69 Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20 nformation:.**
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68 * http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 43 20 66 75 6e 63 contains C func
0380: 74 69 6f 6e 73 20 61 6e 64 20 70 72 6f 63 65 64 tions and proced
0390: 75 72 65 73 20 74 68 61 74 20 70 72 6f 76 69 64 ures that provid
03a0: 65 20 75 73 65 66 75 6c 0a 2a 2a 20 73 65 72 76 e useful.** serv
03b0: 69 63 65 73 20 74 6f 20 43 47 49 20 70 72 6f 67 ices to CGI prog
03c0: 72 61 6d 73 2e 20 20 54 68 65 72 65 20 61 72 65 rams. There are
03d0: 20 70 72 6f 63 65 64 75 72 65 73 20 66 6f 72 20 procedures for
03e0: 70 61 72 73 69 6e 67 20 61 6e 64 0a 2a 2a 20 64 parsing and.** d
03f0: 69 73 70 65 6e 73 69 6e 67 20 51 55 45 52 59 5f ispensing QUERY_
0400: 53 54 52 49 4e 47 20 70 61 72 61 6d 65 74 65 72 STRING parameter
0410: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2c 20 74 s and cookies, t
0420: 68 65 20 22 6d 70 72 69 6e 74 66 28 29 22 0a 2a he "mprintf()".*
0430: 2a 20 66 6f 72 6d 61 74 74 69 6e 67 20 66 75 6e * formatting fun
0440: 63 74 69 6f 6e 20 61 6e 64 20 69 74 73 20 63 6f ction and its co
0450: 75 73 69 6e 73 2c 20 61 6e 64 20 72 6f 75 74 69 usins, and routi
0460: 6e 65 73 20 74 6f 20 65 6e 63 6f 64 65 20 61 6e nes to encode an
0470: 64 0a 2a 2a 20 64 65 63 6f 64 65 20 73 74 72 69 d.** decode stri
0480: 6e 67 73 20 69 6e 20 48 54 4d 4c 20 6f 72 20 48 ngs in HTML or H
0490: 54 54 50 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 TTP..*/.#include
04a0: 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 66 64 "config.h".#ifd
04b0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 23 ef __MINGW32__.#
04c0: 20 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e 64 6f include <windo
04d0: 77 73 2e 68 3e 20 20 20 20 20 20 20 20 20 20 20 ws.h>
04e0: 2f 2a 20 66 6f 72 20 53 6c 65 65 70 20 6f 6e 63 /* for Sleep onc
04f0: 65 20 73 65 72 76 65 72 20 77 6f 72 6b 73 20 61 e server works a
0500: 67 61 69 6e 20 2a 2f 0a 23 20 20 69 6e 63 6c 75 gain */.# inclu
0510: 64 65 20 3c 77 69 6e 73 6f 63 6b 32 2e 68 3e 20 de <winsock2.h>
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 6f 63 6b /* sock
0530: 65 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f et operations */
0540: 0a 23 20 20 64 65 66 69 6e 65 20 73 6c 65 65 70 .# define sleep
0550: 20 53 6c 65 65 70 20 20 20 20 20 20 20 20 20 20 Sleep
0560: 20 20 2f 2a 20 77 69 6e 64 6f 77 73 20 64 6f 65 /* windows doe
0570: 73 20 6e 6f 74 20 68 61 76 65 20 73 6c 65 65 70 s not have sleep
0580: 2c 20 62 75 74 20 53 6c 65 65 70 20 2a 2f 0a 23 , but Sleep */.#
0590: 20 20 69 6e 63 6c 75 64 65 20 3c 77 73 32 74 63 include <ws2tc
05a0: 70 69 70 2e 68 3e 20 20 20 20 20 20 20 20 20 20 pip.h>
05b0: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64 .#else.# includ
05c0: 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e e <sys/socket.h>
05d0: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74 .# include <net
05e0: 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e inet/in.h>.# in
05f0: 63 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74 clude <arpa/inet
0600: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c .h>.# include <
0610: 73 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20 sys/times.h>.#
0620: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d include <sys/tim
0630: 65 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 e.h>.# include
0640: 3c 73 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20 <sys/wait.h>.#
0650: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c include <sys/sel
0660: 65 63 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69 ect.h>.#endif.#i
0670: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a nclude <time.h>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e #include <stdio.
0690: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 h>.#include <std
06a0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 lib.h>.#include
06b0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c <unistd.h>.#incl
06c0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66 ude "cgi.h"..#if
06d0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a INTERFACE./*.**
06e0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63 Shortcuts for c
06f0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50 gi_parameter. P
0700: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68 ("x") returns th
0710: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79 e value of query
0720: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72 parameter.** or
0730: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20 cookie "x", or
0740: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 NULL if there is
0750: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74 no such paramet
0760: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50 er or cookie. P
0770: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f D("x","y").** do
0780: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65 es the same exce
0790: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e pt "y" is return
07a0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e ed in place of N
07b0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 ULL if there is
07c0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64 not match..*/.#d
07d0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20 efine P(x)
07e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 cgi_parameter(
07f0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50 (x),0).#define P
0800: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70 D(x,y) cgi_p
0810: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29 arameter((x),(y)
0820: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20 ).#define QP(x)
0830: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73 quotable_s
0840: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65 tring(cgi_parame
0850: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66 ter((x),0)).#def
0860: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20 ine QPD(x,y)
0870: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28 quotable_string(
0880: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78 cgi_parameter((x
0890: 29 2c 28 79 29 29 29 0a 0a 0a 2f 2a 0a 2a 2a 20 ),(y))).../*.**
08a0: 44 65 73 74 69 6e 61 74 69 6f 6e 73 20 66 6f 72 Destinations for
08b0: 20 6f 75 74 70 75 74 20 74 65 78 74 2e 0a 2a 2f output text..*/
08c0: 0a 23 64 65 66 69 6e 65 20 43 47 49 5f 48 45 41 .#define CGI_HEA
08d0: 44 45 52 20 20 20 30 0a 23 64 65 66 69 6e 65 20 DER 0.#define
08e0: 43 47 49 5f 42 4f 44 59 20 20 20 20 20 31 0a 0a CGI_BODY 1..
08f0: 23 65 6e 64 69 66 20 2f 2a 20 49 4e 54 45 52 46 #endif /* INTERF
0900: 41 43 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50 72 ACE */../*.** Pr
0910: 6f 76 69 64 65 20 61 20 72 65 6c 69 61 62 6c 65 ovide a reliable
0920: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 implementation
0930: 6f 66 20 61 20 63 61 73 65 6c 65 73 73 20 73 74 of a caseless st
0940: 72 69 6e 67 20 63 6f 6d 70 61 72 69 73 6f 6e 0a ring comparison.
0950: 2a 2a 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a ** function..*/.
0960: 23 64 65 66 69 6e 65 20 73 74 72 69 63 6d 70 20 #define stricmp
0970: 73 71 6c 69 74 65 33 53 74 72 49 43 6d 70 0a 65 sqlite3StrICmp.e
0980: 78 74 65 72 6e 20 69 6e 74 20 73 71 6c 69 74 65 xtern int sqlite
0990: 33 53 74 72 49 43 6d 70 28 63 6f 6e 73 74 20 63 3StrICmp(const c
09a0: 68 61 72 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 har*, const char
09b0: 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 48 *);../*.** The H
09c0: 54 54 50 20 72 65 70 6c 79 20 69 73 20 67 65 6e TTP reply is gen
09d0: 65 72 61 74 65 64 20 69 6e 20 74 77 6f 20 70 69 erated in two pi
09e0: 65 63 65 73 3a 20 74 68 65 20 68 65 61 64 65 72 eces: the header
09f0: 20 61 6e 64 20 74 68 65 20 62 6f 64 79 2e 0a 2a and the body..*
0a00: 2a 20 54 68 65 73 65 20 70 69 65 63 65 73 20 61 * These pieces a
0a10: 72 65 20 67 65 6e 65 72 61 74 65 64 20 73 65 70 re generated sep
0a20: 61 72 61 74 65 6c 79 20 62 65 63 61 75 73 65 20 arately because
0a30: 74 68 65 79 20 61 72 65 20 6e 6f 74 20 6e 65 63 they are not nec
0a40: 65 73 73 61 72 79 0a 2a 2a 20 70 72 6f 64 75 63 essary.** produc
0a50: 65 64 20 69 6e 20 6f 72 64 65 72 2e 20 20 50 61 ed in order. Pa
0a60: 72 74 73 20 6f 66 20 74 68 65 20 68 65 61 64 65 rts of the heade
0a70: 72 20 6d 69 67 68 74 20 62 65 20 62 75 69 6c 74 r might be built
0a80: 20 61 66 74 65 72 20 61 6c 6c 20 6f 72 0a 2a 2a after all or.**
0a90: 20 70 61 72 74 20 6f 66 20 74 68 65 20 62 6f 64 part of the bod
0aa0: 79 2e 20 20 54 68 65 20 68 65 61 64 65 72 20 61 y. The header a
0ab0: 6e 64 20 62 6f 64 79 20 61 72 65 20 61 63 63 75 nd body are accu
0ac0: 6d 75 6c 61 74 65 64 20 69 6e 20 73 65 70 61 72 mulated in separ
0ad0: 61 74 65 0a 2a 2a 20 42 6c 6f 62 20 73 74 72 75 ate.** Blob stru
0ae0: 63 74 75 72 65 73 20 74 68 65 6e 20 6f 75 74 70 ctures then outp
0af0: 75 74 20 73 65 71 75 65 6e 74 69 61 6c 6c 79 20 ut sequentially
0b00: 6f 6e 63 65 20 65 76 65 72 79 74 68 69 6e 67 20 once everything
0b10: 68 61 73 20 62 65 65 6e 0a 2a 2a 20 62 75 69 6c has been.** buil
0b20: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 67 69 t..**.** The cgi
0b30: 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 29 20 69 _destination() i
0b40: 6e 74 65 72 66 61 63 65 20 73 77 69 74 63 68 20 nterface switch
0b50: 62 65 74 77 65 65 6e 20 74 68 65 20 62 75 66 66 between the buff
0b60: 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42 ers..*/.static B
0b70: 6c 6f 62 20 63 67 69 43 6f 6e 74 65 6e 74 5b 32 lob cgiContent[2
0b80: 5d 20 3d 20 7b 20 42 4c 4f 42 5f 49 4e 49 54 49 ] = { BLOB_INITI
0b90: 41 4c 49 5a 45 52 2c 20 42 4c 4f 42 5f 49 4e 49 ALIZER, BLOB_INI
0ba0: 54 49 41 4c 49 5a 45 52 20 7d 3b 0a 73 74 61 74 TIALIZER };.stat
0bb0: 69 63 20 42 6c 6f 62 20 2a 70 43 6f 6e 74 65 6e ic Blob *pConten
0bc0: 74 20 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b t = &cgiContent[
0bd0: 30 5d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 0];../*.** Set t
0be0: 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 62 he destination b
0bf0: 75 66 66 65 72 20 69 6e 74 6f 20 77 68 69 63 68 uffer into which
0c00: 20 74 6f 20 61 63 63 75 6d 75 6c 61 74 65 20 43 to accumulate C
0c10: 47 49 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76 GI content..*/.v
0c20: 6f 69 64 20 63 67 69 5f 64 65 73 74 69 6e 61 74 oid cgi_destinat
0c30: 69 6f 6e 28 69 6e 74 20 64 65 73 74 29 7b 0a 20 ion(int dest){.
0c40: 20 73 77 69 74 63 68 28 20 64 65 73 74 20 29 7b switch( dest ){
0c50: 0a 20 20 20 20 63 61 73 65 20 43 47 49 5f 48 45 . case CGI_HE
0c60: 41 44 45 52 3a 20 7b 0a 20 20 20 20 20 20 70 43 ADER: {. pC
0c70: 6f 6e 74 65 6e 74 20 3d 20 26 63 67 69 43 6f 6e ontent = &cgiCon
0c80: 74 65 6e 74 5b 30 5d 3b 0a 20 20 20 20 20 20 62 tent[0];. b
0c90: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 reak;. }.
0ca0: 63 61 73 65 20 43 47 49 5f 42 4f 44 59 3a 20 7b case CGI_BODY: {
0cb0: 0a 20 20 20 20 20 20 70 43 6f 6e 74 65 6e 74 20 . pContent
0cc0: 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d = &cgiContent[1]
0cd0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 ;. break;.
0ce0: 20 20 20 7d 0a 20 20 20 20 64 65 66 61 75 6c 74 }. default
0cf0: 3a 20 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 61 : {. cgi_pa
0d00: 6e 69 63 28 22 62 61 64 20 64 65 73 74 69 6e 61 nic("bad destina
0d10: 74 69 6f 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20 tion");. }.
0d20: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e }.}../*.** Appen
0d30: 64 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 d reply content
0d40: 74 6f 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 to what already
0d50: 65 78 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 exists..*/.void
0d60: 63 67 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 cgi_append_conte
0d70: 6e 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a nt(const char *z
0d80: 44 61 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b Data, int nAmt){
0d90: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 . blob_append(p
0da0: 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c 20 Content, zData,
0db0: 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 nAmt);.}../*.**
0dc0: 52 65 73 65 74 20 74 68 65 20 48 54 54 50 20 72 Reset the HTTP r
0dd0: 65 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 20 eply text to be
0de0: 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 2e an empty string.
0df0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 73 .*/.void cgi_res
0e00: 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 29 et_content(void)
0e10: 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 {. blob_reset(&
0e20: 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a cgiContent[0]);.
0e30: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67 blob_reset(&cg
0e40: 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 7d 0a iContent[1]);.}.
0e50: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 ./*.** Return a
0e60: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43 pointer to the C
0e70: 47 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a GI output blob..
0e80: 2a 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74 */.Blob *cgi_out
0e90: 70 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a put_blob(void){.
0ea0: 20 20 72 65 74 75 72 6e 20 70 43 6f 6e 74 65 6e return pConten
0eb0: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 62 t;.}../*.** Comb
0ec0: 69 6e 65 20 74 68 65 20 68 65 61 64 65 72 20 61 ine the header a
0ed0: 6e 64 20 62 6f 64 79 20 6f 66 20 74 68 65 20 43 nd body of the C
0ee0: 47 49 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 GI into a single
0ef0: 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 string..*/.stat
0f00: 69 63 20 76 6f 69 64 20 63 67 69 5f 63 6f 6d 62 ic void cgi_comb
0f10: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 ine_header_and_b
0f20: 6f 64 79 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 ody(void){. int
0f30: 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a size = blob_siz
0f40: 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d e(&cgiContent[1]
0f50: 29 3b 0a 20 20 69 66 28 20 73 69 7a 65 3e 30 20 );. if( size>0
0f60: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 ){. blob_appe
0f70: 6e 64 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 nd(&cgiContent[0
0f80: 5d 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 ], blob_buffer(&
0f90: 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 2c 20 cgiContent[1]),
0fa0: 73 69 7a 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f size);. blob_
0fb0: 72 65 73 65 74 28 26 63 67 69 43 6f 6e 74 65 6e reset(&cgiConten
0fc0: 74 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a t[1]);. }.}../*
0fd0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 .** Return a poi
0fe0: 6e 74 65 72 20 74 6f 20 74 68 65 20 48 54 54 50 nter to the HTTP
0ff0: 20 72 65 70 6c 79 20 74 65 78 74 2e 0a 2a 2f 0a reply text..*/.
1000: 63 68 61 72 20 2a 63 67 69 5f 65 78 74 72 61 63 char *cgi_extrac
1010: 74 5f 63 6f 6e 74 65 6e 74 28 69 6e 74 20 2a 70 t_content(int *p
1020: 6e 41 6d 74 29 7b 0a 20 20 63 67 69 5f 63 6f 6d nAmt){. cgi_com
1030: 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f bine_header_and_
1040: 62 6f 64 79 28 29 3b 0a 20 20 72 65 74 75 72 6e body();. return
1050: 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 blob_buffer(&cg
1060: 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 7d 0a iContent[0]);.}.
1070: 0a 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 ./*.** Additiona
1080: 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73 l information us
1090: 65 64 20 74 6f 20 66 6f 72 6d 20 74 68 65 20 48 ed to form the H
10a0: 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 73 74 61 TTP reply.*/.sta
10b0: 74 69 63 20 63 68 61 72 20 2a 7a 43 6f 6e 74 65 tic char *zConte
10c0: 6e 74 54 79 70 65 20 3d 20 22 74 65 78 74 2f 68 ntType = "text/h
10d0: 74 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 43 6f 6e tml"; /* Con
10e0: 74 65 6e 74 20 74 79 70 65 20 6f 66 20 74 68 65 tent type of the
10f0: 20 72 65 70 6c 79 20 2a 2f 0a 73 74 61 74 69 63 reply */.static
1100: 20 63 68 61 72 20 2a 7a 52 65 70 6c 79 53 74 61 char *zReplySta
1110: 74 75 73 20 3d 20 22 4f 4b 22 3b 20 20 20 20 20 tus = "OK";
1120: 20 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 /* Reply
1130: 73 74 61 74 75 73 20 64 65 73 63 72 69 70 74 69 status descripti
1140: 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 on */.static int
1150: 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 iReplyStatus =
1160: 32 30 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 200;
1170: 20 20 20 2f 2a 20 52 65 70 6c 79 20 73 74 61 74 /* Reply stat
1180: 75 73 20 63 6f 64 65 20 2a 2f 0a 73 74 61 74 69 us code */.stati
1190: 63 20 42 6c 6f 62 20 65 78 74 72 61 48 65 61 64 c Blob extraHead
11a0: 65 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 er = BLOB_INITIA
11b0: 4c 49 5a 45 52 3b 20 20 2f 2a 20 45 78 74 72 61 LIZER; /* Extra
11c0: 20 68 65 61 64 65 72 20 74 65 78 74 20 2a 2f 0a header text */.
11d0: 73 74 61 74 69 63 20 69 6e 74 20 66 75 6c 6c 48 static int fullH
11e0: 74 74 70 52 65 70 6c 79 20 3d 20 30 3b 20 20 20 ttpReply = 0;
11f0: 20 20 20 2f 2a 20 54 72 75 65 20 66 6f 72 20 61 /* True for a
1200: 20 66 75 6c 6c 2d 62 6c 6f 77 6e 20 48 54 54 50 full-blown HTTP
1210: 20 68 65 61 64 65 72 20 2a 2f 0a 0a 2f 2a 0a 2a header */../*.*
1220: 2a 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 20 * Set the reply
1230: 63 6f 6e 74 65 6e 74 20 74 79 70 65 0a 2a 2f 0a content type.*/.
1240: 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e void cgi_set_con
1250: 74 65 6e 74 5f 74 79 70 65 28 63 6f 6e 73 74 20 tent_type(const
1260: 63 68 61 72 20 2a 7a 54 79 70 65 29 7b 0a 20 20 char *zType){.
1270: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 6d zContentType = m
1280: 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 54 79 printf("%s", zTy
1290: 70 65 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 pe);.}../*.** Se
12a0: 74 20 74 68 65 20 72 65 70 6c 79 20 63 6f 6e 74 t the reply cont
12b0: 65 6e 74 20 74 6f 20 74 68 65 20 73 70 65 63 69 ent to the speci
12c0: 66 69 65 64 20 42 4c 4f 42 2e 0a 2a 2f 0a 76 6f fied BLOB..*/.vo
12d0: 69 64 20 63 67 69 5f 73 65 74 5f 63 6f 6e 74 65 id cgi_set_conte
12e0: 6e 74 28 42 6c 6f 62 20 2a 70 4e 65 77 43 6f 6e nt(Blob *pNewCon
12f0: 74 65 6e 74 29 7b 0a 20 20 63 67 69 5f 72 65 73 tent){. cgi_res
1300: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 et_content();.
1310: 63 67 69 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 cgi_destination(
1320: 43 47 49 5f 48 45 41 44 45 52 29 3b 0a 20 20 63 CGI_HEADER);. c
1330: 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 20 3d 20 2a giContent[0] = *
1340: 70 4e 65 77 43 6f 6e 74 65 6e 74 3b 0a 20 20 62 pNewContent;. b
1350: 6c 6f 62 5f 7a 65 72 6f 28 70 4e 65 77 43 6f 6e lob_zero(pNewCon
1360: 74 65 6e 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 tent);.}../*.**
1370: 53 65 74 20 74 68 65 20 72 65 70 6c 79 20 73 74 Set the reply st
1380: 61 74 75 73 20 63 6f 64 65 0a 2a 2f 0a 76 6f 69 atus code.*/.voi
1390: 64 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 d cgi_set_status
13a0: 28 69 6e 74 20 69 53 74 61 74 2c 20 63 6f 6e 73 (int iStat, cons
13b0: 74 20 63 68 61 72 20 2a 7a 53 74 61 74 29 7b 0a t char *zStat){.
13c0: 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d zReplyStatus =
13d0: 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 20 7a mprintf("%s", z
13e0: 53 74 61 74 29 3b 0a 20 20 69 52 65 70 6c 79 53 Stat);. iReplyS
13f0: 74 61 74 75 73 20 3d 20 69 53 74 61 74 3b 0a 7d tatus = iStat;.}
1400: 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 74 ../*.** Append t
1410: 65 78 74 20 74 6f 20 74 68 65 20 68 65 61 64 65 ext to the heade
1420: 72 20 6f 66 20 61 6e 20 48 54 54 50 20 72 65 70 r of an HTTP rep
1430: 6c 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 61 ly.*/.void cgi_a
1440: 70 70 65 6e 64 5f 68 65 61 64 65 72 28 63 6f 6e ppend_header(con
1450: 73 74 20 63 68 61 72 20 2a 7a 4c 69 6e 65 29 7b st char *zLine){
1460: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 . blob_append(&
1470: 65 78 74 72 61 48 65 61 64 65 72 2c 20 7a 4c 69 extraHeader, zLi
1480: 6e 65 2c 20 2d 31 29 3b 0a 7d 0a 0a 2f 2a 0a 2a ne, -1);.}../*.*
1490: 2a 20 53 65 74 20 61 20 63 6f 6f 6b 69 65 2e 0a * Set a cookie..
14a0: 2a 2a 0a 2a 2a 20 5a 65 72 6f 20 6c 69 66 65 74 **.** Zero lifet
14b0: 69 6d 65 20 69 6d 70 6c 69 65 73 20 61 20 73 65 ime implies a se
14c0: 73 73 69 6f 6e 20 63 6f 6f 6b 69 65 2e 0a 2a 2f ssion cookie..*/
14d0: 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 63 6f .void cgi_set_co
14e0: 6f 6b 69 65 28 0a 20 20 63 6f 6e 73 74 20 63 68 okie(. const ch
14f0: 61 72 20 2a 7a 4e 61 6d 65 2c 20 20 20 20 2f 2a ar *zName, /*
1500: 20 4e 61 6d 65 20 6f 66 20 74 68 65 20 63 6f 6f Name of the coo
1510: 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 kie */. const c
1520: 68 61 72 20 2a 7a 56 61 6c 75 65 2c 20 20 20 2f har *zValue, /
1530: 2a 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20 63 * Value of the c
1540: 6f 6f 6b 69 65 2e 20 20 41 75 74 6f 6d 61 74 69 ookie. Automati
1550: 63 61 6c 6c 79 20 65 73 63 61 70 65 64 20 2a 2f cally escaped */
1560: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a . const char *z
1570: 50 61 74 68 2c 20 20 20 20 2f 2a 20 50 61 74 68 Path, /* Path
1580: 20 63 6f 6f 6b 69 65 20 61 70 70 6c 69 65 73 20 cookie applies
1590: 74 6f 2e 20 20 4e 55 4c 4c 20 6d 65 61 6e 73 20 to. NULL means
15a0: 22 2f 22 20 2a 2f 0a 20 20 69 6e 74 20 6c 69 66 "/" */. int lif
15b0: 65 74 69 6d 65 20 20 20 20 20 20 20 20 20 20 2f etime /
15c0: 2a 20 45 78 70 69 72 61 74 69 6f 6e 20 6f 66 20 * Expiration of
15d0: 74 68 65 20 63 6f 6f 6b 69 65 20 69 6e 20 73 65 the cookie in se
15e0: 63 6f 6e 64 73 20 66 72 6f 6d 20 6e 6f 77 20 2a conds from now *
15f0: 2f 0a 29 7b 0a 20 20 69 66 28 20 7a 50 61 74 68 /.){. if( zPath
1600: 3d 3d 30 20 29 20 7a 50 61 74 68 20 3d 20 67 2e ==0 ) zPath = g.
1610: 7a 54 6f 70 3b 0a 20 20 69 66 28 20 6c 69 66 65 zTop;. if( life
1620: 74 69 6d 65 3e 30 20 29 7b 0a 20 20 20 20 6c 69 time>0 ){. li
1630: 66 65 74 69 6d 65 20 2b 3d 20 28 69 6e 74 29 74 fetime += (int)t
1640: 69 6d 65 28 30 29 3b 0a 20 20 20 20 62 6c 6f 62 ime(0);. blob
1650: 5f 61 70 70 65 6e 64 66 28 26 65 78 74 72 61 48 _appendf(&extraH
1660: 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 22 53 eader,. "S
1670: 65 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d 25 74 et-Cookie: %s=%t
1680: 3b 20 50 61 74 68 3d 25 73 3b 20 65 78 70 69 72 ; Path=%s; expir
1690: 65 73 3d 25 73 3b 20 56 65 72 73 69 6f 6e 3d 31 es=%s; Version=1
16a0: 5c 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 7a \r\n",. z
16b0: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50 Name, zValue, zP
16c0: 61 74 68 2c 20 63 67 69 5f 72 66 63 38 32 32 5f ath, cgi_rfc822_
16d0: 64 61 74 65 73 74 61 6d 70 28 6c 69 66 65 74 69 datestamp(lifeti
16e0: 6d 65 29 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 me));. }else{.
16f0: 20 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 blob_appendf(
1700: 26 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 &extraHeader,.
1710: 20 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 "Set-Cookie
1720: 3a 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 : %s=%t; Path=%s
1730: 3b 20 56 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e 22 ; Version=1\r\n"
1740: 2c 0a 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 ,. zName,
1750: 7a 56 61 6c 75 65 2c 20 7a 50 61 74 68 29 3b 0a zValue, zPath);.
1760: 20 20 7d 0a 7d 0a 0a 23 69 66 20 30 0a 2f 2a 0a }.}..#if 0./*.
1770: 2a 2a 20 41 64 64 20 61 6e 20 45 54 61 67 20 68 ** Add an ETag h
1780: 65 61 64 65 72 20 6c 69 6e 65 0a 2a 2f 0a 73 74 eader line.*/.st
1790: 61 74 69 63 20 63 68 61 72 20 2a 63 67 69 5f 61 atic char *cgi_a
17a0: 64 64 5f 65 74 61 67 28 63 68 61 72 20 2a 7a 54 dd_etag(char *zT
17b0: 78 74 2c 20 69 6e 74 20 6e 4c 65 6e 29 7b 0a 20 xt, int nLen){.
17c0: 20 4d 44 35 43 6f 6e 74 65 78 74 20 63 74 78 3b MD5Context ctx;
17d0: 0a 20 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 . unsigned char
17e0: 20 64 69 67 65 73 74 5b 31 36 5d 3b 0a 20 20 69 digest[16];. i
17f0: 6e 74 20 69 2c 20 6a 3b 0a 20 20 63 68 61 72 20 nt i, j;. char
1800: 7a 45 54 61 67 5b 36 34 5d 3b 0a 0a 20 20 4d 44 zETag[64];.. MD
1810: 35 49 6e 69 74 28 26 63 74 78 29 3b 0a 20 20 4d 5Init(&ctx);. M
1820: 44 35 55 70 64 61 74 65 28 26 63 74 78 2c 7a 54 D5Update(&ctx,zT
1830: 78 74 2c 6e 4c 65 6e 29 3b 0a 20 20 4d 44 35 46 xt,nLen);. MD5F
1840: 69 6e 61 6c 28 64 69 67 65 73 74 2c 26 63 74 78 inal(digest,&ctx
1850: 29 3b 0a 20 20 66 6f 72 28 6a 3d 69 3d 30 3b 20 );. for(j=i=0;
1860: 69 3c 31 36 3b 20 69 2b 2b 2c 6a 2b 3d 32 29 7b i<16; i++,j+=2){
1870: 0a 20 20 20 20 62 70 72 69 6e 74 66 28 26 7a 45 . bprintf(&zE
1880: 54 61 67 5b 6a 5d 2c 73 69 7a 65 6f 66 28 7a 45 Tag[j],sizeof(zE
1890: 54 61 67 29 2d 6a 2c 22 25 30 32 78 22 2c 28 69 Tag)-j,"%02x",(i
18a0: 6e 74 29 64 69 67 65 73 74 5b 69 5d 29 3b 0a 20 nt)digest[i]);.
18b0: 20 7d 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 }. blob_append
18c0: 66 28 26 65 78 74 72 61 48 65 61 64 65 72 2c 20 f(&extraHeader,
18d0: 22 45 54 61 67 3a 20 25 73 5c 72 5c 6e 22 2c 20 "ETag: %s\r\n",
18e0: 7a 45 54 61 67 29 3b 0a 20 20 72 65 74 75 72 6e zETag);. return
18f0: 20 73 74 72 64 75 70 28 7a 45 54 61 67 29 3b 0a strdup(zETag);.
1900: 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 73 6f 6d 65 }../*.** Do some
1910: 20 63 61 63 68 65 20 63 6f 6e 74 72 6f 6c 20 73 cache control s
1920: 74 75 66 66 2e 20 46 69 72 73 74 2c 20 77 65 20 tuff. First, we
1930: 67 65 6e 65 72 61 74 65 20 61 6e 20 45 54 61 67 generate an ETag
1940: 20 61 6e 64 20 69 6e 63 6c 75 64 65 20 69 74 20 and include it
1950: 69 6e 0a 2a 2a 20 74 68 65 20 72 65 73 70 6f 6e in.** the respon
1960: 73 65 20 68 65 61 64 65 72 73 2e 20 53 65 63 6f se headers. Seco
1970: 6e 64 2c 20 77 65 20 64 6f 20 77 68 61 74 65 76 nd, we do whatev
1980: 65 72 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 er is necessary
1990: 74 6f 20 64 65 74 65 72 6d 69 6e 65 20 69 66 0a to determine if.
19a0: 2a 2a 20 74 68 65 20 72 65 71 75 65 73 74 20 77 ** the request w
19b0: 61 73 20 61 73 6b 69 6e 67 20 61 62 6f 75 74 20 as asking about
19c0: 63 61 63 68 69 6e 67 20 61 6e 64 20 77 68 65 74 caching and whet
19d0: 68 65 72 20 77 65 20 6e 65 65 64 20 74 6f 20 73 her we need to s
19e0: 65 6e 64 20 62 61 63 6b 20 74 68 65 0a 2a 2a 20 end back the.**
19f0: 72 65 73 70 6f 6e 73 65 20 62 6f 64 79 2e 20 49 response body. I
1a00: 66 20 77 65 20 73 68 6f 75 6c 64 6e 27 74 20 73 f we shouldn't s
1a10: 65 6e 64 20 61 20 62 6f 64 79 2c 20 72 65 74 75 end a body, retu
1a20: 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a rn non-zero..**.
1a30: 2a 2a 20 43 75 72 72 65 6e 74 6c 79 2c 20 77 65 ** Currently, we
1a40: 20 6a 75 73 74 20 63 68 65 63 6b 20 74 68 65 20 just check the
1a50: 45 54 61 67 20 61 67 61 69 6e 73 74 20 61 6e 79 ETag against any
1a60: 20 49 66 2d 4e 6f 6e 65 2d 4d 61 74 63 68 20 68 If-None-Match h
1a70: 65 61 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 46 49 58 eader..**.** FIX
1a80: 4d 45 3a 20 49 6e 20 73 6f 6d 65 20 63 61 73 65 ME: In some case
1a90: 73 20 28 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 s (attachments,
1aa0: 66 69 6c 65 20 63 6f 6e 74 65 6e 74 73 29 20 77 file contents) w
1ab0: 65 20 63 6f 75 6c 64 20 63 68 65 63 6b 0a 2a 2a e could check.**
1ac0: 20 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e If-Modified-Sin
1ad0: 63 65 20 68 65 61 64 65 72 73 20 61 6e 64 20 61 ce headers and a
1ae0: 6c 77 61 79 73 20 69 6e 63 6c 75 64 65 20 4c 61 lways include La
1af0: 73 74 2d 4d 6f 64 69 66 69 65 64 20 69 6e 20 72 st-Modified in r
1b00: 65 73 70 6f 6e 73 65 73 2e 0a 2a 2f 0a 73 74 61 esponses..*/.sta
1b10: 74 69 63 20 69 6e 74 20 63 68 65 63 6b 5f 63 61 tic int check_ca
1b20: 63 68 65 5f 63 6f 6e 74 72 6f 6c 28 76 6f 69 64 che_control(void
1b30: 29 7b 0a 20 20 2f 2a 20 46 49 58 4d 45 3a 20 74 ){. /* FIXME: t
1b40: 68 65 72 65 27 73 20 73 6f 6d 65 20 67 6f 74 63 here's some gotc
1b50: 68 61 73 20 77 74 68 20 63 6f 6f 6b 69 65 73 20 has wth cookies
1b60: 61 6e 64 20 73 6f 6d 65 20 68 65 61 64 65 72 73 and some headers
1b70: 2e 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 54 . */. char *zET
1b80: 61 67 20 3d 20 63 67 69 5f 61 64 64 5f 65 74 61 ag = cgi_add_eta
1b90: 67 28 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 g(blob_buffer(&c
1ba0: 67 69 43 6f 6e 74 65 6e 74 29 2c 62 6c 6f 62 5f giContent),blob_
1bb0: 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 size(&cgiContent
1bc0: 29 29 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 61 74 ));. char *zMat
1bd0: 63 68 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f ch = P("HTTP_IF_
1be0: 4e 4f 4e 45 5f 4d 41 54 43 48 22 29 3b 0a 0a 20 NONE_MATCH");..
1bf0: 20 69 66 28 20 7a 45 54 61 67 21 3d 30 20 26 26 if( zETag!=0 &&
1c00: 20 7a 4d 61 74 63 68 21 3d 30 20 29 20 7b 0a 20 zMatch!=0 ) {.
1c10: 20 20 20 63 68 61 72 20 2a 7a 42 75 66 20 3d 20 char *zBuf =
1c20: 73 74 72 64 75 70 28 7a 4d 61 74 63 68 29 3b 0a strdup(zMatch);.
1c30: 20 20 20 20 69 66 28 20 7a 42 75 66 21 3d 30 20 if( zBuf!=0
1c40: 29 7b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a ){. char *z
1c50: 54 6f 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 63 Tok = 0;. c
1c60: 68 61 72 20 2a 7a 50 6f 73 3b 0a 20 20 20 20 20 har *zPos;.
1c70: 20 66 6f 72 28 20 7a 54 6f 6b 20 3d 20 73 74 72 for( zTok = str
1c80: 74 6f 6b 5f 72 28 7a 42 75 66 2c 20 22 2c 5c 22 tok_r(zBuf, ",\"
1c90: 22 2c 26 7a 50 6f 73 29 3b 0a 20 20 20 20 20 20 ",&zPos);.
1ca0: 20 20 20 20 20 7a 54 6f 6b 20 26 26 20 73 74 72 zTok && str
1cb0: 63 61 73 65 63 6d 70 28 7a 54 6f 6b 2c 7a 45 54 casecmp(zTok,zET
1cc0: 61 67 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 ag);.
1cd0: 7a 54 6f 6b 20 3d 20 20 73 74 72 74 6f 6b 5f 72 zTok = strtok_r
1ce0: 28 30 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 (0, ",\"",&zPos)
1cf0: 29 7b 7d 0a 20 20 20 20 20 20 66 72 65 65 28 7a ){}. free(z
1d00: 42 75 66 29 3b 0a 20 20 20 20 20 20 69 66 28 7a Buf);. if(z
1d10: 54 6f 6b 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 Tok) return 1;.
1d20: 20 20 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72 65 }. }. . re
1d30: 74 75 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69 66 turn 0;.}.#endif
1d40: 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 6e 6f 72 ../*.** Do a nor
1d50: 6d 61 6c 20 48 54 54 50 20 72 65 70 6c 79 0a 2a mal HTTP reply.*
1d60: 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 79 /.void cgi_reply
1d70: 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 74 6f (void){. int to
1d80: 74 61 6c 5f 73 69 7a 65 20 3d 20 30 3b 0a 20 20 tal_size = 0;.
1d90: 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 if( iReplyStatus
1da0: 3c 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c <=0 ){. iRepl
1db0: 79 53 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20 yStatus = 200;.
1dc0: 20 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 zReplyStatus
1dd0: 3d 20 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66 = "OK";. }..#if
1de0: 20 30 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 0. if( iReplyS
1df0: 74 61 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68 tatus==200 && ch
1e00: 65 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f eck_cache_contro
1e10: 6c 28 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63 l() ) {. /* c
1e20: 68 61 6e 67 65 20 74 68 65 20 73 74 61 74 75 73 hange the status
1e30: 20 74 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20 to "unchanged"
1e40: 61 6e 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20 and we can skip
1e50: 73 65 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20 sending the.
1e60: 2a 2a 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e ** actual respon
1e70: 73 65 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73 se body. Obvious
1e80: 6c 79 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68 ly we only do th
1e90: 69 73 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65 is when we _have
1ea0: 5f 20 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20 _ a. ** body
1eb0: 28 63 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20 (code 200)..
1ec0: 2a 2f 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 */. iReplySta
1ed0: 74 75 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a tus = 304;. z
1ee0: 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e ReplyStatus = "N
1ef0: 6f 74 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20 ot Modified";.
1f00: 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 }.#endif.. if(
1f10: 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b fullHttpReply ){
1f20: 0a 20 20 20 20 66 70 72 69 6e 74 66 28 67 2e 68 . fprintf(g.h
1f30: 74 74 70 4f 75 74 2c 20 22 48 54 54 50 2f 31 2e ttpOut, "HTTP/1.
1f40: 30 20 25 64 20 25 73 5c 72 5c 6e 22 2c 20 69 52 0 %d %s\r\n", iR
1f50: 65 70 6c 79 53 74 61 74 75 73 2c 20 7a 52 65 70 eplyStatus, zRep
1f60: 6c 79 53 74 61 74 75 73 29 3b 0a 20 20 20 20 66 lyStatus);. f
1f70: 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 printf(g.httpOut
1f80: 2c 20 22 44 61 74 65 3a 20 25 73 5c 72 5c 6e 22 , "Date: %s\r\n"
1f90: 2c 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 , cgi_rfc822_dat
1fa0: 65 73 74 61 6d 70 28 74 69 6d 65 28 30 29 29 29 estamp(time(0)))
1fb0: 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 67 2e ;. fprintf(g.
1fc0: 68 74 74 70 4f 75 74 2c 20 22 43 6f 6e 6e 65 63 httpOut, "Connec
1fd0: 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e 22 tion: close\r\n"
1fe0: 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 );. }else{.
1ff0: 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 fprintf(g.httpOu
2000: 74 2c 20 22 53 74 61 74 75 73 3a 20 25 64 20 25 t, "Status: %d %
2010: 73 5c 72 5c 6e 22 2c 20 69 52 65 70 6c 79 53 74 s\r\n", iReplySt
2020: 61 74 75 73 2c 20 7a 52 65 70 6c 79 53 74 61 74 atus, zReplyStat
2030: 75 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 us);. }.. if(
2040: 62 6c 6f 62 5f 73 69 7a 65 28 26 65 78 74 72 61 blob_size(&extra
2050: 48 65 61 64 65 72 29 3e 30 20 29 7b 0a 20 20 20 Header)>0 ){.
2060: 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f fprintf(g.httpO
2070: 75 74 2c 20 22 25 73 22 2c 20 62 6c 6f 62 5f 62 ut, "%s", blob_b
2080: 75 66 66 65 72 28 26 65 78 74 72 61 48 65 61 64 uffer(&extraHead
2090: 65 72 29 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 er));. }.. if(
20a0: 20 67 2e 69 73 43 6f 6e 73 74 20 29 7b 0a 20 20 g.isConst ){.
20b0: 20 20 2f 2a 20 63 6f 6e 73 74 61 6e 74 20 6d 65 /* constant me
20c0: 61 6e 73 20 74 68 61 74 20 74 68 65 20 69 6e 70 ans that the inp
20d0: 75 74 20 55 52 4c 20 77 69 6c 6c 20 5f 6e 65 76 ut URL will _nev
20e0: 65 72 5f 20 67 65 6e 65 72 61 74 65 20 61 6e 79 er_ generate any
20f0: 74 68 69 6e 67 0a 20 20 20 20 2a 2a 20 65 6c 73 thing. ** els
2100: 65 2e 20 49 6e 20 74 68 65 20 63 61 73 65 20 6f e. In the case o
2110: 66 20 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 74 f attachments, t
2120: 68 65 20 63 6f 6e 74 65 6e 74 73 20 77 6f 6e 27 he contents won'
2130: 74 20 63 68 61 6e 67 65 20 62 65 63 61 75 73 65 t change because
2140: 0a 20 20 20 20 2a 2a 20 61 6e 20 61 74 74 65 6d . ** an attem
2150: 70 74 20 74 6f 20 63 68 61 6e 67 65 20 74 68 65 pt to change the
2160: 6d 20 67 65 6e 65 72 61 74 65 73 20 61 20 6e 65 m generates a ne
2170: 77 20 61 74 74 61 63 68 6d 65 6e 74 20 6e 75 6d w attachment num
2180: 62 65 72 2e 20 49 6e 20 74 68 65 0a 20 20 20 20 ber. In the.
2190: 2a 2a 20 63 61 73 65 20 6f 66 20 6d 6f 73 74 20 ** case of most
21a0: 2f 67 65 74 66 69 6c 65 20 63 61 6c 6c 73 20 66 /getfile calls f
21b0: 6f 72 20 73 70 65 63 69 66 69 63 20 76 65 72 73 or specific vers
21c0: 69 6f 6e 73 2c 20 74 68 65 20 6f 6e 6c 79 20 77 ions, the only w
21d0: 61 79 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 6f ay the. ** co
21e0: 6e 74 65 6e 74 20 63 68 61 6e 67 65 73 20 69 73 ntent changes is
21f0: 20 69 66 20 73 6f 6d 65 6f 6e 65 20 62 72 65 61 if someone brea
2200: 6b 73 20 74 68 65 20 53 43 4d 2e 20 41 6e 64 20 ks the SCM. And
2210: 69 66 20 74 68 61 74 20 68 61 70 70 65 6e 73 2c if that happens,
2220: 20 61 0a 20 20 20 20 2a 2a 20 73 74 61 6c 65 20 a. ** stale
2230: 63 61 63 68 65 20 69 73 20 74 68 65 20 6c 65 61 cache is the lea
2240: 73 74 20 6f 66 20 74 68 65 20 70 72 6f 62 6c 65 st of the proble
2250: 6d 2e 20 53 6f 20 77 65 20 70 72 6f 76 69 64 65 m. So we provide
2260: 20 61 6e 20 45 78 70 69 72 65 73 0a 20 20 20 20 an Expires.
2270: 2a 2a 20 68 65 61 64 65 72 20 73 65 74 20 74 6f ** header set to
2280: 20 61 20 72 65 61 73 6f 6e 61 62 6c 65 20 70 65 a reasonable pe
2290: 72 69 6f 64 20 28 64 65 66 61 75 6c 74 3a 20 6f riod (default: o
22a0: 6e 65 20 77 65 65 6b 29 2e 0a 20 20 20 20 2a 2f ne week).. */
22b0: 0a 20 20 20 20 2f 2a 74 69 6d 65 5f 74 20 65 78 . /*time_t ex
22c0: 70 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 pires = time(0)
22d0: 2b 20 61 74 6f 69 28 64 62 5f 63 6f 6e 66 69 67 + atoi(db_config
22e0: 28 22 63 6f 6e 73 74 61 6e 74 5f 65 78 70 69 72 ("constant_expir
22f0: 65 73 22 2c 22 36 30 34 38 30 30 22 29 29 3b 2a es","604800"));*
2300: 2f 0a 20 20 20 20 74 69 6d 65 5f 74 20 65 78 70 /. time_t exp
2310: 69 72 65 73 20 3d 20 74 69 6d 65 28 30 29 20 2b ires = time(0) +
2320: 20 36 30 34 38 30 30 3b 0a 20 20 20 20 66 70 72 604800;. fpr
2330: 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 intf(g.httpOut,
2340: 22 45 78 70 69 72 65 73 3a 20 25 73 5c 72 5c 6e "Expires: %s\r\n
2350: 22 2c 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 ", cgi_rfc822_da
2360: 74 65 73 74 61 6d 70 28 65 78 70 69 72 65 73 29 testamp(expires)
2370: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 43 6f 6e );. }.. /* Con
2380: 74 65 6e 74 20 69 6e 74 65 6e 64 65 64 20 66 6f tent intended fo
2390: 72 20 6c 6f 67 67 65 64 20 69 6e 20 75 73 65 72 r logged in user
23a0: 73 20 73 68 6f 75 6c 64 20 6f 6e 6c 79 20 62 65 s should only be
23b0: 20 63 61 63 68 65 64 20 69 6e 0a 20 20 2a 2a 20 cached in. **
23c0: 74 68 65 20 62 72 6f 77 73 65 72 2c 20 6e 6f 74 the browser, not
23d0: 20 73 6f 6d 65 20 73 68 61 72 65 64 20 6c 6f 63 some shared loc
23e0: 61 74 69 6f 6e 2e 0a 20 20 2a 2f 0a 20 20 66 70 ation.. */. fp
23f0: 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c rintf(g.httpOut,
2400: 20 22 43 61 63 68 65 2d 63 6f 6e 74 72 6f 6c 3a "Cache-control:
2410: 20 70 72 69 76 61 74 65 5c 72 5c 6e 22 29 3b 0a private\r\n");.
2420: 0a 23 69 66 20 46 4f 53 53 49 4c 5f 49 31 38 4e .#if FOSSIL_I18N
2430: 0a 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 . fprintf(g.htt
2440: 70 4f 75 74 2c 0a 20 20 20 20 20 22 43 6f 6e 74 pOut,. "Cont
2450: 65 6e 74 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 ent-Type: %s; ch
2460: 61 72 73 65 74 3d 25 73 5c 72 5c 6e 22 2c 20 7a arset=%s\r\n", z
2470: 43 6f 6e 74 65 6e 74 54 79 70 65 2c 20 6e 6c 5f ContentType, nl_
2480: 6c 61 6e 67 69 6e 66 6f 28 43 4f 44 45 53 45 54 langinfo(CODESET
2490: 29 29 3b 0a 23 65 6c 73 65 0a 20 20 66 70 72 69 ));.#else. fpri
24a0: 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 0a 20 ntf(g.httpOut,.
24b0: 20 20 20 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 "Content-Typ
24c0: 65 3a 20 25 73 3b 20 63 68 61 72 73 65 74 3d 49 e: %s; charset=I
24d0: 53 4f 2d 38 38 35 39 2d 31 5c 72 5c 6e 22 2c 20 SO-8859-1\r\n",
24e0: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 29 3b 0a 23 zContentType);.#
24f0: 65 6e 64 69 66 0a 20 20 69 66 28 20 73 74 72 63 endif. if( strc
2500: 6d 70 28 7a 43 6f 6e 74 65 6e 74 54 79 70 65 2c mp(zContentType,
2510: 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 "application/x-f
2520: 6f 73 73 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 ossil")==0 ){.
2530: 20 20 63 67 69 5f 63 6f 6d 62 69 6e 65 5f 68 65 cgi_combine_he
2540: 61 64 65 72 5f 61 6e 64 5f 62 6f 64 79 28 29 3b ader_and_body();
2550: 0a 20 20 20 20 62 6c 6f 62 5f 63 6f 6d 70 72 65 . blob_compre
2560: 73 73 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 ss(&cgiContent[0
2570: 5d 2c 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 ], &cgiContent[0
2580: 5d 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 69 ]);. }.. if( i
2590: 52 65 70 6c 79 53 74 61 74 75 73 20 21 3d 20 33 ReplyStatus != 3
25a0: 30 34 20 29 20 7b 0a 20 20 20 20 74 6f 74 61 6c 04 ) {. total
25b0: 5f 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a _size = blob_siz
25c0: 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d e(&cgiContent[0]
25d0: 29 20 2b 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 ) + blob_size(&c
25e0: 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 20 giContent[1]);.
25f0: 20 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 fprintf(g.htt
2600: 70 4f 75 74 2c 20 22 43 6f 6e 74 65 6e 74 2d 4c pOut, "Content-L
2610: 65 6e 67 74 68 3a 20 25 64 5c 72 5c 6e 22 2c 20 ength: %d\r\n",
2620: 74 6f 74 61 6c 5f 73 69 7a 65 29 3b 0a 20 20 7d total_size);. }
2630: 0a 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 . fprintf(g.htt
2640: 70 4f 75 74 2c 20 22 5c 72 5c 6e 22 29 3b 0a 20 pOut, "\r\n");.
2650: 20 69 66 28 20 74 6f 74 61 6c 5f 73 69 7a 65 3e if( total_size>
2660: 30 20 26 26 20 69 52 65 70 6c 79 53 74 61 74 75 0 && iReplyStatu
2670: 73 20 21 3d 20 33 30 34 20 29 7b 0a 20 20 20 20 s != 304 ){.
2680: 69 6e 74 20 69 2c 20 73 69 7a 65 3b 0a 20 20 20 int i, size;.
2690: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 32 3b 20 69 for(i=0; i<2; i
26a0: 2b 2b 29 7b 0a 20 20 20 20 20 20 73 69 7a 65 20 ++){. size
26b0: 3d 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 = blob_size(&cgi
26c0: 43 6f 6e 74 65 6e 74 5b 69 5d 29 3b 0a 20 20 20 Content[i]);.
26d0: 20 20 20 69 66 28 20 73 69 7a 65 3e 30 20 29 7b if( size>0 ){
26e0: 0a 20 20 20 20 20 20 20 20 66 77 72 69 74 65 28 . fwrite(
26f0: 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 69 blob_buffer(&cgi
2700: 43 6f 6e 74 65 6e 74 5b 69 5d 29 2c 20 31 2c 20 Content[i]), 1,
2710: 73 69 7a 65 2c 20 67 2e 68 74 74 70 4f 75 74 29 size, g.httpOut)
2720: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a ;. }. }.
2730: 20 20 7d 0a 20 20 43 47 49 44 45 42 55 47 28 28 }. CGIDEBUG((
2740: 22 44 4f 4e 45 5c 6e 22 29 29 3b 0a 7d 0a 0a 2f "DONE\n"));.}../
2750: 2a 0a 2a 2a 20 44 6f 20 61 20 72 65 64 69 72 65 *.** Do a redire
2760: 63 74 20 72 65 71 75 65 73 74 20 74 6f 20 74 68 ct request to th
2770: 65 20 55 52 4c 20 67 69 76 65 6e 20 69 6e 20 74 e URL given in t
2780: 68 65 20 61 72 67 75 6d 65 6e 74 2e 0a 2a 2a 0a he argument..**.
2790: 2a 2a 20 54 68 65 20 55 52 4c 20 6d 75 73 74 20 ** The URL must
27a0: 62 65 20 72 65 6c 61 74 69 76 65 20 74 6f 20 74 be relative to t
27b0: 68 65 20 62 61 73 65 20 6f 66 20 74 68 65 20 66 he base of the f
27c0: 6f 73 73 69 6c 20 73 65 72 76 65 72 2e 0a 2a 2f ossil server..*/
27d0: 0a 76 6f 69 64 20 63 67 69 5f 72 65 64 69 72 65 .void cgi_redire
27e0: 63 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a ct(const char *z
27f0: 55 52 4c 29 7b 0a 20 20 63 68 61 72 20 2a 7a 4c URL){. char *zL
2800: 6f 63 61 74 69 6f 6e 3b 0a 20 20 43 47 49 44 45 ocation;. CGIDE
2810: 42 55 47 28 28 22 72 65 64 69 72 65 63 74 20 74 BUG(("redirect t
2820: 6f 20 25 73 5c 6e 22 2c 20 7a 55 52 4c 29 29 3b o %s\n", zURL));
2830: 0a 20 20 69 66 28 20 73 74 72 6e 63 6d 70 28 7a . if( strncmp(z
2840: 55 52 4c 2c 22 68 74 74 70 3a 22 2c 35 29 3d 3d URL,"http:",5)==
2850: 30 20 7c 7c 20 73 74 72 6e 63 6d 70 28 7a 55 52 0 || strncmp(zUR
2860: 4c 2c 22 68 74 74 70 73 3a 22 2c 36 29 3d 3d 30 L,"https:",6)==0
2870: 20 7c 7c 20 2a 7a 55 52 4c 3d 3d 27 2f 27 20 29 || *zURL=='/' )
2880: 7b 0a 20 20 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 {. zLocation
2890: 3d 20 6d 70 72 69 6e 74 66 28 22 4c 6f 63 61 74 = mprintf("Locat
28a0: 69 6f 6e 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 55 ion: %s\r\n", zU
28b0: 52 4c 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 RL);. }else{.
28c0: 20 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 zLocation = mp
28d0: 72 69 6e 74 66 28 22 4c 6f 63 61 74 69 6f 6e 3a rintf("Location:
28e0: 20 25 73 2f 25 73 5c 72 5c 6e 22 2c 20 67 2e 7a %s/%s\r\n", g.z
28f0: 42 61 73 65 55 52 4c 2c 20 7a 55 52 4c 29 3b 0a BaseURL, zURL);.
2900: 20 20 7d 0a 20 20 63 67 69 5f 61 70 70 65 6e 64 }. cgi_append
2910: 5f 68 65 61 64 65 72 28 7a 4c 6f 63 61 74 69 6f _header(zLocatio
2920: 6e 29 3b 0a 20 20 63 67 69 5f 72 65 73 65 74 5f n);. cgi_reset_
2930: 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63 67 69 content();. cgi
2940: 5f 70 72 69 6e 74 66 28 22 3c 68 74 6d 6c 3e 5c _printf("<html>\
2950: 6e 3c 70 3e 52 65 64 69 72 65 63 74 20 74 6f 20 n<p>Redirect to
2960: 25 68 3c 2f 70 3e 5c 6e 3c 2f 68 74 6d 6c 3e 5c %h</p>\n</html>\
2970: 6e 22 2c 20 7a 55 52 4c 29 3b 0a 20 20 63 67 69 n", zURL);. cgi
2980: 5f 73 65 74 5f 73 74 61 74 75 73 28 33 30 32 2c _set_status(302,
2990: 20 22 4d 6f 76 65 64 20 54 65 6d 70 6f 72 61 72 "Moved Temporar
29a0: 69 6c 79 22 29 3b 0a 20 20 66 72 65 65 28 7a 4c ily");. free(zL
29b0: 6f 63 61 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f ocation);. cgi_
29c0: 72 65 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 reply();. exit(
29d0: 30 29 3b 0a 7d 0a 76 6f 69 64 20 63 67 69 5f 72 0);.}.void cgi_r
29e0: 65 64 69 72 65 63 74 66 28 63 6f 6e 73 74 20 63 edirectf(const c
29f0: 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e har *zFormat, ..
2a00: 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 .){. va_list ap
2a10: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c ;. va_start(ap,
2a20: 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 20 63 67 69 zFormat);. cgi
2a30: 5f 72 65 64 69 72 65 63 74 28 76 6d 70 72 69 6e _redirect(vmprin
2a40: 74 66 28 7a 46 6f 72 6d 61 74 2c 20 61 70 29 29 tf(zFormat, ap))
2a50: 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a ;. va_end(ap);.
2a60: 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 66 6f 72 6d 61 }../*.** Informa
2a70: 74 69 6f 6e 20 61 62 6f 75 74 20 61 6c 6c 20 71 tion about all q
2a80: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 uery parameters
2a90: 61 6e 64 20 63 6f 6f 6b 69 65 73 20 61 72 65 20 and cookies are
2aa0: 73 74 6f 72 65 64 0a 2a 2a 20 69 6e 20 74 68 65 stored.** in the
2ab0: 73 65 20 76 61 72 69 61 62 6c 65 73 2e 0a 2a 2f se variables..*/
2ac0: 0a 73 74 61 74 69 63 20 69 6e 74 20 6e 41 6c 6c .static int nAll
2ad0: 6f 63 51 50 20 3d 20 30 3b 20 2f 2a 20 53 70 61 ocQP = 0; /* Spa
2ae0: 63 65 20 61 6c 6c 6f 63 61 74 65 64 20 66 6f 72 ce allocated for
2af0: 20 61 50 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 aParamQP[] */.s
2b00: 74 61 74 69 63 20 69 6e 74 20 6e 55 73 65 64 51 tatic int nUsedQ
2b10: 50 20 3d 20 30 3b 20 20 2f 2a 20 53 70 61 63 65 P = 0; /* Space
2b20: 20 61 63 74 75 61 6c 6c 79 20 75 73 65 64 20 69 actually used i
2b30: 6e 20 61 50 61 72 61 6d 51 50 5b 5d 20 2a 2f 0a n aParamQP[] */.
2b40: 73 74 61 74 69 63 20 69 6e 74 20 73 6f 72 74 51 static int sortQ
2b50: 50 20 3d 20 30 3b 20 20 20 2f 2a 20 54 72 75 65 P = 0; /* True
2b60: 20 69 66 20 61 50 61 72 61 6d 51 50 5b 5d 20 6e if aParamQP[] n
2b70: 65 65 64 73 20 73 6f 72 74 69 6e 67 20 2a 2f 0a eeds sorting */.
2b80: 73 74 61 74 69 63 20 69 6e 74 20 73 65 71 51 50 static int seqQP
2b90: 20 3d 20 30 3b 20 20 20 20 2f 2a 20 53 65 71 75 = 0; /* Sequ
2ba0: 65 6e 63 65 20 6e 75 6d 62 65 72 73 20 2a 2f 0a ence numbers */.
2bb0: 73 74 61 74 69 63 20 73 74 72 75 63 74 20 51 50 static struct QP
2bc0: 61 72 61 6d 20 7b 20 20 20 2f 2a 20 4f 6e 65 20 aram { /* One
2bd0: 65 6e 74 72 79 20 66 6f 72 20 65 61 63 68 20 71 entry for each q
2be0: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f uery parameter o
2bf0: 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f r cookie */. co
2c00: 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 3b nst char *zName;
2c10: 20 20 20 20 20 20 20 20 2f 2a 20 50 61 72 61 6d /* Param
2c20: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 6e eter or cookie n
2c30: 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 ame */. const c
2c40: 68 61 72 20 2a 7a 56 61 6c 75 65 3b 20 20 20 20 har *zValue;
2c50: 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f 66 20 74 /* Value of t
2c60: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 he query paramet
2c70: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 2a 2f 0a er or cookie */.
2c80: 20 20 69 6e 74 20 73 65 71 3b 20 20 20 20 20 20 int seq;
2c90: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 4f /* O
2ca0: 72 64 65 72 20 6f 66 20 69 6e 73 65 72 74 69 6f rder of insertio
2cb0: 6e 20 2a 2f 0a 7d 20 2a 61 50 61 72 61 6d 51 50 n */.} *aParamQP
2cc0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a ; /*
2cd0: 20 41 6e 20 61 72 72 61 79 20 6f 66 20 61 6c 6c An array of all
2ce0: 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e 64 20 parameters and
2cf0: 63 6f 6f 6b 69 65 73 20 2a 2f 0a 0a 2f 2a 0a 2a cookies */../*.*
2d00: 2a 20 41 64 64 20 61 6e 6f 74 68 65 72 20 71 75 * Add another qu
2d10: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 ery parameter or
2d20: 20 63 6f 6f 6b 69 65 20 74 6f 20 74 68 65 20 70 cookie to the p
2d30: 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a arameter set..**
2d40: 20 7a 4e 61 6d 65 20 69 73 20 74 68 65 20 6e 61 zName is the na
2d50: 6d 65 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 me of the query
2d60: 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f parameter or coo
2d70: 6b 69 65 20 61 6e 64 20 7a 56 61 6c 75 65 0a 2a kie and zValue.*
2d80: 2a 20 69 73 20 69 74 73 20 66 75 6c 6c 79 20 64 * is its fully d
2d90: 65 63 6f 64 65 64 20 76 61 6c 75 65 2e 0a 2a 2a ecoded value..**
2da0: 0a 2a 2a 20 7a 4e 61 6d 65 20 61 6e 64 20 7a 56 .** zName and zV
2db0: 61 6c 75 65 20 61 72 65 20 6e 6f 74 20 63 6f 70 alue are not cop
2dc0: 69 65 64 20 61 6e 64 20 6d 75 73 74 20 6e 6f 74 ied and must not
2dd0: 20 63 68 61 6e 67 65 20 6f 72 20 62 65 0a 2a 2a change or be.**
2de0: 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 61 66 74 deallocated aft
2df0: 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e 65 20 er this routine
2e00: 72 65 74 75 72 6e 73 2e 0a 2a 2f 0a 76 6f 69 64 returns..*/.void
2e10: 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 cgi_set_paramet
2e20: 65 72 5f 6e 6f 63 6f 70 79 28 63 6f 6e 73 74 20 er_nocopy(const
2e30: 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e char *zName, con
2e40: 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 st char *zValue)
2e50: 7b 0a 20 20 69 66 28 20 6e 41 6c 6c 6f 63 51 50 {. if( nAllocQP
2e60: 3c 3d 6e 55 73 65 64 51 50 20 29 7b 0a 20 20 20 <=nUsedQP ){.
2e70: 20 6e 41 6c 6c 6f 63 51 50 20 3d 20 6e 41 6c 6c nAllocQP = nAll
2e80: 6f 63 51 50 2a 32 20 2b 20 31 30 3b 0a 20 20 20 ocQP*2 + 10;.
2e90: 20 61 50 61 72 61 6d 51 50 20 3d 20 72 65 61 6c aParamQP = real
2ea0: 6c 6f 63 28 20 61 50 61 72 61 6d 51 50 2c 20 6e loc( aParamQP, n
2eb0: 41 6c 6c 6f 63 51 50 2a 73 69 7a 65 6f 66 28 61 AllocQP*sizeof(a
2ec0: 50 61 72 61 6d 51 50 5b 30 5d 29 20 29 3b 0a 20 ParamQP[0]) );.
2ed0: 20 20 20 69 66 28 20 61 50 61 72 61 6d 51 50 3d if( aParamQP=
2ee0: 3d 30 20 29 20 65 78 69 74 28 31 29 3b 0a 20 20 =0 ) exit(1);.
2ef0: 7d 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 }. aParamQP[nUs
2f00: 65 64 51 50 5d 2e 7a 4e 61 6d 65 20 3d 20 7a 4e edQP].zName = zN
2f10: 61 6d 65 3b 0a 20 20 61 50 61 72 61 6d 51 50 5b ame;. aParamQP[
2f20: 6e 55 73 65 64 51 50 5d 2e 7a 56 61 6c 75 65 20 nUsedQP].zValue
2f30: 3d 20 7a 56 61 6c 75 65 3b 0a 20 20 61 50 61 72 = zValue;. aPar
2f40: 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d 2e 73 65 amQP[nUsedQP].se
2f50: 71 20 3d 20 73 65 71 51 50 2b 2b 3b 0a 20 20 6e q = seqQP++;. n
2f60: 55 73 65 64 51 50 2b 2b 3b 0a 20 20 73 6f 72 74 UsedQP++;. sort
2f70: 51 50 20 3d 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a QP = 1;.}../*.**
2f80: 20 41 64 64 20 61 6e 6f 74 68 65 72 20 71 75 65 Add another que
2f90: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 ry parameter or
2fa0: 63 6f 6f 6b 69 65 20 74 6f 20 74 68 65 20 70 61 cookie to the pa
2fb0: 72 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a 20 rameter set..**
2fc0: 7a 4e 61 6d 65 20 69 73 20 74 68 65 20 6e 61 6d zName is the nam
2fd0: 65 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 e of the query p
2fe0: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b arameter or cook
2ff0: 69 65 20 61 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a ie and zValue.**
3000: 20 69 73 20 69 74 73 20 66 75 6c 6c 79 20 64 65 is its fully de
3010: 63 6f 64 65 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a coded value..**.
3020: 2a 2a 20 43 6f 70 69 65 73 20 61 72 65 20 6d 61 ** Copies are ma
3030: 64 65 20 6f 66 20 62 6f 74 68 20 74 68 65 20 7a de of both the z
3040: 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c 75 65 20 Name and zValue
3050: 70 61 72 61 6d 65 74 65 72 73 2e 0a 2a 2f 0a 76 parameters..*/.v
3060: 6f 69 64 20 63 67 69 5f 73 65 74 5f 70 61 72 61 oid cgi_set_para
3070: 6d 65 74 65 72 28 63 6f 6e 73 74 20 63 68 61 72 meter(const char
3080: 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 *zName, const c
3090: 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 har *zValue){.
30a0: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 cgi_set_paramete
30b0: 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 r_nocopy(mprintf
30c0: 28 22 25 73 22 2c 7a 4e 61 6d 65 29 2c 20 6d 70 ("%s",zName), mp
30d0: 72 69 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 rintf("%s",zValu
30e0: 65 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 e));.}../*.** Re
30f0: 70 6c 61 63 65 20 61 20 70 61 72 61 6d 65 74 65 place a paramete
3100: 72 20 77 69 74 68 20 61 20 6e 65 77 20 76 61 6c r with a new val
3110: 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f ue..*/.void cgi_
3120: 72 65 70 6c 61 63 65 5f 70 61 72 61 6d 65 74 65 replace_paramete
3130: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e r(const char *zN
3140: 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 ame, const char
3150: 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 69 6e 74 20 *zValue){. int
3160: 69 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c i;. for(i=0; i<
3170: 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 nUsedQP; i++){.
3180: 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61 50 if( strcmp(aP
3190: 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c aramQP[i].zName,
31a0: 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 zName)==0 ){.
31b0: 20 20 20 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a aParamQP[i].z
31c0: 56 61 6c 75 65 20 3d 20 7a 56 61 6c 75 65 3b 0a Value = zValue;.
31d0: 20 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 return;.
31e0: 20 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 73 65 }. }. cgi_se
31f0: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f t_parameter_noco
3200: 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 py(zName, zValue
3210: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 );.}../*.** Add
3220: 61 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 a query paramete
3230: 72 2e 20 20 54 68 65 20 7a 4e 61 6d 65 20 70 6f r. The zName po
3240: 72 74 69 6f 6e 20 69 73 20 66 69 78 65 64 20 62 rtion is fixed b
3250: 75 74 20 61 20 63 6f 70 79 0a 2a 2a 20 6d 75 73 ut a copy.** mus
3260: 74 20 62 65 20 6d 61 64 65 20 6f 66 20 7a 56 61 t be made of zVa
3270: 6c 75 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 lue..*/.void cgi
3280: 5f 73 65 74 65 6e 76 28 63 6f 6e 73 74 20 63 68 _setenv(const ch
3290: 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 ar *zName, const
32a0: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a char *zValue){.
32b0: 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 cgi_set_parame
32c0: 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 ter_nocopy(zName
32d0: 2c 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a , mprintf("%s",z
32e0: 56 61 6c 75 65 29 29 3b 0a 7d 0a 20 0a 0a 2f 2a Value));.}. ../*
32f0: 0a 2a 2a 20 41 64 64 20 61 20 6c 69 73 74 20 6f .** Add a list o
3300: 66 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 f query paramete
3310: 72 73 20 6f 72 20 63 6f 6f 6b 69 65 73 20 74 6f rs or cookies to
3320: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 73 the parameter s
3330: 65 74 2e 0a 2a 2a 0a 2a 2a 20 45 61 63 68 20 70 et..**.** Each p
3340: 61 72 61 6d 65 74 65 72 20 69 73 20 6f 66 20 74 arameter is of t
3350: 68 65 20 66 6f 72 6d 20 4e 41 4d 45 3d 56 41 4c he form NAME=VAL
3360: 55 45 2e 20 20 42 6f 74 68 20 74 68 65 20 4e 41 UE. Both the NA
3370: 4d 45 20 61 6e 64 20 74 68 65 0a 2a 2a 20 56 41 ME and the.** VA
3380: 4c 55 45 20 6d 61 79 20 62 65 20 75 72 6c 2d 65 LUE may be url-e
3390: 6e 63 6f 64 65 64 20 28 22 2b 22 20 66 6f 72 20 ncoded ("+" for
33a0: 73 70 61 63 65 2c 20 22 25 48 48 22 20 66 6f 72 space, "%HH" for
33b0: 20 6f 74 68 65 72 20 73 70 65 63 69 61 6c 0a 2a other special.*
33c0: 2a 20 63 68 61 72 61 63 74 65 72 73 29 2e 20 20 * characters).
33d0: 42 75 74 20 74 68 69 73 20 72 6f 75 74 69 6e 65 But this routine
33e0: 20 61 73 73 75 6d 65 73 20 74 68 61 74 20 4e 41 assumes that NA
33f0: 4d 45 20 63 6f 6e 74 61 69 6e 73 20 6e 6f 0a 2a ME contains no.*
3400: 2a 20 73 70 65 63 69 61 6c 20 63 68 61 72 61 63 * special charac
3410: 74 65 72 20 61 6e 64 20 74 68 65 72 65 66 6f 72 ter and therefor
3420: 65 20 64 6f 65 73 20 6e 6f 74 20 64 65 63 6f 64 e does not decod
3430: 65 20 69 74 2e 0a 2a 2a 0a 2a 2a 20 49 66 20 4e e it..**.** If N
3440: 41 4d 45 20 62 65 67 69 6e 73 20 77 69 74 68 20 AME begins with
3450: 61 6e 6f 74 68 65 72 20 6f 74 68 65 72 20 74 68 another other th
3460: 61 6e 20 61 20 6c 6f 77 65 72 2d 63 61 73 65 20 an a lower-case
3470: 6c 65 74 74 65 72 20 74 68 65 6e 0a 2a 2a 20 74 letter then.** t
3480: 68 65 20 65 6e 74 69 72 65 20 4e 41 4d 45 3d 56 he entire NAME=V
3490: 41 4c 55 45 20 74 65 72 6d 20 69 73 20 69 67 6e ALUE term is ign
34a0: 6f 72 65 64 2e 20 20 48 65 6e 63 65 3a 0a 2a 2a ored. Hence:.**
34b0: 0a 2a 2a 20 20 20 20 20 20 2a 20 20 63 6f 6f 6b .** * cook
34c0: 69 65 73 20 61 6e 64 20 71 75 65 72 79 20 70 61 ies and query pa
34d0: 72 61 6d 65 74 65 72 73 20 74 68 61 74 20 68 61 rameters that ha
34e0: 76 65 20 75 70 70 65 72 63 61 73 65 20 6e 61 6d ve uppercase nam
34f0: 65 73 0a 2a 2a 20 20 20 20 20 20 20 20 20 61 72 es.** ar
3500: 65 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a e ignored..**.**
3510: 20 20 20 20 20 20 2a 20 20 69 74 20 69 73 20 69 * it is i
3520: 6d 70 6f 73 73 69 62 6c 65 20 66 6f 72 20 61 20 mpossible for a
3530: 63 6f 6f 6b 69 65 20 6f 72 20 71 75 65 72 79 20 cookie or query
3540: 70 61 72 61 6d 65 74 65 72 20 74 6f 0a 2a 2a 20 parameter to.**
3550: 20 20 20 20 20 20 20 20 6f 76 65 72 72 69 64 65 override
3560: 20 74 68 65 20 76 61 6c 75 65 20 6f 66 20 61 6e the value of an
3570: 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 environment var
3580: 69 61 62 6c 65 20 73 69 6e 63 65 0a 2a 2a 20 20 iable since.**
3590: 20 20 20 20 20 20 20 65 6e 76 69 72 6f 6e 6d 65 environme
35a0: 6e 74 20 76 61 72 69 61 62 6c 65 73 20 61 6c 77 nt variables alw
35b0: 61 79 73 20 68 61 76 65 20 75 70 70 65 72 63 61 ays have upperca
35c0: 73 65 20 6e 61 6d 65 73 2e 0a 2a 2a 0a 2a 2a 20 se names..**.**
35d0: 50 61 72 61 6d 65 74 65 72 73 20 61 72 65 20 73 Parameters are s
35e0: 65 70 61 72 61 74 65 64 20 62 79 20 74 68 65 20 eparated by the
35f0: 22 74 65 72 6d 69 6e 61 74 6f 72 22 20 63 68 61 "terminator" cha
3600: 72 61 63 74 65 72 2e 20 20 57 68 69 74 65 73 70 racter. Whitesp
3610: 61 63 65 0a 2a 2a 20 62 65 66 6f 72 65 20 74 68 ace.** before th
3620: 65 20 4e 41 4d 45 20 69 73 20 69 67 6e 6f 72 65 e NAME is ignore
3630: 64 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 d..**.** The inp
3640: 75 74 20 73 74 72 69 6e 67 20 22 7a 22 20 69 73 ut string "z" is
3650: 20 6d 6f 64 69 66 69 65 64 20 62 75 74 20 6e 6f modified but no
3660: 20 63 6f 70 69 65 73 20 69 73 20 6d 61 64 65 2e copies is made.
3670: 20 20 22 7a 22 0a 2a 2a 20 73 68 6f 75 6c 64 20 "z".** should
3680: 6e 6f 74 20 62 65 20 64 65 61 6c 6c 6f 63 61 74 not be deallocat
3690: 65 64 20 6f 72 20 63 68 61 6e 67 65 64 20 61 67 ed or changed ag
36a0: 61 69 6e 20 61 66 74 65 72 20 74 68 69 73 20 72 ain after this r
36b0: 6f 75 74 69 6e 65 0a 2a 2a 20 72 65 74 75 72 6e outine.** return
36c0: 73 20 6f 72 20 69 74 20 77 69 6c 6c 20 63 6f 72 s or it will cor
36d0: 72 75 70 74 20 74 68 65 20 70 61 72 61 6d 65 74 rupt the paramet
36e0: 65 72 20 74 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 er table..*/.sta
36f0: 74 69 63 20 76 6f 69 64 20 61 64 64 5f 70 61 72 tic void add_par
3700: 61 6d 5f 6c 69 73 74 28 63 68 61 72 20 2a 7a 2c am_list(char *z,
3710: 20 69 6e 74 20 74 65 72 6d 69 6e 61 74 6f 72 29 int terminator)
3720: 7b 0a 20 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b {. while( *z ){
3730: 0a 20 20 20 20 63 68 61 72 20 2a 7a 4e 61 6d 65 . char *zName
3740: 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c ;. char *zVal
3750: 75 65 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 ue;. while( i
3760: 73 73 70 61 63 65 28 2a 7a 29 20 29 7b 20 7a 2b sspace(*z) ){ z+
3770: 2b 3b 20 7d 0a 20 20 20 20 7a 4e 61 6d 65 20 3d +; }. zName =
3780: 20 7a 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 2a z;. while( *
3790: 7a 20 26 26 20 2a 7a 21 3d 27 3d 27 20 26 26 20 z && *z!='=' &&
37a0: 2a 7a 21 3d 74 65 72 6d 69 6e 61 74 6f 72 20 29 *z!=terminator )
37b0: 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69 66 28 { z++; }. if(
37c0: 20 2a 7a 3d 3d 27 3d 27 20 29 7b 0a 20 20 20 20 *z=='=' ){.
37d0: 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 *z = 0;.
37e0: 7a 2b 2b 3b 0a 20 20 20 20 20 20 7a 56 61 6c 75 z++;. zValu
37f0: 65 20 3d 20 7a 3b 0a 20 20 20 20 20 20 77 68 69 e = z;. whi
3800: 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 74 65 le( *z && *z!=te
3810: 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b 3b rminator ){ z++;
3820: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20 }. if( *z
3830: 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a 20 3d 20 ){. *z =
3840: 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b 2b 3b 0a 0;. z++;.
3850: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 64 65 }. de
3860: 68 74 74 70 69 7a 65 28 7a 56 61 6c 75 65 29 3b httpize(zValue);
3870: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 . }else{.
3880: 20 20 69 66 28 20 2a 7a 20 29 7b 20 2a 7a 2b 2b if( *z ){ *z++
3890: 20 3d 20 30 3b 20 7d 0a 20 20 20 20 20 20 7a 56 = 0; }. zV
38a0: 61 6c 75 65 20 3d 20 22 22 3b 0a 20 20 20 20 7d alue = "";. }
38b0: 0a 20 20 20 20 69 66 28 20 69 73 6c 6f 77 65 72 . if( islower
38c0: 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 (zName[0]) ){.
38d0: 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 cgi_set_para
38e0: 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 meter_nocopy(zNa
38f0: 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20 20 me, zValue);.
3900: 20 7d 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 }. }.}../*.**
3910: 2a 70 7a 20 69 73 20 61 20 73 74 72 69 6e 67 20 *pz is a string
3920: 74 68 61 74 20 63 6f 6e 73 69 73 74 73 20 6f 66 that consists of
3930: 20 6d 75 6c 74 69 70 6c 65 20 6c 69 6e 65 73 20 multiple lines
3940: 6f 66 20 74 65 78 74 2e 20 20 54 68 69 73 0a 2a of text. This.*
3950: 2a 20 72 6f 75 74 69 6e 65 20 66 69 6e 64 73 20 * routine finds
3960: 74 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 63 the end of the c
3970: 75 72 72 65 6e 74 20 6c 69 6e 65 20 6f 66 20 74 urrent line of t
3980: 65 78 74 20 61 6e 64 20 63 6f 6e 76 65 72 74 73 ext and converts
3990: 0a 2a 2a 20 74 68 65 20 22 5c 6e 22 20 6f 72 20 .** the "\n" or
39a0: 22 5c 72 5c 6e 22 20 74 68 61 74 20 65 6e 64 73 "\r\n" that ends
39b0: 20 74 68 61 74 20 6c 69 6e 65 20 69 6e 74 6f 20 that line into
39c0: 61 20 22 5c 30 30 30 22 2e 20 20 49 74 20 74 68 a "\000". It th
39d0: 65 6e 0a 2a 2a 20 61 64 76 61 6e 63 65 73 20 2a en.** advances *
39e0: 70 7a 20 74 6f 20 74 68 65 20 62 65 67 69 6e 6e pz to the beginn
39f0: 69 6e 67 20 6f 66 20 74 68 65 20 6e 65 78 74 20 ing of the next
3a00: 6c 69 6e 65 20 61 6e 64 20 72 65 74 75 72 6e 73 line and returns
3a10: 20 74 68 65 0a 2a 2a 20 70 72 65 76 69 6f 75 73 the.** previous
3a20: 20 76 61 6c 75 65 20 6f 66 20 2a 70 7a 20 28 77 value of *pz (w
3a30: 68 69 63 68 20 69 73 20 74 68 65 20 73 74 61 72 hich is the star
3a40: 74 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e 74 t of the current
3a50: 20 6c 69 6e 65 2e 29 0a 2a 2f 0a 73 74 61 74 69 line.).*/.stati
3a60: 63 20 63 68 61 72 20 2a 67 65 74 5f 6c 69 6e 65 c char *get_line
3a70: 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 63 68 61 _from_string(cha
3a80: 72 20 2a 2a 70 7a 2c 20 69 6e 74 20 2a 70 4c 65 r **pz, int *pLe
3a90: 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 n){. char *z =
3aa0: 2a 70 7a 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 *pz;. int i;.
3ab0: 69 66 28 20 7a 5b 30 5d 3d 3d 30 20 29 20 72 65 if( z[0]==0 ) re
3ac0: 74 75 72 6e 20 30 3b 0a 20 20 66 6f 72 28 69 3d turn 0;. for(i=
3ad0: 30 3b 20 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 0; z[i]; i++){.
3ae0: 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e if( z[i]=='\n
3af0: 27 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 69 ' ){. if( i
3b00: 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d 3d 27 5c >0 && z[i-1]=='\
3b10: 72 27 20 29 7b 0a 20 20 20 20 20 20 20 20 7a 5b r' ){. z[
3b20: 69 2d 31 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 i-1] = 0;.
3b30: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 7a }else{. z
3b40: 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 7d [i] = 0;. }
3b50: 0a 20 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 . i++;.
3b60: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 break;. }.
3b70: 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a 5b 69 5d }. *pz = &z[i]
3b80: 3b 0a 20 20 2a 70 4c 65 6e 20 2d 3d 20 69 3b 0a ;. *pLen -= i;.
3b90: 20 20 72 65 74 75 72 6e 20 7a 3b 0a 7d 0a 0a 2f return z;.}../
3ba0: 2a 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74 20 2a *.** The input *
3bb0: 70 7a 20 70 6f 69 6e 74 73 20 74 6f 20 63 6f 6e pz points to con
3bc0: 74 65 6e 74 20 74 68 61 74 20 69 73 20 74 65 72 tent that is ter
3bd0: 6d 69 6e 61 74 65 64 20 62 79 20 61 20 22 5c 72 minated by a "\r
3be0: 5c 6e 22 0a 2a 2a 20 66 6f 6c 6c 6f 77 65 64 20 \n".** followed
3bf0: 62 79 20 74 68 65 20 62 6f 75 6e 64 72 79 20 6d by the boundry m
3c00: 61 72 6b 65 72 20 7a 42 6f 75 6e 64 72 79 2e 20 arker zBoundry.
3c10: 20 41 6e 20 65 78 74 72 61 20 22 2d 2d 22 20 6d An extra "--" m
3c20: 61 79 20 6f 72 0a 2a 2a 20 6d 61 79 20 6e 6f 74 ay or.** may not
3c30: 20 62 65 20 61 70 70 65 6e 64 65 64 20 74 6f 20 be appended to
3c40: 74 68 65 20 62 6f 75 6e 64 72 79 20 6d 61 72 6b the boundry mark
3c50: 65 72 2e 20 20 54 68 65 72 65 20 61 72 65 20 2a er. There are *
3c60: 70 4c 65 6e 20 63 68 61 72 61 63 74 65 72 73 0a pLen characters.
3c70: 2a 2a 20 69 6e 20 2a 70 7a 2e 0a 2a 2a 0a 2a 2a ** in *pz..**.**
3c80: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 61 64 This routine ad
3c90: 64 73 20 61 20 22 5c 30 30 30 22 20 74 6f 20 74 ds a "\000" to t
3ca0: 68 65 20 65 6e 64 20 6f 66 20 74 68 65 20 63 6f he end of the co
3cb0: 6e 74 65 6e 74 20 28 6f 76 65 72 77 72 69 74 69 ntent (overwriti
3cc0: 6e 67 0a 2a 2a 20 74 68 65 20 22 5c 72 5c 6e 22 ng.** the "\r\n"
3cd0: 29 20 61 6e 64 20 72 65 74 75 72 6e 73 20 61 20 ) and returns a
3ce0: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 63 pointer to the c
3cf0: 6f 6e 74 65 6e 74 2e 20 20 54 68 65 20 2a 70 7a ontent. The *pz
3d00: 20 69 6e 70 75 74 0a 2a 2a 20 69 73 20 61 64 6a input.** is adj
3d10: 75 73 74 65 64 20 74 6f 20 70 6f 69 6e 74 20 74 usted to point t
3d20: 6f 20 74 68 65 20 66 69 72 73 74 20 6c 69 6e 65 o the first line
3d30: 20 66 6f 6c 6c 6f 77 69 6e 67 20 74 68 65 20 62 following the b
3d40: 6f 75 6e 64 72 79 2e 0a 2a 2a 20 54 68 65 20 6c oundry..** The l
3d50: 65 6e 67 74 68 20 6f 66 20 74 68 65 20 63 6f 6e ength of the con
3d60: 74 65 6e 74 20 69 73 20 73 74 6f 72 65 64 20 69 tent is stored i
3d70: 6e 20 2a 70 6e 43 6f 6e 74 65 6e 74 2e 0a 2a 2f n *pnContent..*/
3d80: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 67 65 .static char *ge
3d90: 74 5f 62 6f 75 6e 64 65 64 5f 63 6f 6e 74 65 6e t_bounded_conten
3da0: 74 28 0a 20 20 63 68 61 72 20 2a 2a 70 7a 2c 20 t(. char **pz,
3db0: 20 20 20 20 20 20 20 20 2f 2a 20 43 6f 6e 74 65 /* Conte
3dc0: 6e 74 20 74 61 6b 65 6e 20 66 72 6f 6d 20 68 65 nt taken from he
3dd0: 72 65 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 4c 65 re */. int *pLe
3de0: 6e 2c 20 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 n, /* Nu
3df0: 6d 62 65 72 20 6f 66 20 62 79 74 65 73 20 6f 66 mber of bytes of
3e00: 20 64 61 74 61 20 69 6e 20 28 2a 70 7a 29 5b 5d data in (*pz)[]
3e10: 20 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 42 6f 75 */. char *zBou
3e20: 6e 64 72 79 2c 20 20 20 20 2f 2a 20 42 6f 75 6e ndry, /* Boun
3e30: 64 72 79 20 74 65 78 74 20 6d 61 72 6b 69 6e 67 dry text marking
3e40: 20 74 68 65 20 65 6e 64 20 6f 66 20 63 6f 6e 74 the end of cont
3e50: 65 6e 74 20 2a 2f 0a 20 20 69 6e 74 20 2a 70 6e ent */. int *pn
3e60: 43 6f 6e 74 65 6e 74 20 20 20 20 20 2f 2a 20 57 Content /* W
3e70: 72 69 74 65 20 74 68 65 20 73 69 7a 65 20 6f 66 rite the size of
3e80: 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 68 65 72 the content her
3e90: 65 20 2a 2f 0a 29 7b 0a 20 20 63 68 61 72 20 2a e */.){. char *
3ea0: 7a 20 3d 20 2a 70 7a 3b 0a 20 20 69 6e 74 20 6c z = *pz;. int l
3eb0: 65 6e 20 3d 20 2a 70 4c 65 6e 3b 0a 20 20 69 6e en = *pLen;. in
3ec0: 74 20 69 3b 0a 20 20 69 6e 74 20 6e 42 6f 75 6e t i;. int nBoun
3ed0: 64 72 79 20 3d 20 73 74 72 6c 65 6e 28 7a 42 6f dry = strlen(zBo
3ee0: 75 6e 64 72 79 29 3b 0a 20 20 2a 70 6e 43 6f 6e undry);. *pnCon
3ef0: 74 65 6e 74 20 3d 20 6c 65 6e 3b 0a 20 20 66 6f tent = len;. fo
3f00: 72 28 69 3d 30 3b 20 69 3c 6c 65 6e 3b 20 69 2b r(i=0; i<len; i+
3f10: 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a 5b 69 5d +){. if( z[i]
3f20: 3d 3d 27 5c 6e 27 20 26 26 20 73 74 72 6e 63 6d =='\n' && strncm
3f30: 70 28 7a 42 6f 75 6e 64 72 79 2c 20 26 7a 5b 69 p(zBoundry, &z[i
3f40: 2b 31 5d 2c 20 6e 42 6f 75 6e 64 72 79 29 3d 3d +1], nBoundry)==
3f50: 30 20 29 7b 0a 20 20 20 20 20 20 69 66 28 20 69 0 ){. if( i
3f60: 3e 30 20 26 26 20 7a 5b 69 2d 31 5d 3d 3d 27 5c >0 && z[i-1]=='\
3f70: 72 27 20 29 20 69 2d 2d 3b 0a 20 20 20 20 20 20 r' ) i--;.
3f80: 7a 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 z[i] = 0;.
3f90: 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d 20 69 3b 0a *pnContent = i;.
3fa0: 20 20 20 20 20 20 69 20 2b 3d 20 6e 42 6f 75 6e i += nBoun
3fb0: 64 72 79 3b 0a 20 20 20 20 20 20 62 72 65 61 6b dry;. break
3fc0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 ;. }. }. *p
3fd0: 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 67 65 74 z = &z[i];. get
3fe0: 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e _line_from_strin
3ff0: 67 28 70 7a 2c 20 70 4c 65 6e 29 3b 0a 20 20 72 g(pz, pLen);. r
4000: 65 74 75 72 6e 20 7a 3b 20 20 20 20 20 20 0a 7d eturn z; .}
4010: 0a 0a 2f 2a 0a 2a 2a 20 54 6f 6b 65 6e 69 7a 65 ../*.** Tokenize
4020: 20 61 20 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 a line of text
4030: 69 6e 74 6f 20 61 73 20 6d 61 6e 79 20 61 73 20 into as many as
4040: 6e 41 72 67 20 74 6f 6b 65 6e 73 2e 20 20 4d 61 nArg tokens. Ma
4050: 6b 65 0a 2a 2a 20 61 7a 41 72 67 5b 5d 20 70 6f ke.** azArg[] po
4060: 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72 74 int to the start
4070: 20 6f 66 20 65 61 63 68 20 74 6f 6b 65 6e 2e 0a of each token..
4080: 2a 2a 0a 2a 2a 20 54 6f 6b 65 6e 73 20 63 6f 6e **.** Tokens con
4090: 73 69 73 74 20 6f 66 20 73 70 61 63 65 20 6f 72 sist of space or
40a0: 20 73 65 6d 69 2d 63 6f 6c 6f 6e 20 64 65 6c 69 semi-colon deli
40b0: 6d 69 74 65 64 20 77 6f 72 64 73 20 6f 72 0a 2a mited words or.*
40c0: 2a 20 73 74 72 69 6e 67 73 20 69 6e 73 69 64 65 * strings inside
40d0: 20 64 6f 75 62 6c 65 2d 71 75 6f 74 65 73 2e 20 double-quotes.
40e0: 20 45 78 61 6d 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 Example:.**.**
40f0: 20 20 20 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f content-dispo
4100: 73 69 74 69 6f 6e 3a 20 66 6f 72 6d 2d 64 61 74 sition: form-dat
4110: 61 3b 20 6e 61 6d 65 3d 22 66 6e 22 3b 20 66 69 a; name="fn"; fi
4120: 6c 65 6e 61 6d 65 3d 22 69 6e 64 65 78 2e 68 74 lename="index.ht
4130: 6d 6c 22 0a 2a 2a 0a 2a 2a 20 54 68 65 20 6c 69 ml".**.** The li
4140: 6e 65 20 61 62 6f 76 65 20 69 73 20 74 6f 6b 65 ne above is toke
4150: 6e 69 7a 65 64 20 61 73 20 66 6f 6c 6c 6f 77 73 nized as follows
4160: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 61 7a 41 72 67 :.**.** azArg
4170: 5b 30 5d 20 3d 20 22 63 6f 6e 74 65 6e 74 2d 64 [0] = "content-d
4180: 69 73 70 6f 73 69 74 69 6f 6e 3a 22 0a 2a 2a 20 isposition:".**
4190: 20 20 20 61 7a 41 72 67 5b 31 5d 20 3d 20 22 66 azArg[1] = "f
41a0: 6f 72 6d 2d 64 61 74 61 22 0a 2a 2a 20 20 20 20 orm-data".**
41b0: 61 7a 41 72 67 5b 32 5d 20 3d 20 22 6e 61 6d 65 azArg[2] = "name
41c0: 3d 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 33 =".** azArg[3
41d0: 5d 20 3d 20 22 66 6e 22 0a 2a 2a 20 20 20 20 61 ] = "fn".** a
41e0: 7a 41 72 67 5b 34 5d 20 3d 20 22 66 69 6c 65 6e zArg[4] = "filen
41f0: 61 6d 65 3d 22 0a 2a 2a 20 20 20 20 61 7a 41 72 ame=".** azAr
4200: 67 5b 35 5d 20 3d 20 22 69 6e 64 65 78 2e 68 74 g[5] = "index.ht
4210: 6d 6c 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b ml".** azArg[
4220: 36 5d 20 3d 20 30 3b 0a 2a 2a 0a 2a 2a 20 27 5c 6] = 0;.**.** '\
4230: 30 30 30 27 20 63 68 61 72 61 63 74 65 72 73 20 000' characters
4240: 61 72 65 20 69 6e 73 65 72 74 65 64 20 69 6e 20 are inserted in
4250: 7a 5b 5d 20 61 74 20 74 68 65 20 65 6e 64 20 6f z[] at the end o
4260: 66 20 65 61 63 68 20 74 6f 6b 65 6e 2e 0a 2a 2a f each token..**
4270: 20 54 68 69 73 20 72 6f 75 74 69 6e 65 20 72 65 This routine re
4280: 74 75 72 6e 73 20 74 68 65 20 74 6f 74 61 6c 20 turns the total
4290: 6e 75 6d 62 65 72 20 6f 66 20 74 6f 6b 65 6e 73 number of tokens
42a0: 20 6f 6e 20 74 68 65 20 6c 69 6e 65 2c 20 36 0a on the line, 6.
42b0: 2a 2a 20 69 6e 20 74 68 65 20 65 78 61 6d 70 6c ** in the exampl
42c0: 65 20 61 62 6f 76 65 2e 0a 2a 2f 0a 73 74 61 74 e above..*/.stat
42d0: 69 63 20 69 6e 74 20 74 6f 6b 65 6e 69 7a 65 5f ic int tokenize_
42e0: 6c 69 6e 65 28 63 68 61 72 20 2a 7a 2c 20 69 6e line(char *z, in
42f0: 74 20 6d 78 41 72 67 2c 20 63 68 61 72 20 2a 2a t mxArg, char **
4300: 61 7a 41 72 67 29 7b 0a 20 20 69 6e 74 20 69 20 azArg){. int i
4310: 3d 20 30 3b 0a 20 20 77 68 69 6c 65 28 20 2a 7a = 0;. while( *z
4320: 20 29 7b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 ){. while( i
4330: 73 73 70 61 63 65 28 2a 7a 29 20 7c 7c 20 2a 7a sspace(*z) || *z
4340: 3d 3d 27 3b 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a ==';' ){ z++; }.
4350: 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27 22 27 20 if( *z=='"'
4360: 26 26 20 7a 5b 31 5d 20 29 7b 0a 20 20 20 20 20 && z[1] ){.
4370: 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a *z = 0;. z
4380: 2b 2b 3b 0a 20 20 20 20 20 20 69 66 28 20 69 3c ++;. if( i<
4390: 6d 78 41 72 67 2d 31 20 29 7b 20 61 7a 41 72 67 mxArg-1 ){ azArg
43a0: 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a 20 20 20 [i++] = z; }.
43b0: 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 while( *z &&
43c0: 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b 20 *z!='"' ){ z++;
43d0: 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 3d 3d }. if( *z==
43e0: 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 20 20 20 0 ) break;.
43f0: 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a *z = 0;. z
4400: 2b 2b 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 ++;. }else{.
4410: 20 20 20 20 20 69 66 28 20 69 3c 6d 78 41 72 67 if( i<mxArg
4420: 2d 31 20 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d -1 ){ azArg[i++]
4430: 20 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68 = z; }. wh
4440: 69 6c 65 28 20 2a 7a 20 26 26 20 21 69 73 73 70 ile( *z && !issp
4450: 61 63 65 28 2a 7a 29 20 26 26 20 2a 7a 21 3d 27 ace(*z) && *z!='
4460: 3b 27 20 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b ;' && *z!='"' ){
4470: 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 69 66 z++; }. if
4480: 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 22 27 20 ( *z && *z!='"'
4490: 29 7b 0a 20 20 20 20 20 20 20 20 2a 7a 20 3d 20 ){. *z =
44a0: 30 3b 0a 20 20 20 20 20 20 20 20 7a 2b 2b 3b 0a 0;. z++;.
44b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 }. }.
44c0: 7d 0a 20 20 61 7a 41 72 67 5b 69 5d 20 3d 20 30 }. azArg[i] = 0
44d0: 3b 0a 20 20 72 65 74 75 72 6e 20 69 3b 0a 7d 0a ;. return i;.}.
44e0: 0a 2f 2a 0a 2a 2a 20 53 63 61 6e 20 74 68 65 20 ./*.** Scan the
44f0: 6d 75 6c 74 69 70 61 72 74 2d 66 6f 72 6d 20 63 multipart-form c
4500: 6f 6e 74 65 6e 74 20 61 6e 64 20 6d 61 6b 65 20 ontent and make
4510: 61 70 70 72 6f 70 72 69 61 74 65 20 65 6e 74 72 appropriate entr
4520: 69 65 73 0a 2a 2a 20 69 6e 74 6f 20 74 68 65 20 ies.** into the
4530: 70 61 72 61 6d 65 74 65 72 20 74 61 62 6c 65 2e parameter table.
4540: 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 6f 6e 74 65 .**.** The conte
4550: 6e 74 20 73 74 72 69 6e 67 20 22 7a 22 20 69 73 nt string "z" is
4560: 20 6d 6f 64 69 66 69 65 64 20 62 79 20 74 68 69 modified by thi
4570: 73 20 72 6f 75 74 69 6e 65 20 62 75 74 20 69 74 s routine but it
4580: 20 69 73 0a 2a 2a 20 6e 6f 74 20 63 6f 70 69 65 is.** not copie
4590: 64 2e 20 20 54 68 65 20 63 61 6c 6c 69 6e 67 20 d. The calling
45a0: 66 75 6e 63 74 69 6f 6e 20 6d 75 73 74 20 6e 6f function must no
45b0: 74 20 64 65 61 6c 6c 6f 63 61 74 65 20 6f 72 20 t deallocate or
45c0: 6d 6f 64 69 66 79 0a 2a 2a 20 22 7a 22 20 61 66 modify.** "z" af
45d0: 74 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e 65 ter this routine
45e0: 20 66 69 6e 69 73 68 65 73 20 6f 72 20 69 74 20 finishes or it
45f0: 63 6f 75 6c 64 20 63 6f 72 72 75 70 74 20 74 68 could corrupt th
4600: 65 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 74 e parameter.** t
4610: 61 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 able..*/.static
4620: 76 6f 69 64 20 70 72 6f 63 65 73 73 5f 6d 75 6c void process_mul
4630: 74 69 70 61 72 74 5f 66 6f 72 6d 5f 64 61 74 61 tipart_form_data
4640: 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6c 65 (char *z, int le
4650: 6e 29 7b 0a 20 20 63 68 61 72 20 2a 7a 4c 69 6e n){. char *zLin
4660: 65 3b 0a 20 20 69 6e 74 20 6e 41 72 67 2c 20 69 e;. int nArg, i
4670: 3b 0a 20 20 63 68 61 72 20 2a 7a 42 6f 75 6e 64 ;. char *zBound
4680: 72 79 3b 0a 20 20 63 68 61 72 20 2a 7a 56 61 6c ry;. char *zVal
4690: 75 65 3b 0a 20 20 63 68 61 72 20 2a 7a 4e 61 6d ue;. char *zNam
46a0: 65 20 3d 20 30 3b 0a 20 20 69 6e 74 20 73 68 6f e = 0;. int sho
46b0: 77 42 79 74 65 73 20 3d 20 30 3b 0a 20 20 63 68 wBytes = 0;. ch
46c0: 61 72 20 2a 61 7a 41 72 67 5b 35 30 5d 3b 0a 0a ar *azArg[50];..
46d0: 20 20 7a 42 6f 75 6e 64 72 79 20 3d 20 67 65 74 zBoundry = get
46e0: 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e _line_from_strin
46f0: 67 28 26 7a 2c 20 26 6c 65 6e 29 3b 0a 20 20 69 g(&z, &len);. i
4700: 66 28 20 7a 42 6f 75 6e 64 72 79 3d 3d 30 20 29 f( zBoundry==0 )
4710: 20 72 65 74 75 72 6e 3b 0a 20 20 77 68 69 6c 65 return;. while
4720: 28 20 28 7a 4c 69 6e 65 20 3d 20 67 65 74 5f 6c ( (zLine = get_l
4730: 69 6e 65 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 ine_from_string(
4740: 26 7a 2c 20 26 6c 65 6e 29 29 21 3d 30 20 29 7b &z, &len))!=0 ){
4750: 0a 20 20 20 20 69 66 28 20 7a 4c 69 6e 65 5b 30 . if( zLine[0
4760: 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 69 6e ]==0 ){. in
4770: 74 20 6e 43 6f 6e 74 65 6e 74 20 3d 20 30 3b 0a t nContent = 0;.
4780: 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 67 zValue = g
4790: 65 74 5f 62 6f 75 6e 64 65 64 5f 63 6f 6e 74 65 et_bounded_conte
47a0: 6e 74 28 26 7a 2c 20 26 6c 65 6e 2c 20 7a 42 6f nt(&z, &len, zBo
47b0: 75 6e 64 72 79 2c 20 26 6e 43 6f 6e 74 65 6e 74 undry, &nContent
47c0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 4e 61 );. if( zNa
47d0: 6d 65 20 26 26 20 7a 56 61 6c 75 65 20 26 26 20 me && zValue &&
47e0: 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 5d islower(zName[0]
47f0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 63 67 69 ) ){. cgi
4800: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e _set_parameter_n
4810: 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 ocopy(zName, zVa
4820: 6c 75 65 29 3b 0a 20 20 20 20 20 20 20 20 69 66 lue);. if
4830: 28 20 73 68 6f 77 42 79 74 65 73 20 29 7b 0a 20 ( showBytes ){.
4840: 20 20 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 cgi_set
4850: 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 _parameter_nocop
4860: 79 28 6d 70 72 69 6e 74 66 28 22 25 73 3a 62 79 y(mprintf("%s:by
4870: 74 65 73 22 2c 20 7a 4e 61 6d 65 29 2c 0a 20 20 tes", zName),.
4880: 20 20 20 20 20 20 20 20 20 20 20 20 20 6d 70 72 mpr
4890: 69 6e 74 66 28 22 25 64 22 2c 6e 43 6f 6e 74 65 intf("%d",nConte
48a0: 6e 74 29 29 3b 0a 20 20 20 20 20 20 20 20 7d 0a nt));. }.
48b0: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7a 4e }. zN
48c0: 61 6d 65 20 3d 20 30 3b 0a 20 20 20 20 20 20 73 ame = 0;. s
48d0: 68 6f 77 42 79 74 65 73 20 3d 20 30 3b 0a 20 20 howBytes = 0;.
48e0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6e }else{. n
48f0: 41 72 67 20 3d 20 74 6f 6b 65 6e 69 7a 65 5f 6c Arg = tokenize_l
4900: 69 6e 65 28 7a 4c 69 6e 65 2c 20 73 69 7a 65 6f ine(zLine, sizeo
4910: 66 28 61 7a 41 72 67 29 2f 73 69 7a 65 6f 66 28 f(azArg)/sizeof(
4920: 61 7a 41 72 67 5b 30 5d 29 2c 20 61 7a 41 72 67 azArg[0]), azArg
4930: 29 3b 0a 20 20 20 20 20 20 66 6f 72 28 69 3d 30 );. for(i=0
4940: 3b 20 69 3c 6e 41 72 67 3b 20 69 2b 2b 29 7b 0a ; i<nArg; i++){.
4950: 20 20 20 20 20 20 20 20 69 6e 74 20 63 20 3d 20 int c =
4960: 74 6f 6c 6f 77 65 72 28 61 7a 41 72 67 5b 69 5d tolower(azArg[i]
4970: 5b 30 5d 29 3b 0a 20 20 20 20 20 20 20 20 69 66 [0]);. if
4980: 28 20 63 3d 3d 27 63 27 20 26 26 20 73 74 72 69 ( c=='c' && stri
4990: 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 63 6f cmp(azArg[i],"co
49a0: 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f ntent-dispositio
49b0: 6e 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 n:")==0 ){.
49c0: 20 20 20 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 i++;.
49d0: 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 }else if( c=='
49e0: 6e 27 20 26 26 20 73 74 72 69 63 6d 70 28 61 7a n' && stricmp(az
49f0: 41 72 67 5b 69 5d 2c 22 6e 61 6d 65 3d 22 29 3d Arg[i],"name=")=
4a00: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 =0 ){.
4a10: 7a 4e 61 6d 65 20 3d 20 61 7a 41 72 67 5b 2b 2b zName = azArg[++
4a20: 69 5d 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 i];. }els
4a30: 65 20 69 66 28 20 63 3d 3d 27 66 27 20 26 26 20 e if( c=='f' &&
4a40: 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d stricmp(azArg[i]
4a50: 2c 22 66 69 6c 65 6e 61 6d 65 3d 22 29 3d 3d 30 ,"filename=")==0
4a60: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63 68 ){. ch
4a70: 61 72 20 2a 7a 20 3d 20 61 7a 41 72 67 5b 2b 2b ar *z = azArg[++
4a80: 69 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 69 66 i];. if
4a90: 28 20 7a 4e 61 6d 65 20 26 26 20 7a 20 26 26 20 ( zName && z &&
4aa0: 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 5d islower(zName[0]
4ab0: 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 ) ){.
4ac0: 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 cgi_set_paramet
4ad0: 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 er_nocopy(mprint
4ae0: 66 28 22 25 73 3a 66 69 6c 65 6e 61 6d 65 22 2c f("%s:filename",
4af0: 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a 20 20 20 20 zName), z);.
4b00: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 20 }.
4b10: 20 20 73 68 6f 77 42 79 74 65 73 20 3d 20 31 3b showBytes = 1;
4b20: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 . }else i
4b30: 66 28 20 63 3d 3d 27 63 27 20 26 26 20 73 74 72 f( c=='c' && str
4b40: 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 63 icmp(azArg[i],"c
4b50: 6f 6e 74 65 6e 74 2d 74 79 70 65 3a 22 29 3d 3d ontent-type:")==
4b60: 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 63 0 ){. c
4b70: 68 61 72 20 2a 7a 20 3d 20 61 7a 41 72 67 5b 2b har *z = azArg[+
4b80: 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 20 20 69 +i];. i
4b90: 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a 20 26 26 f( zName && z &&
4ba0: 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 islower(zName[0
4bb0: 5d 29 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 ]) ){.
4bc0: 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 cgi_set_parame
4bd0: 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e ter_nocopy(mprin
4be0: 74 66 28 22 25 73 3a 6d 69 6d 65 74 79 70 65 22 tf("%s:mimetype"
4bf0: 2c 7a 4e 61 6d 65 29 2c 20 7a 29 3b 0a 20 20 20 ,zName), z);.
4c00: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 20 }.
4c10: 20 7d 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d }. }. }
4c20: 0a 20 20 7d 20 20 20 20 20 20 20 20 0a 7d 0a 0a . } .}..
4c30: 2f 2a 0a 2a 2a 20 49 6e 69 74 69 61 6c 69 7a 65 /*.** Initialize
4c40: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d the query param
4c50: 65 74 65 72 20 64 61 74 61 62 61 73 65 2e 20 20 eter database.
4c60: 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 69 73 20 70 Information is p
4c70: 75 6c 6c 65 64 20 66 72 6f 6d 0a 2a 2a 20 74 68 ulled from.** th
4c80: 65 20 51 55 45 52 59 5f 53 54 52 49 4e 47 20 65 e QUERY_STRING e
4c90: 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 nvironment varia
4ca0: 62 6c 65 20 28 69 66 20 69 74 20 65 78 69 73 74 ble (if it exist
4cb0: 73 29 2c 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 s), from standar
4cc0: 64 0a 2a 2a 20 69 6e 70 75 74 20 69 66 20 74 68 d.** input if th
4cd0: 65 72 65 20 69 73 20 50 4f 53 54 20 64 61 74 61 ere is POST data
4ce0: 2c 20 61 6e 64 20 66 72 6f 6d 20 48 54 54 50 5f , and from HTTP_
4cf0: 43 4f 4f 4b 49 45 2e 0a 2a 2f 0a 76 6f 69 64 20 COOKIE..*/.void
4d00: 63 67 69 5f 69 6e 69 74 28 76 6f 69 64 29 7b 0a cgi_init(void){.
4d10: 20 20 63 68 61 72 20 2a 7a 3b 0a 20 20 63 6f 6e char *z;. con
4d20: 73 74 20 63 68 61 72 20 2a 7a 54 79 70 65 3b 0a st char *zType;.
4d30: 20 20 69 6e 74 20 6c 65 6e 3b 0a 20 20 63 67 69 int len;. cgi
4d40: 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 43 47 49 _destination(CGI
4d50: 5f 42 4f 44 59 29 3b 0a 20 20 7a 20 3d 20 28 63 _BODY);. z = (c
4d60: 68 61 72 2a 29 50 28 22 51 55 45 52 59 5f 53 54 har*)P("QUERY_ST
4d70: 52 49 4e 47 22 29 3b 0a 20 20 69 66 28 20 7a 20 RING");. if( z
4d80: 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e ){. z = mprin
4d90: 74 66 28 22 25 73 22 2c 7a 29 3b 0a 20 20 20 20 tf("%s",z);.
4da0: 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a add_param_list(z
4db0: 2c 20 27 26 27 29 3b 0a 20 20 7d 0a 0a 20 20 6c , '&');. }.. l
4dc0: 65 6e 20 3d 20 61 74 6f 69 28 50 44 28 22 43 4f en = atoi(PD("CO
4dd0: 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 22 NTENT_LENGTH", "
4de0: 30 22 29 29 3b 0a 20 20 67 2e 7a 43 6f 6e 74 65 0"));. g.zConte
4df0: 6e 74 54 79 70 65 20 3d 20 7a 54 79 70 65 20 3d ntType = zType =
4e00: 20 50 28 22 43 4f 4e 54 45 4e 54 5f 54 59 50 45 P("CONTENT_TYPE
4e10: 22 29 3b 0a 20 20 69 66 28 20 6c 65 6e 3e 30 20 ");. if( len>0
4e20: 26 26 20 7a 54 79 70 65 20 29 7b 0a 20 20 20 20 && zType ){.
4e30: 62 6c 6f 62 5f 7a 65 72 6f 28 26 67 2e 63 67 69 blob_zero(&g.cgi
4e40: 49 6e 29 3b 0a 20 20 20 20 69 66 28 20 73 74 72 In);. if( str
4e50: 63 6d 70 28 7a 54 79 70 65 2c 22 61 70 70 6c 69 cmp(zType,"appli
4e60: 63 61 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 cation/x-www-for
4e70: 6d 2d 75 72 6c 65 6e 63 6f 64 65 64 22 29 3d 3d m-urlencoded")==
4e80: 30 20 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 73 0 . || s
4e90: 74 72 6e 63 6d 70 28 7a 54 79 70 65 2c 22 6d 75 trncmp(zType,"mu
4ea0: 6c 74 69 70 61 72 74 2f 66 6f 72 6d 2d 64 61 74 ltipart/form-dat
4eb0: 61 22 2c 31 39 29 3d 3d 30 20 29 7b 0a 20 20 20 a",19)==0 ){.
4ec0: 20 20 20 7a 20 3d 20 6d 61 6c 6c 6f 63 28 20 6c z = malloc( l
4ed0: 65 6e 2b 31 20 29 3b 0a 20 20 20 20 20 20 69 66 en+1 );. if
4ee0: 28 20 7a 3d 3d 30 20 29 20 65 78 69 74 28 31 29 ( z==0 ) exit(1)
4ef0: 3b 0a 20 20 20 20 20 20 6c 65 6e 20 3d 20 66 72 ;. len = fr
4f00: 65 61 64 28 7a 2c 20 31 2c 20 6c 65 6e 2c 20 67 ead(z, 1, len, g
4f10: 2e 68 74 74 70 49 6e 29 3b 0a 20 20 20 20 20 20 .httpIn);.
4f20: 7a 5b 6c 65 6e 5d 20 3d 20 30 3b 0a 20 20 20 20 z[len] = 0;.
4f30: 20 20 69 66 28 20 7a 54 79 70 65 5b 30 5d 3d 3d if( zType[0]==
4f40: 27 61 27 20 29 7b 0a 20 20 20 20 20 20 20 20 61 'a' ){. a
4f50: 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c dd_param_list(z,
4f60: 20 27 26 27 29 3b 0a 20 20 20 20 20 20 7d 65 6c '&');. }el
4f70: 73 65 7b 0a 20 20 20 20 20 20 20 20 70 72 6f 63 se{. proc
4f80: 65 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66 6f ess_multipart_fo
4f90: 72 6d 5f 64 61 74 61 28 7a 2c 20 6c 65 6e 29 3b rm_data(z, len);
4fa0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c . }. }el
4fb0: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54 se if( strcmp(zT
4fc0: 79 70 65 2c 20 22 61 70 70 6c 69 63 61 74 69 6f ype, "applicatio
4fd0: 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 20 n/x-fossil")==0
4fe0: 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 ){. blob_re
4ff0: 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 ad_from_channel(
5000: 26 67 2e 63 67 69 49 6e 2c 20 67 2e 68 74 74 70 &g.cgiIn, g.http
5010: 49 6e 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 In, len);.
5020: 62 6c 6f 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 blob_uncompress(
5030: 26 67 2e 63 67 69 49 6e 2c 20 26 67 2e 63 67 69 &g.cgiIn, &g.cgi
5040: 49 6e 29 3b 0a 20 20 20 20 20 20 2f 2a 20 49 66 In);. /* If
5050: 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 74 79 70 the content typ
5060: 65 20 69 73 20 61 70 70 6c 69 63 61 74 69 6f 6e e is application
5070: 2f 78 2d 66 6f 73 73 69 6c 2c 20 74 68 65 6e 20 /x-fossil, then
5080: 69 67 6e 6f 72 65 0a 20 20 20 20 20 20 2a 2a 20 ignore. **
5090: 74 68 65 20 70 61 74 68 20 69 6e 20 74 68 65 20 the path in the
50a0: 66 69 72 73 74 20 6c 69 6e 65 20 6f 66 20 74 68 first line of th
50b0: 65 20 48 54 54 50 20 68 65 61 64 65 72 20 61 6e e HTTP header an
50c0: 64 20 61 6c 77 61 79 73 0a 20 20 20 20 20 20 2a d always. *
50d0: 2a 20 75 73 65 20 74 68 65 20 2f 78 66 65 72 20 * use the /xfer
50e0: 6d 65 74 68 6f 64 20 73 69 6e 63 65 20 74 68 65 method since the
50f0: 20 2f 78 66 65 72 20 6d 65 74 68 6f 64 20 69 73 /xfer method is
5100: 20 74 68 65 20 6f 6e 6c 79 0a 20 20 20 20 20 20 the only.
5110: 2a 2a 20 6d 65 74 68 6f 64 20 74 68 61 74 20 75 ** method that u
5120: 6e 64 65 72 73 74 61 6e 64 73 20 74 68 65 20 61 nderstands the a
5130: 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 pplication/x-fos
5140: 73 69 6c 20 63 6f 6e 74 65 6e 74 0a 20 20 20 20 sil content.
5150: 20 20 2a 2a 20 74 79 70 65 2e 0a 20 20 20 20 20 ** type..
5160: 20 2a 2f 0a 20 20 20 20 20 20 63 67 69 5f 72 65 */. cgi_re
5170: 70 6c 61 63 65 5f 70 61 72 61 6d 65 74 65 72 28 place_parameter(
5180: 22 50 41 54 48 5f 49 4e 46 4f 22 2c 20 22 2f 78 "PATH_INFO", "/x
5190: 66 65 72 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 fer");. }else
51a0: 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54 79 70 if( strcmp(zTyp
51b0: 65 2c 20 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f e, "application/
51c0: 78 2d 66 6f 73 73 69 6c 2d 64 65 62 75 67 22 29 x-fossil-debug")
51d0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f ==0 ){. blo
51e0: 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 63 68 61 6e b_read_from_chan
51f0: 6e 65 6c 28 26 67 2e 63 67 69 49 6e 2c 20 67 2e nel(&g.cgiIn, g.
5200: 68 74 74 70 49 6e 2c 20 6c 65 6e 29 3b 0a 20 20 httpIn, len);.
5210: 20 20 20 20 63 67 69 5f 72 65 70 6c 61 63 65 5f cgi_replace_
5220: 70 61 72 61 6d 65 74 65 72 28 22 50 41 54 48 5f parameter("PATH_
5230: 49 4e 46 4f 22 2c 20 22 2f 78 66 65 72 22 29 3b INFO", "/xfer");
5240: 20 20 2f 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74 /* See comment
5250: 20 61 62 6f 76 65 20 2a 2f 0a 20 20 20 20 7d 0a above */. }.
5260: 20 20 7d 0a 0a 20 20 7a 20 3d 20 28 63 68 61 72 }.. z = (char
5270: 2a 29 50 28 22 48 54 54 50 5f 43 4f 4f 4b 49 45 *)P("HTTP_COOKIE
5280: 22 29 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 ");. if( z ){.
5290: 20 20 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 z = mprintf("
52a0: 25 73 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f %s",z);. add_
52b0: 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 3b param_list(z, ';
52c0: 27 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a ');. }.}../*.**
52d0: 20 54 68 69 73 20 69 73 20 74 68 65 20 63 6f 6d This is the com
52e0: 70 61 72 69 73 6f 6e 20 66 75 6e 63 74 69 6f 6e parison function
52f0: 20 75 73 65 64 20 74 6f 20 73 6f 72 74 20 74 68 used to sort th
5300: 65 20 61 50 61 72 61 6d 51 50 5b 5d 20 61 72 72 e aParamQP[] arr
5310: 61 79 20 6f 66 0a 2a 2a 20 71 75 65 72 79 20 70 ay of.** query p
5320: 61 72 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f arameters and co
5330: 6f 6b 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 okies..*/.static
5340: 20 69 6e 74 20 71 70 61 72 61 6d 5f 63 6f 6d 70 int qparam_comp
5350: 61 72 65 28 63 6f 6e 73 74 20 76 6f 69 64 20 2a are(const void *
5360: 61 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 62 a, const void *b
5370: 29 7b 0a 20 20 73 74 72 75 63 74 20 51 50 61 72 ){. struct QPar
5380: 61 6d 20 2a 70 41 20 3d 20 28 73 74 72 75 63 74 am *pA = (struct
5390: 20 51 50 61 72 61 6d 2a 29 61 3b 0a 20 20 73 74 QParam*)a;. st
53a0: 72 75 63 74 20 51 50 61 72 61 6d 20 2a 70 42 20 ruct QParam *pB
53b0: 3d 20 28 73 74 72 75 63 74 20 51 50 61 72 61 6d = (struct QParam
53c0: 2a 29 62 3b 0a 20 20 69 6e 74 20 63 3b 0a 20 20 *)b;. int c;.
53d0: 63 20 3d 20 73 74 72 63 6d 70 28 70 41 2d 3e 7a c = strcmp(pA->z
53e0: 4e 61 6d 65 2c 20 70 42 2d 3e 7a 4e 61 6d 65 29 Name, pB->zName)
53f0: 3b 0a 20 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a ;. if( c==0 ){.
5400: 20 20 20 20 63 20 3d 20 70 41 2d 3e 73 65 71 20 c = pA->seq
5410: 2d 20 70 42 2d 3e 73 65 71 3b 0a 20 20 7d 0a 20 - pB->seq;. }.
5420: 20 72 65 74 75 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a return c;.}../*
5430: 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76 .** Return the v
5440: 61 6c 75 65 20 6f 66 20 61 20 71 75 65 72 79 20 alue of a query
5450: 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f parameter or coo
5460: 6b 69 65 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 kie whose name i
5470: 73 20 7a 4e 61 6d 65 2e 0a 2a 2a 20 49 66 20 74 s zName..** If t
5480: 68 65 72 65 20 69 73 20 6e 6f 20 71 75 65 72 79 here is no query
5490: 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f parameter or co
54a0: 6f 6b 69 65 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 okie named zName
54b0: 20 61 6e 64 20 74 68 65 20 66 69 72 73 74 0a 2a and the first.*
54c0: 2a 20 63 68 61 72 61 63 74 65 72 20 6f 66 20 7a * character of z
54d0: 4e 61 6d 65 20 69 73 20 75 70 70 65 72 63 61 73 Name is uppercas
54e0: 65 2c 20 74 68 65 6e 20 63 68 65 63 6b 20 74 6f e, then check to
54f0: 20 73 65 65 20 69 66 20 74 68 65 72 65 20 69 73 see if there is
5500: 20 61 6e 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 an.** environme
5510: 6e 74 20 76 61 72 69 61 62 6c 65 20 62 79 20 74 nt variable by t
5520: 68 61 74 20 6e 61 6d 65 20 61 6e 64 20 72 65 74 hat name and ret
5530: 75 72 6e 20 69 74 20 69 66 20 74 68 65 72 65 20 urn it if there
5540: 69 73 2e 20 20 41 73 0a 2a 2a 20 61 20 6c 61 73 is. As.** a las
5550: 74 20 72 65 73 6f 72 74 20 77 68 65 6e 20 6e 6f t resort when no
5560: 74 68 69 6e 67 20 65 6c 73 65 20 6d 61 74 63 68 thing else match
5570: 65 73 2c 20 72 65 74 75 72 6e 20 7a 44 65 66 61 es, return zDefa
5580: 75 6c 74 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 ult..*/.const ch
5590: 61 72 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 ar *cgi_paramete
55a0: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e r(const char *zN
55b0: 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 ame, const char
55c0: 2a 7a 44 65 66 61 75 6c 74 29 7b 0a 20 20 69 6e *zDefault){. in
55d0: 74 20 6c 6f 2c 20 68 69 2c 20 6d 69 64 2c 20 63 t lo, hi, mid, c
55e0: 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 73 6f 72 74 ;.. /* The sort
55f0: 51 50 20 66 6c 61 67 20 69 73 20 73 65 74 20 77 QP flag is set w
5600: 68 65 6e 65 76 65 72 20 61 20 6e 65 77 20 71 75 henever a new qu
5610: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 69 73 ery parameter is
5620: 20 69 6e 73 65 72 74 65 64 2e 0a 20 20 2a 2a 20 inserted.. **
5630: 49 74 20 69 6e 64 69 63 61 74 65 73 20 74 68 61 It indicates tha
5640: 74 20 77 65 20 6e 65 65 64 20 74 6f 20 72 65 73 t we need to res
5650: 6f 72 74 20 74 68 65 20 71 75 65 72 79 20 70 61 ort the query pa
5660: 72 61 6d 65 74 65 72 73 2e 0a 20 20 2a 2f 0a 20 rameters.. */.
5670: 20 69 66 28 20 73 6f 72 74 51 50 20 29 7b 0a 20 if( sortQP ){.
5680: 20 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 20 int i, j;.
5690: 20 71 73 6f 72 74 28 61 50 61 72 61 6d 51 50 2c qsort(aParamQP,
56a0: 20 6e 55 73 65 64 51 50 2c 20 73 69 7a 65 6f 66 nUsedQP, sizeof
56b0: 28 61 50 61 72 61 6d 51 50 5b 30 5d 29 2c 20 71 (aParamQP[0]), q
56c0: 70 61 72 61 6d 5f 63 6f 6d 70 61 72 65 29 3b 0a param_compare);.
56d0: 20 20 20 20 73 6f 72 74 51 50 20 3d 20 30 3b 0a sortQP = 0;.
56e0: 20 20 20 20 2f 2a 20 41 66 74 65 72 20 73 6f 72 /* After sor
56f0: 74 69 6e 67 2c 20 72 65 6d 6f 76 65 20 64 75 70 ting, remove dup
5700: 6c 69 63 61 74 65 20 70 61 72 61 6d 65 74 65 72 licate parameter
5710: 73 2e 20 20 54 68 65 20 73 65 63 6f 6e 64 61 72 s. The secondar
5720: 79 20 73 6f 72 74 0a 20 20 20 20 2a 2a 20 6b 65 y sort. ** ke
5730: 79 20 69 73 20 61 50 61 72 61 6d 51 50 5b 5d 2e y is aParamQP[].
5740: 73 65 71 20 61 6e 64 20 77 65 20 6b 65 65 70 20 seq and we keep
5750: 74 68 65 20 66 69 72 73 74 20 65 6e 74 72 79 2e the first entry.
5760: 20 20 54 68 61 74 20 6d 65 61 6e 73 0a 20 20 20 That means.
5770: 20 2a 2a 20 77 69 74 68 20 64 75 70 6c 69 63 61 ** with duplica
5780: 74 65 20 63 61 6c 6c 73 20 74 6f 20 63 67 69 5f te calls to cgi_
5790: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 28 29 20 set_parameter()
57a0: 74 68 65 20 73 65 63 6f 6e 64 20 61 6e 64 0a 20 the second and.
57b0: 20 20 20 2a 2a 20 73 75 62 73 65 71 75 65 6e 74 ** subsequent
57c0: 20 63 61 6c 6c 73 20 61 72 65 20 65 66 66 65 63 calls are effec
57d0: 74 69 76 65 6c 79 20 6e 6f 2d 6f 70 73 2e 20 2a tively no-ops. *
57e0: 2f 0a 20 20 20 20 66 6f 72 28 69 3d 6a 3d 31 3b /. for(i=j=1;
57f0: 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 i<nUsedQP; i++)
5800: 7b 0a 20 20 20 20 20 20 69 66 28 20 73 74 72 63 {. if( strc
5810: 6d 70 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a mp(aParamQP[i].z
5820: 4e 61 6d 65 2c 61 50 61 72 61 6d 51 50 5b 69 2d Name,aParamQP[i-
5830: 31 5d 2e 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 1].zName)==0 ){.
5840: 20 20 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 continue
5850: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 ;. }.
5860: 69 66 28 20 6a 3c 69 20 29 7b 0a 20 20 20 20 20 if( j<i ){.
5870: 20 20 20 6d 65 6d 63 70 79 28 26 61 50 61 72 61 memcpy(&aPara
5880: 6d 51 50 5b 6a 5d 2c 20 26 61 50 61 72 61 6d 51 mQP[j], &aParamQ
5890: 50 5b 69 5d 2c 20 73 69 7a 65 6f 66 28 61 50 61 P[i], sizeof(aPa
58a0: 72 61 6d 51 50 5b 6a 5d 29 29 3b 0a 20 20 20 20 ramQP[j]));.
58b0: 20 20 7d 0a 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 }. j++;.
58c0: 20 20 20 7d 0a 20 20 20 20 6e 55 73 65 64 51 50 }. nUsedQP
58d0: 20 3d 20 6a 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 = j;. }.. /*
58e0: 44 6f 20 61 20 62 69 6e 61 72 79 20 73 65 61 72 Do a binary sear
58f0: 63 68 20 66 6f 72 20 61 20 6d 61 74 63 68 69 6e ch for a matchin
5900: 67 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 g query paramete
5910: 72 20 2a 2f 0a 20 20 6c 6f 20 3d 20 30 3b 0a 20 r */. lo = 0;.
5920: 20 68 69 20 3d 20 6e 55 73 65 64 51 50 2d 31 3b hi = nUsedQP-1;
5930: 0a 20 20 77 68 69 6c 65 28 20 6c 6f 3c 3d 68 69 . while( lo<=hi
5940: 20 29 7b 0a 20 20 20 20 6d 69 64 20 3d 20 28 6c ){. mid = (l
5950: 6f 2b 68 69 29 2f 32 3b 0a 20 20 20 20 63 20 3d o+hi)/2;. c =
5960: 20 73 74 72 63 6d 70 28 61 50 61 72 61 6d 51 50 strcmp(aParamQP
5970: 5b 6d 69 64 5d 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 [mid].zName, zNa
5980: 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 63 3d 3d me);. if( c==
5990: 30 20 29 7b 0a 20 20 20 20 20 20 43 47 49 44 45 0 ){. CGIDE
59a0: 42 55 47 28 28 22 6d 65 6d 2d 6d 61 74 63 68 20 BUG(("mem-match
59b0: 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 [%s] = [%s]\n",
59c0: 7a 4e 61 6d 65 2c 20 61 50 61 72 61 6d 51 50 5b zName, aParamQP[
59d0: 6d 69 64 5d 2e 7a 56 61 6c 75 65 29 29 3b 0a 20 mid].zValue));.
59e0: 20 20 20 20 20 72 65 74 75 72 6e 20 61 50 61 72 return aPar
59f0: 61 6d 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 amQP[mid].zValue
5a00: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 ;. }else if(
5a10: 63 3e 30 20 29 7b 0a 20 20 20 20 20 20 68 69 20 c>0 ){. hi
5a20: 3d 20 6d 69 64 2d 31 3b 0a 20 20 20 20 7d 65 6c = mid-1;. }el
5a30: 73 65 7b 0a 20 20 20 20 20 20 6c 6f 20 3d 20 6d se{. lo = m
5a40: 69 64 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a id+1;. }. }.
5a50: 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 6d 61 74 63 . /* If no matc
5a60: 68 20 69 73 20 66 6f 75 6e 64 20 61 6e 64 20 74 h is found and t
5a70: 68 65 20 6e 61 6d 65 20 62 65 67 69 6e 73 20 77 he name begins w
5a80: 69 74 68 20 61 6e 20 75 70 70 65 72 2d 63 61 73 ith an upper-cas
5a90: 65 0a 20 20 2a 2a 20 6c 65 74 74 65 72 2c 20 74 e. ** letter, t
5aa0: 68 65 6e 20 63 68 65 63 6b 20 74 6f 20 73 65 65 hen check to see
5ab0: 20 69 66 20 74 68 65 72 65 20 69 73 20 61 6e 20 if there is an
5ac0: 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 environment vari
5ad0: 61 62 6c 65 0a 20 20 2a 2a 20 77 69 74 68 20 74 able. ** with t
5ae0: 68 65 20 67 69 76 65 6e 20 6e 61 6d 65 2e 0a 20 he given name..
5af0: 20 2a 2f 0a 20 20 69 66 28 20 69 73 75 70 70 65 */. if( isuppe
5b00: 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 r(zName[0]) ){.
5b10: 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a const char *z
5b20: 56 61 6c 75 65 20 3d 20 67 65 74 65 6e 76 28 7a Value = getenv(z
5b30: 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 7a Name);. if( z
5b40: 56 61 6c 75 65 20 29 7b 0a 20 20 20 20 20 20 63 Value ){. c
5b50: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 gi_set_parameter
5b60: 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a _nocopy(zName, z
5b70: 56 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 43 47 Value);. CG
5b80: 49 44 45 42 55 47 28 28 22 65 6e 76 2d 6d 61 74 IDEBUG(("env-mat
5b90: 63 68 20 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e ch [%s] = [%s]\n
5ba0: 22 2c 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 ", zName, zValue
5bb0: 29 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e ));. return
5bc0: 20 7a 56 61 6c 75 65 3b 0a 20 20 20 20 7d 0a 20 zValue;. }.
5bd0: 20 7d 0a 20 20 43 47 49 44 45 42 55 47 28 28 22 }. CGIDEBUG(("
5be0: 6e 6f 2d 6d 61 74 63 68 20 5b 25 73 5d 5c 6e 22 no-match [%s]\n"
5bf0: 2c 20 7a 4e 61 6d 65 29 29 3b 0a 20 20 72 65 74 , zName));. ret
5c00: 75 72 6e 20 7a 44 65 66 61 75 6c 74 3b 0a 7d 0a urn zDefault;.}.
5c10: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 ./*.** Return th
5c20: 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 69 2d e name of the i-
5c30: 74 68 20 43 47 49 20 70 61 72 61 6d 65 74 65 72 th CGI parameter
5c40: 2e 20 20 52 65 74 75 72 6e 20 4e 55 4c 4c 20 69 . Return NULL i
5c50: 66 20 74 68 65 72 65 0a 2a 2a 20 61 72 65 20 66 f there.** are f
5c60: 65 77 65 72 20 74 68 61 6e 20 69 20 72 65 67 69 ewer than i regi
5c70: 73 74 65 72 65 64 20 43 47 49 20 70 61 72 6d 61 stered CGI parma
5c80: 65 74 65 72 73 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 eters..*/.const
5c90: 63 68 61 72 20 2a 63 67 69 5f 70 61 72 61 6d 65 char *cgi_parame
5ca0: 74 65 72 5f 6e 61 6d 65 28 69 6e 74 20 69 29 7b ter_name(int i){
5cb0: 0a 20 20 69 66 28 20 69 3e 3d 30 20 26 26 20 69 . if( i>=0 && i
5cc0: 3c 6e 55 73 65 64 51 50 20 29 7b 0a 20 20 20 20 <nUsedQP ){.
5cd0: 72 65 74 75 72 6e 20 61 50 61 72 61 6d 51 50 5b return aParamQP[
5ce0: 69 5d 2e 7a 4e 61 6d 65 3b 0a 20 20 7d 65 6c 73 i].zName;. }els
5cf0: 65 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b e{. return 0;
5d00: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 . }.}../*.** Pr
5d10: 69 6e 74 20 43 47 49 20 64 65 62 75 67 67 69 6e int CGI debuggin
5d20: 67 20 6d 65 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 g messages..*/.v
5d30: 6f 69 64 20 63 67 69 5f 64 65 62 75 67 28 63 6f oid cgi_debug(co
5d40: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 nst char *zForma
5d50: 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 t, ...){. va_li
5d60: 73 74 20 61 70 3b 0a 20 20 69 66 28 20 67 2e 66 st ap;. if( g.f
5d70: 44 65 62 75 67 20 29 7b 0a 20 20 20 20 76 61 5f Debug ){. va_
5d80: 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 start(ap, zForma
5d90: 74 29 3b 0a 20 20 20 20 76 66 70 72 69 6e 74 66 t);. vfprintf
5da0: 28 67 2e 66 44 65 62 75 67 2c 20 7a 46 6f 72 6d (g.fDebug, zForm
5db0: 61 74 2c 20 61 70 29 3b 0a 20 20 20 20 76 61 5f at, ap);. va_
5dc0: 65 6e 64 28 61 70 29 3b 0a 20 20 20 20 66 66 6c end(ap);. ffl
5dd0: 75 73 68 28 67 2e 66 44 65 62 75 67 29 3b 0a 20 ush(g.fDebug);.
5de0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 }.}../*.** Retu
5df0: 72 6e 20 74 72 75 65 20 69 66 20 61 6e 79 20 6f rn true if any o
5e00: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 f the query para
5e10: 6d 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 meters in the ar
5e20: 67 75 6d 65 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 gument.** list a
5e30: 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 re defined..*/.i
5e40: 6e 74 20 63 67 69 5f 61 6e 79 28 63 6f 6e 73 74 nt cgi_any(const
5e50: 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a char *z, ...){.
5e60: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 va_list ap;.
5e70: 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 char *z2;. if(
5e80: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c cgi_parameter(z,
5e90: 30 29 21 3d 30 20 29 20 72 65 74 75 72 6e 20 31 0)!=0 ) return 1
5ea0: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c ;. va_start(ap,
5eb0: 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a z);. while( (z
5ec0: 32 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 2 = va_arg(ap, c
5ed0: 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 har*))!=0 ){.
5ee0: 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 if( cgi_paramet
5ef0: 65 72 28 7a 32 2c 30 29 21 3d 30 20 29 20 72 65 er(z2,0)!=0 ) re
5f00: 74 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 76 61 turn 1;. }. va
5f10: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 _end(ap);. retu
5f20: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 rn 0;.}../*.** R
5f30: 65 74 75 72 6e 20 74 72 75 65 20 69 66 20 61 6c eturn true if al
5f40: 6c 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 l of the query p
5f50: 61 72 61 6d 65 74 65 72 73 20 69 6e 20 74 68 65 arameters in the
5f60: 20 61 72 67 75 6d 65 6e 74 20 6c 69 73 74 0a 2a argument list.*
5f70: 2a 20 61 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a * are defined..*
5f80: 2f 0a 69 6e 74 20 63 67 69 5f 61 6c 6c 28 63 6f /.int cgi_all(co
5f90: 6e 73 74 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e nst char *z, ...
5fa0: 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b ){. va_list ap;
5fb0: 0a 20 20 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 . char *z2;. i
5fc0: 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 f( cgi_parameter
5fd0: 28 7a 2c 30 29 3d 3d 30 20 29 20 72 65 74 75 72 (z,0)==0 ) retur
5fe0: 6e 20 30 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 n 0;. va_start(
5ff0: 61 70 2c 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 ap, z);. while(
6000: 20 28 7a 32 20 3d 20 76 61 5f 61 72 67 28 61 70 (z2 = va_arg(ap
6010: 2c 20 63 68 61 72 2a 29 29 3d 3d 30 20 29 7b 0a , char*))==0 ){.
6020: 20 20 20 20 69 66 28 20 63 67 69 5f 70 61 72 61 if( cgi_para
6030: 6d 65 74 65 72 28 7a 32 2c 30 29 3d 3d 30 20 29 meter(z2,0)==0 )
6040: 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 return 0;. }.
6050: 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 va_end(ap);. r
6060: 65 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a eturn 1;.}../*.*
6070: 2a 20 50 72 69 6e 74 20 61 6c 6c 20 71 75 65 72 * Print all quer
6080: 79 20 70 61 72 61 6d 65 74 65 72 73 20 6f 6e 20 y parameters on
6090: 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e standard output.
60a0: 20 20 46 6f 72 6d 61 74 20 74 68 65 0a 2a 2a 20 Format the.**
60b0: 70 61 72 61 6d 65 74 65 72 73 20 61 73 20 48 54 parameters as HT
60c0: 4d 4c 2e 20 20 54 68 69 73 20 69 73 20 75 73 65 ML. This is use
60d0: 64 20 66 6f 72 20 74 65 73 74 69 6e 67 20 61 6e d for testing an
60e0: 64 20 64 65 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a d debugging..*/.
60f0: 76 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 5f 61 void cgi_print_a
6100: 6c 6c 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 ll(void){. int
6110: 69 3b 0a 20 20 63 67 69 5f 70 61 72 61 6d 65 74 i;. cgi_paramet
6120: 65 72 28 22 22 2c 22 22 29 3b 20 20 2f 2a 20 46 er("",""); /* F
6130: 6f 72 63 65 20 74 68 65 20 70 61 72 61 6d 65 74 orce the paramet
6140: 65 72 73 20 69 6e 74 6f 20 73 6f 72 74 65 64 20 ers into sorted
6150: 6f 72 64 65 72 20 2a 2f 0a 20 20 66 6f 72 28 69 order */. for(i
6160: 3d 30 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 =0; i<nUsedQP; i
6170: 2b 2b 29 7b 0a 20 20 20 20 63 67 69 5f 70 72 69 ++){. cgi_pri
6180: 6e 74 66 28 22 25 73 20 3d 20 25 73 20 20 3c 62 ntf("%s = %s <b
6190: 72 20 2f 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 r />\n",.
61a0: 68 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 htmlize(aParamQP
61b0: 5b 69 5d 2e 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 [i].zName, -1),
61c0: 68 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 htmlize(aParamQP
61d0: 5b 69 5d 2e 7a 56 61 6c 75 65 2c 20 2d 31 29 29 [i].zValue, -1))
61e0: 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 ;. }.}../*.** W
61f0: 72 69 74 65 20 48 54 4d 4c 20 74 65 78 74 20 66 rite HTML text f
6200: 6f 72 20 61 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e or an option men
6210: 75 20 74 6f 20 73 74 61 6e 64 61 72 64 20 6f 75 u to standard ou
6220: 74 70 75 74 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a tput. zParam.**
6230: 20 69 73 20 74 68 65 20 71 75 65 72 79 20 70 61 is the query pa
6240: 72 61 6d 65 74 65 72 20 74 68 61 74 20 74 68 65 rameter that the
6250: 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 73 65 74 option menu set
6260: 73 2e 20 20 7a 44 66 6c 74 20 69 73 20 74 68 65 s. zDflt is the
6270: 0a 2a 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 .** initial valu
6280: 65 20 6f 66 20 74 68 65 20 6f 70 74 69 6f 6e 20 e of the option
6290: 6d 65 6e 75 2e 20 20 41 64 64 69 74 69 6f 6e 20 menu. Addition
62a0: 61 72 67 75 6d 65 6e 74 73 20 61 72 65 20 6e 61 arguments are na
62b0: 6d 65 2f 76 61 6c 75 65 0a 2a 2a 20 70 61 69 72 me/value.** pair
62c0: 73 20 74 68 61 74 20 64 65 66 69 6e 65 20 76 61 s that define va
62d0: 6c 75 65 73 20 6f 6e 20 74 68 65 20 6d 65 6e 75 lues on the menu
62e0: 2e 20 20 54 68 65 20 6c 69 73 74 20 69 73 20 74 . The list is t
62f0: 65 72 6d 69 6e 61 74 65 64 20 77 69 74 68 0a 2a erminated with.*
6300: 2a 20 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 * a single NULL
6310: 61 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 argument..*/.voi
6320: 64 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 d cgi_optionmenu
6330: 28 69 6e 74 20 69 6e 2c 20 63 6f 6e 73 74 20 63 (int in, const c
6340: 68 61 72 20 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 har *zP, const c
6350: 68 61 72 20 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 har *zD, ...){.
6360: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 va_list ap;. c
6370: 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 har *zName, *zVa
6380: 6c 3b 0a 20 20 69 6e 74 20 64 66 6c 74 53 65 65 l;. int dfltSee
6390: 6e 20 3d 20 30 3b 0a 20 20 63 67 69 5f 70 72 69 n = 0;. cgi_pri
63a0: 6e 74 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 ntf("%*s<select
63b0: 73 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 size=1 name=\"%s
63c0: 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 \">\n", in, "",
63d0: 7a 50 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 zP);. va_start(
63e0: 61 70 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 ap, zD);. while
63f0: 28 20 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 ( (zName = va_ar
6400: 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 g(ap, char*))!=0
6410: 20 26 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 && (zVal = va_a
6420: 72 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d rg(ap, char*))!=
6430: 30 20 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 0 ){. if( str
6440: 63 6d 70 28 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 cmp(zVal,zD)==0
6450: 29 7b 20 64 66 6c 74 53 65 65 6e 20 3d 20 31 3b ){ dfltSeen = 1;
6460: 20 62 72 65 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 break; }. }.
6470: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 69 66 va_end(ap);. if
6480: 28 20 21 64 66 6c 74 53 65 65 6e 20 29 7b 0a 20 ( !dfltSeen ){.
6490: 20 20 20 69 66 28 20 7a 44 5b 30 5d 20 29 7b 0a if( zD[0] ){.
64a0: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 cgi_printf
64b0: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c ("%*s<option val
64c0: 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 ue=\"%h\" select
64d0: 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e ed>%h</option>\n
64e0: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c ",. in+2,
64f0: 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 "", zD, zD);.
6500: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 }else{. c
6510: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f gi_printf("%*s<o
6520: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 ption value=\"\"
6530: 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b selected>
6540: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e </option>\n", in
6550: 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 0a 20 +2, "");. }.
6560: 20 7d 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 }. va_start(ap
6570: 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 , zD);. while(
6580: 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 (zName = va_arg(
6590: 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 ap, char*))!=0 &
65a0: 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 & (zVal = va_arg
65b0: 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 (ap, char*))!=0
65c0: 29 7b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 ){. if( zName
65d0: 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 [0] ){. cgi
65e0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 _printf("%*s<opt
65f0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 ion value=\"%h\"
6600: 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e %s>%h</option>\n
6610: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c ",. in+2,
6620: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 "",. zVa
6630: 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d l,. strcm
6640: 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 p(zVal, zD) ? ""
6650: 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a : " selected",.
6660: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 zName.
6670: 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 );. }else
6680: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e {. cgi_prin
6690: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 tf("%*s<option v
66a0: 61 6c 75 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 alue=\"\"%s>&nbs
66b0: 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a p;</option>\n",.
66c0: 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 in+2, ""
66d0: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 ,. strcmp
66e0: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 (zVal, zD) ? ""
66f0: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 : " selected".
6700: 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d );. }. }
6710: 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 . va_end(ap);.
6720: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 cgi_printf("%*s
6730: 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e </select>\n", in
6740: 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 , "");.}../*.**
6750: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 This routine wor
6760: 6b 73 20 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67 ks a lot like cg
6770: 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65 i_optionmenu() e
6780: 78 63 65 70 74 20 74 68 61 74 20 74 68 65 20 6c xcept that the l
6790: 69 73 74 20 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 ist of.** values
67a0: 20 69 73 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e is contained in
67b0: 20 61 6e 20 61 72 72 61 79 2e 20 20 41 6c 73 6f an array. Also
67c0: 2c 20 74 68 65 20 76 61 6c 75 65 73 20 61 72 65 , the values are
67d0: 20 6a 75 73 74 20 76 61 6c 75 65 73 2c 20 6e 6f just values, no
67e0: 74 0a 2a 2a 20 6e 61 6d 65 2f 76 61 6c 75 65 20 t.** name/value
67f0: 70 61 69 72 73 20 61 73 20 69 6e 20 63 67 69 5f pairs as in cgi_
6800: 6f 70 74 69 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 optionmenu..*/.v
6810: 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e oid cgi_v_option
6820: 6d 65 6e 75 28 0a 20 20 69 6e 74 20 69 6e 2c 20 menu(. int in,
6830: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
6840: 49 6e 64 65 6e 74 20 62 79 20 74 68 69 73 20 61 Indent by this a
6850: 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 mount */. const
6860: 20 63 68 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 char *zP,
6870: 2f 2a 20 54 68 65 20 71 75 65 72 79 20 70 61 72 /* The query par
6880: 61 6d 65 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 ameter name */.
6890: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c const char *zD,
68a0: 20 20 20 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 /* Default
68b0: 20 76 61 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 value */. cons
68c0: 74 20 63 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 t char **az
68d0: 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 /* NULL-termina
68e0: 74 65 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f ted list of allo
68f0: 77 65 64 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b wed values */.){
6900: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a . const char *z
6910: 56 61 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 Val;. int i;.
6920: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
6930: 73 65 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 select size=1 na
6940: 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 me=\"%s\">\n", i
6950: 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f n, "", zP);. fo
6960: 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b r(i=0; az[i]; i+
6970: 2b 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 +){. if( strc
6980: 6d 70 28 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 mp(az[i],zD)==0
6990: 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 ) break;. }. i
69a0: 66 28 20 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 f( az[i]==0 ){.
69b0: 20 20 20 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 if( zD[0]==0
69c0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 ){. cgi_pri
69d0: 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 ntf("%*s<option
69e0: 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 value=\"\" selec
69f0: 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 ted> </opti
6a00: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 on>\n",. i
6a10: 6e 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 n+2, "");. }e
6a20: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 lse{. cgi_p
6a30: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f rintf("%*s<optio
6a40: 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 n value=\"%h\" s
6a50: 65 6c 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 elected>%h</opti
6a60: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 on>\n",. i
6a70: 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 n+2, "", zD, zD)
6a80: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 ;. }. }. wh
6a90: 69 6c 65 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 ile( (zVal = *(a
6aa0: 7a 2b 2b 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 z++))!=0 ){.
6ab0: 20 69 66 28 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a if( zVal[0] ){.
6ac0: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 cgi_printf
6ad0: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c ("%*s<option val
6ae0: 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f ue=\"%h\"%s>%h</
6af0: 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 option>\n",.
6b00: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 in+2, "",.
6b10: 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 zVal,.
6b20: 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c strcmp(zVal,
6b30: 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 zD) ? "" : " se
6b40: 6c 65 63 74 65 64 22 2c 0a 20 20 20 20 20 20 20 lected",.
6b50: 20 7a 56 61 6c 0a 20 20 20 20 20 20 29 3b 0a 20 zVal. );.
6b60: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
6b70: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
6b80: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c option value=\"\
6b90: 22 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 "%s> </opti
6ba0: 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 on>\n",.
6bb0: 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 in+2, "",.
6bc0: 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a strcmp(zVal, z
6bd0: 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 D) ? "" : " sele
6be0: 63 74 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 cted". );.
6bf0: 20 20 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70 }. }. cgi_p
6c00: 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 rintf("%*s</sele
6c10: 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b ct>\n", in, "");
6c20: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 .}../*.** This r
6c30: 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c outine works a l
6c40: 6f 74 20 6c 69 6b 65 20 63 67 69 5f 76 5f 6f 70 ot like cgi_v_op
6c50: 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 tionmenu() excep
6c60: 74 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 0a t that the list.
6c70: 2a 2a 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20 ** is a list of
6c80: 70 61 69 72 73 2e 20 20 54 68 65 20 66 69 72 73 pairs. The firs
6c90: 74 20 65 6c 65 6d 65 6e 74 20 6f 66 20 65 61 63 t element of eac
6ca0: 68 20 70 61 69 72 20 69 73 20 74 68 65 20 76 61 h pair is the va
6cb0: 6c 75 65 20 75 73 65 64 0a 2a 2a 20 69 6e 74 65 lue used.** inte
6cc0: 72 6e 61 6c 6c 79 20 61 6e 64 20 74 68 65 20 73 rnally and the s
6cd0: 65 63 6f 6e 64 20 65 6c 65 6d 65 6e 74 20 69 73 econd element is
6ce0: 20 74 68 65 20 76 61 6c 75 65 20 64 69 73 70 6c the value displ
6cf0: 61 79 65 64 20 74 6f 20 74 68 65 20 75 73 65 72 ayed to the user
6d00: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f ..*/.void cgi_v_
6d10: 6f 70 74 69 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 optionmenu2(. i
6d20: 6e 74 20 69 6e 2c 20 20 20 20 20 20 20 20 20 20 nt in,
6d30: 20 20 20 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 /* Indent by
6d40: 20 74 68 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a this amount */.
6d50: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 const char *zP
6d60: 2c 20 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75 , /* The qu
6d70: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6e 61 ery parameter na
6d80: 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 me */. const ch
6d90: 61 72 20 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 ar *zD, /*
6da0: 44 65 66 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f Default value */
6db0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a . const char **
6dc0: 61 7a 20 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d az /* NULL-
6dd0: 74 65 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 terminated list
6de0: 6f 66 20 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 of allowed value
6df0: 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 s */.){. const
6e00: 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e char *zVal;. in
6e10: 74 20 69 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 t i;. cgi_print
6e20: 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 f("%*s<select si
6e30: 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 ze=1 name=\"%s\"
6e40: 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 >\n", in, "", zP
6e50: 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a );. for(i=0; az
6e60: 5b 69 5d 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20 [i]; i+=2){.
6e70: 69 66 28 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d if( strcmp(az[i]
6e80: 2c 7a 44 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b ,zD)==0 ) break;
6e90: 0a 20 20 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d . }. if( az[i]
6ea0: 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a ==0 ){. if( z
6eb0: 44 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 D[0]==0 ){.
6ec0: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 cgi_printf("%*s
6ed0: 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 <option value=\"
6ee0: 5c 22 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 \" selected>&nbs
6ef0: 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a p;</option>\n",.
6f00: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 in+2, "")
6f10: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 ;. }else{.
6f20: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 cgi_printf("%
6f30: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d *s<option value=
6f40: 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e \"%h\" selected>
6f50: 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a %h</option>\n",.
6f60: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c in+2, "",
6f70: 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a zD, zD);. }.
6f80: 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 }. while( (zV
6f90: 61 6c 20 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 al = *(az++))!=0
6fa0: 20 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 ){. const c
6fb0: 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 har *zName = *(a
6fc0: 7a 2b 2b 29 3b 0a 20 20 20 20 69 66 28 20 7a 4e z++);. if( zN
6fd0: 61 6d 65 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 ame[0] ){.
6fe0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
6ff0: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 option value=\"%
7000: 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e h\"%s>%h</option
7010: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e >\n",. in
7020: 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 +2, "",.
7030: 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 zVal,. st
7040: 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f rcmp(zVal, zD) ?
7050: 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 "" : " selected
7060: 22 2c 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 ",. zName
7070: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 . );. }e
7080: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 lse{. cgi_p
7090: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f rintf("%*s<optio
70a0: 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 n value=\"%h\"%s
70b0: 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e > </option>
70c0: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b \n",. in+
70d0: 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 2, "",. z
70e0: 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 Val,. str
70f0: 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 cmp(zVal, zD) ?
7100: 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 "" : " selected"
7110: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a . );. }.
7120: 20 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 }. cgi_printf
7130: 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e ("%*s</select>\n
7140: 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f ", in, "");.}../
7150: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e *.** This routin
7160: 65 20 77 6f 72 6b 73 20 6c 69 6b 65 20 22 70 72 e works like "pr
7170: 69 6e 74 66 22 20 65 78 63 65 70 74 20 74 68 61 intf" except tha
7180: 74 20 69 74 20 68 61 73 20 74 68 65 0a 2a 2a 20 t it has the.**
7190: 65 78 74 72 61 20 66 6f 72 6d 61 74 74 69 6e 67 extra formatting
71a0: 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 73 75 capabilities su
71b0: 63 68 20 61 73 20 25 68 20 61 6e 64 20 25 74 2e ch as %h and %t.
71c0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 72 69 .*/.void cgi_pri
71d0: 6e 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20 2a ntf(const char *
71e0: 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 zFormat, ...){.
71f0: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 va_list ap;. v
7200: 61 5f 73 74 61 72 74 28 61 70 2c 7a 46 6f 72 6d a_start(ap,zForm
7210: 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 at);. vxprintf(
7220: 70 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 pContent,zFormat
7230: 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 ,ap);. va_end(a
7240: 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 p);.}../*.** Thi
7250: 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 s routine works
7260: 6c 69 6b 65 20 22 76 70 72 69 6e 74 66 22 20 65 like "vprintf" e
7270: 78 63 65 70 74 20 74 68 61 74 20 69 74 20 68 61 xcept that it ha
7280: 73 20 74 68 65 0a 2a 2a 20 65 78 74 72 61 20 66 s the.** extra f
7290: 6f 72 6d 61 74 74 69 6e 67 20 63 61 70 61 62 69 ormatting capabi
72a0: 6c 69 74 69 65 73 20 73 75 63 68 20 61 73 20 25 lities such as %
72b0: 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 h and %t..*/.voi
72c0: 64 20 63 67 69 5f 76 70 72 69 6e 74 66 28 63 6f d cgi_vprintf(co
72d0: 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 nst char *zForma
72e0: 74 2c 20 76 61 5f 6c 69 73 74 20 61 70 29 7b 0a t, va_list ap){.
72f0: 20 20 76 78 70 72 69 6e 74 66 28 70 43 6f 6e 74 vxprintf(pCont
7300: 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b ent,zFormat,ap);
7310: 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 .}.../*.** Send
7320: 61 20 72 65 70 6c 79 20 69 6e 64 69 63 61 74 69 a reply indicati
7330: 6e 67 20 74 68 61 74 20 74 68 65 20 48 54 54 50 ng that the HTTP
7340: 20 72 65 71 75 65 73 74 20 77 61 73 20 6d 61 6c request was mal
7350: 66 6f 72 6d 65 64 0a 2a 2f 0a 73 74 61 74 69 63 formed.*/.static
7360: 20 76 6f 69 64 20 6d 61 6c 66 6f 72 6d 65 64 5f void malformed_
7370: 72 65 71 75 65 73 74 28 76 6f 69 64 29 7b 0a 20 request(void){.
7380: 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 cgi_set_status(
7390: 35 30 31 2c 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 501, "Not Implem
73a0: 65 6e 74 65 64 22 29 3b 0a 20 20 63 67 69 5f 70 ented");. cgi_p
73b0: 72 69 6e 74 66 28 0a 20 20 20 20 22 3c 68 74 6d rintf(. "<htm
73c0: 6c 3e 3c 62 6f 64 79 3e 55 6e 72 65 63 6f 67 6e l><body>Unrecogn
73d0: 69 7a 65 64 20 48 54 54 50 20 52 65 71 75 65 73 ized HTTP Reques
73e0: 74 3c 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c t</body></html>\
73f0: 6e 22 0a 20 20 29 3b 0a 20 20 63 67 69 5f 72 65 n". );. cgi_re
7400: 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 ply();. exit(0)
7410: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 ;.}../*.** Panic
7420: 20 61 6e 64 20 64 69 65 20 77 68 69 6c 65 20 70 and die while p
7430: 72 6f 63 65 73 73 69 6e 67 20 61 20 77 65 62 70 rocessing a webp
7440: 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 age..*/.void cgi
7450: 5f 70 61 6e 69 63 28 63 6f 6e 73 74 20 63 68 61 _panic(const cha
7460: 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 r *zFormat, ...)
7470: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a {. va_list ap;.
7480: 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 cgi_reset_cont
7490: 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f 73 65 74 ent();. cgi_set
74a0: 5f 73 74 61 74 75 73 28 35 30 30 2c 20 22 49 6e _status(500, "In
74b0: 74 65 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 ternal Server Er
74c0: 72 6f 72 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 ror");. cgi_pri
74d0: 6e 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e ntf(. "<html>
74e0: 3c 62 6f 64 79 3e 3c 68 31 3e 49 6e 74 65 72 6e <body><h1>Intern
74f0: 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72 3c al Server Error<
7500: 2f 68 31 3e 5c 6e 22 0a 20 20 20 20 22 3c 70 6c /h1>\n". "<pl
7510: 61 69 6e 74 65 78 74 3e 22 0a 20 20 29 3b 0a 20 aintext>". );.
7520: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 va_start(ap, zF
7530: 6f 72 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e ormat);. vxprin
7540: 74 66 28 70 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 tf(pContent,zFor
7550: 6d 61 74 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e mat,ap);. va_en
7560: 64 28 61 70 29 3b 0a 20 20 63 67 69 5f 72 65 70 d(ap);. cgi_rep
7570: 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 31 29 3b ly();. exit(1);
7580: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 .}../*.** Remove
7590: 20 74 68 65 20 66 69 72 73 74 20 73 70 61 63 65 the first space
75a0: 2d 64 65 6c 69 6d 69 74 65 64 20 74 6f 6b 65 6e -delimited token
75b0: 20 66 72 6f 6d 20 61 20 73 74 72 69 6e 67 20 61 from a string a
75c0: 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20 61 20 70 nd return.** a p
75d0: 6f 69 6e 74 65 72 20 74 6f 20 69 74 2e 20 20 41 ointer to it. A
75e0: 64 64 20 61 20 4e 55 4c 4c 20 74 6f 20 74 68 65 dd a NULL to the
75f0: 20 73 74 72 69 6e 67 20 74 6f 20 74 65 72 6d 69 string to termi
7600: 6e 61 74 65 20 74 68 65 20 74 6f 6b 65 6e 2e 0a nate the token..
7610: 2a 2a 20 4d 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 ** Make *zLeftOv
7620: 65 72 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 er point to the
7630: 73 74 61 72 74 20 6f 66 20 74 68 65 20 6e 65 78 start of the nex
7640: 74 20 74 6f 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 t token..*/.stat
7650: 69 63 20 63 68 61 72 20 2a 65 78 74 72 61 63 74 ic char *extract
7660: 5f 74 6f 6b 65 6e 28 63 68 61 72 20 2a 7a 49 6e _token(char *zIn
7670: 70 75 74 2c 20 63 68 61 72 20 2a 2a 7a 4c 65 66 put, char **zLef
7680: 74 4f 76 65 72 29 7b 0a 20 20 63 68 61 72 20 2a tOver){. char *
7690: 7a 52 65 73 75 6c 74 20 3d 20 30 3b 0a 20 20 69 zResult = 0;. i
76a0: 66 28 20 7a 49 6e 70 75 74 3d 3d 30 20 29 7b 0a f( zInput==0 ){.
76b0: 20 20 20 20 69 66 28 20 7a 4c 65 66 74 4f 76 65 if( zLeftOve
76c0: 72 20 29 20 2a 7a 4c 65 66 74 4f 76 65 72 20 3d r ) *zLeftOver =
76d0: 20 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 0;. return 0
76e0: 3b 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 69 ;. }. while( i
76f0: 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 sspace(*zInput)
7700: 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 ){ zInput++; }.
7710: 20 7a 52 65 73 75 6c 74 20 3d 20 7a 49 6e 70 75 zResult = zInpu
7720: 74 3b 0a 20 20 77 68 69 6c 65 28 20 2a 7a 49 6e t;. while( *zIn
7730: 70 75 74 20 26 26 20 21 69 73 73 70 61 63 65 28 put && !isspace(
7740: 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 *zInput) ){ zInp
7750: 75 74 2b 2b 3b 20 7d 0a 20 20 69 66 28 20 2a 7a ut++; }. if( *z
7760: 49 6e 70 75 74 20 29 7b 0a 20 20 20 20 2a 7a 49 Input ){. *zI
7770: 6e 70 75 74 20 3d 20 30 3b 0a 20 20 20 20 7a 49 nput = 0;. zI
7780: 6e 70 75 74 2b 2b 3b 0a 20 20 20 20 77 68 69 6c nput++;. whil
7790: 65 28 20 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 e( isspace(*zInp
77a0: 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b ut) ){ zInput++;
77b0: 20 7d 0a 20 20 7d 0a 20 20 69 66 28 20 7a 4c 65 }. }. if( zLe
77c0: 66 74 4f 76 65 72 20 29 7b 20 2a 7a 4c 65 66 74 ftOver ){ *zLeft
77d0: 4f 76 65 72 20 3d 20 7a 49 6e 70 75 74 3b 20 7d Over = zInput; }
77e0: 0a 20 20 72 65 74 75 72 6e 20 7a 52 65 73 75 6c . return zResul
77f0: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 t;.}../*.** This
7800: 20 72 6f 75 74 69 6e 65 20 68 61 6e 64 6c 65 73 routine handles
7810: 20 61 20 73 69 6e 67 6c 65 20 48 54 54 50 20 72 a single HTTP r
7820: 65 71 75 65 73 74 20 77 68 69 63 68 20 69 73 20 equest which is
7830: 63 6f 6d 69 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 coming in on.**
7840: 73 74 61 6e 64 61 72 64 20 69 6e 70 75 74 20 61 standard input a
7850: 6e 64 20 77 68 69 63 68 20 72 65 70 6c 69 65 73 nd which replies
7860: 20 6f 6e 20 73 74 61 6e 64 61 72 64 20 6f 75 74 on standard out
7870: 70 75 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 put..**.** The H
7880: 54 54 50 20 72 65 71 75 65 73 74 20 69 73 20 72 TTP request is r
7890: 65 61 64 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 ead from standar
78a0: 64 20 69 6e 70 75 74 20 61 6e 64 20 69 73 20 75 d input and is u
78b0: 73 65 64 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a sed to initializ
78c0: 65 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 e.** environment
78d0: 20 76 61 72 69 61 62 6c 65 73 20 61 73 20 70 65 variables as pe
78e0: 72 20 43 47 49 2e 20 20 54 68 65 20 63 67 69 5f r CGI. The cgi_
78f0: 69 6e 69 74 28 29 20 72 6f 75 74 69 6e 65 20 74 init() routine t
7900: 6f 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 o complete.** th
7910: 65 20 73 65 74 75 70 2e 20 20 4f 6e 63 65 20 61 e setup. Once a
7920: 6c 6c 20 74 68 65 20 73 65 74 75 70 20 69 73 20 ll the setup is
7930: 66 69 6e 69 73 68 65 64 2c 20 74 68 69 73 20 70 finished, this p
7940: 72 6f 63 65 64 75 72 65 20 72 65 74 75 72 6e 73 rocedure returns
7950: 0a 2a 2a 20 61 6e 64 20 73 75 62 73 65 71 75 65 .** and subseque
7960: 6e 74 20 63 6f 64 65 20 68 61 6e 64 6c 65 73 20 nt code handles
7970: 74 68 65 20 61 63 74 75 61 6c 20 67 65 6e 65 72 the actual gener
7980: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 77 65 62 ation of the web
7990: 70 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 page..*/.void cg
79a0: 69 5f 68 61 6e 64 6c 65 5f 68 74 74 70 5f 72 65 i_handle_http_re
79b0: 71 75 65 73 74 28 63 6f 6e 73 74 20 63 68 61 72 quest(const char
79c0: 20 2a 7a 49 70 41 64 64 72 29 7b 0a 20 20 63 68 *zIpAddr){. ch
79d0: 61 72 20 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a ar *z, *zToken;.
79e0: 20 20 69 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 int i;. struc
79f0: 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 t sockaddr_in re
7a00: 6d 6f 74 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 moteName;. size
7a10: 5f 74 20 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 _t size = sizeof
7a20: 28 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 (struct sockaddr
7a30: 5f 69 6e 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 _in);. char zLi
7a40: 6e 65 5b 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a ne[2000]; /*
7a50: 20 41 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f A single line o
7a60: 66 20 69 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 66 f input. */.. f
7a70: 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 3d 20 31 ullHttpReply = 1
7a80: 3b 0a 20 20 69 66 28 20 66 67 65 74 73 28 7a 4c ;. if( fgets(zL
7a90: 69 6e 65 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e ine, sizeof(zLin
7aa0: 65 29 2c 67 2e 68 74 74 70 49 6e 29 3d 3d 30 20 e),g.httpIn)==0
7ab0: 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 ){. malformed
7ac0: 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a _request();. }.
7ad0: 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61 zToken = extra
7ae0: 63 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e 65 2c 20 ct_token(zLine,
7af0: 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65 &z);. if( zToke
7b00: 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 n==0 ){. malf
7b10: 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28 29 3b ormed_request();
7b20: 0a 20 20 7d 0a 20 20 69 66 28 20 73 74 72 63 6d . }. if( strcm
7b30: 70 28 7a 54 6f 6b 65 6e 2c 22 47 45 54 22 29 21 p(zToken,"GET")!
7b40: 3d 30 20 26 26 20 73 74 72 63 6d 70 28 7a 54 6f =0 && strcmp(zTo
7b50: 6b 65 6e 2c 22 50 4f 53 54 22 29 21 3d 30 0a 20 ken,"POST")!=0.
7b60: 20 20 20 20 20 26 26 20 73 74 72 63 6d 70 28 7a && strcmp(z
7b70: 54 6f 6b 65 6e 2c 22 48 45 41 44 22 29 21 3d 30 Token,"HEAD")!=0
7b80: 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 ){. malforme
7b90: 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d d_request();. }
7ba0: 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 47 . cgi_setenv("G
7bb0: 41 54 45 57 41 59 5f 49 4e 54 45 52 46 41 43 45 ATEWAY_INTERFACE
7bc0: 22 2c 22 43 47 49 2f 31 2e 30 22 29 3b 0a 20 20 ","CGI/1.0");.
7bd0: 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45 51 55 cgi_setenv("REQU
7be0: 45 53 54 5f 4d 45 54 48 4f 44 22 2c 7a 54 6f 6b EST_METHOD",zTok
7bf0: 65 6e 29 3b 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 en);. zToken =
7c00: 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 2c extract_token(z,
7c10: 20 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f 6b &z);. if( zTok
7c20: 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c en==0 ){. mal
7c30: 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28 29 formed_request()
7c40: 3b 0a 20 20 7d 0a 20 20 63 67 69 5f 73 65 74 65 ;. }. cgi_sete
7c50: 6e 76 28 22 52 45 51 55 45 53 54 5f 55 52 49 22 nv("REQUEST_URI"
7c60: 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 66 6f 72 , zToken);. for
7c70: 28 69 3d 30 3b 20 7a 54 6f 6b 65 6e 5b 69 5d 20 (i=0; zToken[i]
7c80: 26 26 20 7a 54 6f 6b 65 6e 5b 69 5d 21 3d 27 3f && zToken[i]!='?
7c90: 27 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69 66 28 20 '; i++){}. if(
7ca0: 7a 54 6f 6b 65 6e 5b 69 5d 20 29 20 7a 54 6f 6b zToken[i] ) zTok
7cb0: 65 6e 5b 69 2b 2b 5d 20 3d 20 30 3b 0a 20 20 63 en[i++] = 0;. c
7cc0: 67 69 5f 73 65 74 65 6e 76 28 22 50 41 54 48 5f gi_setenv("PATH_
7cd0: 49 4e 46 4f 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a INFO", zToken);.
7ce0: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 51 55 cgi_setenv("QU
7cf0: 45 52 59 5f 53 54 52 49 4e 47 22 2c 20 26 7a 54 ERY_STRING", &zT
7d00: 6f 6b 65 6e 5b 69 5d 29 3b 0a 20 20 69 66 28 20 oken[i]);. if(
7d10: 7a 49 70 41 64 64 72 3d 3d 30 20 26 26 0a 20 20 zIpAddr==0 &&.
7d20: 20 20 20 20 20 20 67 65 74 70 65 65 72 6e 61 6d getpeernam
7d30: 65 28 66 69 6c 65 6e 6f 28 67 2e 68 74 74 70 49 e(fileno(g.httpI
7d40: 6e 29 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b n), (struct sock
7d50: 61 64 64 72 2a 29 26 72 65 6d 6f 74 65 4e 61 6d addr*)&remoteNam
7d60: 65 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 20 e, .
7d70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
7d80: 20 20 20 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 (socklen_t*)
7d90: 26 73 69 7a 65 29 3e 3d 30 0a 20 20 29 7b 0a 20 &size)>=0. ){.
7da0: 20 20 20 7a 49 70 41 64 64 72 20 3d 20 69 6e 65 zIpAddr = ine
7db0: 74 5f 6e 74 6f 61 28 72 65 6d 6f 74 65 4e 61 6d t_ntoa(remoteNam
7dc0: 65 2e 73 69 6e 5f 61 64 64 72 29 3b 0a 20 20 7d e.sin_addr);. }
7dd0: 0a 20 20 69 66 28 20 7a 49 70 41 64 64 72 20 29 . if( zIpAddr )
7de0: 7b 20 20 20 0a 20 20 20 20 63 67 69 5f 73 65 74 { . cgi_set
7df0: 65 6e 76 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 env("REMOTE_ADDR
7e00: 22 2c 20 7a 49 70 41 64 64 72 29 3b 0a 20 20 20 ", zIpAddr);.
7e10: 20 67 2e 7a 49 70 41 64 64 72 20 3d 20 6d 70 72 g.zIpAddr = mpr
7e20: 69 6e 74 66 28 22 25 73 22 2c 20 7a 49 70 41 64 intf("%s", zIpAd
7e30: 64 72 29 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a 20 dr);. }. . /*
7e40: 47 65 74 20 61 6c 6c 20 74 68 65 20 6f 70 74 69 Get all the opti
7e50: 6f 6e 61 6c 20 66 69 65 6c 64 73 20 74 68 61 74 onal fields that
7e60: 20 66 6f 6c 6c 6f 77 20 74 68 65 20 66 69 72 73 follow the firs
7e70: 74 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20 77 t line.. */. w
7e80: 68 69 6c 65 28 20 66 67 65 74 73 28 7a 4c 69 6e hile( fgets(zLin
7e90: 65 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c e,sizeof(zLine),
7ea0: 67 2e 68 74 74 70 49 6e 29 20 29 7b 0a 20 20 20 g.httpIn) ){.
7eb0: 20 63 68 61 72 20 2a 7a 46 69 65 6c 64 4e 61 6d char *zFieldNam
7ec0: 65 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 61 e;. char *zVa
7ed0: 6c 3b 0a 0a 20 20 20 20 7a 46 69 65 6c 64 4e 61 l;.. zFieldNa
7ee0: 6d 65 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b me = extract_tok
7ef0: 65 6e 28 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b en(zLine,&zVal);
7f00: 0a 20 20 20 20 69 66 28 20 7a 46 69 65 6c 64 4e . if( zFieldN
7f10: 61 6d 65 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c ame==0 || *zFiel
7f20: 64 4e 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b dName==0 ) break
7f30: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 ;. while( iss
7f40: 70 61 63 65 28 2a 7a 56 61 6c 29 20 29 7b 20 7a pace(*zVal) ){ z
7f50: 56 61 6c 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 3d Val++; }. i =
7f60: 20 73 74 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20 strlen(zVal);.
7f70: 20 20 20 77 68 69 6c 65 28 20 69 3e 30 20 26 26 while( i>0 &&
7f80: 20 69 73 73 70 61 63 65 28 7a 56 61 6c 5b 69 2d isspace(zVal[i-
7f90: 31 5d 29 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20 1]) ){ i--; }.
7fa0: 20 20 7a 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 zVal[i] = 0;.
7fb0: 20 20 20 66 6f 72 28 69 3d 30 3b 20 7a 46 69 65 for(i=0; zFie
7fc0: 6c 64 4e 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b ldName[i]; i++){
7fd0: 20 7a 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d zFieldName[i] =
7fe0: 20 74 6f 6c 6f 77 65 72 28 7a 46 69 65 6c 64 4e tolower(zFieldN
7ff0: 61 6d 65 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 69 ame[i]); }. i
8000: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 f( strcmp(zField
8010: 4e 61 6d 65 2c 22 75 73 65 72 2d 61 67 65 6e 74 Name,"user-agent
8020: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 :")==0 ){.
8030: 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 cgi_setenv("HTTP
8040: 5f 55 53 45 52 5f 41 47 45 4e 54 22 2c 20 7a 56 _USER_AGENT", zV
8050: 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 al);. }else i
8060: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 f( strcmp(zField
8070: 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65 Name,"content-le
8080: 6e 67 74 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 ngth:")==0 ){.
8090: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 cgi_setenv("
80a0: 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c CONTENT_LENGTH",
80b0: 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 zVal);. }els
80c0: 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 e if( strcmp(zFi
80d0: 65 6c 64 4e 61 6d 65 2c 22 72 65 66 65 72 65 72 eldName,"referer
80e0: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 :")==0 ){.
80f0: 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 50 cgi_setenv("HTTP
8100: 5f 52 45 46 45 52 45 52 22 2c 20 7a 56 61 6c 29 _REFERER", zVal)
8110: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 ;. }else if(
8120: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d strcmp(zFieldNam
8130: 65 2c 22 68 6f 73 74 3a 22 29 3d 3d 30 20 29 7b e,"host:")==0 ){
8140: 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e . cgi_seten
8150: 76 28 22 48 54 54 50 5f 48 4f 53 54 22 2c 20 7a v("HTTP_HOST", z
8160: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 Val);. }else
8170: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c if( strcmp(zFiel
8180: 64 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 74 dName,"content-t
8190: 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 ype:")==0 ){.
81a0: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 cgi_setenv("C
81b0: 4f 4e 54 45 4e 54 5f 54 59 50 45 22 2c 20 7a 56 ONTENT_TYPE", zV
81c0: 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 al);. }else i
81d0: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 f( strcmp(zField
81e0: 4e 61 6d 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d Name,"cookie:")=
81f0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f =0 ){. cgi_
8200: 73 65 74 65 6e 76 28 22 48 54 54 50 5f 43 4f 4f setenv("HTTP_COO
8210: 4b 49 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 KIE", zVal);.
8220: 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 6d }else if( strcm
8230: 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 p(zFieldName,"if
8240: 2d 6e 6f 6e 65 2d 6d 61 74 63 68 3a 22 29 3d 3d -none-match:")==
8250: 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 0 ){. cgi_s
8260: 65 74 65 6e 76 28 22 48 54 54 50 5f 49 46 5f 4e etenv("HTTP_IF_N
8270: 4f 4e 45 5f 4d 41 54 43 48 22 2c 20 7a 56 61 6c ONE_MATCH", zVal
8280: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 );. }else if(
8290: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 strcmp(zFieldNa
82a0: 6d 65 2c 22 69 66 2d 6d 6f 64 69 66 69 65 64 2d me,"if-modified-
82b0: 73 69 6e 63 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 since:")==0 ){.
82c0: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 cgi_setenv(
82d0: 22 48 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 "HTTP_IF_MODIFIE
82e0: 44 5f 53 49 4e 43 45 22 2c 20 7a 56 61 6c 29 3b D_SINCE", zVal);
82f0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 67 . }. }.. cg
8300: 69 5f 69 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a i_init();.}../*.
8310: 2a 2a 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 ** Maximum numbe
8320: 72 20 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65 r of child proce
8330: 73 73 65 73 20 74 68 61 74 20 77 65 20 63 61 6e sses that we can
8340: 20 68 61 76 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a have running.**
8350: 20 61 74 20 6f 6e 65 20 74 69 6d 65 20 62 65 66 at one time bef
8360: 6f 72 65 20 77 65 20 73 74 61 72 74 20 73 6c 6f ore we start slo
8370: 77 69 6e 67 20 74 68 69 6e 67 73 20 64 6f 77 6e wing things down
8380: 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 41 58 ..*/.#define MAX
8390: 5f 50 41 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a _PARALLEL 2../*.
83a0: 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 ** Implement an
83b0: 48 54 54 50 20 73 65 72 76 65 72 20 64 61 65 6d HTTP server daem
83c0: 6f 6e 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20 on listening on
83d0: 70 6f 72 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a port iPort..**.*
83e0: 2a 20 41 73 20 6e 65 77 20 63 6f 6e 6e 65 63 74 * As new connect
83f0: 69 6f 6e 73 20 61 72 72 69 76 65 2c 20 66 6f 72 ions arrive, for
8400: 6b 20 61 20 63 68 69 6c 64 20 61 6e 64 20 6c 65 k a child and le
8410: 74 20 63 68 69 6c 64 20 72 65 74 75 72 6e 0a 2a t child return.*
8420: 2a 20 6f 75 74 20 6f 66 20 74 68 69 73 20 70 72 * out of this pr
8430: 6f 63 65 64 75 72 65 20 63 61 6c 6c 2e 20 20 54 ocedure call. T
8440: 68 65 20 63 68 69 6c 64 20 77 69 6c 6c 20 68 61 he child will ha
8450: 6e 64 6c 65 20 74 68 65 20 72 65 71 75 65 73 74 ndle the request
8460: 2e 0a 2a 2a 20 54 68 65 20 70 61 72 65 6e 74 20 ..** The parent
8470: 6e 65 76 65 72 20 72 65 74 75 72 6e 73 20 66 72 never returns fr
8480: 6f 6d 20 74 68 69 73 20 70 72 6f 63 65 64 75 72 om this procedur
8490: 65 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 e..**.** Return
84a0: 30 20 74 6f 20 65 61 63 68 20 63 68 69 6c 64 20 0 to each child
84b0: 61 73 20 69 74 20 72 75 6e 73 2e 20 20 49 66 20 as it runs. If
84c0: 75 6e 61 62 6c 65 20 74 6f 20 65 73 74 61 62 6c unable to establ
84d0: 69 73 68 20 61 0a 2a 2a 20 6c 69 73 74 65 6e 69 ish a.** listeni
84e0: 6e 67 20 73 6f 63 6b 65 74 2c 20 72 65 74 75 72 ng socket, retur
84f0: 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2f 0a 69 n non-zero..*/.i
8500: 6e 74 20 63 67 69 5f 68 74 74 70 5f 73 65 72 76 nt cgi_http_serv
8510: 65 72 28 69 6e 74 20 69 50 6f 72 74 2c 20 63 68 er(int iPort, ch
8520: 61 72 20 2a 7a 42 72 6f 77 73 65 72 29 7b 0a 23 ar *zBrowser){.#
8530: 69 66 64 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f ifdef __MINGW32_
8540: 5f 0a 20 20 66 70 72 69 6e 74 66 28 73 74 64 65 _. fprintf(stde
8550: 72 72 2c 22 73 65 72 76 65 72 20 6e 6f 74 20 79 rr,"server not y
8560: 65 74 20 61 76 61 69 6c 61 62 6c 65 20 69 6e 20 et available in
8570: 77 69 6e 64 6f 77 73 20 76 65 72 73 69 6f 6e 20 windows version
8580: 6f 66 20 66 6f 73 73 69 6c 5c 6e 22 29 3b 0a 20 of fossil\n");.
8590: 20 65 78 69 74 28 31 29 3b 0a 23 65 6c 73 65 0a exit(1);.#else.
85a0: 20 20 69 6e 74 20 6c 69 73 74 65 6e 65 72 3b 20 int listener;
85b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f /
85c0: 2a 20 54 68 65 20 73 65 72 76 65 72 20 73 6f 63 * The server soc
85d0: 6b 65 74 20 2a 2f 0a 20 20 69 6e 74 20 63 6f 6e ket */. int con
85e0: 6e 65 63 74 69 6f 6e 3b 20 20 20 20 20 20 20 20 nection;
85f0: 20 20 20 20 20 20 2f 2a 20 41 20 73 6f 63 6b 65 /* A socke
8600: 74 20 66 6f 72 20 65 61 63 68 20 69 6e 64 69 76 t for each indiv
8610: 69 64 75 61 6c 20 63 6f 6e 6e 65 63 74 69 6f 6e idual connection
8620: 20 2a 2f 0a 20 20 66 64 5f 73 65 74 20 72 65 61 */. fd_set rea
8630: 64 66 64 73 3b 20 20 20 20 20 20 20 20 20 20 20 dfds;
8640: 20 20 20 2f 2a 20 53 65 74 20 6f 66 20 66 69 6c /* Set of fil
8650: 65 20 64 65 73 63 72 69 70 74 6f 72 73 20 66 6f e descriptors fo
8660: 72 20 73 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 r select() */.
8670: 73 69 7a 65 5f 74 20 6c 65 6e 61 64 64 72 3b 20 size_t lenaddr;
8680: 20 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 /*
8690: 4c 65 6e 67 74 68 20 6f 66 20 74 68 65 20 69 6e Length of the in
86a0: 61 64 64 72 20 73 74 72 75 63 74 75 72 65 20 2a addr structure *
86b0: 2f 0a 20 20 69 6e 74 20 63 68 69 6c 64 3b 20 20 /. int child;
86c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
86d0: 20 2f 2a 20 50 49 44 20 6f 66 20 74 68 65 20 63 /* PID of the c
86e0: 68 69 6c 64 20 70 72 6f 63 65 73 73 20 2a 2f 0a hild process */.
86f0: 20 20 69 6e 74 20 6e 63 68 69 6c 64 72 65 6e 20 int nchildren
8700: 3d 20 30 3b 20 20 20 20 20 20 20 20 20 20 20 2f = 0; /
8710: 2a 20 4e 75 6d 62 65 72 20 6f 66 20 63 68 69 6c * Number of chil
8720: 64 20 70 72 6f 63 65 73 73 65 73 20 2a 2f 0a 20 d processes */.
8730: 20 73 74 72 75 63 74 20 74 69 6d 65 76 61 6c 20 struct timeval
8740: 64 65 6c 61 79 3b 20 20 20 20 20 20 20 20 2f 2a delay; /*
8750: 20 48 6f 77 20 6c 6f 6e 67 20 74 6f 20 77 61 69 How long to wai
8760: 74 20 69 6e 73 69 64 65 20 73 65 6c 65 63 74 28 t inside select(
8770: 29 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 73 6f ) */. struct so
8780: 63 6b 61 64 64 72 5f 69 6e 20 69 6e 61 64 64 72 ckaddr_in inaddr
8790: 3b 20 20 20 2f 2a 20 54 68 65 20 73 6f 63 6b 65 ; /* The socke
87a0: 74 20 61 64 64 72 65 73 73 20 2a 2f 0a 20 20 69 t address */. i
87b0: 6e 74 20 6f 70 74 20 3d 20 31 3b 20 20 20 20 20 nt opt = 1;
87c0: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 73 /* s
87d0: 65 74 73 6f 63 6b 6f 70 74 20 66 6c 61 67 20 2a etsockopt flag *
87e0: 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 26 69 6e 61 /.. memset(&ina
87f0: 64 64 72 2c 20 30 2c 20 73 69 7a 65 6f 66 28 69 ddr, 0, sizeof(i
8800: 6e 61 64 64 72 29 29 3b 0a 20 20 69 6e 61 64 64 naddr));. inadd
8810: 72 2e 73 69 6e 5f 66 61 6d 69 6c 79 20 3d 20 41 r.sin_family = A
8820: 46 5f 49 4e 45 54 3b 0a 20 20 69 6e 61 64 64 72 F_INET;. inaddr
8830: 2e 73 69 6e 5f 61 64 64 72 2e 73 5f 61 64 64 72 .sin_addr.s_addr
8840: 20 3d 20 49 4e 41 44 44 52 5f 41 4e 59 3b 0a 20 = INADDR_ANY;.
8850: 20 69 6e 61 64 64 72 2e 73 69 6e 5f 70 6f 72 74 inaddr.sin_port
8860: 20 3d 20 68 74 6f 6e 73 28 69 50 6f 72 74 29 3b = htons(iPort);
8870: 0a 20 20 6c 69 73 74 65 6e 65 72 20 3d 20 73 6f . listener = so
8880: 63 6b 65 74 28 41 46 5f 49 4e 45 54 2c 20 53 4f cket(AF_INET, SO
8890: 43 4b 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a 20 CK_STREAM, 0);.
88a0: 20 69 66 28 20 6c 69 73 74 65 6e 65 72 3c 30 20 if( listener<0
88b0: 29 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 31 3b ){. return 1;
88c0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 69 66 20 77 65 . }.. /* if we
88d0: 20 63 61 6e 27 74 20 74 65 72 6d 69 6e 61 74 65 can't terminate
88e0: 20 6e 69 63 65 6c 79 2c 20 61 74 20 6c 65 61 73 nicely, at leas
88f0: 74 20 61 6c 6c 6f 77 20 74 68 65 20 73 6f 63 6b t allow the sock
8900: 65 74 20 74 6f 20 62 65 20 72 65 75 73 65 64 20 et to be reused
8910: 2a 2f 0a 20 20 73 65 74 73 6f 63 6b 6f 70 74 28 */. setsockopt(
8920: 6c 69 73 74 65 6e 65 72 2c 53 4f 4c 5f 53 4f 43 listener,SOL_SOC
8930: 4b 45 54 2c 53 4f 5f 52 45 55 53 45 41 44 44 52 KET,SO_REUSEADDR
8940: 2c 26 6f 70 74 2c 73 69 7a 65 6f 66 28 6f 70 74 ,&opt,sizeof(opt
8950: 29 29 3b 0a 0a 20 20 69 66 28 20 62 69 6e 64 28 ));.. if( bind(
8960: 6c 69 73 74 65 6e 65 72 2c 20 28 73 74 72 75 63 listener, (struc
8970: 74 20 73 6f 63 6b 61 64 64 72 2a 29 26 69 6e 61 t sockaddr*)&ina
8980: 64 64 72 2c 20 73 69 7a 65 6f 66 28 69 6e 61 64 ddr, sizeof(inad
8990: 64 72 29 29 3c 30 20 29 7b 0a 20 20 20 20 63 6c dr))<0 ){. cl
89a0: 6f 73 65 28 6c 69 73 74 65 6e 65 72 29 3b 0a 20 ose(listener);.
89b0: 20 20 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 7d return 1;. }
89c0: 0a 20 20 6c 69 73 74 65 6e 28 6c 69 73 74 65 6e . listen(listen
89d0: 65 72 2c 31 30 29 3b 0a 20 20 69 66 28 20 7a 42 er,10);. if( zB
89e0: 72 6f 77 73 65 72 20 29 7b 0a 20 20 20 20 73 79 rowser ){. sy
89f0: 73 74 65 6d 28 7a 42 72 6f 77 73 65 72 29 3b 0a stem(zBrowser);.
8a00: 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 31 20 29 }. while( 1 )
8a10: 7b 0a 20 20 20 20 69 66 28 20 6e 63 68 69 6c 64 {. if( nchild
8a20: 72 65 6e 3e 4d 41 58 5f 50 41 52 41 4c 4c 45 4c ren>MAX_PARALLEL
8a30: 20 29 7b 0a 20 20 20 20 20 20 2f 2a 20 53 6c 6f ){. /* Slo
8a40: 77 20 64 6f 77 6e 20 69 66 20 63 6f 6e 6e 65 63 w down if connec
8a50: 74 69 6f 6e 73 20 61 72 65 20 61 72 72 69 76 69 tions are arrivi
8a60: 6e 67 20 74 6f 6f 20 66 61 73 74 20 2a 2f 0a 20 ng too fast */.
8a70: 20 20 20 20 20 73 6c 65 65 70 28 20 6e 63 68 69 sleep( nchi
8a80: 6c 64 72 65 6e 2d 4d 41 58 5f 50 41 52 41 4c 4c ldren-MAX_PARALL
8a90: 45 4c 20 29 3b 0a 20 20 20 20 7d 0a 20 20 20 20 EL );. }.
8aa0: 64 65 6c 61 79 2e 74 76 5f 73 65 63 20 3d 20 36 delay.tv_sec = 6
8ab0: 30 3b 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 5f 0;. delay.tv_
8ac0: 75 73 65 63 20 3d 20 30 3b 0a 20 20 20 20 46 44 usec = 0;. FD
8ad0: 5f 5a 45 52 4f 28 26 72 65 61 64 66 64 73 29 3b _ZERO(&readfds);
8ae0: 0a 20 20 20 20 46 44 5f 53 45 54 28 20 6c 69 73 . FD_SET( lis
8af0: 74 65 6e 65 72 2c 20 26 72 65 61 64 66 64 73 29 tener, &readfds)
8b00: 3b 0a 20 20 20 20 69 66 28 20 73 65 6c 65 63 74 ;. if( select
8b10: 28 20 6c 69 73 74 65 6e 65 72 2b 31 2c 20 26 72 ( listener+1, &r
8b20: 65 61 64 66 64 73 2c 20 30 2c 20 30 2c 20 26 64 eadfds, 0, 0, &d
8b30: 65 6c 61 79 29 20 29 7b 0a 20 20 20 20 20 20 6c elay) ){. l
8b40: 65 6e 61 64 64 72 20 3d 20 73 69 7a 65 6f 66 28 enaddr = sizeof(
8b50: 69 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 20 63 inaddr);. c
8b60: 6f 6e 6e 65 63 74 69 6f 6e 20 3d 20 61 63 63 65 onnection = acce
8b70: 70 74 28 6c 69 73 74 65 6e 65 72 2c 20 28 73 74 pt(listener, (st
8b80: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26 ruct sockaddr*)&
8b90: 69 6e 61 64 64 72 2c 0a 20 20 20 20 20 20 20 20 inaddr,.
8ba0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8bb0: 20 20 20 20 20 20 20 20 20 20 20 20 28 73 6f 63 (soc
8bc0: 6b 6c 65 6e 5f 74 2a 29 20 26 6c 65 6e 61 64 64 klen_t*) &lenadd
8bd0: 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20 63 6f r);. if( co
8be0: 6e 6e 65 63 74 69 6f 6e 3e 3d 30 20 29 7b 0a 20 nnection>=0 ){.
8bf0: 20 20 20 20 20 20 20 63 68 69 6c 64 20 3d 20 66 child = f
8c00: 6f 72 6b 28 29 3b 0a 20 20 20 20 20 20 20 20 69 ork();. i
8c10: 66 28 20 63 68 69 6c 64 21 3d 30 20 29 7b 0a 20 f( child!=0 ){.
8c20: 20 20 20 20 20 20 20 20 20 69 66 28 20 63 68 69 if( chi
8c30: 6c 64 3e 30 20 29 20 6e 63 68 69 6c 64 72 65 6e ld>0 ) nchildren
8c40: 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 63 6c ++;. cl
8c50: 6f 73 65 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b ose(connection);
8c60: 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a . }else{.
8c70: 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 close(
8c80: 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 75 0);. du
8c90: 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 p(connection);.
8ca0: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 31 close(1
8cb0: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 75 70 );. dup
8cc0: 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 (connection);.
8cd0: 20 20 20 20 20 20 20 20 69 66 28 20 21 67 2e 66 if( !g.f
8ce0: 48 74 74 70 54 72 61 63 65 20 29 7b 0a 20 20 20 HttpTrace ){.
8cf0: 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 32 close(2
8d00: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 20 64 );. d
8d10: 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a up(connection);.
8d20: 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 }.
8d30: 20 20 20 20 20 20 63 6c 6f 73 65 28 63 6f 6e 6e close(conn
8d40: 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 ection);.
8d50: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 20 return 0;.
8d60: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 }. }.
8d70: 20 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75 72 79 }. /* Bury
8d80: 20 64 65 61 64 20 63 68 69 6c 64 72 65 6e 20 2a dead children *
8d90: 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 77 61 69 /. while( wai
8da0: 74 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f 48 41 tpid(0, 0, WNOHA
8db0: 4e 47 29 3e 30 20 29 7b 0a 20 20 20 20 20 20 6e NG)>0 ){. n
8dc0: 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20 20 20 children--;.
8dd0: 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54 20 52 }. }. /* NOT R
8de0: 45 41 43 48 45 44 20 2a 2f 20 20 0a 20 20 65 78 EACHED */ . ex
8df0: 69 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a it(1);.#endif.}.
8e00: 0a 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66 20 ../*.** Name of
8e10: 64 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73 2e days and months.
8e20: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 .*/.static const
8e30: 20 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d 20 char *azDays[]
8e40: 3d 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22 4d =. {"Sun", "M
8e50: 6f 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65 64 on", "Tue", "Wed
8e60: 22 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22 2c ", "Thu", "Fri",
8e70: 20 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61 74 "Sat", 0};.stat
8e80: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 ic const char *a
8e90: 7a 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20 20 zMonths[] =.
8ea0: 7b 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20 22 {"Jan", "Feb", "
8eb0: 4d 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d 61 Mar", "Apr", "Ma
8ec0: 79 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20 20 y", "Jun",.
8ed0: 22 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22 53 "Jul", "Aug", "S
8ee0: 65 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f 76 ep", "Oct", "Nov
8ef0: 22 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a 0a ", "Dec", 0};...
8f00: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61 6e /*.** Returns an
8f10: 20 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 RFC822-formatte
8f20: 64 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73 75 d time string su
8f30: 69 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50 20 itable for HTTP
8f40: 68 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a 2a headers, among.*
8f50: 2a 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e 0a * other things..
8f60: 2a 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d 65 ** Returned time
8f70: 7a 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20 47 zone is always G
8f80: 4d 54 20 61 73 20 72 65 71 75 69 72 65 64 20 62 MT as required b
8f90: 79 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63 69 y HTTP/1.1 speci
8fa0: 66 69 63 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 fication..**.**
8fb0: 53 65 65 20 68 74 74 70 3a 2f 2f 77 77 77 2e 66 See http://www.f
8fc0: 61 71 73 2e 6f 72 67 2f 72 66 63 73 2f 72 66 63 aqs.org/rfcs/rfc
8fd0: 38 32 32 2e 68 74 6d 6c 2c 20 73 65 63 74 69 6f 822.html, sectio
8fe0: 6e 20 35 0a 2a 2a 20 61 6e 64 20 68 74 74 70 3a n 5.** and http:
8ff0: 2f 2f 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f 72 //www.faqs.org/r
9000: 66 63 73 2f 72 66 63 32 36 31 36 2e 68 74 6d 6c fcs/rfc2616.html
9010: 2c 20 73 65 63 74 69 6f 6e 20 33 2e 33 2e 0a 2a , section 3.3..*
9020: 2f 0a 63 68 61 72 20 2a 63 67 69 5f 72 66 63 38 /.char *cgi_rfc8
9030: 32 32 5f 64 61 74 65 73 74 61 6d 70 28 74 69 6d 22_datestamp(tim
9040: 65 5f 74 20 6e 6f 77 29 7b 0a 20 20 73 74 72 75 e_t now){. stru
9050: 63 74 20 74 6d 20 2a 70 54 6d 3b 0a 20 20 70 54 ct tm *pTm;. pT
9060: 6d 20 3d 20 67 6d 74 69 6d 65 28 26 6e 6f 77 29 m = gmtime(&now)
9070: 3b 0a 20 20 69 66 28 20 70 54 6d 3d 3d 30 20 29 ;. if( pTm==0 )
9080: 20 72 65 74 75 72 6e 20 22 22 3b 0a 20 20 72 65 return "";. re
9090: 74 75 72 6e 20 6d 70 72 69 6e 74 66 28 22 25 73 turn mprintf("%s
90a0: 2c 20 25 64 20 25 73 20 25 30 32 64 20 25 30 32 , %d %s %02d %02
90b0: 64 3a 25 30 32 64 3a 25 30 32 64 20 47 4d 54 22 d:%02d:%02d GMT"
90c0: 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 ,.
90d0: 20 20 20 61 7a 44 61 79 73 5b 70 54 6d 2d 3e 74 azDays[pTm->t
90e0: 6d 5f 77 64 61 79 5d 2c 20 70 54 6d 2d 3e 74 6d m_wday], pTm->tm
90f0: 5f 6d 64 61 79 2c 20 61 7a 4d 6f 6e 74 68 73 5b _mday, azMonths[
9100: 70 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d 2c 0a 20 20 pTm->tm_mon],.
9110: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 p
9120: 54 6d 2d 3e 74 6d 5f 79 65 61 72 2b 31 39 30 30 Tm->tm_year+1900
9130: 2c 20 70 54 6d 2d 3e 74 6d 5f 68 6f 75 72 2c 20 , pTm->tm_hour,
9140: 70 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c 20 70 54 6d pTm->tm_min, pTm
9150: 2d 3e 74 6d 5f 73 65 63 29 3b 0a 7d 0a 0a 2f 2a ->tm_sec);.}../*
9160: 0a 2a 2a 20 50 61 72 73 65 20 61 6e 20 52 46 43 .** Parse an RFC
9170: 38 32 32 2d 66 6f 72 6d 61 74 74 65 64 20 74 69 822-formatted ti
9180: 6d 65 73 74 61 6d 70 20 61 73 20 77 65 27 64 20 mestamp as we'd
9190: 65 78 70 65 63 74 20 66 72 6f 6d 20 48 54 54 50 expect from HTTP
91a0: 20 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20 61 and return.** a
91b0: 20 55 6e 69 78 20 65 70 6f 63 68 20 74 69 6d 65 Unix epoch time
91c0: 2e 20 3c 3d 20 7a 65 72 6f 20 69 73 20 72 65 74 . <= zero is ret
91d0: 75 72 6e 65 64 20 6f 6e 20 66 61 69 6c 75 72 65 urned on failure
91e0: 2e 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 ..**.** Note tha
91f0: 74 20 74 68 69 73 20 77 6f 6e 27 74 20 68 61 6e t this won't han
9200: 64 6c 65 20 61 6c 6c 20 74 68 65 20 5f 61 6c 6c dle all the _all
9210: 6f 77 65 64 5f 20 48 54 54 50 20 66 6f 72 6d 61 owed_ HTTP forma
9220: 74 73 2c 20 6a 75 73 74 20 74 68 65 0a 2a 2a 20 ts, just the.**
9230: 6d 6f 73 74 20 70 6f 70 75 6c 61 72 20 6f 6e 65 most popular one
9240: 20 28 74 68 65 20 6f 6e 65 20 67 65 6e 65 72 61 (the one genera
9250: 74 65 64 20 62 79 20 63 67 69 5f 72 66 63 38 32 ted by cgi_rfc82
9260: 32 5f 64 61 74 65 73 74 61 6d 70 28 29 2c 20 61 2_datestamp(), a
9270: 63 74 75 61 6c 6c 79 29 2e 0a 2a 2f 0a 74 69 6d ctually)..*/.tim
9280: 65 5f 74 20 63 67 69 5f 72 66 63 38 32 32 5f 70 e_t cgi_rfc822_p
9290: 61 72 73 65 64 61 74 65 28 63 6f 6e 73 74 20 63 arsedate(const c
92a0: 68 61 72 20 2a 7a 44 61 74 65 29 7b 0a 20 20 73 har *zDate){. s
92b0: 74 72 75 63 74 20 74 6d 20 74 3b 0a 20 20 63 68 truct tm t;. ch
92c0: 61 72 20 7a 49 67 6e 6f 72 65 5b 31 36 5d 3b 0a ar zIgnore[16];.
92d0: 20 20 63 68 61 72 20 7a 4d 6f 6e 74 68 5b 31 36 char zMonth[16
92e0: 5d 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 74 2c ];.. memset(&t,
92f0: 20 30 2c 20 73 69 7a 65 6f 66 28 74 29 29 3b 0a 0, sizeof(t));.
9300: 20 20 69 66 28 20 37 3d 3d 73 73 63 61 6e 66 28 if( 7==sscanf(
9310: 7a 44 61 74 65 2c 20 22 25 31 32 5b 41 2d 5a 61 zDate, "%12[A-Za
9320: 2d 7a 2c 5d 20 25 64 20 25 31 32 5b 41 2d 5a 61 -z,] %d %12[A-Za
9330: 2d 7a 5d 20 25 64 20 25 64 3a 25 64 3a 25 64 22 -z] %d %d:%d:%d"
9340: 2c 20 7a 49 67 6e 6f 72 65 2c 0a 20 20 20 20 20 , zIgnore,.
9350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
9360: 20 20 26 74 2e 74 6d 5f 6d 64 61 79 2c 20 7a 4d &t.tm_mday, zM
9370: 6f 6e 74 68 2c 20 26 74 2e 74 6d 5f 79 65 61 72 onth, &t.tm_year
9380: 2c 20 26 74 2e 74 6d 5f 68 6f 75 72 2c 20 26 74 , &t.tm_hour, &t
9390: 2e 74 6d 5f 6d 69 6e 2c 0a 20 20 20 20 20 20 20 .tm_min,.
93a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
93b0: 26 74 2e 74 6d 5f 73 65 63 29 29 7b 0a 0a 20 20 &t.tm_sec)){..
93c0: 20 20 69 66 28 20 74 2e 74 6d 5f 79 65 61 72 20 if( t.tm_year
93d0: 3e 20 31 39 30 30 20 29 20 74 2e 74 6d 5f 79 65 > 1900 ) t.tm_ye
93e0: 61 72 20 2d 3d 20 31 39 30 30 3b 0a 20 20 20 20 ar -= 1900;.
93f0: 66 6f 72 28 74 2e 74 6d 5f 6d 6f 6e 3d 30 3b 20 for(t.tm_mon=0;
9400: 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f azMonths[t.tm_mo
9410: 6e 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e 2b 2b 29 7b n]; t.tm_mon++){
9420: 0a 20 20 20 20 20 20 69 66 28 20 21 73 74 72 6e . if( !strn
9430: 63 61 73 65 63 6d 70 28 20 61 7a 4d 6f 6e 74 68 casecmp( azMonth
9440: 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c 20 7a 4d 6f s[t.tm_mon], zMo
9450: 6e 74 68 2c 20 33 20 29 29 7b 0a 20 20 20 20 20 nth, 3 )){.
9460: 20 20 20 72 65 74 75 72 6e 20 6d 6b 67 6d 74 69 return mkgmti
9470: 6d 65 28 26 74 29 3b 0a 20 20 20 20 20 20 7d 0a me(&t);. }.
9480: 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 }. }.. ret
9490: 75 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 urn 0;.}../*.**
94a0: 43 6f 6e 76 65 72 74 20 61 20 73 74 72 75 63 74 Convert a struct
94b0: 20 74 6d 2a 20 74 68 61 74 20 72 65 70 72 65 73 tm* that repres
94c0: 65 6e 74 73 20 61 20 6d 6f 6d 65 6e 74 20 69 6e ents a moment in
94d0: 20 55 54 43 20 69 6e 74 6f 20 74 68 65 20 6e 75 UTC into the nu
94e0: 6d 62 65 72 0a 2a 2a 20 6f 66 20 73 65 63 6f 6e mber.** of secon
94f0: 64 73 20 69 6e 20 31 39 37 30 2c 20 55 54 43 2e ds in 1970, UTC.
9500: 0a 2a 2f 0a 74 69 6d 65 5f 74 20 6d 6b 67 6d 74 .*/.time_t mkgmt
9510: 69 6d 65 28 73 74 72 75 63 74 20 74 6d 20 2a 70 ime(struct tm *p
9520: 29 7b 0a 20 20 74 69 6d 65 5f 74 20 74 3b 0a 20 ){. time_t t;.
9530: 20 69 6e 74 20 6e 44 61 79 3b 0a 20 20 69 6e 74 int nDay;. int
9540: 20 69 73 4c 65 61 70 59 72 3b 0a 20 20 2f 2a 20 isLeapYr;. /*
9550: 44 61 79 73 20 69 6e 20 65 61 63 68 20 6d 6f 6e Days in each mon
9560: 74 68 3a 20 20 20 20 20 20 20 33 31 2c 20 32 38 th: 31, 28
9570: 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33 30 , 31, 30, 31, 30
9580: 2c 20 33 31 2c 20 33 31 2c 20 33 30 2c 20 33 31 , 31, 31, 30, 31
9590: 2c 20 33 30 2c 20 33 31 20 2a 2f 0a 20 20 73 74 , 30, 31 */. st
95a0: 61 74 69 63 20 69 6e 74 20 70 72 69 6f 72 44 61 atic int priorDa
95b0: 79 73 5b 5d 20 20 20 3d 20 7b 20 20 30 2c 20 33 ys[] = { 0, 3
95c0: 31 2c 20 35 39 2c 20 39 30 2c 31 32 30 2c 31 35 1, 59, 90,120,15
95d0: 31 2c 31 38 31 2c 32 31 32 2c 32 34 33 2c 32 37 1,181,212,243,27
95e0: 33 2c 33 30 34 2c 33 33 34 20 7d 3b 0a 20 20 69 3,304,334 };. i
95f0: 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3c 30 20 29 f( p->tm_mon<0 )
9600: 7b 0a 20 20 20 20 69 6e 74 20 6e 59 65 61 72 20 {. int nYear
9610: 3d 20 28 31 31 20 2d 20 70 2d 3e 74 6d 5f 6d 6f = (11 - p->tm_mo
9620: 6e 29 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74 6d n)/12;. p->tm
9630: 5f 79 65 61 72 20 2d 3d 20 6e 59 65 61 72 3b 0a _year -= nYear;.
9640: 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 20 2b 3d p->tm_mon +=
9650: 20 6e 59 65 61 72 2a 31 32 3b 0a 20 20 7d 65 6c nYear*12;. }el
9660: 73 65 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e se if( p->tm_mon
9670: 3e 31 31 20 29 7b 0a 20 20 20 20 70 2d 3e 74 6d >11 ){. p->tm
9680: 5f 79 65 61 72 20 2b 3d 20 70 2d 3e 74 6d 5f 6d _year += p->tm_m
9690: 6f 6e 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74 6d on/12;. p->tm
96a0: 5f 6d 6f 6e 20 25 3d 20 31 32 3b 0a 20 20 7d 0a _mon %= 12;. }.
96b0: 20 20 69 73 4c 65 61 70 59 72 20 3d 20 70 2d 3e isLeapYr = p->
96c0: 74 6d 5f 79 65 61 72 25 34 3d 3d 30 20 26 26 20 tm_year%4==0 &&
96d0: 28 70 2d 3e 74 6d 5f 79 65 61 72 25 31 30 30 21 (p->tm_year%100!
96e0: 3d 30 20 7c 7c 20 28 70 2d 3e 74 6d 5f 79 65 61 =0 || (p->tm_yea
96f0: 72 2b 33 30 30 29 25 34 30 30 3d 3d 30 29 3b 0a r+300)%400==0);.
9700: 20 20 70 2d 3e 74 6d 5f 79 64 61 79 20 3d 20 70 p->tm_yday = p
9710: 72 69 6f 72 44 61 79 73 5b 70 2d 3e 74 6d 5f 6d riorDays[p->tm_m
9720: 6f 6e 5d 20 2b 20 70 2d 3e 74 6d 5f 6d 64 61 79 on] + p->tm_mday
9730: 20 2d 20 31 3b 0a 20 20 69 66 28 20 69 73 4c 65 - 1;. if( isLe
9740: 61 70 59 72 20 26 26 20 70 2d 3e 74 6d 5f 6d 6f apYr && p->tm_mo
9750: 6e 3e 31 20 29 20 70 2d 3e 74 6d 5f 79 64 61 79 n>1 ) p->tm_yday
9760: 2b 2b 3b 0a 20 20 6e 44 61 79 20 3d 20 28 70 2d ++;. nDay = (p-
9770: 3e 74 6d 5f 79 65 61 72 2d 37 30 29 2a 33 36 35 >tm_year-70)*365
9780: 20 2b 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 36 + (p->tm_year-6
9790: 39 29 2f 34 20 2d 70 2d 3e 74 6d 5f 79 65 61 72 9)/4 -p->tm_year
97a0: 2f 31 30 30 20 2b 20 0a 20 20 20 20 20 20 20 20 /100 + .
97b0: 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2b 33 30 30 (p->tm_year+300
97c0: 29 2f 34 30 30 20 2b 20 70 2d 3e 74 6d 5f 79 64 )/400 + p->tm_yd
97d0: 61 79 3b 0a 20 20 74 20 3d 20 28 28 6e 44 61 79 ay;. t = ((nDay
97e0: 2a 32 34 20 2b 20 70 2d 3e 74 6d 5f 68 6f 75 72 *24 + p->tm_hour
97f0: 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 6d 69 6e )*60 + p->tm_min
9800: 29 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 73 65 63 )*60 + p->tm_sec
9810: 3b 0a 20 20 72 65 74 75 72 6e 20 74 3b 0a 7d 0a ;. return t;.}.
9820: 0a 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 65 ./*.** Check the
9830: 20 6f 62 6a 65 63 74 54 69 6d 65 20 61 67 61 69 objectTime agai
9840: 6e 73 74 20 74 68 65 20 49 66 2d 4d 6f 64 69 66 nst the If-Modif
9850: 69 65 64 2d 53 69 6e 63 65 20 72 65 71 75 65 73 ied-Since reques
9860: 74 20 68 65 61 64 65 72 2e 20 49 66 20 74 68 65 t header. If the
9870: 0a 2a 2a 20 6f 62 6a 65 63 74 20 74 69 6d 65 20 .** object time
9880: 69 73 6e 27 74 20 61 6e 79 20 6e 65 77 65 72 20 isn't any newer
9890: 74 68 61 6e 20 74 68 65 20 68 65 61 64 65 72 2c than the header,
98a0: 20 77 65 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 we immediately
98b0: 73 65 6e 64 20 62 61 63 6b 0a 2a 2a 20 61 20 33 send back.** a 3
98c0: 30 34 20 72 65 70 6c 79 20 61 6e 64 20 65 78 69 04 reply and exi
98d0: 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 6d t..*/.void cgi_m
98e0: 6f 64 69 66 69 65 64 5f 73 69 6e 63 65 28 74 69 odified_since(ti
98f0: 6d 65 5f 74 20 6f 62 6a 65 63 74 54 69 6d 65 29 me_t objectTime)
9900: 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a {. const char *
9910: 7a 49 66 20 3d 20 50 28 22 48 54 54 50 5f 49 46 zIf = P("HTTP_IF
9920: 5f 4d 4f 44 49 46 49 45 44 5f 53 49 4e 43 45 22 _MODIFIED_SINCE"
9930: 29 3b 0a 20 20 69 66 28 20 7a 49 66 3d 3d 30 20 );. if( zIf==0
9940: 29 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 ) return;. if(
9950: 6f 62 6a 65 63 74 54 69 6d 65 20 3e 20 63 67 69 objectTime > cgi
9960: 5f 72 66 63 38 32 32 5f 70 61 72 73 65 64 61 74 _rfc822_parsedat
9970: 65 28 7a 49 66 29 20 29 20 72 65 74 75 72 6e 3b e(zIf) ) return;
9980: 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 . cgi_set_statu
9990: 73 28 33 30 34 2c 22 4e 6f 74 20 4d 6f 64 69 66 s(304,"Not Modif
99a0: 69 65 64 22 29 3b 0a 20 20 63 67 69 5f 72 65 73 ied");. cgi_res
99b0: 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 et_content();.
99c0: 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 cgi_reply();. e
99d0: 78 69 74 28 30 29 3b 0a 7d 0a xit(0);.}.