Hex Artifact Content

Artifact 99eaeee2abee5afd189125a7473bef1ef3022af0:


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 73 79 73 2f 77 61 69 74 2e 68  lude <sys/wait.h
00a0: 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 70 74 68 72  >.#include <pthr
00b0: 65 61 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ead.h>.#include 
00c0: 3c 73 74 72 69 6e 67 73 2e 68 3e 0a 23 69 6e 63  <strings.h>.#inc
00d0: 6c 75 64 65 20 3c 73 69 67 6e 61 6c 2e 68 3e 0a  lude <signal.h>.
00e0: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 6c 69 62  #include <stdlib
00f0: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 75 6e  .h>.#include <un
0100: 69 73 74 64 2e 68 3e 0a 23 69 6e 63 6c 75 64 65  istd.h>.#include
0110: 20 3c 73 74 72 69 6e 67 2e 68 3e 0a 23 69 6e 63   <string.h>.#inc
0120: 6c 75 64 65 20 3c 67 65 74 6f 70 74 2e 68 3e 0a  lude <getopt.h>.
0130: 23 69 6e 63 6c 75 64 65 20 3c 73 74 64 61 72 67  #include <stdarg
0140: 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20 3c 66 63  .h>.#include <fc
0150: 6e 74 6c 2e 68 3e 0a 23 69 6e 63 6c 75 64 65 20  ntl.h>.#include 
0160: 3c 73 74 64 69 6f 2e 68 3e 0a 23 69 6e 63 6c 75  <stdio.h>.#inclu
0170: 64 65 20 3c 65 72 72 6e 6f 2e 68 3e 0a 23 69 6e  de <errno.h>.#in
0180: 63 6c 75 64 65 20 3c 74 69 6d 65 2e 68 3e 0a 23  clude <time.h>.#
0190: 69 6e 63 6c 75 64 65 20 3c 70 77 64 2e 68 3e 0a  include <pwd.h>.
01a0: 0a 2f 2a 20 43 6f 6d 70 69 6c 65 20 74 69 6d 65  ./* Compile time
01b0: 20 63 6f 6e 73 74 61 6e 74 73 20 2a 2f 0a 23 64   constants */.#d
01c0: 65 66 69 6e 65 20 46 49 4c 45 44 5f 56 45 52 53  efine FILED_VERS
01d0: 49 4f 4e 20 22 30 2e 39 22 0a 23 64 65 66 69 6e  ION "0.9".#defin
01e0: 65 20 46 49 4c 45 44 5f 53 45 4e 44 46 49 4c 45  e FILED_SENDFILE
01f0: 5f 4d 41 58 20 31 36 37 37 37 32 31 35 0a 23 64  _MAX 16777215.#d
0200: 65 66 69 6e 65 20 46 49 4c 45 44 5f 4d 41 58 5f  efine FILED_MAX_
0210: 46 41 49 4c 55 52 45 5f 43 4f 55 4e 54 20 33 30  FAILURE_COUNT 30
0220: 0a 23 64 65 66 69 6e 65 20 46 49 4c 45 44 5f 44  .#define FILED_D
0230: 45 46 41 55 4c 54 5f 54 59 50 45 20 22 61 70 70  EFAULT_TYPE "app
0240: 6c 69 63 61 74 69 6f 6e 2f 6f 63 74 65 74 2d 73  lication/octet-s
0250: 74 72 65 61 6d 22 0a 0a 2f 2a 20 44 65 66 61 75  tream"../* Defau
0260: 6c 74 20 76 61 6c 75 65 73 20 2a 2f 0a 23 64 65  lt values */.#de
0270: 66 69 6e 65 20 50 4f 52 54 20 38 30 0a 23 64 65  fine PORT 80.#de
0280: 66 69 6e 65 20 54 48 52 45 41 44 5f 43 4f 55 4e  fine THREAD_COUN
0290: 54 20 35 0a 23 64 65 66 69 6e 65 20 42 49 4e 44  T 5.#define BIND
02a0: 5f 41 44 44 52 20 22 3a 3a 22 0a 23 64 65 66 69  _ADDR "::".#defi
02b0: 6e 65 20 43 41 43 48 45 5f 53 49 5a 45 20 38 32  ne CACHE_SIZE 82
02c0: 30 39 0a 23 64 65 66 69 6e 65 20 4c 4f 47 5f 46  09.#define LOG_F
02d0: 49 4c 45 20 22 2d 22 0a 0a 2f 2a 20 41 72 67 75  ILE "-"../* Argu
02e0: 6d 65 6e 74 73 20 66 6f 72 20 77 6f 72 6b 65 72  ments for worker
02f0: 20 74 68 72 65 61 64 73 20 2a 2f 0a 73 74 72 75   threads */.stru
0300: 63 74 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f  ct filed_worker_
0310: 74 68 72 65 61 64 5f 61 72 67 73 20 7b 0a 09 69  thread_args {..i
0320: 6e 74 20 66 64 3b 0a 7d 3b 0a 0a 2f 2a 20 41 72  nt fd;.};../* Ar
0330: 67 75 6d 65 6e 74 73 20 66 6f 72 20 6c 6f 67 67  guments for logg
0340: 69 6e 67 20 74 68 72 65 61 64 73 20 2a 2f 0a 73  ing threads */.s
0350: 74 72 75 63 74 20 66 69 6c 65 64 5f 6c 6f 67 67  truct filed_logg
0360: 69 6e 67 5f 74 68 72 65 61 64 5f 61 72 67 73 20  ing_thread_args 
0370: 7b 0a 09 46 49 4c 45 20 2a 66 70 3b 0a 7d 3b 0a  {..FILE *fp;.};.
0380: 0a 2f 2a 20 46 69 6c 65 20 69 6e 66 6f 72 6d 61  ./* File informa
0390: 74 69 6f 6e 20 2a 2f 0a 73 74 72 75 63 74 20 66  tion */.struct f
03a0: 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 20 7b 0a  iled_fileinfo {.
03b0: 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 74  .pthread_mutex_t
03c0: 20 6d 75 74 65 78 3b 0a 09 63 68 61 72 20 2a 70   mutex;..char *p
03d0: 61 74 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 09 6f  ath;..int fd;..o
03e0: 66 66 5f 74 20 6c 65 6e 3b 0a 09 63 68 61 72 20  ff_t len;..char 
03f0: 2a 6c 61 73 74 6d 6f 64 3b 0a 09 63 68 61 72 20  *lastmod;..char 
0400: 6c 61 73 74 6d 6f 64 5f 62 5b 36 34 5d 3b 0a 09  lastmod_b[64];..
0410: 63 6f 6e 73 74 20 63 68 61 72 20 2a 74 79 70 65  const char *type
0420: 3b 0a 7d 3b 0a 0a 2f 2a 20 52 65 71 75 65 73 74  ;.};../* Request
0430: 20 76 61 72 69 61 62 6c 65 73 20 2a 2f 0a 73 74   variables */.st
0440: 72 75 63 74 20 66 69 6c 65 64 5f 68 74 74 70 5f  ruct filed_http_
0450: 72 65 71 75 65 73 74 20 7b 0a 09 2f 2a 2a 20 42  request {../** B
0460: 75 66 66 65 72 73 20 2a 2a 2f 0a 09 73 74 72 75  uffers **/..stru
0470: 63 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66  ct filed_fileinf
0480: 6f 20 66 69 6c 65 69 6e 66 6f 3b 0a 09 63 68 61  o fileinfo;..cha
0490: 72 20 70 61 74 68 5f 62 5b 31 30 31 30 5d 3b 0a  r path_b[1010];.
04a0: 09 63 68 61 72 20 74 6d 70 62 75 66 5b 31 30 31  .char tmpbuf[101
04b0: 30 5d 3b 0a 0a 09 2f 2a 2a 20 48 54 54 50 20 52  0];.../** HTTP R
04c0: 65 71 75 65 73 74 20 69 6e 66 6f 72 6d 61 74 69  equest informati
04d0: 6f 6e 20 2a 2a 2f 0a 09 63 68 61 72 20 2a 70 61  on **/..char *pa
04e0: 74 68 3b 20 20 20 20 20 2f 2a 2a 2a 20 50 61 74  th;     /*** Pat
04f0: 68 20 62 65 69 6e 67 20 72 65 71 75 65 73 74 65  h being requeste
0500: 64 20 2a 2a 2a 2f 0a 0a 09 73 74 72 75 63 74 20  d ***/...struct 
0510: 7b 0a 09 09 73 74 72 75 63 74 20 7b 0a 09 09 09  {...struct {....
0520: 69 6e 74 20 70 72 65 73 65 6e 74 3b 0a 09 09 09  int present;....
0530: 6f 66 66 5f 74 20 6f 66 66 73 65 74 3b 20 20 20  off_t offset;   
0540: 2f 2a 2a 2a 20 52 61 6e 67 65 20 73 74 61 72 74  /*** Range start
0550: 20 2a 2a 2a 2f 0a 09 09 09 6f 66 66 5f 74 20 6c   ***/....off_t l
0560: 65 6e 67 74 68 3b 20 20 20 2f 2a 2a 2a 20 52 61  ength;   /*** Ra
0570: 6e 67 65 20 6c 65 6e 67 74 68 20 2a 2a 2a 2f 0a  nge length ***/.
0580: 09 09 7d 20 72 61 6e 67 65 3b 0a 09 7d 20 68 65  ..} range;..} he
0590: 61 64 65 72 73 3b 0a 7d 3b 0a 0a 2f 2a 20 4c 6f  aders;.};../* Lo
05a0: 67 20 72 65 63 6f 72 64 20 2a 2f 0a 73 74 72 75  g record */.stru
05b0: 63 74 20 66 69 6c 65 64 5f 6c 6f 67 5f 65 6e 74  ct filed_log_ent
05c0: 72 79 20 7b 0a 09 73 74 72 75 63 74 20 66 69 6c  ry {..struct fil
05d0: 65 64 5f 6c 6f 67 5f 65 6e 74 72 79 20 2a 5f 6e  ed_log_entry *_n
05e0: 65 78 74 3b 0a 09 73 74 72 75 63 74 20 66 69 6c  ext;..struct fil
05f0: 65 64 5f 6c 6f 67 5f 65 6e 74 72 79 20 2a 5f 70  ed_log_entry *_p
0600: 72 65 76 3b 0a 09 70 74 68 72 65 61 64 5f 74 20  rev;..pthread_t 
0610: 74 68 72 65 61 64 3b 0a 09 63 68 61 72 20 62 75  thread;..char bu
0620: 66 66 65 72 5b 31 30 31 30 5d 3b 0a 09 69 6e 74  ffer[1010];..int
0630: 20 6c 65 76 65 6c 3b 0a 7d 3b 0a 0a 2f 2a 20 47   level;.};../* G
0640: 6c 6f 62 61 6c 20 76 61 72 69 61 62 6c 65 73 20  lobal variables 
0650: 2a 2f 0a 2f 2a 2a 20 4f 70 65 6e 20 46 69 6c 65  */./** Open File
0660: 20 63 61 63 68 65 20 2a 2a 2f 0a 73 74 72 75 63   cache **/.struc
0670: 74 20 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  t filed_fileinfo
0680: 20 2a 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f   *filed_fileinfo
0690: 5f 66 64 63 61 63 68 65 20 3d 20 4e 55 4c 4c 3b  _fdcache = NULL;
06a0: 0a 75 6e 73 69 67 6e 65 64 20 69 6e 74 20 66 69  .unsigned int fi
06b0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63  led_fileinfo_fdc
06c0: 61 63 68 65 5f 73 69 7a 65 20 3d 20 30 3b 0a 0a  ache_size = 0;..
06d0: 2f 2a 2a 20 4c 6f 67 67 69 6e 67 20 2a 2a 2f 0a  /** Logging **/.
06e0: 73 74 72 75 63 74 20 66 69 6c 65 64 5f 6c 6f 67  struct filed_log
06f0: 5f 65 6e 74 72 79 20 2a 66 69 6c 65 64 5f 6c 6f  _entry *filed_lo
0700: 67 5f 6d 73 67 5f 6c 69 73 74 3b 0a 70 74 68 72  g_msg_list;.pthr
0710: 65 61 64 5f 6d 75 74 65 78 5f 74 20 66 69 6c 65  ead_mutex_t file
0720: 64 5f 6c 6f 67 5f 6d 73 67 5f 6c 69 73 74 5f 6d  d_log_msg_list_m
0730: 75 74 65 78 3b 0a 70 74 68 72 65 61 64 5f 63 6f  utex;.pthread_co
0740: 6e 64 5f 74 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d  nd_t filed_log_m
0750: 73 67 5f 6c 69 73 74 5f 72 65 61 64 79 3b 0a 0a  sg_list_ready;..
0760: 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 63 61  /* Initialize ca
0770: 63 68 65 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  che */.static in
0780: 74 20 66 69 6c 65 64 5f 69 6e 69 74 5f 63 61 63  t filed_init_cac
0790: 68 65 28 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  he(unsigned int 
07a0: 63 61 63 68 65 5f 73 69 7a 65 29 20 7b 0a 09 75  cache_size) {..u
07b0: 6e 73 69 67 6e 65 64 20 69 6e 74 20 69 64 78 3b  nsigned int idx;
07c0: 0a 09 69 6e 74 20 6d 75 74 65 78 5f 69 6e 69 74  ..int mutex_init
07d0: 5f 72 65 74 3b 0a 0a 09 2f 2a 20 43 61 63 68 65  _ret;.../* Cache
07e0: 20 6d 61 79 20 6e 6f 74 20 62 65 20 72 65 2d 69   may not be re-i
07f0: 6e 69 74 69 61 6c 69 7a 65 64 20 2a 2f 0a 09 69  nitialized */..i
0800: 66 20 28 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66  f (filed_fileinf
0810: 6f 5f 66 64 63 61 63 68 65 5f 73 69 7a 65 20 21  o_fdcache_size !
0820: 3d 20 30 20 7c 7c 20 66 69 6c 65 64 5f 66 69 6c  = 0 || filed_fil
0830: 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 20 21 3d  einfo_fdcache !=
0840: 20 4e 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72   NULL) {...retur
0850: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 41 6c  n(1);..}.../* Al
0860: 6c 6f 63 61 74 65 20 63 61 63 68 65 20 2a 2f 0a  locate cache */.
0870: 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f  .filed_fileinfo_
0880: 66 64 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 63  fdcache_size = c
0890: 61 63 68 65 5f 73 69 7a 65 3b 0a 09 66 69 6c 65  ache_size;..file
08a0: 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63  d_fileinfo_fdcac
08b0: 68 65 20 3d 20 6d 61 6c 6c 6f 63 28 73 69 7a 65  he = malloc(size
08c0: 6f 66 28 2a 66 69 6c 65 64 5f 66 69 6c 65 69 6e  of(*filed_filein
08d0: 66 6f 5f 66 64 63 61 63 68 65 29 20 2a 20 66 69  fo_fdcache) * fi
08e0: 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63  led_fileinfo_fdc
08f0: 61 63 68 65 5f 73 69 7a 65 29 3b 0a 09 69 66 20  ache_size);..if 
0900: 28 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f 5f  (filed_fileinfo_
0910: 66 64 63 61 63 68 65 20 3d 3d 20 4e 55 4c 4c 29  fdcache == NULL)
0920: 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a   {...return(1);.
0930: 09 7d 0a 0a 09 2f 2a 20 49 6e 69 74 69 61 6c 69  .}.../* Initiali
0940: 7a 65 20 63 61 63 68 65 20 65 6e 74 72 69 65 73  ze cache entries
0950: 20 2a 2f 0a 09 66 6f 72 20 28 69 64 78 20 3d 20   */..for (idx = 
0960: 30 3b 20 69 64 78 20 3c 20 66 69 6c 65 64 5f 66  0; idx < filed_f
0970: 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65 5f  ileinfo_fdcache_
0980: 73 69 7a 65 3b 20 69 64 78 2b 2b 29 20 7b 0a 09  size; idx++) {..
0990: 09 6d 75 74 65 78 5f 69 6e 69 74 5f 72 65 74 20  .mutex_init_ret 
09a0: 3d 20 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f  = pthread_mutex_
09b0: 69 6e 69 74 28 26 66 69 6c 65 64 5f 66 69 6c 65  init(&filed_file
09c0: 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64 78  info_fdcache[idx
09d0: 5d 2e 6d 75 74 65 78 2c 20 4e 55 4c 4c 29 3b 0a  ].mutex, NULL);.
09e0: 09 09 69 66 20 28 6d 75 74 65 78 5f 69 6e 69 74  ..if (mutex_init
09f0: 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 09  _ret != 0) {....
0a00: 72 65 74 75 72 6e 28 31 29 3b 0a 09 09 7d 0a 0a  return(1);...}..
0a10: 09 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66 6f  ..filed_fileinfo
0a20: 5f 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 70 61  _fdcache[idx].pa
0a30: 74 68 20 3d 20 73 74 72 64 75 70 28 22 22 29 3b  th = strdup("");
0a40: 0a 09 09 66 69 6c 65 64 5f 66 69 6c 65 69 6e 66  ...filed_fileinf
0a50: 6f 5f 66 64 63 61 63 68 65 5b 69 64 78 5d 2e 66  o_fdcache[idx].f
0a60: 64 20 3d 20 2d 31 3b 0a 09 09 66 69 6c 65 64 5f  d = -1;...filed_
0a70: 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68 65  fileinfo_fdcache
0a80: 5b 69 64 78 5d 2e 6c 61 73 74 6d 6f 64 20 3d 20  [idx].lastmod = 
0a90: 22 22 3b 0a 09 09 66 69 6c 65 64 5f 66 69 6c 65  "";...filed_file
0aa0: 69 6e 66 6f 5f 66 64 63 61 63 68 65 5b 69 64 78  info_fdcache[idx
0ab0: 5d 2e 74 79 70 65 20 3d 20 22 22 3b 0a 09 7d 0a  ].type = "";..}.
0ac0: 0a 09 72 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a  ..return(0);.}..
0ad0: 2f 2a 20 49 6e 69 74 69 61 6c 69 7a 65 20 70 72  /* Initialize pr
0ae0: 6f 63 65 73 73 20 2a 2f 0a 73 74 61 74 69 63 20  ocess */.static 
0af0: 69 6e 74 20 66 69 6c 65 64 5f 69 6e 69 74 28 75  int filed_init(u
0b00: 6e 73 69 67 6e 65 64 20 69 6e 74 20 63 61 63 68  nsigned int cach
0b10: 65 5f 73 69 7a 65 29 20 7b 0a 09 73 74 61 74 69  e_size) {..stati
0b20: 63 20 69 6e 74 20 63 61 6c 6c 65 64 20 3d 20 30  c int called = 0
0b30: 3b 0a 09 69 6e 74 20 63 61 63 68 65 5f 72 65 74  ;..int cache_ret
0b40: 3b 0a 0a 09 69 66 20 28 63 61 6c 6c 65 64 29 20  ;...if (called) 
0b50: 7b 0a 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  {...return(0);..
0b60: 7d 0a 0a 09 63 61 6c 6c 65 64 20 3d 20 31 3b 0a  }...called = 1;.
0b70: 0a 09 6d 6c 6f 63 6b 61 6c 6c 28 4d 43 4c 5f 43  ..mlockall(MCL_C
0b80: 55 52 52 45 4e 54 20 7c 20 4d 43 4c 5f 46 55 54  URRENT | MCL_FUT
0b90: 55 52 45 29 3b 0a 0a 09 73 69 67 6e 61 6c 28 53  URE);...signal(S
0ba0: 49 47 50 49 50 45 2c 20 53 49 47 5f 49 47 4e 29  IGPIPE, SIG_IGN)
0bb0: 3b 0a 0a 09 63 61 63 68 65 5f 72 65 74 20 3d 20  ;...cache_ret = 
0bc0: 66 69 6c 65 64 5f 69 6e 69 74 5f 63 61 63 68 65  filed_init_cache
0bd0: 28 63 61 63 68 65 5f 73 69 7a 65 29 3b 0a 09 69  (cache_size);..i
0be0: 66 20 28 63 61 63 68 65 5f 72 65 74 20 21 3d 20  f (cache_ret != 
0bf0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 63 61  0) {...return(ca
0c00: 63 68 65 5f 72 65 74 29 3b 0a 09 7d 0a 0a 09 72  che_ret);..}...r
0c10: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20  eturn(0);.}../* 
0c20: 4c 69 73 74 65 6e 20 6f 6e 20 61 20 70 61 72 74  Listen on a part
0c30: 69 63 75 6c 61 72 20 61 64 64 72 65 73 73 2f 70  icular address/p
0c40: 6f 72 74 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e  ort */.static in
0c50: 74 20 66 69 6c 65 64 5f 6c 69 73 74 65 6e 28 63  t filed_listen(c
0c60: 6f 6e 73 74 20 63 68 61 72 20 2a 61 64 64 72 65  onst char *addre
0c70: 73 73 2c 20 75 6e 73 69 67 6e 65 64 20 69 6e 74  ss, unsigned int
0c80: 20 70 6f 72 74 29 20 7b 0a 09 73 74 72 75 63 74   port) {..struct
0c90: 20 73 6f 63 6b 61 64 64 72 5f 69 6e 36 20 61 64   sockaddr_in6 ad
0ca0: 64 72 5f 76 36 3b 0a 09 73 74 72 75 63 74 20 73  dr_v6;..struct s
0cb0: 6f 63 6b 61 64 64 72 5f 69 6e 20 61 64 64 72 5f  ockaddr_in addr_
0cc0: 76 34 3b 0a 09 73 74 72 75 63 74 20 73 6f 63 6b  v4;..struct sock
0cd0: 61 64 64 72 20 2a 61 64 64 72 3b 0a 09 73 6f 63  addr *addr;..soc
0ce0: 6b 6c 65 6e 5f 74 20 61 64 64 72 5f 6c 65 6e 3b  klen_t addr_len;
0cf0: 0a 09 69 6e 74 20 70 74 6f 6e 5f 72 65 74 2c 20  ..int pton_ret, 
0d00: 62 69 6e 64 5f 72 65 74 2c 20 6c 69 73 74 65 6e  bind_ret, listen
0d10: 5f 72 65 74 3b 0a 09 69 6e 74 20 66 61 6d 69 6c  _ret;..int famil
0d20: 79 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 0a 09 66  y;..int fd;....f
0d30: 61 6d 69 6c 79 20 3d 20 41 46 5f 49 4e 45 54 36  amily = AF_INET6
0d40: 3b 0a 09 70 74 6f 6e 5f 72 65 74 20 3d 20 69 6e  ;..pton_ret = in
0d50: 65 74 5f 70 74 6f 6e 28 66 61 6d 69 6c 79 2c 20  et_pton(family, 
0d60: 61 64 64 72 65 73 73 2c 20 26 61 64 64 72 5f 76  address, &addr_v
0d70: 36 2e 73 69 6e 36 5f 61 64 64 72 2e 73 36 5f 61  6.sin6_addr.s6_a
0d80: 64 64 72 29 3b 0a 09 69 66 20 28 70 74 6f 6e 5f  ddr);..if (pton_
0d90: 72 65 74 20 21 3d 20 31 29 20 7b 0a 09 09 66 61  ret != 1) {...fa
0da0: 6d 69 6c 79 20 3d 20 41 46 5f 49 4e 45 54 3b 0a  mily = AF_INET;.
0db0: 09 09 70 74 6f 6e 5f 72 65 74 20 3d 20 69 6e 65  ..pton_ret = ine
0dc0: 74 5f 70 74 6f 6e 28 66 61 6d 69 6c 79 2c 20 61  t_pton(family, a
0dd0: 64 64 72 65 73 73 2c 20 26 61 64 64 72 5f 76 34  ddress, &addr_v4
0de0: 2e 73 69 6e 5f 61 64 64 72 2e 73 5f 61 64 64 72  .sin_addr.s_addr
0df0: 29 3b 0a 09 09 69 66 20 28 70 74 6f 6e 5f 72 65  );...if (pton_re
0e00: 74 20 21 3d 20 31 29 20 7b 0a 09 09 09 72 65 74  t != 1) {....ret
0e10: 75 72 6e 28 2d 31 29 3b 0a 09 09 7d 0a 0a 09 09  urn(-1);...}....
0e20: 61 64 64 72 5f 76 34 2e 73 69 6e 5f 66 61 6d 69  addr_v4.sin_fami
0e30: 6c 79 20 3d 20 66 61 6d 69 6c 79 3b 0a 09 09 61  ly = family;...a
0e40: 64 64 72 5f 76 34 2e 73 69 6e 5f 70 6f 72 74 20  ddr_v4.sin_port 
0e50: 3d 20 68 74 6f 6e 73 28 70 6f 72 74 29 3b 0a 0a  = htons(port);..
0e60: 09 09 61 64 64 72 20 3d 20 28 73 74 72 75 63 74  ..addr = (struct
0e70: 20 73 6f 63 6b 61 64 64 72 20 2a 29 20 26 61 64   sockaddr *) &ad
0e80: 64 72 5f 76 34 3b 0a 09 09 61 64 64 72 5f 6c 65  dr_v4;...addr_le
0e90: 6e 20 3d 20 73 69 7a 65 6f 66 28 61 64 64 72 5f  n = sizeof(addr_
0ea0: 76 34 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a 09  v4);..} else {..
0eb0: 09 61 64 64 72 5f 76 36 2e 73 69 6e 36 5f 66 61  .addr_v6.sin6_fa
0ec0: 6d 69 6c 79 20 3d 20 41 46 5f 49 4e 45 54 36 3b  mily = AF_INET6;
0ed0: 0a 09 09 61 64 64 72 5f 76 36 2e 73 69 6e 36 5f  ...addr_v6.sin6_
0ee0: 66 6c 6f 77 69 6e 66 6f 20 3d 20 30 3b 0a 09 09  flowinfo = 0;...
0ef0: 61 64 64 72 5f 76 36 2e 73 69 6e 36 5f 73 63 6f  addr_v6.sin6_sco
0f00: 70 65 5f 69 64 20 3d 20 30 3b 0a 09 09 61 64 64  pe_id = 0;...add
0f10: 72 5f 76 36 2e 73 69 6e 36 5f 70 6f 72 74 20 3d  r_v6.sin6_port =
0f20: 20 68 74 6f 6e 73 28 70 6f 72 74 29 3b 0a 0a 09   htons(port);...
0f30: 09 61 64 64 72 20 3d 20 28 73 74 72 75 63 74 20  .addr = (struct 
0f40: 73 6f 63 6b 61 64 64 72 20 2a 29 20 26 61 64 64  sockaddr *) &add
0f50: 72 5f 76 36 3b 0a 09 09 61 64 64 72 5f 6c 65 6e  r_v6;...addr_len
0f60: 20 3d 20 73 69 7a 65 6f 66 28 61 64 64 72 5f 76   = sizeof(addr_v
0f70: 36 29 3b 0a 09 7d 0a 0a 09 66 64 20 3d 20 73 6f  6);..}...fd = so
0f80: 63 6b 65 74 28 66 61 6d 69 6c 79 2c 20 53 4f 43  cket(family, SOC
0f90: 4b 5f 53 54 52 45 41 4d 2c 20 30 29 3b 0a 09 69  K_STREAM, 0);..i
0fa0: 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 72  f (fd < 0) {...r
0fb0: 65 74 75 72 6e 28 66 64 29 3b 0a 09 7d 0a 0a 09  eturn(fd);..}...
0fc0: 62 69 6e 64 5f 72 65 74 20 3d 20 62 69 6e 64 28  bind_ret = bind(
0fd0: 66 64 2c 20 61 64 64 72 2c 20 61 64 64 72 5f 6c  fd, addr, addr_l
0fe0: 65 6e 29 3b 0a 09 69 66 20 28 62 69 6e 64 5f 72  en);..if (bind_r
0ff0: 65 74 20 3c 20 30 29 20 7b 0a 09 09 63 6c 6f 73  et < 0) {...clos
1000: 65 28 66 64 29 3b 0a 0a 09 09 72 65 74 75 72 6e  e(fd);....return
1010: 28 2d 31 29 3b 0a 09 7d 0a 0a 09 6c 69 73 74 65  (-1);..}...liste
1020: 6e 5f 72 65 74 20 3d 20 6c 69 73 74 65 6e 28 66  n_ret = listen(f
1030: 64 2c 20 31 32 38 29 3b 0a 09 69 66 20 28 6c 69  d, 128);..if (li
1040: 73 74 65 6e 5f 72 65 74 20 21 3d 20 30 29 20 7b  sten_ret != 0) {
1050: 0a 09 09 63 6c 6f 73 65 28 66 64 29 3b 0a 0a 09  ...close(fd);...
1060: 09 72 65 74 75 72 6e 28 2d 31 29 3b 0a 09 7d 0a  .return(-1);..}.
1070: 0a 09 72 65 74 75 72 6e 28 66 64 29 3b 0a 7d 0a  ..return(fd);.}.
1080: 0a 2f 2a 20 4c 6f 67 20 61 20 6d 65 73 73 61 67  ./* Log a messag
1090: 65 20 2a 2f 0a 23 69 66 64 65 66 20 46 49 4c 45  e */.#ifdef FILE
10a0: 44 5f 44 4f 4e 54 5f 4c 4f 47 0a 23 20 20 64 65  D_DONT_LOG.#  de
10b0: 66 69 6e 65 20 66 69 6c 65 64 5f 6c 6f 67 67 69  fine filed_loggi
10c0: 6e 67 5f 74 68 72 65 61 64 5f 69 6e 69 74 28 78  ng_thread_init(x
10d0: 29 20 30 0a 23 20 20 64 65 66 69 6e 65 20 66 69  ) 0.#  define fi
10e0: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75  led_log_msg_debu
10f0: 67 28 78 2c 20 2e 2e 2e 29 20 2f 2a 2a 2f 0a 23  g(x, ...) /**/.#
1100: 20 20 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c    define filed_l
1110: 6f 67 5f 6d 73 67 28 78 2c 20 2e 2e 2e 29 20 2f  og_msg(x, ...) /
1120: 2a 2a 2f 0a 23 65 6c 73 65 0a 23 69 66 64 65 66  **/.#else.#ifdef
1130: 20 46 49 4c 45 44 5f 44 45 42 55 47 0a 23 20 20   FILED_DEBUG.#  
1140: 64 65 66 69 6e 65 20 66 69 6c 65 64 5f 6c 6f 67  define filed_log
1150: 5f 6d 73 67 5f 64 65 62 75 67 28 78 2c 20 2e 2e  _msg_debug(x, ..
1160: 2e 29 20 7b 20 66 70 72 69 6e 74 66 28 73 74 64  .) { fprintf(std
1170: 65 72 72 2c 20 78 2c 20 5f 5f 56 41 5f 41 52 47  err, x, __VA_ARG
1180: 53 5f 5f 29 3b 20 66 70 72 69 6e 74 66 28 73 74  S__); fprintf(st
1190: 64 65 72 72 2c 20 22 5c 6e 22 29 3b 20 66 66 6c  derr, "\n"); ffl
11a0: 75 73 68 28 73 74 64 65 72 72 29 3b 20 7d 0a 23  ush(stderr); }.#
11b0: 65 6c 73 65 0a 23 20 20 64 65 66 69 6e 65 20 66  else.#  define f
11c0: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62  iled_log_msg_deb
11d0: 75 67 28 78 2c 20 2e 2e 2e 29 20 2f 2a 2a 2f 0a  ug(x, ...) /**/.
11e0: 23 65 6e 64 69 66 0a 0a 2f 2a 20 49 6e 69 74 69  #endif../* Initi
11f0: 61 6c 69 7a 65 20 6c 6f 67 67 69 6e 67 20 74 68  alize logging th
1200: 72 65 61 64 20 2a 2f 0a 73 74 61 74 69 63 20 76  read */.static v
1210: 6f 69 64 20 2a 66 69 6c 65 64 5f 6c 6f 67 67 69  oid *filed_loggi
1220: 6e 67 5f 74 68 72 65 61 64 28 76 6f 69 64 20 2a  ng_thread(void *
1230: 61 72 67 5f 70 29 20 7b 0a 09 73 74 72 75 63 74  arg_p) {..struct
1240: 20 66 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74   filed_logging_t
1250: 68 72 65 61 64 5f 61 72 67 73 20 2a 61 72 67 3b  hread_args *arg;
1260: 0a 09 73 74 72 75 63 74 20 66 69 6c 65 64 5f 6c  ..struct filed_l
1270: 6f 67 5f 65 6e 74 72 79 20 2a 63 75 72 72 2c 20  og_entry *curr, 
1280: 2a 70 72 65 76 3b 0a 09 46 49 4c 45 20 2a 66 70  *prev;..FILE *fp
1290: 3b 0a 0a 09 61 72 67 20 3d 20 61 72 67 5f 70 3b  ;...arg = arg_p;
12a0: 0a 0a 09 66 70 20 3d 20 61 72 67 2d 3e 66 70 3b  ...fp = arg->fp;
12b0: 0a 0a 09 77 68 69 6c 65 20 28 31 29 20 7b 0a 09  ...while (1) {..
12c0: 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 6c  .pthread_mutex_l
12d0: 6f 63 6b 28 26 66 69 6c 65 64 5f 6c 6f 67 5f 6d  ock(&filed_log_m
12e0: 73 67 5f 6c 69 73 74 5f 6d 75 74 65 78 29 3b 0a  sg_list_mutex);.
12f0: 09 09 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f 77  ..pthread_cond_w
1300: 61 69 74 28 26 66 69 6c 65 64 5f 6c 6f 67 5f 6d  ait(&filed_log_m
1310: 73 67 5f 6c 69 73 74 5f 72 65 61 64 79 2c 20 26  sg_list_ready, &
1320: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 6c 69  filed_log_msg_li
1330: 73 74 5f 6d 75 74 65 78 29 3b 0a 0a 09 09 63 75  st_mutex);....cu
1340: 72 72 20 3d 20 66 69 6c 65 64 5f 6c 6f 67 5f 6d  rr = filed_log_m
1350: 73 67 5f 6c 69 73 74 3b 0a 09 09 66 69 6c 65 64  sg_list;...filed
1360: 5f 6c 6f 67 5f 6d 73 67 5f 6c 69 73 74 20 3d 20  _log_msg_list = 
1370: 4e 55 4c 4c 3b 0a 0a 09 09 70 74 68 72 65 61 64  NULL;....pthread
1380: 5f 6d 75 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 66  _mutex_unlock(&f
1390: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 6c 69 73  iled_log_msg_lis
13a0: 74 5f 6d 75 74 65 78 29 3b 0a 0a 09 09 70 72 65  t_mutex);....pre
13b0: 76 20 3d 20 4e 55 4c 4c 3b 0a 09 09 66 6f 72 20  v = NULL;...for 
13c0: 28 3b 20 63 75 72 72 3b 20 63 75 72 72 20 3d 20  (; curr; curr = 
13d0: 63 75 72 72 2d 3e 5f 6e 65 78 74 29 20 7b 0a 09  curr->_next) {..
13e0: 09 09 63 75 72 72 2d 3e 5f 70 72 65 76 20 3d 20  ..curr->_prev = 
13f0: 70 72 65 76 3b 0a 0a 09 09 09 70 72 65 76 20 3d  prev;.....prev =
1400: 20 63 75 72 72 3b 0a 09 09 7d 0a 0a 09 09 63 75   curr;...}....cu
1410: 72 72 20 3d 20 70 72 65 76 3b 0a 09 09 77 68 69  rr = prev;...whi
1420: 6c 65 20 28 63 75 72 72 29 20 7b 0a 09 09 09 66  le (curr) {....f
1430: 70 72 69 6e 74 66 28 66 70 2c 20 22 25 73 20 54  printf(fp, "%s T
1440: 48 52 45 41 44 3d 25 6c 6c 75 5c 6e 22 2c 20 63  HREAD=%llu\n", c
1450: 75 72 72 2d 3e 62 75 66 66 65 72 2c 20 28 75 6e  urr->buffer, (un
1460: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
1470: 29 20 63 75 72 72 2d 3e 74 68 72 65 61 64 29 3b  ) curr->thread);
1480: 0a 09 09 09 66 66 6c 75 73 68 28 66 70 29 3b 0a  ....fflush(fp);.
1490: 0a 09 09 09 70 72 65 76 20 3d 20 63 75 72 72 3b  ....prev = curr;
14a0: 0a 09 09 09 63 75 72 72 20 3d 20 63 75 72 72 2d  ....curr = curr-
14b0: 3e 5f 70 72 65 76 3b 0a 0a 09 09 09 66 72 65 65  >_prev;.....free
14c0: 28 70 72 65 76 29 3b 0a 09 09 7d 0a 09 7d 0a 0a  (prev);...}..}..
14d0: 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 7d  .return(NULL);.}
14e0: 0a 0a 73 74 61 74 69 63 20 69 6e 74 20 66 69 6c  ..static int fil
14f0: 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65 61  ed_logging_threa
1500: 64 5f 69 6e 69 74 28 46 49 4c 45 20 2a 6c 6f 67  d_init(FILE *log
1510: 66 70 29 20 7b 0a 09 73 74 72 75 63 74 20 66 69  fp) {..struct fi
1520: 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65  led_logging_thre
1530: 61 64 5f 61 72 67 73 20 2a 61 72 67 73 3b 0a 09  ad_args *args;..
1540: 70 74 68 72 65 61 64 5f 74 20 74 68 72 65 61 64  pthread_t thread
1550: 5f 69 64 3b 0a 0a 09 61 72 67 73 20 3d 20 6d 61  _id;...args = ma
1560: 6c 6c 6f 63 28 73 69 7a 65 6f 66 28 2a 61 72 67  lloc(sizeof(*arg
1570: 73 29 29 3b 0a 09 61 72 67 73 2d 3e 66 70 20 3d  s));..args->fp =
1580: 20 6c 6f 67 66 70 3b 0a 0a 09 66 69 6c 65 64 5f   logfp;...filed_
1590: 6c 6f 67 5f 6d 73 67 5f 6c 69 73 74 20 3d 20 4e  log_msg_list = N
15a0: 55 4c 4c 3b 0a 0a 09 70 74 68 72 65 61 64 5f 6d  ULL;...pthread_m
15b0: 75 74 65 78 5f 69 6e 69 74 28 26 66 69 6c 65 64  utex_init(&filed
15c0: 5f 6c 6f 67 5f 6d 73 67 5f 6c 69 73 74 5f 6d 75  _log_msg_list_mu
15d0: 74 65 78 2c 20 4e 55 4c 4c 29 3b 0a 0a 09 70 74  tex, NULL);...pt
15e0: 68 72 65 61 64 5f 63 72 65 61 74 65 28 26 74 68  hread_create(&th
15f0: 72 65 61 64 5f 69 64 2c 20 4e 55 4c 4c 2c 20 66  read_id, NULL, f
1600: 69 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72  iled_logging_thr
1610: 65 61 64 2c 20 61 72 67 73 29 3b 0a 0a 09 72 65  ead, args);...re
1620: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 73 74 61 74  turn(0);.}..stat
1630: 69 63 20 76 6f 69 64 20 66 69 6c 65 64 5f 6c 6f  ic void filed_lo
1640: 67 5f 6d 73 67 28 63 6f 6e 73 74 20 63 68 61 72  g_msg(const char
1650: 20 2a 66 6d 74 2c 20 2e 2e 2e 29 20 7b 0a 09 73   *fmt, ...) {..s
1660: 74 72 75 63 74 20 66 69 6c 65 64 5f 6c 6f 67 5f  truct filed_log_
1670: 65 6e 74 72 79 20 2a 65 6e 74 72 79 3b 0a 09 76  entry *entry;..v
1680: 61 5f 6c 69 73 74 20 61 72 67 73 3b 0a 0a 09 65  a_list args;...e
1690: 6e 74 72 79 20 3d 20 6d 61 6c 6c 6f 63 28 73 69  ntry = malloc(si
16a0: 7a 65 6f 66 28 2a 65 6e 74 72 79 29 29 3b 0a 0a  zeof(*entry));..
16b0: 09 76 61 5f 73 74 61 72 74 28 61 72 67 73 2c 20  .va_start(args, 
16c0: 66 6d 74 29 3b 0a 0a 09 76 73 6e 70 72 69 6e 74  fmt);...vsnprint
16d0: 66 28 65 6e 74 72 79 2d 3e 62 75 66 66 65 72 2c  f(entry->buffer,
16e0: 20 73 69 7a 65 6f 66 28 65 6e 74 72 79 2d 3e 62   sizeof(entry->b
16f0: 75 66 66 65 72 29 2c 20 66 6d 74 2c 20 61 72 67  uffer), fmt, arg
1700: 73 29 3b 0a 0a 09 76 61 5f 65 6e 64 28 61 72 67  s);...va_end(arg
1710: 73 29 3b 0a 0a 09 65 6e 74 72 79 2d 3e 74 68 72  s);...entry->thr
1720: 65 61 64 20 3d 20 70 74 68 72 65 61 64 5f 73 65  ead = pthread_se
1730: 6c 66 28 29 3b 0a 09 65 6e 74 72 79 2d 3e 6c 65  lf();..entry->le
1740: 76 65 6c 20 3d 20 30 3b 0a 0a 09 70 74 68 72 65  vel = 0;...pthre
1750: 61 64 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 66  ad_mutex_lock(&f
1760: 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 6c 69 73  iled_log_msg_lis
1770: 74 5f 6d 75 74 65 78 29 3b 0a 0a 09 65 6e 74 72  t_mutex);...entr
1780: 79 2d 3e 5f 6e 65 78 74 20 3d 20 66 69 6c 65 64  y->_next = filed
1790: 5f 6c 6f 67 5f 6d 73 67 5f 6c 69 73 74 3b 0a 09  _log_msg_list;..
17a0: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 6c 69  filed_log_msg_li
17b0: 73 74 20 3d 20 65 6e 74 72 79 3b 0a 0a 09 70 74  st = entry;...pt
17c0: 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c 6f  hread_mutex_unlo
17d0: 63 6b 28 26 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  ck(&filed_log_ms
17e0: 67 5f 6c 69 73 74 5f 6d 75 74 65 78 29 3b 0a 0a  g_list_mutex);..
17f0: 09 70 74 68 72 65 61 64 5f 63 6f 6e 64 5f 73 69  .pthread_cond_si
1800: 67 6e 61 6c 28 26 66 69 6c 65 64 5f 6c 6f 67 5f  gnal(&filed_log_
1810: 6d 73 67 5f 6c 69 73 74 5f 72 65 61 64 79 29 3b  msg_list_ready);
1820: 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d 0a 23 65 6e  ...return;.}.#en
1830: 64 69 66 0a 0a 2f 2a 20 46 6f 72 6d 61 74 20 74  dif../* Format t
1840: 69 6d 65 20 70 65 72 20 52 46 43 32 36 31 36 20  ime per RFC2616 
1850: 2a 2f 0a 73 74 61 74 69 63 20 63 68 61 72 20 2a  */.static char *
1860: 66 69 6c 65 64 5f 66 6f 72 6d 61 74 5f 74 69 6d  filed_format_tim
1870: 65 28 63 68 61 72 20 2a 62 75 66 66 65 72 2c 20  e(char *buffer, 
1880: 73 69 7a 65 5f 74 20 62 75 66 66 65 72 5f 6c 65  size_t buffer_le
1890: 6e 2c 20 63 6f 6e 73 74 20 74 69 6d 65 5f 74 20  n, const time_t 
18a0: 74 69 6d 65 69 6e 66 6f 29 20 7b 0a 09 73 74 72  timeinfo) {..str
18b0: 75 63 74 20 74 6d 20 74 69 6d 65 69 6e 66 6f 5f  uct tm timeinfo_
18c0: 74 6d 2c 20 2a 74 69 6d 65 69 6e 66 6f 5f 74 6d  tm, *timeinfo_tm
18d0: 5f 70 3b 0a 0a 09 74 69 6d 65 69 6e 66 6f 5f 74  _p;...timeinfo_t
18e0: 6d 5f 70 20 3d 20 67 6d 74 69 6d 65 5f 72 28 26  m_p = gmtime_r(&
18f0: 74 69 6d 65 69 6e 66 6f 2c 20 26 74 69 6d 65 69  timeinfo, &timei
1900: 6e 66 6f 5f 74 6d 29 3b 0a 09 69 66 20 28 74 69  nfo_tm);..if (ti
1910: 6d 65 69 6e 66 6f 5f 74 6d 5f 70 20 3d 3d 20 4e  meinfo_tm_p == N
1920: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
1930: 22 75 6e 6b 6e 6f 77 6e 22 29 3b 0a 09 7d 0a 0a  "unknown");..}..
1940: 09 62 75 66 66 65 72 5b 62 75 66 66 65 72 5f 6c  .buffer[buffer_l
1950: 65 6e 20 2d 20 31 5d 20 3d 20 27 5c 30 27 3b 0a  en - 1] = '\0';.
1960: 09 62 75 66 66 65 72 5f 6c 65 6e 20 3d 20 73 74  .buffer_len = st
1970: 72 66 74 69 6d 65 28 62 75 66 66 65 72 2c 20 62  rftime(buffer, b
1980: 75 66 66 65 72 5f 6c 65 6e 20 2d 20 31 2c 20 22  uffer_len - 1, "
1990: 25 61 2c 20 25 64 20 25 62 20 25 59 20 25 48 3a  %a, %d %b %Y %H:
19a0: 25 4d 3a 25 53 20 47 4d 54 22 2c 20 74 69 6d 65  %M:%S GMT", time
19b0: 69 6e 66 6f 5f 74 6d 5f 70 29 3b 0a 0a 09 72 65  info_tm_p);...re
19c0: 74 75 72 6e 28 62 75 66 66 65 72 29 3b 0a 7d 0a  turn(buffer);.}.
19d0: 0a 2f 2a 20 68 61 73 68 20 2a 2f 0a 73 74 61 74  ./* hash */.stat
19e0: 69 63 20 75 6e 73 69 67 6e 65 64 20 69 6e 74 20  ic unsigned int 
19f0: 66 69 6c 65 64 5f 68 61 73 68 28 63 6f 6e 73 74  filed_hash(const
1a00: 20 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a   unsigned char *
1a10: 76 61 6c 75 65 2c 20 75 6e 73 69 67 6e 65 64 20  value, unsigned 
1a20: 69 6e 74 20 6d 6f 64 75 6c 75 73 29 20 7b 0a 09  int modulus) {..
1a30: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 63 75  unsigned char cu
1a40: 72 72 2c 20 70 72 65 76 3b 0a 09 69 6e 74 20 64  rr, prev;..int d
1a50: 69 66 66 3b 0a 09 75 6e 73 69 67 6e 65 64 20 69  iff;..unsigned i
1a60: 6e 74 20 72 65 74 76 61 6c 3b 0a 0a 09 72 65 74  nt retval;...ret
1a70: 76 61 6c 20 3d 20 6d 6f 64 75 6c 75 73 20 2d 20  val = modulus - 
1a80: 31 3b 0a 09 70 72 65 76 20 3d 20 6d 6f 64 75 6c  1;..prev = modul
1a90: 75 73 20 25 20 32 35 35 3b 0a 0a 09 77 68 69 6c  us % 255;...whil
1aa0: 65 20 28 28 63 75 72 72 20 3d 20 2a 76 61 6c 75  e ((curr = *valu
1ab0: 65 29 29 20 7b 0a 09 09 69 66 20 28 63 75 72 72  e)) {...if (curr
1ac0: 20 3c 20 33 32 29 20 7b 0a 09 09 09 63 75 72 72   < 32) {....curr
1ad0: 20 3d 20 32 35 35 20 2d 20 63 75 72 72 3b 0a 09   = 255 - curr;..
1ae0: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 63 75 72  .} else {....cur
1af0: 72 20 2d 3d 20 33 32 3b 0a 09 09 7d 0a 0a 09 09  r -= 32;...}....
1b00: 69 66 20 28 70 72 65 76 20 3c 20 63 75 72 72 29  if (prev < curr)
1b10: 20 7b 0a 09 09 09 64 69 66 66 20 3d 20 63 75 72   {....diff = cur
1b20: 72 20 2d 20 70 72 65 76 3b 0a 09 09 7d 20 65 6c  r - prev;...} el
1b30: 73 65 20 7b 0a 09 09 09 64 69 66 66 20 3d 20 70  se {....diff = p
1b40: 72 65 76 20 2d 20 63 75 72 72 3b 0a 09 09 7d 0a  rev - curr;...}.
1b50: 0a 09 09 70 72 65 76 20 3d 20 63 75 72 72 3b 0a  ...prev = curr;.
1b60: 0a 09 09 72 65 74 76 61 6c 20 3c 3c 3d 20 33 3b  ...retval <<= 3;
1b70: 0a 09 09 72 65 74 76 61 6c 20 26 3d 20 30 78 46  ...retval &= 0xF
1b80: 46 46 46 46 46 46 46 4c 55 3b 0a 09 09 72 65 74  FFFFFFFLU;...ret
1b90: 76 61 6c 20 5e 3d 20 64 69 66 66 3b 0a 0a 09 09  val ^= diff;....
1ba0: 76 61 6c 75 65 2b 2b 3b 0a 09 7d 0a 0a 09 72 65  value++;..}...re
1bb0: 74 76 61 6c 20 3d 20 72 65 74 76 61 6c 20 25 20  tval = retval % 
1bc0: 6d 6f 64 75 6c 75 73 3b 0a 0a 09 72 65 74 75 72  modulus;...retur
1bd0: 6e 28 72 65 74 76 61 6c 29 3b 0a 7d 0a 0a 2f 2a  n(retval);.}../*
1be0: 20 46 69 6e 64 20 61 20 6d 69 6d 65 2d 74 79 70   Find a mime-typ
1bf0: 65 20 62 61 73 65 64 20 6f 6e 20 74 68 65 20 66  e based on the f
1c00: 69 6c 65 6e 61 6d 65 20 2a 2f 0a 73 74 61 74 69  ilename */.stati
1c10: 63 20 63 6f 6e 73 74 20 63 68 61 72 20 2a 66 69  c const char *fi
1c20: 6c 65 64 5f 64 65 74 65 72 6d 69 6e 65 5f 6d 69  led_determine_mi
1c30: 6d 65 74 79 70 65 28 63 6f 6e 73 74 20 63 68 61  metype(const cha
1c40: 72 20 2a 70 61 74 68 29 20 7b 0a 09 63 6f 6e 73  r *path) {..cons
1c50: 74 20 63 68 61 72 20 2a 70 3b 0a 0a 09 70 20 3d  t char *p;...p =
1c60: 20 73 74 72 72 63 68 72 28 70 61 74 68 2c 20 27   strrchr(path, '
1c70: 2e 27 29 3b 0a 09 69 66 20 28 70 20 3d 3d 20 4e  .');..if (p == N
1c80: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
1c90: 46 49 4c 45 44 5f 44 45 46 41 55 4c 54 5f 54 59  FILED_DEFAULT_TY
1ca0: 50 45 29 3b 0a 09 7d 0a 0a 09 70 2b 2b 3b 0a 09  PE);..}...p++;..
1cb0: 69 66 20 28 2a 70 20 3d 3d 20 27 5c 30 27 29 20  if (*p == '\0') 
1cc0: 7b 0a 09 09 72 65 74 75 72 6e 28 46 49 4c 45 44  {...return(FILED
1cd0: 5f 44 45 46 41 55 4c 54 5f 54 59 50 45 29 3b 0a  _DEFAULT_TYPE);.
1ce0: 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d  .}...filed_log_m
1cf0: 73 67 5f 64 65 62 75 67 28 22 4c 6f 6f 6b 69 6e  sg_debug("Lookin
1d00: 67 20 75 70 20 4d 49 4d 45 20 74 79 70 65 20 66  g up MIME type f
1d10: 6f 72 20 25 73 20 28 68 61 73 68 20 3d 20 25 6c  or %s (hash = %l
1d20: 6c 75 29 22 2c 20 70 2c 20 28 75 6e 73 69 67 6e  lu)", p, (unsign
1d30: 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69  ed long long) fi
1d40: 6c 65 64 5f 68 61 73 68 28 28 63 6f 6e 73 74 20  led_hash((const 
1d50: 75 6e 73 69 67 6e 65 64 20 63 68 61 72 20 2a 29  unsigned char *)
1d60: 20 70 2c 20 31 36 37 37 37 32 35 39 29 29 3b 0a   p, 16777259));.
1d70: 0a 23 69 6e 63 6c 75 64 65 20 22 66 69 6c 65 64  .#include "filed
1d80: 2d 6d 69 6d 65 2d 74 79 70 65 73 2e 68 22 0a 0a  -mime-types.h"..
1d90: 09 72 65 74 75 72 6e 28 46 49 4c 45 44 5f 44 45  .return(FILED_DE
1da0: 46 41 55 4c 54 5f 54 59 50 45 29 3b 0a 7d 0a 0a  FAULT_TYPE);.}..
1db0: 2f 2a 20 4f 70 65 6e 20 61 20 66 69 6c 65 20 61  /* Open a file a
1dc0: 6e 64 20 72 65 74 75 72 6e 20 66 69 6c 65 20 69  nd return file i
1dd0: 6e 66 6f 72 6d 61 74 69 6f 6e 20 2a 2f 0a 73 74  nformation */.st
1de0: 61 74 69 63 20 73 74 72 75 63 74 20 66 69 6c 65  atic struct file
1df0: 64 5f 66 69 6c 65 69 6e 66 6f 20 2a 66 69 6c 65  d_fileinfo *file
1e00: 64 5f 6f 70 65 6e 5f 66 69 6c 65 28 63 6f 6e 73  d_open_file(cons
1e10: 74 20 63 68 61 72 20 2a 70 61 74 68 2c 20 73 74  t char *path, st
1e20: 72 75 63 74 20 66 69 6c 65 64 5f 66 69 6c 65 69  ruct filed_filei
1e30: 6e 66 6f 20 2a 62 75 66 66 65 72 29 20 7b 0a 09  nfo *buffer) {..
1e40: 73 74 72 75 63 74 20 66 69 6c 65 64 5f 66 69 6c  struct filed_fil
1e50: 65 69 6e 66 6f 20 2a 63 61 63 68 65 3b 0a 09 63  einfo *cache;..c
1e60: 6f 6e 73 74 20 63 68 61 72 20 2a 6f 70 65 6e 5f  onst char *open_
1e70: 70 61 74 68 3b 0a 09 75 6e 73 69 67 6e 65 64 20  path;..unsigned 
1e80: 69 6e 74 20 63 61 63 68 65 5f 69 64 78 3b 0a 09  int cache_idx;..
1e90: 6f 66 66 5f 74 20 6c 65 6e 3b 0a 09 69 6e 74 20  off_t len;..int 
1ea0: 66 64 3b 0a 0a 09 63 61 63 68 65 5f 69 64 78 20  fd;...cache_idx 
1eb0: 3d 20 66 69 6c 65 64 5f 68 61 73 68 28 28 63 6f  = filed_hash((co
1ec0: 6e 73 74 20 75 6e 73 69 67 6e 65 64 20 63 68 61  nst unsigned cha
1ed0: 72 20 2a 29 20 70 61 74 68 2c 20 66 69 6c 65 64  r *) path, filed
1ee0: 5f 66 69 6c 65 69 6e 66 6f 5f 66 64 63 61 63 68  _fileinfo_fdcach
1ef0: 65 5f 73 69 7a 65 29 3b 0a 0a 09 63 61 63 68 65  e_size);...cache
1f00: 20 3d 20 26 66 69 6c 65 64 5f 66 69 6c 65 69 6e   = &filed_filein
1f10: 66 6f 5f 66 64 63 61 63 68 65 5b 63 61 63 68 65  fo_fdcache[cache
1f20: 5f 69 64 78 5d 3b 0a 0a 09 66 69 6c 65 64 5f 6c  _idx];...filed_l
1f30: 6f 67 5f 6d 73 67 5f 64 65 62 75 67 28 22 4c 6f  og_msg_debug("Lo
1f40: 63 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f 72 20  cking mutex for 
1f50: 69 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e 73 69  idx: %lu", (unsi
1f60: 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 65  gned long) cache
1f70: 5f 69 64 78 29 3b 0a 0a 09 70 74 68 72 65 61 64  _idx);...pthread
1f80: 5f 6d 75 74 65 78 5f 6c 6f 63 6b 28 26 63 61 63  _mutex_lock(&cac
1f90: 68 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 66 69  he->mutex);...fi
1fa0: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75  led_log_msg_debu
1fb0: 67 28 22 43 6f 6d 70 6c 65 74 65 64 20 6c 6f 63  g("Completed loc
1fc0: 6b 69 6e 67 20 6d 75 74 65 78 20 66 6f 72 20 69  king mutex for i
1fd0: 64 78 3a 20 25 6c 75 22 2c 20 28 75 6e 73 69 67  dx: %lu", (unsig
1fe0: 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f  ned long) cache_
1ff0: 69 64 78 29 3b 0a 0a 09 69 66 20 28 73 74 72 63  idx);...if (strc
2000: 6d 70 28 70 61 74 68 2c 20 63 61 63 68 65 2d 3e  mp(path, cache->
2010: 70 61 74 68 29 20 21 3d 20 30 29 20 7b 0a 09 09  path) != 0) {...
2020: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65  filed_log_msg_de
2030: 62 75 67 28 22 43 61 63 68 65 20 6d 69 73 73 20  bug("Cache miss 
2040: 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20 4f 4c  for idx: %lu: OL
2050: 44 20 5c 22 25 73 5c 22 2c 20 4e 45 57 20 5c 22  D \"%s\", NEW \"
2060: 25 73 5c 22 22 2c 20 28 75 6e 73 69 67 6e 65 64  %s\"", (unsigned
2070: 20 6c 6f 6e 67 29 20 63 61 63 68 65 5f 69 64 78   long) cache_idx
2080: 2c 20 63 61 63 68 65 2d 3e 70 61 74 68 2c 20 70  , cache->path, p
2090: 61 74 68 29 3b 0a 0a 09 09 2f 2a 20 46 6f 72 20  ath);..../* For 
20a0: 72 65 71 75 65 73 74 73 20 66 6f 72 20 74 68 65  requests for the
20b0: 20 72 6f 6f 74 20 64 69 72 65 63 74 6f 72 79 2c   root directory,
20c0: 20 73 65 72 76 65 20 6f 75 74 20 69 6e 64 65 78   serve out index
20d0: 2e 68 74 6d 6c 20 2a 2f 0a 09 09 69 66 20 28 70  .html */...if (p
20e0: 61 74 68 5b 30 5d 20 3d 3d 20 27 5c 30 27 20 7c  ath[0] == '\0' |
20f0: 7c 20 28 70 61 74 68 5b 30 5d 20 3d 3d 20 27 2f  | (path[0] == '/
2100: 27 20 26 26 20 70 61 74 68 5b 31 5d 20 3d 3d 20  ' && path[1] == 
2110: 27 5c 30 27 29 29 20 7b 0a 09 09 09 6f 70 65 6e  '\0')) {....open
2120: 5f 70 61 74 68 20 3d 20 22 2f 69 6e 64 65 78 2e  _path = "/index.
2130: 68 74 6d 6c 22 3b 0a 09 09 7d 20 65 6c 73 65 20  html";...} else 
2140: 7b 0a 09 09 09 6f 70 65 6e 5f 70 61 74 68 20 3d  {....open_path =
2150: 20 70 61 74 68 3b 0a 09 09 7d 0a 0a 09 09 66 64   path;...}....fd
2160: 20 3d 20 6f 70 65 6e 28 6f 70 65 6e 5f 70 61 74   = open(open_pat
2170: 68 2c 20 4f 5f 52 44 4f 4e 4c 59 20 7c 20 4f 5f  h, O_RDONLY | O_
2180: 4c 41 52 47 45 46 49 4c 45 29 3b 0a 09 09 69 66  LARGEFILE);...if
2190: 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 09 70   (fd < 0) {....p
21a0: 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75 6e 6c  thread_mutex_unl
21b0: 6f 63 6b 28 26 63 61 63 68 65 2d 3e 6d 75 74 65  ock(&cache->mute
21c0: 78 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28 4e  x);.....return(N
21d0: 55 4c 4c 29 3b 0a 09 09 7d 0a 0a 09 09 66 72 65  ULL);...}....fre
21e0: 65 28 63 61 63 68 65 2d 3e 70 61 74 68 29 3b 0a  e(cache->path);.
21f0: 09 09 69 66 20 28 63 61 63 68 65 2d 3e 66 64 20  ..if (cache->fd 
2200: 3e 3d 20 30 29 20 7b 0a 09 09 09 63 6c 6f 73 65  >= 0) {....close
2210: 28 63 61 63 68 65 2d 3e 66 64 29 3b 0a 09 09 7d  (cache->fd);...}
2220: 0a 0a 09 09 6c 65 6e 20 3d 20 6c 73 65 65 6b 28  ....len = lseek(
2230: 66 64 2c 20 30 2c 20 53 45 45 4b 5f 45 4e 44 29  fd, 0, SEEK_END)
2240: 3b 0a 09 09 6c 73 65 65 6b 28 66 64 2c 20 30 2c  ;...lseek(fd, 0,
2250: 20 53 45 45 4b 5f 53 45 54 29 3b 0a 0a 09 09 63   SEEK_SET);....c
2260: 61 63 68 65 2d 3e 66 64 20 3d 20 66 64 3b 0a 09  ache->fd = fd;..
2270: 09 63 61 63 68 65 2d 3e 6c 65 6e 20 3d 20 6c 65  .cache->len = le
2280: 6e 3b 0a 09 09 63 61 63 68 65 2d 3e 70 61 74 68  n;...cache->path
2290: 20 3d 20 73 74 72 64 75 70 28 70 61 74 68 29 3b   = strdup(path);
22a0: 0a 09 09 63 61 63 68 65 2d 3e 74 79 70 65 20 3d  ...cache->type =
22b0: 20 66 69 6c 65 64 5f 64 65 74 65 72 6d 69 6e 65   filed_determine
22c0: 5f 6d 69 6d 65 74 79 70 65 28 6f 70 65 6e 5f 70  _mimetype(open_p
22d0: 61 74 68 29 3b 0a 0a 09 09 2f 2a 20 58 58 58 3a  ath);..../* XXX:
22e0: 54 4f 44 4f 3a 20 44 65 74 65 72 6d 69 6e 65 20  TODO: Determine 
22f0: 2a 2f 0a 09 09 63 61 63 68 65 2d 3e 6c 61 73 74  */...cache->last
2300: 6d 6f 64 20 3d 20 66 69 6c 65 64 5f 66 6f 72 6d  mod = filed_form
2310: 61 74 5f 74 69 6d 65 28 63 61 63 68 65 2d 3e 6c  at_time(cache->l
2320: 61 73 74 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f 66  astmod_b, sizeof
2330: 28 63 61 63 68 65 2d 3e 6c 61 73 74 6d 6f 64 5f  (cache->lastmod_
2340: 62 29 2c 20 74 69 6d 65 28 4e 55 4c 4c 29 20 2d  b), time(NULL) -
2350: 20 33 30 29 3b 0a 09 7d 20 65 6c 73 65 20 7b 0a   30);..} else {.
2360: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 5f  ..filed_log_msg_
2370: 64 65 62 75 67 28 22 43 61 63 68 65 20 68 69 74  debug("Cache hit
2380: 20 66 6f 72 20 69 64 78 3a 20 25 6c 75 3a 20 50   for idx: %lu: P
2390: 41 54 48 20 5c 22 25 73 5c 22 22 2c 20 28 75 6e  ATH \"%s\"", (un
23a0: 73 69 67 6e 65 64 20 6c 6f 6e 67 29 20 63 61 63  signed long) cac
23b0: 68 65 5f 69 64 78 2c 20 70 61 74 68 29 3b 0a 09  he_idx, path);..
23c0: 7d 0a 0a 09 2f 2a 0a 09 20 2a 20 57 65 20 68 61  }.../*.. * We ha
23d0: 76 65 20 74 6f 20 6d 61 6b 65 20 61 20 64 75 70  ve to make a dup
23e0: 6c 69 63 61 74 65 20 46 44 2c 20 62 65 63 61 75  licate FD, becau
23f0: 73 65 20 6f 6e 63 65 20 77 65 20 72 65 6c 65 61  se once we relea
2400: 73 65 20 74 68 65 20 63 61 63 68 65 0a 09 20 2a  se the cache.. *
2410: 20 6d 75 74 65 78 2c 20 74 68 65 20 66 69 6c 65   mutex, the file
2420: 20 64 65 73 63 72 69 70 74 6f 72 20 6d 61 79 20   descriptor may 
2430: 62 65 20 63 6c 6f 73 65 64 0a 09 20 2a 2f 0a 09  be closed.. */..
2440: 66 64 20 3d 20 64 75 70 28 63 61 63 68 65 2d 3e  fd = dup(cache->
2450: 66 64 29 3b 0a 09 69 66 20 28 66 64 20 3c 20 30  fd);..if (fd < 0
2460: 29 20 7b 0a 09 09 70 74 68 72 65 61 64 5f 6d 75  ) {...pthread_mu
2470: 74 65 78 5f 75 6e 6c 6f 63 6b 28 26 63 61 63 68  tex_unlock(&cach
2480: 65 2d 3e 6d 75 74 65 78 29 3b 0a 0a 09 09 72 65  e->mutex);....re
2490: 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a 0a  turn(NULL);..}..
24a0: 09 62 75 66 66 65 72 2d 3e 66 64 20 3d 20 66 64  .buffer->fd = fd
24b0: 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 65 6e 20 3d  ;..buffer->len =
24c0: 20 63 61 63 68 65 2d 3e 6c 65 6e 3b 0a 09 62 75   cache->len;..bu
24d0: 66 66 65 72 2d 3e 74 79 70 65 20 3d 20 63 61 63  ffer->type = cac
24e0: 68 65 2d 3e 74 79 70 65 3b 0a 09 6d 65 6d 63 70  he->type;..memcp
24f0: 79 28 62 75 66 66 65 72 2d 3e 6c 61 73 74 6d 6f  y(buffer->lastmo
2500: 64 5f 62 2c 20 63 61 63 68 65 2d 3e 6c 61 73 74  d_b, cache->last
2510: 6d 6f 64 5f 62 2c 20 73 69 7a 65 6f 66 28 62 75  mod_b, sizeof(bu
2520: 66 66 65 72 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29  ffer->lastmod_b)
2530: 29 3b 0a 09 62 75 66 66 65 72 2d 3e 6c 61 73 74  );..buffer->last
2540: 6d 6f 64 20 3d 20 62 75 66 66 65 72 2d 3e 6c 61  mod = buffer->la
2550: 73 74 6d 6f 64 5f 62 20 2b 20 28 63 61 63 68 65  stmod_b + (cache
2560: 2d 3e 6c 61 73 74 6d 6f 64 20 2d 20 63 61 63 68  ->lastmod - cach
2570: 65 2d 3e 6c 61 73 74 6d 6f 64 5f 62 29 3b 0a 0a  e->lastmod_b);..
2580: 09 70 74 68 72 65 61 64 5f 6d 75 74 65 78 5f 75  .pthread_mutex_u
2590: 6e 6c 6f 63 6b 28 26 63 61 63 68 65 2d 3e 6d 75  nlock(&cache->mu
25a0: 74 65 78 29 3b 0a 0a 09 72 65 74 75 72 6e 28 62  tex);...return(b
25b0: 75 66 66 65 72 29 3b 0a 7d 0a 0a 2f 2a 20 50 72  uffer);.}../* Pr
25c0: 6f 63 65 73 73 20 61 6e 20 48 54 54 50 20 72 65  ocess an HTTP re
25d0: 71 75 65 73 74 20 61 6e 64 20 72 65 74 75 72 6e  quest and return
25e0: 20 74 68 65 20 70 61 74 68 20 72 65 71 75 65 73   the path reques
25f0: 74 65 64 20 2a 2f 0a 73 74 61 74 69 63 20 73 74  ted */.static st
2600: 72 75 63 74 20 66 69 6c 65 64 5f 68 74 74 70 5f  ruct filed_http_
2610: 72 65 71 75 65 73 74 20 2a 66 69 6c 65 64 5f 67  request *filed_g
2620: 65 74 5f 68 74 74 70 5f 72 65 71 75 65 73 74 28  et_http_request(
2630: 46 49 4c 45 20 2a 66 70 2c 20 73 74 72 75 63 74  FILE *fp, struct
2640: 20 66 69 6c 65 64 5f 68 74 74 70 5f 72 65 71 75   filed_http_requ
2650: 65 73 74 20 2a 62 75 66 66 65 72 5f 73 74 29 20  est *buffer_st) 
2660: 7b 0a 09 63 68 61 72 20 2a 6d 65 74 68 6f 64 2c  {..char *method,
2670: 20 2a 70 61 74 68 3b 0a 09 63 68 61 72 20 2a 62   *path;..char *b
2680: 75 66 66 65 72 2c 20 2a 74 6d 70 62 75 66 66 65  uffer, *tmpbuffe
2690: 72 2c 20 2a 77 6f 72 6b 62 75 66 66 65 72 2c 20  r, *workbuffer, 
26a0: 2a 77 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78 74  *workbuffer_next
26b0: 3b 0a 09 73 69 7a 65 5f 74 20 62 75 66 66 65 72  ;..size_t buffer
26c0: 5f 6c 65 6e 2c 20 74 6d 70 62 75 66 66 65 72 5f  _len, tmpbuffer_
26d0: 6c 65 6e 3b 0a 09 6f 66 66 5f 74 20 72 61 6e 67  len;..off_t rang
26e0: 65 5f 73 74 61 72 74 2c 20 72 61 6e 67 65 5f 65  e_start, range_e
26f0: 6e 64 2c 20 72 61 6e 67 65 5f 6c 65 6e 67 74 68  nd, range_length
2700: 3b 0a 09 69 6e 74 20 72 61 6e 67 65 5f 72 65 71  ;..int range_req
2710: 75 65 73 74 3b 0a 09 69 6e 74 20 66 64 3b 0a 09  uest;..int fd;..
2720: 69 6e 74 20 69 3b 0a 0a 09 66 64 20 3d 20 66 69  int i;...fd = fi
2730: 6c 65 6e 6f 28 66 70 29 3b 0a 0a 09 72 61 6e 67  leno(fp);...rang
2740: 65 5f 73 74 61 72 74 20 3d 20 30 3b 0a 09 72 61  e_start = 0;..ra
2750: 6e 67 65 5f 65 6e 64 20 20 20 3d 20 30 3b 0a 09  nge_end   = 0;..
2760: 72 61 6e 67 65 5f 72 65 71 75 65 73 74 20 3d 20  range_request = 
2770: 30 3b 0a 09 72 61 6e 67 65 5f 6c 65 6e 67 74 68  0;..range_length
2780: 20 3d 20 2d 31 3b 0a 0a 09 62 75 66 66 65 72 20   = -1;...buffer 
2790: 3d 20 62 75 66 66 65 72 5f 73 74 2d 3e 70 61 74  = buffer_st->pat
27a0: 68 5f 62 3b 0a 09 62 75 66 66 65 72 5f 6c 65 6e  h_b;..buffer_len
27b0: 20 3d 20 73 69 7a 65 6f 66 28 62 75 66 66 65 72   = sizeof(buffer
27c0: 5f 73 74 2d 3e 70 61 74 68 5f 62 29 3b 0a 0a 09  _st->path_b);...
27d0: 74 6d 70 62 75 66 66 65 72 20 3d 20 62 75 66 66  tmpbuffer = buff
27e0: 65 72 5f 73 74 2d 3e 74 6d 70 62 75 66 3b 0a 09  er_st->tmpbuf;..
27f0: 74 6d 70 62 75 66 66 65 72 5f 6c 65 6e 20 3d 20  tmpbuffer_len = 
2800: 73 69 7a 65 6f 66 28 62 75 66 66 65 72 5f 73 74  sizeof(buffer_st
2810: 2d 3e 74 6d 70 62 75 66 29 3b 0a 0a 09 66 69 6c  ->tmpbuf);...fil
2820: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 57 41 49 54  ed_log_msg("WAIT
2830: 5f 46 4f 52 5f 52 45 51 55 45 53 54 20 46 44 3d  _FOR_REQUEST FD=
2840: 25 69 22 2c 20 66 64 29 3b 0a 0a 09 66 67 65 74  %i", fd);...fget
2850: 73 28 62 75 66 66 65 72 2c 20 62 75 66 66 65 72  s(buffer, buffer
2860: 5f 6c 65 6e 2c 20 66 70 29 3b 0a 0a 09 6d 65 74  _len, fp);...met
2870: 68 6f 64 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09  hod = buffer;...
2880: 62 75 66 66 65 72 20 3d 20 73 74 72 63 68 72 28  buffer = strchr(
2890: 62 75 66 66 65 72 2c 20 27 20 27 29 3b 0a 09 69  buffer, ' ');..i
28a0: 66 20 28 62 75 66 66 65 72 20 3d 3d 20 4e 55 4c  f (buffer == NUL
28b0: 4c 29 20 7b 0a 09 09 66 69 6c 65 64 5f 6c 6f 67  L) {...filed_log
28c0: 5f 6d 73 67 28 22 47 4f 54 5f 52 45 51 55 45 53  _msg("GOT_REQUES
28d0: 54 20 46 44 3d 25 69 20 45 52 52 4f 52 3d 66 6f  T FD=%i ERROR=fo
28e0: 72 6d 61 74 22 2c 20 66 64 29 3b 0a 0a 09 09 72  rmat", fd);....r
28f0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
2900: 0a 09 2a 62 75 66 66 65 72 20 3d 20 27 5c 30 27  ..*buffer = '\0'
2910: 3b 0a 09 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 70  ;..buffer++;...p
2920: 61 74 68 20 3d 20 62 75 66 66 65 72 3b 0a 0a 09  ath = buffer;...
2930: 62 75 66 66 65 72 20 3d 20 73 74 72 63 68 72 28  buffer = strchr(
2940: 62 75 66 66 65 72 2c 20 27 20 27 29 3b 0a 09 69  buffer, ' ');..i
2950: 66 20 28 62 75 66 66 65 72 20 21 3d 20 4e 55 4c  f (buffer != NUL
2960: 4c 29 20 7b 0a 09 09 2a 62 75 66 66 65 72 20 3d  L) {...*buffer =
2970: 20 27 5c 30 27 3b 0a 09 09 62 75 66 66 65 72 2b   '\0';...buffer+
2980: 2b 3b 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f  +;..}...filed_lo
2990: 67 5f 6d 73 67 28 22 47 4f 54 5f 52 45 51 55 45  g_msg("GOT_REQUE
29a0: 53 54 20 46 44 3d 25 69 20 50 41 54 48 3d 25 73  ST FD=%i PATH=%s
29b0: 22 2c 20 66 64 2c 20 70 61 74 68 29 3b 0a 0a 09  ", fd, path);...
29c0: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 57  filed_log_msg("W
29d0: 41 49 54 5f 46 4f 52 5f 48 45 41 44 45 52 53 20  AIT_FOR_HEADERS 
29e0: 46 44 3d 25 69 22 2c 20 66 64 29 3b 0a 0a 09 66  FD=%i", fd);...f
29f0: 6f 72 20 28 69 20 3d 20 30 3b 20 69 20 3c 20 31  or (i = 0; i < 1
2a00: 30 30 3b 20 69 2b 2b 29 20 7b 0a 09 09 66 67 65  00; i++) {...fge
2a10: 74 73 28 74 6d 70 62 75 66 66 65 72 2c 20 74 6d  ts(tmpbuffer, tm
2a20: 70 62 75 66 66 65 72 5f 6c 65 6e 2c 20 66 70 29  pbuffer_len, fp)
2a30: 3b 0a 0a 09 09 69 66 20 28 73 74 72 6e 63 61 73  ;....if (strncas
2a40: 65 63 6d 70 28 74 6d 70 62 75 66 66 65 72 2c 20  ecmp(tmpbuffer, 
2a50: 22 52 61 6e 67 65 3a 20 22 2c 20 37 29 20 3d 3d  "Range: ", 7) ==
2a60: 20 30 29 20 7b 0a 09 09 09 77 6f 72 6b 62 75 66   0) {....workbuf
2a70: 66 65 72 20 3d 20 74 6d 70 62 75 66 66 65 72 20  fer = tmpbuffer 
2a80: 2b 20 37 3b 0a 0a 09 09 09 69 66 20 28 73 74 72  + 7;.....if (str
2a90: 6e 63 61 73 65 63 6d 70 28 77 6f 72 6b 62 75 66  ncasecmp(workbuf
2aa0: 66 65 72 2c 20 22 62 79 74 65 73 3d 22 2c 20 36  fer, "bytes=", 6
2ab0: 29 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 77 6f  ) == 0) {.....wo
2ac0: 72 6b 62 75 66 66 65 72 20 2b 3d 20 36 3b 0a 0a  rkbuffer += 6;..
2ad0: 09 09 09 09 72 61 6e 67 65 5f 72 65 71 75 65 73  ....range_reques
2ae0: 74 20 3d 20 31 3b 0a 0a 09 09 09 09 72 61 6e 67  t = 1;......rang
2af0: 65 5f 73 74 61 72 74 20 3d 20 73 74 72 74 6f 75  e_start = strtou
2b00: 6c 6c 28 77 6f 72 6b 62 75 66 66 65 72 2c 20 26  ll(workbuffer, &
2b10: 77 6f 72 6b 62 75 66 66 65 72 5f 6e 65 78 74 2c  workbuffer_next,
2b20: 20 31 30 29 3b 0a 0a 09 09 09 09 77 6f 72 6b 62   10);......workb
2b30: 75 66 66 65 72 20 3d 20 77 6f 72 6b 62 75 66 66  uffer = workbuff
2b40: 65 72 5f 6e 65 78 74 3b 0a 0a 09 09 09 09 69 66  er_next;......if
2b50: 20 28 2a 77 6f 72 6b 62 75 66 66 65 72 20 3d 3d   (*workbuffer ==
2b60: 20 27 2d 27 29 20 7b 0a 09 09 09 09 09 77 6f 72   '-') {......wor
2b70: 6b 62 75 66 66 65 72 2b 2b 3b 0a 0a 09 09 09 09  kbuffer++;......
2b80: 09 69 66 20 28 2a 77 6f 72 6b 62 75 66 66 65 72  .if (*workbuffer
2b90: 20 21 3d 20 27 5c 72 27 20 26 26 20 2a 77 6f 72   != '\r' && *wor
2ba0: 6b 62 75 66 66 65 72 20 21 3d 20 27 5c 6e 27 29  kbuffer != '\n')
2bb0: 20 7b 0a 09 09 09 09 09 09 72 61 6e 67 65 5f 65   {.......range_e
2bc0: 6e 64 20 3d 20 73 74 72 74 6f 75 6c 6c 28 77 6f  nd = strtoull(wo
2bd0: 72 6b 62 75 66 66 65 72 2c 20 26 77 6f 72 6b 62  rkbuffer, &workb
2be0: 75 66 66 65 72 5f 6e 65 78 74 2c 20 31 30 29 3b  uffer_next, 10);
2bf0: 0a 09 09 09 09 09 7d 0a 09 09 09 09 7d 0a 09 09  ......}.....}...
2c00: 09 7d 0a 09 09 7d 0a 0a 09 09 69 66 20 28 6d 65  .}...}....if (me
2c10: 6d 63 6d 70 28 74 6d 70 62 75 66 66 65 72 2c 20  mcmp(tmpbuffer, 
2c20: 22 5c 72 5c 6e 22 2c 20 32 29 20 3d 3d 20 30 29  "\r\n", 2) == 0)
2c30: 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a 09 09 7d   {....break;...}
2c40: 0a 09 7d 0a 0a 09 66 69 6c 65 64 5f 6c 6f 67 5f  ..}...filed_log_
2c50: 6d 73 67 28 22 47 4f 54 5f 48 45 41 44 45 52 53  msg("GOT_HEADERS
2c60: 20 46 44 3d 25 69 22 2c 20 66 64 29 3b 0a 0a 09   FD=%i", fd);...
2c70: 2f 2a 20 57 65 20 6f 6e 6c 79 20 68 61 6e 64 6c  /* We only handl
2c80: 65 20 74 68 65 20 22 47 45 54 22 20 6d 65 74 68  e the "GET" meth
2c90: 6f 64 20 2a 2f 0a 09 69 66 20 28 73 74 72 63 61  od */..if (strca
2ca0: 73 65 63 6d 70 28 6d 65 74 68 6f 64 2c 20 22 67  secmp(method, "g
2cb0: 65 74 22 29 20 21 3d 20 30 29 20 7b 0a 09 09 72  et") != 0) {...r
2cc0: 65 74 75 72 6e 28 4e 55 4c 4c 29 3b 0a 09 7d 0a  eturn(NULL);..}.
2cd0: 0a 09 2f 2a 20 44 65 74 65 72 6d 69 6e 65 20 72  ../* Determine r
2ce0: 61 6e 67 65 20 2a 2f 0a 09 69 66 20 28 72 61 6e  ange */..if (ran
2cf0: 67 65 5f 65 6e 64 20 21 3d 20 30 29 20 7b 0a 09  ge_end != 0) {..
2d00: 09 69 66 20 28 72 61 6e 67 65 5f 65 6e 64 20 3c  .if (range_end <
2d10: 3d 20 72 61 6e 67 65 5f 73 74 61 72 74 29 20 7b  = range_start) {
2d20: 0a 09 09 09 72 65 74 75 72 6e 28 4e 55 4c 4c 29  ....return(NULL)
2d30: 3b 0a 09 09 7d 0a 0a 09 09 72 61 6e 67 65 5f 6c  ;...}....range_l
2d40: 65 6e 67 74 68 20 3d 20 72 61 6e 67 65 5f 65 6e  ength = range_en
2d50: 64 20 2d 20 72 61 6e 67 65 5f 73 74 61 72 74 3b  d - range_start;
2d60: 0a 0a 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  ....filed_log_ms
2d70: 67 5f 64 65 62 75 67 28 22 43 6f 6d 70 75 74 69  g_debug("Computi
2d80: 6e 67 20 6c 65 6e 67 74 68 20 70 61 72 61 6d 65  ng length parame
2d90: 74 65 72 3a 20 25 6c 6c 75 20 3d 20 25 6c 6c 75  ter: %llu = %llu
2da0: 20 2d 20 25 6c 6c 75 22 2c 0a 09 09 09 28 75 6e   - %llu",....(un
2db0: 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67  signed long long
2dc0: 29 20 72 61 6e 67 65 5f 6c 65 6e 67 74 68 2c 0a  ) range_length,.
2dd0: 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ...(unsigned lon
2de0: 67 20 6c 6f 6e 67 29 20 72 61 6e 67 65 5f 65 6e  g long) range_en
2df0: 64 2c 0a 09 09 09 28 75 6e 73 69 67 6e 65 64 20  d,....(unsigned 
2e00: 6c 6f 6e 67 20 6c 6f 6e 67 29 20 72 61 6e 67 65  long long) range
2e10: 5f 73 74 61 72 74 0a 09 09 29 3b 0a 09 7d 0a 0a  _start...);..}..
2e20: 09 2f 2a 20 46 69 6c 6c 20 75 70 20 73 74 72 75  ./* Fill up stru
2e30: 63 74 75 72 65 20 74 6f 20 72 65 74 75 72 6e 20  cture to return 
2e40: 2a 2f 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 70  */..buffer_st->p
2e50: 61 74 68 20 20 20 3d 20 70 61 74 68 3b 0a 09 62  ath   = path;..b
2e60: 75 66 66 65 72 5f 73 74 2d 3e 68 65 61 64 65 72  uffer_st->header
2e70: 73 2e 72 61 6e 67 65 2e 70 72 65 73 65 6e 74 20  s.range.present 
2e80: 3d 20 72 61 6e 67 65 5f 72 65 71 75 65 73 74 3b  = range_request;
2e90: 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 68 65 61  ..buffer_st->hea
2ea0: 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65  ders.range.offse
2eb0: 74 20 20 3d 20 72 61 6e 67 65 5f 73 74 61 72 74  t  = range_start
2ec0: 3b 0a 09 62 75 66 66 65 72 5f 73 74 2d 3e 68 65  ;..buffer_st->he
2ed0: 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67  aders.range.leng
2ee0: 74 68 20 20 3d 20 72 61 6e 67 65 5f 6c 65 6e 67  th  = range_leng
2ef0: 74 68 3b 0a 0a 09 72 65 74 75 72 6e 28 62 75 66  th;...return(buf
2f00: 66 65 72 5f 73 74 29 3b 0a 0a 09 2f 2a 20 4d 61  fer_st);.../* Ma
2f10: 6b 65 20 63 6f 6d 70 69 6c 65 72 20 68 61 70 70  ke compiler happ
2f20: 79 20 2a 2f 0a 09 66 64 20 3d 20 66 64 3b 0a 7d  y */..fd = fd;.}
2f30: 0a 0a 2f 2a 20 52 65 74 75 72 6e 20 61 6e 20 65  ../* Return an e
2f40: 72 72 6f 72 20 70 61 67 65 20 2a 2f 0a 73 74 61  rror page */.sta
2f50: 74 69 63 20 76 6f 69 64 20 66 69 6c 65 64 5f 65  tic void filed_e
2f60: 72 72 6f 72 5f 70 61 67 65 28 46 49 4c 45 20 2a  rror_page(FILE *
2f70: 66 70 2c 20 63 6f 6e 73 74 20 63 68 61 72 20 2a  fp, const char *
2f80: 64 61 74 65 5f 63 75 72 72 65 6e 74 2c 20 69 6e  date_current, in
2f90: 74 20 65 72 72 6f 72 5f 6e 75 6d 62 65 72 29 20  t error_number) 
2fa0: 7b 0a 09 63 68 61 72 20 2a 65 72 72 6f 72 5f 73  {..char *error_s
2fb0: 74 72 69 6e 67 20 3d 20 22 3c 68 74 6d 6c 3e 3c  tring = "<html><
2fc0: 68 65 61 64 3e 3c 74 69 74 6c 65 3e 45 52 52 4f  head><title>ERRO
2fd0: 52 3c 2f 74 69 74 6c 65 3e 3c 2f 68 65 61 64 3e  R</title></head>
2fe0: 3c 62 6f 64 79 3e 55 6e 61 62 6c 65 20 74 6f 20  <body>Unable to 
2ff0: 70 72 6f 63 65 73 73 20 72 65 71 75 65 73 74 3c  process request<
3000: 2f 62 6f 64 79 3e 3c 2f 68 74 6d 6c 3e 22 3b 0a  /body></html>";.
3010: 0a 09 66 70 72 69 6e 74 66 28 66 70 2c 20 22 48  ..fprintf(fp, "H
3020: 54 54 50 2f 31 2e 31 20 25 69 20 4e 6f 74 20 4f  TTP/1.1 %i Not O
3030: 4b 5c 72 5c 6e 44 61 74 65 3a 20 25 73 5c 72 5c  K\r\nDate: %s\r\
3040: 6e 53 65 72 76 65 72 3a 20 66 69 6c 65 64 5c 72  nServer: filed\r
3050: 5c 6e 4c 61 73 74 2d 4d 6f 64 69 66 69 65 64 3a  \nLast-Modified:
3060: 20 25 73 5c 72 5c 6e 43 6f 6e 74 65 6e 74 2d 4c   %s\r\nContent-L
3070: 65 6e 67 74 68 3a 20 25 6c 6c 75 5c 72 5c 6e 43  ength: %llu\r\nC
3080: 6f 6e 74 65 6e 74 2d 54 79 70 65 3a 20 25 73 5c  ontent-Type: %s\
3090: 72 5c 6e 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63  r\nConnection: c
30a0: 6c 6f 73 65 5c 72 5c 6e 5c 72 5c 6e 25 73 22 2c  lose\r\n\r\n%s",
30b0: 0a 09 09 65 72 72 6f 72 5f 6e 75 6d 62 65 72 2c  ...error_number,
30c0: 0a 09 09 64 61 74 65 5f 63 75 72 72 65 6e 74 2c  ...date_current,
30d0: 0a 09 09 64 61 74 65 5f 63 75 72 72 65 6e 74 2c  ...date_current,
30e0: 0a 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e  ...(unsigned lon
30f0: 67 20 6c 6f 6e 67 29 20 73 74 72 6c 65 6e 28 65  g long) strlen(e
3100: 72 72 6f 72 5f 73 74 72 69 6e 67 29 2c 0a 09 09  rror_string),...
3110: 22 74 65 78 74 2f 68 74 6d 6c 22 2c 0a 09 09 65  "text/html",...e
3120: 72 72 6f 72 5f 73 74 72 69 6e 67 0a 09 29 3b 0a  rror_string..);.
3130: 7d 0a 0a 2f 2a 20 48 61 6e 64 6c 65 20 61 20 73  }../* Handle a s
3140: 69 6e 67 6c 65 20 72 65 71 75 65 73 74 20 66 72  ingle request fr
3150: 6f 6d 20 61 20 63 6c 69 65 6e 74 20 2a 2f 0a 73  om a client */.s
3160: 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c 65 64  tatic void filed
3170: 5f 68 61 6e 64 6c 65 5f 63 6c 69 65 6e 74 28 69  _handle_client(i
3180: 6e 74 20 66 64 2c 20 73 74 72 75 63 74 20 66 69  nt fd, struct fi
3190: 6c 65 64 5f 68 74 74 70 5f 72 65 71 75 65 73 74  led_http_request
31a0: 20 2a 72 65 71 75 65 73 74 29 20 7b 0a 09 73 74   *request) {..st
31b0: 72 75 63 74 20 66 69 6c 65 64 5f 66 69 6c 65 69  ruct filed_filei
31c0: 6e 66 6f 20 2a 66 69 6c 65 69 6e 66 6f 3b 0a 09  nfo *fileinfo;..
31d0: 73 73 69 7a 65 5f 74 20 73 65 6e 64 66 69 6c 65  ssize_t sendfile
31e0: 5f 72 65 74 3b 0a 09 73 69 7a 65 5f 74 20 73 65  _ret;..size_t se
31f0: 6e 64 66 69 6c 65 5f 73 69 7a 65 3b 0a 09 6f 66  ndfile_size;..of
3200: 66 5f 74 20 73 65 6e 64 66 69 6c 65 5f 6f 66 66  f_t sendfile_off
3210: 73 65 74 2c 20 73 65 6e 64 66 69 6c 65 5f 73 65  set, sendfile_se
3220: 6e 74 2c 20 73 65 6e 64 66 69 6c 65 5f 6c 65 6e  nt, sendfile_len
3230: 3b 0a 09 63 68 61 72 20 2a 70 61 74 68 3b 0a 09  ;..char *path;..
3240: 63 68 61 72 20 2a 64 61 74 65 5f 63 75 72 72 65  char *date_curre
3250: 6e 74 2c 20 64 61 74 65 5f 63 75 72 72 65 6e 74  nt, date_current
3260: 5f 62 5b 36 34 5d 3b 0a 09 69 6e 74 20 68 74 74  _b[64];..int htt
3270: 70 5f 63 6f 64 65 3b 0a 09 46 49 4c 45 20 2a 66  p_code;..FILE *f
3280: 70 3b 0a 0a 09 2f 2a 20 44 65 74 65 72 6d 69 6e  p;.../* Determin
3290: 65 20 63 75 72 72 65 6e 74 20 74 69 6d 65 20 2a  e current time *
32a0: 2f 0a 09 64 61 74 65 5f 63 75 72 72 65 6e 74 20  /..date_current 
32b0: 3d 20 66 69 6c 65 64 5f 66 6f 72 6d 61 74 5f 74  = filed_format_t
32c0: 69 6d 65 28 64 61 74 65 5f 63 75 72 72 65 6e 74  ime(date_current
32d0: 5f 62 2c 20 73 69 7a 65 6f 66 28 64 61 74 65 5f  _b, sizeof(date_
32e0: 63 75 72 72 65 6e 74 5f 62 29 2c 20 74 69 6d 65  current_b), time
32f0: 28 4e 55 4c 4c 29 29 3b 0a 0a 09 2f 2a 20 4f 70  (NULL));.../* Op
3300: 65 6e 20 73 6f 63 6b 65 74 20 61 73 20 41 4e 53  en socket as ANS
3310: 49 20 49 2f 4f 20 66 6f 72 20 65 61 73 65 20 6f  I I/O for ease o
3320: 66 20 75 73 65 20 2a 2f 0a 09 66 70 20 3d 20 66  f use */..fp = f
3330: 64 6f 70 65 6e 28 66 64 2c 20 22 77 2b 62 22 29  dopen(fd, "w+b")
3340: 3b 0a 09 69 66 20 28 66 70 20 3d 3d 20 4e 55 4c  ;..if (fp == NUL
3350: 4c 29 20 7b 0a 09 09 63 6c 6f 73 65 28 66 64 29  L) {...close(fd)
3360: 3b 0a 0a 09 09 72 65 74 75 72 6e 3b 0a 09 7d 0a  ;....return;..}.
3370: 0a 09 72 65 71 75 65 73 74 20 3d 20 66 69 6c 65  ..request = file
3380: 64 5f 67 65 74 5f 68 74 74 70 5f 72 65 71 75 65  d_get_http_reque
3390: 73 74 28 66 70 2c 20 72 65 71 75 65 73 74 29 3b  st(fp, request);
33a0: 0a 0a 09 69 66 20 28 72 65 71 75 65 73 74 20 3d  ...if (request =
33b0: 3d 20 4e 55 4c 4c 20 7c 7c 20 72 65 71 75 65 73  = NULL || reques
33c0: 74 2d 3e 70 61 74 68 20 3d 3d 20 4e 55 4c 4c 29  t->path == NULL)
33d0: 20 7b 0a 09 09 66 69 6c 65 64 5f 65 72 72 6f 72   {...filed_error
33e0: 5f 70 61 67 65 28 66 70 2c 20 64 61 74 65 5f 63  _page(fp, date_c
33f0: 75 72 72 65 6e 74 2c 20 35 30 30 29 3b 0a 0a 09  urrent, 500);...
3400: 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22  .filed_log_msg("
3410: 49 4e 56 41 4c 49 44 5f 52 45 51 55 45 53 54 20  INVALID_REQUEST 
3420: 46 44 3d 25 69 20 45 52 52 4f 52 3d 35 30 30 22  FD=%i ERROR=500"
3430: 2c 20 66 64 29 3b 0a 0a 09 09 66 63 6c 6f 73 65  , fd);....fclose
3440: 28 66 70 29 3b 0a 0a 09 09 72 65 74 75 72 6e 3b  (fp);....return;
3450: 0a 09 7d 0a 0a 09 69 66 20 28 72 65 71 75 65 73  ..}...if (reques
3460: 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65  t->headers.range
3470: 2e 70 72 65 73 65 6e 74 29 20 7b 0a 09 09 66 69  .present) {...fi
3480: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f  led_log_msg("PRO
3490: 43 45 53 53 5f 52 45 50 4c 59 5f 53 54 41 52 54  CESS_REPLY_START
34a0: 20 46 44 3d 25 69 20 50 41 54 48 3d 25 73 20 52   FD=%i PATH=%s R
34b0: 41 4e 47 45 5f 53 54 41 52 54 3d 25 6c 6c 75 20  ANGE_START=%llu 
34c0: 52 41 4e 47 45 5f 4c 45 4e 47 54 48 3d 25 6c 6c  RANGE_LENGTH=%ll
34d0: 75 22 2c 0a 09 09 09 66 64 2c 0a 09 09 09 72 65  u",....fd,....re
34e0: 71 75 65 73 74 2d 3e 70 61 74 68 2c 0a 09 09 09  quest->path,....
34f0: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
3500: 6f 6e 67 29 20 72 65 71 75 65 73 74 2d 3e 68 65  ong) request->he
3510: 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73  aders.range.offs
3520: 65 74 2c 0a 09 09 09 28 75 6e 73 69 67 6e 65 64  et,....(unsigned
3530: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 72 65 71 75   long long) requ
3540: 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e  est->headers.ran
3550: 67 65 2e 6c 65 6e 67 74 68 0a 09 09 29 3b 0a 09  ge.length...);..
3560: 7d 20 65 6c 73 65 20 7b 0a 09 09 66 69 6c 65 64  } else {...filed
3570: 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f 43 45 53  _log_msg("PROCES
3580: 53 5f 52 45 50 4c 59 5f 53 54 41 52 54 20 46 44  S_REPLY_START FD
3590: 3d 25 69 20 50 41 54 48 3d 25 73 22 2c 20 66 64  =%i PATH=%s", fd
35a0: 2c 20 72 65 71 75 65 73 74 2d 3e 70 61 74 68 29  , request->path)
35b0: 3b 0a 09 7d 0a 0a 09 70 61 74 68 20 3d 20 72 65  ;..}...path = re
35c0: 71 75 65 73 74 2d 3e 70 61 74 68 3b 0a 0a 09 68  quest->path;...h
35d0: 74 74 70 5f 63 6f 64 65 20 3d 20 2d 31 3b 0a 0a  ttp_code = -1;..
35e0: 09 66 69 6c 65 69 6e 66 6f 20 3d 20 66 69 6c 65  .fileinfo = file
35f0: 64 5f 6f 70 65 6e 5f 66 69 6c 65 28 70 61 74 68  d_open_file(path
3600: 2c 20 26 72 65 71 75 65 73 74 2d 3e 66 69 6c 65  , &request->file
3610: 69 6e 66 6f 29 3b 0a 09 69 66 20 28 66 69 6c 65  info);..if (file
3620: 69 6e 66 6f 20 3d 3d 20 4e 55 4c 4c 29 20 7b 0a  info == NULL) {.
3630: 09 09 66 69 6c 65 64 5f 65 72 72 6f 72 5f 70 61  ..filed_error_pa
3640: 67 65 28 66 70 2c 20 64 61 74 65 5f 63 75 72 72  ge(fp, date_curr
3650: 65 6e 74 2c 20 34 30 34 29 3b 0a 0a 09 09 66 69  ent, 404);....fi
3660: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f  led_log_msg("PRO
3670: 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 4c  CESS_REPLY_COMPL
3680: 45 54 45 20 46 44 3d 25 69 20 45 52 52 4f 52 3d  ETE FD=%i ERROR=
3690: 34 30 34 22 2c 20 66 64 29 3b 0a 09 7d 20 65 6c  404", fd);..} el
36a0: 73 65 20 7b 0a 09 09 69 66 20 28 72 65 71 75 65  se {...if (reque
36b0: 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67  st->headers.rang
36c0: 65 2e 6f 66 66 73 65 74 20 21 3d 20 30 20 7c 7c  e.offset != 0 ||
36d0: 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72   request->header
36e0: 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 20 3e  s.range.length >
36f0: 3d 20 30 29 20 7b 0a 09 09 09 69 66 20 28 72 65  = 0) {....if (re
3700: 71 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72  quest->headers.r
3710: 61 6e 67 65 2e 6f 66 66 73 65 74 20 3e 3d 20 66  ange.offset >= f
3720: 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e 29 20 7b 0a  ileinfo->len) {.
3730: 09 09 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73  ....filed_log_ms
3740: 67 28 22 50 52 4f 43 45 53 53 5f 52 45 50 4c 59  g("PROCESS_REPLY
3750: 5f 43 4f 4d 50 4c 45 54 45 20 46 44 3d 25 69 20  _COMPLETE FD=%i 
3760: 45 52 52 4f 52 3d 34 31 36 22 2c 20 66 64 29 3b  ERROR=416", fd);
3770: 0a 0a 09 09 09 09 66 69 6c 65 64 5f 65 72 72 6f  ......filed_erro
3780: 72 5f 70 61 67 65 28 66 70 2c 20 64 61 74 65 5f  r_page(fp, date_
3790: 63 75 72 72 65 6e 74 2c 20 34 31 36 29 3b 0a 09  current, 416);..
37a0: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 69  ..} else {.....i
37b0: 66 20 28 72 65 71 75 65 73 74 2d 3e 68 65 61 64  f (request->head
37c0: 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68  ers.range.length
37d0: 20 3c 20 30 29 20 7b 0a 09 09 09 09 09 66 69 6c   < 0) {......fil
37e0: 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67  ed_log_msg_debug
37f0: 28 22 43 6f 6d 70 75 74 69 6e 67 20 6c 65 6e 67  ("Computing leng
3800: 74 68 20 74 6f 20 66 69 74 20 69 6e 20 62 6f 75  th to fit in bou
3810: 6e 64 73 3a 20 66 69 6c 65 69 6e 66 6f 2d 3e 6c  nds: fileinfo->l
3820: 65 6e 20 3d 20 25 6c 6c 75 2c 20 72 65 71 75 65  en = %llu, reque
3830: 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67  st->headers.rang
3840: 65 2e 6f 66 66 73 65 74 20 3d 20 25 6c 6c 75 22  e.offset = %llu"
3850: 2c 0a 09 09 09 09 09 09 28 75 6e 73 69 67 6e 65  ,.......(unsigne
3860: 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 66 69 6c  d long long) fil
3870: 65 69 6e 66 6f 2d 3e 6c 65 6e 2c 0a 09 09 09 09  einfo->len,.....
3880: 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  ..(unsigned long
3890: 20 6c 6f 6e 67 29 20 72 65 71 75 65 73 74 2d 3e   long) request->
38a0: 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66  headers.range.of
38b0: 66 73 65 74 0a 09 09 09 09 09 29 3b 0a 0a 09 09  fset......);....
38c0: 09 09 09 72 65 71 75 65 73 74 2d 3e 68 65 61 64  ...request->head
38d0: 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68  ers.range.length
38e0: 20 3d 20 66 69 6c 65 69 6e 66 6f 2d 3e 6c 65 6e   = fileinfo->len
38f0: 20 2d 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64   - request->head
3900: 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74  ers.range.offset
3910: 3b 0a 09 09 09 09 7d 0a 0a 09 09 09 09 66 69 6c  ;.....}......fil
3920: 65 64 5f 6c 6f 67 5f 6d 73 67 5f 64 65 62 75 67  ed_log_msg_debug
3930: 28 22 50 61 72 74 69 61 6c 20 72 65 71 75 65 73  ("Partial reques
3940: 74 2c 20 73 74 61 72 74 69 6e 67 20 61 74 3a 20  t, starting at: 
3950: 25 6c 6c 75 20 61 6e 64 20 72 75 6e 6e 69 6e 67  %llu and running
3960: 20 66 6f 72 20 25 6c 6c 75 20 62 79 74 65 73 22   for %llu bytes"
3970: 2c 0a 09 09 09 09 09 28 75 6e 73 69 67 6e 65 64  ,......(unsigned
3980: 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 72 65 71 75   long long) requ
3990: 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e  est->headers.ran
39a0: 67 65 2e 6f 66 66 73 65 74 2c 0a 09 09 09 09 09  ge.offset,......
39b0: 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 20 6c  (unsigned long l
39c0: 6f 6e 67 29 20 72 65 71 75 65 73 74 2d 3e 68 65  ong) request->he
39d0: 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67  aders.range.leng
39e0: 74 68 0a 09 09 09 09 29 3b 0a 0a 09 09 09 09 68  th.....);......h
39f0: 74 74 70 5f 63 6f 64 65 20 3d 20 32 30 36 3b 0a  ttp_code = 206;.
3a00: 09 09 09 7d 0a 09 09 7d 20 65 6c 73 65 20 7b 0a  ...}...} else {.
3a10: 09 09 09 69 66 20 28 72 65 71 75 65 73 74 2d 3e  ...if (request->
3a20: 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 70 72  headers.range.pr
3a30: 65 73 65 6e 74 29 20 7b 0a 09 09 09 09 68 74 74  esent) {.....htt
3a40: 70 5f 63 6f 64 65 20 3d 20 32 30 36 3b 0a 09 09  p_code = 206;...
3a50: 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 68 74  .} else {.....ht
3a60: 74 70 5f 63 6f 64 65 20 3d 20 32 30 30 3b 0a 09  tp_code = 200;..
3a70: 09 09 7d 0a 09 09 09 72 65 71 75 65 73 74 2d 3e  ..}....request->
3a80: 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6f 66  headers.range.of
3a90: 66 73 65 74 20 3d 20 30 3b 0a 09 09 09 72 65 71  fset = 0;....req
3aa0: 75 65 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61  uest->headers.ra
3ab0: 6e 67 65 2e 6c 65 6e 67 74 68 20 3d 20 66 69 6c  nge.length = fil
3ac0: 65 69 6e 66 6f 2d 3e 6c 65 6e 3b 0a 09 09 7d 0a  einfo->len;...}.
3ad0: 0a 09 09 69 66 20 28 68 74 74 70 5f 63 6f 64 65  ...if (http_code
3ae0: 20 3e 20 30 29 20 7b 0a 09 09 09 66 70 72 69 6e   > 0) {....fprin
3af0: 74 66 28 66 70 2c 20 22 48 54 54 50 2f 31 2e 31  tf(fp, "HTTP/1.1
3b00: 20 25 69 20 4f 4b 5c 72 5c 6e 44 61 74 65 3a 20   %i OK\r\nDate: 
3b10: 25 73 5c 72 5c 6e 53 65 72 76 65 72 3a 20 66 69  %s\r\nServer: fi
3b20: 6c 65 64 5c 72 5c 6e 4c 61 73 74 2d 4d 6f 64 69  led\r\nLast-Modi
3b30: 66 69 65 64 3a 20 25 73 5c 72 5c 6e 43 6f 6e 74  fied: %s\r\nCont
3b40: 65 6e 74 2d 4c 65 6e 67 74 68 3a 20 25 6c 6c 75  ent-Length: %llu
3b50: 5c 72 5c 6e 41 63 63 65 70 74 2d 52 61 6e 67 65  \r\nAccept-Range
3b60: 73 3a 20 62 79 74 65 73 5c 72 5c 6e 43 6f 6e 74  s: bytes\r\nCont
3b70: 65 6e 74 2d 54 79 70 65 3a 20 25 73 5c 72 5c 6e  ent-Type: %s\r\n
3b80: 43 6f 6e 6e 65 63 74 69 6f 6e 3a 20 63 6c 6f 73  Connection: clos
3b90: 65 5c 72 5c 6e 22 2c 0a 09 09 09 09 68 74 74 70  e\r\n",.....http
3ba0: 5f 63 6f 64 65 2c 0a 09 09 09 09 64 61 74 65 5f  _code,.....date_
3bb0: 63 75 72 72 65 6e 74 2c 0a 09 09 09 09 66 69 6c  current,.....fil
3bc0: 65 69 6e 66 6f 2d 3e 6c 61 73 74 6d 6f 64 2c 0a  einfo->lastmod,.
3bd0: 09 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f  ....(unsigned lo
3be0: 6e 67 20 6c 6f 6e 67 29 20 72 65 71 75 65 73 74  ng long) request
3bf0: 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e  ->headers.range.
3c00: 6c 65 6e 67 74 68 2c 0a 09 09 09 09 66 69 6c 65  length,.....file
3c10: 69 6e 66 6f 2d 3e 74 79 70 65 0a 09 09 09 29 3b  info->type....);
3c20: 0a 09 09 09 69 66 20 28 68 74 74 70 5f 63 6f 64  ....if (http_cod
3c30: 65 20 3d 3d 20 32 30 36 29 20 7b 0a 09 09 09 09  e == 206) {.....
3c40: 66 70 72 69 6e 74 66 28 66 70 2c 20 22 43 6f 6e  fprintf(fp, "Con
3c50: 74 65 6e 74 2d 52 61 6e 67 65 3a 20 62 79 74 65  tent-Range: byte
3c60: 73 20 25 6c 6c 75 2d 25 6c 6c 75 2f 25 6c 6c 75  s %llu-%llu/%llu
3c70: 5c 72 5c 6e 22 2c 0a 09 09 09 09 09 28 75 6e 73  \r\n",......(uns
3c80: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
3c90: 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72   request->header
3ca0: 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74 2c 0a  s.range.offset,.
3cb0: 09 09 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c  .....(unsigned l
3cc0: 6f 6e 67 20 6c 6f 6e 67 29 20 28 72 65 71 75 65  ong long) (reque
3cd0: 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67  st->headers.rang
3ce0: 65 2e 6f 66 66 73 65 74 20 2b 20 72 65 71 75 65  e.offset + reque
3cf0: 73 74 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67  st->headers.rang
3d00: 65 2e 6c 65 6e 67 74 68 20 2d 20 31 29 2c 0a 09  e.length - 1),..
3d10: 09 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f  ....(unsigned lo
3d20: 6e 67 20 6c 6f 6e 67 29 20 66 69 6c 65 69 6e 66  ng long) fileinf
3d30: 6f 2d 3e 6c 65 6e 0a 09 09 09 09 29 3b 0a 09 09  o->len.....);...
3d40: 09 7d 0a 09 09 09 66 70 72 69 6e 74 66 28 66 70  .}....fprintf(fp
3d50: 2c 20 22 5c 72 5c 6e 22 29 3b 0a 09 09 09 66 66  , "\r\n");....ff
3d60: 6c 75 73 68 28 66 70 29 3b 0a 0a 09 09 09 66 69  lush(fp);.....fi
3d70: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 50 52 4f  led_log_msg("PRO
3d80: 43 45 53 53 5f 52 45 50 4c 59 5f 43 4f 4d 50 4c  CESS_REPLY_COMPL
3d90: 45 54 45 20 46 44 3d 25 69 20 53 54 41 54 55 53  ETE FD=%i STATUS
3da0: 3d 25 69 22 2c 20 66 64 2c 20 68 74 74 70 5f 63  =%i", fd, http_c
3db0: 6f 64 65 29 3b 0a 0a 23 69 66 64 65 66 20 46 49  ode);..#ifdef FI
3dc0: 4c 45 44 5f 4e 4f 4e 42 4c 4f 43 4b 5f 48 54 54  LED_NONBLOCK_HTT
3dd0: 50 0a 09 09 09 69 6e 74 20 73 6f 63 6b 65 74 5f  P....int socket_
3de0: 66 6c 61 67 73 3b 0a 09 09 09 66 64 5f 73 65 74  flags;....fd_set
3df0: 20 72 66 64 2c 20 77 66 64 3b 0a 09 09 09 63 68   rfd, wfd;....ch
3e00: 61 72 20 73 69 6e 6b 62 75 66 5b 38 31 39 32 5d  ar sinkbuf[8192]
3e10: 3b 0a 09 09 09 73 73 69 7a 65 5f 74 20 72 65 61  ;....ssize_t rea
3e20: 64 5f 72 65 74 3b 0a 0a 09 09 09 46 44 5f 5a 45  d_ret;.....FD_ZE
3e30: 52 4f 28 26 72 66 64 29 3b 0a 09 09 09 46 44 5f  RO(&rfd);....FD_
3e40: 5a 45 52 4f 28 26 77 66 64 29 3b 0a 09 09 09 46  ZERO(&wfd);....F
3e50: 44 5f 53 45 54 28 66 64 2c 20 26 72 66 64 29 3b  D_SET(fd, &rfd);
3e60: 0a 09 09 09 46 44 5f 53 45 54 28 66 64 2c 20 26  ....FD_SET(fd, &
3e70: 77 66 64 29 3b 0a 0a 09 09 09 73 6f 63 6b 65 74  wfd);.....socket
3e80: 5f 66 6c 61 67 73 20 3d 20 66 63 6e 74 6c 28 66  _flags = fcntl(f
3e90: 64 2c 20 46 5f 47 45 54 46 4c 29 3b 0a 09 09 09  d, F_GETFL);....
3ea0: 66 63 6e 74 6c 28 66 64 2c 20 46 5f 53 45 54 46  fcntl(fd, F_SETF
3eb0: 4c 2c 20 73 6f 63 6b 65 74 5f 66 6c 61 67 73 20  L, socket_flags 
3ec0: 7c 20 4f 5f 4e 4f 4e 42 4c 4f 43 4b 29 3b 0a 23  | O_NONBLOCK);.#
3ed0: 65 6e 64 69 66 0a 0a 09 09 09 66 69 6c 65 64 5f  endif.....filed_
3ee0: 6c 6f 67 5f 6d 73 67 28 22 53 45 4e 44 5f 53 54  log_msg("SEND_ST
3ef0: 41 52 54 20 46 49 4c 45 5f 46 44 3d 25 69 20 46  ART FILE_FD=%i F
3f00: 44 3d 25 69 20 42 59 54 45 53 3d 25 6c 6c 75 20  D=%i BYTES=%llu 
3f10: 4f 46 46 53 45 54 3d 25 6c 6c 75 22 2c 0a 09 09  OFFSET=%llu",...
3f20: 09 09 66 69 6c 65 69 6e 66 6f 2d 3e 66 64 2c 0a  ..fileinfo->fd,.
3f30: 09 09 09 09 66 64 2c 0a 09 09 09 09 28 75 6e 73  ....fd,.....(uns
3f40: 69 67 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29  igned long long)
3f50: 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72   request->header
3f60: 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 2c 0a  s.range.length,.
3f70: 09 09 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f  ....(unsigned lo
3f80: 6e 67 20 6c 6f 6e 67 29 20 72 65 71 75 65 73 74  ng long) request
3f90: 2d 3e 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e  ->headers.range.
3fa0: 6f 66 66 73 65 74 0a 09 09 09 29 3b 0a 0a 09 09  offset....);....
3fb0: 09 73 65 6e 64 66 69 6c 65 5f 6f 66 66 73 65 74  .sendfile_offset
3fc0: 20 3d 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64   = request->head
3fd0: 65 72 73 2e 72 61 6e 67 65 2e 6f 66 66 73 65 74  ers.range.offset
3fe0: 3b 0a 09 09 09 73 65 6e 64 66 69 6c 65 5f 6c 65  ;....sendfile_le
3ff0: 6e 20 3d 20 72 65 71 75 65 73 74 2d 3e 68 65 61  n = request->hea
4000: 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74  ders.range.lengt
4010: 68 3b 0a 09 09 09 73 65 6e 64 66 69 6c 65 5f 73  h;....sendfile_s
4020: 65 6e 74 20 3d 20 30 3b 0a 09 09 09 77 68 69 6c  ent = 0;....whil
4030: 65 20 28 31 29 20 7b 0a 09 09 09 09 69 66 20 28  e (1) {.....if (
4040: 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 20 3e 20 46  sendfile_len > F
4050: 49 4c 45 44 5f 53 45 4e 44 46 49 4c 45 5f 4d 41  ILED_SENDFILE_MA
4060: 58 29 20 7b 0a 09 09 09 09 09 73 65 6e 64 66 69  X) {......sendfi
4070: 6c 65 5f 73 69 7a 65 20 3d 20 46 49 4c 45 44 5f  le_size = FILED_
4080: 53 45 4e 44 46 49 4c 45 5f 4d 41 58 3b 0a 09 09  SENDFILE_MAX;...
4090: 09 09 7d 20 65 6c 73 65 20 7b 0a 09 09 09 09 09  ..} else {......
40a0: 73 65 6e 64 66 69 6c 65 5f 73 69 7a 65 20 3d 20  sendfile_size = 
40b0: 73 65 6e 64 66 69 6c 65 5f 6c 65 6e 3b 0a 09 09  sendfile_len;...
40c0: 09 09 7d 0a 0a 09 09 09 09 73 65 6e 64 66 69 6c  ..}......sendfil
40d0: 65 5f 72 65 74 20 3d 20 73 65 6e 64 66 69 6c 65  e_ret = sendfile
40e0: 28 66 64 2c 20 66 69 6c 65 69 6e 66 6f 2d 3e 66  (fd, fileinfo->f
40f0: 64 2c 20 26 73 65 6e 64 66 69 6c 65 5f 6f 66 66  d, &sendfile_off
4100: 73 65 74 2c 20 73 65 6e 64 66 69 6c 65 5f 73 69  set, sendfile_si
4110: 7a 65 29 3b 0a 09 09 09 09 69 66 20 28 73 65 6e  ze);.....if (sen
4120: 64 66 69 6c 65 5f 72 65 74 20 3c 3d 20 30 29 20  dfile_ret <= 0) 
4130: 7b 0a 23 69 66 64 65 66 20 46 49 4c 45 44 5f 4e  {.#ifdef FILED_N
4140: 4f 4e 42 4c 4f 43 4b 5f 48 54 54 50 0a 09 09 09  ONBLOCK_HTTP....
4150: 09 09 69 66 20 28 65 72 72 6e 6f 20 3d 3d 20 45  ..if (errno == E
4160: 41 47 41 49 4e 29 20 7b 0a 09 09 09 09 09 09 73  AGAIN) {.......s
4170: 65 6e 64 66 69 6c 65 5f 72 65 74 20 3d 20 30 3b  endfile_ret = 0;
4180: 0a 0a 09 09 09 09 09 09 77 68 69 6c 65 20 28 31  ........while (1
4190: 29 20 7b 0a 09 09 09 09 09 09 09 73 65 6c 65 63  ) {........selec
41a0: 74 28 66 64 20 2b 20 31 2c 20 26 72 66 64 2c 20  t(fd + 1, &rfd, 
41b0: 26 77 66 64 2c 20 4e 55 4c 4c 2c 20 4e 55 4c 4c  &wfd, NULL, NULL
41c0: 29 3b 0a 09 09 09 09 09 09 09 69 66 20 28 46 44  );........if (FD
41d0: 5f 49 53 53 45 54 28 66 64 2c 20 26 72 66 64 29  _ISSET(fd, &rfd)
41e0: 29 20 7b 0a 09 09 09 09 09 09 09 09 72 65 61 64  ) {.........read
41f0: 5f 72 65 74 20 3d 20 72 65 61 64 28 66 64 2c 20  _ret = read(fd, 
4200: 73 69 6e 6b 62 75 66 2c 20 73 69 7a 65 6f 66 28  sinkbuf, sizeof(
4210: 73 69 6e 6b 62 75 66 29 29 3b 0a 0a 09 09 09 09  sinkbuf));......
4220: 09 09 09 09 69 66 20 28 72 65 61 64 5f 72 65 74  ....if (read_ret
4230: 20 3c 3d 20 30 29 20 7b 0a 09 09 09 09 09 09 09   <= 0) {........
4240: 09 09 62 72 65 61 6b 3b 0a 09 09 09 09 09 09 09  ..break;........
4250: 09 7d 0a 09 09 09 09 09 09 09 7d 0a 0a 09 09 09  .}........}.....
4260: 09 09 09 09 69 66 20 28 46 44 5f 49 53 53 45 54  ....if (FD_ISSET
4270: 28 66 64 2c 20 26 77 66 64 29 29 20 7b 0a 09 09  (fd, &wfd)) {...
4280: 09 09 09 09 09 09 72 65 61 64 5f 72 65 74 20 3d  ......read_ret =
4290: 20 31 3b 0a 0a 09 09 09 09 09 09 09 09 62 72 65   1;..........bre
42a0: 61 6b 3b 0a 09 09 09 09 09 09 09 7d 0a 09 09 09  ak;........}....
42b0: 09 09 09 7d 0a 0a 09 09 09 09 09 09 69 66 20 28  ...}........if (
42c0: 72 65 61 64 5f 72 65 74 20 3c 3d 20 30 29 20 7b  read_ret <= 0) {
42d0: 0a 09 09 09 09 09 09 09 62 72 65 61 6b 3b 0a 09  ........break;..
42e0: 09 09 09 09 09 7d 0a 09 09 09 09 09 7d 20 65 6c  .....}......} el
42f0: 73 65 20 7b 0a 09 09 09 09 09 09 62 72 65 61 6b  se {.......break
4300: 3b 0a 09 09 09 09 09 7d 0a 23 65 6c 73 65 0a 09  ;......}.#else..
4310: 09 09 09 09 62 72 65 61 6b 3b 0a 23 65 6e 64 69  ....break;.#endi
4320: 66 0a 09 09 09 09 7d 0a 0a 09 09 09 09 73 65 6e  f.....}......sen
4330: 64 66 69 6c 65 5f 6c 65 6e 20 2d 3d 20 73 65 6e  dfile_len -= sen
4340: 64 66 69 6c 65 5f 72 65 74 3b 0a 09 09 09 09 73  dfile_ret;.....s
4350: 65 6e 64 66 69 6c 65 5f 73 65 6e 74 20 2b 3d 20  endfile_sent += 
4360: 73 65 6e 64 66 69 6c 65 5f 72 65 74 3b 0a 09 09  sendfile_ret;...
4370: 09 09 69 66 20 28 73 65 6e 64 66 69 6c 65 5f 6c  ..if (sendfile_l
4380: 65 6e 20 3d 3d 20 30 29 20 7b 0a 09 09 09 09 09  en == 0) {......
4390: 62 72 65 61 6b 3b 0a 09 09 09 09 7d 0a 09 09 09  break;.....}....
43a0: 7d 0a 0a 09 09 09 66 69 6c 65 64 5f 6c 6f 67 5f  }.....filed_log_
43b0: 6d 73 67 28 22 53 45 4e 44 5f 43 4f 4d 50 4c 45  msg("SEND_COMPLE
43c0: 54 45 20 53 54 41 54 55 53 3d 25 73 20 46 49 4c  TE STATUS=%s FIL
43d0: 45 5f 46 44 3d 25 69 20 46 44 3d 25 69 20 42 59  E_FD=%i FD=%i BY
43e0: 54 45 53 3d 25 6c 6c 75 20 42 59 54 45 53 5f 53  TES=%llu BYTES_S
43f0: 45 4e 54 3d 25 6c 6c 75 22 2c 0a 09 09 09 09 28  ENT=%llu",.....(
4400: 73 65 6e 64 66 69 6c 65 5f 73 65 6e 74 20 3d 3d  sendfile_sent ==
4410: 20 72 65 71 75 65 73 74 2d 3e 68 65 61 64 65 72   request->header
4420: 73 2e 72 61 6e 67 65 2e 6c 65 6e 67 74 68 29 20  s.range.length) 
4430: 3f 20 22 4f 4b 22 20 3a 20 22 50 41 52 54 49 41  ? "OK" : "PARTIA
4440: 4c 22 2c 0a 09 09 09 09 66 69 6c 65 69 6e 66 6f  L",.....fileinfo
4450: 2d 3e 66 64 2c 0a 09 09 09 09 66 64 2c 0a 09 09  ->fd,.....fd,...
4460: 09 09 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67  ..(unsigned long
4470: 20 6c 6f 6e 67 29 20 72 65 71 75 65 73 74 2d 3e   long) request->
4480: 68 65 61 64 65 72 73 2e 72 61 6e 67 65 2e 6c 65  headers.range.le
4490: 6e 67 74 68 2c 0a 09 09 09 09 28 75 6e 73 69 67  ngth,.....(unsig
44a0: 6e 65 64 20 6c 6f 6e 67 20 6c 6f 6e 67 29 20 73  ned long long) s
44b0: 65 6e 64 66 69 6c 65 5f 73 65 6e 74 0a 09 09 09  endfile_sent....
44c0: 29 3b 0a 09 09 7d 0a 0a 09 09 63 6c 6f 73 65 28  );...}....close(
44d0: 66 69 6c 65 69 6e 66 6f 2d 3e 66 64 29 3b 0a 0a  fileinfo->fd);..
44e0: 09 09 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28  ..filed_log_msg(
44f0: 22 43 4c 4f 53 45 5f 46 49 4c 45 20 46 44 3d 25  "CLOSE_FILE FD=%
4500: 69 22 2c 20 66 64 29 3b 0a 09 7d 0a 0a 09 66 69  i", fd);..}...fi
4510: 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 43 4c 4f  led_log_msg("CLO
4520: 53 45 5f 43 4f 4e 4e 45 43 54 49 4f 4e 20 46 44  SE_CONNECTION FD
4530: 3d 25 69 22 2c 20 66 64 29 3b 0a 0a 09 66 63 6c  =%i", fd);...fcl
4540: 6f 73 65 28 66 70 29 3b 0a 0a 09 72 65 74 75 72  ose(fp);...retur
4550: 6e 3b 0a 7d 0a 0a 2f 2a 20 48 61 6e 64 6c 65 20  n;.}../* Handle 
4560: 69 6e 63 6f 6d 69 6e 67 20 63 6f 6e 6e 65 63 74  incoming connect
4570: 69 6f 6e 73 20 2a 2f 0a 73 74 61 74 69 63 20 76  ions */.static v
4580: 6f 69 64 20 2a 66 69 6c 65 64 5f 77 6f 72 6b 65  oid *filed_worke
4590: 72 5f 74 68 72 65 61 64 28 76 6f 69 64 20 2a 61  r_thread(void *a
45a0: 72 67 5f 76 29 20 7b 0a 09 73 74 72 75 63 74 20  rg_v) {..struct 
45b0: 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72  filed_worker_thr
45c0: 65 61 64 5f 61 72 67 73 20 2a 61 72 67 3b 0a 09  ead_args *arg;..
45d0: 73 74 72 75 63 74 20 66 69 6c 65 64 5f 68 74 74  struct filed_htt
45e0: 70 5f 72 65 71 75 65 73 74 20 72 65 71 75 65 73  p_request reques
45f0: 74 3b 0a 09 73 74 72 75 63 74 20 73 6f 63 6b 61  t;..struct socka
4600: 64 64 72 5f 69 6e 36 20 61 64 64 72 3b 0a 09 63  ddr_in6 addr;..c
4610: 68 61 72 20 6c 6f 67 62 75 66 5f 69 70 5b 31 32  har logbuf_ip[12
4620: 38 5d 3b 0a 09 73 6f 63 6b 6c 65 6e 5f 74 20 61  8];..socklen_t a
4630: 64 64 72 6c 65 6e 3b 0a 09 69 6e 74 20 66 61 69  ddrlen;..int fai
4640: 6c 75 72 65 5f 63 6f 75 6e 74 20 3d 20 30 2c 20  lure_count = 0, 
4650: 6d 61 78 5f 66 61 69 6c 75 72 65 5f 63 6f 75 6e  max_failure_coun
4660: 74 20 3d 20 46 49 4c 45 44 5f 4d 41 58 5f 46 41  t = FILED_MAX_FA
4670: 49 4c 55 52 45 5f 43 4f 55 4e 54 3b 0a 09 69 6e  ILURE_COUNT;..in
4680: 74 20 6d 61 73 74 65 72 5f 66 64 2c 20 66 64 3b  t master_fd, fd;
4690: 0a 0a 09 2f 2a 20 52 65 61 64 20 61 72 67 75 6d  .../* Read argum
46a0: 65 6e 74 73 20 2a 2f 0a 09 61 72 67 20 3d 20 61  ents */..arg = a
46b0: 72 67 5f 76 3b 0a 0a 09 6d 61 73 74 65 72 5f 66  rg_v;...master_f
46c0: 64 20 3d 20 61 72 67 2d 3e 66 64 3b 0a 0a 09 77  d = arg->fd;...w
46d0: 68 69 6c 65 20 28 31 29 20 7b 0a 09 09 2f 2a 20  hile (1) {.../* 
46e0: 46 61 69 6c 75 72 65 20 6c 6f 6f 70 20 70 72 65  Failure loop pre
46f0: 76 65 6e 74 69 6f 6e 20 2a 2f 0a 09 09 69 66 20  vention */...if 
4700: 28 66 61 69 6c 75 72 65 5f 63 6f 75 6e 74 20 3e  (failure_count >
4710: 20 6d 61 78 5f 66 61 69 6c 75 72 65 5f 63 6f 75   max_failure_cou
4720: 6e 74 29 20 7b 0a 09 09 09 62 72 65 61 6b 3b 0a  nt) {....break;.
4730: 09 09 7d 0a 0a 09 09 2f 2a 20 41 63 63 65 70 74  ..}..../* Accept
4740: 20 61 20 6e 65 77 20 63 6c 69 65 6e 74 20 2a 2f   a new client */
4750: 0a 09 09 61 64 64 72 6c 65 6e 20 3d 20 73 69 7a  ...addrlen = siz
4760: 65 6f 66 28 61 64 64 72 29 3b 0a 09 09 66 64 20  eof(addr);...fd 
4770: 3d 20 61 63 63 65 70 74 28 6d 61 73 74 65 72 5f  = accept(master_
4780: 66 64 2c 20 28 73 74 72 75 63 74 20 73 6f 63 6b  fd, (struct sock
4790: 61 64 64 72 20 2a 29 20 26 61 64 64 72 2c 20 26  addr *) &addr, &
47a0: 61 64 64 72 6c 65 6e 29 3b 0a 0a 09 09 2f 2a 0a  addrlen);..../*.
47b0: 09 09 20 2a 20 49 66 20 77 65 20 66 61 69 6c 2c  .. * If we fail,
47c0: 20 6d 61 6b 65 20 61 20 6e 6f 74 65 20 6f 66 20   make a note of 
47d0: 69 74 20 73 6f 20 77 65 20 64 6f 6e 27 74 20 67  it so we don't g
47e0: 6f 20 69 6e 74 6f 20 61 20 6c 6f 6f 70 20 6f 66  o into a loop of
47f0: 0a 09 09 20 2a 20 61 63 63 65 70 74 28 29 20 66  ... * accept() f
4800: 61 69 6c 69 6e 67 0a 09 09 20 2a 2f 0a 09 09 69  ailing... */...i
4810: 66 20 28 66 64 20 3c 20 30 29 20 7b 0a 09 09 09  f (fd < 0) {....
4820: 2f 2a 20 4c 6f 67 20 74 68 65 20 6e 65 77 20 63  /* Log the new c
4830: 6f 6e 6e 65 63 74 69 6f 6e 20 2a 2f 0a 09 09 09  onnection */....
4840: 66 69 6c 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 41  filed_log_msg("A
4850: 43 43 45 50 54 5f 46 41 49 4c 45 44 22 29 3b 0a  CCEPT_FAILED");.
4860: 0a 09 09 09 66 61 69 6c 75 72 65 5f 63 6f 75 6e  ....failure_coun
4870: 74 2b 2b 3b 0a 0a 09 09 09 63 6f 6e 74 69 6e 75  t++;.....continu
4880: 65 3b 0a 09 09 7d 0a 0a 09 09 2f 2a 20 4c 6f 67  e;...}..../* Log
4890: 20 74 68 65 20 6e 65 77 20 63 6f 6e 6e 65 63 74   the new connect
48a0: 69 6f 6e 20 2a 2f 0a 09 09 66 69 6c 65 64 5f 6c  ion */...filed_l
48b0: 6f 67 5f 6d 73 67 28 22 4e 45 57 5f 43 4f 4e 4e  og_msg("NEW_CONN
48c0: 45 43 54 49 4f 4e 20 53 52 43 5f 41 44 44 52 3d  ECTION SRC_ADDR=
48d0: 25 73 20 53 52 43 5f 50 4f 52 54 3d 25 6c 75 20  %s SRC_PORT=%lu 
48e0: 46 44 3d 25 69 22 2c 0a 09 09 09 69 6e 65 74 5f  FD=%i",....inet_
48f0: 6e 74 6f 70 28 41 46 5f 49 4e 45 54 36 2c 20 26  ntop(AF_INET6, &
4900: 61 64 64 72 2e 73 69 6e 36 5f 61 64 64 72 2c 20  addr.sin6_addr, 
4910: 6c 6f 67 62 75 66 5f 69 70 2c 20 73 69 7a 65 6f  logbuf_ip, sizeo
4920: 66 28 6c 6f 67 62 75 66 5f 69 70 29 29 20 3f 20  f(logbuf_ip)) ? 
4930: 6c 6f 67 62 75 66 5f 69 70 20 3a 20 22 3c 75 6e  logbuf_ip : "<un
4940: 6b 6e 6f 77 6e 3e 22 2c 0a 09 09 09 28 75 6e 73  known>",....(uns
4950: 69 67 6e 65 64 20 6c 6f 6e 67 29 20 61 64 64 72  igned long) addr
4960: 2e 73 69 6e 36 5f 70 6f 72 74 2c 0a 09 09 09 66  .sin6_port,....f
4970: 64 0a 09 09 29 3b 0a 0a 09 09 2f 2a 20 52 65 73  d...);..../* Res
4980: 65 74 20 66 61 69 6c 75 72 65 20 63 6f 75 6e 74  et failure count
4990: 2a 2f 0a 09 09 66 61 69 6c 75 72 65 5f 63 6f 75  */...failure_cou
49a0: 6e 74 20 3d 20 30 3b 0a 0a 09 09 2f 2a 20 48 61  nt = 0;..../* Ha
49b0: 6e 64 6c 65 20 73 6f 63 6b 65 74 20 2a 2f 0a 09  ndle socket */..
49c0: 09 66 69 6c 65 64 5f 68 61 6e 64 6c 65 5f 63 6c  .filed_handle_cl
49d0: 69 65 6e 74 28 66 64 2c 20 26 72 65 71 75 65 73  ient(fd, &reques
49e0: 74 29 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 70 6f  t);..}.../* Repo
49f0: 72 74 20 65 72 72 6f 72 20 2a 2f 0a 09 66 69 6c  rt error */..fil
4a00: 65 64 5f 6c 6f 67 5f 6d 73 67 28 22 54 48 52 45  ed_log_msg("THRE
4a10: 41 44 5f 44 49 45 44 20 41 42 4e 4f 52 4d 41 4c  AD_DIED ABNORMAL
4a20: 22 29 3b 0a 0a 09 72 65 74 75 72 6e 28 4e 55 4c  ");...return(NUL
4a30: 4c 29 3b 0a 0a 09 2f 2a 20 4d 61 6b 65 20 63 6f  L);.../* Make co
4a40: 6d 70 69 6c 65 72 20 68 61 70 70 79 20 2a 2f 0a  mpiler happy */.
4a50: 09 6c 6f 67 62 75 66 5f 69 70 5b 30 5d 20 3d 20  .logbuf_ip[0] = 
4a60: 27 5c 30 27 3b 0a 09 6c 6f 67 62 75 66 5f 69 70  '\0';..logbuf_ip
4a70: 5b 30 5d 20 3d 20 6c 6f 67 62 75 66 5f 69 70 5b  [0] = logbuf_ip[
4a80: 30 5d 3b 0a 0a 7d 0a 0a 2f 2a 20 43 72 65 61 74  0];..}../* Creat
4a90: 65 20 77 6f 72 6b 65 72 20 74 68 72 65 61 64 73  e worker threads
4aa0: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66   */.static int f
4ab0: 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65  iled_worker_thre
4ac0: 61 64 73 5f 69 6e 69 74 28 69 6e 74 20 66 64 2c  ads_init(int fd,
4ad0: 20 69 6e 74 20 74 68 72 65 61 64 5f 63 6f 75 6e   int thread_coun
4ae0: 74 29 20 7b 0a 09 73 74 72 75 63 74 20 66 69 6c  t) {..struct fil
4af0: 65 64 5f 77 6f 72 6b 65 72 5f 74 68 72 65 61 64  ed_worker_thread
4b00: 5f 61 72 67 73 20 2a 61 72 67 3b 0a 09 70 74 68  _args *arg;..pth
4b10: 72 65 61 64 5f 74 20 74 68 72 65 61 64 69 64 3b  read_t threadid;
4b20: 0a 09 69 6e 74 20 70 74 68 72 65 61 64 5f 72 65  ..int pthread_re
4b30: 74 3b 0a 09 69 6e 74 20 69 3b 0a 0a 09 66 6f 72  t;..int i;...for
4b40: 20 28 69 20 3d 20 30 3b 20 69 20 3c 20 74 68 72   (i = 0; i < thr
4b50: 65 61 64 5f 63 6f 75 6e 74 3b 20 69 2b 2b 29 20  ead_count; i++) 
4b60: 7b 0a 09 09 61 72 67 20 3d 20 6d 61 6c 6c 6f 63  {...arg = malloc
4b70: 28 73 69 7a 65 6f 66 28 2a 61 72 67 29 29 3b 0a  (sizeof(*arg));.
4b80: 0a 09 09 61 72 67 2d 3e 66 64 20 3d 20 66 64 3b  ...arg->fd = fd;
4b90: 0a 0a 09 09 70 74 68 72 65 61 64 5f 72 65 74 20  ....pthread_ret 
4ba0: 3d 20 70 74 68 72 65 61 64 5f 63 72 65 61 74 65  = pthread_create
4bb0: 28 26 74 68 72 65 61 64 69 64 2c 20 4e 55 4c 4c  (&threadid, NULL
4bc0: 2c 20 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f 74  , filed_worker_t
4bd0: 68 72 65 61 64 2c 20 61 72 67 29 3b 0a 09 09 69  hread, arg);...i
4be0: 66 20 28 70 74 68 72 65 61 64 5f 72 65 74 20 21  f (pthread_ret !
4bf0: 3d 20 30 29 20 7b 0a 09 09 09 72 65 74 75 72 6e  = 0) {....return
4c00: 28 2d 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 72  (-1);...}..}...r
4c10: 65 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20  eturn(0);.}../* 
4c20: 44 69 73 70 6c 61 79 20 68 65 6c 70 20 2a 2f 0a  Display help */.
4c30: 73 74 61 74 69 63 20 76 6f 69 64 20 66 69 6c 65  static void file
4c40: 64 5f 70 72 69 6e 74 5f 68 65 6c 70 28 46 49 4c  d_print_help(FIL
4c50: 45 20 2a 6f 75 74 70 75 74 2c 20 69 6e 74 20 6c  E *output, int l
4c60: 6f 6e 67 5f 68 65 6c 70 2c 20 63 6f 6e 73 74 20  ong_help, const 
4c70: 63 68 61 72 20 2a 65 78 74 72 61 29 20 7b 0a 09  char *extra) {..
4c80: 69 66 20 28 65 78 74 72 61 29 20 7b 0a 09 09 66  if (extra) {...f
4c90: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22  printf(output, "
4ca0: 25 73 5c 6e 22 2c 20 65 78 74 72 61 29 3b 0a 09  %s\n", extra);..
4cb0: 7d 0a 0a 09 66 70 72 69 6e 74 66 28 6f 75 74 70  }...fprintf(outp
4cc0: 75 74 2c 20 22 55 73 61 67 65 3a 20 66 69 6c 65  ut, "Usage: file
4cd0: 64 20 5b 3c 6f 70 74 69 6f 6e 73 3e 5d 5c 6e 22  d [<options>]\n"
4ce0: 29 3b 0a 09 66 70 72 69 6e 74 66 28 6f 75 74 70  );..fprintf(outp
4cf0: 75 74 2c 20 22 20 20 4f 70 74 69 6f 6e 73 3a 5c  ut, "  Options:\
4d00: 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 6f 75  n");..fprintf(ou
4d10: 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d 68 2c  tput, "      -h,
4d20: 20 2d 2d 68 65 6c 70 5c 6e 22 29 3b 0a 09 66 70   --help\n");..fp
4d30: 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20  rintf(output, " 
4d40: 20 20 20 20 20 2d 64 2c 20 2d 2d 64 61 65 6d 6f       -d, --daemo
4d50: 6e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  n\n");..fprintf(
4d60: 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d  output, "      -
4d70: 76 2c 20 2d 2d 76 65 72 73 69 6f 6e 5c 6e 22 29  v, --version\n")
4d80: 3b 0a 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75  ;..fprintf(outpu
4d90: 74 2c 20 22 20 20 20 20 20 20 2d 62 20 3c 61 64  t, "      -b <ad
4da0: 64 72 65 73 73 3e 2c 20 2d 2d 62 69 6e 64 20 3c  dress>, --bind <
4db0: 61 64 64 72 65 73 73 3e 5c 6e 22 29 3b 0a 09 66  address>\n");..f
4dc0: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22  printf(output, "
4dd0: 20 20 20 20 20 20 2d 70 20 3c 70 6f 72 74 3e 2c        -p <port>,
4de0: 20 2d 2d 70 6f 72 74 20 3c 70 6f 72 74 3e 5c 6e   --port <port>\n
4df0: 22 29 3b 0a 09 66 70 72 69 6e 74 66 28 6f 75 74  ");..fprintf(out
4e00: 70 75 74 2c 20 22 20 20 20 20 20 20 2d 74 20 3c  put, "      -t <
4e10: 63 6f 75 6e 74 3e 2c 20 2d 2d 74 68 72 65 61 64  count>, --thread
4e20: 73 20 3c 63 6f 75 6e 74 3e 5c 6e 22 29 3b 0a 09  s <count>\n");..
4e30: 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20  fprintf(output, 
4e40: 22 20 20 20 20 20 20 2d 63 20 3c 65 6e 74 72 69  "      -c <entri
4e50: 65 73 3e 2c 20 2d 2d 63 61 63 68 65 20 3c 65 6e  es>, --cache <en
4e60: 74 72 69 65 73 3e 5c 6e 22 29 3b 0a 09 66 70 72  tries>\n");..fpr
4e70: 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20  intf(output, "  
4e80: 20 20 20 20 2d 6c 20 3c 66 69 6c 65 3e 2c 20 2d      -l <file>, -
4e90: 2d 6c 6f 67 20 3c 66 69 6c 65 3e 5c 6e 22 29 3b  -log <file>\n");
4ea0: 0a 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
4eb0: 2c 20 22 20 20 20 20 20 20 2d 75 20 3c 75 73 65  , "      -u <use
4ec0: 72 3e 2c 20 2d 2d 75 73 65 72 20 3c 75 73 65 72  r>, --user <user
4ed0: 3e 5c 6e 22 29 3b 0a 09 66 70 72 69 6e 74 66 28  >\n");..fprintf(
4ee0: 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d  output, "      -
4ef0: 72 20 3c 64 69 72 65 63 74 6f 72 79 3e 2c 20 2d  r <directory>, -
4f00: 2d 72 6f 6f 74 20 3c 64 69 72 65 63 74 6f 72 79  -root <directory
4f10: 3e 5c 6e 22 29 3b 0a 0a 09 69 66 20 28 6c 6f 6e  >\n");...if (lon
4f20: 67 5f 68 65 6c 70 29 20 7b 0a 09 09 66 70 72 69  g_help) {...fpri
4f30: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 5c 6e 22  ntf(output, "\n"
4f40: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74  );...fprintf(out
4f50: 70 75 74 2c 20 22 20 20 55 73 61 67 65 3a 5c 6e  put, "  Usage:\n
4f60: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75  ");...fprintf(ou
4f70: 74 70 75 74 2c 20 22 20 20 20 20 20 20 2d 68 20  tput, "      -h 
4f80: 28 6f 72 20 2d 2d 68 65 6c 70 29 20 70 72 69 6e  (or --help) prin
4f90: 74 73 20 74 68 69 73 20 75 73 61 67 65 20 69 6e  ts this usage in
4fa0: 66 6f 72 6d 61 74 69 6f 6e 2e 5c 6e 22 29 3b 0a  formation.\n");.
4fb0: 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
4fc0: 2c 20 22 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  , "\n");...fprin
4fd0: 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20  tf(output, "    
4fe0: 20 20 2d 64 20 28 6f 72 20 2d 2d 64 61 65 6d 6f    -d (or --daemo
4ff0: 6e 29 20 69 6e 73 74 72 75 63 74 73 20 66 69 6c  n) instructs fil
5000: 65 64 20 74 6f 20 62 65 63 6f 6d 65 20 61 20 64  ed to become a d
5010: 61 65 6d 6f 6e 20 61 66 74 65 72 20 69 6e 69 74  aemon after init
5020: 69 61 6c 69 7a 69 6e 67 5c 6e 22 29 3b 0a 09 09  ializing\n");...
5030: 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20  fprintf(output, 
5040: 22 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  "               
5050: 20 20 20 20 20 20 20 20 74 68 65 20 6c 69 73 74          the list
5060: 65 6e 69 6e 67 20 54 43 50 20 73 6f 63 6b 65 74  ening TCP socket
5070: 20 61 6e 64 20 6c 6f 67 20 66 69 6c 65 73 2e 5c   and log files.\
5080: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f  n");...fprintf(o
5090: 75 74 70 75 74 2c 20 22 5c 6e 22 29 3b 0a 09 09  utput, "\n");...
50a0: 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20  fprintf(output, 
50b0: 22 20 20 20 20 20 20 2d 76 20 28 6f 72 20 2d 2d  "      -v (or --
50c0: 76 65 72 73 69 6f 6e 29 20 69 6e 73 74 72 75 63  version) instruc
50d0: 74 73 20 66 69 6c 65 64 20 70 72 69 6e 74 20 6f  ts filed print o
50e0: 75 74 20 74 68 65 20 76 65 72 73 69 6f 6e 20 6e  ut the version n
50f0: 75 6d 62 65 72 20 61 6e 64 20 65 78 69 74 2e 5c  umber and exit.\
5100: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f  n");...fprintf(o
5110: 75 74 70 75 74 2c 20 22 5c 6e 22 29 3b 0a 09 09  utput, "\n");...
5120: 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20  fprintf(output, 
5130: 22 20 20 20 20 20 20 2d 62 20 28 6f 72 20 2d 2d  "      -b (or --
5140: 62 69 6e 64 29 20 73 70 65 63 69 66 69 65 73 20  bind) specifies 
5150: 74 68 65 20 61 64 64 72 65 73 73 20 74 6f 20 6c  the address to l
5160: 69 73 74 65 6e 20 66 6f 72 20 69 6e 63 6f 6d 69  isten for incomi
5170: 6e 67 20 48 54 54 50 5c 6e 22 29 3b 0a 09 09 66  ng HTTP\n");...f
5180: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22  printf(output, "
5190: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
51a0: 20 20 20 20 20 72 65 71 75 65 73 74 73 20 6f 6e       requests on
51b0: 2e 20 20 54 68 65 20 64 65 66 61 75 6c 74 20 76  .  The default v
51c0: 61 6c 75 65 20 69 73 20 5c 22 25 73 5c 22 2e 5c  alue is \"%s\".\
51d0: 6e 22 2c 20 42 49 4e 44 5f 41 44 44 52 29 3b 0a  n", BIND_ADDR);.
51e0: 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
51f0: 2c 20 22 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  , "\n");...fprin
5200: 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20  tf(output, "    
5210: 20 20 2d 70 20 28 6f 72 20 2d 2d 70 6f 72 74 29    -p (or --port)
5220: 20 73 70 65 63 69 66 69 65 73 20 74 68 65 20 54   specifies the T
5230: 43 50 20 70 6f 72 74 20 6e 75 6d 62 65 72 20 74  CP port number t
5240: 6f 20 6c 69 73 74 65 6e 20 66 6f 72 20 69 6e 63  o listen for inc
5250: 6f 6d 69 6e 67 20 48 54 54 50 5c 6e 22 29 3b 0a  oming HTTP\n");.
5260: 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
5270: 2c 20 22 20 20 20 20 20 20 20 20 20 20 20 20 20  , "             
5280: 20 20 20 20 20 20 20 20 72 65 71 75 65 73 74 73          requests
5290: 20 6f 6e 2e 20 20 54 68 65 20 64 65 66 61 75 6c   on.  The defaul
52a0: 74 20 69 73 20 25 75 2e 5c 6e 22 2c 20 28 75 6e  t is %u.\n", (un
52b0: 73 69 67 6e 65 64 20 69 6e 74 29 20 50 4f 52 54  signed int) PORT
52c0: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74  );...fprintf(out
52d0: 70 75 74 2c 20 22 5c 6e 22 29 3b 0a 09 09 66 70  put, "\n");...fp
52e0: 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20  rintf(output, " 
52f0: 20 20 20 20 20 2d 74 20 28 6f 72 20 2d 2d 74 68       -t (or --th
5300: 72 65 61 64 73 29 20 73 70 65 63 69 66 69 65 73  reads) specifies
5310: 20 74 68 65 20 6e 75 6d 62 65 72 20 6f 66 20 77   the number of w
5320: 6f 72 6b 65 72 20 74 68 72 65 61 64 73 20 74 6f  orker threads to
5330: 20 63 72 65 61 74 65 2e 20 45 61 63 68 5c 6e 22   create. Each\n"
5340: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74  );...fprintf(out
5350: 70 75 74 2c 20 22 20 20 20 20 20 20 20 20 20 20  put, "          
5360: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 77 6f                wo
5370: 72 6b 65 72 20 74 68 72 65 61 64 20 63 61 6e 20  rker thread can 
5380: 73 65 72 76 69 63 65 20 6f 6e 65 20 63 6f 6e 63  service one conc
5390: 75 72 72 65 6e 74 20 48 54 54 50 20 73 65 73 73  urrent HTTP sess
53a0: 69 6f 6e 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69  ion.\n");...fpri
53b0: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20  ntf(output, "   
53c0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
53d0: 20 20 20 20 20 54 68 75 73 20 74 68 65 20 6e 75       Thus the nu
53e0: 6d 62 65 72 20 6f 66 20 74 68 72 65 61 64 73 20  mber of threads 
53f0: 63 72 65 61 74 65 64 20 77 69 6c 6c 20 64 65 74  created will det
5400: 65 72 6d 69 6e 65 20 68 6f 77 5c 6e 22 29 3b 0a  ermine how\n");.
5410: 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
5420: 2c 20 22 20 20 20 20 20 20 20 20 20 20 20 20 20  , "             
5430: 20 20 20 20 20 20 20 20 20 20 20 6d 61 6e 79 20             many 
5440: 73 69 6d 75 6c 74 61 6e 65 6f 75 73 20 74 72 61  simultaneous tra
5450: 6e 73 66 65 72 73 20 77 69 6c 6c 20 62 65 20 70  nsfers will be p
5460: 6f 73 73 69 62 6c 65 2e 20 54 68 65 5c 6e 22 29  ossible. The\n")
5470: 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70  ;...fprintf(outp
5480: 75 74 2c 20 22 20 20 20 20 20 20 20 20 20 20 20  ut, "           
5490: 20 20 20 20 20 20 20 20 20 20 20 20 20 64 65 66               def
54a0: 61 75 6c 74 20 69 73 20 25 6c 75 2e 5c 6e 22 2c  ault is %lu.\n",
54b0: 20 28 75 6e 73 69 67 6e 65 64 20 6c 6f 6e 67 29   (unsigned long)
54c0: 20 54 48 52 45 41 44 5f 43 4f 55 4e 54 29 3b 0a   THREAD_COUNT);.
54d0: 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
54e0: 2c 20 22 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  , "\n");...fprin
54f0: 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20  tf(output, "    
5500: 20 20 2d 63 20 28 6f 72 20 2d 2d 63 61 63 68 65    -c (or --cache
5510: 29 20 73 70 65 63 69 66 69 65 73 20 74 68 65 20  ) specifies the 
5520: 6e 75 6d 62 65 72 20 6f 66 20 66 69 6c 65 20 69  number of file i
5530: 6e 66 6f 72 6d 61 74 69 6f 6e 20 63 61 63 68 65  nformation cache
5540: 20 65 6e 74 72 69 65 73 5c 6e 22 29 3b 0a 09 09   entries\n");...
5550: 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20  fprintf(output, 
5560: 22 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  "               
5570: 20 20 20 20 20 20 20 74 6f 20 61 6c 6c 6f 63 61         to alloca
5580: 74 65 2e 20 20 45 61 63 68 20 63 61 63 68 65 20  te.  Each cache 
5590: 65 6e 74 72 79 20 68 6f 6c 64 73 20 66 69 6c 65  entry holds file
55a0: 20 69 6e 66 6f 72 6d 61 74 69 6f 6e 20 61 73 5c   information as\
55b0: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f  n");...fprintf(o
55c0: 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 20 20  utput, "        
55d0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 77 65                we
55e0: 6c 6c 20 61 73 20 61 6e 20 6f 70 65 6e 20 66 69  ll as an open fi
55f0: 6c 65 20 64 65 73 63 72 69 70 74 6f 72 20 74 6f  le descriptor to
5600: 20 74 68 65 20 66 69 6c 65 2c 20 73 6f 20 72 65   the file, so re
5610: 73 6f 75 72 63 65 5c 6e 22 29 3b 0a 09 09 66 70  source\n");...fp
5620: 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20  rintf(output, " 
5630: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5640: 20 20 20 20 20 6c 69 6d 69 74 73 20 28 69 2e 65       limits (i.e
5650: 2e 2c 20 75 6c 69 6d 69 74 29 20 73 68 6f 75 6c  ., ulimit) shoul
5660: 64 20 62 65 20 63 6f 6e 73 69 64 65 72 65 64 2e  d be considered.
5670: 20 20 54 68 69 73 20 73 68 6f 75 6c 64 5c 6e 22    This should\n"
5680: 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74  );...fprintf(out
5690: 70 75 74 2c 20 22 20 20 20 20 20 20 20 20 20 20  put, "          
56a0: 20 20 20 20 20 20 20 20 20 20 20 20 62 65 20 61              be a
56b0: 20 70 72 69 6d 65 20 6e 75 6d 62 65 72 20 66 6f   prime number fo
56c0: 72 20 69 64 65 61 6c 20 75 73 65 20 77 69 74 68  r ideal use with
56d0: 20 74 68 65 20 6c 6f 6f 6b 75 70 20 6d 65 74 68   the lookup meth
56e0: 6f 64 2e 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  od.\n");...fprin
56f0: 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20  tf(output, "    
5700: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5710: 20 20 54 68 65 20 64 65 66 61 75 6c 74 20 69 73    The default is
5720: 20 25 6c 75 2e 5c 6e 22 2c 20 28 75 6e 73 69 67   %lu.\n", (unsig
5730: 6e 65 64 20 6c 6f 6e 67 29 20 43 41 43 48 45 5f  ned long) CACHE_
5740: 53 49 5a 45 29 3b 0a 09 09 66 70 72 69 6e 74 66  SIZE);...fprintf
5750: 28 6f 75 74 70 75 74 2c 20 22 5c 6e 22 29 3b 0a  (output, "\n");.
5760: 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
5770: 2c 20 22 20 20 20 20 20 20 2d 6c 20 28 6f 72 20  , "      -l (or 
5780: 2d 2d 6c 6f 67 29 20 73 70 65 63 69 66 69 65 73  --log) specifies
5790: 20 61 20 66 69 6c 65 6e 61 6d 65 20 74 6f 20 6f   a filename to o
57a0: 70 65 6e 20 66 6f 72 20 77 72 69 74 69 6e 67 20  pen for writing 
57b0: 6c 6f 67 20 65 6e 74 72 69 65 73 2e 20 20 4c 6f  log entries.  Lo
57c0: 67 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66  g\n");...fprintf
57d0: 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20 20 20  (output, "      
57e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 65 6e                en
57f0: 74 72 69 65 73 20 61 72 65 20 6d 61 64 65 20 66  tries are made f
5800: 6f 72 20 76 61 72 69 6f 75 73 20 73 74 61 67 65  or various stage
5810: 73 20 69 6e 20 74 72 61 6e 73 66 65 72 69 6e 67  s in transfering
5820: 20 66 69 6c 65 73 2e 5c 6e 22 29 3b 0a 09 09 66   files.\n");...f
5830: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22  printf(output, "
5840: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5850: 20 20 20 20 54 68 65 20 6c 6f 67 20 66 69 6c 65      The log file
5860: 20 69 73 20 6f 70 65 6e 65 64 20 62 65 66 6f 72   is opened befor
5870: 65 20 73 77 69 74 63 68 69 6e 67 20 75 73 65 72  e switching user
5880: 73 20 28 73 65 65 20 5c 22 2d 75 5c 22 29 5c 6e  s (see \"-u\")\n
5890: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75  ");...fprintf(ou
58a0: 74 70 75 74 2c 20 22 20 20 20 20 20 20 20 20 20  tput, "         
58b0: 20 20 20 20 20 20 20 20 20 20 20 61 6e 64 20 72             and r
58c0: 6f 6f 74 20 64 69 72 65 63 74 6f 72 69 65 73 20  oot directories 
58d0: 28 73 65 65 20 5c 22 2d 72 5c 22 29 2e 20 20 54  (see \"-r\").  T
58e0: 68 65 20 6c 6f 67 20 66 69 6c 65 20 69 73 20 6e  he log file is n
58f0: 65 76 65 72 5c 6e 22 29 3b 0a 09 09 66 70 72 69  ever\n");...fpri
5900: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20  ntf(output, "   
5910: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5920: 20 63 6c 6f 73 65 64 20 73 6f 20 6c 6f 67 20 72   closed so log r
5930: 6f 74 61 74 69 6f 6e 20 77 69 74 68 6f 75 74 20  otation without 
5940: 73 74 6f 70 70 69 6e 67 20 74 68 65 20 64 61 65  stopping the dae
5950: 6d 6f 6e 20 69 73 20 77 69 6c 6c 5c 6e 22 29 3b  mon is will\n");
5960: 0a 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75  ...fprintf(outpu
5970: 74 2c 20 22 20 20 20 20 20 20 20 20 20 20 20 20  t, "            
5980: 20 20 20 20 20 20 20 20 6e 6f 74 20 77 6f 72 6b          not work
5990: 2e 20 20 54 68 65 20 76 61 6c 75 65 20 6f 66 20  .  The value of 
59a0: 5c 22 2d 5c 22 20 69 6e 64 69 63 61 74 65 73 20  \"-\" indicates 
59b0: 74 68 61 74 20 73 74 61 6e 64 61 72 64 20 6f 75  that standard ou
59c0: 74 70 75 74 5c 6e 22 29 3b 0a 09 09 66 70 72 69  tput\n");...fpri
59d0: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20  ntf(output, "   
59e0: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
59f0: 20 73 68 6f 75 6c 64 20 62 65 20 75 73 65 64 20   should be used 
5a00: 66 6f 72 20 6c 6f 67 67 69 6e 67 2e 20 20 54 68  for logging.  Th
5a10: 65 20 64 65 66 61 75 6c 74 20 69 73 20 5c 22 25  e default is \"%
5a20: 73 5c 22 2e 5c 6e 22 2c 20 4c 4f 47 5f 46 49 4c  s\".\n", LOG_FIL
5a30: 45 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75  E);...fprintf(ou
5a40: 74 70 75 74 2c 20 22 5c 6e 22 29 3b 0a 09 09 66  tput, "\n");...f
5a50: 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20 22  printf(output, "
5a60: 20 20 20 20 20 20 2d 75 20 28 6f 72 20 2d 2d 75        -u (or --u
5a70: 73 65 72 29 20 73 70 65 63 69 66 69 65 73 20 74  ser) specifies t
5a80: 68 65 20 75 73 65 72 20 74 6f 20 73 77 69 74 63  he user to switc
5a90: 68 20 75 73 65 72 20 49 44 73 20 74 6f 20 62 65  h user IDs to be
5aa0: 66 6f 72 65 20 73 65 72 76 69 63 69 6e 67 5c 6e  fore servicing\n
5ab0: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75  ");...fprintf(ou
5ac0: 74 70 75 74 2c 20 22 20 20 20 20 20 20 20 20 20  tput, "         
5ad0: 20 20 20 20 20 20 20 20 20 20 20 20 72 65 71 75              requ
5ae0: 65 73 74 73 2e 20 20 54 68 65 20 64 65 66 61 75  ests.  The defau
5af0: 6c 74 20 69 73 20 6e 6f 74 20 63 68 61 6e 67 65  lt is not change
5b00: 20 75 73 65 72 20 49 44 73 2e 5c 6e 22 29 3b 0a   user IDs.\n");.
5b10: 09 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74  ..fprintf(output
5b20: 2c 20 22 5c 6e 22 29 3b 0a 09 09 66 70 72 69 6e  , "\n");...fprin
5b30: 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20 20  tf(output, "    
5b40: 20 20 2d 72 20 28 6f 72 20 2d 2d 72 6f 6f 74 29    -r (or --root)
5b50: 20 73 70 65 63 69 66 69 65 73 20 74 68 65 20 64   specifies the d
5b60: 69 72 65 63 74 6f 72 79 20 74 6f 20 61 63 74 20  irectory to act 
5b70: 61 73 20 74 68 65 20 72 6f 6f 74 20 64 69 72 65  as the root dire
5b80: 63 74 6f 72 79 20 66 6f 72 5c 6e 22 29 3b 0a 09  ctory for\n");..
5b90: 09 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c  .fprintf(output,
5ba0: 20 22 20 20 20 20 20 20 20 20 20 20 20 20 20 20   "              
5bb0: 20 20 20 20 20 20 20 74 68 65 20 66 69 6c 65 20         the file 
5bc0: 73 65 72 76 65 72 2e 20 20 49 66 20 74 68 69 73  server.  If this
5bd0: 20 6f 70 74 69 6f 6e 20 69 73 20 73 70 65 63 69   option is speci
5be0: 66 69 65 64 2c 20 63 68 72 6f 6f 74 28 32 29 5c  fied, chroot(2)\
5bf0: 6e 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f  n");...fprintf(o
5c00: 75 74 70 75 74 2c 20 22 20 20 20 20 20 20 20 20  utput, "        
5c10: 20 20 20 20 20 20 20 20 20 20 20 20 20 69 73 20               is 
5c20: 63 61 6c 6c 65 64 2e 20 20 54 68 65 20 64 65 66  called.  The def
5c30: 61 75 6c 74 20 69 73 20 6e 6f 74 20 63 68 61 6e  ault is not chan
5c40: 67 65 20 72 6f 6f 74 20 64 69 72 65 63 74 6f 72  ge root director
5c50: 69 65 73 2c 5c 6e 22 29 3b 0a 09 09 66 70 72 69  ies,\n");...fpri
5c60: 6e 74 66 28 6f 75 74 70 75 74 2c 20 22 20 20 20  ntf(output, "   
5c70: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20                  
5c80: 20 20 74 68 61 74 20 69 73 2c 20 74 68 65 20 5c    that is, the \
5c90: 22 2f 5c 22 20 64 69 72 65 63 74 6f 72 79 20 69  "/\" directory i
5ca0: 73 20 73 68 61 72 65 64 20 6f 75 74 2e 20 20 54  s shared out.  T
5cb0: 68 69 73 20 77 69 6c 6c 5c 6e 22 29 3b 0a 09 09  his will\n");...
5cc0: 66 70 72 69 6e 74 66 28 6f 75 74 70 75 74 2c 20  fprintf(output, 
5cd0: 22 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20  "               
5ce0: 20 20 20 20 20 20 6c 69 6b 65 6c 79 20 62 65 20        likely be 
5cf0: 61 20 73 65 63 75 72 69 74 79 20 69 73 73 75 65  a security issue
5d00: 2c 20 73 6f 20 74 68 69 73 20 6f 70 74 69 6f 6e  , so this option
5d10: 20 73 68 6f 75 6c 64 20 61 6c 77 61 79 73 5c 6e   should always\n
5d20: 22 29 3b 0a 09 09 66 70 72 69 6e 74 66 28 6f 75  ");...fprintf(ou
5d30: 74 70 75 74 2c 20 22 20 20 20 20 20 20 20 20 20  tput, "         
5d40: 20 20 20 20 20 20 20 20 20 20 20 20 62 65 20 75              be u
5d50: 73 65 64 2e 5c 6e 22 29 3b 0a 09 7d 0a 0a 09 72  sed.\n");..}...r
5d60: 65 74 75 72 6e 3b 0a 7d 0a 0a 2f 2a 20 41 64 64  eturn;.}../* Add
5d70: 20 61 20 67 65 74 6f 70 74 20 6f 70 74 69 6f 6e   a getopt option
5d80: 20 2a 2f 0a 73 74 61 74 69 63 20 76 6f 69 64 20   */.static void 
5d90: 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e  filed_getopt_lon
5da0: 67 5f 73 65 74 6f 70 74 28 73 74 72 75 63 74 20  g_setopt(struct 
5db0: 6f 70 74 69 6f 6e 20 2a 6f 70 74 2c 20 63 6f 6e  option *opt, con
5dc0: 73 74 20 63 68 61 72 20 2a 6e 61 6d 65 2c 20 69  st char *name, i
5dd0: 6e 74 20 68 61 73 5f 61 72 67 2c 20 69 6e 74 20  nt has_arg, int 
5de0: 76 61 6c 29 20 7b 0a 09 6f 70 74 2d 3e 6e 61 6d  val) {..opt->nam
5df0: 65 20 20 20 20 20 3d 20 6e 61 6d 65 3b 0a 09 6f  e     = name;..o
5e00: 70 74 2d 3e 68 61 73 5f 61 72 67 20 20 3d 20 68  pt->has_arg  = h
5e10: 61 73 5f 61 72 67 3b 0a 09 6f 70 74 2d 3e 66 6c  as_arg;..opt->fl
5e20: 61 67 20 20 20 20 20 3d 20 4e 55 4c 4c 3b 0a 09  ag     = NULL;..
5e30: 6f 70 74 2d 3e 76 61 6c 20 20 20 20 20 20 3d 20  opt->val      = 
5e40: 76 61 6c 3b 0a 0a 09 72 65 74 75 72 6e 3b 0a 7d  val;...return;.}
5e50: 0a 0a 2f 2a 20 52 65 73 6f 6c 76 65 20 61 20 75  ../* Resolve a u
5e60: 73 65 72 6e 61 6d 65 20 74 6f 20 61 20 55 49 44  sername to a UID
5e70: 20 2a 2f 0a 73 74 61 74 69 63 20 69 6e 74 20 66   */.static int f
5e80: 69 6c 65 64 5f 75 73 65 72 5f 6c 6f 6f 6b 75 70  iled_user_lookup
5e90: 28 63 6f 6e 73 74 20 63 68 61 72 20 2a 75 73 65  (const char *use
5ea0: 72 2c 20 75 69 64 5f 74 20 2a 75 73 65 72 5f 69  r, uid_t *user_i
5eb0: 64 29 20 7b 0a 09 63 68 61 72 20 2a 6e 65 78 74  d) {..char *next
5ec0: 3b 0a 09 75 69 64 5f 74 20 75 73 65 72 5f 69 64  ;..uid_t user_id
5ed0: 5f 63 68 65 63 6b 3b 0a 23 69 66 6e 64 65 66 20  _check;.#ifndef 
5ee0: 46 49 4c 45 44 5f 4e 4f 5f 47 45 54 50 57 4e 41  FILED_NO_GETPWNA
5ef0: 4d 0a 09 73 74 72 75 63 74 20 70 61 73 73 77 64  M..struct passwd
5f00: 20 2a 65 6e 74 3b 0a 0a 09 65 6e 74 20 3d 20 67   *ent;...ent = g
5f10: 65 74 70 77 6e 61 6d 28 75 73 65 72 29 3b 0a 09  etpwnam(user);..
5f20: 69 66 20 28 65 6e 74 20 21 3d 20 4e 55 4c 4c 29  if (ent != NULL)
5f30: 20 7b 0a 09 09 2a 75 73 65 72 5f 69 64 20 3d 20   {...*user_id = 
5f40: 65 6e 74 2d 3e 70 77 5f 75 69 64 3b 0a 0a 09 09  ent->pw_uid;....
5f50: 72 65 74 75 72 6e 28 30 29 3b 0a 09 7d 0a 23 65  return(0);..}.#e
5f60: 6e 64 69 66 0a 0a 09 75 73 65 72 5f 69 64 5f 63  ndif...user_id_c
5f70: 68 65 63 6b 20 3d 20 73 74 72 74 6f 75 6c 6c 28  heck = strtoull(
5f80: 75 73 65 72 2c 20 26 6e 65 78 74 2c 20 31 30 29  user, &next, 10)
5f90: 3b 0a 09 69 66 20 28 6e 65 78 74 20 3d 3d 20 4e  ;..if (next == N
5fa0: 55 4c 4c 29 20 7b 0a 09 09 72 65 74 75 72 6e 28  ULL) {...return(
5fb0: 31 29 3b 0a 09 7d 0a 0a 09 69 66 20 28 6e 65 78  1);..}...if (nex
5fc0: 74 5b 30 5d 20 21 3d 20 27 5c 30 27 29 20 7b 0a  t[0] != '\0') {.
5fd0: 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a  ..return(1);..}.
5fe0: 0a 09 2a 75 73 65 72 5f 69 64 20 3d 20 75 73 65  ..*user_id = use
5ff0: 72 5f 69 64 5f 63 68 65 63 6b 3b 0a 0a 09 72 65  r_id_check;...re
6000: 74 75 72 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 44  turn(0);.}../* D
6010: 61 65 6d 6f 6e 69 7a 65 20 2a 2f 0a 73 74 61 74  aemonize */.stat
6020: 69 63 20 69 6e 74 20 66 69 6c 65 64 5f 64 61 65  ic int filed_dae
6030: 6d 6f 6e 69 7a 65 28 76 6f 69 64 29 20 7b 0a 09  monize(void) {..
6040: 70 69 64 5f 74 20 73 65 74 73 69 64 5f 72 65 74  pid_t setsid_ret
6050: 2c 20 66 6f 72 6b 5f 72 65 74 3b 0a 09 69 6e 74  , fork_ret;..int
6060: 20 63 68 64 69 72 5f 72 65 74 2c 20 64 75 70 32   chdir_ret, dup2
6070: 5f 72 65 74 3b 0a 09 69 6e 74 20 66 64 5f 69 6e  _ret;..int fd_in
6080: 2c 20 66 64 5f 6f 75 74 3b 0a 0a 09 63 68 64 69  , fd_out;...chdi
6090: 72 5f 72 65 74 20 3d 20 63 68 64 69 72 28 22 2f  r_ret = chdir("/
60a0: 22 29 3b 0a 09 69 66 20 28 63 68 64 69 72 5f 72  ");..if (chdir_r
60b0: 65 74 20 21 3d 20 30 29 20 7b 0a 09 09 72 65 74  et != 0) {...ret
60c0: 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 66 6f 72  urn(1);..}...for
60d0: 6b 5f 72 65 74 20 3d 20 66 6f 72 6b 28 29 3b 0a  k_ret = fork();.
60e0: 09 69 66 20 28 66 6f 72 6b 5f 72 65 74 20 3c 20  .if (fork_ret < 
60f0: 30 29 20 7b 0a 09 09 72 65 74 75 72 6e 28 31 29  0) {...return(1)
6100: 3b 0a 09 7d 0a 0a 09 69 66 20 28 66 6f 72 6b 5f  ;..}...if (fork_
6110: 72 65 74 20 3e 20 30 29 20 7b 0a 09 09 2f 2a 20  ret > 0) {.../* 
6120: 50 61 72 65 6e 74 20 2a 2f 0a 09 09 77 61 69 74  Parent */...wait
6130: 70 69 64 28 66 6f 72 6b 5f 72 65 74 2c 20 4e 55  pid(fork_ret, NU
6140: 4c 4c 2c 20 30 29 3b 0a 0a 09 09 65 78 69 74 28  LL, 0);....exit(
6150: 45 58 49 54 5f 53 55 43 43 45 53 53 29 3b 0a 09  EXIT_SUCCESS);..
6160: 7d 0a 0a 09 2f 2a 20 43 68 69 6c 64 20 2a 2f 0a  }.../* Child */.
6170: 09 69 66 20 28 66 6f 72 6b 28 29 20 21 3d 20 30  .if (fork() != 0
6180: 29 20 7b 0a 09 09 2f 2a 20 43 68 69 6c 64 20 2a  ) {.../* Child *
6190: 2f 0a 09 09 65 78 69 74 28 45 58 49 54 5f 53 55  /...exit(EXIT_SU
61a0: 43 43 45 53 53 29 3b 0a 09 7d 0a 0a 09 2f 2a 20  CCESS);..}.../* 
61b0: 47 72 61 6e 64 20 63 68 69 6c 64 20 2a 2f 0a 09  Grand child */..
61c0: 73 65 74 73 69 64 5f 72 65 74 20 3d 20 73 65 74  setsid_ret = set
61d0: 73 69 64 28 29 3b 0a 09 69 66 20 28 73 65 74 73  sid();..if (sets
61e0: 69 64 5f 72 65 74 20 3d 3d 20 28 28 70 69 64 5f  id_ret == ((pid_
61f0: 74 29 20 2d 31 29 29 20 7b 0a 09 09 72 65 74 75  t) -1)) {...retu
6200: 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 66 64 5f 69  rn(1);..}...fd_i
6210: 6e 20 3d 20 6f 70 65 6e 28 22 2f 64 65 76 2f 6e  n = open("/dev/n
6220: 75 6c 6c 22 2c 20 4f 5f 52 44 4f 4e 4c 59 29 3b  ull", O_RDONLY);
6230: 0a 09 66 64 5f 6f 75 74 20 3d 20 6f 70 65 6e 28  ..fd_out = open(
6240: 22 2f 64 65 76 2f 6e 75 6c 6c 22 2c 20 4f 5f 57  "/dev/null", O_W
6250: 52 4f 4e 4c 59 29 3b 0a 09 69 66 20 28 66 64 5f  RONLY);..if (fd_
6260: 69 6e 20 3c 20 30 20 7c 7c 20 66 64 5f 6f 75 74  in < 0 || fd_out
6270: 20 3c 20 30 29 20 7b 0a 09 09 72 65 74 75 72 6e   < 0) {...return
6280: 28 31 29 3b 0a 09 7d 0a 0a 09 64 75 70 32 5f 72  (1);..}...dup2_r
6290: 65 74 20 3d 20 64 75 70 32 28 66 64 5f 69 6e 2c  et = dup2(fd_in,
62a0: 20 53 54 44 49 4e 5f 46 49 4c 45 4e 4f 29 3b 0a   STDIN_FILENO);.
62b0: 09 69 66 20 28 64 75 70 32 5f 72 65 74 20 21 3d  .if (dup2_ret !=
62c0: 20 53 54 44 49 4e 5f 46 49 4c 45 4e 4f 29 20 7b   STDIN_FILENO) {
62d0: 0a 09 09 72 65 74 75 72 6e 28 31 29 3b 0a 09 7d  ...return(1);..}
62e0: 0a 0a 09 64 75 70 32 5f 72 65 74 20 3d 20 64 75  ...dup2_ret = du
62f0: 70 32 28 66 64 5f 6f 75 74 2c 20 53 54 44 4f 55  p2(fd_out, STDOU
6300: 54 5f 46 49 4c 45 4e 4f 29 3b 0a 09 69 66 20 28  T_FILENO);..if (
6310: 64 75 70 32 5f 72 65 74 20 21 3d 20 53 54 44 4f  dup2_ret != STDO
6320: 55 54 5f 46 49 4c 45 4e 4f 29 20 7b 0a 09 09 72  UT_FILENO) {...r
6330: 65 74 75 72 6e 28 31 29 3b 0a 09 7d 0a 0a 09 64  eturn(1);..}...d
6340: 75 70 32 5f 72 65 74 20 3d 20 64 75 70 32 28 66  up2_ret = dup2(f
6350: 64 5f 6f 75 74 2c 20 53 54 44 45 52 52 5f 46 49  d_out, STDERR_FI
6360: 4c 45 4e 4f 29 3b 0a 09 69 66 20 28 64 75 70 32  LENO);..if (dup2
6370: 5f 72 65 74 20 21 3d 20 53 54 44 45 52 52 5f 46  _ret != STDERR_F
6380: 49 4c 45 4e 4f 29 20 7b 0a 09 09 72 65 74 75 72  ILENO) {...retur
6390: 6e 28 31 29 3b 0a 09 7d 0a 0a 09 63 6c 6f 73 65  n(1);..}...close
63a0: 28 66 64 5f 69 6e 29 3b 0a 09 63 6c 6f 73 65 28  (fd_in);..close(
63b0: 66 64 5f 6f 75 74 29 3b 0a 0a 09 72 65 74 75 72  fd_out);...retur
63c0: 6e 28 30 29 3b 0a 7d 0a 0a 2f 2a 20 52 75 6e 20  n(0);.}../* Run 
63d0: 70 72 6f 63 65 73 73 20 2a 2f 0a 69 6e 74 20 6d  process */.int m
63e0: 61 69 6e 28 69 6e 74 20 61 72 67 63 2c 20 63 68  ain(int argc, ch
63f0: 61 72 20 2a 2a 61 72 67 76 29 20 7b 0a 09 73 74  ar **argv) {..st
6400: 72 75 63 74 20 6f 70 74 69 6f 6e 20 6f 70 74 69  ruct option opti
6410: 6f 6e 73 5b 31 31 5d 3b 0a 09 63 6f 6e 73 74 20  ons[11];..const 
6420: 63 68 61 72 20 2a 62 69 6e 64 5f 61 64 64 72 20  char *bind_addr 
6430: 3d 20 42 49 4e 44 5f 41 44 44 52 2c 20 2a 6e 65  = BIND_ADDR, *ne
6440: 77 72 6f 6f 74 20 3d 20 4e 55 4c 4c 2c 20 2a 6c  wroot = NULL, *l
6450: 6f 67 5f 66 69 6c 65 20 3d 20 4c 4f 47 5f 46 49  og_file = LOG_FI
6460: 4c 45 3b 0a 09 46 49 4c 45 20 2a 6c 6f 67 5f 66  LE;..FILE *log_f
6470: 70 3b 0a 09 75 69 64 5f 74 20 75 73 65 72 20 3d  p;..uid_t user =
6480: 20 30 3b 0a 09 69 6e 74 20 70 6f 72 74 20 3d 20   0;..int port = 
6490: 50 4f 52 54 2c 20 74 68 72 65 61 64 5f 63 6f 75  PORT, thread_cou
64a0: 6e 74 20 3d 20 54 48 52 45 41 44 5f 43 4f 55 4e  nt = THREAD_COUN
64b0: 54 3b 0a 09 69 6e 74 20 63 61 63 68 65 5f 73 69  T;..int cache_si
64c0: 7a 65 20 3d 20 43 41 43 48 45 5f 53 49 5a 45 3b  ze = CACHE_SIZE;
64d0: 0a 09 69 6e 74 20 69 6e 69 74 5f 72 65 74 2c 20  ..int init_ret, 
64e0: 63 68 72 6f 6f 74 5f 72 65 74 2c 20 73 65 74 75  chroot_ret, setu
64f0: 69 64 5f 72 65 74 2c 20 6c 6f 6f 6b 75 70 5f 72  id_ret, lookup_r
6500: 65 74 2c 20 63 68 64 69 72 5f 72 65 74 3b 0a 09  et, chdir_ret;..
6510: 69 6e 74 20 73 65 74 75 69 64 5f 65 6e 61 62 6c  int setuid_enabl
6520: 65 64 20 3d 20 30 2c 20 64 61 65 6d 6f 6e 5f 65  ed = 0, daemon_e
6530: 6e 61 62 6c 65 64 20 3d 20 30 3b 0a 09 69 6e 74  nabled = 0;..int
6540: 20 63 68 3b 0a 09 69 6e 74 20 66 64 3b 0a 0a 09   ch;..int fd;...
6550: 2f 2a 20 50 72 6f 63 65 73 73 20 61 72 67 75 6d  /* Process argum
6560: 65 6e 74 73 20 2a 2f 0a 09 66 69 6c 65 64 5f 67  ents */..filed_g
6570: 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74 6f 70  etopt_long_setop
6580: 74 28 26 6f 70 74 69 6f 6e 73 5b 30 5d 2c 20 22  t(&options[0], "
6590: 70 6f 72 74 22 2c 20 72 65 71 75 69 72 65 64 5f  port", required_
65a0: 61 72 67 75 6d 65 6e 74 2c 20 27 70 27 29 3b 0a  argument, 'p');.
65b0: 09 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c 6f  .filed_getopt_lo
65c0: 6e 67 5f 73 65 74 6f 70 74 28 26 6f 70 74 69 6f  ng_setopt(&optio
65d0: 6e 73 5b 31 5d 2c 20 22 74 68 72 65 61 64 73 22  ns[1], "threads"
65e0: 2c 20 72 65 71 75 69 72 65 64 5f 61 72 67 75 6d  , required_argum
65f0: 65 6e 74 2c 20 27 74 27 29 3b 0a 09 66 69 6c 65  ent, 't');..file
6600: 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65  d_getopt_long_se
6610: 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 32 5d  topt(&options[2]
6620: 2c 20 22 63 61 63 68 65 22 2c 20 72 65 71 75 69  , "cache", requi
6630: 72 65 64 5f 61 72 67 75 6d 65 6e 74 2c 20 27 63  red_argument, 'c
6640: 27 29 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70  ');..filed_getop
6650: 74 5f 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f  t_long_setopt(&o
6660: 70 74 69 6f 6e 73 5b 33 5d 2c 20 22 62 69 6e 64  ptions[3], "bind
6670: 22 2c 20 72 65 71 75 69 72 65 64 5f 61 72 67 75  ", required_argu
6680: 6d 65 6e 74 2c 20 27 62 27 29 3b 0a 09 66 69 6c  ment, 'b');..fil
6690: 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73  ed_getopt_long_s
66a0: 65 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 34  etopt(&options[4
66b0: 5d 2c 20 22 75 73 65 72 22 2c 20 72 65 71 75 69  ], "user", requi
66c0: 72 65 64 5f 61 72 67 75 6d 65 6e 74 2c 20 27 75  red_argument, 'u
66d0: 27 29 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70  ');..filed_getop
66e0: 74 5f 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f  t_long_setopt(&o
66f0: 70 74 69 6f 6e 73 5b 35 5d 2c 20 22 72 6f 6f 74  ptions[5], "root
6700: 22 2c 20 72 65 71 75 69 72 65 64 5f 61 72 67 75  ", required_argu
6710: 6d 65 6e 74 2c 20 27 72 27 29 3b 0a 09 66 69 6c  ment, 'r');..fil
6720: 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73  ed_getopt_long_s
6730: 65 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73 5b 36  etopt(&options[6
6740: 5d 2c 20 22 68 65 6c 70 22 2c 20 6e 6f 5f 61 72  ], "help", no_ar
6750: 67 75 6d 65 6e 74 2c 20 27 68 27 29 3b 0a 09 66  gument, 'h');..f
6760: 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67  iled_getopt_long
6770: 5f 73 65 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73  _setopt(&options
6780: 5b 37 5d 2c 20 22 64 61 65 6d 6f 6e 22 2c 20 6e  [7], "daemon", n
6790: 6f 5f 61 72 67 75 6d 65 6e 74 2c 20 27 64 27 29  o_argument, 'd')
67a0: 3b 0a 09 66 69 6c 65 64 5f 67 65 74 6f 70 74 5f  ;..filed_getopt_
67b0: 6c 6f 6e 67 5f 73 65 74 6f 70 74 28 26 6f 70 74  long_setopt(&opt
67c0: 69 6f 6e 73 5b 38 5d 2c 20 22 6c 6f 67 22 2c 20  ions[8], "log", 
67d0: 72 65 71 75 69 72 65 64 5f 61 72 67 75 6d 65 6e  required_argumen
67e0: 74 2c 20 27 6c 27 29 3b 0a 09 66 69 6c 65 64 5f  t, 'l');..filed_
67f0: 67 65 74 6f 70 74 5f 6c 6f 6e 67 5f 73 65 74 6f  getopt_long_seto
6800: 70 74 28 26 6f 70 74 69 6f 6e 73 5b 39 5d 2c 20  pt(&options[9], 
6810: 22 76 65 72 73 69 6f 6e 22 2c 20 6e 6f 5f 61 72  "version", no_ar
6820: 67 75 6d 65 6e 74 2c 20 27 76 27 29 3b 0a 09 66  gument, 'v');..f
6830: 69 6c 65 64 5f 67 65 74 6f 70 74 5f 6c 6f 6e 67  iled_getopt_long
6840: 5f 73 65 74 6f 70 74 28 26 6f 70 74 69 6f 6e 73  _setopt(&options
6850: 5b 31 30 5d 2c 20 4e 55 4c 4c 2c 20 30 2c 20 30  [10], NULL, 0, 0
6860: 29 3b 0a 09 77 68 69 6c 65 20 28 28 63 68 20 3d  );..while ((ch =
6870: 20 67 65 74 6f 70 74 5f 6c 6f 6e 67 28 61 72 67   getopt_long(arg
6880: 63 2c 20 61 72 67 76 2c 20 22 70 3a 74 3a 63 3a  c, argv, "p:t:c:
6890: 62 3a 75 3a 72 3a 6c 3a 68 64 76 22 2c 20 6f 70  b:u:r:l:hdv", op
68a0: 74 69 6f 6e 73 2c 20 4e 55 4c 4c 29 29 20 21 3d  tions, NULL)) !=
68b0: 20 2d 31 29 20 7b 0a 09 09 73 77 69 74 63 68 28   -1) {...switch(
68c0: 63 68 29 20 7b 0a 09 09 09 63 61 73 65 20 27 70  ch) {....case 'p
68d0: 27 3a 0a 09 09 09 09 70 6f 72 74 20 3d 20 61 74  ':.....port = at
68e0: 6f 69 28 6f 70 74 61 72 67 29 3b 0a 09 09 09 09  oi(optarg);.....
68f0: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
6900: 74 27 3a 0a 09 09 09 09 74 68 72 65 61 64 5f 63  t':.....thread_c
6910: 6f 75 6e 74 20 3d 20 61 74 6f 69 28 6f 70 74 61  ount = atoi(opta
6920: 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a  rg);.....break;.
6930: 09 09 09 63 61 73 65 20 27 63 27 3a 0a 09 09 09  ...case 'c':....
6940: 09 63 61 63 68 65 5f 73 69 7a 65 20 3d 20 61 74  .cache_size = at
6950: 6f 69 28 6f 70 74 61 72 67 29 3b 0a 09 09 09 09  oi(optarg);.....
6960: 62 72 65 61 6b 3b 0a 09 09 09 63 61 73 65 20 27  break;....case '
6970: 62 27 3a 0a 09 09 09 09 62 69 6e 64 5f 61 64 64  b':.....bind_add
6980: 72 20 3d 20 73 74 72 64 75 70 28 6f 70 74 61 72  r = strdup(optar
6990: 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b 0a 09  g);.....break;..
69a0: 09 09 63 61 73 65 20 27 75 27 3a 0a 09 09 09 09  ..case 'u':.....
69b0: 73 65 74 75 69 64 5f 65 6e 61 62 6c 65 64 20 3d  setuid_enabled =
69c0: 20 31 3b 0a 09 09 09 09 6c 6f 6f 6b 75 70 5f 72   1;.....lookup_r
69d0: 65 74 20 3d 20 66 69 6c 65 64 5f 75 73 65 72 5f  et = filed_user_
69e0: 6c 6f 6f 6b 75 70 28 6f 70 74 61 72 67 2c 20 26  lookup(optarg, &
69f0: 75 73 65 72 29 3b 0a 09 09 09 09 69 66 20 28 6c  user);.....if (l
6a00: 6f 6f 6b 75 70 5f 72 65 74 20 21 3d 20 30 29 20  ookup_ret != 0) 
6a10: 7b 0a 09 09 09 09 09 66 69 6c 65 64 5f 70 72 69  {......filed_pri
6a20: 6e 74 5f 68 65 6c 70 28 73 74 64 65 72 72 2c 20  nt_help(stderr, 
6a30: 30 2c 20 22 49 6e 76 61 6c 69 64 20 75 73 65 72  0, "Invalid user
6a40: 6e 61 6d 65 20 73 70 65 63 69 66 69 65 64 22 29  name specified")
6a50: 3b 0a 0a 09 09 09 09 09 72 65 74 75 72 6e 28 31  ;.......return(1
6a60: 29 3b 0a 09 09 09 09 7d 0a 09 09 09 09 62 72 65  );.....}.....bre
6a70: 61 6b 3b 0a 09 09 09 63 61 73 65 20 27 72 27 3a  ak;....case 'r':
6a80: 0a 09 09 09 09 6e 65 77 72 6f 6f 74 20 3d 20 73  .....newroot = s
6a90: 74 72 64 75 70 28 6f 70 74 61 72 67 29 3b 0a 09  trdup(optarg);..
6aa0: 09 09 09 62 72 65 61 6b 3b 0a 09 09 09 63 61 73  ...break;....cas
6ab0: 65 20 27 6c 27 3a 0a 09 09 09 09 6c 6f 67 5f 66  e 'l':.....log_f
6ac0: 69 6c 65 20 3d 20 73 74 72 64 75 70 28 6f 70 74  ile = strdup(opt
6ad0: 61 72 67 29 3b 0a 09 09 09 09 62 72 65 61 6b 3b  arg);.....break;
6ae0: 0a 09 09 09 63 61 73 65 20 27 64 27 3a 0a 09 09  ....case 'd':...
6af0: 09 09 64 61 65 6d 6f 6e 5f 65 6e 61 62 6c 65 64  ..daemon_enabled
6b00: 20 3d 20 31 3b 0a 09 09 09 09 62 72 65 61 6b 3b   = 1;.....break;
6b10: 0a 09 09 09 63 61 73 65 20 27 76 27 3a 0a 09 09  ....case 'v':...
6b20: 09 09 70 72 69 6e 74 66 28 22 66 69 6c 65 64 20  ..printf("filed 
6b30: 76 65 72 73 69 6f 6e 20 25 73 5c 6e 22 2c 20 46  version %s\n", F
6b40: 49 4c 45 44 5f 56 45 52 53 49 4f 4e 29 3b 0a 0a  ILED_VERSION);..
6b50: 09 09 09 09 72 65 74 75 72 6e 28 30 29 3b 0a 09  ....return(0);..
6b60: 09 09 63 61 73 65 20 27 3f 27 3a 0a 09 09 09 63  ..case '?':....c
6b70: 61 73 65 20 27 3a 27 3a 0a 09 09 09 09 66 69 6c  ase ':':.....fil
6b80: 65 64 5f 70 72 69 6e 74 5f 68 65 6c 70 28 73 74  ed_print_help(st
6b90: 64 65 72 72 2c 20 30 2c 20 4e 55 4c 4c 29 3b 0a  derr, 0, NULL);.
6ba0: 0a 09 09 09 09 72 65 74 75 72 6e 28 31 29 3b 0a  .....return(1);.
6bb0: 09 09 09 63 61 73 65 20 27 68 27 3a 0a 09 09 09  ...case 'h':....
6bc0: 09 66 69 6c 65 64 5f 70 72 69 6e 74 5f 68 65 6c  .filed_print_hel
6bd0: 70 28 73 74 64 6f 75 74 2c 20 31 2c 20 4e 55 4c  p(stdout, 1, NUL
6be0: 4c 29 3b 0a 0a 09 09 09 09 72 65 74 75 72 6e 28  L);......return(
6bf0: 30 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 20  0);...}..}.../* 
6c00: 4f 70 65 6e 20 6c 6f 67 20 66 69 6c 65 20 2a 2f  Open log file */
6c10: 0a 09 69 66 20 28 73 74 72 63 6d 70 28 6c 6f 67  ..if (strcmp(log
6c20: 5f 66 69 6c 65 2c 20 22 2d 22 29 20 3d 3d 20 30  _file, "-") == 0
6c30: 29 20 7b 0a 09 09 6c 6f 67 5f 66 70 20 3d 20 73  ) {...log_fp = s
6c40: 74 64 6f 75 74 3b 0a 09 7d 20 65 6c 73 65 20 7b  tdout;..} else {
6c50: 0a 09 09 6c 6f 67 5f 66 70 20 3d 20 66 6f 70 65  ...log_fp = fope
6c60: 6e 28 6c 6f 67 5f 66 69 6c 65 2c 20 22 61 2b 22  n(log_file, "a+"
6c70: 29 3b 0a 09 09 69 66 20 28 6c 6f 67 5f 66 70 20  );...if (log_fp 
6c80: 3d 3d 20 4e 55 4c 4c 29 20 7b 0a 09 09 09 70 65  == NULL) {....pe
6c90: 72 72 6f 72 28 22 66 6f 70 65 6e 22 29 3b 0a 0a  rror("fopen");..
6ca0: 09 09 09 72 65 74 75 72 6e 28 34 29 3b 0a 09 09  ...return(4);...
6cb0: 7d 0a 09 7d 0a 0a 09 2f 2a 20 43 72 65 61 74 65  }..}.../* Create
6cc0: 20 6c 69 73 74 65 6e 69 6e 67 20 73 6f 63 6b 65   listening socke
6cd0: 74 20 2a 2f 0a 09 66 64 20 3d 20 66 69 6c 65 64  t */..fd = filed
6ce0: 5f 6c 69 73 74 65 6e 28 62 69 6e 64 5f 61 64 64  _listen(bind_add
6cf0: 72 2c 20 70 6f 72 74 29 3b 0a 09 69 66 20 28 66  r, port);..if (f
6d00: 64 20 3c 20 30 29 20 7b 0a 09 09 70 65 72 72 6f  d < 0) {...perro
6d10: 72 28 22 66 69 6c 65 64 5f 6c 69 73 74 65 6e 22  r("filed_listen"
6d20: 29 3b 0a 0a 09 09 72 65 74 75 72 6e 28 31 29 3b  );....return(1);
6d30: 0a 09 7d 0a 0a 09 2f 2a 20 42 65 63 6f 6d 65 20  ..}.../* Become 
6d40: 61 20 64 61 65 6d 6f 6e 20 2a 2f 0a 09 69 66 20  a daemon */..if 
6d50: 28 64 61 65 6d 6f 6e 5f 65 6e 61 62 6c 65 64 29  (daemon_enabled)
6d60: 20 7b 0a 09 09 69 6e 69 74 5f 72 65 74 20 3d 20   {...init_ret = 
6d70: 66 69 6c 65 64 5f 64 61 65 6d 6f 6e 69 7a 65 28  filed_daemonize(
6d80: 29 3b 0a 09 09 69 66 20 28 69 6e 69 74 5f 72 65  );...if (init_re
6d90: 74 20 21 3d 20 30 29 20 7b 0a 09 09 09 70 65 72  t != 0) {....per
6da0: 72 6f 72 28 22 66 69 6c 65 64 5f 64 61 65 6d 6f  ror("filed_daemo
6db0: 6e 69 7a 65 22 29 3b 0a 0a 09 09 09 72 65 74 75  nize");.....retu
6dc0: 72 6e 28 36 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09  rn(6);...}..}...
6dd0: 2f 2a 20 43 68 72 6f 6f 74 2c 20 69 66 20 61 70  /* Chroot, if ap
6de0: 70 72 6f 70 72 69 61 74 65 20 2a 2f 0a 09 69 66  propriate */..if
6df0: 20 28 6e 65 77 72 6f 6f 74 29 20 7b 0a 09 09 63   (newroot) {...c
6e00: 68 64 69 72 5f 72 65 74 20 3d 20 63 68 64 69 72  hdir_ret = chdir
6e10: 28 6e 65 77 72 6f 6f 74 29 3b 0a 09 09 69 66 20  (newroot);...if 
6e20: 28 63 68 64 69 72 5f 72 65 74 20 21 3d 20 30 29  (chdir_ret != 0)
6e30: 20 7b 0a 09 09 09 70 65 72 72 6f 72 28 22 63 68   {....perror("ch
6e40: 64 69 72 22 29 3b 0a 0a 09 09 09 72 65 74 75 72  dir");.....retur
6e50: 6e 28 31 29 3b 0a 09 09 7d 0a 0a 09 09 63 68 72  n(1);...}....chr
6e60: 6f 6f 74 5f 72 65 74 20 3d 20 63 68 72 6f 6f 74  oot_ret = chroot
6e70: 28 22 2e 22 29 3b 0a 09 09 69 66 20 28 63 68 72  (".");...if (chr
6e80: 6f 6f 74 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  oot_ret != 0) {.
6e90: 09 09 09 70 65 72 72 6f 72 28 22 63 68 72 6f 6f  ...perror("chroo
6ea0: 74 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  t");.....return(
6eb0: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 20  1);...}..}.../* 
6ec0: 44 72 6f 70 20 70 72 69 76 69 6c 65 67 65 73 2c  Drop privileges,
6ed0: 20 69 66 20 61 70 70 72 6f 70 72 69 61 74 65 20   if appropriate 
6ee0: 2a 2f 0a 09 69 66 20 28 73 65 74 75 69 64 5f 65  */..if (setuid_e
6ef0: 6e 61 62 6c 65 64 29 20 7b 0a 09 09 73 65 74 75  nabled) {...setu
6f00: 69 64 5f 72 65 74 20 3d 20 73 65 74 75 69 64 28  id_ret = setuid(
6f10: 75 73 65 72 29 3b 0a 09 09 69 66 20 28 73 65 74  user);...if (set
6f20: 75 69 64 5f 72 65 74 20 21 3d 20 30 29 20 7b 0a  uid_ret != 0) {.
6f30: 09 09 09 70 65 72 72 6f 72 28 22 73 65 74 75 69  ...perror("setui
6f40: 64 22 29 3b 0a 0a 09 09 09 72 65 74 75 72 6e 28  d");.....return(
6f50: 31 29 3b 0a 09 09 7d 0a 09 7d 0a 0a 09 2f 2a 20  1);...}..}.../* 
6f60: 49 6e 69 74 69 61 6c 69 7a 65 20 2a 2f 0a 09 69  Initialize */..i
6f70: 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 64 5f  nit_ret = filed_
6f80: 69 6e 69 74 28 63 61 63 68 65 5f 73 69 7a 65 29  init(cache_size)
6f90: 3b 0a 09 69 66 20 28 69 6e 69 74 5f 72 65 74 20  ;..if (init_ret 
6fa0: 21 3d 20 30 29 20 7b 0a 09 09 70 65 72 72 6f 72  != 0) {...perror
6fb0: 28 22 66 69 6c 65 64 5f 69 6e 69 74 22 29 3b 0a  ("filed_init");.
6fc0: 0a 09 09 72 65 74 75 72 6e 28 33 29 3b 0a 09 7d  ...return(3);..}
6fd0: 0a 0a 09 2f 2a 20 43 72 65 61 74 65 20 6c 6f 67  .../* Create log
6fe0: 67 69 6e 67 20 74 68 72 65 61 64 20 2a 2f 0a 09  ging thread */..
6ff0: 69 6e 69 74 5f 72 65 74 20 3d 20 66 69 6c 65 64  init_ret = filed
7000: 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65 61 64 5f  _logging_thread_
7010: 69 6e 69 74 28 6c 6f 67 5f 66 70 29 3b 0a 09 69  init(log_fp);..i
7020: 66 20 28 69 6e 69 74 5f 72 65 74 20 21 3d 20 30  f (init_ret != 0
7030: 29 20 7b 0a 09 09 70 65 72 72 6f 72 28 22 66 69  ) {...perror("fi
7040: 6c 65 64 5f 6c 6f 67 67 69 6e 67 5f 74 68 72 65  led_logging_thre
7050: 61 64 5f 69 6e 69 74 22 29 3b 0a 0a 09 09 72 65  ad_init");....re
7060: 74 75 72 6e 28 34 29 3b 0a 09 7d 0a 0a 09 2f 2a  turn(4);..}.../*
7070: 20 43 72 65 61 74 65 20 77 6f 72 6b 65 72 20 74   Create worker t
7080: 68 72 65 61 64 73 20 2a 2f 0a 09 69 6e 69 74 5f  hreads */..init_
7090: 72 65 74 20 3d 20 66 69 6c 65 64 5f 77 6f 72 6b  ret = filed_work
70a0: 65 72 5f 74 68 72 65 61 64 73 5f 69 6e 69 74 28  er_threads_init(
70b0: 66 64 2c 20 74 68 72 65 61 64 5f 63 6f 75 6e 74  fd, thread_count
70c0: 29 3b 0a 09 69 66 20 28 69 6e 69 74 5f 72 65 74  );..if (init_ret
70d0: 20 21 3d 20 30 29 20 7b 0a 09 09 70 65 72 72 6f   != 0) {...perro
70e0: 72 28 22 66 69 6c 65 64 5f 77 6f 72 6b 65 72 5f  r("filed_worker_
70f0: 74 68 72 65 61 64 73 5f 69 6e 69 74 22 29 3b 0a  threads_init");.
7100: 0a 09 09 72 65 74 75 72 6e 28 35 29 3b 0a 09 7d  ...return(5);..}
7110: 0a 0a 09 2f 2a 20 57 61 69 74 20 66 6f 72 20 74  .../* Wait for t
7120: 68 72 65 61 64 73 20 74 6f 20 65 78 69 74 20 2a  hreads to exit *
7130: 2f 0a 09 2f 2a 20 58 58 58 3a 54 4f 44 4f 3a 20  /../* XXX:TODO: 
7140: 4d 6f 6e 69 74 6f 72 20 74 68 72 65 61 64 20 75  Monitor thread u
7150: 73 61 67 65 20 2a 2f 0a 09 77 68 69 6c 65 20 28  sage */..while (
7160: 31 29 20 7b 0a 09 09 73 6c 65 65 70 28 36 30 29  1) {...sleep(60)
7170: 3b 0a 09 7d 0a 0a 09 2f 2a 20 52 65 74 75 72 6e  ;..}.../* Return
7180: 20 69 6e 20 66 61 69 6c 75 72 65 20 2a 2f 0a 09   in failure */..
7190: 72 65 74 75 72 6e 28 32 29 3b 0a 7d 0a           return(2);.}.