Hex Artifact Content

Artifact 3fb691b2d3f62f459cb798b83b9c070fe5c3327d:


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 74 64 6c 69 62 2e 68 3e 0a 23 69 6e 63 6c 75  stdlib.h>.#inclu
00d0: 64 65 20 3c 75 6e 69 73 74 64 2e 68 3e 0a 23 69  de <unistd.h>.#i
00e0: 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e 67 2e 68  nclude <string.h
00f0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63 6e 74  >.#include <fcnt
0100: 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73  l.h>.#include <s
0110: 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  tdio.h>.#include
0120: 20 3c 74 69 6d 65 2e 68 3e 0a 0a 2f 2a 20 44 65   <time.h>../* De
0130: 66 61 75 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a  fault values */.
0140: 23 64 65 66 69 6e 65 20 4d 41 58 5f 46 41 49 4c  #define MAX_FAIL
0150: 55 52 45 5f 43 4f 55 4e 54 20 33 30 0a 23 64 65  URE_COUNT 30.#de
0160: 66 69 6e 65 20 50 4f 52 54 20 38 30 38 30 0a 23  fine PORT 8080.#
0170: 64 65 66 69 6e 65 20 54 48 52 45 41 44 5f 43 4f  define THREAD_CO
0180: 55 4e 54 20 31 30 0a 23 64 65 66 69 6e 65 20 42  UNT 10.#define B
0190: 49 4e 44 5f 41 44 44 52 20 22 3a 3a 22 0a 0a 2f  IND_ADDR "::"../
01a0: 2a 20 41 72 67 75 6d 65 6e 74 73 20 66 6f 72 20  * Arguments for 
01b0: 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20 2a  worker threads *
01c0: 2f 0a 73 74 72 75 63 74 20 66 69 6c 65 64 5f 77  /.struct filed_w
01d0: 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f 61 72 67  orker_thread_arg
01e0: 73 20 7b 0a 09 69 6e 74 20 66 64 3b 0a 7d 3b 0a  s {..int fd;.};.
01f0: 0a 2f 2a 20 46 69 6c 65 20 69 6e 66 6f 72 6d 61  ./* File informa
0200: 74 69 6f 6e 20 2a 2f 0a 73 74 72 75 63 74 20 66  tion */.struct f
0210: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 7b 0a  iled_fileinfo {.
0220: 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74  .pthread_mutex_t
0230: 20 6d 75 74 65 78 3b 0a 09 63 68 61 72 20 2a 70   mutex;..char *p
0240: 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 09 73  ath;..int fd;..s
0250: 69 7a 65 5f 74 20 6c 65 6e 3b 0a 09 63 68 61 72  ize_t len;..char
0260: 20 2a 6c 61 73 74 6d 6f 64 3b 0a 09 63 68 61 72   *lastmod;..char
0270: 20 6c 61 73 74 6d 6f 64 5f 62 5b 36 34 5d 3b 0a   lastmod_b[64];.
0280: 09 63 68 61 72 20 2a 74 79 70 65 3b 0a 7d 3b 0a  .char *type;.};.
0290: 0a 2f 2a 20 47 6c 6f 62 61 6c 20 76 61 72 69 61  ./* Global varia
02a0: 62 6c 65 73 20 2a 2f 0a 73 74 72 75 63 74 20 66  bles */.struct f
02b0: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66  iled_fileinfo *f
02c0: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64  iled_fileinfo_fd
02d0: 63 61 63 68 65 3b 0a 75 6e 73 69 67 6e 65 64 20  cache;.unsigned 
02e0: 69 6e 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e  int filed_filein
02f0: 66 6f 5f 66 64 63 61 63 68 65 5f 73 69 7a 65 20  fo_fdcache_size 
0300: 3d 20 38 31 39 32 3b 0a 0a 2f 2a 20 49 6e 69 74  = 8192;../* Init
0310: 69 61 6c 69 7a 65 20 70 72 6f 63 65 73 73 20 2a  ialize process *
0320: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c  /.static int fil
0330: 65 64 5f 69 6e 69 74 28 76 6f 69 64 29 20 7b 0a  ed_init(void) {.
0340: 09 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 64  .unsigned int id
0350: 78 3b 0a 09 69 6e 74 20 6d 75 74 65 78 5f 69 6e  x;..int mutex_in
0360: 69 74 5f 72 65 74 3b 0a 0a 09 6d 6c 6f 63 6b 61  it_ret;...mlocka
0370: 6c 6c 28 4d 43 4c 5f 43 55 52 52 45 4e 54 20 7c  ll(MCL_CURRENT |
0380: 20 4d 43 4c 5f 46 55 54 55 52 45 29 3b 0a 0a 09   MCL_FUTURE);...
0390: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66  filed_fileinfo_f
03a0: 64 63 61 63 68 65 20 3d 20 6d 61 6c 6c 6f 63 28  dcache = malloc(
03b0: 73 69 7a 65 6f 66 28 2a 66 69 6c 65 64 5f 66 69  sizeof(*filed_fi
03c0: 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 29 20  leinfo_fdcache) 
03d0: 2a 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  * filed_fileinfo
03e0: 5f 66 64 63 61 63 68 65 5f 73 69 7a 65 29 3b 0a  _fdcache_size);.
03f0: 09 69 66 20 28 66 69 6c 65 64 5f 66 69 6c 65 69  .if (filed_filei
0400: 6e 66 6f 5f 66 64 63 61 63 68 65 20 3d 3d 20 4e  nfo_fdcache == N
0410: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
0420: 31 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28 69 64  1);..}...for (id
0430: 78 20 3d 20 30 3b 20 69 64 78 20 3c 20 66 69 6c  x = 0; idx < fil
0440: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61  ed_fileinfo_fdca
0450: 63 68 65 5f 73 69 7a 65 3b 20 69 64 78 2b 2b 29  che_size; idx++)
0460: 20 7b 0a 09 09 6d 75 74 65 78 5f 69 6e 69 74 5f   {...mutex_init_
0470: 72 65 74 20 3d 20 70 74 68 72 65 61 64 5f 6d 75  ret = pthread_mu
0480: 74 65 78 5f 69 6e 69 74 28 26 66 69 6c 65 64 5f  tex_init(&filed_
0490: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65  fileinfo_fdcache
04a0: 5b 69 64 78 5d 2e 6d 75 74 65 78 2c 20 4e 55 4c  [idx].mutex, NUL
04b0: 4c 29 3b 0a 09 09 69 66 20 28 6d 75 74 65 78 5f  L);...if (mutex_
04c0: 69 6e 69 74 5f 72 65 74 20 21 3d 20 30 29 20 7b  init_ret != 0) {
04d0: 0a 09 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09  ....return(1);..
04e0: 09 7d 0a 0a 09 09 66 69 6c 65 64 5f 66 69 6c 65  .}....filed_file
04f0: 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64 78  info_fdcache[idx
0500: 5d 2e 70 61 74 68 20 3d 20 73 74 72 64 75 70 28  ].path = strdup(
0510: 22 22 29 3b 0a 09 09 66 69 6c 65 64 5f 66 69 6c  "");...filed_fil
0520: 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64  einfo_fdcache[id
0530: 78 5d 2e 66 64 20 3d 20 2d 31 3b 0a 09 09 66 69  x].fd = -1;...fi
0540: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63  led_fileinfo_fdc
0550: 61 63 68 65 5b 69 64 78 5d 2e 6c 61 73 74 6d 6f  ache[idx].lastmo
0560: 64 20 3d 20 22 22 3b 0a 09 09 66 69 6c 65 64 5f  d = "";...filed_
0570: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65  fileinfo_fdcache
0580: 5b 69 64 78 5d 2e 74 79 70 65 20 3d 20 22 22 3b  [idx].type = "";
0590: 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b  ..}...return(0);
05a0: 0a 7d 0a 0a 2f 2a 20 4c 69 73 74 65 6e 20 6f 6e  .}../* Listen on
05b0: 20 61 20 70 61 72 74 69 63 75 6c 61 72 20 61 64   a particular ad
05c0: 64 72 65 73 73 2f 70 6f 72 74 20 2a 2f 0a 73 74  dress/port */.st
05d0: 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 6c  atic int filed_l
05e0: 69 73 74 65 6e 28 63 6f 6e 73 74 20 63 68 61 72  isten(const char
05f0: 20 2a 61 64 64 72 65 73 73 2c 20 75 6e 73 69 67   *address, unsig
0600: 6e 65 64 20 69 6e 74 20 70 6f 72 74 29 20 7b 0a  ned int port) {.
0610: 09 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72  .struct sockaddr
0620: 5f 69 6e 36 20 61 64 64 72 3b 0a 09 69 6e 74 20  _in6 addr;..int 
0630: 70 74 6f 6e 5f 72 65 74 2c 20 62 69 6e 64 5f 72  pton_ret, bind_r
0640: 65 74 2c 20 6c 69 73 74 65 6e 5f 72 65 74 3b 0a  et, listen_ret;.
0650: 09 69 6e 74 20 66 64 3b 0a 0a 09 61 64 64 72 2e  .int fd;...addr.
0660: 73 69 6e 36 5f 66 61 6d 69 6c 79 20 3d 20 41 46  sin6_family = AF
0670: 5f 49 4e 45 54 36 3b 0a 09 61 64 64 72 2e 73 69  _INET6;..addr.si
0680: 6e 36 5f 66 6c 6f 77 69 6e 66 6f 20 3d 20 30 3b  n6_flowinfo = 0;
0690: 0a 09 61 64 64 72 2e 73 69 6e 36 5f 73 63 6f 70  ..addr.sin6_scop
06a0: 65 5f 69 64 20 3d 20 30 3b 0a 09 61 64 64 72 2e  e_id = 0;..addr.
06b0: 73 69 6e 36 5f 70 6f 72 74 20 3d 20 68 74 6f 6e  sin6_port = hton
06c0: 73 28 70 6f 72 74 29 3b 0a 09 70 74 6f 6e 5f 72  s(port);..pton_r
06d0: 65 74 20 3d 20 69 6e 65 74 5f 70 74 6f 6e 28 41  et = inet_pton(A
06e0: 46 5f 49 4e 45 54 36 2c 20 61 64 64 72 65 73 73  F_INET6, address
06f0: 2c 20 61 64 64 72 2e 73 69 6e 36 5f 61 64 64 72  , addr.sin6_addr
0700: 2e 73 36 5f 61 64 64 72 29 3b 0a 09 69 66 20 28  .s6_addr);..if (
0710: 70 74 6f 6e 5f 72 65 74 20 21 3d 20 31 29 20 7b  pton_ret != 1) {
0720: 0a 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09  ...return(-1);..
0730: 7d 0a 0a 09 66 64 20 3d 20 73 6f 63 6b 65 74 28  }...fd = socket(
0740: 41 46 5f 49 4e 45 54 36 2c 20 53 4f 43 4b 5f 53  AF_INET6, SOCK_S
0750: 54 52 45 41 4d 2c 20 30 29 3b 0a 09 69 66 20 28  TREAM, 0);..if (
0760: 66 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75  fd < 0) {...retu
0770: 72 6e 28 66 64 29 3b 0a 09 7d 0a 0a 09 62 69 6e  rn(fd);..}...bin
0780: 64 5f 72 65 74 20 3d 20 62 69 6e 64 28 66 64 2c  d_ret = bind(fd,
0790: 20 28 63 6f 6e 73 74 20 73 74 72 75 63 74 20 73   (const struct s
07a0: 6f 63 6b 61 64 64 72 20 2a 29 20 26 61 64 64 72  ockaddr *) &addr
07b0: 2c 20 73 69 7a 65 6f 66 28 61 64 64 72 29 29 3b  , sizeof(addr));
07c0: 0a 09 69 66 20 28 62 69 6e 64 5f 72 65 74 20 3c  ..if (bind_ret <
07d0: 20 30 29 20 7b 0a 09 09 63 6c 6f 73 65 28 66 64   0) {...close(fd
07e0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29  );....return(-1)
07f0: 3b 0a 09 7d 0a 0a 09 6c 69 73 74 65 6e 5f 72 65  ;..}...listen_re
0800: 74 20 3d 20 6c 69 73 74 65 6e 28 66 64 2c 20 31  t = listen(fd, 1
0810: 32 38 29 3b 0a 09 69 66 20 28 6c 69 73 74 65 6e  28);..if (listen
0820: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 63  _ret != 0) {...c
0830: 6c 6f 73 65 28 66 64 29 3b 0a 0a 09 09 72 65 74  lose(fd);....ret
0840: 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65  urn(-1);..}...re
0850: 74 75 72 6e 28 66 64 29 3b 0a 7d 0a 0a 2f 2a 20  turn(fd);.}../* 
0860: 4c 6f 67 20 61 20 6d 65 73 73 61 67 65 20 2a 2f  Log a message */
0870: 0a 23 64 65 66 69 6e 65 20 46 49 4c 45 44 5f 44  .#define FILED_D
0880: 4f 4e 54 5f 4c 4f 47 0a 23 69 66 64 65 66 20 46  ONT_LOG.#ifdef F
0890: 49 4c 45 44 5f 44 4f 4e 54 5f 4c 4f 47 0a 23 20  ILED_DONT_LOG.# 
08a0: 20 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c 6f   define filed_lo
08b0: 67 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e 69  gging_thread_ini
08c0: 74 28 29 20 30 0a 23 20 20 64 65 66 69 6e 65 20  t() 0.#  define 
08d0: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65  filed_log_msg_de
08e0: 62 75 67 28 78 2c 20 2e 2e 2e 29 20 2f 2a 2a 2f  bug(x, ...) /**/
08f0: 0a 23 20 20 64 65 66 69 6e 65 20 66 69 6c 65 64  .#  define filed
0900: 5f 6c 6f 67 5f 6d 73 67 28 78 29 20 2f 2a 2a 2f  _log_msg(x) /**/
0910: 0a 23 65 6c 73 65 0a 2f 2a 20 49 6e 69 74 69 61  .#else./* Initia
0920: 6c 69 7a 65 20 6c 6f 67 67 69 6e 67 20 74 68 72  lize logging thr
0930: 65 61 64 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ead */.static in
0940: 74 20 66 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f  t filed_logging_
0950: 74 68 72 65 61 64 5f 69 6e 69 74 28 76 6f 69 64  thread_init(void
0960: 29 20 7b 0a 09 2f 2a 20 58 58 58 3a 54 4f 44 4f  ) {../* XXX:TODO
0970: 3a 20 55 6e 69 6d 70 6c 65 6d 65 6e 74 65 64 20  : Unimplemented 
0980: 2a 2f 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d  */..return(0);.}
0990: 0a 0a 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 55  ../* XXX:TODO: U
09a0: 6e 69 6d 70 6c 65 6d 65 6e 74 65 64 20 2a 2f 0a  nimplemented */.
09b0: 23 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c 6f  #define filed_lo
09c0: 67 5f 6d 73 67 5f 64 65 62 75 67 28 78 2c 20 2e  g_msg_debug(x, .
09d0: 2e 2e 29 20 7b 20 66 70 72 69 6e 74 66 28 73 74  ..) { fprintf(st
09e0: 64 65 72 72 2c 20 78 2c 20 5f 5f 56 41 5f 41 52  derr, x, __VA_AR
09f0: 47 53 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28 73  GS__); fprintf(s
0a00: 74 64 65 72 72 2c 20 22 5c 6e 22 29 3b 20 66 66  tderr, "\n"); ff
0a10: 6c 75 73 68 28 73 74 64 65 72 72 29 3b 20 7d 0a  lush(stderr); }.
0a20: 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c  .static void fil
0a30: 65 64 5f 6c 6f 67 5f 6d 73 67 28 63 6f 6e 73 74  ed_log_msg(const
0a40: 20 63 68 61 72 20 2a 62 75 66 66 65 72 29 20 7b   char *buffer) {
0a50: 0a 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 55  ../* XXX:TODO: U
0a60: 6e 69 6d 70 6c 65 6d 65 6e 74 65 64 20 2a 2f 0a  nimplemented */.
0a70: 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72 2c  .fprintf(stderr,
0a80: 20 22 25 73 5c 6e 22 2c 20 62 75 66 66 65 72 29   "%s\n", buffer)
0a90: 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a 23  ;...return;.}..#
0aa0: 65 6e 64 69 66 0a 2f 2a 20 46 6f 72 6d 61 74 20  endif./* Format 
0ab0: 74 69 6d 65 20 70 65 72 20 52 46 43 32 36 31 36  time per RFC2616
0ac0: 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20   */.static char 
0ad0: 2a 66 69 6c 65 64 5f 66 6f 72 6d 61 74 5f 74 69  *filed_format_ti
0ae0: 6d 65 28 63 68 61 72 20 2a 62 75 66 66 65 72 2c  me(char *buffer,
0af0: 20 73 69 7a 65 5f 74 20 62 75 66 66 65 72 5f 6c   size_t buffer_l
0b00: 65 6e 2c 20 63 6f 6e 73 74 20 74 69 6d 65 5f 74  en, const time_t
0b10: 20 74 69 6d 65 69 6e 66 6f 29 20 7b 0a 09 73 74   timeinfo) {..st
0b20: 72 75 63 74 20 74 6d 20 74 69 6d 65 69 6e 66 6f  ruct tm timeinfo
0b30: 5f 74 6d 2c 20 2a 74 69 6d 65 69 6e 66 6f 5f 74  _tm, *timeinfo_t
0b40: 6d 5f 70 3b 0a 0a 09 74 69 6d 65 69 6e 66 6f 5f  m_p;...timeinfo_
0b50: 74 6d 5f 70 20 3d 20 67 6d 74 69 6d 65 5f 72 28  tm_p = gmtime_r(
0b60: 26 74 69 6d 65 69 6e 66 6f 2c 20 26 74 69 6d 65  &timeinfo, &time
0b70: 69 6e 66 6f 5f 74 6d 29 3b 0a 09 69 66 20 28 74  info_tm);..if (t
0b80: 69 6d 65 69 6e 66 6f 5f 74 6d 5f 70 20 3d 3d 20  imeinfo_tm_p == 
0b90: 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e  NULL) {...return
0ba0: 28 22 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 09 7d 0a  ("unknown");..}.
0bb0: 0a 09 62 75 66 66 65 72 5b 62 75 66 66 65 72 5f  ..buffer[buffer_
0bc0: 6c 65 6e 20 2d 20 31 5d 20 3d 20 27 5c 30 27 3b  len - 1] = '\0';
0bd0: 0a 09 62 75 66 66 65 72 5f 6c 65 6e 20 3d 20 73  ..buffer_len = s
0be0: 74 72 66 74 69 6d 65 28 62 75 66 66 65 72 2c 20  trftime(buffer, 
0bf0: 62 75 66 66 65 72 5f 6c 65 6e 20 2d 20 31 2c 20  buffer_len - 1, 
0c00: 22 25 61 2c 20 25 64 20 25 62 20 25 59 20 25 48  "%a, %d %b %Y %H
0c10: 3a 25 4d 3a 25 53 20 47 4d 54 22 2c 20 74 69 6d  :%M:%S GMT", tim
0c20: 65 69 6e 66 6f 5f 74 6d 5f 70 29 3b 0a 0a 09 72  einfo_tm_p);...r
0c30: 65 74 75 72 6e 28 62 75 66 66 65 72 29 3b 0a 7d  eturn(buffer);.}
0c40: 0a 0a 2f 2a 20 68 61 73 68 20 2a 2f 0a 73 74 61  ../* hash */.sta
0c50: 74 69 63 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  tic unsigned int
0c60: 20 66 69 6c 65 64 5f 68 61 73 68 28 63 6f 6e 73   filed_hash(cons
0c70: 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20  t unsigned char 
0c80: 2a 76 61 6c 75 65 2c 20 75 6e 73 69 67 6e 65 64  *value, unsigned
0c90: 20 69 6e 74 20 6d 6f 64 75 6c 75 73 29 20 7b 0a   int modulus) {.
0ca0: 09 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 63  .unsigned char c
0cb0: 75 72 72 3b 0a 09 75 6e 73 69 67 6e 65 64 20 69  urr;..unsigned i
0cc0: 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74  nt retval;...ret
0cd0: 76 61 6c 20 3d 20 6d 6f 64 75 6c 75 73 20 2d 20  val = modulus - 
0ce0: 31 3b 0a 0a 09 77 68 69 6c 65 20 28 28 63 75 72  1;...while ((cur
0cf0: 72 20 3d 20 2a 76 61 6c 75 65 29 29 20 7b 0a 09  r = *value)) {..
0d00: 09 69 66 20 28 63 75 72 72 20 3c 20 33 32 29 20  .if (curr < 32) 
0d10: 7b 0a 09 09 09 63 75 72 72 20 3d 20 32 35 35 20  {....curr = 255 
0d20: 2d 20 63 75 72 72 3b 0a 09 09 7d 20 65 6c 73 65  - curr;...} else
0d30: 20 7b 0a 09 09 09 63 75 72 72 20 2d 3d 20 33 32   {....curr -= 32
0d40: 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 76 61 6c 20  ;...}....retval 
0d50: 3c 3c 3d 20 35 3b 0a 09 09 72 65 74 76 61 6c 20  <<= 5;...retval 
0d60: 2b 3d 20 63 75 72 72 3b 0a 0a 09 09 76 61 6c 75  += curr;....valu
0d70: 65 2b 2b 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c  e++;..}...retval
0d80: 20 3d 20 72 65 74 76 61 6c 20 25 20 6d 6f 64 75   = retval % modu
0d90: 6c 75 73 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65  lus;...return(re
0da0: 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 20 4f 70 65  tval);.}../* Ope
0db0: 6e 20 61 20 66 69 6c 65 20 61 6e 64 20 72 65 74  n a file and ret
0dc0: 75 72 6e 20 66 69 6c 65 20 69 6e 66 6f 72 6d 61  urn file informa
0dd0: 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 73  tion */.static s
0de0: 74 72 75 63 74 20 66 69 6c 65 64 5f 66 69 6c 65  truct filed_file
0df0: 69 6e 66 6f 20 2a 66 69 6c 65 64 5f 6f 70 65 6e  info *filed_open
0e00: 5f 66 69 6c 65 28 63 6f 6e 73 74 20 63 68 61 72  _file(const char
0e10: 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 66   *path, struct f
0e20: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 62  iled_fileinfo *b
0e30: 75 66 66 65 72 29 20 7b 0a 09 73 74 72 75 63 74  uffer) {..struct
0e40: 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20   filed_fileinfo 
0e50: 2a 63 61 63 68 65 3b 0a 09 75 6e 73 69 67 6e 65  *cache;..unsigne
0e60: 64 20 69 6e 74 20 63 61 63 68 65 5f 69 64 78 3b  d int cache_idx;
0e70: 0a 09 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 69 6e  ..off_t len;..in
0e80: 74 20 66 64 3b 0a 0a 09 63 61 63 68 65 5f 69 64  t fd;...cache_id
0e90: 78 20 3d 20 66 69 6c 65 64 5f 68 61 73 68 28 28  x = filed_hash((
0ea0: 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63  const unsigned c
0eb0: 68 61 72 20 2a 29 20 70 61 74 68 2c 20 66 69 6c  har *) path, fil
0ec0: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61  ed_fileinfo_fdca
0ed0: 63 68 65 5f 73 69 7a 65 29 3b 0a 0a 09 63 61 63  che_size);...cac
0ee0: 68 65 20 3d 20 26 66 69 6c 65 64 5f 66 69 6c 65  he = &filed_file
0ef0: 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 63 61 63  info_fdcache[cac
0f00: 68 65 5f 69 64 78 5d 3b 0a 0a 09 66 69 6c 65 64  he_idx];...filed
0f10: 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 22  _log_msg_debug("
0f20: 4c 6f 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f  Locking mutex fo
0f30: 72 20 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e  r idx: %lu", (un
0f40: 73 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63  signed long) cac
0f50: 68 65 5f 69 64 78 29 3b 0a 0a 09 70 74 68 72 65  he_idx);...pthre
0f60: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 63  ad_mutex_lock(&c
0f70: 61 63 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09  ache->mutex);...
0f80: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65  filed_log_msg_de
0f90: 62 75 67 28 22 43 6f 6d 70 6c 65 74 65 64 20 6c  bug("Completed l
0fa0: 6f 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f 72  ocking mutex for
0fb0: 20 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e 73   idx: %lu", (uns
0fc0: 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68  igned long) cach
0fd0: 65 5f 69 64 78 29 3b 0a 0a 09 69 66 20 28 73 74  e_idx);...if (st
0fe0: 72 63 6d 70 28 70 61 74 68 2c 20 63 61 63 68 65  rcmp(path, cache
0ff0: 2d 3e 70 61 74 68 29 20 21 3d 20 30 29 20 7b 0a  ->path) != 0) {.
1000: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f  ..filed_log_msg_
1010: 64 65 62 75 67 28 22 43 61 63 68 65 20 6d 69 73  debug("Cache mis
1020: 73 20 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20  s for idx: %lu: 
1030: 4f 4c 44 20 5c 22 25 73 5c 22 2c 20 4e 45 57 20  OLD \"%s\", NEW 
1040: 5c 22 25 73 5c 22 22 2c 20 28 75 6e 73 69 67 6e  \"%s\"", (unsign
1050: 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f 69  ed long) cache_i
1060: 64 78 2c 20 63 61 63 68 65 2d 3e 70 61 74 68 2c  dx, cache->path,
1070: 20 70 61 74 68 29 3b 0a 0a 09 09 66 64 20 3d 20   path);....fd = 
1080: 6f 70 65 6e 28 70 61 74 68 2c 20 4f 5f 52 44 4f  open(path, O_RDO
1090: 4e 4c 59 29 3b 0a 09 09 69 66 20 28 66 64 20 3c  NLY);...if (fd <
10a0: 20 30 29 20 7b 0a 09 09 09 70 74 68 72 65 61 64   0) {....pthread
10b0: 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 63  _mutex_unlock(&c
10c0: 61 63 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09  ache->mutex);...
10d0: 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a  ..return(NULL);.
10e0: 09 09 7d 0a 0a 09 09 66 72 65 65 28 63 61 63 68  ..}....free(cach
10f0: 65 2d 3e 70 61 74 68 29 3b 0a 09 09 69 66 20 28  e->path);...if (
1100: 63 61 63 68 65 2d 3e 66 64 20 3e 3d 20 30 29 20  cache->fd >= 0) 
1110: 7b 0a 09 09 09 63 6c 6f 73 65 28 63 61 63 68 65  {....close(cache
1120: 2d 3e 66 64 29 3b 0a 09 09 7d 0a 0a 09 09 6c 65  ->fd);...}....le
1130: 6e 20 3d 20 6c 73 65 65 6b 28 66 64 2c 20 30 2c  n = lseek(fd, 0,
1140: 20 53 45 45 4b 5f 45 4e 44 29 3b 0a 09 09 6c 73   SEEK_END);...ls
1150: 65 65 6b 28 66 64 2c 20 30 2c 20 53 45 45 4b 5f  eek(fd, 0, SEEK_
1160: 53 45 54 29 3b 0a 0a 09 09 63 61 63 68 65 2d 3e  SET);....cache->
1170: 66 64 20 3d 20 66 64 3b 0a 09 09 63 61 63 68 65  fd = fd;...cache
1180: 2d 3e 6c 65 6e 20 3d 20 6c 65 6e 3b 0a 09 09 63  ->len = len;...c
1190: 61 63 68 65 2d 3e 70 61 74 68 20 3d 20 73 74 72  ache->path = str
11a0: 64 75 70 28 70 61 74 68 29 3b 0a 0a 09 09 2f 2a  dup(path);..../*
11b0: 20 58 58 58 3a 54 4f 44 4f 3a 20 44 65 74 65 72   XXX:TODO: Deter
11c0: 6d 69 6e 65 20 2a 2f 0a 09 09 63 61 63 68 65 2d  mine */...cache-
11d0: 3e 74 79 70 65 20 3d 20 22 61 70 70 6c 69 63 61  >type = "applica
11e0: 74 69 6f 6e 2f 6f 63 74 65 74 2d 73 74 72 65 61  tion/octet-strea
11f0: 6d 22 3b 0a 09 09 63 61 63 68 65 2d 3e 6c 61 73  m";...cache->las
1200: 74 6d 6f 64 20 3d 20 66 69 6c 65 64 5f 66 6f 72  tmod = filed_for
1210: 6d 61 74 5f 74 69 6d 65 28 63 61 63 68 65 2d 3e  mat_time(cache->
1220: 6c 61 73 74 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f  lastmod_b, sizeo
1230: 66 28 63 61 63 68 65 2d 3e 6c 61 73 74 6d 6f 64  f(cache->lastmod
1240: 5f 62 29 2c 20 74 69 6d 65 28 4e 55 4c 4c 29 20  _b), time(NULL) 
1250: 2d 20 33 30 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  - 30);..} else {
1260: 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67  ...filed_log_msg
1270: 5f 64 65 62 75 67 28 22 43 61 63 68 65 20 68 69  _debug("Cache hi
1280: 74 20 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20  t for idx: %lu: 
1290: 50 41 54 48 20 5c 22 25 73 5c 22 22 2c 20 28 75  PATH \"%s\"", (u
12a0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61  nsigned long) ca
12b0: 63 68 65 5f 69 64 78 2c 20 70 61 74 68 29 3b 0a  che_idx, path);.
12c0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 57 65 20 68  .}.../*.. * We h
12d0: 61 76 65 20 74 6f 20 6d 61 6b 65 20 61 20 64 75  ave to make a du
12e0: 70 6c 69 63 61 74 65 20 46 44 2c 20 62 65 63 61  plicate FD, beca
12f0: 75 73 65 20 6f 6e 63 65 20 77 65 20 72 65 6c 65  use once we rele
1300: 61 73 65 20 74 68 65 20 63 61 63 68 65 0a 09 20  ase the cache.. 
1310: 2a 20 6d 75 74 65 78 2c 20 74 68 65 20 66 69 6c  * mutex, the fil
1320: 65 20 64 65 73 63 72 69 70 74 6f 72 20 6d 61 79  e descriptor may
1330: 20 62 65 20 63 6c 6f 73 65 64 0a 09 20 2a 2f 0a   be closed.. */.
1340: 09 66 64 20 3d 20 64 75 70 28 63 61 63 68 65 2d  .fd = dup(cache-
1350: 3e 66 64 29 3b 0a 09 69 66 20 28 66 64 20 3c 20  >fd);..if (fd < 
1360: 30 29 20 7b 0a 09 09 70 74 68 72 65 61 64 5f 6d  0) {...pthread_m
1370: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63  utex_unlock(&cac
1380: 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 72  he->mutex);....r
1390: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
13a0: 0a 09 62 75 66 66 65 72 2d 3e 66 64 20 3d 20 66  ..buffer->fd = f
13b0: 64 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 65 6e 20  d;..buffer->len 
13c0: 3d 20 63 61 63 68 65 2d 3e 6c 65 6e 3b 0a 09 62  = cache->len;..b
13d0: 75 66 66 65 72 2d 3e 74 79 70 65 20 3d 20 63 61  uffer->type = ca
13e0: 63 68 65 2d 3e 74 79 70 65 3b 0a 09 6d 65 6d 63  che->type;..memc
13f0: 70 79 28 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d  py(buffer->lastm
1400: 6f 64 5f 62 2c 20 63 61 63 68 65 2d 3e 6c 61 73  od_b, cache->las
1410: 74 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28 62  tmod_b, sizeof(b
1420: 75 66 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 5f 62  uffer->lastmod_b
1430: 29 29 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 61 73  ));..buffer->las
1440: 74 6d 6f 64 20 3d 20 62 75 66 66 65 72 2d 3e 6c  tmod = buffer->l
1450: 61 73 74 6d 6f 64 5f 62 20 2b 20 28 63 61 63 68  astmod_b + (cach
1460: 65 2d 3e 6c 61 73 74 6d 6f 64 20 2d 20 63 61 63  e->lastmod - cac
1470: 68 65 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 3b 0a  he->lastmod_b);.
1480: 0a 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  ..pthread_mutex_
1490: 75 6e 6c 6f 63 6b 28 26 63 61 63 68 65 2d 3e 6d  unlock(&cache->m
14a0: 75 74 65 78 29 3b 0a 0a 09 72 65 74 75 72 6e 28  utex);...return(
14b0: 62 75 66 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50  buffer);.}../* P
14c0: 72 6f 63 65 73 73 20 61 6e 20 48 54 54 50 20 72  rocess an HTTP r
14d0: 65 71 75 65 73 74 20 61 6e 64 20 72 65 74 75 72  equest and retur
14e0: 6e 20 74 68 65 20 70 61 74 68 20 72 65 71 75 65  n the path reque
14f0: 73 74 65 64 20 2a 2f 0a 73 74 61 74 69 63 20 63  sted */.static c
1500: 68 61 72 20 2a 66 69 6c 65 64 5f 67 65 74 5f 68  har *filed_get_h
1510: 74 74 70 5f 72 65 71 75 65 73 74 28 46 49 4c 45  ttp_request(FILE
1520: 20 2a 66 70 2c 20 63 68 61 72 20 2a 62 75 66 66   *fp, char *buff
1530: 65 72 2c 20 73 69 7a 65 5f 74 20 62 75 66 66 65  er, size_t buffe
1540: 72 5f 6c 65 6e 29 20 7b 0a 09 63 68 61 72 20 2a  r_len) {..char *
1550: 6d 65 74 68 6f 64 2c 20 2a 70 61 74 68 3b 0a 09  method, *path;..
1560: 63 68 61 72 20 74 6d 70 62 75 66 5b 31 30 31 30  char tmpbuf[1010
1570: 5d 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 66 69 6c  ];..int i;...fil
1580: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 57 41 49 54  ed_log_msg("WAIT
1590: 5f 46 4f 52 5f 52 45 51 55 45 53 54 20 46 44 3d  _FOR_REQUEST FD=
15a0: 2e 2e 2e 22 29 3b 0a 0a 09 66 67 65 74 73 28 62  ...");...fgets(b
15b0: 75 66 66 65 72 2c 20 62 75 66 66 65 72 5f 6c 65  uffer, buffer_le
15c0: 6e 2c 20 66 70 29 3b 0a 0a 09 6d 65 74 68 6f 64  n, fp);...method
15d0: 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09 62 75 66   = buffer;...buf
15e0: 66 65 72 20 3d 20 73 74 72 63 68 72 28 62 75 66  fer = strchr(buf
15f0: 66 65 72 2c 20 27 20 27 29 3b 0a 09 69 66 20 28  fer, ' ');..if (
1600: 62 75 66 66 65 72 20 3d 3d 20 4e 55 4c 4c 29 20  buffer == NULL) 
1610: 7b 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  {...filed_log_ms
1620: 67 28 22 47 4f 54 5f 52 45 51 55 45 53 54 20 46  g("GOT_REQUEST F
1630: 44 3d 2e 2e 2e 20 45 52 52 4f 52 3d 66 6f 72 6d  D=... ERROR=form
1640: 61 74 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  at");....return(
1650: 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2a 62 75 66  NULL);..}...*buf
1660: 66 65 72 20 3d 20 27 5c 30 27 3b 0a 09 62 75 66  fer = '\0';..buf
1670: 66 65 72 2b 2b 3b 0a 0a 09 70 61 74 68 20 3d 20  fer++;...path = 
1680: 62 75 66 66 65 72 3b 0a 0a 09 62 75 66 66 65 72  buffer;...buffer
1690: 20 3d 20 73 74 72 63 68 72 28 62 75 66 66 65 72   = strchr(buffer
16a0: 2c 20 27 20 27 29 3b 0a 09 69 66 20 28 62 75 66  , ' ');..if (buf
16b0: 66 65 72 20 21 3d 20 4e 55 4c 4c 29 20 7b 0a 09  fer != NULL) {..
16c0: 09 2a 62 75 66 66 65 72 20 3d 20 27 5c 30 27 3b  .*buffer = '\0';
16d0: 0a 09 09 62 75 66 66 65 72 2b 2b 3b 0a 09 7d 0a  ...buffer++;..}.
16e0: 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
16f0: 22 47 4f 54 5f 52 45 51 55 45 53 54 20 46 44 3d  "GOT_REQUEST FD=
1700: 2e 2e 2e 20 50 41 54 48 3d 2e 2e 2e 22 29 3b 0a  ... PATH=...");.
1710: 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
1720: 22 57 41 49 54 5f 46 4f 52 5f 48 45 41 44 45 52  "WAIT_FOR_HEADER
1730: 53 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 66 6f  S FD=...");...fo
1740: 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20 31 30  r (i = 0; i < 10
1750: 30 3b 20 69 2b 2b 29 20 7b 0a 09 09 66 67 65 74  0; i++) {...fget
1760: 73 28 74 6d 70 62 75 66 2c 20 73 69 7a 65 6f 66  s(tmpbuf, sizeof
1770: 28 74 6d 70 62 75 66 29 2c 20 66 70 29 3b 0a 09  (tmpbuf), fp);..
1780: 09 69 66 20 28 6d 65 6d 63 6d 70 28 74 6d 70 62  .if (memcmp(tmpb
1790: 75 66 2c 20 22 5c 72 5c 6e 22 2c 20 32 29 20 3d  uf, "\r\n", 2) =
17a0: 3d 20 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b  = 0) {....break;
17b0: 0a 09 09 7d 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f  ...}..}...filed_
17c0: 6c 6f 67 5f 6d 73 67 28 22 47 4f 54 5f 48 45 41  log_msg("GOT_HEA
17d0: 44 45 52 53 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a  DERS FD=...");..
17e0: 09 66 66 6c 75 73 68 28 66 70 29 3b 0a 0a 09 2f  .fflush(fp);.../
17f0: 2a 20 57 65 20 6f 6e 6c 79 20 68 61 6e 64 6c 65  * We only handle
1800: 20 74 68 65 20 22 47 45 54 22 20 6d 65 74 68 6f   the "GET" metho
1810: 64 20 2a 2f 0a 09 69 66 20 28 73 74 72 63 61 73  d */..if (strcas
1820: 65 63 6d 70 28 6d 65 74 68 6f 64 2c 20 22 67 65  ecmp(method, "ge
1830: 74 22 29 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  t") != 0) {...re
1840: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1850: 09 72 65 74 75 72 6e 28 70 61 74 68 29 3b 0a 7d  .return(path);.}
1860: 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 65  ../* Return an e
1870: 72 72 6f 72 20 70 61 67 65 20 2a 2f 0a 73 74 61  rror page */.sta
1880: 74 69 63 20 76 6f 69 64 20 66 69 6c 65 64 5f 65  tic void filed_e
1890: 72 72 6f 72 5f 70 61 67 65 28 46 49 4c 45 20 2a  rror_page(FILE *
18a0: 66 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  fp, const char *
18b0: 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 20 69 6e  date_current, in
18c0: 74 20 65 72 72 6f 72 5f 6e 75 6d 62 65 72 29 20  t error_number) 
18d0: 7b 0a 09 63 68 61 72 20 2a 65 72 72 6f 72 5f 73  {..char *error_s
18e0: 74 72 69 6e 67 20 3d 20 22 3c 68 74 6d 6c 3e 3c  tring = "<html><
18f0: 68 65 61 64 3e 3c 74 69 74 6c 65 3e 45 52 52 4f  head><title>ERRO
1900: 52 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 3e  R</title></head>
1910: 3c 62 6f 64 79 3e 55 6e 61 62 6c 65 20 74 6f 20  <body>Unable to 
1920: 70 72 6f 63 65 73 73 20 72 65 71 75 65 73 74 3c  process request<
1930: 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 22 3b 0a  /body></html>";.
1940: 0a 09 66 70 72 69 6e 74 66 28 66 70 2c 20 22 48  ..fprintf(fp, "H
1950: 54 54 50 2f 31 2e 31 20 25 69 20 4f 4b 5c 72 5c  TTP/1.1 %i OK\r\
1960: 6e 44 61 74 65 3a 20 25 73 5c 72 5c 6e 53 65 72  nDate: %s\r\nSer
1970: 76 65 72 3a 20 66 69 6c 65 64 5c 72 5c 6e 4c 61  ver: filed\r\nLa
1980: 73 74 2d 4d 6f 64 69 66 69 65 64 3a 20 25 73 5c  st-Modified: %s\
1990: 72 5c 6e 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67 74  r\nContent-Lengt
19a0: 68 3a 20 25 6c 6c 75 5c 72 5c 6e 43 6f 6e 74 65  h: %llu\r\nConte
19b0: 6e 74 2d 54 79 70 65 3a 20 25 73 5c 72 5c 6e 43  nt-Type: %s\r\nC
19c0: 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73 65  onnection: close
19d0: 5c 72 5c 6e 5c 72 5c 6e 25 73 22 2c 0a 09 09 65  \r\n\r\n%s",...e
19e0: 72 72 6f 72 5f 6e 75 6d 62 65 72 2c 0a 09 09 64  rror_number,...d
19f0: 61 74 65 5f 63 75 72 72 65 6e 74 2c 0a 09 09 64  ate_current,...d
1a00: 61 74 65 5f 63 75 72 72 65 6e 74 2c 0a 09 09 28  ate_current,...(
1a10: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
1a20: 6e 67 29 20 73 74 72 6c 65 6e 28 65 72 72 6f 72  ng) strlen(error
1a30: 5f 73 74 72 69 6e 67 29 2c 0a 09 09 22 74 65 78  _string),..."tex
1a40: 74 2f 68 74 6d 6c 22 2c 0a 09 09 65 72 72 6f 72  t/html",...error
1a50: 5f 73 74 72 69 6e 67 0a 09 29 3b 0a 7d 0a 0a 2f  _string..);.}../
1a60: 2a 20 48 61 6e 64 6c 65 20 61 20 73 69 6e 67 6c  * Handle a singl
1a70: 65 20 72 65 71 75 65 73 74 20 66 72 6f 6d 20 61  e request from a
1a80: 20 63 6c 69 65 6e 74 20 2a 2f 0a 73 74 61 74 69   client */.stati
1a90: 63 20 76 6f 69 64 20 66 69 6c 65 64 5f 68 61 6e  c void filed_han
1aa0: 64 6c 65 5f 63 6c 69 65 6e 74 28 69 6e 74 20 66  dle_client(int f
1ab0: 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66 69 6c  d) {..struct fil
1ac0: 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66 69 6c  ed_fileinfo *fil
1ad0: 65 69 6e 66 6f 2c 20 66 69 6c 65 69 6e 66 6f 5f  einfo, fileinfo_
1ae0: 62 3b 0a 09 73 73 69 7a 65 5f 74 20 73 65 6e 64  b;..ssize_t send
1af0: 66 69 6c 65 5f 72 65 74 3b 0a 09 73 69 7a 65 5f  file_ret;..size_
1b00: 74 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 3b 0a  t sendfile_len;.
1b10: 09 6f 66 66 5f 74 20 73 65 6e 64 66 69 6c 65 5f  .off_t sendfile_
1b20: 6f 66 66 73 65 74 3b 0a 09 63 68 61 72 20 2a 70  offset;..char *p
1b30: 61 74 68 2c 20 70 61 74 68 5f 62 5b 31 30 31 30  ath, path_b[1010
1b40: 5d 3b 0a 09 63 68 61 72 20 2a 64 61 74 65 5f 63  ];..char *date_c
1b50: 75 72 72 65 6e 74 2c 20 64 61 74 65 5f 63 75 72  urrent, date_cur
1b60: 72 65 6e 74 5f 62 5b 36 34 5d 3b 0a 09 46 49 4c  rent_b[64];..FIL
1b70: 45 20 2a 66 70 3b 0a 0a 09 2f 2a 20 44 65 74 65  E *fp;.../* Dete
1b80: 72 6d 69 6e 65 20 63 75 72 72 65 6e 74 20 74 69  rmine current ti
1b90: 6d 65 20 2a 2f 0a 09 64 61 74 65 5f 63 75 72 72  me */..date_curr
1ba0: 65 6e 74 20 3d 20 66 69 6c 65 64 5f 66 6f 72 6d  ent = filed_form
1bb0: 61 74 5f 74 69 6d 65 28 64 61 74 65 5f 63 75 72  at_time(date_cur
1bc0: 72 65 6e 74 5f 62 2c 20 73 69 7a 65 6f 66 28 64  rent_b, sizeof(d
1bd0: 61 74 65 5f 63 75 72 72 65 6e 74 5f 62 29 2c 20  ate_current_b), 
1be0: 74 69 6d 65 28 4e 55 4c 4c 29 29 3b 0a 0a 09 2f  time(NULL));.../
1bf0: 2a 20 4f 70 65 6e 20 73 6f 63 6b 65 74 20 61 73  * Open socket as
1c00: 20 41 4e 53 49 20 49 2f 4f 20 66 6f 72 20 65 61   ANSI I/O for ea
1c10: 73 65 20 6f 66 20 75 73 65 20 2a 2f 0a 09 66 70  se of use */..fp
1c20: 20 3d 20 66 64 6f 70 65 6e 28 66 64 2c 20 22 77   = fdopen(fd, "w
1c30: 2b 62 22 29 3b 0a 09 69 66 20 28 66 70 20 3d 3d  +b");..if (fp ==
1c40: 20 4e 55 4c 4c 29 20 7b 0a 09 09 63 6c 6f 73 65   NULL) {...close
1c50: 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b  (fd);....return;
1c60: 0a 09 7d 0a 0a 09 70 61 74 68 20 3d 20 66 69 6c  ..}...path = fil
1c70: 65 64 5f 67 65 74 5f 68 74 74 70 5f 72 65 71 75  ed_get_http_requ
1c80: 65 73 74 28 66 70 2c 20 70 61 74 68 5f 62 2c 20  est(fp, path_b, 
1c90: 73 69 7a 65 6f 66 28 70 61 74 68 5f 62 29 29 3b  sizeof(path_b));
1ca0: 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67  ...filed_log_msg
1cb0: 28 22 50 52 4f 43 45 53 53 5f 52 45 50 4c 59 5f  ("PROCESS_REPLY_
1cc0: 53 54 41 52 54 20 46 44 3d 2e 2e 2e 20 50 41 54  START FD=... PAT
1cd0: 48 3d 2e 2e 2e 22 29 3b 0a 0a 09 69 66 20 28 70  H=...");...if (p
1ce0: 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  ath == NULL) {..
1cf0: 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61 67  .filed_error_pag
1d00: 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72 72 65  e(fp, date_curre
1d10: 6e 74 2c 20 35 30 30 29 3b 0a 0a 09 09 66 69 6c  nt, 500);....fil
1d20: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f 43  ed_log_msg("PROC
1d30: 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 4c 45  ESS_REPLY_COMPLE
1d40: 54 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f 52 3d  TE FD=... ERROR=
1d50: 35 30 30 22 29 3b 0a 0a 09 09 66 63 6c 6f 73 65  500");....fclose
1d60: 28 66 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b  (fp);....return;
1d70: 0a 09 7d 0a 0a 09 66 69 6c 65 69 6e 66 6f 20 3d  ..}...fileinfo =
1d80: 20 66 69 6c 65 64 5f 6f 70 65 6e 5f 66 69 6c 65   filed_open_file
1d90: 28 70 61 74 68 2c 20 26 66 69 6c 65 69 6e 66 6f  (path, &fileinfo
1da0: 5f 62 29 3b 0a 09 69 66 20 28 66 69 6c 65 69 6e  _b);..if (filein
1db0: 66 6f 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  fo == NULL) {...
1dc0: 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61 67 65  filed_error_page
1dd0: 28 66 70 2c 20 64 61 74 65 5f 63 75 72 72 65 6e  (fp, date_curren
1de0: 74 2c 20 34 30 34 29 3b 0a 0a 09 09 66 69 6c 65  t, 404);....file
1df0: 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f 43 45  d_log_msg("PROCE
1e00: 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 4c 45 54  SS_REPLY_COMPLET
1e10: 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f 52 3d 34  E FD=... ERROR=4
1e20: 30 34 22 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a  04");..} else {.
1e30: 09 09 66 70 72 69 6e 74 66 28 66 70 2c 20 22 48  ..fprintf(fp, "H
1e40: 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b 5c 72  TTP/1.1 200 OK\r
1e50: 5c 6e 44 61 74 65 3a 20 25 73 5c 72 5c 6e 53 65  \nDate: %s\r\nSe
1e60: 72 76 65 72 3a 20 66 69 6c 65 64 5c 72 5c 6e 4c  rver: filed\r\nL
1e70: 61 73 74 2d 4d 6f 64 69 66 69 65 64 3a 20 25 73  ast-Modified: %s
1e80: 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 4c 65 6e 67  \r\nContent-Leng
1e90: 74 68 3a 20 25 6c 6c 75 5c 72 5c 6e 43 6f 6e 74  th: %llu\r\nCont
1ea0: 65 6e 74 2d 54 79 70 65 3a 20 25 73 5c 72 5c 6e  ent-Type: %s\r\n
1eb0: 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73  Connection: clos
1ec0: 65 5c 72 5c 6e 5c 72 5c 6e 22 2c 0a 09 09 09 64  e\r\n\r\n",....d
1ed0: 61 74 65 5f 63 75 72 72 65 6e 74 2c 0a 09 09 09  ate_current,....
1ee0: 66 69 6c 65 69 6e 66 6f 2d 3e 6c 61 73 74 6d 6f  fileinfo->lastmo
1ef0: 64 2c 0a 09 09 09 28 75 6e 73 69 67 6e 65 64 20  d,....(unsigned 
1f00: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 6c 65 69  long long) filei
1f10: 6e 66 6f 2d 3e 6c 65 6e 2c 0a 09 09 09 66 69 6c  nfo->len,....fil
1f20: 65 69 6e 66 6f 2d 3e 74 79 70 65 0a 09 09 29 3b  einfo->type...);
1f30: 0a 09 09 66 66 6c 75 73 68 28 66 70 29 3b 0a 0a  ...fflush(fp);..
1f40: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
1f50: 22 50 52 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43  "PROCESS_REPLY_C
1f60: 4f 4d 50 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 53  OMPLETE FD=... S
1f70: 54 41 54 55 53 3d 32 30 30 22 29 3b 0a 0a 09 09  TATUS=200");....
1f80: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 53  filed_log_msg("S
1f90: 45 4e 44 5f 53 54 41 52 54 20 49 46 44 3d 2e 2e  END_START IFD=..
1fa0: 2e 20 4f 46 44 3d 2e 2e 2e 20 42 59 54 45 53 3d  . OFD=... BYTES=
1fb0: 2e 2e 2e 22 29 3b 0a 0a 09 09 73 65 6e 64 66 69  ...");....sendfi
1fc0: 6c 65 5f 6f 66 66 73 65 74 20 3d 20 30 3b 0a 09  le_offset = 0;..
1fd0: 09 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 3d 20  .sendfile_len = 
1fe0: 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 3b 0a 09  fileinfo->len;..
1ff0: 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 09  .while (1) {....
2000: 73 65 6e 64 66 69 6c 65 5f 72 65 74 20 3d 20 73  sendfile_ret = s
2010: 65 6e 64 66 69 6c 65 28 66 64 2c 20 66 69 6c 65  endfile(fd, file
2020: 69 6e 66 6f 2d 3e 66 64 2c 20 26 73 65 6e 64 66  info->fd, &sendf
2030: 69 6c 65 5f 6f 66 66 73 65 74 2c 20 73 65 6e 64  ile_offset, send
2040: 66 69 6c 65 5f 6c 65 6e 29 3b 0a 09 09 09 69 66  file_len);....if
2050: 20 28 73 65 6e 64 66 69 6c 65 5f 72 65 74 20 3c   (sendfile_ret <
2060: 3d 20 30 29 20 7b 0a 09 09 09 09 62 72 65 61 6b  = 0) {.....break
2070: 3b 0a 09 09 09 7d 0a 0a 09 09 09 73 65 6e 64 66  ;....}.....sendf
2080: 69 6c 65 5f 6c 65 6e 20 2d 3d 20 73 65 6e 64 66  ile_len -= sendf
2090: 69 6c 65 5f 72 65 74 3b 0a 09 09 09 69 66 20 28  ile_ret;....if (
20a0: 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 3d 3d 20  sendfile_len == 
20b0: 30 29 20 7b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  0) {.....break;.
20c0: 09 09 09 7d 0a 09 09 7d 0a 0a 09 09 66 69 6c 65  ...}...}....file
20d0: 64 5f 6c 6f 67 5f 6d 73 67 28 22 53 45 4e 44 5f  d_log_msg("SEND_
20e0: 43 4f 4d 50 4c 45 54 45 20 53 54 41 54 55 53 3d  COMPLETE STATUS=
20f0: 2e 2e 2e 20 49 46 44 3d 2e 2e 2e 20 4f 46 44 3d  ... IFD=... OFD=
2100: 2e 2e 2e 20 42 59 54 45 53 3d 2e 2e 2e 20 42 59  ... BYTES=... BY
2110: 54 45 53 5f 53 45 4e 54 3d 2e 2e 2e 22 29 3b 0a  TES_SENT=...");.
2120: 0a 09 09 63 6c 6f 73 65 28 66 69 6c 65 69 6e 66  ...close(fileinf
2130: 6f 2d 3e 66 64 29 3b 0a 0a 09 09 66 69 6c 65 64  o->fd);....filed
2140: 5f 6c 6f 67 5f 6d 73 67 28 22 43 4c 4f 53 45 5f  _log_msg("CLOSE_
2150: 46 49 4c 45 20 46 44 3d 2e 2e 2e 22 29 3b 0a 09  FILE FD=...");..
2160: 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  }...filed_log_ms
2170: 67 28 22 43 4c 4f 53 45 5f 43 4f 4e 4e 45 43 54  g("CLOSE_CONNECT
2180: 49 4f 4e 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09  ION FD=...");...
2190: 66 63 6c 6f 73 65 28 66 70 29 3b 0a 0a 09 72 65  fclose(fp);...re
21a0: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e 64  turn;.}../* Hand
21b0: 6c 65 20 69 6e 63 6f 6d 69 6e 67 20 63 6f 6e 6e  le incoming conn
21c0: 65 63 74 69 6f 6e 73 20 2a 2f 0a 73 74 61 74 69  ections */.stati
21d0: 63 20 76 6f 69 64 20 2a 66 69 6c 65 64 5f 77 6f  c void *filed_wo
21e0: 72 6b 65 72 5f 74 68 72 65 61 64 28 76 6f 69 64  rker_thread(void
21f0: 20 2a 61 72 67 5f 76 29 20 7b 0a 09 73 74 72 75   *arg_v) {..stru
2200: 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f  ct filed_worker_
2210: 74 68 72 65 61 64 5f 61 72 67 73 20 2a 61 72 67  thread_args *arg
2220: 3b 0a 09 73 74 72 75 63 74 20 73 6f 63 6b 61 64  ;..struct sockad
2230: 64 72 5f 69 6e 36 20 61 64 64 72 3b 0a 09 73 6f  dr_in6 addr;..so
2240: 63 6b 6c 65 6e 5f 74 20 61 64 64 72 6c 65 6e 3b  cklen_t addrlen;
2250: 0a 09 69 6e 74 20 66 61 69 6c 75 72 65 5f 63 6f  ..int failure_co
2260: 75 6e 74 20 3d 20 30 2c 20 6d 61 78 5f 66 61 69  unt = 0, max_fai
2270: 6c 75 72 65 5f 63 6f 75 6e 74 20 3d 20 4d 41 58  lure_count = MAX
2280: 5f 46 41 49 4c 55 52 45 5f 43 4f 55 4e 54 3b 0a  _FAILURE_COUNT;.
2290: 09 69 6e 74 20 6d 61 73 74 65 72 5f 66 64 2c 20  .int master_fd, 
22a0: 66 64 3b 0a 0a 09 2f 2a 20 52 65 61 64 20 61 72  fd;.../* Read ar
22b0: 67 75 6d 65 6e 74 73 20 2a 2f 0a 09 61 72 67 20  guments */..arg 
22c0: 3d 20 61 72 67 5f 76 3b 0a 0a 09 6d 61 73 74 65  = arg_v;...maste
22d0: 72 5f 66 64 20 3d 20 61 72 67 2d 3e 66 64 3b 0a  r_fd = arg->fd;.
22e0: 0a 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09  ..while (1) {...
22f0: 2f 2a 20 46 61 69 6c 75 72 65 20 6c 6f 6f 70 20  /* Failure loop 
2300: 70 72 65 76 65 6e 74 69 6f 6e 20 2a 2f 0a 09 09  prevention */...
2310: 69 66 20 28 66 61 69 6c 75 72 65 5f 63 6f 75 6e  if (failure_coun
2320: 74 20 3e 20 6d 61 78 5f 66 61 69 6c 75 72 65 5f  t > max_failure_
2330: 63 6f 75 6e 74 29 20 7b 0a 09 09 09 62 72 65 61  count) {....brea
2340: 6b 3b 0a 09 09 7d 0a 0a 09 09 2f 2a 20 41 63 63  k;...}..../* Acc
2350: 65 70 74 20 61 20 6e 65 77 20 63 6c 69 65 6e 74  ept a new client
2360: 20 2a 2f 0a 09 09 61 64 64 72 6c 65 6e 20 3d 20   */...addrlen = 
2370: 73 69 7a 65 6f 66 28 61 64 64 72 29 3b 0a 09 09  sizeof(addr);...
2380: 66 64 20 3d 20 61 63 63 65 70 74 28 6d 61 73 74  fd = accept(mast
2390: 65 72 5f 66 64 2c 20 28 73 74 72 75 63 74 20 73  er_fd, (struct s
23a0: 6f 63 6b 61 64 64 72 20 2a 29 20 26 61 64 64 72  ockaddr *) &addr
23b0: 2c 20 26 61 64 64 72 6c 65 6e 29 3b 0a 0a 09 09  , &addrlen);....
23c0: 2f 2a 0a 09 09 20 2a 20 49 66 20 77 65 20 66 61  /*... * If we fa
23d0: 69 6c 2c 20 6d 61 6b 65 20 61 20 6e 6f 74 65 20  il, make a note 
23e0: 6f 66 20 69 74 20 73 6f 20 77 65 20 64 6f 6e 27  of it so we don'
23f0: 74 20 67 6f 20 69 6e 74 6f 20 61 20 6c 6f 6f 70  t go into a loop
2400: 20 6f 66 0a 09 09 20 2a 20 61 63 63 65 70 74 28   of... * accept(
2410: 29 20 66 61 69 6c 69 6e 67 0a 09 09 20 2a 2f 0a  ) failing... */.
2420: 09 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b 0a  ..if (fd < 0) {.
2430: 09 09 09 2f 2a 20 4c 6f 67 20 74 68 65 20 6e 65  .../* Log the ne
2440: 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  w connection */.
2450: 09 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67  ...filed_log_msg
2460: 28 22 41 43 43 45 50 54 5f 46 41 49 4c 45 44 22  ("ACCEPT_FAILED"
2470: 29 3b 0a 0a 09 09 09 66 61 69 6c 75 72 65 5f 63  );.....failure_c
2480: 6f 75 6e 74 2b 2b 3b 0a 0a 09 09 09 63 6f 6e 74  ount++;.....cont
2490: 69 6e 75 65 3b 0a 09 09 7d 0a 0a 09 09 2f 2a 20  inue;...}..../* 
24a0: 4c 6f 67 20 74 68 65 20 6e 65 77 20 63 6f 6e 6e  Log the new conn
24b0: 65 63 74 69 6f 6e 20 2a 2f 0a 09 09 66 69 6c 65  ection */...file
24c0: 64 5f 6c 6f 67 5f 6d 73 67 28 22 4e 45 57 5f 43  d_log_msg("NEW_C
24d0: 4f 4e 4e 45 43 54 49 4f 4e 20 53 52 43 5f 41 44  ONNECTION SRC_AD
24e0: 44 52 3d 2e 2e 2e 20 53 52 43 5f 50 4f 52 54 3d  DR=... SRC_PORT=
24f0: 2e 2e 2e 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09  ... FD=...");...
2500: 09 2f 2a 20 52 65 73 65 74 20 66 61 69 6c 75 72  ./* Reset failur
2510: 65 20 63 6f 75 6e 74 2a 2f 0a 09 09 66 61 69 6c  e count*/...fail
2520: 75 72 65 5f 63 6f 75 6e 74 20 3d 20 30 3b 0a 0a  ure_count = 0;..
2530: 09 09 2f 2a 20 48 61 6e 64 6c 65 20 73 6f 63 6b  ../* Handle sock
2540: 65 74 20 2a 2f 0a 09 09 66 69 6c 65 64 5f 68 61  et */...filed_ha
2550: 6e 64 6c 65 5f 63 6c 69 65 6e 74 28 66 64 29 3b  ndle_client(fd);
2560: 0a 09 7d 0a 0a 09 2f 2a 20 52 65 70 6f 72 74 20  ..}.../* Report 
2570: 65 72 72 6f 72 20 2a 2f 0a 09 66 69 6c 65 64 5f  error */..filed_
2580: 6c 6f 67 5f 6d 73 67 28 22 54 48 52 45 41 44 5f  log_msg("THREAD_
2590: 44 49 45 44 20 41 42 4e 4f 52 4d 41 4c 22 29 3b  DIED ABNORMAL");
25a0: 0a 0a 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
25b0: 0a 7d 0a 0a 2f 2a 20 43 72 65 61 74 65 20 77 6f  .}../* Create wo
25c0: 72 6b 65 72 20 74 68 72 65 61 64 73 20 2a 2f 0a  rker threads */.
25d0: 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64  static int filed
25e0: 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 73 5f  _worker_threads_
25f0: 69 6e 69 74 28 69 6e 74 20 66 64 2c 20 69 6e 74  init(int fd, int
2600: 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 29 20 7b   thread_count) {
2610: 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f 77  ..struct filed_w
2620: 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f 61 72 67  orker_thread_arg
2630: 73 20 2a 61 72 67 3b 0a 09 70 74 68 72 65 61 64  s *arg;..pthread
2640: 5f 74 20 74 68 72 65 61 64 69 64 3b 0a 09 69 6e  _t threadid;..in
2650: 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 09  t pthread_ret;..
2660: 69 6e 74 20 69 3b 0a 0a 09 66 6f 72 20 28 69 20  int i;...for (i 
2670: 3d 20 30 3b 20 69 20 3c 20 74 68 72 65 61 64 5f  = 0; i < thread_
2680: 63 6f 75 6e 74 3b 20 69 2b 2b 29 20 7b 0a 09 09  count; i++) {...
2690: 61 72 67 20 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a  arg = malloc(siz
26a0: 65 6f 66 28 2a 61 72 67 29 29 3b 0a 0a 09 09 61  eof(*arg));....a
26b0: 72 67 2d 3e 66 64 20 3d 20 66 64 3b 0a 0a 09 09  rg->fd = fd;....
26c0: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
26d0: 68 72 65 61 64 5f 63 72 65 61 74 65 28 26 74 68  hread_create(&th
26e0: 72 65 61 64 69 64 2c 20 4e 55 4c 4c 2c 20 66 69  readid, NULL, fi
26f0: 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61  led_worker_threa
2700: 64 2c 20 61 72 67 29 3b 0a 09 09 69 66 20 28 70  d, arg);...if (p
2710: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
2720: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d 31 29   {....return(-1)
2730: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72  ;...}..}...retur
2740: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 52 75 6e 20  n(0);.}../* Run 
2750: 70 72 6f 63 65 73 73 20 2a 2f 0a 69 6e 74 20 6d  process */.int m
2760: 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68  ain(int argc, ch
2770: 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09 69 6e  ar **argv) {..in
2780: 74 20 70 6f 72 74 20 3d 20 50 4f 52 54 2c 20 74  t port = PORT, t
2790: 68 72 65 61 64 5f 63 6f 75 6e 74 20 3d 20 54 48  hread_count = TH
27a0: 52 45 41 44 5f 43 4f 55 4e 54 3b 0a 09 63 6f 6e  READ_COUNT;..con
27b0: 73 74 20 63 68 61 72 20 2a 62 69 6e 64 5f 61 64  st char *bind_ad
27c0: 64 72 20 3d 20 42 49 4e 44 5f 41 44 44 52 3b 0a  dr = BIND_ADDR;.
27d0: 09 69 6e 74 20 69 6e 69 74 5f 72 65 74 3b 0a 09  .int init_ret;..
27e0: 69 6e 74 20 66 64 3b 0a 0a 09 2f 2a 20 58 58 58  int fd;.../* XXX
27f0: 3a 20 54 4f 44 4f 3a 20 50 72 6f 63 65 73 73 20  : TODO: Process 
2800: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 09 61 72  arguments */..ar
2810: 67 63 20 3d 20 61 72 67 63 3b 0a 09 61 72 67 76  gc = argc;..argv
2820: 20 3d 20 61 72 67 76 3b 0a 0a 09 2f 2a 20 43 72   = argv;.../* Cr
2830: 65 61 74 65 20 6c 69 73 74 65 6e 69 6e 67 20 73  eate listening s
2840: 6f 63 6b 65 74 20 2a 2f 0a 09 66 64 20 3d 20 66  ocket */..fd = f
2850: 69 6c 65 64 5f 6c 69 73 74 65 6e 28 62 69 6e 64  iled_listen(bind
2860: 5f 61 64 64 72 2c 20 70 6f 72 74 29 3b 0a 09 69  _addr, port);..i
2870: 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 70  f (fd < 0) {...p
2880: 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 6c 69 73  error("filed_lis
2890: 74 65 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  ten");....return
28a0: 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 42 65 63  (1);..}.../* Bec
28b0: 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 20 2a 2f 0a  ome a daemon */.
28c0: 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 42 65  ./* XXX:TODO: Be
28d0: 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 20 2a 2f  come a daemon */
28e0: 0a 0a 09 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65  .../* Initialize
28f0: 20 2a 2f 0a 09 69 6e 69 74 5f 72 65 74 20 3d 20   */..init_ret = 
2900: 66 69 6c 65 64 5f 69 6e 69 74 28 29 3b 0a 09 69  filed_init();..i
2910: 66 20 28 69 6e 69 74 5f 72 65 74 20 21 3d 20 30  f (init_ret != 0
2920: 29 20 7b 0a 09 09 70 65 72 72 6f 72 28 22 66 69  ) {...perror("fi
2930: 6c 65 64 5f 69 6e 69 74 22 29 3b 0a 0a 09 09 72  led_init");....r
2940: 65 74 75 72 6e 28 33 29 3b 0a 09 7d 0a 0a 09 2f  eturn(3);..}.../
2950: 2a 20 43 72 65 61 74 65 20 6c 6f 67 67 69 6e 67  * Create logging
2960: 20 74 68 72 65 61 64 20 2a 2f 0a 09 69 6e 69 74   thread */..init
2970: 5f 72 65 74 20 3d 20 66 69 6c 65 64 5f 6c 6f 67  _ret = filed_log
2980: 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e 69 74  ging_thread_init
2990: 28 29 3b 0a 09 69 66 20 28 69 6e 69 74 5f 72 65  ();..if (init_re
29a0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 70 65 72 72  t != 0) {...perr
29b0: 6f 72 28 22 66 69 6c 65 64 5f 6c 6f 67 67 69 6e  or("filed_loggin
29c0: 67 5f 74 68 72 65 61 64 5f 69 6e 69 74 22 29 3b  g_thread_init");
29d0: 0a 0a 09 09 72 65 74 75 72 6e 28 34 29 3b 0a 09  ....return(4);..
29e0: 7d 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20 77 6f  }.../* Create wo
29f0: 72 6b 65 72 20 74 68 72 65 61 64 73 20 2a 2f 0a  rker threads */.
2a00: 09 69 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65  .init_ret = file
2a10: 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 73  d_worker_threads
2a20: 5f 69 6e 69 74 28 66 64 2c 20 74 68 72 65 61 64  _init(fd, thread
2a30: 5f 63 6f 75 6e 74 29 3b 0a 09 69 66 20 28 69 6e  _count);..if (in
2a40: 69 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  it_ret != 0) {..
2a50: 09 70 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 77  .perror("filed_w
2a60: 6f 72 6b 65 72 5f 74 68 72 65 61 64 73 5f 69 6e  orker_threads_in
2a70: 69 74 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  it");....return(
2a80: 34 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 57 61 69 74  4);..}.../* Wait
2a90: 20 66 6f 72 20 74 68 72 65 61 64 73 20 74 6f 20   for threads to 
2aa0: 65 78 69 74 20 2a 2f 0a 09 2f 2a 20 58 58 58 3a  exit */../* XXX:
2ab0: 54 4f 44 4f 3a 20 4d 6f 6e 69 74 6f 72 20 74 68  TODO: Monitor th
2ac0: 72 65 61 64 20 75 73 61 67 65 20 2a 2f 0a 09 77  read usage */..w
2ad0: 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 73 6c 65  hile (1) {...sle
2ae0: 65 70 28 36 30 29 3b 0a 09 7d 0a 0a 09 2f 2a 20  ep(60);..}.../* 
2af0: 52 65 74 75 72 6e 20 69 6e 20 66 61 69 6c 75 72  Return in failur
2b00: 65 20 2a 2f 0a 09 72 65 74 75 72 6e 28 32 29 3b  e */..return(2);
2b10: 0a 7d 0a                                         .}.