예제 #1
0
static errcode_t parse_time(struct field_set_info *info, char *field, char *arg)
{
	time_t		t;
	__u32		*ptr32;

	ptr32 = (__u32 *) info->ptr;

	t = string_to_time(arg);

	if (t == ((time_t) -1)) {
		fprintf(stderr, "Couldn't parse '%s' for field %s.\n",
			arg, info->name);
		return EINVAL;
	}
	*ptr32 = t;
	return 0;
}
예제 #2
0
파일: call_log.c 프로젝트: kouqi/linphone
void call_logs_read_from_config_file(LinphoneCore *lc){
	char logsection[32];
	int i;
	const char *tmp;
	uint64_t sec;
	LpConfig *cfg=lc->config;
	for(i=0;;++i){
		snprintf(logsection,sizeof(logsection),"call_log_%i",i);
		if (lp_config_has_section(cfg,logsection)){
			LinphoneCallLog *cl;
			LinphoneAddress *from=NULL,*to=NULL;
			tmp=lp_config_get_string(cfg,logsection,"from",NULL);
			if (tmp) from=linphone_address_new(tmp);
			tmp=lp_config_get_string(cfg,logsection,"to",NULL);
			if (tmp) to=linphone_address_new(tmp);
			if (!from || !to)
				continue;
			cl=linphone_call_log_new(lp_config_get_int(cfg,logsection,"dir",0),from,to);
			cl->status=lp_config_get_int(cfg,logsection,"status",0);
			sec=lp_config_get_int64(cfg,logsection,"start_date_time",0);
			if (sec) {
				/*new call log format with date expressed in seconds */
				cl->start_date_time=(time_t)sec;
				set_call_log_date(cl,cl->start_date_time);
			}else{
				tmp=lp_config_get_string(cfg,logsection,"start_date",NULL);
				if (tmp) {
					strncpy(cl->start_date,tmp,sizeof(cl->start_date));
					cl->start_date_time=string_to_time(cl->start_date);
				}
			}
			cl->duration=lp_config_get_int(cfg,logsection,"duration",0);
			tmp=lp_config_get_string(cfg,logsection,"refkey",NULL);
			if (tmp) cl->refkey=ms_strdup(tmp);
			cl->quality=lp_config_get_float(cfg,logsection,"quality",-1);
			cl->video_enabled=lp_config_get_int(cfg,logsection,"video_enabled",0);
			tmp=lp_config_get_string(cfg,logsection,"call_id",NULL);
			if (tmp) cl->call_id=ms_strdup(tmp);
			lc->call_logs=ms_list_append(lc->call_logs,cl);
		}else break;
	}
}
예제 #3
0
/** @brief Yes we need a main function **/
int main(void) {
	char buffer[MAX_DATETIME_LENGTH];
	int result = OK;

	/* get the arguments passed in the URL */
	process_cgivars();

	/* reset internal variables */
	reset_cgi_vars();

	/* read the CGI configuration file */
	result = read_cgi_config_file(get_cgi_config_location());
	if (result == ERROR) {
		document_header(CGI_ID, FALSE, "Error");
		print_error(get_cgi_config_location(), ERROR_CGI_CFG_FILE, FALSE);
		document_footer(CGI_ID);
		return ERROR;
	}

	/* read the main configuration file */
	result = read_main_config_file(main_config_file);
	if (result == ERROR) {
		document_header(CGI_ID, FALSE, "Error");
		print_error(main_config_file, ERROR_CGI_MAIN_CFG, FALSE);
		document_footer(CGI_ID);
		return ERROR;
	}

	/* read all object configuration data */
	result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA);
	if (result == ERROR) {
		document_header(CGI_ID, FALSE, "Error");
		print_error(NULL, ERROR_CGI_OBJECT_DATA, FALSE);
		document_footer(CGI_ID);
		return ERROR;
	}

	/* This requires the date_format parameter in the main config file */
	if (timeperiod_type == TIMEPERIOD_CUSTOM) {
		if (strcmp(start_time_string, ""))
			string_to_time(start_time_string, &ts_start);

		if (strcmp(end_time_string, ""))
			string_to_time(end_time_string, &ts_end);
	}

	/* overwrite config value with amount we got via GET */
	result_limit = (get_result_limit != -1) ? get_result_limit : result_limit;

	/* for json and csv output return all by default */
	if (get_result_limit == -1 && (content_type == JSON_CONTENT || content_type == CSV_CONTENT))
		result_limit = 0;

	document_header(CGI_ID, TRUE, "Alert Notifications");

	/* get authentication information */
	get_authentication_information(&current_authdata);

	/* calculate timestamps for reading logs */
	convert_timeperiod_to_times(timeperiod_type, &ts_start, &ts_end);

	if (display_header == TRUE) {

		/* begin top table */
		printf("<table border='0' width='100%%'>\n");
		printf("<tr>\n");

		/* left column of top row */
		printf("<td align='left' valign='top' width='33%%'>\n");

		if (query_type == DISPLAY_SERVICES)
			display_info_table("Service Notifications", &current_authdata, daemon_check);
		else if (query_type == DISPLAY_HOSTGROUPS)
			display_info_table("Hostgroup Notifications", &current_authdata, daemon_check);
		else if (query_type == DISPLAY_SERVICEGROUPS)
			display_info_table("Servicegroup Notifications", &current_authdata, daemon_check);
		else if (query_type == DISPLAY_HOSTS) {
			if (find_all == TRUE)
				display_info_table("Notifications", &current_authdata, daemon_check);
			else
				display_info_table("Host Notifications", &current_authdata, daemon_check);
		} else
			display_info_table("Contact Notifications", &current_authdata, daemon_check);

		if (query_type == DISPLAY_HOSTS || query_type == DISPLAY_SERVICES || query_type == DISPLAY_HOSTGROUPS || query_type == DISPLAY_SERVICEGROUPS) {
			printf("<table border='1' cellpadding='0' cellspacing='0' class='linkBox'>\n");
			printf("<tr><td class='linkBox'>\n");
			if (query_type == DISPLAY_HOSTS) {
				printf("<a href='%s?host=%s'>View <b>Status Detail</b> For <b>%s</b></a><br>\n", STATUS_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name), (find_all == TRUE) ? "All Hosts" : "This Host");
				printf("<a href='%s?host=%s'>View <b>Alert History</b> For <b>%s</b></a><br>\n", HISTORY_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name), (find_all == TRUE) ? "All Hosts" : "This Host");
#ifdef USE_TRENDS
				if (find_all == FALSE)
					printf("<a href='%s?host=%s'>View <b>Trends</b> For <b>This Host</b></a><br>\n", TRENDS_CGI, url_encode(query_host_name));
#endif
				printf("<a href='%s?type=%d&amp;host=%s'>View <b>Information</b> For <b>This Host</b></a><br>\n", EXTINFO_CGI, DISPLAY_HOST_INFO, url_encode(query_host_name));
				printf("<a href='%s?host=%s&amp;show_log_entries'>View <b>Availability Report</b> For <b>This Host</b></a><br>\n", AVAIL_CGI, url_encode(query_host_name));
			} else if (query_type == DISPLAY_SERVICES) {
				printf("<a href='%s?host=%s&amp;", HISTORY_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name));
				printf("service=%s'>View <b>Alert History</b> For <b>This Service</b></a><br>\n", url_encode(query_svc_description));
