Hex Artifact Content

Artifact de3f48af844fa5c6363f6ffb3116bacc42ef71e6:


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 2f 2a 20 57 65 20 6f 6e 6c 79 20 68 61 6e 64  ./* We only hand
17f0: 6c 65 20 74 68 65 20 22 47 45 54 22 20 6d 65 74  le the "GET" met
1800: 68 6f 64 20 2a 2f 0a 09 69 66 20 28 73 74 72 63  hod */..if (strc
1810: 61 73 65 63 6d 70 28 6d 65 74 68 6f 64 2c 20 22  asecmp(method, "
1820: 67 65 74 22 29 20 21 3d 20 30 29 20 7b 0a 09 09  get") != 0) {...
1830: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
1840: 0a 0a 09 72 65 74 75 72 6e 28 70 61 74 68 29 3b  ...return(path);
1850: 0a 7d 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 6e  .}../* Return an
1860: 20 65 72 72 6f 72 20 70 61 67 65 20 2a 2f 0a 73   error page */.s
1870: 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c 65 64  tatic void filed
1880: 5f 65 72 72 6f 72 5f 70 61 67 65 28 46 49 4c 45  _error_page(FILE
1890: 20 2a 66 70 2c 20 63 6f 6e 73 74 20 63 68 61 72   *fp, const char
18a0: 20 2a 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 20   *date_current, 
18b0: 69 6e 74 20 65 72 72 6f 72 5f 6e 75 6d 62 65 72  int error_number
18c0: 29 20 7b 0a 09 63 68 61 72 20 2a 65 72 72 6f 72  ) {..char *error
18d0: 5f 73 74 72 69 6e 67 20 3d 20 22 3c 68 74 6d 6c  _string = "<html
18e0: 3e 3c 68 65 61 64 3e 3c 74 69 74 6c 65 3e 45 52  ><head><title>ER
18f0: 52 4f 52 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61  ROR</title></hea
1900: 64 3e 3c 62 6f 64 79 3e 55 6e 61 62 6c 65 20 74  d><body>Unable t
1910: 6f 20 70 72 6f 63 65 73 73 20 72 65 71 75 65 73  o process reques
1920: 74 3c 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 22  t</body></html>"
1930: 3b 0a 0a 09 66 70 72 69 6e 74 66 28 66 70 2c 20  ;...fprintf(fp, 
1940: 22 48 54 54 50 2f 31 2e 31 20 25 69 20 4f 4b 5c  "HTTP/1.1 %i OK\
1950: 72 5c 6e 44 61 74 65 3a 20 25 73 5c 72 5c 6e 53  r\nDate: %s\r\nS
1960: 65 72 76 65 72 3a 20 66 69 6c 65 64 5c 72 5c 6e  erver: filed\r\n
1970: 4c 61 73 74 2d 4d 6f 64 69 66 69 65 64 3a 20 25  Last-Modified: %
1980: 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 4c 65 6e  s\r\nContent-Len
1990: 67 74 68 3a 20 25 6c 6c 75 5c 72 5c 6e 43 6f 6e  gth: %llu\r\nCon
19a0: 74 65 6e 74 2d 54 79 70 65 3a 20 25 73 5c 72 5c  tent-Type: %s\r\
19b0: 6e 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f  nConnection: clo
19c0: 73 65 5c 72 5c 6e 5c 72 5c 6e 25 73 22 2c 0a 09  se\r\n\r\n%s",..
19d0: 09 65 72 72 6f 72 5f 6e 75 6d 62 65 72 2c 0a 09  .error_number,..
19e0: 09 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 0a 09  .date_current,..
19f0: 09 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 0a 09  .date_current,..
1a00: 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20  .(unsigned long 
1a10: 6c 6f 6e 67 29 20 73 74 72 6c 65 6e 28 65 72 72  long) strlen(err
1a20: 6f 72 5f 73 74 72 69 6e 67 29 2c 0a 09 09 22 74  or_string),..."t
1a30: 65 78 74 2f 68 74 6d 6c 22 2c 0a 09 09 65 72 72  ext/html",...err
1a40: 6f 72 5f 73 74 72 69 6e 67 0a 09 29 3b 0a 7d 0a  or_string..);.}.
1a50: 0a 2f 2a 20 48 61 6e 64 6c 65 20 61 20 73 69 6e  ./* Handle a sin
1a60: 67 6c 65 20 72 65 71 75 65 73 74 20 66 72 6f 6d  gle request from
1a70: 20 61 20 63 6c 69 65 6e 74 20 2a 2f 0a 73 74 61   a client */.sta
1a80: 74 69 63 20 76 6f 69 64 20 66 69 6c 65 64 5f 68  tic void filed_h
1a90: 61 6e 64 6c 65 5f 63 6c 69 65 6e 74 28 69 6e 74  andle_client(int
1aa0: 20 66 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66   fd) {..struct f
1ab0: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66  iled_fileinfo *f
1ac0: 69 6c 65 69 6e 66 6f 2c 20 66 69 6c 65 69 6e 66  ileinfo, fileinf
1ad0: 6f 5f 62 3b 0a 09 73 73 69 7a 65 5f 74 20 73 65  o_b;..ssize_t se
1ae0: 6e 64 66 69 6c 65 5f 72 65 74 3b 0a 09 73 69 7a  ndfile_ret;..siz
1af0: 65 5f 74 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e  e_t sendfile_len
1b00: 3b 0a 09 6f 66 66 5f 74 20 73 65 6e 64 66 69 6c  ;..off_t sendfil
1b10: 65 5f 6f 66 66 73 65 74 3b 0a 09 63 68 61 72 20  e_offset;..char 
1b20: 2a 70 61 74 68 2c 20 70 61 74 68 5f 62 5b 31 30  *path, path_b[10
1b30: 31 30 5d 3b 0a 09 63 68 61 72 20 2a 64 61 74 65  10];..char *date
1b40: 5f 63 75 72 72 65 6e 74 2c 20 64 61 74 65 5f 63  _current, date_c
1b50: 75 72 72 65 6e 74 5f 62 5b 36 34 5d 3b 0a 09 46  urrent_b[64];..F
1b60: 49 4c 45 20 2a 66 70 3b 0a 0a 09 2f 2a 20 44 65  ILE *fp;.../* De
1b70: 74 65 72 6d 69 6e 65 20 63 75 72 72 65 6e 74 20  termine current 
1b80: 74 69 6d 65 20 2a 2f 0a 09 64 61 74 65 5f 63 75  time */..date_cu
1b90: 72 72 65 6e 74 20 3d 20 66 69 6c 65 64 5f 66 6f  rrent = filed_fo
1ba0: 72 6d 61 74 5f 74 69 6d 65 28 64 61 74 65 5f 63  rmat_time(date_c
1bb0: 75 72 72 65 6e 74 5f 62 2c 20 73 69 7a 65 6f 66  urrent_b, sizeof
1bc0: 28 64 61 74 65 5f 63 75 72 72 65 6e 74 5f 62 29  (date_current_b)
1bd0: 2c 20 74 69 6d 65 28 4e 55 4c 4c 29 29 3b 0a 0a  , time(NULL));..
1be0: 09 2f 2a 20 4f 70 65 6e 20 73 6f 63 6b 65 74 20  ./* Open socket 
1bf0: 61 73 20 41 4e 53 49 20 49 2f 4f 20 66 6f 72 20  as ANSI I/O for 
1c00: 65 61 73 65 20 6f 66 20 75 73 65 20 2a 2f 0a 09  ease of use */..
1c10: 66 70 20 3d 20 66 64 6f 70 65 6e 28 66 64 2c 20  fp = fdopen(fd, 
1c20: 22 77 2b 62 22 29 3b 0a 09 69 66 20 28 66 70 20  "w+b");..if (fp 
1c30: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 63 6c 6f  == NULL) {...clo
1c40: 73 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72  se(fd);....retur
1c50: 6e 3b 0a 09 7d 0a 0a 09 70 61 74 68 20 3d 20 66  n;..}...path = f
1c60: 69 6c 65 64 5f 67 65 74 5f 68 74 74 70 5f 72 65  iled_get_http_re
1c70: 71 75 65 73 74 28 66 70 2c 20 70 61 74 68 5f 62  quest(fp, path_b
1c80: 2c 20 73 69 7a 65 6f 66 28 70 61 74 68 5f 62 29  , sizeof(path_b)
1c90: 29 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d  );...filed_log_m
1ca0: 73 67 28 22 50 52 4f 43 45 53 53 5f 52 45 50 4c  sg("PROCESS_REPL
1cb0: 59 5f 53 54 41 52 54 20 46 44 3d 2e 2e 2e 20 50  Y_START FD=... P
1cc0: 41 54 48 3d 2e 2e 2e 22 29 3b 0a 0a 09 69 66 20  ATH=...");...if 
1cd0: 28 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  (path == NULL) {
1ce0: 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70  ...filed_error_p
1cf0: 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72  age(fp, date_cur
1d00: 72 65 6e 74 2c 20 35 30 30 29 3b 0a 0a 09 09 66  rent, 500);....f
1d10: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52  iled_log_msg("PR
1d20: 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50  OCESS_REPLY_COMP
1d30: 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f  LETE FD=... ERRO
1d40: 52 3d 35 30 30 22 29 3b 0a 0a 09 09 66 63 6c 6f  R=500");....fclo
1d50: 73 65 28 66 70 29 3b 0a 0a 09 09 72 65 74 75 72  se(fp);....retur
1d60: 6e 3b 0a 09 7d 0a 0a 09 66 69 6c 65 69 6e 66 6f  n;..}...fileinfo
1d70: 20 3d 20 66 69 6c 65 64 5f 6f 70 65 6e 5f 66 69   = filed_open_fi
1d80: 6c 65 28 70 61 74 68 2c 20 26 66 69 6c 65 69 6e  le(path, &filein
1d90: 66 6f 5f 62 29 3b 0a 09 69 66 20 28 66 69 6c 65  fo_b);..if (file
1da0: 69 6e 66 6f 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  info == NULL) {.
1db0: 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61  ..filed_error_pa
1dc0: 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72 72  ge(fp, date_curr
1dd0: 65 6e 74 2c 20 34 30 34 29 3b 0a 0a 09 09 66 69  ent, 404);....fi
1de0: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f  led_log_msg("PRO
1df0: 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 4c  CESS_REPLY_COMPL
1e00: 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f 52  ETE FD=... ERROR
1e10: 3d 34 30 34 22 29 3b 0a 09 7d 20 65 6c 73 65 20  =404");..} else 
1e20: 7b 0a 09 09 66 70 72 69 6e 74 66 28 66 70 2c 20  {...fprintf(fp, 
1e30: 22 48 54 54 50 2f 31 2e 31 20 32 30 30 20 4f 4b  "HTTP/1.1 200 OK
1e40: 5c 72 5c 6e 44 61 74 65 3a 20 25 73 5c 72 5c 6e  \r\nDate: %s\r\n
1e50: 53 65 72 76 65 72 3a 20 66 69 6c 65 64 5c 72 5c  Server: filed\r\
1e60: 6e 4c 61 73 74 2d 4d 6f 64 69 66 69 65 64 3a 20  nLast-Modified: 
1e70: 25 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 4c 65  %s\r\nContent-Le
1e80: 6e 67 74 68 3a 20 25 6c 6c 75 5c 72 5c 6e 43 6f  ngth: %llu\r\nCo
1e90: 6e 74 65 6e 74 2d 54 79 70 65 3a 20 25 73 5c 72  ntent-Type: %s\r
1ea0: 5c 6e 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c  \nConnection: cl
1eb0: 6f 73 65 5c 72 5c 6e 5c 72 5c 6e 22 2c 0a 09 09  ose\r\n\r\n",...
1ec0: 09 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 0a 09  .date_current,..
1ed0: 09 09 66 69 6c 65 69 6e 66 6f 2d 3e 6c 61 73 74  ..fileinfo->last
1ee0: 6d 6f 64 2c 0a 09 09 09 28 75 6e 73 69 67 6e 65  mod,....(unsigne
1ef0: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 6c  d long long) fil
1f00: 65 69 6e 66 6f 2d 3e 6c 65 6e 2c 0a 09 09 09 66  einfo->len,....f
1f10: 69 6c 65 69 6e 66 6f 2d 3e 74 79 70 65 0a 09 09  ileinfo->type...
1f20: 29 3b 0a 09 09 66 66 6c 75 73 68 28 66 70 29 3b  );...fflush(fp);
1f30: 0a 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  ....filed_log_ms
1f40: 67 28 22 50 52 4f 43 45 53 53 5f 52 45 50 4c 59  g("PROCESS_REPLY
1f50: 5f 43 4f 4d 50 4c 45 54 45 20 46 44 3d 2e 2e 2e  _COMPLETE FD=...
1f60: 20 53 54 41 54 55 53 3d 32 30 30 22 29 3b 0a 0a   STATUS=200");..
1f70: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
1f80: 22 53 45 4e 44 5f 53 54 41 52 54 20 49 46 44 3d  "SEND_START IFD=
1f90: 2e 2e 2e 20 4f 46 44 3d 2e 2e 2e 20 42 59 54 45  ... OFD=... BYTE
1fa0: 53 3d 2e 2e 2e 22 29 3b 0a 0a 09 09 73 65 6e 64  S=...");....send
1fb0: 66 69 6c 65 5f 6f 66 66 73 65 74 20 3d 20 30 3b  file_offset = 0;
1fc0: 0a 09 09 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20  ...sendfile_len 
1fd0: 3d 20 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 3b  = fileinfo->len;
1fe0: 0a 09 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09  ...while (1) {..
1ff0: 09 09 73 65 6e 64 66 69 6c 65 5f 72 65 74 20 3d  ..sendfile_ret =
2000: 20 73 65 6e 64 66 69 6c 65 28 66 64 2c 20 66 69   sendfile(fd, fi
2010: 6c 65 69 6e 66 6f 2d 3e 66 64 2c 20 26 73 65 6e  leinfo->fd, &sen
2020: 64 66 69 6c 65 5f 6f 66 66 73 65 74 2c 20 73 65  dfile_offset, se
2030: 6e 64 66 69 6c 65 5f 6c 65 6e 29 3b 0a 09 09 09  ndfile_len);....
2040: 69 66 20 28 73 65 6e 64 66 69 6c 65 5f 72 65 74  if (sendfile_ret
2050: 20 3c 3d 20 30 29 20 7b 0a 09 09 09 09 62 72 65   <= 0) {.....bre
2060: 61 6b 3b 0a 09 09 09 7d 0a 0a 09 09 09 73 65 6e  ak;....}.....sen
2070: 64 66 69 6c 65 5f 6c 65 6e 20 2d 3d 20 73 65 6e  dfile_len -= sen
2080: 64 66 69 6c 65 5f 72 65 74 3b 0a 09 09 09 69 66  dfile_ret;....if
2090: 20 28 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 3d   (sendfile_len =
20a0: 3d 20 30 29 20 7b 0a 09 09 09 09 62 72 65 61 6b  = 0) {.....break
20b0: 3b 0a 09 09 09 7d 0a 09 09 7d 0a 0a 09 09 66 69  ;....}...}....fi
20c0: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 53 45 4e  led_log_msg("SEN
20d0: 44 5f 43 4f 4d 50 4c 45 54 45 20 53 54 41 54 55  D_COMPLETE STATU
20e0: 53 3d 2e 2e 2e 20 49 46 44 3d 2e 2e 2e 20 4f 46  S=... IFD=... OF
20f0: 44 3d 2e 2e 2e 20 42 59 54 45 53 3d 2e 2e 2e 20  D=... BYTES=... 
2100: 42 59 54 45 53 5f 53 45 4e 54 3d 2e 2e 2e 22 29  BYTES_SENT=...")
2110: 3b 0a 0a 09 09 63 6c 6f 73 65 28 66 69 6c 65 69  ;....close(filei
2120: 6e 66 6f 2d 3e 66 64 29 3b 0a 0a 09 09 66 69 6c  nfo->fd);....fil
2130: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 43 4c 4f 53  ed_log_msg("CLOS
2140: 45 5f 46 49 4c 45 20 46 44 3d 2e 2e 2e 22 29 3b  E_FILE FD=...");
2150: 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f  ..}...filed_log_
2160: 6d 73 67 28 22 43 4c 4f 53 45 5f 43 4f 4e 4e 45  msg("CLOSE_CONNE
2170: 43 54 49 4f 4e 20 46 44 3d 2e 2e 2e 22 29 3b 0a  CTION FD=...");.
2180: 0a 09 66 63 6c 6f 73 65 28 66 70 29 3b 0a 0a 09  ..fclose(fp);...
2190: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 48 61  return;.}../* Ha
21a0: 6e 64 6c 65 20 69 6e 63 6f 6d 69 6e 67 20 63 6f  ndle incoming co
21b0: 6e 6e 65 63 74 69 6f 6e 73 20 2a 2f 0a 73 74 61  nnections */.sta
21c0: 74 69 63 20 76 6f 69 64 20 2a 66 69 6c 65 64 5f  tic void *filed_
21d0: 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 28 76 6f  worker_thread(vo
21e0: 69 64 20 2a 61 72 67 5f 76 29 20 7b 0a 09 73 74  id *arg_v) {..st
21f0: 72 75 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65  ruct filed_worke
2200: 72 5f 74 68 72 65 61 64 5f 61 72 67 73 20 2a 61  r_thread_args *a
2210: 72 67 3b 0a 09 73 74 72 75 63 74 20 73 6f 63 6b  rg;..struct sock
2220: 61 64 64 72 5f 69 6e 36 20 61 64 64 72 3b 0a 09  addr_in6 addr;..
2230: 73 6f 63 6b 6c 65 6e 5f 74 20 61 64 64 72 6c 65  socklen_t addrle
2240: 6e 3b 0a 09 69 6e 74 20 66 61 69 6c 75 72 65 5f  n;..int failure_
2250: 63 6f 75 6e 74 20 3d 20 30 2c 20 6d 61 78 5f 66  count = 0, max_f
2260: 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3d 20 4d  ailure_count = M
2270: 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f 55 4e 54  AX_FAILURE_COUNT
2280: 3b 0a 09 69 6e 74 20 6d 61 73 74 65 72 5f 66 64  ;..int master_fd
2290: 2c 20 66 64 3b 0a 0a 09 2f 2a 20 52 65 61 64 20  , fd;.../* Read 
22a0: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 09 61 72  arguments */..ar
22b0: 67 20 3d 20 61 72 67 5f 76 3b 0a 0a 09 6d 61 73  g = arg_v;...mas
22c0: 74 65 72 5f 66 64 20 3d 20 61 72 67 2d 3e 66 64  ter_fd = arg->fd
22d0: 3b 0a 0a 09 77 68 69 6c 65 20 28 31 29 20 7b 0a  ;...while (1) {.
22e0: 09 09 2f 2a 20 46 61 69 6c 75 72 65 20 6c 6f 6f  ../* Failure loo
22f0: 70 20 70 72 65 76 65 6e 74 69 6f 6e 20 2a 2f 0a  p prevention */.
2300: 09 09 69 66 20 28 66 61 69 6c 75 72 65 5f 63 6f  ..if (failure_co
2310: 75 6e 74 20 3e 20 6d 61 78 5f 66 61 69 6c 75 72  unt > max_failur
2320: 65 5f 63 6f 75 6e 74 29 20 7b 0a 09 09 09 62 72  e_count) {....br
2330: 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 2f 2a 20 41  eak;...}..../* A
2340: 63 63 65 70 74 20 61 20 6e 65 77 20 63 6c 69 65  ccept a new clie
2350: 6e 74 20 2a 2f 0a 09 09 61 64 64 72 6c 65 6e 20  nt */...addrlen 
2360: 3d 20 73 69 7a 65 6f 66 28 61 64 64 72 29 3b 0a  = sizeof(addr);.
2370: 09 09 66 64 20 3d 20 61 63 63 65 70 74 28 6d 61  ..fd = accept(ma
2380: 73 74 65 72 5f 66 64 2c 20 28 73 74 72 75 63 74  ster_fd, (struct
2390: 20 73 6f 63 6b 61 64 64 72 20 2a 29 20 26 61 64   sockaddr *) &ad
23a0: 64 72 2c 20 26 61 64 64 72 6c 65 6e 29 3b 0a 0a  dr, &addrlen);..
23b0: 09 09 2f 2a 0a 09 09 20 2a 20 49 66 20 77 65 20  ../*... * If we 
23c0: 66 61 69 6c 2c 20 6d 61 6b 65 20 61 20 6e 6f 74  fail, make a not
23d0: 65 20 6f 66 20 69 74 20 73 6f 20 77 65 20 64 6f  e of it so we do
23e0: 6e 27 74 20 67 6f 20 69 6e 74 6f 20 61 20 6c 6f  n't go into a lo
23f0: 6f 70 20 6f 66 0a 09 09 20 2a 20 61 63 63 65 70  op of... * accep
2400: 74 28 29 20 66 61 69 6c 69 6e 67 0a 09 09 20 2a  t() failing... *
2410: 2f 0a 09 09 69 66 20 28 66 64 20 3c 20 30 29 20  /...if (fd < 0) 
2420: 7b 0a 09 09 09 2f 2a 20 4c 6f 67 20 74 68 65 20  {..../* Log the 
2430: 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a  new connection *
2440: 2f 0a 09 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d  /....filed_log_m
2450: 73 67 28 22 41 43 43 45 50 54 5f 46 41 49 4c 45  sg("ACCEPT_FAILE
2460: 44 22 29 3b 0a 0a 09 09 09 66 61 69 6c 75 72 65  D");.....failure
2470: 5f 63 6f 75 6e 74 2b 2b 3b 0a 0a 09 09 09 63 6f  _count++;.....co
2480: 6e 74 69 6e 75 65 3b 0a 09 09 7d 0a 0a 09 09 2f  ntinue;...}..../
2490: 2a 20 4c 6f 67 20 74 68 65 20 6e 65 77 20 63 6f  * Log the new co
24a0: 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 09 09 66 69  nnection */...fi
24b0: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 4e 45 57  led_log_msg("NEW
24c0: 5f 43 4f 4e 4e 45 43 54 49 4f 4e 20 53 52 43 5f  _CONNECTION SRC_
24d0: 41 44 44 52 3d 2e 2e 2e 20 53 52 43 5f 50 4f 52  ADDR=... SRC_POR
24e0: 54 3d 2e 2e 2e 20 46 44 3d 2e 2e 2e 22 29 3b 0a  T=... FD=...");.
24f0: 0a 09 09 2f 2a 20 52 65 73 65 74 20 66 61 69 6c  .../* Reset fail
2500: 75 72 65 20 63 6f 75 6e 74 2a 2f 0a 09 09 66 61  ure count*/...fa
2510: 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3d 20 30 3b  ilure_count = 0;
2520: 0a 0a 09 09 2f 2a 20 48 61 6e 64 6c 65 20 73 6f  ..../* Handle so
2530: 63 6b 65 74 20 2a 2f 0a 09 09 66 69 6c 65 64 5f  cket */...filed_
2540: 68 61 6e 64 6c 65 5f 63 6c 69 65 6e 74 28 66 64  handle_client(fd
2550: 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 70 6f 72  );..}.../* Repor
2560: 74 20 65 72 72 6f 72 20 2a 2f 0a 09 66 69 6c 65  t error */..file
2570: 64 5f 6c 6f 67 5f 6d 73 67 28 22 54 48 52 45 41  d_log_msg("THREA
2580: 44 5f 44 49 45 44 20 41 42 4e 4f 52 4d 41 4c 22  D_DIED ABNORMAL"
2590: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 4e 55 4c 4c  );...return(NULL
25a0: 29 3b 0a 7d 0a 0a 2f 2a 20 43 72 65 61 74 65 20  );.}../* Create 
25b0: 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20 2a  worker threads *
25c0: 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c  /.static int fil
25d0: 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64  ed_worker_thread
25e0: 73 5f 69 6e 69 74 28 69 6e 74 20 66 64 2c 20 69  s_init(int fd, i
25f0: 6e 74 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 29  nt thread_count)
2600: 20 7b 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64   {..struct filed
2610: 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f 61  _worker_thread_a
2620: 72 67 73 20 2a 61 72 67 3b 0a 09 70 74 68 72 65  rgs *arg;..pthre
2630: 61 64 5f 74 20 74 68 72 65 61 64 69 64 3b 0a 09  ad_t threadid;..
2640: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
2650: 0a 09 69 6e 74 20 69 3b 0a 0a 09 66 6f 72 20 28  ..int i;...for (
2660: 69 20 3d 20 30 3b 20 69 20 3c 20 74 68 72 65 61  i = 0; i < threa
2670: 64 5f 63 6f 75 6e 74 3b 20 69 2b 2b 29 20 7b 0a  d_count; i++) {.
2680: 09 09 61 72 67 20 3d 20 6d 61 6c 6c 6f 63 28 73  ..arg = malloc(s
2690: 69 7a 65 6f 66 28 2a 61 72 67 29 29 3b 0a 0a 09  izeof(*arg));...
26a0: 09 61 72 67 2d 3e 66 64 20 3d 20 66 64 3b 0a 0a  .arg->fd = fd;..
26b0: 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
26c0: 70 74 68 72 65 61 64 5f 63 72 65 61 74 65 28 26  pthread_create(&
26d0: 74 68 72 65 61 64 69 64 2c 20 4e 55 4c 4c 2c 20  threadid, NULL, 
26e0: 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72  filed_worker_thr
26f0: 65 61 64 2c 20 61 72 67 29 3b 0a 09 09 69 66 20  ead, arg);...if 
2700: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
2710: 30 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d  0) {....return(-
2720: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74  1);...}..}...ret
2730: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 52 75  urn(0);.}../* Ru
2740: 6e 20 70 72 6f 63 65 73 73 20 2a 2f 0a 69 6e 74  n process */.int
2750: 20 6d 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20   main(int argc, 
2760: 63 68 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09  char **argv) {..
2770: 69 6e 74 20 70 6f 72 74 20 3d 20 50 4f 52 54 2c  int port = PORT,
2780: 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 20 3d 20   thread_count = 
2790: 54 48 52 45 41 44 5f 43 4f 55 4e 54 3b 0a 09 63  THREAD_COUNT;..c
27a0: 6f 6e 73 74 20 63 68 61 72 20 2a 62 69 6e 64 5f  onst char *bind_
27b0: 61 64 64 72 20 3d 20 42 49 4e 44 5f 41 44 44 52  addr = BIND_ADDR
27c0: 3b 0a 09 69 6e 74 20 69 6e 69 74 5f 72 65 74 3b  ;..int init_ret;
27d0: 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 2f 2a 20 58  ..int fd;.../* X
27e0: 58 58 3a 20 54 4f 44 4f 3a 20 50 72 6f 63 65 73  XX: TODO: Proces
27f0: 73 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 09  s arguments */..
2800: 61 72 67 63 20 3d 20 61 72 67 63 3b 0a 09 61 72  argc = argc;..ar
2810: 67 76 20 3d 20 61 72 67 76 3b 0a 0a 09 2f 2a 20  gv = argv;.../* 
2820: 43 72 65 61 74 65 20 6c 69 73 74 65 6e 69 6e 67  Create listening
2830: 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 66 64 20 3d   socket */..fd =
2840: 20 66 69 6c 65 64 5f 6c 69 73 74 65 6e 28 62 69   filed_listen(bi
2850: 6e 64 5f 61 64 64 72 2c 20 70 6f 72 74 29 3b 0a  nd_addr, port);.
2860: 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09  .if (fd < 0) {..
2870: 09 70 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 6c  .perror("filed_l
2880: 69 73 74 65 6e 22 29 3b 0a 0a 09 09 72 65 74 75  isten");....retu
2890: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 42  rn(1);..}.../* B
28a0: 65 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 20 2a  ecome a daemon *
28b0: 2f 0a 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20  /../* XXX:TODO: 
28c0: 42 65 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 20  Become a daemon 
28d0: 2a 2f 0a 0a 09 2f 2a 20 49 6e 69 74 69 61 6c 69  */.../* Initiali
28e0: 7a 65 20 2a 2f 0a 09 69 6e 69 74 5f 72 65 74 20  ze */..init_ret 
28f0: 3d 20 66 69 6c 65 64 5f 69 6e 69 74 28 29 3b 0a  = filed_init();.
2900: 09 69 66 20 28 69 6e 69 74 5f 72 65 74 20 21 3d  .if (init_ret !=
2910: 20 30 29 20 7b 0a 09 09 70 65 72 72 6f 72 28 22   0) {...perror("
2920: 66 69 6c 65 64 5f 69 6e 69 74 22 29 3b 0a 0a 09  filed_init");...
2930: 09 72 65 74 75 72 6e 28 33 29 3b 0a 09 7d 0a 0a  .return(3);..}..
2940: 09 2f 2a 20 43 72 65 61 74 65 20 6c 6f 67 67 69  ./* Create loggi
2950: 6e 67 20 74 68 72 65 61 64 20 2a 2f 0a 09 69 6e  ng thread */..in
2960: 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 64 5f 6c  it_ret = filed_l
2970: 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e  ogging_thread_in
2980: 69 74 28 29 3b 0a 09 69 66 20 28 69 6e 69 74 5f  it();..if (init_
2990: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 70 65  ret != 0) {...pe
29a0: 72 72 6f 72 28 22 66 69 6c 65 64 5f 6c 6f 67 67  rror("filed_logg
29b0: 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e 69 74 22  ing_thread_init"
29c0: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 34 29 3b  );....return(4);
29d0: 0a 09 7d 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20  ..}.../* Create 
29e0: 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20 2a  worker threads *
29f0: 2f 0a 09 69 6e 69 74 5f 72 65 74 20 3d 20 66 69  /..init_ret = fi
2a00: 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61  led_worker_threa
2a10: 64 73 5f 69 6e 69 74 28 66 64 2c 20 74 68 72 65  ds_init(fd, thre
2a20: 61 64 5f 63 6f 75 6e 74 29 3b 0a 09 69 66 20 28  ad_count);..if (
2a30: 69 6e 69 74 5f 72 65 74 20 21 3d 20 30 29 20 7b  init_ret != 0) {
2a40: 0a 09 09 70 65 72 72 6f 72 28 22 66 69 6c 65 64  ...perror("filed
2a50: 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 73 5f  _worker_threads_
2a60: 69 6e 69 74 22 29 3b 0a 0a 09 09 72 65 74 75 72  init");....retur
2a70: 6e 28 34 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 57 61  n(4);..}.../* Wa
2a80: 69 74 20 66 6f 72 20 74 68 72 65 61 64 73 20 74  it for threads t
2a90: 6f 20 65 78 69 74 20 2a 2f 0a 09 2f 2a 20 58 58  o exit */../* XX
2aa0: 58 3a 54 4f 44 4f 3a 20 4d 6f 6e 69 74 6f 72 20  X:TODO: Monitor 
2ab0: 74 68 72 65 61 64 20 75 73 61 67 65 20 2a 2f 0a  thread usage */.
2ac0: 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 73  .while (1) {...s
2ad0: 6c 65 65 70 28 36 30 29 3b 0a 09 7d 0a 0a 09 2f  leep(60);..}.../
2ae0: 2a 20 52 65 74 75 72 6e 20 69 6e 20 66 61 69 6c  * Return in fail
2af0: 75 72 65 20 2a 2f 0a 09 72 65 74 75 72 6e 28 32  ure */..return(2
2b00: 29 3b 0a 7d 0a                                   );.}.