25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
|
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
+
+
+
+
+
+
|
#define FILED_DEFAULT_TYPE "application/octet-stream"
/* Default values */
#define PORT 80
#define THREAD_COUNT 5
#define BIND_ADDR "::"
#define CACHE_SIZE 8209
#define LOG_FILE "-"
/* Arguments for worker threads */
struct filed_worker_thread_args {
int fd;
};
/* Arguments for logging threads */
struct filed_logging_thread_args {
FILE *fp;
};
/* File information */
struct filed_fileinfo {
pthread_mutex_t mutex;
char *path;
int fd;
off_t len;
|
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
|
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
|
struct {
int present;
off_t offset; /*** Range start ***/
off_t length; /*** Range length ***/
} range;
} headers;
};
/* Log record */
struct filed_log_entry {
struct filed_log_entry *_next;
struct filed_log_entry *_prev;
pthread_t thread;
char buffer[1010];
int level;
};
/* Global variables */
/** Open File cache **/
struct filed_fileinfo *filed_fileinfo_fdcache = NULL;
unsigned int filed_fileinfo_fdcache_size = 0;
/** Logging **/
struct filed_log_entry *filed_log_msg_list;
pthread_mutex_t filed_log_msg_list_mutex;
pthread_cond_t filed_log_msg_list_ready;
/* Initialize cache */
static int filed_init_cache(unsigned int cache_size) {
unsigned int idx;
int mutex_init_ret;
/* Cache may not be re-initialized */
if (filed_fileinfo_fdcache_size != 0 || filed_fileinfo_fdcache != NULL) {
|
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
|
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
|
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
-
+
+
+
-
+
+
+
+
+
+
+
+
+
|
/* Log a message */
//#define FILED_DONT_LOG
#ifdef FILED_DONT_LOG
# define filed_logging_thread_init() 0
# define filed_log_msg_debug(x, ...) /**/
# define filed_log_msg(x) /**/
#else
#ifdef FILED_DEBUG
# define filed_log_msg_debug(x, ...) { fprintf(stderr, x, __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); }
#else
# define filed_log_msg_debug(x, ...) /**/
#endif
/* Initialize logging thread */
static void *filed_logging_thread(void *arg_p) {
struct filed_logging_thread_args *arg;
struct filed_log_entry *curr, *prev;
FILE *fp;
arg = arg_p;
fp = arg->fp;
while (1) {
pthread_mutex_lock(&filed_log_msg_list_mutex);
pthread_cond_wait(&filed_log_msg_list_ready, &filed_log_msg_list_mutex);
curr = filed_log_msg_list;
filed_log_msg_list = NULL;
pthread_mutex_unlock(&filed_log_msg_list_mutex);
prev = NULL;
for (; curr; curr = curr->_next) {
curr->_prev = prev;
prev = curr;
}
curr = prev;
while (curr) {
fprintf(fp, "%s THREAD=%llu\n", curr->buffer, (unsigned long long) curr->thread);
prev = curr;
curr = curr->_prev;
free(prev);
}
}
return(NULL);
}
static int filed_logging_thread_init(void) {
/* XXX:TODO: Unimplemented */
return(0);
}
/* XXX:TODO: Unimplemented */
#define filed_log_msg_debug(x, ...) { fprintf(stderr, x, __VA_ARGS__); fprintf(stderr, "\n"); fflush(stderr); }
static int filed_logging_thread_init(const char *logfile) {
struct filed_logging_thread_args *args;
pthread_t thread_id;
FILE *logfp;
if (strcmp(logfile, "-") == 0) {
logfp = stdout;
} else {
logfp = fopen(logfile, "a+");
if (logfp == NULL) {
return(1);
}
}
args = malloc(sizeof(*args));
args->fp = logfp;
filed_log_msg_list = NULL;
pthread_mutex_init(&filed_log_msg_list_mutex, NULL);
pthread_create(&thread_id, NULL, filed_logging_thread, args);
return(0);
}
static void filed_log_msg(const char *fmt, ...) {
char buffer[1010];
struct filed_log_entry *entry;
va_list args;
entry = malloc(sizeof(*entry));
va_start(args, fmt);
vsnprintf(buffer, sizeof(buffer), fmt, args);
vsnprintf(entry->buffer, sizeof(entry->buffer), fmt, args);
va_end(args);
entry->thread = pthread_self();
entry->level = 0;
fprintf(stderr, "%s\n", buffer);
pthread_mutex_lock(&filed_log_msg_list_mutex);
entry->_next = filed_log_msg_list;
filed_log_msg_list = entry;
pthread_mutex_unlock(&filed_log_msg_list_mutex);
pthread_cond_signal(&filed_log_msg_list_ready);
return;
}
#endif
/* Format time per RFC2616 */
static char *filed_format_time(char *buffer, size_t buffer_len, const time_t timeinfo) {
|
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
|
302
303
304
305
306
307
308
309
310
311
312
313
314
315
|
-
|
buffer[buffer_len - 1] = '\0';
buffer_len = strftime(buffer, buffer_len - 1, "%a, %d %b %Y %H:%M:%S GMT", timeinfo_tm_p);
return(buffer);
}
/* hash */
/* XXX:TODO: Rewrite this */
static unsigned int filed_hash(const unsigned char *value, unsigned int modulus) {
unsigned char curr, prev;
int diff;
unsigned int retval;
retval = modulus - 1;
prev = modulus % 255;
|
664
665
666
667
668
669
670
671
672
673
674
675
676
677
|
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
|
+
|
}
/* Handle incoming connections */
static void *filed_worker_thread(void *arg_v) {
struct filed_worker_thread_args *arg;
struct filed_http_request request;
struct sockaddr_in6 addr;
char logbuf[128];
socklen_t addrlen;
int failure_count = 0, max_failure_count = MAX_FAILURE_COUNT;
int master_fd, fd;
/* Read arguments */
arg = arg_v;
|
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
|
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
|
+
+
-
+
|
failure_count++;
continue;
}
/* Log the new connection */
logbuf[0]='\0';
inet_ntop(AF_INET6, &addr.sin6_addr, logbuf, sizeof(logbuf));
filed_log_msg("NEW_CONNECTION SRC_ADDR=... SRC_PORT=... FD=%i", fd);
filed_log_msg("NEW_CONNECTION SRC_ADDR=%s SRC_PORT=%lu FD=%i", logbuf, (unsigned long) addr.sin6_port, fd);
/* Reset failure count*/
failure_count = 0;
/* Handle socket */
filed_handle_client(fd, &request);
}
|
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
|
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
|
-
+
|
return(0);
}
/* Run process */
int main(int argc, char **argv) {
struct option options[9];
const char *bind_addr = BIND_ADDR, *newroot = NULL;
const char *bind_addr = BIND_ADDR, *newroot = NULL, *log_file = LOG_FILE;
uid_t user = 0;
int port = PORT, thread_count = THREAD_COUNT;
int cache_size = CACHE_SIZE;
int init_ret, chroot_ret, setuid_ret, lookup_ret, chdir_ret;
int setuid_enabled = 0, daemon_enabled = 0;
int ch;
int fd;
|
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
|
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
|
-
+
|
if (init_ret != 0) {
perror("filed_init");
return(3);
}
/* Create logging thread */
init_ret = filed_logging_thread_init();
init_ret = filed_logging_thread_init(log_file);
if (init_ret != 0) {
perror("filed_logging_thread_init");
return(4);
}
/* Create worker threads */
|