#ifdef USE_TRENDS
				printf("<a href='%s?host=%s&amp;", TRENDS_CGI, (find_all == TRUE) ? "all" : url_encode(query_host_name));
				printf("service=%s'>View <b>Trends</b> For <b>This Service</b></a><br>\n", url_encode(query_svc_description));
#endif
				printf("<a href='%s?type=%d&amp;host=%s&amp;service=%s'>View <b>Information</b> For <b>This Service</b></a><br>\n", EXTINFO_CGI, DISPLAY_SERVICE_INFO, url_encode(query_host_name), url_encode(query_svc_description));
				printf("<a href='%s?host=%s&amp;service=%s&amp;show_log_entries'>View <b>Availability Report</b> For <b>This Service</b></a><br>\n", AVAIL_CGI, url_encode(query_host_name), url_encode(query_svc_description));
				printf("<a href='%s?host=%s'>View <b>Notifications</b> For <b>This Host</b></a><br>\n", NOTIFICATIONS_CGI, url_encode(query_host_name));
			} else if (query_type == DISPLAY_HOSTGROUPS) {
				printf("<a href='%s?hostgroup=%s&amp;style=hostdetail'>View <b>Host Status Detail</b> For <b>This Hostgroup</b></a><br>\n", STATUS_CGI, url_encode(query_hostgroup_name));
				printf("<a href='%s?hostgroup=%s&amp;style=detail'>View <b>Service Status Detail</b> For <b>This Hostgroup</b></a><br>\n", STATUS_CGI, url_encode(query_hostgroup_name));
				printf("<a href='%s?hostgroup=%s'>View <b>Alert History</b> For <b>This Hostgroup</b></a><br>\n", HISTORY_CGI, url_encode(query_hostgroup_name));
			} else if (query_type == DISPLAY_SERVICEGROUPS) {
				printf("<a href='%s?servicegroup=%s&amp;style=hostdetail'>View <b>Host Status Detail</b> For <b>This Servicegroup</b></a><br>\n", STATUS_CGI, url_encode(query_servicegroup_name));
				printf("<a href='%s?servicegroup=%s&amp;style=detail'>View <b>Service Status Detail</b> For <b>This Servicegroup</b></a><br>\n", STATUS_CGI, url_encode(query_servicegroup_name));
				printf("<a href='%s?servicegroup=%s'>View <b>Alert History</b> For <b>This Servicegroup</b></a><br>\n", HISTORY_CGI, url_encode(query_servicegroup_name));
			}
			printf("</td></tr>\n");
			printf("</table>\n");
		}

		printf("</td>\n");

		/* middle column of top row */
		printf("<td align='center' valign='top' width='33%%'>\n");

		printf("<div align='center' class='dataTitle'>\n");
		if (query_type == DISPLAY_SERVICES)
			printf("Service '%s' on Host '%s'", query_svc_description, query_host_name);
		else if (query_type == DISPLAY_HOSTS) {
			if (find_all == TRUE)
				printf("All Hosts and Services");
			else
				printf("Host '%s'", html_encode(query_host_name, TRUE));
		} else if (query_type == DISPLAY_HOSTGROUPS) {
			printf("Host Group '%s'", html_encode(query_hostgroup_name, TRUE));
		} else if (query_type == DISPLAY_SERVICEGROUPS) {
			printf("Service Group '%s'", html_encode(query_servicegroup_name, TRUE));
		} else {
			if (find_all == TRUE)
				printf("All Contacts");
			else
				printf("Contact '%s'", html_encode(query_contact_name, TRUE));
		}
		printf("</div>\n");
		printf("<br>\n");

		display_nav_table(ts_start, ts_end);

		printf("</td>\n");

		/* right hand column of top row */
		printf("<td align='right' valign='top' width='33%%'>\n");

		printf("<form method='GET' action='%s'>\n", NOTIFICATIONS_CGI);
		if (query_type == DISPLAY_SERVICES) {
			printf("<input type='hidden' name='host' value='%s'>\n", escape_string(query_host_name));
			printf("<input type='hidden' name='service' value='%s'>\n", escape_string(query_svc_description));
		} else if (query_type == DISPLAY_HOSTGROUPS) {
			printf("<input type='hidden' name='hostgroup' value='%s'>\n", escape_string(query_hostgroup_name));
		} else if (query_type == DISPLAY_SERVICEGROUPS) {
			printf("<input type='hidden' name='servicegroup' value='%s'>\n", escape_string(query_servicegroup_name));
		} else
			printf("<input type='hidden' name='%s' value='%s'>\n", (query_type == DISPLAY_HOSTS) ? "host" : "contact", (query_type == DISPLAY_HOSTS) ? escape_string(query_host_name) : escape_string(query_contact_name));
		printf("<input type='hidden' name='ts_start' value='%lu'>\n", ts_start);
		printf("<input type='hidden' name='ts_end' value='%lu'>\n", ts_end);
		printf("<input type='hidden' name='limit' value='%d'>\n", result_limit);

		printf("<table border='0' class='optBox'>\n");
		printf("<tr>\n");
		if (query_type == DISPLAY_SERVICES)
			printf("<td align='left' colspan='2' class='optBoxItem'>Notification detail level for this service:</td>");
		if (query_type == DISPLAY_HOSTGROUPS || query_type == DISPLAY_SERVICEGROUPS)
			printf("<td align='left' colspan='2' class='optBoxItem'>Notification detail level for this %sgroup:</td>", (query_type == DISPLAY_HOSTGROUPS) ? "host" : "service");
		else
			printf("<td align='left' colspan='2' class='optBoxItem'>Notification detail level for %s %s%s:</td>", (find_all == TRUE) ? "all" : "this", (query_type == DISPLAY_HOSTS) ? "host" : "contact", (find_all == TRUE) ? "s" : "");
		printf("</tr>\n");
		printf("<tr><td></td>\n");
		printf("<td align='left' class='optBoxItem'><select name='type'>\n");
		printf("<option value='%d' %s>All notifications\n", NOTIFICATION_ALL, (notification_options == NOTIFICATION_ALL) ? "selected" : "");
		if (query_type != DISPLAY_SERVICES) {
			printf("<option value='%d' %s>All service notifications\n", NOTIFICATION_SERVICE_ALL, (notification_options == NOTIFICATION_SERVICE_ALL) ? "selected" : "");
			printf("<option value='%d' %s>All host notifications\n", NOTIFICATION_HOST_ALL, (notification_options == NOTIFICATION_HOST_ALL) ? "selected" : "");
		}
		printf("<option value='%d' %s>Service custom\n", NOTIFICATION_SERVICE_CUSTOM, (notification_options == NOTIFICATION_SERVICE_CUSTOM) ? "selected" : "");
		printf("<option value='%d' %s>Service acknowledgements\n", NOTIFICATION_SERVICE_ACK, (notification_options == NOTIFICATION_SERVICE_ACK) ? "selected" : "");
		printf("<option value='%d' %s>Service warning\n", NOTIFICATION_SERVICE_WARNING, (notification_options == NOTIFICATION_SERVICE_WARNING) ? "selected" : "");
		printf("<option value='%d' %s>Service unknown\n", NOTIFICATION_SERVICE_UNKNOWN, (notification_options == NOTIFICATION_SERVICE_UNKNOWN) ? "selected" : "");
		printf("<option value='%d' %s>Service critical\n", NOTIFICATION_SERVICE_CRITICAL, (notification_options == NOTIFICATION_SERVICE_CRITICAL) ? "selected" : "");
		printf("<option value='%d' %s>Service recovery\n", NOTIFICATION_SERVICE_RECOVERY, (notification_options == NOTIFICATION_SERVICE_RECOVERY) ? "selected" : "");
		printf("<option value='%d' %s>Service flapping\n", NOTIFICATION_SERVICE_FLAP, (notification_options == NOTIFICATION_SERVICE_FLAP) ? "selected" : "");
		if (query_type != DISPLAY_SERVICES) {
			printf("<option value='%d' %s>Host custom\n", NOTIFICATION_HOST_CUSTOM, (notification_options == NOTIFICATION_HOST_CUSTOM) ? "selected" : "");
			printf("<option value='%d' %s>Host acknowledgements\n", NOTIFICATION_HOST_ACK, (notification_options == NOTIFICATION_HOST_ACK) ? "selected" : "");
			printf("<option value='%d' %s>Host down\n", NOTIFICATION_HOST_DOWN, (notification_options == NOTIFICATION_HOST_DOWN) ? "selected" : "");
			printf("<option value='%d' %s>Host unreachable\n", NOTIFICATION_HOST_UNREACHABLE, (notification_options == NOTIFICATION_HOST_UNREACHABLE) ? "selected" : "");
			printf("<option value='%d' %s>Host recovery\n", NOTIFICATION_HOST_RECOVERY, (notification_options == NOTIFICATION_HOST_RECOVERY) ? "selected" : "");
			printf("<option value='%d' %s>Host flapping\n", NOTIFICATION_HOST_FLAP, (notification_options == NOTIFICATION_HOST_FLAP) ? "selected" : "");
		}
		printf("</select></td>\n");
		printf("</tr>\n");

		/* Order */
		printf("<tr><td align='right'>Order:</td>");
		printf("<td nowrap><input type='radio' name='order' value='new2old' %s> Newer Entries First&nbsp;&nbsp;| <input type='radio' name='order' value='old2new' %s> Older Entries First</td></tr>\n", (reverse == TRUE) ? "" : "checked", (reverse == TRUE) ? "checked" : "");

		/* Timeperiod */
		printf("<tr><td align='left'>Timeperiod:</td>");
		printf("<td align='left'>\n");

		printf("<select id='selecttp' name='timeperiod' onChange=\"var i=document.getElementById('selecttp').selectedIndex; if (document.getElementById('selecttp').options[i].value == 'custom') { $( '#custtime' ).toggle( 'blind', {}, 200 ); } else { $( '#custtime' ).toggle( 'blind', {}, 200 ); }\">\n");
		printf("<option value='singleday' %s>Single Day\n", (timeperiod_type == TIMEPERIOD_SINGLE_DAY) ? "selected" : "");
		printf("<option value='today' %s>Today\n", (timeperiod_type == TIMEPERIOD_TODAY) ? "selected" : "");
		printf("<option value='last24hours' %s>Last 24 Hours\n", (timeperiod_type == TIMEPERIOD_LAST24HOURS) ? "selected" : "");
		printf("<option value='thisweek' %s>This Week\n", (timeperiod_type == TIMEPERIOD_THISWEEK) ? "selected" : "");
		printf("<option value='last7days' %s>Last 7 Days\n", (timeperiod_type == TIMEPERIOD_LAST7DAYS) ? "selected" : "");
		printf("<option value='lastweek' %s>Last Week\n", (timeperiod_type == TIMEPERIOD_LASTWEEK) ? "selected" : "");
		printf("<option value='thismonth' %s>This Month\n", (timeperiod_type == TIMEPERIOD_THISMONTH) ? "selected" : "");
		printf("<option value='last31days' %s>Last 31 Days\n", (timeperiod_type == TIMEPERIOD_LAST31DAYS) ? "selected" : "");
		printf("<option value='lastmonth' %s>Last Month\n", (timeperiod_type == TIMEPERIOD_LASTMONTH) ? "selected" : "");
		printf("<option value='thisyear' %s>This Year\n", (timeperiod_type == TIMEPERIOD_THISYEAR) ? "selected" : "");
		printf("<option value='lastyear' %s>Last Year\n", (timeperiod_type == TIMEPERIOD_LASTYEAR) ? "selected" : "");
		printf("<option value='custom' %s>* CUSTOM PERIOD *\n", (timeperiod_type == TIMEPERIOD_CUSTOM) ? "selected" : "");
		printf("</select>\n");
		printf("<div id='custtime' style='display:%s;'>", (timeperiod_type == TIMEPERIOD_CUSTOM) ? "" : "none");

		printf("<br><table border='0' cellspacing='0' cellpadding='0'>\n");
		get_time_string(&ts_start, buffer, sizeof(buffer) - 1, SHORT_DATE_TIME);
		printf("<tr><td>Start:&nbsp;&nbsp;</td><td><input type='text' class='timepicker' name='start_time' value='%s' size='25'></td></tr>", buffer);

		get_time_string(&ts_end, buffer, sizeof(buffer) - 1, SHORT_DATE_TIME);
		printf("<tr><td>End:&nbsp;&nbsp;</td><td><input type='text' class='timepicker' name='end_time' value='%s' size='25'></td></tr></table></div>", buffer);

		printf("</td></tr>\n");

		/* submit Button */
		printf("<tr><td><input type='submit' value='Update'></td><td align='right'><input type='reset' value='Reset' onClick=\"window.location.href='%s?order=new2old&amp;timeperiod=singleday&amp;limit=%d'\">&nbsp;</td></tr>\n", NOTIFICATIONS_CGI, result_limit);

		printf("</table>\n");
		printf("</form>\n");

		printf("</td>\n");

		/* end of top table */
		printf("</tr>\n");
		printf("</table>\n");
	}

	/* display notifications */
	display_notifications();

	/* display footer */
	document_footer(CGI_ID);

	/* free allocated memory */
	free_memory();

	return OK;
}
예제 #4
0
파일: showlog.c 프로젝트: hornet2001/icinga
/** @brief Yes we need a main function **/
int main(void) {
	int result = OK;

	/* get the CGI variables passed in the URL */
	process_cgivars();

	/* reset internal variables */
	reset_cgi_vars();

	/* read the CGI configuration file */
	result = read_cgi_config_file(get_cgi_config_location());
	if (result == ERROR) {
		document_header(CGI_ID, FALSE, "Error");
		print_error(get_cgi_config_location(), ERROR_CGI_CFG_FILE, FALSE);
		document_footer(CGI_ID);
		return ERROR;
	}

	/* read the main configuration file */
	result = read_main_config_file(main_config_file);
	if (result == ERROR) {
		document_header(CGI_ID, FALSE, "Error");
		print_error(main_config_file, ERROR_CGI_MAIN_CFG, FALSE);
		document_footer(CGI_ID);
		return ERROR;
	}

	/* read all object configuration data */
	result = read_all_object_configuration_data(main_config_file, READ_ALL_OBJECT_DATA);
	if (result == ERROR) {
		document_header(CGI_ID, FALSE, "Error");
		print_error(NULL, ERROR_CGI_OBJECT_DATA, FALSE);
		document_footer(CGI_ID);
		return ERROR;
	}

	/* This requires the date_format parameter in the main config file */
	if (timeperiod_type == TIMEPERIOD_CUSTOM) {
		if (strcmp(start_time_string, ""))
			string_to_time(start_time_string, &ts_start);

		if (strcmp(end_time_string, ""))
			string_to_time(end_time_string, &ts_end);
	}

	/* overwrite config value with amount we got via GET */
	result_limit = (get_result_limit != -1) ? get_result_limit : result_limit;

	/* for json and csv output return all by default */
	if (get_result_limit == -1 && (content_type == JSON_CONTENT || content_type == CSV_CONTENT))
		result_limit = 0;

	document_header(CGI_ID, TRUE, "Log File");

	/* calculate timestamps for reading logs */
	convert_timeperiod_to_times(timeperiod_type, &ts_start, &ts_end);

	/* get authentication information */
	get_authentication_information(&current_authdata);

	if (display_header == TRUE) {

		/* start input form */
		printf("<form method='GET' style='margin:0;' action='%s'>\n", SHOWLOG_CGI);
		printf("<input type='hidden' name='ts_start' value='%lu'>\n", ts_start);
		printf("<input type='hidden' name='ts_end' value='%lu'>\n", ts_end);
		printf("<input type='hidden' name='limit' value='%d'>\n", result_limit);

		/* begin top table */
		printf("<table border=0 width=100%% cellpadding=0 cellspacing=0>\n");
		printf("<tr>\n");

		/* left column of top table - info box */
		printf("<td align=left valign=top width=33%%>\n");
		display_info_table("Event Log", &current_authdata, daemon_check);
		printf("</td>\n");

		/* middle column of top table - log file navigation options */
		printf("<td align=center valign=top width=33%%>\n");
		display_nav_table(ts_start, ts_end);
		printf("</td>\n");

		/* right hand column of top row */
		printf("<td align=right valign=top width=33%%>\n");

		/* show filter */
		printf("<table border=0 cellspacing=0 cellpadding=0 CLASS='optBox' align=right><tr><td>\n");
		show_filter();
		printf("</td></tr>\n");

		printf("</table>\n");

		printf("</td>\n");

		/* end of top table */
		printf("</tr>\n");
		printf("</table>\n");

		printf("</form>\n");
	}

	/* check to see if the user is authorized to view the log file */
	if (is_authorized_for_system_information(&current_authdata) == FALSE) {
		print_generic_error_message("It appears as though you do not have permission to view the log file...", "If you believe this is an error, check the HTTP server authentication requirements for accessing this CGI and check the authorization options in your CGI configuration file.", 0);
		return ERROR;
	}

	/* display the contents of the log file */
	display_logentries();

	document_footer(CGI_ID);

	/* free allocated memory */
	free_memory();

	return OK;
}
예제 #5
0
파일: ggs.c 프로젝트: markkings/reversi
/**
 * @brief ggs_parse_move
 *
 * Translate input word into time (as ms).
 *
 * @param time Time.
 * @param word Word.
 * @return true if parsing succeed.
 */
