Hex Artifact Content

Artifact 0d0ecd3cdc6f6f9999dc71b56419efe9335c40c0:


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: 67 65 74 6f 70 74 2e 68 3e 0a 23 69 6e 63 6c 75  getopt.h>.#inclu
0120: 64 65 20 3c 66 63 6e 74 6c 2e 68 3e 0a 23 69 6e  de <fcntl.h>.#in
0130: 63 6c 75 64 65 20 3c 73 74 64 69 6f 2e 68 3e 0a  clude <stdio.h>.
0140: 23 69 6e 63 6c 75 64 65 20 3c 65 72 72 6e 6f 2e  #include <errno.
0150: 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 74 69 6d  h>.#include <tim
0160: 65 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70  e.h>.#include <p
0170: 77 64 2e 68 3e 0a 0a 2f 2a 20 43 6f 6d 70 69 6c  wd.h>../* Compil
0180: 65 20 74 69 6d 65 20 63 6f 6e 73 74 61 6e 74 73  e time constants
0190: 20 2a 2f 0a 23 64 65 66 69 6e 65 20 46 49 4c 45   */.#define FILE
01a0: 44 5f 53 45 4e 44 46 49 4c 45 5f 4d 41 58 20 31  D_SENDFILE_MAX 1
01b0: 36 37 37 37 32 31 35 0a 23 64 65 66 69 6e 65 20  6777215.#define 
01c0: 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f 55 4e  MAX_FAILURE_COUN
01d0: 54 20 33 30 0a 0a 2f 2a 20 44 65 66 61 75 6c 74  T 30../* Default
01e0: 20 76 61 6c 75 65 73 20 2a 2f 0a 23 64 65 66 69   values */.#defi
01f0: 6e 65 20 50 4f 52 54 20 38 30 0a 23 64 65 66 69  ne PORT 80.#defi
0200: 6e 65 20 54 48 52 45 41 44 5f 43 4f 55 4e 54 20  ne THREAD_COUNT 
0210: 35 0a 23 64 65 66 69 6e 65 20 42 49 4e 44 5f 41  5.#define BIND_A
0220: 44 44 52 20 22 3a 3a 22 0a 23 64 65 66 69 6e 65  DDR "::".#define
0230: 20 43 41 43 48 45 5f 53 49 5a 45 20 38 31 39 33   CACHE_SIZE 8193
0240: 0a 0a 2f 2a 20 41 72 67 75 6d 65 6e 74 73 20 66  ../* Arguments f
0250: 6f 72 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64  or worker thread
0260: 73 20 2a 2f 0a 73 74 72 75 63 74 20 66 69 6c 65  s */.struct file
0270: 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 5f  d_worker_thread_
0280: 61 72 67 73 20 7b 0a 09 69 6e 74 20 66 64 3b 0a  args {..int fd;.
0290: 7d 3b 0a 0a 2f 2a 20 46 69 6c 65 20 69 6e 66 6f  };../* File info
02a0: 72 6d 61 74 69 6f 6e 20 2a 2f 0a 73 74 72 75 63  rmation */.struc
02b0: 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  t filed_fileinfo
02c0: 20 7b 0a 09 70 74 68 72 65 61 64 5f 6d 75 74 65   {..pthread_mute
02d0: 78 5f 74 20 6d 75 74 65 78 3b 0a 09 63 68 61 72  x_t mutex;..char
02e0: 20 2a 70 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b   *path;..int fd;
02f0: 0a 09 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 63 68  ..off_t len;..ch
0300: 61 72 20 2a 6c 61 73 74 6d 6f 64 3b 0a 09 63 68  ar *lastmod;..ch
0310: 61 72 20 6c 61 73 74 6d 6f 64 5f 62 5b 36 34 5d  ar lastmod_b[64]
0320: 3b 0a 09 63 68 61 72 20 2a 74 79 70 65 3b 0a 7d  ;..char *type;.}
0330: 3b 0a 0a 2f 2a 20 52 65 71 75 65 73 74 20 76 61  ;../* Request va
0340: 72 69 61 62 6c 65 73 20 2a 2f 0a 73 74 72 75 63  riables */.struc
0350: 74 20 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 71  t filed_http_req
0360: 75 65 73 74 20 7b 0a 09 2f 2a 2a 20 42 75 66 66  uest {../** Buff
0370: 65 72 73 20 2a 2a 2f 0a 09 73 74 72 75 63 74 20  ers **/..struct 
0380: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 66  filed_fileinfo f
0390: 69 6c 65 69 6e 66 6f 3b 0a 09 63 68 61 72 20 70  ileinfo;..char p
03a0: 61 74 68 5f 62 5b 31 30 31 30 5d 3b 0a 09 63 68  ath_b[1010];..ch
03b0: 61 72 20 74 6d 70 62 75 66 5b 31 30 31 30 5d 3b  ar tmpbuf[1010];
03c0: 0a 0a 09 2f 2a 2a 20 48 54 54 50 20 52 65 71 75  .../** HTTP Requ
03d0: 65 73 74 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20  est information 
03e0: 2a 2a 2f 0a 09 63 68 61 72 20 2a 70 61 74 68 3b  **/..char *path;
03f0: 20 20 20 20 20 2f 2a 2a 2a 20 50 61 74 68 20 62       /*** Path b
0400: 65 69 6e 67 20 72 65 71 75 65 73 74 65 64 20 2a  eing requested *
0410: 2a 2a 2f 0a 0a 09 73 74 72 75 63 74 20 7b 0a 09  **/...struct {..
0420: 09 73 74 72 75 63 74 20 7b 0a 09 09 09 69 6e 74  .struct {....int
0430: 20 70 72 65 73 65 6e 74 3b 0a 09 09 09 6f 66 66   present;....off
0440: 5f 74 20 6f 66 66 73 65 74 3b 20 20 20 2f 2a 2a  _t offset;   /**
0450: 2a 20 52 61 6e 67 65 20 73 74 61 72 74 20 2a 2a  * Range start **
0460: 2a 2f 0a 09 09 09 6f 66 66 5f 74 20 6c 65 6e 67  */....off_t leng
0470: 74 68 3b 20 20 20 2f 2a 2a 2a 20 52 61 6e 67 65  th;   /*** Range
0480: 20 6c 65 6e 67 74 68 20 2a 2a 2a 2f 0a 09 09 7d   length ***/...}
0490: 20 72 61 6e 67 65 3b 0a 09 7d 20 68 65 61 64 65   range;..} heade
04a0: 72 73 3b 0a 7d 3b 0a 0a 2f 2a 20 47 6c 6f 62 61  rs;.};../* Globa
04b0: 6c 20 76 61 72 69 61 62 6c 65 73 20 2a 2f 0a 2f  l variables */./
04c0: 2a 2a 20 4f 70 65 6e 20 46 69 6c 65 20 63 61 63  ** Open File cac
04d0: 68 65 20 2a 2a 2f 0a 73 74 72 75 63 74 20 66 69  he **/.struct fi
04e0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66 69  led_fileinfo *fi
04f0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63  led_fileinfo_fdc
0500: 61 63 68 65 20 3d 20 4e 55 4c 4c 3b 0a 75 6e 73  ache = NULL;.uns
0510: 69 67 6e 65 64 20 69 6e 74 20 66 69 6c 65 64 5f  igned int filed_
0520: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65  fileinfo_fdcache
0530: 5f 73 69 7a 65 20 3d 20 30 3b 0a 0a 2f 2a 20 49  _size = 0;../* I
0540: 6e 69 74 69 61 6c 69 7a 65 20 63 61 63 68 65 20  nitialize cache 
0550: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69  */.static int fi
0560: 6c 65 64 5f 69 6e 69 74 5f 63 61 63 68 65 28 75  led_init_cache(u
0570: 6e 73 69 67 6e 65 64 20 69 6e 74 20 63 61 63 68  nsigned int cach
0580: 65 5f 73 69 7a 65 29 20 7b 0a 09 75 6e 73 69 67  e_size) {..unsig
0590: 6e 65 64 20 69 6e 74 20 69 64 78 3b 0a 09 69 6e  ned int idx;..in
05a0: 74 20 6d 75 74 65 78 5f 69 6e 69 74 5f 72 65 74  t mutex_init_ret
05b0: 3b 0a 0a 09 2f 2a 20 43 61 63 68 65 20 6d 61 79  ;.../* Cache may
05c0: 20 6e 6f 74 20 62 65 20 72 65 2d 69 6e 69 74 69   not be re-initi
05d0: 61 6c 69 7a 65 64 20 2a 2f 0a 09 69 66 20 28 66  alized */..if (f
05e0: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64  iled_fileinfo_fd
05f0: 63 61 63 68 65 5f 73 69 7a 65 20 21 3d 20 30 20  cache_size != 0 
0600: 7c 7c 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66  || filed_fileinf
0610: 6f 5f 66 64 63 61 63 68 65 20 21 3d 20 4e 55 4c  o_fdcache != NUL
0620: 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29  L) {...return(1)
0630: 3b 0a 09 7d 0a 0a 09 2f 2a 20 41 6c 6c 6f 63 61  ;..}.../* Alloca
0640: 74 65 20 63 61 63 68 65 20 2a 2f 0a 09 66 69 6c  te cache */..fil
0650: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61  ed_fileinfo_fdca
0660: 63 68 65 5f 73 69 7a 65 20 3d 20 63 61 63 68 65  che_size = cache
0670: 5f 73 69 7a 65 3b 0a 09 66 69 6c 65 64 5f 66 69  _size;..filed_fi
0680: 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 20 3d  leinfo_fdcache =
0690: 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a   malloc(sizeof(*
06a0: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66  filed_fileinfo_f
06b0: 64 63 61 63 68 65 29 20 2a 20 66 69 6c 65 64 5f  dcache) * filed_
06c0: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65  fileinfo_fdcache
06d0: 5f 73 69 7a 65 29 3b 0a 09 69 66 20 28 66 69 6c  _size);..if (fil
06e0: 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61  ed_fileinfo_fdca
06f0: 63 68 65 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  che == NULL) {..
0700: 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a  .return(1);..}..
0710: 09 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 63  ./* Initialize c
0720: 61 63 68 65 20 65 6e 74 72 69 65 73 20 2a 2f 0a  ache entries */.
0730: 09 66 6f 72 20 28 69 64 78 20 3d 20 30 3b 20 69  .for (idx = 0; i
0740: 64 78 20 3c 20 66 69 6c 65 64 5f 66 69 6c 65 69  dx < filed_filei
0750: 6e 66 6f 5f 66 64 63 61 63 68 65 5f 73 69 7a 65  nfo_fdcache_size
0760: 3b 20 69 64 78 2b 2b 29 20 7b 0a 09 09 6d 75 74  ; idx++) {...mut
0770: 65 78 5f 69 6e 69 74 5f 72 65 74 20 3d 20 70 74  ex_init_ret = pt
0780: 68 72 65 61 64 5f 6d 75 74 65 78 5f 69 6e 69 74  hread_mutex_init
0790: 28 26 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  (&filed_fileinfo
07a0: 5f 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 6d 75  _fdcache[idx].mu
07b0: 74 65 78 2c 20 4e 55 4c 4c 29 3b 0a 09 09 69 66  tex, NULL);...if
07c0: 20 28 6d 75 74 65 78 5f 69 6e 69 74 5f 72 65 74   (mutex_init_ret
07d0: 20 21 3d 20 30 29 20 7b 0a 09 09 09 72 65 74 75   != 0) {....retu
07e0: 72 6e 28 31 29 3b 0a 09 09 7d 0a 0a 09 09 66 69  rn(1);...}....fi
07f0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63  led_fileinfo_fdc
0800: 61 63 68 65 5b 69 64 78 5d 2e 70 61 74 68 20 3d  ache[idx].path =
0810: 20 73 74 72 64 75 70 28 22 22 29 3b 0a 09 09 66   strdup("");...f
0820: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64  iled_fileinfo_fd
0830: 63 61 63 68 65 5b 69 64 78 5d 2e 66 64 20 3d 20  cache[idx].fd = 
0840: 2d 31 3b 0a 09 09 66 69 6c 65 64 5f 66 69 6c 65  -1;...filed_file
0850: 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64 78  info_fdcache[idx
0860: 5d 2e 6c 61 73 74 6d 6f 64 20 3d 20 22 22 3b 0a  ].lastmod = "";.
0870: 09 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  ..filed_fileinfo
0880: 5f 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 74 79  _fdcache[idx].ty
0890: 70 65 20 3d 20 22 22 3b 0a 09 7d 0a 0a 09 72 65  pe = "";..}...re
08a0: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 49  turn(0);.}../* I
08b0: 6e 69 74 69 61 6c 69 7a 65 20 70 72 6f 63 65 73  nitialize proces
08c0: 73 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  s */.static int 
08d0: 66 69 6c 65 64 5f 69 6e 69 74 28 75 6e 73 69 67  filed_init(unsig
08e0: 6e 65 64 20 69 6e 74 20 63 61 63 68 65 5f 73 69  ned int cache_si
08f0: 7a 65 29 20 7b 0a 09 73 74 61 74 69 63 20 69 6e  ze) {..static in
0900: 74 20 63 61 6c 6c 65 64 20 3d 20 30 3b 0a 09 69  t called = 0;..i
0910: 6e 74 20 63 61 63 68 65 5f 72 65 74 3b 0a 0a 09  nt cache_ret;...
0920: 69 66 20 28 63 61 6c 6c 65 64 29 20 7b 0a 09 09  if (called) {...
0930: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 0a 09  return(0);..}...
0940: 63 61 6c 6c 65 64 20 3d 20 31 3b 0a 0a 09 6d 6c  called = 1;...ml
0950: 6f 63 6b 61 6c 6c 28 4d 43 4c 5f 43 55 52 52 45  ockall(MCL_CURRE
0960: 4e 54 20 7c 20 4d 43 4c 5f 46 55 54 55 52 45 29  NT | MCL_FUTURE)
0970: 3b 0a 0a 09 73 69 67 6e 61 6c 28 53 49 47 50 49  ;...signal(SIGPI
0980: 50 45 2c 20 53 49 47 5f 49 47 4e 29 3b 0a 0a 09  PE, SIG_IGN);...
0990: 63 61 63 68 65 5f 72 65 74 20 3d 20 66 69 6c 65  cache_ret = file
09a0: 64 5f 69 6e 69 74 5f 63 61 63 68 65 28 63 61 63  d_init_cache(cac
09b0: 68 65 5f 73 69 7a 65 29 3b 0a 09 69 66 20 28 63  he_size);..if (c
09c0: 61 63 68 65 5f 72 65 74 20 21 3d 20 30 29 20 7b  ache_ret != 0) {
09d0: 0a 09 09 72 65 74 75 72 6e 28 63 61 63 68 65 5f  ...return(cache_
09e0: 72 65 74 29 3b 0a 09 7d 0a 0a 09 72 65 74 75 72  ret);..}...retur
09f0: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 4c 69 73 74  n(0);.}../* List
0a00: 65 6e 20 6f 6e 20 61 20 70 61 72 74 69 63 75 6c  en on a particul
0a10: 61 72 20 61 64 64 72 65 73 73 2f 70 6f 72 74 20  ar address/port 
0a20: 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69  */.static int fi
0a30: 6c 65 64 5f 6c 69 73 74 65 6e 28 63 6f 6e 73 74  led_listen(const
0a40: 20 63 68 61 72 20 2a 61 64 64 72 65 73 73 2c 20   char *address, 
0a50: 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 70 6f 72  unsigned int por
0a60: 74 29 20 7b 0a 09 73 74 72 75 63 74 20 73 6f 63  t) {..struct soc
0a70: 6b 61 64 64 72 5f 69 6e 36 20 61 64 64 72 3b 0a  kaddr_in6 addr;.
0a80: 09 69 6e 74 20 70 74 6f 6e 5f 72 65 74 2c 20 62  .int pton_ret, b
0a90: 69 6e 64 5f 72 65 74 2c 20 6c 69 73 74 65 6e 5f  ind_ret, listen_
0aa0: 72 65 74 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09  ret;..int fd;...
0ab0: 61 64 64 72 2e 73 69 6e 36 5f 66 61 6d 69 6c 79  addr.sin6_family
0ac0: 20 3d 20 41 46 5f 49 4e 45 54 36 3b 0a 09 61 64   = AF_INET6;..ad
0ad0: 64 72 2e 73 69 6e 36 5f 66 6c 6f 77 69 6e 66 6f  dr.sin6_flowinfo
0ae0: 20 3d 20 30 3b 0a 09 61 64 64 72 2e 73 69 6e 36   = 0;..addr.sin6
0af0: 5f 73 63 6f 70 65 5f 69 64 20 3d 20 30 3b 0a 09  _scope_id = 0;..
0b00: 61 64 64 72 2e 73 69 6e 36 5f 70 6f 72 74 20 3d  addr.sin6_port =
0b10: 20 68 74 6f 6e 73 28 70 6f 72 74 29 3b 0a 09 70   htons(port);..p
0b20: 74 6f 6e 5f 72 65 74 20 3d 20 69 6e 65 74 5f 70  ton_ret = inet_p
0b30: 74 6f 6e 28 41 46 5f 49 4e 45 54 36 2c 20 61 64  ton(AF_INET6, ad
0b40: 64 72 65 73 73 2c 20 61 64 64 72 2e 73 69 6e 36  dress, addr.sin6
0b50: 5f 61 64 64 72 2e 73 36 5f 61 64 64 72 29 3b 0a  _addr.s6_addr);.
0b60: 09 69 66 20 28 70 74 6f 6e 5f 72 65 74 20 21 3d  .if (pton_ret !=
0b70: 20 31 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 2d   1) {...return(-
0b80: 31 29 3b 0a 09 7d 0a 0a 09 66 64 20 3d 20 73 6f  1);..}...fd = so
0b90: 63 6b 65 74 28 41 46 5f 49 4e 45 54 36 2c 20 53  cket(AF_INET6, S
0ba0: 4f 43 4b 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a  OCK_STREAM, 0);.
0bb0: 09 69 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09  .if (fd < 0) {..
0bc0: 09 72 65 74 75 72 6e 28 66 64 29 3b 0a 09 7d 0a  .return(fd);..}.
0bd0: 0a 09 62 69 6e 64 5f 72 65 74 20 3d 20 62 69 6e  ..bind_ret = bin
0be0: 64 28 66 64 2c 20 28 63 6f 6e 73 74 20 73 74 72  d(fd, (const str
0bf0: 75 63 74 20 73 6f 63 6b 61 64 64 72 20 2a 29 20  uct sockaddr *) 
0c00: 26 61 64 64 72 2c 20 73 69 7a 65 6f 66 28 61 64  &addr, sizeof(ad
0c10: 64 72 29 29 3b 0a 09 69 66 20 28 62 69 6e 64 5f  dr));..if (bind_
0c20: 72 65 74 20 3c 20 30 29 20 7b 0a 09 09 63 6c 6f  ret < 0) {...clo
0c30: 73 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72  se(fd);....retur
0c40: 6e 28 2d 31 29 3b 0a 09 7d 0a 0a 09 6c 69 73 74  n(-1);..}...list
0c50: 65 6e 5f 72 65 74 20 3d 20 6c 69 73 74 65 6e 28  en_ret = listen(
0c60: 66 64 2c 20 31 32 38 29 3b 0a 09 69 66 20 28 6c  fd, 128);..if (l
0c70: 69 73 74 65 6e 5f 72 65 74 20 21 3d 20 30 29 20  isten_ret != 0) 
0c80: 7b 0a 09 09 63 6c 6f 73 65 28 66 64 29 3b 0a 0a  {...close(fd);..
0c90: 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d  ..return(-1);..}
0ca0: 0a 0a 09 72 65 74 75 72 6e 28 66 64 29 3b 0a 7d  ...return(fd);.}
0cb0: 0a 0a 2f 2a 20 4c 6f 67 20 61 20 6d 65 73 73 61  ../* Log a messa
0cc0: 67 65 20 2a 2f 0a 2f 2f 23 64 65 66 69 6e 65 20  ge */.//#define 
0cd0: 46 49 4c 45 44 5f 44 4f 4e 54 5f 4c 4f 47 0a 23  FILED_DONT_LOG.#
0ce0: 69 66 64 65 66 20 46 49 4c 45 44 5f 44 4f 4e 54  ifdef FILED_DONT
0cf0: 5f 4c 4f 47 0a 23 20 20 64 65 66 69 6e 65 20 66  _LOG.#  define f
0d00: 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72  iled_logging_thr
0d10: 65 61 64 5f 69 6e 69 74 28 29 20 30 0a 23 20 20  ead_init() 0.#  
0d20: 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c 6f 67  define filed_log
0d30: 5f 6d 73 67 5f 64 65 62 75 67 28 78 2c 20 2e 2e  _msg_debug(x, ..
0d40: 2e 29 20 2f 2a 2a 2f 0a 23 20 20 64 65 66 69 6e  .) /**/.#  defin
0d50: 65 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  e filed_log_msg(
0d60: 78 29 20 2f 2a 2a 2f 0a 23 65 6c 73 65 0a 2f 2a  x) /**/.#else./*
0d70: 20 49 6e 69 74 69 61 6c 69 7a 65 20 6c 6f 67 67   Initialize logg
0d80: 69 6e 67 20 74 68 72 65 61 64 20 2a 2f 0a 73 74  ing thread */.st
0d90: 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 6c  atic int filed_l
0da0: 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e  ogging_thread_in
0db0: 69 74 28 76 6f 69 64 29 20 7b 0a 09 2f 2a 20 58  it(void) {../* X
0dc0: 58 58 3a 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c 65  XX:TODO: Unimple
0dd0: 6d 65 6e 74 65 64 20 2a 2f 0a 09 72 65 74 75 72  mented */..retur
0de0: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 58 58 58 3a  n(0);.}../* XXX:
0df0: 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c 65 6d 65 6e  TODO: Unimplemen
0e00: 74 65 64 20 2a 2f 0a 23 64 65 66 69 6e 65 20 66  ted */.#define f
0e10: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62  iled_log_msg_deb
0e20: 75 67 28 78 2c 20 2e 2e 2e 29 20 7b 20 66 70 72  ug(x, ...) { fpr
0e30: 69 6e 74 66 28 73 74 64 65 72 72 2c 20 78 2c 20  intf(stderr, x, 
0e40: 5f 5f 56 41 5f 41 52 47 53 5f 5f 29 3b 20 66 70  __VA_ARGS__); fp
0e50: 72 69 6e 74 66 28 73 74 64 65 72 72 2c 20 22 5c  rintf(stderr, "\
0e60: 6e 22 29 3b 20 66 66 6c 75 73 68 28 73 74 64 65  n"); fflush(stde
0e70: 72 72 29 3b 20 7d 0a 0a 73 74 61 74 69 63 20 76  rr); }..static v
0e80: 6f 69 64 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  oid filed_log_ms
0e90: 67 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 62 75  g(const char *bu
0ea0: 66 66 65 72 29 20 7b 0a 09 2f 2a 20 58 58 58 3a  ffer) {../* XXX:
0eb0: 54 4f 44 4f 3a 20 55 6e 69 6d 70 6c 65 6d 65 6e  TODO: Unimplemen
0ec0: 74 65 64 20 2a 2f 0a 09 66 70 72 69 6e 74 66 28  ted */..fprintf(
0ed0: 73 74 64 65 72 72 2c 20 22 25 73 5c 6e 22 2c 20  stderr, "%s\n", 
0ee0: 62 75 66 66 65 72 29 3b 0a 0a 09 72 65 74 75 72  buffer);...retur
0ef0: 6e 3b 0a 7d 0a 23 65 6e 64 69 66 0a 0a 2f 2a 20  n;.}.#endif../* 
0f00: 46 6f 72 6d 61 74 20 74 69 6d 65 20 70 65 72 20  Format time per 
0f10: 52 46 43 32 36 31 36 20 2a 2f 0a 73 74 61 74 69  RFC2616 */.stati
0f20: 63 20 63 68 61 72 20 2a 66 69 6c 65 64 5f 66 6f  c char *filed_fo
0f30: 72 6d 61 74 5f 74 69 6d 65 28 63 68 61 72 20 2a  rmat_time(char *
0f40: 62 75 66 66 65 72 2c 20 73 69 7a 65 5f 74 20 62  buffer, size_t b
0f50: 75 66 66 65 72 5f 6c 65 6e 2c 20 63 6f 6e 73 74  uffer_len, const
0f60: 20 74 69 6d 65 5f 74 20 74 69 6d 65 69 6e 66 6f   time_t timeinfo
0f70: 29 20 7b 0a 09 73 74 72 75 63 74 20 74 6d 20 74  ) {..struct tm t
0f80: 69 6d 65 69 6e 66 6f 5f 74 6d 2c 20 2a 74 69 6d  imeinfo_tm, *tim
0f90: 65 69 6e 66 6f 5f 74 6d 5f 70 3b 0a 0a 09 74 69  einfo_tm_p;...ti
0fa0: 6d 65 69 6e 66 6f 5f 74 6d 5f 70 20 3d 20 67 6d  meinfo_tm_p = gm
0fb0: 74 69 6d 65 5f 72 28 26 74 69 6d 65 69 6e 66 6f  time_r(&timeinfo
0fc0: 2c 20 26 74 69 6d 65 69 6e 66 6f 5f 74 6d 29 3b  , &timeinfo_tm);
0fd0: 0a 09 69 66 20 28 74 69 6d 65 69 6e 66 6f 5f 74  ..if (timeinfo_t
0fe0: 6d 5f 70 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09  m_p == NULL) {..
0ff0: 09 72 65 74 75 72 6e 28 22 75 6e 6b 6e 6f 77 6e  .return("unknown
1000: 22 29 3b 0a 09 7d 0a 0a 09 62 75 66 66 65 72 5b  ");..}...buffer[
1010: 62 75 66 66 65 72 5f 6c 65 6e 20 2d 20 31 5d 20  buffer_len - 1] 
1020: 3d 20 27 5c 30 27 3b 0a 09 62 75 66 66 65 72 5f  = '\0';..buffer_
1030: 6c 65 6e 20 3d 20 73 74 72 66 74 69 6d 65 28 62  len = strftime(b
1040: 75 66 66 65 72 2c 20 62 75 66 66 65 72 5f 6c 65  uffer, buffer_le
1050: 6e 20 2d 20 31 2c 20 22 25 61 2c 20 25 64 20 25  n - 1, "%a, %d %
1060: 62 20 25 59 20 25 48 3a 25 4d 3a 25 53 20 47 4d  b %Y %H:%M:%S GM
1070: 54 22 2c 20 74 69 6d 65 69 6e 66 6f 5f 74 6d 5f  T", timeinfo_tm_
1080: 70 29 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75 66  p);...return(buf
1090: 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 68 61 73 68  fer);.}../* hash
10a0: 20 2a 2f 0a 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a   */./* XXX:TODO:
10b0: 20 52 65 77 72 69 74 65 20 74 68 69 73 20 2a 2f   Rewrite this */
10c0: 0a 73 74 61 74 69 63 20 75 6e 73 69 67 6e 65 64  .static unsigned
10d0: 20 69 6e 74 20 66 69 6c 65 64 5f 68 61 73 68 28   int filed_hash(
10e0: 63 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63  const unsigned c
10f0: 68 61 72 20 2a 76 61 6c 75 65 2c 20 75 6e 73 69  har *value, unsi
1100: 67 6e 65 64 20 69 6e 74 20 6d 6f 64 75 6c 75 73  gned int modulus
1110: 29 20 7b 0a 09 75 6e 73 69 67 6e 65 64 20 63 68  ) {..unsigned ch
1120: 61 72 20 63 75 72 72 2c 20 70 72 65 76 3b 0a 09  ar curr, prev;..
1130: 69 6e 74 20 64 69 66 66 3b 0a 09 75 6e 73 69 67  int diff;..unsig
1140: 6e 65 64 20 69 6e 74 20 72 65 74 76 61 6c 3b 0a  ned int retval;.
1150: 0a 09 72 65 74 76 61 6c 20 3d 20 6d 6f 64 75 6c  ..retval = modul
1160: 75 73 20 2d 20 31 3b 0a 09 70 72 65 76 20 3d 20  us - 1;..prev = 
1170: 6d 6f 64 75 6c 75 73 20 25 20 32 35 35 3b 0a 0a  modulus % 255;..
1180: 09 77 68 69 6c 65 20 28 28 63 75 72 72 20 3d 20  .while ((curr = 
1190: 2a 76 61 6c 75 65 29 29 20 7b 0a 09 09 69 66 20  *value)) {...if 
11a0: 28 63 75 72 72 20 3c 20 33 32 29 20 7b 0a 09 09  (curr < 32) {...
11b0: 09 63 75 72 72 20 3d 20 32 35 35 20 2d 20 63 75  .curr = 255 - cu
11c0: 72 72 3b 0a 09 09 7d 20 65 6c 73 65 20 7b 0a 09  rr;...} else {..
11d0: 09 09 63 75 72 72 20 2d 3d 20 33 32 3b 0a 09 09  ..curr -= 32;...
11e0: 7d 0a 0a 09 09 69 66 20 28 70 72 65 76 20 3c 20  }....if (prev < 
11f0: 63 75 72 72 29 20 7b 0a 09 09 09 64 69 66 66 20  curr) {....diff 
1200: 3d 20 63 75 72 72 20 2d 20 70 72 65 76 3b 0a 09  = curr - prev;..
1210: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 64 69 66  .} else {....dif
1220: 66 20 3d 20 70 72 65 76 20 2d 20 63 75 72 72 3b  f = prev - curr;
1230: 0a 09 09 7d 0a 0a 09 09 72 65 74 76 61 6c 20 3c  ...}....retval <
1240: 3c 3d 20 33 3b 0a 09 09 72 65 74 76 61 6c 20 5e  <= 3;...retval ^
1250: 3d 20 64 69 66 66 3b 0a 0a 09 09 76 61 6c 75 65  = diff;....value
1260: 2b 2b 3b 0a 09 7d 0a 0a 09 72 65 74 76 61 6c 20  ++;..}...retval 
1270: 3d 20 72 65 74 76 61 6c 20 25 20 6d 6f 64 75 6c  = retval % modul
1280: 75 73 3b 0a 0a 09 72 65 74 75 72 6e 28 72 65 74  us;...return(ret
1290: 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a 20 4f 70 65 6e  val);.}../* Open
12a0: 20 61 20 66 69 6c 65 20 61 6e 64 20 72 65 74 75   a file and retu
12b0: 72 6e 20 66 69 6c 65 20 69 6e 66 6f 72 6d 61 74  rn file informat
12c0: 69 6f 6e 20 2a 2f 0a 73 74 61 74 69 63 20 73 74  ion */.static st
12d0: 72 75 63 74 20 66 69 6c 65 64 5f 66 69 6c 65 69  ruct filed_filei
12e0: 6e 66 6f 20 2a 66 69 6c 65 64 5f 6f 70 65 6e 5f  nfo *filed_open_
12f0: 66 69 6c 65 28 63 6f 6e 73 74 20 63 68 61 72 20  file(const char 
1300: 2a 70 61 74 68 2c 20 73 74 72 75 63 74 20 66 69  *path, struct fi
1310: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 62 75  led_fileinfo *bu
1320: 66 66 65 72 29 20 7b 0a 09 73 74 72 75 63 74 20  ffer) {..struct 
1330: 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 2a  filed_fileinfo *
1340: 63 61 63 68 65 3b 0a 09 75 6e 73 69 67 6e 65 64  cache;..unsigned
1350: 20 69 6e 74 20 63 61 63 68 65 5f 69 64 78 3b 0a   int cache_idx;.
1360: 09 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 69 6e 74  .off_t len;..int
1370: 20 66 64 3b 0a 0a 09 63 61 63 68 65 5f 69 64 78   fd;...cache_idx
1380: 20 3d 20 66 69 6c 65 64 5f 68 61 73 68 28 28 63   = filed_hash((c
1390: 6f 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68  onst unsigned ch
13a0: 61 72 20 2a 29 20 70 61 74 68 2c 20 66 69 6c 65  ar *) path, file
13b0: 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63  d_fileinfo_fdcac
13c0: 68 65 5f 73 69 7a 65 29 3b 0a 0a 09 63 61 63 68  he_size);...cach
13d0: 65 20 3d 20 26 66 69 6c 65 64 5f 66 69 6c 65 69  e = &filed_filei
13e0: 6e 66 6f 5f 66 64 63 61 63 68 65 5b 63 61 63 68  nfo_fdcache[cach
13f0: 65 5f 69 64 78 5d 3b 0a 0a 09 66 69 6c 65 64 5f  e_idx];...filed_
1400: 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 4c  log_msg_debug("L
1410: 6f 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f 72  ocking mutex for
1420: 20 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e 73   idx: %lu", (uns
1430: 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68  igned long) cach
1440: 65 5f 69 64 78 29 3b 0a 0a 09 70 74 68 72 65 61  e_idx);...pthrea
1450: 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 63 61  d_mutex_lock(&ca
1460: 63 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 66  che->mutex);...f
1470: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62  iled_log_msg_deb
1480: 75 67 28 22 43 6f 6d 70 6c 65 74 65 64 20 6c 6f  ug("Completed lo
1490: 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f 72 20  cking mutex for 
14a0: 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e 73 69  idx: %lu", (unsi
14b0: 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 65  gned long) cache
14c0: 5f 69 64 78 29 3b 0a 0a 09 69 66 20 28 73 74 72  _idx);...if (str
14d0: 63 6d 70 28 70 61 74 68 2c 20 63 61 63 68 65 2d  cmp(path, cache-
14e0: 3e 70 61 74 68 29 20 21 3d 20 30 29 20 7b 0a 09  >path) != 0) {..
14f0: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64  .filed_log_msg_d
1500: 65 62 75 67 28 22 43 61 63 68 65 20 6d 69 73 73  ebug("Cache miss
1510: 20 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20 4f   for idx: %lu: O
1520: 4c 44 20 5c 22 25 73 5c 22 2c 20 4e 45 57 20 5c  LD \"%s\", NEW \
1530: 22 25 73 5c 22 22 2c 20 28 75 6e 73 69 67 6e 65  "%s\"", (unsigne
1540: 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f 69 64  d long) cache_id
1550: 78 2c 20 63 61 63 68 65 2d 3e 70 61 74 68 2c 20  x, cache->path, 
1560: 70 61 74 68 29 3b 0a 0a 09 09 66 64 20 3d 20 6f  path);....fd = o
1570: 70 65 6e 28 70 61 74 68 2c 20 4f 5f 52 44 4f 4e  pen(path, O_RDON
1580: 4c 59 20 7c 20 4f 5f 4c 41 52 47 45 46 49 4c 45  LY | O_LARGEFILE
1590: 29 3b 0a 09 09 69 66 20 28 66 64 20 3c 20 30 29  );...if (fd < 0)
15a0: 20 7b 0a 09 09 09 70 74 68 72 65 61 64 5f 6d 75   {....pthread_mu
15b0: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63 68  tex_unlock(&cach
15c0: 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 09 72  e->mutex);.....r
15d0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 09 7d  eturn(NULL);...}
15e0: 0a 0a 09 09 66 72 65 65 28 63 61 63 68 65 2d 3e  ....free(cache->
15f0: 70 61 74 68 29 3b 0a 09 09 69 66 20 28 63 61 63  path);...if (cac
1600: 68 65 2d 3e 66 64 20 3e 3d 20 30 29 20 7b 0a 09  he->fd >= 0) {..
1610: 09 09 63 6c 6f 73 65 28 63 61 63 68 65 2d 3e 66  ..close(cache->f
1620: 64 29 3b 0a 09 09 7d 0a 0a 09 09 6c 65 6e 20 3d  d);...}....len =
1630: 20 6c 73 65 65 6b 28 66 64 2c 20 30 2c 20 53 45   lseek(fd, 0, SE
1640: 45 4b 5f 45 4e 44 29 3b 0a 09 09 6c 73 65 65 6b  EK_END);...lseek
1650: 28 66 64 2c 20 30 2c 20 53 45 45 4b 5f 53 45 54  (fd, 0, SEEK_SET
1660: 29 3b 0a 0a 09 09 63 61 63 68 65 2d 3e 66 64 20  );....cache->fd 
1670: 3d 20 66 64 3b 0a 09 09 63 61 63 68 65 2d 3e 6c  = fd;...cache->l
1680: 65 6e 20 3d 20 6c 65 6e 3b 0a 09 09 63 61 63 68  en = len;...cach
1690: 65 2d 3e 70 61 74 68 20 3d 20 73 74 72 64 75 70  e->path = strdup
16a0: 28 70 61 74 68 29 3b 0a 0a 09 09 2f 2a 20 58 58  (path);..../* XX
16b0: 58 3a 54 4f 44 4f 3a 20 44 65 74 65 72 6d 69 6e  X:TODO: Determin
16c0: 65 20 2a 2f 0a 09 09 63 61 63 68 65 2d 3e 74 79  e */...cache->ty
16d0: 70 65 20 3d 20 22 76 69 64 65 6f 2f 6d 70 34 22  pe = "video/mp4"
16e0: 3b 0a 09 09 63 61 63 68 65 2d 3e 6c 61 73 74 6d  ;...cache->lastm
16f0: 6f 64 20 3d 20 66 69 6c 65 64 5f 66 6f 72 6d 61  od = filed_forma
1700: 74 5f 74 69 6d 65 28 63 61 63 68 65 2d 3e 6c 61  t_time(cache->la
1710: 73 74 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28  stmod_b, sizeof(
1720: 63 61 63 68 65 2d 3e 6c 61 73 74 6d 6f 64 5f 62  cache->lastmod_b
1730: 29 2c 20 74 69 6d 65 28 4e 55 4c 4c 29 20 2d 20  ), time(NULL) - 
1740: 33 30 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  30);..} else {..
1750: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64  .filed_log_msg_d
1760: 65 62 75 67 28 22 43 61 63 68 65 20 68 69 74 20  ebug("Cache hit 
1770: 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20 50 41  for idx: %lu: PA
1780: 54 48 20 5c 22 25 73 5c 22 22 2c 20 28 75 6e 73  TH \"%s\"", (uns
1790: 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68  igned long) cach
17a0: 65 5f 69 64 78 2c 20 70 61 74 68 29 3b 0a 09 7d  e_idx, path);..}
17b0: 0a 0a 09 2f 2a 0a 09 20 2a 20 57 65 20 68 61 76  .../*.. * We hav
17c0: 65 20 74 6f 20 6d 61 6b 65 20 61 20 64 75 70 6c  e to make a dupl
17d0: 69 63 61 74 65 20 46 44 2c 20 62 65 63 61 75 73  icate FD, becaus
17e0: 65 20 6f 6e 63 65 20 77 65 20 72 65 6c 65 61 73  e once we releas
17f0: 65 20 74 68 65 20 63 61 63 68 65 0a 09 20 2a 20  e the cache.. * 
1800: 6d 75 74 65 78 2c 20 74 68 65 20 66 69 6c 65 20  mutex, the file 
1810: 64 65 73 63 72 69 70 74 6f 72 20 6d 61 79 20 62  descriptor may b
1820: 65 20 63 6c 6f 73 65 64 0a 09 20 2a 2f 0a 09 66  e closed.. */..f
1830: 64 20 3d 20 64 75 70 28 63 61 63 68 65 2d 3e 66  d = dup(cache->f
1840: 64 29 3b 0a 09 69 66 20 28 66 64 20 3c 20 30 29  d);..if (fd < 0)
1850: 20 7b 0a 09 09 70 74 68 72 65 61 64 5f 6d 75 74   {...pthread_mut
1860: 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63 68 65  ex_unlock(&cache
1870: 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 72 65 74  ->mutex);....ret
1880: 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09  urn(NULL);..}...
1890: 62 75 66 66 65 72 2d 3e 66 64 20 3d 20 66 64 3b  buffer->fd = fd;
18a0: 0a 09 62 75 66 66 65 72 2d 3e 6c 65 6e 20 3d 20  ..buffer->len = 
18b0: 63 61 63 68 65 2d 3e 6c 65 6e 3b 0a 09 62 75 66  cache->len;..buf
18c0: 66 65 72 2d 3e 74 79 70 65 20 3d 20 63 61 63 68  fer->type = cach
18d0: 65 2d 3e 74 79 70 65 3b 0a 09 6d 65 6d 63 70 79  e->type;..memcpy
18e0: 28 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d 6f 64  (buffer->lastmod
18f0: 5f 62 2c 20 63 61 63 68 65 2d 3e 6c 61 73 74 6d  _b, cache->lastm
1900: 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28 62 75 66  od_b, sizeof(buf
1910: 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 29  fer->lastmod_b))
1920: 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d  ;..buffer->lastm
1930: 6f 64 20 3d 20 62 75 66 66 65 72 2d 3e 6c 61 73  od = buffer->las
1940: 74 6d 6f 64 5f 62 20 2b 20 28 63 61 63 68 65 2d  tmod_b + (cache-
1950: 3e 6c 61 73 74 6d 6f 64 20 2d 20 63 61 63 68 65  >lastmod - cache
1960: 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 3b 0a 0a 09  ->lastmod_b);...
1970: 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e  pthread_mutex_un
1980: 6c 6f 63 6b 28 26 63 61 63 68 65 2d 3e 6d 75 74  lock(&cache->mut
1990: 65 78 29 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75  ex);...return(bu
19a0: 66 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50 72 6f  ffer);.}../* Pro
19b0: 63 65 73 73 20 61 6e 20 48 54 54 50 20 72 65 71  cess an HTTP req
19c0: 75 65 73 74 20 61 6e 64 20 72 65 74 75 72 6e 20  uest and return 
19d0: 74 68 65 20 70 61 74 68 20 72 65 71 75 65 73 74  the path request
19e0: 65 64 20 2a 2f 0a 73 74 61 74 69 63 20 73 74 72  ed */.static str
19f0: 75 63 74 20 66 69 6c 65 64 5f 68 74 74 70 5f 72  uct filed_http_r
1a00: 65 71 75 65 73 74 20 2a 66 69 6c 65 64 5f 67 65  equest *filed_ge
1a10: 74 5f 68 74 74 70 5f 72 65 71 75 65 73 74 28 46  t_http_request(F
1a20: 49 4c 45 20 2a 66 70 2c 20 73 74 72 75 63 74 20  ILE *fp, struct 
1a30: 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 71 75 65  filed_http_reque
1a40: 73 74 20 2a 62 75 66 66 65 72 5f 73 74 29 20 7b  st *buffer_st) {
1a50: 0a 09 63 68 61 72 20 2a 6d 65 74 68 6f 64 2c 20  ..char *method, 
1a60: 2a 70 61 74 68 3b 0a 09 63 68 61 72 20 2a 62 75  *path;..char *bu
1a70: 66 66 65 72 2c 20 2a 74 6d 70 62 75 66 66 65 72  ffer, *tmpbuffer
1a80: 2c 20 2a 77 6f 72 6b 62 75 66 66 65 72 2c 20 2a  , *workbuffer, *
1a90: 77 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78 74 3b  workbuffer_next;
1aa0: 0a 09 73 69 7a 65 5f 74 20 62 75 66 66 65 72 5f  ..size_t buffer_
1ab0: 6c 65 6e 2c 20 74 6d 70 62 75 66 66 65 72 5f 6c  len, tmpbuffer_l
1ac0: 65 6e 3b 0a 09 6f 66 66 5f 74 20 72 61 6e 67 65  en;..off_t range
1ad0: 5f 73 74 61 72 74 2c 20 72 61 6e 67 65 5f 65 6e  _start, range_en
1ae0: 64 2c 20 72 61 6e 67 65 5f 6c 65 6e 67 74 68 3b  d, range_length;
1af0: 0a 09 69 6e 74 20 72 61 6e 67 65 5f 72 65 71 75  ..int range_requ
1b00: 65 73 74 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 72  est;..int i;...r
1b10: 61 6e 67 65 5f 73 74 61 72 74 20 3d 20 30 3b 0a  ange_start = 0;.
1b20: 09 72 61 6e 67 65 5f 65 6e 64 20 20 20 3d 20 30  .range_end   = 0
1b30: 3b 0a 09 72 61 6e 67 65 5f 72 65 71 75 65 73 74  ;..range_request
1b40: 20 3d 20 30 3b 0a 09 72 61 6e 67 65 5f 6c 65 6e   = 0;..range_len
1b50: 67 74 68 20 3d 20 2d 31 3b 0a 0a 09 62 75 66 66  gth = -1;...buff
1b60: 65 72 20 3d 20 62 75 66 66 65 72 5f 73 74 2d 3e  er = buffer_st->
1b70: 70 61 74 68 5f 62 3b 0a 09 62 75 66 66 65 72 5f  path_b;..buffer_
1b80: 6c 65 6e 20 3d 20 73 69 7a 65 6f 66 28 62 75 66  len = sizeof(buf
1b90: 66 65 72 5f 73 74 2d 3e 70 61 74 68 5f 62 29 3b  fer_st->path_b);
1ba0: 0a 0a 09 74 6d 70 62 75 66 66 65 72 20 3d 20 62  ...tmpbuffer = b
1bb0: 75 66 66 65 72 5f 73 74 2d 3e 74 6d 70 62 75 66  uffer_st->tmpbuf
1bc0: 3b 0a 09 74 6d 70 62 75 66 66 65 72 5f 6c 65 6e  ;..tmpbuffer_len
1bd0: 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 66 65 72   = sizeof(buffer
1be0: 5f 73 74 2d 3e 74 6d 70 62 75 66 29 3b 0a 0a 09  _st->tmpbuf);...
1bf0: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 57  filed_log_msg("W
1c00: 41 49 54 5f 46 4f 52 5f 52 45 51 55 45 53 54 20  AIT_FOR_REQUEST 
1c10: 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 66 67 65 74  FD=...");...fget
1c20: 73 28 62 75 66 66 65 72 2c 20 62 75 66 66 65 72  s(buffer, buffer
1c30: 5f 6c 65 6e 2c 20 66 70 29 3b 0a 0a 09 6d 65 74  _len, fp);...met
1c40: 68 6f 64 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09  hod = buffer;...
1c50: 62 75 66 66 65 72 20 3d 20 73 74 72 63 68 72 28  buffer = strchr(
1c60: 62 75 66 66 65 72 2c 20 27 20 27 29 3b 0a 09 69  buffer, ' ');..i
1c70: 66 20 28 62 75 66 66 65 72 20 3d 3d 20 4e 55 4c  f (buffer == NUL
1c80: 4c 29 20 7b 0a 09 09 66 69 6c 65 64 5f 6c 6f 67  L) {...filed_log
1c90: 5f 6d 73 67 28 22 47 4f 54 5f 52 45 51 55 45 53  _msg("GOT_REQUES
1ca0: 54 20 46 44 3d 2e 2e 2e 20 45 52 52 4f 52 3d 66  T FD=... ERROR=f
1cb0: 6f 72 6d 61 74 22 29 3b 0a 0a 09 09 72 65 74 75  ormat");....retu
1cc0: 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a 09 2a  rn(NULL);..}...*
1cd0: 62 75 66 66 65 72 20 3d 20 27 5c 30 27 3b 0a 09  buffer = '\0';..
1ce0: 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 70 61 74 68  buffer++;...path
1cf0: 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09 62 75 66   = buffer;...buf
1d00: 66 65 72 20 3d 20 73 74 72 63 68 72 28 62 75 66  fer = strchr(buf
1d10: 66 65 72 2c 20 27 20 27 29 3b 0a 09 69 66 20 28  fer, ' ');..if (
1d20: 62 75 66 66 65 72 20 21 3d 20 4e 55 4c 4c 29 20  buffer != NULL) 
1d30: 7b 0a 09 09 2a 62 75 66 66 65 72 20 3d 20 27 5c  {...*buffer = '\
1d40: 30 27 3b 0a 09 09 62 75 66 66 65 72 2b 2b 3b 0a  0';...buffer++;.
1d50: 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d  .}...filed_log_m
1d60: 73 67 28 22 47 4f 54 5f 52 45 51 55 45 53 54 20  sg("GOT_REQUEST 
1d70: 46 44 3d 2e 2e 2e 20 50 41 54 48 3d 2e 2e 2e 22  FD=... PATH=..."
1d80: 29 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d  );...filed_log_m
1d90: 73 67 28 22 57 41 49 54 5f 46 4f 52 5f 48 45 41  sg("WAIT_FOR_HEA
1da0: 44 45 52 53 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a  DERS FD=...");..
1db0: 09 66 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c  .for (i = 0; i <
1dc0: 20 31 30 30 3b 20 69 2b 2b 29 20 7b 0a 09 09 66   100; i++) {...f
1dd0: 67 65 74 73 28 74 6d 70 62 75 66 66 65 72 2c 20  gets(tmpbuffer, 
1de0: 74 6d 70 62 75 66 66 65 72 5f 6c 65 6e 2c 20 66  tmpbuffer_len, f
1df0: 70 29 3b 0a 0a 09 09 69 66 20 28 73 74 72 6e 63  p);....if (strnc
1e00: 61 73 65 63 6d 70 28 74 6d 70 62 75 66 66 65 72  asecmp(tmpbuffer
1e10: 2c 20 22 52 61 6e 67 65 3a 20 22 2c 20 37 29 20  , "Range: ", 7) 
1e20: 3d 3d 20 30 29 20 7b 0a 09 09 09 77 6f 72 6b 62  == 0) {....workb
1e30: 75 66 66 65 72 20 3d 20 74 6d 70 62 75 66 66 65  uffer = tmpbuffe
1e40: 72 20 2b 20 37 3b 0a 0a 09 09 09 69 66 20 28 73  r + 7;.....if (s
1e50: 74 72 6e 63 61 73 65 63 6d 70 28 77 6f 72 6b 62  trncasecmp(workb
1e60: 75 66 66 65 72 2c 20 22 62 79 74 65 73 3d 22 2c  uffer, "bytes=",
1e70: 20 36 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09   6) == 0) {.....
1e80: 77 6f 72 6b 62 75 66 66 65 72 20 2b 3d 20 36 3b  workbuffer += 6;
1e90: 0a 0a 09 09 09 09 72 61 6e 67 65 5f 72 65 71 75  ......range_requ
1ea0: 65 73 74 20 3d 20 31 3b 0a 0a 09 09 09 09 72 61  est = 1;......ra
1eb0: 6e 67 65 5f 73 74 61 72 74 20 3d 20 73 74 72 74  nge_start = strt
1ec0: 6f 75 6c 6c 28 77 6f 72 6b 62 75 66 66 65 72 2c  oull(workbuffer,
1ed0: 20 26 77 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78   &workbuffer_nex
1ee0: 74 2c 20 31 30 29 3b 0a 0a 09 09 09 09 77 6f 72  t, 10);......wor
1ef0: 6b 62 75 66 66 65 72 20 3d 20 77 6f 72 6b 62 75  kbuffer = workbu
1f00: 66 66 65 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09  ffer_next;......
1f10: 69 66 20 28 2a 77 6f 72 6b 62 75 66 66 65 72 20  if (*workbuffer 
1f20: 3d 3d 20 27 2d 27 29 20 7b 0a 09 09 09 09 09 77  == '-') {......w
1f30: 6f 72 6b 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 09  orkbuffer++;....
1f40: 09 09 09 69 66 20 28 2a 77 6f 72 6b 62 75 66 66  ...if (*workbuff
1f50: 65 72 20 21 3d 20 27 5c 72 27 20 26 26 20 2a 77  er != '\r' && *w
1f60: 6f 72 6b 62 75 66 66 65 72 20 21 3d 20 27 5c 6e  orkbuffer != '\n
1f70: 27 29 20 7b 0a 09 09 09 09 09 09 72 61 6e 67 65  ') {.......range
1f80: 5f 65 6e 64 20 3d 20 73 74 72 74 6f 75 6c 6c 28  _end = strtoull(
1f90: 77 6f 72 6b 62 75 66 66 65 72 2c 20 26 77 6f 72  workbuffer, &wor
1fa0: 6b 62 75 66 66 65 72 5f 6e 65 78 74 2c 20 31 30  kbuffer_next, 10
1fb0: 29 3b 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a  );......}.....}.
1fc0: 09 09 09 7d 0a 09 09 7d 0a 0a 09 09 69 66 20 28  ...}...}....if (
1fd0: 6d 65 6d 63 6d 70 28 74 6d 70 62 75 66 66 65 72  memcmp(tmpbuffer
1fe0: 2c 20 22 5c 72 5c 6e 22 2c 20 32 29 20 3d 3d 20  , "\r\n", 2) == 
1ff0: 30 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09  0) {....break;..
2000: 09 7d 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f  .}..}...filed_lo
2010: 67 5f 6d 73 67 28 22 47 4f 54 5f 48 45 41 44 45  g_msg("GOT_HEADE
2020: 52 53 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09 2f  RS FD=...");.../
2030: 2a 20 57 65 20 6f 6e 6c 79 20 68 61 6e 64 6c 65  * We only handle
2040: 20 74 68 65 20 22 47 45 54 22 20 6d 65 74 68 6f   the "GET" metho
2050: 64 20 2a 2f 0a 09 69 66 20 28 73 74 72 63 61 73  d */..if (strcas
2060: 65 63 6d 70 28 6d 65 74 68 6f 64 2c 20 22 67 65  ecmp(method, "ge
2070: 74 22 29 20 21 3d 20 30 29 20 7b 0a 09 09 72 65  t") != 0) {...re
2080: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
2090: 09 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 72 61  ./* Determine ra
20a0: 6e 67 65 20 2a 2f 0a 09 69 66 20 28 72 61 6e 67  nge */..if (rang
20b0: 65 5f 65 6e 64 20 21 3d 20 30 29 20 7b 0a 09 09  e_end != 0) {...
20c0: 69 66 20 28 72 61 6e 67 65 5f 65 6e 64 20 3c 3d  if (range_end <=
20d0: 20 72 61 6e 67 65 5f 73 74 61 72 74 29 20 7b 0a   range_start) {.
20e0: 09 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b  ...return(NULL);
20f0: 0a 09 09 7d 0a 0a 09 09 72 61 6e 67 65 5f 6c 65  ...}....range_le
2100: 6e 67 74 68 20 3d 20 72 61 6e 67 65 5f 65 6e 64  ngth = range_end
2110: 20 2d 20 72 61 6e 67 65 5f 73 74 61 72 74 3b 0a   - range_start;.
2120: 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67  ...filed_log_msg
2130: 5f 64 65 62 75 67 28 22 43 6f 6d 70 75 74 69 6e  _debug("Computin
2140: 67 20 6c 65 6e 67 74 68 20 70 61 72 61 6d 65 74  g length paramet
2150: 65 72 3a 20 25 6c 6c 75 20 3d 20 25 6c 6c 75 20  er: %llu = %llu 
2160: 2d 20 25 6c 6c 75 22 2c 0a 09 09 09 28 75 6e 73  - %llu",....(uns
2170: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
2180: 20 72 61 6e 67 65 5f 6c 65 6e 67 74 68 2c 0a 09   range_length,..
2190: 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  ..(unsigned long
21a0: 20 6c 6f 6e 67 29 20 72 61 6e 67 65 5f 65 6e 64   long) range_end
21b0: 2c 0a 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c  ,....(unsigned l
21c0: 6f 6e 67 20 6c 6f 6e 67 29 20 72 61 6e 67 65 5f  ong long) range_
21d0: 73 74 61 72 74 0a 09 09 29 3b 0a 09 7d 0a 0a 09  start...);..}...
21e0: 2f 2a 20 46 69 6c 6c 20 75 70 20 73 74 72 75 63  /* Fill up struc
21f0: 74 75 72 65 20 74 6f 20 72 65 74 75 72 6e 20 2a  ture to return *
2200: 2f 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 70 61  /..buffer_st->pa
2210: 74 68 20 20 20 3d 20 70 61 74 68 3b 0a 09 62 75  th   = path;..bu
2220: 66 66 65 72 5f 73 74 2d 3e 68 65 61 64 65 72 73  ffer_st->headers
2230: 2e 72 61 6e 67 65 2e 70 72 65 73 65 6e 74 20 3d  .range.present =
2240: 20 72 61 6e 67 65 5f 72 65 71 75 65 73 74 3b 0a   range_request;.
2250: 09 62 75 66 66 65 72 5f 73 74 2d 3e 68 65 61 64  .buffer_st->head
2260: 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74  ers.range.offset
2270: 20 20 3d 20 72 61 6e 67 65 5f 73 74 61 72 74 3b    = range_start;
2280: 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 68 65 61  ..buffer_st->hea
2290: 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74  ders.range.lengt
22a0: 68 20 20 3d 20 72 61 6e 67 65 5f 6c 65 6e 67 74  h  = range_lengt
22b0: 68 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75 66 66  h;...return(buff
22c0: 65 72 5f 73 74 29 3b 0a 7d 0a 0a 2f 2a 20 52 65  er_st);.}../* Re
22d0: 74 75 72 6e 20 61 6e 20 65 72 72 6f 72 20 70 61  turn an error pa
22e0: 67 65 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69  ge */.static voi
22f0: 64 20 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61  d filed_error_pa
2300: 67 65 28 46 49 4c 45 20 2a 66 70 2c 20 63 6f 6e  ge(FILE *fp, con
2310: 73 74 20 63 68 61 72 20 2a 64 61 74 65 5f 63 75  st char *date_cu
2320: 72 72 65 6e 74 2c 20 69 6e 74 20 65 72 72 6f 72  rrent, int error
2330: 5f 6e 75 6d 62 65 72 29 20 7b 0a 09 63 68 61 72  _number) {..char
2340: 20 2a 65 72 72 6f 72 5f 73 74 72 69 6e 67 20 3d   *error_string =
2350: 20 22 3c 68 74 6d 6c 3e 3c 68 65 61 64 3e 3c 74   "<html><head><t
2360: 69 74 6c 65 3e 45 52 52 4f 52 3c 2f 74 69 74 6c  itle>ERROR</titl
2370: 65 3e 3c 2f 68 65 61 64 3e 3c 62 6f 64 79 3e 55  e></head><body>U
2380: 6e 61 62 6c 65 20 74 6f 20 70 72 6f 63 65 73 73  nable to process
2390: 20 72 65 71 75 65 73 74 3c 2f 62 6f 64 79 3e 3c   request</body><
23a0: 2f 68 74 6d 6c 3e 22 3b 0a 0a 09 66 70 72 69 6e  /html>";...fprin
23b0: 74 66 28 66 70 2c 20 22 48 54 54 50 2f 31 2e 31  tf(fp, "HTTP/1.1
23c0: 20 25 69 20 4f 4b 5c 72 5c 6e 44 61 74 65 3a 20   %i OK\r\nDate: 
23d0: 25 73 5c 72 5c 6e 53 65 72 76 65 72 3a 20 66 69  %s\r\nServer: fi
23e0: 6c 65 64 5c 72 5c 6e 4c 61 73 74 2d 4d 6f 64 69  led\r\nLast-Modi
23f0: 66 69 65 64 3a 20 25 73 5c 72 5c 6e 43 6f 6e 74  fied: %s\r\nCont
2400: 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 6c 6c 75  ent-Length: %llu
2410: 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 54 79 70 65  \r\nContent-Type
2420: 3a 20 25 73 5c 72 5c 6e 43 6f 6e 6e 65 63 74 69  : %s\r\nConnecti
2430: 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e 5c 72 5c  on: close\r\n\r\
2440: 6e 25 73 22 2c 0a 09 09 65 72 72 6f 72 5f 6e 75  n%s",...error_nu
2450: 6d 62 65 72 2c 0a 09 09 64 61 74 65 5f 63 75 72  mber,...date_cur
2460: 72 65 6e 74 2c 0a 09 09 64 61 74 65 5f 63 75 72  rent,...date_cur
2470: 72 65 6e 74 2c 0a 09 09 28 75 6e 73 69 67 6e 65  rent,...(unsigne
2480: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73 74 72  d long long) str
2490: 6c 65 6e 28 65 72 72 6f 72 5f 73 74 72 69 6e 67  len(error_string
24a0: 29 2c 0a 09 09 22 74 65 78 74 2f 68 74 6d 6c 22  ),..."text/html"
24b0: 2c 0a 09 09 65 72 72 6f 72 5f 73 74 72 69 6e 67  ,...error_string
24c0: 0a 09 29 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e 64 6c  ..);.}../* Handl
24d0: 65 20 61 20 73 69 6e 67 6c 65 20 72 65 71 75 65  e a single reque
24e0: 73 74 20 66 72 6f 6d 20 61 20 63 6c 69 65 6e 74  st from a client
24f0: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
2500: 66 69 6c 65 64 5f 68 61 6e 64 6c 65 5f 63 6c 69  filed_handle_cli
2510: 65 6e 74 28 69 6e 74 20 66 64 2c 20 73 74 72 75  ent(int fd, stru
2520: 63 74 20 66 69 6c 65 64 5f 68 74 74 70 5f 72 65  ct filed_http_re
2530: 71 75 65 73 74 20 2a 72 65 71 75 65 73 74 29 20  quest *request) 
2540: 7b 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f  {..struct filed_
2550: 66 69 6c 65 69 6e 66 6f 20 2a 66 69 6c 65 69 6e  fileinfo *filein
2560: 66 6f 3b 0a 09 73 73 69 7a 65 5f 74 20 73 65 6e  fo;..ssize_t sen
2570: 64 66 69 6c 65 5f 72 65 74 3b 0a 09 73 69 7a 65  dfile_ret;..size
2580: 5f 74 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 2c  _t sendfile_len,
2590: 20 73 65 6e 64 66 69 6c 65 5f 73 65 6e 74 2c 20   sendfile_sent, 
25a0: 73 65 6e 64 66 69 6c 65 5f 73 69 7a 65 3b 0a 09  sendfile_size;..
25b0: 6f 66 66 5f 74 20 73 65 6e 64 66 69 6c 65 5f 6f  off_t sendfile_o
25c0: 66 66 73 65 74 3b 0a 09 63 68 61 72 20 2a 70 61  ffset;..char *pa
25d0: 74 68 3b 0a 09 63 68 61 72 20 2a 64 61 74 65 5f  th;..char *date_
25e0: 63 75 72 72 65 6e 74 2c 20 64 61 74 65 5f 63 75  current, date_cu
25f0: 72 72 65 6e 74 5f 62 5b 36 34 5d 3b 0a 09 69 6e  rrent_b[64];..in
2600: 74 20 68 74 74 70 5f 63 6f 64 65 3b 0a 09 46 49  t http_code;..FI
2610: 4c 45 20 2a 66 70 3b 0a 0a 09 2f 2a 20 44 65 74  LE *fp;.../* Det
2620: 65 72 6d 69 6e 65 20 63 75 72 72 65 6e 74 20 74  ermine current t
2630: 69 6d 65 20 2a 2f 0a 09 64 61 74 65 5f 63 75 72  ime */..date_cur
2640: 72 65 6e 74 20 3d 20 66 69 6c 65 64 5f 66 6f 72  rent = filed_for
2650: 6d 61 74 5f 74 69 6d 65 28 64 61 74 65 5f 63 75  mat_time(date_cu
2660: 72 72 65 6e 74 5f 62 2c 20 73 69 7a 65 6f 66 28  rrent_b, sizeof(
2670: 64 61 74 65 5f 63 75 72 72 65 6e 74 5f 62 29 2c  date_current_b),
2680: 20 74 69 6d 65 28 4e 55 4c 4c 29 29 3b 0a 0a 09   time(NULL));...
2690: 2f 2a 20 4f 70 65 6e 20 73 6f 63 6b 65 74 20 61  /* Open socket a
26a0: 73 20 41 4e 53 49 20 49 2f 4f 20 66 6f 72 20 65  s ANSI I/O for e
26b0: 61 73 65 20 6f 66 20 75 73 65 20 2a 2f 0a 09 66  ase of use */..f
26c0: 70 20 3d 20 66 64 6f 70 65 6e 28 66 64 2c 20 22  p = fdopen(fd, "
26d0: 77 2b 62 22 29 3b 0a 09 69 66 20 28 66 70 20 3d  w+b");..if (fp =
26e0: 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 63 6c 6f 73  = NULL) {...clos
26f0: 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  e(fd);....return
2700: 3b 0a 09 7d 0a 0a 09 72 65 71 75 65 73 74 20 3d  ;..}...request =
2710: 20 66 69 6c 65 64 5f 67 65 74 5f 68 74 74 70 5f   filed_get_http_
2720: 72 65 71 75 65 73 74 28 66 70 2c 20 72 65 71 75  request(fp, requ
2730: 65 73 74 29 3b 0a 0a 09 66 69 6c 65 64 5f 6c 6f  est);...filed_lo
2740: 67 5f 6d 73 67 28 22 50 52 4f 43 45 53 53 5f 52  g_msg("PROCESS_R
2750: 45 50 4c 59 5f 53 54 41 52 54 20 46 44 3d 2e 2e  EPLY_START FD=..
2760: 2e 20 50 41 54 48 3d 2e 2e 2e 20 52 41 4e 47 45  . PATH=... RANGE
2770: 5f 53 54 41 52 54 3d 2e 2e 2e 20 52 41 4e 47 45  _START=... RANGE
2780: 5f 4c 45 4e 47 54 48 3d 2e 2e 2e 22 29 3b 0a 0a  _LENGTH=...");..
2790: 09 69 66 20 28 72 65 71 75 65 73 74 20 3d 3d 20  .if (request == 
27a0: 4e 55 4c 4c 20 7c 7c 20 72 65 71 75 65 73 74 2d  NULL || request-
27b0: 3e 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29 20 7b  >path == NULL) {
27c0: 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70  ...filed_error_p
27d0: 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72  age(fp, date_cur
27e0: 72 65 6e 74 2c 20 35 30 30 29 3b 0a 0a 09 09 66  rent, 500);....f
27f0: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52  iled_log_msg("PR
2800: 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50  OCESS_REPLY_COMP
2810: 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f  LETE FD=... ERRO
2820: 52 3d 35 30 30 22 29 3b 0a 0a 09 09 66 63 6c 6f  R=500");....fclo
2830: 73 65 28 66 70 29 3b 0a 0a 09 09 72 65 74 75 72  se(fp);....retur
2840: 6e 3b 0a 09 7d 0a 0a 09 70 61 74 68 20 3d 20 72  n;..}...path = r
2850: 65 71 75 65 73 74 2d 3e 70 61 74 68 3b 0a 0a 09  equest->path;...
2860: 68 74 74 70 5f 63 6f 64 65 20 3d 20 2d 31 3b 0a  http_code = -1;.
2870: 0a 09 66 69 6c 65 69 6e 66 6f 20 3d 20 66 69 6c  ..fileinfo = fil
2880: 65 64 5f 6f 70 65 6e 5f 66 69 6c 65 28 70 61 74  ed_open_file(pat
2890: 68 2c 20 26 72 65 71 75 65 73 74 2d 3e 66 69 6c  h, &request->fil
28a0: 65 69 6e 66 6f 29 3b 0a 09 69 66 20 28 66 69 6c  einfo);..if (fil
28b0: 65 69 6e 66 6f 20 3d 3d 20 4e 55 4c 4c 29 20 7b  einfo == NULL) {
28c0: 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70  ...filed_error_p
28d0: 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72  age(fp, date_cur
28e0: 72 65 6e 74 2c 20 34 30 34 29 3b 0a 0a 09 09 66  rent, 404);....f
28f0: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52  iled_log_msg("PR
2900: 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50  OCESS_REPLY_COMP
2910: 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45 52 52 4f  LETE FD=... ERRO
2920: 52 3d 34 30 34 22 29 3b 0a 09 7d 20 65 6c 73 65  R=404");..} else
2930: 20 7b 0a 09 09 69 66 20 28 72 65 71 75 65 73 74   {...if (request
2940: 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e  ->headers.range.
2950: 6f 66 66 73 65 74 20 21 3d 20 30 20 7c 7c 20 72  offset != 0 || r
2960: 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e  equest->headers.
2970: 72 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3e 3d 20  range.length >= 
2980: 30 29 20 7b 0a 09 09 09 69 66 20 28 72 65 71 75  0) {....if (requ
2990: 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e  est->headers.ran
29a0: 67 65 2e 6f 66 66 73 65 74 20 3e 3d 20 66 69 6c  ge.offset >= fil
29b0: 65 69 6e 66 6f 2d 3e 6c 65 6e 29 20 7b 0a 09 09  einfo->len) {...
29c0: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
29d0: 22 50 52 4f 43 45 53 53 5f 52 45 50 4c 59 5f 43  "PROCESS_REPLY_C
29e0: 4f 4d 50 4c 45 54 45 20 46 44 3d 2e 2e 2e 20 45  OMPLETE FD=... E
29f0: 52 52 4f 52 3d 34 31 36 22 29 3b 0a 0a 09 09 09  RROR=416");.....
2a00: 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61 67  .filed_error_pag
2a10: 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72 72 65  e(fp, date_curre
2a20: 6e 74 2c 20 34 31 36 29 3b 0a 09 09 09 7d 20 65  nt, 416);....} e
2a30: 6c 73 65 20 7b 0a 09 09 09 09 69 66 20 28 72 65  lse {.....if (re
2a40: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72  quest->headers.r
2a50: 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3c 20 30 29  ange.length < 0)
2a60: 20 7b 0a 09 09 09 09 09 66 69 6c 65 64 5f 6c 6f   {......filed_lo
2a70: 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 43 6f 6d  g_msg_debug("Com
2a80: 70 75 74 69 6e 67 20 6c 65 6e 67 74 68 20 74 6f  puting length to
2a90: 20 66 69 74 20 69 6e 20 62 6f 75 6e 64 73 3a 20   fit in bounds: 
2aa0: 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 20 3d 20  fileinfo->len = 
2ab0: 25 6c 6c 75 2c 20 72 65 71 75 65 73 74 2d 3e 68  %llu, request->h
2ac0: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66  eaders.range.off
2ad0: 73 65 74 20 3d 20 25 6c 6c 75 22 2c 0a 09 09 09  set = %llu",....
2ae0: 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ...(unsigned lon
2af0: 67 20 6c 6f 6e 67 29 20 66 69 6c 65 69 6e 66 6f  g long) fileinfo
2b00: 2d 3e 6c 65 6e 2c 0a 09 09 09 09 09 09 28 75 6e  ->len,.......(un
2b10: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
2b20: 29 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65  ) request->heade
2b30: 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74 0a  rs.range.offset.
2b40: 09 09 09 09 09 29 3b 0a 0a 09 09 09 09 09 72 65  .....);.......re
2b50: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72  quest->headers.r
2b60: 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3d 20 66 69  ange.length = fi
2b70: 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 20 2d 20 72 65  leinfo->len - re
2b80: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72  quest->headers.r
2b90: 61 6e 67 65 2e 6f 66 66 73 65 74 3b 0a 09 09 09  ange.offset;....
2ba0: 09 7d 0a 0a 09 09 09 09 66 69 6c 65 64 5f 6c 6f  .}......filed_lo
2bb0: 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 50 61 72  g_msg_debug("Par
2bc0: 74 69 61 6c 20 72 65 71 75 65 73 74 2c 20 73 74  tial request, st
2bd0: 61 72 74 69 6e 67 20 61 74 3a 20 25 6c 6c 75 20  arting at: %llu 
2be0: 61 6e 64 20 72 75 6e 6e 69 6e 67 20 66 6f 72 20  and running for 
2bf0: 25 6c 6c 75 20 62 79 74 65 73 22 2c 0a 09 09 09  %llu bytes",....
2c00: 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  ..(unsigned long
2c10: 20 6c 6f 6e 67 29 20 72 65 71 75 65 73 74 2d 3e   long) request->
2c20: 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66  headers.range.of
2c30: 66 73 65 74 2c 0a 09 09 09 09 09 28 75 6e 73 69  fset,......(unsi
2c40: 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20  gned long long) 
2c50: 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73  request->headers
2c60: 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 0a 09 09  .range.length...
2c70: 09 09 29 3b 0a 0a 09 09 09 09 68 74 74 70 5f 63  ..);......http_c
2c80: 6f 64 65 20 3d 20 32 30 36 3b 0a 09 09 09 7d 0a  ode = 206;....}.
2c90: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 69 66  ..} else {....if
2ca0: 20 28 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65   (request->heade
2cb0: 72 73 2e 72 61 6e 67 65 2e 70 72 65 73 65 6e 74  rs.range.present
2cc0: 29 20 7b 0a 09 09 09 09 68 74 74 70 5f 63 6f 64  ) {.....http_cod
2cd0: 65 20 3d 20 32 30 36 3b 0a 09 09 09 7d 20 65 6c  e = 206;....} el
2ce0: 73 65 20 7b 0a 09 09 09 09 68 74 74 70 5f 63 6f  se {.....http_co
2cf0: 64 65 20 3d 20 32 30 30 3b 0a 09 09 09 7d 0a 09  de = 200;....}..
2d00: 09 09 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65  ..request->heade
2d10: 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74 20  rs.range.offset 
2d20: 3d 20 30 3b 0a 09 09 09 72 65 71 75 65 73 74 2d  = 0;....request-
2d30: 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c  >headers.range.l
2d40: 65 6e 67 74 68 20 3d 20 66 69 6c 65 69 6e 66 6f  ength = fileinfo
2d50: 2d 3e 6c 65 6e 3b 0a 09 09 7d 0a 0a 09 09 69 66  ->len;...}....if
2d60: 20 28 68 74 74 70 5f 63 6f 64 65 20 3e 20 30 29   (http_code > 0)
2d70: 20 7b 0a 09 09 09 66 70 72 69 6e 74 66 28 66 70   {....fprintf(fp
2d80: 2c 20 22 48 54 54 50 2f 31 2e 31 20 25 69 20 4f  , "HTTP/1.1 %i O
2d90: 4b 5c 72 5c 6e 44 61 74 65 3a 20 25 73 5c 72 5c  K\r\nDate: %s\r\
2da0: 6e 53 65 72 76 65 72 3a 20 66 69 6c 65 64 5c 72  nServer: filed\r
2db0: 5c 6e 4c 61 73 74 2d 4d 6f 64 69 66 69 65 64 3a  \nLast-Modified:
2dc0: 20 25 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 4c   %s\r\nContent-L
2dd0: 65 6e 67 74 68 3a 20 25 6c 6c 75 5c 72 5c 6e 41  ength: %llu\r\nA
2de0: 63 63 65 70 74 2d 52 61 6e 67 65 73 3a 20 62 79  ccept-Ranges: by
2df0: 74 65 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 54  tes\r\nContent-T
2e00: 79 70 65 3a 20 25 73 5c 72 5c 6e 43 6f 6e 6e 65  ype: %s\r\nConne
2e10: 63 74 69 6f 6e 3a 20 63 6c 6f 73 65 5c 72 5c 6e  ction: close\r\n
2e20: 22 2c 0a 09 09 09 09 68 74 74 70 5f 63 6f 64 65  ",.....http_code
2e30: 2c 0a 09 09 09 09 64 61 74 65 5f 63 75 72 72 65  ,.....date_curre
2e40: 6e 74 2c 0a 09 09 09 09 66 69 6c 65 69 6e 66 6f  nt,.....fileinfo
2e50: 2d 3e 6c 61 73 74 6d 6f 64 2c 0a 09 09 09 09 28  ->lastmod,.....(
2e60: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
2e70: 6e 67 29 20 72 65 71 75 65 73 74 2d 3e 68 65 61  ng) request->hea
2e80: 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74  ders.range.lengt
2e90: 68 2c 0a 09 09 09 09 66 69 6c 65 69 6e 66 6f 2d  h,.....fileinfo-
2ea0: 3e 74 79 70 65 0a 09 09 09 29 3b 0a 09 09 09 69  >type....);....i
2eb0: 66 20 28 68 74 74 70 5f 63 6f 64 65 20 3d 3d 20  f (http_code == 
2ec0: 32 30 36 29 20 7b 0a 09 09 09 09 66 70 72 69 6e  206) {.....fprin
2ed0: 74 66 28 66 70 2c 20 22 43 6f 6e 74 65 6e 74 2d  tf(fp, "Content-
2ee0: 52 61 6e 67 65 3a 20 62 79 74 65 73 20 25 6c 6c  Range: bytes %ll
2ef0: 75 2d 25 6c 6c 75 2f 25 6c 6c 75 5c 72 5c 6e 22  u-%llu/%llu\r\n"
2f00: 2c 0a 09 09 09 09 09 28 75 6e 73 69 67 6e 65 64  ,......(unsigned
2f10: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 72 65 71 75   long long) requ
2f20: 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e  est->headers.ran
2f30: 67 65 2e 6f 66 66 73 65 74 2c 0a 09 09 09 09 09  ge.offset,......
2f40: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
2f50: 6f 6e 67 29 20 28 72 65 71 75 65 73 74 2d 3e 68  ong) (request->h
2f60: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66  eaders.range.off
2f70: 73 65 74 20 2b 20 72 65 71 75 65 73 74 2d 3e 68  set + request->h
2f80: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e  eaders.range.len
2f90: 67 74 68 20 2d 20 31 29 2c 0a 09 09 09 09 09 28  gth - 1),......(
2fa0: 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f  unsigned long lo
2fb0: 6e 67 29 20 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65  ng) fileinfo->le
2fc0: 6e 0a 09 09 09 09 29 3b 0a 09 09 09 7d 0a 09 09  n.....);....}...
2fd0: 09 66 70 72 69 6e 74 66 28 66 70 2c 20 22 5c 72  .fprintf(fp, "\r
2fe0: 5c 6e 22 29 3b 0a 09 09 09 66 66 6c 75 73 68 28  \n");....fflush(
2ff0: 66 70 29 3b 0a 0a 09 09 09 66 69 6c 65 64 5f 6c  fp);.....filed_l
3000: 6f 67 5f 6d 73 67 28 22 50 52 4f 43 45 53 53 5f  og_msg("PROCESS_
3010: 52 45 50 4c 59 5f 43 4f 4d 50 4c 45 54 45 20 46  REPLY_COMPLETE F
3020: 44 3d 2e 2e 2e 20 53 54 41 54 55 53 3d 32 30 58  D=... STATUS=20X
3030: 22 29 3b 0a 0a 23 69 66 64 65 66 20 46 49 4c 45  ");..#ifdef FILE
3040: 44 5f 4e 4f 4e 42 4c 4f 43 4b 5f 48 54 54 50 0a  D_NONBLOCK_HTTP.
3050: 09 09 09 69 6e 74 20 73 6f 63 6b 65 74 5f 66 6c  ...int socket_fl
3060: 61 67 73 3b 0a 09 09 09 66 64 5f 73 65 74 20 72  ags;....fd_set r
3070: 66 64 2c 20 77 66 64 3b 0a 09 09 09 63 68 61 72  fd, wfd;....char
3080: 20 73 69 6e 6b 62 75 66 5b 38 31 39 32 5d 3b 0a   sinkbuf[8192];.
3090: 09 09 09 73 73 69 7a 65 5f 74 20 72 65 61 64 5f  ...ssize_t read_
30a0: 72 65 74 3b 0a 0a 09 09 09 46 44 5f 5a 45 52 4f  ret;.....FD_ZERO
30b0: 28 26 72 66 64 29 3b 0a 09 09 09 46 44 5f 5a 45  (&rfd);....FD_ZE
30c0: 52 4f 28 26 77 66 64 29 3b 0a 09 09 09 46 44 5f  RO(&wfd);....FD_
30d0: 53 45 54 28 66 64 2c 20 26 72 66 64 29 3b 0a 09  SET(fd, &rfd);..
30e0: 09 09 46 44 5f 53 45 54 28 66 64 2c 20 26 77 66  ..FD_SET(fd, &wf
30f0: 64 29 3b 0a 0a 09 09 09 73 6f 63 6b 65 74 5f 66  d);.....socket_f
3100: 6c 61 67 73 20 3d 20 66 63 6e 74 6c 28 66 64 2c  lags = fcntl(fd,
3110: 20 46 5f 47 45 54 46 4c 29 3b 0a 09 09 09 66 63   F_GETFL);....fc
3120: 6e 74 6c 28 66 64 2c 20 46 5f 53 45 54 46 4c 2c  ntl(fd, F_SETFL,
3130: 20 73 6f 63 6b 65 74 5f 66 6c 61 67 73 20 7c 20   socket_flags | 
3140: 4f 5f 4e 4f 4e 42 4c 4f 43 4b 29 3b 0a 23 65 6e  O_NONBLOCK);.#en
3150: 64 69 66 0a 0a 09 09 09 66 69 6c 65 64 5f 6c 6f  dif.....filed_lo
3160: 67 5f 6d 73 67 28 22 53 45 4e 44 5f 53 54 41 52  g_msg("SEND_STAR
3170: 54 20 49 46 44 3d 2e 2e 2e 20 4f 46 44 3d 2e 2e  T IFD=... OFD=..
3180: 2e 20 42 59 54 45 53 3d 2e 2e 2e 22 29 3b 0a 0a  . BYTES=...");..
3190: 09 09 09 73 65 6e 64 66 69 6c 65 5f 6f 66 66 73  ...sendfile_offs
31a0: 65 74 20 3d 20 72 65 71 75 65 73 74 2d 3e 68 65  et = request->he
31b0: 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73  aders.range.offs
31c0: 65 74 3b 0a 09 09 09 73 65 6e 64 66 69 6c 65 5f  et;....sendfile_
31d0: 6c 65 6e 20 3d 20 72 65 71 75 65 73 74 2d 3e 68  len = request->h
31e0: 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e  eaders.range.len
31f0: 67 74 68 3b 0a 09 09 09 73 65 6e 64 66 69 6c 65  gth;....sendfile
3200: 5f 73 65 6e 74 20 3d 20 30 3b 0a 09 09 09 77 68  _sent = 0;....wh
3210: 69 6c 65 20 28 31 29 20 7b 0a 09 09 09 09 69 66  ile (1) {.....if
3220: 20 28 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 3e   (sendfile_len >
3230: 20 46 49 4c 45 44 5f 53 45 4e 44 46 49 4c 45 5f   FILED_SENDFILE_
3240: 4d 41 58 29 20 7b 0a 09 09 09 09 09 73 65 6e 64  MAX) {......send
3250: 66 69 6c 65 5f 73 69 7a 65 20 3d 20 46 49 4c 45  file_size = FILE
3260: 44 5f 53 45 4e 44 46 49 4c 45 5f 4d 41 58 3b 0a  D_SENDFILE_MAX;.
3270: 09 09 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09  ....} else {....
3280: 09 09 73 65 6e 64 66 69 6c 65 5f 73 69 7a 65 20  ..sendfile_size 
3290: 3d 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 3b 0a  = sendfile_len;.
32a0: 09 09 09 09 7d 0a 0a 09 09 09 09 73 65 6e 64 66  ....}......sendf
32b0: 69 6c 65 5f 72 65 74 20 3d 20 73 65 6e 64 66 69  ile_ret = sendfi
32c0: 6c 65 28 66 64 2c 20 66 69 6c 65 69 6e 66 6f 2d  le(fd, fileinfo-
32d0: 3e 66 64 2c 20 26 73 65 6e 64 66 69 6c 65 5f 6f  >fd, &sendfile_o
32e0: 66 66 73 65 74 2c 20 73 65 6e 64 66 69 6c 65 5f  ffset, sendfile_
32f0: 73 69 7a 65 29 3b 0a 09 09 09 09 69 66 20 28 73  size);.....if (s
3300: 65 6e 64 66 69 6c 65 5f 72 65 74 20 3c 3d 20 30  endfile_ret <= 0
3310: 29 20 7b 0a 23 69 66 64 65 66 20 46 49 4c 45 44  ) {.#ifdef FILED
3320: 5f 4e 4f 4e 42 4c 4f 43 4b 5f 48 54 54 50 0a 09  _NONBLOCK_HTTP..
3330: 09 09 09 09 69 66 20 28 65 72 72 6e 6f 20 3d 3d  ....if (errno ==
3340: 20 45 41 47 41 49 4e 29 20 7b 0a 09 09 09 09 09   EAGAIN) {......
3350: 09 73 65 6e 64 66 69 6c 65 5f 72 65 74 20 3d 20  .sendfile_ret = 
3360: 30 3b 0a 0a 09 09 09 09 09 09 77 68 69 6c 65 20  0;........while 
3370: 28 31 29 20 7b 0a 09 09 09 09 09 09 09 73 65 6c  (1) {........sel
3380: 65 63 74 28 66 64 20 2b 20 31 2c 20 26 72 66 64  ect(fd + 1, &rfd
3390: 2c 20 26 77 66 64 2c 20 4e 55 4c 4c 2c 20 4e 55  , &wfd, NULL, NU
33a0: 4c 4c 29 3b 0a 09 09 09 09 09 09 09 69 66 20 28  LL);........if (
33b0: 46 44 5f 49 53 53 45 54 28 66 64 2c 20 26 72 66  FD_ISSET(fd, &rf
33c0: 64 29 29 20 7b 0a 09 09 09 09 09 09 09 09 72 65  d)) {.........re
33d0: 61 64 5f 72 65 74 20 3d 20 72 65 61 64 28 66 64  ad_ret = read(fd
33e0: 2c 20 73 69 6e 6b 62 75 66 2c 20 73 69 7a 65 6f  , sinkbuf, sizeo
33f0: 66 28 73 69 6e 6b 62 75 66 29 29 3b 0a 0a 09 09  f(sinkbuf));....
3400: 09 09 09 09 09 09 69 66 20 28 72 65 61 64 5f 72  ......if (read_r
3410: 65 74 20 3c 3d 20 30 29 20 7b 0a 09 09 09 09 09  et <= 0) {......
3420: 09 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09  ....break;......
3430: 09 09 09 7d 0a 09 09 09 09 09 09 09 7d 0a 0a 09  ...}........}...
3440: 09 09 09 09 09 09 69 66 20 28 46 44 5f 49 53 53  ......if (FD_ISS
3450: 45 54 28 66 64 2c 20 26 77 66 64 29 29 20 7b 0a  ET(fd, &wfd)) {.
3460: 09 09 09 09 09 09 09 09 72 65 61 64 5f 72 65 74  ........read_ret
3470: 20 3d 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62   = 1;..........b
3480: 72 65 61 6b 3b 0a 09 09 09 09 09 09 09 7d 0a 09  reak;........}..
3490: 09 09 09 09 09 7d 0a 0a 09 09 09 09 09 09 69 66  .....}........if
34a0: 20 28 72 65 61 64 5f 72 65 74 20 3c 3d 20 30 29   (read_ret <= 0)
34b0: 20 7b 0a 09 09 09 09 09 09 09 62 72 65 61 6b 3b   {........break;
34c0: 0a 09 09 09 09 09 09 7d 0a 09 09 09 09 09 7d 20  .......}......} 
34d0: 65 6c 73 65 20 7b 0a 09 09 09 09 09 09 62 72 65  else {.......bre
34e0: 61 6b 3b 0a 09 09 09 09 09 7d 0a 23 65 6c 73 65  ak;......}.#else
34f0: 0a 09 09 09 09 09 62 72 65 61 6b 3b 0a 23 65 6e  ......break;.#en
3500: 64 69 66 0a 09 09 09 09 7d 0a 0a 09 09 09 09 73  dif.....}......s
3510: 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 2d 3d 20 73  endfile_len -= s
3520: 65 6e 64 66 69 6c 65 5f 72 65 74 3b 0a 09 09 09  endfile_ret;....
3530: 09 73 65 6e 64 66 69 6c 65 5f 73 65 6e 74 20 2b  .sendfile_sent +
3540: 3d 20 73 65 6e 64 66 69 6c 65 5f 72 65 74 3b 0a  = sendfile_ret;.
3550: 09 09 09 09 69 66 20 28 73 65 6e 64 66 69 6c 65  ....if (sendfile
3560: 5f 6c 65 6e 20 3d 3d 20 30 29 20 7b 0a 09 09 09  _len == 0) {....
3570: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 7d 0a 09  ..break;.....}..
3580: 09 09 7d 0a 0a 09 09 09 66 69 6c 65 64 5f 6c 6f  ..}.....filed_lo
3590: 67 5f 6d 73 67 28 22 53 45 4e 44 5f 43 4f 4d 50  g_msg("SEND_COMP
35a0: 4c 45 54 45 20 53 54 41 54 55 53 3d 2e 2e 2e 20  LETE STATUS=... 
35b0: 49 46 44 3d 2e 2e 2e 20 4f 46 44 3d 2e 2e 2e 20  IFD=... OFD=... 
35c0: 42 59 54 45 53 3d 2e 2e 2e 20 42 59 54 45 53 5f  BYTES=... BYTES_
35d0: 53 45 4e 54 3d 2e 2e 2e 22 29 3b 0a 09 09 7d 0a  SENT=...");...}.
35e0: 0a 09 09 63 6c 6f 73 65 28 66 69 6c 65 69 6e 66  ...close(fileinf
35f0: 6f 2d 3e 66 64 29 3b 0a 0a 09 09 66 69 6c 65 64  o->fd);....filed
3600: 5f 6c 6f 67 5f 6d 73 67 28 22 43 4c 4f 53 45 5f  _log_msg("CLOSE_
3610: 46 49 4c 45 20 46 44 3d 2e 2e 2e 22 29 3b 0a 09  FILE FD=...");..
3620: 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  }...filed_log_ms
3630: 67 28 22 43 4c 4f 53 45 5f 43 4f 4e 4e 45 43 54  g("CLOSE_CONNECT
3640: 49 4f 4e 20 46 44 3d 2e 2e 2e 22 29 3b 0a 0a 09  ION FD=...");...
3650: 66 63 6c 6f 73 65 28 66 70 29 3b 0a 0a 09 72 65  fclose(fp);...re
3660: 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e 64  turn;.}../* Hand
3670: 6c 65 20 69 6e 63 6f 6d 69 6e 67 20 63 6f 6e 6e  le incoming conn
3680: 65 63 74 69 6f 6e 73 20 2a 2f 0a 73 74 61 74 69  ections */.stati
3690: 63 20 76 6f 69 64 20 2a 66 69 6c 65 64 5f 77 6f  c void *filed_wo
36a0: 72 6b 65 72 5f 74 68 72 65 61 64 28 76 6f 69 64  rker_thread(void
36b0: 20 2a 61 72 67 5f 76 29 20 7b 0a 09 73 74 72 75   *arg_v) {..stru
36c0: 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f  ct filed_worker_
36d0: 74 68 72 65 61 64 5f 61 72 67 73 20 2a 61 72 67  thread_args *arg
36e0: 3b 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f  ;..struct filed_
36f0: 68 74 74 70 5f 72 65 71 75 65 73 74 20 72 65 71  http_request req
3700: 75 65 73 74 3b 0a 09 73 74 72 75 63 74 20 73 6f  uest;..struct so
3710: 63 6b 61 64 64 72 5f 69 6e 36 20 61 64 64 72 3b  ckaddr_in6 addr;
3720: 0a 09 73 6f 63 6b 6c 65 6e 5f 74 20 61 64 64 72  ..socklen_t addr
3730: 6c 65 6e 3b 0a 09 69 6e 74 20 66 61 69 6c 75 72  len;..int failur
3740: 65 5f 63 6f 75 6e 74 20 3d 20 30 2c 20 6d 61 78  e_count = 0, max
3750: 5f 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3d  _failure_count =
3760: 20 4d 41 58 5f 46 41 49 4c 55 52 45 5f 43 4f 55   MAX_FAILURE_COU
3770: 4e 54 3b 0a 09 69 6e 74 20 6d 61 73 74 65 72 5f  NT;..int master_
3780: 66 64 2c 20 66 64 3b 0a 0a 09 2f 2a 20 52 65 61  fd, fd;.../* Rea
3790: 64 20 61 72 67 75 6d 65 6e 74 73 20 2a 2f 0a 09  d arguments */..
37a0: 61 72 67 20 3d 20 61 72 67 5f 76 3b 0a 0a 09 6d  arg = arg_v;...m
37b0: 61 73 74 65 72 5f 66 64 20 3d 20 61 72 67 2d 3e  aster_fd = arg->
37c0: 66 64 3b 0a 0a 09 77 68 69 6c 65 20 28 31 29 20  fd;...while (1) 
37d0: 7b 0a 09 09 2f 2a 20 46 61 69 6c 75 72 65 20 6c  {.../* Failure l
37e0: 6f 6f 70 20 70 72 65 76 65 6e 74 69 6f 6e 20 2a  oop prevention *
37f0: 2f 0a 09 09 69 66 20 28 66 61 69 6c 75 72 65 5f  /...if (failure_
3800: 63 6f 75 6e 74 20 3e 20 6d 61 78 5f 66 61 69 6c  count > max_fail
3810: 75 72 65 5f 63 6f 75 6e 74 29 20 7b 0a 09 09 09  ure_count) {....
3820: 62 72 65 61 6b 3b 0a 09 09 7d 0a 0a 09 09 2f 2a  break;...}..../*
3830: 20 41 63 63 65 70 74 20 61 20 6e 65 77 20 63 6c   Accept a new cl
3840: 69 65 6e 74 20 2a 2f 0a 09 09 61 64 64 72 6c 65  ient */...addrle
3850: 6e 20 3d 20 73 69 7a 65 6f 66 28 61 64 64 72 29  n = sizeof(addr)
3860: 3b 0a 09 09 66 64 20 3d 20 61 63 63 65 70 74 28  ;...fd = accept(
3870: 6d 61 73 74 65 72 5f 66 64 2c 20 28 73 74 72 75  master_fd, (stru
3880: 63 74 20 73 6f 63 6b 61 64 64 72 20 2a 29 20 26  ct sockaddr *) &
3890: 61 64 64 72 2c 20 26 61 64 64 72 6c 65 6e 29 3b  addr, &addrlen);
38a0: 0a 0a 09 09 2f 2a 0a 09 09 20 2a 20 49 66 20 77  ..../*... * If w
38b0: 65 20 66 61 69 6c 2c 20 6d 61 6b 65 20 61 20 6e  e fail, make a n
38c0: 6f 74 65 20 6f 66 20 69 74 20 73 6f 20 77 65 20  ote of it so we 
38d0: 64 6f 6e 27 74 20 67 6f 20 69 6e 74 6f 20 61 20  don't go into a 
38e0: 6c 6f 6f 70 20 6f 66 0a 09 09 20 2a 20 61 63 63  loop of... * acc
38f0: 65 70 74 28 29 20 66 61 69 6c 69 6e 67 0a 09 09  ept() failing...
3900: 20 2a 2f 0a 09 09 69 66 20 28 66 64 20 3c 20 30   */...if (fd < 0
3910: 29 20 7b 0a 09 09 09 2f 2a 20 4c 6f 67 20 74 68  ) {..../* Log th
3920: 65 20 6e 65 77 20 63 6f 6e 6e 65 63 74 69 6f 6e  e new connection
3930: 20 2a 2f 0a 09 09 09 66 69 6c 65 64 5f 6c 6f 67   */....filed_log
3940: 5f 6d 73 67 28 22 41 43 43 45 50 54 5f 46 41 49  _msg("ACCEPT_FAI
3950: 4c 45 44 22 29 3b 0a 0a 09 09 09 66 61 69 6c 75  LED");.....failu
3960: 72 65 5f 63 6f 75 6e 74 2b 2b 3b 0a 0a 09 09 09  re_count++;.....
3970: 63 6f 6e 74 69 6e 75 65 3b 0a 09 09 7d 0a 0a 09  continue;...}...
3980: 09 2f 2a 20 4c 6f 67 20 74 68 65 20 6e 65 77 20  ./* Log the new 
3990: 63 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 09 09  connection */...
39a0: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 4e  filed_log_msg("N
39b0: 45 57 5f 43 4f 4e 4e 45 43 54 49 4f 4e 20 53 52  EW_CONNECTION SR
39c0: 43 5f 41 44 44 52 3d 2e 2e 2e 20 53 52 43 5f 50  C_ADDR=... SRC_P
39d0: 4f 52 54 3d 2e 2e 2e 20 46 44 3d 2e 2e 2e 22 29  ORT=... FD=...")
39e0: 3b 0a 0a 09 09 2f 2a 20 52 65 73 65 74 20 66 61  ;..../* Reset fa
39f0: 69 6c 75 72 65 20 63 6f 75 6e 74 2a 2f 0a 09 09  ilure count*/...
3a00: 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3d 20  failure_count = 
3a10: 30 3b 0a 0a 09 09 2f 2a 20 48 61 6e 64 6c 65 20  0;..../* Handle 
3a20: 73 6f 63 6b 65 74 20 2a 2f 0a 09 09 66 69 6c 65  socket */...file
3a30: 64 5f 68 61 6e 64 6c 65 5f 63 6c 69 65 6e 74 28  d_handle_client(
3a40: 66 64 2c 20 26 72 65 71 75 65 73 74 29 3b 0a 09  fd, &request);..
3a50: 7d 0a 0a 09 2f 2a 20 52 65 70 6f 72 74 20 65 72  }.../* Report er
3a60: 72 6f 72 20 2a 2f 0a 09 66 69 6c 65 64 5f 6c 6f  ror */..filed_lo
3a70: 67 5f 6d 73 67 28 22 54 48 52 45 41 44 5f 44 49  g_msg("THREAD_DI
3a80: 45 44 20 41 42 4e 4f 52 4d 41 4c 22 29 3b 0a 0a  ED ABNORMAL");..
3a90: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 7d  .return(NULL);.}
3aa0: 0a 0a 2f 2a 20 43 72 65 61 74 65 20 77 6f 72 6b  ../* Create work
3ab0: 65 72 20 74 68 72 65 61 64 73 20 2a 2f 0a 73 74  er threads */.st
3ac0: 61 74 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 77  atic int filed_w
3ad0: 6f 72 6b 65 72 5f 74 68 72 65 61 64 73 5f 69 6e  orker_threads_in
3ae0: 69 74 28 69 6e 74 20 66 64 2c 20 69 6e 74 20 74  it(int fd, int t
3af0: 68 72 65 61 64 5f 63 6f 75 6e 74 29 20 7b 0a 09  hread_count) {..
3b00: 73 74 72 75 63 74 20 66 69 6c 65 64 5f 77 6f 72  struct filed_wor
3b10: 6b 65 72 5f 74 68 72 65 61 64 5f 61 72 67 73 20  ker_thread_args 
3b20: 2a 61 72 67 3b 0a 09 70 74 68 72 65 61 64 5f 74  *arg;..pthread_t
3b30: 20 74 68 72 65 61 64 69 64 3b 0a 09 69 6e 74 20   threadid;..int 
3b40: 70 74 68 72 65 61 64 5f 72 65 74 3b 0a 09 69 6e  pthread_ret;..in
3b50: 74 20 69 3b 0a 0a 09 66 6f 72 20 28 69 20 3d 20  t i;...for (i = 
3b60: 30 3b 20 69 20 3c 20 74 68 72 65 61 64 5f 63 6f  0; i < thread_co
3b70: 75 6e 74 3b 20 69 2b 2b 29 20 7b 0a 09 09 61 72  unt; i++) {...ar
3b80: 67 20 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a 65 6f  g = malloc(sizeo
3b90: 66 28 2a 61 72 67 29 29 3b 0a 0a 09 09 61 72 67  f(*arg));....arg
3ba0: 2d 3e 66 64 20 3d 20 66 64 3b 0a 0a 09 09 70 74  ->fd = fd;....pt
3bb0: 68 72 65 61 64 5f 72 65 74 20 3d 20 70 74 68 72  hread_ret = pthr
3bc0: 65 61 64 5f 63 72 65 61 74 65 28 26 74 68 72 65  ead_create(&thre
3bd0: 61 64 69 64 2c 20 4e 55 4c 4c 2c 20 66 69 6c 65  adid, NULL, file
3be0: 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64 2c  d_worker_thread,
3bf0: 20 61 72 67 29 3b 0a 09 09 69 66 20 28 70 74 68   arg);...if (pth
3c00: 72 65 61 64 5f 72 65 74 20 21 3d 20 30 29 20 7b  read_ret != 0) {
3c10: 0a 09 09 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a  ....return(-1);.
3c20: 09 09 7d 0a 09 7d 0a 0a 09 72 65 74 75 72 6e 28  ..}..}...return(
3c30: 30 29 3b 0a 7d 0a 0a 2f 2a 20 44 69 73 70 6c 61  0);.}../* Displa
3c40: 79 20 68 65 6c 70 20 2a 2f 0a 73 74 61 74 69 63  y help */.static
3c50: 20 76 6f 69 64 20 66 69 6c 65 64 5f 70 72 69 6e   void filed_prin
3c60: 74 5f 68 65 6c 70 28 46 49 4c 45 20 2a 6f 75 74  t_help(FILE *out
3c70: 70 75 74 2c 20 63 6f 6e 73 74 20 63 68 61 72 20  put, const char 
3c80: 2a 65 78 74 72 61 29 20 7b 0a 09 69 66 20 28 65  *extra) {..if (e
3c90: 78 74 72 61 29 20 7b 0a 09 09 66 70 72 69 6e 74  xtra) {...fprint
3ca0: 66 28 6f 75 74 70 75 74 2c 20 22 25 73 5c 6e 22  f(output, "%s\n"
3cb0: 2c 20 65 78 74 72 61 29 3b 0a 09 7d 0a 0a 09 66  , extra);..}...f
3cc0: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22  printf(output, "
3cd0: 55 73 61 67 65 3a 20 66 69 6c 65 64 20 5b 3c 6f  Usage: filed [<o
3ce0: 70 74 69 6f 6e 73 3e 5d 5c 6e 22 29 3b 0a 0a 09  ptions>]\n");...
3cf0: 72 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 41 64  return;.}../* Ad
3d00: 64 20 61 20 67 65 74 6f 70 74 20 6f 70 74 69 6f  d a getopt optio
3d10: 6e 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64  n */.static void
3d20: 20 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c 6f   filed_getopt_lo
3d30: 6e 67 5f 73 65 74 6f 70 74 28 73 74 72 75 63 74  ng_setopt(struct
3d40: 20 6f 70 74 69 6f 6e 20 2a 6f 70 74 2c 20 63 6f   option *opt, co
3d50: 6e 73 74 20 63 68 61 72 20 2a 6e 61 6d 65 2c 20  nst char *name, 
3d60: 69 6e 74 20 68 61 73 5f 61 72 67 2c 20 69 6e 74  int has_arg, int
3d70: 20 76 61 6c 29 20 7b 0a 09 6f 70 74 2d 3e 6e 61   val) {..opt->na
3d80: 6d 65 20 20 20 20 20 3d 20 6e 61 6d 65 3b 0a 09  me     = name;..
3d90: 6f 70 74 2d 3e 68 61 73 5f 61 72 67 20 20 3d 20  opt->has_arg  = 
3da0: 68 61 73 5f 61 72 67 3b 0a 09 6f 70 74 2d 3e 66  has_arg;..opt->f
3db0: 6c 61 67 20 20 20 20 20 3d 20 4e 55 4c 4c 3b 0a  lag     = NULL;.
3dc0: 09 6f 70 74 2d 3e 76 61 6c 20 20 20 20 20 20 3d  .opt->val      =
3dd0: 20 76 61 6c 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a   val;...return;.
3de0: 7d 0a 0a 2f 2a 20 52 65 73 6f 6c 76 65 20 61 20  }../* Resolve a 
3df0: 75 73 65 72 6e 61 6d 65 20 74 6f 20 61 20 55 49  username to a UI
3e00: 44 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20  D */.static int 
3e10: 66 69 6c 65 64 5f 75 73 65 72 5f 6c 6f 6f 6b 75  filed_user_looku
3e20: 70 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 75 73  p(const char *us
3e30: 65 72 2c 20 75 69 64 5f 74 20 2a 75 73 65 72 5f  er, uid_t *user_
3e40: 69 64 29 20 7b 0a 09 73 74 72 75 63 74 20 70 61  id) {..struct pa
3e50: 73 73 77 64 20 2a 65 6e 74 3b 0a 0a 09 65 6e 74  sswd *ent;...ent
3e60: 20 3d 20 67 65 74 70 77 6e 61 6d 28 75 73 65 72   = getpwnam(user
3e70: 29 3b 0a 09 69 66 20 28 65 6e 74 20 3d 3d 20 4e  );..if (ent == N
3e80: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
3e90: 31 29 3b 0a 09 7d 0a 0a 09 2a 75 73 65 72 5f 69  1);..}...*user_i
3ea0: 64 20 3d 20 65 6e 74 2d 3e 70 77 5f 75 69 64 3b  d = ent->pw_uid;
3eb0: 0a 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a  ...return(0);.}.
3ec0: 0a 2f 2a 20 52 75 6e 20 70 72 6f 63 65 73 73 20  ./* Run process 
3ed0: 2a 2f 0a 69 6e 74 20 6d 61 69 6e 28 69 6e 74 20  */.int main(int 
3ee0: 61 72 67 63 2c 20 63 68 61 72 20 2a 2a 61 72 67  argc, char **arg
3ef0: 76 29 20 7b 0a 09 73 74 72 75 63 74 20 6f 70 74  v) {..struct opt
3f00: 69 6f 6e 20 6f 70 74 69 6f 6e 73 5b 38 5d 3b 0a  ion options[8];.
3f10: 09 63 6f 6e 73 74 20 63 68 61 72 20 2a 62 69 6e  .const char *bin
3f20: 64 5f 61 64 64 72 20 3d 20 42 49 4e 44 5f 41 44  d_addr = BIND_AD
3f30: 44 52 2c 20 2a 6e 65 77 72 6f 6f 74 20 3d 20 4e  DR, *newroot = N
3f40: 55 4c 4c 3b 0a 09 75 69 64 5f 74 20 75 73 65 72  ULL;..uid_t user
3f50: 20 3d 20 30 3b 0a 09 69 6e 74 20 70 6f 72 74 20   = 0;..int port 
3f60: 3d 20 50 4f 52 54 2c 20 74 68 72 65 61 64 5f 63  = PORT, thread_c
3f70: 6f 75 6e 74 20 3d 20 54 48 52 45 41 44 5f 43 4f  ount = THREAD_CO
3f80: 55 4e 54 3b 0a 09 69 6e 74 20 63 61 63 68 65 5f  UNT;..int cache_
3f90: 73 69 7a 65 20 3d 20 43 41 43 48 45 5f 53 49 5a  size = CACHE_SIZ
3fa0: 45 3b 0a 09 69 6e 74 20 69 6e 69 74 5f 72 65 74  E;..int init_ret
3fb0: 2c 20 63 68 72 6f 6f 74 5f 72 65 74 2c 20 73 65  , chroot_ret, se
3fc0: 74 75 69 64 5f 72 65 74 2c 20 6c 6f 6f 6b 75 70  tuid_ret, lookup
3fd0: 5f 72 65 74 2c 20 63 68 64 69 72 5f 72 65 74 3b  _ret, chdir_ret;
3fe0: 0a 09 69 6e 74 20 73 65 74 75 69 64 5f 65 6e 61  ..int setuid_ena
3ff0: 62 6c 65 64 20 3d 20 30 3b 0a 09 69 6e 74 20 63  bled = 0;..int c
4000: 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09 2f 2a  h;..int fd;.../*
4010: 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d 65 6e   Process argumen
4020: 74 73 20 2a 2f 0a 09 66 69 6c 65 64 5f 67 65 74  ts */..filed_get
4030: 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74 6f 70 74 28  opt_long_setopt(
4040: 26 6f 70 74 69 6f 6e 73 5b 30 5d 2c 20 22 70 6f  &options[0], "po
4050: 72 74 22 2c 20 72 65 71 75 69 72 65 64 5f 61 72  rt", required_ar
4060: 67 75 6d 65 6e 74 2c 20 27 70 27 29 3b 0a 09 66  gument, 'p');..f
4070: 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67  iled_getopt_long
4080: 5f 73 65 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73  _setopt(&options
4090: 5b 31 5d 2c 20 22 74 68 72 65 61 64 73 22 2c 20  [1], "threads", 
40a0: 72 65 71 75 69 72 65 64 5f 61 72 67 75 6d 65 6e  required_argumen
40b0: 74 2c 20 27 74 27 29 3b 0a 09 66 69 6c 65 64 5f  t, 't');..filed_
40c0: 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74 6f  getopt_long_seto
40d0: 70 74 28 26 6f 70 74 69 6f 6e 73 5b 32 5d 2c 20  pt(&options[2], 
40e0: 22 63 61 63 68 65 22 2c 20 72 65 71 75 69 72 65  "cache", require
40f0: 64 5f 61 72 67 75 6d 65 6e 74 2c 20 27 63 27 29  d_argument, 'c')
4100: 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f  ;..filed_getopt_
4110: 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f 70 74  long_setopt(&opt
4120: 69 6f 6e 73 5b 33 5d 2c 20 22 62 69 6e 64 22 2c  ions[3], "bind",
4130: 20 72 65 71 75 69 72 65 64 5f 61 72 67 75 6d 65   required_argume
4140: 6e 74 2c 20 27 62 27 29 3b 0a 09 66 69 6c 65 64  nt, 'b');..filed
4150: 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74  _getopt_long_set
4160: 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 34 5d 2c  opt(&options[4],
4170: 20 22 75 73 65 72 22 2c 20 72 65 71 75 69 72 65   "user", require
4180: 64 5f 61 72 67 75 6d 65 6e 74 2c 20 27 75 27 29  d_argument, 'u')
4190: 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f  ;..filed_getopt_
41a0: 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f 70 74  long_setopt(&opt
41b0: 69 6f 6e 73 5b 35 5d 2c 20 22 72 6f 6f 74 22 2c  ions[5], "root",
41c0: 20 72 65 71 75 69 72 65 64 5f 61 72 67 75 6d 65   required_argume
41d0: 6e 74 2c 20 27 72 27 29 3b 0a 09 66 69 6c 65 64  nt, 'r');..filed
41e0: 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74  _getopt_long_set
41f0: 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 36 5d 2c  opt(&options[6],
4200: 20 22 68 65 6c 70 22 2c 20 6e 6f 5f 61 72 67 75   "help", no_argu
4210: 6d 65 6e 74 2c 20 27 68 27 29 3b 0a 09 66 69 6c  ment, 'h');..fil
4220: 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73  ed_getopt_long_s
4230: 65 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 37  etopt(&options[7
4240: 5d 2c 20 4e 55 4c 4c 2c 20 30 2c 20 30 29 3b 0a  ], NULL, 0, 0);.
4250: 09 77 68 69 6c 65 20 28 28 63 68 20 3d 20 67 65  .while ((ch = ge
4260: 74 6f 70 74 5f 6c 6f 6e 67 28 61 72 67 63 2c 20  topt_long(argc, 
4270: 61 72 67 76 2c 20 22 70 3a 74 3a 63 3a 62 3a 75  argv, "p:t:c:b:u
4280: 3a 72 3a 68 22 2c 20 6f 70 74 69 6f 6e 73 2c 20  :r:h", options, 
4290: 4e 55 4c 4c 29 29 20 21 3d 20 2d 31 29 20 7b 0a  NULL)) != -1) {.
42a0: 09 09 73 77 69 74 63 68 28 63 68 29 20 7b 0a 09  ..switch(ch) {..
42b0: 09 09 63 61 73 65 20 27 70 27 3a 0a 09 09 09 09  ..case 'p':.....
42c0: 70 6f 72 74 20 3d 20 61 74 6f 69 28 6f 70 74 61  port = atoi(opta
42d0: 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  rg);.....break;.
42e0: 09 09 09 63 61 73 65 20 27 74 27 3a 0a 09 09 09  ...case 't':....
42f0: 09 74 68 72 65 61 64 5f 63 6f 75 6e 74 20 3d 20  .thread_count = 
4300: 61 74 6f 69 28 6f 70 74 61 72 67 29 3b 0a 09 09  atoi(optarg);...
4310: 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65  ..break;....case
4320: 20 27 63 27 3a 0a 09 09 09 09 63 61 63 68 65 5f   'c':.....cache_
4330: 73 69 7a 65 20 3d 20 61 74 6f 69 28 6f 70 74 61  size = atoi(opta
4340: 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  rg);.....break;.
4350: 09 09 09 63 61 73 65 20 27 62 27 3a 0a 09 09 09  ...case 'b':....
4360: 09 62 69 6e 64 5f 61 64 64 72 20 3d 20 73 74 72  .bind_addr = str
4370: 64 75 70 28 6f 70 74 61 72 67 29 3b 0a 09 09 09  dup(optarg);....
4380: 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20  .break;....case 
4390: 27 75 27 3a 0a 09 09 09 09 73 65 74 75 69 64 5f  'u':.....setuid_
43a0: 65 6e 61 62 6c 65 64 20 3d 20 31 3b 0a 09 09 09  enabled = 1;....
43b0: 09 6c 6f 6f 6b 75 70 5f 72 65 74 20 3d 20 66 69  .lookup_ret = fi
43c0: 6c 65 64 5f 75 73 65 72 5f 6c 6f 6f 6b 75 70 28  led_user_lookup(
43d0: 6f 70 74 61 72 67 2c 20 26 75 73 65 72 29 3b 0a  optarg, &user);.
43e0: 09 09 09 09 69 66 20 28 6c 6f 6f 6b 75 70 5f 72  ....if (lookup_r
43f0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 09 09  et != 0) {......
4400: 66 69 6c 65 64 5f 70 72 69 6e 74 5f 68 65 6c 70  filed_print_help
4410: 28 73 74 64 65 72 72 2c 20 22 49 6e 76 61 6c 69  (stderr, "Invali
4420: 64 20 75 73 65 72 6e 61 6d 65 20 73 70 65 63 69  d username speci
4430: 66 69 65 64 22 29 3b 0a 0a 09 09 09 09 09 72 65  fied");.......re
4440: 74 75 72 6e 28 31 29 3b 0a 09 09 09 09 7d 0a 09  turn(1);.....}..
4450: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
4460: 65 20 27 72 27 3a 0a 09 09 09 09 6e 65 77 72 6f  e 'r':.....newro
4470: 6f 74 20 3d 20 73 74 72 64 75 70 28 6f 70 74 61  ot = strdup(opta
4480: 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  rg);.....break;.
4490: 09 09 09 63 61 73 65 20 27 3f 27 3a 0a 09 09 09  ...case '?':....
44a0: 63 61 73 65 20 27 3a 27 3a 0a 09 09 09 09 66 69  case ':':.....fi
44b0: 6c 65 64 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73  led_print_help(s
44c0: 74 64 65 72 72 2c 20 4e 55 4c 4c 29 3b 0a 0a 09  tderr, NULL);...
44d0: 09 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09  ...return(1);...
44e0: 09 63 61 73 65 20 27 68 27 3a 0a 09 09 09 09 66  .case 'h':.....f
44f0: 69 6c 65 64 5f 70 72 69 6e 74 5f 68 65 6c 70 28  iled_print_help(
4500: 73 74 64 6f 75 74 2c 20 4e 55 4c 4c 29 3b 0a 0a  stdout, NULL);..
4510: 09 09 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
4520: 09 7d 0a 09 7d 0a 0a 09 2f 2a 20 43 72 65 61 74  .}..}.../* Creat
4530: 65 20 6c 69 73 74 65 6e 69 6e 67 20 73 6f 63 6b  e listening sock
4540: 65 74 20 2a 2f 0a 09 66 64 20 3d 20 66 69 6c 65  et */..fd = file
4550: 64 5f 6c 69 73 74 65 6e 28 62 69 6e 64 5f 61 64  d_listen(bind_ad
4560: 64 72 2c 20 70 6f 72 74 29 3b 0a 09 69 66 20 28  dr, port);..if (
4570: 66 64 20 3c 20 30 29 20 7b 0a 09 09 70 65 72 72  fd < 0) {...perr
4580: 6f 72 28 22 66 69 6c 65 64 5f 6c 69 73 74 65 6e  or("filed_listen
4590: 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29  ");....return(1)
45a0: 3b 0a 09 7d 0a 0a 09 2f 2a 20 43 68 72 6f 6f 74  ;..}.../* Chroot
45b0: 2c 20 69 66 20 61 70 70 72 6f 70 72 69 61 74 65  , if appropriate
45c0: 20 2a 2f 0a 09 69 66 20 28 6e 65 77 72 6f 6f 74   */..if (newroot
45d0: 29 20 7b 0a 09 09 63 68 64 69 72 5f 72 65 74 20  ) {...chdir_ret 
45e0: 3d 20 63 68 64 69 72 28 6e 65 77 72 6f 6f 74 29  = chdir(newroot)
45f0: 3b 0a 09 09 69 66 20 28 63 68 64 69 72 5f 72 65  ;...if (chdir_re
4600: 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 70 65 72  t != 0) {....per
4610: 72 6f 72 28 22 63 68 64 69 72 22 29 3b 0a 0a 09  ror("chdir");...
4620: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 7d  ..return(1);...}
4630: 0a 0a 09 09 63 68 72 6f 6f 74 5f 72 65 74 20 3d  ....chroot_ret =
4640: 20 63 68 72 6f 6f 74 28 22 2e 22 29 3b 0a 09 09   chroot(".");...
4650: 69 66 20 28 63 68 72 6f 6f 74 5f 72 65 74 20 21  if (chroot_ret !
4660: 3d 20 30 29 20 7b 0a 09 09 09 70 65 72 72 6f 72  = 0) {....perror
4670: 28 22 63 68 72 6f 6f 74 22 29 3b 0a 0a 09 09 09  ("chroot");.....
4680: 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 7d 0a 09  return(1);...}..
4690: 7d 0a 0a 09 2f 2a 20 44 72 6f 70 20 70 72 69 76  }.../* Drop priv
46a0: 69 6c 65 67 65 73 2c 20 69 66 20 61 70 70 72 6f  ileges, if appro
46b0: 70 72 69 61 74 65 20 2a 2f 0a 09 69 66 20 28 73  priate */..if (s
46c0: 65 74 75 69 64 5f 65 6e 61 62 6c 65 64 29 20 7b  etuid_enabled) {
46d0: 0a 09 09 73 65 74 75 69 64 5f 72 65 74 20 3d 20  ...setuid_ret = 
46e0: 73 65 74 75 69 64 28 75 73 65 72 29 3b 0a 09 09  setuid(user);...
46f0: 69 66 20 28 73 65 74 75 69 64 5f 72 65 74 20 21  if (setuid_ret !
4700: 3d 20 30 29 20 7b 0a 09 09 09 70 65 72 72 6f 72  = 0) {....perror
4710: 28 22 73 65 74 75 69 64 22 29 3b 0a 0a 09 09 09  ("setuid");.....
4720: 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 7d 0a 09  return(1);...}..
4730: 7d 0a 0a 09 2f 2a 20 42 65 63 6f 6d 65 20 61 20  }.../* Become a 
4740: 64 61 65 6d 6f 6e 20 2a 2f 0a 09 2f 2a 20 58 58  daemon */../* XX
4750: 58 3a 54 4f 44 4f 3a 20 42 65 63 6f 6d 65 20 61  X:TODO: Become a
4760: 20 64 61 65 6d 6f 6e 20 2a 2f 0a 0a 09 2f 2a 20   daemon */.../* 
4770: 49 6e 69 74 69 61 6c 69 7a 65 20 2a 2f 0a 09 69  Initialize */..i
4780: 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 64 5f  nit_ret = filed_
4790: 69 6e 69 74 28 63 61 63 68 65 5f 73 69 7a 65 29  init(cache_size)
47a0: 3b 0a 09 69 66 20 28 69 6e 69 74 5f 72 65 74 20  ;..if (init_ret 
47b0: 21 3d 20 30 29 20 7b 0a 09 09 70 65 72 72 6f 72  != 0) {...perror
47c0: 28 22 66 69 6c 65 64 5f 69 6e 69 74 22 29 3b 0a  ("filed_init");.
47d0: 0a 09 09 72 65 74 75 72 6e 28 33 29 3b 0a 09 7d  ...return(3);..}
47e0: 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20 6c 6f 67  .../* Create log
47f0: 67 69 6e 67 20 74 68 72 65 61 64 20 2a 2f 0a 09  ging thread */..
4800: 69 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 64  init_ret = filed
4810: 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f  _logging_thread_
4820: 69 6e 69 74 28 29 3b 0a 09 69 66 20 28 69 6e 69  init();..if (ini
4830: 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09  t_ret != 0) {...
4840: 70 65 72 72 6f 72 28 22 66 69 6c 65 64 5f 6c 6f  perror("filed_lo
4850: 67 67 69 6e 67 5f 74 68 72 65 61 64 5f 69 6e 69  gging_thread_ini
4860: 74 22 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 34  t");....return(4
4870: 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 43 72 65 61 74  );..}.../* Creat
4880: 65 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73  e worker threads
4890: 20 2a 2f 0a 09 69 6e 69 74 5f 72 65 74 20 3d 20   */..init_ret = 
48a0: 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72  filed_worker_thr
48b0: 65 61 64 73 5f 69 6e 69 74 28 66 64 2c 20 74 68  eads_init(fd, th
48c0: 72 65 61 64 5f 63 6f 75 6e 74 29 3b 0a 09 69 66  read_count);..if
48d0: 20 28 69 6e 69 74 5f 72 65 74 20 21 3d 20 30 29   (init_ret != 0)
48e0: 20 7b 0a 09 09 70 65 72 72 6f 72 28 22 66 69 6c   {...perror("fil
48f0: 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64  ed_worker_thread
4900: 73 5f 69 6e 69 74 22 29 3b 0a 0a 09 09 72 65 74  s_init");....ret
4910: 75 72 6e 28 34 29 3b 0a 09 7d 0a 0a 09 2f 2a 20  urn(4);..}.../* 
4920: 57 61 69 74 20 66 6f 72 20 74 68 72 65 61 64 73  Wait for threads
4930: 20 74 6f 20 65 78 69 74 20 2a 2f 0a 09 2f 2a 20   to exit */../* 
4940: 58 58 58 3a 54 4f 44 4f 3a 20 4d 6f 6e 69 74 6f  XXX:TODO: Monito
4950: 72 20 74 68 72 65 61 64 20 75 73 61 67 65 20 2a  r thread usage *
4960: 2f 0a 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09  /..while (1) {..
4970: 09 73 6c 65 65 70 28 36 30 29 3b 0a 09 7d 0a 0a  .sleep(60);..}..
4980: 09 2f 2a 20 52 65 74 75 72 6e 20 69 6e 20 66 61  ./* Return in fa
4990: 69 6c 75 72 65 20 2a 2f 0a 09 72 65 74 75 72 6e  ilure */..return
49a0: 28 32 29 3b 0a 7d 0a                             (2);.}.