#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <time.h>
#include "../base.h"

#define PORT 23240

int main()
{
	int sockfd, newsockfd;
	int num_r, num_w;
	int errcode;
	socklen_t clilen=0;
	struct sockaddr_in cli_addr, serv_addr;
	struct timespec start[3], stop[3];
	float diff_time;
	float exec_time = 0.0;

	sockfd = socket(AF_INET, SOCK_STREAM, 0);
	if (sockfd == -1) {
		system_error();
	}

	memset(&serv_addr, 0, sizeof(serv_addr));
	serv_addr.sin_family = AF_INET;
	serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
	serv_addr.sin_port = htons(PORT);
	int optval = 1;
	setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof(optval));

	errcode = bind(sockfd, (struct sockaddr*)&serv_addr, sizeof(struct sockaddr));
	if (errcode == -1) {
		system_error();
	}

	if (listen(sockfd, 5) == -1) {
		system_error();
	}

	while (1) {
		newsockfd = accept(sockfd, (struct sockaddr*)&cli_addr, &clilen);
		if (newsockfd == -1) {
			system_error();
		}
		FILE *stream = fdopen(newsockfd, "r+");
		FILE *scan_fptr;
		float result;

		fwrite("GRANT SERVICE", sizeof(char), 14, stream);

		/* Get size of file */
		int file_size;
		num_r = fread(&file_size, sizeof(int), 1, stream);
		/* Receive file, each time with 1KB */
		char temp[2001];
		int num;
		scan_fptr = fopen("file_to_scan", "w");
		while (file_size != 0) {
			if (file_size > 2000)
				num = 2000;
			else
				num = file_size;
				
			num_r = fread(temp, sizeof(char), num, stream);
			num_w = fwrite(temp, sizeof(char), num, scan_fptr);
			file_size -= num;
		}
		fclose(scan_fptr);

		int infected = 0;
		char command[100];
		clock_gettime(CLOCK_MONOTONIC, &start[0]);
		{
			FILE *fptr;
			char buff[100];

			sprintf(command, "clamscan file_to_scan 2>&1");
			if (!(fptr = popen(command, "r"))) {
				system_error();
			} 

			while (fgets(buff, 100, fptr) != NULL) {
				if (strstr(buff, "Infected files") != NULL) {
					sscanf(buff, "%*s%*s%d", &infected);
				}   
				else if (strstr(buff, "Time") != NULL) {
					sscanf(buff, "%*s%f", &diff_time);
				}   
			}   
			pclose(fptr);

			if (infected > 0)
				printf("scan result: %d file be infected\n", infected);
			else 
				printf("scan result: no infected file\n");
		}
		clock_gettime(CLOCK_MONOTONIC, &stop[0]);
		exec_time = calc_diff_time(&start[0], &stop[0]);

		exec_time = exec_time/1000; /* us */
		fwrite(&exec_time, sizeof(float), 1, stream);
		printf("exec time: %f\n", exec_time);
		fwrite(&infected, sizeof(int), 1, stream);

		fclose(stream);
		close(newsockfd);
	}
	close(sockfd);

	return 0;
}

