Hex Artifact Content

Artifact 0f86783dcaf2298f6e6a5f248d51f0cffddff6a9:


0000: 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65  #include <sys/se
0010: 6e 64 66 69 6c 65 2e 68 3e 0a 23 69 6e 63 6c 75  ndfile.h>.#inclu
0020: 64 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68  de <sys/socket.h
0030: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f  >.#include <sys/
0040: 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c 75 64  types.h>.#includ
0050: 65 20 3c 61 72 70 61 2f 69 6e 65 74 2e 68 3e 0a  e <arpa/inet.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 6d 6d  #include <sys/mm
0070: 61 6e 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  an.h>.#include <
0080: 73 79 73 2f 73 74 61 74 2e 68 3e 0a 23 69 6e 63  sys/stat.h>.#inc
0090: 6c 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e  lude <pthread.h>
00a0: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69  .#include <stdli
00b0: 62 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75  b.h>.#include <u
00c0: 6e 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64  nistd.h>.#includ
00d0: 65 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e  e <string.h>.#in
00e0: 63 6c 75 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a  clude <fcntl.h>.
00f0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e  #include <stdio.
0100: 68 3e 0a 0a 2f 2a 20 44 65 66 61 75 6c 74 20 76  h>../* Default v
0110: 61 6c 75 65 73 20 2a 2f 0a 23 64 65 66 69 6e 65  alues */.#define
0120: 20 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f 55   MAX_FAILURE_COU
0130: 4e 54 20 33 30 0a 23 64 65 66 69 6e 65 20 50 4f  NT 30.#define PO
0140: 52 54 20 38 30 38 30 0a 23 64 65 66 69 6e 65 20  RT 8080.#define 
0150: 54 48 52 45 41 44 5f 43 4f 55 4e 54 20 31 30 0a  THREAD_COUNT 10.
0160: 23 64 65 66 69 6e 65 20 42 49 4e 44 5f 41 44 44  #define BIND_ADD
0170: 52 20 22 3a 3a 22 0a 0a 2f 2a 20 41 72 67 75 6d  R "::"../* Argum
0180: 65 6e 74 73 20 66 6f 72 20 77 6f 72 6b 65 72 20  ents for worker 
0190: 74 68 72 65 61 64 73 20 2a 2f 0a 73 74 72 75 63  threads */.struc
01a0: 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74  t filed_worker_t
01b0: 68 72 65 61 64 5f 61 72 67 73 20 7b 0a 09 69 6e  hread_args {..in
01c0: 74 20 66 64 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63  t fd;.};..static
01d0: 20 76 6f 69 64 20 66 69 6c 65 64 5f 69 6e 69 74   void filed_init
01e0: 28 76 6f 69 64 29 20 7b 0a 09 6d 6c 6f 63 6b 61  (void) {..mlocka
01f0: 6c 6c 28 4d 43 4c 5f 43 55 52 52 45 4e 54 20 7c  ll(MCL_CURRENT |
0200: 20 4d 43 4c 5f 46 55 54 55 52 45 29 3b 0a 7d 0a   MCL_FUTURE);.}.
0210: 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65  .static int file
0220: 64 5f 6c 69 73 74 65 6e 28 63 6f 6e 73 74 20 63  d_listen(const c
0230: 68 61 72 20 2a 61 64 64 72 65 73 73 2c 20 75 6e  har *address, un
0240: 73 69 67 6e 65 64 20 69 6e 74 20 70 6f 72 74 29  signed int port)
0250: 20 7b 0a 09 73 74 72 75 63 74 20 73 6f 63 6b 61   {..struct socka
0260: 64 64 72 5f 69 6e 36 20 61 64 64 72 3b 0a 09 69  ddr_in6 addr;..i
0270: 6e 74 20 70 74 6f 6e 5f 72 65 74 2c 20 62 69 6e  nt pton_ret, bin
0280: 64 5f 72 65 74 2c 20 6c 69 73 74 65 6e 5f 72 65  d_ret, listen_re
0290: 74 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 61 64  t;..int fd;...ad
02a0: 64 72 2e 73 69 6e 36 5f 66 61 6d 69 6c 79 20 3d  dr.sin6_family =
02b0: 20 41 46 5f 49 4e 45 54 36 3b 0a 09 61 64 64 72   AF_INET6;..addr
02c0: 2e 73 69 6e 36 5f 66 6c 6f 77 69 6e 66 6f 20 3d  .sin6_flowinfo =
02d0: 20 30 3b 0a 09 61 64 64 72 2e 73 69 6e 36 5f 73   0;..addr.sin6_s
02e0: 63 6f 70 65 5f 69 64 20 3d 20 30 3b 0a 09 61 64  cope_id = 0;..ad
02f0: 64 72 2e 73 69 6e 36 5f 70 6f 72 74 20 3d 20 68  dr.sin6_port = h
0300: 74 6f 6e 73 28 70 6f 72 74 29 3b 0a 09 70 74 6f  tons(port);..pto
0310: 6e 5f 72 65 74 20 3d 20 69 6e 65 74 5f 70 74 6f  n_ret = inet_pto
0320: 6e 28 41 46 5f 49 4e 45 54 36 2c 20 61 64 64 72  n(AF_INET6, addr
0330: 65 73 73 2c 20 61 64 64 72 2e 73 69 6e 36 5f 61  ess, addr.sin6_a
0340: 64 64 72 2e 73 36 5f 61 64 64 72 29 3b 0a 09 69  ddr.s6_addr);..i
0350: 66 20 28 70 74 6f 6e 5f 72 65 74 20 21 3d 20 31  f (pton_ret != 1
0360: 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d 31 29  ) {...return(-1)
0370: 3b 0a 09 7d 0a 0a 09 66 64 20 3d 20 73 6f 63 6b  ;..}...fd = sock
0380: 65 74 28 41 46 5f 49 4e 45 54 36 2c 20 53 4f 43  et(AF_INET6, SOC
0390: 4b 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a 09 69  K_STREAM, 0);..i
03a0: 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 72  f (fd < 0) {...r
03b0: 65 74 75 72 6e 28 66 64 29 3b 0a 09 7d 0a 0a 09  eturn(fd);..}...
03c0: 62 69 6e 64 5f 72 65 74 20 3d 20 62 69 6e 64 28  bind_ret = bind(
03d0: 66 64 2c 20 28 63 6f 6e 73 74 20 73 74 72 75 63  fd, (const struc
03e0: 74 20 73 6f 63 6b 61 64 64 72 20 2a 29 20 26 61  t sockaddr *) &a
03f0: 64 64 72 2c 20 73 69 7a 65 6f 66 28 61 64 64 72  ddr, sizeof(addr
0400: 29 29 3b 0a 09 69 66 20 28 62 69 6e 64 5f 72 65  ));..if (bind_re
0410: 74 20 3c 20 30 29 20 7b 0a 09 09 63 6c 6f 73 65  t < 0) {...close
0420: 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  (fd);....return(
0430: 2d 31 29 3b 0a 09 7d 0a 0a 09 6c 69 73 74 65 6e  -1);..}...listen
0440: 5f 72 65 74 20 3d 20 6c 69 73 74 65 6e 28 66 64  _ret = listen(fd
0450: 2c 20 31 32 38 29 3b 0a 09 69 66 20 28 6c 69 73  , 128);..if (lis
0460: 74 65 6e 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  ten_ret != 0) {.
0470: 09 09 63 6c 6f 73 65 28 66 64 29 3b 0a 0a 09 09  ..close(fd);....
0480: 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a  return(-1);..}..
0490: 09 72 65 74 75 72 6e 28 66 64 29 3b 0a 7d 0a 0a  .return(fd);.}..
04a0: 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64  static int filed
04b0: 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f  _logging_thread_
04c0: 69 6e 69 74 28 76 6f 69 64 29 20 7b 0a 09 2f 2a  init(void) {../*
04d0: 20 58 58 58 3a 54 4f 44 4f 3a 20 55 6e 69 6d 70   XXX:TODO: Unimp
04e0: 6c 65 6d 65 6e 74 65 64 20 2a 2f 0a 09 72 65 74  lemented */..ret
04f0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 72 75 63  urn(0);.}..struc
0500: 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  t filed_fileinfo
0510: 20 7b 0a 09 69 6e 74 20 66 64 3b 0a 09 73 69 7a   {..int fd;..siz
0520: 65 5f 74 20 6c 65 6e 3b 0a 09 63 68 61 72 20 2a  e_t len;..char *
0530: 6c 61 73 74 6d 6f 64 3b 0a 09 63 68 61 72 20 2a  lastmod;..char *
0540: 74 79 70 65 3b 0a 7d 3b 0a 0a 73 74 61 74 69 63  type;.};..static
0550: 20 73 74 72 75 63 74 20 66 69 6c 65 64 5f 66 69   struct filed_fi
0560: 6c 65 69 6e 66 6f 20 2a 66 69 6c 65 64 5f 6f 70  leinfo *filed_op
0570: 65 6e 5f 66 69 6c 65 28 63 6f 6e 73 74 20 63 68  en_file(const ch
0580: 61 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74  ar *path, struct
0590: 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20   filed_fileinfo 
05a0: 2a 62 75 66 66 65 72 29 20 7b 0a 09 2f 2a 20 58  *buffer) {../* X
05b0: 58 58 3a 54 4f 44 4f 3a 20 43 61 63 68 65 20 66  XX:TODO: Cache f
05c0: 69 6c 65 20 64 65 73 63 72 69 70 74 6f 72 73 20  ile descriptors 
05d0: 2a 2f 0a 0a 09 6f 66 66 5f 74 20 6c 65 6e 3b 0a  */...off_t len;.
05e0: 09 69 6e 74 20 66 64 3b 0a 0a 09 66 64 20 3d 20  .int fd;...fd = 
05f0: 6f 70 65 6e 28 70 61 74 68 2c 20 4f 5f 52 44 4f  open(path, O_RDO
0600: 4e 4c 59 29 3b 0a 09 69 66 20 28 66 64 20 3c 20  NLY);..if (fd < 
0610: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 4e 55  0) {...return(NU
0620: 4c 4c 29 3b 0a 09 7d 0a 0a 09 6c 65 6e 20 3d 20  LL);..}...len = 
0630: 6c 73 65 65 6b 28 66 64 2c 20 30 2c 20 53 45 45  lseek(fd, 0, SEE
0640: 4b 5f 45 4e 44 29 3b 0a 09 6c 73 65 65 6b 28 66  K_END);..lseek(f
0650: 64 2c 20 30 2c 20 53 45 45 4b 5f 53 45 54 29 3b  d, 0, SEEK_SET);
0660: 0a 0a 09 62 75 66 66 65 72 2d 3e 66 64 20 3d 20  ...buffer->fd = 
0670: 66 64 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 65 6e  fd;..buffer->len
0680: 20 3d 20 6c 65 6e 3b 0a 0a 09 2f 2a 20 58 58 58   = len;.../* XXX
0690: 3a 54 4f 44 4f 3a 20 44 65 74 65 72 6d 69 6e 65  :TODO: Determine
06a0: 20 2a 2f 0a 09 62 75 66 66 65 72 2d 3e 74 79 70   */..buffer->typ
06b0: 65 20 3d 20 22 74 65 78 74 2f 70 6c 61 69 6e 22  e = "text/plain"
06c0: 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d  ;..buffer->lastm
06d0: 6f 64 20 3d 20 22 4e 6f 77 22 3b 0a 0a 09 72 65  od = "Now";...re
06e0: 74 75 72 6e 28 62 75 66 66 65 72 29 3b 0a 7d 0a  turn(buffer);.}.
06f0: 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a 66 69  .static char *fi
0700: 6c 65 64 5f 67 65 74 5f 68 74 74 70 5f 72 65 71  led_get_http_req
0710: 75 65 73 74 28 46 49 4c 45 20 2a 66 70 2c 20 63  uest(FILE *fp, c
0720: 68 61 72 20 2a 62 75 66 66 65 72 2c 20 73 69 7a  har *buffer, siz
0730: 65 5f 74 20 62 75 66 66 65 72 5f 6c 65 6e 29 20  e_t buffer_len) 
0740: 7b 0a 09 63 68 61 72 20 2a 6d 65 74 68 6f 64 2c  {..char *method,
0750: 20 2a 70 61 74 68 2c 20 2a 76 65 72 73 69 6f 6e   *path, *version
0760: 3b 0a 09 63 68 61 72 20 74 6d 70 62 75 66 5b 31  ;..char tmpbuf[1
0770: 30 31 30 5d 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09  010];..int i;...
0780: 73 65 74 6c 69 6e 65 62 75 66 28 66 70 29 3b 0a  setlinebuf(fp);.
0790: 0a 09 66 67 65 74 73 28 62 75 66 66 65 72 2c 20  ..fgets(buffer, 
07a0: 62 75 66 66 65 72 5f 6c 65 6e 2c 20 66 70 29 3b  buffer_len, fp);
07b0: 0a 0a 09 6d 65 74 68 6f 64 20 3d 20 62 75 66 66  ...method = buff
07c0: 65 72 3b 0a 0a 09 62 75 66 66 65 72 20 3d 20 73  er;...buffer = s
07d0: 74 72 63 68 72 28 62 75 66 66 65 72 2c 20 27 20  trchr(buffer, ' 
07e0: 27 29 3b 0a 09 69 66 20 28 62 75 66 66 65 72 20  ');..if (buffer 
07f0: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74  == NULL) {...ret
0800: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
0810: 2a 62 75 66 66 65 72 20 3d 20 27 5c 30 27 3b 0a  *buffer = '\0';.
0820: 09 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 70 61 74  .buffer++;...pat
0830: 68 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09 62 75  h = buffer;...bu
0840: 66 66 65 72 20 3d 20 73 74 72 63 68 72 28 62 75  ffer = strchr(bu
0850: 66 66 65 72 2c 20 27 20 27 29 3b 0a 09 69 66 20  ffer, ' ');..if 
0860: 28 62 75 66 66 65 72 20 21 3d 20 4e 55 4c 4c 29  (buffer != NULL)
0870: 20 7b 0a 09 09 2a 62 75 66 66 65 72 20 3d 20 27   {...*buffer = '
0880: 5c 30 27 3b 0a 09 09 62 75 66 66 65 72 2b 2b 3b  \0';...buffer++;
0890: 0a 0a 09 09 76 65 72 73 69 6f 6e 20 3d 20 62 75  ....version = bu
08a0: 66 66 65 72 3b 0a 09 7d 0a 0a 09 66 6f 72 20 28  ffer;..}...for (
08b0: 69 20 3d 20 30 3b 20 69 20 3c 20 31 30 30 3b 20  i = 0; i < 100; 
08c0: 69 2b 2b 29 20 7b 0a 09 09 66 67 65 74 73 28 74  i++) {...fgets(t
08d0: 6d 70 62 75 66 2c 20 73 69 7a 65 6f 66 28 74 6d  mpbuf, sizeof(tm
08e0: 70 62 75 66 29 2c 20 66 70 29 3b 0a 09 09 69 66  pbuf), fp);...if
08f0: 20 28 6d 65 6d 63 6d 70 28 74 6d 70 62 75 66 2c   (memcmp(tmpbuf,
0900: 20 22 5c 72 5c 6e 22 2c 20 32 29 20 3d 3d 20 30   "\r\n", 2) == 0
0910: 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09  ) {....break;...
0920: 7d 0a 09 7d 0a 0a 09 66 66 6c 75 73 68 28 66 70  }..}...fflush(fp
0930: 29 3b 0a 0a 09 2f 2a 20 49 47 4e 4f 52 45 44 20  );.../* IGNORED 
0940: 2a 2f 0a 09 76 65 72 73 69 6f 6e 20 3d 20 76 65  */..version = ve
0950: 72 73 69 6f 6e 3b 0a 09 6d 65 74 68 6f 64 20 3d  rsion;..method =
0960: 20 6d 65 74 68 6f 64 3b 0a 0a 09 72 65 74 75 72   method;...retur
0970: 6e 28 70 61 74 68 29 3b 0a 7d 0a 0a 73 74 61 74  n(path);.}..stat
0980: 69 63 20 76 6f 69 64 20 66 69 6c 65 64 5f 68 61  ic void filed_ha
0990: 6e 64 6c 65 5f 63 6c 69 65 6e 74 28 69 6e 74 20  ndle_client(int 
09a0: 66 64 29 20 7b 0a 09 73 74 72 75 63 74 20 66 69  fd) {..struct fi
09b0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66 69  led_fileinfo *fi
09c0: 6c 65 69 6e 66 6f 2c 20 66 69 6c 65 69 6e 66 6f  leinfo, fileinfo
09d0: 5f 62 3b 0a 09 63 68 61 72 20 2a 70 61 74 68 2c  _b;..char *path,
09e0: 20 70 61 74 68 5f 62 5b 31 30 31 30 5d 3b 0a 09   path_b[1010];..
09f0: 63 68 61 72 20 2a 64 61 74 65 5f 63 75 72 72 65  char *date_curre
0a00: 6e 74 3b 0a 09 46 49 4c 45 20 2a 66 70 3b 0a 0a  nt;..FILE *fp;..
0a10: 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 44 65  ./* XXX:TODO: De
0a20: 74 65 72 6d 69 6e 65 20 2a 2f 0a 09 64 61 74 65  termine */..date
0a30: 5f 63 75 72 72 65 6e 74 20 3d 20 22 4e 6f 77 22  _current = "Now"
0a40: 3b 0a 0a 09 2f 2a 20 4f 70 65 6e 20 73 6f 63 6b  ;.../* Open sock
0a50: 65 74 20 61 73 20 41 4e 53 49 20 49 2f 4f 20 66  et as ANSI I/O f
0a60: 6f 72 20 65 61 73 65 20 6f 66 20 75 73 65 20 2a  or ease of use *
0a70: 2f 0a 09 66 70 20 3d 20 66 64 6f 70 65 6e 28 66  /..fp = fdopen(f
0a80: 64 2c 20 22 77 2b 62 22 29 3b 0a 09 69 66 20 28  d, "w+b");..if (
0a90: 66 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09  fp == NULL) {...
0aa0: 63 6c 6f 73 65 28 66 64 29 3b 0a 0a 09 09 72 65  close(fd);....re
0ab0: 74 75 72 6e 3b 0a 09 7d 0a 0a 09 70 61 74 68 20  turn;..}...path 
0ac0: 3d 20 66 69 6c 65 64 5f 67 65 74 5f 68 74 74 70  = filed_get_http
0ad0: 5f 72 65 71 75 65 73 74 28 66 70 2c 20 70 61 74  _request(fp, pat
0ae0: 68 5f 62 2c 20 73 69 7a 65 6f 66 28 70 61 74 68  h_b, sizeof(path
0af0: 5f 62 29 29 3b 0a 09 69 66 20 28 70 61 74 68 20  _b));..if (path 
0b00: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 2f 2a 20  == NULL) {.../* 
0b10: 58 58 58 3a 20 54 4f 44 4f 3a 20 52 65 74 75 72  XXX: TODO: Retur
0b20: 6e 20 65 72 72 6f 72 20 70 61 67 65 20 2a 2f 0a  n error page */.
0b30: 09 09 66 63 6c 6f 73 65 28 66 70 29 3b 0a 0a 09  ..fclose(fp);...
0b40: 09 72 65 74 75 72 6e 3b 0a 09 7d 0a 0a 09 66 69  .return;..}...fi
0b50: 6c 65 69 6e 66 6f 20 3d 20 66 69 6c 65 64 5f 6f  leinfo = filed_o
0b60: 70 65 6e 5f 66 69 6c 65 28 70 61 74 68 2c 20 26  pen_file(path, &
0b70: 66 69 6c 65 69 6e 66 6f 5f 62 29 3b 0a 09 69 66  fileinfo_b);..if
0b80: 20 28 66 69 6c 65 69 6e 66 6f 20 3d 3d 20 4e 55   (fileinfo == NU
0b90: 4c 4c 29 20 7b 0a 09 09 2f 2a 20 58 58 58 3a 20  LL) {.../* XXX: 
0ba0: 54 4f 44 4f 3a 20 52 65 74 75 72 6e 20 65 72 72  TODO: Return err
0bb0: 6f 72 20 70 61 67 65 20 2a 2f 0a 09 7d 20 65 6c  or page */..} el
0bc0: 73 65 20 7b 0a 09 09 66 70 72 69 6e 74 66 28 66  se {...fprintf(f
0bd0: 70 2c 20 22 48 54 54 50 2f 31 2e 31 20 32 30 30  p, "HTTP/1.1 200
0be0: 20 4f 4b 5c 72 5c 6e 44 61 74 65 3a 20 25 73 5c   OK\r\nDate: %s\
0bf0: 72 5c 6e 53 65 72 76 65 72 3a 20 66 69 6c 65 64  r\nServer: filed
0c00: 5c 72 5c 6e 4c 61 73 74 2d 4d 6f 64 69 66 69 65  \r\nLast-Modifie
0c10: 64 3a 20 25 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74  d: %s\r\nContent
0c20: 2d 4c 65 6e 67 74 68 3a 20 25 6c 6c 75 5c 72 5c  -Length: %llu\r\
0c30: 6e 43 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 25  nContent-Type: %
0c40: 73 5c 72 5c 6e 43 6f 6e 6e 65 63 74 69 6f 6e 3a  s\r\nConnection:
0c50: 20 63 6c 6f 73 65 5c 72 5c 6e 5c 72 5c 6e 22 2c   close\r\n\r\n",
0c60: 0a 09 09 09 64 61 74 65 5f 63 75 72 72 65 6e 74  ....date_current
0c70: 2c 0a 09 09 09 66 69 6c 65 69 6e 66 6f 2d 3e 6c  ,....fileinfo->l
0c80: 61 73 74 6d 6f 64 2c 0a 09 09 09 28 75 6e 73 69  astmod,....(unsi
0c90: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20  gned long long) 
0ca0: 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 2c 0a 09  fileinfo->len,..
0cb0: 09 09 66 69 6c 65 69 6e 66 6f 2d 3e 74 79 70 65  ..fileinfo->type
0cc0: 0a 09 09 29 3b 0a 0a 09 09 73 65 6e 64 66 69 6c  ...);....sendfil
0cd0: 65 28 66 64 2c 20 66 69 6c 65 69 6e 66 6f 2d 3e  e(fd, fileinfo->
0ce0: 66 64 2c 20 4e 55 4c 4c 2c 20 66 69 6c 65 69 6e  fd, NULL, filein
0cf0: 66 6f 2d 3e 6c 65 6e 29 3b 0a 0a 09 09 63 6c 6f  fo->len);....clo
0d00: 73 65 28 66 69 6c 65 69 6e 66 6f 2d 3e 66 64 29  se(fileinfo->fd)
0d10: 3b 0a 09 7d 0a 0a 09 66 63 6c 6f 73 65 28 66 70  ;..}...fclose(fp
0d20: 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  );...return;.}..
0d30: 73 74 61 74 69 63 20 76 6f 69 64 20 2a 66 69 6c  static void *fil
0d40: 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64  ed_worker_thread
0d50: 28 76 6f 69 64 20 2a 61 72 67 5f 76 29 20 7b 0a  (void *arg_v) {.
0d60: 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f 77 6f  .struct filed_wo
0d70: 72 6b 65 72 5f 74 68 72 65 61 64 5f 61 72 67 73  rker_thread_args
0d80: 20 2a 61 72 67 3b 0a 09 73 74 72 75 63 74 20 73   *arg;..struct s
0d90: 6f 63 6b 61 64 64 72 5f 69 6e 36 20 61 64 64 72  ockaddr_in6 addr
0da0: 3b 0a 09 73 6f 63 6b 6c 65 6e 5f 74 20 61 64 64  ;..socklen_t add
0db0: 72 6c 65 6e 3b 0a 09 69 6e 74 20 66 61 69 6c 75  rlen;..int failu
0dc0: 72 65 5f 63 6f 75 6e 74 20 3d 20 30 2c 20 6d 61  re_count = 0, ma
0dd0: 78 5f 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20  x_failure_count 
0de0: 3d 20 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f  = MAX_FAILURE_CO
0df0: 55 4e 54 3b 0a 09 69 6e 74 20 6d 61 73 74 65 72  UNT;..int master
0e00: 5f 66 64 2c 20 66 64 3b 0a 0a 09 2f 2a 20 52 65  _fd, fd;.../* Re
0e10: 61 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a  ad arguments */.
0e20: 09 61 72 67 20 3d 20 61 72 67 5f 76 3b 0a 0a 09  .arg = arg_v;...
0e30: 6d 61 73 74 65 72 5f 66 64 20 3d 20 61 72 67 2d  master_fd = arg-
0e40: 3e 66 64 3b 0a 0a 09 77 68 69 6c 65 20 28 31 29  >fd;...while (1)
0e50: 20 7b 0a 09 09 2f 2a 20 46 61 69 6c 75 72 65 20   {.../* Failure 
0e60: 6c 6f 6f 70 20 70 72 65 76 65 6e 74 69 6f 6e 20  loop prevention 
0e70: 2a 2f 0a 09 09 69 66 20 28 66 61 69 6c 75 72 65  */...if (failure
0e80: 5f 63 6f 75 6e 74 20 3e 20 6d 61 78 5f 66 61 69  _count > max_fai
0e90: 6c 75 72 65 5f 63 6f 75 6e 74 29 20 7b 0a 09 09  lure_count) {...
0ea0: 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 2f  .break;...}..../
0eb0: 2a 20 41 63 63 65 70 74 20 61 20 6e 65 77 20 63  * Accept a new c
0ec0: 6c 69 65 6e 74 20 2a 2f 0a 09 09 61 64 64 72 6c  lient */...addrl
0ed0: 65 6e 20 3d 20 73 69 7a 65 6f 66 28 61 64 64 72  en = sizeof(addr
0ee0: 29 3b 0a 09 09 66 64 20 3d 20 61 63 63 65 70 74  );...fd = accept
0ef0: 28 6d 61 73 74 65 72 5f 66 64 2c 20 28 73 74 72  (master_fd, (str
0f00: 75 63 74 20 73 6f 63 6b 61 64 64 72 20 2a 29 20  uct sockaddr *) 
0f10: 26 61 64 64 72 2c 20 26 61 64 64 72 6c 65 6e 29  &addr, &addrlen)
0f20: 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 49 66 20  ;..../*... * If 
0f30: 77 65 20 66 61 69 6c 2c 20 6d 61 6b 65 20 61 20  we fail, make a 
0f40: 6e 6f 74 65 20 6f 66 20 69 74 20 73 6f 20 77 65  note of it so we
0f50: 20 64 6f 6e 27 74 20 67 6f 20 69 6e 74 6f 20 61   don't go into a
0f60: 20 6c 6f 6f 70 20 6f 66 0a 09 09 20 2a 20 61 63   loop of... * ac
0f70: 63 65 70 74 28 29 20 66 61 69 6c 69 6e 67 0a 09  cept() failing..
0f80: 09 20 2a 2f 0a 09 09 69 66 20 28 66 64 20 3c 20  . */...if (fd < 
0f90: 30 29 20 7b 0a 09 09 09 66 61 69 6c 75 72 65 5f  0) {....failure_
0fa0: 63 6f 75 6e 74 2b 2b 3b 0a 0a 09 09 09 63 6f 6e  count++;.....con
0fb0: 74 69 6e 75 65 3b 0a 09 09 7d 0a 0a 09 09 2f 2a  tinue;...}..../*
0fc0: 20 52 65 73 65 74 20 66 61 69 6c 75 72 65 20 63   Reset failure c
0fd0: 6f 75 6e 74 2a 2f 0a 09 09 66 61 69 6c 75 72 65  ount*/...failure
0fe0: 5f 63 6f 75 6e 74 20 3d 20 30 3b 0a 0a 09 09 2f  _count = 0;..../
0ff0: 2a 20 48 61 6e 64 6c 65 20 73 6f 63 6b 65 74 20  * Handle socket 
1000: 2a 2f 0a 09 09 66 69 6c 65 64 5f 68 61 6e 64 6c  */...filed_handl
1010: 65 5f 63 6c 69 65 6e 74 28 66 64 29 3b 0a 09 7d  e_client(fd);..}
1020: 0a 0a 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20  .../* XXX:TODO: 
1030: 52 65 70 6f 72 74 20 65 72 72 6f 72 20 2a 2f 0a  Report error */.
1040: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 7d  .return(NULL);.}
1050: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c  ..static int fil
1060: 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64  ed_worker_thread
1070: 73 5f 69 6e 69 74 28 69 6e 74 20 66 64 2c 20 69  s_init(int fd, i
1080: 6e 74 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 29  nt thread_count)
1090: 20 7b 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64   {..struct filed
10a0: 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f 61  _worker_thread_a
10b0: 72 67 73 20 2a 61 72 67 3b 0a 09 70 74 68 72 65  rgs *arg;..pthre
10c0: 61 64 5f 74 20 74 68 72 65 61 64 69 64 3b 0a 09  ad_t threadid;..
10d0: 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b  int pthread_ret;
10e0: 0a 09 69 6e 74 20 69 3b 0a 0a 09 66 6f 72 20 28  ..int i;...for (
10f0: 69 20 3d 20 30 3b 20 69 20 3c 20 74 68 72 65 61  i = 0; i < threa
1100: 64 5f 63 6f 75 6e 74 3b 20 69 2b 2b 29 20 7b 0a  d_count; i++) {.
1110: 09 09 61 72 67 20 3d 20 6d 61 6c 6c 6f 63 28 73  ..arg = malloc(s
1120: 69 7a 65 6f 66 28 2a 61 72 67 29 29 3b 0a 0a 09  izeof(*arg));...
1130: 09 61 72 67 2d 3e 66 64 20 3d 20 66 64 3b 0a 0a  .arg->fd = fd;..
1140: 09 09 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20  ..pthread_ret = 
1150: 70 74 68 72 65 61 64 5f 63 72 65 61 74 65 28 26  pthread_create(&
1160: 74 68 72 65 61 64 69 64 2c 20 4e 55 4c 4c 2c 20  threadid, NULL, 
1170: 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72  filed_worker_thr
1180: 65 61 64 2c 20 61 72 67 29 3b 0a 09 09 69 66 20  ead, arg);...if 
1190: 28 70 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20  (pthread_ret != 
11a0: 30 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d  0) {....return(-
11b0: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74  1);...}..}...ret
11c0: 75 72 6e 28 30 29 3b 0a 7d 0a 0a 69 6e 74 20 6d  urn(0);.}..int m
11d0: 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68  ain(int argc, ch
11e0: 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09 69 6e  ar **argv) {..in
11f0: 74 20 70 6f 72 74 20 3d 20 50 4f 52 54 2c 20 74  t port = PORT, t
1200: 68 72 65 61 64 5f 63 6f 75 6e 74 20 3d 20 54 48  hread_count = TH
1210: 52 45 41 44 5f 43 4f 55 4e 54 3b 0a 09 63 6f 6e  READ_COUNT;..con
1220: 73 74 20 63 68 61 72 20 2a 62 69 6e 64 5f 61 64  st char *bind_ad
1230: 64 72 20 3d 20 42 49 4e 44 5f 41 44 44 52 3b 0a  dr = BIND_ADDR;.
1240: 09 69 6e 74 20 66 64 3b 0a 0a 09 2f 2a 20 49 67  .int fd;.../* Ig
1250: 6e 6f 72 65 20 2a 2f 0a 09 61 72 67 63 20 3d 20  nore */..argc = 
1260: 61 72 67 63 3b 0a 09 61 72 67 76 20 3d 20 61 72  argc;..argv = ar
1270: 67 76 3b 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20  gv;.../* Create 
1280: 6c 69 73 74 65 6e 69 6e 67 20 73 6f 63 6b 65 74  listening socket
1290: 20 2a 2f 0a 09 66 64 20 3d 20 66 69 6c 65 64 5f   */..fd = filed_
12a0: 6c 69 73 74 65 6e 28 62 69 6e 64 5f 61 64 64 72  listen(bind_addr
12b0: 2c 20 70 6f 72 74 29 3b 0a 09 69 66 20 28 66 64  , port);..if (fd
12c0: 20 3c 20 30 29 20 7b 0a 09 09 70 65 72 72 6f 72   < 0) {...perror
12d0: 28 22 66 69 6c 65 64 5f 6c 69 73 74 65 6e 22 29  ("filed_listen")
12e0: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  ;....return(1);.
12f0: 09 7d 0a 0a 09 2f 2a 20 42 65 63 6f 6d 65 20 61  .}.../* Become a
1300: 20 64 61 65 6d 6f 6e 20 2a 2f 0a 09 2f 2a 20 58   daemon */../* X
1310: 58 58 3a 54 4f 44 4f 3a 20 42 65 63 6f 6d 65 20  XX:TODO: Become 
1320: 61 20 64 61 65 6d 6f 6e 20 2a 2f 0a 0a 09 2f 2a  a daemon */.../*
1330: 20 49 6e 69 74 69 61 6c 69 7a 65 20 2a 2f 0a 09   Initialize */..
1340: 66 69 6c 65 64 5f 69 6e 69 74 28 29 3b 0a 0a 09  filed_init();...
1350: 2f 2a 20 43 72 65 61 74 65 20 6c 6f 67 67 69 6e  /* Create loggin
1360: 67 20 74 68 72 65 61 64 20 2a 2f 0a 09 2f 2a 20  g thread */../* 
1370: 58 58 58 3a 54 4f 44 4f 3a 20 43 68 65 63 6b 20  XXX:TODO: Check 
1380: 66 6f 72 20 65 72 72 6f 72 73 20 2a 2f 0a 09 66  for errors */..f
1390: 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72  iled_logging_thr
13a0: 65 61 64 5f 69 6e 69 74 28 29 3b 0a 0a 09 2f 2a  ead_init();.../*
13b0: 20 43 72 65 61 74 65 20 77 6f 72 6b 65 72 20 74   Create worker t
13c0: 68 72 65 61 64 73 20 2a 2f 0a 09 2f 2a 20 58 58  hreads */../* XX
13d0: 58 3a 54 4f 44 4f 3a 20 43 68 65 63 6b 20 66 6f  X:TODO: Check fo
13e0: 72 20 65 72 72 6f 72 73 20 2a 2f 0a 09 66 69 6c  r errors */..fil
13f0: 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64  ed_worker_thread
1400: 73 5f 69 6e 69 74 28 66 64 2c 20 74 68 72 65 61  s_init(fd, threa
1410: 64 5f 63 6f 75 6e 74 29 3b 0a 0a 09 2f 2a 20 57  d_count);.../* W
1420: 61 69 74 20 66 6f 72 20 74 68 72 65 61 64 73 20  ait for threads 
1430: 74 6f 20 65 78 69 74 20 2a 2f 0a 09 2f 2a 20 58  to exit */../* X
1440: 58 58 3a 54 4f 44 4f 3a 20 4d 6f 6e 69 74 6f 72  XX:TODO: Monitor
1450: 20 74 68 72 65 61 64 20 75 73 61 67 65 20 2a 2f   thread usage */
1460: 0a 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09  ..while (1) {...
1470: 73 6c 65 65 70 28 36 30 29 3b 0a 09 7d 0a 0a 09  sleep(60);..}...
1480: 2f 2a 20 52 65 74 75 72 6e 20 69 6e 20 66 61 69  /* Return in fai
1490: 6c 75 72 65 20 2a 2f 0a 09 72 65 74 75 72 6e 28  lure */..return(
14a0: 32 29 3b 0a 7d 0a                                2);.}.