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 64 6c 69 .#include <stdli
00b0: 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75 b.h>.#include <u
00c0: 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 nistd.h>.#includ
00d0: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e e <string.h>.#in
00e0: 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a clude <fcntl.h>.
00f0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e #include <stdio.
0100: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74 69 6d h>.#include <tim
0110: 65 2e 68 3e 0a 0a 2f 2a 20 44 65 66 61 75 6c 74 e.h>../* Default
0120: 20 76 61 6c 75 65 73 20 2a 2f 0a 23 64 65 66 69 values */.#defi
0130: 6e 65 20 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 ne MAX_FAILURE_C
0140: 4f 55 4e 54 20 33 30 0a 23 64 65 66 69 6e 65 20 OUNT 30.#define
0150: 50 4f 52 54 20 38 30 38 30 0a 23 64 65 66 69 6e PORT 8080.#defin
0160: 65 20 54 48 52 45 41 44 5f 43 4f 55 4e 54 20 31 e THREAD_COUNT 1
0170: 30 0a 23 64 65 66 69 6e 65 20 42 49 4e 44 5f 41 0.#define BIND_A
0180: 44 44 52 20 22 3a 3a 22 0a 0a 2f 2a 20 41 72 67 DDR "::"../* Arg
0190: 75 6d 65 6e 74 73 20 66 6f 72 20 77 6f 72 6b 65 uments for worke
01a0: 72 20 74 68 72 65 61 64 73 20 2a 2f 0a 73 74 72 r threads */.str
01b0: 75 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 uct filed_worker
01c0: 5f 74 68 72 65 61 64 5f 61 72 67 73 20 7b 0a 09 _thread_args {..
01d0: 69 6e 74 20 66 64 3b 0a 7d 3b 0a 0a 2f 2a 20 46 int fd;.};../* F
01e0: 69 6c 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 ile information
01f0: 2a 2f 0a 73 74 72 75 63 74 20 66 69 6c 65 64 5f */.struct filed_
0200: 66 69 6c 65 69 6e 66 6f 20 7b 0a 09 70 74 68 72 fileinfo {..pthr
0210: 65 61 64 5f 6d 75 74 65 78 5f 74 20 6d 75 74 65 ead_mutex_t mute
0220: 78 3b 0a 09 63 68 61 72 20 2a 70 61 74 68 3b 0a x;..char *path;.
0230: 09 69 6e 74 20 66 64 3b 0a 09 73 69 7a 65 5f 74 .int fd;..size_t
0240: 20 6c 65 6e 3b 0a 09 63 68 61 72 20 2a 6c 61 73 len;..char *las
0250: 74 6d 6f 64 3b 0a 09 63 68 61 72 20 6c 61 73 74 tmod;..char last
0260: 6d 6f 64 5f 62 5b 36 34 5d 3b 0a 09 63 68 61 72 mod_b[64];..char
0270: 20 2a 74 79 70 65 3b 0a 7d 3b 0a 0a 2f 2a 20 47 *type;.};../* G
0280: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20 lobal variables
0290: 2a 2f 0a 73 74 72 75 63 74 20 66 69 6c 65 64 5f */.struct filed_
02a0: 66 69 6c 65 69 6e 66 6f 20 2a 66 69 6c 65 64 5f fileinfo *filed_
02b0: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 fileinfo_fdcache
02c0: 3b 0a 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 66 ;.unsigned int f
02d0: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 iled_fileinfo_fd
02e0: 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 38 31 39 cache_size = 819
02f0: 32 3b 0a 0a 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 2;../* Initializ
0300: 65 20 70 72 6f 63 65 73 73 20 2a 2f 0a 73 74 61 e process */.sta
0310: 74 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 69 6e tic int filed_in
0320: 69 74 28 76 6f 69 64 29 20 7b 0a 09 75 6e 73 69 it(void) {..unsi
0330: 67 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09 69 gned int idx;..i
0340: 6e 74 20 6d 75 74 65 78 5f 69 6e 69 74 5f 72 65 nt mutex_init_re
0350: 74 3b 0a 0a 09 6d 6c 6f 63 6b 61 6c 6c 28 4d 43 t;...mlockall(MC
0360: 4c 5f 43 55 52 52 45 4e 54 20 7c 20 4d 43 4c 5f L_CURRENT | MCL_
0370: 46 55 54 55 52 45 29 3b 0a 0a 09 66 69 6c 65 64 FUTURE);...filed
0380: 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 _fileinfo_fdcach
0390: 65 20 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f e = malloc(sizeo
03a0: 66 28 2a 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 f(*filed_fileinf
03b0: 6f 5f 66 64 63 61 63 68 65 29 20 2a 20 66 69 6c o_fdcache) * fil
03c0: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 ed_fileinfo_fdca
03d0: 63 68 65 5f 73 69 7a 65 29 3b 0a 09 69 66 20 28 che_size);..if (
03e0: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 filed_fileinfo_f
03f0: 64 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 dcache == NULL)
0400: 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 {...return(1);..
0410: 7d 0a 0a 09 66 6f 72 20 28 69 64 78 20 3d 20 30 }...for (idx = 0
0420: 3b 20 69 64 78 20 3c 20 66 69 6c 65 64 5f 66 69 ; idx < filed_fi
0430: 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 5f 73 leinfo_fdcache_s
0440: 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 ize; idx++) {...
0450: 6d 75 74 65 78 5f 69 6e 69 74 5f 72 65 74 20 3d mutex_init_ret =
0460: 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 69 pthread_mutex_i
0470: 6e 69 74 28 26 66 69 6c 65 64 5f 66 69 6c 65 69 nit(&filed_filei
0480: 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64 78 5d nfo_fdcache[idx]
0490: 2e 6d 75 74 65 78 2c 20 4e 55 4c 4c 29 3b 0a 09 .mutex, NULL);..
04a0: 09 69 66 20 28 6d 75 74 65 78 5f 69 6e 69 74 5f .if (mutex_init_
04b0: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 72 ret != 0) {....r
04c0: 65 74 75 72 6e 28 31 29 3b 0a 09 09 7d 0a 0a 09 eturn(1);...}...
04d0: 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f .filed_fileinfo_
04e0: 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 70 61 74 fdcache[idx].pat
04f0: 68 20 3d 20 73 74 72 64 75 70 28 22 22 29 3b 0a h = strdup("");.
0500: 09 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f ..filed_fileinfo
0510: 5f 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 66 64 _fdcache[idx].fd
0520: 20 3d 20 2d 31 3b 0a 09 09 66 69 6c 65 64 5f 66 = -1;...filed_f
0530: 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b ileinfo_fdcache[
0540: 69 64 78 5d 2e 6c 61 73 74 6d 6f 64 20 3d 20 22 idx].lastmod = "
0550: 22 3b 0a 09 09 66 69 6c 65 64 5f 66 69 6c 65 69 ";...filed_filei
0560: 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64 78 5d nfo_fdcache[idx]
0570: 2e 74 79 70 65 20 3d 20 22 22 3b 0a 09 7d 0a 0a .type = "";..}..
0580: 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f .return(0);.}../
0590: 2a 20 4c 69 73 74 65 6e 20 6f 6e 20 61 20 70 61 * Listen on a pa
05a0: 72 74 69 63 75 6c 61 72 20 61 64 64 72 65 73 73 rticular address
05b0: 2f 70 6f 72 74 20 2a 2f 0a 73 74 61 74 69 63 20 /port */.static
05c0: 69 6e 74 20 66 69 6c 65 64 5f 6c 69 73 74 65 6e int filed_listen
05d0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 61 64 64 (const char *add
05e0: 72 65 73 73 2c 20 75 6e 73 69 67 6e 65 64 20 69 ress, unsigned i
05f0: 6e 74 20 70 6f 72 74 29 20 7b 0a 09 73 74 72 75 nt port) {..stru
0600: 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e 36 20 ct sockaddr_in6
0610: 61 64 64 72 3b 0a 09 69 6e 74 20 70 74 6f 6e 5f addr;..int pton_
0620: 72 65 74 2c 20 62 69 6e 64 5f 72 65 74 2c 20 6c ret, bind_ret, l
0630: 69 73 74 65 6e 5f 72 65 74 3b 0a 09 69 6e 74 20 isten_ret;..int
0640: 66 64 3b 0a 0a 09 61 64 64 72 2e 73 69 6e 36 5f fd;...addr.sin6_
0650: 66 61 6d 69 6c 79 20 3d 20 41 46 5f 49 4e 45 54 family = AF_INET
0660: 36 3b 0a 09 61 64 64 72 2e 73 69 6e 36 5f 66 6c 6;..addr.sin6_fl
0670: 6f 77 69 6e 66 6f 20 3d 20 30 3b 0a 09 61 64 64 owinfo = 0;..add
0680: 72 2e 73 69 6e 36 5f 73 63 6f 70 65 5f 69 64 20 r.sin6_scope_id
0690: 3d 20 30 3b 0a 09 61 64 64 72 2e 73 69 6e 36 5f = 0;..addr.sin6_
06a0: 70 6f 72 74 20 3d 20 68 74 6f 6e 73 28 70 6f 72 port = htons(por
06b0: 74 29 3b 0a 09 70 74 6f 6e 5f 72 65 74 20 3d 20 t);..pton_ret =
06c0: 69 6e 65 74 5f 70 74 6f 6e 28 41 46 5f 49 4e 45 inet_pton(AF_INE
06d0: 54 36 2c 20 61 64 64 72 65 73 73 2c 20 61 64 64 T6, address, add
06e0: 72 2e 73 69 6e 36 5f 61 64 64 72 2e 73 36 5f 61 r.sin6_addr.s6_a
06f0: 64 64 72 29 3b 0a 09 69 66 20 28 70 74 6f 6e 5f ddr);..if (pton_
0700: 72 65 74 20 21 3d 20 31 29 20 7b 0a 09 09 72 65 ret != 1) {...re
0710: 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 66 turn(-1);..}...f
0720: 64 20 3d 20 73 6f 63 6b 65 74 28 41 46 5f 49 4e d = socket(AF_IN
0730: 45 54 36 2c 20 53 4f 43 4b 5f 53 54 52 45 41 4d ET6, SOCK_STREAM
0740: 2c 20 30 29 3b 0a 09 69 66 20 28 66 64 20 3c 20 , 0);..if (fd <
0750: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 66 64 0) {...return(fd
0760: 29 3b 0a 09 7d 0a 0a 09 62 69 6e 64 5f 72 65 74 );..}...bind_ret
0770: 20 3d 20 62 69 6e 64 28 66 64 2c 20 28 63 6f 6e = bind(fd, (con
0780: 73 74 20 73 74 72 75 63 74 20 73 6f 63 6b 61 64 st struct sockad
0790: 64 72 20 2a 29 20 26 61 64 64 72 2c 20 73 69 7a dr *) &addr, siz
07a0: 65 6f 66 28 61 64 64 72 29 29 3b 0a 09 69 66 20 eof(addr));..if
07b0: 28 62 69 6e 64 5f 72 65 74 20 3c 20 30 29 20 7b (bind_ret < 0) {
07c0: 0a 09 09 63 6c 6f 73 65 28 66 64 29 3b 0a 0a 09 ...close(fd);...
07d0: 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a .return(-1);..}.
07e0: 0a 09 6c 69 73 74 65 6e 5f 72 65 74 20 3d 20 6c ..listen_ret = l
07f0: 69 73 74 65 6e 28 66 64 2c 20 31 32 38 29 3b 0a isten(fd, 128);.
0800: 09 69 66 20 28 6c 69 73 74 65 6e 5f 72 65 74 20 .if (listen_ret
0810: 21 3d 20 30 29 20 7b 0a 09 09 63 6c 6f 73 65 28 != 0) {...close(
0820: 66 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d fd);....return(-
0830: 31 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 1);..}...return(
0840: 66 64 29 3b 0a 7d 0a 0a 2f 2a 20 4c 6f 67 20 61 fd);.}../* Log a
0850: 20 6d 65 73 73 61 67 65 20 2a 2f 0a 23 64 65 66 message */.#def
0860: 69 6e 65 20 46 49 4c 45 44 5f 44 4f 4e 54 5f 4c ine FILED_DONT_L
0870: 4f 47 0a 23 69 66 64 65 66 20 46 49 4c 45 44 5f OG.#ifdef FILED_
0880: 44 4f 4e 54 5f 4c 4f 47 0a 23 20 20 64 65 66 69 DONT_LOG.# defi
0890: 6e 65 20 66 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 ne filed_logging
08a0: 5f 74 68 72 65 61 64 5f 69 6e 69 74 28 29 20 30 _thread_init() 0
08b0: 0a 23 20 20 64 65 66 69 6e 65 20 66 69 6c 65 64 .# define filed
08c0: 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 78 _log_msg_debug(x
08d0: 2c 20 2e 2e 2e 29 20 2f 2a 2a 2f 0a 23 20 20 64 , ...) /**/.# d
08e0: 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c 6f 67 5f efine filed_log_
08f0: 6d 73 67 28 78 29 20 2f 2a 2a 2f 0a 23 65 6c 73 msg(x) /**/.#els
0900: 65 0a 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 e./* Initialize
0910: 6c 6f 67 67 69 6e 67 20 74 68 72 65 61 64 20 2a logging thread *
0920: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c /.static int fil
0930: 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65 61 ed_logging_threa
0940: 64 5f 69 6e 69 74 28 76 6f 69 64 29 20 7b 0a 09 d_init(void) {..
0950: 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 55 6e 69 /* XXX:TODO: Uni
0960: 6d 70 6c 65 6d 65 6e 74 65 64 20 2a 2f 0a 09 72 mplemented */..r
0970: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 eturn(0);.}../*
0980: 58 58 58 3a 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c XXX:TODO: Unimpl
0990: 65 6d 65 6e 74 65 64 20 2a 2f 0a 23 64 65 66 69 emented */.#defi
09a0: 6e 65 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 ne filed_log_msg
09b0: 5f 64 65 62 75 67 28 78 2c 20 2e 2e 2e 29 20 7b _debug(x, ...) {
09c0: 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c fprintf(stderr,
09d0: 20 78 2c 20 5f 5f 56 41 5f 41 52 47 53 5f 5f 29 x, __VA_ARGS__)
09e0: 3b 20 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 ; fprintf(stderr
09f0: 2c 20 22 5c 6e 22 29 3b 20 66 66 6c 75 73 68 28 , "\n"); fflush(
0a00: 73 74 64 65 72 72 29 3b 20 7d 0a 0a 73 74 61 74 stderr); }..stat
0a10: 69 63 20 76 6f 69 64 20 66 69 6c 65 64 5f 6c 6f ic void filed_lo
0a20: 67 5f 6d 73 67 28 63 6f 6e 73 74 20 63 68 61 72 g_msg(const char
0a30: 20 2a 62 75 66 66 65 72 29 20 7b 0a 09 2f 2a 20 *buffer) {../*
0a40: 58 58 58 3a 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c XXX:TODO: Unimpl
0a50: 65 6d 65 6e 74 65 64 20 2a 2f 0a 09 66 70 72 69 emented */..fpri
0a60: 6e 74 66 28 73 74 64 65 72 72 2c 20 22 25 73 5c ntf(stderr, "%s\
0a70: 6e 22 2c 20 62 75 66 66 65 72 29 3b 0a 0a 09 72 n", buffer);...r
0a80: 65 74 75 72 6e 3b 0a 7d 0a 0a 23 65 6e 64 69 66 eturn;.}..#endif
0a90: 0a 2f 2a 20 46 6f 72 6d 61 74 20 74 69 6d 65 20 ./* Format time
0aa0: 70 65 72 20 52 46 43 32 36 31 36 20 2a 2f 0a 73 per RFC2616 */.s
0ab0: 74 61 74 69 63 20 63 68 61 72 20 2a 66 69 6c 65 tatic char *file
0ac0: 64 5f 66 6f 72 6d 61 74 5f 74 69 6d 65 28 63 68 d_format_time(ch
0ad0: 61 72 20 2a 62 75 66 66 65 72 2c 20 73 69 7a 65 ar *buffer, size
0ae0: 5f 74 20 62 75 66 66 65 72 5f 6c 65 6e 2c 20 63 _t buffer_len, c
0af0: 6f 6e 73 74 20 74 69 6d 65 5f 74 20 74 69 6d 65 onst time_t time
0b00: 69 6e 66 6f 29 20 7b 0a 09 73 74 72 75 63 74 20 info) {..struct
0b10: 74 6d 20 74 69 6d 65 69 6e 66 6f 5f 74 6d 2c 20 tm timeinfo_tm,
0b20: 2a 74 69 6d 65 69 6e 66 6f 5f 74 6d 5f 70 3b 0a *timeinfo_tm_p;.
0b30: 0a 09 74 69 6d 65 69 6e 66 6f 5f 74 6d 5f 70 20 ..timeinfo_tm_p
0b40: 3d 20 67 6d 74 69 6d 65 5f 72 28 26 74 69 6d 65 = gmtime_r(&time
0b50: 69 6e 66 6f 2c 20 26 74 69 6d 65 69 6e 66 6f 5f info, &timeinfo_
0b60: 74 6d 29 3b 0a 09 69 66 20 28 74 69 6d 65 69 6e tm);..if (timein
0b70: 66 6f 5f 74 6d 5f 70 20 3d 3d 20 4e 55 4c 4c 29 fo_tm_p == NULL)
0b80: 20 7b 0a 09 09 72 65 74 75 72 6e 28 22 75 6e 6b {...return("unk
0b90: 6e 6f 77 6e 22 29 3b 0a 09 7d 0a 0a 09 62 75 66 nown");..}...buf
0ba0: 66 65 72 5b 62 75 66 66 65 72 5f 6c 65 6e 20 2d fer[buffer_len -
0bb0: 20 31 5d 20 3d 20 27 5c 30 27 3b 0a 09 62 75 66 1] = '\0';..buf
0bc0: 66 65 72 5f 6c 65 6e 20 3d 20 73 74 72 66 74 69 fer_len = strfti
0bd0: 6d 65 28 62 75 66 66 65 72 2c 20 62 75 66 66 65 me(buffer, buffe
0be0: 72 5f 6c 65 6e 20 2d 20 31 2c 20 22 25 61 2c 20 r_len - 1, "%a,
0bf0: 25 64 20 25 62 20 25 59 20 25 48 3a 25 4d 3a 25 %d %b %Y %H:%M:%
0c00: 53 20 47 4d 54 22 2c 20 74 69 6d 65 69 6e 66 6f S GMT", timeinfo
0c10: 5f 74 6d 5f 70 29 3b 0a 0a 09 72 65 74 75 72 6e _tm_p);...return
0c20: 28 62 75 66 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 (buffer);.}../*
0c30: 68 61 73 68 20 2a 2f 0a 73 74 61 74 69 63 20 75 hash */.static u
0c40: 6e 73 69 67 6e 65 64 20 69 6e 74 20 66 69 6c 65 nsigned int file
0c50: 64 5f 68 61 73 68 28 63 6f 6e 73 74 20 75 6e 73 d_hash(const uns
0c60: 69 67 6e 65 64 20 63 68 61 72 20 2a 76 61 6c 75 igned char *valu
0c70: 65 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 e, unsigned int
0c80: 6d 6f 64 75 6c 75 73 29 20 7b 0a 09 75 6e 73 69 modulus) {..unsi
0c90: 67 6e 65 64 20 63 68 61 72 20 63 75 72 72 3b 0a gned char curr;.
0ca0: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 72 65 .unsigned int re
0cb0: 74 76 61 6c 3b 0a 0a 09 72 65 74 76 61 6c 20 3d tval;...retval =
0cc0: 20 6d 6f 64 75 6c 75 73 20 2d 20 31 3b 0a 0a 09 modulus - 1;...
0cd0: 77 68 69 6c 65 20 28 28 63 75 72 72 20 3d 20 2a while ((curr = *
0ce0: 76 61 6c 75 65 29 29 20 7b 0a 09 09 69 66 20 28 value)) {...if (
0cf0: 63 75 72 72 20 3c 20 33 32 29 20 7b 0a 09 09 09 curr < 32) {....
0d00: 63 75 72 72 20 3d 20 32 35 35 20 2d 20 63 75 72 curr = 255 - cur
0d10: 72 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 r;...} else {...
0d20: 09 63 75 72 72 20 2d 3d 20 33 32 3b 0a 09 09 7d .curr -= 32;...}
0d30: 0a 0a 09 09 72 65 74 76 61 6c 20 3c 3c 3d 20 35 ....retval <<= 5
0d40: 3b 0a 09 09 72 65 74 76 61 6c 20 2b 3d 20 63 75 ;...retval += cu
0d50: 72 72 3b 0a 0a 09 09 76 61 6c 75 65 2b 2b 3b 0a rr;....value++;.
0d60: 09 7d 0a 0a 09 72 65 74 76 61 6c 20 3d 20 72 65 .}...retval = re
0d70: 74 76 61 6c 20 25 20 6d 6f 64 75 6c 75 73 3b 0a tval % modulus;.
0d80: 0a 09 72 65 74 75 72 6e 28 72 65 74 76 61 6c 29 ..return(retval)
0d90: 3b 0a 7d 0a 0a 2f 2a 20 4f 70 65 6e 20 61 20 66 ;.}../* Open a f
0da0: 69 6c 65 20 61 6e 64 20 72 65 74 75 72 6e 20 66 ile and return f
0db0: 69 6c 65 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 ile information
0dc0: 2a 2f 0a 73 74 61 74 69 63 20 73 74 72 75 63 74 */.static struct
0dd0: 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 filed_fileinfo
0de0: 2a 66 69 6c 65 64 5f 6f 70 65 6e 5f 66 69 6c 65 *filed_open_file
0df0: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 70 61 74 (const char *pat
0e00: 68 2c 20 73 74 72 75 63 74 20 66 69 6c 65 64 5f h, struct filed_
0e10: 66 69 6c 65 69 6e 66 6f 20 2a 62 75 66 66 65 72 fileinfo *buffer
0e20: 29 20 7b 0a 09 73 74 72 75 63 74 20 66 69 6c 65 ) {..struct file
0e30: 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 63 61 63 68 d_fileinfo *cach
0e40: 65 3b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 e;..unsigned int
0e50: 20 63 61 63 68 65 5f 69 64 78 3b 0a 09 6f 66 66 cache_idx;..off
0e60: 5f 74 20 6c 65 6e 3b 0a 09 69 6e 74 20 66 64 3b _t len;..int fd;
0e70: 0a 0a 09 63 61 63 68 65 5f 69 64 78 20 3d 20 66 ...cache_idx = f
0e80: 69 6c 65 64 5f 68 61 73 68 28 28 63 6f 6e 73 74 iled_hash((const
0e90: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a unsigned char *
0ea0: 29 20 70 61 74 68 2c 20 66 69 6c 65 64 5f 66 69 ) path, filed_fi
0eb0: 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 5f 73 leinfo_fdcache_s
0ec0: 69 7a 65 29 3b 0a 0a 09 63 61 63 68 65 20 3d 20 ize);...cache =
0ed0: 26 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f &filed_fileinfo_
0ee0: 66 64 63 61 63 68 65 5b 63 61 63 68 65 5f 69 64 fdcache[cache_id
0ef0: 78 5d 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f x];...filed_log_
0f00: 6d 73 67 5f 64 65 62 75 67 28 22 4c 6f 63 6b 69 msg_debug("Locki
0f10: 6e 67 20 6d 75 74 65 78 20 66 6f 72 20 69 64 78 ng mutex for idx
0f20: 3a 20 25 6c 75 22 2c 20 28 75 6e 73 69 67 6e 65 : %lu", (unsigne
0f30: 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f 69 64 d long) cache_id
0f40: 78 29 3b 0a 0a 09 70 74 68 72 65 61 64 5f 6d 75 x);...pthread_mu
0f50: 74 65 78 5f 6c 6f 63 6b 28 26 63 61 63 68 65 2d tex_lock(&cache-
0f60: 3e 6d 75 74 65 78 29 3b 0a 0a 09 66 69 6c 65 64 >mutex);...filed
0f70: 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 _log_msg_debug("
0f80: 43 6f 6d 70 6c 65 74 65 64 20 6c 6f 63 6b 69 6e Completed lockin
0f90: 67 20 6d 75 74 65 78 20 66 6f 72 20 69 64 78 3a g mutex for idx:
0fa0: 20 25 6c 75 22 2c 20 28 75 6e 73 69 67 6e 65 64 %lu", (unsigned
0fb0: 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f 69 64 78 long) cache_idx
0fc0: 29 3b 0a 0a 09 69 66 20 28 73 74 72 63 6d 70 28 );...if (strcmp(
0fd0: 70 61 74 68 2c 20 63 61 63 68 65 2d 3e 70 61 74 path, cache->pat
0fe0: 68 29 20 21 3d 20 30 29 20 7b 0a 09 09 66 69 6c h) != 0) {...fil
0ff0: 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 ed_log_msg_debug
1000: 28 22 43 61 63 68 65 20 6d 69 73 73 20 66 6f 72 ("Cache miss for
1010: 20 69 64 78 3a 20 25 6c 75 3a 20 4f 4c 44 20 5c idx: %lu: OLD \
1020: 22 25 73 5c 22 2c 20 4e 45 57 20 5c 22 25 73 5c "%s\", NEW \"%s\
1030: 22 22 2c 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f "", (unsigned lo
1040: 6e 67 29 20 63 61 63 68 65 5f 69 64 78 2c 20 63 ng) cache_idx, c
1050: 61 63 68 65 2d 3e 70 61 74 68 2c 20 70 61 74 68 ache->path, path
1060: 29 3b 0a 0a 09 09 66 64 20 3d 20 6f 70 65 6e 28 );....fd = open(
1070: 70 61 74 68 2c 20 4f 5f 52 44 4f 4e 4c 59 29 3b path, O_RDONLY);
1080: 0a 09 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b ...if (fd < 0) {
1090: 0a 09 09 09 70 74 68 72 65 61 64 5f 6d 75 74 65 ....pthread_mute
10a0: 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63 68 65 2d x_unlock(&cache-
10b0: 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 09 72 65 74 >mutex);.....ret
10c0: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d 0a 0a urn(NULL);...}..
10d0: 09 09 66 72 65 65 28 63 61 63 68 65 2d 3e 70 61 ..free(cache->pa
10e0: 74 68 29 3b 0a 09 09 69 66 20 28 63 61 63 68 65 th);...if (cache
10f0: 2d 3e 66 64 20 3e 3d 20 30 29 20 7b 0a 09 09 09 ->fd >= 0) {....
1100: 63 6c 6f 73 65 28 63 61 63 68 65 2d 3e 66 64 29 close(cache->fd)
1110: 3b 0a 09 09 7d 0a 0a 09 09 6c 65 6e 20 3d 20 6c ;...}....len = l
1120: 73 65 65 6b 28 66 64 2c 20 30 2c 20 53 45 45 4b seek(fd, 0, SEEK
1130: 5f 45 4e 44 29 3b 0a 09 09 6c 73 65 65 6b 28 66 _END);...lseek(f
1140: 64 2c 20 30 2c 20 53 45 45 4b 5f 53 45 54 29 3b d, 0, SEEK_SET);
1150: 0a 0a 09 09 63 61 63 68 65 2d 3e 66 64 20 3d 20 ....cache->fd =
1160: 66 64 3b 0a 09 09 63 61 63 68 65 2d 3e 6c 65 6e fd;...cache->len
1170: 20 3d 20 6c 65 6e 3b 0a 09 09 63 61 63 68 65 2d = len;...cache-
1180: 3e 70 61 74 68 20 3d 20 73 74 72 64 75 70 28 70 >path = strdup(p
1190: 61 74 68 29 3b 0a 0a 09 09 2f 2a 20 58 58 58 3a ath);..../* XXX:
11a0: 54 4f 44 4f 3a 20 44 65 74 65 72 6d 69 6e 65 20 TODO: Determine
11b0: 2a 2f 0a 09 09 63 61 63 68 65 2d 3e 74 79 70 65 */...cache->type
11c0: 20 3d 20 22 61 70 70 6c 69 63 61 74 69 6f 6e 2f = "application/
11d0: 6f 63 74 65 74 2d 73 74 72 65 61 6d 22 3b 0a 09 octet-stream";..
11e0: 09 63 61 63 68 65 2d 3e 6c 61 73 74 6d 6f 64 20 .cache->lastmod
11f0: 3d 20 66 69 6c 65 64 5f 66 6f 72 6d 61 74 5f 74 = filed_format_t
1200: 69 6d 65 28 63 61 63 68 65 2d 3e 6c 61 73 74 6d ime(cache->lastm
1210: 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28 63 61 63 od_b, sizeof(cac
1220: 68 65 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 2c 20 he->lastmod_b),
1230: 74 69 6d 65 28 4e 55 4c 4c 29 20 2d 20 33 30 29 time(NULL) - 30)
1240: 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 66 69 ;..} else {...fi
1250: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 led_log_msg_debu
1260: 67 28 22 43 61 63 68 65 20 68 69 74 20 66 6f 72 g("Cache hit for
1270: 20 69 64 78 3a 20 25 6c 75 3a 20 50 41 54 48 20 idx: %lu: PATH
1280: 5c 22 25 73 5c 22 22 2c 20 28 75 6e 73 69 67 6e \"%s\"", (unsign
1290: 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f 69 ed long) cache_i
12a0: 64 78 2c 20 70 61 74 68 29 3b 0a 09 7d 0a 0a 09 dx, path);..}...
12b0: 2f 2a 0a 09 20 2a 20 57 65 20 68 61 76 65 20 74 /*.. * We have t
12c0: 6f 20 6d 61 6b 65 20 61 20 64 75 70 6c 69 63 61 o make a duplica
12d0: 74 65 20 46 44 2c 20 62 65 63 61 75 73 65 20 6f te FD, because o
12e0: 6e 63 65 20 77 65 20 72 65 6c 65 61 73 65 20 74 nce we release t
12f0: 68 65 20 63 61 63 68 65 0a 09 20 2a 20 6d 75 74 he cache.. * mut
1300: 65 78 2c 20 74 68 65 20 66 69 6c 65 20 64 65 73 ex, the file des
1310: 63 72 69 70 74 6f 72 20 6d 61 79 20 62 65 20 63 criptor may be c
1320: 6c 6f 73 65 64 0a 09 20 2a 2f 0a 09 66 64 20 3d losed.. */..fd =
1330: 20 64 75 70 28 63 61 63 68 65 2d 3e 66 64 29 3b dup(cache->fd);
1340: 0a 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b 0a ..if (fd < 0) {.
1350: 09 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f ..pthread_mutex_
1360: 75 6e 6c 6f 63 6b 28 26 63 61 63 68 65 2d 3e 6d unlock(&cache->m
1370: 75 74 65 78 29 3b 0a 0a 09 09 72 65 74 75 72 6e utex);....return
1380: 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 62 75 66 (NULL);..}...buf
1390: 66 65 72 2d 3e 66 64 20 3d 20 66 64 3b 0a 09 62 fer->fd = fd;..b
13a0: 75 66 66 65 72 2d 3e 6c 65 6e 20 3d 20 63 61 63 uffer->len = cac
13b0: 68 65 2d 3e 6c 65 6e 3b 0a 09 62 75 66 66 65 72 he->len;..buffer
13c0: 2d 3e 74 79 70 65 20 3d 20 63 61 63 68 65 2d 3e ->type = cache->
13d0: 74 79 70 65 3b 0a 09 6d 65 6d 63 70 79 28 62 75 type;..memcpy(bu
13e0: 66 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 5f 62 2c ffer->lastmod_b,
13f0: 20 63 61 63 68 65 2d 3e 6c 61 73 74 6d 6f 64 5f cache->lastmod_
1400: 62 2c 20 73 69 7a 65 6f 66 28 62 75 66 66 65 72 b, sizeof(buffer
1410: 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 29 3b 0a 09 ->lastmod_b));..
1420: 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 20 buffer->lastmod
1430: 3d 20 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d 6f = buffer->lastmo
1440: 64 5f 62 20 2b 20 28 63 61 63 68 65 2d 3e 6c 61 d_b + (cache->la
1450: 73 74 6d 6f 64 20 2d 20 63 61 63 68 65 2d 3e 6c stmod - cache->l
1460: 61 73 74 6d 6f 64 5f 62 29 3b 0a 0a 09 70 74 68 astmod_b);...pth
1470: 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 read_mutex_unloc
1480: 6b 28 26 63 61 63 68 65 2d 3e 6d 75 74 65 78 29 k(&cache->mutex)
1490: 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75 66 66 65 ;...return(buffe
14a0: 72 29 3b 0a 7d 0a 0a 2f 2a 20 50 72 6f 63 65 73 r);.}../* Proces
14b0: 73 20 61 6e 20 48 54 54 50 20 72 65 71 75 65 73 s an HTTP reques
14c0: 74 20 61 6e 64 20 72 65 74 75 72 6e 20 74 68 65 t and return the
14d0: 20 70 61 74 68 20 72 65 71 75 65 73 74 65 64 20 path requested
14e0: 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a */.static char *
14f0: 66 69 6c 65 64 5f 67 65 74 5f 68 74 74 70 5f 72 filed_get_http_r
1500: 65 71 75 65 73 74 28 46 49 4c 45 20 2a 66 70 2c equest(FILE *fp,
1510: 20 63 68 61 72 20 2a 62 75 66 66 65 72 2c 20 73 char *buffer, s
1520: 69 7a 65 5f 74 20 62 75 66 66 65 72 5f 6c 65 6e ize_t buffer_len
1530: 29 20 7b 0a 09 63 68 61 72 20 2a 6d 65 74 68 6f ) {..char *metho
1540: 64 2c 20 2a 70 61 74 68 3b 0a 09 63 68 61 72 20 d, *path;..char
1550: 74 6d 70 62 75 66 5b 31 30 31 30 5d 3b 0a 09 69 tmpbuf[1010];..i
1560: 6e 74 20 69 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f nt i;...filed_lo
1570: 67 5f 6d 73 67 28 22 57 41 49 54 5f 46 4f 52 5f g_msg("WAIT_FOR_
1580: 52 45 51 55 45 53 54 20 46 44 3d 2e 2e 2e 22 29 REQUEST FD=...")
1590: 3b 0a 0a 09 66 67 65 74 73 28 62 75 66 66 65 72 ;...fgets(buffer
15a0: 2c 20 62 75 66 66 65 72 5f 6c 65 6e 2c 20 66 70 , buffer_len, fp
15b0: 29 3b 0a 0a 09 6d 65 74 68 6f 64 20 3d 20 62 75 );...method = bu
15c0: 66 66 65 72 3b 0a 0a 09 62 75 66 66 65 72 20 3d ffer;...buffer =
15d0: 20 73 74 72 63 68 72 28 62 75 66 66 65 72 2c 20 strchr(buffer,
15e0: 27 20 27 29 3b 0a 09 69 66 20 28 62 75 66 66 65 ' ');..if (buffe
15f0: 72 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 r == NULL) {...f
1600: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 47 4f iled_log_msg("GO
1610: 54 5f 52 45 51 55 45 53 54 20 46 44 3d 2e 2e 2e T_REQUEST FD=...
1620: 20 45 52 52 4f 52 3d 66 6f 72 6d 61 74 22 29 3b ERROR=format");
1630: 0a 0a 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 ....return(NULL)
1640: 3b 0a 09 7d 0a 0a 09 2a 62 75 66 66 65 72 20 3d ;..}...*buffer =
1650: 20 27 5c 30 27 3b 0a 09 62 75 66 66 65 72 2b 2b '\0';..buffer++
1660: 3b 0a 0a 09 70 61 74 68 20 3d 20 62 75 66 66 65 ;...path = buffe
1670: 72 3b 0a 0a 09 62 75 66 66 65 72 20 3d 20 73 74 r;...buffer = st
1680: 72 63 68 72 28 62 75 66 66 65 72 2c 20 27 20 27 rchr(buffer, ' '
1690: 29 3b 0a 09 69 66 20 28 62 75 66 66 65 72 20 21 );..if (buffer !
16a0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2a 62 75 66 = NULL) {...*buf
16b0: 66 65 72 20 3d 20 27 5c 30 27 3b 0a 09 09 62 75 fer = '\0';...bu
16c0: 66 66 65 72 2b 2b 3b 0a 09 7d 0a 0a 09 66 69 6c ffer++;..}...fil
16d0: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 47 4f 54 5f ed_log_msg("GOT_
16e0: 52 45 51 55 45 53 54 20 46 44 3d 2e 2e 2e 20 50 REQUEST FD=... P
16f0: 41 54 48 3d 2e 2e 2e 22 29 3b 0a 0a 09 66 69 6c ATH=...");...fil
1700: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 57 41 49 54 ed_log_msg("WAIT
1710: 5f 46 4f 52 5f 48 45 41 44 45 52 53 20 46 44 3d _FOR_HEADERS FD=
1720: 2e 2e 2e 22 29 3b 0a 0a 09 66 6f 72 20 28 69 20 ...");...for (i
1730: 3d 20 30 3b 20 69 20 3c 20 31 30 30 3b 20 69 2b = 0; i < 100; i+
1740: 2b 29 20 7b 0a 09 09 66 67 65 74 73 28 74 6d 70 +) {...fgets(tmp
1750: 62 75 66 2c 20 73 69 7a 65 6f 66 28 74 6d 70 62 buf, sizeof(tmpb
1760: 75 66 29 2c 20 66 70 29 3b 0a 09 09 69 66 20 28 uf), fp);...if (
1770: 6d 65 6d 63 6d 70 28 74 6d 70 62 75 66 2c 20 22 memcmp(tmpbuf, "
1780: 5c 72 5c 6e 22 2c 20 32 29 20 3d 3d 20 30 29 20 \r\n", 2) == 0)
1790: 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a {....break;...}.
17a0: 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d .}...filed_log_m
17b0: 73 67 28 22 47 4f 54 5f 48 45 41 44 45 52 53 20 sg("GOT_HEADERS
17c0: 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 66 66 6c 75 FD=...");...fflu
17d0: 73 68 28 66 70 29 3b 0a 0a 09 2f 2a 20 57 65 20 sh(fp);.../* We
17e0: 6f 6e 6c 79 20 68 61 6e 64 6c 65 20 74 68 65 20 only handle the
17f0: 22 47 45 54 22 20 6d 65 74 68 6f 64 20 2a 2f 0a "GET" method */.
1800: 09 69 66 20 28 73 74 72 63 61 73 65 63 6d 70 28 .if (strcasecmp(
1810: 6d 65 74 68 6f 64 2c 20 22 67 65 74 22 29 20 21 method, "get") !
1820: 3d 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 = 0) {...return(
1830: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 NULL);..}...retu
1840: 72 6e 28 70 61 74 68 29 3b 0a 7d 0a 0a 2f 2a 20 rn(path);.}../*
1850: 52 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 20 Return an error
1860: 70 61 67 65 20 2a 2f 0a 73 74 61 74 69 63 20 76 page */.static v
1870: 6f 69 64 20 66 69 6c 65 64 5f 65 72 72 6f 72 5f oid filed_error_
1880: 70 61 67 65 28 46 49 4c 45 20 2a 66 70 2c 20 63 page(FILE *fp, c
1890: 6f 6e 73 74 20 63 68 61 72 20 2a 64 61 74 65 5f onst char *date_
18a0: 63 75 72 72 65 6e 74 2c 20 69 6e 74 20 65 72 72 current, int err
18b0: 6f 72 5f 6e 75 6d 62 65 72 29 20 7b 0a 09 63 68 or_number) {..ch
18c0: 61 72 20 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 ar *error_string
18d0: 20 3d 20 22 3c 68 74 6d 6c 3e 3c 68 65 61 64 3e = "<html><head>
18e0: 3c 74 69 74 6c 65 3e 45 52 52 4f 52 3c 2f 74 69 <title>ERROR</ti
18f0: 74 6c 65 3e 3c 2f 68 65 61 64 3e 3c 62 6f 64 79 tle></head><body
1900: 3e 55 6e 61 62 6c 65 20 74 6f 20 70 72 6f 63 65 >Unable to proce
1910: 73 73 20 72 65 71 75 65 73 74 3c 2f 62 6f 64 79 ss request</body
1920: 3e 3c 2f 68 74 6d 6c 3e 22 3b 0a 0a 09 66 70 72 ></html>";...fpr
1930: 69 6e 74 66 28 66 70 2c 20 22 48 54 54 50 2f 31 intf(fp, "HTTP/1
1940: 2e 31 20 25 69 20 4f 4b 5c 72 5c 6e 44 61 74 65 .1 %i OK\r\nDate
1950: 3a 20 25 73 5c 72 5c 6e 53 65 72 76 65 72 3a 20 : %s\r\nServer:
1960: 66 69 6c 65 64 5c 72 5c 6e 4c 61 73 74 2d 4d 6f filed\r\nLast-Mo
1970: 64 69 66 69 65 64 3a 20 25 73 5c 72 5c 6e 43 6f dified: %s\r\nCo
1980: 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 6c ntent-Length: %l
1990: 6c 75 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 54 79 lu\r\nContent-Ty
19a0: 70 65 3a 20 25 73 5c 72 5c 6e 43 6f 6e 6e 65 63 pe: %s\r\nConnec
19b0: 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e 5c tion: close\r\n\
19c0: 72 5c 6e 25 73 22 2c 0a 09 09 65 72 72 6f 72 5f r\n%s",...error_
19d0: 6e 75 6d 62 65 72 2c 0a 09 09 64 61 74 65 5f 63 number,...date_c
19e0: 75 72 72 65 6e 74 2c 0a 09 09 64 61 74 65 5f 63 urrent,...date_c
19f0: 75 72 72 65 6e 74 2c 0a 09 09 28 75 6e 73 69 67 urrent,...(unsig
1a00: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 ned long long) s
1a10: 74 72 6c 65 6e 28 65 72 72 6f 72 5f 73 74 72 69 trlen(error_stri
1a20: 6e 67 29 2c 0a 09 09 22 74 65 78 74 2f 68 74 6d ng),..."text/htm
1a30: 6c 22 2c 0a 09 09 65 72 72 6f 72 5f 73 74 72 69 l",...error_stri
1a40: 6e 67 0a 09 29 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e ng..);.}../* Han
1a50: 64 6c 65 20 61 20 73 69 6e 67 6c 65 20 72 65 71 dle a single req
1a60: 75 65 73 74 20 66 72 6f 6d 20 61 20 63 6c 69 65 uest from a clie
1a70: 6e 74 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 nt */.static voi
1a80: 64 20 66 69 6c 65 64 5f 68 61 6e 64 6c 65 5f 63 d filed_handle_c
1a90: 6c 69 65 6e 74 28 69 6e 74 20 66 64 29 20 7b 0a lient(int fd) {.
1aa0: 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f 66 69 .struct filed_fi
1ab0: 6c 65 69 6e 66 6f 20 2a 66 69 6c 65 69 6e 66 6f leinfo *fileinfo
1ac0: 2c 20 66 69 6c 65 69 6e 66 6f 5f 62 3b 0a 09 73 , fileinfo_b;..s
1ad0: 73 69 7a 65 5f 74 20 73 65 6e 64 66 69 6c 65 5f size_t sendfile_
1ae0: 72 65 74 3b 0a 09 73 69 7a 65 5f 74 20 73 65 6e ret;..size_t sen
1af0: 64 66 69 6c 65 5f 6c 65 6e 3b 0a 09 6f 66 66 5f dfile_len;..off_
1b00: 74 20 73 65 6e 64 66 69 6c 65 5f 6f 66 66 73 65 t sendfile_offse
1b10: 74 3b 0a 09 63 68 61 72 20 2a 70 61 74 68 2c 20 t;..char *path,
1b20: 70 61 74 68 5f 62 5b 31 30 31 30 5d 3b 0a 09 63 path_b[1010];..c
1b30: 68 61 72 20 2a 64 61 74 65 5f 63 75 72 72 65 6e har *date_curren
1b40: 74 2c 20 64 61 74 65 5f 63 75 72 72 65 6e 74 5f t, date_current_
1b50: 62 5b 36 34 5d 3b 0a 09 46 49 4c 45 20 2a 66 70 b[64];..FILE *fp
1b60: 3b 0a 0a 09 2f 2a 20 44 65 74 65 72 6d 69 6e 65 ;.../* Determine
1b70: 20 63 75 72 72 65 6e 74 20 74 69 6d 65 20 2a 2f current time */
1b80: 0a 09 64 61 74 65 5f 63 75 72 72 65 6e 74 20 3d ..date_current =
1b90: 20 66 69 6c 65 64 5f 66 6f 72 6d 61 74 5f 74 69 filed_format_ti
1ba0: 6d 65 28 64 61 74 65 5f 63 75 72 72 65 6e 74 5f me(date_current_
1bb0: 62 2c 20 73 69 7a 65 6f 66 28 64 61 74 65 5f 63 b, sizeof(date_c
1bc0: 75 72 72 65 6e 74 5f 62 29 2c 20 74 69 6d 65 28 urrent_b), time(
1bd0: 4e 55 4c 4c 29 29 3b 0a 0a 09 2f 2a 20 4f 70 65 NULL));.../* Ope
1be0: 6e 20 73 6f 63 6b 65 74 20 61 73 20 41 4e 53 49 n socket as ANSI
1bf0: 20 49 2f 4f 20 66 6f 72 20 65 61 73 65 20 6f 66 I/O for ease of
1c00: 20 75 73 65 20 2a 2f 0a 09 66 70 20 3d 20 66 64 use */..fp = fd
1c10: 6f 70 65 6e 28 66 64 2c 20 22 77 2b 62 22 29 3b open(fd, "w+b");
1c20: 0a 09 69 66 20 28 66 70 20 3d 3d 20 4e 55 4c 4c ..if (fp == NULL
1c30: 29 20 7b 0a 09 09 63 6c 6f 73 65 28 66 64 29 3b ) {...close(fd);
1c40: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a ....return;..}..
1c50: 09 70 61 74 68 20 3d 20 66 69 6c 65 64 5f 67 65 .path = filed_ge
1c60: 74 5f 68 74 74 70 5f 72 65 71 75 65 73 74 28 66 t_http_request(f
1c70: 70 2c 20 70 61 74 68 5f 62 2c 20 73 69 7a 65 6f p, path_b, sizeo
1c80: 66 28 70 61 74 68 5f 62 29 29 3b 0a 0a 09 66 69 f(path_b));...fi
1c90: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f led_log_msg("PRO
1ca0: 43 45 53 53 5f 52 45 50 4c 59 5f 53 54 41 52 54 CESS_REPLY_START
1cb0: 20 46 44 3d 2e 2e 2e 20 50 41 54 48 3d 2e 2e 2e FD=... PATH=...
1cc0: 22 29 3b 0a 0a 09 69 66 20 28 70 61 74 68 20 3d ");...if (path =
1cd0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 69 6c 65 = NULL) {...file
1ce0: 64 5f 65 72 72 6f 72 5f 70 61 67 65 28 66 70 2c d_error_page(fp,
1cf0: 20 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 20 35 date_current, 5
1d00: 30 30 29 3b 0a 0a 09 09 66 69 6c 65 64 5f 6c 6f 00);....filed_lo
1d10: 67 5f 6d 73 67 28 22 50 52 4f 43 45 53 53 5f 52 g_msg("PROCESS_R
1d20: 45 50 4c 59 5f 43 4f 4d 50 4c 45 54 45 20 46 44 EPLY_COMPLETE FD
1d30: 3d 2e 2e 2e 20 45 52 52 4f 52 3d 35 30 30 22 29 =... ERROR=500")
1d40: 3b 0a 0a 09 09 66 63 6c 6f 73 65 28 66 70 29 3b ;....fclose(fp);
1d50: 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a ....return;..}..
1d60: 09 66 69 6c 65 69 6e 66 6f 20 3d 20 66 69 6c 65 .fileinfo = file
1d70: 64 5f 6f 70 65 6e 5f 66 69 6c 65 28 70 61 74 68 d_open_file(path
1d80: 2c 20 26 66 69 6c 65 69 6e 66 6f 5f 62 29 3b 0a , &fileinfo_b);.
1d90: 09 69 66 20 28 66 69 6c 65 69 6e 66 6f 20 3d 3d .if (fileinfo ==
1da0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 66 69 6c 65 64 NULL) {...filed
1db0: 5f 65 72 72 6f 72 5f 70 61 67 65 28 66 70 2c 20 _error_page(fp,
1dc0: 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 20 34 30 date_current, 40
1dd0: 34 29 3b 0a 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 4);....filed_log
1de0: 5f 6d 73 67 28 22 50 52 4f 43 45 53 53 5f 52 45 _msg("PROCESS_RE
1df0: 50 4c 59 5f 43 4f 4d 50 4c 45 54 45 20 46 44 3d PLY_COMPLETE FD=
1e00: 2e 2e 2e 20 45 52 52 4f 52 3d 34 30 34 22 29 3b ... ERROR=404");
1e10: 0a 09 7d 20 65 6c 73 65 20 7b 0a 09 09 66 70 72 ..} else {...fpr
1e20: 69 6e 74 66 28 66 70 2c 20 22 48 54 54 50 2f 31 intf(fp, "HTTP/1
1e30: 2e 31 20 32 30 30 20 4f 4b 5c 72 5c 6e 44 61 74 .1 200 OK\r\nDat
1e40: 65 3a 20 25 73 5c 72 5c 6e 53 65 72 76 65 72 3a e: %s\r\nServer:
1e50: 20 66 69 6c 65 64 5c 72 5c 6e 4c 61 73 74 2d 4d filed\r\nLast-M
1e60: 6f 64 69 66 69 65 64 3a 20 25 73 5c 72 5c 6e 43 odified: %s\r\nC
1e70: 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 ontent-Length: %
1e80: 6c 6c 75 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 54 llu\r\nContent-T
1e90: 79 70 65 3a 20 25 73 5c 72 5c 6e 43 6f 6e 6e 65 ype: %s\r\nConne
1ea0: 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e ction: close\r\n
1eb0: 5c 72 5c 6e 22 2c 0a 09 09 09 64 61 74 65 5f 63 \r\n",....date_c
1ec0: 75 72 72 65 6e 74 2c 0a 09 09 09 66 69 6c 65 69 urrent,....filei
1ed0: 6e 66 6f 2d 3e 6c 61 73 74 6d 6f 64 2c 0a 09 09 nfo->lastmod,...
1ee0: 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 .(unsigned long
1ef0: 6c 6f 6e 67 29 20 66 69 6c 65 69 6e 66 6f 2d 3e long) fileinfo->
1f00: 6c 65 6e 2c 0a 09 09 09 66 69 6c 65 69 6e 66 6f len,....fileinfo
1f10: 2d 3e 74 79 70 65 0a 09 09 29 3b 0a 09 09 66 66 ->type...);...ff
1f20: 6c 75 73 68 28 66 70 29 3b 0a 0a 09 09 66 69 6c lush(fp);....fil
1f30: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f 43 ed_log_msg("PROC
1f40: 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 4c 45 ESS_REPLY_COMPLE
1f50: 54 45 20 46 44 3d 2e 2e 2e 20 53 54 41 54 55 53 TE FD=... STATUS
1f60: 3d 32 30 30 22 29 3b 0a 0a 09 09 66 69 6c 65 64 =200");....filed
1f70: 5f 6c 6f 67 5f 6d 73 67 28 22 53 45 4e 44 5f 53 _log_msg("SEND_S
1f80: 54 41 52 54 20 49 46 44 3d 2e 2e 2e 20 4f 46 44 TART IFD=... OFD
1f90: 3d 2e 2e 2e 20 42 59 54 45 53 3d 2e 2e 2e 22 29 =... BYTES=...")
1fa0: 3b 0a 0a 09 09 73 65 6e 64 66 69 6c 65 5f 6f 66 ;....sendfile_of
1fb0: 66 73 65 74 20 3d 20 30 3b 0a 09 09 73 65 6e 64 fset = 0;...send
1fc0: 66 69 6c 65 5f 6c 65 6e 20 3d 20 66 69 6c 65 69 file_len = filei
1fd0: 6e 66 6f 2d 3e 6c 65 6e 3b 0a 09 09 77 68 69 6c nfo->len;...whil
1fe0: 65 20 28 31 29 20 7b 0a 09 09 09 73 65 6e 64 66 e (1) {....sendf
1ff0: 69 6c 65 5f 72 65 74 20 3d 20 73 65 6e 64 66 69 ile_ret = sendfi
2000: 6c 65 28 66 64 2c 20 66 69 6c 65 69 6e 66 6f 2d le(fd, fileinfo-
2010: 3e 66 64 2c 20 26 73 65 6e 64 66 69 6c 65 5f 6f >fd, &sendfile_o
2020: 66 66 73 65 74 2c 20 73 65 6e 64 66 69 6c 65 5f ffset, sendfile_
2030: 6c 65 6e 29 3b 0a 09 09 09 69 66 20 28 73 65 6e len);....if (sen
2040: 64 66 69 6c 65 5f 72 65 74 20 3c 3d 20 30 29 20 dfile_ret <= 0)
2050: 7b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 {.....break;....
2060: 7d 0a 0a 09 09 09 73 65 6e 64 66 69 6c 65 5f 6c }.....sendfile_l
2070: 65 6e 20 2d 3d 20 73 65 6e 64 66 69 6c 65 5f 72 en -= sendfile_r
2080: 65 74 3b 0a 09 09 09 69 66 20 28 73 65 6e 64 66 et;....if (sendf
2090: 69 6c 65 5f 6c 65 6e 20 3d 3d 20 30 29 20 7b 0a ile_len == 0) {.
20a0: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 7d 0a ....break;....}.
20b0: 09 09 7d 0a 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 ..}....filed_log
20c0: 5f 6d 73 67 28 22 53 45 4e 44 5f 43 4f 4d 50 4c _msg("SEND_COMPL
20d0: 45 54 45 20 53 54 41 54 55 53 3d 2e 2e 2e 20 49 ETE STATUS=... I
20e0: 46 44 3d 2e 2e 2e 20 4f 46 44 3d 2e 2e 2e 20 42 FD=... OFD=... B
20f0: 59 54 45 53 3d 2e 2e 2e 20 42 59 54 45 53 5f 53 YTES=... BYTES_S
2100: 45 4e 54 3d 2e 2e 2e 22 29 3b 0a 0a 09 09 63 6c ENT=...");....cl
2110: 6f 73 65 28 66 69 6c 65 69 6e 66 6f 2d 3e 66 64 ose(fileinfo->fd
2120: 29 3b 0a 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f );....filed_log_
2130: 6d 73 67 28 22 43 4c 4f 53 45 5f 46 49 4c 45 20 msg("CLOSE_FILE
2140: 46 44 3d 2e 2e 2e 22 29 3b 0a 09 7d 0a 0a 09 66 FD=...");..}...f
2150: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 43 4c iled_log_msg("CL
2160: 4f 53 45 5f 43 4f 4e 4e 45 43 54 49 4f 4e 20 46 OSE_CONNECTION F
2170: 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 66 63 6c 6f 73 D=...");...fclos
2180: 65 28 66 70 29 3b 0a 0a 09 72 65 74 75 72 6e 3b e(fp);...return;
2190: 0a 7d 0a 0a 2f 2a 20 48 61 6e 64 6c 65 20 69 6e .}../* Handle in
21a0: 63 6f 6d 69 6e 67 20 63 6f 6e 6e 65 63 74 69 6f coming connectio
21b0: 6e 73 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 ns */.static voi
21c0: 64 20 2a 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f d *filed_worker_
21d0: 74 68 72 65 61 64 28 76 6f 69 64 20 2a 61 72 67 thread(void *arg
21e0: 5f 76 29 20 7b 0a 09 73 74 72 75 63 74 20 66 69 _v) {..struct fi
21f0: 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 led_worker_threa
2200: 64 5f 61 72 67 73 20 2a 61 72 67 3b 0a 09 73 74 d_args *arg;..st
2210: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f 69 6e ruct sockaddr_in
2220: 36 20 61 64 64 72 3b 0a 09 73 6f 63 6b 6c 65 6e 6 addr;..socklen
2230: 5f 74 20 61 64 64 72 6c 65 6e 3b 0a 09 69 6e 74 _t addrlen;..int
2240: 20 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3d failure_count =
2250: 20 30 2c 20 6d 61 78 5f 66 61 69 6c 75 72 65 5f 0, max_failure_
2260: 63 6f 75 6e 74 20 3d 20 4d 41 58 5f 46 41 49 4c count = MAX_FAIL
2270: 55 52 45 5f 43 4f 55 4e 54 3b 0a 09 69 6e 74 20 URE_COUNT;..int
2280: 6d 61 73 74 65 72 5f 66 64 2c 20 66 64 3b 0a 0a master_fd, fd;..
2290: 09 2f 2a 20 52 65 61 64 20 61 72 67 75 6d 65 6e ./* Read argumen
22a0: 74 73 20 2a 2f 0a 09 61 72 67 20 3d 20 61 72 67 ts */..arg = arg
22b0: 5f 76 3b 0a 0a 09 6d 61 73 74 65 72 5f 66 64 20 _v;...master_fd
22c0: 3d 20 61 72 67 2d 3e 66 64 3b 0a 0a 09 77 68 69 = arg->fd;...whi
22d0: 6c 65 20 28 31 29 20 7b 0a 09 09 2f 2a 20 46 61 le (1) {.../* Fa
22e0: 69 6c 75 72 65 20 6c 6f 6f 70 20 70 72 65 76 65 ilure loop preve
22f0: 6e 74 69 6f 6e 20 2a 2f 0a 09 09 69 66 20 28 66 ntion */...if (f
2300: 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3e 20 6d ailure_count > m
2310: 61 78 5f 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 ax_failure_count
2320: 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 ) {....break;...
2330: 7d 0a 0a 09 09 2f 2a 20 41 63 63 65 70 74 20 61 }..../* Accept a
2340: 20 6e 65 77 20 63 6c 69 65 6e 74 20 2a 2f 0a 09 new client */..
2350: 09 61 64 64 72 6c 65 6e 20 3d 20 73 69 7a 65 6f .addrlen = sizeo
2360: 66 28 61 64 64 72 29 3b 0a 09 09 66 64 20 3d 20 f(addr);...fd =
2370: 61 63 63 65 70 74 28 6d 61 73 74 65 72 5f 66 64 accept(master_fd
2380: 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b 61 64 , (struct sockad
2390: 64 72 20 2a 29 20 26 61 64 64 72 2c 20 26 61 64 dr *) &addr, &ad
23a0: 64 72 6c 65 6e 29 3b 0a 0a 09 09 2f 2a 0a 09 09 drlen);..../*...
23b0: 20 2a 20 49 66 20 77 65 20 66 61 69 6c 2c 20 6d * If we fail, m
23c0: 61 6b 65 20 61 20 6e 6f 74 65 20 6f 66 20 69 74 ake a note of it
23d0: 20 73 6f 20 77 65 20 64 6f 6e 27 74 20 67 6f 20 so we don't go
23e0: 69 6e 74 6f 20 61 20 6c 6f 6f 70 20 6f 66 0a 09 into a loop of..
23f0: 09 20 2a 20 61 63 63 65 70 74 28 29 20 66 61 69 . * accept() fai
2400: 6c 69 6e 67 0a 09 09 20 2a 2f 0a 09 09 69 66 20 ling... */...if
2410: 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 09 2f 2a (fd < 0) {..../*
2420: 20 4c 6f 67 20 74 68 65 20 6e 65 77 20 63 6f 6e Log the new con
2430: 6e 65 63 74 69 6f 6e 20 2a 2f 0a 09 09 09 66 69 nection */....fi
2440: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 41 43 43 led_log_msg("ACC
2450: 45 50 54 5f 46 41 49 4c 45 44 22 29 3b 0a 0a 09 EPT_FAILED");...
2460: 09 09 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 2b ..failure_count+
2470: 2b 3b 0a 0a 09 09 09 63 6f 6e 74 69 6e 75 65 3b +;.....continue;
2480: 0a 09 09 7d 0a 0a 09 09 2f 2a 20 4c 6f 67 20 74 ...}..../* Log t
2490: 68 65 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f he new connectio
24a0: 6e 20 2a 2f 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 n */...filed_log
24b0: 5f 6d 73 67 28 22 4e 45 57 5f 43 4f 4e 4e 45 43 _msg("NEW_CONNEC
24c0: 54 49 4f 4e 20 53 52 43 5f 41 44 44 52 3d 2e 2e TION SRC_ADDR=..
24d0: 2e 20 53 52 43 5f 50 4f 52 54 3d 2e 2e 2e 20 46 . SRC_PORT=... F
24e0: 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 09 2f 2a 20 52 D=...");..../* R
24f0: 65 73 65 74 20 66 61 69 6c 75 72 65 20 63 6f 75 eset failure cou
2500: 6e 74 2a 2f 0a 09 09 66 61 69 6c 75 72 65 5f 63 nt*/...failure_c
2510: 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 2f 2a 20 ount = 0;..../*
2520: 48 61 6e 64 6c 65 20 73 6f 63 6b 65 74 20 2a 2f Handle socket */
2530: 0a 09 09 66 69 6c 65 64 5f 68 61 6e 64 6c 65 5f ...filed_handle_
2540: 63 6c 69 65 6e 74 28 66 64 29 3b 0a 09 7d 0a 0a client(fd);..}..
2550: 09 2f 2a 20 52 65 70 6f 72 74 20 65 72 72 6f 72 ./* Report error
2560: 20 2a 2f 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d */..filed_log_m
2570: 73 67 28 22 54 48 52 45 41 44 5f 44 49 45 44 20 sg("THREAD_DIED
2580: 41 42 4e 4f 52 4d 41 4c 22 29 3b 0a 0a 09 72 65 ABNORMAL");...re
2590: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 7d 0a 0a 2f turn(NULL);.}../
25a0: 2a 20 43 72 65 61 74 65 20 77 6f 72 6b 65 72 20 * Create worker
25b0: 74 68 72 65 61 64 73 20 2a 2f 0a 73 74 61 74 69 threads */.stati
25c0: 63 20 69 6e 74 20 66 69 6c 65 64 5f 77 6f 72 6b c int filed_work
25d0: 65 72 5f 74 68 72 65 61 64 73 5f 69 6e 69 74 28 er_threads_init(
25e0: 69 6e 74 20 66 64 2c 20 69 6e 74 20 74 68 72 65 int fd, int thre
25f0: 61 64 5f 63 6f 75 6e 74 29 20 7b 0a 09 73 74 72 ad_count) {..str
2600: 75 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 uct filed_worker
2610: 5f 74 68 72 65 61 64 5f 61 72 67 73 20 2a 61 72 _thread_args *ar
2620: 67 3b 0a 09 70 74 68 72 65 61 64 5f 74 20 74 68 g;..pthread_t th
2630: 72 65 61 64 69 64 3b 0a 09 69 6e 74 20 70 74 68 readid;..int pth
2640: 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e 74 20 69 read_ret;..int i
2650: 3b 0a 0a 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 ;...for (i = 0;
2660: 69 20 3c 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 i < thread_count
2670: 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72 67 20 3d ; i++) {...arg =
2680: 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a malloc(sizeof(*
2690: 61 72 67 29 29 3b 0a 0a 09 09 61 72 67 2d 3e 66 arg));....arg->f
26a0: 64 20 3d 20 66 64 3b 0a 0a 09 09 70 74 68 72 65 d = fd;....pthre
26b0: 61 64 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64 ad_ret = pthread
26c0: 5f 63 72 65 61 74 65 28 26 74 68 72 65 61 64 69 _create(&threadi
26d0: 64 2c 20 4e 55 4c 4c 2c 20 66 69 6c 65 64 5f 77 d, NULL, filed_w
26e0: 6f 72 6b 65 72 5f 74 68 72 65 61 64 2c 20 61 72 orker_thread, ar
26f0: 67 29 3b 0a 09 09 69 66 20 28 70 74 68 72 65 61 g);...if (pthrea
2700: 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 d_ret != 0) {...
2710: 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 09 7d .return(-1);...}
2720: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b ..}...return(0);
2730: 0a 7d 0a 0a 2f 2a 20 52 75 6e 20 70 72 6f 63 65 .}../* Run proce
2740: 73 73 20 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69 ss */.int main(i
2750: 6e 74 20 61 72 67 63 2c 20 63 68 61 72 20 2a 2a nt argc, char **
2760: 61 72 67 76 29 20 7b 0a 09 69 6e 74 20 70 6f 72 argv) {..int por
2770: 74 20 3d 20 50 4f 52 54 2c 20 74 68 72 65 61 64 t = PORT, thread
2780: 5f 63 6f 75 6e 74 20 3d 20 54 48 52 45 41 44 5f _count = THREAD_
2790: 43 4f 55 4e 54 3b 0a 09 63 6f 6e 73 74 20 63 68 COUNT;..const ch
27a0: 61 72 20 2a 62 69 6e 64 5f 61 64 64 72 20 3d 20 ar *bind_addr =
27b0: 42 49 4e 44 5f 41 44 44 52 3b 0a 09 69 6e 74 20 BIND_ADDR;..int
27c0: 69 6e 69 74 5f 72 65 74 3b 0a 09 69 6e 74 20 66 init_ret;..int f
27d0: 64 3b 0a 0a 09 2f 2a 20 58 58 58 3a 20 54 4f 44 d;.../* XXX: TOD
27e0: 4f 3a 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d O: Process argum
27f0: 65 6e 74 73 20 2a 2f 0a 09 61 72 67 63 20 3d 20 ents */..argc =
2800: 61 72 67 63 3b 0a 09 61 72 67 76 20 3d 20 61 72 argc;..argv = ar
2810: 67 76 3b 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20 gv;.../* Create
2820: 6c 69 73 74 65 6e 69 6e 67 20 73 6f 63 6b 65 74 listening socket
2830: 20 2a 2f 0a 09 66 64 20 3d 20 66 69 6c 65 64 5f */..fd = filed_
2840: 6c 69 73 74 65 6e 28 62 69 6e 64 5f 61 64 64 72 listen(bind_addr
2850: 2c 20 70 6f 72 74 29 3b 0a 09 69 66 20 28 66 64 , port);..if (fd
2860: 20 3c 20 30 29 20 7b 0a 09 09 70 65 72 72 6f 72 < 0) {...perror
2870: 28 22 66 69 6c 65 64 5f 6c 69 73 74 65 6e 22 29 ("filed_listen")
2880: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a ;....return(1);.
2890: 09 7d 0a 0a 09 2f 2a 20 42 65 63 6f 6d 65 20 61 .}.../* Become a
28a0: 20 64 61 65 6d 6f 6e 20 2a 2f 0a 09 2f 2a 20 58 daemon */../* X
28b0: 58 58 3a 54 4f 44 4f 3a 20 42 65 63 6f 6d 65 20 XX:TODO: Become
28c0: 61 20 64 61 65 6d 6f 6e 20 2a 2f 0a 0a 09 2f 2a a daemon */.../*
28d0: 20 49 6e 69 74 69 61 6c 69 7a 65 20 2a 2f 0a 09 Initialize */..
28e0: 69 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 64 init_ret = filed
28f0: 5f 69 6e 69 74 28 29 3b 0a 09 69 66 20 28 69 6e _init();..if (in
2900: 69 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 it_ret != 0) {..
2910: 09 70 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 69 .perror("filed_i
2920: 6e 69 74 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e nit");....return
2930: 28 33 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 43 72 65 (3);..}.../* Cre
2940: 61 74 65 20 6c 6f 67 67 69 6e 67 20 74 68 72 65 ate logging thre
2950: 61 64 20 2a 2f 0a 09 69 6e 69 74 5f 72 65 74 20 ad */..init_ret
2960: 3d 20 66 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f = filed_logging_
2970: 74 68 72 65 61 64 5f 69 6e 69 74 28 29 3b 0a 09 thread_init();..
2980: 69 66 20 28 69 6e 69 74 5f 72 65 74 20 21 3d 20 if (init_ret !=
2990: 30 29 20 7b 0a 09 09 70 65 72 72 6f 72 28 22 66 0) {...perror("f
29a0: 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 iled_logging_thr
29b0: 65 61 64 5f 69 6e 69 74 22 29 3b 0a 0a 09 09 72 ead_init");....r
29c0: 65 74 75 72 6e 28 34 29 3b 0a 09 7d 0a 0a 09 2f eturn(4);..}.../
29d0: 2a 20 43 72 65 61 74 65 20 77 6f 72 6b 65 72 20 * Create worker
29e0: 74 68 72 65 61 64 73 20 2a 2f 0a 09 69 6e 69 74 threads */..init
29f0: 5f 72 65 74 20 3d 20 66 69 6c 65 64 5f 77 6f 72 _ret = filed_wor
2a00: 6b 65 72 5f 74 68 72 65 61 64 73 5f 69 6e 69 74 ker_threads_init
2a10: 28 66 64 2c 20 74 68 72 65 61 64 5f 63 6f 75 6e (fd, thread_coun
2a20: 74 29 3b 0a 09 69 66 20 28 69 6e 69 74 5f 72 65 t);..if (init_re
2a30: 74 20 21 3d 20 30 29 20 7b 0a 09 09 70 65 72 72 t != 0) {...perr
2a40: 6f 72 28 22 66 69 6c 65 64 5f 77 6f 72 6b 65 72 or("filed_worker
2a50: 5f 74 68 72 65 61 64 73 5f 69 6e 69 74 22 29 3b _threads_init");
2a60: 0a 0a 09 09 72 65 74 75 72 6e 28 34 29 3b 0a 09 ....return(4);..
2a70: 7d 0a 0a 09 2f 2a 20 57 61 69 74 20 66 6f 72 20 }.../* Wait for
2a80: 74 68 72 65 61 64 73 20 74 6f 20 65 78 69 74 20 threads to exit
2a90: 2a 2f 0a 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a */../* XXX:TODO:
2aa0: 20 4d 6f 6e 69 74 6f 72 20 74 68 72 65 61 64 20 Monitor thread
2ab0: 75 73 61 67 65 20 2a 2f 0a 09 77 68 69 6c 65 20 usage */..while
2ac0: 28 31 29 20 7b 0a 09 09 73 6c 65 65 70 28 36 30 (1) {...sleep(60
2ad0: 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 74 75 72 );..}.../* Retur
2ae0: 6e 20 69 6e 20 66 61 69 6c 75 72 65 20 2a 2f 0a n in failure */.
2af0: 09 72 65 74 75 72 6e 28 32 29 3b 0a 7d 0a .return(2);.}.