Hex Artifact Content

Artifact 5f7a2da005f0fcbc645ca6ffcad75181f0bf761c:


0000: 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 73 65  #include <sys/se
0010: 6e 64 66 69 6c 65 2e 68 3e 0a 23 69 6e 63 6c 75  ndfile.h>.#inclu
0020: 64 65 20 3c 73 79 73 2f 73 6f 63 6b 65 74 2e 68  de <sys/socket.h
0030: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f  >.#include <sys/
0040: 74 79 70 65 73 2e 68 3e 0a 23 69 6e 63 6c 75 64  types.h>.#includ
0050: 65 20 3c 61 72 70 61 2f 69 6e 65 74 2e 68 3e 0a  e <arpa/inet.h>.
0060: 23 69 6e 63 6c 75 64 65 20 3c 73 79 73 2f 6d 6d  #include <sys/mm
0070: 61 6e 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  an.h>.#include <
0080: 73 79 73 2f 73 74 61 74 2e 68 3e 0a 23 69 6e 63  sys/stat.h>.#inc
0090: 6c 75 64 65 20 3c 70 74 68 72 65 61 64 2e 68 3e  lude <pthread.h>
00a0: 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69 6e  .#include <strin
00b0: 67 73 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  gs.h>.#include <
00c0: 73 69 67 6e 61 6c 2e 68 3e 0a 23 69 6e 63 6c 75  signal.h>.#inclu
00d0: 64 65 20 3c 73 74 64 6c 69 62 2e 68 3e 0a 23 69  de <stdlib.h>.#i
00e0: 6e 63 6c 75 64 65 20 3c 75 6e 69 73 74 64 2e 68  nclude <unistd.h
00f0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 73 74 72 69  >.#include <stri
0100: 6e 67 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c  ng.h>.#include <
0110: 66 63 6e 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64  fcntl.h>.#includ
0120: 65 20 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63  e <stdio.h>.#inc
0130: 6c 75 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23  lude <errno.h>.#
0140: 69 6e 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e  include <time.h>
0150: 0a 0a 2f 2a 20 43 6f 6d 70 69 6c 65 20 74 69 6d  ../* Compile tim
0160: 65 20 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 23  e constants */.#
0170: 64 65 66 69 6e 65 20 46 49 4c 45 44 5f 53 45 4e  define FILED_SEN
0180: 44 46 49 4c 45 5f 4d 41 58 20 31 36 37 37 37 32  DFILE_MAX 167772
0190: 31 35 0a 0a 2f 2a 20 44 65 66 61 75 6c 74 20 76  15../* Default v
01a0: 61 6c 75 65 73 20 2a 2f 0a 23 64 65 66 69 6e 65  alues */.#define
01b0: 20 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f 55   MAX_FAILURE_COU
01c0: 4e 54 20 33 30 0a 23 64 65 66 69 6e 65 20 50 4f  NT 30.#define PO
01d0: 52 54 20 38 30 38 30 0a 23 64 65 66 69 6e 65 20  RT 8080.#define 
01e0: 54 48 52 45 41 44 5f 43 4f 55 4e 54 20 31 30 0a  THREAD_COUNT 10.
01f0: 23 64 65 66 69 6e 65 20 42 49 4e 44 5f 41 44 44  #define BIND_ADD
0200: 52 20 22 3a 3a 22 0a 23 64 65 66 69 6e 65 20 43  R "::".#define C
0210: 41 43 48 45 5f 53 49 5a 45 20 38 31 39 32 0a 0a  ACHE_SIZE 8192..
0220: 2f 2a 20 41 72 67 75 6d 65 6e 74 73 20 66 6f 72  /* Arguments for
0230: 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20   worker threads 
0240: 2a 2f 0a 73 74 72 75 63 74 20 66 69 6c 65 64 5f  */.struct filed_
0250: 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f 61 72  worker_thread_ar
0260: 67 73 20 7b 0a 09 69 6e 74 20 66 64 3b 0a 7d 3b  gs {..int fd;.};
0270: 0a 0a 2f 2a 20 46 69 6c 65 20 69 6e 66 6f 72 6d  ../* File inform
0280: 61 74 69 6f 6e 20 2a 2f 0a 73 74 72 75 63 74 20  ation */.struct 
0290: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 7b  filed_fileinfo {
02a0: 0a 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  ..pthread_mutex_
02b0: 74 20 6d 75 74 65 78 3b 0a 09 63 68 61 72 20 2a  t mutex;..char *
02c0: 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 09  path;..int fd;..
02d0: 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 63 68 61 72  off_t len;..char
02e0: 20 2a 6c 61 73 74 6d 6f 64 3b 0a 09 63 68 61 72   *lastmod;..char
02f0: 20 6c 61 73 74 6d 6f 64 5f 62 5b 36 34 5d 3b 0a   lastmod_b[64];.
0300: 09 63 68 61 72 20 2a 74 79 70 65 3b 0a 7d 3b 0a  .char *type;.};.
0310: 0a 2f 2a 20 52 65 71 75 65 73 74 20 76 61 72 69  ./* Request vari
0320: 61 62 6c 65 73 20 2a 2f 0a 73 74 72 75 63 74 20  ables */.struct 
0330: 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 71 75 65  filed_http_reque
0340: 73 74 20 7b 0a 09 2f 2a 2a 20 42 75 66 66 65 72  st {../** Buffer
0350: 73 20 2a 2a 2f 0a 09 73 74 72 75 63 74 20 66 69  s **/..struct fi
0360: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 66 69 6c  led_fileinfo fil
0370: 65 69 6e 66 6f 3b 0a 09 63 68 61 72 20 70 61 74  einfo;..char pat
0380: 68 5f 62 5b 31 30 31 30 5d 3b 0a 09 63 68 61 72  h_b[1010];..char
0390: 20 74 6d 70 62 75 66 5b 31 30 31 30 5d 3b 0a 0a   tmpbuf[1010];..
03a0: 09 2f 2a 2a 20 48 54 54 50 20 52 65 71 75 65 73  ./** HTTP Reques
03b0: 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a 2a  t information **
03c0: 2f 0a 09 63 68 61 72 20 2a 70 61 74 68 3b 20 20  /..char *path;  
03d0: 20 20 20 2f 2a 2a 2a 20 50 61 74 68 20 62 65 69     /*** Path bei
03e0: 6e 67 20 72 65 71 75 65 73 74 65 64 20 2a 2a 2a  ng requested ***
03f0: 2f 0a 0a 09 73 74 72 75 63 74 20 7b 0a 09 09 73  /...struct {...s
0400: 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74 20 70  truct {....int p
0410: 72 65 73 65 6e 74 3b 0a 09 09 09 6f 66 66 5f 74  resent;....off_t
0420: 20 6f 66 66 73 65 74 3b 20 20 20 2f 2a 2a 2a 20   offset;   /*** 
0430: 52 61 6e 67 65 20 73 74 61 72 74 20 2a 2a 2a 2f  Range start ***/
0440: 0a 09 09 09 6f 66 66 5f 74 20 6c 65 6e 67 74 68  ....off_t length
0450: 3b 20 20 20 2f 2a 2a 2a 20 52 61 6e 67 65 20 6c  ;   /*** Range l
0460: 65 6e 67 74 68 20 2a 2a 2a 2f 0a 09 09 7d 20 72  ength ***/...} r
0470: 61 6e 67 65 3b 0a 09 7d 20 68 65 61 64 65 72 73  ange;..} headers
0480: 3b 0a 7d 3b 0a 0a 2f 2a 20 47 6c 6f 62 61 6c 20  ;.};../* Global 
0490: 76 61 72 69 61 62 6c 65 73 20 2a 2f 0a 2f 2a 2a  variables */./**
04a0: 20 4f 70 65 6e 20 46 69 6c 65 20 63 61 63 68 65   Open File cache
04b0: 20 2a 2a 2f 0a 73 74 72 75 63 74 20 66 69 6c 65   **/.struct file
04c0: 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66 69 6c 65  d_fileinfo *file
04d0: 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63  d_fileinfo_fdcac
04e0: 68 65 3b 0a 75 6e 73 69 67 6e 65 64 20 69 6e 74  he;.unsigned int
04f0: 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f   filed_fileinfo_
0500: 66 64 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 43  fdcache_size = C
0510: 41 43 48 45 5f 53 49 5a 45 3b 0a 0a 2f 2a 20 49  ACHE_SIZE;../* I
0520: 6e 69 74 69 61 6c 69 7a 65 20 70 72 6f 63 65 73  nitialize proces
0530: 73 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  s */.static int 
0540: 66 69 6c 65 64 5f 69 6e 69 74 28 76 6f 69 64 29  filed_init(void)
0550: 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 69 6e 74   {..unsigned int
0560: 20 69 64 78 3b 0a 09 69 6e 74 20 6d 75 74 65 78   idx;..int mutex
0570: 5f 69 6e 69 74 5f 72 65 74 3b 0a 0a 09 6d 6c 6f  _init_ret;...mlo
0580: 63 6b 61 6c 6c 28 4d 43 4c 5f 43 55 52 52 45 4e  ckall(MCL_CURREN
0590: 54 20 7c 20 4d 43 4c 5f 46 55 54 55 52 45 29 3b  T | MCL_FUTURE);
05a0: 0a 0a 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66  ...filed_fileinf
05b0: 6f 5f 66 64 63 61 63 68 65 20 3d 20 6d 61 6c 6c  o_fdcache = mall
05c0: 6f 63 28 73 69 7a 65 6f 66 28 2a 66 69 6c 65 64  oc(sizeof(*filed
05d0: 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68  _fileinfo_fdcach
05e0: 65 29 20 2a 20 66 69 6c 65 64 5f 66 69 6c 65 69  e) * filed_filei
05f0: 6e 66 6f 5f 66 64 63 61 63 68 65 5f 73 69 7a 65  nfo_fdcache_size
0600: 29 3b 0a 09 69 66 20 28 66 69 6c 65 64 5f 66 69  );..if (filed_fi
0610: 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 20 3d  leinfo_fdcache =
0620: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75  = NULL) {...retu
0630: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 66 6f 72 20  rn(1);..}...for 
0640: 28 69 64 78 20 3d 20 30 3b 20 69 64 78 20 3c 20  (idx = 0; idx < 
0650: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66  filed_fileinfo_f
0660: 64 63 61 63 68 65 5f 73 69 7a 65 3b 20 69 64 78  dcache_size; idx
0670: 2b 2b 29 20 7b 0a 09 09 6d 75 74 65 78 5f 69 6e  ++) {...mutex_in
0680: 69 74 5f 72 65 74 20 3d 20 70 74 68 72 65 61 64  it_ret = pthread
0690: 5f 6d 75 74 65 78 5f 69 6e 69 74 28 26 66 69 6c  _mutex_init(&fil
06a0: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61  ed_fileinfo_fdca
06b0: 63 68 65 5b 69 64 78 5d 2e 6d 75 74 65 78 2c 20  che[idx].mutex, 
06c0: 4e 55 4c 4c 29 3b 0a 09 09 69 66 20 28 6d 75 74  NULL);...if (mut
06d0: 65 78 5f 69 6e 69 74 5f 72 65 74 20 21 3d 20 30  ex_init_ret != 0
06e0: 29 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 31 29  ) {....return(1)
06f0: 3b 0a 09 09 7d 0a 0a 09 09 66 69 6c 65 64 5f 66  ;...}....filed_f
0700: 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b  ileinfo_fdcache[
0710: 69 64 78 5d 2e 70 61 74 68 20 3d 20 73 74 72 64  idx].path = strd
0720: 75 70 28 22 22 29 3b 0a 09 09 66 69 6c 65 64 5f  up("");...filed_
0730: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65  fileinfo_fdcache
0740: 5b 69 64 78 5d 2e 66 64 20 3d 20 2d 31 3b 0a 09  [idx].fd = -1;..
0750: 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f  .filed_fileinfo_
0760: 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 6c 61 73  fdcache[idx].las
0770: 74 6d 6f 64 20 3d 20 22 22 3b 0a 09 09 66 69 6c  tmod = "";...fil
0780: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61  ed_fileinfo_fdca
0790: 63 68 65 5b 69 64 78 5d 2e 74 79 70 65 20 3d 20  che[idx].type = 
07a0: 22 22 3b 0a 09 7d 0a 0a 09 73 69 67 6e 61 6c 28  "";..}...signal(
07b0: 53 49 47 50 49 50 45 2c 20 53 49 47 5f 49 47 4e  SIGPIPE, SIG_IGN
07c0: 29 3b 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a  );...return(0);.
07d0: 7d 0a 0a 2f 2a 20 4c 69 73 74 65 6e 20 6f 6e 20  }../* Listen on 
07e0: 61 20 70 61 72 74 69 63 75 6c 61 72 20 61 64 64  a particular add
07f0: 72 65 73 73 2f 70 6f 72 74 20 2a 2f 0a 73 74 61  ress/port */.sta
0800: 74 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 6c 69  tic int filed_li
0810: 73 74 65 6e 28 63 6f 6e 73 74 20 63 68 61 72 20  sten(const char 
0820: 2a 61 64 64 72 65 73 73 2c 20 75 6e 73 69 67 6e  *address, unsign
0830: 65 64 20 69 6e 74 20 70 6f 72 74 29 20 7b 0a 09  ed int port) {..
0840: 73 74 72 75 63 74 20 73 6f 63 6b 61 64 64 72 5f  struct sockaddr_
0850: 69 6e 36 20 61 64 64 72 3b 0a 09 69 6e 74 20 70  in6 addr;..int p
0860: 74 6f 6e 5f 72 65 74 2c 20 62 69 6e 64 5f 72 65  ton_ret, bind_re
0870: 74 2c 20 6c 69 73 74 65 6e 5f 72 65 74 3b 0a 09  t, listen_ret;..
0880: 69 6e 74 20 66 64 3b 0a 0a 09 61 64 64 72 2e 73  int fd;...addr.s
0890: 69 6e 36 5f 66 61 6d 69 6c 79 20 3d 20 41 46 5f  in6_family = AF_
08a0: 49 4e 45 54 36 3b 0a 09 61 64 64 72 2e 73 69 6e  INET6;..addr.sin
08b0: 36 5f 66 6c 6f 77 69 6e 66 6f 20 3d 20 30 3b 0a  6_flowinfo = 0;.
08c0: 09 61 64 64 72 2e 73 69 6e 36 5f 73 63 6f 70 65  .addr.sin6_scope
08d0: 5f 69 64 20 3d 20 30 3b 0a 09 61 64 64 72 2e 73  _id = 0;..addr.s
08e0: 69 6e 36 5f 70 6f 72 74 20 3d 20 68 74 6f 6e 73  in6_port = htons
08f0: 28 70 6f 72 74 29 3b 0a 09 70 74 6f 6e 5f 72 65  (port);..pton_re
0900: 74 20 3d 20 69 6e 65 74 5f 70 74 6f 6e 28 41 46  t = inet_pton(AF
0910: 5f 49 4e 45 54 36 2c 20 61 64 64 72 65 73 73 2c  _INET6, address,
0920: 20 61 64 64 72 2e 73 69 6e 36 5f 61 64 64 72 2e   addr.sin6_addr.
0930: 73 36 5f 61 64 64 72 29 3b 0a 09 69 66 20 28 70  s6_addr);..if (p
0940: 74 6f 6e 5f 72 65 74 20 21 3d 20 31 29 20 7b 0a  ton_ret != 1) {.
0950: 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d  ..return(-1);..}
0960: 0a 0a 09 66 64 20 3d 20 73 6f 63 6b 65 74 28 41  ...fd = socket(A
0970: 46 5f 49 4e 45 54 36 2c 20 53 4f 43 4b 5f 53 54  F_INET6, SOCK_ST
0980: 52 45 41 4d 2c 20 30 29 3b 0a 09 69 66 20 28 66  REAM, 0);..if (f
0990: 64 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72  d < 0) {...retur
09a0: 6e 28 66 64 29 3b 0a 09 7d 0a 0a 09 62 69 6e 64  n(fd);..}...bind
09b0: 5f 72 65 74 20 3d 20 62 69 6e 64 28 66 64 2c 20  _ret = bind(fd, 
09c0: 28 63 6f 6e 73 74 20 73 74 72 75 63 74 20 73 6f  (const struct so
09d0: 63 6b 61 64 64 72 20 2a 29 20 26 61 64 64 72 2c  ckaddr *) &addr,
09e0: 20 73 69 7a 65 6f 66 28 61 64 64 72 29 29 3b 0a   sizeof(addr));.
09f0: 09 69 66 20 28 62 69 6e 64 5f 72 65 74 20 3c 20  .if (bind_ret < 
0a00: 30 29 20 7b 0a 09 09 63 6c 6f 73 65 28 66 64 29  0) {...close(fd)
0a10: 3b 0a 0a 09 09 72 65 74 75 72 6e 28 2d 31 29 3b  ;....return(-1);
0a20: 0a 09 7d 0a 0a 09 6c 69 73 74 65 6e 5f 72 65 74  ..}...listen_ret
0a30: 20 3d 20 6c 69 73 74 65 6e 28 66 64 2c 20 31 32   = listen(fd, 12
0a40: 38 29 3b 0a 09 69 66 20 28 6c 69 73 74 65 6e 5f  8);..if (listen_
0a50: 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 63 6c  ret != 0) {...cl
0a60: 6f 73 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75  ose(fd);....retu
0a70: 72 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 72 65 74  rn(-1);..}...ret
0a80: 75 72 6e 28 66 64 29 3b 0a 7d 0a 0a 2f 2a 20 4c  urn(fd);.}../* L
0a90: 6f 67 20 61 20 6d 65 73 73 61 67 65 20 2a 2f 0a  og a message */.
0aa0: 2f 2f 23 64 65 66 69 6e 65 20 46 49 4c 45 44 5f  //#define FILED_
0ab0: 44 4f 4e 54 5f 4c 4f 47 0a 23 69 66 64 65 66 20  DONT_LOG.#ifdef 
0ac0: 46 49 4c 45 44 5f 44 4f 4e 54 5f 4c 4f 47 0a 23  FILED_DONT_LOG.#
0ad0: 20 20 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c    define filed_l
0ae0: 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e  ogging_thread_in
0af0: 69 74 28 29 20 30 0a 23 20 20 64 65 66 69 6e 65  it() 0.#  define
0b00: 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64   filed_log_msg_d
0b10: 65 62 75 67 28 78 2c 20 2e 2e 2e 29 20 2f 2a 2a  ebug(x, ...) /**
0b20: 2f 0a 23 20 20 64 65 66 69 6e 65 20 66 69 6c 65  /.#  define file
0b30: 64 5f 6c 6f 67 5f 6d 73 67 28 78 29 20 2f 2a 2a  d_log_msg(x) /**
0b40: 2f 0a 23 65 6c 73 65 0a 2f 2a 20 49 6e 69 74 69  /.#else./* Initi
0b50: 61 6c 69 7a 65 20 6c 6f 67 67 69 6e 67 20 74 68  alize logging th
0b60: 72 65 61 64 20 2a 2f 0a 73 74 61 74 69 63 20 69  read */.static i
0b70: 6e 74 20 66 69 6c 65 64 5f 6c 6f 67 67 69 6e 67  nt filed_logging
0b80: 5f 74 68 72 65 61 64 5f 69 6e 69 74 28 76 6f 69  _thread_init(voi
0b90: 64 29 20 7b 0a 09 2f 2a 20 58 58 58 3a 54 4f 44  d) {../* XXX:TOD
0ba0: 4f 3a 20 55 6e 69 6d 70 6c 65 6d 65 6e 74 65 64  O: Unimplemented
0bb0: 20 2a 2f 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a   */..return(0);.
0bc0: 7d 0a 0a 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20  }../* XXX:TODO: 
0bd0: 55 6e 69 6d 70 6c 65 6d 65 6e 74 65 64 20 2a 2f  Unimplemented */
0be0: 0a 23 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c  .#define filed_l
0bf0: 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 78 2c 20  og_msg_debug(x, 
0c00: 2e 2e 2e 29 20 7b 20 66 70 72 69 6e 74 66 28 73  ...) { fprintf(s
0c10: 74 64 65 72 72 2c 20 78 2c 20 5f 5f 56 41 5f 41  tderr, x, __VA_A
0c20: 52 47 53 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28  RGS__); fprintf(
0c30: 73 74 64 65 72 72 2c 20 22 5c 6e 22 29 3b 20 66  stderr, "\n"); f
0c40: 66 6c 75 73 68 28 73 74 64 65 72 72 29 3b 20 7d  flush(stderr); }
0c50: 0a 0a 73 74 61 74 69 63 20 76 6f 69 64 20 66 69  ..static void fi
0c60: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 63 6f 6e 73  led_log_msg(cons
0c70: 74 20 63 68 61 72 20 2a 62 75 66 66 65 72 29 20  t char *buffer) 
0c80: 7b 0a 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20  {../* XXX:TODO: 
0c90: 55 6e 69 6d 70 6c 65 6d 65 6e 74 65 64 20 2a 2f  Unimplemented */
0ca0: 0a 09 66 70 72 69 6e 74 66 28 73 74 64 65 72 72  ..fprintf(stderr
0cb0: 2c 20 22 25 73 5c 6e 22 2c 20 62 75 66 66 65 72  , "%s\n", buffer
0cc0: 29 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 0a  );...return;.}..
0cd0: 23 65 6e 64 69 66 0a 2f 2a 20 46 6f 72 6d 61 74  #endif./* Format
0ce0: 20 74 69 6d 65 20 70 65 72 20 52 46 43 32 36 31   time per RFC261
0cf0: 36 20 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72  6 */.static char
0d00: 20 2a 66 69 6c 65 64 5f 66 6f 72 6d 61 74 5f 74   *filed_format_t
0d10: 69 6d 65 28 63 68 61 72 20 2a 62 75 66 66 65 72  ime(char *buffer
0d20: 2c 20 73 69 7a 65 5f 74 20 62 75 66 66 65 72 5f  , size_t buffer_
0d30: 6c 65 6e 2c 20 63 6f 6e 73 74 20 74 69 6d 65 5f  len, const time_
0d40: 74 20 74 69 6d 65 69 6e 66 6f 29 20 7b 0a 09 73  t timeinfo) {..s
0d50: 74 72 75 63 74 20 74 6d 20 74 69 6d 65 69 6e 66  truct tm timeinf
0d60: 6f 5f 74 6d 2c 20 2a 74 69 6d 65 69 6e 66 6f 5f  o_tm, *timeinfo_
0d70: 74 6d 5f 70 3b 0a 0a 09 74 69 6d 65 69 6e 66 6f  tm_p;...timeinfo
0d80: 5f 74 6d 5f 70 20 3d 20 67 6d 74 69 6d 65 5f 72  _tm_p = gmtime_r
0d90: 28 26 74 69 6d 65 69 6e 66 6f 2c 20 26 74 69 6d  (&timeinfo, &tim
0da0: 65 69 6e 66 6f 5f 74 6d 29 3b 0a 09 69 66 20 28  einfo_tm);..if (
0db0: 74 69 6d 65 69 6e 66 6f 5f 74 6d 5f 70 20 3d 3d  timeinfo_tm_p ==
0dc0: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
0dd0: 6e 28 22 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 09 7d  n("unknown");..}
0de0: 0a 0a 09 62 75 66 66 65 72 5b 62 75 66 66 65 72  ...buffer[buffer
0df0: 5f 6c 65 6e 20 2d 20 31 5d 20 3d 20 27 5c 30 27  _len - 1] = '\0'
0e00: 3b 0a 09 62 75 66 66 65 72 5f 6c 65 6e 20 3d 20  ;..buffer_len = 
0e10: 73 74 72 66 74 69 6d 65 28 62 75 66 66 65 72 2c  strftime(buffer,
0e20: 20 62 75 66 66 65 72 5f 6c 65 6e 20 2d 20 31 2c   buffer_len - 1,
0e30: 20 22 25 61 2c 20 25 64 20 25 62 20 25 59 20 25   "%a, %d %b %Y %
0e40: 48 3a 25 4d 3a 25 53 20 47 4d 54 22 2c 20 74 69  H:%M:%S GMT", ti
0e50: 6d 65 69 6e 66 6f 5f 74 6d 5f 70 29 3b 0a 0a 09  meinfo_tm_p);...
0e60: 72 65 74 75 72 6e 28 62 75 66 66 65 72 29 3b 0a  return(buffer);.
0e70: 7d 0a 0a 2f 2a 20 68 61 73 68 20 2a 2f 0a 73 74  }../* hash */.st
0e80: 61 74 69 63 20 75 6e 73 69 67 6e 65 64 20 69 6e  atic unsigned in
0e90: 74 20 66 69 6c 65 64 5f 68 61 73 68 28 63 6f 6e  t filed_hash(con
0ea0: 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72  st unsigned char
0eb0: 20 2a 76 61 6c 75 65 2c 20 75 6e 73 69 67 6e 65   *value, unsigne
0ec0: 64 20 69 6e 74 20 6d 6f 64 75 6c 75 73 29 20 7b  d int modulus) {
0ed0: 0a 09 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20  ..unsigned char 
0ee0: 63 75 72 72 3b 0a 09 75 6e 73 69 67 6e 65 64 20  curr;..unsigned 
0ef0: 69 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65  int retval;...re
0f00: 74 76 61 6c 20 3d 20 6d 6f 64 75 6c 75 73 20 2d  tval = modulus -
0f10: 20 31 3b 0a 0a 09 77 68 69 6c 65 20 28 28 63 75   1;...while ((cu
0f20: 72 72 20 3d 20 2a 76 61 6c 75 65 29 29 20 7b 0a  rr = *value)) {.
0f30: 09 09 69 66 20 28 63 75 72 72 20 3c 20 33 32 29  ..if (curr < 32)
0f40: 20 7b 0a 09 09 09 63 75 72 72 20 3d 20 32 35 35   {....curr = 255
0f50: 20 2d 20 63 75 72 72 3b 0a 09 09 7d 20 65 6c 73   - curr;...} els
0f60: 65 20 7b 0a 09 09 09 63 75 72 72 20 2d 3d 20 33  e {....curr -= 3
0f70: 32 3b 0a 09 09 7d 0a 0a 09 09 72 65 74 76 61 6c  2;...}....retval
0f80: 20 3c 3c 3d 20 35 3b 0a 09 09 72 65 74 76 61 6c   <<= 5;...retval
0f90: 20 2b 3d 20 63 75 72 72 3b 0a 0a 09 09 76 61 6c   += curr;....val
0fa0: 75 65 2b 2b 3b 0a 09 7d 0a 0a 09 72 65 74 76 61  ue++;..}...retva
0fb0: 6c 20 3d 20 72 65 74 76 61 6c 20 25 20 6d 6f 64  l = retval % mod
0fc0: 75 6c 75 73 3b 0a 0a 09 72 65 74 75 72 6e 28 72  ulus;...return(r
0fd0: 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 20 4f 70  etval);.}../* Op
0fe0: 65 6e 20 61 20 66 69 6c 65 20 61 6e 64 20 72 65  en a file and re
0ff0: 74 75 72 6e 20 66 69 6c 65 20 69 6e 66 6f 72 6d  turn file inform
1000: 61 74 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20  ation */.static 
1010: 73 74 72 75 63 74 20 66 69 6c 65 64 5f 66 69 6c  struct filed_fil
1020: 65 69 6e 66 6f 20 2a 66 69 6c 65 64 5f 6f 70 65  einfo *filed_ope
1030: 6e 5f 66 69 6c 65 28 63 6f 6e 73 74 20 63 68 61  n_file(const cha
1040: 72 20 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20  r *path, struct 
1050: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a  filed_fileinfo *
1060: 62 75 66 66 65 72 29 20 7b 0a 09 73 74 72 75 63  buffer) {..struc
1070: 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  t filed_fileinfo
1080: 20 2a 63 61 63 68 65 3b 0a 09 75 6e 73 69 67 6e   *cache;..unsign
1090: 65 64 20 69 6e 74 20 63 61 63 68 65 5f 69 64 78  ed int cache_idx
10a0: 3b 0a 09 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 69  ;..off_t len;..i
10b0: 6e 74 20 66 64 3b 0a 0a 09 63 61 63 68 65 5f 69  nt fd;...cache_i
10c0: 64 78 20 3d 20 66 69 6c 65 64 5f 68 61 73 68 28  dx = filed_hash(
10d0: 28 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20  (const unsigned 
10e0: 63 68 61 72 20 2a 29 20 70 61 74 68 2c 20 66 69  char *) path, fi
10f0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63  led_fileinfo_fdc
1100: 61 63 68 65 5f 73 69 7a 65 29 3b 0a 0a 09 63 61  ache_size);...ca
1110: 63 68 65 20 3d 20 26 66 69 6c 65 64 5f 66 69 6c  che = &filed_fil
1120: 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 63 61  einfo_fdcache[ca
1130: 63 68 65 5f 69 64 78 5d 3b 0a 0a 09 66 69 6c 65  che_idx];...file
1140: 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28  d_log_msg_debug(
1150: 22 4c 6f 63 6b 69 6e 67 20 6d 75 74 65 78 20 66  "Locking mutex f
1160: 6f 72 20 69 64 78 3a 20 25 6c 75 22 2c 20 28 75  or idx: %lu", (u
1170: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61  nsigned long) ca
1180: 63 68 65 5f 69 64 78 29 3b 0a 0a 09 70 74 68 72  che_idx);...pthr
1190: 65 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26  ead_mutex_lock(&
11a0: 63 61 63 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a  cache->mutex);..
11b0: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64  .filed_log_msg_d
11c0: 65 62 75 67 28 22 43 6f 6d 70 6c 65 74 65 64 20  ebug("Completed 
11d0: 6c 6f 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f  locking mutex fo
11e0: 72 20 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e  r idx: %lu", (un
11f0: 73 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63  signed long) cac
1200: 68 65 5f 69 64 78 29 3b 0a 0a 09 69 66 20 28 73  he_idx);...if (s
1210: 74 72 63 6d 70 28 70 61 74 68 2c 20 63 61 63 68  trcmp(path, cach
1220: 65 2d 3e 70 61 74 68 29 20 21 3d 20 30 29 20 7b  e->path) != 0) {
1230: 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67  ...filed_log_msg
1240: 5f 64 65 62 75 67 28 22 43 61 63 68 65 20 6d 69  _debug("Cache mi
1250: 73 73 20 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a  ss for idx: %lu:
1260: 20 4f 4c 44 20 5c 22 25 73 5c 22 2c 20 4e 45 57   OLD \"%s\", NEW
1270: 20 5c 22 25 73 5c 22 22 2c 20 28 75 6e 73 69 67   \"%s\"", (unsig
1280: 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f  ned long) cache_
1290: 69 64 78 2c 20 63 61 63 68 65 2d 3e 70 61 74 68  idx, cache->path
12a0: 2c 20 70 61 74 68 29 3b 0a 0a 09 09 66 64 20 3d  , path);....fd =
12b0: 20 6f 70 65 6e 28 70 61 74 68 2c 20 4f 5f 52 44   open(path, O_RD
12c0: 4f 4e 4c 59 20 7c 20 4f 5f 4c 41 52 47 45 46 49  ONLY | O_LARGEFI
12d0: 4c 45 29 3b 0a 09 09 69 66 20 28 66 64 20 3c 20  LE);...if (fd < 
12e0: 30 29 20 7b 0a 09 09 09 70 74 68 72 65 61 64 5f  0) {....pthread_
12f0: 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61  mutex_unlock(&ca
1300: 63 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09  che->mutex);....
1310: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09  .return(NULL);..
1320: 09 7d 0a 0a 09 09 66 72 65 65 28 63 61 63 68 65  .}....free(cache
1330: 2d 3e 70 61 74 68 29 3b 0a 09 09 69 66 20 28 63  ->path);...if (c
1340: 61 63 68 65 2d 3e 66 64 20 3e 3d 20 30 29 20 7b  ache->fd >= 0) {
1350: 0a 09 09 09 63 6c 6f 73 65 28 63 61 63 68 65 2d  ....close(cache-
1360: 3e 66 64 29 3b 0a 09 09 7d 0a 0a 09 09 6c 65 6e  >fd);...}....len
1370: 20 3d 20 6c 73 65 65 6b 28 66 64 2c 20 30 2c 20   = lseek(fd, 0, 
1380: 53 45 45 4b 5f 45 4e 44 29 3b 0a 09 09 6c 73 65  SEEK_END);...lse
1390: 65 6b 28 66 64 2c 20 30 2c 20 53 45 45 4b 5f 53  ek(fd, 0, SEEK_S
13a0: 45 54 29 3b 0a 0a 09 09 63 61 63 68 65 2d 3e 66  ET);....cache->f
13b0: 64 20 3d 20 66 64 3b 0a 09 09 63 61 63 68 65 2d  d = fd;...cache-
13c0: 3e 6c 65 6e 20 3d 20 6c 65 6e 3b 0a 09 09 63 61  >len = len;...ca
13d0: 63 68 65 2d 3e 70 61 74 68 20 3d 20 73 74 72 64  che->path = strd
13e0: 75 70 28 70 61 74 68 29 3b 0a 0a 09 09 2f 2a 20  up(path);..../* 
13f0: 58 58 58 3a 54 4f 44 4f 3a 20 44 65 74 65 72 6d  XXX:TODO: Determ
1400: 69 6e 65 20 2a 2f 0a 09 09 63 61 63 68 65 2d 3e  ine */...cache->
1410: 74 79 70 65 20 3d 20 22 76 69 64 65 6f 2f 6d 70  type = "video/mp
1420: 34 22 3b 0a 09 09 63 61 63 68 65 2d 3e 6c 61 73  4";...cache->las
1430: 74 6d 6f 64 20 3d 20 66 69 6c 65 64 5f 66 6f 72  tmod = filed_for
1440: 6d 61 74 5f 74 69 6d 65 28 63 61 63 68 65 2d 3e  mat_time(cache->
1450: 6c 61 73 74 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f  lastmod_b, sizeo
1460: 66 28 63 61 63 68 65 2d 3e 6c 61 73 74 6d 6f 64  f(cache->lastmod
1470: 5f 62 29 2c 20 74 69 6d 65 28 4e 55 4c 4c 29 20  _b), time(NULL) 
1480: 2d 20 33 30 29 3b 0a 09 7d 20 65 6c 73 65 20 7b  - 30);..} else {
1490: 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67  ...filed_log_msg
14a0: 5f 64 65 62 75 67 28 22 43 61 63 68 65 20 68 69  _debug("Cache hi
14b0: 74 20 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20  t for idx: %lu: 
14c0: 50 41 54 48 20 5c 22 25 73 5c 22 22 2c 20 28 75  PATH \"%s\"", (u
14d0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61  nsigned long) ca
14e0: 63 68 65 5f 69 64 78 2c 20 70 61 74 68 29 3b 0a  che_idx, path);.
14f0: 09 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 57 65 20 68  .}.../*.. * We h
1500: 61 76 65 20 74 6f 20 6d 61 6b 65 20 61 20 64 75  ave to make a du
1510: 70 6c 69 63 61 74 65 20 46 44 2c 20 62 65 63 61  plicate FD, beca
1520: 75 73 65 20 6f 6e 63 65 20 77 65 20 72 65 6c 65  use once we rele
1530: 61 73 65 20 74 68 65 20 63 61 63 68 65 0a 09 20  ase the cache.. 
1540: 2a 20 6d 75 74 65 78 2c 20 74 68 65 20 66 69 6c  * mutex, the fil
1550: 65 20 64 65 73 63 72 69 70 74 6f 72 20 6d 61 79  e descriptor may
1560: 20 62 65 20 63 6c 6f 73 65 64 0a 09 20 2a 2f 0a   be closed.. */.
1570: 09 66 64 20 3d 20 64 75 70 28 63 61 63 68 65 2d  .fd = dup(cache-
1580: 3e 66 64 29 3b 0a 09 69 66 20 28 66 64 20 3c 20  >fd);..if (fd < 
1590: 30 29 20 7b 0a 09 09 70 74 68 72 65 61 64 5f 6d  0) {...pthread_m
15a0: 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63  utex_unlock(&cac
15b0: 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 72  he->mutex);....r
15c0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
15d0: 0a 09 62 75 66 66 65 72 2d 3e 66 64 20 3d 20 66  ..buffer->fd = f
15e0: 64 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 65 6e 20  d;..buffer->len 
15f0: 3d 20 63 61 63 68 65 2d 3e 6c 65 6e 3b 0a 09 62  = cache->len;..b
1600: 75 66 66 65 72 2d 3e 74 79 70 65 20 3d 20 63 61  uffer->type = ca
1610: 63 68 65 2d 3e 74 79 70 65 3b 0a 09 6d 65 6d 63  che->type;..memc
1620: 70 79 28 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d  py(buffer->lastm
1630: 6f 64 5f 62 2c 20 63 61 63 68 65 2d 3e 6c 61 73  od_b, cache->las
1640: 74 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28 62  tmod_b, sizeof(b
1650: 75 66 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 5f 62  uffer->lastmod_b
1660: 29 29 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 61 73  ));..buffer->las
1670: 74 6d 6f 64 20 3d 20 62 75 66 66 65 72 2d 3e 6c  tmod = buffer->l
1680: 61 73 74 6d 6f 64 5f 62 20 2b 20 28 63 61 63 68  astmod_b + (cach
1690: 65 2d 3e 6c 61 73 74 6d 6f 64 20 2d 20 63 61 63  e->lastmod - cac
16a0: 68 65 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 3b 0a  he->lastmod_b);.
16b0: 0a 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  ..pthread_mutex_
16c0: 75 6e 6c 6f 63 6b 28 26 63 61 63 68 65 2d 3e 6d  unlock(&cache->m
16d0: 75 74 65 78 29 3b 0a 0a 09 72 65 74 75 72 6e 28  utex);...return(
16e0: 62 75 66 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50  buffer);.}../* P
16f0: 72 6f 63 65 73 73 20 61 6e 20 48 54 54 50 20 72  rocess an HTTP r
1700: 65 71 75 65 73 74 20 61 6e 64 20 72 65 74 75 72  equest and retur
1710: 6e 20 74 68 65 20 70 61 74 68 20 72 65 71 75 65  n the path reque
1720: 73 74 65 64 20 2a 2f 0a 73 74 61 74 69 63 20 73  sted */.static s
1730: 74 72 75 63 74 20 66 69 6c 65 64 5f 68 74 74 70  truct filed_http
1740: 5f 72 65 71 75 65 73 74 20 2a 66 69 6c 65 64 5f  _request *filed_
1750: 67 65 74 5f 68 74 74 70 5f 72 65 71 75 65 73 74  get_http_request
1760: 28 46 49 4c 45 20 2a 66 70 2c 20 73 74 72 75 63  (FILE *fp, struc
1770: 74 20 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 71  t filed_http_req
1780: 75 65 73 74 20 2a 62 75 66 66 65 72 5f 73 74 29  uest *buffer_st)
1790: 20 7b 0a 09 63 68 61 72 20 2a 6d 65 74 68 6f 64   {..char *method
17a0: 2c 20 2a 70 61 74 68 3b 0a 09 63 68 61 72 20 2a  , *path;..char *
17b0: 62 75 66 66 65 72 2c 20 2a 74 6d 70 62 75 66 66  buffer, *tmpbuff
17c0: 65 72 2c 20 2a 77 6f 72 6b 62 75 66 66 65 72 2c  er, *workbuffer,
17d0: 20 2a 77 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78   *workbuffer_nex
17e0: 74 3b 0a 09 73 69 7a 65 5f 74 20 62 75 66 66 65  t;..size_t buffe
17f0: 72 5f 6c 65 6e 2c 20 74 6d 70 62 75 66 66 65 72  r_len, tmpbuffer
1800: 5f 6c 65 6e 3b 0a 09 6f 66 66 5f 74 20 72 61 6e  _len;..off_t ran
1810: 67 65 5f 73 74 61 72 74 2c 20 72 61 6e 67 65 5f  ge_start, range_
1820: 65 6e 64 2c 20 72 61 6e 67 65 5f 6c 65 6e 67 74  end, range_lengt
1830: 68 3b 0a 09 69 6e 74 20 72 61 6e 67 65 5f 72 65  h;..int range_re
1840: 71 75 65 73 74 3b 0a 09 69 6e 74 20 69 3b 0a 0a  quest;..int i;..
1850: 09 72 61 6e 67 65 5f 73 74 61 72 74 20 3d 20 30  .range_start = 0
1860: 3b 0a 09 72 61 6e 67 65 5f 65 6e 64 20 20 20 3d  ;..range_end   =
1870: 20 30 3b 0a 09 72 61 6e 67 65 5f 72 65 71 75 65   0;..range_reque
1880: 73 74 20 3d 20 30 3b 0a 09 72 61 6e 67 65 5f 6c  st = 0;..range_l
1890: 65 6e 67 74 68 20 3d 20 2d 31 3b 0a 0a 09 62 75  ength = -1;...bu
18a0: 66 66 65 72 20 3d 20 62 75 66 66 65 72 5f 73 74  ffer = buffer_st
18b0: 2d 3e 70 61 74 68 5f 62 3b 0a 09 62 75 66 66 65  ->path_b;..buffe
18c0: 72 5f 6c 65 6e 20 3d 20 73 69 7a 65 6f 66 28 62  r_len = sizeof(b
18d0: 75 66 66 65 72 5f 73 74 2d 3e 70 61 74 68 5f 62  uffer_st->path_b
18e0: 29 3b 0a 0a 09 74 6d 70 62 75 66 66 65 72 20 3d  );...tmpbuffer =
18f0: 20 62 75 66 66 65 72 5f 73 74 2d 3e 74 6d 70 62   buffer_st->tmpb
1900: 75 66 3b 0a 09 74 6d 70 62 75 66 66 65 72 5f 6c  uf;..tmpbuffer_l
1910: 65 6e 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 66  en = sizeof(buff
1920: 65 72 5f 73 74 2d 3e 74 6d 70 62 75 66 29 3b 0a  er_st->tmpbuf);.
1930: 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
1940: 22 57 41 49 54 5f 46 4f 52 5f 52 45 51 55 45 53  "WAIT_FOR_REQUES
1950: 54 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 66 67  T FD=...");...fg
1960: 65 74 73 28 62 75 66 66 65 72 2c 20 62 75 66 66  ets(buffer, buff
1970: 65 72 5f 6c 65 6e 2c 20 66 70 29 3b 0a 0a 09 6d  er_len, fp);...m
1980: 65 74 68 6f 64 20 3d 20 62 75 66 66 65 72 3b 0a  ethod = buffer;.
1990: 0a 09 62 75 66 66 65 72 20 3d 20 73 74 72 63 68  ..buffer = strch
19a0: 72 28 62 75 66 66 65 72 2c 20 27 20 27 29 3b 0a  r(buffer, ' ');.
19b0: 09 69 66 20 28 62 75 66 66 65 72 20 3d 3d 20 4e  .if (buffer == N
19c0: 55 4c 4c 29 20 7b 0a 09 09 66 69 6c 65 64 5f 6c  ULL) {...filed_l
19d0: 6f 67 5f 6d 73 67 28 22 47 4f 54 5f 52 45 51 55  og_msg("GOT_REQU
19e0: 45 53 54 20 46 44 3d 2e 2e 2e 20 45 52 52 4f 52  EST FD=... ERROR
19f0: 3d 66 6f 72 6d 61 74 22 29 3b 0a 0a 09 09 72 65  =format");....re
1a00: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
1a10: 09 2a 62 75 66 66 65 72 20 3d 20 27 5c 30 27 3b  .*buffer = '\0';
1a20: 0a 09 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 70 61  ..buffer++;...pa
1a30: 74 68 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09 62  th = buffer;...b
1a40: 75 66 66 65 72 20 3d 20 73 74 72 63 68 72 28 62  uffer = strchr(b
1a50: 75 66 66 65 72 2c 20 27 20 27 29 3b 0a 09 69 66  uffer, ' ');..if
1a60: 20 28 62 75 66 66 65 72 20 21 3d 20 4e 55 4c 4c   (buffer != NULL
1a70: 29 20 7b 0a 09 09 2a 62 75 66 66 65 72 20 3d 20  ) {...*buffer = 
1a80: 27 5c 30 27 3b 0a 09 09 62 75 66 66 65 72 2b 2b  '\0';...buffer++
1a90: 3b 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67  ;..}...filed_log
1aa0: 5f 6d 73 67 28 22 47 4f 54 5f 52 45 51 55 45 53  _msg("GOT_REQUES
1ab0: 54 20 46 44 3d 2e 2e 2e 20 50 41 54 48 3d 2e 2e  T FD=... PATH=..
1ac0: 2e 22 29 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67  .");...filed_log
1ad0: 5f 6d 73 67 28 22 57 41 49 54 5f 46 4f 52 5f 48  _msg("WAIT_FOR_H
1ae0: 45 41 44 45 52 53 20 46 44 3d 2e 2e 2e 22 29 3b  EADERS FD=...");
1af0: 0a 0a 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 69  ...for (i = 0; i
1b00: 20 3c 20 31 30 30 3b 20 69 2b 2b 29 20 7b 0a 09   < 100; i++) {..
1b10: 09 66 67 65 74 73 28 74 6d 70 62 75 66 66 65 72  .fgets(tmpbuffer
1b20: 2c 20 74 6d 70 62 75 66 66 65 72 5f 6c 65 6e 2c  , tmpbuffer_len,
1b30: 20 66 70 29 3b 0a 0a 09 09 69 66 20 28 73 74 72   fp);....if (str
1b40: 6e 63 61 73 65 63 6d 70 28 74 6d 70 62 75 66 66  ncasecmp(tmpbuff
1b50: 65 72 2c 20 22 52 61 6e 67 65 3a 20 22 2c 20 37  er, "Range: ", 7
1b60: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 77 6f 72  ) == 0) {....wor
1b70: 6b 62 75 66 66 65 72 20 3d 20 74 6d 70 62 75 66  kbuffer = tmpbuf
1b80: 66 65 72 20 2b 20 37 3b 0a 0a 09 09 09 69 66 20  fer + 7;.....if 
1b90: 28 73 74 72 6e 63 61 73 65 63 6d 70 28 77 6f 72  (strncasecmp(wor
1ba0: 6b 62 75 66 66 65 72 2c 20 22 62 79 74 65 73 3d  kbuffer, "bytes=
1bb0: 22 2c 20 36 29 20 3d 3d 20 30 29 20 7b 0a 09 09  ", 6) == 0) {...
1bc0: 09 09 77 6f 72 6b 62 75 66 66 65 72 20 2b 3d 20  ..workbuffer += 
1bd0: 36 3b 0a 0a 09 09 09 09 72 61 6e 67 65 5f 72 65  6;......range_re
1be0: 71 75 65 73 74 20 3d 20 31 3b 0a 0a 09 09 09 09  quest = 1;......
1bf0: 72 61 6e 67 65 5f 73 74 61 72 74 20 3d 20 73 74  range_start = st
1c00: 72 74 6f 75 6c 6c 28 77 6f 72 6b 62 75 66 66 65  rtoull(workbuffe
1c10: 72 2c 20 26 77 6f 72 6b 62 75 66 66 65 72 5f 6e  r, &workbuffer_n
1c20: 65 78 74 2c 20 31 30 29 3b 0a 0a 09 09 09 09 77  ext, 10);......w
1c30: 6f 72 6b 62 75 66 66 65 72 20 3d 20 77 6f 72 6b  orkbuffer = work
1c40: 62 75 66 66 65 72 5f 6e 65 78 74 3b 0a 0a 09 09  buffer_next;....
1c50: 09 09 69 66 20 28 2a 77 6f 72 6b 62 75 66 66 65  ..if (*workbuffe
1c60: 72 20 3d 3d 20 27 2d 27 29 20 7b 0a 09 09 09 09  r == '-') {.....
1c70: 09 77 6f 72 6b 62 75 66 66 65 72 2b 2b 3b 0a 0a  .workbuffer++;..
1c80: 09 09 09 09 09 69 66 20 28 2a 77 6f 72 6b 62 75  .....if (*workbu
1c90: 66 66 65 72 20 21 3d 20 27 5c 72 27 20 26 26 20  ffer != '\r' && 
1ca0: 2a 77 6f 72 6b 62 75 66 66 65 72 20 21 3d 20 27  *workbuffer != '
1cb0: 5c 6e 27 29 20 7b 0a 09 09 09 09 09 09 72 61 6e  \n') {.......ran
1cc0: 67 65 5f 65 6e 64 20 3d 20 73 74 72 74 6f 75 6c  ge_end = strtoul
1cd0: 6c 28 77 6f 72 6b 62 75 66 66 65 72 2c 20 26 77  l(workbuffer, &w
1ce0: 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78 74 2c 20  orkbuffer_next, 
1cf0: 31 30 29 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09  10);......}.....
1d00: 7d 0a 09 09 09 7d 0a 09 09 7d 0a 0a 09 09 69 66  }....}...}....if
1d10: 20 28 6d 65 6d 63 6d 70 28 74 6d 70 62 75 66 66   (memcmp(tmpbuff
1d20: 65 72 2c 20 22 5c 72 5c 6e 22 2c 20 32 29 20 3d  er, "\r\n", 2) =
1d30: 3d 20 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b  = 0) {....break;
1d40: 0a 09 09 7d 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f  ...}..}...filed_
1d50: 6c 6f 67 5f 6d 73 67 28 22 47 4f 54 5f 48 45 41  log_msg("GOT_HEA
1d60: 44 45 52 53 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a  DERS FD=...");..
1d70: 09 2f 2a 20 57 65 20 6f 6e 6c 79 20 68 61 6e 64  ./* We only hand
1d80: 6c 65 20 74 68 65 20 22 47 45 54 22 20 6d 65 74  le the "GET" met
1d90: 68 6f 64 20 2a 2f 0a 09 69 66 20 28 73 74 72 63  hod */..if (strc
1da0: 61 73 65 63 6d 70 28 6d 65 74 68 6f 64 2c 20 22  asecmp(method, "
1db0: 67 65 74 22 29 20 21 3d 20 30 29 20 7b 0a 09 09  get") != 0) {...
1dc0: 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d  return(NULL);..}
1dd0: 0a 0a 09 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20  .../* Determine 
1de0: 72 61 6e 67 65 20 2a 2f 0a 09 69 66 20 28 72 61  range */..if (ra
1df0: 6e 67 65 5f 65 6e 64 20 21 3d 20 30 29 20 7b 0a  nge_end != 0) {.
1e00: 09 09 69 66 20 28 72 61 6e 67 65 5f 65 6e 64 20  ..if (range_end 
1e10: 3c 3d 20 72 61 6e 67 65 5f 73 74 61 72 74 29 20  <= range_start) 
1e20: 7b 0a 09 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c  {....return(NULL
1e30: 29 3b 0a 09 09 7d 0a 0a 09 09 72 61 6e 67 65 5f  );...}....range_
1e40: 6c 65 6e 67 74 68 20 3d 20 72 61 6e 67 65 5f 65  length = range_e
1e50: 6e 64 20 2d 20 72 61 6e 67 65 5f 73 74 61 72 74  nd - range_start
1e60: 3b 0a 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d  ;....filed_log_m
1e70: 73 67 5f 64 65 62 75 67 28 22 43 6f 6d 70 75 74  sg_debug("Comput
1e80: 69 6e 67 20 6c 65 6e 67 74 68 20 70 61 72 61 6d  ing length param
1e90: 65 74 65 72 3a 20 25 6c 6c 75 20 3d 20 25 6c 6c  eter: %llu = %ll
1ea0: 75 20 2d 20 25 6c 6c 75 22 2c 0a 09 09 09 28 75  u - %llu",....(u
1eb0: 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e  nsigned long lon
1ec0: 67 29 20 72 61 6e 67 65 5f 6c 65 6e 67 74 68 2c  g) range_length,
1ed0: 0a 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f  ....(unsigned lo
1ee0: 6e 67 20 6c 6f 6e 67 29 20 72 61 6e 67 65 5f 65  ng long) range_e
1ef0: 6e 64 2c 0a 09 09 09 28 75 6e 73 69 67 6e 65 64  nd,....(unsigned
1f00: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 72 61 6e 67   long long) rang
1f10: 65 5f 73 74 61 72 74 0a 09 09 29 3b 0a 09 7d 0a  e_start...);..}.
1f20: 0a 09 2f 2a 20 46 69 6c 6c 20 75 70 20 73 74 72  ../* Fill up str
1f30: 75 63 74 75 72 65 20 74 6f 20 72 65 74 75 72 6e  ucture to return
1f40: 20 2a 2f 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e   */..buffer_st->
1f50: 70 61 74 68 20 20 20 3d 20 70 61 74 68 3b 0a 09  path   = path;..
1f60: 62 75 66 66 65 72 5f 73 74 2d 3e 68 65 61 64 65  buffer_st->heade
1f70: 72 73 2e 72 61 6e 67 65 2e 70 72 65 73 65 6e 74  rs.range.present
1f80: 20 3d 20 72 61 6e 67 65 5f 72 65 71 75 65 73 74   = range_request
1f90: 3b 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 68 65  ;..buffer_st->he
1fa0: 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73  aders.range.offs
1fb0: 65 74 20 20 3d 20 72 61 6e 67 65 5f 73 74 61 72  et  = range_star
1fc0: 74 3b 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 68  t;..buffer_st->h
1fd0: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e  eaders.range.len
1fe0: 67 74 68 20 20 3d 20 72 61 6e 67 65 5f 6c 65 6e  gth  = range_len
1ff0: 67 74 68 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75  gth;...return(bu
2000: 66 66 65 72 5f 73 74 29 3b 0a 7d 0a 0a 2f 2a 20  ffer_st);.}../* 
2010: 52 65 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 20  Return an error 
2020: 70 61 67 65 20 2a 2f 0a 73 74 61 74 69 63 20 76  page */.static v
2030: 6f 69 64 20 66 69 6c 65 64 5f 65 72 72 6f 72 5f  oid filed_error_
2040: 70 61 67 65 28 46 49 4c 45 20 2a 66 70 2c 20 63  page(FILE *fp, c
2050: 6f 6e 73 74 20 63 68 61 72 20 2a 64 61 74 65 5f  onst char *date_
2060: 63 75 72 72 65 6e 74 2c 20 69 6e 74 20 65 72 72  current, int err
2070: 6f 72 5f 6e 75 6d 62 65 72 29 20 7b 0a 09 63 68  or_number) {..ch
2080: 61 72 20 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67  ar *error_string
2090: 20 3d 20 22 3c 68 74 6d 6c 3e 3c 68 65 61 64 3e   = "<html><head>
20a0: 3c 74 69 74 6c 65 3e 45 52 52 4f 52 3c 2f 74 69  <title>ERROR</ti
20b0: 74 6c 65 3e 3c 2f 68 65 61 64 3e 3c 62 6f 64 79  tle></head><body
20c0: 3e 55 6e 61 62 6c 65 20 74 6f 20 70 72 6f 63 65  >Unable to proce
20d0: 73 73 20 72 65 71 75 65 73 74 3c 2f 62 6f 64 79  ss request</body
20e0: 3e 3c 2f 68 74 6d 6c 3e 22 3b 0a 0a 09 66 70 72  ></html>";...fpr
20f0: 69 6e 74 66 28 66 70 2c 20 22 48 54 54 50 2f 31  intf(fp, "HTTP/1
2100: 2e 31 20 25 69 20 4f 4b 5c 72 5c 6e 44 61 74 65  .1 %i OK\r\nDate
2110: 3a 20 25 73 5c 72 5c 6e 53 65 72 76 65 72 3a 20  : %s\r\nServer: 
2120: 66 69 6c 65 64 5c 72 5c 6e 4c 61 73 74 2d 4d 6f  filed\r\nLast-Mo
2130: 64 69 66 69 65 64 3a 20 25 73 5c 72 5c 6e 43 6f  dified: %s\r\nCo
2140: 6e 74 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 6c  ntent-Length: %l
2150: 6c 75 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 54 79  lu\r\nContent-Ty
2160: 70 65 3a 20 25 73 5c 72 5c 6e 43 6f 6e 6e 65 63  pe: %s\r\nConnec
2170: 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e 5c  tion: close\r\n\
2180: 72 5c 6e 25 73 22 2c 0a 09 09 65 72 72 6f 72 5f  r\n%s",...error_
2190: 6e 75 6d 62 65 72 2c 0a 09 09 64 61 74 65 5f 63  number,...date_c
21a0: 75 72 72 65 6e 74 2c 0a 09 09 64 61 74 65 5f 63  urrent,...date_c
21b0: 75 72 72 65 6e 74 2c 0a 09 09 28 75 6e 73 69 67  urrent,...(unsig
21c0: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73  ned long long) s
21d0: 74 72 6c 65 6e 28 65 72 72 6f 72 5f 73 74 72 69  trlen(error_stri
21e0: 6e 67 29 2c 0a 09 09 22 74 65 78 74 2f 68 74 6d  ng),..."text/htm
21f0: 6c 22 2c 0a 09 09 65 72 72 6f 72 5f 73 74 72 69  l",...error_stri
2200: 6e 67 0a 09 29 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e  ng..);.}../* Han
2210: 64 6c 65 20 61 20 73 69 6e 67 6c 65 20 72 65 71  dle a single req
2220: 75 65 73 74 20 66 72 6f 6d 20 61 20 63 6c 69 65  uest from a clie
2230: 6e 74 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  nt */.static voi
2240: 64 20 66 69 6c 65 64 5f 68 61 6e 64 6c 65 5f 63  d filed_handle_c
2250: 6c 69 65 6e 74 28 69 6e 74 20 66 64 2c 20 73 74  lient(int fd, st
2260: 72 75 63 74 20 66 69 6c 65 64 5f 68 74 74 70 5f  ruct filed_http_
2270: 72 65 71 75 65 73 74 20 2a 72 65 71 75 65 73 74  request *request
2280: 29 20 7b 0a 09 73 74 72 75 63 74 20 66 69 6c 65  ) {..struct file
2290: 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66 69 6c 65  d_fileinfo *file
22a0: 69 6e 66 6f 3b 0a 09 73 73 69 7a 65 5f 74 20 73  info;..ssize_t s
22b0: 65 6e 64 66 69 6c 65 5f 72 65 74 3b 0a 09 73 69  endfile_ret;..si
22c0: 7a 65 5f 74 20 73 65 6e 64 66 69 6c 65 5f 6c 65  ze_t sendfile_le
22d0: 6e 2c 20 73 65 6e 64 66 69 6c 65 5f 73 65 6e 74  n, sendfile_sent
22e0: 2c 20 73 65 6e 64 66 69 6c 65 5f 73 69 7a 65 3b  , sendfile_size;
22f0: 0a 09 6f 66 66 5f 74 20 73 65 6e 64 66 69 6c 65  ..off_t sendfile
2300: 5f 6f 66 66 73 65 74 3b 0a 09 63 68 61 72 20 2a  _offset;..char *
2310: 70 61 74 68 3b 0a 09 63 68 61 72 20 2a 64 61 74  path;..char *dat
2320: 65 5f 63 75 72 72 65 6e 74 2c 20 64 61 74 65 5f  e_current, date_
2330: 63 75 72 72 65 6e 74 5f 62 5b 36 34 5d 3b 0a 09  current_b[64];..
2340: 69 6e 74 20 68 74 74 70 5f 63 6f 64 65 3b 0a 09  int http_code;..
2350: 46 49 4c 45 20 2a 66 70 3b 0a 0a 09 2f 2a 20 44  FILE *fp;.../* D
2360: 65 74 65 72 6d 69 6e 65 20 63 75 72 72 65 6e 74  etermine current
2370: 20 74 69 6d 65 20 2a 2f 0a 09 64 61 74 65 5f 63   time */..date_c
2380: 75 72 72 65 6e 74 20 3d 20 66 69 6c 65 64 5f 66  urrent = filed_f
2390: 6f 72 6d 61 74 5f 74 69 6d 65 28 64 61 74 65 5f  ormat_time(date_
23a0: 63 75 72 72 65 6e 74 5f 62 2c 20 73 69 7a 65 6f  current_b, sizeo
23b0: 66 28 64 61 74 65 5f 63 75 72 72 65 6e 74 5f 62  f(date_current_b
23c0: 29 2c 20 74 69 6d 65 28 4e 55 4c 4c 29 29 3b 0a  ), time(NULL));.
23d0: 0a 09 2f 2a 20 4f 70 65 6e 20 73 6f 63 6b 65 74  ../* Open socket
23e0: 20 61 73 20 41 4e 53 49 20 49 2f 4f 20 66 6f 72   as ANSI I/O for
23f0: 20 65 61 73 65 20 6f 66 20 75 73 65 20 2a 2f 0a   ease of use */.
2400: 09 66 70 20 3d 20 66 64 6f 70 65 6e 28 66 64 2c  .fp = fdopen(fd,
2410: 20 22 77 2b 62 22 29 3b 0a 09 69 66 20 28 66 70   "w+b");..if (fp
2420: 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 63 6c   == NULL) {...cl
2430: 6f 73 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75  ose(fd);....retu
2440: 72 6e 3b 0a 09 7d 0a 0a 09 72 65 71 75 65 73 74  rn;..}...request
2450: 20 3d 20 66 69 6c 65 64 5f 67 65 74 5f 68 74 74   = filed_get_htt
2460: 70 5f 72 65 71 75 65 73 74 28 66 70 2c 20 72 65  p_request(fp, re
2470: 71 75 65 73 74 29 3b 0a 0a 09 66 69 6c 65 64 5f  quest);...filed_
2480: 6c 6f 67 5f 6d 73 67 28 22 50 52 4f 43 45 53 53  log_msg("PROCESS
2490: 5f 52 45 50 4c 59 5f 53 54 41 52 54 20 46 44 3d  _REPLY_START FD=
24a0: 2e 2e 2e 20 50 41 54 48 3d 2e 2e 2e 20 52 41 4e  ... PATH=... RAN
24b0: 47 45 5f 53 54 41 52 54 3d 2e 2e 2e 20 52 41 4e  GE_START=... RAN
24c0: 47 45 5f 4c 45 4e 47 54 48 3d 2e 2e 2e 22 29 3b  GE_LENGTH=...");
24d0: 0a 0a 09 69 66 20 28 72 65 71 75 65 73 74 20 3d  ...if (request =
24e0: 3d 20 4e 55 4c 4c 20 7c 7c 20 72 65 71 75 65 73  = NULL || reques
24f0: 74 2d 3e 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  t->path == NULL)
2500: 20 7b 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72   {...filed_error
2510: 5f 70 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63  _page(fp, date_c
2520: 75 72 72 65 6e 74 2c 20 35 30 30 29 3b 0a 0a 09  urrent, 500);...
2530: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22  .filed_log_msg("
2540: 50 52 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f  PROCESS_REPLY_CO
2550: 4d 50 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52  MPLETE FD=... ER
2560: 52 4f 52 3d 35 30 30 22 29 3b 0a 0a 09 09 66 63  ROR=500");....fc
2570: 6c 6f 73 65 28 66 70 29 3b 0a 0a 09 09 72 65 74  lose(fp);....ret
2580: 75 72 6e 3b 0a 09 7d 0a 0a 09 70 61 74 68 20 3d  urn;..}...path =
2590: 20 72 65 71 75 65 73 74 2d 3e 70 61 74 68 3b 0a   request->path;.
25a0: 0a 09 68 74 74 70 5f 63 6f 64 65 20 3d 20 2d 31  ..http_code = -1
25b0: 3b 0a 0a 09 66 69 6c 65 69 6e 66 6f 20 3d 20 66  ;...fileinfo = f
25c0: 69 6c 65 64 5f 6f 70 65 6e 5f 66 69 6c 65 28 70  iled_open_file(p
25d0: 61 74 68 2c 20 26 72 65 71 75 65 73 74 2d 3e 66  ath, &request->f
25e0: 69 6c 65 69 6e 66 6f 29 3b 0a 09 69 66 20 28 66  ileinfo);..if (f
25f0: 69 6c 65 69 6e 66 6f 20 3d 3d 20 4e 55 4c 4c 29  ileinfo == NULL)
2600: 20 7b 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72   {...filed_error
2610: 5f 70 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63  _page(fp, date_c
2620: 75 72 72 65 6e 74 2c 20 34 30 34 29 3b 0a 0a 09  urrent, 404);...
2630: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22  .filed_log_msg("
2640: 50 52 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f  PROCESS_REPLY_CO
2650: 4d 50 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52  MPLETE FD=... ER
2660: 52 4f 52 3d 34 30 34 22 29 3b 0a 09 7d 20 65 6c  ROR=404");..} el
2670: 73 65 20 7b 0a 09 09 69 66 20 28 72 65 71 75 65  se {...if (reque
2680: 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67  st->headers.rang
2690: 65 2e 6f 66 66 73 65 74 20 21 3d 20 30 20 7c 7c  e.offset != 0 ||
26a0: 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72   request->header
26b0: 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3e  s.range.length >
26c0: 3d 20 30 29 20 7b 0a 09 09 09 69 66 20 28 72 65  = 0) {....if (re
26d0: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72  quest->headers.r
26e0: 61 6e 67 65 2e 6f 66 66 73 65 74 20 3e 3d 20 66  ange.offset >= f
26f0: 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 29 20 7b 0a  ileinfo->len) {.
2700: 09 09 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  ....filed_log_ms
2710: 67 28 22 50 52 4f 43 45 53 53 5f 52 45 50 4c 59  g("PROCESS_REPLY
2720: 5f 43 4f 4d 50 4c 45 54 45 20 46 44 3d 2e 2e 2e  _COMPLETE FD=...
2730: 20 45 52 52 4f 52 3d 34 31 36 22 29 3b 0a 0a 09   ERROR=416");...
2740: 09 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70  ...filed_error_p
2750: 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72  age(fp, date_cur
2760: 72 65 6e 74 2c 20 34 31 36 29 3b 0a 09 09 09 7d  rent, 416);....}
2770: 20 65 6c 73 65 20 7b 0a 09 09 09 09 69 66 20 28   else {.....if (
2780: 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73  request->headers
2790: 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3c 20  .range.length < 
27a0: 30 29 20 7b 0a 09 09 09 09 09 66 69 6c 65 64 5f  0) {......filed_
27b0: 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 43  log_msg_debug("C
27c0: 6f 6d 70 75 74 69 6e 67 20 6c 65 6e 67 74 68 20  omputing length 
27d0: 74 6f 20 66 69 74 20 69 6e 20 62 6f 75 6e 64 73  to fit in bounds
27e0: 3a 20 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 20  : fileinfo->len 
27f0: 3d 20 25 6c 6c 75 2c 20 72 65 71 75 65 73 74 2d  = %llu, request-
2800: 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f  >headers.range.o
2810: 66 66 73 65 74 20 3d 20 25 6c 6c 75 22 2c 0a 09  ffset = %llu",..
2820: 09 09 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c  .....(unsigned l
2830: 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 6c 65 69 6e  ong long) filein
2840: 66 6f 2d 3e 6c 65 6e 2c 0a 09 09 09 09 09 09 28  fo->len,.......(
2850: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
2860: 6e 67 29 20 72 65 71 75 65 73 74 2d 3e 68 65 61  ng) request->hea
2870: 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65  ders.range.offse
2880: 74 0a 09 09 09 09 09 29 3b 0a 0a 09 09 09 09 09  t......);.......
2890: 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73  request->headers
28a0: 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3d 20  .range.length = 
28b0: 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 20 2d 20  fileinfo->len - 
28c0: 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73  request->headers
28d0: 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74 3b 0a 09  .range.offset;..
28e0: 09 09 09 7d 0a 0a 09 09 09 09 66 69 6c 65 64 5f  ...}......filed_
28f0: 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 50  log_msg_debug("P
2900: 61 72 74 69 61 6c 20 72 65 71 75 65 73 74 2c 20  artial request, 
2910: 73 74 61 72 74 69 6e 67 20 61 74 3a 20 25 6c 6c  starting at: %ll
2920: 75 20 61 6e 64 20 72 75 6e 6e 69 6e 67 20 66 6f  u and running fo
2930: 72 20 25 6c 6c 75 20 62 79 74 65 73 22 2c 0a 09  r %llu bytes",..
2940: 09 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f  ....(unsigned lo
2950: 6e 67 20 6c 6f 6e 67 29 20 72 65 71 75 65 73 74  ng long) request
2960: 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e  ->headers.range.
2970: 6f 66 66 73 65 74 2c 0a 09 09 09 09 09 28 75 6e  offset,......(un
2980: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
2990: 29 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65  ) request->heade
29a0: 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 0a  rs.range.length.
29b0: 09 09 09 09 29 3b 0a 0a 09 09 09 09 68 74 74 70  ....);......http
29c0: 5f 63 6f 64 65 20 3d 20 32 30 36 3b 0a 09 09 09  _code = 206;....
29d0: 7d 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  }...} else {....
29e0: 69 66 20 28 72 65 71 75 65 73 74 2d 3e 68 65 61  if (request->hea
29f0: 64 65 72 73 2e 72 61 6e 67 65 2e 70 72 65 73 65  ders.range.prese
2a00: 6e 74 29 20 7b 0a 09 09 09 09 68 74 74 70 5f 63  nt) {.....http_c
2a10: 6f 64 65 20 3d 20 32 30 36 3b 0a 09 09 09 7d 20  ode = 206;....} 
2a20: 65 6c 73 65 20 7b 0a 09 09 09 09 68 74 74 70 5f  else {.....http_
2a30: 63 6f 64 65 20 3d 20 32 30 30 3b 0a 09 09 09 7d  code = 200;....}
2a40: 0a 09 09 09 72 65 71 75 65 73 74 2d 3e 68 65 61  ....request->hea
2a50: 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65  ders.range.offse
2a60: 74 20 3d 20 30 3b 0a 09 09 09 72 65 71 75 65 73  t = 0;....reques
2a70: 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65  t->headers.range
2a80: 2e 6c 65 6e 67 74 68 20 3d 20 66 69 6c 65 69 6e  .length = filein
2a90: 66 6f 2d 3e 6c 65 6e 3b 0a 09 09 7d 0a 0a 09 09  fo->len;...}....
2aa0: 69 66 20 28 68 74 74 70 5f 63 6f 64 65 20 3e 20  if (http_code > 
2ab0: 30 29 20 7b 0a 09 09 09 66 70 72 69 6e 74 66 28  0) {....fprintf(
2ac0: 66 70 2c 20 22 48 54 54 50 2f 31 2e 31 20 25 69  fp, "HTTP/1.1 %i
2ad0: 20 4f 4b 5c 72 5c 6e 44 61 74 65 3a 20 25 73 5c   OK\r\nDate: %s\
2ae0: 72 5c 6e 53 65 72 76 65 72 3a 20 66 69 6c 65 64  r\nServer: filed
2af0: 5c 72 5c 6e 4c 61 73 74 2d 4d 6f 64 69 66 69 65  \r\nLast-Modifie
2b00: 64 3a 20 25 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74  d: %s\r\nContent
2b10: 2d 4c 65 6e 67 74 68 3a 20 25 6c 6c 75 5c 72 5c  -Length: %llu\r\
2b20: 6e 41 63 63 65 70 74 2d 52 61 6e 67 65 73 3a 20  nAccept-Ranges: 
2b30: 62 79 74 65 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74  bytes\r\nContent
2b40: 2d 54 79 70 65 3a 20 25 73 5c 72 5c 6e 43 6f 6e  -Type: %s\r\nCon
2b50: 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72  nection: close\r
2b60: 5c 6e 22 2c 0a 09 09 09 09 68 74 74 70 5f 63 6f  \n",.....http_co
2b70: 64 65 2c 0a 09 09 09 09 64 61 74 65 5f 63 75 72  de,.....date_cur
2b80: 72 65 6e 74 2c 0a 09 09 09 09 66 69 6c 65 69 6e  rent,.....filein
2b90: 66 6f 2d 3e 6c 61 73 74 6d 6f 64 2c 0a 09 09 09  fo->lastmod,....
2ba0: 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20  .(unsigned long 
2bb0: 6c 6f 6e 67 29 20 72 65 71 75 65 73 74 2d 3e 68  long) request->h
2bc0: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e  eaders.range.len
2bd0: 67 74 68 2c 0a 09 09 09 09 66 69 6c 65 69 6e 66  gth,.....fileinf
2be0: 6f 2d 3e 74 79 70 65 0a 09 09 09 29 3b 0a 09 09  o->type....);...
2bf0: 09 69 66 20 28 68 74 74 70 5f 63 6f 64 65 20 3d  .if (http_code =
2c00: 3d 20 32 30 36 29 20 7b 0a 09 09 09 09 66 70 72  = 206) {.....fpr
2c10: 69 6e 74 66 28 66 70 2c 20 22 43 6f 6e 74 65 6e  intf(fp, "Conten
2c20: 74 2d 52 61 6e 67 65 3a 20 62 79 74 65 73 20 25  t-Range: bytes %
2c30: 6c 6c 75 2d 25 6c 6c 75 2f 25 6c 6c 75 5c 72 5c  llu-%llu/%llu\r\
2c40: 6e 22 2c 0a 09 09 09 09 09 28 75 6e 73 69 67 6e  n",......(unsign
2c50: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 72 65  ed long long) re
2c60: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72  quest->headers.r
2c70: 61 6e 67 65 2e 6f 66 66 73 65 74 2c 0a 09 09 09  ange.offset,....
2c80: 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  ..(unsigned long
2c90: 20 6c 6f 6e 67 29 20 28 72 65 71 75 65 73 74 2d   long) (request-
2ca0: 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f  >headers.range.o
2cb0: 66 66 73 65 74 20 2b 20 72 65 71 75 65 73 74 2d  ffset + request-
2cc0: 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c  >headers.range.l
2cd0: 65 6e 67 74 68 20 2d 20 31 29 2c 0a 09 09 09 09  ength - 1),.....
2ce0: 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20  .(unsigned long 
2cf0: 6c 6f 6e 67 29 20 66 69 6c 65 69 6e 66 6f 2d 3e  long) fileinfo->
2d00: 6c 65 6e 0a 09 09 09 09 29 3b 0a 09 09 09 7d 0a  len.....);....}.
2d10: 09 09 09 66 70 72 69 6e 74 66 28 66 70 2c 20 22  ...fprintf(fp, "
2d20: 5c 72 5c 6e 22 29 3b 0a 09 09 09 66 66 6c 75 73  \r\n");....fflus
2d30: 68 28 66 70 29 3b 0a 0a 09 09 09 66 69 6c 65 64  h(fp);.....filed
2d40: 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f 43 45 53  _log_msg("PROCES
2d50: 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 4c 45 54 45  S_REPLY_COMPLETE
2d60: 20 46 44 3d 2e 2e 2e 20 53 54 41 54 55 53 3d 32   FD=... STATUS=2
2d70: 30 58 22 29 3b 0a 0a 23 69 66 64 65 66 20 46 49  0X");..#ifdef FI
2d80: 4c 45 44 5f 4e 4f 4e 42 4c 4f 43 4b 5f 48 54 54  LED_NONBLOCK_HTT
2d90: 50 0a 09 09 09 69 6e 74 20 73 6f 63 6b 65 74 5f  P....int socket_
2da0: 66 6c 61 67 73 3b 0a 09 09 09 66 64 5f 73 65 74  flags;....fd_set
2db0: 20 72 66 64 2c 20 77 66 64 3b 0a 09 09 09 63 68   rfd, wfd;....ch
2dc0: 61 72 20 73 69 6e 6b 62 75 66 5b 38 31 39 32 5d  ar sinkbuf[8192]
2dd0: 3b 0a 09 09 09 73 73 69 7a 65 5f 74 20 72 65 61  ;....ssize_t rea
2de0: 64 5f 72 65 74 3b 0a 0a 09 09 09 46 44 5f 5a 45  d_ret;.....FD_ZE
2df0: 52 4f 28 26 72 66 64 29 3b 0a 09 09 09 46 44 5f  RO(&rfd);....FD_
2e00: 5a 45 52 4f 28 26 77 66 64 29 3b 0a 09 09 09 46  ZERO(&wfd);....F
2e10: 44 5f 53 45 54 28 66 64 2c 20 26 72 66 64 29 3b  D_SET(fd, &rfd);
2e20: 0a 09 09 09 46 44 5f 53 45 54 28 66 64 2c 20 26  ....FD_SET(fd, &
2e30: 77 66 64 29 3b 0a 0a 09 09 09 73 6f 63 6b 65 74  wfd);.....socket
2e40: 5f 66 6c 61 67 73 20 3d 20 66 63 6e 74 6c 28 66  _flags = fcntl(f
2e50: 64 2c 20 46 5f 47 45 54 46 4c 29 3b 0a 09 09 09  d, F_GETFL);....
2e60: 66 63 6e 74 6c 28 66 64 2c 20 46 5f 53 45 54 46  fcntl(fd, F_SETF
2e70: 4c 2c 20 73 6f 63 6b 65 74 5f 66 6c 61 67 73 20  L, socket_flags 
2e80: 7c 20 4f 5f 4e 4f 4e 42 4c 4f 43 4b 29 3b 0a 23  | O_NONBLOCK);.#
2e90: 65 6e 64 69 66 0a 0a 09 09 09 66 69 6c 65 64 5f  endif.....filed_
2ea0: 6c 6f 67 5f 6d 73 67 28 22 53 45 4e 44 5f 53 54  log_msg("SEND_ST
2eb0: 41 52 54 20 49 46 44 3d 2e 2e 2e 20 4f 46 44 3d  ART IFD=... OFD=
2ec0: 2e 2e 2e 20 42 59 54 45 53 3d 2e 2e 2e 22 29 3b  ... BYTES=...");
2ed0: 0a 0a 09 09 09 73 65 6e 64 66 69 6c 65 5f 6f 66  .....sendfile_of
2ee0: 66 73 65 74 20 3d 20 72 65 71 75 65 73 74 2d 3e  fset = request->
2ef0: 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66  headers.range.of
2f00: 66 73 65 74 3b 0a 09 09 09 73 65 6e 64 66 69 6c  fset;....sendfil
2f10: 65 5f 6c 65 6e 20 3d 20 72 65 71 75 65 73 74 2d  e_len = request-
2f20: 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c  >headers.range.l
2f30: 65 6e 67 74 68 3b 0a 09 09 09 73 65 6e 64 66 69  ength;....sendfi
2f40: 6c 65 5f 73 65 6e 74 20 3d 20 30 3b 0a 09 09 09  le_sent = 0;....
2f50: 77 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 09 09  while (1) {.....
2f60: 69 66 20 28 73 65 6e 64 66 69 6c 65 5f 6c 65 6e  if (sendfile_len
2f70: 20 3e 20 46 49 4c 45 44 5f 53 45 4e 44 46 49 4c   > FILED_SENDFIL
2f80: 45 5f 4d 41 58 29 20 7b 0a 09 09 09 09 09 73 65  E_MAX) {......se
2f90: 6e 64 66 69 6c 65 5f 73 69 7a 65 20 3d 20 46 49  ndfile_size = FI
2fa0: 4c 45 44 5f 53 45 4e 44 46 49 4c 45 5f 4d 41 58  LED_SENDFILE_MAX
2fb0: 3b 0a 09 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09  ;.....} else {..
2fc0: 09 09 09 09 73 65 6e 64 66 69 6c 65 5f 73 69 7a  ....sendfile_siz
2fd0: 65 20 3d 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e  e = sendfile_len
2fe0: 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 73 65 6e  ;.....}......sen
2ff0: 64 66 69 6c 65 5f 72 65 74 20 3d 20 73 65 6e 64  dfile_ret = send
3000: 66 69 6c 65 28 66 64 2c 20 66 69 6c 65 69 6e 66  file(fd, fileinf
3010: 6f 2d 3e 66 64 2c 20 26 73 65 6e 64 66 69 6c 65  o->fd, &sendfile
3020: 5f 6f 66 66 73 65 74 2c 20 73 65 6e 64 66 69 6c  _offset, sendfil
3030: 65 5f 73 69 7a 65 29 3b 0a 09 09 09 09 69 66 20  e_size);.....if 
3040: 28 73 65 6e 64 66 69 6c 65 5f 72 65 74 20 3c 3d  (sendfile_ret <=
3050: 20 30 29 20 7b 0a 23 69 66 64 65 66 20 46 49 4c   0) {.#ifdef FIL
3060: 45 44 5f 4e 4f 4e 42 4c 4f 43 4b 5f 48 54 54 50  ED_NONBLOCK_HTTP
3070: 0a 09 09 09 09 09 69 66 20 28 65 72 72 6e 6f 20  ......if (errno 
3080: 3d 3d 20 45 41 47 41 49 4e 29 20 7b 0a 09 09 09  == EAGAIN) {....
3090: 09 09 09 73 65 6e 64 66 69 6c 65 5f 72 65 74 20  ...sendfile_ret 
30a0: 3d 20 30 3b 0a 0a 09 09 09 09 09 09 77 68 69 6c  = 0;........whil
30b0: 65 20 28 31 29 20 7b 0a 09 09 09 09 09 09 09 73  e (1) {........s
30c0: 65 6c 65 63 74 28 66 64 20 2b 20 31 2c 20 26 72  elect(fd + 1, &r
30d0: 66 64 2c 20 26 77 66 64 2c 20 4e 55 4c 4c 2c 20  fd, &wfd, NULL, 
30e0: 4e 55 4c 4c 29 3b 0a 09 09 09 09 09 09 09 69 66  NULL);........if
30f0: 20 28 46 44 5f 49 53 53 45 54 28 66 64 2c 20 26   (FD_ISSET(fd, &
3100: 72 66 64 29 29 20 7b 0a 09 09 09 09 09 09 09 09  rfd)) {.........
3110: 72 65 61 64 5f 72 65 74 20 3d 20 72 65 61 64 28  read_ret = read(
3120: 66 64 2c 20 73 69 6e 6b 62 75 66 2c 20 73 69 7a  fd, sinkbuf, siz
3130: 65 6f 66 28 73 69 6e 6b 62 75 66 29 29 3b 0a 0a  eof(sinkbuf));..
3140: 09 09 09 09 09 09 09 09 69 66 20 28 72 65 61 64  ........if (read
3150: 5f 72 65 74 20 3c 3d 20 30 29 20 7b 0a 09 09 09  _ret <= 0) {....
3160: 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09  ......break;....
3170: 09 09 09 09 09 7d 0a 09 09 09 09 09 09 09 7d 0a  .....}........}.
3180: 0a 09 09 09 09 09 09 09 69 66 20 28 46 44 5f 49  ........if (FD_I
3190: 53 53 45 54 28 66 64 2c 20 26 77 66 64 29 29 20  SSET(fd, &wfd)) 
31a0: 7b 0a 09 09 09 09 09 09 09 09 72 65 61 64 5f 72  {.........read_r
31b0: 65 74 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09  et = 1;.........
31c0: 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 09 7d  .break;........}
31d0: 0a 09 09 09 09 09 09 7d 0a 0a 09 09 09 09 09 09  .......}........
31e0: 69 66 20 28 72 65 61 64 5f 72 65 74 20 3c 3d 20  if (read_ret <= 
31f0: 30 29 20 7b 0a 09 09 09 09 09 09 09 62 72 65 61  0) {........brea
3200: 6b 3b 0a 09 09 09 09 09 09 7d 0a 09 09 09 09 09  k;.......}......
3210: 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09 09 62  } else {.......b
3220: 72 65 61 6b 3b 0a 09 09 09 09 09 7d 0a 23 65 6c  reak;......}.#el
3230: 73 65 0a 09 09 09 09 09 62 72 65 61 6b 3b 0a 23  se......break;.#
3240: 65 6e 64 69 66 0a 09 09 09 09 7d 0a 0a 09 09 09  endif.....}.....
3250: 09 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 2d 3d  .sendfile_len -=
3260: 20 73 65 6e 64 66 69 6c 65 5f 72 65 74 3b 0a 09   sendfile_ret;..
3270: 09 09 09 73 65 6e 64 66 69 6c 65 5f 73 65 6e 74  ...sendfile_sent
3280: 20 2b 3d 20 73 65 6e 64 66 69 6c 65 5f 72 65 74   += sendfile_ret
3290: 3b 0a 09 09 09 09 69 66 20 28 73 65 6e 64 66 69  ;.....if (sendfi
32a0: 6c 65 5f 6c 65 6e 20 3d 3d 20 30 29 20 7b 0a 09  le_len == 0) {..
32b0: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 7d  ....break;.....}
32c0: 0a 09 09 09 7d 0a 0a 09 09 09 66 69 6c 65 64 5f  ....}.....filed_
32d0: 6c 6f 67 5f 6d 73 67 28 22 53 45 4e 44 5f 43 4f  log_msg("SEND_CO
32e0: 4d 50 4c 45 54 45 20 53 54 41 54 55 53 3d 2e 2e  MPLETE STATUS=..
32f0: 2e 20 49 46 44 3d 2e 2e 2e 20 4f 46 44 3d 2e 2e  . IFD=... OFD=..
3300: 2e 20 42 59 54 45 53 3d 2e 2e 2e 20 42 59 54 45  . BYTES=... BYTE
3310: 53 5f 53 45 4e 54 3d 2e 2e 2e 22 29 3b 0a 09 09  S_SENT=...");...
3320: 7d 0a 0a 09 09 63 6c 6f 73 65 28 66 69 6c 65 69  }....close(filei
3330: 6e 66 6f 2d 3e 66 64 29 3b 0a 0a 09 09 66 69 6c  nfo->fd);....fil
3340: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 43 4c 4f 53  ed_log_msg("CLOS
3350: 45 5f 46 49 4c 45 20 46 44 3d 2e 2e 2e 22 29 3b  E_FILE FD=...");
3360: 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f  ..}...filed_log_
3370: 6d 73 67 28 22 43 4c 4f 53 45 5f 43 4f 4e 4e 45  msg("CLOSE_CONNE
3380: 43 54 49 4f 4e 20 46 44 3d 2e 2e 2e 22 29 3b 0a  CTION FD=...");.
3390: 0a 09 66 63 6c 6f 73 65 28 66 70 29 3b 0a 0a 09  ..fclose(fp);...
33a0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 48 61  return;.}../* Ha
33b0: 6e 64 6c 65 20 69 6e 63 6f 6d 69 6e 67 20 63 6f  ndle incoming co
33c0: 6e 6e 65 63 74 69 6f 6e 73 20 2a 2f 0a 73 74 61  nnections */.sta
33d0: 74 69 63 20 76 6f 69 64 20 2a 66 69 6c 65 64 5f  tic void *filed_
33e0: 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 28 76 6f  worker_thread(vo
33f0: 69 64 20 2a 61 72 67 5f 76 29 20 7b 0a 09 73 74  id *arg_v) {..st
3400: 72 75 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65  ruct filed_worke
3410: 72 5f 74 68 72 65 61 64 5f 61 72 67 73 20 2a 61  r_thread_args *a
3420: 72 67 3b 0a 09 73 74 72 75 63 74 20 66 69 6c 65  rg;..struct file
3430: 64 5f 68 74 74 70 5f 72 65 71 75 65 73 74 20 72  d_http_request r
3440: 65 71 75 65 73 74 3b 0a 09 73 74 72 75 63 74 20  equest;..struct 
3450: 73 6f 63 6b 61 64 64 72 5f 69 6e 36 20 61 64 64  sockaddr_in6 add
3460: 72 3b 0a 09 73 6f 63 6b 6c 65 6e 5f 74 20 61 64  r;..socklen_t ad
3470: 64 72 6c 65 6e 3b 0a 09 69 6e 74 20 66 61 69 6c  drlen;..int fail
3480: 75 72 65 5f 63 6f 75 6e 74 20 3d 20 30 2c 20 6d  ure_count = 0, m
3490: 61 78 5f 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74  ax_failure_count
34a0: 20 3d 20 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43   = MAX_FAILURE_C
34b0: 4f 55 4e 54 3b 0a 09 69 6e 74 20 6d 61 73 74 65  OUNT;..int maste
34c0: 72 5f 66 64 2c 20 66 64 3b 0a 0a 09 2f 2a 20 52  r_fd, fd;.../* R
34d0: 65 61 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f  ead arguments */
34e0: 0a 09 61 72 67 20 3d 20 61 72 67 5f 76 3b 0a 0a  ..arg = arg_v;..
34f0: 09 6d 61 73 74 65 72 5f 66 64 20 3d 20 61 72 67  .master_fd = arg
3500: 2d 3e 66 64 3b 0a 0a 09 77 68 69 6c 65 20 28 31  ->fd;...while (1
3510: 29 20 7b 0a 09 09 2f 2a 20 46 61 69 6c 75 72 65  ) {.../* Failure
3520: 20 6c 6f 6f 70 20 70 72 65 76 65 6e 74 69 6f 6e   loop prevention
3530: 20 2a 2f 0a 09 09 69 66 20 28 66 61 69 6c 75 72   */...if (failur
3540: 65 5f 63 6f 75 6e 74 20 3e 20 6d 61 78 5f 66 61  e_count > max_fa
3550: 69 6c 75 72 65 5f 63 6f 75 6e 74 29 20 7b 0a 09  ilure_count) {..
3560: 09 09 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09  ..break;...}....
3570: 2f 2a 20 41 63 63 65 70 74 20 61 20 6e 65 77 20  /* Accept a new 
3580: 63 6c 69 65 6e 74 20 2a 2f 0a 09 09 61 64 64 72  client */...addr
3590: 6c 65 6e 20 3d 20 73 69 7a 65 6f 66 28 61 64 64  len = sizeof(add
35a0: 72 29 3b 0a 09 09 66 64 20 3d 20 61 63 63 65 70  r);...fd = accep
35b0: 74 28 6d 61 73 74 65 72 5f 66 64 2c 20 28 73 74  t(master_fd, (st
35c0: 72 75 63 74 20 73 6f 63 6b 61 64 64 72 20 2a 29  ruct sockaddr *)
35d0: 20 26 61 64 64 72 2c 20 26 61 64 64 72 6c 65 6e   &addr, &addrlen
35e0: 29 3b 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 49 66  );..../*... * If
35f0: 20 77 65 20 66 61 69 6c 2c 20 6d 61 6b 65 20 61   we fail, make a
3600: 20 6e 6f 74 65 20 6f 66 20 69 74 20 73 6f 20 77   note of it so w
3610: 65 20 64 6f 6e 27 74 20 67 6f 20 69 6e 74 6f 20  e don't go into 
3620: 61 20 6c 6f 6f 70 20 6f 66 0a 09 09 20 2a 20 61  a loop of... * a
3630: 63 63 65 70 74 28 29 20 66 61 69 6c 69 6e 67 0a  ccept() failing.
3640: 09 09 20 2a 2f 0a 09 09 69 66 20 28 66 64 20 3c  .. */...if (fd <
3650: 20 30 29 20 7b 0a 09 09 09 2f 2a 20 4c 6f 67 20   0) {..../* Log 
3660: 74 68 65 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69  the new connecti
3670: 6f 6e 20 2a 2f 0a 09 09 09 66 69 6c 65 64 5f 6c  on */....filed_l
3680: 6f 67 5f 6d 73 67 28 22 41 43 43 45 50 54 5f 46  og_msg("ACCEPT_F
3690: 41 49 4c 45 44 22 29 3b 0a 0a 09 09 09 66 61 69  AILED");.....fai
36a0: 6c 75 72 65 5f 63 6f 75 6e 74 2b 2b 3b 0a 0a 09  lure_count++;...
36b0: 09 09 63 6f 6e 74 69 6e 75 65 3b 0a 09 09 7d 0a  ..continue;...}.
36c0: 0a 09 09 2f 2a 20 4c 6f 67 20 74 68 65 20 6e 65  .../* Log the ne
36d0: 77 20 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a  w connection */.
36e0: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
36f0: 22 4e 45 57 5f 43 4f 4e 4e 45 43 54 49 4f 4e 20  "NEW_CONNECTION 
3700: 53 52 43 5f 41 44 44 52 3d 2e 2e 2e 20 53 52 43  SRC_ADDR=... SRC
3710: 5f 50 4f 52 54 3d 2e 2e 2e 20 46 44 3d 2e 2e 2e  _PORT=... FD=...
3720: 22 29 3b 0a 0a 09 09 2f 2a 20 52 65 73 65 74 20  ");..../* Reset 
3730: 66 61 69 6c 75 72 65 20 63 6f 75 6e 74 2a 2f 0a  failure count*/.
3740: 09 09 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20  ..failure_count 
3750: 3d 20 30 3b 0a 0a 09 09 2f 2a 20 48 61 6e 64 6c  = 0;..../* Handl
3760: 65 20 73 6f 63 6b 65 74 20 2a 2f 0a 09 09 66 69  e socket */...fi
3770: 6c 65 64 5f 68 61 6e 64 6c 65 5f 63 6c 69 65 6e  led_handle_clien
3780: 74 28 66 64 2c 20 26 72 65 71 75 65 73 74 29 3b  t(fd, &request);
3790: 0a 09 7d 0a 0a 09 2f 2a 20 52 65 70 6f 72 74 20  ..}.../* Report 
37a0: 65 72 72 6f 72 20 2a 2f 0a 09 66 69 6c 65 64 5f  error */..filed_
37b0: 6c 6f 67 5f 6d 73 67 28 22 54 48 52 45 41 44 5f  log_msg("THREAD_
37c0: 44 49 45 44 20 41 42 4e 4f 52 4d 41 4c 22 29 3b  DIED ABNORMAL");
37d0: 0a 0a 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
37e0: 0a 7d 0a 0a 2f 2a 20 43 72 65 61 74 65 20 77 6f  .}../* Create wo
37f0: 72 6b 65 72 20 74 68 72 65 61 64 73 20 2a 2f 0a  rker threads */.
3800: 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64  static int filed
3810: 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 73 5f  _worker_threads_
3820: 69 6e 69 74 28 69 6e 74 20 66 64 2c 20 69 6e 74  init(int fd, int
3830: 20 74 68 72 65 61 64 5f 63 6f 75 6e 74 29 20 7b   thread_count) {
3840: 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f 77  ..struct filed_w
3850: 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f 61 72 67  orker_thread_arg
3860: 73 20 2a 61 72 67 3b 0a 09 70 74 68 72 65 61 64  s *arg;..pthread
3870: 5f 74 20 74 68 72 65 61 64 69 64 3b 0a 09 69 6e  _t threadid;..in
3880: 74 20 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 09  t pthread_ret;..
3890: 69 6e 74 20 69 3b 0a 0a 09 66 6f 72 20 28 69 20  int i;...for (i 
38a0: 3d 20 30 3b 20 69 20 3c 20 74 68 72 65 61 64 5f  = 0; i < thread_
38b0: 63 6f 75 6e 74 3b 20 69 2b 2b 29 20 7b 0a 09 09  count; i++) {...
38c0: 61 72 67 20 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a  arg = malloc(siz
38d0: 65 6f 66 28 2a 61 72 67 29 29 3b 0a 0a 09 09 61  eof(*arg));....a
38e0: 72 67 2d 3e 66 64 20 3d 20 66 64 3b 0a 0a 09 09  rg->fd = fd;....
38f0: 70 74 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74  pthread_ret = pt
3900: 68 72 65 61 64 5f 63 72 65 61 74 65 28 26 74 68  hread_create(&th
3910: 72 65 61 64 69 64 2c 20 4e 55 4c 4c 2c 20 66 69  readid, NULL, fi
3920: 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61  led_worker_threa
3930: 64 2c 20 61 72 67 29 3b 0a 09 09 69 66 20 28 70  d, arg);...if (p
3940: 74 68 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29  thread_ret != 0)
3950: 20 7b 0a 09 09 09 72 65 74 75 72 6e 28 2d 31 29   {....return(-1)
3960: 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72  ;...}..}...retur
3970: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 52 75 6e 20  n(0);.}../* Run 
3980: 70 72 6f 63 65 73 73 20 2a 2f 0a 69 6e 74 20 6d  process */.int m
3990: 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68  ain(int argc, ch
39a0: 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09 69 6e  ar **argv) {..in
39b0: 74 20 70 6f 72 74 20 3d 20 50 4f 52 54 2c 20 74  t port = PORT, t
39c0: 68 72 65 61 64 5f 63 6f 75 6e 74 20 3d 20 54 48  hread_count = TH
39d0: 52 45 41 44 5f 43 4f 55 4e 54 3b 0a 09 63 6f 6e  READ_COUNT;..con
39e0: 73 74 20 63 68 61 72 20 2a 62 69 6e 64 5f 61 64  st char *bind_ad
39f0: 64 72 20 3d 20 42 49 4e 44 5f 41 44 44 52 3b 0a  dr = BIND_ADDR;.
3a00: 09 69 6e 74 20 69 6e 69 74 5f 72 65 74 3b 0a 09  .int init_ret;..
3a10: 69 6e 74 20 66 64 3b 0a 0a 09 2f 2a 20 58 58 58  int fd;.../* XXX
3a20: 3a 20 54 4f 44 4f 3a 20 50 72 6f 63 65 73 73 20  : TODO: Process 
3a30: 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 09 61 72  arguments */..ar
3a40: 67 63 20 3d 20 61 72 67 63 3b 0a 09 61 72 67 76  gc = argc;..argv
3a50: 20 3d 20 61 72 67 76 3b 0a 0a 09 2f 2a 20 43 72   = argv;.../* Cr
3a60: 65 61 74 65 20 6c 69 73 74 65 6e 69 6e 67 20 73  eate listening s
3a70: 6f 63 6b 65 74 20 2a 2f 0a 09 66 64 20 3d 20 66  ocket */..fd = f
3a80: 69 6c 65 64 5f 6c 69 73 74 65 6e 28 62 69 6e 64  iled_listen(bind
3a90: 5f 61 64 64 72 2c 20 70 6f 72 74 29 3b 0a 09 69  _addr, port);..i
3aa0: 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 70  f (fd < 0) {...p
3ab0: 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 6c 69 73  error("filed_lis
3ac0: 74 65 6e 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e  ten");....return
3ad0: 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 42 65 63  (1);..}.../* Bec
3ae0: 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 20 2a 2f 0a  ome a daemon */.
3af0: 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20 42 65  ./* XXX:TODO: Be
3b00: 63 6f 6d 65 20 61 20 64 61 65 6d 6f 6e 20 2a 2f  come a daemon */
3b10: 0a 0a 09 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65  .../* Initialize
3b20: 20 2a 2f 0a 09 69 6e 69 74 5f 72 65 74 20 3d 20   */..init_ret = 
3b30: 66 69 6c 65 64 5f 69 6e 69 74 28 29 3b 0a 09 69  filed_init();..i
3b40: 66 20 28 69 6e 69 74 5f 72 65 74 20 21 3d 20 30  f (init_ret != 0
3b50: 29 20 7b 0a 09 09 70 65 72 72 6f 72 28 22 66 69  ) {...perror("fi
3b60: 6c 65 64 5f 69 6e 69 74 22 29 3b 0a 0a 09 09 72  led_init");....r
3b70: 65 74 75 72 6e 28 33 29 3b 0a 09 7d 0a 0a 09 2f  eturn(3);..}.../
3b80: 2a 20 43 72 65 61 74 65 20 6c 6f 67 67 69 6e 67  * Create logging
3b90: 20 74 68 72 65 61 64 20 2a 2f 0a 09 69 6e 69 74   thread */..init
3ba0: 5f 72 65 74 20 3d 20 66 69 6c 65 64 5f 6c 6f 67  _ret = filed_log
3bb0: 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e 69 74  ging_thread_init
3bc0: 28 29 3b 0a 09 69 66 20 28 69 6e 69 74 5f 72 65  ();..if (init_re
3bd0: 74 20 21 3d 20 30 29 20 7b 0a 09 09 70 65 72 72  t != 0) {...perr
3be0: 6f 72 28 22 66 69 6c 65 64 5f 6c 6f 67 67 69 6e  or("filed_loggin
3bf0: 67 5f 74 68 72 65 61 64 5f 69 6e 69 74 22 29 3b  g_thread_init");
3c00: 0a 0a 09 09 72 65 74 75 72 6e 28 34 29 3b 0a 09  ....return(4);..
3c10: 7d 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20 77 6f  }.../* Create wo
3c20: 72 6b 65 72 20 74 68 72 65 61 64 73 20 2a 2f 0a  rker threads */.
3c30: 09 69 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65  .init_ret = file
3c40: 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 73  d_worker_threads
3c50: 5f 69 6e 69 74 28 66 64 2c 20 74 68 72 65 61 64  _init(fd, thread
3c60: 5f 63 6f 75 6e 74 29 3b 0a 09 69 66 20 28 69 6e  _count);..if (in
3c70: 69 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09  it_ret != 0) {..
3c80: 09 70 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 77  .perror("filed_w
3c90: 6f 72 6b 65 72 5f 74 68 72 65 61 64 73 5f 69 6e  orker_threads_in
3ca0: 69 74 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28  it");....return(
3cb0: 34 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 57 61 69 74  4);..}.../* Wait
3cc0: 20 66 6f 72 20 74 68 72 65 61 64 73 20 74 6f 20   for threads to 
3cd0: 65 78 69 74 20 2a 2f 0a 09 2f 2a 20 58 58 58 3a  exit */../* XXX:
3ce0: 54 4f 44 4f 3a 20 4d 6f 6e 69 74 6f 72 20 74 68  TODO: Monitor th
3cf0: 72 65 61 64 20 75 73 61 67 65 20 2a 2f 0a 09 77  read usage */..w
3d00: 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 73 6c 65  hile (1) {...sle
3d10: 65 70 28 36 30 29 3b 0a 09 7d 0a 0a 09 2f 2a 20  ep(60);..}.../* 
3d20: 52 65 74 75 72 6e 20 69 6e 20 66 61 69 6c 75 72  Return in failur
3d30: 65 20 2a 2f 0a 09 72 65 74 75 72 6e 28 32 29 3b  e */..return(2);
3d40: 0a 7d 0a                                         .}.