0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20 /*.** Copyright
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68 (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54 ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66 his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75 u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20 te it and/or.**
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20 modify it under
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65 the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62 GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76 lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65 ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73 s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20 tributed in the
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20 l be useful,.**
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20 but WITHOUT ANY
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75 WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54 * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52 Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55 A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20 RPOSE. See the
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50 GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20 d have received
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63 U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72 g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69 ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65 te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20 ation, Inc., 59
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53 Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73 uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31 ton, MA 02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20 307, USA..**.**
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69 Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20 nformation:.**
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68 * http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 43 20 66 75 6e 63 contains C func
0380: 74 69 6f 6e 73 20 61 6e 64 20 70 72 6f 63 65 64 tions and proced
0390: 75 72 65 73 20 74 68 61 74 20 70 72 6f 76 69 64 ures that provid
03a0: 65 20 75 73 65 66 75 6c 0a 2a 2a 20 73 65 72 76 e useful.** serv
03b0: 69 63 65 73 20 74 6f 20 43 47 49 20 70 72 6f 67 ices to CGI prog
03c0: 72 61 6d 73 2e 20 20 54 68 65 72 65 20 61 72 65 rams. There are
03d0: 20 70 72 6f 63 65 64 75 72 65 73 20 66 6f 72 20 procedures for
03e0: 70 61 72 73 69 6e 67 20 61 6e 64 0a 2a 2a 20 64 parsing and.** d
03f0: 69 73 70 65 6e 73 69 6e 67 20 51 55 45 52 59 5f ispensing QUERY_
0400: 53 54 52 49 4e 47 20 70 61 72 61 6d 65 74 65 72 STRING parameter
0410: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2c 20 74 s and cookies, t
0420: 68 65 20 22 6d 70 72 69 6e 74 66 28 29 22 0a 2a he "mprintf()".*
0430: 2a 20 66 6f 72 6d 61 74 74 69 6e 67 20 66 75 6e * formatting fun
0440: 63 74 69 6f 6e 20 61 6e 64 20 69 74 73 20 63 6f ction and its co
0450: 75 73 69 6e 73 2c 20 61 6e 64 20 72 6f 75 74 69 usins, and routi
0460: 6e 65 73 20 74 6f 20 65 6e 63 6f 64 65 20 61 6e nes to encode an
0470: 64 0a 2a 2a 20 64 65 63 6f 64 65 20 73 74 72 69 d.** decode stri
0480: 6e 67 73 20 69 6e 20 48 54 4d 4c 20 6f 72 20 48 ngs in HTML or H
0490: 54 54 50 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 TTP..*/.#include
04a0: 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 66 64 "config.h".#ifd
04b0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 23 ef __MINGW32__.#
04c0: 20 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e 64 6f include <windo
04d0: 77 73 2e 68 3e 20 20 20 20 20 20 20 20 20 20 20 ws.h>
04e0: 2f 2a 20 66 6f 72 20 53 6c 65 65 70 20 6f 6e 63 /* for Sleep onc
04f0: 65 20 73 65 72 76 65 72 20 77 6f 72 6b 73 20 61 e server works a
0500: 67 61 69 6e 20 2a 2f 0a 23 20 20 69 6e 63 6c 75 gain */.# inclu
0510: 64 65 20 3c 77 69 6e 73 6f 63 6b 32 2e 68 3e 20 de <winsock2.h>
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 6f 63 6b /* sock
0530: 65 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f et operations */
0540: 0a 23 20 20 64 65 66 69 6e 65 20 73 6c 65 65 70 .# define sleep
0550: 20 53 6c 65 65 70 20 20 20 20 20 20 20 20 20 20 Sleep
0560: 20 20 2f 2a 20 77 69 6e 64 6f 77 73 20 64 6f 65 /* windows doe
0570: 73 20 6e 6f 74 20 68 61 76 65 20 73 6c 65 65 70 s not have sleep
0580: 2c 20 62 75 74 20 53 6c 65 65 70 20 2a 2f 0a 23 , but Sleep */.#
0590: 20 20 69 6e 63 6c 75 64 65 20 3c 77 73 32 74 63 include <ws2tc
05a0: 70 69 70 2e 68 3e 20 20 20 20 20 20 20 20 20 20 pip.h>
05b0: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64 .#else.# includ
05c0: 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e e <sys/socket.h>
05d0: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74 .# include <net
05e0: 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e inet/in.h>.# in
05f0: 63 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74 clude <arpa/inet
0600: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c .h>.# include <
0610: 73 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20 sys/times.h>.#
0620: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d include <sys/tim
0630: 65 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 e.h>.# include
0640: 3c 73 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20 <sys/wait.h>.#
0650: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c include <sys/sel
0660: 65 63 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69 ect.h>.#endif.#i
0670: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a nclude <time.h>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e #include <stdio.
0690: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 h>.#include <std
06a0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 lib.h>.#include
06b0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c <unistd.h>.#incl
06c0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66 ude "cgi.h"..#if
06d0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a INTERFACE./*.**
06e0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63 Shortcuts for c
06f0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50 gi_parameter. P
0700: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68 ("x") returns th
0710: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79 e value of query
0720: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72 parameter.** or
0730: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20 cookie "x", or
0740: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 NULL if there is
0750: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74 no such paramet
0760: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50 er or cookie. P
0770: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f D("x","y").** do
0780: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65 es the same exce
0790: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e pt "y" is return
07a0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e ed in place of N
07b0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 ULL if there is
07c0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64 not match..*/.#d
07d0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20 efine P(x)
07e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 cgi_parameter(
07f0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50 (x),0).#define P
0800: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70 D(x,y) cgi_p
0810: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29 arameter((x),(y)
0820: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20 ).#define QP(x)
0830: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73 quotable_s
0840: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65 tring(cgi_parame
0850: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66 ter((x),0)).#def
0860: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20 ine QPD(x,y)
0870: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28 quotable_string(
0880: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78 cgi_parameter((x
0890: 29 2c 28 79 29 29 29 0a 0a 0a 2f 2a 0a 2a 2a 20 ),(y))).../*.**
08a0: 44 65 73 74 69 6e 61 74 69 6f 6e 73 20 66 6f 72 Destinations for
08b0: 20 6f 75 74 70 75 74 20 74 65 78 74 2e 0a 2a 2f output text..*/
08c0: 0a 23 64 65 66 69 6e 65 20 43 47 49 5f 48 45 41 .#define CGI_HEA
08d0: 44 45 52 20 20 20 30 0a 23 64 65 66 69 6e 65 20 DER 0.#define
08e0: 43 47 49 5f 42 4f 44 59 20 20 20 20 20 31 0a 0a CGI_BODY 1..
08f0: 23 65 6e 64 69 66 20 2f 2a 20 49 4e 54 45 52 46 #endif /* INTERF
0900: 41 43 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 50 72 ACE */../*.** Pr
0910: 6f 76 69 64 65 20 61 20 72 65 6c 69 61 62 6c 65 ovide a reliable
0920: 20 69 6d 70 6c 65 6d 65 6e 74 61 74 69 6f 6e 20 implementation
0930: 6f 66 20 61 20 63 61 73 65 6c 65 73 73 20 73 74 of a caseless st
0940: 72 69 6e 67 20 63 6f 6d 70 61 72 69 73 6f 6e 0a ring comparison.
0950: 2a 2a 20 66 75 6e 63 74 69 6f 6e 2e 0a 2a 2f 0a ** function..*/.
0960: 23 64 65 66 69 6e 65 20 73 74 72 69 63 6d 70 20 #define stricmp
0970: 73 71 6c 69 74 65 33 53 74 72 49 43 6d 70 0a 65 sqlite3StrICmp.e
0980: 78 74 65 72 6e 20 69 6e 74 20 73 71 6c 69 74 65 xtern int sqlite
0990: 33 53 74 72 49 43 6d 70 28 63 6f 6e 73 74 20 63 3StrICmp(const c
09a0: 68 61 72 2a 2c 20 63 6f 6e 73 74 20 63 68 61 72 har*, const char
09b0: 2a 29 3b 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 20 48 *);../*.** The H
09c0: 54 54 50 20 72 65 70 6c 79 20 69 73 20 67 65 6e TTP reply is gen
09d0: 65 72 61 74 65 64 20 69 6e 20 74 77 6f 20 70 69 erated in two pi
09e0: 65 63 65 73 3a 20 74 68 65 20 68 65 61 64 65 72 eces: the header
09f0: 20 61 6e 64 20 74 68 65 20 62 6f 64 79 2e 0a 2a and the body..*
0a00: 2a 20 54 68 65 73 65 20 70 69 65 63 65 73 20 61 * These pieces a
0a10: 72 65 20 67 65 6e 65 72 61 74 65 64 20 73 65 70 re generated sep
0a20: 61 72 61 74 65 6c 79 20 62 65 63 61 75 73 65 20 arately because
0a30: 74 68 65 79 20 61 72 65 20 6e 6f 74 20 6e 65 63 they are not nec
0a40: 65 73 73 61 72 79 0a 2a 2a 20 70 72 6f 64 75 63 essary.** produc
0a50: 65 64 20 69 6e 20 6f 72 64 65 72 2e 20 20 50 61 ed in order. Pa
0a60: 72 74 73 20 6f 66 20 74 68 65 20 68 65 61 64 65 rts of the heade
0a70: 72 20 6d 69 67 68 74 20 62 65 20 62 75 69 6c 74 r might be built
0a80: 20 61 66 74 65 72 20 61 6c 6c 20 6f 72 0a 2a 2a after all or.**
0a90: 20 70 61 72 74 20 6f 66 20 74 68 65 20 62 6f 64 part of the bod
0aa0: 79 2e 20 20 54 68 65 20 68 65 61 64 65 72 20 61 y. The header a
0ab0: 6e 64 20 62 6f 64 79 20 61 72 65 20 61 63 63 75 nd body are accu
0ac0: 6d 75 6c 61 74 65 64 20 69 6e 20 73 65 70 61 72 mulated in separ
0ad0: 61 74 65 0a 2a 2a 20 42 6c 6f 62 20 73 74 72 75 ate.** Blob stru
0ae0: 63 74 75 72 65 73 20 74 68 65 6e 20 6f 75 74 70 ctures then outp
0af0: 75 74 20 73 65 71 75 65 6e 74 69 61 6c 6c 79 20 ut sequentially
0b00: 6f 6e 63 65 20 65 76 65 72 79 74 68 69 6e 67 20 once everything
0b10: 68 61 73 20 62 65 65 6e 0a 2a 2a 20 62 75 69 6c has been.** buil
0b20: 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 63 67 69 t..**.** The cgi
0b30: 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 29 20 69 _destination() i
0b40: 6e 74 65 72 66 61 63 65 20 73 77 69 74 63 68 20 nterface switch
0b50: 62 65 74 77 65 65 6e 20 74 68 65 20 62 75 66 66 between the buff
0b60: 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42 ers..*/.static B
0b70: 6c 6f 62 20 63 67 69 43 6f 6e 74 65 6e 74 5b 32 lob cgiContent[2
0b80: 5d 20 3d 20 7b 20 42 4c 4f 42 5f 49 4e 49 54 49 ] = { BLOB_INITI
0b90: 41 4c 49 5a 45 52 2c 20 42 4c 4f 42 5f 49 4e 49 ALIZER, BLOB_INI
0ba0: 54 49 41 4c 49 5a 45 52 20 7d 3b 0a 73 74 61 74 TIALIZER };.stat
0bb0: 69 63 20 42 6c 6f 62 20 2a 70 43 6f 6e 74 65 6e ic Blob *pConten
0bc0: 74 20 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b t = &cgiContent[
0bd0: 30 5d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 0];../*.** Set t
0be0: 68 65 20 64 65 73 74 69 6e 61 74 69 6f 6e 20 62 he destination b
0bf0: 75 66 66 65 72 20 69 6e 74 6f 20 77 68 69 63 68 uffer into which
0c00: 20 74 6f 20 61 63 63 75 6d 75 6c 61 74 65 20 43 to accumulate C
0c10: 47 49 20 63 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 76 GI content..*/.v
0c20: 6f 69 64 20 63 67 69 5f 64 65 73 74 69 6e 61 74 oid cgi_destinat
0c30: 69 6f 6e 28 69 6e 74 20 64 65 73 74 29 7b 0a 20 ion(int dest){.
0c40: 20 73 77 69 74 63 68 28 20 64 65 73 74 20 29 7b switch( dest ){
0c50: 0a 20 20 20 20 63 61 73 65 20 43 47 49 5f 48 45 . case CGI_HE
0c60: 41 44 45 52 3a 20 7b 0a 20 20 20 20 20 20 70 43 ADER: {. pC
0c70: 6f 6e 74 65 6e 74 20 3d 20 26 63 67 69 43 6f 6e ontent = &cgiCon
0c80: 74 65 6e 74 5b 30 5d 3b 0a 20 20 20 20 20 20 62 tent[0];. b
0c90: 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 reak;. }.
0ca0: 63 61 73 65 20 43 47 49 5f 42 4f 44 59 3a 20 7b case CGI_BODY: {
0cb0: 0a 20 20 20 20 20 20 70 43 6f 6e 74 65 6e 74 20 . pContent
0cc0: 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d = &cgiContent[1]
0cd0: 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 ;. break;.
0ce0: 20 20 20 7d 0a 20 20 20 20 64 65 66 61 75 6c 74 }. default
0cf0: 3a 20 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 61 : {. cgi_pa
0d00: 6e 69 63 28 22 62 61 64 20 64 65 73 74 69 6e 61 nic("bad destina
0d10: 74 69 6f 6e 22 29 3b 0a 20 20 20 20 7d 0a 20 20 tion");. }.
0d20: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e }.}../*.** Appen
0d30: 64 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 d reply content
0d40: 74 6f 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 to what already
0d50: 65 78 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 exists..*/.void
0d60: 63 67 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 cgi_append_conte
0d70: 6e 74 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a nt(const char *z
0d80: 44 61 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b Data, int nAmt){
0d90: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 70 . blob_append(p
0da0: 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c 20 Content, zData,
0db0: 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 nAmt);.}../*.**
0dc0: 52 65 73 65 74 20 74 68 65 20 48 54 54 50 20 72 Reset the HTTP r
0dd0: 65 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 20 eply text to be
0de0: 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 2e an empty string.
0df0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 73 .*/.void cgi_res
0e00: 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 29 et_content(void)
0e10: 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 {. blob_reset(&
0e20: 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a cgiContent[0]);.
0e30: 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67 blob_reset(&cg
0e40: 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b 0a 7d 0a iContent[1]);.}.
0e50: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 ./*.** Return a
0e60: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43 pointer to the C
0e70: 47 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a GI output blob..
0e80: 2a 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74 */.Blob *cgi_out
0e90: 70 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a put_blob(void){.
0ea0: 20 20 72 65 74 75 72 6e 20 70 43 6f 6e 74 65 6e return pConten
0eb0: 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6d 62 t;.}../*.** Comb
0ec0: 69 6e 65 20 74 68 65 20 68 65 61 64 65 72 20 61 ine the header a
0ed0: 6e 64 20 62 6f 64 79 20 6f 66 20 74 68 65 20 43 nd body of the C
0ee0: 47 49 20 69 6e 74 6f 20 61 20 73 69 6e 67 6c 65 GI into a single
0ef0: 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 74 61 74 string..*/.stat
0f00: 69 63 20 76 6f 69 64 20 63 67 69 5f 63 6f 6d 62 ic void cgi_comb
0f10: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 ine_header_and_b
0f20: 6f 64 79 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 ody(void){. int
0f30: 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f 73 69 7a size = blob_siz
0f40: 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d e(&cgiContent[1]
0f50: 29 3b 0a 20 20 69 66 28 20 73 69 7a 65 3e 30 20 );. if( size>0
0f60: 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 70 65 ){. blob_appe
0f70: 6e 64 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 nd(&cgiContent[0
0f80: 5d 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 ], blob_buffer(&
0f90: 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 2c 20 cgiContent[1]),
0fa0: 73 69 7a 65 29 3b 0a 20 20 20 20 62 6c 6f 62 5f size);. blob_
0fb0: 72 65 73 65 74 28 26 63 67 69 43 6f 6e 74 65 6e reset(&cgiConten
0fc0: 74 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a t[1]);. }.}../*
0fd0: 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 70 6f 69 .** Return a poi
0fe0: 6e 74 65 72 20 74 6f 20 74 68 65 20 48 54 54 50 nter to the HTTP
0ff0: 20 72 65 70 6c 79 20 74 65 78 74 2e 0a 2a 2f 0a reply text..*/.
1000: 63 68 61 72 20 2a 63 67 69 5f 65 78 74 72 61 63 char *cgi_extrac
1010: 74 5f 63 6f 6e 74 65 6e 74 28 69 6e 74 20 2a 70 t_content(int *p
1020: 6e 41 6d 74 29 7b 0a 20 20 63 67 69 5f 63 6f 6d nAmt){. cgi_com
1030: 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f bine_header_and_
1040: 62 6f 64 79 28 29 3b 0a 20 20 72 65 74 75 72 6e body();. return
1050: 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 blob_buffer(&cg
1060: 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 7d 0a iContent[0]);.}.
1070: 0a 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 6f 6e 61 ./*.** Additiona
1080: 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 75 73 l information us
1090: 65 64 20 74 6f 20 66 6f 72 6d 20 74 68 65 20 48 ed to form the H
10a0: 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 73 74 61 TTP reply.*/.sta
10b0: 74 69 63 20 63 68 61 72 20 2a 7a 43 6f 6e 74 65 tic char *zConte
10c0: 6e 74 54 79 70 65 20 3d 20 22 74 65 78 74 2f 68 ntType = "text/h
10d0: 74 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 43 6f 6e tml"; /* Con
10e0: 74 65 6e 74 20 74 79 70 65 20 6f 66 20 74 68 65 tent type of the
10f0: 20 72 65 70 6c 79 20 2a 2f 0a 73 74 61 74 69 63 reply */.static
1100: 20 63 68 61 72 20 2a 7a 52 65 70 6c 79 53 74 61 char *zReplySta
1110: 74 75 73 20 3d 20 22 4f 4b 22 3b 20 20 20 20 20 tus = "OK";
1120: 20 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 /* Reply
1130: 73 74 61 74 75 73 20 64 65 73 63 72 69 70 74 69 status descripti
1140: 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 on */.static int
1150: 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 iReplyStatus =
1160: 32 30 30 3b 20 20 20 20 20 20 20 20 20 20 20 20 200;
1170: 20 20 20 2f 2a 20 52 65 70 6c 79 20 73 74 61 74 /* Reply stat
1180: 75 73 20 63 6f 64 65 20 2a 2f 0a 73 74 61 74 69 us code */.stati
1190: 63 20 42 6c 6f 62 20 65 78 74 72 61 48 65 61 64 c Blob extraHead
11a0: 65 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 54 49 41 er = BLOB_INITIA
11b0: 4c 49 5a 45 52 3b 20 20 2f 2a 20 45 78 74 72 61 LIZER; /* Extra
11c0: 20 68 65 61 64 65 72 20 74 65 78 74 20 2a 2f 0a header text */.
11d0: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 ./*.** Set the r
11e0: 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 79 70 eply content typ
11f0: 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 e.*/.void cgi_se
1200: 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65 28 63 t_content_type(c
1210: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 70 65 onst char *zType
1220: 29 7b 0a 20 20 7a 43 6f 6e 74 65 6e 74 54 79 70 ){. zContentTyp
1230: 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 e = mprintf("%s"
1240: 2c 20 7a 54 79 70 65 29 3b 0a 7d 0a 0a 2f 2a 0a , zType);.}../*.
1250: 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70 6c 79 ** Set the reply
1260: 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68 65 20 content to the
1270: 73 70 65 63 69 66 69 65 64 20 42 4c 4f 42 2e 0a specified BLOB..
1280: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f */.void cgi_set_
1290: 63 6f 6e 74 65 6e 74 28 42 6c 6f 62 20 2a 70 4e content(Blob *pN
12a0: 65 77 43 6f 6e 74 65 6e 74 29 7b 0a 20 20 63 67 ewContent){. cg
12b0: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 i_reset_content(
12c0: 29 3b 0a 20 20 63 67 69 5f 64 65 73 74 69 6e 61 );. cgi_destina
12d0: 74 69 6f 6e 28 43 47 49 5f 48 45 41 44 45 52 29 tion(CGI_HEADER)
12e0: 3b 0a 20 20 63 67 69 43 6f 6e 74 65 6e 74 5b 30 ;. cgiContent[0
12f0: 5d 20 3d 20 2a 70 4e 65 77 43 6f 6e 74 65 6e 74 ] = *pNewContent
1300: 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f 28 70 4e ;. blob_zero(pN
1310: 65 77 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a 0a 2f ewContent);.}../
1320: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70 *.** Set the rep
1330: 6c 79 20 73 74 61 74 75 73 20 63 6f 64 65 0a 2a ly status code.*
1340: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 73 /.void cgi_set_s
1350: 74 61 74 75 73 28 69 6e 74 20 69 53 74 61 74 2c tatus(int iStat,
1360: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 53 74 const char *zSt
1370: 61 74 29 7b 0a 20 20 7a 52 65 70 6c 79 53 74 61 at){. zReplySta
1380: 74 75 73 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 tus = mprintf("%
1390: 73 22 2c 20 7a 53 74 61 74 29 3b 0a 20 20 69 52 s", zStat);. iR
13a0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 69 53 74 eplyStatus = iSt
13b0: 61 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 at;.}../*.** App
13c0: 65 6e 64 20 74 65 78 74 20 74 6f 20 74 68 65 20 end text to the
13d0: 68 65 61 64 65 72 20 6f 66 20 61 6e 20 48 54 54 header of an HTT
13e0: 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 6f 69 64 20 P reply.*/.void
13f0: 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 61 64 65 cgi_append_heade
1400: 72 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4c r(const char *zL
1410: 69 6e 65 29 7b 0a 20 20 62 6c 6f 62 5f 61 70 70 ine){. blob_app
1420: 65 6e 64 28 26 65 78 74 72 61 48 65 61 64 65 72 end(&extraHeader
1430: 2c 20 7a 4c 69 6e 65 2c 20 2d 31 29 3b 0a 7d 0a , zLine, -1);.}.
1440: 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 20 63 6f 6f ./*.** Set a coo
1450: 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 5a 65 72 6f 20 kie..**.** Zero
1460: 6c 69 66 65 74 69 6d 65 20 69 6d 70 6c 69 65 73 lifetime implies
1470: 20 61 20 73 65 73 73 69 6f 6e 20 63 6f 6f 6b 69 a session cooki
1480: 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 e..*/.void cgi_s
1490: 65 74 5f 63 6f 6f 6b 69 65 28 0a 20 20 63 6f 6e et_cookie(. con
14a0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 st char *zName,
14b0: 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 20 74 68 /* Name of th
14c0: 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 63 6f e cookie */. co
14d0: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 nst char *zValue
14e0: 2c 20 20 20 2f 2a 20 56 61 6c 75 65 20 6f 66 20 , /* Value of
14f0: 74 68 65 20 63 6f 6f 6b 69 65 2e 20 20 41 75 74 the cookie. Aut
1500: 6f 6d 61 74 69 63 61 6c 6c 79 20 65 73 63 61 70 omatically escap
1510: 65 64 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 ed */. const ch
1520: 61 72 20 2a 7a 50 61 74 68 2c 20 20 20 20 2f 2a ar *zPath, /*
1530: 20 50 61 74 68 20 63 6f 6f 6b 69 65 20 61 70 70 Path cookie app
1540: 6c 69 65 73 20 74 6f 2e 20 20 4e 55 4c 4c 20 6d lies to. NULL m
1550: 65 61 6e 73 20 22 2f 22 20 2a 2f 0a 20 20 69 6e eans "/" */. in
1560: 74 20 6c 69 66 65 74 69 6d 65 20 20 20 20 20 20 t lifetime
1570: 20 20 20 20 2f 2a 20 45 78 70 69 72 61 74 69 6f /* Expiratio
1580: 6e 20 6f 66 20 74 68 65 20 63 6f 6f 6b 69 65 20 n of the cookie
1590: 69 6e 20 73 65 63 6f 6e 64 73 20 66 72 6f 6d 20 in seconds from
15a0: 6e 6f 77 20 2a 2f 0a 29 7b 0a 20 20 69 66 28 20 now */.){. if(
15b0: 7a 50 61 74 68 3d 3d 30 20 29 20 7a 50 61 74 68 zPath==0 ) zPath
15c0: 20 3d 20 67 2e 7a 54 6f 70 3b 0a 20 20 69 66 28 = g.zTop;. if(
15d0: 20 6c 69 66 65 74 69 6d 65 3e 30 20 29 7b 0a 20 lifetime>0 ){.
15e0: 20 20 20 63 68 61 72 20 2a 7a 44 61 74 65 3b 0a char *zDate;.
15f0: 20 20 20 20 6c 69 66 65 74 69 6d 65 20 2b 3d 20 lifetime +=
1600: 28 69 6e 74 29 74 69 6d 65 28 30 29 3b 0a 20 20 (int)time(0);.
1610: 20 20 7a 44 61 74 65 20 3d 20 63 67 69 5f 72 66 zDate = cgi_rf
1620: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 6c c822_datestamp(l
1630: 69 66 65 74 69 6d 65 29 3b 0a 20 20 20 20 62 6c ifetime);. bl
1640: 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 78 74 72 ob_appendf(&extr
1650: 61 48 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 aHeader,.
1660: 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d "Set-Cookie: %s=
1670: 25 74 3b 20 50 61 74 68 3d 25 73 3b 20 65 78 70 %t; Path=%s; exp
1680: 69 72 65 73 3d 25 73 3b 20 56 65 72 73 69 6f 6e ires=%s; Version
1690: 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 =1\r\n",.
16a0: 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 zName, zValue,
16b0: 7a 50 61 74 68 2c 20 7a 44 61 74 65 29 3b 0a 20 zPath, zDate);.
16c0: 20 20 20 69 66 28 20 7a 44 61 74 65 5b 30 5d 20 if( zDate[0]
16d0: 29 20 66 72 65 65 28 20 7a 44 61 74 65 20 29 3b ) free( zDate );
16e0: 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 62 6c . }else{. bl
16f0: 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 78 74 72 ob_appendf(&extr
1700: 61 48 65 61 64 65 72 2c 0a 20 20 20 20 20 20 20 aHeader,.
1710: 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 25 73 3d "Set-Cookie: %s=
1720: 25 74 3b 20 50 61 74 68 3d 25 73 3b 20 56 65 72 %t; Path=%s; Ver
1730: 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20 sion=1\r\n",.
1740: 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 zName, zValu
1750: 65 2c 20 7a 50 61 74 68 29 3b 0a 20 20 7d 0a 7d e, zPath);. }.}
1760: 0a 0a 23 69 66 20 30 0a 2f 2a 0a 2a 2a 20 41 64 ..#if 0./*.** Ad
1770: 64 20 61 6e 20 45 54 61 67 20 68 65 61 64 65 72 d an ETag header
1780: 20 6c 69 6e 65 0a 2a 2f 0a 73 74 61 74 69 63 20 line.*/.static
1790: 63 68 61 72 20 2a 63 67 69 5f 61 64 64 5f 65 74 char *cgi_add_et
17a0: 61 67 28 63 68 61 72 20 2a 7a 54 78 74 2c 20 69 ag(char *zTxt, i
17b0: 6e 74 20 6e 4c 65 6e 29 7b 0a 20 20 4d 44 35 43 nt nLen){. MD5C
17c0: 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20 20 75 6e ontext ctx;. un
17d0: 73 69 67 6e 65 64 20 63 68 61 72 20 64 69 67 65 signed char dige
17e0: 73 74 5b 31 36 5d 3b 0a 20 20 69 6e 74 20 69 2c st[16];. int i,
17f0: 20 6a 3b 0a 20 20 63 68 61 72 20 7a 45 54 61 67 j;. char zETag
1800: 5b 36 34 5d 3b 0a 0a 20 20 4d 44 35 49 6e 69 74 [64];.. MD5Init
1810: 28 26 63 74 78 29 3b 0a 20 20 4d 44 35 55 70 64 (&ctx);. MD5Upd
1820: 61 74 65 28 26 63 74 78 2c 7a 54 78 74 2c 6e 4c ate(&ctx,zTxt,nL
1830: 65 6e 29 3b 0a 20 20 4d 44 35 46 69 6e 61 6c 28 en);. MD5Final(
1840: 64 69 67 65 73 74 2c 26 63 74 78 29 3b 0a 20 20 digest,&ctx);.
1850: 66 6f 72 28 6a 3d 69 3d 30 3b 20 69 3c 31 36 3b for(j=i=0; i<16;
1860: 20 69 2b 2b 2c 6a 2b 3d 32 29 7b 0a 20 20 20 20 i++,j+=2){.
1870: 62 70 72 69 6e 74 66 28 26 7a 45 54 61 67 5b 6a bprintf(&zETag[j
1880: 5d 2c 73 69 7a 65 6f 66 28 7a 45 54 61 67 29 2d ],sizeof(zETag)-
1890: 6a 2c 22 25 30 32 78 22 2c 28 69 6e 74 29 64 69 j,"%02x",(int)di
18a0: 67 65 73 74 5b 69 5d 29 3b 0a 20 20 7d 0a 20 20 gest[i]);. }.
18b0: 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 78 blob_appendf(&ex
18c0: 74 72 61 48 65 61 64 65 72 2c 20 22 45 54 61 67 traHeader, "ETag
18d0: 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 45 54 61 67 : %s\r\n", zETag
18e0: 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 74 72 64 );. return strd
18f0: 75 70 28 7a 45 54 61 67 29 3b 0a 7d 0a 0a 2f 2a up(zETag);.}../*
1900: 0a 2a 2a 20 44 6f 20 73 6f 6d 65 20 63 61 63 68 .** Do some cach
1910: 65 20 63 6f 6e 74 72 6f 6c 20 73 74 75 66 66 2e e control stuff.
1920: 20 46 69 72 73 74 2c 20 77 65 20 67 65 6e 65 72 First, we gener
1930: 61 74 65 20 61 6e 20 45 54 61 67 20 61 6e 64 20 ate an ETag and
1940: 69 6e 63 6c 75 64 65 20 69 74 20 69 6e 0a 2a 2a include it in.**
1950: 20 74 68 65 20 72 65 73 70 6f 6e 73 65 20 68 65 the response he
1960: 61 64 65 72 73 2e 20 53 65 63 6f 6e 64 2c 20 77 aders. Second, w
1970: 65 20 64 6f 20 77 68 61 74 65 76 65 72 20 69 73 e do whatever is
1980: 20 6e 65 63 65 73 73 61 72 79 20 74 6f 20 64 65 necessary to de
1990: 74 65 72 6d 69 6e 65 20 69 66 0a 2a 2a 20 74 68 termine if.** th
19a0: 65 20 72 65 71 75 65 73 74 20 77 61 73 20 61 73 e request was as
19b0: 6b 69 6e 67 20 61 62 6f 75 74 20 63 61 63 68 69 king about cachi
19c0: 6e 67 20 61 6e 64 20 77 68 65 74 68 65 72 20 77 ng and whether w
19d0: 65 20 6e 65 65 64 20 74 6f 20 73 65 6e 64 20 62 e need to send b
19e0: 61 63 6b 20 74 68 65 0a 2a 2a 20 72 65 73 70 6f ack the.** respo
19f0: 6e 73 65 20 62 6f 64 79 2e 20 49 66 20 77 65 20 nse body. If we
1a00: 73 68 6f 75 6c 64 6e 27 74 20 73 65 6e 64 20 61 shouldn't send a
1a10: 20 62 6f 64 79 2c 20 72 65 74 75 72 6e 20 6e 6f body, return no
1a20: 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a 20 43 75 n-zero..**.** Cu
1a30: 72 72 65 6e 74 6c 79 2c 20 77 65 20 6a 75 73 74 rrently, we just
1a40: 20 63 68 65 63 6b 20 74 68 65 20 45 54 61 67 20 check the ETag
1a50: 61 67 61 69 6e 73 74 20 61 6e 79 20 49 66 2d 4e against any If-N
1a60: 6f 6e 65 2d 4d 61 74 63 68 20 68 65 61 64 65 72 one-Match header
1a70: 2e 0a 2a 2a 0a 2a 2a 20 46 49 58 4d 45 3a 20 49 ..**.** FIXME: I
1a80: 6e 20 73 6f 6d 65 20 63 61 73 65 73 20 28 61 74 n some cases (at
1a90: 74 61 63 68 6d 65 6e 74 73 2c 20 66 69 6c 65 20 tachments, file
1aa0: 63 6f 6e 74 65 6e 74 73 29 20 77 65 20 63 6f 75 contents) we cou
1ab0: 6c 64 20 63 68 65 63 6b 0a 2a 2a 20 49 66 2d 4d ld check.** If-M
1ac0: 6f 64 69 66 69 65 64 2d 53 69 6e 63 65 20 68 65 odified-Since he
1ad0: 61 64 65 72 73 20 61 6e 64 20 61 6c 77 61 79 73 aders and always
1ae0: 20 69 6e 63 6c 75 64 65 20 4c 61 73 74 2d 4d 6f include Last-Mo
1af0: 64 69 66 69 65 64 20 69 6e 20 72 65 73 70 6f 6e dified in respon
1b00: 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 ses..*/.static i
1b10: 6e 74 20 63 68 65 63 6b 5f 63 61 63 68 65 5f 63 nt check_cache_c
1b20: 6f 6e 74 72 6f 6c 28 76 6f 69 64 29 7b 0a 20 20 ontrol(void){.
1b30: 2f 2a 20 46 49 58 4d 45 3a 20 74 68 65 72 65 27 /* FIXME: there'
1b40: 73 20 73 6f 6d 65 20 67 6f 74 63 68 61 73 20 77 s some gotchas w
1b50: 74 68 20 63 6f 6f 6b 69 65 73 20 61 6e 64 20 73 th cookies and s
1b60: 6f 6d 65 20 68 65 61 64 65 72 73 2e 20 2a 2f 0a ome headers. */.
1b70: 20 20 63 68 61 72 20 2a 7a 45 54 61 67 20 3d 20 char *zETag =
1b80: 63 67 69 5f 61 64 64 5f 65 74 61 67 28 62 6c 6f cgi_add_etag(blo
1b90: 62 5f 62 75 66 66 65 72 28 26 63 67 69 43 6f 6e b_buffer(&cgiCon
1ba0: 74 65 6e 74 29 2c 62 6c 6f 62 5f 73 69 7a 65 28 tent),blob_size(
1bb0: 26 63 67 69 43 6f 6e 74 65 6e 74 29 29 3b 0a 20 &cgiContent));.
1bc0: 20 63 68 61 72 20 2a 7a 4d 61 74 63 68 20 3d 20 char *zMatch =
1bd0: 50 28 22 48 54 54 50 5f 49 46 5f 4e 4f 4e 45 5f P("HTTP_IF_NONE_
1be0: 4d 41 54 43 48 22 29 3b 0a 0a 20 20 69 66 28 20 MATCH");.. if(
1bf0: 7a 45 54 61 67 21 3d 30 20 26 26 20 7a 4d 61 74 zETag!=0 && zMat
1c00: 63 68 21 3d 30 20 29 20 7b 0a 20 20 20 20 63 68 ch!=0 ) {. ch
1c10: 61 72 20 2a 7a 42 75 66 20 3d 20 73 74 72 64 75 ar *zBuf = strdu
1c20: 70 28 7a 4d 61 74 63 68 29 3b 0a 20 20 20 20 69 p(zMatch);. i
1c30: 66 28 20 7a 42 75 66 21 3d 30 20 29 7b 0a 20 20 f( zBuf!=0 ){.
1c40: 20 20 20 20 63 68 61 72 20 2a 7a 54 6f 6b 20 3d char *zTok =
1c50: 20 30 3b 0a 20 20 20 20 20 20 63 68 61 72 20 2a 0;. char *
1c60: 7a 50 6f 73 3b 0a 20 20 20 20 20 20 66 6f 72 28 zPos;. for(
1c70: 20 7a 54 6f 6b 20 3d 20 73 74 72 74 6f 6b 5f 72 zTok = strtok_r
1c80: 28 7a 42 75 66 2c 20 22 2c 5c 22 22 2c 26 7a 50 (zBuf, ",\"",&zP
1c90: 6f 73 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 os);.
1ca0: 7a 54 6f 6b 20 26 26 20 73 74 72 63 61 73 65 63 zTok && strcasec
1cb0: 6d 70 28 7a 54 6f 6b 2c 7a 45 54 61 67 29 3b 0a mp(zTok,zETag);.
1cc0: 20 20 20 20 20 20 20 20 20 20 20 7a 54 6f 6b 20 zTok
1cd0: 3d 20 20 73 74 72 74 6f 6b 5f 72 28 30 2c 20 22 = strtok_r(0, "
1ce0: 2c 5c 22 22 2c 26 7a 50 6f 73 29 29 7b 7d 0a 20 ,\"",&zPos)){}.
1cf0: 20 20 20 20 20 66 72 65 65 28 7a 42 75 66 29 3b free(zBuf);
1d00: 0a 20 20 20 20 20 20 69 66 28 7a 54 6f 6b 29 20 . if(zTok)
1d10: 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 20 7d 0a return 1;. }.
1d20: 20 20 7d 0a 20 20 0a 20 20 72 65 74 75 72 6e 20 }. . return
1d30: 30 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 0a 0;.}.#endif../*.
1d40: 2a 2a 20 44 6f 20 61 20 6e 6f 72 6d 61 6c 20 48 ** Do a normal H
1d50: 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 6f 69 TTP reply.*/.voi
1d60: 64 20 63 67 69 5f 72 65 70 6c 79 28 76 6f 69 64 d cgi_reply(void
1d70: 29 7b 0a 20 20 69 6e 74 20 74 6f 74 61 6c 5f 73 ){. int total_s
1d80: 69 7a 65 20 3d 20 30 3b 0a 20 20 69 66 28 20 69 ize = 0;. if( i
1d90: 52 65 70 6c 79 53 74 61 74 75 73 3c 3d 30 20 29 ReplyStatus<=0 )
1da0: 7b 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 74 {. iReplyStat
1db0: 75 73 20 3d 20 32 30 30 3b 0a 20 20 20 20 7a 52 us = 200;. zR
1dc0: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4f 4b eplyStatus = "OK
1dd0: 22 3b 0a 20 20 7d 0a 0a 23 69 66 20 30 0a 20 20 ";. }..#if 0.
1de0: 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 if( iReplyStatus
1df0: 3d 3d 32 30 30 20 26 26 20 63 68 65 63 6b 5f 63 ==200 && check_c
1e00: 61 63 68 65 5f 63 6f 6e 74 72 6f 6c 28 29 20 29 ache_control() )
1e10: 20 7b 0a 20 20 20 20 2f 2a 20 63 68 61 6e 67 65 {. /* change
1e20: 20 74 68 65 20 73 74 61 74 75 73 20 74 6f 20 22 the status to "
1e30: 75 6e 63 68 61 6e 67 65 64 22 20 61 6e 64 20 77 unchanged" and w
1e40: 65 20 63 61 6e 20 73 6b 69 70 20 73 65 6e 64 69 e can skip sendi
1e50: 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a 20 61 63 ng the. ** ac
1e60: 74 75 61 6c 20 72 65 73 70 6f 6e 73 65 20 62 6f tual response bo
1e70: 64 79 2e 20 4f 62 76 69 6f 75 73 6c 79 20 77 65 dy. Obviously we
1e80: 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73 20 77 68 only do this wh
1e90: 65 6e 20 77 65 20 5f 68 61 76 65 5f 20 61 0a 20 en we _have_ a.
1ea0: 20 20 20 2a 2a 20 62 6f 64 79 20 28 63 6f 64 65 ** body (code
1eb0: 20 32 30 30 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 200).. */.
1ec0: 20 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d iReplyStatus =
1ed0: 20 33 30 34 3b 0a 20 20 20 20 7a 52 65 70 6c 79 304;. zReply
1ee0: 53 74 61 74 75 73 20 3d 20 22 4e 6f 74 20 4d 6f Status = "Not Mo
1ef0: 64 69 66 69 65 64 22 3b 0a 20 20 7d 0a 23 65 6e dified";. }.#en
1f00: 64 69 66 0a 0a 20 20 69 66 28 20 67 2e 66 75 6c dif.. if( g.ful
1f10: 6c 48 74 74 70 52 65 70 6c 79 20 29 7b 0a 20 20 lHttpReply ){.
1f20: 20 20 63 68 61 72 20 2a 7a 44 61 74 65 20 3d 20 char *zDate =
1f30: 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 65 73 cgi_rfc822_dates
1f40: 74 61 6d 70 28 74 69 6d 65 28 30 29 29 3b 0a 20 tamp(time(0));.
1f50: 20 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 fprintf(g.htt
1f60: 70 4f 75 74 2c 20 22 48 54 54 50 2f 31 2e 30 20 pOut, "HTTP/1.0
1f70: 25 64 20 25 73 5c 72 5c 6e 22 2c 20 69 52 65 70 %d %s\r\n", iRep
1f80: 6c 79 53 74 61 74 75 73 2c 20 7a 52 65 70 6c 79 lyStatus, zReply
1f90: 53 74 61 74 75 73 29 3b 0a 20 20 20 20 66 70 72 Status);. fpr
1fa0: 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 intf(g.httpOut,
1fb0: 22 44 61 74 65 3a 20 25 73 5c 72 5c 6e 22 2c 20 "Date: %s\r\n",
1fc0: 7a 44 61 74 65 20 29 3b 0a 20 20 20 20 69 66 28 zDate );. if(
1fd0: 20 7a 44 61 74 65 5b 30 5d 20 29 20 66 72 65 65 zDate[0] ) free
1fe0: 28 20 7a 44 61 74 65 20 29 3b 0a 20 20 20 20 66 ( zDate );. f
1ff0: 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 printf(g.httpOut
2000: 2c 20 22 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 , "Connection: c
2010: 6c 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20 20 7d 65 lose\r\n");. }e
2020: 6c 73 65 7b 0a 20 20 20 20 66 70 72 69 6e 74 66 lse{. fprintf
2030: 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 53 74 61 (g.httpOut, "Sta
2040: 74 75 73 3a 20 25 64 20 25 73 5c 72 5c 6e 22 2c tus: %d %s\r\n",
2050: 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a iReplyStatus, z
2060: 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20 ReplyStatus);.
2070: 7d 0a 0a 20 20 69 66 28 20 62 6c 6f 62 5f 73 69 }.. if( blob_si
2080: 7a 65 28 26 65 78 74 72 61 48 65 61 64 65 72 29 ze(&extraHeader)
2090: 3e 30 20 29 7b 0a 20 20 20 20 66 70 72 69 6e 74 >0 ){. fprint
20a0: 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 25 73 f(g.httpOut, "%s
20b0: 22 2c 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 ", blob_buffer(&
20c0: 65 78 74 72 61 48 65 61 64 65 72 29 29 3b 0a 20 extraHeader));.
20d0: 20 7d 0a 0a 20 20 69 66 28 20 67 2e 69 73 43 6f }.. if( g.isCo
20e0: 6e 73 74 20 29 7b 0a 20 20 20 20 2f 2a 20 63 6f nst ){. /* co
20f0: 6e 73 74 61 6e 74 20 6d 65 61 6e 73 20 74 68 61 nstant means tha
2100: 74 20 74 68 65 20 69 6e 70 75 74 20 55 52 4c 20 t the input URL
2110: 77 69 6c 6c 20 5f 6e 65 76 65 72 5f 20 67 65 6e will _never_ gen
2120: 65 72 61 74 65 20 61 6e 79 74 68 69 6e 67 0a 20 erate anything.
2130: 20 20 20 2a 2a 20 65 6c 73 65 2e 20 49 6e 20 74 ** else. In t
2140: 68 65 20 63 61 73 65 20 6f 66 20 61 74 74 61 63 he case of attac
2150: 68 6d 65 6e 74 73 2c 20 74 68 65 20 63 6f 6e 74 hments, the cont
2160: 65 6e 74 73 20 77 6f 6e 27 74 20 63 68 61 6e 67 ents won't chang
2170: 65 20 62 65 63 61 75 73 65 0a 20 20 20 20 2a 2a e because. **
2180: 20 61 6e 20 61 74 74 65 6d 70 74 20 74 6f 20 63 an attempt to c
2190: 68 61 6e 67 65 20 74 68 65 6d 20 67 65 6e 65 72 hange them gener
21a0: 61 74 65 73 20 61 20 6e 65 77 20 61 74 74 61 63 ates a new attac
21b0: 68 6d 65 6e 74 20 6e 75 6d 62 65 72 2e 20 49 6e hment number. In
21c0: 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 61 73 65 the. ** case
21d0: 20 6f 66 20 6d 6f 73 74 20 2f 67 65 74 66 69 6c of most /getfil
21e0: 65 20 63 61 6c 6c 73 20 66 6f 72 20 73 70 65 63 e calls for spec
21f0: 69 66 69 63 20 76 65 72 73 69 6f 6e 73 2c 20 74 ific versions, t
2200: 68 65 20 6f 6e 6c 79 20 77 61 79 20 74 68 65 0a he only way the.
2210: 20 20 20 20 2a 2a 20 63 6f 6e 74 65 6e 74 20 63 ** content c
2220: 68 61 6e 67 65 73 20 69 73 20 69 66 20 73 6f 6d hanges is if som
2230: 65 6f 6e 65 20 62 72 65 61 6b 73 20 74 68 65 20 eone breaks the
2240: 53 43 4d 2e 20 41 6e 64 20 69 66 20 74 68 61 74 SCM. And if that
2250: 20 68 61 70 70 65 6e 73 2c 20 61 0a 20 20 20 20 happens, a.
2260: 2a 2a 20 73 74 61 6c 65 20 63 61 63 68 65 20 69 ** stale cache i
2270: 73 20 74 68 65 20 6c 65 61 73 74 20 6f 66 20 74 s the least of t
2280: 68 65 20 70 72 6f 62 6c 65 6d 2e 20 53 6f 20 77 he problem. So w
2290: 65 20 70 72 6f 76 69 64 65 20 61 6e 20 45 78 70 e provide an Exp
22a0: 69 72 65 73 0a 20 20 20 20 2a 2a 20 68 65 61 64 ires. ** head
22b0: 65 72 20 73 65 74 20 74 6f 20 61 20 72 65 61 73 er set to a reas
22c0: 6f 6e 61 62 6c 65 20 70 65 72 69 6f 64 20 28 64 onable period (d
22d0: 65 66 61 75 6c 74 3a 20 6f 6e 65 20 77 65 65 6b efault: one week
22e0: 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 2f 2a ).. */. /*
22f0: 74 69 6d 65 5f 74 20 65 78 70 69 72 65 73 20 3d time_t expires =
2300: 20 74 69 6d 65 28 30 29 20 2b 20 61 74 6f 69 28 time(0) + atoi(
2310: 64 62 5f 63 6f 6e 66 69 67 28 22 63 6f 6e 73 74 db_config("const
2320: 61 6e 74 5f 65 78 70 69 72 65 73 22 2c 22 36 30 ant_expires","60
2330: 34 38 30 30 22 29 29 3b 2a 2f 0a 20 20 20 20 74 4800"));*/. t
2340: 69 6d 65 5f 74 20 65 78 70 69 72 65 73 20 3d 20 ime_t expires =
2350: 74 69 6d 65 28 30 29 20 2b 20 36 30 34 38 30 30 time(0) + 604800
2360: 3b 0a 20 20 20 20 63 68 61 72 20 2a 20 7a 44 61 ;. char * zDa
2370: 74 65 20 3d 20 63 67 69 5f 72 66 63 38 32 32 5f te = cgi_rfc822_
2380: 64 61 74 65 73 74 61 6d 70 28 65 78 70 69 72 65 datestamp(expire
2390: 73 29 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 s);. fprintf(
23a0: 67 2e 68 74 74 70 4f 75 74 2c 20 22 45 78 70 69 g.httpOut, "Expi
23b0: 72 65 73 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 44 res: %s\r\n", zD
23c0: 61 74 65 20 29 3b 0a 20 20 20 20 69 66 28 20 7a ate );. if( z
23d0: 44 61 74 65 5b 30 5d 20 29 20 66 72 65 65 28 20 Date[0] ) free(
23e0: 7a 44 61 74 65 20 29 3b 0a 20 20 7d 0a 0a 20 20 zDate );. }..
23f0: 2f 2a 20 43 6f 6e 74 65 6e 74 20 69 6e 74 65 6e /* Content inten
2400: 64 65 64 20 66 6f 72 20 6c 6f 67 67 65 64 20 69 ded for logged i
2410: 6e 20 75 73 65 72 73 20 73 68 6f 75 6c 64 20 6f n users should o
2420: 6e 6c 79 20 62 65 20 63 61 63 68 65 64 20 69 6e nly be cached in
2430: 0a 20 20 2a 2a 20 74 68 65 20 62 72 6f 77 73 65 . ** the browse
2440: 72 2c 20 6e 6f 74 20 73 6f 6d 65 20 73 68 61 72 r, not some shar
2450: 65 64 20 6c 6f 63 61 74 69 6f 6e 2e 0a 20 20 2a ed location.. *
2460: 2f 0a 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 /. fprintf(g.ht
2470: 74 70 4f 75 74 2c 20 22 43 61 63 68 65 2d 63 6f tpOut, "Cache-co
2480: 6e 74 72 6f 6c 3a 20 70 72 69 76 61 74 65 5c 72 ntrol: private\r
2490: 5c 6e 22 29 3b 0a 0a 23 69 66 20 46 4f 53 53 49 \n");..#if FOSSI
24a0: 4c 5f 49 31 38 4e 0a 20 20 66 70 72 69 6e 74 66 L_I18N. fprintf
24b0: 28 67 2e 68 74 74 70 4f 75 74 2c 0a 20 20 20 20 (g.httpOut,.
24c0: 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 "Content-Type:
24d0: 25 73 3b 20 63 68 61 72 73 65 74 3d 25 73 5c 72 %s; charset=%s\r
24e0: 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79 70 \n", zContentTyp
24f0: 65 2c 20 6e 6c 5f 6c 61 6e 67 69 6e 66 6f 28 43 e, nl_langinfo(C
2500: 4f 44 45 53 45 54 29 29 3b 0a 23 65 6c 73 65 0a ODESET));.#else.
2510: 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 fprintf(g.http
2520: 4f 75 74 2c 0a 20 20 20 20 20 22 43 6f 6e 74 65 Out,. "Conte
2530: 6e 74 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 nt-Type: %s; cha
2540: 72 73 65 74 3d 49 53 4f 2d 38 38 35 39 2d 31 5c rset=ISO-8859-1\
2550: 72 5c 6e 22 2c 20 7a 43 6f 6e 74 65 6e 74 54 79 r\n", zContentTy
2560: 70 65 29 3b 0a 23 65 6e 64 69 66 0a 20 20 69 66 pe);.#endif. if
2570: 28 20 73 74 72 63 6d 70 28 7a 43 6f 6e 74 65 6e ( strcmp(zConten
2580: 74 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74 69 tType,"applicati
2590: 6f 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 on/x-fossil")==0
25a0: 20 29 7b 0a 20 20 20 20 63 67 69 5f 63 6f 6d 62 ){. cgi_comb
25b0: 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e 64 5f 62 ine_header_and_b
25c0: 6f 64 79 28 29 3b 0a 20 20 20 20 62 6c 6f 62 5f ody();. blob_
25d0: 63 6f 6d 70 72 65 73 73 28 26 63 67 69 43 6f 6e compress(&cgiCon
25e0: 74 65 6e 74 5b 30 5d 2c 20 26 63 67 69 43 6f 6e tent[0], &cgiCon
25f0: 74 65 6e 74 5b 30 5d 29 3b 0a 20 20 7d 0a 0a 20 tent[0]);. }..
2600: 20 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 if( iReplyStatu
2610: 73 20 21 3d 20 33 30 34 20 29 20 7b 0a 20 20 20 s != 304 ) {.
2620: 20 74 6f 74 61 6c 5f 73 69 7a 65 20 3d 20 62 6c total_size = bl
2630: 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 ob_size(&cgiCont
2640: 65 6e 74 5b 30 5d 29 20 2b 20 62 6c 6f 62 5f 73 ent[0]) + blob_s
2650: 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b ize(&cgiContent[
2660: 31 5d 29 3b 0a 23 69 66 64 65 66 20 5f 5f 4d 49 1]);.#ifdef __MI
2670: 4e 47 57 33 32 5f 5f 0a 20 20 20 20 2f 2a 20 49 NGW32__. /* I
2680: 6e 20 77 69 6e 64 6f 77 73 20 76 65 72 73 69 6f n windows versio
2690: 6e 73 20 6f 66 20 41 70 61 63 68 65 2c 20 65 78 ns of Apache, ex
26a0: 74 72 61 20 5c 72 20 63 68 61 72 61 63 74 65 72 tra \r character
26b0: 73 20 67 65 74 20 61 64 64 65 64 20 74 6f 20 74 s get added to t
26c0: 68 65 0a 20 20 20 20 2a 2a 20 72 65 73 70 6f 6e he. ** respon
26d0: 73 65 2c 20 77 68 69 63 68 20 6d 65 73 73 20 75 se, which mess u
26e0: 70 20 74 68 65 20 43 6f 6e 74 65 6e 74 2d 4c 65 p the Content-Le
26f0: 6e 67 74 68 2e 20 20 53 6f 20 6c 65 74 20 61 70 ngth. So let ap
2700: 61 63 68 65 20 66 69 67 75 72 65 0a 20 20 20 20 ache figure.
2710: 2a 2a 20 6f 75 74 20 74 68 65 20 63 6f 6e 74 65 ** out the conte
2720: 6e 74 20 6c 65 6e 67 74 68 20 66 6f 72 20 69 74 nt length for it
2730: 73 65 6c 66 20 69 66 20 77 65 20 61 72 65 20 75 self if we are u
2740: 73 69 6e 67 20 43 47 49 2e 20 20 49 66 20 74 68 sing CGI. If th
2750: 69 73 0a 20 20 20 20 2a 2a 20 69 73 20 61 20 63 is. ** is a c
2760: 6f 6d 70 6c 65 74 65 20 73 74 61 6e 64 2d 61 6c omplete stand-al
2770: 6f 6e 65 20 77 65 62 73 65 72 76 65 72 2c 20 6f one webserver, o
2780: 6e 20 74 68 65 20 6f 74 68 65 72 20 68 61 6e 64 n the other hand
2790: 2c 20 77 65 20 73 74 69 6c 6c 0a 20 20 20 20 2a , we still. *
27a0: 2a 20 6e 65 65 64 20 74 68 65 20 43 6f 6e 74 65 * need the Conte
27b0: 6e 74 2d 4c 65 6e 67 74 68 2e 0a 20 20 20 20 2a nt-Length.. *
27c0: 2f 0a 20 20 20 20 69 66 28 20 67 2e 66 75 6c 6c /. if( g.full
27d0: 48 74 74 70 52 65 70 6c 79 20 29 7b 0a 20 20 20 HttpReply ){.
27e0: 20 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 fprintf(g.htt
27f0: 70 4f 75 74 2c 20 22 43 6f 6e 74 65 6e 74 2d 4c pOut, "Content-L
2800: 65 6e 67 74 68 3a 20 25 64 5c 72 5c 6e 22 2c 20 ength: %d\r\n",
2810: 74 6f 74 61 6c 5f 73 69 7a 65 29 3b 0a 20 20 20 total_size);.
2820: 20 7d 0a 23 65 6c 73 65 0a 20 20 20 20 2f 2a 20 }.#else. /*
2830: 4f 6e 20 75 6e 69 78 2c 20 5c 6e 20 74 6f 20 5c On unix, \n to \
2840: 72 5c 6e 20 74 72 61 6e 73 6c 61 74 69 6f 6e 20 r\n translation
2850: 69 73 20 6e 65 76 65 72 20 61 20 70 72 6f 62 6c is never a probl
2860: 65 6d 2e 20 20 57 65 20 6b 6e 6f 77 20 74 68 65 em. We know the
2870: 0a 20 20 20 20 2a 2a 20 63 6f 6e 74 65 6e 74 20 . ** content
2880: 6c 65 6e 67 74 68 2c 20 73 6f 20 77 65 20 6d 69 length, so we mi
2890: 67 68 74 20 61 73 20 77 65 6c 6c 20 67 6f 20 61 ght as well go a
28a0: 68 65 61 64 20 61 6e 64 20 74 65 6c 6c 20 74 68 head and tell th
28b0: 65 20 77 65 62 73 65 72 76 65 72 0a 20 20 20 20 e webserver.
28c0: 2a 2a 20 77 68 61 74 20 69 74 20 69 73 20 69 6e ** what it is in
28d0: 20 61 6c 6c 20 63 61 73 65 73 2e 0a 20 20 20 20 all cases..
28e0: 2a 2f 0a 20 20 20 20 66 70 72 69 6e 74 66 28 67 */. fprintf(g
28f0: 2e 68 74 74 70 4f 75 74 2c 20 22 43 6f 6e 74 65 .httpOut, "Conte
2900: 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 64 5c 72 5c nt-Length: %d\r\
2910: 6e 22 2c 20 74 6f 74 61 6c 5f 73 69 7a 65 29 3b n", total_size);
2920: 0a 23 65 6e 64 69 66 0a 20 20 7d 0a 20 20 66 70 .#endif. }. fp
2930: 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c rintf(g.httpOut,
2940: 20 22 5c 72 5c 6e 22 29 3b 0a 20 20 69 66 28 20 "\r\n");. if(
2950: 74 6f 74 61 6c 5f 73 69 7a 65 3e 30 20 26 26 20 total_size>0 &&
2960: 69 52 65 70 6c 79 53 74 61 74 75 73 20 21 3d 20 iReplyStatus !=
2970: 33 30 34 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 304 ){. int i
2980: 2c 20 73 69 7a 65 3b 0a 20 20 20 20 66 6f 72 28 , size;. for(
2990: 69 3d 30 3b 20 69 3c 32 3b 20 69 2b 2b 29 7b 0a i=0; i<2; i++){.
29a0: 20 20 20 20 20 20 73 69 7a 65 20 3d 20 62 6c 6f size = blo
29b0: 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 b_size(&cgiConte
29c0: 6e 74 5b 69 5d 29 3b 0a 20 20 20 20 20 20 69 66 nt[i]);. if
29d0: 28 20 73 69 7a 65 3e 30 20 29 7b 0a 20 20 20 20 ( size>0 ){.
29e0: 20 20 20 20 66 77 72 69 74 65 28 62 6c 6f 62 5f fwrite(blob_
29f0: 62 75 66 66 65 72 28 26 63 67 69 43 6f 6e 74 65 buffer(&cgiConte
2a00: 6e 74 5b 69 5d 29 2c 20 31 2c 20 73 69 7a 65 2c nt[i]), 1, size,
2a10: 20 67 2e 68 74 74 70 4f 75 74 29 3b 0a 20 20 20 g.httpOut);.
2a20: 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 }. }. }.
2a30: 20 43 47 49 44 45 42 55 47 28 28 22 44 4f 4e 45 CGIDEBUG(("DONE
2a40: 5c 6e 22 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 \n"));.}../*.**
2a50: 44 6f 20 61 20 72 65 64 69 72 65 63 74 20 72 65 Do a redirect re
2a60: 71 75 65 73 74 20 74 6f 20 74 68 65 20 55 52 4c quest to the URL
2a70: 20 67 69 76 65 6e 20 69 6e 20 74 68 65 20 61 72 given in the ar
2a80: 67 75 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 gument..**.** Th
2a90: 65 20 55 52 4c 20 6d 75 73 74 20 62 65 20 72 65 e URL must be re
2aa0: 6c 61 74 69 76 65 20 74 6f 20 74 68 65 20 62 61 lative to the ba
2ab0: 73 65 20 6f 66 20 74 68 65 20 66 6f 73 73 69 6c se of the fossil
2ac0: 20 73 65 72 76 65 72 2e 0a 2a 2f 0a 76 6f 69 64 server..*/.void
2ad0: 20 63 67 69 5f 72 65 64 69 72 65 63 74 28 63 6f cgi_redirect(co
2ae0: 6e 73 74 20 63 68 61 72 20 2a 7a 55 52 4c 29 7b nst char *zURL){
2af0: 0a 20 20 63 68 61 72 20 2a 7a 4c 6f 63 61 74 69 . char *zLocati
2b00: 6f 6e 3b 0a 20 20 43 47 49 44 45 42 55 47 28 28 on;. CGIDEBUG((
2b10: 22 72 65 64 69 72 65 63 74 20 74 6f 20 25 73 5c "redirect to %s\
2b20: 6e 22 2c 20 7a 55 52 4c 29 29 3b 0a 20 20 69 66 n", zURL));. if
2b30: 28 20 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22 ( strncmp(zURL,"
2b40: 68 74 74 70 3a 22 2c 35 29 3d 3d 30 20 7c 7c 20 http:",5)==0 ||
2b50: 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22 68 74 strncmp(zURL,"ht
2b60: 74 70 73 3a 22 2c 36 29 3d 3d 30 20 7c 7c 20 2a tps:",6)==0 || *
2b70: 7a 55 52 4c 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 zURL=='/' ){.
2b80: 20 7a 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 72 zLocation = mpr
2b90: 69 6e 74 66 28 22 4c 6f 63 61 74 69 6f 6e 3a 20 intf("Location:
2ba0: 25 73 5c 72 5c 6e 22 2c 20 7a 55 52 4c 29 3b 0a %s\r\n", zURL);.
2bb0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 4c 6f }else{. zLo
2bc0: 63 61 74 69 6f 6e 20 3d 20 6d 70 72 69 6e 74 66 cation = mprintf
2bd0: 28 22 4c 6f 63 61 74 69 6f 6e 3a 20 25 73 2f 25 ("Location: %s/%
2be0: 73 5c 72 5c 6e 22 2c 20 67 2e 7a 42 61 73 65 55 s\r\n", g.zBaseU
2bf0: 52 4c 2c 20 7a 55 52 4c 29 3b 0a 20 20 7d 0a 20 RL, zURL);. }.
2c00: 20 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 61 64 cgi_append_head
2c10: 65 72 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a 20 er(zLocation);.
2c20: 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 cgi_reset_conte
2c30: 6e 74 28 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e nt();. cgi_prin
2c40: 74 66 28 22 3c 68 74 6d 6c 3e 5c 6e 3c 70 3e 52 tf("<html>\n<p>R
2c50: 65 64 69 72 65 63 74 20 74 6f 20 25 68 3c 2f 70 edirect to %h</p
2c60: 3e 5c 6e 3c 2f 68 74 6d 6c 3e 5c 6e 22 2c 20 7a >\n</html>\n", z
2c70: 55 52 4c 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f URL);. cgi_set_
2c80: 73 74 61 74 75 73 28 33 30 32 2c 20 22 4d 6f 76 status(302, "Mov
2c90: 65 64 20 54 65 6d 70 6f 72 61 72 69 6c 79 22 29 ed Temporarily")
2ca0: 3b 0a 20 20 66 72 65 65 28 7a 4c 6f 63 61 74 69 ;. free(zLocati
2cb0: 6f 6e 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 on);. cgi_reply
2cc0: 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d ();. exit(0);.}
2cd0: 0a 76 6f 69 64 20 63 67 69 5f 72 65 64 69 72 65 .void cgi_redire
2ce0: 63 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20 2a ctf(const char *
2cf0: 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 zFormat, ...){.
2d00: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 va_list ap;. v
2d10: 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 a_start(ap, zFor
2d20: 6d 61 74 29 3b 0a 20 20 63 67 69 5f 72 65 64 69 mat);. cgi_redi
2d30: 72 65 63 74 28 76 6d 70 72 69 6e 74 66 28 7a 46 rect(vmprintf(zF
2d40: 6f 72 6d 61 74 2c 20 61 70 29 29 3b 0a 20 20 76 ormat, ap));. v
2d50: 61 5f 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 2f 2a a_end(ap);.}../*
2d60: 0a 2a 2a 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 .** Information
2d70: 61 62 6f 75 74 20 61 6c 6c 20 71 75 65 72 79 20 about all query
2d80: 70 61 72 61 6d 65 74 65 72 73 20 61 6e 64 20 63 parameters and c
2d90: 6f 6f 6b 69 65 73 20 61 72 65 20 73 74 6f 72 65 ookies are store
2da0: 64 0a 2a 2a 20 69 6e 20 74 68 65 73 65 20 76 61 d.** in these va
2db0: 72 69 61 62 6c 65 73 2e 0a 2a 2f 0a 73 74 61 74 riables..*/.stat
2dc0: 69 63 20 69 6e 74 20 6e 41 6c 6c 6f 63 51 50 20 ic int nAllocQP
2dd0: 3d 20 30 3b 20 2f 2a 20 53 70 61 63 65 20 61 6c = 0; /* Space al
2de0: 6c 6f 63 61 74 65 64 20 66 6f 72 20 61 50 61 72 located for aPar
2df0: 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 69 63 amQP[] */.static
2e00: 20 69 6e 74 20 6e 55 73 65 64 51 50 20 3d 20 30 int nUsedQP = 0
2e10: 3b 20 20 2f 2a 20 53 70 61 63 65 20 61 63 74 75 ; /* Space actu
2e20: 61 6c 6c 79 20 75 73 65 64 20 69 6e 20 61 50 61 ally used in aPa
2e30: 72 61 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 69 ramQP[] */.stati
2e40: 63 20 69 6e 74 20 73 6f 72 74 51 50 20 3d 20 30 c int sortQP = 0
2e50: 3b 20 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 ; /* True if a
2e60: 50 61 72 61 6d 51 50 5b 5d 20 6e 65 65 64 73 20 ParamQP[] needs
2e70: 73 6f 72 74 69 6e 67 20 2a 2f 0a 73 74 61 74 69 sorting */.stati
2e80: 63 20 69 6e 74 20 73 65 71 51 50 20 3d 20 30 3b c int seqQP = 0;
2e90: 20 20 20 20 2f 2a 20 53 65 71 75 65 6e 63 65 20 /* Sequence
2ea0: 6e 75 6d 62 65 72 73 20 2a 2f 0a 73 74 61 74 69 numbers */.stati
2eb0: 63 20 73 74 72 75 63 74 20 51 50 61 72 61 6d 20 c struct QParam
2ec0: 7b 20 20 20 2f 2a 20 4f 6e 65 20 65 6e 74 72 79 { /* One entry
2ed0: 20 66 6f 72 20 65 61 63 68 20 71 75 65 72 79 20 for each query
2ee0: 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f parameter or coo
2ef0: 6b 69 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 kie */. const c
2f00: 68 61 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 har *zName;
2f10: 20 20 20 2f 2a 20 50 61 72 61 6d 65 74 65 72 20 /* Parameter
2f20: 6f 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 20 2a or cookie name *
2f30: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a /. const char *
2f40: 7a 56 61 6c 75 65 3b 20 20 20 20 20 20 20 2f 2a zValue; /*
2f50: 20 56 61 6c 75 65 20 6f 66 20 74 68 65 20 71 75 Value of the qu
2f60: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 ery parameter or
2f70: 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 20 69 6e 74 cookie */. int
2f80: 20 73 65 71 3b 20 20 20 20 20 20 20 20 20 20 20 seq;
2f90: 20 20 20 20 20 20 20 2f 2a 20 4f 72 64 65 72 20 /* Order
2fa0: 6f 66 20 69 6e 73 65 72 74 69 6f 6e 20 2a 2f 0a of insertion */.
2fb0: 7d 20 2a 61 50 61 72 61 6d 51 50 3b 20 20 20 20 } *aParamQP;
2fc0: 20 20 20 20 20 20 20 20 20 2f 2a 20 41 6e 20 61 /* An a
2fd0: 72 72 61 79 20 6f 66 20 61 6c 6c 20 70 61 72 61 rray of all para
2fe0: 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 meters and cooki
2ff0: 65 73 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 es */../*.** Add
3000: 20 61 6e 6f 74 68 65 72 20 71 75 65 72 79 20 70 another query p
3010: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b arameter or cook
3020: 69 65 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65 ie to the parame
3030: 74 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d ter set..** zNam
3040: 65 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 e is the name of
3050: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d the query param
3060: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61 eter or cookie a
3070: 6e 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20 nd zValue.** is
3080: 69 74 73 20 66 75 6c 6c 79 20 64 65 63 6f 64 65 its fully decode
3090: 64 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 7a d value..**.** z
30a0: 4e 61 6d 65 20 61 6e 64 20 7a 56 61 6c 75 65 20 Name and zValue
30b0: 61 72 65 20 6e 6f 74 20 63 6f 70 69 65 64 20 61 are not copied a
30c0: 6e 64 20 6d 75 73 74 20 6e 6f 74 20 63 68 61 6e nd must not chan
30d0: 67 65 20 6f 72 20 62 65 0a 2a 2a 20 64 65 61 6c ge or be.** deal
30e0: 6c 6f 63 61 74 65 64 20 61 66 74 65 72 20 74 68 located after th
30f0: 69 73 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72 is routine retur
3100: 6e 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f ns..*/.void cgi_
3110: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f set_parameter_no
3120: 63 6f 70 79 28 63 6f 6e 73 74 20 63 68 61 72 20 copy(const char
3130: 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 *zName, const ch
3140: 61 72 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 69 ar *zValue){. i
3150: 66 28 20 6e 41 6c 6c 6f 63 51 50 3c 3d 6e 55 73 f( nAllocQP<=nUs
3160: 65 64 51 50 20 29 7b 0a 20 20 20 20 6e 41 6c 6c edQP ){. nAll
3170: 6f 63 51 50 20 3d 20 6e 41 6c 6c 6f 63 51 50 2a ocQP = nAllocQP*
3180: 32 20 2b 20 31 30 3b 0a 20 20 20 20 61 50 61 72 2 + 10;. aPar
3190: 61 6d 51 50 20 3d 20 72 65 61 6c 6c 6f 63 28 20 amQP = realloc(
31a0: 61 50 61 72 61 6d 51 50 2c 20 6e 41 6c 6c 6f 63 aParamQP, nAlloc
31b0: 51 50 2a 73 69 7a 65 6f 66 28 61 50 61 72 61 6d QP*sizeof(aParam
31c0: 51 50 5b 30 5d 29 20 29 3b 0a 20 20 20 20 69 66 QP[0]) );. if
31d0: 28 20 61 50 61 72 61 6d 51 50 3d 3d 30 20 29 20 ( aParamQP==0 )
31e0: 65 78 69 74 28 31 29 3b 0a 20 20 7d 0a 20 20 61 exit(1);. }. a
31f0: 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d ParamQP[nUsedQP]
3200: 2e 7a 4e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a .zName = zName;.
3210: 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 aParamQP[nUsed
3220: 51 50 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56 61 QP].zValue = zVa
3230: 6c 75 65 3b 0a 20 20 61 50 61 72 61 6d 51 50 5b lue;. aParamQP[
3240: 6e 55 73 65 64 51 50 5d 2e 73 65 71 20 3d 20 73 nUsedQP].seq = s
3250: 65 71 51 50 2b 2b 3b 0a 20 20 6e 55 73 65 64 51 eqQP++;. nUsedQ
3260: 50 2b 2b 3b 0a 20 20 73 6f 72 74 51 50 20 3d 20 P++;. sortQP =
3270: 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 1;.}../*.** Add
3280: 61 6e 6f 74 68 65 72 20 71 75 65 72 79 20 70 61 another query pa
3290: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 rameter or cooki
32a0: 65 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 e to the paramet
32b0: 65 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 er set..** zName
32c0: 20 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 is the name of
32d0: 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 the query parame
32e0: 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61 6e ter or cookie an
32f0: 64 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20 69 d zValue.** is i
3300: 74 73 20 66 75 6c 6c 79 20 64 65 63 6f 64 65 64 ts fully decoded
3310: 20 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 43 6f value..**.** Co
3320: 70 69 65 73 20 61 72 65 20 6d 61 64 65 20 6f 66 pies are made of
3330: 20 62 6f 74 68 20 74 68 65 20 7a 4e 61 6d 65 20 both the zName
3340: 61 6e 64 20 7a 56 61 6c 75 65 20 70 61 72 61 6d and zValue param
3350: 65 74 65 72 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 eters..*/.void c
3360: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 gi_set_parameter
3370: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 (const char *zNa
3380: 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a me, const char *
3390: 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f 73 zValue){. cgi_s
33a0: 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 et_parameter_noc
33b0: 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 22 opy(mprintf("%s"
33c0: 2c 7a 4e 61 6d 65 29 2c 20 6d 70 72 69 6e 74 66 ,zName), mprintf
33d0: 28 22 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b 0a ("%s",zValue));.
33e0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 70 6c 61 63 65 }../*.** Replace
33f0: 20 61 20 70 61 72 61 6d 65 74 65 72 20 77 69 74 a parameter wit
3400: 68 20 61 20 6e 65 77 20 76 61 6c 75 65 2e 0a 2a h a new value..*
3410: 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 61 /.void cgi_repla
3420: 63 65 5f 70 61 72 61 6d 65 74 65 72 28 63 6f 6e ce_parameter(con
3430: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 st char *zName,
3440: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c const char *zVal
3450: 75 65 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 ue){. int i;.
3460: 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 55 73 65 64 for(i=0; i<nUsed
3470: 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 QP; i++){. if
3480: 28 20 73 74 72 63 6d 70 28 61 50 61 72 61 6d 51 ( strcmp(aParamQ
3490: 50 5b 69 5d 2e 7a 4e 61 6d 65 2c 7a 4e 61 6d 65 P[i].zName,zName
34a0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 50 )==0 ){. aP
34b0: 61 72 61 6d 51 50 5b 69 5d 2e 7a 56 61 6c 75 65 aramQP[i].zValue
34c0: 20 3d 20 7a 56 61 6c 75 65 3b 0a 20 20 20 20 20 = zValue;.
34d0: 20 72 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 return;. }.
34e0: 20 7d 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 72 }. cgi_set_par
34f0: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e ameter_nocopy(zN
3500: 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 7d 0a ame, zValue);.}.
3510: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 20 71 75 65 ./*.** Add a que
3520: 72 79 20 70 61 72 61 6d 65 74 65 72 2e 20 20 54 ry parameter. T
3530: 68 65 20 7a 4e 61 6d 65 20 70 6f 72 74 69 6f 6e he zName portion
3540: 20 69 73 20 66 69 78 65 64 20 62 75 74 20 61 20 is fixed but a
3550: 63 6f 70 79 0a 2a 2a 20 6d 75 73 74 20 62 65 20 copy.** must be
3560: 6d 61 64 65 20 6f 66 20 7a 56 61 6c 75 65 2e 0a made of zValue..
3570: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 65 */.void cgi_sete
3580: 6e 76 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a nv(const char *z
3590: 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 Name, const char
35a0: 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 *zValue){. cgi
35b0: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e _set_parameter_n
35c0: 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 6d 70 72 ocopy(zName, mpr
35d0: 69 6e 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 intf("%s",zValue
35e0: 29 29 3b 0a 7d 0a 20 0a 0a 2f 2a 0a 2a 2a 20 41 ));.}. ../*.** A
35f0: 64 64 20 61 20 6c 69 73 74 20 6f 66 20 71 75 65 dd a list of que
3600: 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 6f 72 ry parameters or
3610: 20 63 6f 6f 6b 69 65 73 20 74 6f 20 74 68 65 20 cookies to the
3620: 70 61 72 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a parameter set..*
3630: 2a 0a 2a 2a 20 45 61 63 68 20 70 61 72 61 6d 65 *.** Each parame
3640: 74 65 72 20 69 73 20 6f 66 20 74 68 65 20 66 6f ter is of the fo
3650: 72 6d 20 4e 41 4d 45 3d 56 41 4c 55 45 2e 20 20 rm NAME=VALUE.
3660: 42 6f 74 68 20 74 68 65 20 4e 41 4d 45 20 61 6e Both the NAME an
3670: 64 20 74 68 65 0a 2a 2a 20 56 41 4c 55 45 20 6d d the.** VALUE m
3680: 61 79 20 62 65 20 75 72 6c 2d 65 6e 63 6f 64 65 ay be url-encode
3690: 64 20 28 22 2b 22 20 66 6f 72 20 73 70 61 63 65 d ("+" for space
36a0: 2c 20 22 25 48 48 22 20 66 6f 72 20 6f 74 68 65 , "%HH" for othe
36b0: 72 20 73 70 65 63 69 61 6c 0a 2a 2a 20 63 68 61 r special.** cha
36c0: 72 61 63 74 65 72 73 29 2e 20 20 42 75 74 20 74 racters). But t
36d0: 68 69 73 20 72 6f 75 74 69 6e 65 20 61 73 73 75 his routine assu
36e0: 6d 65 73 20 74 68 61 74 20 4e 41 4d 45 20 63 6f mes that NAME co
36f0: 6e 74 61 69 6e 73 20 6e 6f 0a 2a 2a 20 73 70 65 ntains no.** spe
3700: 63 69 61 6c 20 63 68 61 72 61 63 74 65 72 20 61 cial character a
3710: 6e 64 20 74 68 65 72 65 66 6f 72 65 20 64 6f 65 nd therefore doe
3720: 73 20 6e 6f 74 20 64 65 63 6f 64 65 20 69 74 2e s not decode it.
3730: 0a 2a 2a 0a 2a 2a 20 49 66 20 4e 41 4d 45 20 62 .**.** If NAME b
3740: 65 67 69 6e 73 20 77 69 74 68 20 61 6e 6f 74 68 egins with anoth
3750: 65 72 20 6f 74 68 65 72 20 74 68 61 6e 20 61 20 er other than a
3760: 6c 6f 77 65 72 2d 63 61 73 65 20 6c 65 74 74 65 lower-case lette
3770: 72 20 74 68 65 6e 0a 2a 2a 20 74 68 65 20 65 6e r then.** the en
3780: 74 69 72 65 20 4e 41 4d 45 3d 56 41 4c 55 45 20 tire NAME=VALUE
3790: 74 65 72 6d 20 69 73 20 69 67 6e 6f 72 65 64 2e term is ignored.
37a0: 20 20 48 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a 20 20 Hence:.**.**
37b0: 20 20 20 20 2a 20 20 63 6f 6f 6b 69 65 73 20 61 * cookies a
37c0: 6e 64 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 nd query paramet
37d0: 65 72 73 20 74 68 61 74 20 68 61 76 65 20 75 70 ers that have up
37e0: 70 65 72 63 61 73 65 20 6e 61 6d 65 73 0a 2a 2a percase names.**
37f0: 20 20 20 20 20 20 20 20 20 61 72 65 20 69 67 6e are ign
3800: 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 ored..**.**
3810: 20 2a 20 20 69 74 20 69 73 20 69 6d 70 6f 73 73 * it is imposs
3820: 69 62 6c 65 20 66 6f 72 20 61 20 63 6f 6f 6b 69 ible for a cooki
3830: 65 20 6f 72 20 71 75 65 72 79 20 70 61 72 61 6d e or query param
3840: 65 74 65 72 20 74 6f 0a 2a 2a 20 20 20 20 20 20 eter to.**
3850: 20 20 20 6f 76 65 72 72 69 64 65 20 74 68 65 20 override the
3860: 76 61 6c 75 65 20 6f 66 20 61 6e 20 65 6e 76 69 value of an envi
3870: 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 ronment variable
3880: 20 73 69 6e 63 65 0a 2a 2a 20 20 20 20 20 20 20 since.**
3890: 20 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 environment va
38a0: 72 69 61 62 6c 65 73 20 61 6c 77 61 79 73 20 68 riables always h
38b0: 61 76 65 20 75 70 70 65 72 63 61 73 65 20 6e 61 ave uppercase na
38c0: 6d 65 73 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d mes..**.** Param
38d0: 65 74 65 72 73 20 61 72 65 20 73 65 70 61 72 61 eters are separa
38e0: 74 65 64 20 62 79 20 74 68 65 20 22 74 65 72 6d ted by the "term
38f0: 69 6e 61 74 6f 72 22 20 63 68 61 72 61 63 74 65 inator" characte
3900: 72 2e 20 20 57 68 69 74 65 73 70 61 63 65 0a 2a r. Whitespace.*
3910: 2a 20 62 65 66 6f 72 65 20 74 68 65 20 4e 41 4d * before the NAM
3920: 45 20 69 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a E is ignored..**
3930: 0a 2a 2a 20 54 68 65 20 69 6e 70 75 74 20 73 74 .** The input st
3940: 72 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 ring "z" is modi
3950: 66 69 65 64 20 62 75 74 20 6e 6f 20 63 6f 70 69 fied but no copi
3960: 65 73 20 69 73 20 6d 61 64 65 2e 20 20 22 7a 22 es is made. "z"
3970: 0a 2a 2a 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62 .** should not b
3980: 65 20 64 65 61 6c 6c 6f 63 61 74 65 64 20 6f 72 e deallocated or
3990: 20 63 68 61 6e 67 65 64 20 61 67 61 69 6e 20 61 changed again a
39a0: 66 74 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e fter this routin
39b0: 65 0a 2a 2a 20 72 65 74 75 72 6e 73 20 6f 72 20 e.** returns or
39c0: 69 74 20 77 69 6c 6c 20 63 6f 72 72 75 70 74 20 it will corrupt
39d0: 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 74 61 the parameter ta
39e0: 62 6c 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 ble..*/.static v
39f0: 6f 69 64 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 oid add_param_li
3a00: 73 74 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 st(char *z, int
3a10: 74 65 72 6d 69 6e 61 74 6f 72 29 7b 0a 20 20 77 terminator){. w
3a20: 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 hile( *z ){.
3a30: 63 68 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 char *zName;.
3a40: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 char *zValue;.
3a50: 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 while( isspac
3a60: 65 28 2a 7a 29 20 29 7b 20 7a 2b 2b 3b 20 7d 0a e(*z) ){ z++; }.
3a70: 20 20 20 20 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 zName = z;.
3a80: 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 while( *z &&
3a90: 2a 7a 21 3d 27 3d 27 20 26 26 20 2a 7a 21 3d 74 *z!='=' && *z!=t
3aa0: 65 72 6d 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b erminator ){ z++
3ab0: 3b 20 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d ; }. if( *z==
3ac0: 27 3d 27 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 '=' ){. *z
3ad0: 3d 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a = 0;. z++;.
3ae0: 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 7a zValue = z
3af0: 3b 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a ;. while( *
3b00: 7a 20 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 z && *z!=termina
3b10: 74 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 tor ){ z++; }.
3b20: 20 20 20 20 69 66 28 20 2a 7a 20 29 7b 0a 20 20 if( *z ){.
3b30: 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 *z = 0;.
3b40: 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 z++;.
3b50: 20 7d 0a 20 20 20 20 20 20 64 65 68 74 74 70 69 }. dehttpi
3b60: 7a 65 28 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 ze(zValue);.
3b70: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 }else{. if(
3b80: 20 2a 7a 20 29 7b 20 2a 7a 2b 2b 20 3d 20 30 3b *z ){ *z++ = 0;
3b90: 20 7d 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20 }. zValue
3ba0: 3d 20 22 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 = "";. }.
3bb0: 69 66 28 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d if( islower(zNam
3bc0: 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 63 e[0]) ){. c
3bd0: 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 gi_set_parameter
3be0: 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a _nocopy(zName, z
3bf0: 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d 0a 20 20 Value);. }.
3c00: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 2a 70 7a 20 69 }.}../*.** *pz i
3c10: 73 20 61 20 73 74 72 69 6e 67 20 74 68 61 74 20 s a string that
3c20: 63 6f 6e 73 69 73 74 73 20 6f 66 20 6d 75 6c 74 consists of mult
3c30: 69 70 6c 65 20 6c 69 6e 65 73 20 6f 66 20 74 65 iple lines of te
3c40: 78 74 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 xt. This.** rou
3c50: 74 69 6e 65 20 66 69 6e 64 73 20 74 68 65 20 65 tine finds the e
3c60: 6e 64 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e nd of the curren
3c70: 74 20 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 61 t line of text a
3c80: 6e 64 20 63 6f 6e 76 65 72 74 73 0a 2a 2a 20 74 nd converts.** t
3c90: 68 65 20 22 5c 6e 22 20 6f 72 20 22 5c 72 5c 6e he "\n" or "\r\n
3ca0: 22 20 74 68 61 74 20 65 6e 64 73 20 74 68 61 74 " that ends that
3cb0: 20 6c 69 6e 65 20 69 6e 74 6f 20 61 20 22 5c 30 line into a "\0
3cc0: 30 30 22 2e 20 20 49 74 20 74 68 65 6e 0a 2a 2a 00". It then.**
3cd0: 20 61 64 76 61 6e 63 65 73 20 2a 70 7a 20 74 6f advances *pz to
3ce0: 20 74 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f the beginning o
3cf0: 66 20 74 68 65 20 6e 65 78 74 20 6c 69 6e 65 20 f the next line
3d00: 61 6e 64 20 72 65 74 75 72 6e 73 20 74 68 65 0a and returns the.
3d10: 2a 2a 20 70 72 65 76 69 6f 75 73 20 76 61 6c 75 ** previous valu
3d20: 65 20 6f 66 20 2a 70 7a 20 28 77 68 69 63 68 20 e of *pz (which
3d30: 69 73 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 is the start of
3d40: 74 68 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65 the current line
3d50: 2e 29 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 .).*/.static cha
3d60: 72 20 2a 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d r *get_line_from
3d70: 5f 73 74 72 69 6e 67 28 63 68 61 72 20 2a 2a 70 _string(char **p
3d80: 7a 2c 20 69 6e 74 20 2a 70 4c 65 6e 29 7b 0a 20 z, int *pLen){.
3d90: 20 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a char *z = *pz;.
3da0: 20 20 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a int i;. if( z
3db0: 5b 30 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 [0]==0 ) return
3dc0: 30 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 5b 0;. for(i=0; z[
3dd0: 69 5d 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 i]; i++){. if
3de0: 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29 7b 0a ( z[i]=='\n' ){.
3df0: 20 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 if( i>0 &&
3e00: 20 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 7b z[i-1]=='\r' ){
3e10: 0a 20 20 20 20 20 20 20 20 7a 5b 69 2d 31 5d 20 . z[i-1]
3e20: 3d 20 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 = 0;. }else
3e30: 7b 0a 20 20 20 20 20 20 20 20 7a 5b 69 5d 20 3d {. z[i] =
3e40: 20 30 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 0;. }.
3e50: 20 20 69 2b 2b 3b 0a 20 20 20 20 20 20 62 72 65 i++;. bre
3e60: 61 6b 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 ak;. }. }.
3e70: 2a 70 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 2a *pz = &z[i];. *
3e80: 70 4c 65 6e 20 2d 3d 20 69 3b 0a 20 20 72 65 74 pLen -= i;. ret
3e90: 75 72 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 urn z;.}../*.**
3ea0: 54 68 65 20 69 6e 70 75 74 20 2a 70 7a 20 70 6f The input *pz po
3eb0: 69 6e 74 73 20 74 6f 20 63 6f 6e 74 65 6e 74 20 ints to content
3ec0: 74 68 61 74 20 69 73 20 74 65 72 6d 69 6e 61 74 that is terminat
3ed0: 65 64 20 62 79 20 61 20 22 5c 72 5c 6e 22 0a 2a ed by a "\r\n".*
3ee0: 2a 20 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74 68 * followed by th
3ef0: 65 20 62 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 e boundry marker
3f00: 20 7a 42 6f 75 6e 64 72 79 2e 20 20 41 6e 20 65 zBoundry. An e
3f10: 78 74 72 61 20 22 2d 2d 22 20 6d 61 79 20 6f 72 xtra "--" may or
3f20: 0a 2a 2a 20 6d 61 79 20 6e 6f 74 20 62 65 20 61 .** may not be a
3f30: 70 70 65 6e 64 65 64 20 74 6f 20 74 68 65 20 62 ppended to the b
3f40: 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 2e 20 20 oundry marker.
3f50: 54 68 65 72 65 20 61 72 65 20 2a 70 4c 65 6e 20 There are *pLen
3f60: 63 68 61 72 61 63 74 65 72 73 0a 2a 2a 20 69 6e characters.** in
3f70: 20 2a 70 7a 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 *pz..**.** This
3f80: 20 72 6f 75 74 69 6e 65 20 61 64 64 73 20 61 20 routine adds a
3f90: 22 5c 30 30 30 22 20 74 6f 20 74 68 65 20 65 6e "\000" to the en
3fa0: 64 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 d of the content
3fb0: 20 28 6f 76 65 72 77 72 69 74 69 6e 67 0a 2a 2a (overwriting.**
3fc0: 20 74 68 65 20 22 5c 72 5c 6e 22 29 20 61 6e 64 the "\r\n") and
3fd0: 20 72 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 returns a point
3fe0: 65 72 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e er to the conten
3ff0: 74 2e 20 20 54 68 65 20 2a 70 7a 20 69 6e 70 75 t. The *pz inpu
4000: 74 0a 2a 2a 20 69 73 20 61 64 6a 75 73 74 65 64 t.** is adjusted
4010: 20 74 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 to point to the
4020: 20 66 69 72 73 74 20 6c 69 6e 65 20 66 6f 6c 6c first line foll
4030: 6f 77 69 6e 67 20 74 68 65 20 62 6f 75 6e 64 72 owing the boundr
4040: 79 2e 0a 2a 2a 20 54 68 65 20 6c 65 6e 67 74 68 y..** The length
4050: 20 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 of the content
4060: 69 73 20 73 74 6f 72 65 64 20 69 6e 20 2a 70 6e is stored in *pn
4070: 43 6f 6e 74 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 Content..*/.stat
4080: 69 63 20 63 68 61 72 20 2a 67 65 74 5f 62 6f 75 ic char *get_bou
4090: 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28 0a 20 20 nded_content(.
40a0: 63 68 61 72 20 2a 2a 70 7a 2c 20 20 20 20 20 20 char **pz,
40b0: 20 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 61 /* Content ta
40c0: 6b 65 6e 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f ken from here */
40d0: 0a 20 20 69 6e 74 20 2a 70 4c 65 6e 2c 20 20 20 . int *pLen,
40e0: 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 /* Number
40f0: 6f 66 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 of bytes of data
4100: 20 69 6e 20 28 2a 70 7a 29 5b 5d 20 2a 2f 0a 20 in (*pz)[] */.
4110: 20 63 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 2c char *zBoundry,
4120: 20 20 20 20 2f 2a 20 42 6f 75 6e 64 72 79 20 74 /* Boundry t
4130: 65 78 74 20 6d 61 72 6b 69 6e 67 20 74 68 65 20 ext marking the
4140: 65 6e 64 20 6f 66 20 63 6f 6e 74 65 6e 74 20 2a end of content *
4150: 2f 0a 20 20 69 6e 74 20 2a 70 6e 43 6f 6e 74 65 /. int *pnConte
4160: 6e 74 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 nt /* Write
4170: 74 68 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 the size of the
4180: 63 6f 6e 74 65 6e 74 20 68 65 72 65 20 2a 2f 0a content here */.
4190: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 2a ){. char *z = *
41a0: 70 7a 3b 0a 20 20 69 6e 74 20 6c 65 6e 20 3d 20 pz;. int len =
41b0: 2a 70 4c 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a *pLen;. int i;.
41c0: 20 20 69 6e 74 20 6e 42 6f 75 6e 64 72 79 20 3d int nBoundry =
41d0: 20 73 74 72 6c 65 6e 28 7a 42 6f 75 6e 64 72 79 strlen(zBoundry
41e0: 29 3b 0a 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 );. *pnContent
41f0: 3d 20 6c 65 6e 3b 0a 20 20 66 6f 72 28 69 3d 30 = len;. for(i=0
4200: 3b 20 69 3c 6c 65 6e 3b 20 69 2b 2b 29 7b 0a 20 ; i<len; i++){.
4210: 20 20 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e if( z[i]=='\n
4220: 27 20 26 26 20 73 74 72 6e 63 6d 70 28 7a 42 6f ' && strncmp(zBo
4230: 75 6e 64 72 79 2c 20 26 7a 5b 69 2b 31 5d 2c 20 undry, &z[i+1],
4240: 6e 42 6f 75 6e 64 72 79 29 3d 3d 30 20 29 7b 0a nBoundry)==0 ){.
4250: 20 20 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 if( i>0 &&
4260: 20 7a 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 20 z[i-1]=='\r' )
4270: 69 2d 2d 3b 0a 20 20 20 20 20 20 7a 5b 69 5d 20 i--;. z[i]
4280: 3d 20 30 3b 0a 20 20 20 20 20 20 2a 70 6e 43 6f = 0;. *pnCo
4290: 6e 74 65 6e 74 20 3d 20 69 3b 0a 20 20 20 20 20 ntent = i;.
42a0: 20 69 20 2b 3d 20 6e 42 6f 75 6e 64 72 79 3b 0a i += nBoundry;.
42b0: 20 20 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 break;.
42c0: 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 }. }. *pz = &
42d0: 7a 5b 69 5d 3b 0a 20 20 67 65 74 5f 6c 69 6e 65 z[i];. get_line
42e0: 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 70 7a 2c _from_string(pz,
42f0: 20 70 4c 65 6e 29 3b 0a 20 20 72 65 74 75 72 6e pLen);. return
4300: 20 7a 3b 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a z; .}../*.
4310: 2a 2a 20 54 6f 6b 65 6e 69 7a 65 20 61 20 6c 69 ** Tokenize a li
4320: 6e 65 20 6f 66 20 74 65 78 74 20 69 6e 74 6f 20 ne of text into
4330: 61 73 20 6d 61 6e 79 20 61 73 20 6e 41 72 67 20 as many as nArg
4340: 74 6f 6b 65 6e 73 2e 20 20 4d 61 6b 65 0a 2a 2a tokens. Make.**
4350: 20 61 7a 41 72 67 5b 5d 20 70 6f 69 6e 74 20 74 azArg[] point t
4360: 6f 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 65 o the start of e
4370: 61 63 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a ach token..**.**
4380: 20 54 6f 6b 65 6e 73 20 63 6f 6e 73 69 73 74 20 Tokens consist
4390: 6f 66 20 73 70 61 63 65 20 6f 72 20 73 65 6d 69 of space or semi
43a0: 2d 63 6f 6c 6f 6e 20 64 65 6c 69 6d 69 74 65 64 -colon delimited
43b0: 20 77 6f 72 64 73 20 6f 72 0a 2a 2a 20 73 74 72 words or.** str
43c0: 69 6e 67 73 20 69 6e 73 69 64 65 20 64 6f 75 62 ings inside doub
43d0: 6c 65 2d 71 75 6f 74 65 73 2e 20 20 45 78 61 6d le-quotes. Exam
43e0: 70 6c 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 63 6f ple:.**.** co
43f0: 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f ntent-dispositio
4400: 6e 3a 20 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 n: form-data; na
4410: 6d 65 3d 22 66 6e 22 3b 20 66 69 6c 65 6e 61 6d me="fn"; filenam
4420: 65 3d 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a e="index.html".*
4430: 2a 0a 2a 2a 20 54 68 65 20 6c 69 6e 65 20 61 62 *.** The line ab
4440: 6f 76 65 20 69 73 20 74 6f 6b 65 6e 69 7a 65 64 ove is tokenized
4450: 20 61 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a as follows:.**.
4460: 2a 2a 20 20 20 20 61 7a 41 72 67 5b 30 5d 20 3d ** azArg[0] =
4470: 20 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 "content-dispos
4480: 69 74 69 6f 6e 3a 22 0a 2a 2a 20 20 20 20 61 7a ition:".** az
4490: 41 72 67 5b 31 5d 20 3d 20 22 66 6f 72 6d 2d 64 Arg[1] = "form-d
44a0: 61 74 61 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 ata".** azArg
44b0: 5b 32 5d 20 3d 20 22 6e 61 6d 65 3d 22 0a 2a 2a [2] = "name=".**
44c0: 20 20 20 20 61 7a 41 72 67 5b 33 5d 20 3d 20 22 azArg[3] = "
44d0: 66 6e 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b fn".** azArg[
44e0: 34 5d 20 3d 20 22 66 69 6c 65 6e 61 6d 65 3d 22 4] = "filename="
44f0: 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 35 5d 20 .** azArg[5]
4500: 3d 20 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a = "index.html".*
4510: 2a 20 20 20 20 61 7a 41 72 67 5b 36 5d 20 3d 20 * azArg[6] =
4520: 30 3b 0a 2a 2a 0a 2a 2a 20 27 5c 30 30 30 27 20 0;.**.** '\000'
4530: 63 68 61 72 61 63 74 65 72 73 20 61 72 65 20 69 characters are i
4540: 6e 73 65 72 74 65 64 20 69 6e 20 7a 5b 5d 20 61 nserted in z[] a
4550: 74 20 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 t the end of eac
4560: 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 54 68 69 73 h token..** This
4570: 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 routine returns
4580: 20 74 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 the total numbe
4590: 72 20 6f 66 20 74 6f 6b 65 6e 73 20 6f 6e 20 74 r of tokens on t
45a0: 68 65 20 6c 69 6e 65 2c 20 36 0a 2a 2a 20 69 6e he line, 6.** in
45b0: 20 74 68 65 20 65 78 61 6d 70 6c 65 20 61 62 6f the example abo
45c0: 76 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e ve..*/.static in
45d0: 74 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 t tokenize_line(
45e0: 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 6d 78 41 char *z, int mxA
45f0: 72 67 2c 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 rg, char **azArg
4600: 29 7b 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a ){. int i = 0;.
4610: 20 20 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 while( *z ){.
4620: 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 while( isspac
4630: 65 28 2a 7a 29 20 7c 7c 20 2a 7a 3d 3d 27 3b 27 e(*z) || *z==';'
4640: 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69 ){ z++; }. i
4650: 66 28 20 2a 7a 3d 3d 27 22 27 20 26 26 20 7a 5b f( *z=='"' && z[
4660: 31 5d 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 1] ){. *z =
4670: 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 0;. z++;.
4680: 20 20 20 20 20 69 66 28 20 69 3c 6d 78 41 72 67 if( i<mxArg
4690: 2d 31 20 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d -1 ){ azArg[i++]
46a0: 20 3d 20 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68 = z; }. wh
46b0: 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 ile( *z && *z!='
46c0: 22 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 "' ){ z++; }.
46d0: 20 20 20 69 66 28 20 2a 7a 3d 3d 30 20 29 20 62 if( *z==0 ) b
46e0: 72 65 61 6b 3b 0a 20 20 20 20 20 20 2a 7a 20 3d reak;. *z =
46f0: 20 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 0;. z++;.
4700: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
4710: 69 66 28 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b if( i<mxArg-1 ){
4720: 20 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b azArg[i++] = z;
4730: 20 7d 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 }. while(
4740: 2a 7a 20 26 26 20 21 69 73 73 70 61 63 65 28 2a *z && !isspace(*
4750: 7a 29 20 26 26 20 2a 7a 21 3d 27 3b 27 20 26 26 z) && *z!=';' &&
4760: 20 2a 7a 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b *z!='"' ){ z++;
4770: 20 7d 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20 }. if( *z
4780: 26 26 20 2a 7a 21 3d 27 22 27 20 29 7b 0a 20 20 && *z!='"' ){.
4790: 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 *z = 0;.
47a0: 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 z++;.
47b0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 }. }. }. a
47c0: 7a 41 72 67 5b 69 5d 20 3d 20 30 3b 0a 20 20 72 zArg[i] = 0;. r
47d0: 65 74 75 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a eturn i;.}../*.*
47e0: 2a 20 53 63 61 6e 20 74 68 65 20 6d 75 6c 74 69 * Scan the multi
47f0: 70 61 72 74 2d 66 6f 72 6d 20 63 6f 6e 74 65 6e part-form conten
4800: 74 20 61 6e 64 20 6d 61 6b 65 20 61 70 70 72 6f t and make appro
4810: 70 72 69 61 74 65 20 65 6e 74 72 69 65 73 0a 2a priate entries.*
4820: 2a 20 69 6e 74 6f 20 74 68 65 20 70 61 72 61 6d * into the param
4830: 65 74 65 72 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a eter table..**.*
4840: 2a 20 54 68 65 20 63 6f 6e 74 65 6e 74 20 73 74 * The content st
4850: 72 69 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 ring "z" is modi
4860: 66 69 65 64 20 62 79 20 74 68 69 73 20 72 6f 75 fied by this rou
4870: 74 69 6e 65 20 62 75 74 20 69 74 20 69 73 0a 2a tine but it is.*
4880: 2a 20 6e 6f 74 20 63 6f 70 69 65 64 2e 20 20 54 * not copied. T
4890: 68 65 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 he calling funct
48a0: 69 6f 6e 20 6d 75 73 74 20 6e 6f 74 20 64 65 61 ion must not dea
48b0: 6c 6c 6f 63 61 74 65 20 6f 72 20 6d 6f 64 69 66 llocate or modif
48c0: 79 0a 2a 2a 20 22 7a 22 20 61 66 74 65 72 20 74 y.** "z" after t
48d0: 68 69 73 20 72 6f 75 74 69 6e 65 20 66 69 6e 69 his routine fini
48e0: 73 68 65 73 20 6f 72 20 69 74 20 63 6f 75 6c 64 shes or it could
48f0: 20 63 6f 72 72 75 70 74 20 74 68 65 20 70 61 72 corrupt the par
4900: 61 6d 65 74 65 72 0a 2a 2a 20 74 61 62 6c 65 2e ameter.** table.
4910: 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 .*/.static void
4920: 70 72 6f 63 65 73 73 5f 6d 75 6c 74 69 70 61 72 process_multipar
4930: 74 5f 66 6f 72 6d 5f 64 61 74 61 28 63 68 61 72 t_form_data(char
4940: 20 2a 7a 2c 20 69 6e 74 20 6c 65 6e 29 7b 0a 20 *z, int len){.
4950: 20 63 68 61 72 20 2a 7a 4c 69 6e 65 3b 0a 20 20 char *zLine;.
4960: 69 6e 74 20 6e 41 72 67 2c 20 69 3b 0a 20 20 63 int nArg, i;. c
4970: 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 3b 0a 20 har *zBoundry;.
4980: 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 char *zValue;.
4990: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 30 char *zName = 0
49a0: 3b 0a 20 20 69 6e 74 20 73 68 6f 77 42 79 74 65 ;. int showByte
49b0: 73 20 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 61 s = 0;. char *a
49c0: 7a 41 72 67 5b 35 30 5d 3b 0a 0a 20 20 7a 42 6f zArg[50];.. zBo
49d0: 75 6e 64 72 79 20 3d 20 67 65 74 5f 6c 69 6e 65 undry = get_line
49e0: 5f 66 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c _from_string(&z,
49f0: 20 26 6c 65 6e 29 3b 0a 20 20 69 66 28 20 7a 42 &len);. if( zB
4a00: 6f 75 6e 64 72 79 3d 3d 30 20 29 20 72 65 74 75 oundry==0 ) retu
4a10: 72 6e 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4c rn;. while( (zL
4a20: 69 6e 65 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 ine = get_line_f
4a30: 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 rom_string(&z, &
4a40: 6c 65 6e 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 len))!=0 ){.
4a50: 69 66 28 20 7a 4c 69 6e 65 5b 30 5d 3d 3d 30 20 if( zLine[0]==0
4a60: 29 7b 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f ){. int nCo
4a70: 6e 74 65 6e 74 20 3d 20 30 3b 0a 20 20 20 20 20 ntent = 0;.
4a80: 20 7a 56 61 6c 75 65 20 3d 20 67 65 74 5f 62 6f zValue = get_bo
4a90: 75 6e 64 65 64 5f 63 6f 6e 74 65 6e 74 28 26 7a unded_content(&z
4aa0: 2c 20 26 6c 65 6e 2c 20 7a 42 6f 75 6e 64 72 79 , &len, zBoundry
4ab0: 2c 20 26 6e 43 6f 6e 74 65 6e 74 29 3b 0a 20 20 , &nContent);.
4ac0: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 if( zName &&
4ad0: 20 7a 56 61 6c 75 65 20 26 26 20 69 73 6c 6f 77 zValue && islow
4ae0: 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a er(zName[0]) ){.
4af0: 20 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f cgi_set_
4b00: 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 parameter_nocopy
4b10: 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b (zName, zValue);
4b20: 0a 20 20 20 20 20 20 20 20 69 66 28 20 73 68 6f . if( sho
4b30: 77 42 79 74 65 73 20 29 7b 0a 20 20 20 20 20 20 wBytes ){.
4b40: 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 cgi_set_para
4b50: 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 meter_nocopy(mpr
4b60: 69 6e 74 66 28 22 25 73 3a 62 79 74 65 73 22 2c intf("%s:bytes",
4b70: 20 7a 4e 61 6d 65 29 2c 0a 20 20 20 20 20 20 20 zName),.
4b80: 20 20 20 20 20 20 20 20 6d 70 72 69 6e 74 66 28 mprintf(
4b90: 22 25 64 22 2c 6e 43 6f 6e 74 65 6e 74 29 29 3b "%d",nContent));
4ba0: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 . }.
4bb0: 20 7d 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d }. zName =
4bc0: 20 30 3b 0a 20 20 20 20 20 20 73 68 6f 77 42 79 0;. showBy
4bd0: 74 65 73 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c tes = 0;. }el
4be0: 73 65 7b 0a 20 20 20 20 20 20 6e 41 72 67 20 3d se{. nArg =
4bf0: 20 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 7a tokenize_line(z
4c00: 4c 69 6e 65 2c 20 73 69 7a 65 6f 66 28 61 7a 41 Line, sizeof(azA
4c10: 72 67 29 2f 73 69 7a 65 6f 66 28 61 7a 41 72 67 rg)/sizeof(azArg
4c20: 5b 30 5d 29 2c 20 61 7a 41 72 67 29 3b 0a 20 20 [0]), azArg);.
4c30: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e for(i=0; i<n
4c40: 41 72 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 Arg; i++){.
4c50: 20 20 20 69 6e 74 20 63 20 3d 20 74 6f 6c 6f 77 int c = tolow
4c60: 65 72 28 61 7a 41 72 67 5b 69 5d 5b 30 5d 29 3b er(azArg[i][0]);
4c70: 0a 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d . if( c==
4c80: 27 63 27 20 26 26 20 73 74 72 69 63 6d 70 28 61 'c' && stricmp(a
4c90: 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74 zArg[i],"content
4ca0: 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a 22 29 3d -disposition:")=
4cb0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 =0 ){.
4cc0: 69 2b 2b 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c i++;. }el
4cd0: 73 65 20 69 66 28 20 63 3d 3d 27 6e 27 20 26 26 se if( c=='n' &&
4ce0: 20 73 74 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 stricmp(azArg[i
4cf0: 5d 2c 22 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b ],"name=")==0 ){
4d00: 0a 20 20 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 . zName
4d10: 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 = azArg[++i];.
4d20: 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 }else if(
4d30: 20 63 3d 3d 27 66 27 20 26 26 20 73 74 72 69 63 c=='f' && stric
4d40: 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 66 69 6c mp(azArg[i],"fil
4d50: 65 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a 20 ename=")==0 ){.
4d60: 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a char *z
4d70: 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 = azArg[++i];.
4d80: 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61 if( zNa
4d90: 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f 77 me && z && islow
4da0: 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a er(zName[0]) ){.
4db0: 20 20 20 20 20 20 20 20 20 20 20 20 63 67 69 5f cgi_
4dc0: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f set_parameter_no
4dd0: 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 copy(mprintf("%s
4de0: 3a 66 69 6c 65 6e 61 6d 65 22 2c 7a 4e 61 6d 65 :filename",zName
4df0: 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 ), z);.
4e00: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 73 68 6f }. sho
4e10: 77 42 79 74 65 73 20 3d 20 31 3b 0a 20 20 20 20 wBytes = 1;.
4e20: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d }else if( c=
4e30: 3d 27 63 27 20 26 26 20 73 74 72 69 63 6d 70 28 ='c' && stricmp(
4e40: 61 7a 41 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e azArg[i],"conten
4e50: 74 2d 74 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a t-type:")==0 ){.
4e60: 20 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a char *
4e70: 7a 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a z = azArg[++i];.
4e80: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e if( zN
4e90: 61 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f ame && z && islo
4ea0: 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b wer(zName[0]) ){
4eb0: 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 67 69 . cgi
4ec0: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e _set_parameter_n
4ed0: 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 ocopy(mprintf("%
4ee0: 73 3a 6d 69 6d 65 74 79 70 65 22 2c 7a 4e 61 6d s:mimetype",zNam
4ef0: 65 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 e), z);.
4f00: 20 20 7d 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 }. }.
4f10: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 }. }. }
4f20: 20 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a .}../*.**
4f30: 20 49 6e 69 74 69 61 6c 69 7a 65 20 74 68 65 20 Initialize the
4f40: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 query parameter
4f50: 64 61 74 61 62 61 73 65 2e 20 20 49 6e 66 6f 72 database. Infor
4f60: 6d 61 74 69 6f 6e 20 69 73 20 70 75 6c 6c 65 64 mation is pulled
4f70: 20 66 72 6f 6d 0a 2a 2a 20 74 68 65 20 51 55 45 from.** the QUE
4f80: 52 59 5f 53 54 52 49 4e 47 20 65 6e 76 69 72 6f RY_STRING enviro
4f90: 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 28 nment variable (
4fa0: 69 66 20 69 74 20 65 78 69 73 74 73 29 2c 20 66 if it exists), f
4fb0: 72 6f 6d 20 73 74 61 6e 64 61 72 64 0a 2a 2a 20 rom standard.**
4fc0: 69 6e 70 75 74 20 69 66 20 74 68 65 72 65 20 69 input if there i
4fd0: 73 20 50 4f 53 54 20 64 61 74 61 2c 20 61 6e 64 s POST data, and
4fe0: 20 66 72 6f 6d 20 48 54 54 50 5f 43 4f 4f 4b 49 from HTTP_COOKI
4ff0: 45 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 69 E..*/.void cgi_i
5000: 6e 69 74 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 nit(void){. cha
5010: 72 20 2a 7a 3b 0a 20 20 63 6f 6e 73 74 20 63 68 r *z;. const ch
5020: 61 72 20 2a 7a 54 79 70 65 3b 0a 20 20 69 6e 74 ar *zType;. int
5030: 20 6c 65 6e 3b 0a 20 20 63 67 69 5f 64 65 73 74 len;. cgi_dest
5040: 69 6e 61 74 69 6f 6e 28 43 47 49 5f 42 4f 44 59 ination(CGI_BODY
5050: 29 3b 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 );. z = (char*)
5060: 50 28 22 51 55 45 52 59 5f 53 54 52 49 4e 47 22 P("QUERY_STRING"
5070: 29 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 );. if( z ){.
5080: 20 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 z = mprintf("%
5090: 73 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 s",z);. add_p
50a0: 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 26 27 aram_list(z, '&'
50b0: 29 3b 0a 20 20 7d 0a 0a 20 20 6c 65 6e 20 3d 20 );. }.. len =
50c0: 61 74 6f 69 28 50 44 28 22 43 4f 4e 54 45 4e 54 atoi(PD("CONTENT
50d0: 5f 4c 45 4e 47 54 48 22 2c 20 22 30 22 29 29 3b _LENGTH", "0"));
50e0: 0a 20 20 67 2e 7a 43 6f 6e 74 65 6e 74 54 79 70 . g.zContentTyp
50f0: 65 20 3d 20 7a 54 79 70 65 20 3d 20 50 28 22 43 e = zType = P("C
5100: 4f 4e 54 45 4e 54 5f 54 59 50 45 22 29 3b 0a 20 ONTENT_TYPE");.
5110: 20 69 66 28 20 6c 65 6e 3e 30 20 26 26 20 7a 54 if( len>0 && zT
5120: 79 70 65 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f ype ){. blob_
5130: 7a 65 72 6f 28 26 67 2e 63 67 69 49 6e 29 3b 0a zero(&g.cgiIn);.
5140: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a if( strcmp(z
5150: 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74 69 6f Type,"applicatio
5160: 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c n/x-www-form-url
5170: 65 6e 63 6f 64 65 64 22 29 3d 3d 30 20 0a 20 20 encoded")==0 .
5180: 20 20 20 20 20 20 20 7c 7c 20 73 74 72 6e 63 6d || strncm
5190: 70 28 7a 54 79 70 65 2c 22 6d 75 6c 74 69 70 61 p(zType,"multipa
51a0: 72 74 2f 66 6f 72 6d 2d 64 61 74 61 22 2c 31 39 rt/form-data",19
51b0: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 7a 20 )==0 ){. z
51c0: 3d 20 6d 61 6c 6c 6f 63 28 20 6c 65 6e 2b 31 20 = malloc( len+1
51d0: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 3d 3d );. if( z==
51e0: 30 20 29 20 65 78 69 74 28 31 29 3b 0a 20 20 20 0 ) exit(1);.
51f0: 20 20 20 6c 65 6e 20 3d 20 66 72 65 61 64 28 7a len = fread(z
5200: 2c 20 31 2c 20 6c 65 6e 2c 20 67 2e 68 74 74 70 , 1, len, g.http
5210: 49 6e 29 3b 0a 20 20 20 20 20 20 7a 5b 6c 65 6e In);. z[len
5220: 5d 20 3d 20 30 3b 0a 20 20 20 20 20 20 69 66 28 ] = 0;. if(
5230: 20 7a 54 79 70 65 5b 30 5d 3d 3d 27 61 27 20 29 zType[0]=='a' )
5240: 7b 0a 20 20 20 20 20 20 20 20 61 64 64 5f 70 61 {. add_pa
5250: 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 26 27 29 ram_list(z, '&')
5260: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 ;. }else{.
5270: 20 20 20 20 20 20 20 70 72 6f 63 65 73 73 5f 6d process_m
5280: 75 6c 74 69 70 61 72 74 5f 66 6f 72 6d 5f 64 61 ultipart_form_da
5290: 74 61 28 7a 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 ta(z, len);.
52a0: 20 20 7d 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 }. }else if
52b0: 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20 ( strcmp(zType,
52c0: 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 "application/x-f
52d0: 6f 73 73 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 ossil")==0 ){.
52e0: 20 20 20 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 blob_read_fr
52f0: 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26 67 2e 63 67 om_channel(&g.cg
5300: 69 49 6e 2c 20 67 2e 68 74 74 70 49 6e 2c 20 6c iIn, g.httpIn, l
5310: 65 6e 29 3b 0a 20 20 20 20 20 20 62 6c 6f 62 5f en);. blob_
5320: 75 6e 63 6f 6d 70 72 65 73 73 28 26 67 2e 63 67 uncompress(&g.cg
5330: 69 49 6e 2c 20 26 67 2e 63 67 69 49 6e 29 3b 0a iIn, &g.cgiIn);.
5340: 20 20 20 20 20 20 2f 2a 20 49 66 20 74 68 65 20 /* If the
5350: 63 6f 6e 74 65 6e 74 20 74 79 70 65 20 69 73 20 content type is
5360: 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f application/x-fo
5370: 73 73 69 6c 2c 20 74 68 65 6e 20 69 67 6e 6f 72 ssil, then ignor
5380: 65 0a 20 20 20 20 20 20 2a 2a 20 74 68 65 20 70 e. ** the p
5390: 61 74 68 20 69 6e 20 74 68 65 20 66 69 72 73 74 ath in the first
53a0: 20 6c 69 6e 65 20 6f 66 20 74 68 65 20 48 54 54 line of the HTT
53b0: 50 20 68 65 61 64 65 72 20 61 6e 64 20 61 6c 77 P header and alw
53c0: 61 79 73 0a 20 20 20 20 20 20 2a 2a 20 75 73 65 ays. ** use
53d0: 20 74 68 65 20 2f 78 66 65 72 20 6d 65 74 68 6f the /xfer metho
53e0: 64 20 73 69 6e 63 65 20 74 68 65 20 2f 78 66 65 d since the /xfe
53f0: 72 20 6d 65 74 68 6f 64 20 69 73 20 74 68 65 20 r method is the
5400: 6f 6e 6c 79 0a 20 20 20 20 20 20 2a 2a 20 6d 65 only. ** me
5410: 74 68 6f 64 20 74 68 61 74 20 75 6e 64 65 72 73 thod that unders
5420: 74 61 6e 64 73 20 74 68 65 20 61 70 70 6c 69 63 tands the applic
5430: 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 20 63 ation/x-fossil c
5440: 6f 6e 74 65 6e 74 0a 20 20 20 20 20 20 2a 2a 20 ontent. **
5450: 74 79 70 65 2e 0a 20 20 20 20 20 20 2a 2f 0a 20 type.. */.
5460: 20 20 20 20 20 63 67 69 5f 72 65 70 6c 61 63 65 cgi_replace
5470: 5f 70 61 72 61 6d 65 74 65 72 28 22 50 41 54 48 _parameter("PATH
5480: 5f 49 4e 46 4f 22 2c 20 22 2f 78 66 65 72 22 29 _INFO", "/xfer")
5490: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 ;. }else if(
54a0: 73 74 72 63 6d 70 28 7a 54 79 70 65 2c 20 22 61 strcmp(zType, "a
54b0: 70 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 pplication/x-fos
54c0: 73 69 6c 2d 64 65 62 75 67 22 29 3d 3d 30 20 29 sil-debug")==0 )
54d0: 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 61 {. blob_rea
54e0: 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26 d_from_channel(&
54f0: 67 2e 63 67 69 49 6e 2c 20 67 2e 68 74 74 70 49 g.cgiIn, g.httpI
5500: 6e 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 63 n, len);. c
5510: 67 69 5f 72 65 70 6c 61 63 65 5f 70 61 72 61 6d gi_replace_param
5520: 65 74 65 72 28 22 50 41 54 48 5f 49 4e 46 4f 22 eter("PATH_INFO"
5530: 2c 20 22 2f 78 66 65 72 22 29 3b 20 20 2f 2a 20 , "/xfer"); /*
5540: 53 65 65 20 63 6f 6d 6d 65 6e 74 20 61 62 6f 76 See comment abov
5550: 65 20 2a 2f 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a e */. }. }..
5560: 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 50 28 22 z = (char*)P("
5570: 48 54 54 50 5f 43 4f 4f 4b 49 45 22 29 3b 0a 20 HTTP_COOKIE");.
5580: 20 69 66 28 20 7a 20 29 7b 0a 20 20 20 20 7a 20 if( z ){. z
5590: 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a = mprintf("%s",z
55a0: 29 3b 0a 20 20 20 20 61 64 64 5f 70 61 72 61 6d );. add_param
55b0: 5f 6c 69 73 74 28 7a 2c 20 27 3b 27 29 3b 0a 20 _list(z, ';');.
55c0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 }.}../*.** This
55d0: 20 69 73 20 74 68 65 20 63 6f 6d 70 61 72 69 73 is the comparis
55e0: 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 75 73 65 64 on function used
55f0: 20 74 6f 20 73 6f 72 74 20 74 68 65 20 61 50 61 to sort the aPa
5600: 72 61 6d 51 50 5b 5d 20 61 72 72 61 79 20 6f 66 ramQP[] array of
5610: 0a 2a 2a 20 71 75 65 72 79 20 70 61 72 61 6d 65 .** query parame
5620: 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 ters and cookies
5630: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ..*/.static int
5640: 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72 65 28 63 qparam_compare(c
5650: 6f 6e 73 74 20 76 6f 69 64 20 2a 61 2c 20 63 6f onst void *a, co
5660: 6e 73 74 20 76 6f 69 64 20 2a 62 29 7b 0a 20 20 nst void *b){.
5670: 73 74 72 75 63 74 20 51 50 61 72 61 6d 20 2a 70 struct QParam *p
5680: 41 20 3d 20 28 73 74 72 75 63 74 20 51 50 61 72 A = (struct QPar
5690: 61 6d 2a 29 61 3b 0a 20 20 73 74 72 75 63 74 20 am*)a;. struct
56a0: 51 50 61 72 61 6d 20 2a 70 42 20 3d 20 28 73 74 QParam *pB = (st
56b0: 72 75 63 74 20 51 50 61 72 61 6d 2a 29 62 3b 0a ruct QParam*)b;.
56c0: 20 20 69 6e 74 20 63 3b 0a 20 20 63 20 3d 20 73 int c;. c = s
56d0: 74 72 63 6d 70 28 70 41 2d 3e 7a 4e 61 6d 65 2c trcmp(pA->zName,
56e0: 20 70 42 2d 3e 7a 4e 61 6d 65 29 3b 0a 20 20 69 pB->zName);. i
56f0: 66 28 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20 63 f( c==0 ){. c
5700: 20 3d 20 70 41 2d 3e 73 65 71 20 2d 20 70 42 2d = pA->seq - pB-
5710: 3e 73 65 71 3b 0a 20 20 7d 0a 20 20 72 65 74 75 >seq;. }. retu
5720: 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 rn c;.}../*.** R
5730: 65 74 75 72 6e 20 74 68 65 20 76 61 6c 75 65 20 eturn the value
5740: 6f 66 20 61 20 71 75 65 72 79 20 70 61 72 61 6d of a query param
5750: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 77 eter or cookie w
5760: 68 6f 73 65 20 6e 61 6d 65 20 69 73 20 7a 4e 61 hose name is zNa
5770: 6d 65 2e 0a 2a 2a 20 49 66 20 74 68 65 72 65 20 me..** If there
5780: 69 73 20 6e 6f 20 71 75 65 72 79 20 70 61 72 61 is no query para
5790: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 meter or cookie
57a0: 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 61 6e 64 20 named zName and
57b0: 74 68 65 20 66 69 72 73 74 0a 2a 2a 20 63 68 61 the first.** cha
57c0: 72 61 63 74 65 72 20 6f 66 20 7a 4e 61 6d 65 20 racter of zName
57d0: 69 73 20 75 70 70 65 72 63 61 73 65 2c 20 74 68 is uppercase, th
57e0: 65 6e 20 63 68 65 63 6b 20 74 6f 20 73 65 65 20 en check to see
57f0: 69 66 20 74 68 65 72 65 20 69 73 20 61 6e 0a 2a if there is an.*
5800: 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 * environment va
5810: 72 69 61 62 6c 65 20 62 79 20 74 68 61 74 20 6e riable by that n
5820: 61 6d 65 20 61 6e 64 20 72 65 74 75 72 6e 20 69 ame and return i
5830: 74 20 69 66 20 74 68 65 72 65 20 69 73 2e 20 20 t if there is.
5840: 41 73 0a 2a 2a 20 61 20 6c 61 73 74 20 72 65 73 As.** a last res
5850: 6f 72 74 20 77 68 65 6e 20 6e 6f 74 68 69 6e 67 ort when nothing
5860: 20 65 6c 73 65 20 6d 61 74 63 68 65 73 2c 20 72 else matches, r
5870: 65 74 75 72 6e 20 7a 44 65 66 61 75 6c 74 2e 0a eturn zDefault..
5880: 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20 2a 63 */.const char *c
5890: 67 69 5f 70 61 72 61 6d 65 74 65 72 28 63 6f 6e gi_parameter(con
58a0: 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 st char *zName,
58b0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 65 66 const char *zDef
58c0: 61 75 6c 74 29 7b 0a 20 20 69 6e 74 20 6c 6f 2c ault){. int lo,
58d0: 20 68 69 2c 20 6d 69 64 2c 20 63 3b 0a 0a 20 20 hi, mid, c;..
58e0: 2f 2a 20 54 68 65 20 73 6f 72 74 51 50 20 66 6c /* The sortQP fl
58f0: 61 67 20 69 73 20 73 65 74 20 77 68 65 6e 65 76 ag is set whenev
5900: 65 72 20 61 20 6e 65 77 20 71 75 65 72 79 20 70 er a new query p
5910: 61 72 61 6d 65 74 65 72 20 69 73 20 69 6e 73 65 arameter is inse
5920: 72 74 65 64 2e 0a 20 20 2a 2a 20 49 74 20 69 6e rted.. ** It in
5930: 64 69 63 61 74 65 73 20 74 68 61 74 20 77 65 20 dicates that we
5940: 6e 65 65 64 20 74 6f 20 72 65 73 6f 72 74 20 74 need to resort t
5950: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 he query paramet
5960: 65 72 73 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 ers.. */. if(
5970: 73 6f 72 74 51 50 20 29 7b 0a 20 20 20 20 69 6e sortQP ){. in
5980: 74 20 69 2c 20 6a 3b 0a 20 20 20 20 71 73 6f 72 t i, j;. qsor
5990: 74 28 61 50 61 72 61 6d 51 50 2c 20 6e 55 73 65 t(aParamQP, nUse
59a0: 64 51 50 2c 20 73 69 7a 65 6f 66 28 61 50 61 72 dQP, sizeof(aPar
59b0: 61 6d 51 50 5b 30 5d 29 2c 20 71 70 61 72 61 6d amQP[0]), qparam
59c0: 5f 63 6f 6d 70 61 72 65 29 3b 0a 20 20 20 20 73 _compare);. s
59d0: 6f 72 74 51 50 20 3d 20 30 3b 0a 20 20 20 20 2f ortQP = 0;. /
59e0: 2a 20 41 66 74 65 72 20 73 6f 72 74 69 6e 67 2c * After sorting,
59f0: 20 72 65 6d 6f 76 65 20 64 75 70 6c 69 63 61 74 remove duplicat
5a00: 65 20 70 61 72 61 6d 65 74 65 72 73 2e 20 20 54 e parameters. T
5a10: 68 65 20 73 65 63 6f 6e 64 61 72 79 20 73 6f 72 he secondary sor
5a20: 74 0a 20 20 20 20 2a 2a 20 6b 65 79 20 69 73 20 t. ** key is
5a30: 61 50 61 72 61 6d 51 50 5b 5d 2e 73 65 71 20 61 aParamQP[].seq a
5a40: 6e 64 20 77 65 20 6b 65 65 70 20 74 68 65 20 66 nd we keep the f
5a50: 69 72 73 74 20 65 6e 74 72 79 2e 20 20 54 68 61 irst entry. Tha
5a60: 74 20 6d 65 61 6e 73 0a 20 20 20 20 2a 2a 20 77 t means. ** w
5a70: 69 74 68 20 64 75 70 6c 69 63 61 74 65 20 63 61 ith duplicate ca
5a80: 6c 6c 73 20 74 6f 20 63 67 69 5f 73 65 74 5f 70 lls to cgi_set_p
5a90: 61 72 61 6d 65 74 65 72 28 29 20 74 68 65 20 73 arameter() the s
5aa0: 65 63 6f 6e 64 20 61 6e 64 0a 20 20 20 20 2a 2a econd and. **
5ab0: 20 73 75 62 73 65 71 75 65 6e 74 20 63 61 6c 6c subsequent call
5ac0: 73 20 61 72 65 20 65 66 66 65 63 74 69 76 65 6c s are effectivel
5ad0: 79 20 6e 6f 2d 6f 70 73 2e 20 2a 2f 0a 20 20 20 y no-ops. */.
5ae0: 20 66 6f 72 28 69 3d 6a 3d 31 3b 20 69 3c 6e 55 for(i=j=1; i<nU
5af0: 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a 20 20 20 sedQP; i++){.
5b00: 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61 50 if( strcmp(aP
5b10: 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e 61 6d 65 2c aramQP[i].zName,
5b20: 61 50 61 72 61 6d 51 50 5b 69 2d 31 5d 2e 7a 4e aParamQP[i-1].zN
5b30: 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 ame)==0 ){.
5b40: 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 continue;.
5b50: 20 20 20 7d 0a 20 20 20 20 20 20 69 66 28 20 6a }. if( j
5b60: 3c 69 20 29 7b 0a 20 20 20 20 20 20 20 20 6d 65 <i ){. me
5b70: 6d 63 70 79 28 26 61 50 61 72 61 6d 51 50 5b 6a mcpy(&aParamQP[j
5b80: 5d 2c 20 26 61 50 61 72 61 6d 51 50 5b 69 5d 2c ], &aParamQP[i],
5b90: 20 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51 50 sizeof(aParamQP
5ba0: 5b 6a 5d 29 29 3b 0a 20 20 20 20 20 20 7d 0a 20 [j]));. }.
5bb0: 20 20 20 20 20 6a 2b 2b 3b 0a 20 20 20 20 7d 0a j++;. }.
5bc0: 20 20 20 20 6e 55 73 65 64 51 50 20 3d 20 6a 3b nUsedQP = j;
5bd0: 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 6f 20 61 20 . }.. /* Do a
5be0: 62 69 6e 61 72 79 20 73 65 61 72 63 68 20 66 6f binary search fo
5bf0: 72 20 61 20 6d 61 74 63 68 69 6e 67 20 71 75 65 r a matching que
5c00: 72 79 20 70 61 72 61 6d 65 74 65 72 20 2a 2f 0a ry parameter */.
5c10: 20 20 6c 6f 20 3d 20 30 3b 0a 20 20 68 69 20 3d lo = 0;. hi =
5c20: 20 6e 55 73 65 64 51 50 2d 31 3b 0a 20 20 77 68 nUsedQP-1;. wh
5c30: 69 6c 65 28 20 6c 6f 3c 3d 68 69 20 29 7b 0a 20 ile( lo<=hi ){.
5c40: 20 20 20 6d 69 64 20 3d 20 28 6c 6f 2b 68 69 29 mid = (lo+hi)
5c50: 2f 32 3b 0a 20 20 20 20 63 20 3d 20 73 74 72 63 /2;. c = strc
5c60: 6d 70 28 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d mp(aParamQP[mid]
5c70: 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d 65 29 3b 0a .zName, zName);.
5c80: 20 20 20 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a if( c==0 ){.
5c90: 20 20 20 20 20 20 43 47 49 44 45 42 55 47 28 28 CGIDEBUG((
5ca0: 22 6d 65 6d 2d 6d 61 74 63 68 20 5b 25 73 5d 20 "mem-match [%s]
5cb0: 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 = [%s]\n", zName
5cc0: 2c 20 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d 2e , aParamQP[mid].
5cd0: 7a 56 61 6c 75 65 29 29 3b 0a 20 20 20 20 20 20 zValue));.
5ce0: 72 65 74 75 72 6e 20 61 50 61 72 61 6d 51 50 5b return aParamQP[
5cf0: 6d 69 64 5d 2e 7a 56 61 6c 75 65 3b 0a 20 20 20 mid].zValue;.
5d00: 20 7d 65 6c 73 65 20 69 66 28 20 63 3e 30 20 29 }else if( c>0 )
5d10: 7b 0a 20 20 20 20 20 20 68 69 20 3d 20 6d 69 64 {. hi = mid
5d20: 2d 31 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 -1;. }else{.
5d30: 20 20 20 20 20 6c 6f 20 3d 20 6d 69 64 2b 31 3b lo = mid+1;
5d40: 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 2f 2a . }. }.. /*
5d50: 20 49 66 20 6e 6f 20 6d 61 74 63 68 20 69 73 20 If no match is
5d60: 66 6f 75 6e 64 20 61 6e 64 20 74 68 65 20 6e 61 found and the na
5d70: 6d 65 20 62 65 67 69 6e 73 20 77 69 74 68 20 61 me begins with a
5d80: 6e 20 75 70 70 65 72 2d 63 61 73 65 0a 20 20 2a n upper-case. *
5d90: 2a 20 6c 65 74 74 65 72 2c 20 74 68 65 6e 20 63 * letter, then c
5da0: 68 65 63 6b 20 74 6f 20 73 65 65 20 69 66 20 74 heck to see if t
5db0: 68 65 72 65 20 69 73 20 61 6e 20 65 6e 76 69 72 here is an envir
5dc0: 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 0a onment variable.
5dd0: 20 20 2a 2a 20 77 69 74 68 20 74 68 65 20 67 69 ** with the gi
5de0: 76 65 6e 20 6e 61 6d 65 2e 0a 20 20 2a 2f 0a 20 ven name.. */.
5df0: 20 69 66 28 20 69 73 75 70 70 65 72 28 7a 4e 61 if( isupper(zNa
5e00: 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 20 63 6f me[0]) ){. co
5e10: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 nst char *zValue
5e20: 20 3d 20 67 65 74 65 6e 76 28 7a 4e 61 6d 65 29 = getenv(zName)
5e30: 3b 0a 20 20 20 20 69 66 28 20 7a 56 61 6c 75 65 ;. if( zValue
5e40: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 ){. cgi_se
5e50: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f t_parameter_noco
5e60: 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 py(zName, zValue
5e70: 29 3b 0a 20 20 20 20 20 20 43 47 49 44 45 42 55 );. CGIDEBU
5e80: 47 28 28 22 65 6e 76 2d 6d 61 74 63 68 20 5b 25 G(("env-match [%
5e90: 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e s] = [%s]\n", zN
5ea0: 61 6d 65 2c 20 7a 56 61 6c 75 65 29 29 3b 0a 20 ame, zValue));.
5eb0: 20 20 20 20 20 72 65 74 75 72 6e 20 7a 56 61 6c return zVal
5ec0: 75 65 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 ue;. }. }.
5ed0: 43 47 49 44 45 42 55 47 28 28 22 6e 6f 2d 6d 61 CGIDEBUG(("no-ma
5ee0: 74 63 68 20 5b 25 73 5d 5c 6e 22 2c 20 7a 4e 61 tch [%s]\n", zNa
5ef0: 6d 65 29 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a me));. return z
5f00: 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a 2f 2a 0a 2a Default;.}../*.*
5f10: 2a 20 52 65 74 75 72 6e 20 74 68 65 20 6e 61 6d * Return the nam
5f20: 65 20 6f 66 20 74 68 65 20 69 2d 74 68 20 43 47 e of the i-th CG
5f30: 49 20 70 61 72 61 6d 65 74 65 72 2e 20 20 52 65 I parameter. Re
5f40: 74 75 72 6e 20 4e 55 4c 4c 20 69 66 20 74 68 65 turn NULL if the
5f50: 72 65 0a 2a 2a 20 61 72 65 20 66 65 77 65 72 20 re.** are fewer
5f60: 74 68 61 6e 20 69 20 72 65 67 69 73 74 65 72 65 than i registere
5f70: 64 20 43 47 49 20 70 61 72 6d 61 65 74 65 72 73 d CGI parmaeters
5f80: 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 72 20 ..*/.const char
5f90: 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72 5f 6e *cgi_parameter_n
5fa0: 61 6d 65 28 69 6e 74 20 69 29 7b 0a 20 20 69 66 ame(int i){. if
5fb0: 28 20 69 3e 3d 30 20 26 26 20 69 3c 6e 55 73 65 ( i>=0 && i<nUse
5fc0: 64 51 50 20 29 7b 0a 20 20 20 20 72 65 74 75 72 dQP ){. retur
5fd0: 6e 20 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e n aParamQP[i].zN
5fe0: 61 6d 65 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 ame;. }else{.
5ff0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a return 0;. }.
6000: 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74 20 43 }../*.** Print C
6010: 47 49 20 64 65 62 75 67 67 69 6e 67 20 6d 65 73 GI debugging mes
6020: 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 sages..*/.void c
6030: 67 69 5f 64 65 62 75 67 28 63 6f 6e 73 74 20 63 gi_debug(const c
6040: 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e har *zFormat, ..
6050: 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 .){. va_list ap
6060: 3b 0a 20 20 69 66 28 20 67 2e 66 44 65 62 75 67 ;. if( g.fDebug
6070: 20 29 7b 0a 20 20 20 20 76 61 5f 73 74 61 72 74 ){. va_start
6080: 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b 0a 20 (ap, zFormat);.
6090: 20 20 20 76 66 70 72 69 6e 74 66 28 67 2e 66 44 vfprintf(g.fD
60a0: 65 62 75 67 2c 20 7a 46 6f 72 6d 61 74 2c 20 61 ebug, zFormat, a
60b0: 70 29 3b 0a 20 20 20 20 76 61 5f 65 6e 64 28 61 p);. va_end(a
60c0: 70 29 3b 0a 20 20 20 20 66 66 6c 75 73 68 28 67 p);. fflush(g
60d0: 2e 66 44 65 62 75 67 29 3b 0a 20 20 7d 0a 7d 0a .fDebug);. }.}.
60e0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 72 ./*.** Return tr
60f0: 75 65 20 69 66 20 61 6e 79 20 6f 66 20 74 68 65 ue if any of the
6100: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 query parameter
6110: 73 20 69 6e 20 74 68 65 20 61 72 67 75 6d 65 6e s in the argumen
6120: 74 0a 2a 2a 20 6c 69 73 74 20 61 72 65 20 64 65 t.** list are de
6130: 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20 63 67 fined..*/.int cg
6140: 69 5f 61 6e 79 28 63 6f 6e 73 74 20 63 68 61 72 i_any(const char
6150: 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f *z, ...){. va_
6160: 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72 20 list ap;. char
6170: 2a 7a 32 3b 0a 20 20 69 66 28 20 63 67 69 5f 70 *z2;. if( cgi_p
6180: 61 72 61 6d 65 74 65 72 28 7a 2c 30 29 21 3d 30 arameter(z,0)!=0
6190: 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 76 ) return 1;. v
61a0: 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 29 3b 0a a_start(ap, z);.
61b0: 20 20 77 68 69 6c 65 28 20 28 7a 32 20 3d 20 76 while( (z2 = v
61c0: 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 2a 29 a_arg(ap, char*)
61d0: 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 )!=0 ){. if(
61e0: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 32 cgi_parameter(z2
61f0: 2c 30 29 21 3d 30 20 29 20 72 65 74 75 72 6e 20 ,0)!=0 ) return
6200: 31 3b 0a 20 20 7d 0a 20 20 76 61 5f 65 6e 64 28 1;. }. va_end(
6210: 61 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 30 3b ap);. return 0;
6220: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e .}../*.** Return
6230: 20 74 72 75 65 20 69 66 20 61 6c 6c 20 6f 66 20 true if all of
6240: 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 the query parame
6250: 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 67 75 ters in the argu
6260: 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a 20 61 72 65 ment list.** are
6270: 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 defined..*/.int
6280: 20 63 67 69 5f 61 6c 6c 28 63 6f 6e 73 74 20 63 cgi_all(const c
6290: 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 har *z, ...){.
62a0: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 va_list ap;. ch
62b0: 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 67 ar *z2;. if( cg
62c0: 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 29 i_parameter(z,0)
62d0: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a ==0 ) return 0;.
62e0: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a va_start(ap, z
62f0: 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 20 );. while( (z2
6300: 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 = va_arg(ap, cha
6310: 72 2a 29 29 3d 3d 30 20 29 7b 0a 20 20 20 20 69 r*))==0 ){. i
6320: 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 f( cgi_parameter
6330: 28 7a 32 2c 30 29 3d 3d 30 20 29 20 72 65 74 75 (z2,0)==0 ) retu
6340: 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 76 61 5f 65 rn 0;. }. va_e
6350: 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72 6e nd(ap);. return
6360: 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 1;.}../*.** Pri
6370: 6e 74 20 61 6c 6c 20 71 75 65 72 79 20 70 61 72 nt all query par
6380: 61 6d 65 74 65 72 73 20 6f 6e 20 73 74 61 6e 64 ameters on stand
6390: 61 72 64 20 6f 75 74 70 75 74 2e 20 20 46 6f 72 ard output. For
63a0: 6d 61 74 20 74 68 65 0a 2a 2a 20 70 61 72 61 6d mat the.** param
63b0: 65 74 65 72 73 20 61 73 20 48 54 4d 4c 2e 20 20 eters as HTML.
63c0: 54 68 69 73 20 69 73 20 75 73 65 64 20 66 6f 72 This is used for
63d0: 20 74 65 73 74 69 6e 67 20 61 6e 64 20 64 65 62 testing and deb
63e0: 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 ugging..*/.void
63f0: 63 67 69 5f 70 72 69 6e 74 5f 61 6c 6c 28 76 6f cgi_print_all(vo
6400: 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 id){. int i;.
6410: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 22 22 cgi_parameter(""
6420: 2c 22 22 29 3b 20 20 2f 2a 20 46 6f 72 63 65 20 ,""); /* Force
6430: 74 68 65 20 70 61 72 61 6d 65 74 65 72 73 20 69 the parameters i
6440: 6e 74 6f 20 73 6f 72 74 65 64 20 6f 72 64 65 72 nto sorted order
6450: 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 */. for(i=0; i
6460: 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b 0a <nUsedQP; i++){.
6470: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 cgi_printf("
6480: 25 73 20 3d 20 25 73 20 20 3c 62 72 20 2f 3e 5c %s = %s <br />\
6490: 6e 22 2c 0a 20 20 20 20 20 20 20 68 74 6d 6c 69 n",. htmli
64a0: 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a ze(aParamQP[i].z
64b0: 4e 61 6d 65 2c 20 2d 31 29 2c 20 68 74 6d 6c 69 Name, -1), htmli
64c0: 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a ze(aParamQP[i].z
64d0: 56 61 6c 75 65 2c 20 2d 31 29 29 3b 0a 20 20 7d Value, -1));. }
64e0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 65 20 .}../*.** Write
64f0: 48 54 4d 4c 20 74 65 78 74 20 66 6f 72 20 61 6e HTML text for an
6500: 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 74 6f 20 option menu to
6510: 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e standard output.
6520: 20 20 7a 50 61 72 61 6d 0a 2a 2a 20 69 73 20 74 zParam.** is t
6530: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 he query paramet
6540: 65 72 20 74 68 61 74 20 74 68 65 20 6f 70 74 69 er that the opti
6550: 6f 6e 20 6d 65 6e 75 20 73 65 74 73 2e 20 20 7a on menu sets. z
6560: 44 66 6c 74 20 69 73 20 74 68 65 0a 2a 2a 20 69 Dflt is the.** i
6570: 6e 69 74 69 61 6c 20 76 61 6c 75 65 20 6f 66 20 nitial value of
6580: 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 2e the option menu.
6590: 20 20 41 64 64 69 74 69 6f 6e 20 61 72 67 75 6d Addition argum
65a0: 65 6e 74 73 20 61 72 65 20 6e 61 6d 65 2f 76 61 ents are name/va
65b0: 6c 75 65 0a 2a 2a 20 70 61 69 72 73 20 74 68 61 lue.** pairs tha
65c0: 74 20 64 65 66 69 6e 65 20 76 61 6c 75 65 73 20 t define values
65d0: 6f 6e 20 74 68 65 20 6d 65 6e 75 2e 20 20 54 68 on the menu. Th
65e0: 65 20 6c 69 73 74 20 69 73 20 74 65 72 6d 69 6e e list is termin
65f0: 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 61 20 73 ated with.** a s
6600: 69 6e 67 6c 65 20 4e 55 4c 4c 20 61 72 67 75 6d ingle NULL argum
6610: 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 ent..*/.void cgi
6620: 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 69 6e 74 20 _optionmenu(int
6630: 69 6e 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a in, const char *
6640: 7a 50 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a zP, const char *
6650: 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c zD, ...){. va_l
6660: 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72 20 2a ist ap;. char *
6670: 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c 3b 0a 20 20 zName, *zVal;.
6680: 69 6e 74 20 64 66 6c 74 53 65 65 6e 20 3d 20 30 int dfltSeen = 0
6690: 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 ;. cgi_printf("
66a0: 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 3d %*s<select size=
66b0: 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 1 name=\"%s\">\n
66c0: 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a ", in, "", zP);.
66d0: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a va_start(ap, z
66e0: 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4e D);. while( (zN
66f0: 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70 2c ame = va_arg(ap,
6700: 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20 28 char*))!=0 && (
6710: 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 zVal = va_arg(ap
6720: 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a , char*))!=0 ){.
6730: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a if( strcmp(z
6740: 56 61 6c 2c 7a 44 29 3d 3d 30 20 29 7b 20 64 66 Val,zD)==0 ){ df
6750: 6c 74 53 65 65 6e 20 3d 20 31 3b 20 62 72 65 61 ltSeen = 1; brea
6760: 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76 61 5f 65 6e k; }. }. va_en
6770: 64 28 61 70 29 3b 0a 20 20 69 66 28 20 21 64 66 d(ap);. if( !df
6780: 6c 74 53 65 65 6e 20 29 7b 0a 20 20 20 20 69 66 ltSeen ){. if
6790: 28 20 7a 44 5b 30 5d 20 29 7b 0a 20 20 20 20 20 ( zD[0] ){.
67a0: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 cgi_printf("%*s
67b0: 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 <option value=\"
67c0: 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 68 %h\" selected>%h
67d0: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 </option>\n",.
67e0: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 in+2, "",
67f0: 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 65 6c zD, zD);. }el
6800: 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 se{. cgi_pr
6810: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e intf("%*s<option
6820: 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 value=\"\" sele
6830: 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 cted> </opt
6840: 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b 32 2c 20 22 ion>\n", in+2, "
6850: 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 ");. }. }.
6860: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 44 29 va_start(ap, zD)
6870: 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4e 61 6d ;. while( (zNam
6880: 65 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 e = va_arg(ap, c
6890: 68 61 72 2a 29 29 21 3d 30 20 26 26 20 28 7a 56 har*))!=0 && (zV
68a0: 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 al = va_arg(ap,
68b0: 63 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 char*))!=0 ){.
68c0: 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d 20 29 if( zName[0] )
68d0: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e {. cgi_prin
68e0: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 tf("%*s<option v
68f0: 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 25 68 alue=\"%h\"%s>%h
6900: 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 </option>\n",.
6910: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a in+2, "",.
6920: 20 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 zVal,.
6930: 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 strcmp(zVa
6940: 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 l, zD) ? "" : "
6950: 73 65 6c 65 63 74 65 64 22 2c 0a 20 20 20 20 20 selected",.
6960: 20 20 20 7a 4e 61 6d 65 0a 20 20 20 20 20 20 29 zName. )
6970: 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 ;. }else{.
6980: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 cgi_printf("%
6990: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d *s<option value=
69a0: 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f \"\"%s> </o
69b0: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 ption>\n",.
69c0: 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 in+2, "",.
69d0: 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c strcmp(zVal
69e0: 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 , zD) ? "" : " s
69f0: 65 6c 65 63 74 65 64 22 0a 20 20 20 20 20 20 29 elected". )
6a00: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 76 61 ;. }. }. va
6a10: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63 67 69 5f _end(ap);. cgi_
6a20: 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c printf("%*s</sel
6a30: 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 ect>\n", in, "")
6a40: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 ;.}../*.** This
6a50: 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 61 20 routine works a
6a60: 6c 6f 74 20 6c 69 6b 65 20 63 67 69 5f 6f 70 74 lot like cgi_opt
6a70: 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 74 ionmenu() except
6a80: 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 20 6f that the list o
6a90: 66 0a 2a 2a 20 76 61 6c 75 65 73 20 69 73 20 63 f.** values is c
6aa0: 6f 6e 74 61 69 6e 65 64 20 69 6e 20 61 6e 20 61 ontained in an a
6ab0: 72 72 61 79 2e 20 20 41 6c 73 6f 2c 20 74 68 65 rray. Also, the
6ac0: 20 76 61 6c 75 65 73 20 61 72 65 20 6a 75 73 74 values are just
6ad0: 20 76 61 6c 75 65 73 2c 20 6e 6f 74 0a 2a 2a 20 values, not.**
6ae0: 6e 61 6d 65 2f 76 61 6c 75 65 20 70 61 69 72 73 name/value pairs
6af0: 20 61 73 20 69 6e 20 63 67 69 5f 6f 70 74 69 6f as in cgi_optio
6b00: 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f 69 64 20 63 nmenu..*/.void c
6b10: 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 gi_v_optionmenu(
6b20: 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20 20 20 20 . int in,
6b30: 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 65 6e /* Inden
6b40: 74 20 62 79 20 74 68 69 73 20 61 6d 6f 75 6e 74 t by this amount
6b50: 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 */. const char
6b60: 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a 20 54 68 *zP, /* Th
6b70: 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 e query paramete
6b80: 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f 6e 73 r name */. cons
6b90: 74 20 63 68 61 72 20 2a 7a 44 2c 20 20 20 20 20 t char *zD,
6ba0: 20 2f 2a 20 44 65 66 61 75 6c 74 20 76 61 6c 75 /* Default valu
6bb0: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 e */. const cha
6bc0: 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f 2a 20 4e r **az /* N
6bd0: 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 64 20 6c ULL-terminated l
6be0: 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65 64 20 76 ist of allowed v
6bf0: 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 20 63 6f alues */.){. co
6c00: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 3b 0a nst char *zVal;.
6c10: 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69 5f 70 int i;. cgi_p
6c20: 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c 65 63 rintf("%*s<selec
6c30: 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 t size=1 name=\"
6c40: 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 %s\">\n", in, ""
6c50: 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28 69 3d 30 , zP);. for(i=0
6c60: 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b 29 7b 0a 20 ; az[i]; i++){.
6c70: 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 61 7a if( strcmp(az
6c80: 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20 62 72 65 [i],zD)==0 ) bre
6c90: 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 61 7a ak;. }. if( az
6ca0: 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 [i]==0 ){. if
6cb0: 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 ( zD[0]==0 ){.
6cc0: 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 cgi_printf("
6cd0: 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 %*s<option value
6ce0: 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64 3e 26 =\"\" selected>&
6cf0: 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e nbsp;</option>\n
6d00: 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 ",. in+2,
6d10: 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a "");. }else{.
6d20: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 cgi_printf
6d30: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c ("%*s<option val
6d40: 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 ue=\"%h\" select
6d50: 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e ed>%h</option>\n
6d60: 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 ",. in+2,
6d70: 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 "", zD, zD);.
6d80: 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 }. }. while(
6d90: 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b 2b 29 29 (zVal = *(az++))
6da0: 21 3d 30 20 20 29 7b 0a 20 20 20 20 69 66 28 20 !=0 ){. if(
6db0: 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20 20 20 20 20 zVal[0] ){.
6dc0: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 cgi_printf("%*s
6dd0: 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 <option value=\"
6de0: 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69 6f %h\"%s>%h</optio
6df0: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 n>\n",. i
6e00: 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 n+2, "",.
6e10: 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 zVal,. s
6e20: 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 trcmp(zVal, zD)
6e30: 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 ? "" : " selecte
6e40: 64 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c d",. zVal
6e50: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 . );. }e
6e60: 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 lse{. cgi_p
6e70: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f rintf("%*s<optio
6e80: 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25 73 3e 26 n value=\"\"%s>&
6e90: 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e nbsp;</option>\n
6ea0: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c ",. in+2,
6eb0: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 73 74 72 "",. str
6ec0: 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 cmp(zVal, zD) ?
6ed0: 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 "" : " selected"
6ee0: 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a . );. }.
6ef0: 20 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 }. cgi_printf
6f00: 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e ("%*s</select>\n
6f10: 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f ", in, "");.}../
6f20: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e *.** This routin
6f30: 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74 20 6c 69 e works a lot li
6f40: 6b 65 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d ke cgi_v_optionm
6f50: 65 6e 75 28 29 20 65 78 63 65 70 74 20 74 68 61 enu() except tha
6f60: 74 20 74 68 65 20 6c 69 73 74 0a 2a 2a 20 69 73 t the list.** is
6f70: 20 61 20 6c 69 73 74 20 6f 66 20 70 61 69 72 73 a list of pairs
6f80: 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 6c 65 . The first ele
6f90: 6d 65 6e 74 20 6f 66 20 65 61 63 68 20 70 61 69 ment of each pai
6fa0: 72 20 69 73 20 74 68 65 20 76 61 6c 75 65 20 75 r is the value u
6fb0: 73 65 64 0a 2a 2a 20 69 6e 74 65 72 6e 61 6c 6c sed.** internall
6fc0: 79 20 61 6e 64 20 74 68 65 20 73 65 63 6f 6e 64 y and the second
6fd0: 20 65 6c 65 6d 65 6e 74 20 69 73 20 74 68 65 20 element is the
6fe0: 76 61 6c 75 65 20 64 69 73 70 6c 61 79 65 64 20 value displayed
6ff0: 74 6f 20 74 68 65 20 75 73 65 72 2e 0a 2a 2f 0a to the user..*/.
7000: 76 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74 69 6f void cgi_v_optio
7010: 6e 6d 65 6e 75 32 28 0a 20 20 69 6e 74 20 69 6e nmenu2(. int in
7020: 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f , /
7030: 2a 20 49 6e 64 65 6e 74 20 62 79 20 74 68 69 73 * Indent by this
7040: 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f 6e amount */. con
7050: 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 20 20 20 st char *zP,
7060: 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79 20 70 /* The query p
7070: 61 72 61 6d 65 74 65 72 20 6e 61 6d 65 20 2a 2f arameter name */
7080: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a . const char *z
7090: 44 2c 20 20 20 20 20 20 2f 2a 20 44 65 66 61 75 D, /* Defau
70a0: 6c 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20 63 6f lt value */. co
70b0: 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 20 20 20 nst char **az
70c0: 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d 69 /* NULL-termi
70d0: 6e 61 74 65 64 20 6c 69 73 74 20 6f 66 20 61 6c nated list of al
70e0: 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 2a 2f 0a lowed values */.
70f0: 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 ){. const char
7100: 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a *zVal;. int i;.
7110: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
7120: 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 3d 31 20 s<select size=1
7130: 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c name=\"%s\">\n",
7140: 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 20 in, "", zP);.
7150: 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 for(i=0; az[i];
7160: 69 2b 3d 32 29 7b 0a 20 20 20 20 69 66 28 20 73 i+=2){. if( s
7170: 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a 44 29 3d trcmp(az[i],zD)=
7180: 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 7d 0a =0 ) break;. }.
7190: 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d 30 20 29 if( az[i]==0 )
71a0: 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b 30 5d 3d {. if( zD[0]=
71b0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f =0 ){. cgi_
71c0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 printf("%*s<opti
71d0: 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65 on value=\"\" se
71e0: 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f lected> </o
71f0: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 ption>\n",.
7200: 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20 20 20 in+2, "");.
7210: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 }else{. cg
7220: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 i_printf("%*s<op
7230: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c tion value=\"%h\
7240: 22 20 73 65 6c 65 63 74 65 64 3e 25 68 3c 2f 6f " selected>%h</o
7250: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 ption>\n",.
7260: 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 in+2, "", zD,
7270: 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 zD);. }. }.
7280: 20 77 68 69 6c 65 28 20 28 7a 56 61 6c 20 3d 20 while( (zVal =
7290: 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20 29 7b 0a *(az++))!=0 ){.
72a0: 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a const char *
72b0: 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a 2b 2b 29 3b zName = *(az++);
72c0: 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30 . if( zName[0
72d0: 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 ] ){. cgi_p
72e0: 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f rintf("%*s<optio
72f0: 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 n value=\"%h\"%s
7300: 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c >%h</option>\n",
7310: 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 . in+2, "
7320: 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c ",. zVal,
7330: 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 . strcmp(
7340: 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a zVal, zD) ? "" :
7350: 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 20 " selected",.
7360: 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 20 zName.
7370: 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a );. }else{.
7380: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 cgi_printf
7390: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c ("%*s<option val
73a0: 75 65 3d 5c 22 25 68 5c 22 25 73 3e 26 6e 62 73 ue=\"%h\"%s>&nbs
73b0: 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a p;</option>\n",.
73c0: 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 in+2, ""
73d0: 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a ,. zVal,.
73e0: 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a strcmp(z
73f0: 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 Val, zD) ? "" :
7400: 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 20 " selected".
7410: 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 );. }. }.
7420: 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 cgi_printf("%*s
7430: 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e </select>\n", in
7440: 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 , "");.}../*.**
7450: 54 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 This routine wor
7460: 6b 73 20 6c 69 6b 65 20 22 70 72 69 6e 74 66 22 ks like "printf"
7470: 20 65 78 63 65 70 74 20 74 68 61 74 20 69 74 20 except that it
7480: 68 61 73 20 74 68 65 0a 2a 2a 20 65 78 74 72 61 has the.** extra
7490: 20 66 6f 72 6d 61 74 74 69 6e 67 20 63 61 70 61 formatting capa
74a0: 62 69 6c 69 74 69 65 73 20 73 75 63 68 20 61 73 bilities such as
74b0: 20 25 68 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 %h and %t..*/.v
74c0: 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 66 28 63 oid cgi_printf(c
74d0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d onst char *zForm
74e0: 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c at, ...){. va_l
74f0: 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 ist ap;. va_sta
7500: 72 74 28 61 70 2c 7a 46 6f 72 6d 61 74 29 3b 0a rt(ap,zFormat);.
7510: 20 20 76 78 70 72 69 6e 74 66 28 70 43 6f 6e 74 vxprintf(pCont
7520: 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b ent,zFormat,ap);
7530: 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 7d . va_end(ap);.}
7540: 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 ../*.** This rou
7550: 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69 6b 65 20 tine works like
7560: 22 76 70 72 69 6e 74 66 22 20 65 78 63 65 70 74 "vprintf" except
7570: 20 74 68 61 74 20 69 74 20 68 61 73 20 74 68 65 that it has the
7580: 0a 2a 2a 20 65 78 74 72 61 20 66 6f 72 6d 61 74 .** extra format
7590: 74 69 6e 67 20 63 61 70 61 62 69 6c 69 74 69 65 ting capabilitie
75a0: 73 20 73 75 63 68 20 61 73 20 25 68 20 61 6e 64 s such as %h and
75b0: 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 %t..*/.void cgi
75c0: 5f 76 70 72 69 6e 74 66 28 63 6f 6e 73 74 20 63 _vprintf(const c
75d0: 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 76 61 har *zFormat, va
75e0: 5f 6c 69 73 74 20 61 70 29 7b 0a 20 20 76 78 70 _list ap){. vxp
75f0: 72 69 6e 74 66 28 70 43 6f 6e 74 65 6e 74 2c 7a rintf(pContent,z
7600: 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 7d 0a 0a 0a Format,ap);.}...
7610: 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20 72 65 70 /*.** Send a rep
7620: 6c 79 20 69 6e 64 69 63 61 74 69 6e 67 20 74 68 ly indicating th
7630: 61 74 20 74 68 65 20 48 54 54 50 20 72 65 71 75 at the HTTP requ
7640: 65 73 74 20 77 61 73 20 6d 61 6c 66 6f 72 6d 65 est was malforme
7650: 64 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 d.*/.static void
7660: 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 malformed_reque
7670: 73 74 28 76 6f 69 64 29 7b 0a 20 20 63 67 69 5f st(void){. cgi_
7680: 73 65 74 5f 73 74 61 74 75 73 28 35 30 31 2c 20 set_status(501,
7690: 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e 74 65 64 "Not Implemented
76a0: 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 ");. cgi_printf
76b0: 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 6f (. "<html><bo
76c0: 64 79 3e 55 6e 72 65 63 6f 67 6e 69 7a 65 64 20 dy>Unrecognized
76d0: 48 54 54 50 20 52 65 71 75 65 73 74 3c 2f 62 6f HTTP Request</bo
76e0: 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e 22 0a 20 20 dy></html>\n".
76f0: 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 );. cgi_reply()
7700: 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a 0a ;. exit(0);.}..
7710: 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 61 6e 64 20 /*.** Panic and
7720: 64 69 65 20 77 68 69 6c 65 20 70 72 6f 63 65 73 die while proces
7730: 73 69 6e 67 20 61 20 77 65 62 70 61 67 65 2e 0a sing a webpage..
7740: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 61 6e 69 */.void cgi_pani
7750: 63 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 c(const char *zF
7760: 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 ormat, ...){. v
7770: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 67 69 a_list ap;. cgi
7780: 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 _reset_content()
7790: 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74 ;. cgi_set_stat
77a0: 75 73 28 35 30 30 2c 20 22 49 6e 74 65 72 6e 61 us(500, "Interna
77b0: 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72 22 29 l Server Error")
77c0: 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 0a ;. cgi_printf(.
77d0: 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 6f 64 79 "<html><body
77e0: 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 6c 20 53 65 ><h1>Internal Se
77f0: 72 76 65 72 20 45 72 72 6f 72 3c 2f 68 31 3e 5c rver Error</h1>\
7800: 6e 22 0a 20 20 20 20 22 3c 70 6c 61 69 6e 74 65 n". "<plainte
7810: 78 74 3e 22 0a 20 20 29 3b 0a 20 20 76 61 5f 73 xt>". );. va_s
7820: 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 tart(ap, zFormat
7830: 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 70 43 );. vxprintf(pC
7840: 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 ontent,zFormat,a
7850: 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 p);. va_end(ap)
7860: 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 3b ;. cgi_reply();
7870: 0a 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a 0a 2f . exit(1);.}../
7880: 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 *.** Remove the
7890: 66 69 72 73 74 20 73 70 61 63 65 2d 64 65 6c 69 first space-deli
78a0: 6d 69 74 65 64 20 74 6f 6b 65 6e 20 66 72 6f 6d mited token from
78b0: 20 61 20 73 74 72 69 6e 67 20 61 6e 64 20 72 65 a string and re
78c0: 74 75 72 6e 0a 2a 2a 20 61 20 70 6f 69 6e 74 65 turn.** a pointe
78d0: 72 20 74 6f 20 69 74 2e 20 20 41 64 64 20 61 20 r to it. Add a
78e0: 4e 55 4c 4c 20 74 6f 20 74 68 65 20 73 74 72 69 NULL to the stri
78f0: 6e 67 20 74 6f 20 74 65 72 6d 69 6e 61 74 65 20 ng to terminate
7900: 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 4d 61 the token..** Ma
7910: 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 72 20 70 6f ke *zLeftOver po
7920: 69 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72 74 int to the start
7930: 20 6f 66 20 74 68 65 20 6e 65 78 74 20 74 6f 6b of the next tok
7940: 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 en..*/.static ch
7950: 61 72 20 2a 65 78 74 72 61 63 74 5f 74 6f 6b 65 ar *extract_toke
7960: 6e 28 63 68 61 72 20 2a 7a 49 6e 70 75 74 2c 20 n(char *zInput,
7970: 63 68 61 72 20 2a 2a 7a 4c 65 66 74 4f 76 65 72 char **zLeftOver
7980: 29 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65 73 75 ){. char *zResu
7990: 6c 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 7a 49 lt = 0;. if( zI
79a0: 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20 20 69 nput==0 ){. i
79b0: 66 28 20 7a 4c 65 66 74 4f 76 65 72 20 29 20 2a f( zLeftOver ) *
79c0: 7a 4c 65 66 74 4f 76 65 72 20 3d 20 30 3b 0a 20 zLeftOver = 0;.
79d0: 20 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d return 0;. }
79e0: 0a 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 . while( isspac
79f0: 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a 49 e(*zInput) ){ zI
7a00: 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a 52 65 73 nput++; }. zRes
7a10: 75 6c 74 20 3d 20 7a 49 6e 70 75 74 3b 0a 20 20 ult = zInput;.
7a20: 77 68 69 6c 65 28 20 2a 7a 49 6e 70 75 74 20 26 while( *zInput &
7a30: 26 20 21 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 & !isspace(*zInp
7a40: 75 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b ut) ){ zInput++;
7a50: 20 7d 0a 20 20 69 66 28 20 2a 7a 49 6e 70 75 74 }. if( *zInput
7a60: 20 29 7b 0a 20 20 20 20 2a 7a 49 6e 70 75 74 20 ){. *zInput
7a70: 3d 20 30 3b 0a 20 20 20 20 7a 49 6e 70 75 74 2b = 0;. zInput+
7a80: 2b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 +;. while( is
7a90: 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 space(*zInput) )
7aa0: 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 { zInput++; }.
7ab0: 7d 0a 20 20 69 66 28 20 7a 4c 65 66 74 4f 76 65 }. if( zLeftOve
7ac0: 72 20 29 7b 20 2a 7a 4c 65 66 74 4f 76 65 72 20 r ){ *zLeftOver
7ad0: 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a 20 20 72 65 = zInput; }. re
7ae0: 74 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a 7d 0a turn zResult;.}.
7af0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 ./*.** This rout
7b00: 69 6e 65 20 68 61 6e 64 6c 65 73 20 61 20 73 69 ine handles a si
7b10: 6e 67 6c 65 20 48 54 54 50 20 72 65 71 75 65 73 ngle HTTP reques
7b20: 74 20 77 68 69 63 68 20 69 73 20 63 6f 6d 69 6e t which is comin
7b30: 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74 61 6e 64 g in on.** stand
7b40: 61 72 64 20 69 6e 70 75 74 20 61 6e 64 20 77 68 ard input and wh
7b50: 69 63 68 20 72 65 70 6c 69 65 73 20 6f 6e 20 73 ich replies on s
7b60: 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 0a tandard output..
7b70: 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 54 50 20 72 **.** The HTTP r
7b80: 65 71 75 65 73 74 20 69 73 20 72 65 61 64 20 66 equest is read f
7b90: 72 6f 6d 20 73 74 61 6e 64 61 72 64 20 69 6e 70 rom standard inp
7ba0: 75 74 20 61 6e 64 20 69 73 20 75 73 65 64 20 74 ut and is used t
7bb0: 6f 20 69 6e 69 74 69 61 6c 69 7a 65 0a 2a 2a 20 o initialize.**
7bc0: 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 environment vari
7bd0: 61 62 6c 65 73 20 61 73 20 70 65 72 20 43 47 49 ables as per CGI
7be0: 2e 20 20 54 68 65 20 63 67 69 5f 69 6e 69 74 28 . The cgi_init(
7bf0: 29 20 72 6f 75 74 69 6e 65 20 74 6f 20 63 6f 6d ) routine to com
7c00: 70 6c 65 74 65 0a 2a 2a 20 74 68 65 20 73 65 74 plete.** the set
7c10: 75 70 2e 20 20 4f 6e 63 65 20 61 6c 6c 20 74 68 up. Once all th
7c20: 65 20 73 65 74 75 70 20 69 73 20 66 69 6e 69 73 e setup is finis
7c30: 68 65 64 2c 20 74 68 69 73 20 70 72 6f 63 65 64 hed, this proced
7c40: 75 72 65 20 72 65 74 75 72 6e 73 0a 2a 2a 20 61 ure returns.** a
7c50: 6e 64 20 73 75 62 73 65 71 75 65 6e 74 20 63 6f nd subsequent co
7c60: 64 65 20 68 61 6e 64 6c 65 73 20 74 68 65 20 61 de handles the a
7c70: 63 74 75 61 6c 20 67 65 6e 65 72 61 74 69 6f 6e ctual generation
7c80: 20 6f 66 20 74 68 65 20 77 65 62 70 61 67 65 2e of the webpage.
7c90: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 61 6e .*/.void cgi_han
7ca0: 64 6c 65 5f 68 74 74 70 5f 72 65 71 75 65 73 74 dle_http_request
7cb0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 70 (const char *zIp
7cc0: 41 64 64 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a Addr){. char *z
7cd0: 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 20 69 6e 74 , *zToken;. int
7ce0: 20 69 3b 0a 20 20 73 74 72 75 63 74 20 73 6f 63 i;. struct soc
7cf0: 6b 61 64 64 72 5f 69 6e 20 72 65 6d 6f 74 65 4e kaddr_in remoteN
7d00: 61 6d 65 3b 0a 20 20 73 69 7a 65 5f 74 20 73 69 ame;. size_t si
7d10: 7a 65 20 3d 20 73 69 7a 65 6f 66 28 73 74 72 75 ze = sizeof(stru
7d20: 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 29 3b ct sockaddr_in);
7d30: 0a 20 20 63 68 61 72 20 7a 4c 69 6e 65 5b 32 30 . char zLine[20
7d40: 30 30 5d 3b 20 20 20 20 20 2f 2a 20 41 20 73 69 00]; /* A si
7d50: 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 69 6e 70 ngle line of inp
7d60: 75 74 2e 20 2a 2f 0a 0a 20 20 67 2e 66 75 6c 6c ut. */.. g.full
7d70: 48 74 74 70 52 65 70 6c 79 20 3d 20 31 3b 0a 20 HttpReply = 1;.
7d80: 20 69 66 28 20 66 67 65 74 73 28 7a 4c 69 6e 65 if( fgets(zLine
7d90: 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c , sizeof(zLine),
7da0: 67 2e 68 74 74 70 49 6e 29 3d 3d 30 20 29 7b 0a g.httpIn)==0 ){.
7db0: 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 malformed_re
7dc0: 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 7a quest();. }. z
7dd0: 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 5f Token = extract_
7de0: 74 6f 6b 65 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29 token(zLine, &z)
7df0: 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d ;. if( zToken==
7e00: 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 0 ){. malform
7e10: 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 ed_request();.
7e20: 7d 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a }. if( strcmp(z
7e30: 54 6f 6b 65 6e 2c 22 47 45 54 22 29 21 3d 30 20 Token,"GET")!=0
7e40: 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e && strcmp(zToken
7e50: 2c 22 50 4f 53 54 22 29 21 3d 30 0a 20 20 20 20 ,"POST")!=0.
7e60: 20 20 26 26 20 73 74 72 63 6d 70 28 7a 54 6f 6b && strcmp(zTok
7e70: 65 6e 2c 22 48 45 41 44 22 29 21 3d 30 20 29 7b en,"HEAD")!=0 ){
7e80: 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 . malformed_r
7e90: 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 equest();. }.
7ea0: 63 67 69 5f 73 65 74 65 6e 76 28 22 47 41 54 45 cgi_setenv("GATE
7eb0: 57 41 59 5f 49 4e 54 45 52 46 41 43 45 22 2c 22 WAY_INTERFACE","
7ec0: 43 47 49 2f 31 2e 30 22 29 3b 0a 20 20 63 67 69 CGI/1.0");. cgi
7ed0: 5f 73 65 74 65 6e 76 28 22 52 45 51 55 45 53 54 _setenv("REQUEST
7ee0: 5f 4d 45 54 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29 _METHOD",zToken)
7ef0: 3b 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 ;. zToken = ext
7f00: 72 61 63 74 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a ract_token(z, &z
7f10: 29 3b 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 3d );. if( zToken=
7f20: 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 =0 ){. malfor
7f30: 6d 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 med_request();.
7f40: 20 7d 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 }. cgi_setenv(
7f50: 22 52 45 51 55 45 53 54 5f 55 52 49 22 2c 20 7a "REQUEST_URI", z
7f60: 54 6f 6b 65 6e 29 3b 0a 20 20 66 6f 72 28 69 3d Token);. for(i=
7f70: 30 3b 20 7a 54 6f 6b 65 6e 5b 69 5d 20 26 26 20 0; zToken[i] &&
7f80: 7a 54 6f 6b 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20 zToken[i]!='?';
7f90: 69 2b 2b 29 7b 7d 0a 20 20 69 66 28 20 7a 54 6f i++){}. if( zTo
7fa0: 6b 65 6e 5b 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b ken[i] ) zToken[
7fb0: 69 2b 2b 5d 20 3d 20 30 3b 0a 20 20 63 67 69 5f i++] = 0;. cgi_
7fc0: 73 65 74 65 6e 76 28 22 50 41 54 48 5f 49 4e 46 setenv("PATH_INF
7fd0: 4f 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63 O", zToken);. c
7fe0: 67 69 5f 73 65 74 65 6e 76 28 22 51 55 45 52 59 gi_setenv("QUERY
7ff0: 5f 53 54 52 49 4e 47 22 2c 20 26 7a 54 6f 6b 65 _STRING", &zToke
8000: 6e 5b 69 5d 29 3b 0a 20 20 69 66 28 20 7a 49 70 n[i]);. if( zIp
8010: 41 64 64 72 3d 3d 30 20 26 26 0a 20 20 20 20 20 Addr==0 &&.
8020: 20 20 20 67 65 74 70 65 65 72 6e 61 6d 65 28 66 getpeername(f
8030: 69 6c 65 6e 6f 28 67 2e 68 74 74 70 49 6e 29 2c ileno(g.httpIn),
8040: 20 28 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 (struct sockadd
8050: 72 2a 29 26 72 65 6d 6f 74 65 4e 61 6d 65 2c 20 r*)&remoteName,
8060: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
8070: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8080: 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 26 73 69 (socklen_t*)&si
8090: 7a 65 29 3e 3d 30 0a 20 20 29 7b 0a 20 20 20 20 ze)>=0. ){.
80a0: 7a 49 70 41 64 64 72 20 3d 20 69 6e 65 74 5f 6e zIpAddr = inet_n
80b0: 74 6f 61 28 72 65 6d 6f 74 65 4e 61 6d 65 2e 73 toa(remoteName.s
80c0: 69 6e 5f 61 64 64 72 29 3b 0a 20 20 7d 0a 20 20 in_addr);. }.
80d0: 69 66 28 20 7a 49 70 41 64 64 72 20 29 7b 20 20 if( zIpAddr ){
80e0: 20 0a 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 . cgi_setenv
80f0: 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 22 2c 20 ("REMOTE_ADDR",
8100: 7a 49 70 41 64 64 72 29 3b 0a 20 20 20 20 67 2e zIpAddr);. g.
8110: 7a 49 70 41 64 64 72 20 3d 20 6d 70 72 69 6e 74 zIpAddr = mprint
8120: 66 28 22 25 73 22 2c 20 7a 49 70 41 64 64 72 29 f("%s", zIpAddr)
8130: 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a 20 47 65 74 ;. }. . /* Get
8140: 20 61 6c 6c 20 74 68 65 20 6f 70 74 69 6f 6e 61 all the optiona
8150: 6c 20 66 69 65 6c 64 73 20 74 68 61 74 20 66 6f l fields that fo
8160: 6c 6c 6f 77 20 74 68 65 20 66 69 72 73 74 20 6c llow the first l
8170: 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20 77 68 69 6c ine.. */. whil
8180: 65 28 20 66 67 65 74 73 28 7a 4c 69 6e 65 2c 73 e( fgets(zLine,s
8190: 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c 67 2e 68 izeof(zLine),g.h
81a0: 74 74 70 49 6e 29 20 29 7b 0a 20 20 20 20 63 68 ttpIn) ){. ch
81b0: 61 72 20 2a 7a 46 69 65 6c 64 4e 61 6d 65 3b 0a ar *zFieldName;.
81c0: 20 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 3b 0a char *zVal;.
81d0: 0a 20 20 20 20 7a 46 69 65 6c 64 4e 61 6d 65 20 . zFieldName
81e0: 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28 = extract_token(
81f0: 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b 0a 20 20 zLine,&zVal);.
8200: 20 20 69 66 28 20 7a 46 69 65 6c 64 4e 61 6d 65 if( zFieldName
8210: 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c 64 4e 61 ==0 || *zFieldNa
8220: 6d 65 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 me==0 ) break;.
8230: 20 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 while( isspac
8240: 65 28 2a 7a 56 61 6c 29 20 29 7b 20 7a 56 61 6c e(*zVal) ){ zVal
8250: 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 3d 20 73 74 ++; }. i = st
8260: 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20 20 20 20 rlen(zVal);.
8270: 77 68 69 6c 65 28 20 69 3e 30 20 26 26 20 69 73 while( i>0 && is
8280: 73 70 61 63 65 28 7a 56 61 6c 5b 69 2d 31 5d 29 space(zVal[i-1])
8290: 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20 20 20 7a ){ i--; }. z
82a0: 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 Val[i] = 0;.
82b0: 66 6f 72 28 69 3d 30 3b 20 7a 46 69 65 6c 64 4e for(i=0; zFieldN
82c0: 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b 20 7a 46 ame[i]; i++){ zF
82d0: 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d 20 74 6f ieldName[i] = to
82e0: 6c 6f 77 65 72 28 7a 46 69 65 6c 64 4e 61 6d 65 lower(zFieldName
82f0: 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 69 66 28 20 [i]); }. if(
8300: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d strcmp(zFieldNam
8310: 65 2c 22 75 73 65 72 2d 61 67 65 6e 74 3a 22 29 e,"user-agent:")
8320: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 ==0 ){. cgi
8330: 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 55 53 _setenv("HTTP_US
8340: 45 52 5f 41 47 45 4e 54 22 2c 20 7a 56 61 6c 29 ER_AGENT", zVal)
8350: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 ;. }else if(
8360: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d strcmp(zFieldNam
8370: 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65 6e 67 74 e,"content-lengt
8380: 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 h:")==0 ){.
8390: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f 4e cgi_setenv("CON
83a0: 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 7a 56 TENT_LENGTH", zV
83b0: 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 al);. }else i
83c0: 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 f( strcmp(zField
83d0: 4e 61 6d 65 2c 22 72 65 66 65 72 65 72 3a 22 29 Name,"referer:")
83e0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 ==0 ){. cgi
83f0: 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 52 45 _setenv("HTTP_RE
8400: 46 45 52 45 52 22 2c 20 7a 56 61 6c 29 3b 0a 20 FERER", zVal);.
8410: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 }else if( str
8420: 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 cmp(zFieldName,"
8430: 68 6f 73 74 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 host:")==0 ){.
8440: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 cgi_setenv("
8450: 48 54 54 50 5f 48 4f 53 54 22 2c 20 7a 56 61 6c HTTP_HOST", zVal
8460: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 );. }else if(
8470: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 strcmp(zFieldNa
8480: 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 65 me,"content-type
8490: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 :")==0 ){.
84a0: 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f 4e 54 cgi_setenv("CONT
84b0: 45 4e 54 5f 54 59 50 45 22 2c 20 7a 56 61 6c 29 ENT_TYPE", zVal)
84c0: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 ;. }else if(
84d0: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d strcmp(zFieldNam
84e0: 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d 3d 30 20 e,"cookie:")==0
84f0: 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 ){. cgi_set
8500: 65 6e 76 28 22 48 54 54 50 5f 43 4f 4f 4b 49 45 env("HTTP_COOKIE
8510: 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 ", zVal);. }e
8520: 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a lse if( strcmp(z
8530: 46 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d 6e 6f FieldName,"if-no
8540: 6e 65 2d 6d 61 74 63 68 3a 22 29 3d 3d 30 20 29 ne-match:")==0 )
8550: 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 {. cgi_sete
8560: 6e 76 28 22 48 54 54 50 5f 49 46 5f 4e 4f 4e 45 nv("HTTP_IF_NONE
8570: 5f 4d 41 54 43 48 22 2c 20 7a 56 61 6c 29 3b 0a _MATCH", zVal);.
8580: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 }else if( st
8590: 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c rcmp(zFieldName,
85a0: 22 69 66 2d 6d 6f 64 69 66 69 65 64 2d 73 69 6e "if-modified-sin
85b0: 63 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 ce:")==0 ){.
85c0: 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 cgi_setenv("HT
85d0: 54 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f 53 TP_IF_MODIFIED_S
85e0: 49 4e 43 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 INCE", zVal);.
85f0: 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 67 69 5f 69 }. }.. cgi_i
8600: 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 nit();.}../*.**
8610: 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f Maximum number o
8620: 66 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 65 f child processe
8630: 73 20 74 68 61 74 20 77 65 20 63 61 6e 20 68 61 s that we can ha
8640: 76 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20 61 74 ve running.** at
8650: 20 6f 6e 65 20 74 69 6d 65 20 62 65 66 6f 72 65 one time before
8660: 20 77 65 20 73 74 61 72 74 20 73 6c 6f 77 69 6e we start slowin
8670: 67 20 74 68 69 6e 67 73 20 64 6f 77 6e 2e 0a 2a g things down..*
8680: 2f 0a 23 64 65 66 69 6e 65 20 4d 41 58 5f 50 41 /.#define MAX_PA
8690: 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a 2a 2a 20 RALLEL 2../*.**
86a0: 49 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 48 54 54 Implement an HTT
86b0: 50 20 73 65 72 76 65 72 20 64 61 65 6d 6f 6e 20 P server daemon
86c0: 6c 69 73 74 65 6e 69 6e 67 20 6f 6e 20 70 6f 72 listening on por
86d0: 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 41 t iPort..**.** A
86e0: 73 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e s new connection
86f0: 73 20 61 72 72 69 76 65 2c 20 66 6f 72 6b 20 61 s arrive, fork a
8700: 20 63 68 69 6c 64 20 61 6e 64 20 6c 65 74 20 63 child and let c
8710: 68 69 6c 64 20 72 65 74 75 72 6e 0a 2a 2a 20 6f hild return.** o
8720: 75 74 20 6f 66 20 74 68 69 73 20 70 72 6f 63 65 ut of this proce
8730: 64 75 72 65 20 63 61 6c 6c 2e 20 20 54 68 65 20 dure call. The
8740: 63 68 69 6c 64 20 77 69 6c 6c 20 68 61 6e 64 6c child will handl
8750: 65 20 74 68 65 20 72 65 71 75 65 73 74 2e 0a 2a e the request..*
8760: 2a 20 54 68 65 20 70 61 72 65 6e 74 20 6e 65 76 * The parent nev
8770: 65 72 20 72 65 74 75 72 6e 73 20 66 72 6f 6d 20 er returns from
8780: 74 68 69 73 20 70 72 6f 63 65 64 75 72 65 2e 0a this procedure..
8790: 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 30 20 74 **.** Return 0 t
87a0: 6f 20 65 61 63 68 20 63 68 69 6c 64 20 61 73 20 o each child as
87b0: 69 74 20 72 75 6e 73 2e 20 20 49 66 20 75 6e 61 it runs. If una
87c0: 62 6c 65 20 74 6f 20 65 73 74 61 62 6c 69 73 68 ble to establish
87d0: 20 61 0a 2a 2a 20 6c 69 73 74 65 6e 69 6e 67 20 a.** listening
87e0: 73 6f 63 6b 65 74 2c 20 72 65 74 75 72 6e 20 6e socket, return n
87f0: 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2f 0a 69 6e 74 20 on-zero..*/.int
8800: 63 67 69 5f 68 74 74 70 5f 73 65 72 76 65 72 28 cgi_http_server(
8810: 69 6e 74 20 6d 6e 50 6f 72 74 2c 20 69 6e 74 20 int mnPort, int
8820: 6d 78 50 6f 72 74 2c 20 63 68 61 72 20 2a 7a 42 mxPort, char *zB
8830: 72 6f 77 73 65 72 29 7b 0a 23 69 66 64 65 66 20 rowser){.#ifdef
8840: 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 20 20 2f 2a __MINGW32__. /*
8850: 20 55 73 65 20 77 69 6e 33 32 5f 68 74 74 70 5f Use win32_http_
8860: 73 65 72 76 65 72 28 29 20 69 6e 73 74 65 61 64 server() instead
8870: 20 2a 2f 0a 20 20 65 78 69 74 28 31 29 3b 0a 23 */. exit(1);.#
8880: 65 6c 73 65 0a 20 20 69 6e 74 20 6c 69 73 74 65 else. int liste
8890: 6e 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 ner;
88a0: 20 20 20 20 2f 2a 20 54 68 65 20 73 65 72 76 65 /* The serve
88b0: 72 20 73 6f 63 6b 65 74 20 2a 2f 0a 20 20 69 6e r socket */. in
88c0: 74 20 63 6f 6e 6e 65 63 74 69 6f 6e 3b 20 20 20 t connection;
88d0: 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 20 /* A
88e0: 73 6f 63 6b 65 74 20 66 6f 72 20 65 61 63 68 20 socket for each
88f0: 69 6e 64 69 76 69 64 75 61 6c 20 63 6f 6e 6e 65 individual conne
8900: 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 64 5f 73 65 ction */. fd_se
8910: 74 20 72 65 61 64 66 64 73 3b 20 20 20 20 20 20 t readfds;
8920: 20 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20 6f /* Set o
8930: 66 20 66 69 6c 65 20 64 65 73 63 72 69 70 74 6f f file descripto
8940: 72 73 20 66 6f 72 20 73 65 6c 65 63 74 28 29 20 rs for select()
8950: 2a 2f 0a 20 20 73 69 7a 65 5f 74 20 6c 65 6e 61 */. size_t lena
8960: 64 64 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 ddr;
8970: 20 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 74 /* Length of t
8980: 68 65 20 69 6e 61 64 64 72 20 73 74 72 75 63 74 he inaddr struct
8990: 75 72 65 20 2a 2f 0a 20 20 69 6e 74 20 63 68 69 ure */. int chi
89a0: 6c 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 ld;
89b0: 20 20 20 20 20 20 2f 2a 20 50 49 44 20 6f 66 20 /* PID of
89c0: 74 68 65 20 63 68 69 6c 64 20 70 72 6f 63 65 73 the child proces
89d0: 73 20 2a 2f 0a 20 20 69 6e 74 20 6e 63 68 69 6c s */. int nchil
89e0: 64 72 65 6e 20 3d 20 30 3b 20 20 20 20 20 20 20 dren = 0;
89f0: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 /* Number of
8a00: 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 65 73 child processes
8a10: 20 2a 2f 0a 20 20 73 74 72 75 63 74 20 74 69 6d */. struct tim
8a20: 65 76 61 6c 20 64 65 6c 61 79 3b 20 20 20 20 20 eval delay;
8a30: 20 20 20 2f 2a 20 48 6f 77 20 6c 6f 6e 67 20 74 /* How long t
8a40: 6f 20 77 61 69 74 20 69 6e 73 69 64 65 20 73 65 o wait inside se
8a50: 6c 65 63 74 28 29 20 2a 2f 0a 20 20 73 74 72 75 lect() */. stru
8a60: 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20 69 ct sockaddr_in i
8a70: 6e 61 64 64 72 3b 20 20 20 2f 2a 20 54 68 65 20 naddr; /* The
8a80: 73 6f 63 6b 65 74 20 61 64 64 72 65 73 73 20 2a socket address *
8a90: 2f 0a 20 20 69 6e 74 20 6f 70 74 20 3d 20 31 3b /. int opt = 1;
8aa0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8ab0: 20 2f 2a 20 73 65 74 73 6f 63 6b 6f 70 74 20 66 /* setsockopt f
8ac0: 6c 61 67 20 2a 2f 0a 20 20 69 6e 74 20 69 50 6f lag */. int iPo
8ad0: 72 74 20 3d 20 6d 6e 50 6f 72 74 3b 0a 0a 20 20 rt = mnPort;..
8ae0: 77 68 69 6c 65 28 20 69 50 6f 72 74 3c 6d 78 50 while( iPort<mxP
8af0: 6f 72 74 20 29 7b 0a 20 20 20 20 6d 65 6d 73 65 ort ){. memse
8b00: 74 28 26 69 6e 61 64 64 72 2c 20 30 2c 20 73 69 t(&inaddr, 0, si
8b10: 7a 65 6f 66 28 69 6e 61 64 64 72 29 29 3b 0a 20 zeof(inaddr));.
8b20: 20 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f 66 61 inaddr.sin_fa
8b30: 6d 69 6c 79 20 3d 20 41 46 5f 49 4e 45 54 3b 0a mily = AF_INET;.
8b40: 20 20 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f 61 inaddr.sin_a
8b50: 64 64 72 2e 73 5f 61 64 64 72 20 3d 20 49 4e 41 ddr.s_addr = INA
8b60: 44 44 52 5f 41 4e 59 3b 0a 20 20 20 20 69 6e 61 DDR_ANY;. ina
8b70: 64 64 72 2e 73 69 6e 5f 70 6f 72 74 20 3d 20 68 ddr.sin_port = h
8b80: 74 6f 6e 73 28 69 50 6f 72 74 29 3b 0a 20 20 20 tons(iPort);.
8b90: 20 6c 69 73 74 65 6e 65 72 20 3d 20 73 6f 63 6b listener = sock
8ba0: 65 74 28 41 46 5f 49 4e 45 54 2c 20 53 4f 43 4b et(AF_INET, SOCK
8bb0: 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a 20 20 20 _STREAM, 0);.
8bc0: 20 69 66 28 20 6c 69 73 74 65 6e 65 72 3c 30 20 if( listener<0
8bd0: 29 7b 0a 20 20 20 20 20 20 69 50 6f 72 74 2b 2b ){. iPort++
8be0: 3b 0a 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 ;. continue
8bf0: 3b 0a 20 20 20 20 7d 0a 0a 20 20 20 20 2f 2a 20 ;. }.. /*
8c00: 69 66 20 77 65 20 63 61 6e 27 74 20 74 65 72 6d if we can't term
8c10: 69 6e 61 74 65 20 6e 69 63 65 6c 79 2c 20 61 74 inate nicely, at
8c20: 20 6c 65 61 73 74 20 61 6c 6c 6f 77 20 74 68 65 least allow the
8c30: 20 73 6f 63 6b 65 74 20 74 6f 20 62 65 20 72 65 socket to be re
8c40: 75 73 65 64 20 2a 2f 0a 20 20 20 20 73 65 74 73 used */. sets
8c50: 6f 63 6b 6f 70 74 28 6c 69 73 74 65 6e 65 72 2c ockopt(listener,
8c60: 53 4f 4c 5f 53 4f 43 4b 45 54 2c 53 4f 5f 52 45 SOL_SOCKET,SO_RE
8c70: 55 53 45 41 44 44 52 2c 26 6f 70 74 2c 73 69 7a USEADDR,&opt,siz
8c80: 65 6f 66 28 6f 70 74 29 29 3b 0a 0a 20 20 20 20 eof(opt));..
8c90: 69 66 28 20 62 69 6e 64 28 6c 69 73 74 65 6e 65 if( bind(listene
8ca0: 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b 61 r, (struct socka
8cb0: 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 20 73 69 ddr*)&inaddr, si
8cc0: 7a 65 6f 66 28 69 6e 61 64 64 72 29 29 3c 30 20 zeof(inaddr))<0
8cd0: 29 7b 0a 20 20 20 20 20 20 63 6c 6f 73 65 28 6c ){. close(l
8ce0: 69 73 74 65 6e 65 72 29 3b 0a 20 20 20 20 20 20 istener);.
8cf0: 69 50 6f 72 74 2b 2b 3b 0a 20 20 20 20 20 20 63 iPort++;. c
8d00: 6f 6e 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 20 ontinue;. }.
8d10: 20 20 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 break;. }.
8d20: 69 66 28 20 69 50 6f 72 74 3e 6d 78 50 6f 72 74 if( iPort>mxPort
8d30: 20 29 7b 0a 20 20 20 20 69 66 28 20 6d 6e 50 6f ){. if( mnPo
8d40: 72 74 3d 3d 6d 78 50 6f 72 74 20 29 7b 0a 20 20 rt==mxPort ){.
8d50: 20 20 20 20 66 6f 73 73 69 6c 5f 66 61 74 61 6c fossil_fatal
8d60: 28 22 75 6e 61 62 6c 65 20 74 6f 20 6f 70 65 6e ("unable to open
8d70: 20 6c 69 73 74 65 6e 69 6e 67 20 73 6f 63 6b 65 listening socke
8d80: 74 20 6f 6e 20 70 6f 72 74 73 20 25 64 22 2c 20 t on ports %d",
8d90: 6d 6e 50 6f 72 74 29 3b 0a 20 20 20 20 7d 65 6c mnPort);. }el
8da0: 73 65 7b 0a 20 20 20 20 20 20 66 6f 73 73 69 6c se{. fossil
8db0: 5f 66 61 74 61 6c 28 22 75 6e 61 62 6c 65 20 74 _fatal("unable t
8dc0: 6f 20 6f 70 65 6e 20 6c 69 73 74 65 6e 69 6e 67 o open listening
8dd0: 20 73 6f 63 6b 65 74 20 6f 6e 20 61 6e 79 22 0a socket on any".
8de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8df0: 20 20 20 22 20 70 6f 72 74 73 20 25 64 2e 2e 25 " ports %d..%
8e00: 64 22 2c 20 6d 6e 50 6f 72 74 2c 20 6d 78 50 6f d", mnPort, mxPo
8e10: 72 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 rt);. }. }.
8e20: 20 69 66 28 20 69 50 6f 72 74 3e 6d 78 50 6f 72 if( iPort>mxPor
8e30: 74 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 t ) return 1;.
8e40: 6c 69 73 74 65 6e 28 6c 69 73 74 65 6e 65 72 2c listen(listener,
8e50: 31 30 29 3b 0a 20 20 69 66 28 20 69 50 6f 72 74 10);. if( iPort
8e60: 3e 6d 6e 50 6f 72 74 20 29 7b 0a 20 20 20 20 70 >mnPort ){. p
8e70: 72 69 6e 74 66 28 22 4c 69 73 74 65 6e 69 6e 67 rintf("Listening
8e80: 20 66 6f 72 20 48 54 54 50 20 72 65 71 75 65 73 for HTTP reques
8e90: 74 73 20 6f 6e 20 54 43 50 20 70 6f 72 74 20 25 ts on TCP port %
8ea0: 64 5c 6e 22 2c 20 69 50 6f 72 74 29 3b 0a 20 20 d\n", iPort);.
8eb0: 20 20 66 66 6c 75 73 68 28 73 74 64 6f 75 74 29 fflush(stdout)
8ec0: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 7a 42 72 6f ;. }. if( zBro
8ed0: 77 73 65 72 20 29 7b 0a 20 20 20 20 7a 42 72 6f wser ){. zBro
8ee0: 77 73 65 72 20 3d 20 6d 70 72 69 6e 74 66 28 7a wser = mprintf(z
8ef0: 42 72 6f 77 73 65 72 2c 20 69 50 6f 72 74 29 3b Browser, iPort);
8f00: 0a 20 20 20 20 73 79 73 74 65 6d 28 7a 42 72 6f . system(zBro
8f10: 77 73 65 72 29 3b 0a 20 20 7d 0a 20 20 77 68 69 wser);. }. whi
8f20: 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 69 66 28 le( 1 ){. if(
8f30: 20 6e 63 68 69 6c 64 72 65 6e 3e 4d 41 58 5f 50 nchildren>MAX_P
8f40: 41 52 41 4c 4c 45 4c 20 29 7b 0a 20 20 20 20 20 ARALLEL ){.
8f50: 20 2f 2a 20 53 6c 6f 77 20 64 6f 77 6e 20 69 66 /* Slow down if
8f60: 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72 65 connections are
8f70: 20 61 72 72 69 76 69 6e 67 20 74 6f 6f 20 66 61 arriving too fa
8f80: 73 74 20 2a 2f 0a 20 20 20 20 20 20 73 6c 65 65 st */. slee
8f90: 70 28 20 6e 63 68 69 6c 64 72 65 6e 2d 4d 41 58 p( nchildren-MAX
8fa0: 5f 50 41 52 41 4c 4c 45 4c 20 29 3b 0a 20 20 20 _PARALLEL );.
8fb0: 20 7d 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 5f }. delay.tv_
8fc0: 73 65 63 20 3d 20 36 30 3b 0a 20 20 20 20 64 65 sec = 60;. de
8fd0: 6c 61 79 2e 74 76 5f 75 73 65 63 20 3d 20 30 3b lay.tv_usec = 0;
8fe0: 0a 20 20 20 20 46 44 5f 5a 45 52 4f 28 26 72 65 . FD_ZERO(&re
8ff0: 61 64 66 64 73 29 3b 0a 20 20 20 20 46 44 5f 53 adfds);. FD_S
9000: 45 54 28 20 6c 69 73 74 65 6e 65 72 2c 20 26 72 ET( listener, &r
9010: 65 61 64 66 64 73 29 3b 0a 20 20 20 20 69 66 28 eadfds);. if(
9020: 20 73 65 6c 65 63 74 28 20 6c 69 73 74 65 6e 65 select( listene
9030: 72 2b 31 2c 20 26 72 65 61 64 66 64 73 2c 20 30 r+1, &readfds, 0
9040: 2c 20 30 2c 20 26 64 65 6c 61 79 29 20 29 7b 0a , 0, &delay) ){.
9050: 20 20 20 20 20 20 6c 65 6e 61 64 64 72 20 3d 20 lenaddr =
9060: 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 3b 0a sizeof(inaddr);.
9070: 20 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f 6e connection
9080: 20 3d 20 61 63 63 65 70 74 28 6c 69 73 74 65 6e = accept(listen
9090: 65 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b er, (struct sock
90a0: 61 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 0a 20 addr*)&inaddr,.
90b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
90c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
90d0: 20 20 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 20 (socklen_t*)
90e0: 26 6c 65 6e 61 64 64 72 29 3b 0a 20 20 20 20 20 &lenaddr);.
90f0: 20 69 66 28 20 63 6f 6e 6e 65 63 74 69 6f 6e 3e if( connection>
9100: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63 68 =0 ){. ch
9110: 69 6c 64 20 3d 20 66 6f 72 6b 28 29 3b 0a 20 20 ild = fork();.
9120: 20 20 20 20 20 20 69 66 28 20 63 68 69 6c 64 21 if( child!
9130: 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 =0 ){.
9140: 69 66 28 20 63 68 69 6c 64 3e 30 20 29 20 6e 63 if( child>0 ) nc
9150: 68 69 6c 64 72 65 6e 2b 2b 3b 0a 20 20 20 20 20 hildren++;.
9160: 20 20 20 20 20 63 6c 6f 73 65 28 63 6f 6e 6e 65 close(conne
9170: 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 ction);.
9180: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 20 }else{.
9190: 20 63 6c 6f 73 65 28 30 29 3b 0a 20 20 20 20 20 close(0);.
91a0: 20 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 dup(connect
91b0: 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 ion);.
91c0: 63 6c 6f 73 65 28 31 29 3b 0a 20 20 20 20 20 20 close(1);.
91d0: 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 dup(connecti
91e0: 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 69 on);. i
91f0: 66 28 20 21 67 2e 66 48 74 74 70 54 72 61 63 65 f( !g.fHttpTrace
9200: 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 20 ){.
9210: 63 6c 6f 73 65 28 32 29 3b 0a 20 20 20 20 20 20 close(2);.
9220: 20 20 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 dup(connec
9230: 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 tion);.
9240: 20 7d 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f }. clo
9250: 73 65 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a se(connection);.
9260: 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 6e return
9270: 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 0;. }.
9280: 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 20 }. }.
9290: 2f 2a 20 42 75 72 79 20 64 65 61 64 20 63 68 69 /* Bury dead chi
92a0: 6c 64 72 65 6e 20 2a 2f 0a 20 20 20 20 77 68 69 ldren */. whi
92b0: 6c 65 28 20 77 61 69 74 70 69 64 28 30 2c 20 30 le( waitpid(0, 0
92c0: 2c 20 57 4e 4f 48 41 4e 47 29 3e 30 20 29 7b 0a , WNOHANG)>0 ){.
92d0: 20 20 20 20 20 20 6e 63 68 69 6c 64 72 65 6e 2d nchildren-
92e0: 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2f -;. }. }. /
92f0: 2a 20 4e 4f 54 20 52 45 41 43 48 45 44 20 2a 2f * NOT REACHED */
9300: 20 20 0a 20 20 65 78 69 74 28 31 29 3b 0a 23 65 . exit(1);.#e
9310: 6e 64 69 66 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 4e ndif.}.../*.** N
9320: 61 6d 65 20 6f 66 20 64 61 79 73 20 61 6e 64 20 ame of days and
9330: 6d 6f 6e 74 68 73 2e 0a 2a 2f 0a 73 74 61 74 69 months..*/.stati
9340: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a c const char *az
9350: 44 61 79 73 5b 5d 20 3d 0a 20 20 20 20 7b 22 53 Days[] =. {"S
9360: 75 6e 22 2c 20 22 4d 6f 6e 22 2c 20 22 54 75 65 un", "Mon", "Tue
9370: 22 2c 20 22 57 65 64 22 2c 20 22 54 68 75 22 2c ", "Wed", "Thu",
9380: 20 22 46 72 69 22 2c 20 22 53 61 74 22 2c 20 30 "Fri", "Sat", 0
9390: 7d 3b 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 };.static const
93a0: 63 68 61 72 20 2a 61 7a 4d 6f 6e 74 68 73 5b 5d char *azMonths[]
93b0: 20 3d 0a 20 20 20 20 7b 22 4a 61 6e 22 2c 20 22 =. {"Jan", "
93c0: 46 65 62 22 2c 20 22 4d 61 72 22 2c 20 22 41 70 Feb", "Mar", "Ap
93d0: 72 22 2c 20 22 4d 61 79 22 2c 20 22 4a 75 6e 22 r", "May", "Jun"
93e0: 2c 0a 20 20 20 20 20 22 4a 75 6c 22 2c 20 22 41 ,. "Jul", "A
93f0: 75 67 22 2c 20 22 53 65 70 22 2c 20 22 4f 63 74 ug", "Sep", "Oct
9400: 22 2c 20 22 4e 6f 76 22 2c 20 22 44 65 63 22 2c ", "Nov", "Dec",
9410: 20 30 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 0};.../*.** Ret
9420: 75 72 6e 73 20 61 6e 20 52 46 43 38 32 32 2d 66 urns an RFC822-f
9430: 6f 72 6d 61 74 74 65 64 20 74 69 6d 65 20 73 74 ormatted time st
9440: 72 69 6e 67 20 73 75 69 74 61 62 6c 65 20 66 6f ring suitable fo
9450: 72 20 48 54 54 50 20 68 65 61 64 65 72 73 2c 20 r HTTP headers,
9460: 61 6d 6f 6e 67 0a 2a 2a 20 6f 74 68 65 72 20 74 among.** other t
9470: 68 69 6e 67 73 2e 0a 2a 2a 20 52 65 74 75 72 6e hings..** Return
9480: 65 64 20 74 69 6d 65 7a 6f 6e 65 20 69 73 20 61 ed timezone is a
9490: 6c 77 61 79 73 20 47 4d 54 20 61 73 20 72 65 71 lways GMT as req
94a0: 75 69 72 65 64 20 62 79 20 48 54 54 50 2f 31 2e uired by HTTP/1.
94b0: 31 20 73 70 65 63 69 66 69 63 61 74 69 6f 6e 2e 1 specification.
94c0: 0a 2a 2a 20 54 68 65 20 72 65 74 75 72 6e 65 64 .** The returned
94d0: 20 73 74 72 69 6e 67 20 69 73 20 61 6c 6c 6f 63 string is alloc
94e0: 61 74 65 64 20 77 69 74 68 20 6d 61 6c 6c 6f 63 ated with malloc
94f0: 28 29 20 61 6e 64 20 6d 75 73 74 20 62 65 20 66 () and must be f
9500: 72 65 65 64 0a 2a 2a 20 77 69 74 68 20 66 72 65 reed.** with fre
9510: 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 53 65 65 20 68 e()..**.** See h
9520: 74 74 70 3a 2f 2f 77 77 77 2e 66 61 71 73 2e 6f ttp://www.faqs.o
9530: 72 67 2f 72 66 63 73 2f 72 66 63 38 32 32 2e 68 rg/rfcs/rfc822.h
9540: 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 20 35 0a 2a tml, section 5.*
9550: 2a 20 61 6e 64 20 68 74 74 70 3a 2f 2f 77 77 77 * and http://www
9560: 2e 66 61 71 73 2e 6f 72 67 2f 72 66 63 73 2f 72 .faqs.org/rfcs/r
9570: 66 63 32 36 31 36 2e 68 74 6d 6c 2c 20 73 65 63 fc2616.html, sec
9580: 74 69 6f 6e 20 33 2e 33 2e 0a 2a 2f 0a 63 68 61 tion 3.3..*/.cha
9590: 72 20 2a 63 67 69 5f 72 66 63 38 32 32 5f 64 61 r *cgi_rfc822_da
95a0: 74 65 73 74 61 6d 70 28 74 69 6d 65 5f 74 20 6e testamp(time_t n
95b0: 6f 77 29 7b 0a 20 20 73 74 72 75 63 74 20 74 6d ow){. struct tm
95c0: 20 2a 70 54 6d 3b 0a 20 20 70 54 6d 20 3d 20 67 *pTm;. pTm = g
95d0: 6d 74 69 6d 65 28 26 6e 6f 77 29 3b 0a 20 20 69 mtime(&now);. i
95e0: 66 28 20 70 54 6d 3d 3d 30 20 29 20 72 65 74 75 f( pTm==0 ) retu
95f0: 72 6e 20 22 22 3b 0a 20 20 72 65 74 75 72 6e 20 rn "";. return
9600: 6d 70 72 69 6e 74 66 28 22 25 73 2c 20 25 64 20 mprintf("%s, %d
9610: 25 73 20 25 30 32 64 20 25 30 32 64 3a 25 30 32 %s %02d %02d:%02
9620: 64 3a 25 30 32 64 20 47 4d 54 22 2c 0a 20 20 20 d:%02d GMT",.
9630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 7a az
9640: 44 61 79 73 5b 70 54 6d 2d 3e 74 6d 5f 77 64 61 Days[pTm->tm_wda
9650: 79 5d 2c 20 70 54 6d 2d 3e 74 6d 5f 6d 64 61 79 y], pTm->tm_mday
9660: 2c 20 61 7a 4d 6f 6e 74 68 73 5b 70 54 6d 2d 3e , azMonths[pTm->
9670: 74 6d 5f 6d 6f 6e 5d 2c 0a 20 20 20 20 20 20 20 tm_mon],.
9680: 20 20 20 20 20 20 20 20 20 20 70 54 6d 2d 3e 74 pTm->t
9690: 6d 5f 79 65 61 72 2b 31 39 30 30 2c 20 70 54 6d m_year+1900, pTm
96a0: 2d 3e 74 6d 5f 68 6f 75 72 2c 20 70 54 6d 2d 3e ->tm_hour, pTm->
96b0: 74 6d 5f 6d 69 6e 2c 20 70 54 6d 2d 3e 74 6d 5f tm_min, pTm->tm_
96c0: 73 65 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 sec);.}../*.** P
96d0: 61 72 73 65 20 61 6e 20 52 46 43 38 32 32 2d 66 arse an RFC822-f
96e0: 6f 72 6d 61 74 74 65 64 20 74 69 6d 65 73 74 61 ormatted timesta
96f0: 6d 70 20 61 73 20 77 65 27 64 20 65 78 70 65 63 mp as we'd expec
9700: 74 20 66 72 6f 6d 20 48 54 54 50 20 61 6e 64 20 t from HTTP and
9710: 72 65 74 75 72 6e 0a 2a 2a 20 61 20 55 6e 69 78 return.** a Unix
9720: 20 65 70 6f 63 68 20 74 69 6d 65 2e 20 3c 3d 20 epoch time. <=
9730: 7a 65 72 6f 20 69 73 20 72 65 74 75 72 6e 65 64 zero is returned
9740: 20 6f 6e 20 66 61 69 6c 75 72 65 2e 0a 2a 2a 0a on failure..**.
9750: 2a 2a 20 4e 6f 74 65 20 74 68 61 74 20 74 68 69 ** Note that thi
9760: 73 20 77 6f 6e 27 74 20 68 61 6e 64 6c 65 20 61 s won't handle a
9770: 6c 6c 20 74 68 65 20 5f 61 6c 6c 6f 77 65 64 5f ll the _allowed_
9780: 20 48 54 54 50 20 66 6f 72 6d 61 74 73 2c 20 6a HTTP formats, j
9790: 75 73 74 20 74 68 65 0a 2a 2a 20 6d 6f 73 74 20 ust the.** most
97a0: 70 6f 70 75 6c 61 72 20 6f 6e 65 20 28 74 68 65 popular one (the
97b0: 20 6f 6e 65 20 67 65 6e 65 72 61 74 65 64 20 62 one generated b
97c0: 79 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 74 y cgi_rfc822_dat
97d0: 65 73 74 61 6d 70 28 29 2c 20 61 63 74 75 61 6c estamp(), actual
97e0: 6c 79 29 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 63 ly)..*/.time_t c
97f0: 67 69 5f 72 66 63 38 32 32 5f 70 61 72 73 65 64 gi_rfc822_parsed
9800: 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a ate(const char *
9810: 7a 44 61 74 65 29 7b 0a 20 20 73 74 72 75 63 74 zDate){. struct
9820: 20 74 6d 20 74 3b 0a 20 20 63 68 61 72 20 7a 49 tm t;. char zI
9830: 67 6e 6f 72 65 5b 31 36 5d 3b 0a 20 20 63 68 61 gnore[16];. cha
9840: 72 20 7a 4d 6f 6e 74 68 5b 31 36 5d 3b 0a 0a 20 r zMonth[16];..
9850: 20 6d 65 6d 73 65 74 28 26 74 2c 20 30 2c 20 73 memset(&t, 0, s
9860: 69 7a 65 6f 66 28 74 29 29 3b 0a 20 20 69 66 28 izeof(t));. if(
9870: 20 37 3d 3d 73 73 63 61 6e 66 28 7a 44 61 74 65 7==sscanf(zDate
9880: 2c 20 22 25 31 32 5b 41 2d 5a 61 2d 7a 2c 5d 20 , "%12[A-Za-z,]
9890: 25 64 20 25 31 32 5b 41 2d 5a 61 2d 7a 5d 20 25 %d %12[A-Za-z] %
98a0: 64 20 25 64 3a 25 64 3a 25 64 22 2c 20 7a 49 67 d %d:%d:%d", zIg
98b0: 6e 6f 72 65 2c 0a 20 20 20 20 20 20 20 20 20 20 nore,.
98c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 26 74 2e &t.
98d0: 74 6d 5f 6d 64 61 79 2c 20 7a 4d 6f 6e 74 68 2c tm_mday, zMonth,
98e0: 20 26 74 2e 74 6d 5f 79 65 61 72 2c 20 26 74 2e &t.tm_year, &t.
98f0: 74 6d 5f 68 6f 75 72 2c 20 26 74 2e 74 6d 5f 6d tm_hour, &t.tm_m
9900: 69 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 20 in,.
9910: 20 20 20 20 20 20 20 20 20 20 20 26 74 2e 74 6d &t.tm
9920: 5f 73 65 63 29 29 7b 0a 0a 20 20 20 20 69 66 28 _sec)){.. if(
9930: 20 74 2e 74 6d 5f 79 65 61 72 20 3e 20 31 39 30 t.tm_year > 190
9940: 30 20 29 20 74 2e 74 6d 5f 79 65 61 72 20 2d 3d 0 ) t.tm_year -=
9950: 20 31 39 30 30 3b 0a 20 20 20 20 66 6f 72 28 74 1900;. for(t
9960: 2e 74 6d 5f 6d 6f 6e 3d 30 3b 20 61 7a 4d 6f 6e .tm_mon=0; azMon
9970: 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 3b 20 74 ths[t.tm_mon]; t
9980: 2e 74 6d 5f 6d 6f 6e 2b 2b 29 7b 0a 20 20 20 20 .tm_mon++){.
9990: 20 20 69 66 28 20 21 73 74 72 6e 63 61 73 65 63 if( !strncasec
99a0: 6d 70 28 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e 74 mp( azMonths[t.t
99b0: 6d 5f 6d 6f 6e 5d 2c 20 7a 4d 6f 6e 74 68 2c 20 m_mon], zMonth,
99c0: 33 20 29 29 7b 0a 20 20 20 20 20 20 20 20 72 65 3 )){. re
99d0: 74 75 72 6e 20 6d 6b 67 6d 74 69 6d 65 28 26 74 turn mkgmtime(&t
99e0: 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 7d );. }. }
99f0: 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 30 . }.. return 0
9a00: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 76 65 ;.}../*.** Conve
9a10: 72 74 20 61 20 73 74 72 75 63 74 20 74 6d 2a 20 rt a struct tm*
9a20: 74 68 61 74 20 72 65 70 72 65 73 65 6e 74 73 20 that represents
9a30: 61 20 6d 6f 6d 65 6e 74 20 69 6e 20 55 54 43 20 a moment in UTC
9a40: 69 6e 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 0a into the number.
9a50: 2a 2a 20 6f 66 20 73 65 63 6f 6e 64 73 20 69 6e ** of seconds in
9a60: 20 31 39 37 30 2c 20 55 54 43 2e 0a 2a 2f 0a 74 1970, UTC..*/.t
9a70: 69 6d 65 5f 74 20 6d 6b 67 6d 74 69 6d 65 28 73 ime_t mkgmtime(s
9a80: 74 72 75 63 74 20 74 6d 20 2a 70 29 7b 0a 20 20 truct tm *p){.
9a90: 74 69 6d 65 5f 74 20 74 3b 0a 20 20 69 6e 74 20 time_t t;. int
9aa0: 6e 44 61 79 3b 0a 20 20 69 6e 74 20 69 73 4c 65 nDay;. int isLe
9ab0: 61 70 59 72 3b 0a 20 20 2f 2a 20 44 61 79 73 20 apYr;. /* Days
9ac0: 69 6e 20 65 61 63 68 20 6d 6f 6e 74 68 3a 20 20 in each month:
9ad0: 20 20 20 20 20 33 31 2c 20 32 38 2c 20 33 31 2c 31, 28, 31,
9ae0: 20 33 30 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c 30, 31, 30, 31,
9af0: 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33 30 2c 31, 30, 31, 30,
9b00: 20 33 31 20 2a 2f 0a 20 20 73 74 61 74 69 63 20 31 */. static
9b10: 69 6e 74 20 70 72 69 6f 72 44 61 79 73 5b 5d 20 int priorDays[]
9b20: 20 20 3d 20 7b 20 20 30 2c 20 33 31 2c 20 35 39 = { 0, 31, 59
9b30: 2c 20 39 30 2c 31 32 30 2c 31 35 31 2c 31 38 31 , 90,120,151,181
9b40: 2c 32 31 32 2c 32 34 33 2c 32 37 33 2c 33 30 34 ,212,243,273,304
9b50: 2c 33 33 34 20 7d 3b 0a 20 20 69 66 28 20 70 2d ,334 };. if( p-
9b60: 3e 74 6d 5f 6d 6f 6e 3c 30 20 29 7b 0a 20 20 20 >tm_mon<0 ){.
9b70: 20 69 6e 74 20 6e 59 65 61 72 20 3d 20 28 31 31 int nYear = (11
9b80: 20 2d 20 70 2d 3e 74 6d 5f 6d 6f 6e 29 2f 31 32 - p->tm_mon)/12
9b90: 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 79 65 61 72 ;. p->tm_year
9ba0: 20 2d 3d 20 6e 59 65 61 72 3b 0a 20 20 20 20 70 -= nYear;. p
9bb0: 2d 3e 74 6d 5f 6d 6f 6e 20 2b 3d 20 6e 59 65 61 ->tm_mon += nYea
9bc0: 72 2a 31 32 3b 0a 20 20 7d 65 6c 73 65 20 69 66 r*12;. }else if
9bd0: 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3e 31 31 20 29 ( p->tm_mon>11 )
9be0: 7b 0a 20 20 20 20 70 2d 3e 74 6d 5f 79 65 61 72 {. p->tm_year
9bf0: 20 2b 3d 20 70 2d 3e 74 6d 5f 6d 6f 6e 2f 31 32 += p->tm_mon/12
9c00: 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 20 ;. p->tm_mon
9c10: 25 3d 20 31 32 3b 0a 20 20 7d 0a 20 20 69 73 4c %= 12;. }. isL
9c20: 65 61 70 59 72 20 3d 20 70 2d 3e 74 6d 5f 79 65 eapYr = p->tm_ye
9c30: 61 72 25 34 3d 3d 30 20 26 26 20 28 70 2d 3e 74 ar%4==0 && (p->t
9c40: 6d 5f 79 65 61 72 25 31 30 30 21 3d 30 20 7c 7c m_year%100!=0 ||
9c50: 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2b 33 30 30 (p->tm_year+300
9c60: 29 25 34 30 30 3d 3d 30 29 3b 0a 20 20 70 2d 3e )%400==0);. p->
9c70: 74 6d 5f 79 64 61 79 20 3d 20 70 72 69 6f 72 44 tm_yday = priorD
9c80: 61 79 73 5b 70 2d 3e 74 6d 5f 6d 6f 6e 5d 20 2b ays[p->tm_mon] +
9c90: 20 70 2d 3e 74 6d 5f 6d 64 61 79 20 2d 20 31 3b p->tm_mday - 1;
9ca0: 0a 20 20 69 66 28 20 69 73 4c 65 61 70 59 72 20 . if( isLeapYr
9cb0: 26 26 20 70 2d 3e 74 6d 5f 6d 6f 6e 3e 31 20 29 && p->tm_mon>1 )
9cc0: 20 70 2d 3e 74 6d 5f 79 64 61 79 2b 2b 3b 0a 20 p->tm_yday++;.
9cd0: 20 6e 44 61 79 20 3d 20 28 70 2d 3e 74 6d 5f 79 nDay = (p->tm_y
9ce0: 65 61 72 2d 37 30 29 2a 33 36 35 20 2b 20 28 70 ear-70)*365 + (p
9cf0: 2d 3e 74 6d 5f 79 65 61 72 2d 36 39 29 2f 34 20 ->tm_year-69)/4
9d00: 2d 70 2d 3e 74 6d 5f 79 65 61 72 2f 31 30 30 20 -p->tm_year/100
9d10: 2b 20 0a 20 20 20 20 20 20 20 20 20 28 70 2d 3e + . (p->
9d20: 74 6d 5f 79 65 61 72 2b 33 30 30 29 2f 34 30 30 tm_year+300)/400
9d30: 20 2b 20 70 2d 3e 74 6d 5f 79 64 61 79 3b 0a 20 + p->tm_yday;.
9d40: 20 74 20 3d 20 28 28 6e 44 61 79 2a 32 34 20 2b t = ((nDay*24 +
9d50: 20 70 2d 3e 74 6d 5f 68 6f 75 72 29 2a 36 30 20 p->tm_hour)*60
9d60: 2b 20 70 2d 3e 74 6d 5f 6d 69 6e 29 2a 36 30 20 + p->tm_min)*60
9d70: 2b 20 70 2d 3e 74 6d 5f 73 65 63 3b 0a 20 20 72 + p->tm_sec;. r
9d80: 65 74 75 72 6e 20 74 3b 0a 7d 0a 0a 2f 2a 0a 2a eturn t;.}../*.*
9d90: 2a 20 43 68 65 63 6b 20 74 68 65 20 6f 62 6a 65 * Check the obje
9da0: 63 74 54 69 6d 65 20 61 67 61 69 6e 73 74 20 74 ctTime against t
9db0: 68 65 20 49 66 2d 4d 6f 64 69 66 69 65 64 2d 53 he If-Modified-S
9dc0: 69 6e 63 65 20 72 65 71 75 65 73 74 20 68 65 61 ince request hea
9dd0: 64 65 72 2e 20 49 66 20 74 68 65 0a 2a 2a 20 6f der. If the.** o
9de0: 62 6a 65 63 74 20 74 69 6d 65 20 69 73 6e 27 74 bject time isn't
9df0: 20 61 6e 79 20 6e 65 77 65 72 20 74 68 61 6e 20 any newer than
9e00: 74 68 65 20 68 65 61 64 65 72 2c 20 77 65 20 69 the header, we i
9e10: 6d 6d 65 64 69 61 74 65 6c 79 20 73 65 6e 64 20 mmediately send
9e20: 62 61 63 6b 0a 2a 2a 20 61 20 33 30 34 20 72 65 back.** a 304 re
9e30: 70 6c 79 20 61 6e 64 20 65 78 69 74 2e 0a 2a 2f ply and exit..*/
9e40: 0a 76 6f 69 64 20 63 67 69 5f 6d 6f 64 69 66 69 .void cgi_modifi
9e50: 65 64 5f 73 69 6e 63 65 28 74 69 6d 65 5f 74 20 ed_since(time_t
9e60: 6f 62 6a 65 63 74 54 69 6d 65 29 7b 0a 20 20 63 objectTime){. c
9e70: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 66 20 3d onst char *zIf =
9e80: 20 50 28 22 48 54 54 50 5f 49 46 5f 4d 4f 44 49 P("HTTP_IF_MODI
9e90: 46 49 45 44 5f 53 49 4e 43 45 22 29 3b 0a 20 20 FIED_SINCE");.
9ea0: 69 66 28 20 7a 49 66 3d 3d 30 20 29 20 72 65 74 if( zIf==0 ) ret
9eb0: 75 72 6e 3b 0a 20 20 69 66 28 20 6f 62 6a 65 63 urn;. if( objec
9ec0: 74 54 69 6d 65 20 3e 20 63 67 69 5f 72 66 63 38 tTime > cgi_rfc8
9ed0: 32 32 5f 70 61 72 73 65 64 61 74 65 28 7a 49 66 22_parsedate(zIf
9ee0: 29 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 63 67 ) ) return;. cg
9ef0: 69 5f 73 65 74 5f 73 74 61 74 75 73 28 33 30 34 i_set_status(304
9f00: 2c 22 4e 6f 74 20 4d 6f 64 69 66 69 65 64 22 29 ,"Not Modified")
9f10: 3b 0a 20 20 63 67 69 5f 72 65 73 65 74 5f 63 6f ;. cgi_reset_co
9f20: 6e 74 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f 72 ntent();. cgi_r
9f30: 65 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 30 eply();. exit(0
9f40: 29 3b 0a 7d 0a );.}.