Diff

Differences From Artifact [7391155930]:

To Artifact [e20f1f0a83]:


115
116
117
118
119
120
121

122
123
124
125
126
127
128
...
862
863
864
865
866
867
868
869













































870
871
872
873
874
875
876
877
878
...
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
...
941
942
943
944
945
946
947



948
949
950
951
952
953
954
....
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
....
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
....
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
	attr = attr;
}
#endif

/* Configuration options that work threads need to be aware of */
struct filed_options {
	int vhosts_enabled;

};

/* Arguments for worker threads */
struct filed_worker_thread_args {
	int fd;
	struct filed_options options;
};
................................................................................
		(unsigned long long) time(NULL),
		(unsigned long long) random(),
		(unsigned long long) random(),
		(unsigned long long) random(),
		(unsigned long long) random()
	);
}














































/* Open a file and return file information */
static struct filed_fileinfo *filed_open_file(const char *path, struct filed_fileinfo *buffer) {
	struct filed_fileinfo *cache;
	unsigned int cache_idx;
	off_t len;
	int fd;

	if (filed_fileinfo_fdcache_size != 0) {
		cache_idx = filed_hash((const unsigned char *) path, filed_fileinfo_fdcache_size);
................................................................................
		cache->path[0] = '\0';
		cache->fd = -1;
	}

	if (strcmp(path, cache->path) != 0) {
		filed_log_msg_debug("Cache miss for idx: %lu: OLD \"%s\", NEW \"%s\"", (unsigned long) cache_idx, cache->path, path);

		fd = open(path, O_RDONLY | O_LARGEFILE);
		if (fd < 0) {
			if (filed_fileinfo_fdcache_size != 0) {
				pthread_mutex_unlock(&cache->mutex);
			}

			return(NULL);
		}
................................................................................
		memcpy(buffer->etag, cache->etag, sizeof(buffer->etag));
		buffer->lastmod = buffer->lastmod_b + (cache->lastmod - cache->lastmod_b);

		pthread_mutex_unlock(&cache->mutex);
	}

	return(buffer);



}

/* Process an HTTP request and return the path requested */
static struct filed_http_request *filed_get_http_request(FILE *fp, struct filed_http_request *buffer_st, struct filed_options *options) {
	char *method, *path;
	char *buffer, *workbuffer, *workbuffer_next;
	char *fgets_ret;
................................................................................
	/* If the requested path is a directory, redirect to index page */
	if (request->type == FILED_REQUEST_TYPE_DIRECTORY) {
		filed_redirect_index(fp, date_current, path, log);

		return(FILED_CONNECTION_CLOSE);
	}

	fileinfo = filed_open_file(path, &request->fileinfo);
	if (fileinfo == NULL) {
		filed_error_page(fp, date_current, 404, request->method, "open_failed", log);

		return(FILED_CONNECTION_CLOSE);
	}

	if (request->headers.range.present) {
................................................................................

	return(0);
}

/* Run process */
int main(int argc, char **argv) {
	struct option options[12];
	struct filed_options thread_options;
	const char *bind_addr = BIND_ADDR, *newroot = NULL, *log_file = LOG_FILE;
	FILE *log_fp;
	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;

	/* Set default values */
	thread_options.vhosts_enabled = 0;

	/* Process arguments */
	filed_getopt_long_setopt(&options[0], "port", required_argument, 'p');
	filed_getopt_long_setopt(&options[1], "threads", required_argument, 't');
	filed_getopt_long_setopt(&options[2], "cache", required_argument, 'c');
	filed_getopt_long_setopt(&options[3], "bind", required_argument, 'b');
	filed_getopt_long_setopt(&options[4], "user", required_argument, 'u');
	filed_getopt_long_setopt(&options[5], "root", required_argument, 'r');
................................................................................
				if (lookup_ret != 0) {
					filed_print_help(stderr, 0, "Invalid username specified");

					return(1);
				}
				break;
			case 'r':
				newroot = strdup(optarg);
				break;
			case 'l':
				log_file = strdup(optarg);
				break;
			case 'd':
				daemon_enabled = 1;
				break;







>







 








>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>

|







 







|







 







>
>
>







 







|







 







|










<
<
<







 







|







115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
...
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
...
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
...
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
....
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
....
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745



1746
1747
1748
1749
1750
1751
1752
....
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
	attr = attr;
}
#endif

/* Configuration options that work threads need to be aware of */
struct filed_options {
	int vhosts_enabled;
	const char *fake_newroot;
};

/* Arguments for worker threads */
struct filed_worker_thread_args {
	int fd;
	struct filed_options options;
};
................................................................................
		(unsigned long long) time(NULL),
		(unsigned long long) random(),
		(unsigned long long) random(),
		(unsigned long long) random(),
		(unsigned long long) random()
	);
}

