0000: 2f 2a 0a 2a 2a 20 43 6f 70 79 72 69 67 68 74 20 /*.** Copyright
0010: 28 63 29 20 32 30 30 36 20 44 2e 20 52 69 63 68 (c) 2006 D. Rich
0020: 61 72 64 20 48 69 70 70 0a 2a 2a 0a 2a 2a 20 54 ard Hipp.**.** T
0030: 68 69 73 20 70 72 6f 67 72 61 6d 20 69 73 20 66 his program is f
0040: 72 65 65 20 73 6f 66 74 77 61 72 65 3b 20 79 6f ree software; yo
0050: 75 20 63 61 6e 20 72 65 64 69 73 74 72 69 62 75 u can redistribu
0060: 74 65 20 69 74 20 61 6e 64 2f 6f 72 0a 2a 2a 20 te it and/or.**
0070: 6d 6f 64 69 66 79 20 69 74 20 75 6e 64 65 72 20 modify it under
0080: 74 68 65 20 74 65 72 6d 73 20 6f 66 20 74 68 65 the terms of the
0090: 20 47 4e 55 20 47 65 6e 65 72 61 6c 20 50 75 62 GNU General Pub
00a0: 6c 69 63 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 76 lic.** License v
00b0: 65 72 73 69 6f 6e 20 32 20 61 73 20 70 75 62 6c ersion 2 as publ
00c0: 69 73 68 65 64 20 62 79 20 74 68 65 20 46 72 65 ished by the Fre
00d0: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
00e0: 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 ation..**.** Thi
00f0: 73 20 70 72 6f 67 72 61 6d 20 69 73 20 64 69 73 s program is dis
0100: 74 72 69 62 75 74 65 64 20 69 6e 20 74 68 65 20 tributed in the
0110: 68 6f 70 65 20 74 68 61 74 20 69 74 20 77 69 6c hope that it wil
0120: 6c 20 62 65 20 75 73 65 66 75 6c 2c 0a 2a 2a 20 l be useful,.**
0130: 62 75 74 20 57 49 54 48 4f 55 54 20 41 4e 59 20 but WITHOUT ANY
0140: 57 41 52 52 41 4e 54 59 3b 20 77 69 74 68 6f 75 WARRANTY; withou
0150: 74 20 65 76 65 6e 20 74 68 65 20 69 6d 70 6c 69 t even the impli
0160: 65 64 20 77 61 72 72 61 6e 74 79 20 6f 66 0a 2a ed warranty of.*
0170: 2a 20 4d 45 52 43 48 41 4e 54 41 42 49 4c 49 54 * MERCHANTABILIT
0180: 59 20 6f 72 20 46 49 54 4e 45 53 53 20 46 4f 52 Y or FITNESS FOR
0190: 20 41 20 50 41 52 54 49 43 55 4c 41 52 20 50 55 A PARTICULAR PU
01a0: 52 50 4f 53 45 2e 20 20 53 65 65 20 74 68 65 20 RPOSE. See the
01b0: 47 4e 55 0a 2a 2a 20 47 65 6e 65 72 61 6c 20 50 GNU.** General P
01c0: 75 62 6c 69 63 20 4c 69 63 65 6e 73 65 20 66 6f ublic License fo
01d0: 72 20 6d 6f 72 65 20 64 65 74 61 69 6c 73 2e 0a r more details..
01e0: 2a 2a 20 0a 2a 2a 20 59 6f 75 20 73 68 6f 75 6c ** .** You shoul
01f0: 64 20 68 61 76 65 20 72 65 63 65 69 76 65 64 20 d have received
0200: 61 20 63 6f 70 79 20 6f 66 20 74 68 65 20 47 4e a copy of the GN
0210: 55 20 47 65 6e 65 72 61 6c 20 50 75 62 6c 69 63 U General Public
0220: 0a 2a 2a 20 4c 69 63 65 6e 73 65 20 61 6c 6f 6e .** License alon
0230: 67 20 77 69 74 68 20 74 68 69 73 20 6c 69 62 72 g with this libr
0240: 61 72 79 3b 20 69 66 20 6e 6f 74 2c 20 77 72 69 ary; if not, wri
0250: 74 65 20 74 6f 20 74 68 65 0a 2a 2a 20 46 72 65 te to the.** Fre
0260: 65 20 53 6f 66 74 77 61 72 65 20 46 6f 75 6e 64 e Software Found
0270: 61 74 69 6f 6e 2c 20 49 6e 63 2e 2c 20 35 39 20 ation, Inc., 59
0280: 54 65 6d 70 6c 65 20 50 6c 61 63 65 20 2d 20 53 Temple Place - S
0290: 75 69 74 65 20 33 33 30 2c 0a 2a 2a 20 42 6f 73 uite 330,.** Bos
02a0: 74 6f 6e 2c 20 4d 41 20 20 30 32 31 31 31 2d 31 ton, MA 02111-1
02b0: 33 30 37 2c 20 55 53 41 2e 0a 2a 2a 0a 2a 2a 20 307, USA..**.**
02c0: 41 75 74 68 6f 72 20 63 6f 6e 74 61 63 74 20 69 Author contact i
02d0: 6e 66 6f 72 6d 61 74 69 6f 6e 3a 0a 2a 2a 20 20 nformation:.**
02e0: 20 64 72 68 40 68 77 61 63 69 2e 63 6f 6d 0a 2a drh@hwaci.com.*
02f0: 2a 20 20 20 68 74 74 70 3a 2f 2f 77 77 77 2e 68 * http://www.h
0300: 77 61 63 69 2e 63 6f 6d 2f 64 72 68 2f 0a 2a 2a waci.com/drh/.**
0310: 0a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a .***************
0320: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0330: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0340: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0350: 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a 2a ****************
0360: 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 66 69 6c 65 .**.** This file
0370: 20 63 6f 6e 74 61 69 6e 73 20 43 20 66 75 6e 63 contains C func
0380: 74 69 6f 6e 73 20 61 6e 64 20 70 72 6f 63 65 64 tions and proced
0390: 75 72 65 73 20 74 68 61 74 20 70 72 6f 76 69 64 ures that provid
03a0: 65 20 75 73 65 66 75 6c 0a 2a 2a 20 73 65 72 76 e useful.** serv
03b0: 69 63 65 73 20 74 6f 20 43 47 49 20 70 72 6f 67 ices to CGI prog
03c0: 72 61 6d 73 2e 20 20 54 68 65 72 65 20 61 72 65 rams. There are
03d0: 20 70 72 6f 63 65 64 75 72 65 73 20 66 6f 72 20 procedures for
03e0: 70 61 72 73 69 6e 67 20 61 6e 64 0a 2a 2a 20 64 parsing and.** d
03f0: 69 73 70 65 6e 73 69 6e 67 20 51 55 45 52 59 5f ispensing QUERY_
0400: 53 54 52 49 4e 47 20 70 61 72 61 6d 65 74 65 72 STRING parameter
0410: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 2c 20 74 s and cookies, t
0420: 68 65 20 22 6d 70 72 69 6e 74 66 28 29 22 0a 2a he "mprintf()".*
0430: 2a 20 66 6f 72 6d 61 74 74 69 6e 67 20 66 75 6e * formatting fun
0440: 63 74 69 6f 6e 20 61 6e 64 20 69 74 73 20 63 6f ction and its co
0450: 75 73 69 6e 73 2c 20 61 6e 64 20 72 6f 75 74 69 usins, and routi
0460: 6e 65 73 20 74 6f 20 65 6e 63 6f 64 65 20 61 6e nes to encode an
0470: 64 0a 2a 2a 20 64 65 63 6f 64 65 20 73 74 72 69 d.** decode stri
0480: 6e 67 73 20 69 6e 20 48 54 4d 4c 20 6f 72 20 48 ngs in HTML or H
0490: 54 54 50 2e 0a 2a 2f 0a 23 69 6e 63 6c 75 64 65 TTP..*/.#include
04a0: 20 22 63 6f 6e 66 69 67 2e 68 22 0a 23 69 66 64 "config.h".#ifd
04b0: 65 66 20 5f 5f 4d 49 4e 47 57 33 32 5f 5f 0a 23 ef __MINGW32__.#
04c0: 20 20 69 6e 63 6c 75 64 65 20 3c 77 69 6e 64 6f include <windo
04d0: 77 73 2e 68 3e 20 20 20 20 20 20 20 20 20 20 20 ws.h>
04e0: 2f 2a 20 66 6f 72 20 53 6c 65 65 70 20 6f 6e 63 /* for Sleep onc
04f0: 65 20 73 65 72 76 65 72 20 77 6f 72 6b 73 20 61 e server works a
0500: 67 61 69 6e 20 2a 2f 0a 23 20 20 69 6e 63 6c 75 gain */.# inclu
0510: 64 65 20 3c 77 69 6e 73 6f 63 6b 32 2e 68 3e 20 de <winsock2.h>
0520: 20 20 20 20 20 20 20 20 20 2f 2a 20 73 6f 63 6b /* sock
0530: 65 74 20 6f 70 65 72 61 74 69 6f 6e 73 20 2a 2f et operations */
0540: 0a 23 20 20 64 65 66 69 6e 65 20 73 6c 65 65 70 .# define sleep
0550: 20 53 6c 65 65 70 20 20 20 20 20 20 20 20 20 20 Sleep
0560: 20 20 2f 2a 20 77 69 6e 64 6f 77 73 20 64 6f 65 /* windows doe
0570: 73 20 6e 6f 74 20 68 61 76 65 20 73 6c 65 65 70 s not have sleep
0580: 2c 20 62 75 74 20 53 6c 65 65 70 20 2a 2f 0a 23 , but Sleep */.#
0590: 20 20 69 6e 63 6c 75 64 65 20 3c 77 73 32 74 63 include <ws2tc
05a0: 70 69 70 2e 68 3e 20 20 20 20 20 20 20 20 20 20 pip.h>
05b0: 0a 23 65 6c 73 65 0a 23 20 20 69 6e 63 6c 75 64 .#else.# includ
05c0: 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 3e e <sys/socket.h>
05d0: 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c 6e 65 74 .# include <net
05e0: 69 6e 65 74 2f 69 6e 2e 68 3e 0a 23 20 20 69 6e inet/in.h>.# in
05f0: 63 6c 75 64 65 20 3c 61 72 70 61 2f 69 6e 65 74 clude <arpa/inet
0600: 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 3c .h>.# include <
0610: 73 79 73 2f 74 69 6d 65 73 2e 68 3e 0a 23 20 20 sys/times.h>.#
0620: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 74 69 6d include <sys/tim
0630: 65 2e 68 3e 0a 23 20 20 69 6e 63 6c 75 64 65 20 e.h>.# include
0640: 3c 73 79 73 2f 77 61 69 74 2e 68 3e 0a 23 20 20 <sys/wait.h>.#
0650: 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 6c include <sys/sel
0660: 65 63 74 2e 68 3e 0a 23 65 6e 64 69 66 0a 23 69 ect.h>.#endif.#i
0670: 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a nclude <time.h>.
0680: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e #include <stdio.
0690: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 h>.#include <std
06a0: 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 lib.h>.#include
06b0: 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c <unistd.h>.#incl
06c0: 75 64 65 20 22 63 67 69 2e 68 22 0a 0a 23 69 66 ude "cgi.h"..#if
06d0: 20 49 4e 54 45 52 46 41 43 45 0a 2f 2a 0a 2a 2a INTERFACE./*.**
06e0: 20 53 68 6f 72 74 63 75 74 73 20 66 6f 72 20 63 Shortcuts for c
06f0: 67 69 5f 70 61 72 61 6d 65 74 65 72 2e 20 20 50 gi_parameter. P
0700: 28 22 78 22 29 20 72 65 74 75 72 6e 73 20 74 68 ("x") returns th
0710: 65 20 76 61 6c 75 65 20 6f 66 20 71 75 65 72 79 e value of query
0720: 20 70 61 72 61 6d 65 74 65 72 0a 2a 2a 20 6f 72 parameter.** or
0730: 20 63 6f 6f 6b 69 65 20 22 78 22 2c 20 6f 72 20 cookie "x", or
0740: 4e 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 NULL if there is
0750: 20 6e 6f 20 73 75 63 68 20 70 61 72 61 6d 65 74 no such paramet
0760: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 2e 20 20 50 er or cookie. P
0770: 44 28 22 78 22 2c 22 79 22 29 0a 2a 2a 20 64 6f D("x","y").** do
0780: 65 73 20 74 68 65 20 73 61 6d 65 20 65 78 63 65 es the same exce
0790: 70 74 20 22 79 22 20 69 73 20 72 65 74 75 72 6e pt "y" is return
07a0: 65 64 20 69 6e 20 70 6c 61 63 65 20 6f 66 20 4e ed in place of N
07b0: 55 4c 4c 20 69 66 20 74 68 65 72 65 20 69 73 20 ULL if there is
07c0: 6e 6f 74 20 6d 61 74 63 68 2e 0a 2a 2f 0a 23 64 not match..*/.#d
07d0: 65 66 69 6e 65 20 50 28 78 29 20 20 20 20 20 20 efine P(x)
07e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 cgi_parameter(
07f0: 28 78 29 2c 30 29 0a 23 64 65 66 69 6e 65 20 50 (x),0).#define P
0800: 44 28 78 2c 79 29 20 20 20 20 20 63 67 69 5f 70 D(x,y) cgi_p
0810: 61 72 61 6d 65 74 65 72 28 28 78 29 2c 28 79 29 arameter((x),(y)
0820: 29 0a 23 64 65 66 69 6e 65 20 51 50 28 78 29 20 ).#define QP(x)
0830: 20 20 20 20 20 20 71 75 6f 74 61 62 6c 65 5f 73 quotable_s
0840: 74 72 69 6e 67 28 63 67 69 5f 70 61 72 61 6d 65 tring(cgi_parame
0850: 74 65 72 28 28 78 29 2c 30 29 29 0a 23 64 65 66 ter((x),0)).#def
0860: 69 6e 65 20 51 50 44 28 78 2c 79 29 20 20 20 20 ine QPD(x,y)
0870: 71 75 6f 74 61 62 6c 65 5f 73 74 72 69 6e 67 28 quotable_string(
0880: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 28 78 cgi_parameter((x
0890: 29 2c 28 79 29 29 29 0a 0a 23 65 6e 64 69 66 20 ),(y)))..#endif
08a0: 2f 2a 20 49 4e 54 45 52 46 41 43 45 20 2a 2f 0a /* INTERFACE */.
08b0: 0a 2f 2a 0a 2a 2a 20 50 72 6f 76 69 64 65 20 61 ./*.** Provide a
08c0: 20 72 65 6c 69 61 62 6c 65 20 69 6d 70 6c 65 6d reliable implem
08d0: 65 6e 74 61 74 69 6f 6e 20 6f 66 20 61 20 63 61 entation of a ca
08e0: 73 65 6c 65 73 73 20 73 74 72 69 6e 67 20 63 6f seless string co
08f0: 6d 70 61 72 69 73 6f 6e 0a 2a 2a 20 66 75 6e 63 mparison.** func
0900: 74 69 6f 6e 2e 0a 2a 2f 0a 23 64 65 66 69 6e 65 tion..*/.#define
0910: 20 73 74 72 69 63 6d 70 20 73 71 6c 69 74 65 33 stricmp sqlite3
0920: 53 74 72 49 43 6d 70 0a 65 78 74 65 72 6e 20 69 StrICmp.extern i
0930: 6e 74 20 73 71 6c 69 74 65 33 53 74 72 49 43 6d nt sqlite3StrICm
0940: 70 28 63 6f 6e 73 74 20 63 68 61 72 2a 2c 20 63 p(const char*, c
0950: 6f 6e 73 74 20 63 68 61 72 2a 29 3b 0a 0a 2f 2a onst char*);../*
0960: 0a 2a 2a 20 54 68 65 20 62 6f 64 79 20 6f 66 20 .** The body of
0970: 74 68 65 20 48 54 54 50 20 72 65 70 6c 79 20 74 the HTTP reply t
0980: 65 78 74 20 69 73 20 73 74 6f 72 65 64 20 68 65 ext is stored he
0990: 72 65 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 42 6c re..*/.static Bl
09a0: 6f 62 20 63 67 69 43 6f 6e 74 65 6e 74 20 3d 20 ob cgiContent =
09b0: 42 4c 4f 42 5f 49 4e 49 54 49 41 4c 49 5a 45 52 BLOB_INITIALIZER
09c0: 3b 0a 0a 2f 2a 0a 2a 2a 20 41 70 70 65 6e 64 20 ;../*.** Append
09d0: 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 6f reply content to
09e0: 20 77 68 61 74 20 61 6c 72 65 61 64 79 20 65 78 what already ex
09f0: 69 73 74 73 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 ists..*/.void cg
0a00: 69 5f 61 70 70 65 6e 64 5f 63 6f 6e 74 65 6e 74 i_append_content
0a10: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 44 61 (const char *zDa
0a20: 74 61 2c 20 69 6e 74 20 6e 41 6d 74 29 7b 0a 20 ta, int nAmt){.
0a30: 20 62 6c 6f 62 5f 61 70 70 65 6e 64 28 26 63 67 blob_append(&cg
0a40: 69 43 6f 6e 74 65 6e 74 2c 20 7a 44 61 74 61 2c iContent, zData,
0a50: 20 6e 41 6d 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a nAmt);.}../*.**
0a60: 20 52 65 73 65 74 20 74 68 65 20 48 54 54 50 20 Reset the HTTP
0a70: 72 65 70 6c 79 20 74 65 78 74 20 74 6f 20 62 65 reply text to be
0a80: 20 61 6e 20 65 6d 70 74 79 20 73 74 72 69 6e 67 an empty string
0a90: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 ..*/.void cgi_re
0aa0: 73 65 74 5f 63 6f 6e 74 65 6e 74 28 76 6f 69 64 set_content(void
0ab0: 29 7b 0a 20 20 62 6c 6f 62 5f 72 65 73 65 74 28 ){. blob_reset(
0ac0: 26 63 67 69 43 6f 6e 74 65 6e 74 29 3b 0a 7d 0a &cgiContent);.}.
0ad0: 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 61 20 ./*.** Return a
0ae0: 70 6f 69 6e 74 65 72 20 74 6f 20 74 68 65 20 43 pointer to the C
0af0: 47 49 20 6f 75 74 70 75 74 20 62 6c 6f 62 2e 0a GI output blob..
0b00: 2a 2f 0a 42 6c 6f 62 20 2a 63 67 69 5f 6f 75 74 */.Blob *cgi_out
0b10: 70 75 74 5f 62 6c 6f 62 28 76 6f 69 64 29 7b 0a put_blob(void){.
0b20: 20 20 72 65 74 75 72 6e 20 26 63 67 69 43 6f 6e return &cgiCon
0b30: 74 65 6e 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 tent;.}../*.** R
0b40: 65 74 75 72 6e 20 61 20 70 6f 69 6e 74 65 72 20 eturn a pointer
0b50: 74 6f 20 74 68 65 20 48 54 54 50 20 72 65 70 6c to the HTTP repl
0b60: 79 20 74 65 78 74 2e 0a 2a 2f 0a 63 68 61 72 20 y text..*/.char
0b70: 2a 63 67 69 5f 65 78 74 72 61 63 74 5f 63 6f 6e *cgi_extract_con
0b80: 74 65 6e 74 28 69 6e 74 20 2a 70 6e 41 6d 74 29 tent(int *pnAmt)
0b90: 7b 0a 20 20 72 65 74 75 72 6e 20 62 6c 6f 62 5f {. return blob_
0ba0: 62 75 66 66 65 72 28 26 63 67 69 43 6f 6e 74 65 buffer(&cgiConte
0bb0: 6e 74 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 41 64 nt);.}../*.** Ad
0bc0: 64 69 74 69 6f 6e 61 6c 20 69 6e 66 6f 72 6d 61 ditional informa
0bd0: 74 69 6f 6e 20 75 73 65 64 20 74 6f 20 66 6f 72 tion used to for
0be0: 6d 20 74 68 65 20 48 54 54 50 20 72 65 70 6c 79 m the HTTP reply
0bf0: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 .*/.static char
0c00: 2a 7a 43 6f 6e 74 65 6e 74 54 79 70 65 20 3d 20 *zContentType =
0c10: 22 74 65 78 74 2f 68 74 6d 6c 22 3b 20 20 20 20 "text/html";
0c20: 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 79 70 65 /* Content type
0c30: 20 6f 66 20 74 68 65 20 72 65 70 6c 79 20 2a 2f of the reply */
0c40: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 7a 52 .static char *zR
0c50: 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4f 4b eplyStatus = "OK
0c60: 22 3b 20 20 20 20 20 20 20 20 20 20 20 20 2f 2a "; /*
0c70: 20 52 65 70 6c 79 20 73 74 61 74 75 73 20 64 65 Reply status de
0c80: 73 63 72 69 70 74 69 6f 6e 20 2a 2f 0a 73 74 61 scription */.sta
0c90: 74 69 63 20 69 6e 74 20 69 52 65 70 6c 79 53 74 tic int iReplySt
0ca0: 61 74 75 73 20 3d 20 32 30 30 3b 20 20 20 20 20 atus = 200;
0cb0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 52 65 70 /* Rep
0cc0: 6c 79 20 73 74 61 74 75 73 20 63 6f 64 65 20 2a ly status code *
0cd0: 2f 0a 73 74 61 74 69 63 20 42 6c 6f 62 20 65 78 /.static Blob ex
0ce0: 74 72 61 48 65 61 64 65 72 20 3d 20 42 4c 4f 42 traHeader = BLOB
0cf0: 5f 49 4e 49 54 49 41 4c 49 5a 45 52 3b 20 20 2f _INITIALIZER; /
0d00: 2a 20 45 78 74 72 61 20 68 65 61 64 65 72 20 74 * Extra header t
0d10: 65 78 74 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e ext */.static in
0d20: 74 20 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 t fullHttpReply
0d30: 3d 20 30 3b 20 20 20 20 20 20 2f 2a 20 54 72 75 = 0; /* Tru
0d40: 65 20 66 6f 72 20 61 20 66 75 6c 6c 2d 62 6c 6f e for a full-blo
0d50: 77 6e 20 48 54 54 50 20 68 65 61 64 65 72 20 2a wn HTTP header *
0d60: 2f 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 /../*.** Set the
0d70: 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e 74 20 74 reply content t
0d80: 79 70 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f ype.*/.void cgi_
0d90: 73 65 74 5f 63 6f 6e 74 65 6e 74 5f 74 79 70 65 set_content_type
0da0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 54 79 (const char *zTy
0db0: 70 65 29 7b 0a 20 20 7a 43 6f 6e 74 65 6e 74 54 pe){. zContentT
0dc0: 79 70 65 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 ype = mprintf("%
0dd0: 73 22 2c 20 7a 54 79 70 65 29 3b 0a 7d 0a 0a 2f s", zType);.}../
0de0: 2a 0a 2a 2a 20 53 65 74 20 74 68 65 20 72 65 70 *.** Set the rep
0df0: 6c 79 20 63 6f 6e 74 65 6e 74 20 74 6f 20 74 68 ly content to th
0e00: 65 20 73 70 65 63 69 66 69 65 64 20 42 4c 4f 42 e specified BLOB
0e10: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 ..*/.void cgi_se
0e20: 74 5f 63 6f 6e 74 65 6e 74 28 42 6c 6f 62 20 2a t_content(Blob *
0e30: 70 4e 65 77 43 6f 6e 74 65 6e 74 29 7b 0a 20 20 pNewContent){.
0e40: 62 6c 6f 62 5f 72 65 73 65 74 28 26 63 67 69 43 blob_reset(&cgiC
0e50: 6f 6e 74 65 6e 74 29 3b 0a 20 20 63 67 69 43 6f ontent);. cgiCo
0e60: 6e 74 65 6e 74 20 3d 20 2a 70 4e 65 77 43 6f 6e ntent = *pNewCon
0e70: 74 65 6e 74 3b 0a 20 20 62 6c 6f 62 5f 7a 65 72 tent;. blob_zer
0e80: 6f 28 70 4e 65 77 43 6f 6e 74 65 6e 74 29 3b 0a o(pNewContent);.
0e90: 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 74 68 65 }../*.** Set the
0ea0: 20 72 65 70 6c 79 20 73 74 61 74 75 73 20 63 6f reply status co
0eb0: 64 65 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 de.*/.void cgi_s
0ec0: 65 74 5f 73 74 61 74 75 73 28 69 6e 74 20 69 53 et_status(int iS
0ed0: 74 61 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 tat, const char
0ee0: 2a 7a 53 74 61 74 29 7b 0a 20 20 7a 52 65 70 6c *zStat){. zRepl
0ef0: 79 53 74 61 74 75 73 20 3d 20 6d 70 72 69 6e 74 yStatus = mprint
0f00: 66 28 22 25 73 22 2c 20 7a 53 74 61 74 29 3b 0a f("%s", zStat);.
0f10: 20 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 3d iReplyStatus =
0f20: 20 69 53 74 61 74 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a iStat;.}../*.**
0f30: 20 41 70 70 65 6e 64 20 74 65 78 74 20 74 6f 20 Append text to
0f40: 74 68 65 20 68 65 61 64 65 72 20 6f 66 20 61 6e the header of an
0f50: 20 48 54 54 50 20 72 65 70 6c 79 0a 2a 2f 0a 76 HTTP reply.*/.v
0f60: 6f 69 64 20 63 67 69 5f 61 70 70 65 6e 64 5f 68 oid cgi_append_h
0f70: 65 61 64 65 72 28 63 6f 6e 73 74 20 63 68 61 72 eader(const char
0f80: 20 2a 7a 4c 69 6e 65 29 7b 0a 20 20 62 6c 6f 62 *zLine){. blob
0f90: 5f 61 70 70 65 6e 64 28 26 65 78 74 72 61 48 65 _append(&extraHe
0fa0: 61 64 65 72 2c 20 7a 4c 69 6e 65 2c 20 2d 31 29 ader, zLine, -1)
0fb0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 65 74 20 61 ;.}../*.** Set a
0fc0: 20 63 6f 6f 6b 69 65 2e 0a 2a 2a 0a 2a 2a 20 5a cookie..**.** Z
0fd0: 65 72 6f 20 6c 69 66 65 74 69 6d 65 20 69 6d 70 ero lifetime imp
0fe0: 6c 69 65 73 20 61 20 73 65 73 73 69 6f 6e 20 63 lies a session c
0ff0: 6f 6f 6b 69 65 2e 0a 2a 2f 0a 76 6f 69 64 20 63 ookie..*/.void c
1000: 67 69 5f 73 65 74 5f 63 6f 6f 6b 69 65 28 0a 20 gi_set_cookie(.
1010: 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 const char *zNa
1020: 6d 65 2c 20 20 20 20 2f 2a 20 4e 61 6d 65 20 6f me, /* Name o
1030: 66 20 74 68 65 20 63 6f 6f 6b 69 65 20 2a 2f 0a f the cookie */.
1040: 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 const char *zV
1050: 61 6c 75 65 2c 20 20 20 2f 2a 20 56 61 6c 75 65 alue, /* Value
1060: 20 6f 66 20 74 68 65 20 63 6f 6f 6b 69 65 2e 20 of the cookie.
1070: 20 41 75 74 6f 6d 61 74 69 63 61 6c 6c 79 20 65 Automatically e
1080: 73 63 61 70 65 64 20 2a 2f 0a 20 20 63 6f 6e 73 scaped */. cons
1090: 74 20 63 68 61 72 20 2a 7a 50 61 74 68 2c 20 20 t char *zPath,
10a0: 20 20 2f 2a 20 50 61 74 68 20 63 6f 6f 6b 69 65 /* Path cookie
10b0: 20 61 70 70 6c 69 65 73 20 74 6f 2e 20 20 4e 55 applies to. NU
10c0: 4c 4c 20 6d 65 61 6e 73 20 22 2f 22 20 2a 2f 0a LL means "/" */.
10d0: 20 20 69 6e 74 20 6c 69 66 65 74 69 6d 65 20 20 int lifetime
10e0: 20 20 20 20 20 20 20 20 2f 2a 20 45 78 70 69 72 /* Expir
10f0: 61 74 69 6f 6e 20 6f 66 20 74 68 65 20 63 6f 6f ation of the coo
1100: 6b 69 65 20 69 6e 20 73 65 63 6f 6e 64 73 20 66 kie in seconds f
1110: 72 6f 6d 20 6e 6f 77 20 2a 2f 0a 29 7b 0a 20 20 rom now */.){.
1120: 69 66 28 20 7a 50 61 74 68 3d 3d 30 20 29 20 7a if( zPath==0 ) z
1130: 50 61 74 68 20 3d 20 22 2f 22 3b 0a 20 20 69 66 Path = "/";. if
1140: 28 20 6c 69 66 65 74 69 6d 65 3e 30 20 29 7b 0a ( lifetime>0 ){.
1150: 20 20 20 20 6c 69 66 65 74 69 6d 65 20 2b 3d 20 lifetime +=
1160: 28 69 6e 74 29 74 69 6d 65 28 30 29 3b 0a 20 20 (int)time(0);.
1170: 20 20 62 6c 6f 62 5f 61 70 70 65 6e 64 66 28 26 blob_appendf(&
1180: 65 78 74 72 61 48 65 61 64 65 72 2c 0a 20 20 20 extraHeader,.
1190: 20 20 20 20 22 53 65 74 2d 43 6f 6f 6b 69 65 3a "Set-Cookie:
11a0: 20 25 73 3d 25 74 3b 20 50 61 74 68 3d 25 73 3b %s=%t; Path=%s;
11b0: 20 65 78 70 69 72 65 73 3d 25 73 3b 20 56 65 72 expires=%s; Ver
11c0: 73 69 6f 6e 3d 31 5c 72 5c 6e 22 2c 0a 20 20 20 sion=1\r\n",.
11d0: 20 20 20 20 20 7a 4e 61 6d 65 2c 20 7a 56 61 6c zName, zVal
11e0: 75 65 2c 20 7a 50 61 74 68 2c 20 63 67 69 5f 72 ue, zPath, cgi_r
11f0: 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 fc822_datestamp(
1200: 6c 69 66 65 74 69 6d 65 29 29 3b 0a 20 20 7d 65 lifetime));. }e
1210: 6c 73 65 7b 0a 20 20 20 20 62 6c 6f 62 5f 61 70 lse{. blob_ap
1220: 70 65 6e 64 66 28 26 65 78 74 72 61 48 65 61 64 pendf(&extraHead
1230: 65 72 2c 0a 20 20 20 20 20 20 20 22 53 65 74 2d er,. "Set-
1240: 43 6f 6f 6b 69 65 3a 20 25 73 3d 25 74 3b 20 50 Cookie: %s=%t; P
1250: 61 74 68 3d 25 73 3b 20 56 65 72 73 69 6f 6e 3d ath=%s; Version=
1260: 31 5c 72 5c 6e 22 2c 0a 20 20 20 20 20 20 20 7a 1\r\n",. z
1270: 4e 61 6d 65 2c 20 7a 56 61 6c 75 65 2c 20 7a 50 Name, zValue, zP
1280: 61 74 68 29 3b 0a 20 20 7d 0a 7d 0a 0a 23 69 66 ath);. }.}..#if
1290: 20 30 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 20 0./*.** Add an
12a0: 45 54 61 67 20 68 65 61 64 65 72 20 6c 69 6e 65 ETag header line
12b0: 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 .*/.static char
12c0: 2a 63 67 69 5f 61 64 64 5f 65 74 61 67 28 63 68 *cgi_add_etag(ch
12d0: 61 72 20 2a 7a 54 78 74 2c 20 69 6e 74 20 6e 4c ar *zTxt, int nL
12e0: 65 6e 29 7b 0a 20 20 4d 44 35 43 6f 6e 74 65 78 en){. MD5Contex
12f0: 74 20 63 74 78 3b 0a 20 20 75 6e 73 69 67 6e 65 t ctx;. unsigne
1300: 64 20 63 68 61 72 20 64 69 67 65 73 74 5b 31 36 d char digest[16
1310: 5d 3b 0a 20 20 69 6e 74 20 69 2c 20 6a 3b 0a 20 ];. int i, j;.
1320: 20 63 68 61 72 20 7a 45 54 61 67 5b 36 34 5d 3b char zETag[64];
1330: 0a 0a 20 20 4d 44 35 49 6e 69 74 28 26 63 74 78 .. MD5Init(&ctx
1340: 29 3b 0a 20 20 4d 44 35 55 70 64 61 74 65 28 26 );. MD5Update(&
1350: 63 74 78 2c 7a 54 78 74 2c 6e 4c 65 6e 29 3b 0a ctx,zTxt,nLen);.
1360: 20 20 4d 44 35 46 69 6e 61 6c 28 64 69 67 65 73 MD5Final(diges
1370: 74 2c 26 63 74 78 29 3b 0a 20 20 66 6f 72 28 6a t,&ctx);. for(j
1380: 3d 69 3d 30 3b 20 69 3c 31 36 3b 20 69 2b 2b 2c =i=0; i<16; i++,
1390: 6a 2b 3d 32 29 7b 0a 20 20 20 20 62 70 72 69 6e j+=2){. bprin
13a0: 74 66 28 26 7a 45 54 61 67 5b 6a 5d 2c 73 69 7a tf(&zETag[j],siz
13b0: 65 6f 66 28 7a 45 54 61 67 29 2d 6a 2c 22 25 30 eof(zETag)-j,"%0
13c0: 32 78 22 2c 28 69 6e 74 29 64 69 67 65 73 74 5b 2x",(int)digest[
13d0: 69 5d 29 3b 0a 20 20 7d 0a 20 20 62 6c 6f 62 5f i]);. }. blob_
13e0: 61 70 70 65 6e 64 66 28 26 65 78 74 72 61 48 65 appendf(&extraHe
13f0: 61 64 65 72 2c 20 22 45 54 61 67 3a 20 25 73 5c ader, "ETag: %s\
1400: 72 5c 6e 22 2c 20 7a 45 54 61 67 29 3b 0a 20 20 r\n", zETag);.
1410: 72 65 74 75 72 6e 20 73 74 72 64 75 70 28 7a 45 return strdup(zE
1420: 54 61 67 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 44 Tag);.}../*.** D
1430: 6f 20 73 6f 6d 65 20 63 61 63 68 65 20 63 6f 6e o some cache con
1440: 74 72 6f 6c 20 73 74 75 66 66 2e 20 46 69 72 73 trol stuff. Firs
1450: 74 2c 20 77 65 20 67 65 6e 65 72 61 74 65 20 61 t, we generate a
1460: 6e 20 45 54 61 67 20 61 6e 64 20 69 6e 63 6c 75 n ETag and inclu
1470: 64 65 20 69 74 20 69 6e 0a 2a 2a 20 74 68 65 20 de it in.** the
1480: 72 65 73 70 6f 6e 73 65 20 68 65 61 64 65 72 73 response headers
1490: 2e 20 53 65 63 6f 6e 64 2c 20 77 65 20 64 6f 20 . Second, we do
14a0: 77 68 61 74 65 76 65 72 20 69 73 20 6e 65 63 65 whatever is nece
14b0: 73 73 61 72 79 20 74 6f 20 64 65 74 65 72 6d 69 ssary to determi
14c0: 6e 65 20 69 66 0a 2a 2a 20 74 68 65 20 72 65 71 ne if.** the req
14d0: 75 65 73 74 20 77 61 73 20 61 73 6b 69 6e 67 20 uest was asking
14e0: 61 62 6f 75 74 20 63 61 63 68 69 6e 67 20 61 6e about caching an
14f0: 64 20 77 68 65 74 68 65 72 20 77 65 20 6e 65 65 d whether we nee
1500: 64 20 74 6f 20 73 65 6e 64 20 62 61 63 6b 20 74 d to send back t
1510: 68 65 0a 2a 2a 20 72 65 73 70 6f 6e 73 65 20 62 he.** response b
1520: 6f 64 79 2e 20 49 66 20 77 65 20 73 68 6f 75 6c ody. If we shoul
1530: 64 6e 27 74 20 73 65 6e 64 20 61 20 62 6f 64 79 dn't send a body
1540: 2c 20 72 65 74 75 72 6e 20 6e 6f 6e 2d 7a 65 72 , return non-zer
1550: 6f 2e 0a 2a 2a 0a 2a 2a 20 43 75 72 72 65 6e 74 o..**.** Current
1560: 6c 79 2c 20 77 65 20 6a 75 73 74 20 63 68 65 63 ly, we just chec
1570: 6b 20 74 68 65 20 45 54 61 67 20 61 67 61 69 6e k the ETag again
1580: 73 74 20 61 6e 79 20 49 66 2d 4e 6f 6e 65 2d 4d st any If-None-M
1590: 61 74 63 68 20 68 65 61 64 65 72 2e 0a 2a 2a 0a atch header..**.
15a0: 2a 2a 20 46 49 58 4d 45 3a 20 49 6e 20 73 6f 6d ** FIXME: In som
15b0: 65 20 63 61 73 65 73 20 28 61 74 74 61 63 68 6d e cases (attachm
15c0: 65 6e 74 73 2c 20 66 69 6c 65 20 63 6f 6e 74 65 ents, file conte
15d0: 6e 74 73 29 20 77 65 20 63 6f 75 6c 64 20 63 68 nts) we could ch
15e0: 65 63 6b 0a 2a 2a 20 49 66 2d 4d 6f 64 69 66 69 eck.** If-Modifi
15f0: 65 64 2d 53 69 6e 63 65 20 68 65 61 64 65 72 73 ed-Since headers
1600: 20 61 6e 64 20 61 6c 77 61 79 73 20 69 6e 63 6c and always incl
1610: 75 64 65 20 4c 61 73 74 2d 4d 6f 64 69 66 69 65 ude Last-Modifie
1620: 64 20 69 6e 20 72 65 73 70 6f 6e 73 65 73 2e 0a d in responses..
1630: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 63 68 */.static int ch
1640: 65 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f eck_cache_contro
1650: 6c 28 76 6f 69 64 29 7b 0a 20 20 2f 2a 20 46 49 l(void){. /* FI
1660: 58 4d 45 3a 20 74 68 65 72 65 27 73 20 73 6f 6d XME: there's som
1670: 65 20 67 6f 74 63 68 61 73 20 77 74 68 20 63 6f e gotchas wth co
1680: 6f 6b 69 65 73 20 61 6e 64 20 73 6f 6d 65 20 68 okies and some h
1690: 65 61 64 65 72 73 2e 20 2a 2f 0a 20 20 63 68 61 eaders. */. cha
16a0: 72 20 2a 7a 45 54 61 67 20 3d 20 63 67 69 5f 61 r *zETag = cgi_a
16b0: 64 64 5f 65 74 61 67 28 62 6c 6f 62 5f 62 75 66 dd_etag(blob_buf
16c0: 66 65 72 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 fer(&cgiContent)
16d0: 2c 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 ,blob_size(&cgiC
16e0: 6f 6e 74 65 6e 74 29 29 3b 0a 20 20 63 68 61 72 ontent));. char
16f0: 20 2a 7a 4d 61 74 63 68 20 3d 20 50 28 22 48 54 *zMatch = P("HT
1700: 54 50 5f 49 46 5f 4e 4f 4e 45 5f 4d 41 54 43 48 TP_IF_NONE_MATCH
1710: 22 29 3b 0a 0a 20 20 69 66 28 20 7a 45 54 61 67 ");.. if( zETag
1720: 21 3d 30 20 26 26 20 7a 4d 61 74 63 68 21 3d 30 !=0 && zMatch!=0
1730: 20 29 20 7b 0a 20 20 20 20 63 68 61 72 20 2a 7a ) {. char *z
1740: 42 75 66 20 3d 20 73 74 72 64 75 70 28 7a 4d 61 Buf = strdup(zMa
1750: 74 63 68 29 3b 0a 20 20 20 20 69 66 28 20 7a 42 tch);. if( zB
1760: 75 66 21 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 uf!=0 ){. c
1770: 68 61 72 20 2a 7a 54 6f 6b 20 3d 20 30 3b 0a 20 har *zTok = 0;.
1780: 20 20 20 20 20 63 68 61 72 20 2a 7a 50 6f 73 3b char *zPos;
1790: 0a 20 20 20 20 20 20 66 6f 72 28 20 7a 54 6f 6b . for( zTok
17a0: 20 3d 20 73 74 72 74 6f 6b 5f 72 28 7a 42 75 66 = strtok_r(zBuf
17b0: 2c 20 22 2c 5c 22 22 2c 26 7a 50 6f 73 29 3b 0a , ",\"",&zPos);.
17c0: 20 20 20 20 20 20 20 20 20 20 20 7a 54 6f 6b 20 zTok
17d0: 26 26 20 73 74 72 63 61 73 65 63 6d 70 28 7a 54 && strcasecmp(zT
17e0: 6f 6b 2c 7a 45 54 61 67 29 3b 0a 20 20 20 20 20 ok,zETag);.
17f0: 20 20 20 20 20 20 7a 54 6f 6b 20 3d 20 20 73 74 zTok = st
1800: 72 74 6f 6b 5f 72 28 30 2c 20 22 2c 5c 22 22 2c rtok_r(0, ",\"",
1810: 26 7a 50 6f 73 29 29 7b 7d 0a 20 20 20 20 20 20 &zPos)){}.
1820: 66 72 65 65 28 7a 42 75 66 29 3b 0a 20 20 20 20 free(zBuf);.
1830: 20 20 69 66 28 7a 54 6f 6b 29 20 72 65 74 75 72 if(zTok) retur
1840: 6e 20 31 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 n 1;. }. }.
1850: 20 0a 20 20 72 65 74 75 72 6e 20 30 3b 0a 7d 0a . return 0;.}.
1860: 23 65 6e 64 69 66 0a 0a 2f 2a 0a 2a 2a 20 44 6f #endif../*.** Do
1870: 20 61 20 6e 6f 72 6d 61 6c 20 48 54 54 50 20 72 a normal HTTP r
1880: 65 70 6c 79 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 eply.*/.void cgi
1890: 5f 72 65 70 6c 79 28 76 6f 69 64 29 7b 0a 20 20 _reply(void){.
18a0: 69 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 if( iReplyStatus
18b0: 3c 3d 30 20 29 7b 0a 20 20 20 20 69 52 65 70 6c <=0 ){. iRepl
18c0: 79 53 74 61 74 75 73 20 3d 20 32 30 30 3b 0a 20 yStatus = 200;.
18d0: 20 20 20 7a 52 65 70 6c 79 53 74 61 74 75 73 20 zReplyStatus
18e0: 3d 20 22 4f 4b 22 3b 0a 20 20 7d 0a 0a 23 69 66 = "OK";. }..#if
18f0: 20 30 0a 20 20 69 66 28 20 69 52 65 70 6c 79 53 0. if( iReplyS
1900: 74 61 74 75 73 3d 3d 32 30 30 20 26 26 20 63 68 tatus==200 && ch
1910: 65 63 6b 5f 63 61 63 68 65 5f 63 6f 6e 74 72 6f eck_cache_contro
1920: 6c 28 29 20 29 20 7b 0a 20 20 20 20 2f 2a 20 63 l() ) {. /* c
1930: 68 61 6e 67 65 20 74 68 65 20 73 74 61 74 75 73 hange the status
1940: 20 74 6f 20 22 75 6e 63 68 61 6e 67 65 64 22 20 to "unchanged"
1950: 61 6e 64 20 77 65 20 63 61 6e 20 73 6b 69 70 20 and we can skip
1960: 73 65 6e 64 69 6e 67 20 74 68 65 0a 20 20 20 20 sending the.
1970: 2a 2a 20 61 63 74 75 61 6c 20 72 65 73 70 6f 6e ** actual respon
1980: 73 65 20 62 6f 64 79 2e 20 4f 62 76 69 6f 75 73 se body. Obvious
1990: 6c 79 20 77 65 20 6f 6e 6c 79 20 64 6f 20 74 68 ly we only do th
19a0: 69 73 20 77 68 65 6e 20 77 65 20 5f 68 61 76 65 is when we _have
19b0: 5f 20 61 0a 20 20 20 20 2a 2a 20 62 6f 64 79 20 _ a. ** body
19c0: 28 63 6f 64 65 20 32 30 30 29 2e 0a 20 20 20 20 (code 200)..
19d0: 2a 2f 0a 20 20 20 20 69 52 65 70 6c 79 53 74 61 */. iReplySta
19e0: 74 75 73 20 3d 20 33 30 34 3b 0a 20 20 20 20 7a tus = 304;. z
19f0: 52 65 70 6c 79 53 74 61 74 75 73 20 3d 20 22 4e ReplyStatus = "N
1a00: 6f 74 20 4d 6f 64 69 66 69 65 64 22 3b 0a 20 20 ot Modified";.
1a10: 7d 0a 23 65 6e 64 69 66 0a 0a 20 20 69 66 28 20 }.#endif.. if(
1a20: 66 75 6c 6c 48 74 74 70 52 65 70 6c 79 20 29 7b fullHttpReply ){
1a30: 0a 20 20 20 20 70 72 69 6e 74 66 28 22 48 54 54 . printf("HTT
1a40: 50 2f 31 2e 30 20 25 64 20 25 73 5c 72 5c 6e 22 P/1.0 %d %s\r\n"
1a50: 2c 20 69 52 65 70 6c 79 53 74 61 74 75 73 2c 20 , iReplyStatus,
1a60: 7a 52 65 70 6c 79 53 74 61 74 75 73 29 3b 0a 20 zReplyStatus);.
1a70: 20 20 20 70 72 69 6e 74 66 28 22 44 61 74 65 3a printf("Date:
1a80: 20 25 73 5c 72 5c 6e 22 2c 20 63 67 69 5f 72 66 %s\r\n", cgi_rf
1a90: 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 28 74 c822_datestamp(t
1aa0: 69 6d 65 28 30 29 29 29 3b 0a 20 20 20 20 70 72 ime(0)));. pr
1ab0: 69 6e 74 66 28 22 43 6f 6e 6e 65 63 74 69 6f 6e intf("Connection
1ac0: 3a 20 63 6c 6f 73 65 5c 72 5c 6e 22 29 3b 0a 20 : close\r\n");.
1ad0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 70 72 69 6e }else{. prin
1ae0: 74 66 28 22 53 74 61 74 75 73 3a 20 25 64 20 25 tf("Status: %d %
1af0: 73 5c 72 5c 6e 22 2c 20 69 52 65 70 6c 79 53 74 s\r\n", iReplySt
1b00: 61 74 75 73 2c 20 7a 52 65 70 6c 79 53 74 61 74 atus, zReplyStat
1b10: 75 73 29 3b 0a 20 20 7d 0a 0a 20 20 69 66 28 20 us);. }.. if(
1b20: 62 6c 6f 62 5f 73 69 7a 65 28 26 65 78 74 72 61 blob_size(&extra
1b30: 48 65 61 64 65 72 29 3e 30 20 29 7b 0a 20 20 20 Header)>0 ){.
1b40: 20 70 72 69 6e 74 66 28 22 25 73 22 2c 20 62 6c printf("%s", bl
1b50: 6f 62 5f 62 75 66 66 65 72 28 26 65 78 74 72 61 ob_buffer(&extra
1b60: 48 65 61 64 65 72 29 29 3b 0a 20 20 7d 0a 0a 20 Header));. }..
1b70: 20 69 66 28 20 67 2e 69 73 43 6f 6e 73 74 20 29 if( g.isConst )
1b80: 7b 0a 20 20 20 20 2f 2a 20 63 6f 6e 73 74 61 6e {. /* constan
1b90: 74 20 6d 65 61 6e 73 20 74 68 61 74 20 74 68 65 t means that the
1ba0: 20 69 6e 70 75 74 20 55 52 4c 20 77 69 6c 6c 20 input URL will
1bb0: 5f 6e 65 76 65 72 5f 20 67 65 6e 65 72 61 74 65 _never_ generate
1bc0: 20 61 6e 79 74 68 69 6e 67 0a 20 20 20 20 2a 2a anything. **
1bd0: 20 65 6c 73 65 2e 20 49 6e 20 74 68 65 20 63 61 else. In the ca
1be0: 73 65 20 6f 66 20 61 74 74 61 63 68 6d 65 6e 74 se of attachment
1bf0: 73 2c 20 74 68 65 20 63 6f 6e 74 65 6e 74 73 20 s, the contents
1c00: 77 6f 6e 27 74 20 63 68 61 6e 67 65 20 62 65 63 won't change bec
1c10: 61 75 73 65 0a 20 20 20 20 2a 2a 20 61 6e 20 61 ause. ** an a
1c20: 74 74 65 6d 70 74 20 74 6f 20 63 68 61 6e 67 65 ttempt to change
1c30: 20 74 68 65 6d 20 67 65 6e 65 72 61 74 65 73 20 them generates
1c40: 61 20 6e 65 77 20 61 74 74 61 63 68 6d 65 6e 74 a new attachment
1c50: 20 6e 75 6d 62 65 72 2e 20 49 6e 20 74 68 65 0a number. In the.
1c60: 20 20 20 20 2a 2a 20 63 61 73 65 20 6f 66 20 6d ** case of m
1c70: 6f 73 74 20 2f 67 65 74 66 69 6c 65 20 63 61 6c ost /getfile cal
1c80: 6c 73 20 66 6f 72 20 73 70 65 63 69 66 69 63 20 ls for specific
1c90: 76 65 72 73 69 6f 6e 73 2c 20 74 68 65 20 6f 6e versions, the on
1ca0: 6c 79 20 77 61 79 20 74 68 65 0a 20 20 20 20 2a ly way the. *
1cb0: 2a 20 63 6f 6e 74 65 6e 74 20 63 68 61 6e 67 65 * content change
1cc0: 73 20 69 73 20 69 66 20 73 6f 6d 65 6f 6e 65 20 s is if someone
1cd0: 62 72 65 61 6b 73 20 74 68 65 20 53 43 4d 2e 20 breaks the SCM.
1ce0: 41 6e 64 20 69 66 20 74 68 61 74 20 68 61 70 70 And if that happ
1cf0: 65 6e 73 2c 20 61 0a 20 20 20 20 2a 2a 20 73 74 ens, a. ** st
1d00: 61 6c 65 20 63 61 63 68 65 20 69 73 20 74 68 65 ale cache is the
1d10: 20 6c 65 61 73 74 20 6f 66 20 74 68 65 20 70 72 least of the pr
1d20: 6f 62 6c 65 6d 2e 20 53 6f 20 77 65 20 70 72 6f oblem. So we pro
1d30: 76 69 64 65 20 61 6e 20 45 78 70 69 72 65 73 0a vide an Expires.
1d40: 20 20 20 20 2a 2a 20 68 65 61 64 65 72 20 73 65 ** header se
1d50: 74 20 74 6f 20 61 20 72 65 61 73 6f 6e 61 62 6c t to a reasonabl
1d60: 65 20 70 65 72 69 6f 64 20 28 64 65 66 61 75 6c e period (defaul
1d70: 74 3a 20 6f 6e 65 20 77 65 65 6b 29 2e 0a 20 20 t: one week)..
1d80: 20 20 2a 2f 0a 20 20 20 20 2f 2a 74 69 6d 65 5f */. /*time_
1d90: 74 20 65 78 70 69 72 65 73 20 3d 20 74 69 6d 65 t expires = time
1da0: 28 30 29 20 2b 20 61 74 6f 69 28 64 62 5f 63 6f (0) + atoi(db_co
1db0: 6e 66 69 67 28 22 63 6f 6e 73 74 61 6e 74 5f 65 nfig("constant_e
1dc0: 78 70 69 72 65 73 22 2c 22 36 30 34 38 30 30 22 xpires","604800"
1dd0: 29 29 3b 2a 2f 0a 20 20 20 20 74 69 6d 65 5f 74 ));*/. time_t
1de0: 20 65 78 70 69 72 65 73 20 3d 20 74 69 6d 65 28 expires = time(
1df0: 30 29 20 2b 20 36 30 34 38 30 30 3b 0a 20 20 20 0) + 604800;.
1e00: 20 70 72 69 6e 74 66 28 20 22 45 78 70 69 72 65 printf( "Expire
1e10: 73 3a 20 25 73 5c 72 5c 6e 22 2c 20 63 67 69 5f s: %s\r\n", cgi_
1e20: 72 66 63 38 32 32 5f 64 61 74 65 73 74 61 6d 70 rfc822_datestamp
1e30: 28 65 78 70 69 72 65 73 29 29 3b 0a 20 20 7d 0a (expires));. }.
1e40: 0a 20 20 2f 2a 20 43 6f 6e 74 65 6e 74 20 69 6e . /* Content in
1e50: 74 65 6e 64 65 64 20 66 6f 72 20 6c 6f 67 67 65 tended for logge
1e60: 64 20 69 6e 20 75 73 65 72 73 20 73 68 6f 75 6c d in users shoul
1e70: 64 20 6f 6e 6c 79 20 62 65 20 63 61 63 68 65 64 d only be cached
1e80: 20 69 6e 0a 20 20 2a 2a 20 74 68 65 20 62 72 6f in. ** the bro
1e90: 77 73 65 72 2c 20 6e 6f 74 20 73 6f 6d 65 20 73 wser, not some s
1ea0: 68 61 72 65 64 20 6c 6f 63 61 74 69 6f 6e 2e 0a hared location..
1eb0: 20 20 2a 2f 0a 20 20 70 72 69 6e 74 66 28 22 43 */. printf("C
1ec0: 61 63 68 65 2d 63 6f 6e 74 72 6f 6c 3a 20 70 72 ache-control: pr
1ed0: 69 76 61 74 65 5c 72 5c 6e 22 29 3b 0a 0a 23 69 ivate\r\n");..#i
1ee0: 66 20 46 4f 53 53 49 4c 5f 49 31 38 4e 0a 20 20 f FOSSIL_I18N.
1ef0: 70 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74 printf( "Content
1f00: 2d 54 79 70 65 3a 20 25 73 3b 20 63 68 61 72 73 -Type: %s; chars
1f10: 65 74 3d 25 73 5c 72 5c 6e 22 2c 20 7a 43 6f 6e et=%s\r\n", zCon
1f20: 74 65 6e 74 54 79 70 65 2c 20 6e 6c 5f 6c 61 6e tentType, nl_lan
1f30: 67 69 6e 66 6f 28 43 4f 44 45 53 45 54 29 29 3b ginfo(CODESET));
1f40: 0a 23 65 6c 73 65 0a 20 20 70 72 69 6e 74 66 28 .#else. printf(
1f50: 20 22 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 "Content-Type:
1f60: 25 73 3b 20 63 68 61 72 73 65 74 3d 49 53 4f 2d %s; charset=ISO-
1f70: 38 38 35 39 2d 31 5c 72 5c 6e 22 2c 20 7a 43 6f 8859-1\r\n", zCo
1f80: 6e 74 65 6e 74 54 79 70 65 29 3b 0a 23 65 6e 64 ntentType);.#end
1f90: 69 66 0a 20 20 69 66 28 20 73 74 72 63 6d 70 28 if. if( strcmp(
1fa0: 7a 43 6f 6e 74 65 6e 74 54 79 70 65 2c 22 61 70 zContentType,"ap
1fb0: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 plication/x-foss
1fc0: 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 62 il")==0 ){. b
1fd0: 6c 6f 62 5f 63 6f 6d 70 72 65 73 73 28 26 63 67 lob_compress(&cg
1fe0: 69 43 6f 6e 74 65 6e 74 2c 20 26 63 67 69 43 6f iContent, &cgiCo
1ff0: 6e 74 65 6e 74 29 3b 0a 20 20 7d 0a 0a 20 20 69 ntent);. }.. i
2000: 66 28 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 f( iReplyStatus
2010: 21 3d 20 33 30 34 20 29 20 7b 0a 20 20 20 20 70 != 304 ) {. p
2020: 72 69 6e 74 66 28 20 22 43 6f 6e 74 65 6e 74 2d rintf( "Content-
2030: 4c 65 6e 67 74 68 3a 20 25 64 5c 72 5c 6e 22 2c Length: %d\r\n",
2040: 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 43 blob_size(&cgiC
2050: 6f 6e 74 65 6e 74 29 20 29 3b 0a 20 20 7d 0a 20 ontent) );. }.
2060: 20 70 72 69 6e 74 66 28 22 5c 72 5c 6e 22 29 3b printf("\r\n");
2070: 0a 20 20 69 66 28 20 62 6c 6f 62 5f 73 69 7a 65 . if( blob_size
2080: 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 3e 30 20 (&cgiContent)>0
2090: 26 26 20 69 52 65 70 6c 79 53 74 61 74 75 73 20 && iReplyStatus
20a0: 21 3d 20 33 30 34 20 29 7b 0a 20 20 20 20 66 77 != 304 ){. fw
20b0: 72 69 74 65 28 62 6c 6f 62 5f 62 75 66 66 65 72 rite(blob_buffer
20c0: 28 26 63 67 69 43 6f 6e 74 65 6e 74 29 2c 20 31 (&cgiContent), 1
20d0: 2c 20 62 6c 6f 62 5f 73 69 7a 65 28 26 63 67 69 , blob_size(&cgi
20e0: 43 6f 6e 74 65 6e 74 29 2c 20 73 74 64 6f 75 74 Content), stdout
20f0: 29 3b 0a 20 20 7d 0a 20 20 43 47 49 44 45 42 55 );. }. CGIDEBU
2100: 47 28 28 22 44 4f 4e 45 5c 6e 22 29 29 3b 0a 7d G(("DONE\n"));.}
2110: 0a 0a 2f 2a 0a 2a 2a 20 44 6f 20 61 20 72 65 64 ../*.** Do a red
2120: 69 72 65 63 74 20 72 65 71 75 65 73 74 20 74 6f irect request to
2130: 20 74 68 65 20 55 52 4c 20 67 69 76 65 6e 20 69 the URL given i
2140: 6e 20 74 68 65 20 61 72 67 75 6d 65 6e 74 2e 0a n the argument..
2150: 2a 2a 0a 2a 2a 20 54 68 65 20 55 52 4c 20 6d 75 **.** The URL mu
2160: 73 74 20 62 65 20 72 65 6c 61 74 69 76 65 20 74 st be relative t
2170: 6f 20 74 68 65 20 62 61 73 65 20 6f 66 20 74 68 o the base of th
2180: 65 20 66 6f 73 73 69 6c 20 73 65 72 76 65 72 2e e fossil server.
2190: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 72 65 64 .*/.void cgi_red
21a0: 69 72 65 63 74 28 63 6f 6e 73 74 20 63 68 61 72 irect(const char
21b0: 20 2a 7a 55 52 4c 29 7b 0a 20 20 63 68 61 72 20 *zURL){. char
21c0: 2a 7a 4c 6f 63 61 74 69 6f 6e 3b 0a 20 20 43 47 *zLocation;. CG
21d0: 49 44 45 42 55 47 28 28 22 72 65 64 69 72 65 63 IDEBUG(("redirec
21e0: 74 20 74 6f 20 25 73 5c 6e 22 2c 20 7a 55 52 4c t to %s\n", zURL
21f0: 29 29 3b 0a 20 20 69 66 28 20 73 74 72 6e 63 6d ));. if( strncm
2200: 70 28 7a 55 52 4c 2c 22 68 74 74 70 3a 22 2c 35 p(zURL,"http:",5
2210: 29 3d 3d 30 20 7c 7c 20 73 74 72 6e 63 6d 70 28 )==0 || strncmp(
2220: 7a 55 52 4c 2c 22 68 74 74 70 73 3a 22 2c 36 29 zURL,"https:",6)
2230: 3d 3d 30 20 7c 7c 20 2a 7a 55 52 4c 3d 3d 27 2f ==0 || *zURL=='/
2240: 27 20 29 7b 0a 20 20 20 20 63 67 69 5f 70 61 6e ' ){. cgi_pan
2250: 69 63 28 22 69 6e 76 61 6c 69 64 20 72 65 64 69 ic("invalid redi
2260: 72 65 63 74 20 55 52 4c 3a 20 25 73 22 2c 20 7a rect URL: %s", z
2270: 55 52 4c 29 3b 0a 20 20 7d 0a 20 20 7a 4c 6f 63 URL);. }. zLoc
2280: 61 74 69 6f 6e 20 3d 20 6d 70 72 69 6e 74 66 28 ation = mprintf(
2290: 22 4c 6f 63 61 74 69 6f 6e 3a 20 25 73 2f 25 73 "Location: %s/%s
22a0: 5c 72 5c 6e 22 2c 20 67 2e 7a 42 61 73 65 55 52 \r\n", g.zBaseUR
22b0: 4c 2c 20 7a 55 52 4c 29 3b 0a 20 20 63 67 69 5f L, zURL);. cgi_
22c0: 61 70 70 65 6e 64 5f 68 65 61 64 65 72 28 7a 4c append_header(zL
22d0: 6f 63 61 74 69 6f 6e 29 3b 0a 20 20 63 67 69 5f ocation);. cgi_
22e0: 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 29 3b reset_content();
22f0: 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 3c . cgi_printf("<
2300: 68 74 6d 6c 3e 5c 6e 3c 70 3e 52 65 64 69 72 65 html>\n<p>Redire
2310: 63 74 20 74 6f 20 25 68 3c 2f 70 3e 5c 6e 3c 2f ct to %h</p>\n</
2320: 68 74 6d 6c 3e 5c 6e 22 2c 20 7a 55 52 4c 29 3b html>\n", zURL);
2330: 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 . cgi_set_statu
2340: 73 28 33 30 32 2c 20 22 4d 6f 76 65 64 20 54 65 s(302, "Moved Te
2350: 6d 70 6f 72 61 72 69 6c 79 22 29 3b 0a 20 20 66 mporarily");. f
2360: 72 65 65 28 7a 4c 6f 63 61 74 69 6f 6e 29 3b 0a ree(zLocation);.
2370: 20 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 cgi_reply();.
2380: 20 65 78 69 74 28 30 29 3b 0a 7d 0a 76 6f 69 64 exit(0);.}.void
2390: 20 63 67 69 5f 72 65 64 69 72 65 63 74 66 28 63 cgi_redirectf(c
23a0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d onst char *zForm
23b0: 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c at, ...){. va_l
23c0: 69 73 74 20 61 70 3b 0a 20 20 76 61 5f 73 74 61 ist ap;. va_sta
23d0: 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b rt(ap, zFormat);
23e0: 0a 20 20 63 67 69 5f 72 65 64 69 72 65 63 74 28 . cgi_redirect(
23f0: 76 6d 70 72 69 6e 74 66 28 7a 46 6f 72 6d 61 74 vmprintf(zFormat
2400: 2c 20 61 70 29 29 3b 0a 20 20 76 61 5f 65 6e 64 , ap));. va_end
2410: 28 61 70 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 (ap);.}../*.** I
2420: 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 62 6f 75 74 nformation about
2430: 20 61 6c 6c 20 71 75 65 72 79 20 70 61 72 61 6d all query param
2440: 65 74 65 72 73 20 61 6e 64 20 63 6f 6f 6b 69 65 eters and cookie
2450: 73 20 61 72 65 20 73 74 6f 72 65 64 0a 2a 2a 20 s are stored.**
2460: 69 6e 20 74 68 65 73 65 20 76 61 72 69 61 62 6c in these variabl
2470: 65 73 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e es..*/.static in
2480: 74 20 6e 41 6c 6c 6f 63 51 50 20 3d 20 30 3b 20 t nAllocQP = 0;
2490: 2f 2a 20 53 70 61 63 65 20 61 6c 6c 6f 63 61 74 /* Space allocat
24a0: 65 64 20 66 6f 72 20 61 50 61 72 61 6d 51 50 5b ed for aParamQP[
24b0: 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 ] */.static int
24c0: 6e 55 73 65 64 51 50 20 3d 20 30 3b 20 20 2f 2a nUsedQP = 0; /*
24d0: 20 53 70 61 63 65 20 61 63 74 75 61 6c 6c 79 20 Space actually
24e0: 75 73 65 64 20 69 6e 20 61 50 61 72 61 6d 51 50 used in aParamQP
24f0: 5b 5d 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 [] */.static int
2500: 20 73 6f 72 74 51 50 20 3d 20 30 3b 20 20 20 2f sortQP = 0; /
2510: 2a 20 54 72 75 65 20 69 66 20 61 50 61 72 61 6d * True if aParam
2520: 51 50 5b 5d 20 6e 65 65 64 73 20 73 6f 72 74 69 QP[] needs sorti
2530: 6e 67 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 ng */.static int
2540: 20 73 65 71 51 50 20 3d 20 30 3b 20 20 20 20 2f seqQP = 0; /
2550: 2a 20 53 65 71 75 65 6e 63 65 20 6e 75 6d 62 65 * Sequence numbe
2560: 72 73 20 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 rs */.static str
2570: 75 63 74 20 51 50 61 72 61 6d 20 7b 20 20 20 2f uct QParam { /
2580: 2a 20 4f 6e 65 20 65 6e 74 72 79 20 66 6f 72 20 * One entry for
2590: 65 61 63 68 20 71 75 65 72 79 20 70 61 72 61 6d each query param
25a0: 65 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 2a eter or cookie *
25b0: 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a /. const char *
25c0: 7a 4e 61 6d 65 3b 20 20 20 20 20 20 20 20 2f 2a zName; /*
25d0: 20 50 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f Parameter or co
25e0: 6f 6b 69 65 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 okie name */. c
25f0: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 onst char *zValu
2600: 65 3b 20 20 20 20 20 20 20 2f 2a 20 56 61 6c 75 e; /* Valu
2610: 65 20 6f 66 20 74 68 65 20 71 75 65 72 79 20 70 e of the query p
2620: 61 72 61 6d 65 74 65 72 20 6f 72 20 63 6f 6f 6b arameter or cook
2630: 69 65 20 2a 2f 0a 20 20 69 6e 74 20 73 65 71 3b ie */. int seq;
2640: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
2650: 20 20 2f 2a 20 4f 72 64 65 72 20 6f 66 20 69 6e /* Order of in
2660: 73 65 72 74 69 6f 6e 20 2a 2f 0a 7d 20 2a 61 50 sertion */.} *aP
2670: 61 72 61 6d 51 50 3b 20 20 20 20 20 20 20 20 20 aramQP;
2680: 20 20 20 20 2f 2a 20 41 6e 20 61 72 72 61 79 20 /* An array
2690: 6f 66 20 61 6c 6c 20 70 61 72 61 6d 65 74 65 72 of all parameter
26a0: 73 20 61 6e 64 20 63 6f 6f 6b 69 65 73 20 2a 2f s and cookies */
26b0: 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 ../*.** Add anot
26c0: 68 65 72 20 71 75 65 72 79 20 70 61 72 61 6d 65 her query parame
26d0: 74 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 74 6f ter or cookie to
26e0: 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 73 the parameter s
26f0: 65 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 et..** zName is
2700: 74 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 the name of the
2710: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 query parameter
2720: 6f 72 20 63 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 or cookie and zV
2730: 61 6c 75 65 0a 2a 2a 20 69 73 20 69 74 73 20 66 alue.** is its f
2740: 75 6c 6c 79 20 64 65 63 6f 64 65 64 20 76 61 6c ully decoded val
2750: 75 65 2e 0a 2a 2a 0a 2a 2a 20 7a 4e 61 6d 65 20 ue..**.** zName
2760: 61 6e 64 20 7a 56 61 6c 75 65 20 61 72 65 20 6e and zValue are n
2770: 6f 74 20 63 6f 70 69 65 64 20 61 6e 64 20 6d 75 ot copied and mu
2780: 73 74 20 6e 6f 74 20 63 68 61 6e 67 65 20 6f 72 st not change or
2790: 20 62 65 0a 2a 2a 20 64 65 61 6c 6c 6f 63 61 74 be.** deallocat
27a0: 65 64 20 61 66 74 65 72 20 74 68 69 73 20 72 6f ed after this ro
27b0: 75 74 69 6e 65 20 72 65 74 75 72 6e 73 2e 0a 2a utine returns..*
27c0: 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 74 5f 70 /.void cgi_set_p
27d0: 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 arameter_nocopy(
27e0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d const char *zNam
27f0: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a e, const char *z
2800: 56 61 6c 75 65 29 7b 0a 20 20 69 66 28 20 6e 41 Value){. if( nA
2810: 6c 6c 6f 63 51 50 3c 3d 6e 55 73 65 64 51 50 20 llocQP<=nUsedQP
2820: 29 7b 0a 20 20 20 20 6e 41 6c 6c 6f 63 51 50 20 ){. nAllocQP
2830: 3d 20 6e 41 6c 6c 6f 63 51 50 2a 32 20 2b 20 31 = nAllocQP*2 + 1
2840: 30 3b 0a 20 20 20 20 61 50 61 72 61 6d 51 50 20 0;. aParamQP
2850: 3d 20 72 65 61 6c 6c 6f 63 28 20 61 50 61 72 61 = realloc( aPara
2860: 6d 51 50 2c 20 6e 41 6c 6c 6f 63 51 50 2a 73 69 mQP, nAllocQP*si
2870: 7a 65 6f 66 28 61 50 61 72 61 6d 51 50 5b 30 5d zeof(aParamQP[0]
2880: 29 20 29 3b 0a 20 20 20 20 69 66 28 20 61 50 61 ) );. if( aPa
2890: 72 61 6d 51 50 3d 3d 30 20 29 20 65 78 69 74 28 ramQP==0 ) exit(
28a0: 31 29 3b 0a 20 20 7d 0a 20 20 61 50 61 72 61 6d 1);. }. aParam
28b0: 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a 4e 61 6d QP[nUsedQP].zNam
28c0: 65 20 3d 20 7a 4e 61 6d 65 3b 0a 20 20 61 50 61 e = zName;. aPa
28d0: 72 61 6d 51 50 5b 6e 55 73 65 64 51 50 5d 2e 7a ramQP[nUsedQP].z
28e0: 56 61 6c 75 65 20 3d 20 7a 56 61 6c 75 65 3b 0a Value = zValue;.
28f0: 20 20 61 50 61 72 61 6d 51 50 5b 6e 55 73 65 64 aParamQP[nUsed
2900: 51 50 5d 2e 73 65 71 20 3d 20 73 65 71 51 50 2b QP].seq = seqQP+
2910: 2b 3b 0a 20 20 6e 55 73 65 64 51 50 2b 2b 3b 0a +;. nUsedQP++;.
2920: 20 20 73 6f 72 74 51 50 20 3d 20 31 3b 0a 7d 0a sortQP = 1;.}.
2930: 0a 2f 2a 0a 2a 2a 20 41 64 64 20 61 6e 6f 74 68 ./*.** Add anoth
2940: 65 72 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 er query paramet
2950: 65 72 20 6f 72 20 63 6f 6f 6b 69 65 20 74 6f 20 er or cookie to
2960: 74 68 65 20 70 61 72 61 6d 65 74 65 72 20 73 65 the parameter se
2970: 74 2e 0a 2a 2a 20 7a 4e 61 6d 65 20 69 73 20 74 t..** zName is t
2980: 68 65 20 6e 61 6d 65 20 6f 66 20 74 68 65 20 71 he name of the q
2990: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f uery parameter o
29a0: 72 20 63 6f 6f 6b 69 65 20 61 6e 64 20 7a 56 61 r cookie and zVa
29b0: 6c 75 65 0a 2a 2a 20 69 73 20 69 74 73 20 66 75 lue.** is its fu
29c0: 6c 6c 79 20 64 65 63 6f 64 65 64 20 76 61 6c 75 lly decoded valu
29d0: 65 2e 0a 2a 2a 0a 2a 2a 20 43 6f 70 69 65 73 20 e..**.** Copies
29e0: 61 72 65 20 6d 61 64 65 20 6f 66 20 62 6f 74 68 are made of both
29f0: 20 74 68 65 20 7a 4e 61 6d 65 20 61 6e 64 20 7a the zName and z
2a00: 56 61 6c 75 65 20 70 61 72 61 6d 65 74 65 72 73 Value parameters
2a10: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 73 65 ..*/.void cgi_se
2a20: 74 5f 70 61 72 61 6d 65 74 65 72 28 63 6f 6e 73 t_parameter(cons
2a30: 74 20 63 68 61 72 20 2a 7a 4e 61 6d 65 2c 20 63 t char *zName, c
2a40: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c 75 onst char *zValu
2a50: 65 29 7b 0a 20 20 63 67 69 5f 73 65 74 5f 70 61 e){. cgi_set_pa
2a60: 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 6d rameter_nocopy(m
2a70: 70 72 69 6e 74 66 28 22 25 73 22 2c 7a 4e 61 6d printf("%s",zNam
2a80: 65 29 2c 20 6d 70 72 69 6e 74 66 28 22 25 73 22 e), mprintf("%s"
2a90: 2c 7a 56 61 6c 75 65 29 29 3b 0a 7d 0a 0a 2f 2a ,zValue));.}../*
2aa0: 0a 2a 2a 20 41 64 64 20 61 20 71 75 65 72 79 20 .** Add a query
2ab0: 70 61 72 61 6d 65 74 65 72 2e 20 20 54 68 65 20 parameter. The
2ac0: 7a 4e 61 6d 65 20 70 6f 72 74 69 6f 6e 20 69 73 zName portion is
2ad0: 20 66 69 78 65 64 20 62 75 74 20 61 20 63 6f 70 fixed but a cop
2ae0: 79 0a 2a 2a 20 6d 75 73 74 20 62 65 20 6d 61 64 y.** must be mad
2af0: 65 20 6f 66 20 7a 56 61 6c 75 65 2e 0a 2a 2f 0a e of zValue..*/.
2b00: 76 6f 69 64 20 63 67 69 5f 73 65 74 65 6e 76 28 void cgi_setenv(
2b10: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 4e 61 6d const char *zNam
2b20: 65 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a e, const char *z
2b30: 56 61 6c 75 65 29 7b 0a 20 20 63 67 69 5f 73 65 Value){. cgi_se
2b40: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f t_parameter_noco
2b50: 70 79 28 7a 4e 61 6d 65 2c 20 6d 70 72 69 6e 74 py(zName, mprint
2b60: 66 28 22 25 73 22 2c 7a 56 61 6c 75 65 29 29 3b f("%s",zValue));
2b70: 0a 7d 0a 20 0a 0a 2f 2a 0a 2a 2a 20 41 64 64 20 .}. ../*.** Add
2b80: 61 20 6c 69 73 74 20 6f 66 20 71 75 65 72 79 20 a list of query
2b90: 70 61 72 61 6d 65 74 65 72 73 20 6f 72 20 63 6f parameters or co
2ba0: 6f 6b 69 65 73 20 74 6f 20 74 68 65 20 70 61 72 okies to the par
2bb0: 61 6d 65 74 65 72 20 73 65 74 2e 0a 2a 2a 0a 2a ameter set..**.*
2bc0: 2a 20 45 61 63 68 20 70 61 72 61 6d 65 74 65 72 * Each parameter
2bd0: 20 69 73 20 6f 66 20 74 68 65 20 66 6f 72 6d 20 is of the form
2be0: 4e 41 4d 45 3d 56 41 4c 55 45 2e 20 20 42 6f 74 NAME=VALUE. Bot
2bf0: 68 20 74 68 65 20 4e 41 4d 45 20 61 6e 64 20 74 h the NAME and t
2c00: 68 65 0a 2a 2a 20 56 41 4c 55 45 20 6d 61 79 20 he.** VALUE may
2c10: 62 65 20 75 72 6c 2d 65 6e 63 6f 64 65 64 20 28 be url-encoded (
2c20: 22 2b 22 20 66 6f 72 20 73 70 61 63 65 2c 20 22 "+" for space, "
2c30: 25 48 48 22 20 66 6f 72 20 6f 74 68 65 72 20 73 %HH" for other s
2c40: 70 65 63 69 61 6c 0a 2a 2a 20 63 68 61 72 61 63 pecial.** charac
2c50: 74 65 72 73 29 2e 20 20 42 75 74 20 74 68 69 73 ters). But this
2c60: 20 72 6f 75 74 69 6e 65 20 61 73 73 75 6d 65 73 routine assumes
2c70: 20 74 68 61 74 20 4e 41 4d 45 20 63 6f 6e 74 61 that NAME conta
2c80: 69 6e 73 20 6e 6f 0a 2a 2a 20 73 70 65 63 69 61 ins no.** specia
2c90: 6c 20 63 68 61 72 61 63 74 65 72 20 61 6e 64 20 l character and
2ca0: 74 68 65 72 65 66 6f 72 65 20 64 6f 65 73 20 6e therefore does n
2cb0: 6f 74 20 64 65 63 6f 64 65 20 69 74 2e 0a 2a 2a ot decode it..**
2cc0: 0a 2a 2a 20 49 66 20 4e 41 4d 45 20 62 65 67 69 .** If NAME begi
2cd0: 6e 73 20 77 69 74 68 20 61 6e 6f 74 68 65 72 20 ns with another
2ce0: 6f 74 68 65 72 20 74 68 61 6e 20 61 20 6c 6f 77 other than a low
2cf0: 65 72 2d 63 61 73 65 20 6c 65 74 74 65 72 20 74 er-case letter t
2d00: 68 65 6e 0a 2a 2a 20 74 68 65 20 65 6e 74 69 72 hen.** the entir
2d10: 65 20 4e 41 4d 45 3d 56 41 4c 55 45 20 74 65 72 e NAME=VALUE ter
2d20: 6d 20 69 73 20 69 67 6e 6f 72 65 64 2e 20 20 48 m is ignored. H
2d30: 65 6e 63 65 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 20 ence:.**.**
2d40: 20 2a 20 20 63 6f 6f 6b 69 65 73 20 61 6e 64 20 * cookies and
2d50: 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 73 query parameters
2d60: 20 74 68 61 74 20 68 61 76 65 20 75 70 70 65 72 that have upper
2d70: 63 61 73 65 20 6e 61 6d 65 73 0a 2a 2a 20 20 20 case names.**
2d80: 20 20 20 20 20 20 61 72 65 20 69 67 6e 6f 72 65 are ignore
2d90: 64 2e 0a 2a 2a 0a 2a 2a 20 20 20 20 20 20 2a 20 d..**.** *
2da0: 20 69 74 20 69 73 20 69 6d 70 6f 73 73 69 62 6c it is impossibl
2db0: 65 20 66 6f 72 20 61 20 63 6f 6f 6b 69 65 20 6f e for a cookie o
2dc0: 72 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 r query paramete
2dd0: 72 20 74 6f 0a 2a 2a 20 20 20 20 20 20 20 20 20 r to.**
2de0: 6f 76 65 72 72 69 64 65 20 74 68 65 20 76 61 6c override the val
2df0: 75 65 20 6f 66 20 61 6e 20 65 6e 76 69 72 6f 6e ue of an environ
2e00: 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 73 69 ment variable si
2e10: 6e 63 65 0a 2a 2a 20 20 20 20 20 20 20 20 20 65 nce.** e
2e20: 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 nvironment varia
2e30: 62 6c 65 73 20 61 6c 77 61 79 73 20 68 61 76 65 bles always have
2e40: 20 75 70 70 65 72 63 61 73 65 20 6e 61 6d 65 73 uppercase names
2e50: 2e 0a 2a 2a 0a 2a 2a 20 50 61 72 61 6d 65 74 65 ..**.** Paramete
2e60: 72 73 20 61 72 65 20 73 65 70 61 72 61 74 65 64 rs are separated
2e70: 20 62 79 20 74 68 65 20 22 74 65 72 6d 69 6e 61 by the "termina
2e80: 74 6f 72 22 20 63 68 61 72 61 63 74 65 72 2e 20 tor" character.
2e90: 20 57 68 69 74 65 73 70 61 63 65 0a 2a 2a 20 62 Whitespace.** b
2ea0: 65 66 6f 72 65 20 74 68 65 20 4e 41 4d 45 20 69 efore the NAME i
2eb0: 73 20 69 67 6e 6f 72 65 64 2e 0a 2a 2a 0a 2a 2a s ignored..**.**
2ec0: 20 54 68 65 20 69 6e 70 75 74 20 73 74 72 69 6e The input strin
2ed0: 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66 69 65 g "z" is modifie
2ee0: 64 20 62 75 74 20 6e 6f 20 63 6f 70 69 65 73 20 d but no copies
2ef0: 69 73 20 6d 61 64 65 2e 20 20 22 7a 22 0a 2a 2a is made. "z".**
2f00: 20 73 68 6f 75 6c 64 20 6e 6f 74 20 62 65 20 64 should not be d
2f10: 65 61 6c 6c 6f 63 61 74 65 64 20 6f 72 20 63 68 eallocated or ch
2f20: 61 6e 67 65 64 20 61 67 61 69 6e 20 61 66 74 65 anged again afte
2f30: 72 20 74 68 69 73 20 72 6f 75 74 69 6e 65 0a 2a r this routine.*
2f40: 2a 20 72 65 74 75 72 6e 73 20 6f 72 20 69 74 20 * returns or it
2f50: 77 69 6c 6c 20 63 6f 72 72 75 70 74 20 74 68 65 will corrupt the
2f60: 20 70 61 72 61 6d 65 74 65 72 20 74 61 62 6c 65 parameter table
2f70: 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 ..*/.static void
2f80: 20 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 add_param_list(
2f90: 63 68 61 72 20 2a 7a 2c 20 69 6e 74 20 74 65 72 char *z, int ter
2fa0: 6d 69 6e 61 74 6f 72 29 7b 0a 20 20 77 68 69 6c minator){. whil
2fb0: 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 63 68 61 e( *z ){. cha
2fc0: 72 20 2a 7a 4e 61 6d 65 3b 0a 20 20 20 20 63 68 r *zName;. ch
2fd0: 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20 20 20 ar *zValue;.
2fe0: 77 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a while( isspace(*
2ff0: 7a 29 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 z) ){ z++; }.
3000: 20 7a 4e 61 6d 65 20 3d 20 7a 3b 0a 20 20 20 20 zName = z;.
3010: 77 68 69 6c 65 28 20 2a 7a 20 26 26 20 2a 7a 21 while( *z && *z!
3020: 3d 27 3d 27 20 26 26 20 2a 7a 21 3d 74 65 72 6d ='=' && *z!=term
3030: 69 6e 61 74 6f 72 20 29 7b 20 7a 2b 2b 3b 20 7d inator ){ z++; }
3040: 0a 20 20 20 20 69 66 28 20 2a 7a 3d 3d 27 3d 27 . if( *z=='='
3050: 20 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 ){. *z = 0
3060: 3b 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 ;. z++;.
3070: 20 20 20 7a 56 61 6c 75 65 20 3d 20 7a 3b 0a 20 zValue = z;.
3080: 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 26 while( *z &
3090: 26 20 2a 7a 21 3d 74 65 72 6d 69 6e 61 74 6f 72 & *z!=terminator
30a0: 20 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 ){ z++; }.
30b0: 20 69 66 28 20 2a 7a 20 29 7b 0a 20 20 20 20 20 if( *z ){.
30c0: 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 *z = 0;.
30d0: 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a z++;. }.
30e0: 20 20 20 20 20 20 64 65 68 74 74 70 69 7a 65 28 dehttpize(
30f0: 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 7d 65 6c zValue);. }el
3100: 73 65 7b 0a 20 20 20 20 20 20 69 66 28 20 2a 7a se{. if( *z
3110: 20 29 7b 20 2a 7a 2b 2b 20 3d 20 30 3b 20 7d 0a ){ *z++ = 0; }.
3120: 20 20 20 20 20 20 7a 56 61 6c 75 65 20 3d 20 22 zValue = "
3130: 22 3b 0a 20 20 20 20 7d 0a 20 20 20 20 69 66 28 ";. }. if(
3140: 20 69 73 6c 6f 77 65 72 28 7a 4e 61 6d 65 5b 30 islower(zName[0
3150: 5d 29 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f ]) ){. cgi_
3160: 73 65 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f set_parameter_no
3170: 63 6f 70 79 28 7a 4e 61 6d 65 2c 20 7a 56 61 6c copy(zName, zVal
3180: 75 65 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 7d ue);. }. }.}
3190: 0a 0a 2f 2a 0a 2a 2a 20 2a 70 7a 20 69 73 20 61 ../*.** *pz is a
31a0: 20 73 74 72 69 6e 67 20 74 68 61 74 20 63 6f 6e string that con
31b0: 73 69 73 74 73 20 6f 66 20 6d 75 6c 74 69 70 6c sists of multipl
31c0: 65 20 6c 69 6e 65 73 20 6f 66 20 74 65 78 74 2e e lines of text.
31d0: 20 20 54 68 69 73 0a 2a 2a 20 72 6f 75 74 69 6e This.** routin
31e0: 65 20 66 69 6e 64 73 20 74 68 65 20 65 6e 64 20 e finds the end
31f0: 6f 66 20 74 68 65 20 63 75 72 72 65 6e 74 20 6c of the current l
3200: 69 6e 65 20 6f 66 20 74 65 78 74 20 61 6e 64 20 ine of text and
3210: 63 6f 6e 76 65 72 74 73 0a 2a 2a 20 74 68 65 20 converts.** the
3220: 22 5c 6e 22 20 6f 72 20 22 5c 72 5c 6e 22 20 74 "\n" or "\r\n" t
3230: 68 61 74 20 65 6e 64 73 20 74 68 61 74 20 6c 69 hat ends that li
3240: 6e 65 20 69 6e 74 6f 20 61 20 22 5c 30 30 30 22 ne into a "\000"
3250: 2e 20 20 49 74 20 74 68 65 6e 0a 2a 2a 20 61 64 . It then.** ad
3260: 76 61 6e 63 65 73 20 2a 70 7a 20 74 6f 20 74 68 vances *pz to th
3270: 65 20 62 65 67 69 6e 6e 69 6e 67 20 6f 66 20 74 e beginning of t
3280: 68 65 20 6e 65 78 74 20 6c 69 6e 65 20 61 6e 64 he next line and
3290: 20 72 65 74 75 72 6e 73 20 74 68 65 0a 2a 2a 20 returns the.**
32a0: 70 72 65 76 69 6f 75 73 20 76 61 6c 75 65 20 6f previous value o
32b0: 66 20 2a 70 7a 20 28 77 68 69 63 68 20 69 73 20 f *pz (which is
32c0: 74 68 65 20 73 74 61 72 74 20 6f 66 20 74 68 65 the start of the
32d0: 20 63 75 72 72 65 6e 74 20 6c 69 6e 65 2e 29 0a current line.).
32e0: 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a */.static char *
32f0: 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d 5f 73 74 get_line_from_st
3300: 72 69 6e 67 28 63 68 61 72 20 2a 2a 70 7a 2c 20 ring(char **pz,
3310: 69 6e 74 20 2a 70 4c 65 6e 29 7b 0a 20 20 63 68 int *pLen){. ch
3320: 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b 0a 20 20 69 ar *z = *pz;. i
3330: 6e 74 20 69 3b 0a 20 20 69 66 28 20 7a 5b 30 5d nt i;. if( z[0]
3340: 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 3b 0a ==0 ) return 0;.
3350: 20 20 66 6f 72 28 69 3d 30 3b 20 7a 5b 69 5d 3b for(i=0; z[i];
3360: 20 69 2b 2b 29 7b 0a 20 20 20 20 69 66 28 20 7a i++){. if( z
3370: 5b 69 5d 3d 3d 27 5c 6e 27 20 29 7b 0a 20 20 20 [i]=='\n' ){.
3380: 20 20 20 69 66 28 20 69 3e 30 20 26 26 20 7a 5b if( i>0 && z[
3390: 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 7b 0a 20 20 i-1]=='\r' ){.
33a0: 20 20 20 20 20 20 7a 5b 69 2d 31 5d 20 3d 20 30 z[i-1] = 0
33b0: 3b 0a 20 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 ;. }else{.
33c0: 20 20 20 20 20 20 20 7a 5b 69 5d 20 3d 20 30 3b z[i] = 0;
33d0: 0a 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 69 . }. i
33e0: 2b 2b 3b 0a 20 20 20 20 20 20 62 72 65 61 6b 3b ++;. break;
33f0: 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 2a 70 7a . }. }. *pz
3400: 20 3d 20 26 7a 5b 69 5d 3b 0a 20 20 2a 70 4c 65 = &z[i];. *pLe
3410: 6e 20 2d 3d 20 69 3b 0a 20 20 72 65 74 75 72 6e n -= i;. return
3420: 20 7a 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 65 z;.}../*.** The
3430: 20 69 6e 70 75 74 20 2a 70 7a 20 70 6f 69 6e 74 input *pz point
3440: 73 20 74 6f 20 63 6f 6e 74 65 6e 74 20 74 68 61 s to content tha
3450: 74 20 69 73 20 74 65 72 6d 69 6e 61 74 65 64 20 t is terminated
3460: 62 79 20 61 20 22 5c 72 5c 6e 22 0a 2a 2a 20 66 by a "\r\n".** f
3470: 6f 6c 6c 6f 77 65 64 20 62 79 20 74 68 65 20 62 ollowed by the b
3480: 6f 75 6e 64 72 79 20 6d 61 72 6b 65 72 20 7a 42 oundry marker zB
3490: 6f 75 6e 64 72 79 2e 20 20 41 6e 20 65 78 74 72 oundry. An extr
34a0: 61 20 22 2d 2d 22 20 6d 61 79 20 6f 72 0a 2a 2a a "--" may or.**
34b0: 20 6d 61 79 20 6e 6f 74 20 62 65 20 61 70 70 65 may not be appe
34c0: 6e 64 65 64 20 74 6f 20 74 68 65 20 62 6f 75 6e nded to the boun
34d0: 64 72 79 20 6d 61 72 6b 65 72 2e 20 20 54 68 65 dry marker. The
34e0: 72 65 20 61 72 65 20 2a 70 4c 65 6e 20 63 68 61 re are *pLen cha
34f0: 72 61 63 74 65 72 73 0a 2a 2a 20 69 6e 20 2a 70 racters.** in *p
3500: 7a 2e 0a 2a 2a 0a 2a 2a 20 54 68 69 73 20 72 6f z..**.** This ro
3510: 75 74 69 6e 65 20 61 64 64 73 20 61 20 22 5c 30 utine adds a "\0
3520: 30 30 22 20 74 6f 20 74 68 65 20 65 6e 64 20 6f 00" to the end o
3530: 66 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 28 6f f the content (o
3540: 76 65 72 77 72 69 74 69 6e 67 0a 2a 2a 20 74 68 verwriting.** th
3550: 65 20 22 5c 72 5c 6e 22 29 20 61 6e 64 20 72 65 e "\r\n") and re
3560: 74 75 72 6e 73 20 61 20 70 6f 69 6e 74 65 72 20 turns a pointer
3570: 74 6f 20 74 68 65 20 63 6f 6e 74 65 6e 74 2e 20 to the content.
3580: 20 54 68 65 20 2a 70 7a 20 69 6e 70 75 74 0a 2a The *pz input.*
3590: 2a 20 69 73 20 61 64 6a 75 73 74 65 64 20 74 6f * is adjusted to
35a0: 20 70 6f 69 6e 74 20 74 6f 20 74 68 65 20 66 69 point to the fi
35b0: 72 73 74 20 6c 69 6e 65 20 66 6f 6c 6c 6f 77 69 rst line followi
35c0: 6e 67 20 74 68 65 20 62 6f 75 6e 64 72 79 2e 0a ng the boundry..
35d0: 2a 2a 20 54 68 65 20 6c 65 6e 67 74 68 20 6f 66 ** The length of
35e0: 20 74 68 65 20 63 6f 6e 74 65 6e 74 20 69 73 20 the content is
35f0: 73 74 6f 72 65 64 20 69 6e 20 2a 70 6e 43 6f 6e stored in *pnCon
3600: 74 65 6e 74 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 tent..*/.static
3610: 63 68 61 72 20 2a 67 65 74 5f 62 6f 75 6e 64 65 char *get_bounde
3620: 64 5f 63 6f 6e 74 65 6e 74 28 0a 20 20 63 68 61 d_content(. cha
3630: 72 20 2a 2a 70 7a 2c 20 20 20 20 20 20 20 20 20 r **pz,
3640: 2f 2a 20 43 6f 6e 74 65 6e 74 20 74 61 6b 65 6e /* Content taken
3650: 20 66 72 6f 6d 20 68 65 72 65 20 2a 2f 0a 20 20 from here */.
3660: 69 6e 74 20 2a 70 4c 65 6e 2c 20 20 20 20 20 20 int *pLen,
3670: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 /* Number of
3680: 62 79 74 65 73 20 6f 66 20 64 61 74 61 20 69 6e bytes of data in
3690: 20 28 2a 70 7a 29 5b 5d 20 2a 2f 0a 20 20 63 68 (*pz)[] */. ch
36a0: 61 72 20 2a 7a 42 6f 75 6e 64 72 79 2c 20 20 20 ar *zBoundry,
36b0: 20 2f 2a 20 42 6f 75 6e 64 72 79 20 74 65 78 74 /* Boundry text
36c0: 20 6d 61 72 6b 69 6e 67 20 74 68 65 20 65 6e 64 marking the end
36d0: 20 6f 66 20 63 6f 6e 74 65 6e 74 20 2a 2f 0a 20 of content */.
36e0: 20 69 6e 74 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 int *pnContent
36f0: 20 20 20 20 2f 2a 20 57 72 69 74 65 20 74 68 65 /* Write the
3700: 20 73 69 7a 65 20 6f 66 20 74 68 65 20 63 6f 6e size of the con
3710: 74 65 6e 74 20 68 65 72 65 20 2a 2f 0a 29 7b 0a tent here */.){.
3720: 20 20 63 68 61 72 20 2a 7a 20 3d 20 2a 70 7a 3b char *z = *pz;
3730: 0a 20 20 69 6e 74 20 6c 65 6e 20 3d 20 2a 70 4c . int len = *pL
3740: 65 6e 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 69 en;. int i;. i
3750: 6e 74 20 6e 42 6f 75 6e 64 72 79 20 3d 20 73 74 nt nBoundry = st
3760: 72 6c 65 6e 28 7a 42 6f 75 6e 64 72 79 29 3b 0a rlen(zBoundry);.
3770: 20 20 2a 70 6e 43 6f 6e 74 65 6e 74 20 3d 20 6c *pnContent = l
3780: 65 6e 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 69 en;. for(i=0; i
3790: 3c 6c 65 6e 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 <len; i++){.
37a0: 69 66 28 20 7a 5b 69 5d 3d 3d 27 5c 6e 27 20 26 if( z[i]=='\n' &
37b0: 26 20 73 74 72 6e 63 6d 70 28 7a 42 6f 75 6e 64 & strncmp(zBound
37c0: 72 79 2c 20 26 7a 5b 69 2b 31 5d 2c 20 6e 42 6f ry, &z[i+1], nBo
37d0: 75 6e 64 72 79 29 3d 3d 30 20 29 7b 0a 20 20 20 undry)==0 ){.
37e0: 20 20 20 69 66 28 20 69 3e 30 20 26 26 20 7a 5b if( i>0 && z[
37f0: 69 2d 31 5d 3d 3d 27 5c 72 27 20 29 20 69 2d 2d i-1]=='\r' ) i--
3800: 3b 0a 20 20 20 20 20 20 7a 5b 69 5d 20 3d 20 30 ;. z[i] = 0
3810: 3b 0a 20 20 20 20 20 20 2a 70 6e 43 6f 6e 74 65 ;. *pnConte
3820: 6e 74 20 3d 20 69 3b 0a 20 20 20 20 20 20 69 20 nt = i;. i
3830: 2b 3d 20 6e 42 6f 75 6e 64 72 79 3b 0a 20 20 20 += nBoundry;.
3840: 20 20 20 62 72 65 61 6b 3b 0a 20 20 20 20 7d 0a break;. }.
3850: 20 20 7d 0a 20 20 2a 70 7a 20 3d 20 26 7a 5b 69 }. *pz = &z[i
3860: 5d 3b 0a 20 20 67 65 74 5f 6c 69 6e 65 5f 66 72 ];. get_line_fr
3870: 6f 6d 5f 73 74 72 69 6e 67 28 70 7a 2c 20 70 4c om_string(pz, pL
3880: 65 6e 29 3b 0a 20 20 72 65 74 75 72 6e 20 7a 3b en);. return z;
3890: 20 20 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 .}../*.**
38a0: 54 6f 6b 65 6e 69 7a 65 20 61 20 6c 69 6e 65 20 Tokenize a line
38b0: 6f 66 20 74 65 78 74 20 69 6e 74 6f 20 61 73 20 of text into as
38c0: 6d 61 6e 79 20 61 73 20 6e 41 72 67 20 74 6f 6b many as nArg tok
38d0: 65 6e 73 2e 20 20 4d 61 6b 65 0a 2a 2a 20 61 7a ens. Make.** az
38e0: 41 72 67 5b 5d 20 70 6f 69 6e 74 20 74 6f 20 74 Arg[] point to t
38f0: 68 65 20 73 74 61 72 74 20 6f 66 20 65 61 63 68 he start of each
3900: 20 74 6f 6b 65 6e 2e 0a 2a 2a 0a 2a 2a 20 54 6f token..**.** To
3910: 6b 65 6e 73 20 63 6f 6e 73 69 73 74 20 6f 66 20 kens consist of
3920: 73 70 61 63 65 20 6f 72 20 73 65 6d 69 2d 63 6f space or semi-co
3930: 6c 6f 6e 20 64 65 6c 69 6d 69 74 65 64 20 77 6f lon delimited wo
3940: 72 64 73 20 6f 72 0a 2a 2a 20 73 74 72 69 6e 67 rds or.** string
3950: 73 20 69 6e 73 69 64 65 20 64 6f 75 62 6c 65 2d s inside double-
3960: 71 75 6f 74 65 73 2e 20 20 45 78 61 6d 70 6c 65 quotes. Example
3970: 3a 0a 2a 2a 0a 2a 2a 20 20 20 20 63 6f 6e 74 65 :.**.** conte
3980: 6e 74 2d 64 69 73 70 6f 73 69 74 69 6f 6e 3a 20 nt-disposition:
3990: 66 6f 72 6d 2d 64 61 74 61 3b 20 6e 61 6d 65 3d form-data; name=
39a0: 22 66 6e 22 3b 20 66 69 6c 65 6e 61 6d 65 3d 22 "fn"; filename="
39b0: 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a 0a 2a index.html".**.*
39c0: 2a 20 54 68 65 20 6c 69 6e 65 20 61 62 6f 76 65 * The line above
39d0: 20 69 73 20 74 6f 6b 65 6e 69 7a 65 64 20 61 73 is tokenized as
39e0: 20 66 6f 6c 6c 6f 77 73 3a 0a 2a 2a 0a 2a 2a 20 follows:.**.**
39f0: 20 20 20 61 7a 41 72 67 5b 30 5d 20 3d 20 22 63 azArg[0] = "c
3a00: 6f 6e 74 65 6e 74 2d 64 69 73 70 6f 73 69 74 69 ontent-dispositi
3a10: 6f 6e 3a 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 on:".** azArg
3a20: 5b 31 5d 20 3d 20 22 66 6f 72 6d 2d 64 61 74 61 [1] = "form-data
3a30: 22 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 32 5d ".** azArg[2]
3a40: 20 3d 20 22 6e 61 6d 65 3d 22 0a 2a 2a 20 20 20 = "name=".**
3a50: 20 61 7a 41 72 67 5b 33 5d 20 3d 20 22 66 6e 22 azArg[3] = "fn"
3a60: 0a 2a 2a 20 20 20 20 61 7a 41 72 67 5b 34 5d 20 .** azArg[4]
3a70: 3d 20 22 66 69 6c 65 6e 61 6d 65 3d 22 0a 2a 2a = "filename=".**
3a80: 20 20 20 20 61 7a 41 72 67 5b 35 5d 20 3d 20 22 azArg[5] = "
3a90: 69 6e 64 65 78 2e 68 74 6d 6c 22 0a 2a 2a 20 20 index.html".**
3aa0: 20 20 61 7a 41 72 67 5b 36 5d 20 3d 20 30 3b 0a azArg[6] = 0;.
3ab0: 2a 2a 0a 2a 2a 20 27 5c 30 30 30 27 20 63 68 61 **.** '\000' cha
3ac0: 72 61 63 74 65 72 73 20 61 72 65 20 69 6e 73 65 racters are inse
3ad0: 72 74 65 64 20 69 6e 20 7a 5b 5d 20 61 74 20 74 rted in z[] at t
3ae0: 68 65 20 65 6e 64 20 6f 66 20 65 61 63 68 20 74 he end of each t
3af0: 6f 6b 65 6e 2e 0a 2a 2a 20 54 68 69 73 20 72 6f oken..** This ro
3b00: 75 74 69 6e 65 20 72 65 74 75 72 6e 73 20 74 68 utine returns th
3b10: 65 20 74 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f e total number o
3b20: 66 20 74 6f 6b 65 6e 73 20 6f 6e 20 74 68 65 20 f tokens on the
3b30: 6c 69 6e 65 2c 20 36 0a 2a 2a 20 69 6e 20 74 68 line, 6.** in th
3b40: 65 20 65 78 61 6d 70 6c 65 20 61 62 6f 76 65 2e e example above.
3b50: 0a 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 74 .*/.static int t
3b60: 6f 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 63 68 61 okenize_line(cha
3b70: 72 20 2a 7a 2c 20 69 6e 74 20 6d 78 41 72 67 2c r *z, int mxArg,
3b80: 20 63 68 61 72 20 2a 2a 61 7a 41 72 67 29 7b 0a char **azArg){.
3b90: 20 20 69 6e 74 20 69 20 3d 20 30 3b 0a 20 20 77 int i = 0;. w
3ba0: 68 69 6c 65 28 20 2a 7a 20 29 7b 0a 20 20 20 20 hile( *z ){.
3bb0: 77 68 69 6c 65 28 20 69 73 73 70 61 63 65 28 2a while( isspace(*
3bc0: 7a 29 20 7c 7c 20 2a 7a 3d 3d 27 3b 27 20 29 7b z) || *z==';' ){
3bd0: 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 69 66 28 20 z++; }. if(
3be0: 2a 7a 3d 3d 27 22 27 20 26 26 20 7a 5b 31 5d 20 *z=='"' && z[1]
3bf0: 29 7b 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b ){. *z = 0;
3c00: 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 . z++;.
3c10: 20 20 69 66 28 20 69 3c 6d 78 41 72 67 2d 31 20 if( i<mxArg-1
3c20: 29 7b 20 61 7a 41 72 67 5b 69 2b 2b 5d 20 3d 20 ){ azArg[i++] =
3c30: 7a 3b 20 7d 0a 20 20 20 20 20 20 77 68 69 6c 65 z; }. while
3c40: 28 20 2a 7a 20 26 26 20 2a 7a 21 3d 27 22 27 20 ( *z && *z!='"'
3c50: 29 7b 20 7a 2b 2b 3b 20 7d 0a 20 20 20 20 20 20 ){ z++; }.
3c60: 69 66 28 20 2a 7a 3d 3d 30 20 29 20 62 72 65 61 if( *z==0 ) brea
3c70: 6b 3b 0a 20 20 20 20 20 20 2a 7a 20 3d 20 30 3b k;. *z = 0;
3c80: 0a 20 20 20 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 . z++;.
3c90: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 69 66 28 }else{. if(
3ca0: 20 69 3c 6d 78 41 72 67 2d 31 20 29 7b 20 61 7a i<mxArg-1 ){ az
3cb0: 41 72 67 5b 69 2b 2b 5d 20 3d 20 7a 3b 20 7d 0a Arg[i++] = z; }.
3cc0: 20 20 20 20 20 20 77 68 69 6c 65 28 20 2a 7a 20 while( *z
3cd0: 26 26 20 21 69 73 73 70 61 63 65 28 2a 7a 29 20 && !isspace(*z)
3ce0: 26 26 20 2a 7a 21 3d 27 3b 27 20 26 26 20 2a 7a && *z!=';' && *z
3cf0: 21 3d 27 22 27 20 29 7b 20 7a 2b 2b 3b 20 7d 0a !='"' ){ z++; }.
3d00: 20 20 20 20 20 20 69 66 28 20 2a 7a 20 26 26 20 if( *z &&
3d10: 2a 7a 21 3d 27 22 27 20 29 7b 0a 20 20 20 20 20 *z!='"' ){.
3d20: 20 20 20 2a 7a 20 3d 20 30 3b 0a 20 20 20 20 20 *z = 0;.
3d30: 20 20 20 7a 2b 2b 3b 0a 20 20 20 20 20 20 7d 0a z++;. }.
3d40: 20 20 20 20 7d 0a 20 20 7d 0a 20 20 61 7a 41 72 }. }. azAr
3d50: 67 5b 69 5d 20 3d 20 30 3b 0a 20 20 72 65 74 75 g[i] = 0;. retu
3d60: 72 6e 20 69 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 53 rn i;.}../*.** S
3d70: 63 61 6e 20 74 68 65 20 6d 75 6c 74 69 70 61 72 can the multipar
3d80: 74 2d 66 6f 72 6d 20 63 6f 6e 74 65 6e 74 20 61 t-form content a
3d90: 6e 64 20 6d 61 6b 65 20 61 70 70 72 6f 70 72 69 nd make appropri
3da0: 61 74 65 20 65 6e 74 72 69 65 73 0a 2a 2a 20 69 ate entries.** i
3db0: 6e 74 6f 20 74 68 65 20 70 61 72 61 6d 65 74 65 nto the paramete
3dc0: 72 20 74 61 62 6c 65 2e 0a 2a 2a 0a 2a 2a 20 54 r table..**.** T
3dd0: 68 65 20 63 6f 6e 74 65 6e 74 20 73 74 72 69 6e he content strin
3de0: 67 20 22 7a 22 20 69 73 20 6d 6f 64 69 66 69 65 g "z" is modifie
3df0: 64 20 62 79 20 74 68 69 73 20 72 6f 75 74 69 6e d by this routin
3e00: 65 20 62 75 74 20 69 74 20 69 73 0a 2a 2a 20 6e e but it is.** n
3e10: 6f 74 20 63 6f 70 69 65 64 2e 20 20 54 68 65 20 ot copied. The
3e20: 63 61 6c 6c 69 6e 67 20 66 75 6e 63 74 69 6f 6e calling function
3e30: 20 6d 75 73 74 20 6e 6f 74 20 64 65 61 6c 6c 6f must not deallo
3e40: 63 61 74 65 20 6f 72 20 6d 6f 64 69 66 79 0a 2a cate or modify.*
3e50: 2a 20 22 7a 22 20 61 66 74 65 72 20 74 68 69 73 * "z" after this
3e60: 20 72 6f 75 74 69 6e 65 20 66 69 6e 69 73 68 65 routine finishe
3e70: 73 20 6f 72 20 69 74 20 63 6f 75 6c 64 20 63 6f s or it could co
3e80: 72 72 75 70 74 20 74 68 65 20 70 61 72 61 6d 65 rrupt the parame
3e90: 74 65 72 0a 2a 2a 20 74 61 62 6c 65 2e 0a 2a 2f ter.** table..*/
3ea0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 70 72 6f .static void pro
3eb0: 63 65 73 73 5f 6d 75 6c 74 69 70 61 72 74 5f 66 cess_multipart_f
3ec0: 6f 72 6d 5f 64 61 74 61 28 63 68 61 72 20 2a 7a orm_data(char *z
3ed0: 2c 20 69 6e 74 20 6c 65 6e 29 7b 0a 20 20 63 68 , int len){. ch
3ee0: 61 72 20 2a 7a 4c 69 6e 65 3b 0a 20 20 69 6e 74 ar *zLine;. int
3ef0: 20 6e 41 72 67 2c 20 69 3b 0a 20 20 63 68 61 72 nArg, i;. char
3f00: 20 2a 7a 42 6f 75 6e 64 72 79 3b 0a 20 20 63 68 *zBoundry;. ch
3f10: 61 72 20 2a 7a 56 61 6c 75 65 3b 0a 20 20 63 68 ar *zValue;. ch
3f20: 61 72 20 2a 7a 4e 61 6d 65 20 3d 20 30 3b 0a 20 ar *zName = 0;.
3f30: 20 69 6e 74 20 73 68 6f 77 42 79 74 65 73 20 3d int showBytes =
3f40: 20 30 3b 0a 20 20 63 68 61 72 20 2a 61 7a 41 72 0;. char *azAr
3f50: 67 5b 35 30 5d 3b 0a 0a 20 20 7a 42 6f 75 6e 64 g[50];.. zBound
3f60: 72 79 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 72 ry = get_line_fr
3f70: 6f 6d 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 6c om_string(&z, &l
3f80: 65 6e 29 3b 0a 20 20 69 66 28 20 7a 42 6f 75 6e en);. if( zBoun
3f90: 64 72 79 3d 3d 30 20 29 20 72 65 74 75 72 6e 3b dry==0 ) return;
3fa0: 0a 20 20 77 68 69 6c 65 28 20 28 7a 4c 69 6e 65 . while( (zLine
3fb0: 20 3d 20 67 65 74 5f 6c 69 6e 65 5f 66 72 6f 6d = get_line_from
3fc0: 5f 73 74 72 69 6e 67 28 26 7a 2c 20 26 6c 65 6e _string(&z, &len
3fd0: 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 28 ))!=0 ){. if(
3fe0: 20 7a 4c 69 6e 65 5b 30 5d 3d 3d 30 20 29 7b 0a zLine[0]==0 ){.
3ff0: 20 20 20 20 20 20 69 6e 74 20 6e 43 6f 6e 74 65 int nConte
4000: 6e 74 20 3d 20 30 3b 0a 20 20 20 20 20 20 7a 56 nt = 0;. zV
4010: 61 6c 75 65 20 3d 20 67 65 74 5f 62 6f 75 6e 64 alue = get_bound
4020: 65 64 5f 63 6f 6e 74 65 6e 74 28 26 7a 2c 20 26 ed_content(&z, &
4030: 6c 65 6e 2c 20 7a 42 6f 75 6e 64 72 79 2c 20 26 len, zBoundry, &
4040: 6e 43 6f 6e 74 65 6e 74 29 3b 0a 20 20 20 20 20 nContent);.
4050: 20 69 66 28 20 7a 4e 61 6d 65 20 26 26 20 7a 56 if( zName && zV
4060: 61 6c 75 65 20 26 26 20 69 73 6c 6f 77 65 72 28 alue && islower(
4070: 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 zName[0]) ){.
4080: 20 20 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 cgi_set_par
4090: 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e ameter_nocopy(zN
40a0: 61 6d 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20 ame, zValue);.
40b0: 20 20 20 20 20 20 69 66 28 20 73 68 6f 77 42 79 if( showBy
40c0: 74 65 73 20 29 7b 0a 20 20 20 20 20 20 20 20 20 tes ){.
40d0: 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 cgi_set_paramet
40e0: 65 72 5f 6e 6f 63 6f 70 79 28 6d 70 72 69 6e 74 er_nocopy(mprint
40f0: 66 28 22 25 73 3a 62 79 74 65 73 22 2c 20 7a 4e f("%s:bytes", zN
4100: 61 6d 65 29 2c 0a 20 20 20 20 20 20 20 20 20 20 ame),.
4110: 20 20 20 20 20 6d 70 72 69 6e 74 66 28 22 25 64 mprintf("%d
4120: 22 2c 6e 43 6f 6e 74 65 6e 74 29 29 3b 0a 20 20 ",nContent));.
4130: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a }. }.
4140: 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 30 3b zName = 0;
4150: 0a 20 20 20 20 20 20 73 68 6f 77 42 79 74 65 73 . showBytes
4160: 20 3d 20 30 3b 0a 20 20 20 20 7d 65 6c 73 65 7b = 0;. }else{
4170: 0a 20 20 20 20 20 20 6e 41 72 67 20 3d 20 74 6f . nArg = to
4180: 6b 65 6e 69 7a 65 5f 6c 69 6e 65 28 7a 4c 69 6e kenize_line(zLin
4190: 65 2c 20 73 69 7a 65 6f 66 28 61 7a 41 72 67 29 e, sizeof(azArg)
41a0: 2f 73 69 7a 65 6f 66 28 61 7a 41 72 67 5b 30 5d /sizeof(azArg[0]
41b0: 29 2c 20 61 7a 41 72 67 29 3b 0a 20 20 20 20 20 ), azArg);.
41c0: 20 66 6f 72 28 69 3d 30 3b 20 69 3c 6e 41 72 67 for(i=0; i<nArg
41d0: 3b 20 69 2b 2b 29 7b 0a 20 20 20 20 20 20 20 20 ; i++){.
41e0: 69 6e 74 20 63 20 3d 20 74 6f 6c 6f 77 65 72 28 int c = tolower(
41f0: 61 7a 41 72 67 5b 69 5d 5b 30 5d 29 3b 0a 20 20 azArg[i][0]);.
4200: 20 20 20 20 20 20 69 66 28 20 63 3d 3d 27 63 27 if( c=='c'
4210: 20 26 26 20 73 74 72 69 63 6d 70 28 61 7a 41 72 && stricmp(azAr
4220: 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d 64 69 g[i],"content-di
4230: 73 70 6f 73 69 74 69 6f 6e 3a 22 29 3d 3d 30 20 sposition:")==0
4240: 29 7b 0a 20 20 20 20 20 20 20 20 20 20 69 2b 2b ){. i++
4250: 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 20 ;. }else
4260: 69 66 28 20 63 3d 3d 27 6e 27 20 26 26 20 73 74 if( c=='n' && st
4270: 72 69 63 6d 70 28 61 7a 41 72 67 5b 69 5d 2c 22 ricmp(azArg[i],"
4280: 6e 61 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a 20 20 name=")==0 ){.
4290: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 20 3d 20 zName =
42a0: 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 azArg[++i];.
42b0: 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 63 3d }else if( c=
42c0: 3d 27 66 27 20 26 26 20 73 74 72 69 63 6d 70 28 ='f' && stricmp(
42d0: 61 7a 41 72 67 5b 69 5d 2c 22 66 69 6c 65 6e 61 azArg[i],"filena
42e0: 6d 65 3d 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 me=")==0 ){.
42f0: 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20 3d 20 char *z =
4300: 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 20 azArg[++i];.
4310: 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 20 if( zName
4320: 26 26 20 7a 20 26 26 20 69 73 6c 6f 77 65 72 28 && z && islower(
4330: 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 20 zName[0]) ){.
4340: 20 20 20 20 20 20 20 20 20 63 67 69 5f 73 65 74 cgi_set
4350: 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f 70 _parameter_nocop
4360: 79 28 6d 70 72 69 6e 74 66 28 22 25 73 3a 66 69 y(mprintf("%s:fi
4370: 6c 65 6e 61 6d 65 22 2c 7a 4e 61 6d 65 29 2c 20 lename",zName),
4380: 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a z);. }.
4390: 20 20 20 20 20 20 20 20 20 20 73 68 6f 77 42 79 showBy
43a0: 74 65 73 20 3d 20 31 3b 0a 20 20 20 20 20 20 20 tes = 1;.
43b0: 20 7d 65 6c 73 65 20 69 66 28 20 63 3d 3d 27 63 }else if( c=='c
43c0: 27 20 26 26 20 73 74 72 69 63 6d 70 28 61 7a 41 ' && stricmp(azA
43d0: 72 67 5b 69 5d 2c 22 63 6f 6e 74 65 6e 74 2d 74 rg[i],"content-t
43e0: 79 70 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 ype:")==0 ){.
43f0: 20 20 20 20 20 20 20 63 68 61 72 20 2a 7a 20 3d char *z =
4400: 20 61 7a 41 72 67 5b 2b 2b 69 5d 3b 0a 20 20 20 azArg[++i];.
4410: 20 20 20 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 if( zName
4420: 20 26 26 20 7a 20 26 26 20 69 73 6c 6f 77 65 72 && z && islower
4430: 28 7a 4e 61 6d 65 5b 30 5d 29 20 29 7b 0a 20 20 (zName[0]) ){.
4440: 20 20 20 20 20 20 20 20 20 20 63 67 69 5f 73 65 cgi_se
4450: 74 5f 70 61 72 61 6d 65 74 65 72 5f 6e 6f 63 6f t_parameter_noco
4460: 70 79 28 6d 70 72 69 6e 74 66 28 22 25 73 3a 6d py(mprintf("%s:m
4470: 69 6d 65 74 79 70 65 22 2c 7a 4e 61 6d 65 29 2c imetype",zName),
4480: 20 7a 29 3b 0a 20 20 20 20 20 20 20 20 20 20 7d z);. }
4490: 0a 20 20 20 20 20 20 20 20 7d 0a 20 20 20 20 20 . }.
44a0: 20 7d 0a 20 20 20 20 7d 0a 20 20 7d 20 20 20 20 }. }. }
44b0: 20 20 20 20 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 49 6e .}../*.** In
44c0: 69 74 69 61 6c 69 7a 65 20 74 68 65 20 71 75 65 itialize the que
44d0: 72 79 20 70 61 72 61 6d 65 74 65 72 20 64 61 74 ry parameter dat
44e0: 61 62 61 73 65 2e 20 20 49 6e 66 6f 72 6d 61 74 abase. Informat
44f0: 69 6f 6e 20 69 73 20 70 75 6c 6c 65 64 20 66 72 ion is pulled fr
4500: 6f 6d 0a 2a 2a 20 74 68 65 20 51 55 45 52 59 5f om.** the QUERY_
4510: 53 54 52 49 4e 47 20 65 6e 76 69 72 6f 6e 6d 65 STRING environme
4520: 6e 74 20 76 61 72 69 61 62 6c 65 20 28 69 66 20 nt variable (if
4530: 69 74 20 65 78 69 73 74 73 29 2c 20 66 72 6f 6d it exists), from
4540: 20 73 74 61 6e 64 61 72 64 0a 2a 2a 20 69 6e 70 standard.** inp
4550: 75 74 20 69 66 20 74 68 65 72 65 20 69 73 20 50 ut if there is P
4560: 4f 53 54 20 64 61 74 61 2c 20 61 6e 64 20 66 72 OST data, and fr
4570: 6f 6d 20 48 54 54 50 5f 43 4f 4f 4b 49 45 2e 0a om HTTP_COOKIE..
4580: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 69 6e 69 74 */.void cgi_init
4590: 28 76 6f 69 64 29 7b 0a 20 20 63 68 61 72 20 2a (void){. char *
45a0: 7a 3b 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 z;. const char
45b0: 2a 7a 54 79 70 65 3b 0a 20 20 69 6e 74 20 6c 65 *zType;. int le
45c0: 6e 3b 0a 20 20 7a 20 3d 20 28 63 68 61 72 2a 29 n;. z = (char*)
45d0: 50 28 22 51 55 45 52 59 5f 53 54 52 49 4e 47 22 P("QUERY_STRING"
45e0: 29 3b 0a 20 20 69 66 28 20 7a 20 29 7b 0a 20 20 );. if( z ){.
45f0: 20 20 7a 20 3d 20 6d 70 72 69 6e 74 66 28 22 25 z = mprintf("%
4600: 73 22 2c 7a 29 3b 0a 20 20 20 20 61 64 64 5f 70 s",z);. add_p
4610: 61 72 61 6d 5f 6c 69 73 74 28 7a 2c 20 27 26 27 aram_list(z, '&'
4620: 29 3b 0a 20 20 7d 0a 0a 20 20 6c 65 6e 20 3d 20 );. }.. len =
4630: 61 74 6f 69 28 50 44 28 22 43 4f 4e 54 45 4e 54 atoi(PD("CONTENT
4640: 5f 4c 45 4e 47 54 48 22 2c 20 22 30 22 29 29 3b _LENGTH", "0"));
4650: 0a 20 20 67 2e 7a 43 6f 6e 74 65 6e 74 54 79 70 . g.zContentTyp
4660: 65 20 3d 20 7a 54 79 70 65 20 3d 20 50 28 22 43 e = zType = P("C
4670: 4f 4e 54 45 4e 54 5f 54 59 50 45 22 29 3b 0a 20 ONTENT_TYPE");.
4680: 20 69 66 28 20 6c 65 6e 3e 30 20 26 26 20 7a 54 if( len>0 && zT
4690: 79 70 65 20 29 7b 0a 20 20 20 20 62 6c 6f 62 5f ype ){. blob_
46a0: 7a 65 72 6f 28 26 67 2e 63 67 69 49 6e 29 3b 0a zero(&g.cgiIn);.
46b0: 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 7a if( strcmp(z
46c0: 54 79 70 65 2c 22 61 70 70 6c 69 63 61 74 69 6f Type,"applicatio
46d0: 6e 2f 78 2d 77 77 77 2d 66 6f 72 6d 2d 75 72 6c n/x-www-form-url
46e0: 65 6e 63 6f 64 65 64 22 29 3d 3d 30 20 0a 20 20 encoded")==0 .
46f0: 20 20 20 20 20 20 20 7c 7c 20 73 74 72 6e 63 6d || strncm
4700: 70 28 7a 54 79 70 65 2c 22 6d 75 6c 74 69 70 61 p(zType,"multipa
4710: 72 74 2f 66 6f 72 6d 2d 64 61 74 61 22 2c 31 39 rt/form-data",19
4720: 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 7a 20 )==0 ){. z
4730: 3d 20 6d 61 6c 6c 6f 63 28 20 6c 65 6e 2b 31 20 = malloc( len+1
4740: 29 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 3d 3d );. if( z==
4750: 30 20 29 20 65 78 69 74 28 31 29 3b 0a 20 20 20 0 ) exit(1);.
4760: 20 20 20 6c 65 6e 20 3d 20 66 72 65 61 64 28 7a len = fread(z
4770: 2c 20 31 2c 20 6c 65 6e 2c 20 73 74 64 69 6e 29 , 1, len, stdin)
4780: 3b 0a 20 20 20 20 20 20 7a 5b 6c 65 6e 5d 20 3d ;. z[len] =
4790: 20 30 3b 0a 20 20 20 20 20 20 69 66 28 20 7a 54 0;. if( zT
47a0: 79 70 65 5b 30 5d 3d 3d 27 61 27 20 29 7b 0a 20 ype[0]=='a' ){.
47b0: 20 20 20 20 20 20 20 61 64 64 5f 70 61 72 61 6d add_param
47c0: 5f 6c 69 73 74 28 7a 2c 20 27 26 27 29 3b 0a 20 _list(z, '&');.
47d0: 20 20 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 }else{.
47e0: 20 20 20 20 70 72 6f 63 65 73 73 5f 6d 75 6c 74 process_mult
47f0: 69 70 61 72 74 5f 66 6f 72 6d 5f 64 61 74 61 28 ipart_form_data(
4800: 7a 2c 20 6c 65 6e 29 3b 0a 20 20 20 20 20 20 7d z, len);. }
4810: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 . }else if( s
4820: 74 72 63 6d 70 28 7a 54 79 70 65 2c 20 22 61 70 trcmp(zType, "ap
4830: 70 6c 69 63 61 74 69 6f 6e 2f 78 2d 66 6f 73 73 plication/x-foss
4840: 69 6c 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 il")==0 ){.
4850: 20 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f blob_read_from_
4860: 63 68 61 6e 6e 65 6c 28 26 67 2e 63 67 69 49 6e channel(&g.cgiIn
4870: 2c 20 73 74 64 69 6e 2c 20 6c 65 6e 29 3b 0a 20 , stdin, len);.
4880: 20 20 20 20 20 62 6c 6f 62 5f 75 6e 63 6f 6d 70 blob_uncomp
4890: 72 65 73 73 28 26 67 2e 63 67 69 49 6e 2c 20 26 ress(&g.cgiIn, &
48a0: 67 2e 63 67 69 49 6e 29 3b 0a 20 20 20 20 7d 65 g.cgiIn);. }e
48b0: 6c 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a lse if( strcmp(z
48c0: 54 79 70 65 2c 20 22 61 70 70 6c 69 63 61 74 69 Type, "applicati
48d0: 6f 6e 2f 78 2d 66 6f 73 73 69 6c 2d 64 65 62 75 on/x-fossil-debu
48e0: 67 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 g")==0 ){.
48f0: 62 6c 6f 62 5f 72 65 61 64 5f 66 72 6f 6d 5f 63 blob_read_from_c
4900: 68 61 6e 6e 65 6c 28 26 67 2e 63 67 69 49 6e 2c hannel(&g.cgiIn,
4910: 20 73 74 64 69 6e 2c 20 6c 65 6e 29 3b 0a 20 20 stdin, len);.
4920: 20 20 7d 0a 20 20 7d 0a 0a 20 20 7a 20 3d 20 28 }. }.. z = (
4930: 63 68 61 72 2a 29 50 28 22 48 54 54 50 5f 43 4f char*)P("HTTP_CO
4940: 4f 4b 49 45 22 29 3b 0a 20 20 69 66 28 20 7a 20 OKIE");. if( z
4950: 29 7b 0a 20 20 20 20 7a 20 3d 20 6d 70 72 69 6e ){. z = mprin
4960: 74 66 28 22 25 73 22 2c 7a 29 3b 0a 20 20 20 20 tf("%s",z);.
4970: 61 64 64 5f 70 61 72 61 6d 5f 6c 69 73 74 28 7a add_param_list(z
4980: 2c 20 27 3b 27 29 3b 0a 20 20 7d 0a 7d 0a 0a 2f , ';');. }.}../
4990: 2a 0a 2a 2a 20 54 68 69 73 20 69 73 20 74 68 65 *.** This is the
49a0: 20 63 6f 6d 70 61 72 69 73 6f 6e 20 66 75 6e 63 comparison func
49b0: 74 69 6f 6e 20 75 73 65 64 20 74 6f 20 73 6f 72 tion used to sor
49c0: 74 20 74 68 65 20 61 50 61 72 61 6d 51 50 5b 5d t the aParamQP[]
49d0: 20 61 72 72 61 79 20 6f 66 0a 2a 2a 20 71 75 65 array of.** que
49e0: 72 79 20 70 61 72 61 6d 65 74 65 72 73 20 61 6e ry parameters an
49f0: 64 20 63 6f 6f 6b 69 65 73 2e 0a 2a 2f 0a 73 74 d cookies..*/.st
4a00: 61 74 69 63 20 69 6e 74 20 71 70 61 72 61 6d 5f atic int qparam_
4a10: 63 6f 6d 70 61 72 65 28 63 6f 6e 73 74 20 76 6f compare(const vo
4a20: 69 64 20 2a 61 2c 20 63 6f 6e 73 74 20 76 6f 69 id *a, const voi
4a30: 64 20 2a 62 29 7b 0a 20 20 73 74 72 75 63 74 20 d *b){. struct
4a40: 51 50 61 72 61 6d 20 2a 70 41 20 3d 20 28 73 74 QParam *pA = (st
4a50: 72 75 63 74 20 51 50 61 72 61 6d 2a 29 61 3b 0a ruct QParam*)a;.
4a60: 20 20 73 74 72 75 63 74 20 51 50 61 72 61 6d 20 struct QParam
4a70: 2a 70 42 20 3d 20 28 73 74 72 75 63 74 20 51 50 *pB = (struct QP
4a80: 61 72 61 6d 2a 29 62 3b 0a 20 20 69 6e 74 20 63 aram*)b;. int c
4a90: 3b 0a 20 20 63 20 3d 20 73 74 72 63 6d 70 28 70 ;. c = strcmp(p
4aa0: 41 2d 3e 7a 4e 61 6d 65 2c 20 70 42 2d 3e 7a 4e A->zName, pB->zN
4ab0: 61 6d 65 29 3b 0a 20 20 69 66 28 20 63 3d 3d 30 ame);. if( c==0
4ac0: 20 29 7b 0a 20 20 20 20 63 20 3d 20 70 41 2d 3e ){. c = pA->
4ad0: 73 65 71 20 2d 20 70 42 2d 3e 73 65 71 3b 0a 20 seq - pB->seq;.
4ae0: 20 7d 0a 20 20 72 65 74 75 72 6e 20 63 3b 0a 7d }. return c;.}
4af0: 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 74 ../*.** Return t
4b00: 68 65 20 76 61 6c 75 65 20 6f 66 20 61 20 71 75 he value of a qu
4b10: 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f 72 ery parameter or
4b20: 20 63 6f 6f 6b 69 65 20 77 68 6f 73 65 20 6e 61 cookie whose na
4b30: 6d 65 20 69 73 20 7a 4e 61 6d 65 2e 0a 2a 2a 20 me is zName..**
4b40: 49 66 20 74 68 65 72 65 20 69 73 20 6e 6f 20 71 If there is no q
4b50: 75 65 72 79 20 70 61 72 61 6d 65 74 65 72 20 6f uery parameter o
4b60: 72 20 63 6f 6f 6b 69 65 20 6e 61 6d 65 64 20 7a r cookie named z
4b70: 4e 61 6d 65 20 61 6e 64 20 74 68 65 20 66 69 72 Name and the fir
4b80: 73 74 0a 2a 2a 20 63 68 61 72 61 63 74 65 72 20 st.** character
4b90: 6f 66 20 7a 4e 61 6d 65 20 69 73 20 75 70 70 65 of zName is uppe
4ba0: 72 63 61 73 65 2c 20 74 68 65 6e 20 63 68 65 63 rcase, then chec
4bb0: 6b 20 74 6f 20 73 65 65 20 69 66 20 74 68 65 72 k to see if ther
4bc0: 65 20 69 73 20 61 6e 0a 2a 2a 20 65 6e 76 69 72 e is an.** envir
4bd0: 6f 6e 6d 65 6e 74 20 76 61 72 69 61 62 6c 65 20 onment variable
4be0: 62 79 20 74 68 61 74 20 6e 61 6d 65 20 61 6e 64 by that name and
4bf0: 20 72 65 74 75 72 6e 20 69 74 20 69 66 20 74 68 return it if th
4c00: 65 72 65 20 69 73 2e 20 20 41 73 0a 2a 2a 20 61 ere is. As.** a
4c10: 20 6c 61 73 74 20 72 65 73 6f 72 74 20 77 68 65 last resort whe
4c20: 6e 20 6e 6f 74 68 69 6e 67 20 65 6c 73 65 20 6d n nothing else m
4c30: 61 74 63 68 65 73 2c 20 72 65 74 75 72 6e 20 7a atches, return z
4c40: 44 65 66 61 75 6c 74 2e 0a 2a 2f 0a 63 6f 6e 73 Default..*/.cons
4c50: 74 20 63 68 61 72 20 2a 63 67 69 5f 70 61 72 61 t char *cgi_para
4c60: 6d 65 74 65 72 28 63 6f 6e 73 74 20 63 68 61 72 meter(const char
4c70: 20 2a 7a 4e 61 6d 65 2c 20 63 6f 6e 73 74 20 63 *zName, const c
4c80: 68 61 72 20 2a 7a 44 65 66 61 75 6c 74 29 7b 0a har *zDefault){.
4c90: 20 20 69 6e 74 20 6c 6f 2c 20 68 69 2c 20 6d 69 int lo, hi, mi
4ca0: 64 2c 20 63 3b 0a 0a 20 20 2f 2a 20 54 68 65 20 d, c;.. /* The
4cb0: 73 6f 72 74 51 50 20 66 6c 61 67 20 69 73 20 73 sortQP flag is s
4cc0: 65 74 20 77 68 65 6e 65 76 65 72 20 61 20 6e 65 et whenever a ne
4cd0: 77 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 65 w query paramete
4ce0: 72 20 69 73 20 69 6e 73 65 72 74 65 64 2e 0a 20 r is inserted..
4cf0: 20 2a 2a 20 49 74 20 69 6e 64 69 63 61 74 65 73 ** It indicates
4d00: 20 74 68 61 74 20 77 65 20 6e 65 65 64 20 74 6f that we need to
4d10: 20 72 65 73 6f 72 74 20 74 68 65 20 71 75 65 72 resort the quer
4d20: 79 20 70 61 72 61 6d 65 74 65 72 73 2e 0a 20 20 y parameters..
4d30: 2a 2f 0a 20 20 69 66 28 20 73 6f 72 74 51 50 20 */. if( sortQP
4d40: 29 7b 0a 20 20 20 20 69 6e 74 20 69 2c 20 6a 3b ){. int i, j;
4d50: 0a 20 20 20 20 71 73 6f 72 74 28 61 50 61 72 61 . qsort(aPara
4d60: 6d 51 50 2c 20 6e 55 73 65 64 51 50 2c 20 73 69 mQP, nUsedQP, si
4d70: 7a 65 6f 66 28 61 50 61 72 61 6d 51 50 5b 30 5d zeof(aParamQP[0]
4d80: 29 2c 20 71 70 61 72 61 6d 5f 63 6f 6d 70 61 72 ), qparam_compar
4d90: 65 29 3b 0a 20 20 20 20 73 6f 72 74 51 50 20 3d e);. sortQP =
4da0: 20 30 3b 0a 20 20 20 20 2f 2a 20 41 66 74 65 72 0;. /* After
4db0: 20 73 6f 72 74 69 6e 67 2c 20 72 65 6d 6f 76 65 sorting, remove
4dc0: 20 64 75 70 6c 69 63 61 74 65 20 70 61 72 61 6d duplicate param
4dd0: 65 74 65 72 73 2e 20 20 54 68 65 20 73 65 63 6f eters. The seco
4de0: 6e 64 61 72 79 20 73 6f 72 74 0a 20 20 20 20 2a ndary sort. *
4df0: 2a 20 6b 65 79 20 69 73 20 61 50 61 72 61 6d 51 * key is aParamQ
4e00: 50 5b 5d 2e 73 65 71 20 61 6e 64 20 77 65 20 6b P[].seq and we k
4e10: 65 65 70 20 74 68 65 20 66 69 72 73 74 20 65 6e eep the first en
4e20: 74 72 79 2e 20 20 54 68 61 74 20 6d 65 61 6e 73 try. That means
4e30: 0a 20 20 20 20 2a 2a 20 77 69 74 68 20 64 75 70 . ** with dup
4e40: 6c 69 63 61 74 65 20 63 61 6c 6c 73 20 74 6f 20 licate calls to
4e50: 63 67 69 5f 73 65 74 5f 70 61 72 61 6d 65 74 65 cgi_set_paramete
4e60: 72 28 29 20 74 68 65 20 73 65 63 6f 6e 64 20 61 r() the second a
4e70: 6e 64 0a 20 20 20 20 2a 2a 20 73 75 62 73 65 71 nd. ** subseq
4e80: 75 65 6e 74 20 63 61 6c 6c 73 20 61 72 65 20 65 uent calls are e
4e90: 66 66 65 63 74 69 76 65 6c 79 20 6e 6f 2d 6f 70 ffectively no-op
4ea0: 73 2e 20 2a 2f 0a 20 20 20 20 66 6f 72 28 69 3d s. */. for(i=
4eb0: 6a 3d 31 3b 20 69 3c 6e 55 73 65 64 51 50 3b 20 j=1; i<nUsedQP;
4ec0: 69 2b 2b 29 7b 0a 20 20 20 20 20 20 69 66 28 20 i++){. if(
4ed0: 73 74 72 63 6d 70 28 61 50 61 72 61 6d 51 50 5b strcmp(aParamQP[
4ee0: 69 5d 2e 7a 4e 61 6d 65 2c 61 50 61 72 61 6d 51 i].zName,aParamQ
4ef0: 50 5b 69 2d 31 5d 2e 7a 4e 61 6d 65 29 3d 3d 30 P[i-1].zName)==0
4f00: 20 29 7b 0a 20 20 20 20 20 20 20 20 63 6f 6e 74 ){. cont
4f10: 69 6e 75 65 3b 0a 20 20 20 20 20 20 7d 0a 20 20 inue;. }.
4f20: 20 20 20 20 69 66 28 20 6a 3c 69 20 29 7b 0a 20 if( j<i ){.
4f30: 20 20 20 20 20 20 20 6d 65 6d 63 70 79 28 26 61 memcpy(&a
4f40: 50 61 72 61 6d 51 50 5b 6a 5d 2c 20 26 61 50 61 ParamQP[j], &aPa
4f50: 72 61 6d 51 50 5b 69 5d 2c 20 73 69 7a 65 6f 66 ramQP[i], sizeof
4f60: 28 61 50 61 72 61 6d 51 50 5b 6a 5d 29 29 3b 0a (aParamQP[j]));.
4f70: 20 20 20 20 20 20 7d 0a 20 20 20 20 20 20 6a 2b }. j+
4f80: 2b 3b 0a 20 20 20 20 7d 0a 20 20 20 20 6e 55 73 +;. }. nUs
4f90: 65 64 51 50 20 3d 20 6a 3b 0a 20 20 7d 0a 0a 20 edQP = j;. }..
4fa0: 20 2f 2a 20 44 6f 20 61 20 62 69 6e 61 72 79 20 /* Do a binary
4fb0: 73 65 61 72 63 68 20 66 6f 72 20 61 20 6d 61 74 search for a mat
4fc0: 63 68 69 6e 67 20 71 75 65 72 79 20 70 61 72 61 ching query para
4fd0: 6d 65 74 65 72 20 2a 2f 0a 20 20 6c 6f 20 3d 20 meter */. lo =
4fe0: 30 3b 0a 20 20 68 69 20 3d 20 6e 55 73 65 64 51 0;. hi = nUsedQ
4ff0: 50 2d 31 3b 0a 20 20 77 68 69 6c 65 28 20 6c 6f P-1;. while( lo
5000: 3c 3d 68 69 20 29 7b 0a 20 20 20 20 6d 69 64 20 <=hi ){. mid
5010: 3d 20 28 6c 6f 2b 68 69 29 2f 32 3b 0a 20 20 20 = (lo+hi)/2;.
5020: 20 63 20 3d 20 73 74 72 63 6d 70 28 61 50 61 72 c = strcmp(aPar
5030: 61 6d 51 50 5b 6d 69 64 5d 2e 7a 4e 61 6d 65 2c amQP[mid].zName,
5040: 20 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 69 66 28 zName);. if(
5050: 20 63 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 43 c==0 ){. C
5060: 47 49 44 45 42 55 47 28 28 22 6d 65 6d 2d 6d 61 GIDEBUG(("mem-ma
5070: 74 63 68 20 5b 25 73 5d 20 3d 20 5b 25 73 5d 5c tch [%s] = [%s]\
5080: 6e 22 2c 20 7a 4e 61 6d 65 2c 20 61 50 61 72 61 n", zName, aPara
5090: 6d 51 50 5b 6d 69 64 5d 2e 7a 56 61 6c 75 65 29 mQP[mid].zValue)
50a0: 29 3b 0a 20 20 20 20 20 20 72 65 74 75 72 6e 20 );. return
50b0: 61 50 61 72 61 6d 51 50 5b 6d 69 64 5d 2e 7a 56 aParamQP[mid].zV
50c0: 61 6c 75 65 3b 0a 20 20 20 20 7d 65 6c 73 65 20 alue;. }else
50d0: 69 66 28 20 63 3e 30 20 29 7b 0a 20 20 20 20 20 if( c>0 ){.
50e0: 20 68 69 20 3d 20 6d 69 64 2d 31 3b 0a 20 20 20 hi = mid-1;.
50f0: 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 6c 6f }else{. lo
5100: 20 3d 20 6d 69 64 2b 31 3b 0a 20 20 20 20 7d 0a = mid+1;. }.
5110: 20 20 7d 0a 0a 20 20 2f 2a 20 49 66 20 6e 6f 20 }.. /* If no
5120: 6d 61 74 63 68 20 69 73 20 66 6f 75 6e 64 20 61 match is found a
5130: 6e 64 20 74 68 65 20 6e 61 6d 65 20 62 65 67 69 nd the name begi
5140: 6e 73 20 77 69 74 68 20 61 6e 20 75 70 70 65 72 ns with an upper
5150: 2d 63 61 73 65 0a 20 20 2a 2a 20 6c 65 74 74 65 -case. ** lette
5160: 72 2c 20 74 68 65 6e 20 63 68 65 63 6b 20 74 6f r, then check to
5170: 20 73 65 65 20 69 66 20 74 68 65 72 65 20 69 73 see if there is
5180: 20 61 6e 20 65 6e 76 69 72 6f 6e 6d 65 6e 74 20 an environment
5190: 76 61 72 69 61 62 6c 65 0a 20 20 2a 2a 20 77 69 variable. ** wi
51a0: 74 68 20 74 68 65 20 67 69 76 65 6e 20 6e 61 6d th the given nam
51b0: 65 2e 0a 20 20 2a 2f 0a 20 20 69 66 28 20 69 73 e.. */. if( is
51c0: 75 70 70 65 72 28 7a 4e 61 6d 65 5b 30 5d 29 20 upper(zName[0])
51d0: 29 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 ){. const cha
51e0: 72 20 2a 7a 56 61 6c 75 65 20 3d 20 67 65 74 65 r *zValue = gete
51f0: 6e 76 28 7a 4e 61 6d 65 29 3b 0a 20 20 20 20 69 nv(zName);. i
5200: 66 28 20 7a 56 61 6c 75 65 20 29 7b 0a 20 20 20 f( zValue ){.
5210: 20 20 20 63 67 69 5f 73 65 74 5f 70 61 72 61 6d cgi_set_param
5220: 65 74 65 72 5f 6e 6f 63 6f 70 79 28 7a 4e 61 6d eter_nocopy(zNam
5230: 65 2c 20 7a 56 61 6c 75 65 29 3b 0a 20 20 20 20 e, zValue);.
5240: 20 20 43 47 49 44 45 42 55 47 28 28 22 65 6e 76 CGIDEBUG(("env
5250: 2d 6d 61 74 63 68 20 5b 25 73 5d 20 3d 20 5b 25 -match [%s] = [%
5260: 73 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 2c 20 7a 56 s]\n", zName, zV
5270: 61 6c 75 65 29 29 3b 0a 20 20 20 20 20 20 72 65 alue));. re
5280: 74 75 72 6e 20 7a 56 61 6c 75 65 3b 0a 20 20 20 turn zValue;.
5290: 20 7d 0a 20 20 7d 0a 20 20 43 47 49 44 45 42 55 }. }. CGIDEBU
52a0: 47 28 28 22 6e 6f 2d 6d 61 74 63 68 20 5b 25 73 G(("no-match [%s
52b0: 5d 5c 6e 22 2c 20 7a 4e 61 6d 65 29 29 3b 0a 20 ]\n", zName));.
52c0: 20 72 65 74 75 72 6e 20 7a 44 65 66 61 75 6c 74 return zDefault
52d0: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 72 69 6e 74 ;.}../*.** Print
52e0: 20 43 47 49 20 64 65 62 75 67 67 69 6e 67 20 6d CGI debugging m
52f0: 65 73 73 61 67 65 73 2e 0a 2a 2f 0a 76 6f 69 64 essages..*/.void
5300: 20 63 67 69 5f 64 65 62 75 67 28 63 6f 6e 73 74 cgi_debug(const
5310: 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c 20 char *zFormat,
5320: 2e 2e 2e 29 7b 0a 20 20 76 61 5f 6c 69 73 74 20 ...){. va_list
5330: 61 70 3b 0a 20 20 69 66 28 20 67 2e 66 44 65 62 ap;. if( g.fDeb
5340: 75 67 20 29 7b 0a 20 20 20 20 76 61 5f 73 74 61 ug ){. va_sta
5350: 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 74 29 3b rt(ap, zFormat);
5360: 0a 20 20 20 20 76 66 70 72 69 6e 74 66 28 67 2e . vfprintf(g.
5370: 66 44 65 62 75 67 2c 20 7a 46 6f 72 6d 61 74 2c fDebug, zFormat,
5380: 20 61 70 29 3b 0a 20 20 20 20 76 61 5f 65 6e 64 ap);. va_end
5390: 28 61 70 29 3b 0a 20 20 20 20 66 66 6c 75 73 68 (ap);. fflush
53a0: 28 67 2e 66 44 65 62 75 67 29 3b 0a 20 20 7d 0a (g.fDebug);. }.
53b0: 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 72 6e 20 }../*.** Return
53c0: 74 72 75 65 20 69 66 20 61 6e 79 20 6f 66 20 74 true if any of t
53d0: 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 74 he query paramet
53e0: 65 72 73 20 69 6e 20 74 68 65 20 61 72 67 75 6d ers in the argum
53f0: 65 6e 74 0a 2a 2a 20 6c 69 73 74 20 61 72 65 20 ent.** list are
5400: 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 6e 74 20 defined..*/.int
5410: 63 67 69 5f 61 6e 79 28 63 6f 6e 73 74 20 63 68 cgi_any(const ch
5420: 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a 20 20 76 ar *z, ...){. v
5430: 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 a_list ap;. cha
5440: 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 63 67 69 r *z2;. if( cgi
5450: 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c 30 29 21 _parameter(z,0)!
5460: 3d 30 20 29 20 72 65 74 75 72 6e 20 31 3b 0a 20 =0 ) return 1;.
5470: 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a 29 va_start(ap, z)
5480: 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 32 20 3d ;. while( (z2 =
5490: 20 76 61 5f 61 72 67 28 61 70 2c 20 63 68 61 72 va_arg(ap, char
54a0: 2a 29 29 21 3d 30 20 29 7b 0a 20 20 20 20 69 66 *))!=0 ){. if
54b0: 28 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 ( cgi_parameter(
54c0: 7a 32 2c 30 29 21 3d 30 20 29 20 72 65 74 75 72 z2,0)!=0 ) retur
54d0: 6e 20 31 3b 0a 20 20 7d 0a 20 20 76 61 5f 65 6e n 1;. }. va_en
54e0: 64 28 61 70 29 3b 0a 20 20 72 65 74 75 72 6e 20 d(ap);. return
54f0: 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 52 65 74 75 0;.}../*.** Retu
5500: 72 6e 20 74 72 75 65 20 69 66 20 61 6c 6c 20 6f rn true if all o
5510: 66 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 f the query para
5520: 6d 65 74 65 72 73 20 69 6e 20 74 68 65 20 61 72 meters in the ar
5530: 67 75 6d 65 6e 74 20 6c 69 73 74 0a 2a 2a 20 61 gument list.** a
5540: 72 65 20 64 65 66 69 6e 65 64 2e 0a 2a 2f 0a 69 re defined..*/.i
5550: 6e 74 20 63 67 69 5f 61 6c 6c 28 63 6f 6e 73 74 nt cgi_all(const
5560: 20 63 68 61 72 20 2a 7a 2c 20 2e 2e 2e 29 7b 0a char *z, ...){.
5570: 20 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 va_list ap;.
5580: 63 68 61 72 20 2a 7a 32 3b 0a 20 20 69 66 28 20 char *z2;. if(
5590: 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 7a 2c cgi_parameter(z,
55a0: 30 29 3d 3d 30 20 29 20 72 65 74 75 72 6e 20 30 0)==0 ) return 0
55b0: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c ;. va_start(ap,
55c0: 20 7a 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a z);. while( (z
55d0: 32 20 3d 20 76 61 5f 61 72 67 28 61 70 2c 20 63 2 = va_arg(ap, c
55e0: 68 61 72 2a 29 29 3d 3d 30 20 29 7b 0a 20 20 20 har*))==0 ){.
55f0: 20 69 66 28 20 63 67 69 5f 70 61 72 61 6d 65 74 if( cgi_paramet
5600: 65 72 28 7a 32 2c 30 29 3d 3d 30 20 29 20 72 65 er(z2,0)==0 ) re
5610: 74 75 72 6e 20 30 3b 0a 20 20 7d 0a 20 20 76 61 turn 0;. }. va
5620: 5f 65 6e 64 28 61 70 29 3b 0a 20 20 72 65 74 75 _end(ap);. retu
5630: 72 6e 20 31 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 50 rn 1;.}../*.** P
5640: 72 69 6e 74 20 61 6c 6c 20 71 75 65 72 79 20 70 rint all query p
5650: 61 72 61 6d 65 74 65 72 73 20 6f 6e 20 73 74 61 arameters on sta
5660: 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 20 20 46 ndard output. F
5670: 6f 72 6d 61 74 20 74 68 65 0a 2a 2a 20 70 61 72 ormat the.** par
5680: 61 6d 65 74 65 72 73 20 61 73 20 48 54 4d 4c 2e ameters as HTML.
5690: 20 20 54 68 69 73 20 69 73 20 75 73 65 64 20 66 This is used f
56a0: 6f 72 20 74 65 73 74 69 6e 67 20 61 6e 64 20 64 or testing and d
56b0: 65 62 75 67 67 69 6e 67 2e 0a 2a 2f 0a 76 6f 69 ebugging..*/.voi
56c0: 64 20 63 67 69 5f 70 72 69 6e 74 5f 61 6c 6c 28 d cgi_print_all(
56d0: 76 6f 69 64 29 7b 0a 20 20 69 6e 74 20 69 3b 0a void){. int i;.
56e0: 20 20 63 67 69 5f 70 61 72 61 6d 65 74 65 72 28 cgi_parameter(
56f0: 22 22 2c 22 22 29 3b 20 20 2f 2a 20 46 6f 72 63 "",""); /* Forc
5700: 65 20 74 68 65 20 70 61 72 61 6d 65 74 65 72 73 e the parameters
5710: 20 69 6e 74 6f 20 73 6f 72 74 65 64 20 6f 72 64 into sorted ord
5720: 65 72 20 2a 2f 0a 20 20 66 6f 72 28 69 3d 30 3b er */. for(i=0;
5730: 20 69 3c 6e 55 73 65 64 51 50 3b 20 69 2b 2b 29 i<nUsedQP; i++)
5740: 7b 0a 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 {. cgi_printf
5750: 28 22 25 73 20 3d 20 25 73 20 20 3c 62 72 20 2f ("%s = %s <br /
5760: 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 68 74 6d >\n",. htm
5770: 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d lize(aParamQP[i]
5780: 2e 7a 4e 61 6d 65 2c 20 2d 31 29 2c 20 68 74 6d .zName, -1), htm
5790: 6c 69 7a 65 28 61 50 61 72 61 6d 51 50 5b 69 5d lize(aParamQP[i]
57a0: 2e 7a 56 61 6c 75 65 2c 20 2d 31 29 29 3b 0a 20 .zValue, -1));.
57b0: 20 7d 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 57 72 69 74 }.}../*.** Writ
57c0: 65 20 48 54 4d 4c 20 74 65 78 74 20 66 6f 72 20 e HTML text for
57d0: 61 6e 20 6f 70 74 69 6f 6e 20 6d 65 6e 75 20 74 an option menu t
57e0: 6f 20 73 74 61 6e 64 61 72 64 20 6f 75 74 70 75 o standard outpu
57f0: 74 2e 20 20 7a 50 61 72 61 6d 0a 2a 2a 20 69 73 t. zParam.** is
5800: 20 74 68 65 20 71 75 65 72 79 20 70 61 72 61 6d the query param
5810: 65 74 65 72 20 74 68 61 74 20 74 68 65 20 6f 70 eter that the op
5820: 74 69 6f 6e 20 6d 65 6e 75 20 73 65 74 73 2e 20 tion menu sets.
5830: 20 7a 44 66 6c 74 20 69 73 20 74 68 65 0a 2a 2a zDflt is the.**
5840: 20 69 6e 69 74 69 61 6c 20 76 61 6c 75 65 20 6f initial value o
5850: 66 20 74 68 65 20 6f 70 74 69 6f 6e 20 6d 65 6e f the option men
5860: 75 2e 20 20 41 64 64 69 74 69 6f 6e 20 61 72 67 u. Addition arg
5870: 75 6d 65 6e 74 73 20 61 72 65 20 6e 61 6d 65 2f uments are name/
5880: 76 61 6c 75 65 0a 2a 2a 20 70 61 69 72 73 20 74 value.** pairs t
5890: 68 61 74 20 64 65 66 69 6e 65 20 76 61 6c 75 65 hat define value
58a0: 73 20 6f 6e 20 74 68 65 20 6d 65 6e 75 2e 20 20 s on the menu.
58b0: 54 68 65 20 6c 69 73 74 20 69 73 20 74 65 72 6d The list is term
58c0: 69 6e 61 74 65 64 20 77 69 74 68 0a 2a 2a 20 61 inated with.** a
58d0: 20 73 69 6e 67 6c 65 20 4e 55 4c 4c 20 61 72 67 single NULL arg
58e0: 75 6d 65 6e 74 2e 0a 2a 2f 0a 76 6f 69 64 20 63 ument..*/.void c
58f0: 67 69 5f 6f 70 74 69 6f 6e 6d 65 6e 75 28 69 6e gi_optionmenu(in
5900: 74 20 69 6e 2c 20 63 6f 6e 73 74 20 63 68 61 72 t in, const char
5910: 20 2a 7a 50 2c 20 63 6f 6e 73 74 20 63 68 61 72 *zP, const char
5920: 20 2a 7a 44 2c 20 2e 2e 2e 29 7b 0a 20 20 76 61 *zD, ...){. va
5930: 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 68 61 72 _list ap;. char
5940: 20 2a 7a 4e 61 6d 65 2c 20 2a 7a 56 61 6c 3b 0a *zName, *zVal;.
5950: 20 20 69 6e 74 20 64 66 6c 74 53 65 65 6e 20 3d int dfltSeen =
5960: 20 30 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 0;. cgi_printf
5970: 28 22 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a ("%*s<select siz
5980: 65 3d 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e e=1 name=\"%s\">
5990: 5c 6e 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 \n", in, "", zP)
59a0: 3b 0a 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c ;. va_start(ap,
59b0: 20 7a 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 zD);. while( (
59c0: 7a 4e 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 zName = va_arg(a
59d0: 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 p, char*))!=0 &&
59e0: 20 28 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 (zVal = va_arg(
59f0: 61 70 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 ap, char*))!=0 )
5a00: 7b 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 {. if( strcmp
5a10: 28 7a 56 61 6c 2c 7a 44 29 3d 3d 30 20 29 7b 20 (zVal,zD)==0 ){
5a20: 64 66 6c 74 53 65 65 6e 20 3d 20 31 3b 20 62 72 dfltSeen = 1; br
5a30: 65 61 6b 3b 20 7d 0a 20 20 7d 0a 20 20 76 61 5f eak; }. }. va_
5a40: 65 6e 64 28 61 70 29 3b 0a 20 20 69 66 28 20 21 end(ap);. if( !
5a50: 64 66 6c 74 53 65 65 6e 20 29 7b 0a 20 20 20 20 dfltSeen ){.
5a60: 69 66 28 20 7a 44 5b 30 5d 20 29 7b 0a 20 20 20 if( zD[0] ){.
5a70: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 cgi_printf("%
5a80: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d *s<option value=
5a90: 5c 22 25 68 5c 22 20 73 65 6c 65 63 74 65 64 3e \"%h\" selected>
5aa0: 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a %h</option>\n",.
5ab0: 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 in+2, ""
5ac0: 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 20 20 20 7d , zD, zD);. }
5ad0: 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 5f else{. cgi_
5ae0: 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 printf("%*s<opti
5af0: 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 73 65 on value=\"\" se
5b00: 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c 2f 6f lected> </o
5b10: 70 74 69 6f 6e 3e 5c 6e 22 2c 20 69 6e 2b 32 2c ption>\n", in+2,
5b20: 20 22 22 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a "");. }. }.
5b30: 20 20 76 61 5f 73 74 61 72 74 28 61 70 2c 20 7a va_start(ap, z
5b40: 44 29 3b 0a 20 20 77 68 69 6c 65 28 20 28 7a 4e D);. while( (zN
5b50: 61 6d 65 20 3d 20 76 61 5f 61 72 67 28 61 70 2c ame = va_arg(ap,
5b60: 20 63 68 61 72 2a 29 29 21 3d 30 20 26 26 20 28 char*))!=0 && (
5b70: 7a 56 61 6c 20 3d 20 76 61 5f 61 72 67 28 61 70 zVal = va_arg(ap
5b80: 2c 20 63 68 61 72 2a 29 29 21 3d 30 20 29 7b 0a , char*))!=0 ){.
5b90: 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 5b 30 5d if( zName[0]
5ba0: 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 ){. cgi_pr
5bb0: 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e intf("%*s<option
5bc0: 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e value=\"%h\"%s>
5bd0: 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a %h</option>\n",.
5be0: 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 in+2, ""
5bf0: 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c 2c 0a ,. zVal,.
5c00: 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a strcmp(z
5c10: 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 Val, zD) ? "" :
5c20: 22 20 73 65 6c 65 63 74 65 64 22 2c 0a 20 20 20 " selected",.
5c30: 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 20 20 20 zName.
5c40: 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 7b 0a 20 );. }else{.
5c50: 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 cgi_printf(
5c60: 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 "%*s<option valu
5c70: 65 3d 5c 22 5c 22 25 73 3e 26 6e 62 73 70 3b 3c e=\"\"%s> <
5c80: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 /option>\n",.
5c90: 20 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 in+2, "",.
5ca0: 20 20 20 20 20 20 20 73 74 72 63 6d 70 28 7a 56 strcmp(zV
5cb0: 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 3a 20 22 al, zD) ? "" : "
5cc0: 20 73 65 6c 65 63 74 65 64 22 0a 20 20 20 20 20 selected".
5cd0: 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d 0a 20 20 );. }. }.
5ce0: 76 61 5f 65 6e 64 28 61 70 29 3b 0a 20 20 63 67 va_end(ap);. cg
5cf0: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 2f 73 i_printf("%*s</s
5d00: 65 6c 65 63 74 3e 5c 6e 22 2c 20 69 6e 2c 20 22 elect>\n", in, "
5d10: 22 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 ");.}../*.** Thi
5d20: 73 20 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 s routine works
5d30: 61 20 6c 6f 74 20 6c 69 6b 65 20 63 67 69 5f 6f a lot like cgi_o
5d40: 70 74 69 6f 6e 6d 65 6e 75 28 29 20 65 78 63 65 ptionmenu() exce
5d50: 70 74 20 74 68 61 74 20 74 68 65 20 6c 69 73 74 pt that the list
5d60: 20 6f 66 0a 2a 2a 20 76 61 6c 75 65 73 20 69 73 of.** values is
5d70: 20 63 6f 6e 74 61 69 6e 65 64 20 69 6e 20 61 6e contained in an
5d80: 20 61 72 72 61 79 2e 20 20 41 6c 73 6f 2c 20 74 array. Also, t
5d90: 68 65 20 76 61 6c 75 65 73 20 61 72 65 20 6a 75 he values are ju
5da0: 73 74 20 76 61 6c 75 65 73 2c 20 6e 6f 74 0a 2a st values, not.*
5db0: 2a 20 6e 61 6d 65 2f 76 61 6c 75 65 20 70 61 69 * name/value pai
5dc0: 72 73 20 61 73 20 69 6e 20 63 67 69 5f 6f 70 74 rs as in cgi_opt
5dd0: 69 6f 6e 6d 65 6e 75 2e 0a 2a 2f 0a 76 6f 69 64 ionmenu..*/.void
5de0: 20 63 67 69 5f 76 5f 6f 70 74 69 6f 6e 6d 65 6e cgi_v_optionmen
5df0: 75 28 0a 20 20 69 6e 74 20 69 6e 2c 20 20 20 20 u(. int in,
5e00: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 49 6e 64 /* Ind
5e10: 65 6e 74 20 62 79 20 74 68 69 73 20 61 6d 6f 75 ent by this amou
5e20: 6e 74 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 nt */. const ch
5e30: 61 72 20 2a 7a 50 2c 20 20 20 20 20 20 2f 2a 20 ar *zP, /*
5e40: 54 68 65 20 71 75 65 72 79 20 70 61 72 61 6d 65 The query parame
5e50: 74 65 72 20 6e 61 6d 65 20 2a 2f 0a 20 20 63 6f ter name */. co
5e60: 6e 73 74 20 63 68 61 72 20 2a 7a 44 2c 20 20 20 nst char *zD,
5e70: 20 20 20 2f 2a 20 44 65 66 61 75 6c 74 20 76 61 /* Default va
5e80: 6c 75 65 20 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 lue */. const c
5e90: 68 61 72 20 2a 2a 61 7a 20 20 20 20 20 20 2f 2a har **az /*
5ea0: 20 4e 55 4c 4c 2d 74 65 72 6d 69 6e 61 74 65 64 NULL-terminated
5eb0: 20 6c 69 73 74 20 6f 66 20 61 6c 6c 6f 77 65 64 list of allowed
5ec0: 20 76 61 6c 75 65 73 20 2a 2f 0a 29 7b 0a 20 20 values */.){.
5ed0: 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a 56 61 6c const char *zVal
5ee0: 3b 0a 20 20 69 6e 74 20 69 3b 0a 20 20 63 67 69 ;. int i;. cgi
5ef0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 73 65 6c _printf("%*s<sel
5f00: 65 63 74 20 73 69 7a 65 3d 31 20 6e 61 6d 65 3d ect size=1 name=
5f10: 5c 22 25 73 5c 22 3e 5c 6e 22 2c 20 69 6e 2c 20 \"%s\">\n", in,
5f20: 22 22 2c 20 7a 50 29 3b 0a 20 20 66 6f 72 28 69 "", zP);. for(i
5f30: 3d 30 3b 20 61 7a 5b 69 5d 3b 20 69 2b 2b 29 7b =0; az[i]; i++){
5f40: 0a 20 20 20 20 69 66 28 20 73 74 72 63 6d 70 28 . if( strcmp(
5f50: 61 7a 5b 69 5d 2c 7a 44 29 3d 3d 30 20 29 20 62 az[i],zD)==0 ) b
5f60: 72 65 61 6b 3b 0a 20 20 7d 0a 20 20 69 66 28 20 reak;. }. if(
5f70: 61 7a 5b 69 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 az[i]==0 ){.
5f80: 69 66 28 20 7a 44 5b 30 5d 3d 3d 30 20 29 7b 0a if( zD[0]==0 ){.
5f90: 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e 74 66 cgi_printf
5fa0: 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c ("%*s<option val
5fb0: 75 65 3d 5c 22 5c 22 20 73 65 6c 65 63 74 65 64 ue=\"\" selected
5fc0: 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e > </option>
5fd0: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 \n",. in+2
5fe0: 2c 20 22 22 29 3b 0a 20 20 20 20 7d 65 6c 73 65 , "");. }else
5ff0: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e {. cgi_prin
6000: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 tf("%*s<option v
6010: 61 6c 75 65 3d 5c 22 25 68 5c 22 20 73 65 6c 65 alue=\"%h\" sele
6020: 63 74 65 64 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e cted>%h</option>
6030: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 69 6e 2b 32 \n",. in+2
6040: 2c 20 22 22 2c 20 7a 44 2c 20 7a 44 29 3b 0a 20 , "", zD, zD);.
6050: 20 20 20 7d 0a 20 20 7d 0a 20 20 77 68 69 6c 65 }. }. while
6060: 28 20 28 7a 56 61 6c 20 3d 20 2a 28 61 7a 2b 2b ( (zVal = *(az++
6070: 29 29 21 3d 30 20 20 29 7b 0a 20 20 20 20 69 66 ))!=0 ){. if
6080: 28 20 7a 56 61 6c 5b 30 5d 20 29 7b 0a 20 20 20 ( zVal[0] ){.
6090: 20 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 cgi_printf("%
60a0: 2a 73 3c 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d *s<option value=
60b0: 5c 22 25 68 5c 22 25 73 3e 25 68 3c 2f 6f 70 74 \"%h\"%s>%h</opt
60c0: 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 20 20 20 20 ion>\n",.
60d0: 20 69 6e 2b 32 2c 20 22 22 2c 0a 20 20 20 20 20 in+2, "",.
60e0: 20 20 20 7a 56 61 6c 2c 0a 20 20 20 20 20 20 20 zVal,.
60f0: 20 73 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 strcmp(zVal, zD
6100: 29 20 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 ) ? "" : " selec
6110: 74 65 64 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 ted",. zV
6120: 61 6c 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 al. );.
6130: 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 63 67 69 }else{. cgi
6140: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 _printf("%*s<opt
6150: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 25 73 ion value=\"\"%s
6160: 3e 26 6e 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e > </option>
6170: 5c 6e 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b \n",. in+
6180: 32 2c 20 22 22 2c 0a 20 20 20 20 20 20 20 20 73 2, "",. s
6190: 74 72 63 6d 70 28 7a 56 61 6c 2c 20 7a 44 29 20 trcmp(zVal, zD)
61a0: 3f 20 22 22 20 3a 20 22 20 73 65 6c 65 63 74 65 ? "" : " selecte
61b0: 64 22 0a 20 20 20 20 20 20 29 3b 0a 20 20 20 20 d". );.
61c0: 7d 0a 20 20 7d 0a 20 20 63 67 69 5f 70 72 69 6e }. }. cgi_prin
61d0: 74 66 28 22 25 2a 73 3c 2f 73 65 6c 65 63 74 3e tf("%*s</select>
61e0: 5c 6e 22 2c 20 69 6e 2c 20 22 22 29 3b 0a 7d 0a \n", in, "");.}.
61f0: 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 ./*.** This rout
6200: 69 6e 65 20 77 6f 72 6b 73 20 61 20 6c 6f 74 20 ine works a lot
6210: 6c 69 6b 65 20 63 67 69 5f 76 5f 6f 70 74 69 6f like cgi_v_optio
6220: 6e 6d 65 6e 75 28 29 20 65 78 63 65 70 74 20 74 nmenu() except t
6230: 68 61 74 20 74 68 65 20 6c 69 73 74 0a 2a 2a 20 hat the list.**
6240: 69 73 20 61 20 6c 69 73 74 20 6f 66 20 70 61 69 is a list of pai
6250: 72 73 2e 20 20 54 68 65 20 66 69 72 73 74 20 65 rs. The first e
6260: 6c 65 6d 65 6e 74 20 6f 66 20 65 61 63 68 20 70 lement of each p
6270: 61 69 72 20 69 73 20 74 68 65 20 76 61 6c 75 65 air is the value
6280: 20 75 73 65 64 0a 2a 2a 20 69 6e 74 65 72 6e 61 used.** interna
6290: 6c 6c 79 20 61 6e 64 20 74 68 65 20 73 65 63 6f lly and the seco
62a0: 6e 64 20 65 6c 65 6d 65 6e 74 20 69 73 20 74 68 nd element is th
62b0: 65 20 76 61 6c 75 65 20 64 69 73 70 6c 61 79 65 e value displaye
62c0: 64 20 74 6f 20 74 68 65 20 75 73 65 72 2e 0a 2a d to the user..*
62d0: 2f 0a 76 6f 69 64 20 63 67 69 5f 76 5f 6f 70 74 /.void cgi_v_opt
62e0: 69 6f 6e 6d 65 6e 75 32 28 0a 20 20 69 6e 74 20 ionmenu2(. int
62f0: 69 6e 2c 20 20 20 20 20 20 20 20 20 20 20 20 20 in,
6300: 20 2f 2a 20 49 6e 64 65 6e 74 20 62 79 20 74 68 /* Indent by th
6310: 69 73 20 61 6d 6f 75 6e 74 20 2a 2f 0a 20 20 63 is amount */. c
6320: 6f 6e 73 74 20 63 68 61 72 20 2a 7a 50 2c 20 20 onst char *zP,
6330: 20 20 20 20 2f 2a 20 54 68 65 20 71 75 65 72 79 /* The query
6340: 20 70 61 72 61 6d 65 74 65 72 20 6e 61 6d 65 20 parameter name
6350: 2a 2f 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 */. const char
6360: 2a 7a 44 2c 20 20 20 20 20 20 2f 2a 20 44 65 66 *zD, /* Def
6370: 61 75 6c 74 20 76 61 6c 75 65 20 2a 2f 0a 20 20 ault value */.
6380: 63 6f 6e 73 74 20 63 68 61 72 20 2a 2a 61 7a 20 const char **az
6390: 20 20 20 20 20 2f 2a 20 4e 55 4c 4c 2d 74 65 72 /* NULL-ter
63a0: 6d 69 6e 61 74 65 64 20 6c 69 73 74 20 6f 66 20 minated list of
63b0: 61 6c 6c 6f 77 65 64 20 76 61 6c 75 65 73 20 2a allowed values *
63c0: 2f 0a 29 7b 0a 20 20 63 6f 6e 73 74 20 63 68 61 /.){. const cha
63d0: 72 20 2a 7a 56 61 6c 3b 0a 20 20 69 6e 74 20 69 r *zVal;. int i
63e0: 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 ;. cgi_printf("
63f0: 25 2a 73 3c 73 65 6c 65 63 74 20 73 69 7a 65 3d %*s<select size=
6400: 31 20 6e 61 6d 65 3d 5c 22 25 73 5c 22 3e 5c 6e 1 name=\"%s\">\n
6410: 22 2c 20 69 6e 2c 20 22 22 2c 20 7a 50 29 3b 0a ", in, "", zP);.
6420: 20 20 66 6f 72 28 69 3d 30 3b 20 61 7a 5b 69 5d for(i=0; az[i]
6430: 3b 20 69 2b 3d 32 29 7b 0a 20 20 20 20 69 66 28 ; i+=2){. if(
6440: 20 73 74 72 63 6d 70 28 61 7a 5b 69 5d 2c 7a 44 strcmp(az[i],zD
6450: 29 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 )==0 ) break;.
6460: 7d 0a 20 20 69 66 28 20 61 7a 5b 69 5d 3d 3d 30 }. if( az[i]==0
6470: 20 29 7b 0a 20 20 20 20 69 66 28 20 7a 44 5b 30 ){. if( zD[0
6480: 5d 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 ]==0 ){. cg
6490: 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 i_printf("%*s<op
64a0: 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 5c 22 20 tion value=\"\"
64b0: 73 65 6c 65 63 74 65 64 3e 26 6e 62 73 70 3b 3c selected> <
64c0: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 /option>\n",.
64d0: 20 20 20 20 69 6e 2b 32 2c 20 22 22 29 3b 0a 20 in+2, "");.
64e0: 20 20 20 7d 65 6c 73 65 7b 0a 20 20 20 20 20 20 }else{.
64f0: 63 67 69 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c cgi_printf("%*s<
6500: 6f 70 74 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 option value=\"%
6510: 68 5c 22 20 73 65 6c 65 63 74 65 64 3e 25 68 3c h\" selected>%h<
6520: 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 2c 0a 20 20 20 /option>\n",.
6530: 20 20 20 20 69 6e 2b 32 2c 20 22 22 2c 20 7a 44 in+2, "", zD
6540: 2c 20 7a 44 29 3b 0a 20 20 20 20 7d 0a 20 20 7d , zD);. }. }
6550: 0a 20 20 77 68 69 6c 65 28 20 28 7a 56 61 6c 20 . while( (zVal
6560: 3d 20 2a 28 61 7a 2b 2b 29 29 21 3d 30 20 20 29 = *(az++))!=0 )
6570: 7b 0a 20 20 20 20 63 6f 6e 73 74 20 63 68 61 72 {. const char
6580: 20 2a 7a 4e 61 6d 65 20 3d 20 2a 28 61 7a 2b 2b *zName = *(az++
6590: 29 3b 0a 20 20 20 20 69 66 28 20 7a 4e 61 6d 65 );. if( zName
65a0: 5b 30 5d 20 29 7b 0a 20 20 20 20 20 20 63 67 69 [0] ){. cgi
65b0: 5f 70 72 69 6e 74 66 28 22 25 2a 73 3c 6f 70 74 _printf("%*s<opt
65c0: 69 6f 6e 20 76 61 6c 75 65 3d 5c 22 25 68 5c 22 ion value=\"%h\"
65d0: 25 73 3e 25 68 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e %s>%h</option>\n
65e0: 22 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c ",. in+2,
65f0: 20 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 "",. zVa
6600: 6c 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d l,. strcm
6610: 70 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 p(zVal, zD) ? ""
6620: 20 3a 20 22 20 73 65 6c 65 63 74 65 64 22 2c 0a : " selected",.
6630: 20 20 20 20 20 20 20 20 7a 4e 61 6d 65 0a 20 20 zName.
6640: 20 20 20 20 29 3b 0a 20 20 20 20 7d 65 6c 73 65 );. }else
6650: 7b 0a 20 20 20 20 20 20 63 67 69 5f 70 72 69 6e {. cgi_prin
6660: 74 66 28 22 25 2a 73 3c 6f 70 74 69 6f 6e 20 76 tf("%*s<option v
6670: 61 6c 75 65 3d 5c 22 25 68 5c 22 25 73 3e 26 6e alue=\"%h\"%s>&n
6680: 62 73 70 3b 3c 2f 6f 70 74 69 6f 6e 3e 5c 6e 22 bsp;</option>\n"
6690: 2c 0a 20 20 20 20 20 20 20 20 69 6e 2b 32 2c 20 ,. in+2,
66a0: 22 22 2c 0a 20 20 20 20 20 20 20 20 7a 56 61 6c "",. zVal
66b0: 2c 0a 20 20 20 20 20 20 20 20 73 74 72 63 6d 70 ,. strcmp
66c0: 28 7a 56 61 6c 2c 20 7a 44 29 20 3f 20 22 22 20 (zVal, zD) ? ""
66d0: 3a 20 22 20 73 65 6c 65 63 74 65 64 22 0a 20 20 : " selected".
66e0: 20 20 20 20 29 3b 0a 20 20 20 20 7d 0a 20 20 7d );. }. }
66f0: 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 22 25 . cgi_printf("%
6700: 2a 73 3c 2f 73 65 6c 65 63 74 3e 5c 6e 22 2c 20 *s</select>\n",
6710: 69 6e 2c 20 22 22 29 3b 0a 7d 0a 0a 2f 2a 20 0a in, "");.}../* .
6720: 2a 2a 20 54 68 69 73 20 66 75 6e 63 74 69 6f 6e ** This function
6730: 20 69 6d 70 6c 65 6d 65 6e 74 73 20 74 68 65 20 implements the
6740: 63 61 6c 6c 62 61 63 6b 20 66 72 6f 6d 20 76 78 callback from vx
6750: 70 72 69 6e 74 66 2e 20 0a 2a 2a 0a 2a 2a 20 54 printf. .**.** T
6760: 68 69 73 20 72 6f 75 74 69 6e 65 20 73 65 6e 64 his routine send
6770: 73 20 6e 4e 65 77 43 68 61 72 20 63 68 61 72 61 s nNewChar chara
6780: 63 74 65 72 73 20 6f 66 20 74 65 78 74 20 69 6e cters of text in
6790: 20 7a 4e 65 77 54 65 78 74 20 74 6f 0a 2a 2a 20 zNewText to.**
67a0: 43 47 49 20 72 65 70 6c 79 20 63 6f 6e 74 65 6e CGI reply conten
67b0: 74 20 62 75 66 66 65 72 2e 0a 2a 2f 0a 73 74 61 t buffer..*/.sta
67c0: 74 69 63 20 76 6f 69 64 20 73 6f 75 74 28 76 6f tic void sout(vo
67d0: 69 64 20 2a 4e 6f 74 55 73 65 64 2c 20 63 6f 6e id *NotUsed, con
67e0: 73 74 20 63 68 61 72 20 2a 7a 4e 65 77 54 65 78 st char *zNewTex
67f0: 74 2c 20 69 6e 74 20 6e 4e 65 77 43 68 61 72 29 t, int nNewChar)
6800: 7b 0a 20 20 63 67 69 5f 61 70 70 65 6e 64 5f 63 {. cgi_append_c
6810: 6f 6e 74 65 6e 74 28 7a 4e 65 77 54 65 78 74 2c ontent(zNewText,
6820: 20 6e 4e 65 77 43 68 61 72 29 3b 0a 7d 0a 0a 2f nNewChar);.}../
6830: 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 6e *.** This routin
6840: 65 20 77 6f 72 6b 73 20 6c 69 6b 65 20 22 70 72 e works like "pr
6850: 69 6e 74 66 22 20 65 78 63 65 70 74 20 74 68 61 intf" except tha
6860: 74 20 69 74 20 68 61 73 20 74 68 65 0a 2a 2a 20 t it has the.**
6870: 65 78 74 72 61 20 66 6f 72 6d 61 74 74 69 6e 67 extra formatting
6880: 20 63 61 70 61 62 69 6c 69 74 69 65 73 20 73 75 capabilities su
6890: 63 68 20 61 73 20 25 68 20 61 6e 64 20 25 74 2e ch as %h and %t.
68a0: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 72 69 .*/.void cgi_pri
68b0: 6e 74 66 28 63 6f 6e 73 74 20 63 68 61 72 20 2a ntf(const char *
68c0: 7a 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 zFormat, ...){.
68d0: 20 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 76 va_list ap;. v
68e0: 61 5f 73 74 61 72 74 28 61 70 2c 7a 46 6f 72 6d a_start(ap,zForm
68f0: 61 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 at);. vxprintf(
6900: 73 6f 75 74 2c 30 2c 7a 46 6f 72 6d 61 74 2c 61 sout,0,zFormat,a
6910: 70 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 p);. va_end(ap)
6920: 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 54 68 69 73 20 ;.}../*.** This
6930: 72 6f 75 74 69 6e 65 20 77 6f 72 6b 73 20 6c 69 routine works li
6940: 6b 65 20 22 76 70 72 69 6e 74 66 22 20 65 78 63 ke "vprintf" exc
6950: 65 70 74 20 74 68 61 74 20 69 74 20 68 61 73 20 ept that it has
6960: 74 68 65 0a 2a 2a 20 65 78 74 72 61 20 66 6f 72 the.** extra for
6970: 6d 61 74 74 69 6e 67 20 63 61 70 61 62 69 6c 69 matting capabili
6980: 74 69 65 73 20 73 75 63 68 20 61 73 20 25 68 20 ties such as %h
6990: 61 6e 64 20 25 74 2e 0a 2a 2f 0a 76 6f 69 64 20 and %t..*/.void
69a0: 63 67 69 5f 76 70 72 69 6e 74 66 28 63 6f 6e 73 cgi_vprintf(cons
69b0: 74 20 63 68 61 72 20 2a 7a 46 6f 72 6d 61 74 2c t char *zFormat,
69c0: 20 76 61 5f 6c 69 73 74 20 61 70 29 7b 0a 20 20 va_list ap){.
69d0: 76 78 70 72 69 6e 74 66 28 73 6f 75 74 2c 30 2c vxprintf(sout,0,
69e0: 7a 46 6f 72 6d 61 74 2c 61 70 29 3b 0a 7d 0a 0a zFormat,ap);.}..
69f0: 0a 2f 2a 0a 2a 2a 20 53 65 6e 64 20 61 20 72 65 ./*.** Send a re
6a00: 70 6c 79 20 69 6e 64 69 63 61 74 69 6e 67 20 74 ply indicating t
6a10: 68 61 74 20 74 68 65 20 48 54 54 50 20 72 65 71 hat the HTTP req
6a20: 75 65 73 74 20 77 61 73 20 6d 61 6c 66 6f 72 6d uest was malform
6a30: 65 64 0a 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 ed.*/.static voi
6a40: 64 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 d malformed_requ
6a50: 65 73 74 28 76 6f 69 64 29 7b 0a 20 20 63 67 69 est(void){. cgi
6a60: 5f 73 65 74 5f 73 74 61 74 75 73 28 35 30 31 2c _set_status(501,
6a70: 20 22 4e 6f 74 20 49 6d 70 6c 65 6d 65 6e 74 65 "Not Implemente
6a80: 64 22 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 d");. cgi_print
6a90: 66 28 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 f(. "<html><b
6aa0: 6f 64 79 3e 55 6e 72 65 63 6f 67 6e 69 7a 65 64 ody>Unrecognized
6ab0: 20 48 54 54 50 20 52 65 71 75 65 73 74 3c 2f 62 HTTP Request</b
6ac0: 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 5c 6e 22 0a 20 ody></html>\n".
6ad0: 20 29 3b 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 );. cgi_reply(
6ae0: 29 3b 0a 20 20 65 78 69 74 28 30 29 3b 0a 7d 0a );. exit(0);.}.
6af0: 0a 2f 2a 0a 2a 2a 20 50 61 6e 69 63 20 61 6e 64 ./*.** Panic and
6b00: 20 64 69 65 20 77 68 69 6c 65 20 70 72 6f 63 65 die while proce
6b10: 73 73 69 6e 67 20 61 20 77 65 62 70 61 67 65 2e ssing a webpage.
6b20: 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 70 61 6e .*/.void cgi_pan
6b30: 69 63 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a ic(const char *z
6b40: 46 6f 72 6d 61 74 2c 20 2e 2e 2e 29 7b 0a 20 20 Format, ...){.
6b50: 76 61 5f 6c 69 73 74 20 61 70 3b 0a 20 20 63 67 va_list ap;. cg
6b60: 69 5f 72 65 73 65 74 5f 63 6f 6e 74 65 6e 74 28 i_reset_content(
6b70: 29 3b 0a 20 20 63 67 69 5f 73 65 74 5f 73 74 61 );. cgi_set_sta
6b80: 74 75 73 28 35 30 30 2c 20 22 49 6e 74 65 72 6e tus(500, "Intern
6b90: 61 6c 20 53 65 72 76 65 72 20 45 72 72 6f 72 22 al Server Error"
6ba0: 29 3b 0a 20 20 63 67 69 5f 70 72 69 6e 74 66 28 );. cgi_printf(
6bb0: 0a 20 20 20 20 22 3c 68 74 6d 6c 3e 3c 62 6f 64 . "<html><bod
6bc0: 79 3e 3c 68 31 3e 49 6e 74 65 72 6e 61 6c 20 53 y><h1>Internal S
6bd0: 65 72 76 65 72 20 45 72 72 6f 72 3c 2f 68 31 3e erver Error</h1>
6be0: 5c 6e 22 0a 20 20 20 20 22 3c 70 6c 61 69 6e 74 \n". "<plaint
6bf0: 65 78 74 3e 22 0a 20 20 29 3b 0a 20 20 76 61 5f ext>". );. va_
6c00: 73 74 61 72 74 28 61 70 2c 20 7a 46 6f 72 6d 61 start(ap, zForma
6c10: 74 29 3b 0a 20 20 76 78 70 72 69 6e 74 66 28 73 t);. vxprintf(s
6c20: 6f 75 74 2c 30 2c 7a 46 6f 72 6d 61 74 2c 61 70 out,0,zFormat,ap
6c30: 29 3b 0a 20 20 76 61 5f 65 6e 64 28 61 70 29 3b );. va_end(ap);
6c40: 0a 20 20 63 67 69 5f 72 65 70 6c 79 28 29 3b 0a . cgi_reply();.
6c50: 20 20 65 78 69 74 28 31 29 3b 0a 7d 0a 0a 2f 2a exit(1);.}../*
6c60: 0a 2a 2a 20 52 65 6d 6f 76 65 20 74 68 65 20 66 .** Remove the f
6c70: 69 72 73 74 20 73 70 61 63 65 2d 64 65 6c 69 6d irst space-delim
6c80: 69 74 65 64 20 74 6f 6b 65 6e 20 66 72 6f 6d 20 ited token from
6c90: 61 20 73 74 72 69 6e 67 20 61 6e 64 20 72 65 74 a string and ret
6ca0: 75 72 6e 0a 2a 2a 20 61 20 70 6f 69 6e 74 65 72 urn.** a pointer
6cb0: 20 74 6f 20 69 74 2e 20 20 41 64 64 20 61 20 4e to it. Add a N
6cc0: 55 4c 4c 20 74 6f 20 74 68 65 20 73 74 72 69 6e ULL to the strin
6cd0: 67 20 74 6f 20 74 65 72 6d 69 6e 61 74 65 20 74 g to terminate t
6ce0: 68 65 20 74 6f 6b 65 6e 2e 0a 2a 2a 20 4d 61 6b he token..** Mak
6cf0: 65 20 2a 7a 4c 65 66 74 4f 76 65 72 20 70 6f 69 e *zLeftOver poi
6d00: 6e 74 20 74 6f 20 74 68 65 20 73 74 61 72 74 20 nt to the start
6d10: 6f 66 20 74 68 65 20 6e 65 78 74 20 74 6f 6b 65 of the next toke
6d20: 6e 2e 0a 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 n..*/.static cha
6d30: 72 20 2a 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e r *extract_token
6d40: 28 63 68 61 72 20 2a 7a 49 6e 70 75 74 2c 20 63 (char *zInput, c
6d50: 68 61 72 20 2a 2a 7a 4c 65 66 74 4f 76 65 72 29 har **zLeftOver)
6d60: 7b 0a 20 20 63 68 61 72 20 2a 7a 52 65 73 75 6c {. char *zResul
6d70: 74 20 3d 20 30 3b 0a 20 20 69 66 28 20 7a 49 6e t = 0;. if( zIn
6d80: 70 75 74 3d 3d 30 20 29 7b 0a 20 20 20 20 69 66 put==0 ){. if
6d90: 28 20 7a 4c 65 66 74 4f 76 65 72 20 29 20 2a 7a ( zLeftOver ) *z
6da0: 4c 65 66 74 4f 76 65 72 20 3d 20 30 3b 0a 20 20 LeftOver = 0;.
6db0: 20 20 72 65 74 75 72 6e 20 30 3b 0a 20 20 7d 0a return 0;. }.
6dc0: 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65 while( isspace
6dd0: 28 2a 7a 49 6e 70 75 74 29 20 29 7b 20 7a 49 6e (*zInput) ){ zIn
6de0: 70 75 74 2b 2b 3b 20 7d 0a 20 20 7a 52 65 73 75 put++; }. zResu
6df0: 6c 74 20 3d 20 7a 49 6e 70 75 74 3b 0a 20 20 77 lt = zInput;. w
6e00: 68 69 6c 65 28 20 2a 7a 49 6e 70 75 74 20 26 26 hile( *zInput &&
6e10: 20 21 69 73 73 70 61 63 65 28 2a 7a 49 6e 70 75 !isspace(*zInpu
6e20: 74 29 20 29 7b 20 7a 49 6e 70 75 74 2b 2b 3b 20 t) ){ zInput++;
6e30: 7d 0a 20 20 69 66 28 20 2a 7a 49 6e 70 75 74 20 }. if( *zInput
6e40: 29 7b 0a 20 20 20 20 2a 7a 49 6e 70 75 74 20 3d ){. *zInput =
6e50: 20 30 3b 0a 20 20 20 20 7a 49 6e 70 75 74 2b 2b 0;. zInput++
6e60: 3b 0a 20 20 20 20 77 68 69 6c 65 28 20 69 73 73 ;. while( iss
6e70: 70 61 63 65 28 2a 7a 49 6e 70 75 74 29 20 29 7b pace(*zInput) ){
6e80: 20 7a 49 6e 70 75 74 2b 2b 3b 20 7d 0a 20 20 7d zInput++; }. }
6e90: 0a 20 20 69 66 28 20 7a 4c 65 66 74 4f 76 65 72 . if( zLeftOver
6ea0: 20 29 7b 20 2a 7a 4c 65 66 74 4f 76 65 72 20 3d ){ *zLeftOver =
6eb0: 20 7a 49 6e 70 75 74 3b 20 7d 0a 20 20 72 65 74 zInput; }. ret
6ec0: 75 72 6e 20 7a 52 65 73 75 6c 74 3b 0a 7d 0a 0a urn zResult;.}..
6ed0: 2f 2a 0a 2a 2a 20 54 68 69 73 20 72 6f 75 74 69 /*.** This routi
6ee0: 6e 65 20 68 61 6e 64 6c 65 73 20 61 20 73 69 6e ne handles a sin
6ef0: 67 6c 65 20 48 54 54 50 20 72 65 71 75 65 73 74 gle HTTP request
6f00: 20 77 68 69 63 68 20 69 73 20 63 6f 6d 69 6e 67 which is coming
6f10: 20 69 6e 20 6f 6e 0a 2a 2a 20 73 74 61 6e 64 61 in on.** standa
6f20: 72 64 20 69 6e 70 75 74 20 61 6e 64 20 77 68 69 rd input and whi
6f30: 63 68 20 72 65 70 6c 69 65 73 20 6f 6e 20 73 74 ch replies on st
6f40: 61 6e 64 61 72 64 20 6f 75 74 70 75 74 2e 0a 2a andard output..*
6f50: 2a 0a 2a 2a 20 54 68 65 20 48 54 54 50 20 72 65 *.** The HTTP re
6f60: 71 75 65 73 74 20 69 73 20 72 65 61 64 20 66 72 quest is read fr
6f70: 6f 6d 20 73 74 61 6e 64 61 72 64 20 69 6e 70 75 om standard inpu
6f80: 74 20 61 6e 64 20 69 73 20 75 73 65 64 20 74 6f t and is used to
6f90: 20 69 6e 69 74 69 61 6c 69 7a 65 0a 2a 2a 20 65 initialize.** e
6fa0: 6e 76 69 72 6f 6e 6d 65 6e 74 20 76 61 72 69 61 nvironment varia
6fb0: 62 6c 65 73 20 61 73 20 70 65 72 20 43 47 49 2e bles as per CGI.
6fc0: 20 20 54 68 65 20 63 67 69 5f 69 6e 69 74 28 29 The cgi_init()
6fd0: 20 72 6f 75 74 69 6e 65 20 74 6f 20 63 6f 6d 70 routine to comp
6fe0: 6c 65 74 65 0a 2a 2a 20 74 68 65 20 73 65 74 75 lete.** the setu
6ff0: 70 2e 20 20 4f 6e 63 65 20 61 6c 6c 20 74 68 65 p. Once all the
7000: 20 73 65 74 75 70 20 69 73 20 66 69 6e 69 73 68 setup is finish
7010: 65 64 2c 20 74 68 69 73 20 70 72 6f 63 65 64 75 ed, this procedu
7020: 72 65 20 72 65 74 75 72 6e 73 0a 2a 2a 20 61 6e re returns.** an
7030: 64 20 73 75 62 73 65 71 75 65 6e 74 20 63 6f 64 d subsequent cod
7040: 65 20 68 61 6e 64 6c 65 73 20 74 68 65 20 61 63 e handles the ac
7050: 74 75 61 6c 20 67 65 6e 65 72 61 74 69 6f 6e 20 tual generation
7060: 6f 66 20 74 68 65 20 77 65 62 70 61 67 65 2e 0a of the webpage..
7070: 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 68 61 6e 64 */.void cgi_hand
7080: 6c 65 5f 68 74 74 70 5f 72 65 71 75 65 73 74 28 le_http_request(
7090: 76 6f 69 64 29 7b 0a 20 20 63 68 61 72 20 2a 7a void){. char *z
70a0: 2c 20 2a 7a 54 6f 6b 65 6e 3b 0a 20 20 69 6e 74 , *zToken;. int
70b0: 20 69 3b 0a 20 20 73 74 72 75 63 74 20 73 6f 63 i;. struct soc
70c0: 6b 61 64 64 72 5f 69 6e 20 72 65 6d 6f 74 65 4e kaddr_in remoteN
70d0: 61 6d 65 3b 0a 20 20 73 69 7a 65 5f 74 20 73 69 ame;. size_t si
70e0: 7a 65 20 3d 20 73 69 7a 65 6f 66 28 73 74 72 75 ze = sizeof(stru
70f0: 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 29 3b ct sockaddr_in);
7100: 0a 20 20 63 68 61 72 20 7a 4c 69 6e 65 5b 32 30 . char zLine[20
7110: 30 30 5d 3b 20 20 20 20 20 2f 2a 20 41 20 73 69 00]; /* A si
7120: 6e 67 6c 65 20 6c 69 6e 65 20 6f 66 20 69 6e 70 ngle line of inp
7130: 75 74 2e 20 2a 2f 0a 0a 20 20 66 75 6c 6c 48 74 ut. */.. fullHt
7140: 74 70 52 65 70 6c 79 20 3d 20 31 3b 0a 20 20 69 tpReply = 1;. i
7150: 66 28 20 66 67 65 74 73 28 7a 4c 69 6e 65 2c 20 f( fgets(zLine,
7160: 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c 20 73 sizeof(zLine), s
7170: 74 64 69 6e 29 3d 3d 30 20 29 7b 0a 20 20 20 20 tdin)==0 ){.
7180: 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 73 malformed_reques
7190: 74 28 29 3b 0a 20 20 7d 0a 20 20 7a 54 6f 6b 65 t();. }. zToke
71a0: 6e 20 3d 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 n = extract_toke
71b0: 6e 28 7a 4c 69 6e 65 2c 20 26 7a 29 3b 0a 20 20 n(zLine, &z);.
71c0: 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 20 29 7b if( zToken==0 ){
71d0: 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 . malformed_r
71e0: 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 20 equest();. }.
71f0: 69 66 28 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 if( strcmp(zToke
7200: 6e 2c 22 47 45 54 22 29 21 3d 30 20 26 26 20 73 n,"GET")!=0 && s
7210: 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22 50 4f trcmp(zToken,"PO
7220: 53 54 22 29 21 3d 30 0a 20 20 20 20 20 20 26 26 ST")!=0. &&
7230: 20 73 74 72 63 6d 70 28 7a 54 6f 6b 65 6e 2c 22 strcmp(zToken,"
7240: 48 45 41 44 22 29 21 3d 30 20 29 7b 0a 20 20 20 HEAD")!=0 ){.
7250: 20 6d 61 6c 66 6f 72 6d 65 64 5f 72 65 71 75 65 malformed_reque
7260: 73 74 28 29 3b 0a 20 20 7d 0a 20 20 63 67 69 5f st();. }. cgi_
7270: 73 65 74 65 6e 76 28 22 47 41 54 45 57 41 59 5f setenv("GATEWAY_
7280: 49 4e 54 45 52 46 41 43 45 22 2c 22 43 47 49 2f INTERFACE","CGI/
7290: 31 2e 30 22 29 3b 0a 20 20 63 67 69 5f 73 65 74 1.0");. cgi_set
72a0: 65 6e 76 28 22 52 45 51 55 45 53 54 5f 4d 45 54 env("REQUEST_MET
72b0: 48 4f 44 22 2c 7a 54 6f 6b 65 6e 29 3b 0a 20 20 HOD",zToken);.
72c0: 7a 54 6f 6b 65 6e 20 3d 20 65 78 74 72 61 63 74 zToken = extract
72d0: 5f 74 6f 6b 65 6e 28 7a 2c 20 26 7a 29 3b 0a 20 _token(z, &z);.
72e0: 20 69 66 28 20 7a 54 6f 6b 65 6e 3d 3d 30 20 29 if( zToken==0 )
72f0: 7b 0a 20 20 20 20 6d 61 6c 66 6f 72 6d 65 64 5f {. malformed_
7300: 72 65 71 75 65 73 74 28 29 3b 0a 20 20 7d 0a 20 request();. }.
7310: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 52 45 51 cgi_setenv("REQ
7320: 55 45 53 54 5f 55 52 49 22 2c 20 7a 54 6f 6b 65 UEST_URI", zToke
7330: 6e 29 3b 0a 20 20 66 6f 72 28 69 3d 30 3b 20 7a n);. for(i=0; z
7340: 54 6f 6b 65 6e 5b 69 5d 20 26 26 20 7a 54 6f 6b Token[i] && zTok
7350: 65 6e 5b 69 5d 21 3d 27 3f 27 3b 20 69 2b 2b 29 en[i]!='?'; i++)
7360: 7b 7d 0a 20 20 69 66 28 20 7a 54 6f 6b 65 6e 5b {}. if( zToken[
7370: 69 5d 20 29 20 7a 54 6f 6b 65 6e 5b 69 2b 2b 5d i] ) zToken[i++]
7380: 20 3d 20 30 3b 0a 20 20 63 67 69 5f 73 65 74 65 = 0;. cgi_sete
7390: 6e 76 28 22 50 41 54 48 5f 49 4e 46 4f 22 2c 20 nv("PATH_INFO",
73a0: 7a 54 6f 6b 65 6e 29 3b 0a 20 20 63 67 69 5f 73 zToken);. cgi_s
73b0: 65 74 65 6e 76 28 22 51 55 45 52 59 5f 53 54 52 etenv("QUERY_STR
73c0: 49 4e 47 22 2c 20 26 7a 54 6f 6b 65 6e 5b 69 5d ING", &zToken[i]
73d0: 29 3b 0a 20 20 69 66 28 20 67 65 74 70 65 65 72 );. if( getpeer
73e0: 6e 61 6d 65 28 66 69 6c 65 6e 6f 28 73 74 64 69 name(fileno(stdi
73f0: 6e 29 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b n), (struct sock
7400: 61 64 64 72 2a 29 26 72 65 6d 6f 74 65 4e 61 6d addr*)&remoteNam
7410: 65 2c 20 28 73 6f 63 6b 6c 65 6e 5f 74 2a 29 26 e, (socklen_t*)&
7420: 73 69 7a 65 29 3e 3d 30 20 29 7b 0a 20 20 20 20 size)>=0 ){.
7430: 63 68 61 72 20 2a 7a 49 70 41 64 64 72 20 3d 20 char *zIpAddr =
7440: 69 6e 65 74 5f 6e 74 6f 61 28 72 65 6d 6f 74 65 inet_ntoa(remote
7450: 4e 61 6d 65 2e 73 69 6e 5f 61 64 64 72 29 3b 0a Name.sin_addr);.
7460: 20 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 cgi_setenv("
7470: 52 45 4d 4f 54 45 5f 41 44 44 52 22 2c 20 7a 49 REMOTE_ADDR", zI
7480: 70 41 64 64 72 29 3b 0a 0a 20 20 20 20 2f 2a 20 pAddr);.. /*
7490: 53 65 74 20 74 68 65 20 47 6c 6f 62 61 6c 2e 7a Set the Global.z
74a0: 49 70 41 64 64 72 20 76 61 72 69 61 62 6c 65 20 IpAddr variable
74b0: 74 6f 20 74 68 65 20 73 65 72 76 65 72 20 77 65 to the server we
74c0: 20 61 72 65 20 74 61 6c 6b 69 6e 67 20 74 6f 2e are talking to.
74d0: 0a 20 20 20 20 2a 2a 20 54 68 69 73 20 69 73 20 . ** This is
74e0: 75 73 65 64 20 74 6f 20 70 6f 70 75 6c 61 74 65 used to populate
74f0: 20 74 68 65 20 69 70 61 64 64 72 20 63 6f 6c 75 the ipaddr colu
7500: 6d 6e 20 6f 66 20 74 68 65 20 72 63 76 66 72 6f mn of the rcvfro
7510: 6d 20 74 61 62 6c 65 2c 0a 20 20 20 20 2a 2a 20 m table,. **
7520: 69 66 20 61 6e 79 20 66 69 6c 65 73 20 61 72 65 if any files are
7530: 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 74 received from t
7540: 68 65 20 63 6f 6e 6e 65 63 74 65 64 20 63 6c 69 he connected cli
7550: 65 6e 74 2e 0a 20 20 20 20 2a 2f 0a 20 20 20 20 ent.. */.
7560: 67 2e 7a 49 70 41 64 64 72 20 3d 20 6d 70 72 69 g.zIpAddr = mpri
7570: 6e 74 66 28 22 25 73 22 2c 20 7a 49 70 41 64 64 ntf("%s", zIpAdd
7580: 72 29 3b 0a 20 20 7d 0a 20 0a 20 20 2f 2a 20 47 r);. }. . /* G
7590: 65 74 20 61 6c 6c 20 74 68 65 20 6f 70 74 69 6f et all the optio
75a0: 6e 61 6c 20 66 69 65 6c 64 73 20 74 68 61 74 20 nal fields that
75b0: 66 6f 6c 6c 6f 77 20 74 68 65 20 66 69 72 73 74 follow the first
75c0: 20 6c 69 6e 65 2e 0a 20 20 2a 2f 0a 20 20 77 68 line.. */. wh
75d0: 69 6c 65 28 20 66 67 65 74 73 28 7a 4c 69 6e 65 ile( fgets(zLine
75e0: 2c 73 69 7a 65 6f 66 28 7a 4c 69 6e 65 29 2c 73 ,sizeof(zLine),s
75f0: 74 64 69 6e 29 20 29 7b 0a 20 20 20 20 63 68 61 tdin) ){. cha
7600: 72 20 2a 7a 46 69 65 6c 64 4e 61 6d 65 3b 0a 20 r *zFieldName;.
7610: 20 20 20 63 68 61 72 20 2a 7a 56 61 6c 3b 0a 0a char *zVal;..
7620: 20 20 20 20 7a 46 69 65 6c 64 4e 61 6d 65 20 3d zFieldName =
7630: 20 65 78 74 72 61 63 74 5f 74 6f 6b 65 6e 28 7a extract_token(z
7640: 4c 69 6e 65 2c 26 7a 56 61 6c 29 3b 0a 20 20 20 Line,&zVal);.
7650: 20 69 66 28 20 7a 46 69 65 6c 64 4e 61 6d 65 3d if( zFieldName=
7660: 3d 30 20 7c 7c 20 2a 7a 46 69 65 6c 64 4e 61 6d =0 || *zFieldNam
7670: 65 3d 3d 30 20 29 20 62 72 65 61 6b 3b 0a 20 20 e==0 ) break;.
7680: 20 20 77 68 69 6c 65 28 20 69 73 73 70 61 63 65 while( isspace
7690: 28 2a 7a 56 61 6c 29 20 29 7b 20 7a 56 61 6c 2b (*zVal) ){ zVal+
76a0: 2b 3b 20 7d 0a 20 20 20 20 69 20 3d 20 73 74 72 +; }. i = str
76b0: 6c 65 6e 28 7a 56 61 6c 29 3b 0a 20 20 20 20 77 len(zVal);. w
76c0: 68 69 6c 65 28 20 69 3e 30 20 26 26 20 69 73 73 hile( i>0 && iss
76d0: 70 61 63 65 28 7a 56 61 6c 5b 69 2d 31 5d 29 20 pace(zVal[i-1])
76e0: 29 7b 20 69 2d 2d 3b 20 7d 0a 20 20 20 20 7a 56 ){ i--; }. zV
76f0: 61 6c 5b 69 5d 20 3d 20 30 3b 0a 20 20 20 20 66 al[i] = 0;. f
7700: 6f 72 28 69 3d 30 3b 20 7a 46 69 65 6c 64 4e 61 or(i=0; zFieldNa
7710: 6d 65 5b 69 5d 3b 20 69 2b 2b 29 7b 20 7a 46 69 me[i]; i++){ zFi
7720: 65 6c 64 4e 61 6d 65 5b 69 5d 20 3d 20 74 6f 6c eldName[i] = tol
7730: 6f 77 65 72 28 7a 46 69 65 6c 64 4e 61 6d 65 5b ower(zFieldName[
7740: 69 5d 29 3b 20 7d 0a 20 20 20 20 69 66 28 20 73 i]); }. if( s
7750: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 trcmp(zFieldName
7760: 2c 22 75 73 65 72 2d 61 67 65 6e 74 3a 22 29 3d ,"user-agent:")=
7770: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f =0 ){. cgi_
7780: 73 65 74 65 6e 76 28 22 48 54 54 50 5f 55 53 45 setenv("HTTP_USE
7790: 52 5f 41 47 45 4e 54 22 2c 20 7a 56 61 6c 29 3b R_AGENT", zVal);
77a0: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 . }else if( s
77b0: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 trcmp(zFieldName
77c0: 2c 22 63 6f 6e 74 65 6e 74 2d 6c 65 6e 67 74 68 ,"content-length
77d0: 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 :")==0 ){.
77e0: 63 67 69 5f 73 65 74 65 6e 76 28 22 43 4f 4e 54 cgi_setenv("CONT
77f0: 45 4e 54 5f 4c 45 4e 47 54 48 22 2c 20 7a 56 61 ENT_LENGTH", zVa
7800: 6c 29 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 l);. }else if
7810: 28 20 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e ( strcmp(zFieldN
7820: 61 6d 65 2c 22 72 65 66 65 72 65 72 3a 22 29 3d ame,"referer:")=
7830: 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 67 69 5f =0 ){. cgi_
7840: 73 65 74 65 6e 76 28 22 48 54 54 50 5f 52 45 46 setenv("HTTP_REF
7850: 45 52 45 52 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 ERER", zVal);.
7860: 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 63 }else if( strc
7870: 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 68 mp(zFieldName,"h
7880: 6f 73 74 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 ost:")==0 ){.
7890: 20 20 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48 cgi_setenv("H
78a0: 54 54 50 5f 48 4f 53 54 22 2c 20 7a 56 61 6c 29 TTP_HOST", zVal)
78b0: 3b 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 ;. }else if(
78c0: 73 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d strcmp(zFieldNam
78d0: 65 2c 22 63 6f 6e 74 65 6e 74 2d 74 79 70 65 3a e,"content-type:
78e0: 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 20 63 ")==0 ){. c
78f0: 67 69 5f 73 65 74 65 6e 76 28 22 43 4f 4e 54 45 gi_setenv("CONTE
7900: 4e 54 5f 54 59 50 45 22 2c 20 7a 56 61 6c 29 3b NT_TYPE", zVal);
7910: 0a 20 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 . }else if( s
7920: 74 72 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 trcmp(zFieldName
7930: 2c 22 63 6f 6f 6b 69 65 3a 22 29 3d 3d 30 20 29 ,"cookie:")==0 )
7940: 7b 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 {. cgi_sete
7950: 6e 76 28 22 48 54 54 50 5f 43 4f 4f 4b 49 45 22 nv("HTTP_COOKIE"
7960: 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 20 7d 65 6c , zVal);. }el
7970: 73 65 20 69 66 28 20 73 74 72 63 6d 70 28 7a 46 se if( strcmp(zF
7980: 69 65 6c 64 4e 61 6d 65 2c 22 69 66 2d 6e 6f 6e ieldName,"if-non
7990: 65 2d 6d 61 74 63 68 3a 22 29 3d 3d 30 20 29 7b e-match:")==0 ){
79a0: 0a 20 20 20 20 20 20 63 67 69 5f 73 65 74 65 6e . cgi_seten
79b0: 76 28 22 48 54 54 50 5f 49 46 5f 4e 4f 4e 45 5f v("HTTP_IF_NONE_
79c0: 4d 41 54 43 48 22 2c 20 7a 56 61 6c 29 3b 0a 20 MATCH", zVal);.
79d0: 20 20 20 7d 65 6c 73 65 20 69 66 28 20 73 74 72 }else if( str
79e0: 63 6d 70 28 7a 46 69 65 6c 64 4e 61 6d 65 2c 22 cmp(zFieldName,"
79f0: 69 66 2d 6d 6f 64 69 66 69 65 64 2d 73 69 6e 63 if-modified-sinc
7a00: 65 3a 22 29 3d 3d 30 20 29 7b 0a 20 20 20 20 20 e:")==0 ){.
7a10: 20 63 67 69 5f 73 65 74 65 6e 76 28 22 48 54 54 cgi_setenv("HTT
7a20: 50 5f 49 46 5f 4d 4f 44 49 46 49 45 44 5f 53 49 P_IF_MODIFIED_SI
7a30: 4e 43 45 22 2c 20 7a 56 61 6c 29 3b 0a 20 20 20 NCE", zVal);.
7a40: 20 7d 0a 20 20 7d 0a 0a 20 20 63 67 69 5f 69 6e }. }.. cgi_in
7a50: 69 74 28 29 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 4d it();.}../*.** M
7a60: 61 78 69 6d 75 6d 20 6e 75 6d 62 65 72 20 6f 66 aximum number of
7a70: 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 65 73 child processes
7a80: 20 74 68 61 74 20 77 65 20 63 61 6e 20 68 61 76 that we can hav
7a90: 65 20 72 75 6e 6e 69 6e 67 0a 2a 2a 20 61 74 20 e running.** at
7aa0: 6f 6e 65 20 74 69 6d 65 20 62 65 66 6f 72 65 20 one time before
7ab0: 77 65 20 73 74 61 72 74 20 73 6c 6f 77 69 6e 67 we start slowing
7ac0: 20 74 68 69 6e 67 73 20 64 6f 77 6e 2e 0a 2a 2f things down..*/
7ad0: 0a 23 64 65 66 69 6e 65 20 4d 41 58 5f 50 41 52 .#define MAX_PAR
7ae0: 41 4c 4c 45 4c 20 32 0a 0a 2f 2a 0a 2a 2a 20 49 ALLEL 2../*.** I
7af0: 6d 70 6c 65 6d 65 6e 74 20 61 6e 20 48 54 54 50 mplement an HTTP
7b00: 20 73 65 72 76 65 72 20 64 61 65 6d 6f 6e 20 6c server daemon l
7b10: 69 73 74 65 6e 69 6e 67 20 6f 6e 20 70 6f 72 74 istening on port
7b20: 20 69 50 6f 72 74 2e 0a 2a 2a 0a 2a 2a 20 41 73 iPort..**.** As
7b30: 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 73 new connections
7b40: 20 61 72 72 69 76 65 2c 20 66 6f 72 6b 20 61 20 arrive, fork a
7b50: 63 68 69 6c 64 20 61 6e 64 20 6c 65 74 20 63 68 child and let ch
7b60: 69 6c 64 20 72 65 74 75 72 6e 0a 2a 2a 20 6f 75 ild return.** ou
7b70: 74 20 6f 66 20 74 68 69 73 20 70 72 6f 63 65 64 t of this proced
7b80: 75 72 65 20 63 61 6c 6c 2e 20 20 54 68 65 20 63 ure call. The c
7b90: 68 69 6c 64 20 77 69 6c 6c 20 68 61 6e 64 6c 65 hild will handle
7ba0: 20 74 68 65 20 72 65 71 75 65 73 74 2e 0a 2a 2a the request..**
7bb0: 20 54 68 65 20 70 61 72 65 6e 74 20 6e 65 76 65 The parent neve
7bc0: 72 20 72 65 74 75 72 6e 73 20 66 72 6f 6d 20 74 r returns from t
7bd0: 68 69 73 20 70 72 6f 63 65 64 75 72 65 2e 0a 2a his procedure..*
7be0: 2f 0a 76 6f 69 64 20 63 67 69 5f 68 74 74 70 5f /.void cgi_http_
7bf0: 73 65 72 76 65 72 28 69 6e 74 20 69 50 6f 72 74 server(int iPort
7c00: 29 7b 0a 23 69 66 64 65 66 20 5f 5f 4d 49 4e 47 ){.#ifdef __MING
7c10: 57 33 32 5f 5f 0a 20 20 66 70 72 69 6e 74 66 28 W32__. fprintf(
7c20: 73 74 64 65 72 72 2c 22 73 65 72 76 65 72 20 6e stderr,"server n
7c30: 6f 74 20 79 65 74 20 61 76 61 69 6c 61 62 6c 65 ot yet available
7c40: 20 69 6e 20 77 69 6e 64 6f 77 73 20 76 65 72 73 in windows vers
7c50: 69 6f 6e 20 6f 66 20 66 6f 73 73 69 6c 5c 6e 22 ion of fossil\n"
7c60: 29 3b 0a 20 20 65 78 69 74 28 31 29 3b 0a 23 65 );. exit(1);.#e
7c70: 6c 73 65 0a 20 20 69 6e 74 20 6c 69 73 74 65 6e lse. int listen
7c80: 65 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 er;
7c90: 20 20 20 2f 2a 20 54 68 65 20 73 65 72 76 65 72 /* The server
7ca0: 20 73 6f 63 6b 65 74 20 2a 2f 0a 20 20 69 6e 74 socket */. int
7cb0: 20 63 6f 6e 6e 65 63 74 69 6f 6e 3b 20 20 20 20 connection;
7cc0: 20 20 20 20 20 20 20 20 20 20 2f 2a 20 41 20 73 /* A s
7cd0: 6f 63 6b 65 74 20 66 6f 72 20 65 61 63 68 20 69 ocket for each i
7ce0: 6e 64 69 76 69 64 75 61 6c 20 63 6f 6e 6e 65 63 ndividual connec
7cf0: 74 69 6f 6e 20 2a 2f 0a 20 20 66 64 5f 73 65 74 tion */. fd_set
7d00: 20 72 65 61 64 66 64 73 3b 20 20 20 20 20 20 20 readfds;
7d10: 20 20 20 20 20 20 20 2f 2a 20 53 65 74 20 6f 66 /* Set of
7d20: 20 66 69 6c 65 20 64 65 73 63 72 69 70 74 6f 72 file descriptor
7d30: 73 20 66 6f 72 20 73 65 6c 65 63 74 28 29 20 2a s for select() *
7d40: 2f 0a 20 20 73 69 7a 65 5f 74 20 6c 65 6e 61 64 /. size_t lenad
7d50: 64 72 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 dr;
7d60: 20 2f 2a 20 4c 65 6e 67 74 68 20 6f 66 20 74 68 /* Length of th
7d70: 65 20 69 6e 61 64 64 72 20 73 74 72 75 63 74 75 e inaddr structu
7d80: 72 65 20 2a 2f 0a 20 20 69 6e 74 20 63 68 69 6c re */. int chil
7d90: 64 3b 20 20 20 20 20 20 20 20 20 20 20 20 20 20 d;
7da0: 20 20 20 20 20 2f 2a 20 50 49 44 20 6f 66 20 74 /* PID of t
7db0: 68 65 20 63 68 69 6c 64 20 70 72 6f 63 65 73 73 he child process
7dc0: 20 2a 2f 0a 20 20 69 6e 74 20 6e 63 68 69 6c 64 */. int nchild
7dd0: 72 65 6e 20 3d 20 30 3b 20 20 20 20 20 20 20 20 ren = 0;
7de0: 20 20 20 2f 2a 20 4e 75 6d 62 65 72 20 6f 66 20 /* Number of
7df0: 63 68 69 6c 64 20 70 72 6f 63 65 73 73 65 73 20 child processes
7e00: 2a 2f 0a 20 20 73 74 72 75 63 74 20 74 69 6d 65 */. struct time
7e10: 76 61 6c 20 64 65 6c 61 79 3b 20 20 20 20 20 20 val delay;
7e20: 20 20 2f 2a 20 48 6f 77 20 6c 6f 6e 67 20 74 6f /* How long to
7e30: 20 77 61 69 74 20 69 6e 73 69 64 65 20 73 65 6c wait inside sel
7e40: 65 63 74 28 29 20 2a 2f 0a 20 20 73 74 72 75 63 ect() */. struc
7e50: 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 20 69 6e t sockaddr_in in
7e60: 61 64 64 72 3b 20 20 20 2f 2a 20 54 68 65 20 73 addr; /* The s
7e70: 6f 63 6b 65 74 20 61 64 64 72 65 73 73 20 2a 2f ocket address */
7e80: 0a 20 20 69 6e 74 20 6f 70 74 20 3d 20 31 3b 20 . int opt = 1;
7e90: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
7ea0: 2f 2a 20 73 65 74 73 6f 63 6b 6f 70 74 20 66 6c /* setsockopt fl
7eb0: 61 67 20 2a 2f 0a 0a 20 20 6d 65 6d 73 65 74 28 ag */.. memset(
7ec0: 26 69 6e 61 64 64 72 2c 20 30 2c 20 73 69 7a 65 &inaddr, 0, size
7ed0: 6f 66 28 69 6e 61 64 64 72 29 29 3b 0a 20 20 69 of(inaddr));. i
7ee0: 6e 61 64 64 72 2e 73 69 6e 5f 66 61 6d 69 6c 79 naddr.sin_family
7ef0: 20 3d 20 41 46 5f 49 4e 45 54 3b 0a 20 20 69 6e = AF_INET;. in
7f00: 61 64 64 72 2e 73 69 6e 5f 61 64 64 72 2e 73 5f addr.sin_addr.s_
7f10: 61 64 64 72 20 3d 20 49 4e 41 44 44 52 5f 41 4e addr = INADDR_AN
7f20: 59 3b 0a 20 20 69 6e 61 64 64 72 2e 73 69 6e 5f Y;. inaddr.sin_
7f30: 70 6f 72 74 20 3d 20 68 74 6f 6e 73 28 69 50 6f port = htons(iPo
7f40: 72 74 29 3b 0a 20 20 6c 69 73 74 65 6e 65 72 20 rt);. listener
7f50: 3d 20 73 6f 63 6b 65 74 28 41 46 5f 49 4e 45 54 = socket(AF_INET
7f60: 2c 20 53 4f 43 4b 5f 53 54 52 45 41 4d 2c 20 30 , SOCK_STREAM, 0
7f70: 29 3b 0a 20 20 69 66 28 20 6c 69 73 74 65 6e 65 );. if( listene
7f80: 72 3c 30 20 29 7b 0a 20 20 20 20 66 70 72 69 6e r<0 ){. fprin
7f90: 74 66 28 73 74 64 65 72 72 2c 22 43 61 6e 27 74 tf(stderr,"Can't
7fa0: 20 63 72 65 61 74 65 20 61 20 73 6f 63 6b 65 74 create a socket
7fb0: 5c 6e 22 29 3b 0a 20 20 20 20 65 78 69 74 28 31 \n");. exit(1
7fc0: 29 3b 0a 20 20 7d 0a 0a 20 20 2f 2a 20 69 66 20 );. }.. /* if
7fd0: 77 65 20 63 61 6e 27 74 20 74 65 72 6d 69 6e 61 we can't termina
7fe0: 74 65 20 6e 69 63 65 6c 79 2c 20 61 74 20 6c 65 te nicely, at le
7ff0: 61 73 74 20 61 6c 6c 6f 77 20 74 68 65 20 73 6f ast allow the so
8000: 63 6b 65 74 20 74 6f 20 62 65 20 72 65 75 73 65 cket to be reuse
8010: 64 20 2a 2f 0a 20 20 73 65 74 73 6f 63 6b 6f 70 d */. setsockop
8020: 74 28 6c 69 73 74 65 6e 65 72 2c 53 4f 4c 5f 53 t(listener,SOL_S
8030: 4f 43 4b 45 54 2c 53 4f 5f 52 45 55 53 45 41 44 OCKET,SO_REUSEAD
8040: 44 52 2c 26 6f 70 74 2c 73 69 7a 65 6f 66 28 6f DR,&opt,sizeof(o
8050: 70 74 29 29 3b 0a 0a 20 20 69 66 28 20 62 69 6e pt));.. if( bin
8060: 64 28 6c 69 73 74 65 6e 65 72 2c 20 28 73 74 72 d(listener, (str
8070: 75 63 74 20 73 6f 63 6b 61 64 64 72 2a 29 26 69 uct sockaddr*)&i
8080: 6e 61 64 64 72 2c 20 73 69 7a 65 6f 66 28 69 6e naddr, sizeof(in
8090: 61 64 64 72 29 29 3c 30 20 29 7b 0a 20 20 20 20 addr))<0 ){.
80a0: 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c 22 fprintf(stderr,"
80b0: 43 61 6e 27 74 20 62 69 6e 64 20 74 6f 20 70 6f Can't bind to po
80c0: 72 74 20 25 64 5c 6e 22 2c 20 69 50 6f 72 74 29 rt %d\n", iPort)
80d0: 3b 0a 20 20 20 20 65 78 69 74 28 31 29 3b 0a 20 ;. exit(1);.
80e0: 20 7d 0a 20 20 6c 69 73 74 65 6e 28 6c 69 73 74 }. listen(list
80f0: 65 6e 65 72 2c 31 30 29 3b 0a 20 20 77 68 69 6c ener,10);. whil
8100: 65 28 20 31 20 29 7b 0a 20 20 20 20 69 66 28 20 e( 1 ){. if(
8110: 6e 63 68 69 6c 64 72 65 6e 3e 4d 41 58 5f 50 41 nchildren>MAX_PA
8120: 52 41 4c 4c 45 4c 20 29 7b 0a 20 20 20 20 20 20 RALLEL ){.
8130: 2f 2a 20 53 6c 6f 77 20 64 6f 77 6e 20 69 66 20 /* Slow down if
8140: 63 6f 6e 6e 65 63 74 69 6f 6e 73 20 61 72 65 20 connections are
8150: 61 72 72 69 76 69 6e 67 20 74 6f 6f 20 66 61 73 arriving too fas
8160: 74 20 2a 2f 0a 20 20 20 20 20 20 73 6c 65 65 70 t */. sleep
8170: 28 20 6e 63 68 69 6c 64 72 65 6e 2d 4d 41 58 5f ( nchildren-MAX_
8180: 50 41 52 41 4c 4c 45 4c 20 29 3b 0a 20 20 20 20 PARALLEL );.
8190: 7d 0a 20 20 20 20 64 65 6c 61 79 2e 74 76 5f 73 }. delay.tv_s
81a0: 65 63 20 3d 20 36 30 3b 0a 20 20 20 20 64 65 6c ec = 60;. del
81b0: 61 79 2e 74 76 5f 75 73 65 63 20 3d 20 30 3b 0a ay.tv_usec = 0;.
81c0: 20 20 20 20 46 44 5f 5a 45 52 4f 28 26 72 65 61 FD_ZERO(&rea
81d0: 64 66 64 73 29 3b 0a 20 20 20 20 46 44 5f 53 45 dfds);. FD_SE
81e0: 54 28 20 6c 69 73 74 65 6e 65 72 2c 20 26 72 65 T( listener, &re
81f0: 61 64 66 64 73 29 3b 0a 20 20 20 20 69 66 28 20 adfds);. if(
8200: 73 65 6c 65 63 74 28 20 6c 69 73 74 65 6e 65 72 select( listener
8210: 2b 31 2c 20 26 72 65 61 64 66 64 73 2c 20 30 2c +1, &readfds, 0,
8220: 20 30 2c 20 26 64 65 6c 61 79 29 20 29 7b 0a 20 0, &delay) ){.
8230: 20 20 20 20 20 6c 65 6e 61 64 64 72 20 3d 20 73 lenaddr = s
8240: 69 7a 65 6f 66 28 69 6e 61 64 64 72 29 3b 0a 20 izeof(inaddr);.
8250: 20 20 20 20 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 connection
8260: 3d 20 61 63 63 65 70 74 28 6c 69 73 74 65 6e 65 = accept(listene
8270: 72 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b 61 r, (struct socka
8280: 64 64 72 2a 29 26 69 6e 61 64 64 72 2c 20 28 73 ddr*)&inaddr, (s
8290: 6f 63 6b 6c 65 6e 5f 74 2a 29 20 26 6c 65 6e 61 ocklen_t*) &lena
82a0: 64 64 72 29 3b 0a 20 20 20 20 20 20 69 66 28 20 ddr);. if(
82b0: 63 6f 6e 6e 65 63 74 69 6f 6e 3e 3d 30 20 29 7b connection>=0 ){
82c0: 0a 20 20 20 20 20 20 20 20 63 68 69 6c 64 20 3d . child =
82d0: 20 66 6f 72 6b 28 29 3b 0a 20 20 20 20 20 20 20 fork();.
82e0: 20 69 66 28 20 63 68 69 6c 64 21 3d 30 20 29 7b if( child!=0 ){
82f0: 0a 20 20 20 20 20 20 20 20 20 20 69 66 28 20 63 . if( c
8300: 68 69 6c 64 3e 30 20 29 20 6e 63 68 69 6c 64 72 hild>0 ) nchildr
8310: 65 6e 2b 2b 3b 0a 20 20 20 20 20 20 20 20 20 20 en++;.
8320: 63 6c 6f 73 65 28 63 6f 6e 6e 65 63 74 69 6f 6e close(connection
8330: 29 3b 0a 20 20 20 20 20 20 20 20 7d 65 6c 73 65 );. }else
8340: 7b 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 {. clos
8350: 65 28 30 29 3b 0a 20 20 20 20 20 20 20 20 20 20 e(0);.
8360: 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b dup(connection);
8370: 0a 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 . close
8380: 28 31 29 3b 0a 20 20 20 20 20 20 20 20 20 20 64 (1);. d
8390: 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 3b 0a up(connection);.
83a0: 20 20 20 20 20 20 20 20 20 20 69 66 28 20 21 67 if( !g
83b0: 2e 66 48 74 74 70 54 72 61 63 65 20 29 7b 0a 20 .fHttpTrace ){.
83c0: 20 20 20 20 20 20 20 20 20 20 20 63 6c 6f 73 65 close
83d0: 28 32 29 3b 0a 20 20 20 20 20 20 20 20 20 20 20 (2);.
83e0: 20 64 75 70 28 63 6f 6e 6e 65 63 74 69 6f 6e 29 dup(connection)
83f0: 3b 0a 20 20 20 20 20 20 20 20 20 20 7d 0a 20 20 ;. }.
8400: 20 20 20 20 20 20 20 20 63 6c 6f 73 65 28 63 6f close(co
8410: 6e 6e 65 63 74 69 6f 6e 29 3b 0a 20 20 20 20 20 nnection);.
8420: 20 20 20 20 20 72 65 74 75 72 6e 3b 0a 20 20 20 return;.
8430: 20 20 20 20 20 7d 0a 20 20 20 20 20 20 7d 0a 20 }. }.
8440: 20 20 20 7d 0a 20 20 20 20 2f 2a 20 42 75 72 79 }. /* Bury
8450: 20 64 65 61 64 20 63 68 69 6c 64 72 65 6e 20 2a dead children *
8460: 2f 0a 20 20 20 20 77 68 69 6c 65 28 20 77 61 69 /. while( wai
8470: 74 70 69 64 28 30 2c 20 30 2c 20 57 4e 4f 48 41 tpid(0, 0, WNOHA
8480: 4e 47 29 3e 30 20 29 7b 0a 20 20 20 20 20 20 6e NG)>0 ){. n
8490: 63 68 69 6c 64 72 65 6e 2d 2d 3b 0a 20 20 20 20 children--;.
84a0: 7d 0a 20 20 7d 0a 20 20 2f 2a 20 4e 4f 54 20 52 }. }. /* NOT R
84b0: 45 41 43 48 45 44 20 2a 2f 20 20 0a 20 20 65 78 EACHED */ . ex
84c0: 69 74 28 31 29 3b 0a 23 65 6e 64 69 66 0a 7d 0a it(1);.#endif.}.
84d0: 0a 2f 2a 0a 2a 2a 20 4e 61 6d 65 20 6f 66 20 64 ./*.** Name of d
84e0: 61 79 73 20 61 6e 64 20 6d 6f 6e 74 68 73 2e 0a ays and months..
84f0: 2a 2f 0a 73 74 61 74 69 63 20 63 6f 6e 73 74 20 */.static const
8500: 63 68 61 72 20 2a 61 7a 44 61 79 73 5b 5d 20 3d char *azDays[] =
8510: 0a 20 20 20 20 7b 22 53 75 6e 22 2c 20 22 4d 6f . {"Sun", "Mo
8520: 6e 22 2c 20 22 54 75 65 22 2c 20 22 57 65 64 22 n", "Tue", "Wed"
8530: 2c 20 22 54 68 75 22 2c 20 22 46 72 69 22 2c 20 , "Thu", "Fri",
8540: 22 53 61 74 22 2c 20 30 7d 3b 0a 73 74 61 74 69 "Sat", 0};.stati
8550: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 7a c const char *az
8560: 4d 6f 6e 74 68 73 5b 5d 20 3d 0a 20 20 20 20 7b Months[] =. {
8570: 22 4a 61 6e 22 2c 20 22 46 65 62 22 2c 20 22 4d "Jan", "Feb", "M
8580: 61 72 22 2c 20 22 41 70 72 22 2c 20 22 4d 61 79 ar", "Apr", "May
8590: 22 2c 20 22 4a 75 6e 22 2c 0a 20 20 20 20 20 22 ", "Jun",. "
85a0: 4a 75 6c 22 2c 20 22 41 75 67 22 2c 20 22 53 65 Jul", "Aug", "Se
85b0: 70 22 2c 20 22 4f 63 74 22 2c 20 22 4e 6f 76 22 p", "Oct", "Nov"
85c0: 2c 20 22 44 65 63 22 2c 20 30 7d 3b 0a 0a 0a 2f , "Dec", 0};.../
85d0: 2a 0a 2a 2a 20 52 65 74 75 72 6e 73 20 61 6e 20 *.** Returns an
85e0: 52 46 43 38 32 32 2d 66 6f 72 6d 61 74 74 65 64 RFC822-formatted
85f0: 20 74 69 6d 65 20 73 74 72 69 6e 67 20 73 75 69 time string sui
8600: 74 61 62 6c 65 20 66 6f 72 20 48 54 54 50 20 68 table for HTTP h
8610: 65 61 64 65 72 73 2c 20 61 6d 6f 6e 67 0a 2a 2a eaders, among.**
8620: 20 6f 74 68 65 72 20 74 68 69 6e 67 73 2e 0a 2a other things..*
8630: 2a 20 52 65 74 75 72 6e 65 64 20 74 69 6d 65 7a * Returned timez
8640: 6f 6e 65 20 69 73 20 61 6c 77 61 79 73 20 47 4d one is always GM
8650: 54 20 61 73 20 72 65 71 75 69 72 65 64 20 62 79 T as required by
8660: 20 48 54 54 50 2f 31 2e 31 20 73 70 65 63 69 66 HTTP/1.1 specif
8670: 69 63 61 74 69 6f 6e 2e 0a 2a 2a 0a 2a 2a 20 53 ication..**.** S
8680: 65 65 20 68 74 74 70 3a 2f 2f 77 77 77 2e 66 61 ee http://www.fa
8690: 71 73 2e 6f 72 67 2f 72 66 63 73 2f 72 66 63 38 qs.org/rfcs/rfc8
86a0: 32 32 2e 68 74 6d 6c 2c 20 73 65 63 74 69 6f 6e 22.html, section
86b0: 20 35 0a 2a 2a 20 61 6e 64 20 68 74 74 70 3a 2f 5.** and http:/
86c0: 2f 77 77 77 2e 66 61 71 73 2e 6f 72 67 2f 72 66 /www.faqs.org/rf
86d0: 63 73 2f 72 66 63 32 36 31 36 2e 68 74 6d 6c 2c cs/rfc2616.html,
86e0: 20 73 65 63 74 69 6f 6e 20 33 2e 33 2e 0a 2a 2f section 3.3..*/
86f0: 0a 63 68 61 72 20 2a 63 67 69 5f 72 66 63 38 32 .char *cgi_rfc82
8700: 32 5f 64 61 74 65 73 74 61 6d 70 28 74 69 6d 65 2_datestamp(time
8710: 5f 74 20 6e 6f 77 29 7b 0a 20 20 73 74 72 75 63 _t now){. struc
8720: 74 20 74 6d 20 2a 70 54 6d 3b 0a 20 20 70 54 6d t tm *pTm;. pTm
8730: 20 3d 20 67 6d 74 69 6d 65 28 26 6e 6f 77 29 3b = gmtime(&now);
8740: 0a 20 20 69 66 28 20 70 54 6d 3d 3d 30 20 29 20 . if( pTm==0 )
8750: 72 65 74 75 72 6e 20 22 22 3b 0a 20 20 72 65 74 return "";. ret
8760: 75 72 6e 20 6d 70 72 69 6e 74 66 28 22 25 73 2c urn mprintf("%s,
8770: 20 25 64 20 25 73 20 25 30 32 64 20 25 30 32 64 %d %s %02d %02d
8780: 3a 25 30 32 64 3a 25 30 32 64 20 47 4d 54 22 2c :%02d:%02d GMT",
8790: 0a 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 .
87a0: 20 20 61 7a 44 61 79 73 5b 70 54 6d 2d 3e 74 6d azDays[pTm->tm
87b0: 5f 77 64 61 79 5d 2c 20 70 54 6d 2d 3e 74 6d 5f _wday], pTm->tm_
87c0: 6d 64 61 79 2c 20 61 7a 4d 6f 6e 74 68 73 5b 70 mday, azMonths[p
87d0: 54 6d 2d 3e 74 6d 5f 6d 6f 6e 5d 2c 0a 20 20 20 Tm->tm_mon],.
87e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 70 54 pT
87f0: 6d 2d 3e 74 6d 5f 79 65 61 72 2b 31 39 30 30 2c m->tm_year+1900,
8800: 20 70 54 6d 2d 3e 74 6d 5f 68 6f 75 72 2c 20 70 pTm->tm_hour, p
8810: 54 6d 2d 3e 74 6d 5f 6d 69 6e 2c 20 70 54 6d 2d Tm->tm_min, pTm-
8820: 3e 74 6d 5f 73 65 63 29 3b 0a 7d 0a 0a 2f 2a 0a >tm_sec);.}../*.
8830: 2a 2a 20 50 61 72 73 65 20 61 6e 20 52 46 43 38 ** Parse an RFC8
8840: 32 32 2d 66 6f 72 6d 61 74 74 65 64 20 74 69 6d 22-formatted tim
8850: 65 73 74 61 6d 70 20 61 73 20 77 65 27 64 20 65 estamp as we'd e
8860: 78 70 65 63 74 20 66 72 6f 6d 20 48 54 54 50 20 xpect from HTTP
8870: 61 6e 64 20 72 65 74 75 72 6e 0a 2a 2a 20 61 20 and return.** a
8880: 55 6e 69 78 20 65 70 6f 63 68 20 74 69 6d 65 2e Unix epoch time.
8890: 20 3c 3d 20 7a 65 72 6f 20 69 73 20 72 65 74 75 <= zero is retu
88a0: 72 6e 65 64 20 6f 6e 20 66 61 69 6c 75 72 65 2e rned on failure.
88b0: 0a 2a 2a 0a 2a 2a 20 4e 6f 74 65 20 74 68 61 74 .**.** Note that
88c0: 20 74 68 69 73 20 77 6f 6e 27 74 20 68 61 6e 64 this won't hand
88d0: 6c 65 20 61 6c 6c 20 74 68 65 20 5f 61 6c 6c 6f le all the _allo
88e0: 77 65 64 5f 20 48 54 54 50 20 66 6f 72 6d 61 74 wed_ HTTP format
88f0: 73 2c 20 6a 75 73 74 20 74 68 65 0a 2a 2a 20 6d s, just the.** m
8900: 6f 73 74 20 70 6f 70 75 6c 61 72 20 6f 6e 65 20 ost popular one
8910: 28 74 68 65 20 6f 6e 65 20 67 65 6e 65 72 61 74 (the one generat
8920: 65 64 20 62 79 20 63 67 69 5f 72 66 63 38 32 32 ed by cgi_rfc822
8930: 5f 64 61 74 65 73 74 61 6d 70 28 29 2c 20 61 63 _datestamp(), ac
8940: 74 75 61 6c 6c 79 29 2e 0a 2a 2f 0a 74 69 6d 65 tually)..*/.time
8950: 5f 74 20 63 67 69 5f 72 66 63 38 32 32 5f 70 61 _t cgi_rfc822_pa
8960: 72 73 65 64 61 74 65 28 63 6f 6e 73 74 20 63 68 rsedate(const ch
8970: 61 72 20 2a 7a 44 61 74 65 29 7b 0a 20 20 73 74 ar *zDate){. st
8980: 72 75 63 74 20 74 6d 20 74 3b 0a 20 20 63 68 61 ruct tm t;. cha
8990: 72 20 7a 49 67 6e 6f 72 65 5b 31 36 5d 3b 0a 20 r zIgnore[16];.
89a0: 20 63 68 61 72 20 7a 4d 6f 6e 74 68 5b 31 36 5d char zMonth[16]
89b0: 3b 0a 0a 20 20 6d 65 6d 73 65 74 28 26 74 2c 20 ;.. memset(&t,
89c0: 30 2c 20 73 69 7a 65 6f 66 28 74 29 29 3b 0a 20 0, sizeof(t));.
89d0: 20 69 66 28 20 37 3d 3d 73 73 63 61 6e 66 28 7a if( 7==sscanf(z
89e0: 44 61 74 65 2c 20 22 25 31 32 5b 41 2d 5a 61 2d Date, "%12[A-Za-
89f0: 7a 2c 5d 20 25 64 20 25 31 32 5b 41 2d 5a 61 2d z,] %d %12[A-Za-
8a00: 7a 5d 20 25 64 20 25 64 3a 25 64 3a 25 64 22 2c z] %d %d:%d:%d",
8a10: 20 7a 49 67 6e 6f 72 65 2c 0a 20 20 20 20 20 20 zIgnore,.
8a20: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
8a30: 20 26 74 2e 74 6d 5f 6d 64 61 79 2c 20 7a 4d 6f &t.tm_mday, zMo
8a40: 6e 74 68 2c 20 26 74 2e 74 6d 5f 79 65 61 72 2c nth, &t.tm_year,
8a50: 20 26 74 2e 74 6d 5f 68 6f 75 72 2c 20 26 74 2e &t.tm_hour, &t.
8a60: 74 6d 5f 6d 69 6e 2c 0a 20 20 20 20 20 20 20 20 tm_min,.
8a70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 26 &
8a80: 74 2e 74 6d 5f 73 65 63 29 29 7b 0a 0a 20 20 20 t.tm_sec)){..
8a90: 20 69 66 28 20 74 2e 74 6d 5f 79 65 61 72 20 3e if( t.tm_year >
8aa0: 20 31 39 30 30 20 29 20 74 2e 74 6d 5f 79 65 61 1900 ) t.tm_yea
8ab0: 72 20 2d 3d 20 31 39 30 30 3b 0a 20 20 20 20 66 r -= 1900;. f
8ac0: 6f 72 28 74 2e 74 6d 5f 6d 6f 6e 3d 30 3b 20 61 or(t.tm_mon=0; a
8ad0: 7a 4d 6f 6e 74 68 73 5b 74 2e 74 6d 5f 6d 6f 6e zMonths[t.tm_mon
8ae0: 5d 3b 20 74 2e 74 6d 5f 6d 6f 6e 2b 2b 29 7b 0a ]; t.tm_mon++){.
8af0: 20 20 20 20 20 20 69 66 28 20 21 73 74 72 6e 63 if( !strnc
8b00: 61 73 65 63 6d 70 28 20 61 7a 4d 6f 6e 74 68 73 asecmp( azMonths
8b10: 5b 74 2e 74 6d 5f 6d 6f 6e 5d 2c 20 7a 4d 6f 6e [t.tm_mon], zMon
8b20: 74 68 2c 20 33 20 29 29 7b 0a 20 20 20 20 20 20 th, 3 )){.
8b30: 20 20 72 65 74 75 72 6e 20 6d 6b 67 6d 74 69 6d return mkgmtim
8b40: 65 28 26 74 29 3b 0a 20 20 20 20 20 20 7d 0a 20 e(&t);. }.
8b50: 20 20 20 7d 0a 20 20 7d 0a 0a 20 20 72 65 74 75 }. }.. retu
8b60: 72 6e 20 30 3b 0a 7d 0a 0a 2f 2a 0a 2a 2a 20 43 rn 0;.}../*.** C
8b70: 6f 6e 76 65 72 74 20 61 20 73 74 72 75 63 74 20 onvert a struct
8b80: 74 6d 2a 20 74 68 61 74 20 72 65 70 72 65 73 65 tm* that represe
8b90: 6e 74 73 20 61 20 6d 6f 6d 65 6e 74 20 69 6e 20 nts a moment in
8ba0: 55 54 43 20 69 6e 74 6f 20 74 68 65 20 6e 75 6d UTC into the num
8bb0: 62 65 72 0a 2a 2a 20 6f 66 20 73 65 63 6f 6e 64 ber.** of second
8bc0: 73 20 69 6e 20 31 39 37 30 2c 20 55 54 43 2e 0a s in 1970, UTC..
8bd0: 2a 2f 0a 74 69 6d 65 5f 74 20 6d 6b 67 6d 74 69 */.time_t mkgmti
8be0: 6d 65 28 73 74 72 75 63 74 20 74 6d 20 2a 70 29 me(struct tm *p)
8bf0: 7b 0a 20 20 74 69 6d 65 5f 74 20 74 3b 0a 20 20 {. time_t t;.
8c00: 69 6e 74 20 6e 44 61 79 3b 0a 20 20 69 6e 74 20 int nDay;. int
8c10: 69 73 4c 65 61 70 59 72 3b 0a 20 20 2f 2a 20 44 isLeapYr;. /* D
8c20: 61 79 73 20 69 6e 20 65 61 63 68 20 6d 6f 6e 74 ays in each mont
8c30: 68 3a 20 20 20 20 20 20 20 33 31 2c 20 32 38 2c h: 31, 28,
8c40: 20 33 31 2c 20 33 30 2c 20 33 31 2c 20 33 30 2c 31, 30, 31, 30,
8c50: 20 33 31 2c 20 33 31 2c 20 33 30 2c 20 33 31 2c 31, 31, 30, 31,
8c60: 20 33 30 2c 20 33 31 20 2a 2f 0a 20 20 73 74 61 30, 31 */. sta
8c70: 74 69 63 20 69 6e 74 20 70 72 69 6f 72 44 61 79 tic int priorDay
8c80: 73 5b 5d 20 20 20 3d 20 7b 20 20 30 2c 20 33 31 s[] = { 0, 31
8c90: 2c 20 35 39 2c 20 39 30 2c 31 32 30 2c 31 35 31 , 59, 90,120,151
8ca0: 2c 31 38 31 2c 32 31 32 2c 32 34 33 2c 32 37 33 ,181,212,243,273
8cb0: 2c 33 30 34 2c 33 33 34 20 7d 3b 0a 20 20 69 66 ,304,334 };. if
8cc0: 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3c 30 20 29 7b ( p->tm_mon<0 ){
8cd0: 0a 20 20 20 20 69 6e 74 20 6e 59 65 61 72 20 3d . int nYear =
8ce0: 20 28 31 31 20 2d 20 70 2d 3e 74 6d 5f 6d 6f 6e (11 - p->tm_mon
8cf0: 29 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f )/12;. p->tm_
8d00: 79 65 61 72 20 2d 3d 20 6e 59 65 61 72 3b 0a 20 year -= nYear;.
8d10: 20 20 20 70 2d 3e 74 6d 5f 6d 6f 6e 20 2b 3d 20 p->tm_mon +=
8d20: 6e 59 65 61 72 2a 31 32 3b 0a 20 20 7d 65 6c 73 nYear*12;. }els
8d30: 65 20 69 66 28 20 70 2d 3e 74 6d 5f 6d 6f 6e 3e e if( p->tm_mon>
8d40: 31 31 20 29 7b 0a 20 20 20 20 70 2d 3e 74 6d 5f 11 ){. p->tm_
8d50: 79 65 61 72 20 2b 3d 20 70 2d 3e 74 6d 5f 6d 6f year += p->tm_mo
8d60: 6e 2f 31 32 3b 0a 20 20 20 20 70 2d 3e 74 6d 5f n/12;. p->tm_
8d70: 6d 6f 6e 20 25 3d 20 31 32 3b 0a 20 20 7d 0a 20 mon %= 12;. }.
8d80: 20 69 73 4c 65 61 70 59 72 20 3d 20 70 2d 3e 74 isLeapYr = p->t
8d90: 6d 5f 79 65 61 72 25 34 3d 3d 30 20 26 26 20 28 m_year%4==0 && (
8da0: 70 2d 3e 74 6d 5f 79 65 61 72 25 31 30 30 21 3d p->tm_year%100!=
8db0: 30 20 7c 7c 20 28 70 2d 3e 74 6d 5f 79 65 61 72 0 || (p->tm_year
8dc0: 2b 33 30 30 29 25 34 30 30 3d 3d 30 29 3b 0a 20 +300)%400==0);.
8dd0: 20 70 2d 3e 74 6d 5f 79 64 61 79 20 3d 20 70 72 p->tm_yday = pr
8de0: 69 6f 72 44 61 79 73 5b 70 2d 3e 74 6d 5f 6d 6f iorDays[p->tm_mo
8df0: 6e 5d 20 2b 20 70 2d 3e 74 6d 5f 6d 64 61 79 20 n] + p->tm_mday
8e00: 2d 20 31 3b 0a 20 20 69 66 28 20 69 73 4c 65 61 - 1;. if( isLea
8e10: 70 59 72 20 26 26 20 70 2d 3e 74 6d 5f 6d 6f 6e pYr && p->tm_mon
8e20: 3e 31 20 29 20 70 2d 3e 74 6d 5f 79 64 61 79 2b >1 ) p->tm_yday+
8e30: 2b 3b 0a 20 20 6e 44 61 79 20 3d 20 28 70 2d 3e +;. nDay = (p->
8e40: 74 6d 5f 79 65 61 72 2d 37 30 29 2a 33 36 35 20 tm_year-70)*365
8e50: 2b 20 28 70 2d 3e 74 6d 5f 79 65 61 72 2d 36 39 + (p->tm_year-69
8e60: 29 2f 34 20 2d 70 2d 3e 74 6d 5f 79 65 61 72 2f )/4 -p->tm_year/
8e70: 31 30 30 20 2b 20 0a 20 20 20 20 20 20 20 20 20 100 + .
8e80: 28 70 2d 3e 74 6d 5f 79 65 61 72 2b 33 30 30 29 (p->tm_year+300)
8e90: 2f 34 30 30 20 2b 20 70 2d 3e 74 6d 5f 79 64 61 /400 + p->tm_yda
8ea0: 79 3b 0a 20 20 74 20 3d 20 28 28 6e 44 61 79 2a y;. t = ((nDay*
8eb0: 32 34 20 2b 20 70 2d 3e 74 6d 5f 68 6f 75 72 29 24 + p->tm_hour)
8ec0: 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 6d 69 6e 29 *60 + p->tm_min)
8ed0: 2a 36 30 20 2b 20 70 2d 3e 74 6d 5f 73 65 63 3b *60 + p->tm_sec;
8ee0: 0a 20 20 72 65 74 75 72 6e 20 74 3b 0a 7d 0a 0a . return t;.}..
8ef0: 2f 2a 0a 2a 2a 20 43 68 65 63 6b 20 74 68 65 20 /*.** Check the
8f00: 6f 62 6a 65 63 74 54 69 6d 65 20 61 67 61 69 6e objectTime again
8f10: 73 74 20 74 68 65 20 49 66 2d 4d 6f 64 69 66 69 st the If-Modifi
8f20: 65 64 2d 53 69 6e 63 65 20 72 65 71 75 65 73 74 ed-Since request
8f30: 20 68 65 61 64 65 72 2e 20 49 66 20 74 68 65 0a header. If the.
8f40: 2a 2a 20 6f 62 6a 65 63 74 20 74 69 6d 65 20 69 ** object time i
8f50: 73 6e 27 74 20 61 6e 79 20 6e 65 77 65 72 20 74 sn't any newer t
8f60: 68 61 6e 20 74 68 65 20 68 65 61 64 65 72 2c 20 han the header,
8f70: 77 65 20 69 6d 6d 65 64 69 61 74 65 6c 79 20 73 we immediately s
8f80: 65 6e 64 20 62 61 63 6b 0a 2a 2a 20 61 20 33 30 end back.** a 30
8f90: 34 20 72 65 70 6c 79 20 61 6e 64 20 65 78 69 74 4 reply and exit
8fa0: 2e 0a 2a 2f 0a 76 6f 69 64 20 63 67 69 5f 6d 6f ..*/.void cgi_mo
8fb0: 64 69 66 69 65 64 5f 73 69 6e 63 65 28 74 69 6d dified_since(tim
8fc0: 65 5f 74 20 6f 62 6a 65 63 74 54 69 6d 65 29 7b e_t objectTime){
8fd0: 0a 20 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 7a . const char *z
8fe0: 49 66 20 3d 20 50 28 22 48 54 54 50 5f 49 46 5f If = P("HTTP_IF_
8ff0: 4d 4f 44 49 46 49 45 44 5f 53 49 4e 43 45 22 29 MODIFIED_SINCE")
9000: 3b 0a 20 20 69 66 28 20 7a 49 66 3d 3d 30 20 29 ;. if( zIf==0 )
9010: 20 72 65 74 75 72 6e 3b 0a 20 20 69 66 28 20 6f return;. if( o
9020: 62 6a 65 63 74 54 69 6d 65 20 3e 20 63 67 69 5f bjectTime > cgi_
9030: 72 66 63 38 32 32 5f 70 61 72 73 65 64 61 74 65 rfc822_parsedate
9040: 28 7a 49 66 29 20 29 20 72 65 74 75 72 6e 3b 0a (zIf) ) return;.
9050: 20 20 63 67 69 5f 73 65 74 5f 73 74 61 74 75 73 cgi_set_status
9060: 28 33 30 34 2c 22 4e 6f 74 20 4d 6f 64 69 66 69 (304,"Not Modifi
9070: 65 64 22 29 3b 0a 20 20 63 67 69 5f 72 65 73 65 ed");. cgi_rese
9080: 74 5f 63 6f 6e 74 65 6e 74 28 29 3b 0a 20 20 63 t_content();. c
9090: 67 69 5f 72 65 70 6c 79 28 29 3b 0a 20 20 65 78 gi_reply();. ex
90a0: 69 74 28 30 29 3b 0a 7d 0a it(0);.}.