0000: 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65 #include <sys/se
0010: 6e 64 66 69 6c 65 2e 68 3e 0a 23 69 6e 63 6c 75 ndfile.h>.#inclu
0020: 64 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68 de <sys/socket.h
0030: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f >.#include <sys/
0040: 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 types.h>.#includ
0050: 65 20 3c 61 72 70 61 2f 69 6e 65 74 2e 68 3e 0a e <arpa/inet.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 6d 6d #include <sys/mm
0070: 61 6e 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c an.h>.#include <
0080: 73 79 73 2f 73 74 61 74 2e 68 3e 0a 23 69 6e 63 sys/stat.h>.#inc
0090: 6c 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e lude <pthread.h>
00a0: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e .#include <strin
00b0: 67 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c gs.h>.#include <
00c0: 73 69 67 6e 61 6c 2e 68 3e 0a 23 69 6e 63 6c 75 signal.h>.#inclu
00d0: 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69 de <stdlib.h>.#i
00e0: 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68 nclude <unistd.h
00f0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 >.#include <stri
0100: 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c ng.h>.#include <
0110: 67 65 74 6f 70 74 2e 68 3e 0a 23 69 6e 63 6c 75 getopt.h>.#inclu
0120: 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23 69 6e de <fcntl.h>.#in
0130: 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e 0a clude <stdio.h>.
0140: 23 69 6e 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e #include <errno.
0150: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74 69 6d h>.#include <tim
0160: 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 e.h>.#include <p
0170: 77 64 2e 68 3e 0a 0a 2f 2a 20 43 6f 6d 70 69 6c wd.h>../* Compil
0180: 65 20 74 69 6d 65 20 63 6f 6e 73 74 61 6e 74 73 e time constants
0190: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 49 4c 45 */.#define FILE
01a0: 44 5f 53 45 4e 44 46 49 4c 45 5f 4d 41 58 20 31 D_SENDFILE_MAX 1
01b0: 36 37 37 37 32 31 35 0a 23 64 65 66 69 6e 65 20 6777215.#define
01c0: 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f 55 4e MAX_FAILURE_COUN
01d0: 54 20 33 30 0a 0a 2f 2a 20 44 65 66 61 75 6c 74 T 30../* Default
01e0: 20 76 61 6c 75 65 73 20 2a 2f 0a 23 64 65 66 69 values */.#defi
01f0: 6e 65 20 50 4f 52 54 20 38 30 0a 23 64 65 66 69 ne PORT 80.#defi
0200: 6e 65 20 54 48 52 45 41 44 5f 43 4f 55 4e 54 20 ne THREAD_COUNT
0210: 35 0a 23 64 65 66 69 6e 65 20 42 49 4e 44 5f 41 5.#define BIND_A
0220: 44 44 52 20 22 3a 3a 22 0a 23 64 65 66 69 6e 65 DDR "::".#define
0230: 20 43 41 43 48 45 5f 53 49 5a 45 20 38 32 30 39 CACHE_SIZE 8209
0240: 0a 0a 2f 2a 20 41 72 67 75 6d 65 6e 74 73 20 66 ../* Arguments f
0250: 6f 72 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 or worker thread
0260: 73 20 2a 2f 0a 73 74 72 75 63 74 20 66 69 6c 65 s */.struct file
0270: 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f d_worker_thread_
0280: 61 72 67 73 20 7b 0a 09 69 6e 74 20 66 64 3b 0a args {..int fd;.
0290: 7d 3b 0a 0a 2f 2a 20 46 69 6c 65 20 69 6e 66 6f };../* File info
02a0: 72 6d 61 74 69 6f 6e 20 2a 2f 0a 73 74 72 75 63 rmation */.struc
02b0: 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f t filed_fileinfo
02c0: 20 7b 0a 09 70 74 68 72 65 61 64 5f 6d 75 74 65 {..pthread_mute
02d0: 78 5f 74 20 6d 75 74 65 78 3b 0a 09 63 68 61 72 x_t mutex;..char
02e0: 20 2a 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b *path;..int fd;
02f0: 0a 09 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 63 68 ..off_t len;..ch
0300: 61 72 20 2a 6c 61 73 74 6d 6f 64 3b 0a 09 63 68 ar *lastmod;..ch
0310: 61 72 20 6c 61 73 74 6d 6f 64 5f 62 5b 36 34 5d ar lastmod_b[64]
0320: 3b 0a 09 63 68 61 72 20 2a 74 79 70 65 3b 0a 7d ;..char *type;.}
0330: 3b 0a 0a 2f 2a 20 52 65 71 75 65 73 74 20 76 61 ;../* Request va
0340: 72 69 61 62 6c 65 73 20 2a 2f 0a 73 74 72 75 63 riables */.struc
0350: 74 20 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 71 t filed_http_req
0360: 75 65 73 74 20 7b 0a 09 2f 2a 2a 20 42 75 66 66 uest {../** Buff
0370: 65 72 73 20 2a 2a 2f 0a 09 73 74 72 75 63 74 20 ers **/..struct
0380: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 66 filed_fileinfo f
0390: 69 6c 65 69 6e 66 6f 3b 0a 09 63 68 61 72 20 70 ileinfo;..char p
03a0: 61 74 68 5f 62 5b 31 30 31 30 5d 3b 0a 09 63 68 ath_b[1010];..ch
03b0: 61 72 20 74 6d 70 62 75 66 5b 31 30 31 30 5d 3b ar tmpbuf[1010];
03c0: 0a 0a 09 2f 2a 2a 20 48 54 54 50 20 52 65 71 75 .../** HTTP Requ
03d0: 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 est information
03e0: 2a 2a 2f 0a 09 63 68 61 72 20 2a 70 61 74 68 3b **/..char *path;
03f0: 20 20 20 20 20 2f 2a 2a 2a 20 50 61 74 68 20 62 /*** Path b
0400: 65 69 6e 67 20 72 65 71 75 65 73 74 65 64 20 2a eing requested *
0410: 2a 2a 2f 0a 0a 09 73 74 72 75 63 74 20 7b 0a 09 **/...struct {..
0420: 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 .struct {....int
0430: 20 70 72 65 73 65 6e 74 3b 0a 09 09 09 6f 66 66 present;....off
0440: 5f 74 20 6f 66 66 73 65 74 3b 20 20 20 2f 2a 2a _t offset; /**
0450: 2a 20 52 61 6e 67 65 20 73 74 61 72 74 20 2a 2a * Range start **
0460: 2a 2f 0a 09 09 09 6f 66 66 5f 74 20 6c 65 6e 67 */....off_t leng
0470: 74 68 3b 20 20 20 2f 2a 2a 2a 20 52 61 6e 67 65 th; /*** Range
0480: 20 6c 65 6e 67 74 68 20 2a 2a 2a 2f 0a 09 09 7d length ***/...}
0490: 20 72 61 6e 67 65 3b 0a 09 7d 20 68 65 61 64 65 range;..} heade
04a0: 72 73 3b 0a 7d 3b 0a 0a 2f 2a 20 47 6c 6f 62 61 rs;.};../* Globa
04b0: 6c 20 76 61 72 69 61 62 6c 65 73 20 2a 2f 0a 2f l variables */./
04c0: 2a 2a 20 4f 70 65 6e 20 46 69 6c 65 20 63 61 63 ** Open File cac
04d0: 68 65 20 2a 2a 2f 0a 73 74 72 75 63 74 20 66 69 he **/.struct fi
04e0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66 69 led_fileinfo *fi
04f0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 led_fileinfo_fdc
0500: 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 75 6e 73 ache = NULL;.uns
0510: 69 67 6e 65 64 20 69 6e 74 20 66 69 6c 65 64 5f igned int filed_
0520: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 fileinfo_fdcache
0530: 5f 73 69 7a 65 20 3d 20 30 3b 0a 0a 2f 2a 20 49 _size = 0;../* I
0540: 6e 69 74 69 61 6c 69 7a 65 20 63 61 63 68 65 20 nitialize cache
0550: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 */.static int fi
0560: 6c 65 64 5f 69 6e 69 74 5f 63 61 63 68 65 28 75 led_init_cache(u
0570: 6e 73 69 67 6e 65 64 20 69 6e 74 20 63 61 63 68 nsigned int cach
0580: 65 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67 e_size) {..unsig
0590: 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e ned int idx;..in
05a0: 74 20 6d 75 74 65 78 5f 69 6e 69 74 5f 72 65 74 t mutex_init_ret
05b0: 3b 0a 0a 09 2f 2a 20 43 61 63 68 65 20 6d 61 79 ;.../* Cache may
05c0: 20 6e 6f 74 20 62 65 20 72 65 2d 69 6e 69 74 69 not be re-initi
05d0: 61 6c 69 7a 65 64 20 2a 2f 0a 09 69 66 20 28 66 alized */..if (f
05e0: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 iled_fileinfo_fd
05f0: 63 61 63 68 65 5f 73 69 7a 65 20 21 3d 20 30 20 cache_size != 0
0600: 7c 7c 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 || filed_fileinf
0610: 6f 5f 66 64 63 61 63 68 65 20 21 3d 20 4e 55 4c o_fdcache != NUL
0620: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 L) {...return(1)
0630: 3b 0a 09 7d 0a 0a 09 2f 2a 20 41 6c 6c 6f 63 61 ;..}.../* Alloca
0640: 74 65 20 63 61 63 68 65 20 2a 2f 0a 09 66 69 6c te cache */..fil
0650: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 ed_fileinfo_fdca
0660: 63 68 65 5f 73 69 7a 65 20 3d 20 63 61 63 68 65 che_size = cache
0670: 5f 73 69 7a 65 3b 0a 09 66 69 6c 65 64 5f 66 69 _size;..filed_fi
0680: 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 20 3d leinfo_fdcache =
0690: 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a malloc(sizeof(*
06a0: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 filed_fileinfo_f
06b0: 64 63 61 63 68 65 29 20 2a 20 66 69 6c 65 64 5f dcache) * filed_
06c0: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 fileinfo_fdcache
06d0: 5f 73 69 7a 65 29 3b 0a 09 69 66 20 28 66 69 6c _size);..if (fil
06e0: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 ed_fileinfo_fdca
06f0: 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 che == NULL) {..
0700: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a .return(1);..}..
0710: 09 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 63 ./* Initialize c
0720: 61 63 68 65 20 65 6e 74 72 69 65 73 20 2a 2f 0a ache entries */.
0730: 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b 20 69 .for (idx = 0; i
0740: 64 78 20 3c 20 66 69 6c 65 64 5f 66 69 6c 65 69 dx < filed_filei
0750: 6e 66 6f 5f 66 64 63 61 63 68 65 5f 73 69 7a 65 nfo_fdcache_size
0760: 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 6d 75 74 ; idx++) {...mut
0770: 65 78 5f 69 6e 69 74 5f 72 65 74 20 3d 20 70 74 ex_init_ret = pt
0780: 68 72 65 61 64 5f 6d 75 74 65 78 5f 69 6e 69 74 hread_mutex_init
0790: 28 26 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f (&filed_fileinfo
07a0: 5f 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 6d 75 _fdcache[idx].mu
07b0: 74 65 78 2c 20 4e 55 4c 4c 29 3b 0a 09 09 69 66 tex, NULL);...if
07c0: 20 28 6d 75 74 65 78 5f 69 6e 69 74 5f 72 65 74 (mutex_init_ret
07d0: 20 21 3d 20 30 29 20 7b 0a 09 09 09 72 65 74 75 != 0) {....retu
07e0: 72 6e 28 31 29 3b 0a 09 09 7d 0a 0a 09 09 66 69 rn(1);...}....fi
07f0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 led_fileinfo_fdc
0800: 61 63 68 65 5b 69 64 78 5d 2e 70 61 74 68 20 3d ache[idx].path =
0810: 20 73 74 72 64 75 70 28 22 22 29 3b 0a 09 09 66 strdup("");...f
0820: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 iled_fileinfo_fd
0830: 63 61 63 68 65 5b 69 64 78 5d 2e 66 64 20 3d 20 cache[idx].fd =
0840: 2d 31 3b 0a 09 09 66 69 6c 65 64 5f 66 69 6c 65 -1;...filed_file
0850: 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64 78 info_fdcache[idx
0860: 5d 2e 6c 61 73 74 6d 6f 64 20 3d 20 22 22 3b 0a ].lastmod = "";.
0870: 09 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f ..filed_fileinfo
0880: 5f 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 74 79 _fdcache[idx].ty
0890: 70 65 20 3d 20 22 22 3b 0a 09 7d 0a 0a 09 72 65 pe = "";..}...re
08a0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 49 turn(0);.}../* I
08b0: 6e 69 74 69 61 6c 69 7a 65 20 70 72 6f 63 65 73 nitialize proces
08c0: 73 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 s */.static int
08d0: 66 69 6c 65 64 5f 69 6e 69 74 28 75 6e 73 69 67 filed_init(unsig
08e0: 6e 65 64 20 69 6e 74 20 63 61 63 68 65 5f 73 69 ned int cache_si
08f0: 7a 65 29 20 7b 0a 09 73 74 61 74 69 63 20 69 6e ze) {..static in
0900: 74 20 63 61 6c 6c 65 64 20 3d 20 30 3b 0a 09 69 t called = 0;..i
0910: 6e 74 20 63 61 63 68 65 5f 72 65 74 3b 0a 0a 09 nt cache_ret;...
0920: 69 66 20 28 63 61 6c 6c 65 64 29 20 7b 0a 09 09 if (called) {...
0930: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09 return(0);..}...
0940: 63 61 6c 6c 65 64 20 3d 20 31 3b 0a 0a 09 6d 6c called = 1;...ml
0950: 6f 63 6b 61 6c 6c 28 4d 43 4c 5f 43 55 52 52 45 ockall(MCL_CURRE
0960: 4e 54 20 7c 20 4d 43 4c 5f 46 55 54 55 52 45 29 NT | MCL_FUTURE)
0970: 3b 0a 0a 09 73 69 67 6e 61 6c 28 53 49 47 50 49 ;...signal(SIGPI
0980: 50 45 2c 20 53 49 47 5f 49 47 4e 29 3b 0a 0a 09 PE, SIG_IGN);...
0990: 63 61 63 68 65 5f 72 65 74 20 3d 20 66 69 6c 65 cache_ret = file
09a0: 64 5f 69 6e 69 74 5f 63 61 63 68 65 28 63 61 63 d_init_cache(cac
09b0: 68 65 5f 73 69 7a 65 29 3b 0a 09 69 66 20 28 63 he_size);..if (c
09c0: 61 63 68 65 5f 72 65 74 20 21 3d 20 30 29 20 7b ache_ret != 0) {
09d0: 0a 09 09 72 65 74 75 72 6e 28 63 61 63 68 65 5f ...return(cache_
09e0: 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 ret);..}...retur
09f0: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 4c 69 73 74 n(0);.}../* List
0a00: 65 6e 20 6f 6e 20 61 20 70 61 72 74 69 63 75 6c en on a particul
0a10: 61 72 20 61 64 64 72 65 73 73 2f 70 6f 72 74 20 ar address/port
0a20: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 */.static int fi
0a30: 6c 65 64 5f 6c 69 73 74 65 6e 28 63 6f 6e 73 74 led_listen(const
0a40: 20 63 68 61 72 20 2a 61 64 64 72 65 73 73 2c 20 char *address,
0a50: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 70 6f 72 unsigned int por
0a60: 74 29 20 7b 0a 09 73 74 72 75 63 74 20 73 6f 63 t) {..struct soc
0a70: 6b 61 64 64 72 5f 69 6e 36 20 61 64 64 72 3b 0a kaddr_in6 addr;.
0a80: 09 69 6e 74 20 70 74 6f 6e 5f 72 65 74 2c 20 62 .int pton_ret, b
0a90: 69 6e 64 5f 72 65 74 2c 20 6c 69 73 74 65 6e 5f ind_ret, listen_
0aa0: 72 65 74 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 ret;..int fd;...
0ab0: 61 64 64 72 2e 73 69 6e 36 5f 66 61 6d 69 6c 79 addr.sin6_family
0ac0: 20 3d 20 41 46 5f 49 4e 45 54 36 3b 0a 09 61 64 = AF_INET6;..ad
0ad0: 64 72 2e 73 69 6e 36 5f 66 6c 6f 77 69 6e 66 6f dr.sin6_flowinfo
0ae0: 20 3d 20 30 3b 0a 09 61 64 64 72 2e 73 69 6e 36 = 0;..addr.sin6
0af0: 5f 73 63 6f 70 65 5f 69 64 20 3d 20 30 3b 0a 09 _scope_id = 0;..
0b00: 61 64 64 72 2e 73 69 6e 36 5f 70 6f 72 74 20 3d addr.sin6_port =
0b10: 20 68 74 6f 6e 73 28 70 6f 72 74 29 3b 0a 09 70 htons(port);..p
0b20: 74 6f 6e 5f 72 65 74 20 3d 20 69 6e 65 74 5f 70 ton_ret = inet_p
0b30: 74 6f 6e 28 41 46 5f 49 4e 45 54 36 2c 20 61 64 ton(AF_INET6, ad
0b40: 64 72 65 73 73 2c 20 61 64 64 72 2e 73 69 6e 36 dress, addr.sin6
0b50: 5f 61 64 64 72 2e 73 36 5f 61 64 64 72 29 3b 0a _addr.s6_addr);.
0b60: 09 69 66 20 28 70 74 6f 6e 5f 72 65 74 20 21 3d .if (pton_ret !=
0b70: 20 31 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 1) {...return(-
0b80: 31 29 3b 0a 09 7d 0a 0a 09 66 64 20 3d 20 73 6f 1);..}...fd = so
0b90: 63 6b 65 74 28 41 46 5f 49 4e 45 54 36 2c 20 53 cket(AF_INET6, S
0ba0: 4f 43 4b 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a OCK_STREAM, 0);.
0bb0: 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 .if (fd < 0) {..
0bc0: 09 72 65 74 75 72 6e 28 66 64 29 3b 0a 09 7d 0a .return(fd);..}.
0bd0: 0a 09 62 69 6e 64 5f 72 65 74 20 3d 20 62 69 6e ..bind_ret = bin
0be0: 64 28 66 64 2c 20 28 63 6f 6e 73 74 20 73 74 72 d(fd, (const str
0bf0: 75 63 74 20 73 6f 63 6b 61 64 64 72 20 2a 29 20 uct sockaddr *)
0c00: 26 61 64 64 72 2c 20 73 69 7a 65 6f 66 28 61 64 &addr, sizeof(ad
0c10: 64 72 29 29 3b 0a 09 69 66 20 28 62 69 6e 64 5f dr));..if (bind_
0c20: 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 63 6c 6f ret < 0) {...clo
0c30: 73 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72 se(fd);....retur
0c40: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 6c 69 73 74 n(-1);..}...list
0c50: 65 6e 5f 72 65 74 20 3d 20 6c 69 73 74 65 6e 28 en_ret = listen(
0c60: 66 64 2c 20 31 32 38 29 3b 0a 09 69 66 20 28 6c fd, 128);..if (l
0c70: 69 73 74 65 6e 5f 72 65 74 20 21 3d 20 30 29 20 isten_ret != 0)
0c80: 7b 0a 09 09 63 6c 6f 73 65 28 66 64 29 3b 0a 0a {...close(fd);..
0c90: 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d ..return(-1);..}
0ca0: 0a 0a 09 72 65 74 75 72 6e 28 66 64 29 3b 0a 7d ...return(fd);.}
0cb0: 0a 0a 2f 2a 20 4c 6f 67 20 61 20 6d 65 73 73 61 ../* Log a messa
0cc0: 67 65 20 2a 2f 0a 2f 2f 23 64 65 66 69 6e 65 20 ge */.//#define
0cd0: 46 49 4c 45 44 5f 44 4f 4e 54 5f 4c 4f 47 0a 23 FILED_DONT_LOG.#
0ce0: 69 66 64 65 66 20 46 49 4c 45 44 5f 44 4f 4e 54 ifdef FILED_DONT
0cf0: 5f 4c 4f 47 0a 23 20 20 64 65 66 69 6e 65 20 66 _LOG.# define f
0d00: 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 iled_logging_thr
0d10: 65 61 64 5f 69 6e 69 74 28 29 20 30 0a 23 20 20 ead_init() 0.#
0d20: 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c 6f 67 define filed_log
0d30: 5f 6d 73 67 5f 64 65 62 75 67 28 78 2c 20 2e 2e _msg_debug(x, ..
0d40: 2e 29 20 2f 2a 2a 2f 0a 23 20 20 64 65 66 69 6e .) /**/.# defin
0d50: 65 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 e filed_log_msg(
0d60: 78 29 20 2f 2a 2a 2f 0a 23 65 6c 73 65 0a 2f 2a x) /**/.#else./*
0d70: 20 49 6e 69 74 69 61 6c 69 7a 65 20 6c 6f 67 67 Initialize logg
0d80: 69 6e 67 20 74 68 72 65 61 64 20 2a 2f 0a 73 74 ing thread */.st
0d90: 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 6c atic int filed_l
0da0: 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e ogging_thread_in
0db0: 69 74 28 76 6f 69 64 29 20 7b 0a 09 2f 2a 20 58 it(void) {../* X
0dc0: 58 58 3a 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c 65 XX:TODO: Unimple
0dd0: 6d 65 6e 74 65 64 20 2a 2f 0a 09 72 65 74 75 72 mented */..retur
0de0: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 58 58 58 3a n(0);.}../* XXX:
0df0: 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c 65 6d 65 6e TODO: Unimplemen
0e00: 74 65 64 20 2a 2f 0a 23 64 65 66 69 6e 65 20 66 ted */.#define f
0e10: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 iled_log_msg_deb
0e20: 75 67 28 78 2c 20 2e 2e 2e 29 20 7b 20 66 70 72 ug(x, ...) { fpr
0e30: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 78 2c 20 intf(stderr, x,
0e40: 5f 5f 56 41 5f 41 52 47 53 5f 5f 29 3b 20 66 70 __VA_ARGS__); fp
0e50: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5c rintf(stderr, "\
0e60: 6e 22 29 3b 20 66 66 6c 75 73 68 28 73 74 64 65 n"); fflush(stde
0e70: 72 72 29 3b 20 7d 0a 0a 73 74 61 74 69 63 20 76 rr); }..static v
0e80: 6f 69 64 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 oid filed_log_ms
0e90: 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 62 75 g(const char *bu
0ea0: 66 66 65 72 29 20 7b 0a 09 2f 2a 20 58 58 58 3a ffer) {../* XXX:
0eb0: 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c 65 6d 65 6e TODO: Unimplemen
0ec0: 74 65 64 20 2a 2f 0a 09 66 70 72 69 6e 74 66 28 ted */..fprintf(
0ed0: 73 74 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c 20 stderr, "%s\n",
0ee0: 62 75 66 66 65 72 29 3b 0a 0a 09 72 65 74 75 72 buffer);...retur
0ef0: 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20 n;.}.#endif../*
0f00: 46 6f 72 6d 61 74 20 74 69 6d 65 20 70 65 72 20 Format time per
0f10: 52 46 43 32 36 31 36 20 2a 2f 0a 73 74 61 74 69 RFC2616 */.stati
0f20: 63 20 63 68 61 72 20 2a 66 69 6c 65 64 5f 66 6f c char *filed_fo
0f30: 72 6d 61 74 5f 74 69 6d 65 28 63 68 61 72 20 2a rmat_time(char *
0f40: 62 75 66 66 65 72 2c 20 73 69 7a 65 5f 74 20 62 buffer, size_t b
0f50: 75 66 66 65 72 5f 6c 65 6e 2c 20 63 6f 6e 73 74 uffer_len, const
0f60: 20 74 69 6d 65 5f 74 20 74 69 6d 65 69 6e 66 6f time_t timeinfo
0f70: 29 20 7b 0a 09 73 74 72 75 63 74 20 74 6d 20 74 ) {..struct tm t
0f80: 69 6d 65 69 6e 66 6f 5f 74 6d 2c 20 2a 74 69 6d imeinfo_tm, *tim
0f90: 65 69 6e 66 6f 5f 74 6d 5f 70 3b 0a 0a 09 74 69 einfo_tm_p;...ti
0fa0: 6d 65 69 6e 66 6f 5f 74 6d 5f 70 20 3d 20 67 6d meinfo_tm_p = gm
0fb0: 74 69 6d 65 5f 72 28 26 74 69 6d 65 69 6e 66 6f time_r(&timeinfo
0fc0: 2c 20 26 74 69 6d 65 69 6e 66 6f 5f 74 6d 29 3b , &timeinfo_tm);
0fd0: 0a 09 69 66 20 28 74 69 6d 65 69 6e 66 6f 5f 74 ..if (timeinfo_t
0fe0: 6d 5f 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 m_p == NULL) {..
0ff0: 09 72 65 74 75 72 6e 28 22 75 6e 6b 6e 6f 77 6e .return("unknown
1000: 22 29 3b 0a 09 7d 0a 0a 09 62 75 66 66 65 72 5b ");..}...buffer[
1010: 62 75 66 66 65 72 5f 6c 65 6e 20 2d 20 31 5d 20 buffer_len - 1]
1020: 3d 20 27 5c 30 27 3b 0a 09 62 75 66 66 65 72 5f = '\0';..buffer_
1030: 6c 65 6e 20 3d 20 73 74 72 66 74 69 6d 65 28 62 len = strftime(b
1040: 75 66 66 65 72 2c 20 62 75 66 66 65 72 5f 6c 65 uffer, buffer_le
1050: 6e 20 2d 20 31 2c 20 22 25 61 2c 20 25 64 20 25 n - 1, "%a, %d %
1060: 62 20 25 59 20 25 48 3a 25 4d 3a 25 53 20 47 4d b %Y %H:%M:%S GM
1070: 54 22 2c 20 74 69 6d 65 69 6e 66 6f 5f 74 6d 5f T", timeinfo_tm_
1080: 70 29 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75 66 p);...return(buf
1090: 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 68 61 73 68 fer);.}../* hash
10a0: 20 2a 2f 0a 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a */./* XXX:TODO:
10b0: 20 52 65 77 72 69 74 65 20 74 68 69 73 20 2a 2f Rewrite this */
10c0: 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64 .static unsigned
10d0: 20 69 6e 74 20 66 69 6c 65 64 5f 68 61 73 68 28 int filed_hash(
10e0: 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 const unsigned c
10f0: 68 61 72 20 2a 76 61 6c 75 65 2c 20 75 6e 73 69 har *value, unsi
1100: 67 6e 65 64 20 69 6e 74 20 6d 6f 64 75 6c 75 73 gned int modulus
1110: 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 63 68 ) {..unsigned ch
1120: 61 72 20 63 75 72 72 2c 20 70 72 65 76 3b 0a 09 ar curr, prev;..
1130: 69 6e 74 20 64 69 66 66 3b 0a 09 75 6e 73 69 67 int diff;..unsig
1140: 6e 65 64 20 69 6e 74 20 72 65 74 76 61 6c 3b 0a ned int retval;.
1150: 0a 09 72 65 74 76 61 6c 20 3d 20 6d 6f 64 75 6c ..retval = modul
1160: 75 73 20 2d 20 31 3b 0a 09 70 72 65 76 20 3d 20 us - 1;..prev =
1170: 6d 6f 64 75 6c 75 73 20 25 20 32 35 35 3b 0a 0a modulus % 255;..
1180: 09 77 68 69 6c 65 20 28 28 63 75 72 72 20 3d 20 .while ((curr =
1190: 2a 76 61 6c 75 65 29 29 20 7b 0a 09 09 69 66 20 *value)) {...if
11a0: 28 63 75 72 72 20 3c 20 33 32 29 20 7b 0a 09 09 (curr < 32) {...
11b0: 09 63 75 72 72 20 3d 20 32 35 35 20 2d 20 63 75 .curr = 255 - cu
11c0: 72 72 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 rr;...} else {..
11d0: 09 09 63 75 72 72 20 2d 3d 20 33 32 3b 0a 09 09 ..curr -= 32;...
11e0: 7d 0a 0a 09 09 69 66 20 28 70 72 65 76 20 3c 20 }....if (prev <
11f0: 63 75 72 72 29 20 7b 0a 09 09 09 64 69 66 66 20 curr) {....diff
1200: 3d 20 63 75 72 72 20 2d 20 70 72 65 76 3b 0a 09 = curr - prev;..
1210: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 64 69 66 .} else {....dif
1220: 66 20 3d 20 70 72 65 76 20 2d 20 63 75 72 72 3b f = prev - curr;
1230: 0a 09 09 7d 0a 0a 09 09 72 65 74 76 61 6c 20 3c ...}....retval <
1240: 3c 3d 20 33 3b 0a 09 09 72 65 74 76 61 6c 20 5e <= 3;...retval ^
1250: 3d 20 64 69 66 66 3b 0a 0a 09 09 76 61 6c 75 65 = diff;....value
1260: 2b 2b 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c 20 ++;..}...retval
1270: 3d 20 72 65 74 76 61 6c 20 25 20 6d 6f 64 75 6c = retval % modul
1280: 75 73 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74 us;...return(ret
1290: 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 20 4f 70 65 6e val);.}../* Open
12a0: 20 61 20 66 69 6c 65 20 61 6e 64 20 72 65 74 75 a file and retu
12b0: 72 6e 20 66 69 6c 65 20 69 6e 66 6f 72 6d 61 74 rn file informat
12c0: 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 73 74 ion */.static st
12d0: 72 75 63 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 ruct filed_filei
12e0: 6e 66 6f 20 2a 66 69 6c 65 64 5f 6f 70 65 6e 5f nfo *filed_open_
12f0: 66 69 6c 65 28 63 6f 6e 73 74 20 63 68 61 72 20 file(const char
1300: 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 66 69 *path, struct fi
1310: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 62 75 led_fileinfo *bu
1320: 66 66 65 72 29 20 7b 0a 09 73 74 72 75 63 74 20 ffer) {..struct
1330: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a filed_fileinfo *
1340: 63 61 63 68 65 3b 0a 09 75 6e 73 69 67 6e 65 64 cache;..unsigned
1350: 20 69 6e 74 20 63 61 63 68 65 5f 69 64 78 3b 0a int cache_idx;.
1360: 09 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 69 6e 74 .off_t len;..int
1370: 20 66 64 3b 0a 0a 09 63 61 63 68 65 5f 69 64 78 fd;...cache_idx
1380: 20 3d 20 66 69 6c 65 64 5f 68 61 73 68 28 28 63 = filed_hash((c
1390: 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68 onst unsigned ch
13a0: 61 72 20 2a 29 20 70 61 74 68 2c 20 66 69 6c 65 ar *) path, file
13b0: 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 d_fileinfo_fdcac
13c0: 68 65 5f 73 69 7a 65 29 3b 0a 0a 09 63 61 63 68 he_size);...cach
13d0: 65 20 3d 20 26 66 69 6c 65 64 5f 66 69 6c 65 69 e = &filed_filei
13e0: 6e 66 6f 5f 66 64 63 61 63 68 65 5b 63 61 63 68 nfo_fdcache[cach
13f0: 65 5f 69 64 78 5d 3b 0a 0a 09 66 69 6c 65 64 5f e_idx];...filed_
1400: 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 4c log_msg_debug("L
1410: 6f 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f 72 ocking mutex for
1420: 20 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e 73 idx: %lu", (uns
1430: 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 igned long) cach
1440: 65 5f 69 64 78 29 3b 0a 0a 09 70 74 68 72 65 61 e_idx);...pthrea
1450: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 63 61 d_mutex_lock(&ca
1460: 63 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 66 che->mutex);...f
1470: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 iled_log_msg_deb
1480: 75 67 28 22 43 6f 6d 70 6c 65 74 65 64 20 6c 6f ug("Completed lo
1490: 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f 72 20 cking mutex for
14a0: 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e 73 69 idx: %lu", (unsi
14b0: 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 gned long) cache
14c0: 5f 69 64 78 29 3b 0a 0a 09 69 66 20 28 73 74 72 _idx);...if (str
14d0: 63 6d 70 28 70 61 74 68 2c 20 63 61 63 68 65 2d cmp(path, cache-
14e0: 3e 70 61 74 68 29 20 21 3d 20 30 29 20 7b 0a 09 >path) != 0) {..
14f0: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 .filed_log_msg_d
1500: 65 62 75 67 28 22 43 61 63 68 65 20 6d 69 73 73 ebug("Cache miss
1510: 20 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20 4f for idx: %lu: O
1520: 4c 44 20 5c 22 25 73 5c 22 2c 20 4e 45 57 20 5c LD \"%s\", NEW \
1530: 22 25 73 5c 22 22 2c 20 28 75 6e 73 69 67 6e 65 "%s\"", (unsigne
1540: 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f 69 64 d long) cache_id
1550: 78 2c 20 63 61 63 68 65 2d 3e 70 61 74 68 2c 20 x, cache->path,
1560: 70 61 74 68 29 3b 0a 0a 09 09 66 64 20 3d 20 6f path);....fd = o
1570: 70 65 6e 28 70 61 74 68 2c 20 4f 5f 52 44 4f 4e pen(path, O_RDON
1580: 4c 59 20 7c 20 4f 5f 4c 41 52 47 45 46 49 4c 45 LY | O_LARGEFILE
1590: 29 3b 0a 09 09 69 66 20 28 66 64 20 3c 20 30 29 );...if (fd < 0)
15a0: 20 7b 0a 09 09 09 70 74 68 72 65 61 64 5f 6d 75 {....pthread_mu
15b0: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63 68 tex_unlock(&cach
15c0: 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 09 72 e->mutex);.....r
15d0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d eturn(NULL);...}
15e0: 0a 0a 09 09 66 72 65 65 28 63 61 63 68 65 2d 3e ....free(cache->
15f0: 70 61 74 68 29 3b 0a 09 09 69 66 20 28 63 61 63 path);...if (cac
1600: 68 65 2d 3e 66 64 20 3e 3d 20 30 29 20 7b 0a 09 he->fd >= 0) {..
1610: 09 09 63 6c 6f 73 65 28 63 61 63 68 65 2d 3e 66 ..close(cache->f
1620: 64 29 3b 0a 09 09 7d 0a 0a 09 09 6c 65 6e 20 3d d);...}....len =
1630: 20 6c 73 65 65 6b 28 66 64 2c 20 30 2c 20 53 45 lseek(fd, 0, SE
1640: 45 4b 5f 45 4e 44 29 3b 0a 09 09 6c 73 65 65 6b EK_END);...lseek
1650: 28 66 64 2c 20 30 2c 20 53 45 45 4b 5f 53 45 54 (fd, 0, SEEK_SET
1660: 29 3b 0a 0a 09 09 63 61 63 68 65 2d 3e 66 64 20 );....cache->fd
1670: 3d 20 66 64 3b 0a 09 09 63 61 63 68 65 2d 3e 6c = fd;...cache->l
1680: 65 6e 20 3d 20 6c 65 6e 3b 0a 09 09 63 61 63 68 en = len;...cach
1690: 65 2d 3e 70 61 74 68 20 3d 20 73 74 72 64 75 70 e->path = strdup
16a0: 28 70 61 74 68 29 3b 0a 0a 09 09 2f 2a 20 58 58 (path);..../* XX
16b0: 58 3a 54 4f 44 4f 3a 20 44 65 74 65 72 6d 69 6e X:TODO: Determin
16c0: 65 20 2a 2f 0a 09 09 63 61 63 68 65 2d 3e 74 79 e */...cache->ty
16d0: 70 65 20 3d 20 22 76 69 64 65 6f 2f 6d 70 34 22 pe = "video/mp4"
16e0: 3b 0a 09 09 63 61 63 68 65 2d 3e 6c 61 73 74 6d ;...cache->lastm
16f0: 6f 64 20 3d 20 66 69 6c 65 64 5f 66 6f 72 6d 61 od = filed_forma
1700: 74 5f 74 69 6d 65 28 63 61 63 68 65 2d 3e 6c 61 t_time(cache->la
1710: 73 74 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28 stmod_b, sizeof(
1720: 63 61 63 68 65 2d 3e 6c 61 73 74 6d 6f 64 5f 62 cache->lastmod_b
1730: 29 2c 20 74 69 6d 65 28 4e 55 4c 4c 29 20 2d 20 ), time(NULL) -
1740: 33 30 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 30);..} else {..
1750: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 .filed_log_msg_d
1760: 65 62 75 67 28 22 43 61 63 68 65 20 68 69 74 20 ebug("Cache hit
1770: 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20 50 41 for idx: %lu: PA
1780: 54 48 20 5c 22 25 73 5c 22 22 2c 20 28 75 6e 73 TH \"%s\"", (uns
1790: 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 igned long) cach
17a0: 65 5f 69 64 78 2c 20 70 61 74 68 29 3b 0a 09 7d e_idx, path);..}
17b0: 0a 0a 09 2f 2a 0a 09 20 2a 20 57 65 20 68 61 76 .../*.. * We hav
17c0: 65 20 74 6f 20 6d 61 6b 65 20 61 20 64 75 70 6c e to make a dupl
17d0: 69 63 61 74 65 20 46 44 2c 20 62 65 63 61 75 73 icate FD, becaus
17e0: 65 20 6f 6e 63 65 20 77 65 20 72 65 6c 65 61 73 e once we releas
17f0: 65 20 74 68 65 20 63 61 63 68 65 0a 09 20 2a 20 e the cache.. *
1800: 6d 75 74 65 78 2c 20 74 68 65 20 66 69 6c 65 20 mutex, the file
1810: 64 65 73 63 72 69 70 74 6f 72 20 6d 61 79 20 62 descriptor may b
1820: 65 20 63 6c 6f 73 65 64 0a 09 20 2a 2f 0a 09 66 e closed.. */..f
1830: 64 20 3d 20 64 75 70 28 63 61 63 68 65 2d 3e 66 d = dup(cache->f
1840: 64 29 3b 0a 09 69 66 20 28 66 64 20 3c 20 30 29 d);..if (fd < 0)
1850: 20 7b 0a 09 09 70 74 68 72 65 61 64 5f 6d 75 74 {...pthread_mut
1860: 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63 68 65 ex_unlock(&cache
1870: 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 72 65 74 ->mutex);....ret
1880: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 urn(NULL);..}...
1890: 62 75 66 66 65 72 2d 3e 66 64 20 3d 20 66 64 3b buffer->fd = fd;
18a0: 0a 09 62 75 66 66 65 72 2d 3e 6c 65 6e 20 3d 20 ..buffer->len =
18b0: 63 61 63 68 65 2d 3e 6c 65 6e 3b 0a 09 62 75 66 cache->len;..buf
18c0: 66 65 72 2d 3e 74 79 70 65 20 3d 20 63 61 63 68 fer->type = cach
18d0: 65 2d 3e 74 79 70 65 3b 0a 09 6d 65 6d 63 70 79 e->type;..memcpy
18e0: 28 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 (buffer->lastmod
18f0: 5f 62 2c 20 63 61 63 68 65 2d 3e 6c 61 73 74 6d _b, cache->lastm
1900: 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28 62 75 66 od_b, sizeof(buf
1910: 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 29 fer->lastmod_b))
1920: 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d ;..buffer->lastm
1930: 6f 64 20 3d 20 62 75 66 66 65 72 2d 3e 6c 61 73 od = buffer->las
1940: 74 6d 6f 64 5f 62 20 2b 20 28 63 61 63 68 65 2d tmod_b + (cache-
1950: 3e 6c 61 73 74 6d 6f 64 20 2d 20 63 61 63 68 65 >lastmod - cache
1960: 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 3b 0a 0a 09 ->lastmod_b);...
1970: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e pthread_mutex_un
1980: 6c 6f 63 6b 28 26 63 61 63 68 65 2d 3e 6d 75 74 lock(&cache->mut
1990: 65 78 29 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75 ex);...return(bu
19a0: 66 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50 72 6f ffer);.}../* Pro
19b0: 63 65 73 73 20 61 6e 20 48 54 54 50 20 72 65 71 cess an HTTP req
19c0: 75 65 73 74 20 61 6e 64 20 72 65 74 75 72 6e 20 uest and return
19d0: 74 68 65 20 70 61 74 68 20 72 65 71 75 65 73 74 the path request
19e0: 65 64 20 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 ed */.static str
19f0: 75 63 74 20 66 69 6c 65 64 5f 68 74 74 70 5f 72 uct filed_http_r
1a00: 65 71 75 65 73 74 20 2a 66 69 6c 65 64 5f 67 65 equest *filed_ge
1a10: 74 5f 68 74 74 70 5f 72 65 71 75 65 73 74 28 46 t_http_request(F
1a20: 49 4c 45 20 2a 66 70 2c 20 73 74 72 75 63 74 20 ILE *fp, struct
1a30: 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 71 75 65 filed_http_reque
1a40: 73 74 20 2a 62 75 66 66 65 72 5f 73 74 29 20 7b st *buffer_st) {
1a50: 0a 09 63 68 61 72 20 2a 6d 65 74 68 6f 64 2c 20 ..char *method,
1a60: 2a 70 61 74 68 3b 0a 09 63 68 61 72 20 2a 62 75 *path;..char *bu
1a70: 66 66 65 72 2c 20 2a 74 6d 70 62 75 66 66 65 72 ffer, *tmpbuffer
1a80: 2c 20 2a 77 6f 72 6b 62 75 66 66 65 72 2c 20 2a , *workbuffer, *
1a90: 77 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78 74 3b workbuffer_next;
1aa0: 0a 09 73 69 7a 65 5f 74 20 62 75 66 66 65 72 5f ..size_t buffer_
1ab0: 6c 65 6e 2c 20 74 6d 70 62 75 66 66 65 72 5f 6c len, tmpbuffer_l
1ac0: 65 6e 3b 0a 09 6f 66 66 5f 74 20 72 61 6e 67 65 en;..off_t range
1ad0: 5f 73 74 61 72 74 2c 20 72 61 6e 67 65 5f 65 6e _start, range_en
1ae0: 64 2c 20 72 61 6e 67 65 5f 6c 65 6e 67 74 68 3b d, range_length;
1af0: 0a 09 69 6e 74 20 72 61 6e 67 65 5f 72 65 71 75 ..int range_requ
1b00: 65 73 74 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 72 est;..int i;...r
1b10: 61 6e 67 65 5f 73 74 61 72 74 20 3d 20 30 3b 0a ange_start = 0;.
1b20: 09 72 61 6e 67 65 5f 65 6e 64 20 20 20 3d 20 30 .range_end = 0
1b30: 3b 0a 09 72 61 6e 67 65 5f 72 65 71 75 65 73 74 ;..range_request
1b40: 20 3d 20 30 3b 0a 09 72 61 6e 67 65 5f 6c 65 6e = 0;..range_len
1b50: 67 74 68 20 3d 20 2d 31 3b 0a 0a 09 62 75 66 66 gth = -1;...buff
1b60: 65 72 20 3d 20 62 75 66 66 65 72 5f 73 74 2d 3e er = buffer_st->
1b70: 70 61 74 68 5f 62 3b 0a 09 62 75 66 66 65 72 5f path_b;..buffer_
1b80: 6c 65 6e 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 len = sizeof(buf
1b90: 66 65 72 5f 73 74 2d 3e 70 61 74 68 5f 62 29 3b fer_st->path_b);
1ba0: 0a 0a 09 74 6d 70 62 75 66 66 65 72 20 3d 20 62 ...tmpbuffer = b
1bb0: 75 66 66 65 72 5f 73 74 2d 3e 74 6d 70 62 75 66 uffer_st->tmpbuf
1bc0: 3b 0a 09 74 6d 70 62 75 66 66 65 72 5f 6c 65 6e ;..tmpbuffer_len
1bd0: 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 66 65 72 = sizeof(buffer
1be0: 5f 73 74 2d 3e 74 6d 70 62 75 66 29 3b 0a 0a 09 _st->tmpbuf);...
1bf0: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 57 filed_log_msg("W
1c00: 41 49 54 5f 46 4f 52 5f 52 45 51 55 45 53 54 20 AIT_FOR_REQUEST
1c10: 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 66 67 65 74 FD=...");...fget
1c20: 73 28 62 75 66 66 65 72 2c 20 62 75 66 66 65 72 s(buffer, buffer
1c30: 5f 6c 65 6e 2c 20 66 70 29 3b 0a 0a 09 6d 65 74 _len, fp);...met
1c40: 68 6f 64 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09 hod = buffer;...
1c50: 62 75 66 66 65 72 20 3d 20 73 74 72 63 68 72 28 buffer = strchr(
1c60: 62 75 66 66 65 72 2c 20 27 20 27 29 3b 0a 09 69 buffer, ' ');..i
1c70: 66 20 28 62 75 66 66 65 72 20 3d 3d 20 4e 55 4c f (buffer == NUL
1c80: 4c 29 20 7b 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 L) {...filed_log
1c90: 5f 6d 73 67 28 22 47 4f 54 5f 52 45 51 55 45 53 _msg("GOT_REQUES
1ca0: 54 20 46 44 3d 2e 2e 2e 20 45 52 52 4f 52 3d 66 T FD=... ERROR=f
1cb0: 6f 72 6d 61 74 22 29 3b 0a 0a 09 09 72 65 74 75 ormat");....retu
1cc0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2a rn(NULL);..}...*
1cd0: 62 75 66 66 65 72 20 3d 20 27 5c 30 27 3b 0a 09 buffer = '\0';..
1ce0: 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 70 61 74 68 buffer++;...path
1cf0: 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09 62 75 66 = buffer;...buf
1d00: 66 65 72 20 3d 20 73 74 72 63 68 72 28 62 75 66 fer = strchr(buf
1d10: 66 65 72 2c 20 27 20 27 29 3b 0a 09 69 66 20 28 fer, ' ');..if (
1d20: 62 75 66 66 65 72 20 21 3d 20 4e 55 4c 4c 29 20 buffer != NULL)
1d30: 7b 0a 09 09 2a 62 75 66 66 65 72 20 3d 20 27 5c {...*buffer = '\
1d40: 30 27 3b 0a 09 09 62 75 66 66 65 72 2b 2b 3b 0a 0';...buffer++;.
1d50: 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d .}...filed_log_m
1d60: 73 67 28 22 47 4f 54 5f 52 45 51 55 45 53 54 20 sg("GOT_REQUEST
1d70: 46 44 3d 2e 2e 2e 20 50 41 54 48 3d 2e 2e 2e 22 FD=... PATH=..."
1d80: 29 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d );...filed_log_m
1d90: 73 67 28 22 57 41 49 54 5f 46 4f 52 5f 48 45 41 sg("WAIT_FOR_HEA
1da0: 44 45 52 53 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a DERS FD=...");..
1db0: 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c .for (i = 0; i <
1dc0: 20 31 30 30 3b 20 69 2b 2b 29 20 7b 0a 09 09 66 100; i++) {...f
1dd0: 67 65 74 73 28 74 6d 70 62 75 66 66 65 72 2c 20 gets(tmpbuffer,
1de0: 74 6d 70 62 75 66 66 65 72 5f 6c 65 6e 2c 20 66 tmpbuffer_len, f
1df0: 70 29 3b 0a 0a 09 09 69 66 20 28 73 74 72 6e 63 p);....if (strnc
1e00: 61 73 65 63 6d 70 28 74 6d 70 62 75 66 66 65 72 asecmp(tmpbuffer
1e10: 2c 20 22 52 61 6e 67 65 3a 20 22 2c 20 37 29 20 , "Range: ", 7)
1e20: 3d 3d 20 30 29 20 7b 0a 09 09 09 77 6f 72 6b 62 == 0) {....workb
1e30: 75 66 66 65 72 20 3d 20 74 6d 70 62 75 66 66 65 uffer = tmpbuffe
1e40: 72 20 2b 20 37 3b 0a 0a 09 09 09 69 66 20 28 73 r + 7;.....if (s
1e50: 74 72 6e 63 61 73 65 63 6d 70 28 77 6f 72 6b 62 trncasecmp(workb
1e60: 75 66 66 65 72 2c 20 22 62 79 74 65 73 3d 22 2c uffer, "bytes=",
1e70: 20 36 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 6) == 0) {.....
1e80: 77 6f 72 6b 62 75 66 66 65 72 20 2b 3d 20 36 3b workbuffer += 6;
1e90: 0a 0a 09 09 09 09 72 61 6e 67 65 5f 72 65 71 75 ......range_requ
1ea0: 65 73 74 20 3d 20 31 3b 0a 0a 09 09 09 09 72 61 est = 1;......ra
1eb0: 6e 67 65 5f 73 74 61 72 74 20 3d 20 73 74 72 74 nge_start = strt
1ec0: 6f 75 6c 6c 28 77 6f 72 6b 62 75 66 66 65 72 2c oull(workbuffer,
1ed0: 20 26 77 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78 &workbuffer_nex
1ee0: 74 2c 20 31 30 29 3b 0a 0a 09 09 09 09 77 6f 72 t, 10);......wor
1ef0: 6b 62 75 66 66 65 72 20 3d 20 77 6f 72 6b 62 75 kbuffer = workbu
1f00: 66 66 65 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 ffer_next;......
1f10: 69 66 20 28 2a 77 6f 72 6b 62 75 66 66 65 72 20 if (*workbuffer
1f20: 3d 3d 20 27 2d 27 29 20 7b 0a 09 09 09 09 09 77 == '-') {......w
1f30: 6f 72 6b 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 09 orkbuffer++;....
1f40: 09 09 09 69 66 20 28 2a 77 6f 72 6b 62 75 66 66 ...if (*workbuff
1f50: 65 72 20 21 3d 20 27 5c 72 27 20 26 26 20 2a 77 er != '\r' && *w
1f60: 6f 72 6b 62 75 66 66 65 72 20 21 3d 20 27 5c 6e orkbuffer != '\n
1f70: 27 29 20 7b 0a 09 09 09 09 09 09 72 61 6e 67 65 ') {.......range
1f80: 5f 65 6e 64 20 3d 20 73 74 72 74 6f 75 6c 6c 28 _end = strtoull(
1f90: 77 6f 72 6b 62 75 66 66 65 72 2c 20 26 77 6f 72 workbuffer, &wor
1fa0: 6b 62 75 66 66 65 72 5f 6e 65 78 74 2c 20 31 30 kbuffer_next, 10
1fb0: 29 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a );......}.....}.
1fc0: 09 09 09 7d 0a 09 09 7d 0a 0a 09 09 69 66 20 28 ...}...}....if (
1fd0: 6d 65 6d 63 6d 70 28 74 6d 70 62 75 66 66 65 72 memcmp(tmpbuffer
1fe0: 2c 20 22 5c 72 5c 6e 22 2c 20 32 29 20 3d 3d 20 , "\r\n", 2) ==
1ff0: 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 0) {....break;..
2000: 09 7d 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f .}..}...filed_lo
2010: 67 5f 6d 73 67 28 22 47 4f 54 5f 48 45 41 44 45 g_msg("GOT_HEADE
2020: 52 53 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 2f RS FD=...");.../
2030: 2a 20 57 65 20 6f 6e 6c 79 20 68 61 6e 64 6c 65 * We only handle
2040: 20 74 68 65 20 22 47 45 54 22 20 6d 65 74 68 6f the "GET" metho
2050: 64 20 2a 2f 0a 09 69 66 20 28 73 74 72 63 61 73 d */..if (strcas
2060: 65 63 6d 70 28 6d 65 74 68 6f 64 2c 20 22 67 65 ecmp(method, "ge
2070: 74 22 29 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 t") != 0) {...re
2080: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a turn(NULL);..}..
2090: 09 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 72 61 ./* Determine ra
20a0: 6e 67 65 20 2a 2f 0a 09 69 66 20 28 72 61 6e 67 nge */..if (rang
20b0: 65 5f 65 6e 64 20 21 3d 20 30 29 20 7b 0a 09 09 e_end != 0) {...
20c0: 69 66 20 28 72 61 6e 67 65 5f 65 6e 64 20 3c 3d if (range_end <=
20d0: 20 72 61 6e 67 65 5f 73 74 61 72 74 29 20 7b 0a range_start) {.
20e0: 09 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b ...return(NULL);
20f0: 0a 09 09 7d 0a 0a 09 09 72 61 6e 67 65 5f 6c 65 ...}....range_le
2100: 6e 67 74 68 20 3d 20 72 61 6e 67 65 5f 65 6e 64 ngth = range_end
2110: 20 2d 20 72 61 6e 67 65 5f 73 74 61 72 74 3b 0a - range_start;.
2120: 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 ...filed_log_msg
2130: 5f 64 65 62 75 67 28 22 43 6f 6d 70 75 74 69 6e _debug("Computin
2140: 67 20 6c 65 6e 67 74 68 20 70 61 72 61 6d 65 74 g length paramet
2150: 65 72 3a 20 25 6c 6c 75 20 3d 20 25 6c 6c 75 20 er: %llu = %llu
2160: 2d 20 25 6c 6c 75 22 2c 0a 09 09 09 28 75 6e 73 - %llu",....(uns
2170: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 igned long long)
2180: 20 72 61 6e 67 65 5f 6c 65 6e 67 74 68 2c 0a 09 range_length,..
2190: 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 ..(unsigned long
21a0: 20 6c 6f 6e 67 29 20 72 61 6e 67 65 5f 65 6e 64 long) range_end
21b0: 2c 0a 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c ,....(unsigned l
21c0: 6f 6e 67 20 6c 6f 6e 67 29 20 72 61 6e 67 65 5f ong long) range_
21d0: 73 74 61 72 74 0a 09 09 29 3b 0a 09 7d 0a 0a 09 start...);..}...
21e0: 2f 2a 20 46 69 6c 6c 20 75 70 20 73 74 72 75 63 /* Fill up struc
21f0: 74 75 72 65 20 74 6f 20 72 65 74 75 72 6e 20 2a ture to return *
2200: 2f 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 70 61 /..buffer_st->pa
2210: 74 68 20 20 20 3d 20 70 61 74 68 3b 0a 09 62 75 th = path;..bu
2220: 66 66 65 72 5f 73 74 2d 3e 68 65 61 64 65 72 73 ffer_st->headers
2230: 2e 72 61 6e 67 65 2e 70 72 65 73 65 6e 74 20 3d .range.present =
2240: 20 72 61 6e 67 65 5f 72 65 71 75 65 73 74 3b 0a range_request;.
2250: 09 62 75 66 66 65 72 5f 73 74 2d 3e 68 65 61 64 .buffer_st->head
2260: 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74 ers.range.offset
2270: 20 20 3d 20 72 61 6e 67 65 5f 73 74 61 72 74 3b = range_start;
2280: 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 68 65 61 ..buffer_st->hea
2290: 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 ders.range.lengt
22a0: 68 20 20 3d 20 72 61 6e 67 65 5f 6c 65 6e 67 74 h = range_lengt
22b0: 68 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75 66 66 h;...return(buff
22c0: 65 72 5f 73 74 29 3b 0a 7d 0a 0a 2f 2a 20 52 65 er_st);.}../* Re
22d0: 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 20 70 61 turn an error pa
22e0: 67 65 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 ge */.static voi
22f0: 64 20 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61 d filed_error_pa
2300: 67 65 28 46 49 4c 45 20 2a 66 70 2c 20 63 6f 6e ge(FILE *fp, con
2310: 73 74 20 63 68 61 72 20 2a 64 61 74 65 5f 63 75 st char *date_cu
2320: 72 72 65 6e 74 2c 20 69 6e 74 20 65 72 72 6f 72 rrent, int error
2330: 5f 6e 75 6d 62 65 72 29 20 7b 0a 09 63 68 61 72 _number) {..char
2340: 20 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d *error_string =
2350: 20 22 3c 68 74 6d 6c 3e 3c 68 65 61 64 3e 3c 74 "<html><head><t
2360: 69 74 6c 65 3e 45 52 52 4f 52 3c 2f 74 69 74 6c itle>ERROR</titl
2370: 65 3e 3c 2f 68 65 61 64 3e 3c 62 6f 64 79 3e 55 e></head><body>U
2380: 6e 61 62 6c 65 20 74 6f 20 70 72 6f 63 65 73 73 nable to process
2390: 20 72 65 71 75 65 73 74 3c 2f 62 6f 64 79 3e 3c request</body><
23a0: 2f 68 74 6d 6c 3e 22 3b 0a 0a 09 66 70 72 69 6e /html>";...fprin
23b0: 74 66 28 66 70 2c 20 22 48 54 54 50 2f 31 2e 31 tf(fp, "HTTP/1.1
23c0: 20 25 69 20 4f 4b 5c 72 5c 6e 44 61 74 65 3a 20 %i OK\r\nDate:
23d0: 25 73 5c 72 5c 6e 53 65 72 76 65 72 3a 20 66 69 %s\r\nServer: fi
23e0: 6c 65 64 5c 72 5c 6e 4c 61 73 74 2d 4d 6f 64 69 led\r\nLast-Modi
23f0: 66 69 65 64 3a 20 25 73 5c 72 5c 6e 43 6f 6e 74 fied: %s\r\nCont
2400: 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 6c 6c 75 ent-Length: %llu
2410: 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 54 79 70 65 \r\nContent-Type
2420: 3a 20 25 73 5c 72 5c 6e 43 6f 6e 6e 65 63 74 69 : %s\r\nConnecti
2430: 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e 5c 72 5c on: close\r\n\r\
2440: 6e 25 73 22 2c 0a 09 09 65 72 72 6f 72 5f 6e 75 n%s",...error_nu
2450: 6d 62 65 72 2c 0a 09 09 64 61 74 65 5f 63 75 72 mber,...date_cur
2460: 72 65 6e 74 2c 0a 09 09 64 61 74 65 5f 63 75 72 rent,...date_cur
2470: 72 65 6e 74 2c 0a 09 09 28 75 6e 73 69 67 6e 65 rent,...(unsigne
2480: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 72 d long long) str
2490: 6c 65 6e 28 65 72 72 6f 72 5f 73 74 72 69 6e 67 len(error_string
24a0: 29 2c 0a 09 09 22 74 65 78 74 2f 68 74 6d 6c 22 ),..."text/html"
24b0: 2c 0a 09 09 65 72 72 6f 72 5f 73 74 72 69 6e 67 ,...error_string
24c0: 0a 09 29 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e 64 6c ..);.}../* Handl
24d0: 65 20 61 20 73 69 6e 67 6c 65 20 72 65 71 75 65 e a single reque
24e0: 73 74 20 66 72 6f 6d 20 61 20 63 6c 69 65 6e 74 st from a client
24f0: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20 */.static void
2500: 66 69 6c 65 64 5f 68 61 6e 64 6c 65 5f 63 6c 69 filed_handle_cli
2510: 65 6e 74 28 69 6e 74 20 66 64 2c 20 73 74 72 75 ent(int fd, stru
2520: 63 74 20 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 ct filed_http_re
2530: 71 75 65 73 74 20 2a 72 65 71 75 65 73 74 29 20 quest *request)
2540: 7b 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f {..struct filed_
2550: 66 69 6c 65 69 6e 66 6f 20 2a 66 69 6c 65 69 6e fileinfo *filein
2560: 66 6f 3b 0a 09 73 73 69 7a 65 5f 74 20 73 65 6e fo;..ssize_t sen
2570: 64 66 69 6c 65 5f 72 65 74 3b 0a 09 73 69 7a 65 dfile_ret;..size
2580: 5f 74 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 2c _t sendfile_len,
2590: 20 73 65 6e 64 66 69 6c 65 5f 73 65 6e 74 2c 20 sendfile_sent,
25a0: 73 65 6e 64 66 69 6c 65 5f 73 69 7a 65 3b 0a 09 sendfile_size;..
25b0: 6f 66 66 5f 74 20 73 65 6e 64 66 69 6c 65 5f 6f off_t sendfile_o
25c0: 66 66 73 65 74 3b 0a 09 63 68 61 72 20 2a 70 61 ffset;..char *pa
25d0: 74 68 3b 0a 09 63 68 61 72 20 2a 64 61 74 65 5f th;..char *date_
25e0: 63 75 72 72 65 6e 74 2c 20 64 61 74 65 5f 63 75 current, date_cu
25f0: 72 72 65 6e 74 5f 62 5b 36 34 5d 3b 0a 09 69 6e rrent_b[64];..in
2600: 74 20 68 74 74 70 5f 63 6f 64 65 3b 0a 09 46 49 t http_code;..FI
2610: 4c 45 20 2a 66 70 3b 0a 0a 09 2f 2a 20 44 65 74 LE *fp;.../* Det
2620: 65 72 6d 69 6e 65 20 63 75 72 72 65 6e 74 20 74 ermine current t
2630: 69 6d 65 20 2a 2f 0a 09 64 61 74 65 5f 63 75 72 ime */..date_cur
2640: 72 65 6e 74 20 3d 20 66 69 6c 65 64 5f 66 6f 72 rent = filed_for
2650: 6d 61 74 5f 74 69 6d 65 28 64 61 74 65 5f 63 75 mat_time(date_cu
2660: 72 72 65 6e 74 5f 62 2c 20 73 69 7a 65 6f 66 28 rrent_b, sizeof(
2670: 64 61 74 65 5f 63 75 72 72 65 6e 74 5f 62 29 2c date_current_b),
2680: 20 74 69 6d 65 28 4e 55 4c 4c 29 29 3b 0a 0a 09 time(NULL));...
2690: 2f 2a 20 4f 70 65 6e 20 73 6f 63 6b 65 74 20 61 /* Open socket a
26a0: 73 20 41 4e 53 49 20 49 2f 4f 20 66 6f 72 20 65 s ANSI I/O for e
26b0: 61 73 65 20 6f 66 20 75 73 65 20 2a 2f 0a 09 66 ase of use */..f
26c0: 70 20 3d 20 66 64 6f 70 65 6e 28 66 64 2c 20 22 p = fdopen(fd, "
26d0: 77 2b 62 22 29 3b 0a 09 69 66 20 28 66 70 20 3d w+b");..if (fp =
26e0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 63 6c 6f 73 = NULL) {...clos
26f0: 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e e(fd);....return
2700: 3b 0a 09 7d 0a 0a 09 72 65 71 75 65 73 74 20 3d ;..}...request =
2710: 20 66 69 6c 65 64 5f 67 65 74 5f 68 74 74 70 5f filed_get_http_
2720: 72 65 71 75 65 73 74 28 66 70 2c 20 72 65 71 75 request(fp, requ
2730: 65 73 74 29 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f est);...filed_lo
2740: 67 5f 6d 73 67 28 22 50 52 4f 43 45 53 53 5f 52 g_msg("PROCESS_R
2750: 45 50 4c 59 5f 53 54 41 52 54 20 46 44 3d 2e 2e EPLY_START FD=..
2760: 2e 20 50 41 54 48 3d 2e 2e 2e 20 52 41 4e 47 45 . PATH=... RANGE
2770: 5f 53 54 41 52 54 3d 2e 2e 2e 20 52 41 4e 47 45 _START=... RANGE
2780: 5f 4c 45 4e 47 54 48 3d 2e 2e 2e 22 29 3b 0a 0a _LENGTH=...");..
2790: 09 69 66 20 28 72 65 71 75 65 73 74 20 3d 3d 20 .if (request ==
27a0: 4e 55 4c 4c 20 7c 7c 20 72 65 71 75 65 73 74 2d NULL || request-
27b0: 3e 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b >path == NULL) {
27c0: 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 ...filed_error_p
27d0: 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72 age(fp, date_cur
27e0: 72 65 6e 74 2c 20 35 30 30 29 3b 0a 0a 09 09 66 rent, 500);....f
27f0: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 iled_log_msg("PR
2800: 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 OCESS_REPLY_COMP
2810: 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f LETE FD=... ERRO
2820: 52 3d 35 30 30 22 29 3b 0a 0a 09 09 66 63 6c 6f R=500");....fclo
2830: 73 65 28 66 70 29 3b 0a 0a 09 09 72 65 74 75 72 se(fp);....retur
2840: 6e 3b 0a 09 7d 0a 0a 09 70 61 74 68 20 3d 20 72 n;..}...path = r
2850: 65 71 75 65 73 74 2d 3e 70 61 74 68 3b 0a 0a 09 equest->path;...
2860: 68 74 74 70 5f 63 6f 64 65 20 3d 20 2d 31 3b 0a http_code = -1;.
2870: 0a 09 66 69 6c 65 69 6e 66 6f 20 3d 20 66 69 6c ..fileinfo = fil
2880: 65 64 5f 6f 70 65 6e 5f 66 69 6c 65 28 70 61 74 ed_open_file(pat
2890: 68 2c 20 26 72 65 71 75 65 73 74 2d 3e 66 69 6c h, &request->fil
28a0: 65 69 6e 66 6f 29 3b 0a 09 69 66 20 28 66 69 6c einfo);..if (fil
28b0: 65 69 6e 66 6f 20 3d 3d 20 4e 55 4c 4c 29 20 7b einfo == NULL) {
28c0: 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 ...filed_error_p
28d0: 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72 age(fp, date_cur
28e0: 72 65 6e 74 2c 20 34 30 34 29 3b 0a 0a 09 09 66 rent, 404);....f
28f0: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 iled_log_msg("PR
2900: 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 OCESS_REPLY_COMP
2910: 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f LETE FD=... ERRO
2920: 52 3d 34 30 34 22 29 3b 0a 09 7d 20 65 6c 73 65 R=404");..} else
2930: 20 7b 0a 09 09 69 66 20 28 72 65 71 75 65 73 74 {...if (request
2940: 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e ->headers.range.
2950: 6f 66 66 73 65 74 20 21 3d 20 30 20 7c 7c 20 72 offset != 0 || r
2960: 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e equest->headers.
2970: 72 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3e 3d 20 range.length >=
2980: 30 29 20 7b 0a 09 09 09 69 66 20 28 72 65 71 75 0) {....if (requ
2990: 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e est->headers.ran
29a0: 67 65 2e 6f 66 66 73 65 74 20 3e 3d 20 66 69 6c ge.offset >= fil
29b0: 65 69 6e 66 6f 2d 3e 6c 65 6e 29 20 7b 0a 09 09 einfo->len) {...
29c0: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 ..filed_log_msg(
29d0: 22 50 52 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 "PROCESS_REPLY_C
29e0: 4f 4d 50 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 OMPLETE FD=... E
29f0: 52 52 4f 52 3d 34 31 36 22 29 3b 0a 0a 09 09 09 RROR=416");.....
2a00: 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61 67 .filed_error_pag
2a10: 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72 72 65 e(fp, date_curre
2a20: 6e 74 2c 20 34 31 36 29 3b 0a 09 09 09 7d 20 65 nt, 416);....} e
2a30: 6c 73 65 20 7b 0a 09 09 09 09 69 66 20 28 72 65 lse {.....if (re
2a40: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 quest->headers.r
2a50: 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3c 20 30 29 ange.length < 0)
2a60: 20 7b 0a 09 09 09 09 09 66 69 6c 65 64 5f 6c 6f {......filed_lo
2a70: 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 43 6f 6d g_msg_debug("Com
2a80: 70 75 74 69 6e 67 20 6c 65 6e 67 74 68 20 74 6f puting length to
2a90: 20 66 69 74 20 69 6e 20 62 6f 75 6e 64 73 3a 20 fit in bounds:
2aa0: 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 20 3d 20 fileinfo->len =
2ab0: 25 6c 6c 75 2c 20 72 65 71 75 65 73 74 2d 3e 68 %llu, request->h
2ac0: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 eaders.range.off
2ad0: 73 65 74 20 3d 20 25 6c 6c 75 22 2c 0a 09 09 09 set = %llu",....
2ae0: 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e ...(unsigned lon
2af0: 67 20 6c 6f 6e 67 29 20 66 69 6c 65 69 6e 66 6f g long) fileinfo
2b00: 2d 3e 6c 65 6e 2c 0a 09 09 09 09 09 09 28 75 6e ->len,.......(un
2b10: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 signed long long
2b20: 29 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 ) request->heade
2b30: 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74 0a rs.range.offset.
2b40: 09 09 09 09 09 29 3b 0a 0a 09 09 09 09 09 72 65 .....);.......re
2b50: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 quest->headers.r
2b60: 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3d 20 66 69 ange.length = fi
2b70: 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 20 2d 20 72 65 leinfo->len - re
2b80: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 quest->headers.r
2b90: 61 6e 67 65 2e 6f 66 66 73 65 74 3b 0a 09 09 09 ange.offset;....
2ba0: 09 7d 0a 0a 09 09 09 09 66 69 6c 65 64 5f 6c 6f .}......filed_lo
2bb0: 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 50 61 72 g_msg_debug("Par
2bc0: 74 69 61 6c 20 72 65 71 75 65 73 74 2c 20 73 74 tial request, st
2bd0: 61 72 74 69 6e 67 20 61 74 3a 20 25 6c 6c 75 20 arting at: %llu
2be0: 61 6e 64 20 72 75 6e 6e 69 6e 67 20 66 6f 72 20 and running for
2bf0: 25 6c 6c 75 20 62 79 74 65 73 22 2c 0a 09 09 09 %llu bytes",....
2c00: 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 ..(unsigned long
2c10: 20 6c 6f 6e 67 29 20 72 65 71 75 65 73 74 2d 3e long) request->
2c20: 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 headers.range.of
2c30: 66 73 65 74 2c 0a 09 09 09 09 09 28 75 6e 73 69 fset,......(unsi
2c40: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 gned long long)
2c50: 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 request->headers
2c60: 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 0a 09 09 .range.length...
2c70: 09 09 29 3b 0a 0a 09 09 09 09 68 74 74 70 5f 63 ..);......http_c
2c80: 6f 64 65 20 3d 20 32 30 36 3b 0a 09 09 09 7d 0a ode = 206;....}.
2c90: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 69 66 ..} else {....if
2ca0: 20 28 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 (request->heade
2cb0: 72 73 2e 72 61 6e 67 65 2e 70 72 65 73 65 6e 74 rs.range.present
2cc0: 29 20 7b 0a 09 09 09 09 68 74 74 70 5f 63 6f 64 ) {.....http_cod
2cd0: 65 20 3d 20 32 30 36 3b 0a 09 09 09 7d 20 65 6c e = 206;....} el
2ce0: 73 65 20 7b 0a 09 09 09 09 68 74 74 70 5f 63 6f se {.....http_co
2cf0: 64 65 20 3d 20 32 30 30 3b 0a 09 09 09 7d 0a 09 de = 200;....}..
2d00: 09 09 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 ..request->heade
2d10: 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74 20 rs.range.offset
2d20: 3d 20 30 3b 0a 09 09 09 72 65 71 75 65 73 74 2d = 0;....request-
2d30: 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c >headers.range.l
2d40: 65 6e 67 74 68 20 3d 20 66 69 6c 65 69 6e 66 6f ength = fileinfo
2d50: 2d 3e 6c 65 6e 3b 0a 09 09 7d 0a 0a 09 09 69 66 ->len;...}....if
2d60: 20 28 68 74 74 70 5f 63 6f 64 65 20 3e 20 30 29 (http_code > 0)
2d70: 20 7b 0a 09 09 09 66 70 72 69 6e 74 66 28 66 70 {....fprintf(fp
2d80: 2c 20 22 48 54 54 50 2f 31 2e 31 20 25 69 20 4f , "HTTP/1.1 %i O
2d90: 4b 5c 72 5c 6e 44 61 74 65 3a 20 25 73 5c 72 5c K\r\nDate: %s\r\
2da0: 6e 53 65 72 76 65 72 3a 20 66 69 6c 65 64 5c 72 nServer: filed\r
2db0: 5c 6e 4c 61 73 74 2d 4d 6f 64 69 66 69 65 64 3a \nLast-Modified:
2dc0: 20 25 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 4c %s\r\nContent-L
2dd0: 65 6e 67 74 68 3a 20 25 6c 6c 75 5c 72 5c 6e 41 ength: %llu\r\nA
2de0: 63 63 65 70 74 2d 52 61 6e 67 65 73 3a 20 62 79 ccept-Ranges: by
2df0: 74 65 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 54 tes\r\nContent-T
2e00: 79 70 65 3a 20 25 73 5c 72 5c 6e 43 6f 6e 6e 65 ype: %s\r\nConne
2e10: 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e ction: close\r\n
2e20: 22 2c 0a 09 09 09 09 68 74 74 70 5f 63 6f 64 65 ",.....http_code
2e30: 2c 0a 09 09 09 09 64 61 74 65 5f 63 75 72 72 65 ,.....date_curre
2e40: 6e 74 2c 0a 09 09 09 09 66 69 6c 65 69 6e 66 6f nt,.....fileinfo
2e50: 2d 3e 6c 61 73 74 6d 6f 64 2c 0a 09 09 09 09 28 ->lastmod,.....(
2e60: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f unsigned long lo
2e70: 6e 67 29 20 72 65 71 75 65 73 74 2d 3e 68 65 61 ng) request->hea
2e80: 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 ders.range.lengt
2e90: 68 2c 0a 09 09 09 09 66 69 6c 65 69 6e 66 6f 2d h,.....fileinfo-
2ea0: 3e 74 79 70 65 0a 09 09 09 29 3b 0a 09 09 09 69 >type....);....i
2eb0: 66 20 28 68 74 74 70 5f 63 6f 64 65 20 3d 3d 20 f (http_code ==
2ec0: 32 30 36 29 20 7b 0a 09 09 09 09 66 70 72 69 6e 206) {.....fprin
2ed0: 74 66 28 66 70 2c 20 22 43 6f 6e 74 65 6e 74 2d tf(fp, "Content-
2ee0: 52 61 6e 67 65 3a 20 62 79 74 65 73 20 25 6c 6c Range: bytes %ll
2ef0: 75 2d 25 6c 6c 75 2f 25 6c 6c 75 5c 72 5c 6e 22 u-%llu/%llu\r\n"
2f00: 2c 0a 09 09 09 09 09 28 75 6e 73 69 67 6e 65 64 ,......(unsigned
2f10: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 72 65 71 75 long long) requ
2f20: 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e est->headers.ran
2f30: 67 65 2e 6f 66 66 73 65 74 2c 0a 09 09 09 09 09 ge.offset,......
2f40: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c (unsigned long l
2f50: 6f 6e 67 29 20 28 72 65 71 75 65 73 74 2d 3e 68 ong) (request->h
2f60: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 eaders.range.off
2f70: 73 65 74 20 2b 20 72 65 71 75 65 73 74 2d 3e 68 set + request->h
2f80: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e eaders.range.len
2f90: 67 74 68 20 2d 20 31 29 2c 0a 09 09 09 09 09 28 gth - 1),......(
2fa0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f unsigned long lo
2fb0: 6e 67 29 20 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 ng) fileinfo->le
2fc0: 6e 0a 09 09 09 09 29 3b 0a 09 09 09 7d 0a 09 09 n.....);....}...
2fd0: 09 66 70 72 69 6e 74 66 28 66 70 2c 20 22 5c 72 .fprintf(fp, "\r
2fe0: 5c 6e 22 29 3b 0a 09 09 09 66 66 6c 75 73 68 28 \n");....fflush(
2ff0: 66 70 29 3b 0a 0a 09 09 09 66 69 6c 65 64 5f 6c fp);.....filed_l
3000: 6f 67 5f 6d 73 67 28 22 50 52 4f 43 45 53 53 5f og_msg("PROCESS_
3010: 52 45 50 4c 59 5f 43 4f 4d 50 4c 45 54 45 20 46 REPLY_COMPLETE F
3020: 44 3d 2e 2e 2e 20 53 54 41 54 55 53 3d 32 30 58 D=... STATUS=20X
3030: 22 29 3b 0a 0a 23 69 66 64 65 66 20 46 49 4c 45 ");..#ifdef FILE
3040: 44 5f 4e 4f 4e 42 4c 4f 43 4b 5f 48 54 54 50 0a D_NONBLOCK_HTTP.
3050: 09 09 09 69 6e 74 20 73 6f 63 6b 65 74 5f 66 6c ...int socket_fl
3060: 61 67 73 3b 0a 09 09 09 66 64 5f 73 65 74 20 72 ags;....fd_set r
3070: 66 64 2c 20 77 66 64 3b 0a 09 09 09 63 68 61 72 fd, wfd;....char
3080: 20 73 69 6e 6b 62 75 66 5b 38 31 39 32 5d 3b 0a sinkbuf[8192];.
3090: 09 09 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f ...ssize_t read_
30a0: 72 65 74 3b 0a 0a 09 09 09 46 44 5f 5a 45 52 4f ret;.....FD_ZERO
30b0: 28 26 72 66 64 29 3b 0a 09 09 09 46 44 5f 5a 45 (&rfd);....FD_ZE
30c0: 52 4f 28 26 77 66 64 29 3b 0a 09 09 09 46 44 5f RO(&wfd);....FD_
30d0: 53 45 54 28 66 64 2c 20 26 72 66 64 29 3b 0a 09 SET(fd, &rfd);..
30e0: 09 09 46 44 5f 53 45 54 28 66 64 2c 20 26 77 66 ..FD_SET(fd, &wf
30f0: 64 29 3b 0a 0a 09 09 09 73 6f 63 6b 65 74 5f 66 d);.....socket_f
3100: 6c 61 67 73 20 3d 20 66 63 6e 74 6c 28 66 64 2c lags = fcntl(fd,
3110: 20 46 5f 47 45 54 46 4c 29 3b 0a 09 09 09 66 63 F_GETFL);....fc
3120: 6e 74 6c 28 66 64 2c 20 46 5f 53 45 54 46 4c 2c ntl(fd, F_SETFL,
3130: 20 73 6f 63 6b 65 74 5f 66 6c 61 67 73 20 7c 20 socket_flags |
3140: 4f 5f 4e 4f 4e 42 4c 4f 43 4b 29 3b 0a 23 65 6e O_NONBLOCK);.#en
3150: 64 69 66 0a 0a 09 09 09 66 69 6c 65 64 5f 6c 6f dif.....filed_lo
3160: 67 5f 6d 73 67 28 22 53 45 4e 44 5f 53 54 41 52 g_msg("SEND_STAR
3170: 54 20 49 46 44 3d 2e 2e 2e 20 4f 46 44 3d 2e 2e T IFD=... OFD=..
3180: 2e 20 42 59 54 45 53 3d 2e 2e 2e 22 29 3b 0a 0a . BYTES=...");..
3190: 09 09 09 73 65 6e 64 66 69 6c 65 5f 6f 66 66 73 ...sendfile_offs
31a0: 65 74 20 3d 20 72 65 71 75 65 73 74 2d 3e 68 65 et = request->he
31b0: 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 aders.range.offs
31c0: 65 74 3b 0a 09 09 09 73 65 6e 64 66 69 6c 65 5f et;....sendfile_
31d0: 6c 65 6e 20 3d 20 72 65 71 75 65 73 74 2d 3e 68 len = request->h
31e0: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e eaders.range.len
31f0: 67 74 68 3b 0a 09 09 09 73 65 6e 64 66 69 6c 65 gth;....sendfile
3200: 5f 73 65 6e 74 20 3d 20 30 3b 0a 09 09 09 77 68 _sent = 0;....wh
3210: 69 6c 65 20 28 31 29 20 7b 0a 09 09 09 09 69 66 ile (1) {.....if
3220: 20 28 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 3e (sendfile_len >
3230: 20 46 49 4c 45 44 5f 53 45 4e 44 46 49 4c 45 5f FILED_SENDFILE_
3240: 4d 41 58 29 20 7b 0a 09 09 09 09 09 73 65 6e 64 MAX) {......send
3250: 66 69 6c 65 5f 73 69 7a 65 20 3d 20 46 49 4c 45 file_size = FILE
3260: 44 5f 53 45 4e 44 46 49 4c 45 5f 4d 41 58 3b 0a D_SENDFILE_MAX;.
3270: 09 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 ....} else {....
3280: 09 09 73 65 6e 64 66 69 6c 65 5f 73 69 7a 65 20 ..sendfile_size
3290: 3d 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 3b 0a = sendfile_len;.
32a0: 09 09 09 09 7d 0a 0a 09 09 09 09 73 65 6e 64 66 ....}......sendf
32b0: 69 6c 65 5f 72 65 74 20 3d 20 73 65 6e 64 66 69 ile_ret = sendfi
32c0: 6c 65 28 66 64 2c 20 66 69 6c 65 69 6e 66 6f 2d le(fd, fileinfo-
32d0: 3e 66 64 2c 20 26 73 65 6e 64 66 69 6c 65 5f 6f >fd, &sendfile_o
32e0: 66 66 73 65 74 2c 20 73 65 6e 64 66 69 6c 65 5f ffset, sendfile_
32f0: 73 69 7a 65 29 3b 0a 09 09 09 09 69 66 20 28 73 size);.....if (s
3300: 65 6e 64 66 69 6c 65 5f 72 65 74 20 3c 3d 20 30 endfile_ret <= 0
3310: 29 20 7b 0a 23 69 66 64 65 66 20 46 49 4c 45 44 ) {.#ifdef FILED
3320: 5f 4e 4f 4e 42 4c 4f 43 4b 5f 48 54 54 50 0a 09 _NONBLOCK_HTTP..
3330: 09 09 09 09 69 66 20 28 65 72 72 6e 6f 20 3d 3d ....if (errno ==
3340: 20 45 41 47 41 49 4e 29 20 7b 0a 09 09 09 09 09 EAGAIN) {......
3350: 09 73 65 6e 64 66 69 6c 65 5f 72 65 74 20 3d 20 .sendfile_ret =
3360: 30 3b 0a 0a 09 09 09 09 09 09 77 68 69 6c 65 20 0;........while
3370: 28 31 29 20 7b 0a 09 09 09 09 09 09 09 73 65 6c (1) {........sel
3380: 65 63 74 28 66 64 20 2b 20 31 2c 20 26 72 66 64 ect(fd + 1, &rfd
3390: 2c 20 26 77 66 64 2c 20 4e 55 4c 4c 2c 20 4e 55 , &wfd, NULL, NU
33a0: 4c 4c 29 3b 0a 09 09 09 09 09 09 09 69 66 20 28 LL);........if (
33b0: 46 44 5f 49 53 53 45 54 28 66 64 2c 20 26 72 66 FD_ISSET(fd, &rf
33c0: 64 29 29 20 7b 0a 09 09 09 09 09 09 09 09 72 65 d)) {.........re
33d0: 61 64 5f 72 65 74 20 3d 20 72 65 61 64 28 66 64 ad_ret = read(fd
33e0: 2c 20 73 69 6e 6b 62 75 66 2c 20 73 69 7a 65 6f , sinkbuf, sizeo
33f0: 66 28 73 69 6e 6b 62 75 66 29 29 3b 0a 0a 09 09 f(sinkbuf));....
3400: 09 09 09 09 09 09 69 66 20 28 72 65 61 64 5f 72 ......if (read_r
3410: 65 74 20 3c 3d 20 30 29 20 7b 0a 09 09 09 09 09 et <= 0) {......
3420: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 ....break;......
3430: 09 09 09 7d 0a 09 09 09 09 09 09 09 7d 0a 0a 09 ...}........}...
3440: 09 09 09 09 09 09 69 66 20 28 46 44 5f 49 53 53 ......if (FD_ISS
3450: 45 54 28 66 64 2c 20 26 77 66 64 29 29 20 7b 0a ET(fd, &wfd)) {.
3460: 09 09 09 09 09 09 09 09 72 65 61 64 5f 72 65 74 ........read_ret
3470: 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 = 1;..........b
3480: 72 65 61 6b 3b 0a 09 09 09 09 09 09 09 7d 0a 09 reak;........}..
3490: 09 09 09 09 09 7d 0a 0a 09 09 09 09 09 09 69 66 .....}........if
34a0: 20 28 72 65 61 64 5f 72 65 74 20 3c 3d 20 30 29 (read_ret <= 0)
34b0: 20 7b 0a 09 09 09 09 09 09 09 62 72 65 61 6b 3b {........break;
34c0: 0a 09 09 09 09 09 09 7d 0a 09 09 09 09 09 7d 20 .......}......}
34d0: 65 6c 73 65 20 7b 0a 09 09 09 09 09 09 62 72 65 else {.......bre
34e0: 61 6b 3b 0a 09 09 09 09 09 7d 0a 23 65 6c 73 65 ak;......}.#else
34f0: 0a 09 09 09 09 09 62 72 65 61 6b 3b 0a 23 65 6e ......break;.#en
3500: 64 69 66 0a 09 09 09 09 7d 0a 0a 09 09 09 09 73 dif.....}......s
3510: 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 2d 3d 20 73 endfile_len -= s
3520: 65 6e 64 66 69 6c 65 5f 72 65 74 3b 0a 09 09 09 endfile_ret;....
3530: 09 73 65 6e 64 66 69 6c 65 5f 73 65 6e 74 20 2b .sendfile_sent +
3540: 3d 20 73 65 6e 64 66 69 6c 65 5f 72 65 74 3b 0a = sendfile_ret;.
3550: 09 09 09 09 69 66 20 28 73 65 6e 64 66 69 6c 65 ....if (sendfile
3560: 5f 6c 65 6e 20 3d 3d 20 30 29 20 7b 0a 09 09 09 _len == 0) {....
3570: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 7d 0a 09 ..break;.....}..
3580: 09 09 7d 0a 0a 09 09 09 66 69 6c 65 64 5f 6c 6f ..}.....filed_lo
3590: 67 5f 6d 73 67 28 22 53 45 4e 44 5f 43 4f 4d 50 g_msg("SEND_COMP
35a0: 4c 45 54 45 20 53 54 41 54 55 53 3d 2e 2e 2e 20 LETE STATUS=...
35b0: 49 46 44 3d 2e 2e 2e 20 4f 46 44 3d 2e 2e 2e 20 IFD=... OFD=...
35c0: 42 59 54 45 53 3d 2e 2e 2e 20 42 59 54 45 53 5f BYTES=... BYTES_
35d0: 53 45 4e 54 3d 2e 2e 2e 22 29 3b 0a 09 09 7d 0a SENT=...");...}.
35e0: 0a 09 09 63 6c 6f 73 65 28 66 69 6c 65 69 6e 66 ...close(fileinf
35f0: 6f 2d 3e 66 64 29 3b 0a 0a 09 09 66 69 6c 65 64 o->fd);....filed
3600: 5f 6c 6f 67 5f 6d 73 67 28 22 43 4c 4f 53 45 5f _log_msg("CLOSE_
3610: 46 49 4c 45 20 46 44 3d 2e 2e 2e 22 29 3b 0a 09 FILE FD=...");..
3620: 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 }...filed_log_ms
3630: 67 28 22 43 4c 4f 53 45 5f 43 4f 4e 4e 45 43 54 g("CLOSE_CONNECT
3640: 49 4f 4e 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 ION FD=...");...
3650: 66 63 6c 6f 73 65 28 66 70 29 3b 0a 0a 09 72 65 fclose(fp);...re
3660: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e 64 turn;.}../* Hand
3670: 6c 65 20 69 6e 63 6f 6d 69 6e 67 20 63 6f 6e 6e le incoming conn
3680: 65 63 74 69 6f 6e 73 20 2a 2f 0a 73 74 61 74 69 ections */.stati
3690: 63 20 76 6f 69 64 20 2a 66 69 6c 65 64 5f 77 6f c void *filed_wo
36a0: 72 6b 65 72 5f 74 68 72 65 61 64 28 76 6f 69 64 rker_thread(void
36b0: 20 2a 61 72 67 5f 76 29 20 7b 0a 09 73 74 72 75 *arg_v) {..stru
36c0: 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f ct filed_worker_
36d0: 74 68 72 65 61 64 5f 61 72 67 73 20 2a 61 72 67 thread_args *arg
36e0: 3b 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f ;..struct filed_
36f0: 68 74 74 70 5f 72 65 71 75 65 73 74 20 72 65 71 http_request req
3700: 75 65 73 74 3b 0a 09 73 74 72 75 63 74 20 73 6f uest;..struct so
3710: 63 6b 61 64 64 72 5f 69 6e 36 20 61 64 64 72 3b ckaddr_in6 addr;
3720: 0a 09 73 6f 63 6b 6c 65 6e 5f 74 20 61 64 64 72 ..socklen_t addr
3730: 6c 65 6e 3b 0a 09 69 6e 74 20 66 61 69 6c 75 72 len;..int failur
3740: 65 5f 63 6f 75 6e 74 20 3d 20 30 2c 20 6d 61 78 e_count = 0, max
3750: 5f 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3d _failure_count =
3760: 20 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f 55 MAX_FAILURE_COU
3770: 4e 54 3b 0a 09 69 6e 74 20 6d 61 73 74 65 72 5f NT;..int master_
3780: 66 64 2c 20 66 64 3b 0a 0a 09 2f 2a 20 52 65 61 fd, fd;.../* Rea
3790: 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 09 d arguments */..
37a0: 61 72 67 20 3d 20 61 72 67 5f 76 3b 0a 0a 09 6d arg = arg_v;...m
37b0: 61 73 74 65 72 5f 66 64 20 3d 20 61 72 67 2d 3e aster_fd = arg->
37c0: 66 64 3b 0a 0a 09 77 68 69 6c 65 20 28 31 29 20 fd;...while (1)
37d0: 7b 0a 09 09 2f 2a 20 46 61 69 6c 75 72 65 20 6c {.../* Failure l
37e0: 6f 6f 70 20 70 72 65 76 65 6e 74 69 6f 6e 20 2a oop prevention *
37f0: 2f 0a 09 09 69 66 20 28 66 61 69 6c 75 72 65 5f /...if (failure_
3800: 63 6f 75 6e 74 20 3e 20 6d 61 78 5f 66 61 69 6c count > max_fail
3810: 75 72 65 5f 63 6f 75 6e 74 29 20 7b 0a 09 09 09 ure_count) {....
3820: 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 2f 2a break;...}..../*
3830: 20 41 63 63 65 70 74 20 61 20 6e 65 77 20 63 6c Accept a new cl
3840: 69 65 6e 74 20 2a 2f 0a 09 09 61 64 64 72 6c 65 ient */...addrle
3850: 6e 20 3d 20 73 69 7a 65 6f 66 28 61 64 64 72 29 n = sizeof(addr)
3860: 3b 0a 09 09 66 64 20 3d 20 61 63 63 65 70 74 28 ;...fd = accept(
3870: 6d 61 73 74 65 72 5f 66 64 2c 20 28 73 74 72 75 master_fd, (stru
3880: 63 74 20 73 6f 63 6b 61 64 64 72 20 2a 29 20 26 ct sockaddr *) &
3890: 61 64 64 72 2c 20 26 61 64 64 72 6c 65 6e 29 3b addr, &addrlen);
38a0: 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 49 66 20 77 ..../*... * If w
38b0: 65 20 66 61 69 6c 2c 20 6d 61 6b 65 20 61 20 6e e fail, make a n
38c0: 6f 74 65 20 6f 66 20 69 74 20 73 6f 20 77 65 20 ote of it so we
38d0: 64 6f 6e 27 74 20 67 6f 20 69 6e 74 6f 20 61 20 don't go into a
38e0: 6c 6f 6f 70 20 6f 66 0a 09 09 20 2a 20 61 63 63 loop of... * acc
38f0: 65 70 74 28 29 20 66 61 69 6c 69 6e 67 0a 09 09 ept() failing...
3900: 20 2a 2f 0a 09 09 69 66 20 28 66 64 20 3c 20 30 */...if (fd < 0
3910: 29 20 7b 0a 09 09 09 2f 2a 20 4c 6f 67 20 74 68 ) {..../* Log th
3920: 65 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e e new connection
3930: 20 2a 2f 0a 09 09 09 66 69 6c 65 64 5f 6c 6f 67 */....filed_log
3940: 5f 6d 73 67 28 22 41 43 43 45 50 54 5f 46 41 49 _msg("ACCEPT_FAI
3950: 4c 45 44 22 29 3b 0a 0a 09 09 09 66 61 69 6c 75 LED");.....failu
3960: 72 65 5f 63 6f 75 6e 74 2b 2b 3b 0a 0a 09 09 09 re_count++;.....
3970: 63 6f 6e 74 69 6e 75 65 3b 0a 09 09 7d 0a 0a 09 continue;...}...
3980: 09 2f 2a 20 4c 6f 67 20 74 68 65 20 6e 65 77 20 ./* Log the new
3990: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 09 09 connection */...
39a0: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 4e filed_log_msg("N
39b0: 45 57 5f 43 4f 4e 4e 45 43 54 49 4f 4e 20 53 52 EW_CONNECTION SR
39c0: 43 5f 41 44 44 52 3d 2e 2e 2e 20 53 52 43 5f 50 C_ADDR=... SRC_P
39d0: 4f 52 54 3d 2e 2e 2e 20 46 44 3d 2e 2e 2e 22 29 ORT=... FD=...")
39e0: 3b 0a 0a 09 09 2f 2a 20 52 65 73 65 74 20 66 61 ;..../* Reset fa
39f0: 69 6c 75 72 65 20 63 6f 75 6e 74 2a 2f 0a 09 09 ilure count*/...
3a00: 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3d 20 failure_count =
3a10: 30 3b 0a 0a 09 09 2f 2a 20 48 61 6e 64 6c 65 20 0;..../* Handle
3a20: 73 6f 63 6b 65 74 20 2a 2f 0a 09 09 66 69 6c 65 socket */...file
3a30: 64 5f 68 61 6e 64 6c 65 5f 63 6c 69 65 6e 74 28 d_handle_client(
3a40: 66 64 2c 20 26 72 65 71 75 65 73 74 29 3b 0a 09 fd, &request);..
3a50: 7d 0a 0a 09 2f 2a 20 52 65 70 6f 72 74 20 65 72 }.../* Report er
3a60: 72 6f 72 20 2a 2f 0a 09 66 69 6c 65 64 5f 6c 6f ror */..filed_lo
3a70: 67 5f 6d 73 67 28 22 54 48 52 45 41 44 5f 44 49 g_msg("THREAD_DI
3a80: 45 44 20 41 42 4e 4f 52 4d 41 4c 22 29 3b 0a 0a ED ABNORMAL");..
3a90: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 7d .return(NULL);.}
3aa0: 0a 0a 2f 2a 20 43 72 65 61 74 65 20 77 6f 72 6b ../* Create work
3ab0: 65 72 20 74 68 72 65 61 64 73 20 2a 2f 0a 73 74 er threads */.st
3ac0: 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 77 atic int filed_w
3ad0: 6f 72 6b 65 72 5f 74 68 72 65 61 64 73 5f 69 6e orker_threads_in
3ae0: 69 74 28 69 6e 74 20 66 64 2c 20 69 6e 74 20 74 it(int fd, int t
3af0: 68 72 65 61 64 5f 63 6f 75 6e 74 29 20 7b 0a 09 hread_count) {..
3b00: 73 74 72 75 63 74 20 66 69 6c 65 64 5f 77 6f 72 struct filed_wor
3b10: 6b 65 72 5f 74 68 72 65 61 64 5f 61 72 67 73 20 ker_thread_args
3b20: 2a 61 72 67 3b 0a 09 70 74 68 72 65 61 64 5f 74 *arg;..pthread_t
3b30: 20 74 68 72 65 61 64 69 64 3b 0a 09 69 6e 74 20 threadid;..int
3b40: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e pthread_ret;..in
3b50: 74 20 69 3b 0a 0a 09 66 6f 72 20 28 69 20 3d 20 t i;...for (i =
3b60: 30 3b 20 69 20 3c 20 74 68 72 65 61 64 5f 63 6f 0; i < thread_co
3b70: 75 6e 74 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72 unt; i++) {...ar
3b80: 67 20 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f g = malloc(sizeo
3b90: 66 28 2a 61 72 67 29 29 3b 0a 0a 09 09 61 72 67 f(*arg));....arg
3ba0: 2d 3e 66 64 20 3d 20 66 64 3b 0a 0a 09 09 70 74 ->fd = fd;....pt
3bb0: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72 hread_ret = pthr
3bc0: 65 61 64 5f 63 72 65 61 74 65 28 26 74 68 72 65 ead_create(&thre
3bd0: 61 64 69 64 2c 20 4e 55 4c 4c 2c 20 66 69 6c 65 adid, NULL, file
3be0: 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 2c d_worker_thread,
3bf0: 20 61 72 67 29 3b 0a 09 09 69 66 20 28 70 74 68 arg);...if (pth
3c00: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b read_ret != 0) {
3c10: 0a 09 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a ....return(-1);.
3c20: 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 ..}..}...return(
3c30: 30 29 3b 0a 7d 0a 0a 2f 2a 20 44 69 73 70 6c 61 0);.}../* Displa
3c40: 79 20 68 65 6c 70 20 2a 2f 0a 73 74 61 74 69 63 y help */.static
3c50: 20 76 6f 69 64 20 66 69 6c 65 64 5f 70 72 69 6e void filed_prin
3c60: 74 5f 68 65 6c 70 28 46 49 4c 45 20 2a 6f 75 74 t_help(FILE *out
3c70: 70 75 74 2c 20 69 6e 74 20 6c 6f 6e 67 5f 68 65 put, int long_he
3c80: 6c 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a lp, const char *
3c90: 65 78 74 72 61 29 20 7b 0a 09 69 66 20 28 65 78 extra) {..if (ex
3ca0: 74 72 61 29 20 7b 0a 09 09 66 70 72 69 6e 74 66 tra) {...fprintf
3cb0: 28 6f 75 74 70 75 74 2c 20 22 25 73 5c 6e 22 2c (output, "%s\n",
3cc0: 20 65 78 74 72 61 29 3b 0a 09 7d 0a 0a 09 66 70 extra);..}...fp
3cd0: 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 55 rintf(output, "U
3ce0: 73 61 67 65 3a 20 66 69 6c 65 64 20 5b 3c 6f 70 sage: filed [<op
3cf0: 74 69 6f 6e 73 3e 5d 5c 6e 22 29 3b 0a 09 66 70 tions>]\n");..fp
3d00: 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 rintf(output, "
3d10: 20 4f 70 74 69 6f 6e 73 3a 5c 6e 22 29 3b 0a 09 Options:\n");..
3d20: 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 fprintf(output,
3d30: 22 20 20 20 20 20 20 2d 68 2c 20 2d 2d 68 65 6c " -h, --hel
3d40: 70 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 p\n");..fprintf(
3d50: 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d output, " -
3d60: 62 20 3c 61 64 64 72 65 73 73 3e 2c 20 2d 2d 62 b <address>, --b
3d70: 69 6e 64 20 3c 61 64 64 72 65 73 73 3e 5c 6e 22 ind <address>\n"
3d80: 29 3b 0a 09 66 70 72 69 6e 74 66 28 6f 75 74 70 );..fprintf(outp
3d90: 75 74 2c 20 22 20 20 20 20 20 20 2d 70 20 3c 70 ut, " -p <p
3da0: 6f 72 74 3e 2c 20 2d 2d 70 6f 72 74 20 3c 70 6f ort>, --port <po
3db0: 72 74 3e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 rt>\n");..fprint
3dc0: 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 f(output, "
3dd0: 20 2d 74 20 3c 63 6f 75 6e 74 3e 2c 20 2d 2d 74 -t <count>, --t
3de0: 68 72 65 61 64 73 20 3c 63 6f 75 6e 74 3e 5c 6e hreads <count>\n
3df0: 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 6f 75 74 ");..fprintf(out
3e00: 70 75 74 2c 20 22 20 20 20 20 20 20 2d 63 20 3c put, " -c <
3e10: 65 6e 74 72 69 65 73 3e 2c 20 2d 2d 63 61 63 68 entries>, --cach
3e20: 65 20 3c 65 6e 74 72 69 65 73 3e 5c 6e 22 29 3b e <entries>\n");
3e30: 0a 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 ..fprintf(output
3e40: 2c 20 22 20 20 20 20 20 20 2d 75 20 3c 75 73 65 , " -u <use
3e50: 72 3e 2c 20 2d 2d 75 73 65 72 20 3c 75 73 65 72 r>, --user <user
3e60: 3e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 >\n");..fprintf(
3e70: 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d output, " -
3e80: 72 20 3c 64 69 72 65 63 74 6f 72 79 3e 2c 20 2d r <directory>, -
3e90: 2d 72 6f 6f 74 20 3c 64 69 72 65 63 74 6f 72 79 -root <directory
3ea0: 3e 5c 6e 22 29 3b 0a 0a 09 69 66 20 28 6c 6f 6e >\n");...if (lon
3eb0: 67 5f 68 65 6c 70 29 20 7b 0a 09 09 66 70 72 69 g_help) {...fpri
3ec0: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 5c 6e 22 ntf(output, "\n"
3ed0: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 );...fprintf(out
3ee0: 70 75 74 2c 20 22 20 20 55 73 61 67 65 3a 5c 6e put, " Usage:\n
3ef0: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 ");...fprintf(ou
3f00: 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d 68 20 tput, " -h
3f10: 28 6f 72 20 2d 2d 68 65 6c 70 29 20 70 72 69 6e (or --help) prin
3f20: 74 73 20 74 68 69 73 20 75 73 61 67 65 20 69 6e ts this usage in
3f30: 66 6f 72 6d 61 74 69 6f 6e 5c 6e 22 29 3b 0a 09 formation\n");..
3f40: 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c .fprintf(output,
3f50: 20 22 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 "\n");...fprint
3f60: 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 f(output, "
3f70: 20 2d 62 20 28 6f 72 20 2d 2d 62 69 6e 64 29 20 -b (or --bind)
3f80: 73 70 65 63 69 66 69 65 73 20 74 68 65 20 61 64 specifies the ad
3f90: 64 72 65 73 73 20 74 6f 20 6c 69 73 74 65 6e 20 dress to listen
3fa0: 66 6f 72 20 69 6e 63 6f 6d 69 6e 67 20 48 54 54 for incoming HTT
3fb0: 50 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 P\n");...fprintf
3fc0: 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 (output, "
3fd0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 72 r
3fe0: 65 71 75 65 73 74 73 20 6f 6e 2e 20 20 54 68 65 equests on. The
3ff0: 20 64 65 66 61 75 6c 74 20 76 61 6c 75 65 20 69 default value i
4000: 73 20 5c 22 25 73 5c 22 2e 5c 6e 22 2c 20 42 49 s \"%s\".\n", BI
4010: 4e 44 5f 41 44 44 52 29 3b 0a 09 09 66 70 72 69 ND_ADDR);...fpri
4020: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 5c 6e 22 ntf(output, "\n"
4030: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 );...fprintf(out
4040: 70 75 74 2c 20 22 20 20 20 20 20 20 2d 70 20 28 put, " -p (
4050: 6f 72 20 2d 2d 70 6f 72 74 29 20 73 70 65 63 69 or --port) speci
4060: 66 69 65 73 20 74 68 65 20 54 43 50 20 70 6f 72 fies the TCP por
4070: 74 20 6e 75 6d 62 65 72 20 74 6f 20 6c 69 73 74 t number to list
4080: 65 6e 20 66 6f 72 20 69 6e 63 6f 6d 69 6e 67 20 en for incoming
4090: 48 54 54 50 5c 6e 22 29 3b 0a 09 09 66 70 72 69 HTTP\n");...fpri
40a0: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 ntf(output, "
40b0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
40c0: 20 20 72 65 71 75 65 73 74 73 20 6f 6e 2e 20 20 requests on.
40d0: 54 68 65 20 64 65 66 61 75 6c 74 20 69 73 20 25 The default is %
40e0: 75 2e 5c 6e 22 2c 20 28 75 6e 73 69 67 6e 65 64 u.\n", (unsigned
40f0: 20 69 6e 74 29 20 50 4f 52 54 29 3b 0a 09 09 66 int) PORT);...f
4100: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 printf(output, "
4110: 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 \n");...fprintf(
4120: 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d output, " -
4130: 74 20 28 6f 72 20 2d 2d 74 68 72 65 61 64 73 29 t (or --threads)
4140: 20 73 70 65 63 69 66 69 65 73 20 74 68 65 20 6e specifies the n
4150: 75 6d 62 65 72 20 6f 66 20 77 6f 72 6b 65 72 20 umber of worker
4160: 74 68 72 65 61 64 73 20 74 6f 20 63 72 65 61 74 threads to creat
4170: 65 2e 20 45 61 63 68 5c 6e 22 29 3b 0a 09 09 66 e. Each\n");...f
4180: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 printf(output, "
4190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
41a0: 20 20 20 20 20 20 20 20 77 6f 72 6b 65 72 20 74 worker t
41b0: 68 72 65 61 64 20 63 61 6e 20 73 65 72 76 69 63 hread can servic
41c0: 65 20 6f 6e 65 20 63 6f 6e 63 75 72 72 65 6e 74 e one concurrent
41d0: 20 48 54 54 50 20 73 65 73 73 69 6f 6e 2e 5c 6e HTTP session.\n
41e0: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 ");...fprintf(ou
41f0: 74 70 75 74 2c 20 22 20 20 20 20 20 20 20 20 20 tput, "
4200: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 54 T
4210: 68 75 73 20 74 68 65 20 6e 75 6d 62 65 72 20 6f hus the number o
4220: 66 20 74 68 72 65 61 64 73 20 63 72 65 61 74 65 f threads create
4230: 64 20 77 69 6c 6c 20 64 65 74 65 72 6d 69 6e 65 d will determine
4240: 20 68 6f 77 5c 6e 22 29 3b 0a 09 09 66 70 72 69 how\n");...fpri
4250: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 ntf(output, "
4260: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4270: 20 20 20 20 20 6d 61 6e 79 20 73 69 6d 75 6c 74 many simult
4280: 61 6e 65 6f 75 73 20 74 72 61 6e 73 66 65 72 73 aneous transfers
4290: 20 77 69 6c 6c 20 62 65 20 70 6f 73 73 69 62 6c will be possibl
42a0: 65 2e 20 54 68 65 5c 6e 22 29 3b 0a 09 09 66 70 e. The\n");...fp
42b0: 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 rintf(output, "
42c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
42d0: 20 20 20 20 20 20 20 64 65 66 61 75 6c 74 20 69 default i
42e0: 73 20 25 6c 75 2e 5c 6e 22 2c 20 28 75 6e 73 69 s %lu.\n", (unsi
42f0: 67 6e 65 64 20 6c 6f 6e 67 29 20 54 48 52 45 41 gned long) THREA
4300: 44 5f 43 4f 55 4e 54 29 3b 0a 09 09 66 70 72 69 D_COUNT);...fpri
4310: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 5c 6e 22 ntf(output, "\n"
4320: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 );...fprintf(out
4330: 70 75 74 2c 20 22 20 20 20 20 20 20 2d 63 20 28 put, " -c (
4340: 6f 72 20 2d 2d 63 61 63 68 65 29 20 73 70 65 63 or --cache) spec
4350: 69 66 69 65 73 20 74 68 65 20 6e 75 6d 62 65 72 ifies the number
4360: 20 6f 66 20 66 69 6c 65 20 69 6e 66 6f 72 6d 61 of file informa
4370: 74 69 6f 6e 20 63 61 63 68 65 20 65 6e 74 72 69 tion cache entri
4380: 65 73 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 es\n");...fprint
4390: 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 f(output, "
43a0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
43b0: 20 74 6f 20 61 6c 6c 6f 63 61 74 65 2e 20 20 45 to allocate. E
43c0: 61 63 68 20 63 61 63 68 65 20 65 6e 74 72 79 20 ach cache entry
43d0: 68 6f 6c 64 73 20 66 69 6c 65 20 69 6e 66 6f 72 holds file infor
43e0: 6d 61 74 69 6f 6e 20 61 73 5c 6e 22 29 3b 0a 09 mation as\n");..
43f0: 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c .fprintf(output,
4400: 20 22 20 20 20 20 20 20 20 20 20 20 20 20 20 20 "
4410: 20 20 20 20 20 20 20 20 77 65 6c 6c 20 61 73 20 well as
4420: 61 6e 20 6f 70 65 6e 20 66 69 6c 65 20 64 65 73 an open file des
4430: 63 72 69 70 74 6f 72 20 74 6f 20 74 68 65 20 66 criptor to the f
4440: 69 6c 65 2c 20 73 6f 20 72 65 73 6f 75 72 63 65 ile, so resource
4450: 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 \n");...fprintf(
4460: 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 20 output, "
4470: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 6c l
4480: 69 6d 69 74 73 20 28 69 2e 65 2e 2c 20 75 6c 69 imits (i.e., uli
4490: 6d 69 74 29 20 73 68 6f 75 6c 64 20 62 65 20 63 mit) should be c
44a0: 6f 6e 73 69 64 65 72 65 64 2e 20 20 54 68 69 73 onsidered. This
44b0: 20 73 68 6f 75 6c 64 5c 6e 22 29 3b 0a 09 09 66 should\n");...f
44c0: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 printf(output, "
44d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
44e0: 20 20 20 20 20 20 62 65 20 61 20 70 72 69 6d 65 be a prime
44f0: 20 6e 75 6d 62 65 72 20 66 6f 72 20 69 64 65 61 number for idea
4500: 6c 20 75 73 65 20 77 69 74 68 20 74 68 65 20 6c l use with the l
4510: 6f 6f 6b 75 70 20 6d 65 74 68 6f 64 2e 5c 6e 22 ookup method.\n"
4520: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 );...fprintf(out
4530: 70 75 74 2c 20 22 20 20 20 20 20 20 20 20 20 20 put, "
4540: 20 20 20 20 20 20 20 20 20 20 20 20 54 68 65 20 The
4550: 64 65 66 61 75 6c 74 20 69 73 20 25 6c 75 2e 5c default is %lu.\
4560: 6e 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f n", (unsigned lo
4570: 6e 67 29 20 43 41 43 48 45 5f 53 49 5a 45 29 3b ng) CACHE_SIZE);
4580: 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 ...fprintf(outpu
4590: 74 2c 20 22 5c 6e 22 29 3b 0a 09 09 66 70 72 69 t, "\n");...fpri
45a0: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 ntf(output, "
45b0: 20 20 20 2d 75 20 28 6f 72 20 2d 2d 75 73 65 72 -u (or --user
45c0: 29 20 73 70 65 63 69 66 69 65 73 20 74 68 65 20 ) specifies the
45d0: 75 73 65 72 20 74 6f 20 73 77 69 74 63 68 20 75 user to switch u
45e0: 73 65 72 20 49 44 73 20 74 6f 20 62 65 66 6f 72 ser IDs to befor
45f0: 65 20 73 65 72 76 69 63 69 6e 67 5c 6e 22 29 3b e servicing\n");
4600: 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 ...fprintf(outpu
4610: 74 2c 20 22 20 20 20 20 20 20 20 20 20 20 20 20 t, "
4620: 20 20 20 20 20 20 20 20 20 72 65 71 75 65 73 74 request
4630: 73 2e 20 20 54 68 65 20 64 65 66 61 75 6c 74 20 s. The default
4640: 69 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 75 73 is not change us
4650: 65 72 20 49 44 73 2e 5c 6e 22 29 3b 0a 09 09 66 er IDs.\n");...f
4660: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 printf(output, "
4670: 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 \n");...fprintf(
4680: 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d output, " -
4690: 72 20 28 6f 72 20 2d 2d 72 6f 6f 74 29 20 73 70 r (or --root) sp
46a0: 65 63 69 66 69 65 73 20 74 68 65 20 64 69 72 65 ecifies the dire
46b0: 63 74 6f 72 79 20 74 6f 20 61 63 74 20 61 73 20 ctory to act as
46c0: 74 68 65 20 72 6f 6f 74 20 64 69 72 65 63 74 6f the root directo
46d0: 72 79 20 66 6f 72 5c 6e 22 29 3b 0a 09 09 66 70 ry for\n");...fp
46e0: 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 rintf(output, "
46f0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4700: 20 20 20 20 74 68 65 20 66 69 6c 65 20 73 65 72 the file ser
4710: 76 65 72 2e 20 20 49 66 20 74 68 69 73 20 6f 70 ver. If this op
4720: 74 69 6f 6e 20 69 73 20 73 70 65 63 69 66 69 65 tion is specifie
4730: 64 2c 20 63 68 72 6f 6f 74 28 32 29 5c 6e 22 29 d, chroot(2)\n")
4740: 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 ;...fprintf(outp
4750: 75 74 2c 20 22 20 20 20 20 20 20 20 20 20 20 20 ut, "
4760: 20 20 20 20 20 20 20 20 20 20 69 73 20 63 61 6c is cal
4770: 6c 65 64 2e 20 20 54 68 65 20 64 65 66 61 75 6c led. The defaul
4780: 74 20 69 73 20 6e 6f 74 20 63 68 61 6e 67 65 20 t is not change
4790: 72 6f 6f 74 20 64 69 72 65 63 74 6f 72 69 65 73 root directories
47a0: 2c 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 ,\n");...fprintf
47b0: 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 (output, "
47c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 74 t
47d0: 68 61 74 20 69 73 2c 20 74 68 65 20 5c 22 2f 5c hat is, the \"/\
47e0: 22 20 64 69 72 65 63 74 6f 72 79 20 69 73 20 73 " directory is s
47f0: 68 61 72 65 64 20 6f 75 74 2e 20 20 54 68 69 73 hared out. This
4800: 20 77 69 6c 6c 5c 6e 22 29 3b 0a 09 09 66 70 72 will\n");...fpr
4810: 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 intf(output, "
4820: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
4830: 20 20 20 6c 69 6b 65 6c 79 20 62 65 20 61 20 73 likely be a s
4840: 65 63 75 72 69 74 79 20 69 73 73 75 65 2c 20 73 ecurity issue, s
4850: 6f 20 74 68 69 73 20 6f 70 74 69 6f 6e 20 73 68 o this option sh
4860: 6f 75 6c 64 20 61 6c 77 61 79 73 5c 6e 22 29 3b ould always\n");
4870: 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 ...fprintf(outpu
4880: 74 2c 20 22 20 20 20 20 20 20 20 20 20 20 20 20 t, "
4890: 20 20 20 20 20 20 20 20 20 62 65 20 75 73 65 64 be used
48a0: 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 .\n");..}...retu
48b0: 72 6e 3b 0a 7d 0a 0a 2f 2a 20 41 64 64 20 61 20 rn;.}../* Add a
48c0: 67 65 74 6f 70 74 20 6f 70 74 69 6f 6e 20 2a 2f getopt option */
48d0: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c .static void fil
48e0: 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 ed_getopt_long_s
48f0: 65 74 6f 70 74 28 73 74 72 75 63 74 20 6f 70 74 etopt(struct opt
4900: 69 6f 6e 20 2a 6f 70 74 2c 20 63 6f 6e 73 74 20 ion *opt, const
4910: 63 68 61 72 20 2a 6e 61 6d 65 2c 20 69 6e 74 20 char *name, int
4920: 68 61 73 5f 61 72 67 2c 20 69 6e 74 20 76 61 6c has_arg, int val
4930: 29 20 7b 0a 09 6f 70 74 2d 3e 6e 61 6d 65 20 20 ) {..opt->name
4940: 20 20 20 3d 20 6e 61 6d 65 3b 0a 09 6f 70 74 2d = name;..opt-
4950: 3e 68 61 73 5f 61 72 67 20 20 3d 20 68 61 73 5f >has_arg = has_
4960: 61 72 67 3b 0a 09 6f 70 74 2d 3e 66 6c 61 67 20 arg;..opt->flag
4970: 20 20 20 20 3d 20 4e 55 4c 4c 3b 0a 09 6f 70 74 = NULL;..opt
4980: 2d 3e 76 61 6c 20 20 20 20 20 20 3d 20 76 61 6c ->val = val
4990: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f ;...return;.}../
49a0: 2a 20 52 65 73 6f 6c 76 65 20 61 20 75 73 65 72 * Resolve a user
49b0: 6e 61 6d 65 20 74 6f 20 61 20 55 49 44 20 2a 2f name to a UID */
49c0: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65 .static int file
49d0: 64 5f 75 73 65 72 5f 6c 6f 6f 6b 75 70 28 63 6f d_user_lookup(co
49e0: 6e 73 74 20 63 68 61 72 20 2a 75 73 65 72 2c 20 nst char *user,
49f0: 75 69 64 5f 74 20 2a 75 73 65 72 5f 69 64 29 20 uid_t *user_id)
4a00: 7b 0a 09 63 68 61 72 20 2a 6e 65 78 74 3b 0a 09 {..char *next;..
4a10: 75 69 64 5f 74 20 75 73 65 72 5f 69 64 5f 63 68 uid_t user_id_ch
4a20: 65 63 6b 3b 0a 23 69 66 6e 64 65 66 20 46 49 4c eck;.#ifndef FIL
4a30: 45 44 5f 4e 4f 5f 47 45 54 50 57 4e 41 4d 0a 09 ED_NO_GETPWNAM..
4a40: 73 74 72 75 63 74 20 70 61 73 73 77 64 20 2a 65 struct passwd *e
4a50: 6e 74 3b 0a 0a 09 65 6e 74 20 3d 20 67 65 74 70 nt;...ent = getp
4a60: 77 6e 61 6d 28 75 73 65 72 29 3b 0a 09 69 66 20 wnam(user);..if
4a70: 28 65 6e 74 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a (ent != NULL) {.
4a80: 09 09 2a 75 73 65 72 5f 69 64 20 3d 20 65 6e 74 ..*user_id = ent
4a90: 2d 3e 70 77 5f 75 69 64 3b 0a 0a 09 09 72 65 74 ->pw_uid;....ret
4aa0: 75 72 6e 28 30 29 3b 0a 09 7d 0a 23 65 6e 64 69 urn(0);..}.#endi
4ab0: 66 0a 0a 09 75 73 65 72 5f 69 64 5f 63 68 65 63 f...user_id_chec
4ac0: 6b 20 3d 20 73 74 72 74 6f 75 6c 6c 28 75 73 65 k = strtoull(use
4ad0: 72 2c 20 26 6e 65 78 74 2c 20 31 30 29 3b 0a 09 r, &next, 10);..
4ae0: 69 66 20 28 6e 65 78 74 20 3d 3d 20 4e 55 4c 4c if (next == NULL
4af0: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b ) {...return(1);
4b00: 0a 09 7d 0a 0a 09 69 66 20 28 6e 65 78 74 5b 30 ..}...if (next[0
4b10: 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a 09 09 72 ] != '\0') {...r
4b20: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2a eturn(1);..}...*
4b30: 75 73 65 72 5f 69 64 20 3d 20 75 73 65 72 5f 69 user_id = user_i
4b40: 64 5f 63 68 65 63 6b 3b 0a 0a 09 72 65 74 75 72 d_check;...retur
4b50: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 52 75 6e 20 n(0);.}../* Run
4b60: 70 72 6f 63 65 73 73 20 2a 2f 0a 69 6e 74 20 6d process */.int m
4b70: 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68 ain(int argc, ch
4b80: 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09 73 74 ar **argv) {..st
4b90: 72 75 63 74 20 6f 70 74 69 6f 6e 20 6f 70 74 69 ruct option opti
4ba0: 6f 6e 73 5b 38 5d 3b 0a 09 63 6f 6e 73 74 20 63 ons[8];..const c
4bb0: 68 61 72 20 2a 62 69 6e 64 5f 61 64 64 72 20 3d har *bind_addr =
4bc0: 20 42 49 4e 44 5f 41 44 44 52 2c 20 2a 6e 65 77 BIND_ADDR, *new
4bd0: 72 6f 6f 74 20 3d 20 4e 55 4c 4c 3b 0a 09 75 69 root = NULL;..ui
4be0: 64 5f 74 20 75 73 65 72 20 3d 20 30 3b 0a 09 69 d_t user = 0;..i
4bf0: 6e 74 20 70 6f 72 74 20 3d 20 50 4f 52 54 2c 20 nt port = PORT,
4c00: 74 68 72 65 61 64 5f 63 6f 75 6e 74 20 3d 20 54 thread_count = T
4c10: 48 52 45 41 44 5f 43 4f 55 4e 54 3b 0a 09 69 6e HREAD_COUNT;..in
4c20: 74 20 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 43 t cache_size = C
4c30: 41 43 48 45 5f 53 49 5a 45 3b 0a 09 69 6e 74 20 ACHE_SIZE;..int
4c40: 69 6e 69 74 5f 72 65 74 2c 20 63 68 72 6f 6f 74 init_ret, chroot
4c50: 5f 72 65 74 2c 20 73 65 74 75 69 64 5f 72 65 74 _ret, setuid_ret
4c60: 2c 20 6c 6f 6f 6b 75 70 5f 72 65 74 2c 20 63 68 , lookup_ret, ch
4c70: 64 69 72 5f 72 65 74 3b 0a 09 69 6e 74 20 73 65 dir_ret;..int se
4c80: 74 75 69 64 5f 65 6e 61 62 6c 65 64 20 3d 20 30 tuid_enabled = 0
4c90: 3b 0a 09 69 6e 74 20 63 68 3b 0a 09 69 6e 74 20 ;..int ch;..int
4ca0: 66 64 3b 0a 0a 09 2f 2a 20 50 72 6f 63 65 73 73 fd;.../* Process
4cb0: 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 09 66 arguments */..f
4cc0: 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 iled_getopt_long
4cd0: 5f 73 65 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73 _setopt(&options
4ce0: 5b 30 5d 2c 20 22 70 6f 72 74 22 2c 20 72 65 71 [0], "port", req
4cf0: 75 69 72 65 64 5f 61 72 67 75 6d 65 6e 74 2c 20 uired_argument,
4d00: 27 70 27 29 3b 0a 09 66 69 6c 65 64 5f 67 65 74 'p');..filed_get
4d10: 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 opt_long_setopt(
4d20: 26 6f 70 74 69 6f 6e 73 5b 31 5d 2c 20 22 74 68 &options[1], "th
4d30: 72 65 61 64 73 22 2c 20 72 65 71 75 69 72 65 64 reads", required
4d40: 5f 61 72 67 75 6d 65 6e 74 2c 20 27 74 27 29 3b _argument, 't');
4d50: 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c ..filed_getopt_l
4d60: 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f 70 74 69 ong_setopt(&opti
4d70: 6f 6e 73 5b 32 5d 2c 20 22 63 61 63 68 65 22 2c ons[2], "cache",
4d80: 20 72 65 71 75 69 72 65 64 5f 61 72 67 75 6d 65 required_argume
4d90: 6e 74 2c 20 27 63 27 29 3b 0a 09 66 69 6c 65 64 nt, 'c');..filed
4da0: 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74 _getopt_long_set
4db0: 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 33 5d 2c opt(&options[3],
4dc0: 20 22 62 69 6e 64 22 2c 20 72 65 71 75 69 72 65 "bind", require
4dd0: 64 5f 61 72 67 75 6d 65 6e 74 2c 20 27 62 27 29 d_argument, 'b')
4de0: 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f ;..filed_getopt_
4df0: 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f 70 74 long_setopt(&opt
4e00: 69 6f 6e 73 5b 34 5d 2c 20 22 75 73 65 72 22 2c ions[4], "user",
4e10: 20 72 65 71 75 69 72 65 64 5f 61 72 67 75 6d 65 required_argume
4e20: 6e 74 2c 20 27 75 27 29 3b 0a 09 66 69 6c 65 64 nt, 'u');..filed
4e30: 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74 _getopt_long_set
4e40: 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 35 5d 2c opt(&options[5],
4e50: 20 22 72 6f 6f 74 22 2c 20 72 65 71 75 69 72 65 "root", require
4e60: 64 5f 61 72 67 75 6d 65 6e 74 2c 20 27 72 27 29 d_argument, 'r')
4e70: 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f ;..filed_getopt_
4e80: 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f 70 74 long_setopt(&opt
4e90: 69 6f 6e 73 5b 36 5d 2c 20 22 68 65 6c 70 22 2c ions[6], "help",
4ea0: 20 6e 6f 5f 61 72 67 75 6d 65 6e 74 2c 20 27 68 no_argument, 'h
4eb0: 27 29 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70 ');..filed_getop
4ec0: 74 5f 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f t_long_setopt(&o
4ed0: 70 74 69 6f 6e 73 5b 37 5d 2c 20 4e 55 4c 4c 2c ptions[7], NULL,
4ee0: 20 30 2c 20 30 29 3b 0a 09 77 68 69 6c 65 20 28 0, 0);..while (
4ef0: 28 63 68 20 3d 20 67 65 74 6f 70 74 5f 6c 6f 6e (ch = getopt_lon
4f00: 67 28 61 72 67 63 2c 20 61 72 67 76 2c 20 22 70 g(argc, argv, "p
4f10: 3a 74 3a 63 3a 62 3a 75 3a 72 3a 68 22 2c 20 6f :t:c:b:u:r:h", o
4f20: 70 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 20 21 ptions, NULL)) !
4f30: 3d 20 2d 31 29 20 7b 0a 09 09 73 77 69 74 63 68 = -1) {...switch
4f40: 28 63 68 29 20 7b 0a 09 09 09 63 61 73 65 20 27 (ch) {....case '
4f50: 70 27 3a 0a 09 09 09 09 70 6f 72 74 20 3d 20 61 p':.....port = a
4f60: 74 6f 69 28 6f 70 74 61 72 67 29 3b 0a 09 09 09 toi(optarg);....
4f70: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 .break;....case
4f80: 27 74 27 3a 0a 09 09 09 09 74 68 72 65 61 64 5f 't':.....thread_
4f90: 63 6f 75 6e 74 20 3d 20 61 74 6f 69 28 6f 70 74 count = atoi(opt
4fa0: 61 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b arg);.....break;
4fb0: 0a 09 09 09 63 61 73 65 20 27 63 27 3a 0a 09 09 ....case 'c':...
4fc0: 09 09 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 61 ..cache_size = a
4fd0: 74 6f 69 28 6f 70 74 61 72 67 29 3b 0a 09 09 09 toi(optarg);....
4fe0: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 .break;....case
4ff0: 27 62 27 3a 0a 09 09 09 09 62 69 6e 64 5f 61 64 'b':.....bind_ad
5000: 64 72 20 3d 20 73 74 72 64 75 70 28 6f 70 74 61 dr = strdup(opta
5010: 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a rg);.....break;.
5020: 09 09 09 63 61 73 65 20 27 75 27 3a 0a 09 09 09 ...case 'u':....
5030: 09 73 65 74 75 69 64 5f 65 6e 61 62 6c 65 64 20 .setuid_enabled
5040: 3d 20 31 3b 0a 09 09 09 09 6c 6f 6f 6b 75 70 5f = 1;.....lookup_
5050: 72 65 74 20 3d 20 66 69 6c 65 64 5f 75 73 65 72 ret = filed_user
5060: 5f 6c 6f 6f 6b 75 70 28 6f 70 74 61 72 67 2c 20 _lookup(optarg,
5070: 26 75 73 65 72 29 3b 0a 09 09 09 09 69 66 20 28 &user);.....if (
5080: 6c 6f 6f 6b 75 70 5f 72 65 74 20 21 3d 20 30 29 lookup_ret != 0)
5090: 20 7b 0a 09 09 09 09 09 66 69 6c 65 64 5f 70 72 {......filed_pr
50a0: 69 6e 74 5f 68 65 6c 70 28 73 74 64 65 72 72 2c int_help(stderr,
50b0: 20 30 2c 20 22 49 6e 76 61 6c 69 64 20 75 73 65 0, "Invalid use
50c0: 72 6e 61 6d 65 20 73 70 65 63 69 66 69 65 64 22 rname specified"
50d0: 29 3b 0a 0a 09 09 09 09 09 72 65 74 75 72 6e 28 );.......return(
50e0: 31 29 3b 0a 09 09 09 09 7d 0a 09 09 09 09 62 72 1);.....}.....br
50f0: 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 72 27 eak;....case 'r'
5100: 3a 0a 09 09 09 09 6e 65 77 72 6f 6f 74 20 3d 20 :.....newroot =
5110: 73 74 72 64 75 70 28 6f 70 74 61 72 67 29 3b 0a strdup(optarg);.
5120: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 ....break;....ca
5130: 73 65 20 27 3f 27 3a 0a 09 09 09 63 61 73 65 20 se '?':....case
5140: 27 3a 27 3a 0a 09 09 09 09 66 69 6c 65 64 5f 70 ':':.....filed_p
5150: 72 69 6e 74 5f 68 65 6c 70 28 73 74 64 65 72 72 rint_help(stderr
5160: 2c 20 30 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 09 09 , 0, NULL);.....
5170: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 09 63 .return(1);....c
5180: 61 73 65 20 27 68 27 3a 0a 09 09 09 09 66 69 6c ase 'h':.....fil
5190: 65 64 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74 ed_print_help(st
51a0: 64 6f 75 74 2c 20 31 2c 20 4e 55 4c 4c 29 3b 0a dout, 1, NULL);.
51b0: 0a 09 09 09 09 72 65 74 75 72 6e 28 30 29 3b 0a .....return(0);.
51c0: 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 20 43 72 65 61 ..}..}.../* Crea
51d0: 74 65 20 6c 69 73 74 65 6e 69 6e 67 20 73 6f 63 te listening soc
51e0: 6b 65 74 20 2a 2f 0a 09 66 64 20 3d 20 66 69 6c ket */..fd = fil
51f0: 65 64 5f 6c 69 73 74 65 6e 28 62 69 6e 64 5f 61 ed_listen(bind_a
5200: 64 64 72 2c 20 70 6f 72 74 29 3b 0a 09 69 66 20 ddr, port);..if
5210: 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 70 65 72 (fd < 0) {...per
5220: 72 6f 72 28 22 66 69 6c 65 64 5f 6c 69 73 74 65 ror("filed_liste
5230: 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 n");....return(1
5240: 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 43 68 72 6f 6f );..}.../* Chroo
5250: 74 2c 20 69 66 20 61 70 70 72 6f 70 72 69 61 74 t, if appropriat
5260: 65 20 2a 2f 0a 09 69 66 20 28 6e 65 77 72 6f 6f e */..if (newroo
5270: 74 29 20 7b 0a 09 09 63 68 64 69 72 5f 72 65 74 t) {...chdir_ret
5280: 20 3d 20 63 68 64 69 72 28 6e 65 77 72 6f 6f 74 = chdir(newroot
5290: 29 3b 0a 09 09 69 66 20 28 63 68 64 69 72 5f 72 );...if (chdir_r
52a0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 70 65 et != 0) {....pe
52b0: 72 72 6f 72 28 22 63 68 64 69 72 22 29 3b 0a 0a rror("chdir");..
52c0: 09 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 ...return(1);...
52d0: 7d 0a 0a 09 09 63 68 72 6f 6f 74 5f 72 65 74 20 }....chroot_ret
52e0: 3d 20 63 68 72 6f 6f 74 28 22 2e 22 29 3b 0a 09 = chroot(".");..
52f0: 09 69 66 20 28 63 68 72 6f 6f 74 5f 72 65 74 20 .if (chroot_ret
5300: 21 3d 20 30 29 20 7b 0a 09 09 09 70 65 72 72 6f != 0) {....perro
5310: 72 28 22 63 68 72 6f 6f 74 22 29 3b 0a 0a 09 09 r("chroot");....
5320: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 7d 0a .return(1);...}.
5330: 09 7d 0a 0a 09 2f 2a 20 44 72 6f 70 20 70 72 69 .}.../* Drop pri
5340: 76 69 6c 65 67 65 73 2c 20 69 66 20 61 70 70 72 vileges, if appr
5350: 6f 70 72 69 61 74 65 20 2a 2f 0a 09 69 66 20 28 opriate */..if (
5360: 73 65 74 75 69 64 5f 65 6e 61 62 6c 65 64 29 20 setuid_enabled)
5370: 7b 0a 09 09 73 65 74 75 69 64 5f 72 65 74 20 3d {...setuid_ret =
5380: 20 73 65 74 75 69 64 28 75 73 65 72 29 3b 0a 09 setuid(user);..
5390: 09 69 66 20 28 73 65 74 75 69 64 5f 72 65 74 20 .if (setuid_ret
53a0: 21 3d 20 30 29 20 7b 0a 09 09 09 70 65 72 72 6f != 0) {....perro
53b0: 72 28 22 73 65 74 75 69 64 22 29 3b 0a 0a 09 09 r("setuid");....
53c0: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 7d 0a .return(1);...}.
53d0: 09 7d 0a 0a 09 2f 2a 20 42 65 63 6f 6d 65 20 61 .}.../* Become a
53e0: 20 64 61 65 6d 6f 6e 20 2a 2f 0a 09 2f 2a 20 58 daemon */../* X
53f0: 58 58 3a 54 4f 44 4f 3a 20 42 65 63 6f 6d 65 20 XX:TODO: Become
5400: 61 20 64 61 65 6d 6f 6e 20 2a 2f 0a 0a 09 2f 2a a daemon */.../*
5410: 20 49 6e 69 74 69 61 6c 69 7a 65 20 2a 2f 0a 09 Initialize */..
5420: 69 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 64 init_ret = filed
5430: 5f 69 6e 69 74 28 63 61 63 68 65 5f 73 69 7a 65 _init(cache_size
5440: 29 3b 0a 09 69 66 20 28 69 6e 69 74 5f 72 65 74 );..if (init_ret
5450: 20 21 3d 20 30 29 20 7b 0a 09 09 70 65 72 72 6f != 0) {...perro
5460: 72 28 22 66 69 6c 65 64 5f 69 6e 69 74 22 29 3b r("filed_init");
5470: 0a 0a 09 09 72 65 74 75 72 6e 28 33 29 3b 0a 09 ....return(3);..
5480: 7d 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20 6c 6f }.../* Create lo
5490: 67 67 69 6e 67 20 74 68 72 65 61 64 20 2a 2f 0a gging thread */.
54a0: 09 69 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 .init_ret = file
54b0: 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 d_logging_thread
54c0: 5f 69 6e 69 74 28 29 3b 0a 09 69 66 20 28 69 6e _init();..if (in
54d0: 69 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 it_ret != 0) {..
54e0: 09 70 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 6c .perror("filed_l
54f0: 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e ogging_thread_in
5500: 69 74 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 it");....return(
5510: 34 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 43 72 65 61 4);..}.../* Crea
5520: 74 65 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 te worker thread
5530: 73 20 2a 2f 0a 09 69 6e 69 74 5f 72 65 74 20 3d s */..init_ret =
5540: 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 filed_worker_th
5550: 72 65 61 64 73 5f 69 6e 69 74 28 66 64 2c 20 74 reads_init(fd, t
5560: 68 72 65 61 64 5f 63 6f 75 6e 74 29 3b 0a 09 69 hread_count);..i
5570: 66 20 28 69 6e 69 74 5f 72 65 74 20 21 3d 20 30 f (init_ret != 0
5580: 29 20 7b 0a 09 09 70 65 72 72 6f 72 28 22 66 69 ) {...perror("fi
5590: 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 led_worker_threa
55a0: 64 73 5f 69 6e 69 74 22 29 3b 0a 0a 09 09 72 65 ds_init");....re
55b0: 74 75 72 6e 28 34 29 3b 0a 09 7d 0a 0a 09 2f 2a turn(4);..}.../*
55c0: 20 57 61 69 74 20 66 6f 72 20 74 68 72 65 61 64 Wait for thread
55d0: 73 20 74 6f 20 65 78 69 74 20 2a 2f 0a 09 2f 2a s to exit */../*
55e0: 20 58 58 58 3a 54 4f 44 4f 3a 20 4d 6f 6e 69 74 XXX:TODO: Monit
55f0: 6f 72 20 74 68 72 65 61 64 20 75 73 61 67 65 20 or thread usage
5600: 2a 2f 0a 09 77 68 69 6c 65 20 28 31 29 20 7b 0a */..while (1) {.
5610: 09 09 73 6c 65 65 70 28 36 30 29 3b 0a 09 7d 0a ..sleep(60);..}.
5620: 0a 09 2f 2a 20 52 65 74 75 72 6e 20 69 6e 20 66 ../* Return in f
5630: 61 69 6c 75 72 65 20 2a 2f 0a 09 72 65 74 75 72 ailure */..retur
5640: 6e 28 32 29 3b 0a 7d 0a n(2);.}.