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: 66 64 65 66 20 5f 5f 45 4d 58 5f 5f 0a 20 20 20 fdef __EMX__.
0680: 74 79 70 65 64 65 66 20 69 6e 74 20 73 6f 63 6b typedef int sock
0690: 6c 65 6e 5f 74 3b 0a 23 65 6e 64 69 66 0a 23 69 len_t;.#endif.#i
06a0: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a nclude <time.h>.
06b0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e #include <stdio.
06c0: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 h>.#include <std
06d0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 lib.h>.#include
06e0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c <unistd.h>.#incl
06f0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66 ude "cgi.h"..#if
0700: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a INTERFACE./*.**
0710: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63 Shortcuts for c
0720: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50 gi_parameter. P
0730: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68 ("x") returns th
0740: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79 e value of query
0750: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72 parameter.** or
0760: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20 cookie "x", or
0770: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 NULL if there is
0780: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74 no such paramet
0790: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50 er or cookie. P
07a0: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f D("x","y").** do
07b0: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65 es the same exce
07c0: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e pt "y" is return
07d0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e ed in place of N
07e0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 ULL if there is
07f0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64 not match..*/.#d
0800: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20 efine P(x)
0810: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 cgi_parameter(
0820: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50 (x),0).#define P
0830: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70 D(x,y) cgi_p
0840: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29 arameter((x),(y)
0850: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20 ).#define QP(x)
0860: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73 quotable_s
0870: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65 tring(cgi_parame
0880: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66 ter((x),0)).#def
0890: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20 ine QPD(x,y)
08a0: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28 quotable_string(
08b0: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78 cgi_parameter((x
08c0: 29 2c 28 79 29 29 29 0a 0a 0a 2f 2a 0a 2a 2a 20 ),(y))).../*.**
08d0: 44 65 73 74 69 6e 61 74 69 6f 6e 73 20 66 6f 72 Destinations for
08e0: 20 6f 75 74 70 75 74 20 74 65 78 74 2e 0a 2a 2f output text..*/
08f0: 0a 23 64 65 66 69 6e 65 20 43 47 49 5f 48 45 41 .#define CGI_HEA
0900: 44 45 52 20 20 20 30 0a 23 64 65 66 69 6e 65 20 DER 0.#define
0910: 43 47 49 5f 42 4f 44 59 20 20 20 20 20 31 0a 0a CGI_BODY 1..
0920: 23 65 6e 64 69 66 20 2f 2a 20 49 4e 54 45 52 46 #endif /* INTERF
0930: 41 43 45 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 54 68 ACE */../*.** Th
0940: 65 20 48 54 54 50 20 72 65 70 6c 79 20 69 73 20 e HTTP reply is
0950: 67 65 6e 65 72 61 74 65 64 20 69 6e 20 74 77 6f generated in two
0960: 20 70 69 65 63 65 73 3a 20 74 68 65 20 68 65 61 pieces: the hea
0970: 64 65 72 20 61 6e 64 20 74 68 65 20 62 6f 64 79 der and the body
0980: 2e 0a 2a 2a 20 54 68 65 73 65 20 70 69 65 63 65 ..** These piece
0990: 73 20 61 72 65 20 67 65 6e 65 72 61 74 65 64 20 s are generated
09a0: 73 65 70 61 72 61 74 65 6c 79 20 62 65 63 61 75 separately becau
09b0: 73 65 20 74 68 65 79 20 61 72 65 20 6e 6f 74 20 se they are not
09c0: 6e 65 63 65 73 73 61 72 79 0a 2a 2a 20 70 72 6f necessary.** pro
09d0: 64 75 63 65 64 20 69 6e 20 6f 72 64 65 72 2e 20 duced in order.
09e0: 20 50 61 72 74 73 20 6f 66 20 74 68 65 20 68 65 Parts of the he
09f0: 61 64 65 72 20 6d 69 67 68 74 20 62 65 20 62 75 ader might be bu
0a00: 69 6c 74 20 61 66 74 65 72 20 61 6c 6c 20 6f 72 ilt after all or
0a10: 0a 2a 2a 20 70 61 72 74 20 6f 66 20 74 68 65 20 .** part of the
0a20: 62 6f 64 79 2e 20 20 54 68 65 20 68 65 61 64 65 body. The heade
0a30: 72 20 61 6e 64 20 62 6f 64 79 20 61 72 65 20 61 r and body are a
0a40: 63 63 75 6d 75 6c 61 74 65 64 20 69 6e 20 73 65 ccumulated in se
0a50: 70 61 72 61 74 65 0a 2a 2a 20 42 6c 6f 62 20 73 parate.** Blob s
0a60: 74 72 75 63 74 75 72 65 73 20 74 68 65 6e 20 6f tructures then o
0a70: 75 74 70 75 74 20 73 65 71 75 65 6e 74 69 61 6c utput sequential
0a80: 6c 79 20 6f 6e 63 65 20 65 76 65 72 79 74 68 69 ly once everythi
0a90: 6e 67 20 68 61 73 20 62 65 65 6e 0a 2a 2a 20 62 ng has been.** b
0aa0: 75 69 6c 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 uilt..**.** The
0ab0: 63 67 69 5f 64 65 73 74 69 6e 61 74 69 6f 6e 28 cgi_destination(
0ac0: 29 20 69 6e 74 65 72 66 61 63 65 20 73 77 69 74 ) interface swit
0ad0: 63 68 20 62 65 74 77 65 65 6e 20 74 68 65 20 62 ch between the b
0ae0: 75 66 66 65 72 73 2e 0a 2a 2f 0a 73 74 61 74 69 uffers..*/.stati
0af0: 63 20 42 6c 6f 62 20 63 67 69 43 6f 6e 74 65 6e c Blob cgiConten
0b00: 74 5b 32 5d 20 3d 20 7b 20 42 4c 4f 42 5f 49 4e t[2] = { BLOB_IN
0b10: 49 54 49 41 4c 49 5a 45 52 2c 20 42 4c 4f 42 5f ITIALIZER, BLOB_
0b20: 49 4e 49 54 49 41 4c 49 5a 45 52 20 7d 3b 0a 73 INITIALIZER };.s
0b30: 74 61 74 69 63 20 42 6c 6f 62 20 2a 70 43 6f 6e tatic Blob *pCon
0b40: 74 65 6e 74 20 3d 20 26 63 67 69 43 6f 6e 74 65 tent = &cgiConte
0b50: 6e 74 5b 30 5d 3b 0a 0a 2f 2a 0a 2a 2a 20 53 65 nt[0];../*.** Se
0b60: 74 20 74 68 65 20 64 65 73 74 69 6e 61 74 69 6f t the destinatio
0b70: 6e 20 62 75 66 66 65 72 20 69 6e 74 6f 20 77 68 n buffer into wh
0b80: 69 63 68 20 74 6f 20 61 63 63 75 6d 75 6c 61 74 ich to accumulat
0b90: 65 20 43 47 49 20 63 6f 6e 74 65 6e 74 2e 0a 2a e CGI content..*
0ba0: 2f 0a 76 6f 69 64 20 63 67 69 5f 64 65 73 74 69 /.void cgi_desti
0bb0: 6e 61 74 69 6f 6e 28 69 6e 74 20 64 65 73 74 29 nation(int dest)
0bc0: 7b 0a 20 20 73 77 69 74 63 68 28 20 64 65 73 74 {. switch( dest
0bd0: 20 29 7b 0a 20 20 20 20 63 61 73 65 20 43 47 49 ){. case CGI
0be0: 5f 48 45 41 44 45 52 3a 20 7b 0a 20 20 20 20 20 _HEADER: {.
0bf0: 20 70 43 6f 6e 74 65 6e 74 20 3d 20 26 63 67 69 pContent = &cgi
0c00: 43 6f 6e 74 65 6e 74 5b 30 5d 3b 0a 20 20 20 20 Content[0];.
0c10: 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a 20 break;. }.
0c20: 20 20 20 63 61 73 65 20 43 47 49 5f 42 4f 44 59 case CGI_BODY
0c30: 3a 20 7b 0a 20 20 20 20 20 20 70 43 6f 6e 74 65 : {. pConte
0c40: 6e 74 20 3d 20 26 63 67 69 43 6f 6e 74 65 6e 74 nt = &cgiContent
0c50: 5b 31 5d 3b 0a 20 20 20 20 20 20 62 72 65 61 6b [1];. break
0c60: 3b 0a 20 20 20 20 7d 0a 20 20 20 20 64 65 66 61 ;. }. defa
0c70: 75 6c 74 3a 20 7b 0a 20 20 20 20 20 20 63 67 69 ult: {. cgi
0c80: 5f 70 61 6e 69 63 28 22 62 61 64 20 64 65 73 74 _panic("bad dest
0c90: 69 6e 61 74 69 6f 6e 22 29 3b 0a 20 20 20 20 7d ination");. }
0ca0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 70 . }.}../*.** Ap
0cb0: 70 65 6e 64 20 72 65 70 6c 79 20 63 6f 6e 74 65 pend reply conte
0cc0: 6e 74 20 74 6f 20 77 68 61 74 20 61 6c 72 65 61 nt to what alrea
0cd0: 64 79 20 65 78 69 73 74 73 2e 0a 2a 2f 0a 76 6f dy exists..*/.vo
0ce0: 69 64 20 63 67 69 5f 61 70 70 65 6e 64 5f 63 6f id cgi_append_co
0cf0: 6e 74 65 6e 74 28 63 6f 6e 73 74 20 63 68 61 72 ntent(const char
0d00: 20 2a 7a 44 61 74 61 2c 20 69 6e 74 20 6e 41 6d *zData, int nAm
0d10: 74 29 7b 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e t){. blob_appen
0d20: 64 28 70 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 d(pContent, zDat
0d30: 61 2c 20 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a a, nAmt);.}../*.
0d40: 2a 2a 20 52 65 73 65 74 20 74 68 65 20 48 54 54 ** Reset the HTT
0d50: 50 20 72 65 70 6c 79 20 74 65 78 74 20 74 6f 20 P reply text to
0d60: 62 65 20 61 6e 20 65 6d 70 74 79 20 73 74 72 69 be an empty stri
0d70: 6e 67 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f ng..*/.void cgi_
0d80: 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f reset_content(vo
0d90: 69 64 29 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 id){. blob_rese
0da0: 74 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d t(&cgiContent[0]
0db0: 29 3b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 );. blob_reset(
0dc0: 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d 29 3b &cgiContent[1]);
0dd0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e .}../*.** Return
0de0: 20 61 20 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 a pointer to th
0df0: 65 20 43 47 49 20 6f 75 74 70 75 74 20 62 6c 6f e CGI output blo
0e00: 62 2e 0a 2a 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f b..*/.Blob *cgi_
0e10: 6f 75 74 70 75 74 5f 62 6c 6f 62 28 76 6f 69 64 output_blob(void
0e20: 29 7b 0a 20 20 72 65 74 75 72 6e 20 70 43 6f 6e ){. return pCon
0e30: 74 65 6e 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 tent;.}../*.** C
0e40: 6f 6d 62 69 6e 65 20 74 68 65 20 68 65 61 64 65 ombine the heade
0e50: 72 20 61 6e 64 20 62 6f 64 79 20 6f 66 20 74 68 r and body of th
0e60: 65 20 43 47 49 20 69 6e 74 6f 20 61 20 73 69 6e e CGI into a sin
0e70: 67 6c 65 20 73 74 72 69 6e 67 2e 0a 2a 2f 0a 73 gle string..*/.s
0e80: 74 61 74 69 63 20 76 6f 69 64 20 63 67 69 5f 63 tatic void cgi_c
0e90: 6f 6d 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e ombine_header_an
0ea0: 64 5f 62 6f 64 79 28 76 6f 69 64 29 7b 0a 20 20 d_body(void){.
0eb0: 69 6e 74 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f int size = blob_
0ec0: 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 size(&cgiContent
0ed0: 5b 31 5d 29 3b 0a 20 20 69 66 28 20 73 69 7a 65 [1]);. if( size
0ee0: 3e 30 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 >0 ){. blob_a
0ef0: 70 70 65 6e 64 28 26 63 67 69 43 6f 6e 74 65 6e ppend(&cgiConten
0f00: 74 5b 30 5d 2c 20 62 6c 6f 62 5f 62 75 66 66 65 t[0], blob_buffe
0f10: 72 28 26 63 67 69 43 6f 6e 74 65 6e 74 5b 31 5d r(&cgiContent[1]
0f20: 29 2c 20 73 69 7a 65 29 3b 0a 20 20 20 20 62 6c ), size);. bl
0f30: 6f 62 5f 72 65 73 65 74 28 26 63 67 69 43 6f 6e ob_reset(&cgiCon
0f40: 74 65 6e 74 5b 31 5d 29 3b 0a 20 20 7d 0a 7d 0a tent[1]);. }.}.
0f50: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 ./*.** Return a
0f60: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 48 pointer to the H
0f70: 54 54 50 20 72 65 70 6c 79 20 74 65 78 74 2e 0a TTP reply text..
0f80: 2a 2f 0a 63 68 61 72 20 2a 63 67 69 5f 65 78 74 */.char *cgi_ext
0f90: 72 61 63 74 5f 63 6f 6e 74 65 6e 74 28 69 6e 74 ract_content(int
0fa0: 20 2a 70 6e 41 6d 74 29 7b 0a 20 20 63 67 69 5f *pnAmt){. cgi_
0fb0: 63 6f 6d 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 combine_header_a
0fc0: 6e 64 5f 62 6f 64 79 28 29 3b 0a 20 20 72 65 74 nd_body();. ret
0fd0: 75 72 6e 20 62 6c 6f 62 5f 62 75 66 66 65 72 28 urn blob_buffer(
0fe0: 26 63 67 69 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b &cgiContent[0]);
0ff0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 69 74 69 .}../*.** Additi
1000: 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61 74 69 6f 6e onal information
1010: 20 75 73 65 64 20 74 6f 20 66 6f 72 6d 20 74 68 used to form th
1020: 65 20 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a e HTTP reply.*/.
1030: 73 74 61 74 69 63 20 63 68 61 72 20 2a 7a 43 6f static char *zCo
1040: 6e 74 65 6e 74 54 79 70 65 20 3d 20 22 74 65 78 ntentType = "tex
1050: 74 2f 68 74 6d 6c 22 3b 20 20 20 20 20 2f 2a 20 t/html"; /*
1060: 43 6f 6e 74 65 6e 74 20 74 79 70 65 20 6f 66 20 Content type of
1070: 74 68 65 20 72 65 70 6c 79 20 2a 2f 0a 73 74 61 the reply */.sta
1080: 74 69 63 20 63 68 61 72 20 2a 7a 52 65 70 6c 79 tic char *zReply
1090: 53 74 61 74 75 73 20 3d 20 22 4f 4b 22 3b 20 20 Status = "OK";
10a0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 70 /* Rep
10b0: 6c 79 20 73 74 61 74 75 73 20 64 65 73 63 72 69 ly status descri
10c0: 70 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 ption */.static
10d0: 69 6e 74 20 69 52 65 70 6c 79 53 74 61 74 75 73 int iReplyStatus
10e0: 20 3d 20 32 30 30 3b 20 20 20 20 20 20 20 20 20 = 200;
10f0: 20 20 20 20 20 20 2f 2a 20 52 65 70 6c 79 20 73 /* Reply s
1100: 74 61 74 75 73 20 63 6f 64 65 20 2a 2f 0a 73 74 tatus code */.st
1110: 61 74 69 63 20 42 6c 6f 62 20 65 78 74 72 61 48 atic Blob extraH
1120: 65 61 64 65 72 20 3d 20 42 4c 4f 42 5f 49 4e 49 eader = BLOB_INI
1130: 54 49 41 4c 49 5a 45 52 3b 20 20 2f 2a 20 45 78 TIALIZER; /* Ex
1140: 74 72 61 20 68 65 61 64 65 72 20 74 65 78 74 20 tra header text
1150: 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 */../*.** Set th
1160: 65 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 e reply content
1170: 74 79 70 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 type.*/.void cgi
1180: 5f 73 65 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 _set_content_typ
1190: 65 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 e(const char *zT
11a0: 79 70 65 29 7b 0a 20 20 7a 43 6f 6e 74 65 6e 74 ype){. zContent
11b0: 54 79 70 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 Type = mprintf("
11c0: 25 73 22 2c 20 7a 54 79 70 65 29 3b 0a 7d 0a 0a %s", zType);.}..
11d0: 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 /*.** Set the re
11e0: 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 ply content to t
11f0: 68 65 20 73 70 65 63 69 66 69 65 64 20 42 4c 4f he specified BLO
1200: 42 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 B..*/.void cgi_s
1210: 65 74 5f 63 6f 6e 74 65 6e 74 28 42 6c 6f 62 20 et_content(Blob
1220: 2a 70 4e 65 77 43 6f 6e 74 65 6e 74 29 7b 0a 20 *pNewContent){.
1230: 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 cgi_reset_conte
1240: 6e 74 28 29 3b 0a 20 20 63 67 69 5f 64 65 73 74 nt();. cgi_dest
1250: 69 6e 61 74 69 6f 6e 28 43 47 49 5f 48 45 41 44 ination(CGI_HEAD
1260: 45 52 29 3b 0a 20 20 63 67 69 43 6f 6e 74 65 6e ER);. cgiConten
1270: 74 5b 30 5d 20 3d 20 2a 70 4e 65 77 43 6f 6e 74 t[0] = *pNewCont
1280: 65 6e 74 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 6f ent;. blob_zero
1290: 28 70 4e 65 77 43 6f 6e 74 65 6e 74 29 3b 0a 7d (pNewContent);.}
12a0: 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 ../*.** Set the
12b0: 72 65 70 6c 79 20 73 74 61 74 75 73 20 63 6f 64 reply status cod
12c0: 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 e.*/.void cgi_se
12d0: 74 5f 73 74 61 74 75 73 28 69 6e 74 20 69 53 74 t_status(int iSt
12e0: 61 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a at, const char *
12f0: 7a 53 74 61 74 29 7b 0a 20 20 7a 52 65 70 6c 79 zStat){. zReply
1300: 53 74 61 74 75 73 20 3d 20 6d 70 72 69 6e 74 66 Status = mprintf
1310: 28 22 25 73 22 2c 20 7a 53 74 61 74 29 3b 0a 20 ("%s", zStat);.
1320: 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 iReplyStatus =
1330: 69 53 74 61 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 iStat;.}../*.**
1340: 41 70 70 65 6e 64 20 74 65 78 74 20 74 6f 20 74 Append text to t
1350: 68 65 20 68 65 61 64 65 72 20 6f 66 20 61 6e 20 he header of an
1360: 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 6f HTTP reply.*/.vo
1370: 69 64 20 63 67 69 5f 61 70 70 65 6e 64 5f 68 65 id cgi_append_he
1380: 61 64 65 72 28 63 6f 6e 73 74 20 63 68 61 72 20 ader(const char
1390: 2a 7a 4c 69 6e 65 29 7b 0a 20 20 62 6c 6f 62 5f *zLine){. blob_
13a0: 61 70 70 65 6e 64 28 26 65 78 74 72 61 48 65 61 append(&extraHea
13b0: 64 65 72 2c 20 7a 4c 69 6e 65 2c 20 2d 31 29 3b der, zLine, -1);
13c0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 20 .}../*.** Set a
13d0: 63 6f 6f 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 5a 65 cookie..**.** Ze
13e0: 72 6f 20 6c 69 66 65 74 69 6d 65 20 69 6d 70 6c ro lifetime impl
13f0: 69 65 73 20 61 20 73 65 73 73 69 6f 6e 20 63 6f ies a session co
1400: 6f 6b 69 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 okie..*/.void cg
1410: 69 5f 73 65 74 5f 63 6f 6f 6b 69 65 28 0a 20 20 i_set_cookie(.
1420: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d const char *zNam
1430: 65 2c 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f 66 e, /* Name of
1440: 20 74 68 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a 20 the cookie */.
1450: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 const char *zVa
1460: 6c 75 65 2c 20 20 20 2f 2a 20 56 61 6c 75 65 20 lue, /* Value
1470: 6f 66 20 74 68 65 20 63 6f 6f 6b 69 65 2e 20 20 of the cookie.
1480: 41 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 65 73 Automatically es
1490: 63 61 70 65 64 20 2a 2f 0a 20 20 63 6f 6e 73 74 caped */. const
14a0: 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 20 20 20 char *zPath,
14b0: 20 2f 2a 20 50 61 74 68 20 63 6f 6f 6b 69 65 20 /* Path cookie
14c0: 61 70 70 6c 69 65 73 20 74 6f 2e 20 20 4e 55 4c applies to. NUL
14d0: 4c 20 6d 65 61 6e 73 20 22 2f 22 20 2a 2f 0a 20 L means "/" */.
14e0: 20 69 6e 74 20 6c 69 66 65 74 69 6d 65 20 20 20 int lifetime
14f0: 20 20 20 20 20 20 20 2f 2a 20 45 78 70 69 72 61 /* Expira
1500: 74 69 6f 6e 20 6f 66 20 74 68 65 20 63 6f 6f 6b tion of the cook
1510: 69 65 20 69 6e 20 73 65 63 6f 6e 64 73 20 66 72 ie in seconds fr
1520: 6f 6d 20 6e 6f 77 20 2a 2f 0a 29 7b 0a 20 20 69 om now */.){. i
1530: 66 28 20 7a 50 61 74 68 3d 3d 30 20 29 20 7a 50 f( zPath==0 ) zP
1540: 61 74 68 20 3d 20 67 2e 7a 54 6f 70 3b 0a 20 20 ath = g.zTop;.
1550: 69 66 28 20 6c 69 66 65 74 69 6d 65 3e 30 20 29 if( lifetime>0 )
1560: 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a 44 61 74 {. char *zDat
1570: 65 3b 0a 20 20 20 20 6c 69 66 65 74 69 6d 65 20 e;. lifetime
1580: 2b 3d 20 28 69 6e 74 29 74 69 6d 65 28 30 29 3b += (int)time(0);
1590: 0a 20 20 20 20 7a 44 61 74 65 20 3d 20 63 67 69 . zDate = cgi
15a0: 5f 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d _rfc822_datestam
15b0: 70 28 6c 69 66 65 74 69 6d 65 29 3b 0a 20 20 20 p(lifetime);.
15c0: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 blob_appendf(&e
15d0: 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20 20 xtraHeader,.
15e0: 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 "Set-Cookie:
15f0: 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b 20 %s=%t; Path=%s;
1600: 65 78 70 69 72 65 73 3d 25 73 3b 20 56 65 72 73 expires=%s; Vers
1610: 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20 20 ion=1\r\n",.
1620: 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 zName, zValu
1630: 65 2c 20 7a 50 61 74 68 2c 20 7a 44 61 74 65 29 e, zPath, zDate)
1640: 3b 0a 20 20 20 20 69 66 28 20 7a 44 61 74 65 5b ;. if( zDate[
1650: 30 5d 20 29 20 66 72 65 65 28 20 7a 44 61 74 65 0] ) free( zDate
1660: 20 29 3b 0a 20 20 7d 65 6c 73 65 7b 0a 20 20 20 );. }else{.
1670: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 65 blob_appendf(&e
1680: 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20 20 xtraHeader,.
1690: 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a 20 "Set-Cookie:
16a0: 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b 20 %s=%t; Path=%s;
16b0: 56 65 72 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a Version=1\r\n",.
16c0: 20 20 20 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56 zName, zV
16d0: 61 6c 75 65 2c 20 7a 50 61 74 68 29 3b 0a 20 20 alue, zPath);.
16e0: 7d 0a 7d 0a 0a 23 69 66 20 30 0a 2f 2a 0a 2a 2a }.}..#if 0./*.**
16f0: 20 41 64 64 20 61 6e 20 45 54 61 67 20 68 65 61 Add an ETag hea
1700: 64 65 72 20 6c 69 6e 65 0a 2a 2f 0a 73 74 61 74 der line.*/.stat
1710: 69 63 20 63 68 61 72 20 2a 63 67 69 5f 61 64 64 ic char *cgi_add
1720: 5f 65 74 61 67 28 63 68 61 72 20 2a 7a 54 78 74 _etag(char *zTxt
1730: 2c 20 69 6e 74 20 6e 4c 65 6e 29 7b 0a 20 20 4d , int nLen){. M
1740: 44 35 43 6f 6e 74 65 78 74 20 63 74 78 3b 0a 20 D5Context ctx;.
1750: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 64 unsigned char d
1760: 69 67 65 73 74 5b 31 36 5d 3b 0a 20 20 69 6e 74 igest[16];. int
1770: 20 69 2c 20 6a 3b 0a 20 20 63 68 61 72 20 7a 45 i, j;. char zE
1780: 54 61 67 5b 36 34 5d 3b 0a 0a 20 20 4d 44 35 49 Tag[64];.. MD5I
1790: 6e 69 74 28 26 63 74 78 29 3b 0a 20 20 4d 44 35 nit(&ctx);. MD5
17a0: 55 70 64 61 74 65 28 26 63 74 78 2c 7a 54 78 74 Update(&ctx,zTxt
17b0: 2c 6e 4c 65 6e 29 3b 0a 20 20 4d 44 35 46 69 6e ,nLen);. MD5Fin
17c0: 61 6c 28 64 69 67 65 73 74 2c 26 63 74 78 29 3b al(digest,&ctx);
17d0: 0a 20 20 66 6f 72 28 6a 3d 69 3d 30 3b 20 69 3c . for(j=i=0; i<
17e0: 31 36 3b 20 69 2b 2b 2c 6a 2b 3d 32 29 7b 0a 20 16; i++,j+=2){.
17f0: 20 20 20 62 70 72 69 6e 74 66 28 26 7a 45 54 61 bprintf(&zETa
1800: 67 5b 6a 5d 2c 73 69 7a 65 6f 66 28 7a 45 54 61 g[j],sizeof(zETa
1810: 67 29 2d 6a 2c 22 25 30 32 78 22 2c 28 69 6e 74 g)-j,"%02x",(int
1820: 29 64 69 67 65 73 74 5b 69 5d 29 3b 0a 20 20 7d )digest[i]);. }
1830: 0a 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 . blob_appendf(
1840: 26 65 78 74 72 61 48 65 61 64 65 72 2c 20 22 45 &extraHeader, "E
1850: 54 61 67 3a 20 25 73 5c 72 5c 6e 22 2c 20 7a 45 Tag: %s\r\n", zE
1860: 54 61 67 29 3b 0a 20 20 72 65 74 75 72 6e 20 73 Tag);. return s
1870: 74 72 64 75 70 28 7a 45 54 61 67 29 3b 0a 7d 0a trdup(zETag);.}.
1880: 0a 2f 2a 0a 2a 2a 20 44 6f 20 73 6f 6d 65 20 63 ./*.** Do some c
1890: 61 63 68 65 20 63 6f 6e 74 72 6f 6c 20 73 74 75 ache control stu
18a0: 66 66 2e 20 46 69 72 73 74 2c 20 77 65 20 67 65 ff. First, we ge
18b0: 6e 65 72 61 74 65 20 61 6e 20 45 54 61 67 20 61 nerate an ETag a
18c0: 6e 64 20 69 6e 63 6c 75 64 65 20 69 74 20 69 6e nd include it in
18d0: 0a 2a 2a 20 74 68 65 20 72 65 73 70 6f 6e 73 65 .** the response
18e0: 20 68 65 61 64 65 72 73 2e 20 53 65 63 6f 6e 64 headers. Second
18f0: 2c 20 77 65 20 64 6f 20 77 68 61 74 65 76 65 72 , we do whatever
1900: 20 69 73 20 6e 65 63 65 73 73 61 72 79 20 74 6f is necessary to
1910: 20 64 65 74 65 72 6d 69 6e 65 20 69 66 0a 2a 2a determine if.**
1920: 20 74 68 65 20 72 65 71 75 65 73 74 20 77 61 73 the request was
1930: 20 61 73 6b 69 6e 67 20 61 62 6f 75 74 20 63 61 asking about ca
1940: 63 68 69 6e 67 20 61 6e 64 20 77 68 65 74 68 65 ching and whethe
1950: 72 20 77 65 20 6e 65 65 64 20 74 6f 20 73 65 6e r we need to sen
1960: 64 20 62 61 63 6b 20 74 68 65 0a 2a 2a 20 72 65 d back the.** re
1970: 73 70 6f 6e 73 65 20 62 6f 64 79 2e 20 49 66 20 sponse body. If
1980: 77 65 20 73 68 6f 75 6c 64 6e 27 74 20 73 65 6e we shouldn't sen
1990: 64 20 61 20 62 6f 64 79 2c 20 72 65 74 75 72 6e d a body, return
19a0: 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2a 0a 2a 2a non-zero..**.**
19b0: 20 43 75 72 72 65 6e 74 6c 79 2c 20 77 65 20 6a Currently, we j
19c0: 75 73 74 20 63 68 65 63 6b 20 74 68 65 20 45 54 ust check the ET
19d0: 61 67 20 61 67 61 69 6e 73 74 20 61 6e 79 20 49 ag against any I
19e0: 66 2d 4e 6f 6e 65 2d 4d 61 74 63 68 20 68 65 61 f-None-Match hea
19f0: 64 65 72 2e 0a 2a 2a 0a 2a 2a 20 46 49 58 4d 45 der..**.** FIXME
1a00: 3a 20 49 6e 20 73 6f 6d 65 20 63 61 73 65 73 20 : In some cases
1a10: 28 61 74 74 61 63 68 6d 65 6e 74 73 2c 20 66 69 (attachments, fi
1a20: 6c 65 20 63 6f 6e 74 65 6e 74 73 29 20 77 65 20 le contents) we
1a30: 63 6f 75 6c 64 20 63 68 65 63 6b 0a 2a 2a 20 49 could check.** I
1a40: 66 2d 4d 6f 64 69 66 69 65 64 2d 53 69 6e 63 65 f-Modified-Since
1a50: 20 68 65 61 64 65 72 73 20 61 6e 64 20 61 6c 77 headers and alw
1a60: 61 79 73 20 69 6e 63 6c 75 64 65 20 4c 61 73 74 ays include Last
1a70: 2d 4d 6f 64 69 66 69 65 64 20 69 6e 20 72 65 73 -Modified in res
1a80: 70 6f 6e 73 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 ponses..*/.stati
1a90: 63 20 69 6e 74 20 63 68 65 63 6b 5f 63 61 63 68 c int check_cach
1aa0: 65 5f 63 6f 6e 74 72 6f 6c 28 76 6f 69 64 29 7b e_control(void){
1ab0: 0a 20 20 2f 2a 20 46 49 58 4d 45 3a 20 74 68 65 . /* FIXME: the
1ac0: 72 65 27 73 20 73 6f 6d 65 20 67 6f 74 63 68 61 re's some gotcha
1ad0: 73 20 77 74 68 20 63 6f 6f 6b 69 65 73 20 61 6e s wth cookies an
1ae0: 64 20 73 6f 6d 65 20 68 65 61 64 65 72 73 2e 20 d some headers.
1af0: 2a 2f 0a 20 20 63 68 61 72 20 2a 7a 45 54 61 67 */. char *zETag
1b00: 20 3d 20 63 67 69 5f 61 64 64 5f 65 74 61 67 28 = cgi_add_etag(
1b10: 62 6c 6f 62 5f 62 75 66 66 65 72 28 26 63 67 69 blob_buffer(&cgi
1b20: 43 6f 6e 74 65 6e 74 29 2c 62 6c 6f 62 5f 73 69 Content),blob_si
1b30: 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 29 ze(&cgiContent))
1b40: 3b 0a 20 20 63 68 61 72 20 2a 7a 4d 61 74 63 68 ;. char *zMatch
1b50: 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f 4e 4f = P("HTTP_IF_NO
1b60: 4e 45 5f 4d 41 54 43 48 22 29 3b 0a 0a 20 20 69 NE_MATCH");.. i
1b70: 66 28 20 7a 45 54 61 67 21 3d 30 20 26 26 20 7a f( zETag!=0 && z
1b80: 4d 61 74 63 68 21 3d 30 20 29 20 7b 0a 20 20 20 Match!=0 ) {.
1b90: 20 63 68 61 72 20 2a 7a 42 75 66 20 3d 20 73 74 char *zBuf = st
1ba0: 72 64 75 70 28 7a 4d 61 74 63 68 29 3b 0a 20 20 rdup(zMatch);.
1bb0: 20 20 69 66 28 20 7a 42 75 66 21 3d 30 20 29 7b if( zBuf!=0 ){
1bc0: 0a 20 20 20 20 20 20 63 68 61 72 20 2a 7a 54 6f . char *zTo
1bd0: 6b 20 3d 20 30 3b 0a 20 20 20 20 20 20 63 68 61 k = 0;. cha
1be0: 72 20 2a 7a 50 6f 73 3b 0a 20 20 20 20 20 20 66 r *zPos;. f
1bf0: 6f 72 28 20 7a 54 6f 6b 20 3d 20 73 74 72 74 6f or( zTok = strto
1c00: 6b 5f 72 28 7a 42 75 66 2c 20 22 2c 5c 22 22 2c k_r(zBuf, ",\"",
1c10: 26 7a 50 6f 73 29 3b 0a 20 20 20 20 20 20 20 20 &zPos);.
1c20: 20 20 20 7a 54 6f 6b 20 26 26 20 73 74 72 63 61 zTok && strca
1c30: 73 65 63 6d 70 28 7a 54 6f 6b 2c 7a 45 54 61 67 secmp(zTok,zETag
1c40: 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 7a 54 );. zT
1c50: 6f 6b 20 3d 20 20 73 74 72 74 6f 6b 5f 72 28 30 ok = strtok_r(0
1c60: 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 29 7b , ",\"",&zPos)){
1c70: 7d 0a 20 20 20 20 20 20 66 72 65 65 28 7a 42 75 }. free(zBu
1c80: 66 29 3b 0a 20 20 20 20 20 20 69 66 28 7a 54 6f f);. if(zTo
1c90: 6b 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 20 20 k) return 1;.
1ca0: 20 7d 0a 20 20 7d 0a 20 20 0a 20 20 72 65 74 75 }. }. . retu
1cb0: 72 6e 20 30 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a rn 0;.}.#endif..
1cc0: 2f 2a 0a 2a 2a 20 44 6f 20 61 20 6e 6f 72 6d 61 /*.** Do a norma
1cd0: 6c 20 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a l HTTP reply.*/.
1ce0: 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 79 28 76 void cgi_reply(v
1cf0: 6f 69 64 29 7b 0a 20 20 69 6e 74 20 74 6f 74 61 oid){. int tota
1d00: 6c 5f 73 69 7a 65 20 3d 20 30 3b 0a 20 20 69 66 l_size = 0;. if
1d10: 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 3c 3d ( iReplyStatus<=
1d20: 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c 79 53 0 ){. iReplyS
1d30: 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20 20 20 tatus = 200;.
1d40: 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 zReplyStatus =
1d50: 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66 20 30 "OK";. }..#if 0
1d60: 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 74 61 . if( iReplySta
1d70: 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68 65 63 tus==200 && chec
1d80: 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f 6c 28 k_cache_control(
1d90: 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63 68 61 ) ) {. /* cha
1da0: 6e 67 65 20 74 68 65 20 73 74 61 74 75 73 20 74 nge the status t
1db0: 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20 61 6e o "unchanged" an
1dc0: 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20 73 65 d we can skip se
1dd0: 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20 2a 2a nding the. **
1de0: 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e 73 65 actual response
1df0: 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73 6c 79 body. Obviously
1e00: 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68 69 73 we only do this
1e10: 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65 5f 20 when we _have_
1e20: 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20 28 63 a. ** body (c
1e30: 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20 2a 2f ode 200).. */
1e40: 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 74 75 . iReplyStatu
1e50: 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a 52 65 s = 304;. zRe
1e60: 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e 6f 74 plyStatus = "Not
1e70: 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20 7d 0a Modified";. }.
1e80: 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 67 2e #endif.. if( g.
1e90: 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b fullHttpReply ){
1ea0: 0a 20 20 20 20 63 68 61 72 20 2a 7a 44 61 74 65 . char *zDate
1eb0: 20 3d 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 = cgi_rfc822_da
1ec0: 74 65 73 74 61 6d 70 28 74 69 6d 65 28 30 29 29 testamp(time(0))
1ed0: 3b 0a 20 20 20 20 66 70 72 69 6e 74 66 28 67 2e ;. fprintf(g.
1ee0: 68 74 74 70 4f 75 74 2c 20 22 48 54 54 50 2f 31 httpOut, "HTTP/1
1ef0: 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22 2c 20 69 .0 %d %s\r\n", i
1f00: 52 65 70 6c 79 53 74 61 74 75 73 2c 20 7a 52 65 ReplyStatus, zRe
1f10: 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 20 20 20 plyStatus);.
1f20: 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 fprintf(g.httpOu
1f30: 74 2c 20 22 44 61 74 65 3a 20 25 73 5c 72 5c 6e t, "Date: %s\r\n
1f40: 22 2c 20 7a 44 61 74 65 20 29 3b 0a 20 20 20 20 ", zDate );.
1f50: 69 66 28 20 7a 44 61 74 65 5b 30 5d 20 29 20 66 if( zDate[0] ) f
1f60: 72 65 65 28 20 7a 44 61 74 65 20 29 3b 0a 20 20 ree( zDate );.
1f70: 20 20 66 70 72 69 6e 74 66 28 67 2e 68 74 74 70 fprintf(g.http
1f80: 4f 75 74 2c 20 22 43 6f 6e 6e 65 63 74 69 6f 6e Out, "Connection
1f90: 3a 20 63 6c 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20 : close\r\n");.
1fa0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 66 70 72 69 }else{. fpri
1fb0: 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 ntf(g.httpOut, "
1fc0: 53 74 61 74 75 73 3a 20 25 64 20 25 73 5c 72 5c Status: %d %s\r\
1fd0: 6e 22 2c 20 69 52 65 70 6c 79 53 74 61 74 75 73 n", iReplyStatus
1fe0: 2c 20 7a 52 65 70 6c 79 53 74 61 74 75 73 29 3b , zReplyStatus);
1ff0: 0a 20 20 7d 0a 0a 20 20 69 66 28 20 62 6c 6f 62 . }.. if( blob
2000: 5f 73 69 7a 65 28 26 65 78 74 72 61 48 65 61 64 _size(&extraHead
2010: 65 72 29 3e 30 20 29 7b 0a 20 20 20 20 66 70 72 er)>0 ){. fpr
2020: 69 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 intf(g.httpOut,
2030: 22 25 73 22 2c 20 62 6c 6f 62 5f 62 75 66 66 65 "%s", blob_buffe
2040: 72 28 26 65 78 74 72 61 48 65 61 64 65 72 29 29 r(&extraHeader))
2050: 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 67 2e 69 ;. }.. if( g.i
2060: 73 43 6f 6e 73 74 20 29 7b 0a 20 20 20 20 2f 2a sConst ){. /*
2070: 20 63 6f 6e 73 74 61 6e 74 20 6d 65 61 6e 73 20 constant means
2080: 74 68 61 74 20 74 68 65 20 69 6e 70 75 74 20 55 that the input U
2090: 52 4c 20 77 69 6c 6c 20 5f 6e 65 76 65 72 5f 20 RL will _never_
20a0: 67 65 6e 65 72 61 74 65 20 61 6e 79 74 68 69 6e generate anythin
20b0: 67 0a 20 20 20 20 2a 2a 20 65 6c 73 65 2e 20 49 g. ** else. I
20c0: 6e 20 74 68 65 20 63 61 73 65 20 6f 66 20 61 74 n the case of at
20d0: 74 61 63 68 6d 65 6e 74 73 2c 20 74 68 65 20 63 tachments, the c
20e0: 6f 6e 74 65 6e 74 73 20 77 6f 6e 27 74 20 63 68 ontents won't ch
20f0: 61 6e 67 65 20 62 65 63 61 75 73 65 0a 20 20 20 ange because.
2100: 20 2a 2a 20 61 6e 20 61 74 74 65 6d 70 74 20 74 ** an attempt t
2110: 6f 20 63 68 61 6e 67 65 20 74 68 65 6d 20 67 65 o change them ge
2120: 6e 65 72 61 74 65 73 20 61 20 6e 65 77 20 61 74 nerates a new at
2130: 74 61 63 68 6d 65 6e 74 20 6e 75 6d 62 65 72 2e tachment number.
2140: 20 49 6e 20 74 68 65 0a 20 20 20 20 2a 2a 20 63 In the. ** c
2150: 61 73 65 20 6f 66 20 6d 6f 73 74 20 2f 67 65 74 ase of most /get
2160: 66 69 6c 65 20 63 61 6c 6c 73 20 66 6f 72 20 73 file calls for s
2170: 70 65 63 69 66 69 63 20 76 65 72 73 69 6f 6e 73 pecific versions
2180: 2c 20 74 68 65 20 6f 6e 6c 79 20 77 61 79 20 74 , the only way t
2190: 68 65 0a 20 20 20 20 2a 2a 20 63 6f 6e 74 65 6e he. ** conten
21a0: 74 20 63 68 61 6e 67 65 73 20 69 73 20 69 66 20 t changes is if
21b0: 73 6f 6d 65 6f 6e 65 20 62 72 65 61 6b 73 20 74 someone breaks t
21c0: 68 65 20 53 43 4d 2e 20 41 6e 64 20 69 66 20 74 he SCM. And if t
21d0: 68 61 74 20 68 61 70 70 65 6e 73 2c 20 61 0a 20 hat happens, a.
21e0: 20 20 20 2a 2a 20 73 74 61 6c 65 20 63 61 63 68 ** stale cach
21f0: 65 20 69 73 20 74 68 65 20 6c 65 61 73 74 20 6f e is the least o
2200: 66 20 74 68 65 20 70 72 6f 62 6c 65 6d 2e 20 53 f the problem. S
2210: 6f 20 77 65 20 70 72 6f 76 69 64 65 20 61 6e 20 o we provide an
2220: 45 78 70 69 72 65 73 0a 20 20 20 20 2a 2a 20 68 Expires. ** h
2230: 65 61 64 65 72 20 73 65 74 20 74 6f 20 61 20 72 eader set to a r
2240: 65 61 73 6f 6e 61 62 6c 65 20 70 65 72 69 6f 64 easonable period
2250: 20 28 64 65 66 61 75 6c 74 3a 20 6f 6e 65 20 77 (default: one w
2260: 65 65 6b 29 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 eek).. */.
2270: 20 2f 2a 74 69 6d 65 5f 74 20 65 78 70 69 72 65 /*time_t expire
2280: 73 20 3d 20 74 69 6d 65 28 30 29 20 2b 20 61 74 s = time(0) + at
2290: 6f 69 28 64 62 5f 63 6f 6e 66 69 67 28 22 63 6f oi(db_config("co
22a0: 6e 73 74 61 6e 74 5f 65 78 70 69 72 65 73 22 2c nstant_expires",
22b0: 22 36 30 34 38 30 30 22 29 29 3b 2a 2f 0a 20 20 "604800"));*/.
22c0: 20 20 74 69 6d 65 5f 74 20 65 78 70 69 72 65 73 time_t expires
22d0: 20 3d 20 74 69 6d 65 28 30 29 20 2b 20 36 30 34 = time(0) + 604
22e0: 38 30 30 3b 0a 20 20 20 20 63 68 61 72 20 2a 20 800;. char *
22f0: 7a 44 61 74 65 20 3d 20 63 67 69 5f 72 66 63 38 zDate = cgi_rfc8
2300: 32 32 5f 64 61 74 65 73 74 61 6d 70 28 65 78 70 22_datestamp(exp
2310: 69 72 65 73 29 3b 0a 20 20 20 20 66 70 72 69 6e ires);. fprin
2320: 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 45 tf(g.httpOut, "E
2330: 78 70 69 72 65 73 3a 20 25 73 5c 72 5c 6e 22 2c xpires: %s\r\n",
2340: 20 7a 44 61 74 65 20 29 3b 0a 20 20 20 20 69 66 zDate );. if
2350: 28 20 7a 44 61 74 65 5b 30 5d 20 29 20 66 72 65 ( zDate[0] ) fre
2360: 65 28 20 7a 44 61 74 65 20 29 3b 0a 20 20 7d 0a e( zDate );. }.
2370: 0a 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 69 6e . /* Content in
2380: 74 65 6e 64 65 64 20 66 6f 72 20 6c 6f 67 67 65 tended for logge
2390: 64 20 69 6e 20 75 73 65 72 73 20 73 68 6f 75 6c d in users shoul
23a0: 64 20 6f 6e 6c 79 20 62 65 20 63 61 63 68 65 64 d only be cached
23b0: 20 69 6e 0a 20 20 2a 2a 20 74 68 65 20 62 72 6f in. ** the bro
23c0: 77 73 65 72 2c 20 6e 6f 74 20 73 6f 6d 65 20 73 wser, not some s
23d0: 68 61 72 65 64 20 6c 6f 63 61 74 69 6f 6e 2e 0a hared location..
23e0: 20 20 2a 2f 0a 20 20 66 70 72 69 6e 74 66 28 67 */. fprintf(g
23f0: 2e 68 74 74 70 4f 75 74 2c 20 22 43 61 63 68 65 .httpOut, "Cache
2400: 2d 63 6f 6e 74 72 6f 6c 3a 20 6e 6f 2d 63 61 63 -control: no-cac
2410: 68 65 2c 20 6e 6f 2d 73 74 6f 72 65 5c 72 5c 6e he, no-store\r\n
2420: 22 29 3b 0a 20 20 66 70 72 69 6e 74 66 28 67 2e ");. fprintf(g.
2430: 68 74 74 70 4f 75 74 2c 20 22 43 6f 6e 74 65 6e httpOut, "Conten
2440: 74 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 72 t-Type: %s; char
2450: 73 65 74 3d 75 74 66 2d 38 5c 72 5c 6e 22 2c 20 set=utf-8\r\n",
2460: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 29 3b 0a 20 zContentType);.
2470: 20 69 66 28 20 73 74 72 63 6d 70 28 7a 43 6f 6e if( strcmp(zCon
2480: 74 65 6e 74 54 79 70 65 2c 22 61 70 70 6c 69 63 tentType,"applic
2490: 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 69 6c 22 29 ation/x-fossil")
24a0: 3d 3d 30 20 29 7b 0a 20 20 20 20 63 67 69 5f 63 ==0 ){. cgi_c
24b0: 6f 6d 62 69 6e 65 5f 68 65 61 64 65 72 5f 61 6e ombine_header_an
24c0: 64 5f 62 6f 64 79 28 29 3b 0a 20 20 20 20 62 6c d_body();. bl
24d0: 6f 62 5f 63 6f 6d 70 72 65 73 73 28 26 63 67 69 ob_compress(&cgi
24e0: 43 6f 6e 74 65 6e 74 5b 30 5d 2c 20 26 63 67 69 Content[0], &cgi
24f0: 43 6f 6e 74 65 6e 74 5b 30 5d 29 3b 0a 20 20 7d Content[0]);. }
2500: 0a 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 74 .. if( iReplySt
2510: 61 74 75 73 20 21 3d 20 33 30 34 20 29 20 7b 0a atus != 304 ) {.
2520: 20 20 20 20 74 6f 74 61 6c 5f 73 69 7a 65 20 3d total_size =
2530: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 blob_size(&cgiC
2540: 6f 6e 74 65 6e 74 5b 30 5d 29 20 2b 20 62 6c 6f ontent[0]) + blo
2550: 62 5f 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 b_size(&cgiConte
2560: 6e 74 5b 31 5d 29 3b 0a 20 20 20 20 66 70 72 69 nt[1]);. fpri
2570: 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 ntf(g.httpOut, "
2580: 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 Content-Length:
2590: 25 64 5c 72 5c 6e 22 2c 20 74 6f 74 61 6c 5f 73 %d\r\n", total_s
25a0: 69 7a 65 29 3b 0a 20 20 7d 0a 20 20 66 70 72 69 ize);. }. fpri
25b0: 6e 74 66 28 67 2e 68 74 74 70 4f 75 74 2c 20 22 ntf(g.httpOut, "
25c0: 5c 72 5c 6e 22 29 3b 0a 20 20 69 66 28 20 74 6f \r\n");. if( to
25d0: 74 61 6c 5f 73 69 7a 65 3e 30 20 26 26 20 69 52 tal_size>0 && iR
25e0: 65 70 6c 79 53 74 61 74 75 73 20 21 3d 20 33 30 eplyStatus != 30
25f0: 34 20 29 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20 4 ){. int i,
2600: 73 69 7a 65 3b 0a 20 20 20 20 66 6f 72 28 69 3d size;. for(i=
2610: 30 3b 20 69 3c 32 3b 20 69 2b 2b 29 7b 0a 20 20 0; i<2; i++){.
2620: 20 20 20 20 73 69 7a 65 20 3d 20 62 6c 6f 62 5f size = blob_
2630: 73 69 7a 65 28 26 63 67 69 43 6f 6e 74 65 6e 74 size(&cgiContent
2640: 5b 69 5d 29 3b 0a 20 20 20 20 20 20 69 66 28 20 [i]);. if(
2650: 73 69 7a 65 3e 30 20 29 7b 0a 20 20 20 20 20 20 size>0 ){.
2660: 20 20 66 77 72 69 74 65 28 62 6c 6f 62 5f 62 75 fwrite(blob_bu
2670: 66 66 65 72 28 26 63 67 69 43 6f 6e 74 65 6e 74 ffer(&cgiContent
2680: 5b 69 5d 29 2c 20 31 2c 20 73 69 7a 65 2c 20 67 [i]), 1, size, g
2690: 2e 68 74 74 70 4f 75 74 29 3b 0a 20 20 20 20 20 .httpOut);.
26a0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 43 }. }. }. C
26b0: 47 49 44 45 42 55 47 28 28 22 44 4f 4e 45 5c 6e GIDEBUG(("DONE\n
26c0: 22 29 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 6f "));.}../*.** Do
26d0: 20 61 20 72 65 64 69 72 65 63 74 20 72 65 71 75 a redirect requ
26e0: 65 73 74 20 74 6f 20 74 68 65 20 55 52 4c 20 67 est to the URL g
26f0: 69 76 65 6e 20 69 6e 20 74 68 65 20 61 72 67 75 iven in the argu
2700: 6d 65 6e 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 ment..**.** The
2710: 55 52 4c 20 6d 75 73 74 20 62 65 20 72 65 6c 61 URL must be rela
2720: 74 69 76 65 20 74 6f 20 74 68 65 20 62 61 73 65 tive to the base
2730: 20 6f 66 20 74 68 65 20 66 6f 73 73 69 6c 20 73 of the fossil s
2740: 65 72 76 65 72 2e 0a 2a 2f 0a 76 6f 69 64 20 63 erver..*/.void c
2750: 67 69 5f 72 65 64 69 72 65 63 74 28 63 6f 6e 73 gi_redirect(cons
2760: 74 20 63 68 61 72 20 2a 7a 55 52 4c 29 7b 0a 20 t char *zURL){.
2770: 20 63 68 61 72 20 2a 7a 4c 6f 63 61 74 69 6f 6e char *zLocation
2780: 3b 0a 20 20 43 47 49 44 45 42 55 47 28 28 22 72 ;. CGIDEBUG(("r
2790: 65 64 69 72 65 63 74 20 74 6f 20 25 73 5c 6e 22 edirect to %s\n"
27a0: 2c 20 7a 55 52 4c 29 29 3b 0a 20 20 69 66 28 20 , zURL));. if(
27b0: 73 74 72 6e 63 6d 70 28 7a 55 52 4c 2c 22 68 74 strncmp(zURL,"ht
27c0: 74 70 3a 22 2c 35 29 3d 3d 30 20 7c 7c 20 73 74 tp:",5)==0 || st
27d0: 72 6e 63 6d 70 28 7a 55 52 4c 2c 22 68 74 74 70 rncmp(zURL,"http
27e0: 73 3a 22 2c 36 29 3d 3d 30 20 7c 7c 20 2a 7a 55 s:",6)==0 || *zU
27f0: 52 4c 3d 3d 27 2f 27 20 29 7b 0a 20 20 20 20 7a RL=='/' ){. z
2800: 4c 6f 63 61 74 69 6f 6e 20 3d 20 6d 70 72 69 6e Location = mprin
2810: 74 66 28 22 4c 6f 63 61 74 69 6f 6e 3a 20 25 73 tf("Location: %s
2820: 5c 72 5c 6e 22 2c 20 7a 55 52 4c 29 3b 0a 20 20 \r\n", zURL);.
2830: 7d 65 6c 73 65 7b 0a 20 20 20 20 7a 4c 6f 63 61 }else{. zLoca
2840: 74 69 6f 6e 20 3d 20 6d 70 72 69 6e 74 66 28 22 tion = mprintf("
2850: 4c 6f 63 61 74 69 6f 6e 3a 20 25 73 2f 25 73 5c Location: %s/%s\
2860: 72 5c 6e 22 2c 20 67 2e 7a 42 61 73 65 55 52 4c r\n", g.zBaseURL
2870: 2c 20 7a 55 52 4c 29 3b 0a 20 20 7d 0a 20 20 63 , zURL);. }. c
2880: 67 69 5f 61 70 70 65 6e 64 5f 68 65 61 64 65 72 gi_append_header
2890: 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a 20 20 63 (zLocation);. c
28a0: 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 gi_reset_content
28b0: 28 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 ();. cgi_printf
28c0: 28 22 3c 68 74 6d 6c 3e 5c 6e 3c 70 3e 52 65 64 ("<html>\n<p>Red
28d0: 69 72 65 63 74 20 74 6f 20 25 68 3c 2f 70 3e 5c irect to %h</p>\
28e0: 6e 3c 2f 68 74 6d 6c 3e 5c 6e 22 2c 20 7a 55 52 n</html>\n", zUR
28f0: 4c 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 L);. cgi_set_st
2900: 61 74 75 73 28 33 30 32 2c 20 22 4d 6f 76 65 64 atus(302, "Moved
2910: 20 54 65 6d 70 6f 72 61 72 69 6c 79 22 29 3b 0a Temporarily");.
2920: 20 20 66 72 65 65 28 7a 4c 6f 63 61 74 69 6f 6e free(zLocation
2930: 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 );. cgi_reply()
2940: 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a 76 ;. exit(0);.}.v
2950: 6f 69 64 20 63 67 69 5f 72 65 64 69 72 65 63 74 oid cgi_redirect
2960: 66 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 f(const char *zF
2970: 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 ormat, ...){. v
2980: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 5f a_list ap;. va_
2990: 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 start(ap, zForma
29a0: 74 29 3b 0a 20 20 63 67 69 5f 72 65 64 69 72 65 t);. cgi_redire
29b0: 63 74 28 76 6d 70 72 69 6e 74 66 28 7a 46 6f 72 ct(vmprintf(zFor
29c0: 6d 61 74 2c 20 61 70 29 29 3b 0a 20 20 76 61 5f mat, ap));. va_
29d0: 65 6e 64 28 61 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a end(ap);.}../*.*
29e0: 2a 20 49 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 * Information ab
29f0: 6f 75 74 20 61 6c 6c 20 71 75 65 72 79 20 70 61 out all query pa
2a00: 72 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f rameters and coo
2a10: 6b 69 65 73 20 61 72 65 20 73 74 6f 72 65 64 0a kies are stored.
2a20: 2a 2a 20 69 6e 20 74 68 65 73 65 20 76 61 72 69 ** in these vari
2a30: 61 62 6c 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 ables..*/.static
2a40: 20 69 6e 74 20 6e 41 6c 6c 6f 63 51 50 20 3d 20 int nAllocQP =
2a50: 30 3b 20 2f 2a 20 53 70 61 63 65 20 61 6c 6c 6f 0; /* Space allo
2a60: 63 61 74 65 64 20 66 6f 72 20 61 50 61 72 61 6d cated for aParam
2a70: 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 QP[] */.static i
2a80: 6e 74 20 6e 55 73 65 64 51 50 20 3d 20 30 3b 20 nt nUsedQP = 0;
2a90: 20 2f 2a 20 53 70 61 63 65 20 61 63 74 75 61 6c /* Space actual
2aa0: 6c 79 20 75 73 65 64 20 69 6e 20 61 50 61 72 61 ly used in aPara
2ab0: 6d 51 50 5b 5d 20 2a 2f 0a 73 74 61 74 69 63 20 mQP[] */.static
2ac0: 69 6e 74 20 73 6f 72 74 51 50 20 3d 20 30 3b 20 int sortQP = 0;
2ad0: 20 20 2f 2a 20 54 72 75 65 20 69 66 20 61 50 61 /* True if aPa
2ae0: 72 61 6d 51 50 5b 5d 20 6e 65 65 64 73 20 73 6f ramQP[] needs so
2af0: 72 74 69 6e 67 20 2a 2f 0a 73 74 61 74 69 63 20 rting */.static
2b00: 69 6e 74 20 73 65 71 51 50 20 3d 20 30 3b 20 20 int seqQP = 0;
2b10: 20 20 2f 2a 20 53 65 71 75 65 6e 63 65 20 6e 75 /* Sequence nu
2b20: 6d 62 65 72 73 20 2a 2f 0a 73 74 61 74 69 63 20 mbers */.static
2b30: 73 74 72 75 63 74 20 51 50 61 72 61 6d 20 7b 20 struct QParam {
2b40: 20 20 2f 2a 20 4f 6e 65 20 65 6e 74 72 79 20 66 /* One entry f
2b50: 6f 72 20 65 61 63 68 20 71 75 65 72 79 20 70 61 or each query pa
2b60: 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 rameter or cooki
2b70: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 e */. const cha
2b80: 72 20 2a 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 r *zName;
2b90: 20 2f 2a 20 50 61 72 61 6d 65 74 65 72 20 6f 72 /* Parameter or
2ba0: 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 20 2a 2f 0a cookie name */.
2bb0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 const char *zV
2bc0: 61 6c 75 65 3b 20 20 20 20 20 20 20 2f 2a 20 56 alue; /* V
2bd0: 61 6c 75 65 20 6f 66 20 74 68 65 20 71 75 65 72 alue of the quer
2be0: 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 y parameter or c
2bf0: 6f 6f 6b 69 65 20 2a 2f 0a 20 20 69 6e 74 20 73 ookie */. int s
2c00: 65 71 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 eq;
2c10: 20 20 20 20 20 2f 2a 20 4f 72 64 65 72 20 6f 66 /* Order of
2c20: 20 69 6e 73 65 72 74 69 6f 6e 20 2a 2f 0a 7d 20 insertion */.}
2c30: 2a 61 50 61 72 61 6d 51 50 3b 20 20 20 20 20 20 *aParamQP;
2c40: 20 20 20 20 20 20 20 2f 2a 20 41 6e 20 61 72 72 /* An arr
2c50: 61 79 20 6f 66 20 61 6c 6c 20 70 61 72 61 6d 65 ay of all parame
2c60: 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 ters and cookies
2c70: 20 2a 2f 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 */../*.** Add a
2c80: 6e 6f 74 68 65 72 20 71 75 65 72 79 20 70 61 72 nother query par
2c90: 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 ameter or cookie
2ca0: 20 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 to the paramete
2cb0: 72 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 r set..** zName
2cc0: 69 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 is the name of t
2cd0: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 he query paramet
2ce0: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61 6e 64 er or cookie and
2cf0: 20 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20 69 74 zValue.** is it
2d00: 73 20 66 75 6c 6c 79 20 64 65 63 6f 64 65 64 20 s fully decoded
2d10: 76 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 7a 4e 61 value..**.** zNa
2d20: 6d 65 20 61 6e 64 20 7a 56 61 6c 75 65 20 61 72 me and zValue ar
2d30: 65 20 6e 6f 74 20 63 6f 70 69 65 64 20 61 6e 64 e not copied and
2d40: 20 6d 75 73 74 20 6e 6f 74 20 63 68 61 6e 67 65 must not change
2d50: 20 6f 72 20 62 65 0a 2a 2a 20 64 65 61 6c 6c 6f or be.** deallo
2d60: 63 61 74 65 64 20 61 66 74 65 72 20 74 68 69 73 cated after this
2d70: 20 72 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 routine returns
2d80: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 ..*/.void cgi_se
2d90: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f t_parameter_noco
2da0: 70 79 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a py(const char *z
2db0: 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 Name, const char
2dc0: 20 2a 7a 56 61 6c 75 65 29 7b 0a 20 20 69 66 28 *zValue){. if(
2dd0: 20 6e 41 6c 6c 6f 63 51 50 3c 3d 6e 55 73 65 64 nAllocQP<=nUsed
2de0: 51 50 20 29 7b 0a 20 20 20 20 6e 41 6c 6c 6f 63 QP ){. nAlloc
2df0: 51 50 20 3d 20 6e 41 6c 6c 6f 63 51 50 2a 32 20 QP = nAllocQP*2
2e00: 2b 20 31 30 3b 0a 20 20 20 20 61 50 61 72 61 6d + 10;. aParam
2e10: 51 50 20 3d 20 72 65 61 6c 6c 6f 63 28 20 61 50 QP = realloc( aP
2e20: 61 72 61 6d 51 50 2c 20 6e 41 6c 6c 6f 63 51 50 aramQP, nAllocQP
2e30: 2a 73 69 7a 65 6f 66 28 61 50 61 72 61 6d 51 50 *sizeof(aParamQP
2e40: 5b 30 5d 29 20 29 3b 0a 20 20 20 20 69 66 28 20 [0]) );. if(
2e50: 61 50 61 72 61 6d 51 50 3d 3d 30 20 29 20 65 78 aParamQP==0 ) ex
2e60: 69 74 28 31 29 3b 0a 20 20 7d 0a 20 20 61 50 61 it(1);. }. aPa
2e70: 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a ramQP[nUsedQP].z
2e80: 4e 61 6d 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20 Name = zName;.
2e90: 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 aParamQP[nUsedQP
2ea0: 5d 2e 7a 56 61 6c 75 65 20 3d 20 7a 56 61 6c 75 ].zValue = zValu
2eb0: 65 3b 0a 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 e;. aParamQP[nU
2ec0: 73 65 64 51 50 5d 2e 73 65 71 20 3d 20 73 65 71 sedQP].seq = seq
2ed0: 51 50 2b 2b 3b 0a 20 20 6e 55 73 65 64 51 50 2b QP++;. nUsedQP+
2ee0: 2b 3b 0a 20 20 73 6f 72 74 51 50 20 3d 20 31 3b +;. sortQP = 1;
2ef0: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e .}../*.** Add an
2f00: 6f 74 68 65 72 20 71 75 65 72 79 20 70 61 72 61 other query para
2f10: 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 meter or cookie
2f20: 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 to the parameter
2f30: 20 73 65 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 69 set..** zName i
2f40: 73 20 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 s the name of th
2f50: 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 e query paramete
2f60: 72 20 6f 72 20 63 6f 6f 6b 69 65 20 61 6e 64 20 r or cookie and
2f70: 7a 56 61 6c 75 65 0a 2a 2a 20 69 73 20 69 74 73 zValue.** is its
2f80: 20 66 75 6c 6c 79 20 64 65 63 6f 64 65 64 20 76 fully decoded v
2f90: 61 6c 75 65 2e 0a 2a 2a 0a 2a 2a 20 43 6f 70 69 alue..**.** Copi
2fa0: 65 73 20 61 72 65 20 6d 61 64 65 20 6f 66 20 62 es are made of b
2fb0: 6f 74 68 20 74 68 65 20 7a 4e 61 6d 65 20 61 6e oth the zName an
2fc0: 64 20 7a 56 61 6c 75 65 20 70 61 72 61 6d 65 74 d zValue paramet
2fd0: 65 72 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 ers..*/.void cgi
2fe0: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 28 63 _set_parameter(c
2ff0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 onst char *zName
3000: 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 , const char *zV
3010: 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f 73 65 74 alue){. cgi_set
3020: 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 _parameter_nocop
3030: 79 28 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a y(mprintf("%s",z
3040: 4e 61 6d 65 29 2c 20 6d 70 72 69 6e 74 66 28 22 Name), mprintf("
3050: 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a %s",zValue));.}.
3060: 0a 2f 2a 0a 2a 2a 20 52 65 70 6c 61 63 65 20 61 ./*.** Replace a
3070: 20 70 61 72 61 6d 65 74 65 72 20 77 69 74 68 20 parameter with
3080: 61 20 6e 65 77 20 76 61 6c 75 65 2e 0a 2a 2f 0a a new value..*/.
3090: 76 6f 69 64 20 63 67 69 5f 72 65 70 6c 61 63 65 void cgi_replace
30a0: 5f 70 61 72 61 6d 65 74 65 72 28 63 6f 6e 73 74 _parameter(const
30b0: 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 6f char *zName, co
30c0: 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 65 nst char *zValue
30d0: 29 7b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 66 6f ){. int i;. fo
30e0: 72 28 69 3d 30 3b 20 69 3c 6e 55 73 65 64 51 50 r(i=0; i<nUsedQP
30f0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 ; i++){. if(
3100: 73 74 72 63 6d 70 28 61 50 61 72 61 6d 51 50 5b strcmp(aParamQP[
3110: 69 5d 2e 7a 4e 61 6d 65 2c 7a 4e 61 6d 65 29 3d i].zName,zName)=
3120: 3d 30 20 29 7b 0a 20 20 20 20 20 20 61 50 61 72 =0 ){. aPar
3130: 61 6d 51 50 5b 69 5d 2e 7a 56 61 6c 75 65 20 3d amQP[i].zValue =
3140: 20 7a 56 61 6c 75 65 3b 0a 20 20 20 20 20 20 72 zValue;. r
3150: 65 74 75 72 6e 3b 0a 20 20 20 20 7d 0a 20 20 7d eturn;. }. }
3160: 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d . cgi_set_param
3170: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d eter_nocopy(zNam
3180: 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 7d 0a 0a 2f e, zValue);.}../
3190: 2a 0a 2a 2a 20 41 64 64 20 61 20 71 75 65 72 79 *.** Add a query
31a0: 20 70 61 72 61 6d 65 74 65 72 2e 20 20 54 68 65 parameter. The
31b0: 20 7a 4e 61 6d 65 20 70 6f 72 74 69 6f 6e 20 69 zName portion i
31c0: 73 20 66 69 78 65 64 20 62 75 74 20 61 20 63 6f s fixed but a co
31d0: 70 79 0a 2a 2a 20 6d 75 73 74 20 62 65 20 6d 61 py.** must be ma
31e0: 64 65 20 6f 66 20 7a 56 61 6c 75 65 2e 0a 2a 2f de of zValue..*/
31f0: 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 65 6e 76 .void cgi_setenv
3200: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 (const char *zNa
3210: 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a me, const char *
3220: 7a 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f 73 zValue){. cgi_s
3230: 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 et_parameter_noc
3240: 6f 70 79 28 7a 4e 61 6d 65 2c 20 6d 70 72 69 6e opy(zName, mprin
3250: 74 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29 29 tf("%s",zValue))
3260: 3b 0a 7d 0a 20 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 ;.}. ../*.** Add
3270: 20 61 20 6c 69 73 74 20 6f 66 20 71 75 65 72 79 a list of query
3280: 20 70 61 72 61 6d 65 74 65 72 73 20 6f 72 20 63 parameters or c
3290: 6f 6f 6b 69 65 73 20 74 6f 20 74 68 65 20 70 61 ookies to the pa
32a0: 72 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a 0a rameter set..**.
32b0: 2a 2a 20 45 61 63 68 20 70 61 72 61 6d 65 74 65 ** Each paramete
32c0: 72 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d r is of the form
32d0: 20 4e 41 4d 45 3d 56 41 4c 55 45 2e 20 20 42 6f NAME=VALUE. Bo
32e0: 74 68 20 74 68 65 20 4e 41 4d 45 20 61 6e 64 20 th the NAME and
32f0: 74 68 65 0a 2a 2a 20 56 41 4c 55 45 20 6d 61 79 the.** VALUE may
3300: 20 62 65 20 75 72 6c 2d 65 6e 63 6f 64 65 64 20 be url-encoded
3310: 28 22 2b 22 20 66 6f 72 20 73 70 61 63 65 2c 20 ("+" for space,
3320: 22 25 48 48 22 20 66 6f 72 20 6f 74 68 65 72 20 "%HH" for other
3330: 73 70 65 63 69 61 6c 0a 2a 2a 20 63 68 61 72 61 special.** chara
3340: 63 74 65 72 73 29 2e 20 20 42 75 74 20 74 68 69 cters). But thi
3350: 73 20 72 6f 75 74 69 6e 65 20 61 73 73 75 6d 65 s routine assume
3360: 73 20 74 68 61 74 20 4e 41 4d 45 20 63 6f 6e 74 s that NAME cont
3370: 61 69 6e 73 20 6e 6f 0a 2a 2a 20 73 70 65 63 69 ains no.** speci
3380: 61 6c 20 63 68 61 72 61 63 74 65 72 20 61 6e 64 al character and
3390: 20 74 68 65 72 65 66 6f 72 65 20 64 6f 65 73 20 therefore does
33a0: 6e 6f 74 20 64 65 63 6f 64 65 20 69 74 2e 0a 2a not decode it..*
33b0: 2a 0a 2a 2a 20 49 66 20 4e 41 4d 45 20 62 65 67 *.** If NAME beg
33c0: 69 6e 73 20 77 69 74 68 20 61 6e 6f 74 68 65 72 ins with another
33d0: 20 6f 74 68 65 72 20 74 68 61 6e 20 61 20 6c 6f other than a lo
33e0: 77 65 72 2d 63 61 73 65 20 6c 65 74 74 65 72 20 wer-case letter
33f0: 74 68 65 6e 0a 2a 2a 20 74 68 65 20 65 6e 74 69 then.** the enti
3400: 72 65 20 4e 41 4d 45 3d 56 41 4c 55 45 20 74 65 re NAME=VALUE te
3410: 72 6d 20 69 73 20 69 67 6e 6f 72 65 64 2e 20 20 rm is ignored.
3420: 48 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 Hence:.**.**
3430: 20 20 2a 20 20 63 6f 6f 6b 69 65 73 20 61 6e 64 * cookies and
3440: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 query parameter
3450: 73 20 74 68 61 74 20 68 61 76 65 20 75 70 70 65 s that have uppe
3460: 72 63 61 73 65 20 6e 61 6d 65 73 0a 2a 2a 20 20 rcase names.**
3470: 20 20 20 20 20 20 20 61 72 65 20 69 67 6e 6f 72 are ignor
3480: 65 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a ed..**.** *
3490: 20 20 69 74 20 69 73 20 69 6d 70 6f 73 73 69 62 it is impossib
34a0: 6c 65 20 66 6f 72 20 61 20 63 6f 6f 6b 69 65 20 le for a cookie
34b0: 6f 72 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 or query paramet
34c0: 65 72 20 74 6f 0a 2a 2a 20 20 20 20 20 20 20 20 er to.**
34d0: 20 6f 76 65 72 72 69 64 65 20 74 68 65 20 76 61 override the va
34e0: 6c 75 65 20 6f 66 20 61 6e 20 65 6e 76 69 72 6f lue of an enviro
34f0: 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 73 nment variable s
3500: 69 6e 63 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 ince.**
3510: 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 environment vari
3520: 61 62 6c 65 73 20 61 6c 77 61 79 73 20 68 61 76 ables always hav
3530: 65 20 75 70 70 65 72 63 61 73 65 20 6e 61 6d 65 e uppercase name
3540: 73 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 s..**.** Paramet
3550: 65 72 73 20 61 72 65 20 73 65 70 61 72 61 74 65 ers are separate
3560: 64 20 62 79 20 74 68 65 20 22 74 65 72 6d 69 6e d by the "termin
3570: 61 74 6f 72 22 20 63 68 61 72 61 63 74 65 72 2e ator" character.
3580: 20 20 57 68 69 74 65 73 70 61 63 65 0a 2a 2a 20 Whitespace.**
3590: 62 65 66 6f 72 65 20 74 68 65 20 4e 41 4d 45 20 before the NAME
35a0: 69 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a is ignored..**.*
35b0: 2a 20 54 68 65 20 69 6e 70 75 74 20 73 74 72 69 * The input stri
35c0: 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66 69 ng "z" is modifi
35d0: 65 64 20 62 75 74 20 6e 6f 20 63 6f 70 69 65 73 ed but no copies
35e0: 20 69 73 20 6d 61 64 65 2e 20 20 22 7a 22 0a 2a is made. "z".*
35f0: 2a 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62 65 20 * should not be
3600: 64 65 61 6c 6c 6f 63 61 74 65 64 20 6f 72 20 63 deallocated or c
3610: 68 61 6e 67 65 64 20 61 67 61 69 6e 20 61 66 74 hanged again aft
3620: 65 72 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a er this routine.
3630: 2a 2a 20 72 65 74 75 72 6e 73 20 6f 72 20 69 74 ** returns or it
3640: 20 77 69 6c 6c 20 63 6f 72 72 75 70 74 20 74 68 will corrupt th
3650: 65 20 70 61 72 61 6d 65 74 65 72 20 74 61 62 6c e parameter tabl
3660: 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 e..*/.static voi
3670: 64 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 d add_param_list
3680: 28 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 74 65 (char *z, int te
3690: 72 6d 69 6e 61 74 6f 72 29 7b 0a 20 20 77 68 69 rminator){. whi
36a0: 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 63 68 le( *z ){. ch
36b0: 61 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 63 ar *zName;. c
36c0: 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20 20 har *zValue;.
36d0: 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 while( isspace(
36e0: 2a 7a 29 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 *z) ){ z++; }.
36f0: 20 20 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 zName = z;.
3700: 20 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a while( *z && *z
3710: 21 3d 27 3d 27 20 26 26 20 2a 7a 21 3d 74 65 72 !='=' && *z!=ter
3720: 6d 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b 3b 20 minator ){ z++;
3730: 7d 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27 3d }. if( *z=='=
3740: 27 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 20 ' ){. *z =
3750: 30 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 0;. z++;.
3760: 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 7a 3b 0a zValue = z;.
3770: 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 while( *z
3780: 26 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 74 6f && *z!=terminato
3790: 72 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 r ){ z++; }.
37a0: 20 20 69 66 28 20 2a 7a 20 29 7b 0a 20 20 20 20 if( *z ){.
37b0: 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 *z = 0;.
37c0: 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d z++;. }
37d0: 0a 20 20 20 20 20 20 64 65 68 74 74 70 69 7a 65 . dehttpize
37e0: 28 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d 65 (zValue);. }e
37f0: 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 2a lse{. if( *
3800: 7a 20 29 7b 20 2a 7a 2b 2b 20 3d 20 30 3b 20 7d z ){ *z++ = 0; }
3810: 0a 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 . zValue =
3820: 22 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 "";. }. if
3830: 28 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b ( islower(zName[
3840: 30 5d 29 20 29 7b 0a 20 20 20 20 20 20 63 67 69 0]) ){. cgi
3850: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e _set_parameter_n
3860: 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 ocopy(zName, zVa
3870: 6c 75 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a lue);. }. }.
3880: 7d 0a 0a 2f 2a 0a 2a 2a 20 2a 70 7a 20 69 73 20 }../*.** *pz is
3890: 61 20 73 74 72 69 6e 67 20 74 68 61 74 20 63 6f a string that co
38a0: 6e 73 69 73 74 73 20 6f 66 20 6d 75 6c 74 69 70 nsists of multip
38b0: 6c 65 20 6c 69 6e 65 73 20 6f 66 20 74 65 78 74 le lines of text
38c0: 2e 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69 . This.** routi
38d0: 6e 65 20 66 69 6e 64 73 20 74 68 65 20 65 6e 64 ne finds the end
38e0: 20 6f 66 20 74 68 65 20 63 75 72 72 65 6e 74 20 of the current
38f0: 6c 69 6e 65 20 6f 66 20 74 65 78 74 20 61 6e 64 line of text and
3900: 20 63 6f 6e 76 65 72 74 73 0a 2a 2a 20 74 68 65 converts.** the
3910: 20 22 5c 6e 22 20 6f 72 20 22 5c 72 5c 6e 22 20 "\n" or "\r\n"
3920: 74 68 61 74 20 65 6e 64 73 20 74 68 61 74 20 6c that ends that l
3930: 69 6e 65 20 69 6e 74 6f 20 61 20 22 5c 30 30 30 ine into a "\000
3940: 22 2e 20 20 49 74 20 74 68 65 6e 0a 2a 2a 20 61 ". It then.** a
3950: 64 76 61 6e 63 65 73 20 2a 70 7a 20 74 6f 20 74 dvances *pz to t
3960: 68 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 he beginning of
3970: 74 68 65 20 6e 65 78 74 20 6c 69 6e 65 20 61 6e the next line an
3980: 64 20 72 65 74 75 72 6e 73 20 74 68 65 0a 2a 2a d returns the.**
3990: 20 70 72 65 76 69 6f 75 73 20 76 61 6c 75 65 20 previous value
39a0: 6f 66 20 2a 70 7a 20 28 77 68 69 63 68 20 69 73 of *pz (which is
39b0: 20 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 the start of th
39c0: 65 20 63 75 72 72 65 6e 74 20 6c 69 6e 65 2e 29 e current line.)
39d0: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 .*/.static char
39e0: 2a 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 *get_line_from_s
39f0: 74 72 69 6e 67 28 63 68 61 72 20 2a 2a 70 7a 2c tring(char **pz,
3a00: 20 69 6e 74 20 2a 70 4c 65 6e 29 7b 0a 20 20 63 int *pLen){. c
3a10: 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20 har *z = *pz;.
3a20: 69 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a 5b 30 int i;. if( z[0
3a30: 5d 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b ]==0 ) return 0;
3a40: 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a 5b 69 5d . for(i=0; z[i]
3a50: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 ; i++){. if(
3a60: 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 29 7b 0a 20 20 z[i]=='\n' ){.
3a70: 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20 7a if( i>0 && z
3a80: 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 7b 0a 20 [i-1]=='\r' ){.
3a90: 20 20 20 20 20 20 20 7a 5b 69 2d 31 5d 20 3d 20 z[i-1] =
3aa0: 30 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 0;. }else{.
3ab0: 20 20 20 20 20 20 20 20 7a 5b 69 5d 20 3d 20 30 z[i] = 0
3ac0: 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 ;. }.
3ad0: 69 2b 2b 3b 0a 20 20 20 20 20 20 62 72 65 61 6b i++;. break
3ae0: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 ;. }. }. *p
3af0: 7a 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 2a 70 4c z = &z[i];. *pL
3b00: 65 6e 20 2d 3d 20 69 3b 0a 20 20 72 65 74 75 72 en -= i;. retur
3b10: 6e 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 n z;.}../*.** Th
3b20: 65 20 69 6e 70 75 74 20 2a 70 7a 20 70 6f 69 6e e input *pz poin
3b30: 74 73 20 74 6f 20 63 6f 6e 74 65 6e 74 20 74 68 ts to content th
3b40: 61 74 20 69 73 20 74 65 72 6d 69 6e 61 74 65 64 at is terminated
3b50: 20 62 79 20 61 20 22 5c 72 5c 6e 22 0a 2a 2a 20 by a "\r\n".**
3b60: 66 6f 6c 6c 6f 77 65 64 20 62 79 20 74 68 65 20 followed by the
3b70: 62 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 20 7a boundry marker z
3b80: 42 6f 75 6e 64 72 79 2e 20 20 41 6e 20 65 78 74 Boundry. An ext
3b90: 72 61 20 22 2d 2d 22 20 6d 61 79 20 6f 72 0a 2a ra "--" may or.*
3ba0: 2a 20 6d 61 79 20 6e 6f 74 20 62 65 20 61 70 70 * may not be app
3bb0: 65 6e 64 65 64 20 74 6f 20 74 68 65 20 62 6f 75 ended to the bou
3bc0: 6e 64 72 79 20 6d 61 72 6b 65 72 2e 20 20 54 68 ndry marker. Th
3bd0: 65 72 65 20 61 72 65 20 2a 70 4c 65 6e 20 63 68 ere are *pLen ch
3be0: 61 72 61 63 74 65 72 73 0a 2a 2a 20 69 6e 20 2a aracters.** in *
3bf0: 70 7a 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 pz..**.** This r
3c00: 6f 75 74 69 6e 65 20 61 64 64 73 20 61 20 22 5c outine adds a "\
3c10: 30 30 30 22 20 74 6f 20 74 68 65 20 65 6e 64 20 000" to the end
3c20: 6f 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 28 of the content (
3c30: 6f 76 65 72 77 72 69 74 69 6e 67 0a 2a 2a 20 74 overwriting.** t
3c40: 68 65 20 22 5c 72 5c 6e 22 29 20 61 6e 64 20 72 he "\r\n") and r
3c50: 65 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65 72 eturns a pointer
3c60: 20 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74 2e to the content.
3c70: 20 20 54 68 65 20 2a 70 7a 20 69 6e 70 75 74 0a The *pz input.
3c80: 2a 2a 20 69 73 20 61 64 6a 75 73 74 65 64 20 74 ** is adjusted t
3c90: 6f 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 66 o point to the f
3ca0: 69 72 73 74 20 6c 69 6e 65 20 66 6f 6c 6c 6f 77 irst line follow
3cb0: 69 6e 67 20 74 68 65 20 62 6f 75 6e 64 72 79 2e ing the boundry.
3cc0: 0a 2a 2a 20 54 68 65 20 6c 65 6e 67 74 68 20 6f .** The length o
3cd0: 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 69 73 f the content is
3ce0: 20 73 74 6f 72 65 64 20 69 6e 20 2a 70 6e 43 6f stored in *pnCo
3cf0: 6e 74 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 ntent..*/.static
3d00: 20 63 68 61 72 20 2a 67 65 74 5f 62 6f 75 6e 64 char *get_bound
3d10: 65 64 5f 63 6f 6e 74 65 6e 74 28 0a 20 20 63 68 ed_content(. ch
3d20: 61 72 20 2a 2a 70 7a 2c 20 20 20 20 20 20 20 20 ar **pz,
3d30: 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 61 6b 65 /* Content take
3d40: 6e 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f 0a 20 n from here */.
3d50: 20 69 6e 74 20 2a 70 4c 65 6e 2c 20 20 20 20 20 int *pLen,
3d60: 20 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 /* Number of
3d70: 20 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 69 bytes of data i
3d80: 6e 20 28 2a 70 7a 29 5b 5d 20 2a 2f 0a 20 20 63 n (*pz)[] */. c
3d90: 68 61 72 20 2a 7a 42 6f 75 6e 64 72 79 2c 20 20 har *zBoundry,
3da0: 20 20 2f 2a 20 42 6f 75 6e 64 72 79 20 74 65 78 /* Boundry tex
3db0: 74 20 6d 61 72 6b 69 6e 67 20 74 68 65 20 65 6e t marking the en
3dc0: 64 20 6f 66 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a d of content */.
3dd0: 20 20 69 6e 74 20 2a 70 6e 43 6f 6e 74 65 6e 74 int *pnContent
3de0: 20 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 /* Write th
3df0: 65 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63 6f e size of the co
3e00: 6e 74 65 6e 74 20 68 65 72 65 20 2a 2f 0a 29 7b ntent here */.){
3e10: 0a 20 20 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a . char *z = *pz
3e20: 3b 0a 20 20 69 6e 74 20 6c 65 6e 20 3d 20 2a 70 ;. int len = *p
3e30: 4c 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 Len;. int i;.
3e40: 69 6e 74 20 6e 42 6f 75 6e 64 72 79 20 3d 20 73 int nBoundry = s
3e50: 74 72 6c 65 6e 28 7a 42 6f 75 6e 64 72 79 29 3b trlen(zBoundry);
3e60: 0a 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d 20 . *pnContent =
3e70: 6c 65 6e 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 len;. for(i=0;
3e80: 69 3c 6c 65 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 i<len; i++){.
3e90: 20 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 if( z[i]=='\n'
3ea0: 26 26 20 73 74 72 6e 63 6d 70 28 7a 42 6f 75 6e && strncmp(zBoun
3eb0: 64 72 79 2c 20 26 7a 5b 69 2b 31 5d 2c 20 6e 42 dry, &z[i+1], nB
3ec0: 6f 75 6e 64 72 79 29 3d 3d 30 20 29 7b 0a 20 20 oundry)==0 ){.
3ed0: 20 20 20 20 69 66 28 20 69 3e 30 20 26 26 20 7a if( i>0 && z
3ee0: 5b 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 20 69 2d [i-1]=='\r' ) i-
3ef0: 2d 3b 0a 20 20 20 20 20 20 7a 5b 69 5d 20 3d 20 -;. z[i] =
3f00: 30 3b 0a 20 20 20 20 20 20 2a 70 6e 43 6f 6e 74 0;. *pnCont
3f10: 65 6e 74 20 3d 20 69 3b 0a 20 20 20 20 20 20 69 ent = i;. i
3f20: 20 2b 3d 20 6e 42 6f 75 6e 64 72 79 3b 0a 20 20 += nBoundry;.
3f30: 20 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d break;. }
3f40: 0a 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a 5b . }. *pz = &z[
3f50: 69 5d 3b 0a 20 20 67 65 74 5f 6c 69 6e 65 5f 66 i];. get_line_f
3f60: 72 6f 6d 5f 73 74 72 69 6e 67 28 70 7a 2c 20 70 rom_string(pz, p
3f70: 4c 65 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a Len);. return z
3f80: 3b 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a ; .}../*.**
3f90: 20 54 6f 6b 65 6e 69 7a 65 20 61 20 6c 69 6e 65 Tokenize a line
3fa0: 20 6f 66 20 74 65 78 74 20 69 6e 74 6f 20 61 73 of text into as
3fb0: 20 6d 61 6e 79 20 61 73 20 6e 41 72 67 20 74 6f many as nArg to
3fc0: 6b 65 6e 73 2e 20 20 4d 61 6b 65 0a 2a 2a 20 61 kens. Make.** a
3fd0: 7a 41 72 67 5b 5d 20 70 6f 69 6e 74 20 74 6f 20 zArg[] point to
3fe0: 74 68 65 20 73 74 61 72 74 20 6f 66 20 65 61 63 the start of eac
3ff0: 68 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 54 h token..**.** T
4000: 6f 6b 65 6e 73 20 63 6f 6e 73 69 73 74 20 6f 66 okens consist of
4010: 20 73 70 61 63 65 20 6f 72 20 73 65 6d 69 2d 63 space or semi-c
4020: 6f 6c 6f 6e 20 64 65 6c 69 6d 69 74 65 64 20 77 olon delimited w
4030: 6f 72 64 73 20 6f 72 0a 2a 2a 20 73 74 72 69 6e ords or.** strin
4040: 67 73 20 69 6e 73 69 64 65 20 64 6f 75 62 6c 65 gs inside double
4050: 2d 71 75 6f 74 65 73 2e 20 20 45 78 61 6d 70 6c -quotes. Exampl
4060: 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 63 6f 6e 74 e:.**.** cont
4070: 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a ent-disposition:
4080: 20 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 6d 65 form-data; name
4090: 3d 22 66 6e 22 3b 20 66 69 6c 65 6e 61 6d 65 3d ="fn"; filename=
40a0: 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a 0a "index.html".**.
40b0: 2a 2a 20 54 68 65 20 6c 69 6e 65 20 61 62 6f 76 ** The line abov
40c0: 65 20 69 73 20 74 6f 6b 65 6e 69 7a 65 64 20 61 e is tokenized a
40d0: 73 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a s follows:.**.**
40e0: 20 20 20 20 61 7a 41 72 67 5b 30 5d 20 3d 20 22 azArg[0] = "
40f0: 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 content-disposit
4100: 69 6f 6e 3a 22 0a 2a 2a 20 20 20 20 61 7a 41 72 ion:".** azAr
4110: 67 5b 31 5d 20 3d 20 22 66 6f 72 6d 2d 64 61 74 g[1] = "form-dat
4120: 61 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 32 a".** azArg[2
4130: 5d 20 3d 20 22 6e 61 6d 65 3d 22 0a 2a 2a 20 20 ] = "name=".**
4140: 20 20 61 7a 41 72 67 5b 33 5d 20 3d 20 22 66 6e azArg[3] = "fn
4150: 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 34 5d ".** azArg[4]
4160: 20 3d 20 22 66 69 6c 65 6e 61 6d 65 3d 22 0a 2a = "filename=".*
4170: 2a 20 20 20 20 61 7a 41 72 67 5b 35 5d 20 3d 20 * azArg[5] =
4180: 22 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a 20 "index.html".**
4190: 20 20 20 61 7a 41 72 67 5b 36 5d 20 3d 20 30 3b azArg[6] = 0;
41a0: 0a 2a 2a 0a 2a 2a 20 27 5c 30 30 30 27 20 63 68 .**.** '\000' ch
41b0: 61 72 61 63 74 65 72 73 20 61 72 65 20 69 6e 73 aracters are ins
41c0: 65 72 74 65 64 20 69 6e 20 7a 5b 5d 20 61 74 20 erted in z[] at
41d0: 74 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68 20 the end of each
41e0: 74 6f 6b 65 6e 2e 0a 2a 2a 20 54 68 69 73 20 72 token..** This r
41f0: 6f 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20 74 outine returns t
4200: 68 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 he total number
4210: 6f 66 20 74 6f 6b 65 6e 73 20 6f 6e 20 74 68 65 of tokens on the
4220: 20 6c 69 6e 65 2c 20 36 0a 2a 2a 20 69 6e 20 74 line, 6.** in t
4230: 68 65 20 65 78 61 6d 70 6c 65 20 61 62 6f 76 65 he example above
4240: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ..*/.static int
4250: 74 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 63 68 tokenize_line(ch
4260: 61 72 20 2a 7a 2c 20 69 6e 74 20 6d 78 41 72 67 ar *z, int mxArg
4270: 2c 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 29 7b , char **azArg){
4280: 0a 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a 20 20 . int i = 0;.
4290: 77 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 while( *z ){.
42a0: 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 while( isspace(
42b0: 2a 7a 29 20 7c 7c 20 2a 7a 3d 3d 27 3b 27 20 29 *z) || *z==';' )
42c0: 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69 66 28 { z++; }. if(
42d0: 20 2a 7a 3d 3d 27 22 27 20 26 26 20 7a 5b 31 5d *z=='"' && z[1]
42e0: 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 ){. *z = 0
42f0: 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 ;. z++;.
4300: 20 20 20 69 66 28 20 69 3c 6d 78 41 72 67 2d 31 if( i<mxArg-1
4310: 20 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d ){ azArg[i++] =
4320: 20 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68 69 6c z; }. whil
4330: 65 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 22 27 e( *z && *z!='"'
4340: 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 ){ z++; }.
4350: 20 69 66 28 20 2a 7a 3d 3d 30 20 29 20 62 72 65 if( *z==0 ) bre
4360: 61 6b 3b 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 ak;. *z = 0
4370: 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 ;. z++;.
4380: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 }else{. if
4390: 28 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b 20 61 ( i<mxArg-1 ){ a
43a0: 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d zArg[i++] = z; }
43b0: 0a 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a . while( *z
43c0: 20 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a 29 && !isspace(*z)
43d0: 20 26 26 20 2a 7a 21 3d 27 3b 27 20 26 26 20 2a && *z!=';' && *
43e0: 7a 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b 20 7d z!='"' ){ z++; }
43f0: 0a 20 20 20 20 20 20 69 66 28 20 2a 7a 20 26 26 . if( *z &&
4400: 20 2a 7a 21 3d 27 22 27 20 29 7b 0a 20 20 20 20 *z!='"' ){.
4410: 20 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 *z = 0;.
4420: 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d z++;. }
4430: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 7a 41 . }. }. azA
4440: 72 67 5b 69 5d 20 3d 20 30 3b 0a 20 20 72 65 74 rg[i] = 0;. ret
4450: 75 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 urn i;.}../*.**
4460: 53 63 61 6e 20 74 68 65 20 6d 75 6c 74 69 70 61 Scan the multipa
4470: 72 74 2d 66 6f 72 6d 20 63 6f 6e 74 65 6e 74 20 rt-form content
4480: 61 6e 64 20 6d 61 6b 65 20 61 70 70 72 6f 70 72 and make appropr
4490: 69 61 74 65 20 65 6e 74 72 69 65 73 0a 2a 2a 20 iate entries.**
44a0: 69 6e 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 into the paramet
44b0: 65 72 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 er table..**.**
44c0: 54 68 65 20 63 6f 6e 74 65 6e 74 20 73 74 72 69 The content stri
44d0: 6e 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66 69 ng "z" is modifi
44e0: 65 64 20 62 79 20 74 68 69 73 20 72 6f 75 74 69 ed by this routi
44f0: 6e 65 20 62 75 74 20 69 74 20 69 73 0a 2a 2a 20 ne but it is.**
4500: 6e 6f 74 20 63 6f 70 69 65 64 2e 20 20 54 68 65 not copied. The
4510: 20 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f calling functio
4520: 6e 20 6d 75 73 74 20 6e 6f 74 20 64 65 61 6c 6c n must not deall
4530: 6f 63 61 74 65 20 6f 72 20 6d 6f 64 69 66 79 0a ocate or modify.
4540: 2a 2a 20 22 7a 22 20 61 66 74 65 72 20 74 68 69 ** "z" after thi
4550: 73 20 72 6f 75 74 69 6e 65 20 66 69 6e 69 73 68 s routine finish
4560: 65 73 20 6f 72 20 69 74 20 63 6f 75 6c 64 20 63 es or it could c
4570: 6f 72 72 75 70 74 20 74 68 65 20 70 61 72 61 6d orrupt the param
4580: 65 74 65 72 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a eter.** table..*
4590: 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 72 /.static void pr
45a0: 6f 63 65 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f ocess_multipart_
45b0: 66 6f 72 6d 5f 64 61 74 61 28 63 68 61 72 20 2a form_data(char *
45c0: 7a 2c 20 69 6e 74 20 6c 65 6e 29 7b 0a 20 20 63 z, int len){. c
45d0: 68 61 72 20 2a 7a 4c 69 6e 65 3b 0a 20 20 69 6e har *zLine;. in
45e0: 74 20 6e 41 72 67 2c 20 69 3b 0a 20 20 63 68 61 t nArg, i;. cha
45f0: 72 20 2a 7a 42 6f 75 6e 64 72 79 3b 0a 20 20 63 r *zBoundry;. c
4600: 68 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20 63 har *zValue;. c
4610: 68 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 30 3b 0a har *zName = 0;.
4620: 20 20 69 6e 74 20 73 68 6f 77 42 79 74 65 73 20 int showBytes
4630: 3d 20 30 3b 0a 20 20 63 68 61 72 20 2a 61 7a 41 = 0;. char *azA
4640: 72 67 5b 35 30 5d 3b 0a 0a 20 20 7a 42 6f 75 6e rg[50];.. zBoun
4650: 64 72 79 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 dry = get_line_f
4660: 72 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 rom_string(&z, &
4670: 6c 65 6e 29 3b 0a 20 20 69 66 28 20 7a 42 6f 75 len);. if( zBou
4680: 6e 64 72 79 3d 3d 30 20 29 20 72 65 74 75 72 6e ndry==0 ) return
4690: 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4c 69 6e ;. while( (zLin
46a0: 65 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 72 6f e = get_line_fro
46b0: 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 6c 65 m_string(&z, &le
46c0: 6e 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 n))!=0 ){. if
46d0: 28 20 7a 4c 69 6e 65 5b 30 5d 3d 3d 30 20 29 7b ( zLine[0]==0 ){
46e0: 0a 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 6e 74 . int nCont
46f0: 65 6e 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a ent = 0;. z
4700: 56 61 6c 75 65 20 3d 20 67 65 74 5f 62 6f 75 6e Value = get_boun
4710: 64 65 64 5f 63 6f 6e 74 65 6e 74 28 26 7a 2c 20 ded_content(&z,
4720: 26 6c 65 6e 2c 20 7a 42 6f 75 6e 64 72 79 2c 20 &len, zBoundry,
4730: 26 6e 43 6f 6e 74 65 6e 74 29 3b 0a 20 20 20 20 &nContent);.
4740: 20 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a if( zName && z
4750: 56 61 6c 75 65 20 26 26 20 69 73 6c 6f 77 65 72 Value && islower
4760: 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 (zName[0]) ){.
4770: 20 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 cgi_set_pa
4780: 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a rameter_nocopy(z
4790: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 Name, zValue);.
47a0: 20 20 20 20 20 20 20 69 66 28 20 73 68 6f 77 42 if( showB
47b0: 79 74 65 73 20 29 7b 0a 20 20 20 20 20 20 20 20 ytes ){.
47c0: 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 cgi_set_parame
47d0: 74 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e ter_nocopy(mprin
47e0: 74 66 28 22 25 73 3a 62 79 74 65 73 22 2c 20 7a tf("%s:bytes", z
47f0: 4e 61 6d 65 29 2c 0a 20 20 20 20 20 20 20 20 20 Name),.
4800: 20 20 20 20 20 20 6d 70 72 69 6e 74 66 28 22 25 mprintf("%
4810: 64 22 2c 6e 43 6f 6e 74 65 6e 74 29 29 3b 0a 20 d",nContent));.
4820: 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d }. }
4830: 0a 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 30 . zName = 0
4840: 3b 0a 20 20 20 20 20 20 73 68 6f 77 42 79 74 65 ;. showByte
4850: 73 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 s = 0;. }else
4860: 7b 0a 20 20 20 20 20 20 6e 41 72 67 20 3d 20 74 {. nArg = t
4870: 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 7a 4c 69 okenize_line(zLi
4880: 6e 65 2c 20 73 69 7a 65 6f 66 28 61 7a 41 72 67 ne, sizeof(azArg
4890: 29 2f 73 69 7a 65 6f 66 28 61 7a 41 72 67 5b 30 )/sizeof(azArg[0
48a0: 5d 29 2c 20 61 7a 41 72 67 29 3b 0a 20 20 20 20 ]), azArg);.
48b0: 20 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41 72 for(i=0; i<nAr
48c0: 67 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 g; i++){.
48d0: 20 69 6e 74 20 63 20 3d 20 74 6f 6c 6f 77 65 72 int c = tolower
48e0: 28 61 7a 41 72 67 5b 69 5d 5b 30 5d 29 3b 0a 20 (azArg[i][0]);.
48f0: 20 20 20 20 20 20 20 69 6e 74 20 6e 20 3d 20 73 int n = s
4900: 74 72 6c 65 6e 28 61 7a 41 72 67 5b 69 5d 29 3b trlen(azArg[i]);
4910: 0a 20 20 20 20 20 20 20 20 69 66 28 20 63 3d 3d . if( c==
4920: 27 63 27 20 26 26 20 73 71 6c 69 74 65 33 5f 73 'c' && sqlite3_s
4930: 74 72 6e 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d trnicmp(azArg[i]
4940: 2c 22 63 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 ,"content-dispos
4950: 69 74 69 6f 6e 3a 22 2c 6e 29 3d 3d 30 20 29 7b ition:",n)==0 ){
4960: 0a 20 20 20 20 20 20 20 20 20 20 69 2b 2b 3b 0a . i++;.
4970: 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 69 66 }else if
4980: 28 20 63 3d 3d 27 6e 27 20 26 26 20 73 71 6c 69 ( c=='n' && sqli
4990: 74 65 33 5f 73 74 72 6e 69 63 6d 70 28 61 7a 41 te3_strnicmp(azA
49a0: 72 67 5b 69 5d 2c 22 6e 61 6d 65 3d 22 2c 6e 29 rg[i],"name=",n)
49b0: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 ==0 ){.
49c0: 20 7a 4e 61 6d 65 20 3d 20 61 7a 41 72 67 5b 2b zName = azArg[+
49d0: 2b 69 5d 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c +i];. }el
49e0: 73 65 20 69 66 28 20 63 3d 3d 27 66 27 20 26 26 se if( c=='f' &&
49f0: 20 73 71 6c 69 74 65 33 5f 73 74 72 6e 69 63 6d sqlite3_strnicm
4a00: 70 28 61 7a 41 72 67 5b 69 5d 2c 22 66 69 6c 65 p(azArg[i],"file
4a10: 6e 61 6d 65 3d 22 2c 6e 29 3d 3d 30 20 29 7b 0a name=",n)==0 ){.
4a20: 20 20 20 20 20 20 20 20 20 20 63 68 61 72 20 2a char *
4a30: 7a 20 3d 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a z = azArg[++i];.
4a40: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 7a 4e if( zN
4a50: 61 6d 65 20 26 26 20 7a 20 26 26 20 69 73 6c 6f ame && z && islo
4a60: 77 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b wer(zName[0]) ){
4a70: 0a 20 20 20 20 20 20 20 20 20 20 20 20 63 67 69 . cgi
4a80: 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e _set_parameter_n
4a90: 6f 63 6f 70 79 28 6d 70 72 69 6e 74 66 28 22 25 ocopy(mprintf("%
4aa0: 73 3a 66 69 6c 65 6e 61 6d 65 22 2c 7a 4e 61 6d s:filename",zNam
4ab0: 65 29 2c 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 e), z);.
4ac0: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 73 68 }. sh
4ad0: 6f 77 42 79 74 65 73 20 3d 20 31 3b 0a 20 20 20 owBytes = 1;.
4ae0: 20 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 }else if( c
4af0: 3d 3d 27 63 27 20 26 26 20 73 71 6c 69 74 65 33 =='c' && sqlite3
4b00: 5f 73 74 72 6e 69 63 6d 70 28 61 7a 41 72 67 5b _strnicmp(azArg[
4b10: 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 65 i],"content-type
4b20: 3a 22 2c 6e 29 3d 3d 30 20 29 7b 0a 20 20 20 20 :",n)==0 ){.
4b30: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 char *z =
4b40: 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 azArg[++i];.
4b50: 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 if( zName
4b60: 26 26 20 7a 20 26 26 20 69 73 6c 6f 77 65 72 28 && z && islower(
4b70: 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 zName[0]) ){.
4b80: 20 20 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 cgi_set
4b90: 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 _parameter_nocop
4ba0: 79 28 6d 70 72 69 6e 74 66 28 22 25 73 3a 6d 69 y(mprintf("%s:mi
4bb0: 6d 65 74 79 70 65 22 2c 7a 4e 61 6d 65 29 2c 20 metype",zName),
4bc0: 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a z);. }.
4bd0: 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 }.
4be0: 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 20 20 20 20 }. }. }
4bf0: 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e 69 .}../*.** Ini
4c00: 74 69 61 6c 69 7a 65 20 74 68 65 20 71 75 65 72 tialize the quer
4c10: 79 20 70 61 72 61 6d 65 74 65 72 20 64 61 74 61 y parameter data
4c20: 62 61 73 65 2e 20 20 49 6e 66 6f 72 6d 61 74 69 base. Informati
4c30: 6f 6e 20 69 73 20 70 75 6c 6c 65 64 20 66 72 6f on is pulled fro
4c40: 6d 0a 2a 2a 20 74 68 65 20 51 55 45 52 59 5f 53 m.** the QUERY_S
4c50: 54 52 49 4e 47 20 65 6e 76 69 72 6f 6e 6d 65 6e TRING environmen
4c60: 74 20 76 61 72 69 61 62 6c 65 20 28 69 66 20 69 t variable (if i
4c70: 74 20 65 78 69 73 74 73 29 2c 20 66 72 6f 6d 20 t exists), from
4c80: 73 74 61 6e 64 61 72 64 0a 2a 2a 20 69 6e 70 75 standard.** inpu
4c90: 74 20 69 66 20 74 68 65 72 65 20 69 73 20 50 4f t if there is PO
4ca0: 53 54 20 64 61 74 61 2c 20 61 6e 64 20 66 72 6f ST data, and fro
4cb0: 6d 20 48 54 54 50 5f 43 4f 4f 4b 49 45 2e 0a 2a m HTTP_COOKIE..*
4cc0: 2f 0a 76 6f 69 64 20 63 67 69 5f 69 6e 69 74 28 /.void cgi_init(
4cd0: 76 6f 69 64 29 7b 0a 20 20 63 68 61 72 20 2a 7a void){. char *z
4ce0: 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a ;. const char *
4cf0: 7a 54 79 70 65 3b 0a 20 20 69 6e 74 20 6c 65 6e zType;. int len
4d00: 3b 0a 20 20 63 67 69 5f 64 65 73 74 69 6e 61 74 ;. cgi_destinat
4d10: 69 6f 6e 28 43 47 49 5f 42 4f 44 59 29 3b 0a 20 ion(CGI_BODY);.
4d20: 20 7a 20 3d 20 28 63 68 61 72 2a 29 50 28 22 51 z = (char*)P("Q
4d30: 55 45 52 59 5f 53 54 52 49 4e 47 22 29 3b 0a 20 UERY_STRING");.
4d40: 20 69 66 28 20 7a 20 29 7b 0a 20 20 20 20 7a 20 if( z ){. z
4d50: 3d 20 6d 70 72 69 6e 74 66 28 22 25 73 22 2c 7a = mprintf("%s",z
4d60: 29 3b 0a 20 20 20 20 61 64 64 5f 70 61 72 61 6d );. add_param
4d70: 5f 6c 69 73 74 28 7a 2c 20 27 26 27 29 3b 0a 20 _list(z, '&');.
4d80: 20 7d 0a 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a }.. z = (char*
4d90: 29 50 28 22 52 45 4d 4f 54 45 5f 41 44 44 52 22 )P("REMOTE_ADDR"
4da0: 29 3b 0a 20 20 69 66 28 20 7a 20 29 20 67 2e 7a );. if( z ) g.z
4db0: 49 70 41 64 64 72 20 3d 20 6d 70 72 69 6e 74 66 IpAddr = mprintf
4dc0: 28 22 25 73 22 2c 20 7a 29 3b 0a 0a 20 20 6c 65 ("%s", z);.. le
4dd0: 6e 20 3d 20 61 74 6f 69 28 50 44 28 22 43 4f 4e n = atoi(PD("CON
4de0: 54 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 22 30 TENT_LENGTH", "0
4df0: 22 29 29 3b 0a 20 20 67 2e 7a 43 6f 6e 74 65 6e "));. g.zConten
4e00: 74 54 79 70 65 20 3d 20 7a 54 79 70 65 20 3d 20 tType = zType =
4e10: 50 28 22 43 4f 4e 54 45 4e 54 5f 54 59 50 45 22 P("CONTENT_TYPE"
4e20: 29 3b 0a 20 20 69 66 28 20 6c 65 6e 3e 30 20 26 );. if( len>0 &
4e30: 26 20 7a 54 79 70 65 20 29 7b 0a 20 20 20 20 62 & zType ){. b
4e40: 6c 6f 62 5f 7a 65 72 6f 28 26 67 2e 63 67 69 49 lob_zero(&g.cgiI
4e50: 6e 29 3b 0a 20 20 20 20 69 66 28 20 73 74 72 63 n);. if( strc
4e60: 6d 70 28 7a 54 79 70 65 2c 22 61 70 70 6c 69 63 mp(zType,"applic
4e70: 61 74 69 6f 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d ation/x-www-form
4e80: 2d 75 72 6c 65 6e 63 6f 64 65 64 22 29 3d 3d 30 -urlencoded")==0
4e90: 20 0a 20 20 20 20 20 20 20 20 20 7c 7c 20 73 74 . || st
4ea0: 72 6e 63 6d 70 28 7a 54 79 70 65 2c 22 6d 75 6c rncmp(zType,"mul
4eb0: 74 69 70 61 72 74 2f 66 6f 72 6d 2d 64 61 74 61 tipart/form-data
4ec0: 22 2c 31 39 29 3d 3d 30 20 29 7b 0a 20 20 20 20 ",19)==0 ){.
4ed0: 20 20 7a 20 3d 20 6d 61 6c 6c 6f 63 28 20 6c 65 z = malloc( le
4ee0: 6e 2b 31 20 29 3b 0a 20 20 20 20 20 20 69 66 28 n+1 );. if(
4ef0: 20 7a 3d 3d 30 20 29 20 65 78 69 74 28 31 29 3b z==0 ) exit(1);
4f00: 0a 20 20 20 20 20 20 6c 65 6e 20 3d 20 66 72 65 . len = fre
4f10: 61 64 28 7a 2c 20 31 2c 20 6c 65 6e 2c 20 67 2e ad(z, 1, len, g.
4f20: 68 74 74 70 49 6e 29 3b 0a 20 20 20 20 20 20 7a httpIn);. z
4f30: 5b 6c 65 6e 5d 20 3d 20 30 3b 0a 20 20 20 20 20 [len] = 0;.
4f40: 20 69 66 28 20 7a 54 79 70 65 5b 30 5d 3d 3d 27 if( zType[0]=='
4f50: 61 27 20 29 7b 0a 20 20 20 20 20 20 20 20 61 64 a' ){. ad
4f60: 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 d_param_list(z,
4f70: 27 26 27 29 3b 0a 20 20 20 20 20 20 7d 65 6c 73 '&');. }els
4f80: 65 7b 0a 20 20 20 20 20 20 20 20 70 72 6f 63 65 e{. proce
4f90: 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66 6f 72 ss_multipart_for
4fa0: 6d 5f 64 61 74 61 28 7a 2c 20 6c 65 6e 29 3b 0a m_data(z, len);.
4fb0: 20 20 20 20 20 20 7d 0a 20 20 20 20 7d 65 6c 73 }. }els
4fc0: 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 54 79 e if( strcmp(zTy
4fd0: 70 65 2c 20 22 61 70 70 6c 69 63 61 74 69 6f 6e pe, "application
4fe0: 2f 78 2d 66 6f 73 73 69 6c 22 29 3d 3d 30 20 29 /x-fossil")==0 )
4ff0: 7b 0a 20 20 20 20 20 20 62 6c 6f 62 5f 72 65 61 {. blob_rea
5000: 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e 65 6c 28 26 d_from_channel(&
5010: 67 2e 63 67 69 49 6e 2c 20 67 2e 68 74 74 70 49 g.cgiIn, g.httpI
5020: 6e 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 62 n, len);. b
5030: 6c 6f 62 5f 75 6e 63 6f 6d 70 72 65 73 73 28 26 lob_uncompress(&
5040: 67 2e 63 67 69 49 6e 2c 20 26 67 2e 63 67 69 49 g.cgiIn, &g.cgiI
5050: 6e 29 3b 0a 20 20 20 20 20 20 2f 2a 20 49 66 20 n);. /* If
5060: 74 68 65 20 63 6f 6e 74 65 6e 74 20 74 79 70 65 the content type
5070: 20 69 73 20 61 70 70 6c 69 63 61 74 69 6f 6e 2f is application/
5080: 78 2d 66 6f 73 73 69 6c 2c 20 74 68 65 6e 20 69 x-fossil, then i
5090: 67 6e 6f 72 65 0a 20 20 20 20 20 20 2a 2a 20 74 gnore. ** t
50a0: 68 65 20 70 61 74 68 20 69 6e 20 74 68 65 20 66 he path in the f
50b0: 69 72 73 74 20 6c 69 6e 65 20 6f 66 20 74 68 65 irst line of the
50c0: 20 48 54 54 50 20 68 65 61 64 65 72 20 61 6e 64 HTTP header and
50d0: 20 61 6c 77 61 79 73 0a 20 20 20 20 20 20 2a 2a always. **
50e0: 20 75 73 65 20 74 68 65 20 2f 78 66 65 72 20 6d use the /xfer m
50f0: 65 74 68 6f 64 20 73 69 6e 63 65 20 74 68 65 20 ethod since the
5100: 2f 78 66 65 72 20 6d 65 74 68 6f 64 20 69 73 20 /xfer method is
5110: 74 68 65 20 6f 6e 6c 79 0a 20 20 20 20 20 20 2a the only. *
5120: 2a 20 6d 65 74 68 6f 64 20 74 68 61 74 20 75 6e * method that un
5130: 64 65 72 73 74 61 6e 64 73 20 74 68 65 20 61 70 derstands the ap
5140: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 plication/x-foss
5150: 69 6c 20 63 6f 6e 74 65 6e 74 0a 20 20 20 20 20 il content.
5160: 20 2a 2a 20 74 79 70 65 2e 0a 20 20 20 20 20 20 ** type..
5170: 2a 2f 0a 20 20 20 20 20 20 63 67 69 5f 72 65 70 */. cgi_rep
5180: 6c 61 63 65 5f 70 61 72 61 6d 65 74 65 72 28 22 lace_parameter("
5190: 50 41 54 48 5f 49 4e 46 4f 22 2c 20 22 2f 78 66 PATH_INFO", "/xf
51a0: 65 72 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 er");. }else
51b0: 69 66 28 20 73 74 72 63 6d 70 28 7a 54 79 70 65 if( strcmp(zType
51c0: 2c 20 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f 78 , "application/x
51d0: 2d 66 6f 73 73 69 6c 2d 64 65 62 75 67 22 29 3d -fossil-debug")=
51e0: 3d 30 20 29 7b 0a 20 20 20 20 20 20 62 6c 6f 62 =0 ){. blob
51f0: 5f 72 65 61 64 5f 66 72 6f 6d 5f 63 68 61 6e 6e _read_from_chann
5200: 65 6c 28 26 67 2e 63 67 69 49 6e 2c 20 67 2e 68 el(&g.cgiIn, g.h
5210: 74 74 70 49 6e 2c 20 6c 65 6e 29 3b 0a 20 20 20 ttpIn, len);.
5220: 20 20 20 63 67 69 5f 72 65 70 6c 61 63 65 5f 70 cgi_replace_p
5230: 61 72 61 6d 65 74 65 72 28 22 50 41 54 48 5f 49 arameter("PATH_I
5240: 4e 46 4f 22 2c 20 22 2f 78 66 65 72 22 29 3b 20 NFO", "/xfer");
5250: 20 2f 2a 20 53 65 65 20 63 6f 6d 6d 65 6e 74 20 /* See comment
5260: 61 62 6f 76 65 20 2a 2f 0a 20 20 20 20 7d 0a 20 above */. }.
5270: 20 7d 0a 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a }.. z = (char*
5280: 29 50 28 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 )P("HTTP_COOKIE"
5290: 29 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 );. if( z ){.
52a0: 20 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 z = mprintf("%
52b0: 73 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 s",z);. add_p
52c0: 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 3b 27 aram_list(z, ';'
52d0: 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 );. }.}../*.**
52e0: 54 68 69 73 20 69 73 20 74 68 65 20 63 6f 6d 70 This is the comp
52f0: 61 72 69 73 6f 6e 20 66 75 6e 63 74 69 6f 6e 20 arison function
5300: 75 73 65 64 20 74 6f 20 73 6f 72 74 20 74 68 65 used to sort the
5310: 20 61 50 61 72 61 6d 51 50 5b 5d 20 61 72 72 61 aParamQP[] arra
5320: 79 20 6f 66 0a 2a 2a 20 71 75 65 72 79 20 70 61 y of.** query pa
5330: 72 61 6d 65 74 65 72 73 20 61 6e 64 20 63 6f 6f rameters and coo
5340: 6b 69 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 kies..*/.static
5350: 69 6e 74 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 int qparam_compa
5360: 72 65 28 63 6f 6e 73 74 20 76 6f 69 64 20 2a 61 re(const void *a
5370: 2c 20 63 6f 6e 73 74 20 76 6f 69 64 20 2a 62 29 , const void *b)
5380: 7b 0a 20 20 73 74 72 75 63 74 20 51 50 61 72 61 {. struct QPara
5390: 6d 20 2a 70 41 20 3d 20 28 73 74 72 75 63 74 20 m *pA = (struct
53a0: 51 50 61 72 61 6d 2a 29 61 3b 0a 20 20 73 74 72 QParam*)a;. str
53b0: 75 63 74 20 51 50 61 72 61 6d 20 2a 70 42 20 3d uct QParam *pB =
53c0: 20 28 73 74 72 75 63 74 20 51 50 61 72 61 6d 2a (struct QParam*
53d0: 29 62 3b 0a 20 20 69 6e 74 20 63 3b 0a 20 20 63 )b;. int c;. c
53e0: 20 3d 20 73 74 72 63 6d 70 28 70 41 2d 3e 7a 4e = strcmp(pA->zN
53f0: 61 6d 65 2c 20 70 42 2d 3e 7a 4e 61 6d 65 29 3b ame, pB->zName);
5400: 0a 20 20 69 66 28 20 63 3d 3d 30 20 29 7b 0a 20 . if( c==0 ){.
5410: 20 20 20 63 20 3d 20 70 41 2d 3e 73 65 71 20 2d c = pA->seq -
5420: 20 70 42 2d 3e 73 65 71 3b 0a 20 20 7d 0a 20 20 pB->seq;. }.
5430: 72 65 74 75 72 6e 20 63 3b 0a 7d 0a 0a 2f 2a 0a return c;.}../*.
5440: 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 20 76 61 ** Return the va
5450: 6c 75 65 20 6f 66 20 61 20 71 75 65 72 79 20 70 lue of a query p
5460: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b arameter or cook
5470: 69 65 20 77 68 6f 73 65 20 6e 61 6d 65 20 69 73 ie whose name is
5480: 20 7a 4e 61 6d 65 2e 0a 2a 2a 20 49 66 20 74 68 zName..** If th
5490: 65 72 65 20 69 73 20 6e 6f 20 71 75 65 72 79 20 ere is no query
54a0: 70 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f parameter or coo
54b0: 6b 69 65 20 6e 61 6d 65 64 20 7a 4e 61 6d 65 20 kie named zName
54c0: 61 6e 64 20 74 68 65 20 66 69 72 73 74 0a 2a 2a and the first.**
54d0: 20 63 68 61 72 61 63 74 65 72 20 6f 66 20 7a 4e character of zN
54e0: 61 6d 65 20 69 73 20 75 70 70 65 72 63 61 73 65 ame is uppercase
54f0: 2c 20 74 68 65 6e 20 63 68 65 63 6b 20 74 6f 20 , then check to
5500: 73 65 65 20 69 66 20 74 68 65 72 65 20 69 73 20 see if there is
5510: 61 6e 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e an.** environmen
5520: 74 20 76 61 72 69 61 62 6c 65 20 62 79 20 74 68 t variable by th
5530: 61 74 20 6e 61 6d 65 20 61 6e 64 20 72 65 74 75 at name and retu
5540: 72 6e 20 69 74 20 69 66 20 74 68 65 72 65 20 69 rn it if there i
5550: 73 2e 20 20 41 73 0a 2a 2a 20 61 20 6c 61 73 74 s. As.** a last
5560: 20 72 65 73 6f 72 74 20 77 68 65 6e 20 6e 6f 74 resort when not
5570: 68 69 6e 67 20 65 6c 73 65 20 6d 61 74 63 68 65 hing else matche
5580: 73 2c 20 72 65 74 75 72 6e 20 7a 44 65 66 61 75 s, return zDefau
5590: 6c 74 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 68 61 lt..*/.const cha
55a0: 72 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 65 72 r *cgi_parameter
55b0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 (const char *zNa
55c0: 6d 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a me, const char *
55d0: 7a 44 65 66 61 75 6c 74 29 7b 0a 20 20 69 6e 74 zDefault){. int
55e0: 20 6c 6f 2c 20 68 69 2c 20 6d 69 64 2c 20 63 3b lo, hi, mid, c;
55f0: 0a 0a 20 20 2f 2a 20 54 68 65 20 73 6f 72 74 51 .. /* The sortQ
5600: 50 20 66 6c 61 67 20 69 73 20 73 65 74 20 77 68 P flag is set wh
5610: 65 6e 65 76 65 72 20 61 20 6e 65 77 20 71 75 65 enever a new que
5620: 72 79 20 70 61 72 61 6d 65 74 65 72 20 69 73 20 ry parameter is
5630: 69 6e 73 65 72 74 65 64 2e 0a 20 20 2a 2a 20 49 inserted.. ** I
5640: 74 20 69 6e 64 69 63 61 74 65 73 20 74 68 61 74 t indicates that
5650: 20 77 65 20 6e 65 65 64 20 74 6f 20 72 65 73 6f we need to reso
5660: 72 74 20 74 68 65 20 71 75 65 72 79 20 70 61 72 rt the query par
5670: 61 6d 65 74 65 72 73 2e 0a 20 20 2a 2f 0a 20 20 ameters.. */.
5680: 69 66 28 20 73 6f 72 74 51 50 20 29 7b 0a 20 20 if( sortQP ){.
5690: 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 20 20 20 int i, j;.
56a0: 71 73 6f 72 74 28 61 50 61 72 61 6d 51 50 2c 20 qsort(aParamQP,
56b0: 6e 55 73 65 64 51 50 2c 20 73 69 7a 65 6f 66 28 nUsedQP, sizeof(
56c0: 61 50 61 72 61 6d 51 50 5b 30 5d 29 2c 20 71 70 aParamQP[0]), qp
56d0: 61 72 61 6d 5f 63 6f 6d 70 61 72 65 29 3b 0a 20 aram_compare);.
56e0: 20 20 20 73 6f 72 74 51 50 20 3d 20 30 3b 0a 20 sortQP = 0;.
56f0: 20 20 20 2f 2a 20 41 66 74 65 72 20 73 6f 72 74 /* After sort
5700: 69 6e 67 2c 20 72 65 6d 6f 76 65 20 64 75 70 6c ing, remove dupl
5710: 69 63 61 74 65 20 70 61 72 61 6d 65 74 65 72 73 icate parameters
5720: 2e 20 20 54 68 65 20 73 65 63 6f 6e 64 61 72 79 . The secondary
5730: 20 73 6f 72 74 0a 20 20 20 20 2a 2a 20 6b 65 79 sort. ** key
5740: 20 69 73 20 61 50 61 72 61 6d 51 50 5b 5d 2e 73 is aParamQP[].s
5750: 65 71 20 61 6e 64 20 77 65 20 6b 65 65 70 20 74 eq and we keep t
5760: 68 65 20 66 69 72 73 74 20 65 6e 74 72 79 2e 20 he first entry.
5770: 20 54 68 61 74 20 6d 65 61 6e 73 0a 20 20 20 20 That means.
5780: 2a 2a 20 77 69 74 68 20 64 75 70 6c 69 63 61 74 ** with duplicat
5790: 65 20 63 61 6c 6c 73 20 74 6f 20 63 67 69 5f 73 e calls to cgi_s
57a0: 65 74 5f 70 61 72 61 6d 65 74 65 72 28 29 20 74 et_parameter() t
57b0: 68 65 20 73 65 63 6f 6e 64 20 61 6e 64 0a 20 20 he second and.
57c0: 20 20 2a 2a 20 73 75 62 73 65 71 75 65 6e 74 20 ** subsequent
57d0: 63 61 6c 6c 73 20 61 72 65 20 65 66 66 65 63 74 calls are effect
57e0: 69 76 65 6c 79 20 6e 6f 2d 6f 70 73 2e 20 2a 2f ively no-ops. */
57f0: 0a 20 20 20 20 66 6f 72 28 69 3d 6a 3d 31 3b 20 . for(i=j=1;
5800: 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 7b i<nUsedQP; i++){
5810: 0a 20 20 20 20 20 20 69 66 28 20 73 74 72 63 6d . if( strcm
5820: 70 28 61 50 61 72 61 6d 51 50 5b 69 5d 2e 7a 4e p(aParamQP[i].zN
5830: 61 6d 65 2c 61 50 61 72 61 6d 51 50 5b 69 2d 31 ame,aParamQP[i-1
5840: 5d 2e 7a 4e 61 6d 65 29 3d 3d 30 20 29 7b 0a 20 ].zName)==0 ){.
5850: 20 20 20 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b continue;
5860: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 . }. i
5870: 66 28 20 6a 3c 69 20 29 7b 0a 20 20 20 20 20 20 f( j<i ){.
5880: 20 20 6d 65 6d 63 70 79 28 26 61 50 61 72 61 6d memcpy(&aParam
5890: 51 50 5b 6a 5d 2c 20 26 61 50 61 72 61 6d 51 50 QP[j], &aParamQP
58a0: 5b 69 5d 2c 20 73 69 7a 65 6f 66 28 61 50 61 72 [i], sizeof(aPar
58b0: 61 6d 51 50 5b 6a 5d 29 29 3b 0a 20 20 20 20 20 amQP[j]));.
58c0: 20 7d 0a 20 20 20 20 20 20 6a 2b 2b 3b 0a 20 20 }. j++;.
58d0: 20 20 7d 0a 20 20 20 20 6e 55 73 65 64 51 50 20 }. nUsedQP
58e0: 3d 20 6a 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 44 = j;. }.. /* D
58f0: 6f 20 61 20 62 69 6e 61 72 79 20 73 65 61 72 63 o a binary searc
5900: 68 20 66 6f 72 20 61 20 6d 61 74 63 68 69 6e 67 h for a matching
5910: 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 query parameter
5920: 20 2a 2f 0a 20 20 6c 6f 20 3d 20 30 3b 0a 20 20 */. lo = 0;.
5930: 68 69 20 3d 20 6e 55 73 65 64 51 50 2d 31 3b 0a hi = nUsedQP-1;.
5940: 20 20 77 68 69 6c 65 28 20 6c 6f 3c 3d 68 69 20 while( lo<=hi
5950: 29 7b 0a 20 20 20 20 6d 69 64 20 3d 20 28 6c 6f ){. mid = (lo
5960: 2b 68 69 29 2f 32 3b 0a 20 20 20 20 63 20 3d 20 +hi)/2;. c =
5970: 73 74 72 63 6d 70 28 61 50 61 72 61 6d 51 50 5b strcmp(aParamQP[
5980: 6d 69 64 5d 2e 7a 4e 61 6d 65 2c 20 7a 4e 61 6d mid].zName, zNam
5990: 65 29 3b 0a 20 20 20 20 69 66 28 20 63 3d 3d 30 e);. if( c==0
59a0: 20 29 7b 0a 20 20 20 20 20 20 43 47 49 44 45 42 ){. CGIDEB
59b0: 55 47 28 28 22 6d 65 6d 2d 6d 61 74 63 68 20 5b UG(("mem-match [
59c0: 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 2c 20 7a %s] = [%s]\n", z
59d0: 4e 61 6d 65 2c 20 61 50 61 72 61 6d 51 50 5b 6d Name, aParamQP[m
59e0: 69 64 5d 2e 7a 56 61 6c 75 65 29 29 3b 0a 20 20 id].zValue));.
59f0: 20 20 20 20 72 65 74 75 72 6e 20 61 50 61 72 61 return aPara
5a00: 6d 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 3b mQP[mid].zValue;
5a10: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 . }else if( c
5a20: 3e 30 20 29 7b 0a 20 20 20 20 20 20 68 69 20 3d >0 ){. hi =
5a30: 20 6d 69 64 2d 31 3b 0a 20 20 20 20 7d 65 6c 73 mid-1;. }els
5a40: 65 7b 0a 20 20 20 20 20 20 6c 6f 20 3d 20 6d 69 e{. lo = mi
5a50: 64 2b 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a d+1;. }. }..
5a60: 20 20 2f 2a 20 49 66 20 6e 6f 20 6d 61 74 63 68 /* If no match
5a70: 20 69 73 20 66 6f 75 6e 64 20 61 6e 64 20 74 68 is found and th
5a80: 65 20 6e 61 6d 65 20 62 65 67 69 6e 73 20 77 69 e name begins wi
5a90: 74 68 20 61 6e 20 75 70 70 65 72 2d 63 61 73 65 th an upper-case
5aa0: 0a 20 20 2a 2a 20 6c 65 74 74 65 72 2c 20 74 68 . ** letter, th
5ab0: 65 6e 20 63 68 65 63 6b 20 74 6f 20 73 65 65 20 en check to see
5ac0: 69 66 20 74 68 65 72 65 20 69 73 20 61 6e 20 65 if there is an e
5ad0: 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 nvironment varia
5ae0: 62 6c 65 0a 20 20 2a 2a 20 77 69 74 68 20 74 68 ble. ** with th
5af0: 65 20 67 69 76 65 6e 20 6e 61 6d 65 2e 0a 20 20 e given name..
5b00: 2a 2f 0a 20 20 69 66 28 20 69 73 75 70 70 65 72 */. if( isupper
5b10: 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 (zName[0]) ){.
5b20: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 const char *zV
5b30: 61 6c 75 65 20 3d 20 67 65 74 65 6e 76 28 7a 4e alue = getenv(zN
5b40: 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 20 7a 56 ame);. if( zV
5b50: 61 6c 75 65 20 29 7b 0a 20 20 20 20 20 20 63 67 alue ){. cg
5b60: 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f i_set_parameter_
5b70: 6e 6f 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 nocopy(zName, zV
5b80: 61 6c 75 65 29 3b 0a 20 20 20 20 20 20 43 47 49 alue);. CGI
5b90: 44 45 42 55 47 28 28 22 65 6e 76 2d 6d 61 74 63 DEBUG(("env-matc
5ba0: 68 20 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c 6e 22 h [%s] = [%s]\n"
5bb0: 2c 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 29 , zName, zValue)
5bc0: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 );. return
5bd0: 7a 56 61 6c 75 65 3b 0a 20 20 20 20 7d 0a 20 20 zValue;. }.
5be0: 7d 0a 20 20 43 47 49 44 45 42 55 47 28 28 22 6e }. CGIDEBUG(("n
5bf0: 6f 2d 6d 61 74 63 68 20 5b 25 73 5d 5c 6e 22 2c o-match [%s]\n",
5c00: 20 7a 4e 61 6d 65 29 29 3b 0a 20 20 72 65 74 75 zName));. retu
5c10: 72 6e 20 7a 44 65 66 61 75 6c 74 3b 0a 7d 0a 0a rn zDefault;.}..
5c20: 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 68 65 /*.** Return the
5c30: 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 69 2d 74 name of the i-t
5c40: 68 20 43 47 49 20 70 61 72 61 6d 65 74 65 72 2e h CGI parameter.
5c50: 20 20 52 65 74 75 72 6e 20 4e 55 4c 4c 20 69 66 Return NULL if
5c60: 20 74 68 65 72 65 0a 2a 2a 20 61 72 65 20 66 65 there.** are fe
5c70: 77 65 72 20 74 68 61 6e 20 69 20 72 65 67 69 73 wer than i regis
5c80: 74 65 72 65 64 20 43 47 49 20 70 61 72 6d 61 65 tered CGI parmae
5c90: 74 65 72 73 2e 0a 2a 2f 0a 63 6f 6e 73 74 20 63 ters..*/.const c
5ca0: 68 61 72 20 2a 63 67 69 5f 70 61 72 61 6d 65 74 har *cgi_paramet
5cb0: 65 72 5f 6e 61 6d 65 28 69 6e 74 20 69 29 7b 0a er_name(int i){.
5cc0: 20 20 69 66 28 20 69 3e 3d 30 20 26 26 20 69 3c if( i>=0 && i<
5cd0: 6e 55 73 65 64 51 50 20 29 7b 0a 20 20 20 20 72 nUsedQP ){. r
5ce0: 65 74 75 72 6e 20 61 50 61 72 61 6d 51 50 5b 69 eturn aParamQP[i
5cf0: 5d 2e 7a 4e 61 6d 65 3b 0a 20 20 7d 65 6c 73 65 ].zName;. }else
5d00: 7b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0a {. return 0;.
5d10: 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 }.}../*.** Pri
5d20: 6e 74 20 43 47 49 20 64 65 62 75 67 67 69 6e 67 nt CGI debugging
5d30: 20 6d 65 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f messages..*/.vo
5d40: 69 64 20 63 67 69 5f 64 65 62 75 67 28 63 6f 6e id cgi_debug(con
5d50: 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 st char *zFormat
5d60: 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 , ...){. va_lis
5d70: 74 20 61 70 3b 0a 20 20 69 66 28 20 67 2e 66 44 t ap;. if( g.fD
5d80: 65 62 75 67 20 29 7b 0a 20 20 20 20 76 61 5f 73 ebug ){. va_s
5d90: 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 tart(ap, zFormat
5da0: 29 3b 0a 20 20 20 20 76 66 70 72 69 6e 74 66 28 );. vfprintf(
5db0: 67 2e 66 44 65 62 75 67 2c 20 7a 46 6f 72 6d 61 g.fDebug, zForma
5dc0: 74 2c 20 61 70 29 3b 0a 20 20 20 20 76 61 5f 65 t, ap);. va_e
5dd0: 6e 64 28 61 70 29 3b 0a 20 20 20 20 66 66 6c 75 nd(ap);. fflu
5de0: 73 68 28 67 2e 66 44 65 62 75 67 29 3b 0a 20 20 sh(g.fDebug);.
5df0: 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 }.}../*.** Retur
5e00: 6e 20 74 72 75 65 20 69 66 20 61 6e 79 20 6f 66 n true if any of
5e10: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d the query param
5e20: 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 67 eters in the arg
5e30: 75 6d 65 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 72 ument.** list ar
5e40: 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e e defined..*/.in
5e50: 74 20 63 67 69 5f 61 6e 79 28 63 6f 6e 73 74 20 t cgi_any(const
5e60: 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 char *z, ...){.
5e70: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 va_list ap;. c
5e80: 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 har *z2;. if( c
5e90: 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 gi_parameter(z,0
5ea0: 29 21 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b )!=0 ) return 1;
5eb0: 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 . va_start(ap,
5ec0: 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 z);. while( (z2
5ed0: 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 = va_arg(ap, ch
5ee0: 61 72 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 ar*))!=0 ){.
5ef0: 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 if( cgi_paramete
5f00: 72 28 7a 32 2c 30 29 21 3d 30 20 29 20 72 65 74 r(z2,0)!=0 ) ret
5f10: 75 72 6e 20 31 3b 0a 20 20 7d 0a 20 20 76 61 5f urn 1;. }. va_
5f20: 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72 end(ap);. retur
5f30: 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 n 0;.}../*.** Re
5f40: 74 75 72 6e 20 74 72 75 65 20 69 66 20 61 6c 6c turn true if all
5f50: 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 61 of the query pa
5f60: 72 61 6d 65 74 65 72 73 20 69 6e 20 74 68 65 20 rameters in the
5f70: 61 72 67 75 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a argument list.**
5f80: 20 61 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f are defined..*/
5f90: 0a 69 6e 74 20 63 67 69 5f 61 6c 6c 28 63 6f 6e .int cgi_all(con
5fa0: 73 74 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 st char *z, ...)
5fb0: 7b 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a {. va_list ap;.
5fc0: 20 20 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 char *z2;. if
5fd0: 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 ( cgi_parameter(
5fe0: 7a 2c 30 29 3d 3d 30 20 29 20 72 65 74 75 72 6e z,0)==0 ) return
5ff0: 20 30 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 0;. va_start(a
6000: 70 2c 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 p, z);. while(
6010: 28 7a 32 20 3d 20 76 61 5f 61 72 67 28 61 70 2c (z2 = va_arg(ap,
6020: 20 63 68 61 72 2a 29 29 3d 3d 30 20 29 7b 0a 20 char*))==0 ){.
6030: 20 20 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d if( cgi_param
6040: 65 74 65 72 28 7a 32 2c 30 29 3d 3d 30 20 29 20 eter(z2,0)==0 )
6050: 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 return 0;. }.
6060: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 va_end(ap);. re
6070: 74 75 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a turn 1;.}../*.**
6080: 20 50 72 69 6e 74 20 61 6c 6c 20 71 75 65 72 79 Print all query
6090: 20 70 61 72 61 6d 65 74 65 72 73 20 6f 6e 20 73 parameters on s
60a0: 74 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 20 tandard output.
60b0: 20 46 6f 72 6d 61 74 20 74 68 65 0a 2a 2a 20 70 Format the.** p
60c0: 61 72 61 6d 65 74 65 72 73 20 61 73 20 48 54 4d arameters as HTM
60d0: 4c 2e 20 20 54 68 69 73 20 69 73 20 75 73 65 64 L. This is used
60e0: 20 66 6f 72 20 74 65 73 74 69 6e 67 20 61 6e 64 for testing and
60f0: 20 64 65 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76 debugging..*/.v
6100: 6f 69 64 20 63 67 69 5f 70 72 69 6e 74 5f 61 6c oid cgi_print_al
6110: 6c 28 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 l(void){. int i
6120: 3b 0a 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 ;. cgi_paramete
6130: 72 28 22 22 2c 22 22 29 3b 20 20 2f 2a 20 46 6f r("",""); /* Fo
6140: 72 63 65 20 74 68 65 20 70 61 72 61 6d 65 74 65 rce the paramete
6150: 72 73 20 69 6e 74 6f 20 73 6f 72 74 65 64 20 6f rs into sorted o
6160: 72 64 65 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d rder */. for(i=
6170: 30 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 0; i<nUsedQP; i+
6180: 2b 29 7b 0a 20 20 20 20 63 67 69 5f 70 72 69 6e +){. cgi_prin
6190: 74 66 28 22 25 73 20 3d 20 25 73 20 20 3c 62 72 tf("%s = %s <br
61a0: 20 2f 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 68 />\n",. h
61b0: 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b tmlize(aParamQP[
61c0: 69 5d 2e 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 68 i].zName, -1), h
61d0: 74 6d 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b tmlize(aParamQP[
61e0: 69 5d 2e 7a 56 61 6c 75 65 2c 20 2d 31 29 29 3b i].zValue, -1));
61f0: 0a 20 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 . }.}../*.** Wr
6200: 69 74 65 20 48 54 4d 4c 20 74 65 78 74 20 66 6f ite HTML text fo
6210: 72 20 61 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 r an option menu
6220: 20 74 6f 20 73 74 61 6e 64 61 72 64 20 6f 75 74 to standard out
6230: 70 75 74 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a 20 put. zParam.**
6240: 69 73 20 74 68 65 20 71 75 65 72 79 20 70 61 72 is the query par
6250: 61 6d 65 74 65 72 20 74 68 61 74 20 74 68 65 20 ameter that the
6260: 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 73 65 74 73 option menu sets
6270: 2e 20 20 7a 44 66 6c 74 20 69 73 20 74 68 65 0a . zDflt is the.
6280: 2a 2a 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 ** initial value
6290: 20 6f 66 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d of the option m
62a0: 65 6e 75 2e 20 20 41 64 64 69 74 69 6f 6e 20 61 enu. Addition a
62b0: 72 67 75 6d 65 6e 74 73 20 61 72 65 20 6e 61 6d rguments are nam
62c0: 65 2f 76 61 6c 75 65 0a 2a 2a 20 70 61 69 72 73 e/value.** pairs
62d0: 20 74 68 61 74 20 64 65 66 69 6e 65 20 76 61 6c that define val
62e0: 75 65 73 20 6f 6e 20 74 68 65 20 6d 65 6e 75 2e ues on the menu.
62f0: 20 20 54 68 65 20 6c 69 73 74 20 69 73 20 74 65 The list is te
6300: 72 6d 69 6e 61 74 65 64 20 77 69 74 68 0a 2a 2a rminated with.**
6310: 20 61 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 61 a single NULL a
6320: 72 67 75 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 rgument..*/.void
6330: 20 63 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 cgi_optionmenu(
6340: 69 6e 74 20 69 6e 2c 20 63 6f 6e 73 74 20 63 68 int in, const ch
6350: 61 72 20 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 68 ar *zP, const ch
6360: 61 72 20 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20 ar *zD, ...){.
6370: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 va_list ap;. ch
6380: 61 72 20 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c ar *zName, *zVal
6390: 3b 0a 20 20 69 6e 74 20 64 66 6c 74 53 65 65 6e ;. int dfltSeen
63a0: 20 3d 20 30 3b 0a 20 20 63 67 69 5f 70 72 69 6e = 0;. cgi_prin
63b0: 74 66 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 tf("%*s<select s
63c0: 69 7a 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c ize=1 name=\"%s\
63d0: 22 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a ">\n", in, "", z
63e0: 50 29 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 P);. va_start(a
63f0: 70 2c 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 p, zD);. while(
6400: 20 28 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 (zName = va_arg
6410: 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 (ap, char*))!=0
6420: 26 26 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 && (zVal = va_ar
6430: 67 28 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 g(ap, char*))!=0
6440: 20 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 ){. if( strc
6450: 6d 70 28 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 29 mp(zVal,zD)==0 )
6460: 7b 20 64 66 6c 74 53 65 65 6e 20 3d 20 31 3b 20 { dfltSeen = 1;
6470: 62 72 65 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76 break; }. }. v
6480: 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 69 66 28 a_end(ap);. if(
6490: 20 21 64 66 6c 74 53 65 65 6e 20 29 7b 0a 20 20 !dfltSeen ){.
64a0: 20 20 69 66 28 20 7a 44 5b 30 5d 20 29 7b 0a 20 if( zD[0] ){.
64b0: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 cgi_printf(
64c0: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 "%*s<option valu
64d0: 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 65 e=\"%h\" selecte
64e0: 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 d>%h</option>\n"
64f0: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 ,. in+2,
6500: 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 "", zD, zD);.
6510: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 }else{. cg
6520: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 i_printf("%*s<op
6530: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 tion value=\"\"
6540: 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c selected> <
6550: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b /option>\n", in+
6560: 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 0a 20 20 2, "");. }.
6570: 7d 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c }. va_start(ap,
6580: 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 zD);. while( (
6590: 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 zName = va_arg(a
65a0: 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 p, char*))!=0 &&
65b0: 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 (zVal = va_arg(
65c0: 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 ap, char*))!=0 )
65d0: 7b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b {. if( zName[
65e0: 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 0] ){. cgi_
65f0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 printf("%*s<opti
6600: 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 on value=\"%h\"%
6610: 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 s>%h</option>\n"
6620: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 ,. in+2,
6630: 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c "",. zVal
6640: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 ,. strcmp
6650: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 (zVal, zD) ? ""
6660: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 : " selected",.
6670: 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 zName.
6680: 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b );. }else{
6690: 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 . cgi_print
66a0: 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 f("%*s<option va
66b0: 6c 75 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 lue=\"\"%s> 
66c0: 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 ;</option>\n",.
66d0: 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c in+2, "",
66e0: 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 . strcmp(
66f0: 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a zVal, zD) ? "" :
6700: 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 " selected".
6710: 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a );. }. }.
6720: 20 20 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 va_end(ap);.
6730: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
6740: 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c /select>\n", in,
6750: 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 "");.}../*.** T
6760: 68 69 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b his routine work
6770: 73 20 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69 s a lot like cgi
6780: 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 _optionmenu() ex
6790: 63 65 70 74 20 74 68 61 74 20 74 68 65 20 6c 69 cept that the li
67a0: 73 74 20 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 20 st of.** values
67b0: 69 73 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 is contained in
67c0: 61 6e 20 61 72 72 61 79 2e 20 20 41 6c 73 6f 2c an array. Also,
67d0: 20 74 68 65 20 76 61 6c 75 65 73 20 61 72 65 20 the values are
67e0: 6a 75 73 74 20 76 61 6c 75 65 73 2c 20 6e 6f 74 just values, not
67f0: 0a 2a 2a 20 6e 61 6d 65 2f 76 61 6c 75 65 20 70 .** name/value p
6800: 61 69 72 73 20 61 73 20 69 6e 20 63 67 69 5f 6f airs as in cgi_o
6810: 70 74 69 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f ptionmenu..*/.vo
6820: 69 64 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d id cgi_v_optionm
6830: 65 6e 75 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 enu(. int in,
6840: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 /* I
6850: 6e 64 65 6e 74 20 62 79 20 74 68 69 73 20 61 6d ndent by this am
6860: 6f 75 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 ount */. const
6870: 63 68 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f char *zP, /
6880: 2a 20 54 68 65 20 71 75 65 72 79 20 70 61 72 61 * The query para
6890: 6d 65 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 meter name */.
68a0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 const char *zD,
68b0: 20 20 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 /* Default
68c0: 76 61 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 value */. const
68d0: 20 63 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 char **az
68e0: 2f 2a 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 /* NULL-terminat
68f0: 65 64 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 ed list of allow
6900: 65 64 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a ed values */.){.
6910: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 const char *zV
6920: 61 6c 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 al;. int i;. c
6930: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 gi_printf("%*s<s
6940: 65 6c 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d elect size=1 nam
6950: 65 3d 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e e=\"%s\">\n", in
6960: 2c 20 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 , "", zP);. for
6970: 28 69 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b (i=0; az[i]; i++
6980: 29 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d ){. if( strcm
6990: 70 28 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 p(az[i],zD)==0 )
69a0: 20 62 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 break;. }. if
69b0: 28 20 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 ( az[i]==0 ){.
69c0: 20 20 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 if( zD[0]==0 )
69d0: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e {. cgi_prin
69e0: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 tf("%*s<option v
69f0: 61 6c 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 alue=\"\" select
6a00: 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f ed> </optio
6a10: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e n>\n",. in
6a20: 2b 32 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c +2, "");. }el
6a30: 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 se{. cgi_pr
6a40: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e intf("%*s<option
6a50: 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 value=\"%h\" se
6a60: 6c 65 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f lected>%h</optio
6a70: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e n>\n",. in
6a80: 2b 32 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b +2, "", zD, zD);
6a90: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 . }. }. whi
6aa0: 6c 65 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a le( (zVal = *(az
6ab0: 2b 2b 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 ++))!=0 ){.
6ac0: 69 66 28 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20 if( zVal[0] ){.
6ad0: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 cgi_printf(
6ae0: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 "%*s<option valu
6af0: 65 3d 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f e=\"%h\"%s>%h</o
6b00: 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 ption>\n",.
6b10: 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 in+2, "",.
6b20: 20 20 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 zVal,.
6b30: 20 20 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 strcmp(zVal,
6b40: 7a 44 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c zD) ? "" : " sel
6b50: 65 63 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20 ected",.
6b60: 7a 56 61 6c 0a 20 20 20 20 20 20 29 3b 0a 20 20 zVal. );.
6b70: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 }else{. c
6b80: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f gi_printf("%*s<o
6b90: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 ption value=\"\"
6ba0: 25 73 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f %s> </optio
6bb0: 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 n>\n",. i
6bc0: 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 n+2, "",.
6bd0: 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 strcmp(zVal, zD
6be0: 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 ) ? "" : " selec
6bf0: 74 65 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 ted". );.
6c00: 20 20 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72 }. }. cgi_pr
6c10: 69 6e 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 intf("%*s</selec
6c20: 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a t>\n", in, "");.
6c30: 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f }../*.** This ro
6c40: 75 74 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f utine works a lo
6c50: 74 20 6c 69 6b 65 20 63 67 69 5f 76 5f 6f 70 74 t like cgi_v_opt
6c60: 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 74 ionmenu() except
6c70: 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 0a 2a that the list.*
6c80: 2a 20 69 73 20 61 20 6c 69 73 74 20 6f 66 20 70 * is a list of p
6c90: 61 69 72 73 2e 20 20 54 68 65 20 66 69 72 73 74 airs. The first
6ca0: 20 65 6c 65 6d 65 6e 74 20 6f 66 20 65 61 63 68 element of each
6cb0: 20 70 61 69 72 20 69 73 20 74 68 65 20 76 61 6c pair is the val
6cc0: 75 65 20 75 73 65 64 0a 2a 2a 20 69 6e 74 65 72 ue used.** inter
6cd0: 6e 61 6c 6c 79 20 61 6e 64 20 74 68 65 20 73 65 nally and the se
6ce0: 63 6f 6e 64 20 65 6c 65 6d 65 6e 74 20 69 73 20 cond element is
6cf0: 74 68 65 20 76 61 6c 75 65 20 64 69 73 70 6c 61 the value displa
6d00: 79 65 64 20 74 6f 20 74 68 65 20 75 73 65 72 2e yed to the user.
6d10: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f .*/.void cgi_v_o
6d20: 70 74 69 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 6e ptionmenu2(. in
6d30: 74 20 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 t in,
6d40: 20 20 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20 /* Indent by
6d50: 74 68 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 this amount */.
6d60: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c const char *zP,
6d70: 20 20 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65 /* The que
6d80: 72 79 20 70 61 72 61 6d 65 74 65 72 20 6e 61 6d ry parameter nam
6d90: 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 e */. const cha
6da0: 72 20 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44 r *zD, /* D
6db0: 65 66 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a efault value */.
6dc0: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 const char **a
6dd0: 7a 20 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 z /* NULL-t
6de0: 65 72 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 6f erminated list o
6df0: 66 20 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 f allowed values
6e00: 20 2a 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 */.){. const c
6e10: 68 61 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 har *zVal;. int
6e20: 20 69 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 i;. cgi_printf
6e30: 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a ("%*s<select siz
6e40: 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e e=1 name=\"%s\">
6e50: 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 \n", in, "", zP)
6e60: 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b ;. for(i=0; az[
6e70: 69 5d 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20 69 i]; i+=2){. i
6e80: 66 28 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c f( strcmp(az[i],
6e90: 7a 44 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a zD)==0 ) break;.
6ea0: 20 20 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d }. if( az[i]=
6eb0: 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 =0 ){. if( zD
6ec0: 5b 30 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 [0]==0 ){.
6ed0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
6ee0: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c option value=\"\
6ef0: 22 20 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 " selected> 
6f00: 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 ;</option>\n",.
6f10: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b in+2, "");
6f20: 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 . }else{.
6f30: 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a cgi_printf("%*
6f40: 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c s<option value=\
6f50: 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 "%h\" selected>%
6f60: 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 h</option>\n",.
6f70: 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 in+2, "",
6f80: 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 zD, zD);. }.
6f90: 20 7d 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 61 }. while( (zVa
6fa0: 6c 20 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 l = *(az++))!=0
6fb0: 20 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 ){. const ch
6fc0: 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a ar *zName = *(az
6fd0: 2b 2b 29 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 ++);. if( zNa
6fe0: 6d 65 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 me[0] ){. c
6ff0: 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f gi_printf("%*s<o
7000: 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 ption value=\"%h
7010: 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e \"%s>%h</option>
7020: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b \n",. in+
7030: 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 2, "",. z
7040: 56 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 Val,. str
7050: 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 cmp(zVal, zD) ?
7060: 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 "" : " selected"
7070: 2c 0a 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a ,. zName.
7080: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c );. }el
7090: 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 se{. cgi_pr
70a0: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e intf("%*s<option
70b0: 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e value=\"%h\"%s>
70c0: 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c </option>\
70d0: 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 n",. in+2
70e0: 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 , "",. zV
70f0: 61 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 al,. strc
7100: 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 mp(zVal, zD) ? "
7110: 22 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 0a " : " selected".
7120: 20 20 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 );. }.
7130: 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 }. cgi_printf(
7140: 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 "%*s</select>\n"
7150: 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a , in, "");.}../*
7160: 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e 65 .** This routine
7170: 20 77 6f 72 6b 73 20 6c 69 6b 65 20 22 70 72 69 works like "pri
7180: 6e 74 66 22 20 65 78 63 65 70 74 20 74 68 61 74 ntf" except that
7190: 20 69 74 20 68 61 73 20 74 68 65 0a 2a 2a 20 65 it has the.** e
71a0: 78 74 72 61 20 66 6f 72 6d 61 74 74 69 6e 67 20 xtra formatting
71b0: 63 61 70 61 62 69 6c 69 74 69 65 73 20 73 75 63 capabilities suc
71c0: 68 20 61 73 20 25 68 20 61 6e 64 20 25 74 2e 0a h as %h and %t..
71d0: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 72 69 6e */.void cgi_prin
71e0: 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a tf(const char *z
71f0: 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 Format, ...){.
7200: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 61 va_list ap;. va
7210: 5f 73 74 61 72 74 28 61 70 2c 7a 46 6f 72 6d 61 _start(ap,zForma
7220: 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 70 t);. vxprintf(p
7230: 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d 61 74 2c Content,zFormat,
7240: 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 ap);. va_end(ap
7250: 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 );.}../*.** This
7260: 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 6c routine works l
7270: 69 6b 65 20 22 76 70 72 69 6e 74 66 22 20 65 78 ike "vprintf" ex
7280: 63 65 70 74 20 74 68 61 74 20 69 74 20 68 61 73 cept that it has
7290: 20 74 68 65 0a 2a 2a 20 65 78 74 72 61 20 66 6f the.** extra fo
72a0: 72 6d 61 74 74 69 6e 67 20 63 61 70 61 62 69 6c rmatting capabil
72b0: 69 74 69 65 73 20 73 75 63 68 20 61 73 20 25 68 ities such as %h
72c0: 20 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 and %t..*/.void
72d0: 20 63 67 69 5f 76 70 72 69 6e 74 66 28 63 6f 6e cgi_vprintf(con
72e0: 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 st char *zFormat
72f0: 2c 20 76 61 5f 6c 69 73 74 20 61 70 29 7b 0a 20 , va_list ap){.
7300: 20 76 78 70 72 69 6e 74 66 28 70 43 6f 6e 74 65 vxprintf(pConte
7310: 6e 74 2c 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a nt,zFormat,ap);.
7320: 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 }.../*.** Send a
7330: 20 72 65 70 6c 79 20 69 6e 64 69 63 61 74 69 6e reply indicatin
7340: 67 20 74 68 61 74 20 74 68 65 20 48 54 54 50 20 g that the HTTP
7350: 72 65 71 75 65 73 74 20 77 61 73 20 6d 61 6c 66 request was malf
7360: 6f 72 6d 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 ormed.*/.static
7370: 76 6f 69 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 void malformed_r
7380: 65 71 75 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 equest(void){.
7390: 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 35 cgi_set_status(5
73a0: 30 31 2c 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 01, "Not Impleme
73b0: 6e 74 65 64 22 29 3b 0a 20 20 63 67 69 5f 70 72 nted");. cgi_pr
73c0: 69 6e 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c intf(. "<html
73d0: 3e 3c 62 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69 ><body>Unrecogni
73e0: 7a 65 64 20 48 54 54 50 20 52 65 71 75 65 73 74 zed HTTP Request
73f0: 3c 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e </body></html>\n
7400: 22 0a 20 20 29 3b 0a 20 20 63 67 69 5f 72 65 70 ". );. cgi_rep
7410: 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 30 29 3b ly();. exit(0);
7420: 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 .}../*.** Panic
7430: 61 6e 64 20 64 69 65 20 77 68 69 6c 65 20 70 72 and die while pr
7440: 6f 63 65 73 73 69 6e 67 20 61 20 77 65 62 70 61 ocessing a webpa
7450: 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f ge..*/.void cgi_
7460: 70 61 6e 69 63 28 63 6f 6e 73 74 20 63 68 61 72 panic(const char
7470: 20 2a 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b *zFormat, ...){
7480: 0a 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 . va_list ap;.
7490: 20 63 67 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 cgi_reset_conte
74a0: 6e 74 28 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f nt();. cgi_set_
74b0: 73 74 61 74 75 73 28 35 30 30 2c 20 22 49 6e 74 status(500, "Int
74c0: 65 72 6e 61 6c 20 53 65 72 76 65 72 20 45 72 72 ernal Server Err
74d0: 6f 72 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e or");. cgi_prin
74e0: 74 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c tf(. "<html><
74f0: 62 6f 64 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 body><h1>Interna
7500: 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72 3c 2f l Server Error</
7510: 68 31 3e 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61 h1>\n". "<pla
7520: 69 6e 74 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20 intext>". );.
7530: 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 46 6f va_start(ap, zFo
7540: 72 6d 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 rmat);. vxprint
7550: 66 28 70 43 6f 6e 74 65 6e 74 2c 7a 46 6f 72 6d f(pContent,zForm
7560: 61 74 2c 61 70 29 3b 0a 20 20 76 61 5f 65 6e 64 at,ap);. va_end
7570: 28 61 70 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c (ap);. cgi_repl
7580: 79 28 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a y();. exit(1);.
7590: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 6d 6f 76 65 20 }../*.** Remove
75a0: 74 68 65 20 66 69 72 73 74 20 73 70 61 63 65 2d the first space-
75b0: 64 65 6c 69 6d 69 74 65 64 20 74 6f 6b 65 6e 20 delimited token
75c0: 66 72 6f 6d 20 61 20 73 74 72 69 6e 67 20 61 6e from a string an
75d0: 64 20 72 65 74 75 72 6e 0a 2a 2a 20 61 20 70 6f d return.** a po
75e0: 69 6e 74 65 72 20 74 6f 20 69 74 2e 20 20 41 64 inter to it. Ad
75f0: 64 20 61 20 4e 55 4c 4c 20 74 6f 20 74 68 65 20 d a NULL to the
7600: 73 74 72 69 6e 67 20 74 6f 20 74 65 72 6d 69 6e string to termin
7610: 61 74 65 20 74 68 65 20 74 6f 6b 65 6e 2e 0a 2a ate the token..*
7620: 2a 20 4d 61 6b 65 20 2a 7a 4c 65 66 74 4f 76 65 * Make *zLeftOve
7630: 72 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 73 r point to the s
7640: 74 61 72 74 20 6f 66 20 74 68 65 20 6e 65 78 74 tart of the next
7650: 20 74 6f 6b 65 6e 2e 0a 2a 2f 0a 73 74 61 74 69 token..*/.stati
7660: 63 20 63 68 61 72 20 2a 65 78 74 72 61 63 74 5f c char *extract_
7670: 74 6f 6b 65 6e 28 63 68 61 72 20 2a 7a 49 6e 70 token(char *zInp
7680: 75 74 2c 20 63 68 61 72 20 2a 2a 7a 4c 65 66 74 ut, char **zLeft
7690: 4f 76 65 72 29 7b 0a 20 20 63 68 61 72 20 2a 7a Over){. char *z
76a0: 52 65 73 75 6c 74 20 3d 20 30 3b 0a 20 20 69 66 Result = 0;. if
76b0: 28 20 7a 49 6e 70 75 74 3d 3d 30 20 29 7b 0a 20 ( zInput==0 ){.
76c0: 20 20 20 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 if( zLeftOver
76d0: 20 29 20 2a 7a 4c 65 66 74 4f 76 65 72 20 3d 20 ) *zLeftOver =
76e0: 30 3b 0a 20 20 20 20 72 65 74 75 72 6e 20 30 3b 0;. return 0;
76f0: 0a 20 20 7d 0a 20 20 77 68 69 6c 65 28 20 69 73 . }. while( is
7700: 73 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 space(*zInput) )
7710: 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 { zInput++; }.
7720: 7a 52 65 73 75 6c 74 20 3d 20 7a 49 6e 70 75 74 zResult = zInput
7730: 3b 0a 20 20 77 68 69 6c 65 28 20 2a 7a 49 6e 70 ;. while( *zInp
7740: 75 74 20 26 26 20 21 69 73 73 70 61 63 65 28 2a ut && !isspace(*
7750: 7a 49 6e 70 75 74 29 20 29 7b 20 7a 49 6e 70 75 zInput) ){ zInpu
7760: 74 2b 2b 3b 20 7d 0a 20 20 69 66 28 20 2a 7a 49 t++; }. if( *zI
7770: 6e 70 75 74 20 29 7b 0a 20 20 20 20 2a 7a 49 6e nput ){. *zIn
7780: 70 75 74 20 3d 20 30 3b 0a 20 20 20 20 7a 49 6e put = 0;. zIn
7790: 70 75 74 2b 2b 3b 0a 20 20 20 20 77 68 69 6c 65 put++;. while
77a0: 28 20 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 ( isspace(*zInpu
77b0: 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 t) ){ zInput++;
77c0: 7d 0a 20 20 7d 0a 20 20 69 66 28 20 7a 4c 65 66 }. }. if( zLef
77d0: 74 4f 76 65 72 20 29 7b 20 2a 7a 4c 65 66 74 4f tOver ){ *zLeftO
77e0: 76 65 72 20 3d 20 7a 49 6e 70 75 74 3b 20 7d 0a ver = zInput; }.
77f0: 20 20 72 65 74 75 72 6e 20 7a 52 65 73 75 6c 74 return zResult
7800: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 ;.}../*.** This
7810: 72 6f 75 74 69 6e 65 20 68 61 6e 64 6c 65 73 20 routine handles
7820: 61 20 73 69 6e 67 6c 65 20 48 54 54 50 20 72 65 a single HTTP re
7830: 71 75 65 73 74 20 77 68 69 63 68 20 69 73 20 63 quest which is c
7840: 6f 6d 69 6e 67 20 69 6e 20 6f 6e 0a 2a 2a 20 73 oming in on.** s
7850: 74 61 6e 64 61 72 64 20 69 6e 70 75 74 20 61 6e tandard input an
7860: 64 20 77 68 69 63 68 20 72 65 70 6c 69 65 73 20 d which replies
7870: 6f 6e 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 on standard outp
7880: 75 74 2e 0a 2a 2a 0a 2a 2a 20 54 68 65 20 48 54 ut..**.** The HT
7890: 54 50 20 72 65 71 75 65 73 74 20 69 73 20 72 65 TP request is re
78a0: 61 64 20 66 72 6f 6d 20 73 74 61 6e 64 61 72 64 ad from standard
78b0: 20 69 6e 70 75 74 20 61 6e 64 20 69 73 20 75 73 input and is us
78c0: 65 64 20 74 6f 20 69 6e 69 74 69 61 6c 69 7a 65 ed to initialize
78d0: 0a 2a 2a 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 .** environment
78e0: 76 61 72 69 61 62 6c 65 73 20 61 73 20 70 65 72 variables as per
78f0: 20 43 47 49 2e 20 20 54 68 65 20 63 67 69 5f 69 CGI. The cgi_i
7900: 6e 69 74 28 29 20 72 6f 75 74 69 6e 65 20 74 6f nit() routine to
7910: 20 63 6f 6d 70 6c 65 74 65 0a 2a 2a 20 74 68 65 complete.** the
7920: 20 73 65 74 75 70 2e 20 20 4f 6e 63 65 20 61 6c setup. Once al
7930: 6c 20 74 68 65 20 73 65 74 75 70 20 69 73 20 66 l the setup is f
7940: 69 6e 69 73 68 65 64 2c 20 74 68 69 73 20 70 72 inished, this pr
7950: 6f 63 65 64 75 72 65 20 72 65 74 75 72 6e 73 0a ocedure returns.
7960: 2a 2a 20 61 6e 64 20 73 75 62 73 65 71 75 65 6e ** and subsequen
7970: 74 20 63 6f 64 65 20 68 61 6e 64 6c 65 73 20 74 t code handles t
7980: 68 65 20 61 63 74 75 61 6c 20 67 65 6e 65 72 61 he actual genera
7990: 74 69 6f 6e 20 6f 66 20 74 68 65 20 77 65 62 70 tion of the webp
79a0: 61 67 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 age..*/.void cgi
79b0: 5f 68 61 6e 64 6c 65 5f 68 74 74 70 5f 72 65 71 _handle_http_req
79c0: 75 65 73 74 28 63 6f 6e 73 74 20 63 68 61 72 20 uest(const char
79d0: 2a 7a 49 70 41 64 64 72 29 7b 0a 20 20 63 68 61 *zIpAddr){. cha
79e0: 72 20 2a 7a 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 r *z, *zToken;.
79f0: 20 69 6e 74 20 69 3b 0a 20 20 73 74 72 75 63 74 int i;. struct
7a00: 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20 72 65 6d sockaddr_in rem
7a10: 6f 74 65 4e 61 6d 65 3b 0a 20 20 73 69 7a 65 5f oteName;. size_
7a20: 74 20 73 69 7a 65 20 3d 20 73 69 7a 65 6f 66 28 t size = sizeof(
7a30: 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f struct sockaddr_
7a40: 69 6e 29 3b 0a 20 20 63 68 61 72 20 7a 4c 69 6e in);. char zLin
7a50: 65 5b 32 30 30 30 5d 3b 20 20 20 20 20 2f 2a 20 e[2000]; /*
7a60: 41 20 73 69 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 A single line of
7a70: 20 69 6e 70 75 74 2e 20 2a 2f 0a 0a 20 20 67 2e input. */.. g.
7a80: 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 3d 20 fullHttpReply =
7a90: 31 3b 0a 20 20 69 66 28 20 66 67 65 74 73 28 7a 1;. if( fgets(z
7aa0: 4c 69 6e 65 2c 20 73 69 7a 65 6f 66 28 7a 4c 69 Line, sizeof(zLi
7ab0: 6e 65 29 2c 67 2e 68 74 74 70 49 6e 29 3d 3d 30 ne),g.httpIn)==0
7ac0: 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 ){. malforme
7ad0: 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d d_request();. }
7ae0: 0a 20 20 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 . zToken = extr
7af0: 61 63 74 5f 74 6f 6b 65 6e 28 7a 4c 69 6e 65 2c act_token(zLine,
7b00: 20 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f 6b &z);. if( zTok
7b10: 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61 6c en==0 ){. mal
7b20: 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28 29 formed_request()
7b30: 3b 0a 20 20 7d 0a 20 20 69 66 28 20 73 74 72 63 ;. }. if( strc
7b40: 6d 70 28 7a 54 6f 6b 65 6e 2c 22 47 45 54 22 29 mp(zToken,"GET")
7b50: 21 3d 30 20 26 26 20 73 74 72 63 6d 70 28 7a 54 !=0 && strcmp(zT
7b60: 6f 6b 65 6e 2c 22 50 4f 53 54 22 29 21 3d 30 0a oken,"POST")!=0.
7b70: 20 20 20 20 20 20 26 26 20 73 74 72 63 6d 70 28 && strcmp(
7b80: 7a 54 6f 6b 65 6e 2c 22 48 45 41 44 22 29 21 3d zToken,"HEAD")!=
7b90: 30 20 29 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 0 ){. malform
7ba0: 65 64 5f 72 65 71 75 65 73 74 28 29 3b 0a 20 20 ed_request();.
7bb0: 7d 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 }. cgi_setenv("
7bc0: 47 41 54 45 57 41 59 5f 49 4e 54 45 52 46 41 43 GATEWAY_INTERFAC
7bd0: 45 22 2c 22 43 47 49 2f 31 2e 30 22 29 3b 0a 20 E","CGI/1.0");.
7be0: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45 51 cgi_setenv("REQ
7bf0: 55 45 53 54 5f 4d 45 54 48 4f 44 22 2c 7a 54 6f UEST_METHOD",zTo
7c00: 6b 65 6e 29 3b 0a 20 20 7a 54 6f 6b 65 6e 20 3d ken);. zToken =
7c10: 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28 7a extract_token(z
7c20: 2c 20 26 7a 29 3b 0a 20 20 69 66 28 20 7a 54 6f , &z);. if( zTo
7c30: 6b 65 6e 3d 3d 30 20 29 7b 0a 20 20 20 20 6d 61 ken==0 ){. ma
7c40: 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 74 28 lformed_request(
7c50: 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f 73 65 74 );. }. cgi_set
7c60: 65 6e 76 28 22 52 45 51 55 45 53 54 5f 55 52 49 env("REQUEST_URI
7c70: 22 2c 20 7a 54 6f 6b 65 6e 29 3b 0a 20 20 66 6f ", zToken);. fo
7c80: 72 28 69 3d 30 3b 20 7a 54 6f 6b 65 6e 5b 69 5d r(i=0; zToken[i]
7c90: 20 26 26 20 7a 54 6f 6b 65 6e 5b 69 5d 21 3d 27 && zToken[i]!='
7ca0: 3f 27 3b 20 69 2b 2b 29 7b 7d 0a 20 20 69 66 28 ?'; i++){}. if(
7cb0: 20 7a 54 6f 6b 65 6e 5b 69 5d 20 29 20 7a 54 6f zToken[i] ) zTo
7cc0: 6b 65 6e 5b 69 2b 2b 5d 20 3d 20 30 3b 0a 20 20 ken[i++] = 0;.
7cd0: 63 67 69 5f 73 65 74 65 6e 76 28 22 50 41 54 48 cgi_setenv("PATH
7ce0: 5f 49 4e 46 4f 22 2c 20 7a 54 6f 6b 65 6e 29 3b _INFO", zToken);
7cf0: 0a 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 51 . cgi_setenv("Q
7d00: 55 45 52 59 5f 53 54 52 49 4e 47 22 2c 20 26 7a UERY_STRING", &z
7d10: 54 6f 6b 65 6e 5b 69 5d 29 3b 0a 20 20 69 66 28 Token[i]);. if(
7d20: 20 7a 49 70 41 64 64 72 3d 3d 30 20 26 26 0a 20 zIpAddr==0 &&.
7d30: 20 20 20 20 20 20 20 67 65 74 70 65 65 72 6e 61 getpeerna
7d40: 6d 65 28 66 69 6c 65 6e 6f 28 67 2e 68 74 74 70 me(fileno(g.http
7d50: 49 6e 29 2c 20 28 73 74 72 75 63 74 20 73 6f 63 In), (struct soc
7d60: 6b 61 64 64 72 2a 29 26 72 65 6d 6f 74 65 4e 61 kaddr*)&remoteNa
7d70: 6d 65 2c 20 0a 20 20 20 20 20 20 20 20 20 20 20 me, .
7d80: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
7d90: 20 20 20 20 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a (socklen_t*
7da0: 29 26 73 69 7a 65 29 3e 3d 30 0a 20 20 29 7b 0a )&size)>=0. ){.
7db0: 20 20 20 20 7a 49 70 41 64 64 72 20 3d 20 69 6e zIpAddr = in
7dc0: 65 74 5f 6e 74 6f 61 28 72 65 6d 6f 74 65 4e 61 et_ntoa(remoteNa
7dd0: 6d 65 2e 73 69 6e 5f 61 64 64 72 29 3b 0a 20 20 me.sin_addr);.
7de0: 7d 0a 20 20 69 66 28 20 7a 49 70 41 64 64 72 20 }. if( zIpAddr
7df0: 29 7b 20 20 20 0a 20 20 20 20 63 67 69 5f 73 65 ){ . cgi_se
7e00: 74 65 6e 76 28 22 52 45 4d 4f 54 45 5f 41 44 44 tenv("REMOTE_ADD
7e10: 52 22 2c 20 7a 49 70 41 64 64 72 29 3b 0a 20 20 R", zIpAddr);.
7e20: 20 20 67 2e 7a 49 70 41 64 64 72 20 3d 20 6d 70 g.zIpAddr = mp
7e30: 72 69 6e 74 66 28 22 25 73 22 2c 20 7a 49 70 41 rintf("%s", zIpA
7e40: 64 64 72 29 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a ddr);. }. . /*
7e50: 20 47 65 74 20 61 6c 6c 20 74 68 65 20 6f 70 74 Get all the opt
7e60: 69 6f 6e 61 6c 20 66 69 65 6c 64 73 20 74 68 61 ional fields tha
7e70: 74 20 66 6f 6c 6c 6f 77 20 74 68 65 20 66 69 72 t follow the fir
7e80: 73 74 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20 st line.. */.
7e90: 77 68 69 6c 65 28 20 66 67 65 74 73 28 7a 4c 69 while( fgets(zLi
7ea0: 6e 65 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 ne,sizeof(zLine)
7eb0: 2c 67 2e 68 74 74 70 49 6e 29 20 29 7b 0a 20 20 ,g.httpIn) ){.
7ec0: 20 20 63 68 61 72 20 2a 7a 46 69 65 6c 64 4e 61 char *zFieldNa
7ed0: 6d 65 3b 0a 20 20 20 20 63 68 61 72 20 2a 7a 56 me;. char *zV
7ee0: 61 6c 3b 0a 0a 20 20 20 20 7a 46 69 65 6c 64 4e al;.. zFieldN
7ef0: 61 6d 65 20 3d 20 65 78 74 72 61 63 74 5f 74 6f ame = extract_to
7f00: 6b 65 6e 28 7a 4c 69 6e 65 2c 26 7a 56 61 6c 29 ken(zLine,&zVal)
7f10: 3b 0a 20 20 20 20 69 66 28 20 7a 46 69 65 6c 64 ;. if( zField
7f20: 4e 61 6d 65 3d 3d 30 20 7c 7c 20 2a 7a 46 69 65 Name==0 || *zFie
7f30: 6c 64 4e 61 6d 65 3d 3d 30 20 29 20 62 72 65 61 ldName==0 ) brea
7f40: 6b 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 k;. while( is
7f50: 73 70 61 63 65 28 2a 7a 56 61 6c 29 20 29 7b 20 space(*zVal) ){
7f60: 7a 56 61 6c 2b 2b 3b 20 7d 0a 20 20 20 20 69 20 zVal++; }. i
7f70: 3d 20 73 74 72 6c 65 6e 28 7a 56 61 6c 29 3b 0a = strlen(zVal);.
7f80: 20 20 20 20 77 68 69 6c 65 28 20 69 3e 30 20 26 while( i>0 &
7f90: 26 20 69 73 73 70 61 63 65 28 7a 56 61 6c 5b 69 & isspace(zVal[i
7fa0: 2d 31 5d 29 20 29 7b 20 69 2d 2d 3b 20 7d 0a 20 -1]) ){ i--; }.
7fb0: 20 20 20 7a 56 61 6c 5b 69 5d 20 3d 20 30 3b 0a zVal[i] = 0;.
7fc0: 20 20 20 20 66 6f 72 28 69 3d 30 3b 20 7a 46 69 for(i=0; zFi
7fd0: 65 6c 64 4e 61 6d 65 5b 69 5d 3b 20 69 2b 2b 29 eldName[i]; i++)
7fe0: 7b 20 7a 46 69 65 6c 64 4e 61 6d 65 5b 69 5d 20 { zFieldName[i]
7ff0: 3d 20 74 6f 6c 6f 77 65 72 28 7a 46 69 65 6c 64 = tolower(zField
8000: 4e 61 6d 65 5b 69 5d 29 3b 20 7d 0a 20 20 20 20 Name[i]); }.
8010: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c if( strcmp(zFiel
8020: 64 4e 61 6d 65 2c 22 75 73 65 72 2d 61 67 65 6e dName,"user-agen
8030: 74 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 t:")==0 ){.
8040: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 cgi_setenv("HTT
8050: 50 5f 55 53 45 52 5f 41 47 45 4e 54 22 2c 20 7a P_USER_AGENT", z
8060: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 Val);. }else
8070: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c if( strcmp(zFiel
8080: 64 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d 6c dName,"content-l
8090: 65 6e 67 74 68 3a 22 29 3d 3d 30 20 29 7b 0a 20 ength:")==0 ){.
80a0: 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 cgi_setenv(
80b0: 22 43 4f 4e 54 45 4e 54 5f 4c 45 4e 47 54 48 22 "CONTENT_LENGTH"
80c0: 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c , zVal);. }el
80d0: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 se if( strcmp(zF
80e0: 69 65 6c 64 4e 61 6d 65 2c 22 72 65 66 65 72 65 ieldName,"refere
80f0: 72 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 r:")==0 ){.
8100: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 cgi_setenv("HTT
8110: 50 5f 52 45 46 45 52 45 52 22 2c 20 7a 56 61 6c P_REFERER", zVal
8120: 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 );. }else if(
8130: 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 strcmp(zFieldNa
8140: 6d 65 2c 22 68 6f 73 74 3a 22 29 3d 3d 30 20 29 me,"host:")==0 )
8150: 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 {. cgi_sete
8160: 6e 76 28 22 48 54 54 50 5f 48 4f 53 54 22 2c 20 nv("HTTP_HOST",
8170: 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 zVal);. }else
8180: 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 if( strcmp(zFie
8190: 6c 64 4e 61 6d 65 2c 22 63 6f 6e 74 65 6e 74 2d ldName,"content-
81a0: 74 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 type:")==0 ){.
81b0: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 cgi_setenv("
81c0: 43 4f 4e 54 45 4e 54 5f 54 59 50 45 22 2c 20 7a CONTENT_TYPE", z
81d0: 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 Val);. }else
81e0: 69 66 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c if( strcmp(zFiel
81f0: 64 4e 61 6d 65 2c 22 63 6f 6f 6b 69 65 3a 22 29 dName,"cookie:")
8200: 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 ==0 ){. cgi
8210: 5f 73 65 74 65 6e 76 28 22 48 54 54 50 5f 43 4f _setenv("HTTP_CO
8220: 4f 4b 49 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 OKIE", zVal);.
8230: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 }else if( strc
8240: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 69 mp(zFieldName,"i
8250: 66 2d 6e 6f 6e 65 2d 6d 61 74 63 68 3a 22 29 3d f-none-match:")=
8260: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f =0 ){. cgi_
8270: 73 65 74 65 6e 76 28 22 48 54 54 50 5f 49 46 5f setenv("HTTP_IF_
8280: 4e 4f 4e 45 5f 4d 41 54 43 48 22 2c 20 7a 56 61 NONE_MATCH", zVa
8290: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 l);. }else if
82a0: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e ( strcmp(zFieldN
82b0: 61 6d 65 2c 22 69 66 2d 6d 6f 64 69 66 69 65 64 ame,"if-modified
82c0: 2d 73 69 6e 63 65 3a 22 29 3d 3d 30 20 29 7b 0a -since:")==0 ){.
82d0: 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 cgi_setenv
82e0: 28 22 48 54 54 50 5f 49 46 5f 4d 4f 44 49 46 49 ("HTTP_IF_MODIFI
82f0: 45 44 5f 53 49 4e 43 45 22 2c 20 7a 56 61 6c 29 ED_SINCE", zVal)
8300: 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 63 ;. }. }.. c
8310: 67 69 5f 69 6e 69 74 28 29 3b 0a 7d 0a 0a 2f 2a gi_init();.}../*
8320: 0a 2a 2a 20 4d 61 78 69 6d 75 6d 20 6e 75 6d 62 .** Maximum numb
8330: 65 72 20 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 er of child proc
8340: 65 73 73 65 73 20 74 68 61 74 20 77 65 20 63 61 esses that we ca
8350: 6e 20 68 61 76 65 20 72 75 6e 6e 69 6e 67 0a 2a n have running.*
8360: 2a 20 61 74 20 6f 6e 65 20 74 69 6d 65 20 62 65 * at one time be
8370: 66 6f 72 65 20 77 65 20 73 74 61 72 74 20 73 6c fore we start sl
8380: 6f 77 69 6e 67 20 74 68 69 6e 67 73 20 64 6f 77 owing things dow
8390: 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 20 4d 41 n..*/.#define MA
83a0: 58 5f 50 41 52 41 4c 4c 45 4c 20 32 0a 0a 2f 2a X_PARALLEL 2../*
83b0: 0a 2a 2a 20 49 6d 70 6c 65 6d 65 6e 74 20 61 6e .** Implement an
83c0: 20 48 54 54 50 20 73 65 72 76 65 72 20 64 61 65 HTTP server dae
83d0: 6d 6f 6e 20 6c 69 73 74 65 6e 69 6e 67 20 6f 6e mon listening on
83e0: 20 70 6f 72 74 20 69 50 6f 72 74 2e 0a 2a 2a 0a port iPort..**.
83f0: 2a 2a 20 41 73 20 6e 65 77 20 63 6f 6e 6e 65 63 ** As new connec
8400: 74 69 6f 6e 73 20 61 72 72 69 76 65 2c 20 66 6f tions arrive, fo
8410: 72 6b 20 61 20 63 68 69 6c 64 20 61 6e 64 20 6c rk a child and l
8420: 65 74 20 63 68 69 6c 64 20 72 65 74 75 72 6e 0a et child return.
8430: 2a 2a 20 6f 75 74 20 6f 66 20 74 68 69 73 20 70 ** out of this p
8440: 72 6f 63 65 64 75 72 65 20 63 61 6c 6c 2e 20 20 rocedure call.
8450: 54 68 65 20 63 68 69 6c 64 20 77 69 6c 6c 20 68 The child will h
8460: 61 6e 64 6c 65 20 74 68 65 20 72 65 71 75 65 73 andle the reques
8470: 74 2e 0a 2a 2a 20 54 68 65 20 70 61 72 65 6e 74 t..** The parent
8480: 20 6e 65 76 65 72 20 72 65 74 75 72 6e 73 20 66 never returns f
8490: 72 6f 6d 20 74 68 69 73 20 70 72 6f 63 65 64 75 rom this procedu
84a0: 72 65 2e 0a 2a 2a 0a 2a 2a 20 52 65 74 75 72 6e re..**.** Return
84b0: 20 30 20 74 6f 20 65 61 63 68 20 63 68 69 6c 64 0 to each child
84c0: 20 61 73 20 69 74 20 72 75 6e 73 2e 20 20 49 66 as it runs. If
84d0: 20 75 6e 61 62 6c 65 20 74 6f 20 65 73 74 61 62 unable to estab
84e0: 6c 69 73 68 20 61 0a 2a 2a 20 6c 69 73 74 65 6e lish a.** listen
84f0: 69 6e 67 20 73 6f 63 6b 65 74 2c 20 72 65 74 75 ing socket, retu
8500: 72 6e 20 6e 6f 6e 2d 7a 65 72 6f 2e 0a 2a 2f 0a rn non-zero..*/.
8510: 69 6e 74 20 63 67 69 5f 68 74 74 70 5f 73 65 72 int cgi_http_ser
8520: 76 65 72 28 69 6e 74 20 6d 6e 50 6f 72 74 2c 20 ver(int mnPort,
8530: 69 6e 74 20 6d 78 50 6f 72 74 2c 20 63 68 61 72 int mxPort, char
8540: 20 2a 7a 42 72 6f 77 73 65 72 29 7b 0a 23 69 66 *zBrowser){.#if
8550: 64 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a def __MINGW32__.
8560: 20 20 2f 2a 20 55 73 65 20 77 69 6e 33 32 5f 68 /* Use win32_h
8570: 74 74 70 5f 73 65 72 76 65 72 28 29 20 69 6e 73 ttp_server() ins
8580: 74 65 61 64 20 2a 2f 0a 20 20 65 78 69 74 28 31 tead */. exit(1
8590: 29 3b 0a 23 65 6c 73 65 0a 20 20 69 6e 74 20 6c );.#else. int l
85a0: 69 73 74 65 6e 65 72 20 3d 20 2d 31 3b 20 20 20 istener = -1;
85b0: 20 20 20 20 20 20 20 20 2f 2a 20 54 68 65 20 73 /* The s
85c0: 65 72 76 65 72 20 73 6f 63 6b 65 74 20 2a 2f 0a erver socket */.
85d0: 20 20 69 6e 74 20 63 6f 6e 6e 65 63 74 69 6f 6e int connection
85e0: 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 2f ; /
85f0: 2a 20 41 20 73 6f 63 6b 65 74 20 66 6f 72 20 65 * A socket for e
8600: 61 63 68 20 69 6e 64 69 76 69 64 75 61 6c 20 63 ach individual c
8610: 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 20 20 66 onnection */. f
8620: 64 5f 73 65 74 20 72 65 61 64 66 64 73 3b 20 20 d_set readfds;
8630: 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a 20 53 /* S
8640: 65 74 20 6f 66 20 66 69 6c 65 20 64 65 73 63 72 et of file descr
8650: 69 70 74 6f 72 73 20 66 6f 72 20 73 65 6c 65 63 iptors for selec
8660: 74 28 29 20 2a 2f 0a 20 20 73 69 7a 65 5f 74 20 t() */. size_t
8670: 6c 65 6e 61 64 64 72 3b 20 20 20 20 20 20 20 20 lenaddr;
8680: 20 20 20 20 20 20 2f 2a 20 4c 65 6e 67 74 68 20 /* Length
8690: 6f 66 20 74 68 65 20 69 6e 61 64 64 72 20 73 74 of the inaddr st
86a0: 72 75 63 74 75 72 65 20 2a 2f 0a 20 20 69 6e 74 ructure */. int
86b0: 20 63 68 69 6c 64 3b 20 20 20 20 20 20 20 20 20 child;
86c0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 50 49 44 /* PID
86d0: 20 6f 66 20 74 68 65 20 63 68 69 6c 64 20 70 72 of the child pr
86e0: 6f 63 65 73 73 20 2a 2f 0a 20 20 69 6e 74 20 6e ocess */. int n
86f0: 63 68 69 6c 64 72 65 6e 20 3d 20 30 3b 20 20 20 children = 0;
8700: 20 20 20 20 20 20 20 20 2f 2a 20 4e 75 6d 62 65 /* Numbe
8710: 72 20 6f 66 20 63 68 69 6c 64 20 70 72 6f 63 65 r of child proce
8720: 73 73 65 73 20 2a 2f 0a 20 20 73 74 72 75 63 74 sses */. struct
8730: 20 74 69 6d 65 76 61 6c 20 64 65 6c 61 79 3b 20 timeval delay;
8740: 20 20 20 20 20 20 20 2f 2a 20 48 6f 77 20 6c 6f /* How lo
8750: 6e 67 20 74 6f 20 77 61 69 74 20 69 6e 73 69 64 ng to wait insid
8760: 65 20 73 65 6c 65 63 74 28 29 20 2a 2f 0a 20 20 e select() */.
8770: 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f struct sockaddr_
8780: 69 6e 20 69 6e 61 64 64 72 3b 20 20 20 2f 2a 20 in inaddr; /*
8790: 54 68 65 20 73 6f 63 6b 65 74 20 61 64 64 72 65 The socket addre
87a0: 73 73 20 2a 2f 0a 20 20 69 6e 74 20 6f 70 74 20 ss */. int opt
87b0: 3d 20 31 3b 20 20 20 20 20 20 20 20 20 20 20 20 = 1;
87c0: 20 20 20 20 20 2f 2a 20 73 65 74 73 6f 63 6b 6f /* setsocko
87d0: 70 74 20 66 6c 61 67 20 2a 2f 0a 20 20 69 6e 74 pt flag */. int
87e0: 20 69 50 6f 72 74 20 3d 20 6d 6e 50 6f 72 74 3b iPort = mnPort;
87f0: 0a 0a 20 20 77 68 69 6c 65 28 20 69 50 6f 72 74 .. while( iPort
8800: 3c 3d 6d 78 50 6f 72 74 20 29 7b 0a 20 20 20 20 <=mxPort ){.
8810: 6d 65 6d 73 65 74 28 26 69 6e 61 64 64 72 2c 20 memset(&inaddr,
8820: 30 2c 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 0, sizeof(inaddr
8830: 29 29 3b 0a 20 20 20 20 69 6e 61 64 64 72 2e 73 ));. inaddr.s
8840: 69 6e 5f 66 61 6d 69 6c 79 20 3d 20 41 46 5f 49 in_family = AF_I
8850: 4e 45 54 3b 0a 20 20 20 20 69 6e 61 64 64 72 2e NET;. inaddr.
8860: 73 69 6e 5f 61 64 64 72 2e 73 5f 61 64 64 72 20 sin_addr.s_addr
8870: 3d 20 49 4e 41 44 44 52 5f 41 4e 59 3b 0a 20 20 = INADDR_ANY;.
8880: 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f 70 6f 72 inaddr.sin_por
8890: 74 20 3d 20 68 74 6f 6e 73 28 69 50 6f 72 74 29 t = htons(iPort)
88a0: 3b 0a 20 20 20 20 6c 69 73 74 65 6e 65 72 20 3d ;. listener =
88b0: 20 73 6f 63 6b 65 74 28 41 46 5f 49 4e 45 54 2c socket(AF_INET,
88c0: 20 53 4f 43 4b 5f 53 54 52 45 41 4d 2c 20 30 29 SOCK_STREAM, 0)
88d0: 3b 0a 20 20 20 20 69 66 28 20 6c 69 73 74 65 6e ;. if( listen
88e0: 65 72 3c 30 20 29 7b 0a 20 20 20 20 20 20 69 50 er<0 ){. iP
88f0: 6f 72 74 2b 2b 3b 0a 20 20 20 20 20 20 63 6f 6e ort++;. con
8900: 74 69 6e 75 65 3b 0a 20 20 20 20 7d 0a 0a 20 20 tinue;. }..
8910: 20 20 2f 2a 20 69 66 20 77 65 20 63 61 6e 27 74 /* if we can't
8920: 20 74 65 72 6d 69 6e 61 74 65 20 6e 69 63 65 6c terminate nicel
8930: 79 2c 20 61 74 20 6c 65 61 73 74 20 61 6c 6c 6f y, at least allo
8940: 77 20 74 68 65 20 73 6f 63 6b 65 74 20 74 6f 20 w the socket to
8950: 62 65 20 72 65 75 73 65 64 20 2a 2f 0a 20 20 20 be reused */.
8960: 20 73 65 74 73 6f 63 6b 6f 70 74 28 6c 69 73 74 setsockopt(list
8970: 65 6e 65 72 2c 53 4f 4c 5f 53 4f 43 4b 45 54 2c ener,SOL_SOCKET,
8980: 53 4f 5f 52 45 55 53 45 41 44 44 52 2c 26 6f 70 SO_REUSEADDR,&op
8990: 74 2c 73 69 7a 65 6f 66 28 6f 70 74 29 29 3b 0a t,sizeof(opt));.
89a0: 0a 20 20 20 20 69 66 28 20 62 69 6e 64 28 6c 69 . if( bind(li
89b0: 73 74 65 6e 65 72 2c 20 28 73 74 72 75 63 74 20 stener, (struct
89c0: 73 6f 63 6b 61 64 64 72 2a 29 26 69 6e 61 64 64 sockaddr*)&inadd
89d0: 72 2c 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 r, sizeof(inaddr
89e0: 29 29 3c 30 20 29 7b 0a 20 20 20 20 20 20 63 6c ))<0 ){. cl
89f0: 6f 73 65 28 6c 69 73 74 65 6e 65 72 29 3b 0a 20 ose(listener);.
8a00: 20 20 20 20 20 69 50 6f 72 74 2b 2b 3b 0a 20 20 iPort++;.
8a10: 20 20 20 20 63 6f 6e 74 69 6e 75 65 3b 0a 20 20 continue;.
8a20: 20 20 7d 0a 20 20 20 20 62 72 65 61 6b 3b 0a 20 }. break;.
8a30: 20 7d 0a 20 20 69 66 28 20 69 50 6f 72 74 3e 6d }. if( iPort>m
8a40: 78 50 6f 72 74 20 29 7b 0a 20 20 20 20 69 66 28 xPort ){. if(
8a50: 20 6d 6e 50 6f 72 74 3d 3d 6d 78 50 6f 72 74 20 mnPort==mxPort
8a60: 29 7b 0a 20 20 20 20 20 20 66 6f 73 73 69 6c 5f ){. fossil_
8a70: 66 61 74 61 6c 28 22 75 6e 61 62 6c 65 20 74 6f fatal("unable to
8a80: 20 6f 70 65 6e 20 6c 69 73 74 65 6e 69 6e 67 20 open listening
8a90: 73 6f 63 6b 65 74 20 6f 6e 20 70 6f 72 74 73 20 socket on ports
8aa0: 25 64 22 2c 20 6d 6e 50 6f 72 74 29 3b 0a 20 20 %d", mnPort);.
8ab0: 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 66 }else{. f
8ac0: 6f 73 73 69 6c 5f 66 61 74 61 6c 28 22 75 6e 61 ossil_fatal("una
8ad0: 62 6c 65 20 74 6f 20 6f 70 65 6e 20 6c 69 73 74 ble to open list
8ae0: 65 6e 69 6e 67 20 73 6f 63 6b 65 74 20 6f 6e 20 ening socket on
8af0: 61 6e 79 22 0a 20 20 20 20 20 20 20 20 20 20 20 any".
8b00: 20 20 20 20 20 20 20 20 22 20 70 6f 72 74 20 69 " port i
8b10: 6e 20 74 68 65 20 72 61 6e 67 65 20 25 64 2e 2e n the range %d..
8b20: 25 64 22 2c 20 6d 6e 50 6f 72 74 2c 20 6d 78 50 %d", mnPort, mxP
8b30: 6f 72 74 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a ort);. }. }.
8b40: 20 20 69 66 28 20 69 50 6f 72 74 3e 6d 78 50 6f if( iPort>mxPo
8b50: 72 74 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 rt ) return 1;.
8b60: 20 6c 69 73 74 65 6e 28 6c 69 73 74 65 6e 65 72 listen(listener
8b70: 2c 31 30 29 3b 0a 20 20 69 66 28 20 69 50 6f 72 ,10);. if( iPor
8b80: 74 3e 6d 6e 50 6f 72 74 20 29 7b 0a 20 20 20 20 t>mnPort ){.
8b90: 70 72 69 6e 74 66 28 22 4c 69 73 74 65 6e 69 6e printf("Listenin
8ba0: 67 20 66 6f 72 20 48 54 54 50 20 72 65 71 75 65 g for HTTP reque
8bb0: 73 74 73 20 6f 6e 20 54 43 50 20 70 6f 72 74 20 sts on TCP port
8bc0: 25 64 5c 6e 22 2c 20 69 50 6f 72 74 29 3b 0a 20 %d\n", iPort);.
8bd0: 20 20 20 66 66 6c 75 73 68 28 73 74 64 6f 75 74 fflush(stdout
8be0: 29 3b 0a 20 20 7d 0a 20 20 69 66 28 20 7a 42 72 );. }. if( zBr
8bf0: 6f 77 73 65 72 20 29 7b 0a 20 20 20 20 7a 42 72 owser ){. zBr
8c00: 6f 77 73 65 72 20 3d 20 6d 70 72 69 6e 74 66 28 owser = mprintf(
8c10: 7a 42 72 6f 77 73 65 72 2c 20 69 50 6f 72 74 29 zBrowser, iPort)
8c20: 3b 0a 20 20 20 20 73 79 73 74 65 6d 28 7a 42 72 ;. system(zBr
8c30: 6f 77 73 65 72 29 3b 0a 20 20 7d 0a 20 20 77 68 owser);. }. wh
8c40: 69 6c 65 28 20 31 20 29 7b 0a 20 20 20 20 69 66 ile( 1 ){. if
8c50: 28 20 6e 63 68 69 6c 64 72 65 6e 3e 4d 41 58 5f ( nchildren>MAX_
8c60: 50 41 52 41 4c 4c 45 4c 20 29 7b 0a 20 20 20 20 PARALLEL ){.
8c70: 20 20 2f 2a 20 53 6c 6f 77 20 64 6f 77 6e 20 69 /* Slow down i
8c80: 66 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72 f connections ar
8c90: 65 20 61 72 72 69 76 69 6e 67 20 74 6f 6f 20 66 e arriving too f
8ca0: 61 73 74 20 2a 2f 0a 20 20 20 20 20 20 73 6c 65 ast */. sle
8cb0: 65 70 28 20 6e 63 68 69 6c 64 72 65 6e 2d 4d 41 ep( nchildren-MA
8cc0: 58 5f 50 41 52 41 4c 4c 45 4c 20 29 3b 0a 20 20 X_PARALLEL );.
8cd0: 20 20 7d 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 }. delay.tv
8ce0: 5f 73 65 63 20 3d 20 36 30 3b 0a 20 20 20 20 64 _sec = 60;. d
8cf0: 65 6c 61 79 2e 74 76 5f 75 73 65 63 20 3d 20 30 elay.tv_usec = 0
8d00: 3b 0a 20 20 20 20 46 44 5f 5a 45 52 4f 28 26 72 ;. FD_ZERO(&r
8d10: 65 61 64 66 64 73 29 3b 0a 20 20 20 20 46 44 5f eadfds);. FD_
8d20: 53 45 54 28 20 6c 69 73 74 65 6e 65 72 2c 20 26 SET( listener, &
8d30: 72 65 61 64 66 64 73 29 3b 0a 20 20 20 20 69 66 readfds);. if
8d40: 28 20 73 65 6c 65 63 74 28 20 6c 69 73 74 65 6e ( select( listen
8d50: 65 72 2b 31 2c 20 26 72 65 61 64 66 64 73 2c 20 er+1, &readfds,
8d60: 30 2c 20 30 2c 20 26 64 65 6c 61 79 29 20 29 7b 0, 0, &delay) ){
8d70: 0a 20 20 20 20 20 20 6c 65 6e 61 64 64 72 20 3d . lenaddr =
8d80: 20 73 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 3b sizeof(inaddr);
8d90: 0a 20 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f . connectio
8da0: 6e 20 3d 20 61 63 63 65 70 74 28 6c 69 73 74 65 n = accept(liste
8db0: 6e 65 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63 ner, (struct soc
8dc0: 6b 61 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 0a kaddr*)&inaddr,.
8dd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8de0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8df0: 20 20 20 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 (socklen_t*)
8e00: 20 26 6c 65 6e 61 64 64 72 29 3b 0a 20 20 20 20 &lenaddr);.
8e10: 20 20 69 66 28 20 63 6f 6e 6e 65 63 74 69 6f 6e if( connection
8e20: 3e 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 63 >=0 ){. c
8e30: 68 69 6c 64 20 3d 20 66 6f 72 6b 28 29 3b 0a 20 hild = fork();.
8e40: 20 20 20 20 20 20 20 69 66 28 20 63 68 69 6c 64 if( child
8e50: 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 20 20 20 !=0 ){.
8e60: 20 69 66 28 20 63 68 69 6c 64 3e 30 20 29 20 6e if( child>0 ) n
8e70: 63 68 69 6c 64 72 65 6e 2b 2b 3b 0a 20 20 20 20 children++;.
8e80: 20 20 20 20 20 20 63 6c 6f 73 65 28 63 6f 6e 6e close(conn
8e90: 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 ection);.
8ea0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 20 20 }else{.
8eb0: 20 20 63 6c 6f 73 65 28 30 29 3b 0a 20 20 20 20 close(0);.
8ec0: 20 20 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 dup(connec
8ed0: 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 tion);.
8ee0: 20 63 6c 6f 73 65 28 31 29 3b 0a 20 20 20 20 20 close(1);.
8ef0: 20 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 63 74 dup(connect
8f00: 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 20 20 ion);.
8f10: 69 66 28 20 21 67 2e 66 48 74 74 70 54 72 61 63 if( !g.fHttpTrac
8f20: 65 20 29 7b 0a 20 20 20 20 20 20 20 20 20 20 20 e ){.
8f30: 20 63 6c 6f 73 65 28 32 29 3b 0a 20 20 20 20 20 close(2);.
8f40: 20 20 20 20 20 20 20 64 75 70 28 63 6f 6e 6e 65 dup(conne
8f50: 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 20 20 20 ction);.
8f60: 20 20 7d 0a 20 20 20 20 20 20 20 20 20 20 63 6c }. cl
8f70: 6f 73 65 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b ose(connection);
8f80: 0a 20 20 20 20 20 20 20 20 20 20 72 65 74 75 72 . retur
8f90: 6e 20 30 3b 0a 20 20 20 20 20 20 20 20 7d 0a 20 n 0;. }.
8fa0: 20 20 20 20 20 7d 0a 20 20 20 20 7d 0a 20 20 20 }. }.
8fb0: 20 2f 2a 20 42 75 72 79 20 64 65 61 64 20 63 68 /* Bury dead ch
8fc0: 69 6c 64 72 65 6e 20 2a 2f 0a 20 20 20 20 77 68 ildren */. wh
8fd0: 69 6c 65 28 20 77 61 69 74 70 69 64 28 30 2c 20 ile( waitpid(0,
8fe0: 30 2c 20 57 4e 4f 48 41 4e 47 29 3e 30 20 29 7b 0, WNOHANG)>0 ){
8ff0: 0a 20 20 20 20 20 20 6e 63 68 69 6c 64 72 65 6e . nchildren
9000: 2d 2d 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 --;. }. }.
9010: 2f 2a 20 4e 4f 54 20 52 45 41 43 48 45 44 20 2a /* NOT REACHED *
9020: 2f 20 20 0a 20 20 65 78 69 74 28 31 29 3b 0a 23 / . exit(1);.#
9030: 65 6e 64 69 66 0a 7d 0a 0a 0a 2f 2a 0a 2a 2a 20 endif.}.../*.**
9040: 4e 61 6d 65 20 6f 66 20 64 61 79 73 20 61 6e 64 Name of days and
9050: 20 6d 6f 6e 74 68 73 2e 0a 2a 2f 0a 73 74 61 74 months..*/.stat
9060: 69 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 ic const char *a
9070: 7a 44 61 79 73 5b 5d 20 3d 0a 20 20 20 20 7b 22 zDays[] =. {"
9080: 53 75 6e 22 2c 20 22 4d 6f 6e 22 2c 20 22 54 75 Sun", "Mon", "Tu
9090: 65 22 2c 20 22 57 65 64 22 2c 20 22 54 68 75 22 e", "Wed", "Thu"
90a0: 2c 20 22 46 72 69 22 2c 20 22 53 61 74 22 2c 20 , "Fri", "Sat",
90b0: 30 7d 3b 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 0};.static const
90c0: 20 63 68 61 72 20 2a 61 7a 4d 6f 6e 74 68 73 5b char *azMonths[
90d0: 5d 20 3d 0a 20 20 20 20 7b 22 4a 61 6e 22 2c 20 ] =. {"Jan",
90e0: 22 46 65 62 22 2c 20 22 4d 61 72 22 2c 20 22 41 "Feb", "Mar", "A
90f0: 70 72 22 2c 20 22 4d 61 79 22 2c 20 22 4a 75 6e pr", "May", "Jun
9100: 22 2c 0a 20 20 20 20 20 22 4a 75 6c 22 2c 20 22 ",. "Jul", "
9110: 41 75 67 22 2c 20 22 53 65 70 22 2c 20 22 4f 63 Aug", "Sep", "Oc
9120: 74 22 2c 20 22 4e 6f 76 22 2c 20 22 44 65 63 22 t", "Nov", "Dec"
9130: 2c 20 30 7d 3b 0a 0a 0a 2f 2a 0a 2a 2a 20 52 65 , 0};.../*.** Re
9140: 74 75 72 6e 73 20 61 6e 20 52 46 43 38 32 32 2d turns an RFC822-
9150: 66 6f 72 6d 61 74 74 65 64 20 74 69 6d 65 20 73 formatted time s
9160: 74 72 69 6e 67 20 73 75 69 74 61 62 6c 65 20 66 tring suitable f
9170: 6f 72 20 48 54 54 50 20 68 65 61 64 65 72 73 2c or HTTP headers,
9180: 20 61 6d 6f 6e 67 0a 2a 2a 20 6f 74 68 65 72 20 among.** other
9190: 74 68 69 6e 67 73 2e 0a 2a 2a 20 52 65 74 75 72 things..** Retur
91a0: 6e 65 64 20 74 69 6d 65 7a 6f 6e 65 20 69 73 20 ned timezone is
91b0: 61 6c 77 61 79 73 20 47 4d 54 20 61 73 20 72 65 always GMT as re
91c0: 71 75 69 72 65 64 20 62 79 20 48 54 54 50 2f 31 quired by HTTP/1
91d0: 2e 31 20 73 70 65 63 69 66 69 63 61 74 69 6f 6e .1 specification
91e0: 2e 0a 2a 2a 20 54 68 65 20 72 65 74 75 72 6e 65 ..** The returne
91f0: 64 20 73 74 72 69 6e 67 20 69 73 20 61 6c 6c 6f d string is allo
9200: 63 61 74 65 64 20 77 69 74 68 20 6d 61 6c 6c 6f cated with mallo
9210: 63 28 29 20 61 6e 64 20 6d 75 73 74 20 62 65 20 c() and must be
9220: 66 72 65 65 64 0a 2a 2a 20 77 69 74 68 20 66 72 freed.** with fr
9230: 65 65 28 29 2e 0a 2a 2a 0a 2a 2a 20 53 65 65 20 ee()..**.** See
9240: 68 74 74 70 3a 2f 2f 77 77 77 2e 66 61 71 73 2e http://www.faqs.
9250: 6f 72 67 2f 72 66 63 73 2f 72 66 63 38 32 32 2e org/rfcs/rfc822.
9260: 68 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 20 35 0a html, section 5.
9270: 2a 2a 20 61 6e 64 20 68 74 74 70 3a 2f 2f 77 77 ** and http://ww
9280: 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66 63 73 2f w.faqs.org/rfcs/
9290: 72 66 63 32 36 31 36 2e 68 74 6d 6c 2c 20 73 65 rfc2616.html, se
92a0: 63 74 69 6f 6e 20 33 2e 33 2e 0a 2a 2f 0a 63 68 ction 3.3..*/.ch
92b0: 61 72 20 2a 63 67 69 5f 72 66 63 38 32 32 5f 64 ar *cgi_rfc822_d
92c0: 61 74 65 73 74 61 6d 70 28 74 69 6d 65 5f 74 20 atestamp(time_t
92d0: 6e 6f 77 29 7b 0a 20 20 73 74 72 75 63 74 20 74 now){. struct t
92e0: 6d 20 2a 70 54 6d 3b 0a 20 20 70 54 6d 20 3d 20 m *pTm;. pTm =
92f0: 67 6d 74 69 6d 65 28 26 6e 6f 77 29 3b 0a 20 20 gmtime(&now);.
9300: 69 66 28 20 70 54 6d 3d 3d 30 20 29 20 72 65 74 if( pTm==0 ) ret
9310: 75 72 6e 20 22 22 3b 0a 20 20 72 65 74 75 72 6e urn "";. return
9320: 20 6d 70 72 69 6e 74 66 28 22 25 73 2c 20 25 64 mprintf("%s, %d
9330: 20 25 73 20 25 30 32 64 20 25 30 32 64 3a 25 30 %s %02d %02d:%0
9340: 32 64 3a 25 30 32 64 20 47 4d 54 22 2c 0a 20 20 2d:%02d GMT",.
9350: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 61 a
9360: 7a 44 61 79 73 5b 70 54 6d 2d 3e 74 6d 5f 77 64 zDays[pTm->tm_wd
9370: 61 79 5d 2c 20 70 54 6d 2d 3e 74 6d 5f 6d 64 61 ay], pTm->tm_mda
9380: 79 2c 20 61 7a 4d 6f 6e 74 68 73 5b 70 54 6d 2d y, azMonths[pTm-
9390: 3e 74 6d 5f 6d 6f 6e 5d 2c 0a 20 20 20 20 20 20 >tm_mon],.
93a0: 20 20 20 20 20 20 20 20 20 20 20 70 54 6d 2d 3e pTm->
93b0: 74 6d 5f 79 65 61 72 2b 31 39 30 30 2c 20 70 54 tm_year+1900, pT
93c0: 6d 2d 3e 74 6d 5f 68 6f 75 72 2c 20 70 54 6d 2d m->tm_hour, pTm-
93d0: 3e 74 6d 5f 6d 69 6e 2c 20 70 54 6d 2d 3e 74 6d >tm_min, pTm->tm
93e0: 5f 73 65 63 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 _sec);.}../*.**
93f0: 50 61 72 73 65 20 61 6e 20 52 46 43 38 32 32 2d Parse an RFC822-
9400: 66 6f 72 6d 61 74 74 65 64 20 74 69 6d 65 73 74 formatted timest
9410: 61 6d 70 20 61 73 20 77 65 27 64 20 65 78 70 65 amp as we'd expe
9420: 63 74 20 66 72 6f 6d 20 48 54 54 50 20 61 6e 64 ct from HTTP and
9430: 20 72 65 74 75 72 6e 0a 2a 2a 20 61 20 55 6e 69 return.** a Uni
9440: 78 20 65 70 6f 63 68 20 74 69 6d 65 2e 20 3c 3d x epoch time. <=
9450: 20 7a 65 72 6f 20 69 73 20 72 65 74 75 72 6e 65 zero is returne
9460: 64 20 6f 6e 20 66 61 69 6c 75 72 65 2e 0a 2a 2a d on failure..**
9470: 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74 20 74 68 .** Note that th
9480: 69 73 20 77 6f 6e 27 74 20 68 61 6e 64 6c 65 20 is won't handle
9490: 61 6c 6c 20 74 68 65 20 5f 61 6c 6c 6f 77 65 64 all the _allowed
94a0: 5f 20 48 54 54 50 20 66 6f 72 6d 61 74 73 2c 20 _ HTTP formats,
94b0: 6a 75 73 74 20 74 68 65 0a 2a 2a 20 6d 6f 73 74 just the.** most
94c0: 20 70 6f 70 75 6c 61 72 20 6f 6e 65 20 28 74 68 popular one (th
94d0: 65 20 6f 6e 65 20 67 65 6e 65 72 61 74 65 64 20 e one generated
94e0: 62 79 20 63 67 69 5f 72 66 63 38 32 32 5f 64 61 by cgi_rfc822_da
94f0: 74 65 73 74 61 6d 70 28 29 2c 20 61 63 74 75 61 testamp(), actua
9500: 6c 6c 79 29 2e 0a 2a 2f 0a 74 69 6d 65 5f 74 20 lly)..*/.time_t
9510: 63 67 69 5f 72 66 63 38 32 32 5f 70 61 72 73 65 cgi_rfc822_parse
9520: 64 61 74 65 28 63 6f 6e 73 74 20 63 68 61 72 20 date(const char
9530: 2a 7a 44 61 74 65 29 7b 0a 20 20 73 74 72 75 63 *zDate){. struc
9540: 74 20 74 6d 20 74 3b 0a 20 20 63 68 61 72 20 7a t tm t;. char z
9550: 49 67 6e 6f 72 65 5b 31 36 5d 3b 0a 20 20 63 68 Ignore[16];. ch
9560: 61 72 20 7a 4d 6f 6e 74 68 5b 31 36 5d 3b 0a 0a ar zMonth[16];..
9570: 20 20 6d 65 6d 73 65 74 28 26 74 2c 20 30 2c 20 memset(&t, 0,
9580: 73 69 7a 65 6f 66 28 74 29 29 3b 0a 20 20 69 66 sizeof(t));. if
9590: 28 20 37 3d 3d 73 73 63 61 6e 66 28 7a 44 61 74 ( 7==sscanf(zDat
95a0: 65 2c 20 22 25 31 32 5b 41 2d 5a 61 2d 7a 2c 5d e, "%12[A-Za-z,]
95b0: 20 25 64 20 25 31 32 5b 41 2d 5a 61 2d 7a 5d 20 %d %12[A-Za-z]
95c0: 25 64 20 25 64 3a 25 64 3a 25 64 22 2c 20 7a 49 %d %d:%d:%d", zI
95d0: 67 6e 6f 72 65 2c 0a 20 20 20 20 20 20 20 20 20 gnore,.
95e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26 74 &t
95f0: 2e 74 6d 5f 6d 64 61 79 2c 20 7a 4d 6f 6e 74 68 .tm_mday, zMonth
9600: 2c 20 26 74 2e 74 6d 5f 79 65 61 72 2c 20 26 74 , &t.tm_year, &t
9610: 2e 74 6d 5f 68 6f 75 72 2c 20 26 74 2e 74 6d 5f .tm_hour, &t.tm_
9620: 6d 69 6e 2c 0a 20 20 20 20 20 20 20 20 20 20 20 min,.
9630: 20 20 20 20 20 20 20 20 20 20 20 20 26 74 2e 74 &t.t
9640: 6d 5f 73 65 63 29 29 7b 0a 0a 20 20 20 20 69 66 m_sec)){.. if
9650: 28 20 74 2e 74 6d 5f 79 65 61 72 20 3e 20 31 39 ( t.tm_year > 19
9660: 30 30 20 29 20 74 2e 74 6d 5f 79 65 61 72 20 2d 00 ) t.tm_year -
9670: 3d 20 31 39 30 30 3b 0a 20 20 20 20 66 6f 72 28 = 1900;. for(
9680: 74 2e 74 6d 5f 6d 6f 6e 3d 30 3b 20 61 7a 4d 6f t.tm_mon=0; azMo
9690: 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e 5d 3b 20 nths[t.tm_mon];
96a0: 74 2e 74 6d 5f 6d 6f 6e 2b 2b 29 7b 0a 20 20 20 t.tm_mon++){.
96b0: 20 20 20 69 66 28 20 21 73 74 72 6e 63 61 73 65 if( !strncase
96c0: 63 6d 70 28 20 61 7a 4d 6f 6e 74 68 73 5b 74 2e cmp( azMonths[t.
96d0: 74 6d 5f 6d 6f 6e 5d 2c 20 7a 4d 6f 6e 74 68 2c tm_mon], zMonth,
96e0: 20 33 20 29 29 7b 0a 20 20 20 20 20 20 20 20 72 3 )){. r
96f0: 65 74 75 72 6e 20 6d 6b 67 6d 74 69 6d 65 28 26 eturn mkgmtime(&
9700: 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 t);. }.
9710: 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 72 6e 20 }. }.. return
9720: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 6f 6e 76 0;.}../*.** Conv
9730: 65 72 74 20 61 20 73 74 72 75 63 74 20 74 6d 2a ert a struct tm*
9740: 20 74 68 61 74 20 72 65 70 72 65 73 65 6e 74 73 that represents
9750: 20 61 20 6d 6f 6d 65 6e 74 20 69 6e 20 55 54 43 a moment in UTC
9760: 20 69 6e 74 6f 20 74 68 65 20 6e 75 6d 62 65 72 into the number
9770: 0a 2a 2a 20 6f 66 20 73 65 63 6f 6e 64 73 20 69 .** of seconds i
9780: 6e 20 31 39 37 30 2c 20 55 54 43 2e 0a 2a 2f 0a n 1970, UTC..*/.
9790: 74 69 6d 65 5f 74 20 6d 6b 67 6d 74 69 6d 65 28 time_t mkgmtime(
97a0: 73 74 72 75 63 74 20 74 6d 20 2a 70 29 7b 0a 20 struct tm *p){.
97b0: 20 74 69 6d 65 5f 74 20 74 3b 0a 20 20 69 6e 74 time_t t;. int
97c0: 20 6e 44 61 79 3b 0a 20 20 69 6e 74 20 69 73 4c nDay;. int isL
97d0: 65 61 70 59 72 3b 0a 20 20 2f 2a 20 44 61 79 73 eapYr;. /* Days
97e0: 20 69 6e 20 65 61 63 68 20 6d 6f 6e 74 68 3a 20 in each month:
97f0: 20 20 20 20 20 20 33 31 2c 20 32 38 2c 20 33 31 31, 28, 31
9800: 2c 20 33 30 2c 20 33 31 2c 20 33 30 2c 20 33 31 , 30, 31, 30, 31
9810: 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33 30 , 31, 30, 31, 30
9820: 2c 20 33 31 20 2a 2f 0a 20 20 73 74 61 74 69 63 , 31 */. static
9830: 20 69 6e 74 20 70 72 69 6f 72 44 61 79 73 5b 5d int priorDays[]
9840: 20 20 20 3d 20 7b 20 20 30 2c 20 33 31 2c 20 35 = { 0, 31, 5
9850: 39 2c 20 39 30 2c 31 32 30 2c 31 35 31 2c 31 38 9, 90,120,151,18
9860: 31 2c 32 31 32 2c 32 34 33 2c 32 37 33 2c 33 30 1,212,243,273,30
9870: 34 2c 33 33 34 20 7d 3b 0a 20 20 69 66 28 20 70 4,334 };. if( p
9880: 2d 3e 74 6d 5f 6d 6f 6e 3c 30 20 29 7b 0a 20 20 ->tm_mon<0 ){.
9890: 20 20 69 6e 74 20 6e 59 65 61 72 20 3d 20 28 31 int nYear = (1
98a0: 31 20 2d 20 70 2d 3e 74 6d 5f 6d 6f 6e 29 2f 31 1 - p->tm_mon)/1
98b0: 32 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 79 65 61 2;. p->tm_yea
98c0: 72 20 2d 3d 20 6e 59 65 61 72 3b 0a 20 20 20 20 r -= nYear;.
98d0: 70 2d 3e 74 6d 5f 6d 6f 6e 20 2b 3d 20 6e 59 65 p->tm_mon += nYe
98e0: 61 72 2a 31 32 3b 0a 20 20 7d 65 6c 73 65 20 69 ar*12;. }else i
98f0: 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3e 31 31 20 f( p->tm_mon>11
9900: 29 7b 0a 20 20 20 20 70 2d 3e 74 6d 5f 79 65 61 ){. p->tm_yea
9910: 72 20 2b 3d 20 70 2d 3e 74 6d 5f 6d 6f 6e 2f 31 r += p->tm_mon/1
9920: 32 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 2;. p->tm_mon
9930: 20 25 3d 20 31 32 3b 0a 20 20 7d 0a 20 20 69 73 %= 12;. }. is
9940: 4c 65 61 70 59 72 20 3d 20 70 2d 3e 74 6d 5f 79 LeapYr = p->tm_y
9950: 65 61 72 25 34 3d 3d 30 20 26 26 20 28 70 2d 3e ear%4==0 && (p->
9960: 74 6d 5f 79 65 61 72 25 31 30 30 21 3d 30 20 7c tm_year%100!=0 |
9970: 7c 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2b 33 30 | (p->tm_year+30
9980: 30 29 25 34 30 30 3d 3d 30 29 3b 0a 20 20 70 2d 0)%400==0);. p-
9990: 3e 74 6d 5f 79 64 61 79 20 3d 20 70 72 69 6f 72 >tm_yday = prior
99a0: 44 61 79 73 5b 70 2d 3e 74 6d 5f 6d 6f 6e 5d 20 Days[p->tm_mon]
99b0: 2b 20 70 2d 3e 74 6d 5f 6d 64 61 79 20 2d 20 31 + p->tm_mday - 1
99c0: 3b 0a 20 20 69 66 28 20 69 73 4c 65 61 70 59 72 ;. if( isLeapYr
99d0: 20 26 26 20 70 2d 3e 74 6d 5f 6d 6f 6e 3e 31 20 && p->tm_mon>1
99e0: 29 20 70 2d 3e 74 6d 5f 79 64 61 79 2b 2b 3b 0a ) p->tm_yday++;.
99f0: 20 20 6e 44 61 79 20 3d 20 28 70 2d 3e 74 6d 5f nDay = (p->tm_
9a00: 79 65 61 72 2d 37 30 29 2a 33 36 35 20 2b 20 28 year-70)*365 + (
9a10: 70 2d 3e 74 6d 5f 79 65 61 72 2d 36 39 29 2f 34 p->tm_year-69)/4
9a20: 20 2d 70 2d 3e 74 6d 5f 79 65 61 72 2f 31 30 30 -p->tm_year/100
9a30: 20 2b 20 0a 20 20 20 20 20 20 20 20 20 28 70 2d + . (p-
9a40: 3e 74 6d 5f 79 65 61 72 2b 33 30 30 29 2f 34 30 >tm_year+300)/40
9a50: 30 20 2b 20 70 2d 3e 74 6d 5f 79 64 61 79 3b 0a 0 + p->tm_yday;.
9a60: 20 20 74 20 3d 20 28 28 6e 44 61 79 2a 32 34 20 t = ((nDay*24
9a70: 2b 20 70 2d 3e 74 6d 5f 68 6f 75 72 29 2a 36 30 + p->tm_hour)*60
9a80: 20 2b 20 70 2d 3e 74 6d 5f 6d 69 6e 29 2a 36 30 + p->tm_min)*60
9a90: 20 2b 20 70 2d 3e 74 6d 5f 73 65 63 3b 0a 20 20 + p->tm_sec;.
9aa0: 72 65 74 75 72 6e 20 74 3b 0a 7d 0a 0a 2f 2a 0a return t;.}../*.
9ab0: 2a 2a 20 43 68 65 63 6b 20 74 68 65 20 6f 62 6a ** Check the obj
9ac0: 65 63 74 54 69 6d 65 20 61 67 61 69 6e 73 74 20 ectTime against
9ad0: 74 68 65 20 49 66 2d 4d 6f 64 69 66 69 65 64 2d the If-Modified-
9ae0: 53 69 6e 63 65 20 72 65 71 75 65 73 74 20 68 65 Since request he
9af0: 61 64 65 72 2e 20 49 66 20 74 68 65 0a 2a 2a 20 ader. If the.**
9b00: 6f 62 6a 65 63 74 20 74 69 6d 65 20 69 73 6e 27 object time isn'
9b10: 74 20 61 6e 79 20 6e 65 77 65 72 20 74 68 61 6e t any newer than
9b20: 20 74 68 65 20 68 65 61 64 65 72 2c 20 77 65 20 the header, we
9b30: 69 6d 6d 65 64 69 61 74 65 6c 79 20 73 65 6e 64 immediately send
9b40: 20 62 61 63 6b 0a 2a 2a 20 61 20 33 30 34 20 72 back.** a 304 r
9b50: 65 70 6c 79 20 61 6e 64 20 65 78 69 74 2e 0a 2a eply and exit..*
9b60: 2f 0a 76 6f 69 64 20 63 67 69 5f 6d 6f 64 69 66 /.void cgi_modif
9b70: 69 65 64 5f 73 69 6e 63 65 28 74 69 6d 65 5f 74 ied_since(time_t
9b80: 20 6f 62 6a 65 63 74 54 69 6d 65 29 7b 0a 20 20 objectTime){.
9b90: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 49 66 20 const char *zIf
9ba0: 3d 20 50 28 22 48 54 54 50 5f 49 46 5f 4d 4f 44 = P("HTTP_IF_MOD
9bb0: 49 46 49 45 44 5f 53 49 4e 43 45 22 29 3b 0a 20 IFIED_SINCE");.
9bc0: 20 69 66 28 20 7a 49 66 3d 3d 30 20 29 20 72 65 if( zIf==0 ) re
9bd0: 74 75 72 6e 3b 0a 20 20 69 66 28 20 6f 62 6a 65 turn;. if( obje
9be0: 63 74 54 69 6d 65 20 3e 20 63 67 69 5f 72 66 63 ctTime > cgi_rfc
9bf0: 38 32 32 5f 70 61 72 73 65 64 61 74 65 28 7a 49 822_parsedate(zI
9c00: 66 29 20 29 20 72 65 74 75 72 6e 3b 0a 20 20 63 f) ) return;. c
9c10: 67 69 5f 73 65 74 5f 73 74 61 74 75 73 28 33 30 gi_set_status(30
9c20: 34 2c 22 4e 6f 74 20 4d 6f 64 69 66 69 65 64 22 4,"Not Modified"
9c30: 29 3b 0a 20 20 63 67 69 5f 72 65 73 65 74 5f 63 );. cgi_reset_c
9c40: 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63 67 69 5f ontent();. cgi_
9c50: 72 65 70 6c 79 28 29 3b 0a 20 20 65 78 69 74 28 reply();. exit(
9c60: 30 29 3b 0a 7d 0a 0);.}.