static bool ggs_parse_time(int *time, const char *word) {
	errno = 0;	
	*time = string_to_time(parse_skip_spaces(word));
	return errno == 0;
}
예제 #6
0
/**
 * Handle a file request.
 */
void FileHandler::handle_request(struct evhttp_request* request) {
    //Figure out which file to get.
    std::string uri(request_uri_path(request));
    std::string relative_file_path(uri.substr(url_root_.size()));
    
    //Check whether the user entered a valid file path.
    if (!this->is_permitted_file_path(relative_file_path)) {
        // Invalid request.  Cannot find the file.
        server_->send_response(request, std::string(""), HTTP_NOTFOUND);
        return;
    }
    
    //Attempt to load the file.
    //std::string full_path = file_root_ + relative_file_path;
    CachedFilePtr cached_file;
    const bool has_loaded = file_cache_->get_cached_object(relative_file_path, cached_file);
    
    if (!has_loaded) {
        // No such file.
        server_->send_response(request, std::string(""), HTTP_NOTFOUND);
        return;
    }
    
    // Start writing the response.
    // Add Last-Modified response header.
    const time_t last_modified = cached_file->last_modified();
    struct evkeyvalq* response_headers = evhttp_request_get_output_headers(request);
    shared_array<char> sz_last_modified(time_to_string(last_modified));
    evhttp_add_header(response_headers, "Last-Modified", sz_last_modified.get());
    
    // Add Cache Control response header.
    if (!cache_control_.empty()) {
        evhttp_add_header(response_headers, "Cache-Control", cache_control_.c_str());
    }
    
    // Set the Content-Type header.
    std::string extension;
    size_t extension_start = relative_file_path.find_last_of(".");
    const char* content_type = NULL;
    
    if (extension_start != std::string::npos) {
        extension = relative_file_path.substr(extension_start + 1);
    }
    
    if      (extension == "css")    { content_type = "text/css";} 
    else if (extension == "js")     { content_type = "text/javascript"; }
    else if (extension == "png")    { content_type = "image/png"; }
    else if (extension == "jpeg")   { content_type = "image/jpeg"; }
    else if (extension == "jpg")    { content_type = "image/jpeg"; }
    else if (extension == "gif")    { content_type = "image/gif"; }
    else if (extension == "ico")    { content_type = "image/vnd.microsoft.icon"; }
    else if (extension == "txt")    { content_type = "text/plain"; }
    else if (extension == "h")      { content_type = "text/plain"; }
    else if (extension == "cpp")    { content_type = "text/plain"; }
    else if (extension == "hpp")    { content_type = "text/plain"; }
    else if (extension == "html")   { content_type = "text/html"; }
    else                            { content_type = "text/html"; }
    
    evhttp_add_header(response_headers, "Content-Type", content_type);
    
    // Check whether the user agent already has the right version of the file.
    // TODO: need to implement handling "If-None-Match" header.
    struct evkeyvalq* request_headers = evhttp_request_get_input_headers(request);
    const char* if_modified_since = evhttp_find_header(request_headers, "If-Modified-Since");
    const time_t t_if_modified_since = string_to_time(if_modified_since);
    
    if (t_if_modified_since >= cached_file->last_modified()) {
        server_->send_response(request, std::string(""), HTTP_NOTMODIFIED);
        return;
    }
    
    // Respond with the file data..
    shared_array<char> file_data = cached_file->data();
    size_t data_size = cached_file->data_size();
    server_->send_response_data(request, file_data.get(), data_size, HTTP_OK);
}