#ifdef FILED_FAKE_CHROOT
/* Translate a path into a fake chroot path */
static const char *filed_path_translate(const char *path, struct filed_options *options) {
	static __thread char pathBuffer[8192];
	int snprintf_ret;

	/* If no alternative root is specified, return the unadorned path */
	if (!options->fake_newroot) {
		return(path);
	}

	/* Verify that this request will not go outside of the specified root */
	if (strstr(path, "/../") != NULL || path[0] != '/') {
		filed_log_msg_debug("Unable to translate path \"%s\", contains invalid characters", path);

		return(options->fake_newroot);
	}

	/* Create the new path into our local (TLS) static buffer */
	snprintf_ret = snprintf(pathBuffer, sizeof(pathBuffer), "%s/%s", options->fake_newroot, path);
	if (snprintf_ret < 0 || ((unsigned int) snprintf_ret) >= sizeof(pathBuffer)) {
		filed_log_msg_debug("Unable to translate path \"%s\", will not fit into new buffer", path);

		return(options->fake_newroot);
	}

	filed_log_msg_debug("Translating path \"%s\" into \"%s\"", path, pathBuffer);

	/* Return the new path */
	return(pathBuffer);
}

static void filed_path_translate_set_root(const char *var, struct filed_options *options, const char *val) {
	options->fake_newroot = strdup(val);

	return;

	/* var is only used in the macro -- discard it here */
	var = var;
}
#else
#define filed_path_translate(path, options) path
#define filed_path_translate_set_root(var, options, val) var = strdup(val)
#endif

/* Open a file and return file information */
static struct filed_fileinfo *filed_open_file(const char *path, struct filed_fileinfo *buffer, struct filed_options *options) {
	struct filed_fileinfo *cache;
	unsigned int cache_idx;
	off_t len;
	int fd;

	if (filed_fileinfo_fdcache_size != 0) {
		cache_idx = filed_hash((const unsigned char *) path, filed_fileinfo_fdcache_size);
................................................................................
		cache->path[0] = '\0';
		cache->fd = -1;
	}

	if (strcmp(path, cache->path) != 0) {
		filed_log_msg_debug("Cache miss for idx: %lu: OLD \"%s\", NEW \"%s\"", (unsigned long) cache_idx, cache->path, path);

		fd = open(filed_path_translate(path, options), O_RDONLY | O_LARGEFILE);
		if (fd < 0) {
			if (filed_fileinfo_fdcache_size != 0) {
				pthread_mutex_unlock(&cache->mutex);
			}

			return(NULL);
		}
................................................................................
		memcpy(buffer->etag, cache->etag, sizeof(buffer->etag));
		buffer->lastmod = buffer->lastmod_b + (cache->lastmod - cache->lastmod_b);

		pthread_mutex_unlock(&cache->mutex);
	}

	return(buffer);

	/* options is only used if fake chroot is enabled, confuse the compiler */
	options = options;
}

/* Process an HTTP request and return the path requested */
static struct filed_http_request *filed_get_http_request(FILE *fp, struct filed_http_request *buffer_st, struct filed_options *options) {
	char *method, *path;
	char *buffer, *workbuffer, *workbuffer_next;
	char *fgets_ret;
................................................................................
	/* If the requested path is a directory, redirect to index page */
	if (request->type == FILED_REQUEST_TYPE_DIRECTORY) {
		filed_redirect_index(fp, date_current, path, log);

		return(FILED_CONNECTION_CLOSE);
	}

	fileinfo = filed_open_file(path, &request->fileinfo, options);
	if (fileinfo == NULL) {
		filed_error_page(fp, date_current, 404, request->method, "open_failed", log);

		return(FILED_CONNECTION_CLOSE);
	}

	if (request->headers.range.present) {
................................................................................

	return(0);
}

/* Run process */
int main(int argc, char **argv) {
	struct option options[12];
	struct filed_options thread_options = {0};
	const char *bind_addr = BIND_ADDR, *newroot = NULL, *log_file = LOG_FILE;
	FILE *log_fp;
	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;




	/* Process arguments */
	filed_getopt_long_setopt(&options[0], "port", required_argument, 'p');
	filed_getopt_long_setopt(&options[1], "threads", required_argument, 't');
	filed_getopt_long_setopt(&options[2], "cache", required_argument, 'c');
	filed_getopt_long_setopt(&options[3], "bind", required_argument, 'b');
	filed_getopt_long_setopt(&options[4], "user", required_argument, 'u');
	filed_getopt_long_setopt(&options[5], "root", required_argument, 'r');
................................................................................
				if (lookup_ret != 0) {
					filed_print_help(stderr, 0, "Invalid username specified");

					return(1);
				}
				break;
			case 'r':
				filed_path_translate_set_root(newroot, &thread_options, optarg);
				break;
			case 'l':
				log_file = strdup(optarg);
				break;
			case 'd':
				daemon_enabled = 1;
				break;