#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/time.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <sys/sem.h>
#include <sys/msg.h>
#include <sys/file.h>
#include <sys/wait.h>
#include <sys/sysinfo.h>
#include <sys/vfs.h>
#include <stdio.h>
#include <ctype.h>
#include <signal.h>
#include <time.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <string.h>
#include <poll.h>
#include <strings.h>
#include <sys/time.h>
#include <stdlib.h>
#include <pwd.h>
#include <grp.h>
#include <zlib.h>
#include <stdarg.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "base32.h"
#include "gix_img.h"
#include "sysdefs.h"

#define GIX_INETD_VERSION "GIX-INETD-ADMIN-SERVER 3.01-TS"
#define CONFIG_FILE "/big/GIX_INETD/conf/ginetd.conf"
#define LOG_FILE    "/big/GIX_INETD/logs/ginetd.log"
#define INETD_KEY   0xCAFE1970
#define INETD_KEY2 0xDAFE1970
#define INETD_OPTIONS 0xAFFE1970
#define MAX_CONNS   8192
#define MAX_BACKLOG 10

#define CTRL_SHM 0xAFFE0000


#define MAX_BUFFER 4096

int shm_id;
int webserver_pid;
int entries;
char prefix[1024];
int global_index;
int connection_index;
int semid;
int semid2;
int shmid_options;
int msg_id;

char my_hostname[1024];


struct gix_inetd_options *gix_options = NULL;

struct gix_inetd_options {
	int debug;
	char tftp_enabled;
	char tftp_readonly;
	char tftp_root[1024];
	int tftp_pid;
};




struct interface_config *if_config;
int if_count;


#define TEST_PING  1
#define TEST_HTTP  2
#define TEST_HTTPS 3
#define TEST_POP3  4
#define TEST_SMTP  5


char *get_interface_address(char *ifname, int addrfamily){
	int i;
	for ( i = 0; i < if_count; i++ ){
		if ( if_config[i].addrtype == addrfamily && strcmp(ifname,if_config[i].ethname) == 0 ) return(if_config[i].addr);
	}

	return("");
}


char *get_diskname(char *dev){
	static char retval[32];
	char copy[1024];
	char *help;
	char *ptr;
	int r_major, r_minor;
	FILE *fp;
	char buf[1024];


	if ( *dev == '/' ){ // A path...we look in /etc/fstab
		fp = fopen("/etc/fstab","r");
		if ( fp == NULL ) return("n.a.");
		while ( fgets(buf,1024,fp) != NULL ){
			help = buf;
			ptr = strtok_r(buf,"\t \r\n",&help);
			if ( ptr == NULL ) continue;
			if ( strncmp(ptr,"/dev/",5) == 0 ) ptr += 5;
			strcpy(retval,ptr);
			ptr = strtok_r(NULL,"\t \r\n",&help);
			if ( ptr == NULL ) continue;
			if ( strcmp(ptr,dev) == 0 ){
				fclose(fp);
				return(retval);
			}

		}
		fclose(fp);
		return("n.a.");
	}


	strcpy(copy,dev);
	help = copy;
	ptr = strtok_r(copy,": \t\r\n",&help);
	if ( ptr == NULL ) return("n.A.");	
	r_major = atoi(ptr);
	ptr = strtok_r(NULL,": \t\r\n",&help);
	if ( ptr == NULL ) return("N.a.");	
	r_minor = atoi(ptr);
	
	fp = fopen("/proc/diskstats","r");
	if ( fp == NULL ) return("N.A.");
	while ( fgets(buf,1024,fp) != NULL ){
		int major, minor;
		char *ptr;
		help = buf;
		ptr = strtok_r(buf,"\t \r\n",&help);
		if ( ptr == NULL ) continue;
		major = atoi(ptr);
		ptr = strtok_r(NULL,"\t \r\n",&help);
		if ( ptr == NULL ) continue;
		minor = atoi(ptr);
		ptr = strtok_r(NULL,"\t \r\n",&help);
		if ( ptr == NULL ) continue;
		if ( major == r_major && minor == r_minor ){
			strcpy(retval,ptr);
			fclose(fp);
			return(retval);
		}
	}
	fclose(fp);

	return("n.a.");
}



struct test_info {
	int test_kind;
	char remote_name[1024];
	char url[1024];
	int port;
	int addr_family; // AF_INET, AT_INET6
	
	
};

char *convert_bytes(double inp,char *prefix){
	static char retval[1024];

	sprintf(retval,"%d&nbsp;%s",(int)inp,prefix);
	if ( inp > 1024.0 ) sprintf(retval,"%.02f&nbsp;k%s",inp/1024.0,prefix);
	if ( inp > (1024.0*1024.0) ) sprintf(retval,"%.02f&nbsp;M%s",inp/(1024.0*1024.0),prefix);
	if ( inp > (1024.0*1024.0*1024.0) ) sprintf(retval,"%.02f&nbsp;G%s",inp/(1024.0*1024.0*1024.0),prefix);
	if ( inp > (1024.0*1024.0*1024.0*1024.0) ) sprintf(retval,"%.02f&nbsp;T%s",inp/(1024.0*1024.0*1024.0*1024.0),prefix);
	return(retval);
}


struct fsinfo {
	char path[1024];
};

struct ethinfo {
	char ifname[64];
	char if_mac[128];
	char if_ipv4[64];
	char if_ipv6[256];
	struct timeval stamp1;	
	struct timeval stamp2;	

	long long bytes_receive_1;
	long long bytes_receive_2;
	char bytes_receive_t[64];
	double bytes_receive_sec;
	char bytes_receive_sec_t[64];

	long long packets_receive_1;
	long long packets_receive_2;
	char packets_receive_t[64];
	double packets_receive_sec;
	char packets_receive_sec_t[64];

	long long error_receive_1;
	long long error_receive_2;
	char error_receive_t[64];
	double error_receive_sec;
	char error_receive_sec_t[64];

	long long drop_receive_1;
	long long drop_receive_2;
	char drop_receive_t[64];
	double drop_receive_sec;
	char drop_receive_sec_t[64];

	long long bytes_transmit_1;
	long long bytes_transmit_2;
	char bytes_transmit_t[64];
	double bytes_transmit_sec;
	char bytes_transmit_sec_t[64];

	long long packets_transmit_1;
	long long packets_transmit_2;
	char packets_transmit_t[64];
	double packets_transmit_sec;
	char packets_transmit_sec_t[64];

	long long error_transmit_1;
	long long error_transmit_2;
	char error_transmit_t[64];
	double error_transmit_sec;
	char error_transmit_sec_t[64];

	long long drop_transmit_1;
	long long drop_transmit_2;
	char drop_transmit_t[64];
	double drop_transmit_sec;
	char drop_transmit_sec_t[64];

	long long colls_1;
	long long colls_2;
	char colls_t[64];
	double colls_sec;
	char colls_sec_t[64];

	double timestamp_calc;
};


struct process_info {
	int pid;
	int ppid;
	char program[256];
	unsigned long vmsize;
	char vmtext[32];
	long priority;
	long nice;
	unsigned long utime;
	unsigned long stime;
	struct timeval stamp;
	unsigned long utime2; // After sleeping 0.5 secs --> Check ticks again
	unsigned long stime2; // After sleeping 0.5 secs --> Check ticks again
	struct timeval stamp2; // To get the exact 0.5 seconds :-)
	time_t ptime;
	time_t starttime;
	double cpu_usage;
	long num_threads;
	long rss;
	int cpu;
};







char *gix_display_uptime(time_t starttime,char *pathname, char *buf){
        struct stat st;
        time_t tim;
        int seconds;

        if ( starttime == 0 && pathname == NULL){
                // We want system uptime
                struct sysinfo sys;
                sysinfo(&sys);
                seconds   = sys.uptime;
                // r_seconds = sys.uptime;
        } else {
                if ( pathname != NULL ){
                        if ( stat(pathname,&st) != 0 ){
                                tim = time(NULL);
                                seconds = 0;
                        } else {
                                seconds = time(NULL) - st.st_mtime;
                        }
                } else {
                        seconds = time(NULL) - starttime;
                }
        }
        strcpy(buf,"");
        if ( seconds > (365 * 24 * 3600) ){
                if ( seconds / (365 * 24 * 3600) == 1 )
                        sprintf(&buf[strlen(buf)],"%d year ",seconds / (365 * 24 * 3600) );
                else
                        sprintf(&buf[strlen(buf)],"%d years ",seconds / (365 * 24 * 3600) );
                seconds -= (seconds / (365 * 24 * 3600)) * (365 * 24 * 3600);
        }
        if ( seconds > (7 * 24 * 3600) ){
                if ( seconds / (7 * 24 * 3600)  == 1 )
                        sprintf(&buf[strlen(buf)],"%d week ",seconds / (7 * 24 * 3600) );
                else
                        sprintf(&buf[strlen(buf)],"%d weeks ",seconds / (7 * 24 * 3600) );
                seconds -= (seconds / (7 * 24 * 3600)) * (7 * 24 * 3600);
        }
        if ( seconds > ( 24 * 3600) ){
                if ( seconds / (24 * 3600)  == 1 )
                        sprintf(&buf[strlen(buf)],"%d day ",seconds / (24 * 3600) );
                else
                        sprintf(&buf[strlen(buf)],"%d days ",seconds / (24 * 3600) );
                seconds -= (seconds / (24 * 3600)) * (24 * 3600);
        }
        if ( seconds > (  3600) ){
                if ( seconds / 3600  == 1 )
                        sprintf(&buf[strlen(buf)],"%d hour ",seconds / ( 3600) );
                else
                        sprintf(&buf[strlen(buf)],"%d hours ",seconds / ( 3600) );
                seconds -= (seconds / ( 3600)) * ( 3600);
        }
        if ( seconds > (  60) ){
                if ( (seconds / 60) == 1 )
                        sprintf(&buf[strlen(buf)],"%d minute ",seconds / ( 60) );
                else
                        sprintf(&buf[strlen(buf)],"%d minutes ",seconds / ( 60) );
                seconds -= (seconds / ( 60)) * ( 60);
        }
        if ( seconds == 1 )
                sprintf(&buf[strlen(buf)],"%d second",seconds );
        else
                sprintf(&buf[strlen(buf)],"%d seconds",seconds );
        return(buf);

}



struct connection {
	int sock;
	int pid;
	int cpid; // Child-PID i.e.: The program executed
	char source[128];
	char target[128];
	unsigned  port;
	unsigned  t_port;
	time_t created;
	time_t lastin;
};

struct server {
        unsigned short port;
        time_t timeout;
	time_t data_timeout;
        char cmdline[1024];
        int max_conns;
        int pid;
	unsigned short family;  // AF_INET or AF_INET6
	time_t reset;
	int connections;
	int total_count;
	struct connection co[MAX_CONNS];
};

char *month_name[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
char *wday_name[]  = { "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat" };


char *ctime_o(time_t *tim, char *retbuf){
        struct tm tm;

        gmtime_r(tim,&tm);

        sprintf(retbuf,"%s, %d %s %04d %02d:%02d:%02d GMT",
                wday_name[tm.tm_wday], tm.tm_mday, month_name[tm.tm_mon], tm.tm_year + 1900,
                tm.tm_hour, tm.tm_min, tm.tm_sec);
        return(retbuf);
}



struct server *servlist;



void logger(char *prefix, const char *fmt, ...){
	char p[102400]; 
	struct stat st;
	FILE *log;
	va_list ap;
	struct timeval tv;
	struct tm _tm;
	struct tm *tm;
	char datestamp[512];
	gettimeofday(&tv,NULL);
	tm = localtime_r(&tv.tv_sec,&_tm);



	sprintf(datestamp,"[%04d-%02d-%02d %02d:%02d:%02d.%06d]{%d} (%s)",
		tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
		tm->tm_hour, tm->tm_min, tm->tm_sec, tv.tv_usec,
		getpid(), prefix == NULL ? "NULL" : prefix );

	va_start(ap,fmt);
	vsnprintf(p,102400,fmt,ap);
	va_end(ap);

	log = fopen(LOG_FILE,"a");
	if ( log == NULL ) return;
	// while ( flock(fileno(log),LOCK_EX)  && errno == EINTR );
	fprintf(log,"%s %s",datestamp,p);
	fflush(log);	
	// while ( flock(fileno(log),LOCK_UN)  && errno == EINTR );
	fclose(log);
	/*
	if ( stat(LOG_FILE,&st) == 0 && st.st_size > (10 * 1024 * 1024 )){
		char newname[1024];
		sprintf(newname,"%s_%04d-%02d-%02d_%02d_%02d_%02d",LOG_FILE,tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec);
		rename(LOG_FILE,newname);
	}	
	*/
}

int _gzip_string(char *file, int line, char *in, char *out){
	FILE *tmp;
	gzFile gz;
	int newfd;
	int ori_size;
	int retval;
	struct stat st;

	ori_size = strlen(in);
	tmp = tmpfile();
	if ( tmp == NULL ) return(-1);
	gz = gzdopen(fileno(tmp),"w");
	if ( gz == NULL ){ fclose(tmp); return(-2); }
	retval = gzwrite(gz,in,ori_size);
	if ( retval != ori_size ){ fclose(tmp); return(-3); }
	newfd = dup(fileno(tmp));	
	gzclose(gz);
	if ( fstat(newfd,&st) ){ close(newfd); return(-4); }
	bzero(out,st.st_size + 1);	
	if ( lseek(newfd,(off_t)0,SEEK_SET) == (off_t) -1 ){
		close(newfd); 
		return(-5);
	}
	if ( read(newfd,out,st.st_size) != st.st_size ){
		close(newfd); 
		return(-6);
	}
	close(newfd);
	logger(prefix,"GZIP(%s:%d): [%d] --> [%d]\n",file,line,strlen(in),st.st_size);
	return(st.st_size);
}

#define gzip_string(a,b) _gzip_string(__FILE__,__LINE__,(a),(b))


int _m_kill(char *file, int line, int pid, int sig){
	// logger(prefix,"[%s: %d] KILLER PROCESS(%d) --> %d, Signal: %d\n",file,line,getpid(),pid,sig);
	if ( pid ) kill(pid,sig);
}

#define m_kill(a,b) _m_kill(__FILE__,__LINE__,(a),(b))

static int comparer(const void *_p1, const void *_p2){
	struct process_info *p1;
	struct process_info *p2;
	unsigned long time1,time2;

	p1 = (struct process_info *)_p1;
	p2 = (struct process_info *)_p2;

	if ( p1->cpu_usage != p2->cpu_usage ){
		return((int) ((p2->cpu_usage - p1->cpu_usage) * 100.0) );
	} else {
		return(p2->ptime - p1->ptime);
	}


}
static int comparer_eth(const void *_p1, const void *_p2){
	struct ethinfo *p1;
	struct ethinfo *p2;

	p1 = (struct ethinfo *)_p1;
	p2 = (struct ethinfo *)_p2;
	return(strcmp(p1->ifname,p2->ifname));
}


struct socket_info {
	char local_addr[256];
	char remote_addr[256];
	unsigned int local_port;	
	unsigned int remote_port;	
	int family;
	int state;
	unsigned long inode;
	unsigned short timer_kind;
	unsigned long timer_value;
	int uid;
	int pid;
	int protocol;
};

char *procnet[] = { "/proc/net/tcp" , "/proc/net/tcp6", "/proc/net/udp", "/proc/net/udp6", "/proc/net/unix",  NULL };


char *get_ipv4(char *addr){
	static char raddr[256];
	unsigned int a;
	unsigned int b;
	unsigned int c;
	unsigned int d;
	if ( sscanf(addr,"%02X%02X%02X%02X",&a,&b,&c,&d) != 4 ){
		return("0.0.0.0");
	} else {
		sprintf(raddr,"%d.%d.%d.%d",d,c,b,a);
		return(raddr);
	}
}

#define SOCK6_ADDR socky.sin6_addr.s6_addr

char *get_ipv6(char *addr){
	unsigned int addrlist[16];
	static char raddr[256];
	struct sockaddr_in6 socky;
	if ( sscanf(addr,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
		&addrlist[3], &addrlist[2], &addrlist[1], &addrlist[0],
		&addrlist[7], &addrlist[6], &addrlist[5], &addrlist[4],
		&addrlist[11], &addrlist[10], &addrlist[9], &addrlist[8],
		&addrlist[15], &addrlist[14], &addrlist[13], &addrlist[12]) != 16 ){
		return("invalid");
	} else {
		int i;
		for ( i = 0; i < 16; i ++ ){
			SOCK6_ADDR[i] = (unsigned char) addrlist[i];
		}
		bzero(raddr,256);
		/*
		sprintf(raddr,"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
			SOCK6_ADDR[0],SOCK6_ADDR[1],SOCK6_ADDR[2],SOCK6_ADDR[3],
			SOCK6_ADDR[4],SOCK6_ADDR[5],SOCK6_ADDR[6],SOCK6_ADDR[7],
			SOCK6_ADDR[8],SOCK6_ADDR[9],SOCK6_ADDR[10],SOCK6_ADDR[11],
			SOCK6_ADDR[12],SOCK6_ADDR[13],SOCK6_ADDR[14],SOCK6_ADDR[15]);
		*/
		inet_ntop(AF_INET6,&(socky.sin6_addr),raddr,256);	
		return(raddr);
	}
			
}

struct socket_info *get_socket_info(unsigned long inode, int rpid){
	static struct socket_info si;
	unsigned char local[256];
	unsigned char remote[256];
	unsigned char _state[16];
	unsigned int local_port;
	unsigned int remote_port;
	unsigned long timer_value;
	unsigned int timer_kind;
	unsigned long f_inode;
	int uid; 
	int state;
	int fi;
	FILE *fp;
	char buf[1024];

	bzero(&si,sizeof( si));
	for ( fi = 0; procnet[fi] != NULL; fi++ ){
		fp = fopen(procnet[fi],"r");
		if ( fp == NULL ){
			logger("SOCKINFO","WARNING(%s:%d): Cannot open [%s]\n",__FILE__,__LINE__,procnet[fi]);
			return(NULL);
		}	
		while ( fgets(buf,1024,fp) != NULL ){
			char *ptr;
			char *help;
			help = buf;
			bzero(local,sizeof(local));
			bzero(remote,sizeof(remote));
			bzero(_state,sizeof(_state));
			state = 0;
			local_port = 0;	
			remote_port = 0;	
			f_inode = 0;	
			timer_value = 0;	
			timer_kind = 0;	
			if ( strcmp(procnet[fi],"/proc/net/udp") == 0 || strcmp(procnet[fi],"/proc/net/udp6") == 0 ) {
				ptr = strtok_r(buf," \t\r\n",&help);
				if ( ptr == NULL ) continue; // INDEX
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // LOCAL
				strcpy(local,ptr);
				ptr = &local[strlen(local)-1]; 
				while ( ptr > (char *)&local[0] && *ptr != ':' ) ptr--;
				if ( *ptr != ':' ) continue; // Headline is skipped
				*ptr = '\0';
				ptr++;
				if ( sscanf(ptr,"%04X",&local_port) != 1 ) continue;
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // REMOTE
				strcpy(remote,ptr);
				ptr = &remote[strlen(remote)-1]; 
				while ( ptr > (char *)&remote[0] && *ptr != ':' ) ptr--;
				if ( *ptr != ':' ) continue; // Headline is skipped
				*ptr = '\0';
				ptr++;
				if ( sscanf(ptr,"%04X",&remote_port) != 1 ) continue;
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // STATE
				strcpy(_state,ptr);
				sscanf(_state,"%02X",&state);
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // TX-Q, RX-Q
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // TM->WHEN
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // RET
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // UID
				uid = atoi(ptr);
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // TIMEOUT
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // INODE
				f_inode = atol(ptr);
			}
			if ( strcmp(procnet[fi],"/proc/net/unix") == 0 ){
				ptr = strtok_r(buf," \t\r\n",&help);
				if ( ptr == NULL ) continue; // NUM
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // REF
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // PROT
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // FLAGS
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // TYPE
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // State
				if ( sscanf(ptr,"%02X",&state) != 1 ) continue;
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // Inode
				f_inode = atol(ptr);
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // Inode
				strcpy(local,ptr);
			}
			if ( strcmp(procnet[fi],"/proc/net/tcp") == 0 || strcmp(procnet[fi],"/proc/net/tcp6") == 0 ) {
				ptr = strtok_r(buf," \t\r\n",&help);
				if ( ptr == NULL ) continue; // INDEX
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // LOCAL
				strcpy(local,ptr);
				ptr = &local[strlen(local)-1]; 
				while ( ptr > (char *)&local[0] && *ptr != ':' ) ptr--;
				if ( *ptr != ':' ) continue; // Headline is skipped
				*ptr = '\0';
				ptr++;
				if ( sscanf(ptr,"%04X",&local_port) != 1 ) continue;
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // REMOTE
				strcpy(remote,ptr);
				ptr = &remote[strlen(remote)-1]; 
				while ( ptr > (char *)&remote[0] && *ptr != ':' ) ptr--;
				if ( *ptr != ':' ) continue; // Headline is skipped
				*ptr = '\0';
				ptr++;
				if ( sscanf(ptr,"%04X",&remote_port) != 1 ) continue;
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // STATE
				strcpy(_state,ptr);
				sscanf(_state,"%02X",&state);
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // NIX
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // TIMER
				if ( sscanf(ptr,"%02X:%08lX",&timer_kind,&timer_value) != 2 ) continue;
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // SOMETHING
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // UID
				uid = atoi(ptr);
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // TIMEOUT
				ptr = strtok_r(NULL," \t\r\n",&help);
				if ( ptr == NULL ) continue; // INODE
				f_inode = atol(ptr);
			}
			if ( f_inode == inode ){
				logger("SOCKINFO","[%ld] Local: [%s]:%d Remote: [%s]:%d State: [%s] %d Timer: [%d] Value: [%ld] UID: %d Inode: %ld\n",inode,local,local_port,remote,remote_port,_state,state,timer_kind,timer_value,uid,f_inode);	
				if ( strcmp(procnet[fi],"/proc/net/tcp6") == 0 ){
					// Convert IPv4
					si.family = AF_INET6;
					si.state = state;
					si.uid = uid;
					si.timer_value = timer_value;
					si.timer_kind = timer_kind;
					si.local_port = local_port;					
					si.remote_port = remote_port;					
					si.protocol = SOCK_STREAM;
					strcpy(si.local_addr,get_ipv6(local));
					strcpy(si.remote_addr,get_ipv6(remote));
					fclose(fp);
					return(&si);
				}
				if ( strcmp(procnet[fi],"/proc/net/udp6") == 0 ){
					// Convert IPv4
					si.family = AF_INET6;
					si.state = state;
					si.uid = uid;
					si.timer_value = timer_value;
					si.timer_kind = timer_kind;
					si.local_port = local_port;					
					si.remote_port = remote_port;					
					si.protocol = SOCK_DGRAM;
					strcpy(si.local_addr,get_ipv4(local));
					strcpy(si.remote_addr,get_ipv4(remote));
					fclose(fp);
					return(&si);
				}
				if ( strcmp(procnet[fi],"/proc/net/tcp") == 0 ){
					// Convert IPv4
					si.family = AF_INET;
					si.state = state;
					si.uid = uid;
					si.timer_value = timer_value;
					si.timer_kind = timer_kind;
					si.local_port = local_port;					
					si.remote_port = remote_port;					
					si.protocol = SOCK_STREAM;
					strcpy(si.local_addr,get_ipv4(local));
					strcpy(si.remote_addr,get_ipv4(remote));
					fclose(fp);
					return(&si);
				}
				if ( strcmp(procnet[fi],"/proc/net/udp") == 0 ){
					// Convert IPv4
					si.family = AF_INET;
					si.state = state;
					si.uid = uid;
					si.timer_value = timer_value;
					si.timer_kind = timer_kind;
					si.local_port = local_port;					
					si.remote_port = remote_port;					
					si.protocol = SOCK_DGRAM;
					strcpy(si.local_addr,get_ipv4(local));
					strcpy(si.remote_addr,get_ipv4(remote));
					fclose(fp);
					return(&si);
				}
				if ( strcmp(procnet[fi],"/proc/net/unix") == 0 ){
					// Convert IPv4
					si.family = AF_UNIX;
					si.state = state;
					si.uid = uid;
					si.timer_value = 0;
					si.timer_kind = 0;
					si.local_port = 0;
					si.remote_port = 0;
					si.protocol = -1;
					strcpy(si.local_addr,local);
					strcpy(si.remote_addr,"");
					fclose(fp);
					return(&si);
				}
			}
		}
		fclose(fp);
	}

	return(NULL);
}

int sem_lock(int sem_id){
        struct sembuf ops;
	int retval;
	// logger(prefix,"SEM_LOCK (Current-Value: %d)\n",semctl(semid,0,GETVAL));
        ops.sem_num = 0;
        ops.sem_flg = 0;
        ops.sem_op  = -1;
	while (  (retval = semop(sem_id,&ops,1)) < 0 && errno == EINTR );
	// logger(prefix,"SEM_LOCK finished (Retval: %d) Error: [%s] NEWVAL: %d\n",retval, retval < 0 ? strerror(errno) : "no error" ,semctl(semid,0,GETVAL));
        return(retval);
}
int sem_unlock(int sem_id){
        struct sembuf ops;
	int retval;
	// logger(prefix,"SEM_UNLOCK (Current-Value: %d)\n",semctl(semid,0,GETVAL));
        ops.sem_num = 0;
        ops.sem_flg = 0;
        ops.sem_op  = 1;
	while (  (retval = semop(sem_id,&ops,1)) < 0 && errno == EINTR );
	// logger(prefix,"SEM_UNLOCK finished (Retval: %d) Error: [%s] NEWVAL: %d\n",retval, retval < 0 ? strerror(errno) : "no error",semctl(semid,0,GETVAL) );
        return(retval);
}
int sem_set(int sem_id,int val){
        struct sembuf ops;
        ops.sem_num = 0;
        ops.sem_flg = 0;
        ops.sem_op  = val;
        return(semop(sem_id,&ops,1));
}

#define CCON servlist[global_index].co[connection_index]
#define CSERVER servlist[global_index]

void main_reaper(){
	int status;
	int pid;
	while ( (pid = wait(&status)) < 0 );
	// logger(prefix,"Process %d exited with Status: %d\n",pid,status);
}



struct message {
	int pid;
	char mtext[1];	
};
void slave_reaper(int sig, siginfo_t *siginfo, void *context ){
	struct message mess;
	int status;
	int pid;
	while ( (pid = wait(&status)) < 0 );
	// logger(prefix,"WHILE_WAIT AT SLOT %d --> %d received iIGCHLD [Child: %d]\n",global_index,getpid(),pid);
	
	mess.pid = (long)pid;
	mess.mtext[0] = 'C';
	msgsnd(msg_id, &mess, sizeof(struct message), 0);
	return;
}

void garbage_collect(){
	int pid;
	int wstatus;
	struct message mess;
	char exit_msg[64];
	while ( (pid = waitpid(-1,&wstatus,WNOHANG)) > 0 ){
		sprintf(exit_msg,"OTHER REASON (0x%08X)",wstatus); 
		if ( WIFEXITED(wstatus) ){
			sprintf(exit_msg,"NORMAL EXIT");
		}
		if ( WIFSIGNALED(wstatus) ){
			sprintf(exit_msg,"RECEIVED SIGNAL %d, Core-Dump: [%s]",WTERMSIG(wstatus), WCOREDUMP(wstatus) ? "yes" : "no" );
		}
		if ( WIFSTOPPED(wstatus) ){
			sprintf(exit_msg,"RECEIVED STOP-SIGNAL");
		}
		if ( WIFCONTINUED(wstatus) ){
			sprintf(exit_msg,"RECEIVED CONT-SIGNAL");
		}
		logger(prefix,"GARBAGE-COLLECT Found PID: %d, EXIT-STATUS: %d REASON: [%s]\n",pid,WEXITSTATUS(wstatus),exit_msg);
		mess.pid = (long)pid;
		mess.mtext[0] = 'C';
		msgsnd(msg_id, &mess, sizeof(struct message), 0);
	}
}


void server_reaper(int sig, siginfo_t *siginfo, void *context){
	struct message mess;
	int status;
	int pid;
	while ( (pid = waitpid(-1,&status,WNOHANG)) > 0 ){
		mess.pid = (long)pid;
		mess.mtext[0] = 'C';
		msgsnd(msg_id, &mess, sizeof(struct message), 0);
	}
	return;
}

void server_reaper_process(){
	struct message mess;
	int status;
	int pid;
	int i;
	semid = semget(INETD_KEY + global_index,1,0);
	semid2 = semget(INETD_KEY2 + global_index,1,0);
	servlist = (struct server *)shmat(shm_id,NULL,0);
	msg_id = msgget(INETD_KEY + global_index,0);
	logger(prefix,"SERVER_REAPER_PROCESS for slot [%d] starting SEMID: %d, SEMID2: %d, Servlist: 0x%08lX\n",global_index,semid,semid2,servlist);
	while ( 1 ){
		int retval;
		// logger(prefix,"START_WAIT AT SLOT %d [%d]\n",global_index,getpid());
		/*
		while ( (pid = waitpid(-1,&status,WNOHANG)) < 0 ){
			logger(prefix,"POLLED_WAIT AT SLOT %d, ERRNO: %d [%s]\n",global_index,errno,strerror(errno));
			sleep(1);
		}
		*/
		bzero(&mess,sizeof(struct message));
		retval = msgrcv(msg_id, &mess,sizeof(struct message),0,0);
		pid = (int) mess.pid;
		sem_lock(semid2);
		for ( i = 0; i < MAX_CONNS; i++ ){
			if ( CSERVER.co[i].cpid == pid  ){
				if ( CSERVER.co[i].port != 0 ){
					logger(prefix,"RECEIVED MESSAGE --> CPID: %d Index: %d\n",pid,i);
					m_kill(CSERVER.co[i].pid,SIGTERM);
					CSERVER.connections--;
					sem_unlock(semid);
					CSERVER.co[i].port = 0;	
				}
			}
			if ( CSERVER.co[i].pid == pid ){
					logger(prefix,"RECEIVED MESSAGE --> PID: %d Index: %d\n",pid,i);
				logger(prefix,"Connection [%s:%d] closed (%d Seconds active)\n",
					CSERVER.co[i].source,CSERVER.co[i].port,time(NULL) - CSERVER.co[i].created);
				if ( CSERVER.co[i].port != 0 ){
					CSERVER.connections--;
					sem_unlock(semid);
					CSERVER.co[i].port = 0;	
				}
				m_kill(CSERVER.co[i].cpid,SIGTERM);
				m_kill(CSERVER.co[i].cpid,SIGHUP);
				m_kill(CSERVER.co[i].cpid,SIGKILL);
				CSERVER.co[i].cpid = 0;	
			}
		}
		sem_unlock(semid2);
	}
	return;
}

#define TYPE_HTML 0
#define TYPE_CSS  1
#define TYPE_AJAX 2
#define HTML_MIME "text/html"
#define CSS_MIME "text/css"
#define AJAX_MIME "text/plain"

void call_webserver(int sock, char *pwd){
	FILE *ss;
	int html_done;
	char buf[1024];
	char temp[1024];
	char temp2[1024];
	char etag[256];
	char referer[1024];
	int authok;
	int valid;
	char url[128];
	time_t tim;
	char dater[64];
	char *ptr;
	int lines;
	int type_req;
	char method[16];

	servlist = (struct server *)shmat(shm_id,NULL,0);
	if ( servlist == NULL ){
		logger(prefix,"Cannot attach SHM!\n");
		shutdown(sock,SHUT_RDWR);
		close(sock);
		return;
	}
	// logger(prefix,"CALLED ADMIN PWD: [%s]\n",pwd);
	authok = 0;
	valid  = 0;
	{
		int on;
		struct linger linny;
		linny.l_onoff = 1;
		linny.l_linger = 3; // 3 seconds and than die :-)
		if ( setsockopt(sock,SOL_SOCKET,SO_LINGER,&linny,sizeof(linny)) ){
			logger(prefix,"WARNING: cannot set socket to linger-timeout 3\n");
		}	
		on = 1;
		if ( setsockopt(sock,SOL_SOCKET,SO_KEEPALIVE,&on,sizeof(on)) ){
			logger(prefix,"WARNING: cannot set socket to KEEP-ALIVE\n");
		}	
		

	}
	ss = fdopen(sock,"w+");
	lines = 0;
	bzero(etag,256);	
	strcpy(referer,"");
	strcpy(method,"");
	while ( fgets(buf,1024,ss) != NULL ){
		if ( buf[strlen(buf)-1] == '\r' || buf[strlen(buf)-1] == '\n' )  buf[strlen(buf)-1] = '\0';
		if ( buf[strlen(buf)-1] == '\r' || buf[strlen(buf)-1] == '\n' )  buf[strlen(buf)-1] = '\0';
		if ( lines == 0 ){
			if ( strncasecmp(buf,"GET",3) == 0 ){
			 strcpy(method,"GET");
			 valid = 1;
			 ptr = &buf[3];
			 while ( *ptr && ( *ptr == ' ' || *ptr == '\t' ) ) ptr++;
			 strcpy(url,ptr);
			 ptr = url;
			 while ( *ptr && ( *ptr != ' ' && *ptr != '\t' ) ) ptr++;
			 *ptr = '\0';
			}
			if ( strncasecmp(buf,"OPTIONS",7) == 0 ){
			 strcpy(method,"OPTIONS");
			 valid = 1;
			 ptr = &buf[7];
			 while ( *ptr && ( *ptr == ' ' || *ptr == '\t' ) ) ptr++;
			 strcpy(url,ptr);
			 ptr = url;
			 while ( *ptr && ( *ptr != ' ' && *ptr != '\t' ) ) ptr++;
			 *ptr = '\0';
			}
		}
		lines++;
		if ( strncasecmp(buf,"Authorization:",strlen("Authorization:")) == 0 ){
			ptr = &buf[strlen("Authorization:")];
			while ( *ptr && ( *ptr == ' ' || *ptr == '\t' ) ) ptr++;
			strcpy(temp,ptr);	
			ptr = temp;
			while ( *ptr && ( *ptr != ' ' && *ptr != '\t' ) ) ptr++;
			*ptr = '\0';
			if ( strcasecmp(temp,"basic") == 0 ){
				unsigned char credentials[128];
			
				int len;
				ptr++;
				while ( *ptr && ( *ptr == ' ' || *ptr == '\t' ) ) ptr++;
				strcpy(temp2,ptr);
				ptr = temp2;
				while ( *ptr && ( *ptr != ' ' && *ptr != '\t' ) ) ptr++;
				*ptr = '\0';
				len = debase64(temp2,credentials);
				// logger(prefix,"AUTH-BASE64: [%s] --> [%s], should be: [*:%s]\n",temp2,credentials,pwd);	
				ptr = strtok(credentials,":");
				if ( ptr != NULL ){
					// We do not care about user :-)		
					ptr = strtok(NULL,":");
					if ( ptr != NULL ){
						if ( strcmp(ptr,pwd) == 0 ) authok = 1;
					}
				}
			}
		}
		if ( strncasecmp(buf,"Referer:",strlen("Referer:")) == 0 ){
			char gaense;
			int slashes;
			ptr = &buf[strlen("Referer:")];
			while ( *ptr && ( *ptr == ' ' || *ptr == '\t' ) ) ptr++;
			strcpy(referer,ptr);
			slashes = 0;
			ptr = referer;
			while ( *ptr ){
				if ( *ptr == '/' ) slashes++;
				if ( slashes == 3 ) break;
				ptr++;
			}
			*ptr = '\0';
			
		}
		if ( strncasecmp(buf,"If-None-Match:",strlen("If-None-Match:")) == 0 ){
			char gaense;
			ptr = &buf[strlen("If-None-Match:")];
			while ( *ptr && ( *ptr == ' ' || *ptr == '\t' ) ) ptr++;
			if ( *ptr == '\"' || *ptr == '\'' ){
				ptr++;
				strcpy(etag,ptr);
				if ( etag[strlen(etag)-1] == '\"' || etag[strlen(etag)-1] == '\'' ) etag[strlen(etag)-1] = '\0';
			} else {
				strcpy(etag,ptr);
			}
		}
		if ( strlen(buf) < 1 ) break;
		// logger(prefix,"HTML<< [%s]\n",buf);
	}	
	// logger(prefix,"-----------------------------------\n");
	logger(prefix,"HTML << METHOD: [%s] URL: [%s] Auth-OK: [%d] Valid-Request: [%d] ETAG: [%s] Referer: [%s]\n",method,url,authok,valid,etag,referer);

	if ( strcmp(method,"OPTIONS") == 0 ){
		// logger(prefix,"HTML>> HTTP/1.1 204 No content\r\n");
		fprintf(ss,"HTTP/1.1 204 No content\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		if ( strlen(referer)) logger(prefix,"HTML>> Access-Control-Allow-Origin: %s\r\n",referer);
		// logger(prefix,"HTML>> Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n");
		fprintf(ss,"Access-Control-Allow-Methods: POST, GET, OPTIONS\r\n");
		// logger(prefix,"HTML>> Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Access-Control-Allow-Headers: Authorization, Content-Type\r\n");
		// logger(prefix,"HTML>> Access-Control-Allow-Headers: Authorization, Content-Type\r\n");
		fprintf(ss,"Access-Control-Allow-Credentials: true\r\n");
		// logger(prefix,"HTML>> Access-Control-Allow-Credentials: true\r\n");
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		// logger(prefix,"HTML>> Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		// logger(prefix,"HTML>> Connection: close\r\n\r\n");
		fprintf(ss,"Connection: close\r\n\r\n");
		fflush(ss);
		logger(prefix,"OPTIONS-HEADER processed...\n");
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}

	if ( valid == 0 ){
		tim = time(NULL);
		fprintf(ss,"HTTP/1.1 401 Authorization Required\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"WWW-Authenticate: Basic realm=\"GIX-INETD-Admin\"\r\n");
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Content-Type: text/html\r\n\r\n");
		fprintf(ss,"<H1>Access denied</H1>\r\n");
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}

	// Only version asking is allowed :-)
	if ( strcmp(url,"/version") == 0 ){
		fprintf(ss,"HTTP/1.1 200 OK\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Content-Type: text/plain;\r\n\r\n");
		fprintf(ss,"OK[{\"hostname\":\"%s\",\"version\":\"%s\"}]\r\n",my_hostname,GIX_INETD_VERSION);
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}

	if ( authok == 0 ){
		tim = time(NULL);
		fprintf(ss,"HTTP/1.1 401 Authorization Required\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"WWW-Authenticate: Basic realm=\"GIX-INETD-Admin\"\r\n");
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Content-Type: text/html\r\n\r\n");
		fprintf(ss,"<H1>Access denied</H1>\r\n");
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
	if ( strcmp(url,"/version_s") == 0 ){
		fprintf(ss,"HTTP/1.1 200 OK\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Content-Type: text/plain;\r\n\r\n");
		fprintf(ss,"OK[{\"hostname\":\"%s\",\"version\":\"%s\"}]\r\n",my_hostname,GIX_INETD_VERSION);
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
	tim = time(NULL);
        if ( strcmp(url,"/favicon.ico") == 0 ){
		if ( strlen(etag) && strcmp(etag,gix_img_gixicon_etag) == 0 ){
			// logger(prefix,"HTML --> Sending ETAG-OK Header\n");
			fprintf(ss,"HTTP/1.1 304 Not Modified\r\n");
			if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
			fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
			fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
			fprintf(ss,"Connection: close\r\n");
			fprintf(ss,"ETag: \"%s\"\r\n\r\n",etag);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}
		fprintf(ss,"HTTP/1.1 200 OK\r\n");
		if ( strlen(referer) )fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Accept-Ranges: bytes\r\n");
		fprintf(ss,"Content-Length: %d\r\n",gix_img_gixicon_len);
		fprintf(ss,"ETag: \"%s\"\r\n",gix_img_gixicon_etag);
		fprintf(ss,"Content-Type: image/x-icon\r\n\r\n");
		fwrite(gix_img_gixicon_bin,1,gix_img_gixicon_len,ss);
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
        if ( strcmp(url,"/gix_logo.png") == 0 ){
		if ( strlen(etag) && strcmp(etag,gix_img_gixlogo_etag) == 0 ){
			// logger(prefix,"HTML --> Sending ETAG-OK Header\n");
			fprintf(ss,"HTTP/1.1 304 Not Modified\r\n");
			if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
			fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
			fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
			fprintf(ss,"Connection: close\r\n");
			fprintf(ss,"ETag: \"%s\"\r\n\r\n",etag);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}
		fprintf(ss,"HTTP/1.1 200 OK\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Accept-Ranges: bytes\r\n");
		fprintf(ss,"Content-Length: %d\r\n",gix_img_gixlogo_len);
		fprintf(ss,"ETag: \"%s\"\r\n",gix_img_gixlogo_etag);
		fprintf(ss,"Content-Type: image/png\r\n\r\n");
		fwrite(gix_img_gixlogo_bin,1,gix_img_gixlogo_len,ss);
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
        if ( strcmp(url,"/empty.gif") == 0 ){
		if ( strlen(etag) && strcmp(etag,gix_img_empty_etag) == 0 ){ 
			// logger(prefix,"HTML --> Sending ETAG-OK Header\n");
			fprintf(ss,"HTTP/1.1 304 Not Modified\r\n");
			if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
			fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
			fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
			fprintf(ss,"Connection: close\r\n");
			fprintf(ss,"ETag: \"%s\"\r\n\r\n",etag);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}
		fprintf(ss,"HTTP/1.1 200 OK\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Accept-Ranges: bytes\r\n");
		fprintf(ss,"Content-Length: %d\r\n",gix_img_empty_len);
		fprintf(ss,"ETag: \"%s\"\r\n",gix_img_empty_etag);
		fprintf(ss,"Content-Type: image/gif\r\n\r\n");
		fwrite(gix_img_empty_bin,1,gix_img_empty_len,ss);
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
        if ( strcmp(url,"/new_rotator_small.gif") == 0 ){
		if ( strlen(etag) && strcmp(etag,gix_img_new_rotator_small_etag) == 0 ){ 
			// logger(prefix,"HTML --> Sending ETAG-OK Header\n");
			fprintf(ss,"HTTP/1.1 304 Not Modified\r\n");
			if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
			fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
			fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
			fprintf(ss,"Connection: close\r\n");
			fprintf(ss,"ETag: \"%s\"\r\n\r\n",etag);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}
		fprintf(ss,"HTTP/1.1 200 OK\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Accept-Ranges: bytes\r\n");
		fprintf(ss,"Content-Length: %d\r\n",gix_img_new_rotator_small_len);
		fprintf(ss,"ETag: \"%s\"\r\n",gix_img_new_rotator_small_etag);
		fprintf(ss,"Content-Type: image/gif\r\n\r\n");
		fwrite(gix_img_new_rotator_small_bin,1,gix_img_new_rotator_small_len,ss);
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
        if ( strcmp(url,"/new_rotator_big.gif") == 0 ){
		if ( strlen(etag) && strcmp(etag,gix_img_new_rotator_big_etag) == 0 ){ 
			// logger(prefix,"HTML --> Sending ETAG-OK Header\n");
			fprintf(ss,"HTTP/1.1 304 Not Modified\r\n");
			if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
			fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
			fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
			fprintf(ss,"Connection: close\r\n");
			fprintf(ss,"ETag: \"%s\"\r\n\r\n",etag);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}
		fprintf(ss,"HTTP/1.1 200 OK\r\n");
		if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
		fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
		fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
		fprintf(ss,"Connection: close\r\n");
		fprintf(ss,"Accept-Ranges: bytes\r\n");
		fprintf(ss,"Content-Length: %d\r\n",gix_img_new_rotator_big_len);
		fprintf(ss,"ETag: \"%s\"\r\n",gix_img_new_rotator_big_etag);
		fprintf(ss,"Content-Type: image/gif\r\n\r\n");
		fwrite(gix_img_new_rotator_big_bin,1,gix_img_new_rotator_big_len,ss);
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
	fprintf(ss,"HTTP/1.1 200 OK\r\n");
	if ( strlen(referer)) fprintf(ss,"Access-Control-Allow-Origin: %s\r\n",referer);
	fprintf(ss,"Date: %s\r\n",ctime_o(&tim,dater));
	fprintf(ss,"Server: %s\r\n",GIX_INETD_VERSION);
	fprintf(ss,"Connection: close\r\n");
	type_req = TYPE_HTML;
	if ( strstr(url,"/ajax/") != NULL ) type_req = TYPE_AJAX;
	if ( strcmp(url,"/style.css") == 0  ) type_req = TYPE_CSS;

	if ( type_req == TYPE_CSS ){
		fprintf(ss,"Content-Type: text/css\r\n\r\n");
		fprintf(ss,"div.fixed_download {\n");
		fprintf(ss," display: block;\n");
		fprintf(ss," visibility: hidden;\n");
		fprintf(ss," z-index: 13;\n");
		fprintf(ss," position: fixed;\n");
		fprintf(ss," top: 5%;\n");
		fprintf(ss," left: 5%;\n");
		fprintf(ss," width: 90%;\n");
		fprintf(ss," height: 90%;\n");
		fprintf(ss," border: 1px solid black;\n");
		fprintf(ss," box-shadow: 10px 15px 20px black;\n");
		fprintf(ss," padding: 5px;\n");
		fprintf(ss," overflow: auto;\n");
		fprintf(ss," background-color: rgba(0,0,0,0.9);\n");
		fprintf(ss,"}\n");
		fprintf(ss,".mainbody {\n");
		fprintf(ss," background-color: rgb(200,200,200);\n");
		fprintf(ss,"}\n");
		fprintf(ss,".headline {\n");
		fprintf(ss," left: 5%%;\n");
		fprintf(ss," right: 5%%;\n");
		fprintf(ss," z-index: 10;\n");
		fprintf(ss," border: 1px solid black;\n");
		fprintf(ss," position:  fixed;\n");
		fprintf(ss," top: 10px;\n");
		fprintf(ss," margin-right: auto;\n");
		fprintf(ss," margin-left: auto;\n");
		fprintf(ss," background-color: rgb(180,180,180);\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 24px;\n");
		fprintf(ss," width: 90%%;\n");
		fprintf(ss," padding: 4px;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".rotator_div {\n");
		// fprintf(ss," border: 1px solid green;\n");
		// fprintf(ss," width: 100px;\n");
		// fprintf(ss," height: 100px;\n");
		fprintf(ss," padding-left: 40%%;\n");
		fprintf(ss," padding-right: 10px;\n");
		fprintf(ss," padding-top: 25px;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".fd_div {\n");
		fprintf(ss," max-height: 500px;\n");
		fprintf(ss," overflow-y: auto;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".table_list2 {\n");
		fprintf(ss," position: relative;\n");
		fprintf(ss," background-color: grey;\n");
		// fprintf(ss," width: 90%%;\n");
		fprintf(ss," height: 85%%;\n");
		// fprintf(ss," left: 5%%;\n");
		fprintf(ss," top: 5%%;\n");
		fprintf(ss," border: 1px solid white;\n");
		fprintf(ss," overflow-y: auto;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".table_list {\n");
		fprintf(ss," position: relative;\n");
		fprintf(ss," background-color: grey;\n");
		// fprintf(ss," width: 90%%;\n");
		fprintf(ss," height: 85%%;\n");
		// fprintf(ss," left: 5%%;\n");
		fprintf(ss," top: 5%%;\n");
		fprintf(ss," border: 1px solid white;\n");
		fprintf(ss," overflow-y: auto;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".headliner {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 20px;\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss,"}\n");

		fprintf(ss,".gcanvas1 {\n");
		// fprintf(ss," width: 400;\n");
		// fprintf(ss," height: 100;\n");
		fprintf(ss," border: 1px solid black;\n");
		fprintf(ss," background-color: white;\n");
		fprintf(ss,"}\n");

		fprintf(ss,".ethlist {\n");
		// fprintf(ss," max-height: 300px;\n");
		// fprintf(ss," overflow-y: auto;\n");
		fprintf(ss,"}\n");

		fprintf(ss,".mainscreen {\n");
		fprintf(ss," left: 5%%;\n");
		fprintf(ss," right: 5%%;\n");
		fprintf(ss," z-index: 10;\n");
		fprintf(ss," overflow-y: auto;\n");
		fprintf(ss," position:  fixed;\n");
		fprintf(ss," margin-right: auto;\n");
		fprintf(ss," margin-left: auto;\n");
		fprintf(ss," background-color: rgb(180,180,180);\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 16px;\n");
		fprintf(ss," padding: 10px;\n");
		fprintf(ss," border: 1px solid black;\n");
		fprintf(ss," width: 90%%;\n");
		fprintf(ss," max-height: 70%%;\n");
		fprintf(ss," top: 15%%;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".procinfo {\n");
		fprintf(ss,"  height: 400px;\n");
		fprintf(ss,"  overflow-y: scroll;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".theadbig {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 24px;\n");
		fprintf(ss," color: white;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead1s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," color: red;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".input1s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," color: red;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".input2s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," color: black;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".input2serror {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," border: 2px solid red;\n");
		fprintf(ss," color: red;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead2s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," color: black;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead2slink {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss," color: blue;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead2slink:hover {\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead3s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," color: blue;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead3s:hover {\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead4s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," color: green;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead1 {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," color: red;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead2 {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," color: black;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead2link {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," color: blue;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead2links {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," color: blue;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead2link:hover {\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead3 {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss," color: green;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead10 {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss," color: red;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead20 {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss," color: black;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead30 {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss," color: green;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead20s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss," color: black;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".thead30s {\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss," color: green;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".info_div {\n");
		fprintf(ss,"  position: fixed;\n");
		fprintf(ss,"  padding: 4px;\n");
		fprintf(ss,"  z-index: 13;\n");
		fprintf(ss,"  border: 1px solid black;\n");
		fprintf(ss,"  top: 10%%;\n");
		fprintf(ss,"  left: 5%%;\n");
		fprintf(ss,"  width: 90%%;\n");
		fprintf(ss,"  height: 80%%;\n");
		fprintf(ss,"  box-shadow: 10px 15px 20px black;\n");
		fprintf(ss,"  background-color: rgba(0,0,0,0.9);\n");
		fprintf(ss,"}\n");
		fprintf(ss,".footer {\n");
		fprintf(ss," position:  fixed;\n");
		fprintf(ss," z-index: 10;\n");
		fprintf(ss," border: 1px solid black;\n");
		fprintf(ss," background-color: rgb(180,180,180);\n");
		fprintf(ss," left: 5%%;\n");
		fprintf(ss," right: 5%%;\n");
		fprintf(ss," margin-right: auto;\n");
		fprintf(ss," margin-left: auto;\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 16px;\n");
		fprintf(ss," top: 90%%;\n");
		fprintf(ss," width: 90%%;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".filemanagerclose2 {\n");
		fprintf(ss,"  font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss,"  color: white;\n");
		fprintf(ss,"  font-size: 48px;\n");
		fprintf(ss,"  font-weight: bold;\n");
		fprintf(ss,"  cursor: pointer;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".filemanagerclose2:hover {\n");
		fprintf(ss,"  color: green;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".standard_buttons {\n");
		fprintf(ss," background-color: #DD2211;\n");
		fprintf(ss," border: none;\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 12px;\n");
		fprintf(ss," text-align: center;\n");
		fprintf(ss," text-decoration: none;\n");
		fprintf(ss," display: inline-block;\n");
		fprintf(ss," color: white;\n");
		fprintf(ss," padding: 2px 5px;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".standard_buttons:hover {\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".standard_button {\n");
		fprintf(ss," background-color: #DD2211;\n");
		fprintf(ss," border: none;\n");
		fprintf(ss," font-family: Optima, Geneva, sans-serif;\n");
		fprintf(ss," font-size: 14px;\n");
		fprintf(ss," text-align: center;\n");
		fprintf(ss," text-decoration: none;\n");
		fprintf(ss," display: inline-block;\n");
		fprintf(ss," color: white;\n");
		fprintf(ss," padding: 4px 10px;\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".standard_button:hover {\n");
		fprintf(ss," font-weight: bold;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".l_image {\n");
		fprintf(ss," cursor: pointer;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".l_image:hover {\n");
		fprintf(ss," border: 1px solid black;\n");
		fprintf(ss,"}\n");
		fprintf(ss,".simple_div: {\n");
		fprintf(ss," border: 1px solid black;\n");
		fprintf(ss,"}\n");


		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
	if ( type_req == TYPE_AJAX ){
		char command[256];
		char argument[256];
		char *ptr;
		fprintf(ss,"Content-Type: %s\r\n",AJAX_MIME);
		ptr = &url[strlen("/ajax/")];
		bzero(command,256);
		strcpy(command,ptr);
		ptr = command;
		while ( *ptr && ( *ptr != '/' )) ptr++;
		*ptr = '\0';
		ptr++;
		strcpy(argument,ptr);
		// logger(prefix,"AJAX-COMMAND: [%s] Argument: [%s]\n",command,argument);	



		if ( strcmp(command,"CONNSLIST") == 0 ){
			int idx,i;
			char *result;
			char line[1024];
			idx = atoi(argument);
			if ( idx >= entries ){
				fprintf(ss,"\r\nERR[Bad Index]\r\n");
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				return;
			}
			result = strdup("[");
			sem_lock(semid2);
			for ( i = 0; i < MAX_CONNS; i++ ){
				if ( servlist[idx].co[i].port != 0 ){
					struct tm *tm;
					char procfile[1024];
					char cmdline[1024];
					char stack[128];
					char cwd[512];
					char data[128];
					char exe[128];
					char lib[128];
					size_t _io_read;
					size_t _io_write;
					double io_read;
					double io_write;
					double io_read_sec;
					double io_write_sec;
					char io_read_text[1024];
					char io_write_text[1024];
					char io_read_sec_text[1024];
					char io_write_sec_text[1024];
					char source_addr_text[128];	
					char target_addr_text[128];	
					char netstat_file[1024];
					char tcp_state[16];
					char tcp_timeout[32];
					double helper;
					double diff;
					int threads;
					char *ptr;
					FILE *fp;


					strcpy(netstat_file,"");
					strcpy(tcp_state,"UNKNOWN");	
					strcpy(tcp_timeout,"UNKNOWN");	
					bzero(lib,sizeof(lib));
					bzero(exe,sizeof(exe));
					bzero(stack,sizeof(stack));
					bzero(data,sizeof(data));
					bzero(procfile,sizeof(procfile));
					bzero(cmdline,sizeof(cmdline));
					bzero(io_read_text,sizeof(io_read_text));
					bzero(io_write_text,sizeof(io_write_text));
					bzero(io_read_sec_text,sizeof(io_read_sec_text));
					bzero(io_write_sec_text,sizeof(io_write_sec_text));
					bzero(source_addr_text,sizeof(source_addr_text));
					bzero(target_addr_text,sizeof(target_addr_text));
					bzero(cwd,512);


					sprintf(procfile,"/proc/%d/cwd",servlist[idx].co[i].cpid);
					if ( readlink(procfile,cwd,512) < 0 ){
						logger(prefix,"####################### Failed to read symlink [%s]\n",procfile);
						strcpy(cwd,"n.a.");
					}
					
					if ( servlist[idx].family == AF_INET6 ){
						int j;
				        	struct addrinfo *res;
       						struct addrinfo hints;
						struct sockaddr_in6 sin6;
						sprintf(netstat_file,"/proc/net/tcp6");
						bzero(&hints,sizeof(hints));
						hints.ai_family   = AF_INET6;
						hints.ai_flags    = AI_NUMERICHOST;
						hints.ai_socktype = SOCK_STREAM;
						if ( getaddrinfo(servlist[idx].co[i].source,NULL,&hints,&res)  ){
							logger(prefix,"##################### FAILED TO CONVERT: [%s]\n",servlist[idx].co[i].source);
						} else {
							unsigned char hlp[16];
							unsigned long *x0,*x2,*x3,*x4;
							memcpy( (void *)&sin6,(void *)res->ai_addr,res->ai_addrlen);
							hlp[0] = (unsigned char) sin6.sin6_addr.s6_addr[3];
							hlp[1] = (unsigned char) sin6.sin6_addr.s6_addr[2];
							hlp[2] = (unsigned char) sin6.sin6_addr.s6_addr[1];
							hlp[3] = (unsigned char) sin6.sin6_addr.s6_addr[0];
							hlp[4] = (unsigned char) sin6.sin6_addr.s6_addr[7];
							hlp[5] = (unsigned char) sin6.sin6_addr.s6_addr[6];
							hlp[6] = (unsigned char) sin6.sin6_addr.s6_addr[5];
							hlp[7] = (unsigned char) sin6.sin6_addr.s6_addr[4];
							hlp[8] = (unsigned char) sin6.sin6_addr.s6_addr[11];
							hlp[9] = (unsigned char) sin6.sin6_addr.s6_addr[10];
							hlp[10] = (unsigned char) sin6.sin6_addr.s6_addr[9];
							hlp[11] = (unsigned char) sin6.sin6_addr.s6_addr[8];
							hlp[12] = (unsigned char) sin6.sin6_addr.s6_addr[15];
							hlp[13] = (unsigned char) sin6.sin6_addr.s6_addr[14];
							hlp[14] = (unsigned char) sin6.sin6_addr.s6_addr[13];
							hlp[15] = (unsigned char) sin6.sin6_addr.s6_addr[12];
							strcpy(source_addr_text,"");
							for ( j = 0; j < 16; j++ ){
								sprintf(&source_addr_text[strlen(source_addr_text)],"%02X",(unsigned char) hlp[j]);
							}	
							sprintf(&source_addr_text[strlen(source_addr_text)],":%04X",(unsigned int)servlist[idx].co[i].port);
							// logger(prefix,"ADDRESS_CONV_SOURCE ********** [%s]:[%d] --> [%s]\n",servlist[idx].co[i].source,servlist[idx].co[i].port,source_addr_text);
						}
						if ( getaddrinfo(servlist[idx].co[i].target,NULL,&hints,&res)  ){
							logger(prefix,"##################### FAILED TO CONVERT: [%s]\n",servlist[idx].co[i].target);
						} else {
							unsigned char hlp[16];
							unsigned long *x0,*x2,*x3,*x4;
							memcpy( (void *)&sin6,(void *)res->ai_addr,res->ai_addrlen);
							hlp[0] = (unsigned char) sin6.sin6_addr.s6_addr[3];
							hlp[1] = (unsigned char) sin6.sin6_addr.s6_addr[2];
							hlp[2] = (unsigned char) sin6.sin6_addr.s6_addr[1];
							hlp[3] = (unsigned char) sin6.sin6_addr.s6_addr[0];
							hlp[4] = (unsigned char) sin6.sin6_addr.s6_addr[7];
							hlp[5] = (unsigned char) sin6.sin6_addr.s6_addr[6];
							hlp[6] = (unsigned char) sin6.sin6_addr.s6_addr[5];
							hlp[7] = (unsigned char) sin6.sin6_addr.s6_addr[4];
							hlp[8] = (unsigned char) sin6.sin6_addr.s6_addr[11];
							hlp[9] = (unsigned char) sin6.sin6_addr.s6_addr[10];
							hlp[10] = (unsigned char) sin6.sin6_addr.s6_addr[9];
							hlp[11] = (unsigned char) sin6.sin6_addr.s6_addr[8];
							hlp[12] = (unsigned char) sin6.sin6_addr.s6_addr[15];
							hlp[13] = (unsigned char) sin6.sin6_addr.s6_addr[14];
							hlp[14] = (unsigned char) sin6.sin6_addr.s6_addr[13];
							hlp[15] = (unsigned char) sin6.sin6_addr.s6_addr[12];
							strcpy(target_addr_text,"");
							for ( j = 0; j < 16; j++ ){
								sprintf(&target_addr_text[strlen(target_addr_text)],"%02X",(unsigned char) hlp[j]);
							}	
							sprintf(&target_addr_text[strlen(target_addr_text)],":%04X",(unsigned int)servlist[idx].co[i].t_port);
							// logger(prefix,"ADDRESS_CONV_TARGET ********** [%s]:[%d] --> [%s]\n",servlist[idx].co[i].target,servlist[idx].co[i].t_port,target_addr_text);
						}
					}	
					if ( servlist[idx].family == AF_INET ){
						int j;
				        	struct addrinfo *res;
       						struct addrinfo hints;
						struct sockaddr_in sin4;
						sprintf(netstat_file,"/proc/net/tcp");
						bzero(&hints,sizeof(hints));
						hints.ai_family   = AF_INET;
						hints.ai_flags    = AI_NUMERICHOST;
						hints.ai_socktype = SOCK_STREAM;
						if ( getaddrinfo(servlist[idx].co[i].source,NULL,&hints,&res)  ){
							logger(prefix,"##################### FAILED TO CONVERT: [%s]\n",servlist[idx].co[i].source);
						} else {
							unsigned char hlp[16];
							unsigned long *x0,*x2,*x3,*x4;
							memcpy( (void *)&sin4,(void *)res->ai_addr,res->ai_addrlen);
							hlp[0] = (unsigned char) (( sin4.sin_addr.s_addr & 0xFF000000 ) >> 24 );
							hlp[1] = (unsigned char) (( sin4.sin_addr.s_addr & 0x00FF0000 ) >> 16 );
							hlp[2] = (unsigned char) (( sin4.sin_addr.s_addr & 0x0000FF00 ) >> 8 );
							hlp[3] = (unsigned char) (( sin4.sin_addr.s_addr & 0x000000FF ) );
							strcpy(source_addr_text,"");
							for ( j = 0; j < 4; j++ ){
								sprintf(&source_addr_text[strlen(source_addr_text)],"%02X",(unsigned char) hlp[j]);
							}	
							sprintf(&source_addr_text[strlen(source_addr_text)],":%04X",(unsigned int)servlist[idx].co[i].port);
							// logger(prefix,"ADDRESS_CONV_SOURCE ********** [%s]:[%d] --> [%s]\n",servlist[idx].co[i].source,servlist[idx].co[i].port,source_addr_text);
						}
						if ( getaddrinfo(servlist[idx].co[i].target,NULL,&hints,&res)  ){
							logger(prefix,"##################### FAILED TO CONVERT: [%s]\n",servlist[idx].co[i].target);
						} else {
							unsigned char hlp[16];
							unsigned long *x0,*x2,*x3,*x4;
							memcpy( (void *)&sin4,(void *)res->ai_addr,res->ai_addrlen);
							hlp[0] = (unsigned char) (( sin4.sin_addr.s_addr & 0xFF000000 ) >> 24 );
							hlp[1] = (unsigned char) (( sin4.sin_addr.s_addr & 0x00FF0000 ) >> 16 );
							hlp[2] = (unsigned char) (( sin4.sin_addr.s_addr & 0x0000FF00 ) >> 8 );
							hlp[3] = (unsigned char) (( sin4.sin_addr.s_addr & 0x000000FF ) );
							strcpy(target_addr_text,"");
							for ( j = 0; j < 4; j++ ){
								sprintf(&target_addr_text[strlen(target_addr_text)],"%02X",(unsigned char) hlp[j]);
							}	
							sprintf(&target_addr_text[strlen(target_addr_text)],":%04X",(unsigned int)servlist[idx].co[i].t_port);
							// logger(prefix,"ADDRESS_CONV_TARGET ********** [%s]:[%d] --> [%s]\n",servlist[idx].co[i].target,servlist[idx].co[i].t_port,target_addr_text);
						}
					}	
					if ( strlen(netstat_file) && (fp = fopen(netstat_file,"r")) != NULL ){
						char buf[1024];
						while ( fgets(buf,1024,fp) != NULL ){
							int state;
							int timer_mode;
							unsigned long timer_value;
							if ( strstr(buf,":") == NULL ) continue;
							ptr = strtok(buf," \t\r\n");
							if ( ptr == NULL ) continue;
							ptr = strtok(NULL," \t\r\n");
							if ( ptr == NULL ) continue;
							if ( strcmp(ptr,target_addr_text) != 0 ) continue;
							ptr = strtok(NULL," \t\r\n");
							if ( ptr == NULL ) continue;
							if ( strcmp(ptr,source_addr_text) != 0 ) continue;
							ptr = strtok(NULL," \t\r\n");
							if ( ptr == NULL ) continue;
							sscanf(ptr,"%02X",&state);
							ptr = strtok(NULL," \t\r\n");
							if ( ptr == NULL ) continue;
							ptr = strtok(NULL," \t\r\n");
							if ( ptr == NULL ) continue;
							sscanf(ptr,"%02X:%08lX",&timer_mode,&timer_value);
							// logger(prefix,"NETSTAT_CONV_(%s) --> [0x%02X] Timer: [0x%02X] Timer-Value: [0x%08lX]\n",netstat_file,state,timer_mode,timer_value);
							switch ( timer_mode ){
								case 0: sprintf(tcp_timeout,"");
									break;
								case 1: sprintf(tcp_timeout,"Retrans.&nbsp;%d&nbsp;s",timer_value);
									break;
								case 2: sprintf(tcp_timeout,"Other&nbsp;%d&nbsp;s",timer_value);
									break;
								case 3: sprintf(tcp_timeout,"TIME_WAIT&nbsp;%d&nbsp;s",timer_value);
									break;
								case 4: sprintf(tcp_timeout,"ZERO_WIN&nbsp;%d&nbsp;s",timer_value);
									break;
								default: 
									sprintf(tcp_timeout,"[0x%02X]&nbsp;%d&nbsp;s",timer_mode,timer_value);
									break;
							}
							switch ( state ){
									case 0x01: 
										strcpy(tcp_state,"ESTABLISHED");
										break;
									case 0x02: 
										strcpy(tcp_state,"SYN_SENT");
										break;
									case 0x03: 
										strcpy(tcp_state,"SYN_RECV");
										break;
									case 0x04: 
										strcpy(tcp_state,"FIN_WAIT1");
										break;
									case 0x05: 
										strcpy(tcp_state,"FIN_WAIT2");
										break;
									case 0x06: 
										strcpy(tcp_state,"TIME_WAIT");
										break;
									case 0x07: 
										strcpy(tcp_state,"CLOSE");
										break;
									case 0x08: 
										strcpy(tcp_state,"CLOSE_WAIT");
										break;
									case 0x09: 
										strcpy(tcp_state,"LAST_ACK");
										break;
									case 0x0A: 
										strcpy(tcp_state,"LISTEN");
										break;
									case 0x0B: 
										strcpy(tcp_state,"CLOSING");
										break;
									default: 
										sprintf(tcp_state,"UNKNOWN(%02X)",state);
										break;
							}
						}
						fclose(fp);
					}
						
					sprintf(stack,"- kB");
					sprintf(data,"- kB");
					sprintf(exe,"- kB");
					threads = 1;
					sprintf(procfile,"/proc/%d/status",servlist[idx].co[i].cpid);
					fp = fopen(procfile,"r");
					if ( fp != NULL ){
						while ( fgets(cmdline,1024,fp) != NULL ){
							if ( strncmp(cmdline,"VmData:",strlen("VmData:")) == 0 ){
								ptr = &cmdline[strlen("VmData:")];
								while ( *ptr && (*ptr == ' ' || *ptr == '\t' ) ) ptr++;
								strcpy(data,ptr);
								ptr = &data[strlen(data)-1];
								while ( ptr > data && ( *ptr == '\r' || *ptr == '\n' ) )ptr--;
								if ( ptr > data ) ptr++;
								*ptr = '\0';
								continue;
							}
							if ( strncmp(cmdline,"VmStk:",strlen("VmStk:")) == 0 ){
								ptr = &cmdline[strlen("VmStk:")];
								while ( *ptr && (*ptr == ' ' || *ptr == '\t' ) ) ptr++;
								strcpy(stack,ptr);
								ptr = &stack[strlen(stack)-1];
								while ( ptr > stack && ( *ptr == '\r' || *ptr == '\n' ) )ptr--;
								if ( ptr > stack ) ptr++;
								*ptr = '\0';
								continue;
							}
							if ( strncmp(cmdline,"VmExe:",strlen("VmExe:")) == 0 ){
								ptr = &cmdline[strlen("VmExe:")];
								while ( *ptr && (*ptr == ' ' || *ptr == '\t' ) ) ptr++;
								strcpy(exe,ptr);
								ptr = &exe[strlen(exe)-1];
								while ( ptr > exe && ( *ptr == '\r' || *ptr == '\n' ) )ptr--;
								if ( ptr > exe ) ptr++;
								*ptr = '\0';
								continue;
							}
							if ( strncmp(cmdline,"VmLib:",strlen("VmLib:")) == 0 ){
								ptr = &cmdline[strlen("VmLib:")];
								while ( *ptr && (*ptr == ' ' || *ptr == '\t' ) ) ptr++;
								strcpy(lib,ptr);
								ptr = &lib[strlen(lib)-1];
								while ( ptr > lib && ( *ptr == '\r' || *ptr == '\n' ) )ptr--;
								if ( ptr > lib ) ptr++;
								*ptr = '\0';
								continue;
							}
						}
						fclose(fp);
					}
					sprintf(procfile,"/proc/%d/io",servlist[idx].co[i].cpid);
					fp = fopen(procfile,"r");
					_io_read  = 0;
					_io_write = 0;
					if ( fp != NULL ){
						while ( fgets(cmdline,1024,fp) != NULL ){
							if ( strncmp(cmdline,"rchar:",strlen("rchar:")) == 0 ){
								ptr = &cmdline[strlen("rchar:")];
								while ( *ptr && (*ptr == ' ' || *ptr == '\t' ) ) ptr++;
								_io_read = atoll(ptr);
								continue;
							}
							if ( strncmp(cmdline,"wchar:",strlen("wchar:")) == 0 ){
								ptr = &cmdline[strlen("wchar:")];
								while ( *ptr && (*ptr == ' ' || *ptr == '\t' ) ) ptr++;
								_io_write = atoll(ptr);
								continue;
							}
						}
						fclose(fp);
					}
#define BIG1024 (1024.0)
					diff = (double) (time(NULL) - servlist[idx].co[i].created);
					if ( diff <= 0 ) diff = 1.0; // Avoid division by zero
					io_read = (double) _io_read;
					io_read_sec = io_read / diff;
					sprintf(io_read_text,"%d&nbsp;Bytes",(int)io_read);
					if ( io_read > 1024.0 ){
						sprintf(io_read_text,"%.02f&nbsp;kB",io_read / BIG1024);
					}
					if ( io_read > (BIG1024*BIG1024) ){
						sprintf(io_read_text,"%.02f&nbsp;MB",io_read / (BIG1024 * BIG1024));
					}
					if ( io_read > (BIG1024*BIG1024*BIG1024) ){
						sprintf(io_read_text,"%.02f&nbsp;GB",io_read / (BIG1024 * BIG1024 * BIG1024));
					}
					if ( io_read > (BIG1024*BIG1024*BIG1024*BIG1024) ){
						sprintf(io_read_text,"%.02f&nbsp;TB",io_read / (BIG1024 * BIG1024 * BIG1024 * BIG1024));
					}
					if ( io_read > (BIG1024*BIG1024*BIG1024*BIG1024*BIG1024) ){
						sprintf(io_read_text,"%.02f&nbsp;PB",io_read / (BIG1024 * BIG1024 * BIG1024 * BIG1024 * BIG1024));
					}
					sprintf(io_read_sec_text,"%d Bytes/s",(int)io_read_sec);
					if ( io_read_sec > 1024.0 ){
						sprintf(io_read_sec_text,"%.02f&nbsp;kBytes/s",io_read_sec/1024.0);
					}
					if ( io_read_sec > (1024.0*1024.0) ){
						sprintf(io_read_sec_text,"%.02f&nbsp;MBytes/s",io_read_sec/(1024.0 * 1024.0));
					}
					if ( io_read_sec > (1024.0*1024.0*1024.0) ){
						sprintf(io_read_sec_text,"%.02f&nbsp;GBytes/s",io_read_sec/(1024.0 * 1024.0 * 1024.0));
					}
					if ( io_read_sec > (1024.0*1024.0*1024.0*1024.0) ){
						sprintf(io_read_sec_text,"%.02f&nbsp;TBytes/s",io_read_sec/(1024.0 * 1024.0 * 1024.0 * 1024.0));
					}
					if ( io_read_sec > (1024.0*1024.0*1024.0*1024.0*1024.0) ){
						sprintf(io_read_sec_text,"%.02f&nbsp;PBytes/s",io_read_sec/(1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0));
					}
					io_write = (double) _io_write;
					io_write_sec = io_write / diff;
					sprintf(io_write_text,"%d&nbsp;Bytes",(int)io_write);
					if ( io_write > 1024.0 ){
						sprintf(io_write_text,"%.02f&nbsp;kB",io_write / BIG1024);
					}
					if ( io_write > (BIG1024*BIG1024) ){
						sprintf(io_write_text,"%.02f&nbsp;MB",io_write / (BIG1024 * BIG1024));
					}
					if ( io_write > (BIG1024*BIG1024*BIG1024) ){
						sprintf(io_write_text,"%.02f&nbsp;GB",io_write / (BIG1024 * BIG1024 * BIG1024));
					}
					if ( io_write > (BIG1024*BIG1024*BIG1024*BIG1024) ){
						sprintf(io_write_text,"%.02f&nbsp;TB",io_write / (BIG1024 * BIG1024 * BIG1024 * BIG1024));
					}
					if ( io_write > (BIG1024*BIG1024*BIG1024*BIG1024*BIG1024) ){
						sprintf(io_write_text,"%.02f&nbsp;PB",io_write / (BIG1024 * BIG1024 * BIG1024 * BIG1024 * BIG1024));
					}
					sprintf(io_write_sec_text,"%d&nbsp;Bytes/s",(int)io_write_sec);
					if ( io_write_sec > 1024.0 ){
						sprintf(io_write_sec_text,"%.02f&nbsp;kBytes/s",io_write_sec/1024.0);
					}
					if ( io_write_sec > (1024.0*1024.0) ){
						sprintf(io_write_sec_text,"%.0fg&nbsp;MBytes/s",io_write_sec/(1024.0 * 1024.0));
					}
					if ( io_write_sec > (1024.0*1024.0*1024.0) ){
						sprintf(io_write_sec_text,"%.02f&nbsp;GBytes/s",io_write_sec/(1024.0 * 1024.0 * 1024.0));
					}
					if ( io_write_sec > (1024.0*1024.0*1024.0*1024.0) ){
						sprintf(io_write_sec_text,"%.02f&nbsp;TBytes/s",io_write_sec/(1024.0 * 1024.0 * 1024.0 * 1024.0));
					}
					if ( io_write_sec > (1024.0*1024.0*1024.0*1024.0*1024.0) ){
						sprintf(io_write_sec_text,"%.02f&nbsp;PBytes/s",io_write_sec/(1024.0 * 1024.0 * 1024.0 * 1024.0 * 1024.0));
					}



					sprintf(procfile,"/proc/%d/exe",servlist[idx].co[i].cpid);
					bzero(cmdline,1024);
					if ( readlink(procfile,cmdline,1024) < 0 ){
						sprintf(cmdline,"Executable not found");
					} 
					{
						char copy[1024];
						char *in;
						char *out;
						strcpy(copy,stack);
						in = copy;
						out = stack;
						while ( *in ){
							if ( *in == ' ' || *in == '\t' ){
								*out = '&';	
								out++;
								*out = 'n';	
								out++;
								*out = 'b';	
								out++;
								*out = 's';	
								out++;
								*out = 'p';	
								out++;
								*out = ';';	
								out++;
								in++; 
							} else {
								*out = *in;
								in++; out++;
							}
						}
						*out = '\0';
						strcpy(copy,data);
						in = copy;
						out = data;
						while ( *in ){
							if ( *in == ' ' || *in == '\t' ){
								*out = '&';	
								out++;
								*out = 'n';	
								out++;
								*out = 'b';	
								out++;
								*out = 's';	
								out++;
								*out = 'p';	
								out++;
								*out = ';';	
								out++;
								in++; 
							} else {
								*out = *in;
								in++; out++;
							}
						}
						*out = '\0';
						strcpy(copy,lib);
						in = copy;
						out = lib;
						while ( *in ){
							if ( *in == ' ' || *in == '\t' ){
								*out = '&';	
								out++;
								*out = 'n';	
								out++;
								*out = 'b';	
								out++;
								*out = 's';	
								out++;
								*out = 'p';	
								out++;
								*out = ';';	
								out++;
								in++; 
							} else {
								*out = *in;
								in++; out++;
							}
						}
						*out = '\0';
						strcpy(copy,exe);
						in = copy;
						out = exe;
						while ( *in ){
							if ( *in == ' ' || *in == '\t' ){
								*out = '&';	
								out++;
								*out = 'n';	
								out++;
								*out = 'b';	
								out++;
								*out = 's';	
								out++;
								*out = 'p';	
								out++;
								*out = ';';	
								out++;
								in++; 
							} else {
								*out = *in;
								in++; out++;
							}
						}
						*out = '\0';
					}
					
					tm = localtime(&servlist[idx].co[i].created);
					sprintf(line,"{\"cwd\":\"%s\",\"slot\":\"%d/%d\",\"tcp_state\":\"%s\",\"tcp_timeout\":\"%s\",\"io_read\":\"%s\",\"io_read_sec\":\"%s\",\"io_write\":\"%s\",\"io_write_sec\":\"%s\",\"vm_stack\":\"%s\",\"vm_lib\":\"%s\",\"vm_exe\":\"%s\",\"vm_data\":\"%s\",\"cmdline\":\"%s\",\"index\":%d,\"pid\":%d,\"cpid\":%d,\"source\":\"%s\",\"target\":\"%s\",\"source_port\":%d,\"target_port\":%d,\"created\":\"%04d.%02d.%02d&nbsp;%02d:%02d:%02d\"},",
						cwd, i,idx, tcp_state,tcp_timeout,
						io_read_text,io_read_sec_text,
						io_write_text,io_write_sec_text,
						stack,lib,exe,data, cmdline, i,servlist[idx].co[i].pid,servlist[idx].co[i].cpid,servlist[idx].co[i].source,servlist[idx].co[i].target,servlist[idx].co[i].port,servlist[idx].co[i].t_port,tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
						 tm->tm_hour, tm->tm_min, tm->tm_sec);	
					result = (char *)realloc(result, strlen(result) + strlen(line) + 1 );
					strcat(result,line);
				}	
			}
			sem_unlock(semid2);	
			if ( result[strlen(result)-1] == ',' ) result[strlen(result)-1] = '\0';
			strcat(result,"]");
			{
				char *in;
				char *out;
				int newsize;
				in = (char *)malloc(strlen(result) + 20);
				out = (char *)malloc(strlen(result) + 120);
				sprintf(in,"OK[%s]\r\n",result);
				newsize = gzip_string(in,out);
				if ( newsize > 0 ){
					fprintf(ss,"Accept-Range: bytes\r\n");
					fprintf(ss,"Content-Length: %d\r\n",newsize);	
					fprintf(ss,"Content-Encoding: gzip\r\n\r\n",newsize);	
					fwrite(out,1,newsize,ss);
					fflush(ss);
				} else {
					logger(prefix,"GZIP-FAILED: [%d] <-- [%d]\n",newsize,strlen(in));
					fprintf(ss,"\r\n%s",in);
				}
			}
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;		
		}
		if ( strcmp(command,"KILLTCP") == 0 ){
			int pid;
			int slot,index;
			char *ptr;
			fprintf(ss,"\r\n");
			logger(prefix,"KILLTCP ARGUMNET: [%s]\n",argument);
			slot = atoi(argument);
			ptr = argument;
			while ( *ptr && *ptr != '/' ) ptr++; 
			if ( *ptr == '/' ){
				logger(prefix,"KILLTCP 2 ARGUMNET: %d, PTR: [%s]\n",argument,ptr);
				ptr++;
				index = atoi(ptr);
				if ( servlist[slot].co[index].pid != 0 ) m_kill(servlist[slot].co[index].pid,SIGTERM); 
				fprintf(ss,"OK[Sent SIGTERM to %d]\r\n",pid);
			}
			
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}

		if ( strcmp(command,"CONNSCOUNT") == 0 ){
			int idx;
			fprintf(ss,"\r\n");
			idx = atoi(argument);
			if ( idx >= entries ){
				fprintf(ss,"ERR[Bad index]\r\n");
			} else {
				struct tm *tm;
				int semmel;
				tm = localtime(&servlist[idx].reset);
				semmel = semget(INETD_KEY2 + idx,1,0);
				if ( semmel < 0 ){
					logger(prefix,"Cannot get SEM [0x%08lX]\n",INETD_KEY2 + idx);
				} else {
					sem_lock(semmel);
					fprintf(ss,"OK[{\"connections\":%d,\"total_count\":%d,\"reset\":\"%04d.%02d.%02d %02d:%02d:%02d\",\"max_conns\":%d,\"pid\":%d}]\r\n",servlist[idx].connections,servlist[idx].total_count,
						tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
						tm->tm_hour, tm->tm_min, tm->tm_sec, servlist[idx].max_conns,servlist[idx].pid);
					sem_unlock(semmel);
				}
			}
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}
		if ( strcmp(command,"SYSINFO") == 0 ){
			double load[3];
			char uptimer[1024];
			struct sysinfo sys;
			int idx;
			int semmel;
			char json_list[10240];
			fprintf(ss,"\r\n");
			getloadavg(load,3);	
			sysinfo(&sys);
			// Get count of connections 
			strcpy(json_list,"[");
			for ( idx = 0; (semmel = semget(INETD_KEY2 + idx,1,0)) >= 0; idx++ ){
				struct tm *tm;
				tm = localtime(&servlist[idx].reset);
				sem_lock(semmel);
				sprintf(&json_list[strlen(json_list)],"{\"connections\":%d,\"total_count\":%d,\"reset\":\"%04d.%02d.%02d %02d:%02d:%02d\",\"max_conns\":%d,\"pid\":%d},",
					servlist[idx].connections,servlist[idx].total_count,
					tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,tm->tm_hour, tm->tm_min, tm->tm_sec, servlist[idx].max_conns,servlist[idx].pid);
				sem_unlock(semmel);
			}	
			if ( json_list[strlen(json_list)-1] == ',' ) json_list[strlen(json_list)-1] = '\0';
			sprintf(&json_list[strlen(json_list)],"]");
			fprintf(ss,"OK[{\"load1\":\"%.02g\",\"load5\":\"%.02g\",\"load15\":\"%.02g\",\"sys_procs\":%d,\"uptime\":\"%s\",\"inetlist\":%s}]\r\n",
				load[0],load[1],load[2],sys.procs,gix_display_uptime(0,NULL,uptimer),json_list);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}
		if ( strcmp(command,"PROCDETAIL") == 0 ){
			int pid; 
			char *result;
                	struct sysinfo sys;
			struct timeval start;
			struct timeval end;
			long utime_ticks;
			long stime_ticks;
			long utime_ticks2;
			long stime_ticks2;
			double cpu_usage_usr;
			double cpu_usage_sys;
			char fname[1024];
			char exe[1024];
			char *helper;
			char full_exe[1024];
			char full_cwd[1024];
			char commandline[1024];
			int r_gid, r_uid;
			int e_gid, e_uid;
			int c_argc;
			char state;
			int ppid;
			long nice;
			long priority;
			long num_threads;
			long rss;
			int cpu_id;
			char *ptr;
			unsigned long vmsize;
			long long starttime;
			time_t p_start;
			FILE *fp;
			int slot, index;
			int fds;
			DIR *dir;
			struct dirent *diry;
			char dirname[1024];
			char *fd_array;
			fprintf(ss,"\r\n");

			slot = -1;
			index = -1;	

			sysinfo(&sys);
			pid = atoi(argument);


			sprintf(dirname,"/proc/%d/fd",pid);

			dir = opendir(dirname);

			fds = 0;

			fd_array = strdup("[");

			if ( dir != NULL ){
				while ( (diry = readdir(dir)) != NULL ){
					char help2[1024];
					char lname[1024];
					char ltarget[1024];
					char addrinfo[256];
					char type[1024];
					unsigned long inode;
					struct socket_info *si;

					bzero(addrinfo,256);

					sprintf(addrinfo,"\"valid_addr\":false,");

					if ( !isdigit(diry->d_name[0]) ) continue;
					sprintf(lname,"/proc/%d/fd/%s",pid,diry->d_name);
					bzero(ltarget,1024);
					if ( readlink(lname,ltarget,1024) < 0 ) continue;
					sprintf(type,"file");
					if ( strncmp(ltarget,"socket:",strlen("socket:")) == 0 ){
						strcpy(type,"socket");
						inode = atol(&ltarget[strlen("socket:[")]);
						logger(prefix,"PROCDETAIL (Requesting INODE: %ld)\n",inode);
						si = get_socket_info(inode,-1);
						if ( si != NULL ){
							sprintf(addrinfo,"\"valid_addr\":true,\"local_addr\":\"%s\",\"protocol\":%d,\"local_port\":%d,\"remote_addr\":\"%s\",\"remote_port\":%d,\"family\":%d,\"state\":%d,\"timer_kind\":%d,\"timer_value\":%ld,\"uid\":%d,",
								si->local_addr,si->protocol,si->local_port,si->remote_addr,si->remote_port,si->family,si->state,si->timer_kind,si->timer_value,si->uid);
						}
					}
					if ( strncmp(ltarget,"pipe:",strlen("pipe:")) == 0 ) strcpy(type,"pipe");
					if ( strncmp(ltarget,"anon_inode:",strlen("anon_inode:")) == 0 ) strcpy(type,"other");
					sprintf(help2,"{%s\"fd\":%d,\"name\":\"%s\",\"type\":\"%s\"},",addrinfo,atoi(diry->d_name),ltarget,type);
					fd_array = (char *)realloc(fd_array,strlen(fd_array) + strlen(help2) + 10);
					strcat(fd_array,help2);
				
				}
				closedir(dir);
			}
			if ( fd_array[strlen(fd_array)-1] == ',' ) fd_array[strlen(fd_array)-1] = '\0';	
			fd_array = (char *)realloc(fd_array,strlen(fd_array) + 10);
			strcat(fd_array,"]");

			helper = (char *)malloc(1024 + strlen(fd_array) * 2);

			
			if ( pid > 10 ) { 
				int k,l;
				for ( k = 0; k < entries; k++ ){
					for ( l = 0; l < MAX_CONNS; l++ ){
						if ( servlist[k].co[l].cpid == pid || servlist[k].co[l].pid == pid ){
							slot = k;
							index = l;
							break;
						}
					}
					if ( slot >= 0 ) break;
				}
			}

			logger(prefix,"PROCDETAIL[%d] --> Start\n",pid);
			result = strdup("{");

			sprintf(fname,"/proc/%d/exe",pid);
			bzero(full_exe,1024);
			if ( readlink(fname,full_exe,1024) < 0 ){
				strcpy(full_exe,"n.a.");	
			}
			sprintf(fname,"/proc/%d/cwd",pid);
			bzero(full_cwd,1024);
			if ( readlink(fname,full_cwd,1024) < 0 ){
				strcpy(full_cwd,"n.a.");	
			}

			r_uid = 0;
			r_gid = 0;
			e_uid = 0;
			e_gid = 0;

			sprintf(fname,"/proc/%d/status",pid);
			fp = fopen(fname,"r");
			if ( fp == NULL ){
				fprintf(ss,"ERR[Cannot open %s]\r\n",fname);
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				return;
			}	
			while ( fgets(fname,1024,fp) != NULL ){
				if ( strncmp(fname,"Uid:",4) == 0 ){
					char *ptr;
					ptr = &fname[4];
					while ( *ptr && !isdigit(*ptr) ) ptr++;
					r_uid = atoi(ptr);
					while ( *ptr && isdigit(*ptr) ) ptr++;
					while ( *ptr && !isdigit(*ptr) ) ptr++;
					e_uid = atoi(ptr);
					continue;
				}	
				if ( strncmp(fname,"Gid:",4) == 0 ){
					char *ptr;
					ptr = &fname[4];
					while ( *ptr && !isdigit(*ptr) ) ptr++;
					r_gid = atoi(ptr);
					while ( *ptr && isdigit(*ptr) ) ptr++;
					while ( *ptr && !isdigit(*ptr) ) ptr++;
					e_gid = atoi(ptr);
					continue;
				}	
			}

			fclose(fp);
			


			sprintf(fname,"/proc/%d/cmdline",pid);
			fp = fopen(fname,"r");
			if ( fp == NULL ){
				fprintf(ss,"ERR[Cannot open %s]\r\n",fname);
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				return;
			}	
			{
				int c; 
				int lastchar;
				char *ptr;
				ptr = commandline;
				bzero(commandline,1024);
				lastchar = -1;
				c_argc = 0;
				while ( (c = fgetc(fp)) != -1 ){
					if ( c == 0  ){
						c_argc++;
						*ptr = ' '; ptr++;
						continue;
					}
					if ( c == '\n'  ){
						*ptr = ' '; ptr++;
						continue;
					}
					if ( c == '\r'  ){
						*ptr = ' '; ptr++;
						continue;
					}
					if ( c == '\t'  ){
						*ptr = ' '; ptr++;
						continue;
					}
					if ( c == '>'  ){
						*ptr = '&'; ptr++;
						*ptr = 'g'; ptr++;
						*ptr = 't'; ptr++;
						*ptr = ';'; ptr++;
						continue;
					}
					if ( c == '<'  ){
						*ptr = '&'; ptr++;
						*ptr = 'l'; ptr++;
						*ptr = 't'; ptr++;
						*ptr = ';'; ptr++;
						continue;
					}
					*ptr = c;
					ptr++;
					lastchar = c;
				}
			}
			fclose(fp);
			while ( strlen(commandline) && commandline[strlen(commandline)-1] == ' ' ) commandline[strlen(commandline)-1] = '\0';
			if ( commandline[strlen(commandline)-1] == '\r' || commandline[strlen(commandline)-1] == '\n' ) commandline[strlen(commandline)-1] = '\0';
			if ( commandline[strlen(commandline)-1] == '\r' || commandline[strlen(commandline)-1] == '\n' ) commandline[strlen(commandline)-1] = '\0';
			// logger(prefix,"PROCDETAIL: COMMAND-LINE: [%s]\n",commandline);

			sprintf(fname,"/proc/%d/stat",pid);
			fp = fopen(fname,"r");
			if ( fp == NULL ){
				fprintf(ss,"ERR[Cannot open %s]\r\n",fname);
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				return;
			}	
			if ( fgets(fname,1024,fp) == NULL ){ 
				fclose(fp); 
				fprintf(ss,"ERR[Cannot read %s]\r\n",fname);
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				return;
			}
			fclose(fp);

#define EXIT_PROC_READ { fprintf(ss,"ERR[%s:%d corrupted file /proc/%d/stat]\r\n",__FILE__,__LINE__,pid); fflush(ss); shutdown(sock,SHUT_RDWR); fclose(ss); return; }
			ptr = strtok(fname," \t"); // PID
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CMD
			if ( ptr == NULL ) EXIT_PROC_READ;	
			strcpy(exe,ptr);
			ptr = strtok(NULL," \t"); // STATE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			state = *ptr;
			ptr = strtok(NULL," \t"); // PPID
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ppid = atoi(ptr);
			ptr = strtok(NULL," \t"); // PGRP
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // SESSION
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // TTYNR
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // TPGID
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // FLAGS
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // MINFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CMINFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // MAJFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CMAJFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // UTIME
			if ( ptr == NULL ) EXIT_PROC_READ;	
			utime_ticks = atol(ptr);	
			ptr = strtok(NULL," \t"); // STIME
			if ( ptr == NULL ) EXIT_PROC_READ;	
			stime_ticks = atol(ptr);	
			gettimeofday(&start,NULL);
			ptr = strtok(NULL," \t"); // CUTIME
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CSTIME
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // PRIORITY
			if ( ptr == NULL ) EXIT_PROC_READ;	
			priority = atol(ptr);	
			ptr = strtok(NULL," \t"); // NICE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			nice = atol(ptr);	
			ptr = strtok(NULL," \t"); // NUMTHREADS
			if ( ptr == NULL ) EXIT_PROC_READ;	
			num_threads = atol(ptr);	
			ptr = strtok(NULL," \t"); // ITREALVALUE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // STARTTIME
			if ( ptr == NULL ) EXIT_PROC_READ;	
			starttime = atoll(ptr);	
			ptr = strtok(NULL," \t"); // VMSIZE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			vmsize = atol(ptr);	
			ptr = strtok(NULL," \t"); // RSS
			if ( ptr == NULL ) EXIT_PROC_READ;	
			rss = atol(ptr);	
			ptr = strtok(NULL," \t"); // RSSLIM
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // STARTCODE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // ENDCODE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // STARTSTACK
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // KSTKESP
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // KSTKEIP
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // SIGNAL
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // BLOCKED
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // SIGIGNORE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // SIGCATCH
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // WCHAN
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // NSWAP
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CNSWAP
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // EXIT_SIGNAL
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // PROCESSOR
			if ( ptr == NULL ) EXIT_PROC_READ;	
			cpu_id = atoi(ptr);
			p_start = time(NULL) - (sys.uptime - (starttime / sysconf(_SC_CLK_TCK)));
			{ // Sleep now for 0.5 seconds...than check the ticks again
				struct timespec tv;
				struct timespec rem;
				tv.tv_sec = 0;
				tv.tv_nsec = 700000000;
				while ( nanosleep(&tv,&rem) < 0 && errno == EINTR && rem.tv_sec != 0 && rem.tv_nsec != 0 ){
					tv = rem;
				}
			}
			sprintf(fname,"/proc/%d/stat",pid);
			fp = fopen(fname,"r");
			if ( fp == NULL ){
				fprintf(ss,"ERR[Cannot open %s]\r\n",fname);
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				return;
			}
			if ( fgets(fname,1024,fp) == NULL ){ 
				fprintf(ss,"ERR[Cannot read %s]\r\n",fname);
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				fclose(fp);  
				return;
			}	
			fclose(fp);
			ptr = strtok(fname," \t"); // PID
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CMD
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // STATE
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // PPID
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // PGRP
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // SESSION
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // TTYNR
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // TPGID
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // FLAGS
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // MINFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CMINFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // MAJFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // CMAJFLT
			if ( ptr == NULL ) EXIT_PROC_READ;	
			ptr = strtok(NULL," \t"); // UTIME
			if ( ptr == NULL ) EXIT_PROC_READ;	
			utime_ticks2 = atol(ptr);	
			ptr = strtok(NULL," \t"); // STIME
			if ( ptr == NULL ) EXIT_PROC_READ;	
			stime_ticks2 = atol(ptr);	
			gettimeofday(&end,NULL);
			{
				double old, new;
				double ticks; 
				old = (double)start.tv_sec + ((double)start.tv_usec)/1000000.0;
				new = (double)end.tv_sec + ((double)end.tv_usec)/1000000.0;
				ticks = ((double) sysconf(_SC_CLK_TCK)) * (new - old);
				if ( utime_ticks2 ){
					cpu_usage_usr = ((double)(utime_ticks2 -  utime_ticks)/ ticks) * 100.0;
					if ( cpu_usage_usr > 100.0 ) cpu_usage_usr = 100.0;
				} else {
					cpu_usage_usr = 0.0;
				}
				// logger(prefix,"************************* PROCDETAIL: %d [%s] USR:[%.02f %%] Ticks-elapsed: %.02f, Time elapsed: %.02f TICKS: %d\n",pid,exe,cpu_usage_usr,ticks,new-old,utime_ticks2 -  utime_ticks);
				if ( stime_ticks2 ){
					cpu_usage_sys = ((double)(stime_ticks2 -  stime_ticks)/ ticks) * 100.0;
					if ( cpu_usage_sys > 100.0 ) cpu_usage_sys = 100.0;
				} else {
					cpu_usage_sys = 0.0;
				}
				// logger(prefix,"************************* PROCDETAIL: %d [%s] SYS:[%.02f %%] Ticks-elapsed: %.02f, Time elapsed: %.02f TICKS: %d\n",pid,exe,cpu_usage_sys,ticks,new-old,stime_ticks2 -  stime_ticks);

				sprintf(helper,"\"cmd\":\"%s\",\"cpu_usage_sys\":\"%.02f\",\"cpu_usage_usr\":\"%.02f\",",exe,cpu_usage_sys,cpu_usage_usr);		
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"num_threads\":%d,",num_threads);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);
				sprintf(helper,"\"cpu\":%d,",cpu_id);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"full_cwd\":\"%s\",",full_cwd);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"name\":\"%s\",",exe);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"commandline\":\"%s\",",commandline);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"argc\":%d,",c_argc);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				switch(state){
					case 'R':
						sprintf(helper,"\"full_state\":\"R - Running\",");
						break;
					case 'S':
						sprintf(helper,"\"full_state\":\"S - Sleeping\",");
						break;
					case 'D':
						sprintf(helper,"\"full_state\":\"D - Waiting in disk-sleep\",");
						break;
					case 'Z':
						sprintf(helper,"\"full_state\":\"Z - Zombie (defunct)\",");
						break;
					case 'T':
					case 't':
						sprintf(helper,"\"full_state\":\"T - Stopped\",");
						break;
					case 'W':
						sprintf(helper,"\"full_state\":\"W - Paging/Waking\",");
						break;
					case 'X':
					case 'x':
						sprintf(helper,"\"full_state\":\"X - Dead\",");
						break;
					case 'P':
						sprintf(helper,"\"full_state\":\"P - Parked\",");
						break;
					case 'K':
						sprintf(helper,"\"full_state\":\"K - Wakekill\",");
						break;
					default:
						sprintf(helper,"\"full_state\":\"UNKNOWN(%c)\",",state);
						break;
				}	
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);
				{
					int hours;
					int minutes;
					int seconds;
					hours =   (stime_ticks2/sysconf(_SC_CLK_TCK)) / 3600;
					minutes = (stime_ticks2/sysconf(_SC_CLK_TCK) - hours * 3600)/60;
					seconds = (stime_ticks2/sysconf(_SC_CLK_TCK)) % 60;

					sprintf(helper,"\"sys_time\":\"%02d:%02d:%02d&nbsp;(%d ticks)\",",hours,minutes,seconds,stime_ticks2);
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);
				}
				{
					int hours;
					int minutes;
					int seconds;
					hours =   (utime_ticks2/sysconf(_SC_CLK_TCK)) / 3600;
					minutes = (utime_ticks2/sysconf(_SC_CLK_TCK) - hours * 3600)/60;
					seconds = (utime_ticks2/sysconf(_SC_CLK_TCK)) % 60;

					sprintf(helper,"\"usr_time\":\"%02d:%02d:%02d&nbsp;(%d ticks)\",",hours,minutes,seconds,utime_ticks2);
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);
				}

				sprintf(helper,"\"slot\":%d,",slot);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"index\":%d,",index);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"ppid\":%d,",ppid);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				sprintf(helper,"\"fds\":%s,",fd_array);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				{
					struct passwd *pwd;
					struct group  *grp;
					char username[1024];

					pwd = getpwuid(r_uid);
					if ( pwd == NULL ){
						sprintf(username,"%d",r_uid);
					} else {
						strcpy(username,pwd->pw_name);
					}

					sprintf(helper,"\"r_uid\":\"%d (%s)\",",r_uid,username);
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);

					grp = getgrgid(r_gid);
					if ( grp == NULL ){
						sprintf(username,"%d",r_gid);
					} else {
						strcpy(username,grp->gr_name);
					}
	
					sprintf(helper,"\"r_gid\":\"%d (%s)\",",r_gid,username);
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);

					pwd = getpwuid(e_uid);
					if ( pwd == NULL ){
						sprintf(username,"%d",e_uid);
					} else {
						strcpy(username,pwd->pw_name);
					}
	
					sprintf(helper,"\"e_uid\":\"%d (%s)\",",e_uid,username);
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);

					grp = getgrgid(e_gid);
					if ( grp == NULL ){
						sprintf(username,"%d",e_gid);
					} else {
						strcpy(username,grp->gr_name);
					}
	
					sprintf(helper,"\"e_gid\":\"%d (%s)\",",e_gid,username);
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);

				}

				sprintf(helper,"\"full_exe\":\"%s\",",full_exe);
				result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
				strcat(result,helper);

				{
					struct tm *tm;
					tm = localtime(&p_start);
					sprintf(helper,"\"p_start\":\"%04d.%02d.%02d&nbsp;%02d:%02d:%02d\",",
						tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
						tm->tm_hour, tm->tm_min, tm->tm_sec);
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);
				}
#define FAT1024 (1024.0)
				{
					double n_vmsize;
					n_vmsize = (double) vmsize;
					sprintf(helper,"\"vm_size\":\"%d&nbsp;Bytes\",", (int) n_vmsize);				
					if ( n_vmsize > FAT1024 ){ 
						sprintf(helper,"\"vm_size\":\"%.02f&nbsp;KBytes\",", n_vmsize/FAT1024);				
					}
					if ( n_vmsize > (FAT1024*FAT1024) ){ 
						sprintf(helper,"\"vm_size\":\"%.02f&nbsp;MBytes\",", n_vmsize/(FAT1024*FAT1024));				
					}
					if ( n_vmsize > (FAT1024*FAT1024*FAT1024) ){ 
						sprintf(helper,"\"vm_size\":\"%.02f&nbsp;GBytes\",", n_vmsize/(FAT1024*FAT1024*FAT1024));				
					}
					if ( n_vmsize > (FAT1024*FAT1024*FAT1024*FAT1024) ){ 
						sprintf(helper,"\"vm_size\":\"%.02f&nbsp;TBytes\",", n_vmsize/(FAT1024*FAT1024*FAT1024*FAT1024));				
					}
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);
				}
				{	
					double n_rss;
					n_rss = ((double) rss) * ((double) sysconf(_SC_PAGESIZE));
					sprintf(helper,"\"rss\":\"%d&nbsp;Bytes\",", (int)n_rss);				
					if ( n_rss > FAT1024 ){ 
						sprintf(helper,"\"rss\":\"%.02f&nbsp;KBytes\",", n_rss/FAT1024);				
					}
					if ( n_rss > (FAT1024*FAT1024) ){ 
						sprintf(helper,"\"rss\":\"%.02f&nbsp;MBytes\",", n_rss/(FAT1024*FAT1024));				
					}
					if ( n_rss > (FAT1024*FAT1024*FAT1024) ){ 
						sprintf(helper,"\"rss\":\"%.02f&nbsp;GBytes\",", n_rss/(FAT1024*FAT1024*FAT1024));				
					}
					if ( n_rss > (FAT1024*FAT1024*FAT1024*FAT1024) ){ 
						sprintf(helper,"\"rss\":\"%.02f&nbsp;TBytes\",", n_rss/(FAT1024*FAT1024*FAT1024*FAT1024));				
					}
					result = (char *)realloc(result,strlen(result) + strlen(helper) + 10);
					strcat(result,helper);
				}


			}
			if ( result[strlen(result)-1] == ',' ) result[strlen(result)-1] = '\0';
			result = (char *)realloc(result,strlen(result)+2);
			strcat(result,"}");	
			fprintf(ss,"OK[%s]\r\n",result);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
			
		}
		if ( strcmp(command,"PROCLIST") == 0 ){
			int ix;
			int lentries;
			struct ethinfo *eth;
			struct process_info *list;
			DIR *dir;
			struct dirent *diry;
			char *result;
			struct sysinfo sys;
			int cpu_count;
			double *usage_sum;
			int ethcount;
			char *ethjson;
			char *fsjson;
			cpu_count = 0;
			{
				FILE *fp;
				fp = fopen("/proc/stat","r");
				if ( fp != NULL ){
					char buf[1024];
					while ( fgets(buf,1024,fp) != NULL ){
						if ( strncmp(buf,"cpu",3) == 0 ){
							if ( !isspace(buf[3]) ) cpu_count++;
						}
					}
					fclose(fp);
				} 
				if ( cpu_count < 1 ){
					logger(prefix,"PROCLIST: WARNING no CPUs found...assuming 1 CPU\n");
					cpu_count = 1;
				}
			}
			usage_sum = (double *)malloc(sizeof(double) * cpu_count);
			bzero(usage_sum,sizeof(double) * cpu_count);

			{ 
				FILE *fp;
				char buf[1024];

				ethcount = 0;
				fp = fopen("/proc/net/dev","r");
				if ( fp == NULL ){
					fprintf(ss,"\r\nERR[Cannot open /proc/net/dev]\r\n");
					fflush(ss);
					shutdown(sock,SHUT_RDWR);
					fclose(ss);
					return;
				}				
				eth = NULL;
				while ( fgets(buf,1024,fp) != NULL ){
					char ifname[256];
					char *ptr;
					char bytes_receive[64];
					char packets_receive[64];
					char errs_receive[64];
					char drop_receive[64];
					char bytes_transmit[64];
					char packets_transmit[64];
					char errs_transmit[64];
					char drop_transmit[64];
					char colls[64];
					if ( strstr(buf,":") == NULL ) continue;
					ptr = strtok(buf,":\t\r\n ");
					if ( ptr == NULL ) continue;
					sprintf(ifname,"%s",ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(bytes_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(packets_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(errs_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(drop_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // FIFO

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // FRAME

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // COMPRESSED

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // MULTICAST

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(bytes_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(packets_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(errs_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(drop_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // FIFO

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(colls,ptr);
					
					eth = (struct ethinfo *)realloc(eth,sizeof(struct ethinfo) * (ethcount+1));	
					bzero(&eth[ethcount],sizeof(struct ethinfo));
					gettimeofday(&(eth[ethcount].stamp1),NULL);	
					strcpy(eth[ethcount].ifname,ifname);
					strcpy(eth[ethcount].if_mac,get_interface_address(ifname,AF_PACKET));
					strcpy(eth[ethcount].if_ipv4,get_interface_address(ifname,AF_INET));
					strcpy(eth[ethcount].if_ipv6,get_interface_address(ifname,AF_INET6));
					eth[ethcount].bytes_receive_1 = atoll(bytes_receive);
					eth[ethcount].packets_receive_1 = atoll(packets_receive);
					eth[ethcount].error_receive_1 = atoll(errs_receive);
					eth[ethcount].drop_receive_1 = atoll(drop_receive);
					eth[ethcount].bytes_transmit_1 = atoll(bytes_transmit);
					eth[ethcount].packets_transmit_1 = atoll(packets_transmit);
					eth[ethcount].error_transmit_1 = atoll(errs_transmit);
					eth[ethcount].drop_transmit_1 = atoll(drop_transmit);
					eth[ethcount].colls_1 = atoll(colls);
					strcpy(eth[ethcount].bytes_receive_t,convert_bytes((double)eth[ethcount].bytes_receive_1,"Bytes"));
					strcpy(eth[ethcount].packets_receive_t,convert_bytes((double)eth[ethcount].packets_receive_1,"Packets"));
					strcpy(eth[ethcount].error_receive_t,convert_bytes((double)eth[ethcount].error_receive_1,"Packets"));
					strcpy(eth[ethcount].drop_receive_t,convert_bytes((double)eth[ethcount].drop_receive_1,"Packets"));
					strcpy(eth[ethcount].bytes_transmit_t,convert_bytes((double)eth[ethcount].bytes_transmit_1,"Bytes"));
					strcpy(eth[ethcount].packets_transmit_t,convert_bytes((double)eth[ethcount].packets_transmit_1,"Packets"));
					strcpy(eth[ethcount].error_transmit_t,convert_bytes((double)eth[ethcount].error_transmit_1,"Packets"));
					strcpy(eth[ethcount].drop_transmit_t,convert_bytes((double)eth[ethcount].drop_transmit_1,"Packets"));
					strcpy(eth[ethcount].colls_t,convert_bytes((double)eth[ethcount].colls_1,"Packets"));
					ethcount++;
					// logger(prefix,"ETHINFO [%s] --> Bytes: [%s]\n",eth[ethcount-1].ifname, eth[ethcount-1].bytes_receive_t);
				}		
				fclose(fp);	
			
			}


			sysinfo(&sys);

			list = NULL;
			lentries = 0;
			dir = opendir("/proc");
			if ( dir == NULL ){
				fprintf(ss,"\r\nERR[Cannot open /proc]\r\n");
				fflush(ss);
				shutdown(sock,SHUT_RDWR);
				fclose(ss);
				return;
			}
			while ( (diry = readdir(dir)) != NULL ){
				char fname[1024];
				char exe[1024];
				char state;
				unsigned long utime;
				unsigned long stime;
				unsigned long cutime;
				unsigned long cstime;
				long priority;
				long nice;
				long rss;
				long num_threads;
				long long starttime;
				unsigned long vmsize;
				int ppid;
				int cpu_id;
				char *ptr;
				int pid;
				FILE *fp;

				if ( !isdigit(diry->d_name[0]) ) continue;	
				pid = atoi(diry->d_name);
				sprintf(fname,"/proc/%d/stat",pid);
				fp = fopen(fname,"r");
				if ( fp == NULL ) continue;
				if ( fgets(fname,1024,fp) == NULL ){ fclose(fp); continue; }	
				fclose(fp);
				ptr = strtok(fname," \t"); // PID
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // CMD
				if ( ptr == NULL ) continue;	
				strcpy(exe,ptr);
				ptr = strtok(NULL," \t"); // STATE
				if ( ptr == NULL ) continue;	
				state = *ptr;
				ptr = strtok(NULL," \t"); // PPID
				if ( ptr == NULL ) continue;	
				ppid = atoi(ptr);
				ptr = strtok(NULL," \t"); // PGRP
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // SESSION
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // TTYNR
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // TPGID
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // FLAGS
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // MINFLT
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // CMINFLT
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // MAJFLT
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // CMAJFLT
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // UTIME
				if ( ptr == NULL ) continue;	
				utime = atol(ptr);	
				ptr = strtok(NULL," \t"); // STIME
				if ( ptr == NULL ) continue;	
				stime = atol(ptr);	
				ptr = strtok(NULL," \t"); // CUTIME
				if ( ptr == NULL ) continue;	
				cutime = atol(ptr);	
				ptr = strtok(NULL," \t"); // CSTIME
				if ( ptr == NULL ) continue;	
				cstime = atol(ptr);	
				ptr = strtok(NULL," \t"); // PRIORITY
				if ( ptr == NULL ) continue;	
				priority = atol(ptr);	
				ptr = strtok(NULL," \t"); // NICE
				if ( ptr == NULL ) continue;	
				nice = atol(ptr);	
				ptr = strtok(NULL," \t"); // NUMTHREADS
				if ( ptr == NULL ) continue;	
				num_threads = atol(ptr);	
				ptr = strtok(NULL," \t"); // ITREALVALUE
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // STARTTIME
				if ( ptr == NULL ) continue;	
				starttime = atoll(ptr);	
				ptr = strtok(NULL," \t"); // VMSIZE
				if ( ptr == NULL ) continue;	
				vmsize = atol(ptr);	
				ptr = strtok(NULL," \t"); // RSS
				if ( ptr == NULL ) continue;	
				rss = atol(ptr);	
				ptr = strtok(NULL," \t"); // RSSLIM
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // STARTCODE
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // ENDCODE
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // STARTSTACK
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // KSTKESP
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // KSTKEIP
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // SIGNAL
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // BLOCKED
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // SIGIGNORE
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // SIGCATCH
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // WCHAN
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // NSWAP
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // CNSWAP
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // EXIT_SIGNAL
				if ( ptr == NULL ) continue;	
				ptr = strtok(NULL," \t"); // PROCESSOR
				if ( ptr == NULL ) continue;	
				cpu_id = atoi(ptr);

				// logger(prefix,"PROCLIST (%d) CPU: [%d], RSS: [%ld], PPID: %d [%s] VMSIZE: %lu Bytes, NICE: %ld UTIME: %lu ticks STIME: %lu ticks (%d Ticks per second)\n",pid,cpu_id,rss,ppid,exe,vmsize,nice,utime,stime,sysconf(_SC_CLK_TCK));

				list = (struct process_info *)realloc(list,sizeof(struct process_info) * (lentries+1));
				list[lentries].pid  = pid;
				list[lentries].ppid = ppid;
				list[lentries].vmsize = vmsize;
				sprintf(list[lentries].vmtext,"%lu&nbsp;B",vmsize);
				if ( vmsize > 1024 ) sprintf(list[lentries].vmtext,"%lu&nbsp;kB",vmsize / 1024);
				if ( vmsize > (1024*1024) ) sprintf(list[lentries].vmtext,"%lu&nbsp;MB",vmsize / (1024 * 1024));
				strcpy(list[lentries].program,exe);
				list[lentries].nice = nice;
				list[lentries].num_threads = num_threads;
				list[lentries].cpu = cpu_id;
				list[lentries].rss = rss;
				list[lentries].priority = priority;
				list[lentries].ptime = (utime + stime) / sysconf(_SC_CLK_TCK);
				list[lentries].utime = utime;
				list[lentries].utime2 = -1;
				list[lentries].stime = stime;
				list[lentries].stime2 = -1;
				list[lentries].starttime = time(NULL) - (sys.uptime - (starttime / sysconf(_SC_CLK_TCK)));
				gettimeofday(&(list[lentries].stamp),NULL);
				lentries++;
			}
			closedir(dir); 	
			{ // Sleep now for 0.5 seconds...than check the ticks again
				struct timespec tv;
				struct timespec rem;
				tv.tv_sec = 0;
				tv.tv_nsec = 800000000;
				while ( nanosleep(&tv,&rem) < 0 && errno == EINTR && rem.tv_sec != 0 && rem.tv_nsec != 0 ){
					tv = rem;
				}
				for ( ix = 0; ix < lentries; ix++ ){
					char fname[1024];
					FILE *fp;
					unsigned long utime;
					unsigned long stime;
					
					sprintf(fname,"/proc/%d/stat",list[ix].pid);
					fp = fopen(fname,"r");
					if ( fp == NULL ) continue;
					if ( fgets(fname,1024,fp) == NULL ){ fclose(fp); continue; }	
					fclose(fp);
					ptr = strtok(fname," \t"); // PID
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // CMD
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // STATE
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // PPID
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // PGRP
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // SESSION
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // TTYNR
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // TPGID
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // FLAGS
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // MINFLT
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // CMINFLT
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // MAJFLT
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // CMAJFLT
					if ( ptr == NULL ) continue;	
					ptr = strtok(NULL," \t"); // UTIME
					if ( ptr == NULL ) continue;	
					utime = atol(ptr);	
					ptr = strtok(NULL," \t"); // STIME
					if ( ptr == NULL ) continue;	
					stime = atol(ptr);	
					list[ix].utime2 = utime - list[ix].utime;
					list[ix].stime2 = stime - list[ix].stime;
					gettimeofday(&(list[ix].stamp2),NULL);
					{
						double old, new;
						double ticks; 
						old = (double)list[ix].stamp.tv_sec + ((double)list[ix].stamp.tv_usec)/1000000.0;
						new = (double)list[ix].stamp2.tv_sec + ((double)list[ix].stamp2.tv_usec)/1000000.0;
						ticks = ((double) sysconf(_SC_CLK_TCK)) * (new - old);
						if ( list[ix].utime2 || list[ix].stime2 ){
							list[ix].cpu_usage = ((double)(list[ix].utime2 +  list[ix].stime2)/ ticks) * 100.0;
							if ( list[ix].cpu_usage >= 100.0 ) list[ix].cpu_usage = 100.0; // Quick & Dirty :-)
							//  logger(prefix,"************************* PROCLIST: %d [%s] [%.02f %%] Ticks-elapsed: %.02f, Time elapsed: %.02f, UTIME2: %d, STIME2: %d\n",list[ix].pid,list[ix].program,list[ix].cpu_usage,ticks,new-old, list[ix].utime2, list[ix].stime2);
						} else {
							list[ix].cpu_usage = 0.0;
						}
						
					}
				}	
			}
			{ 
				FILE *fp;
				char buf[1024];
				ethcount = 0;
				fp = fopen("/proc/net/dev","r");
				if ( fp == NULL ){
					fprintf(ss,"\r\nERR[Cannot open /proc/net/dev]\r\n");
					fflush(ss);
					shutdown(sock,SHUT_RDWR);
					fclose(ss);
					return;
				}				
				while ( fgets(buf,1024,fp) != NULL ){
					char ifname[256];
					char *ptr;
					char bytes_receive[64];
					char packets_receive[64];
					char errs_receive[64];
					char drop_receive[64];
					char bytes_transmit[64];
					char packets_transmit[64];
					char errs_transmit[64];
					char drop_transmit[64];
					char colls[64];
					if ( strstr(buf,":") == NULL ) continue;
					ptr = strtok(buf,":\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(ifname,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(bytes_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(packets_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(errs_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(drop_receive,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // FIFO

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // FRAME

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // COMPRESSED

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // MULTICAST

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(bytes_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(packets_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(errs_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(drop_transmit,ptr);

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue; // FIFO

					ptr = strtok(NULL,"\t\r\n ");
					if ( ptr == NULL ) continue;
					strcpy(colls,ptr);
					
					gettimeofday(&(eth[ethcount].stamp2),NULL);	
					eth[ethcount].bytes_receive_2 = atoll(bytes_receive);
					eth[ethcount].packets_receive_2 = atoll(packets_receive);
					eth[ethcount].error_receive_2 = atoll(errs_receive);
					eth[ethcount].drop_receive_2 = atoll(drop_receive);
					eth[ethcount].bytes_transmit_2 = atoll(bytes_transmit);
					eth[ethcount].packets_transmit_2 = atoll(packets_transmit);
					eth[ethcount].error_transmit_2 = atoll(errs_transmit);
					eth[ethcount].drop_transmit_2 = atoll(drop_transmit);
					eth[ethcount].colls_2 = atoll(colls);
					strcpy(eth[ethcount].bytes_receive_t,convert_bytes((double)eth[ethcount].bytes_receive_2,"Bytes"));
					strcpy(eth[ethcount].packets_receive_t,convert_bytes((double)eth[ethcount].packets_receive_2,"Packets"));
					strcpy(eth[ethcount].error_receive_t,convert_bytes((double)eth[ethcount].error_receive_2,"Packets"));
					strcpy(eth[ethcount].drop_receive_t,convert_bytes((double)eth[ethcount].drop_receive_2,"Packets"));
					strcpy(eth[ethcount].bytes_transmit_t,convert_bytes((double)eth[ethcount].bytes_transmit_2,"Bytes"));
					strcpy(eth[ethcount].packets_transmit_t,convert_bytes((double)eth[ethcount].packets_transmit_2,"Packets"));
					strcpy(eth[ethcount].error_transmit_t,convert_bytes((double)eth[ethcount].error_transmit_2,"Packets"));
					strcpy(eth[ethcount].drop_transmit_t,convert_bytes((double)eth[ethcount].drop_transmit_2,"Packets"));
					strcpy(eth[ethcount].colls_t,convert_bytes((double)eth[ethcount].colls_2,"Packets"));
					{
						double timediff;
						double datadiff;	
						double datasec;

						eth[ethcount].timestamp_calc = (((double) eth[ethcount].stamp1.tv_sec) + ((double) eth[ethcount].stamp1.tv_usec) / 1000000.0);
						timediff = (((double) eth[ethcount].stamp2.tv_sec) + ((double) eth[ethcount].stamp2.tv_usec) / 1000000.0) - (((double) eth[ethcount].stamp1.tv_sec) + ((double) eth[ethcount].stamp1.tv_usec) / 1000000.0);

						datadiff = ((double) eth[ethcount].bytes_receive_2) -  ((double) eth[ethcount].bytes_receive_1);
						datasec = datadiff / timediff;
						eth[ethcount].bytes_receive_sec = datasec;
						sprintf(eth[ethcount].bytes_receive_sec_t,"%s/s",convert_bytes(datasec,"Bytes"));

						datadiff = ((double) eth[ethcount].packets_receive_2) -  ((double) eth[ethcount].packets_receive_1);
						datasec = datadiff / timediff;
						eth[ethcount].packets_receive_sec = datasec;
						sprintf(eth[ethcount].packets_receive_sec_t,"%s/s",convert_bytes(datasec,"Packets"));
						
						datadiff = ((double) eth[ethcount].error_receive_2) -  ((double) eth[ethcount].error_receive_1);
						datasec = datadiff / timediff;
						eth[ethcount].error_receive_sec = datasec;
						sprintf(eth[ethcount].error_receive_sec_t,"%s/s",convert_bytes(datasec,"Packets"));
						
						datadiff = ((double) eth[ethcount].drop_receive_2) -  ((double) eth[ethcount].drop_receive_1);
						datasec = datadiff / timediff;
						eth[ethcount].drop_receive_sec = datasec;
						sprintf(eth[ethcount].drop_receive_sec_t,"%s/s",convert_bytes(datasec,"Packets"));

						datadiff = ((double) eth[ethcount].bytes_transmit_2) -  ((double) eth[ethcount].bytes_transmit_1);
						datasec = datadiff / timediff;
						eth[ethcount].bytes_transmit_sec = datasec;
						sprintf(eth[ethcount].bytes_transmit_sec_t,"%s/s",convert_bytes(datasec,"Bytes"));

						datadiff = ((double) eth[ethcount].packets_transmit_2) -  ((double) eth[ethcount].packets_transmit_1);
						datasec = datadiff / timediff;
						eth[ethcount].packets_transmit_sec = datasec;
						sprintf(eth[ethcount].packets_transmit_sec_t,"%s/s",convert_bytes(datasec,"Packets"));
						
						datadiff = ((double) eth[ethcount].error_transmit_2) -  ((double) eth[ethcount].error_transmit_1);
						datasec = datadiff / timediff;
						eth[ethcount].error_transmit_sec = datasec;
						sprintf(eth[ethcount].error_transmit_sec_t,"%s/s",convert_bytes(datasec,"Packets"));
						
						datadiff = ((double) eth[ethcount].drop_transmit_2) -  ((double) eth[ethcount].drop_transmit_1);
						datasec = datadiff / timediff;
						eth[ethcount].drop_transmit_sec = datasec;
						sprintf(eth[ethcount].drop_transmit_sec_t,"%s/s",convert_bytes(datasec,"Packets"));

						datadiff = ((double) eth[ethcount].colls_2) -  ((double) eth[ethcount].colls_1);
						datasec = datadiff / timediff;
						eth[ethcount].colls_sec = datasec;
						sprintf(eth[ethcount].colls_sec_t,"%s/s",convert_bytes(datasec,"Packets"));



						// logger(prefix,"ETHINFO(2) [%s] --> B: [%llu] Timediff: %.02f D: %.02f Bytes [%s]\n",eth[ethcount].ifname, eth[ethcount].bytes_receive_1,timediff,datadiff,eth[ethcount].bytes_receive_sec_t);
					}
					ethcount++;
				}		
				fclose(fp);	
			}
			// logger(prefix,"ETHINFO: Interfaces found: %d\n",ethcount);
			qsort(&eth[0],ethcount,sizeof(struct ethinfo),comparer_eth);
			// logger(prefix,"ETHINFO: Interfaces found: %d\n",ethcount);
			{
				int idx;
				ethjson = strdup("[");
				for ( idx = 0; idx < ethcount; idx++ ){
					char line[1048];

					sprintf(line,"{\"ifname\":\"%s\",\"timestamp\":%.06f,",
						eth[idx].ifname, eth[idx].timestamp_calc);
					sprintf(&line[strlen(line)],"\"mac_addr\":\"%s\",\"ipv4_addr\":\"%s\",\"ipv6_addr\":\"%s\",",
						eth[idx].if_mac, eth[idx].if_ipv4,eth[idx].if_ipv6);
					sprintf(&line[strlen(line)],"\"bytes_in_t\":\"%s\",\"bytes_out_t\":\"%s\",",
						eth[idx].bytes_receive_t, eth[idx].bytes_transmit_t);
					sprintf(&line[strlen(line)],"\"packets_in_t\":\"%s\",\"packets_out_t\":\"%s\",",
						eth[idx].packets_receive_t, eth[idx].packets_transmit_t);
					sprintf(&line[strlen(line)],"\"bytes_in_sec\":\"%s\",\"bytes_out_sec\":\"%s\",",
						eth[idx].bytes_receive_sec_t, eth[idx].bytes_transmit_sec_t);
					sprintf(&line[strlen(line)],"\"bytes_in\":%llu,\"bytes_out\":%llu,",
						eth[idx].bytes_receive_1, eth[idx].bytes_transmit_1);
					sprintf(&line[strlen(line)],"\"packets_in\":%llu,\"packets_out\":%llu,",
						eth[idx].packets_receive_1, eth[idx].packets_transmit_1);
					sprintf(&line[strlen(line)],"\"packets_out_sec\":\"%s\",\"packets_in_sec\":\"%s\"},",
						eth[idx].packets_transmit_sec_t, eth[idx].packets_receive_sec_t);


					// logger(prefix,"ETHINFO[%d]: [%s] Timestamp: %.06f [%s], [%s] R: %llu T: %llu TRS: [%s] RRS: [%s] \n",idx,eth[idx].ifname, eth[idx].timestamp_calc,eth[idx].packets_transmit_sec_t, eth[idx].packets_receive_sec_t,  eth[idx].bytes_receive_1, eth[idx].bytes_transmit_1, eth[idx].bytes_receive_sec_t, eth[idx].bytes_transmit_sec_t);

					ethjson = (char *)realloc(ethjson,strlen(ethjson) + strlen(line) + 10);
					sprintf(&ethjson[strlen(ethjson)],"%s",line);
				}
				if ( ethjson[strlen(ethjson)-1] == ',' ) ethjson[strlen(ethjson)-1] = '\0';
				ethjson = (char *)realloc(ethjson,strlen(ethjson) +  10);
				strcat(ethjson,"]");
				
			}
			{ 
				// Get File-System information
				FILE *fp;
				char buf[1024];

				fsjson = strdup("[");

				fp = fopen("/proc/self/mountinfo","r");
				if ( fp != NULL ){
					while (fgets(buf,1024,fp)!= NULL ){
						char line[1024];
						char *ptr;
						char path[256];
						char dev[256];
						char dev_name[256];
						char type[256];
						struct statfs st;
						ptr = strtok(buf," \t\r\n");
						if ( ptr == NULL ) continue; // ID
						ptr = strtok(NULL," \t\r\n");
						if ( ptr == NULL ) continue; // Blabla
						ptr = strtok(NULL," \t\r\n");
						if ( ptr == NULL ) continue; // DEV
						strcpy(dev,ptr);
						ptr = strtok(NULL," \t\r\n");
						if ( ptr == NULL ) continue; // SLASH
						ptr = strtok(NULL," \t\r\n");
						if ( ptr == NULL ) continue; // PATH
						strcpy(path,ptr);
						ptr = strtok(NULL," \t\r\n");
						if ( ptr == NULL ) continue; // OPT
						ptr = strtok(NULL," \t\r\n");
						if ( ptr == NULL ) continue; // X
						ptr = strtok(NULL," \t\r\n");
						if ( ptr == NULL ) continue; // TYPE
						strcpy(type,ptr);
						if ( strncmp(type,"ext",3) != 0  ) continue;
						if ( statfs(path,&st) ) continue;
						logger(prefix,"DSINFO [%s] --> [%s] BLK-SIZE: %d BLOCKS: %llu\n",path,type,(int) st.f_frsize,(unsigned long long) st.f_blocks);	
						strcpy(dev_name, get_diskname(dev));
						sprintf(line,"{\"path\":\"%s\",",path);
						sprintf(&line[strlen(line)],"\"type\":\"%s\",",type);
						sprintf(&line[strlen(line)],"\"dev\":\"%s\",",dev);
						sprintf(&line[strlen(line)],"\"dev_name\":\"%s\",",dev_name);
						sprintf(&line[strlen(line)],"\"b_total\":%llu,",(unsigned long long) st.f_blocks * (unsigned long long) st.f_frsize);
						sprintf(&line[strlen(line)],"\"b_total_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_blocks * (unsigned long long) st.f_frsize),"Bytes"));
						sprintf(&line[strlen(line)],"\"b_free\":%llu,",(unsigned long long) st.f_bfree * (unsigned long long) st.f_frsize);
						sprintf(&line[strlen(line)],"\"b_free_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_bavail * (unsigned long long) st.f_frsize),"Bytes"));
						sprintf(&line[strlen(line)],"\"b_avail\":%llu,",(unsigned long long) st.f_bavail * (unsigned long long) st.f_frsize);
						sprintf(&line[strlen(line)],"\"b_avail_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_bavail * (unsigned long long) st.f_frsize),"Bytes"));
						sprintf(&line[strlen(line)],"\"i_total\":%llu,",(unsigned long long) st.f_files);
						sprintf(&line[strlen(line)],"\"i_total_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_files),"Inodes"));
						sprintf(&line[strlen(line)],"\"i_free\":%llu,",(unsigned long long) st.f_ffree );
						sprintf(&line[strlen(line)],"\"i_free_t\":\"%s\"",convert_bytes((double)((unsigned long long) st.f_ffree),"Inodes"));
						sprintf(&line[strlen(line)],"},");
						fsjson = (char *)realloc(fsjson,strlen(fsjson) + strlen(line) + 10);
						sprintf(&fsjson[strlen(fsjson)],"%s",line);

					}
					fclose(fp);
				} else {
					logger(prefix,"Getting Filesystems from /proc/mounts...\n");
					fp = fopen("/proc/mounts","r");
					if ( fp != NULL ){
						while (fgets(buf,1024,fp)!= NULL ){
							char line[1024];
							char *ptr;
							char path[256];
							char dev[256];
							char dev_name[256];
							char type[256];
							struct statfs st;
							ptr = strtok(buf," \t\r\n");
							if ( ptr == NULL ) continue; // DEV
							strcpy(dev,ptr);
							ptr = strtok(NULL," \t\r\n");
							if ( ptr == NULL ) continue; // PATH
							strcpy(path,ptr);
							ptr = strtok(NULL," \t\r\n");
							if ( ptr == NULL ) continue; // TYPE
							strcpy(type,ptr);
							if ( strncmp(type,"ext",3) != 0  ) continue;
							if ( statfs(path,&st) ) continue;
							logger(prefix,"DSINFO [%s] --> [%s] BLK-SIZE: %d BLOCKS: %llu\n",path,type,(int) st.f_frsize,(unsigned long long) st.f_blocks);	
							strcpy(dev_name, get_diskname(path));
							sprintf(line,"{\"path\":\"%s\",",path);
							sprintf(&line[strlen(line)],"\"type\":\"%s\",",type);
							sprintf(&line[strlen(line)],"\"dev\":\"%s\",",dev);
							sprintf(&line[strlen(line)],"\"dev_name\":\"%s\",",dev_name);
							sprintf(&line[strlen(line)],"\"b_total\":%llu,",(unsigned long long) st.f_blocks * (unsigned long long) st.f_frsize);
							sprintf(&line[strlen(line)],"\"b_total_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_blocks * (unsigned long long) st.f_frsize),"Bytes"));
							sprintf(&line[strlen(line)],"\"b_free\":%llu,",(unsigned long long) st.f_bfree * (unsigned long long) st.f_frsize);
							sprintf(&line[strlen(line)],"\"b_free_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_bavail * (unsigned long long) st.f_frsize),"Bytes"));
							sprintf(&line[strlen(line)],"\"b_avail\":%llu,",(unsigned long long) st.f_bavail * (unsigned long long) st.f_frsize);
							sprintf(&line[strlen(line)],"\"b_avail_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_bavail * (unsigned long long) st.f_frsize),"Bytes"));
							sprintf(&line[strlen(line)],"\"i_total\":%llu,",(unsigned long long) st.f_files);
							sprintf(&line[strlen(line)],"\"i_total_t\":\"%s\",",convert_bytes((double)((unsigned long long) st.f_files),"Inodes"));
							sprintf(&line[strlen(line)],"\"i_free\":%llu,",(unsigned long long) st.f_ffree );
							sprintf(&line[strlen(line)],"\"i_free_t\":\"%s\"",convert_bytes((double)((unsigned long long) st.f_ffree),"Inodes"));
							sprintf(&line[strlen(line)],"},");
							fsjson = (char *)realloc(fsjson,strlen(fsjson) + strlen(line) + 10);
							sprintf(&fsjson[strlen(fsjson)],"%s",line);
						}
						fclose(fp);
					}
				}

				if ( fsjson[strlen(fsjson)-1] == ',' ) fsjson[strlen(fsjson)-1] = '\0';
				fsjson = (char *)realloc(fsjson,strlen(fsjson) + 10);
				sprintf(&fsjson[strlen(fsjson)],"]");
				
			}



			qsort(&list[0],lentries,sizeof(struct process_info), comparer);
			// logger(prefix,"************************PROCLIST:  Sorted %d processes\n",lentries);
			result = strdup("{\"pl\":[");
			for ( ix = 0; ix < lentries; ix++ ){
				char line[1024];
				char ptime[32];
				char stime[32];
				char rss[32];
				double rss_val;
				int slot, index;
				struct tm *tm;
				int hours;
				int minutes;
				int seconds;
				slot = -1;
				index = -1;
				if ( list[ix].pid > 10 ) { 
					int k,l;
					for ( k = 0; k < entries; k++ ){
						for ( l = 0; l < MAX_CONNS; l++ ){
							if ( servlist[k].co[l].cpid == list[ix].pid ){
								slot = k;
								index = l;
								break;
							}
						}
						if ( slot >= 0 ) break;
					}
				}
				hours = list[ix].ptime / 3600;
				minutes = (list[ix].ptime - hours * 3600)/60;
				seconds = list[ix].ptime % 60;
				tm = localtime(&list[ix].starttime);
				sprintf(ptime,"%02d:%02d:%02d",hours,minutes,seconds);
				sprintf(stime,"%04d.%02d.%02d&nbsp;%02d:%02d:%02d",
					tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
					tm->tm_hour, tm->tm_min, tm->tm_sec);


				rss_val = (double) (list[ix].rss * sysconf(_SC_PAGESIZE));
				sprintf(rss,"%d&nbsp;Bytes",(int)rss_val);
				if ( rss_val > 1024.0 ){
					sprintf(rss,"%.02f&nbsp;KB",rss_val / 1024.0);
				}
				if ( rss_val > (1024.0*1024.0) ){
					sprintf(rss,"%.02f&nbsp;MB",rss_val / (1024.0 * 1024.0));
				}
					

				sprintf(line,"{\"rss\":\"%s\",\"num_threads\":%d,\"cpu\":%d,\"cpu_usage\":\"%.02f\",\"pid\":%d,\"ppid\":%d,\"vmsize\":\"%s\",\"prg\":\"%s\",\"stime\":\"%s\",\"ptime\":\"%s\",\"slot\":%d,\"index\":%d,\"_utime\":%ld,\"_stime\":%ld,\"nice\":%ld,\"priority\":%ld},",
					rss, list[ix].num_threads, list[ix].cpu, list[ix].cpu_usage, list[ix].pid,list[ix].ppid,list[ix].vmtext,list[ix].program,stime,ptime,slot,index,list[ix].utime,list[ix].stime,list[ix].nice,list[ix].priority);
				// logger(prefix,"[%05d]PROCLIST: [%s] STRLEN RESULT: %d\n",ix,line,strlen(result));
				if ( list[ix].cpu > cpu_count ){
					usage_sum[0] += list[ix].cpu_usage;	
				} else {
					usage_sum[list[ix].cpu] += list[ix].cpu_usage;	
				}
				result = (char *)realloc(result,strlen(result)+strlen(line)+10);
				strcat(result,line);
			
			}
			if ( result[strlen(result)-1] == ',' ) result[strlen(result)-1] = '\0';
			{
				char tempbuf[20240];
				int dan;
				sprintf(tempbuf,"],\"eth\":%s,\"fs\":%s,\"cpu_count\":%d,\"ul\":[",ethjson,fsjson,cpu_count);
				result = (char *)realloc(result,strlen(result)+strlen(tempbuf) + 10);
				strcat(result,tempbuf);
				for ( dan = 0; dan < cpu_count; dan++ ){
					if ( usage_sum[dan] > 100.0 ) usage_sum[dan] = 100.0;
					sprintf(tempbuf,"{\"total\":\"%.02f\"},",usage_sum[dan]);
					result = (char *)realloc(result,strlen(result)+strlen(tempbuf) + 10);
					strcat(result,tempbuf);
				}
				
				if ( result[strlen(result)-1] == ',' ) result[strlen(result)-1] = '\0';
				result = (char *)realloc(result,strlen(result)+ 10);
				strcat(result,"]}");
			}
			{
				char *in;
				char *out;
				int newsize;
				in = (char *)malloc(strlen(result) + 20);
				out = (char *)malloc(strlen(result) + 120);
				sprintf(in,"OK[%s]\r\n",result);
				newsize = gzip_string(in,out);
				if ( newsize > 0 ){
					fprintf(ss,"Accept-Range: bytes\r\n");
					fprintf(ss,"Content-Length: %d\r\n",newsize);	
					fprintf(ss,"Content-Encoding: gzip\r\n\r\n",newsize);	
					fwrite(out,1,newsize,ss);
					fflush(ss);
				} else {
					logger(prefix,"GZIP-FAILED: [%d] <-- [%d]\n",newsize,strlen(in));
					fprintf(ss,"\r\n%s",in);
				}
			}
			free(result);
			free(list);
			free(usage_sum);
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
			
		}

		if ( strcmp(command,"RESET") == 0 ){
			int idx;
			fprintf(ss,"\r\n");
			logger(prefix,"Resetting %d connections\n",entries);
			for ( idx = 0; idx < entries; idx++ ){
				int semmel;
				semmel = semget(INETD_KEY2 + idx,1,0);
				if ( semmel < 0 ){
					logger(prefix,"Cannot get SEM [0x%08lX]\n",INETD_KEY2 + idx);
				} else {
					sem_lock(semmel);
					servlist[idx].reset = time(NULL);
					servlist[idx].total_count = 0;
					sem_unlock(semmel);
				}
			}
			fprintf(ss,"OK[Reset done]\r\n");
			fflush(ss);
			shutdown(sock,SHUT_RDWR);
			fclose(ss);
			return;
		}


		fprintf(ss,"\r\n");
		fprintf(ss,"ERR[Bad function]\r\n");
		
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
	html_done = 0;
	if ( type_req == TYPE_HTML && strncmp(url,"/supervisor",strlen("/supervisor")) == 0 ){
		html_done = 1;
		fprintf(ss,"Content-Type: %s\r\n\r\n",HTML_MIME);
		fprintf(ss,"<HEAD><meta CHARSET=\"UTF-8\"><LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"/style.css\"></HEAD>\n");
		fprintf(ss,"<BODY CLASS='mainbody' onload=init_all()>");
		fprintf(ss,"<DIV CLASS='headline'><TABLE BORDER=0 WIDTH=100%%><TR><TD ALIGN=LEFT WIDTH=33%%><IMG CLASS=l_image onclick=go_main() SRC=/gix_logo.png></TD><TD WIDTH=33%%><CENTER><SPAN CLASS=headliner>%s (Supervisor) @ %s</SPAN></TD><TD ALIGN=RIGHT WIDTH=33%%><TABLE BORDER=0><TR><TD ALIGN=RIGHT>You:</TD><TD ALIGN=LEFT><B>%s</B></TD></TR><TR><TD ALIGN=RIGHT>Me:</TD><TD ALIGN=LEFT><B>%s</B></TD></TR></TABLE></TD></TR></TABLE>",
			GIX_INETD_VERSION, my_hostname, CCON.source, CCON.target);
		fprintf(ss,"</DIV>");
		fprintf(ss,"<DIV ID='MAIN' CLASS=mainscreen>\n");
		fprintf(ss,"<CENTER>");
		fprintf(ss,"<TABLE BORDER=0 CELLSPACING=1>\n");
		fprintf(ss,"<TR><TD VALIGN=TOP>");
		fprintf(ss,"<DIV ID=HOSTLIST CLASS=simple_div></DIV>");
		fprintf(ss,"</TD><TD VALIGN=TOP>");
		fprintf(ss,"<TABLE BORDER=0 BGCOLOR=black CELLSPACING=1>\n");
		fprintf(ss,"<TR BGCOLOR=lightblue><TD ALIGN=RIGHT><SPAN CLASS=thead2>Scan-IP Start (IPv4):</SPAN></TD><TD ALIGN=LEFT><INPUT TYPE=TEXT CLASS=input2s ID=IPSCAN_START onchange=update_end_field()></TD><TD ROWSPAN=2 VALIGN=BOTTOM><INPUT TYPE=BUTTON VALUE='Start scan...' CLASS=standard_button onclick=start_scan()></TD></TR>\n");
		fprintf(ss,"<TR BGCOLOR=lightblue><TD ALIGN=RIGHT><SPAN CLASS=thead2>Scan-IP End (IPv4):</SPAN></TD><TD ALIGN=LEFT><INPUT TYPE=TEXT CLASS=input2s ID=IPSCAN_END></TD></TR>\n");
		fprintf(ss,"</TABLE>\n");
		fprintf(ss,"</TD></TR>");
		fprintf(ss,"</TABLE>\n");
		fprintf(ss,"</DIV>");

		fprintf(ss,"<DIV CLASS=footer><CENTER>(C) Ing. Andy Paumann, globedom Bulgaria</DIV>");

		fprintf(ss,"<SCRIPT LANGUAGE=JavaScript>\n");
		
		fprintf(ss,"hostentry = {\n");
		fprintf(ss," url: '',\n");
		fprintf(ss," name: '',\n");
		fprintf(ss," version: '',\n");
		fprintf(ss," username: 'derDaniel',\n");
		fprintf(ss," password: '',\n");
		fprintf(ss," remark: '',\n");
		fprintf(ss," active: true\n");
		fprintf(ss,"};\n");


		fprintf(ss,"var hostlist = [];\n");
		fprintf(ss,"var s_hlisttimer = null;\n");
	
		fprintf(ss,"function init_all(){\n");
		fprintf(ss," s_hlisttimer = setInterval(update_responses,2000);\n");
		fprintf(ss," load_cookie();\n");
		fprintf(ss," update_hostlist();\n");
		fprintf(ss," console.log('Init completed');\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function update_hostlist(){\n");
		fprintf(ss," var divvy = document.getElementById('HOSTLIST');\n");
		fprintf(ss," var result = '<CENTER><TABLE BORDER=0 CELLSPACING=1 BGCOLOR=black>';\n");
		fprintf(ss," result += '<TR BGCOLOR=white>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>Active</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>Response-Time</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>Hostname</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>URL</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>Version</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>Username</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>Password</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>Remark</SPAN></TD>';\n");
		fprintf(ss," result += '<TD><SPAN CLASS=thead1>&nbsp;</SPAN></TD>';\n");
		fprintf(ss," result += '</TR>';\n");
		fprintf(ss," for ( var i = 0; i < hostlist.length; i++ ){\n");
		fprintf(ss,"  var color = 'lightblue';\n");
		fprintf(ss,"  if ( i %% 2 ) color = 'yellow';\n");
		fprintf(ss,"  result += '<TR BGCOLOR=' + color + '>';\n");
		fprintf(ss,"  if ( hostlist[i].active ){\n");
		fprintf(ss,"   result += '<TD><INPUT TYPE=CHECKBOX ID=ACTIVE_' + i + ' CHECKED onchange=save_active(' + i + ',false)></TD>';\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT><SPAN CLASS=thead2s ID=RESPONSE_TIME_' + i + '></SPAN></TD>';\n");
		fprintf(ss,"  } else {\n");
		fprintf(ss,"   result += '<TD><INPUT TYPE=CHECKBOX ID=ACTIVE_' + i + '  onchange=save_active(' + i + ',true)></TD>';\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT><SPAN CLASS=thead4s ID=RESPONSE_TIME_' + i + '>not monitored</SPAN></TD>';\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT><SPAN CLASS=thead2s>' + hostlist[i].name + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT><SPAN CLASS=thead2links onclick=goto_url(\"' + hostlist[i].url + '\")>' + hostlist[i].url + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT><SPAN CLASS=thead2s>' + hostlist[i].version + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT><SPAN CLASS=thead2s>' + hostlist[i].username + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD><INPUT TYPE=TEXT CLASS=input2s VALUE=\"' + hostlist[i].password + '\" ID=PASSWORD_' + i + ' onchange=save_pwd(' + i + ')></TD>';\n");
		fprintf(ss,"  result += '<TD><INPUT TYPE=TEXT CLASS=input2s VALUE=\"' + hostlist[i].remark + '\" ID=REMARK_' + i + ' onchange=save_remark(' + i + ')></TD>';\n");
		fprintf(ss,"  result += '<TD>';\n");
		fprintf(ss,"  result += '<INPUT TYPE=BUTTON CLASS=standard_buttons VALUE=\"Delete\" onclick=del_element(' + i + ')>';\n");
		fprintf(ss,"  result += '&nbsp;';\n");
		fprintf(ss,"  result += '<INPUT TYPE=BUTTON CLASS=standard_buttons VALUE=\"Re-Check\" onclick=recheck(' + i + ')>';\n");
		fprintf(ss,"  result += '</TD>';\n");
		fprintf(ss,"  result += '</TR>';\n");
		fprintf(ss," }\n");
		fprintf(ss," result += '</TABLE>';\n");
		fprintf(ss," result += '<P><CENTER>';\n");
		fprintf(ss," result += '<INPUT TYPE=BUTTON CLASS=standard_button VALUE=\"Save hostlist to Cookie\" onclick=save_cookie()>';\n");
		fprintf(ss," result += '&nbsp;<INPUT TYPE=BUTTON CLASS=standard_button VALUE=\"Clear hostlist\" onclick=del_hostlist()>';\n");
		fprintf(ss," divvy.innerHTML = result;\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function update_responses(){\n");
		fprintf(ss," for ( var i = 0; i < hostlist.length; i++ ){\n");
		fprintf(ss,"  if ( hostlist[i].active == false ) continue;\n");
		fprintf(ss,"  var req2 = new XMLHttpRequest();\n");
		fprintf(ss,"  req2.hostlist_idx = i;\n");
		fprintf(ss,"  req2.gix_start_time = Date.now();\n");
		fprintf(ss,"  req2.onreadystatechange = update_responses_callback;\n");
		// fprintf(ss,"  console.log('TESTING: [' + hostlist[i].url + '/version]');\n");
		fprintf(ss,"  req2.open('GET',hostlist[i].url + '/version',true);\n");
		fprintf(ss,"  req2.send();\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function update_responses_callback(){\n");
		fprintf(ss," var req = this;\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status == 200 && req.responseText.charAt(0) == 'O' ){\n");
		fprintf(ss,"  var now = Date.now();\n");
		fprintf(ss,"  var delta = now - req.gix_start_time;\n"); 
		// fprintf(ss,"  console.log('HOST [' + hostlist[req.hostlist_idx].url + '] Response-Time: [' + delta + ' ms]');\n");
		fprintf(ss,"  window.document.getElementById('RESPONSE_TIME_' + req.hostlist_idx).setAttribute('class','thead2s');\n");
		fprintf(ss,"  window.document.getElementById('RESPONSE_TIME_' + req.hostlist_idx).innerHTML = delta + '&nbsp;ms';\n");
		fprintf(ss," } else {\n");
		fprintf(ss,"  console.log('HOST [' + hostlist[req.hostlist_idx].url + '] Response-Time: [' + delta + ' ms] TIMEOUT!');\n");
		fprintf(ss,"  window.document.getElementById('RESPONSE_TIME_' + req.hostlist_idx).setAttribute('class','thead1s');\n");
		fprintf(ss,"  window.document.getElementById('RESPONSE_TIME_' + req.hostlist_idx).innerHTML = '<B>FAILED</B>';\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function setCookie(cname, cvalue, exmins) {\n");
		fprintf(ss,"  var d = new Date();\n");
		fprintf(ss,"  d.setTime(d.getTime() + (exmins*60*1000));\n");
		fprintf(ss,"  var expires = 'expires='+ d.toUTCString();\n");
		fprintf(ss,"  document.cookie = cname + '=' + cvalue + ';' + expires + ';path=/';\n");
		fprintf(ss,"}\n");
		fprintf(ss,"function delCookie(cname) {\n");
		fprintf(ss,"  var d = new Date();\n");
		fprintf(ss,"  d.setTime(d.getTime() - (500*24*60*60*1000) );\n");
		fprintf(ss,"  var expires = 'expires='+ d.toUTCString();\n");
		fprintf(ss,"  document.cookie = cname + '=' + null + ';' + expires + ';path=/';\n");
		fprintf(ss,"}\n");
		fprintf(ss,"\n");
		fprintf(ss,"function getCookie(cname) {\n");
		fprintf(ss,"  var name = cname + '=';\n");
		fprintf(ss,"  var decodedCookie = decodeURIComponent(document.cookie);\n");
		fprintf(ss,"  var ca = decodedCookie.split(';');\n");
		fprintf(ss,"  for(var i = 0; i <ca.length; i++) {\n");
		fprintf(ss,"    var c = ca[i];\n");
		fprintf(ss,"    while (c.charAt(0) == ' ') {\n");
		fprintf(ss,"      c = c.substring(1);\n");
		fprintf(ss,"    }\n");
		fprintf(ss,"    if (c.indexOf(name) == 0) {\n");
		fprintf(ss,"      return c.substring(name.length, c.length);\n");
		fprintf(ss,"    }\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  return '';\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function recheck(idx){\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," request.hostlist_idx = idx;\n");
		fprintf(ss," request.onreadystatechange = function() { recheck_callback(request); };\n");
		fprintf(ss," request.open('GET',hostlist[idx].url + '/version_s',true);\n");
		fprintf(ss," request.setRequestHeader('Authorization','Basic ' + btoa(hostlist[idx].username + ':' + hostlist[idx].password));\n");
		fprintf(ss," request.send();\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function recheck_callback(req){\n");
		fprintf(ss," console.log('ready-State: [' + req.readyState + '] Response-Code: [' + req.status + ']');\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status == 200 && req.responseText.charAt(0) == 'O' ){\n");
		fprintf(ss,"  console.log('Response: [' + req.responseText + ']');\n");
		fprintf(ss,"  var vers = JSON.parse(extract_bracket_val(req.responseText));\n");
		fprintf(ss,"  hostlist[req.hostlist_idx].version = vers.version;\n");
		fprintf(ss,"  hostlist[req.hostlist_idx].name = vers.hostname;\n");
		fprintf(ss,"  update_hostlist();\n");
		fprintf(ss,"  alert('Check successfull, Name and Versioninfo updated');\n");
		fprintf(ss,"  return;\n");
		fprintf(ss," }\n");
		fprintf(ss," alert('Check failed: HTTP-Status: [' + req.status + '] Response-Text: [' + req.responseText + ']');\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function del_hostlist(){\n");
		fprintf(ss," hostlist = [];\n");
		fprintf(ss," update_hostlist();\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function del_element(idx){\n");
		fprintf(ss," hostlist.splice(idx,1);\n");
		fprintf(ss," update_hostlist();\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function save_pwd(idx){\n");
		fprintf(ss,"  hostlist[idx].password = document.getElementById('PASSWORD_' + idx).value;\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function save_active(idx,newval){\n");
		fprintf(ss,"  hostlist[idx].active = newval;\n");
		fprintf(ss,"  if ( newval == false ){\n");
		fprintf(ss,"   window.document.getElementById('RESPONSE_TIME_' + idx).innerHTML = 'not monitored';\n");
		fprintf(ss,"   window.document.getElementById('RESPONSE_TIME_' + idx).setAttribute('class','thead3s');\n");
		fprintf(ss,"  }\n");
		fprintf(ss," update_hostlist();\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function save_remark(idx){\n");
		fprintf(ss,"  hostlist[idx].remark = document.getElementById('REMARK_' + idx).value;\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function save_cookie(){\n");
		fprintf(ss," for ( var i = 0; i < hostlist.length; i++ ){\n");
		fprintf(ss,"  hostlist[i].password = document.getElementById('PASSWORD_' + i).value;\n");
		fprintf(ss,"  hostlist[i].remark = document.getElementById('REMARK_' + i).value;\n");
		fprintf(ss," }\n");
		fprintf(ss," var json_string = JSON.stringify(hostlist);\n");
		fprintf(ss," console.log('JSON_STRING: [' + json_string + ']');\n");
		fprintf(ss," setCookie('gix_inetd_hostlist',json_string,3000000);\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function load_cookie(){\n");
		fprintf(ss," var json_string = getCookie('gix_inetd_hostlist');\n");
		fprintf(ss," console.log('JSON_STRING ON LOAD: [' + json_string + ']');\n");
		fprintf(ss," if ( json_string.length > 3 ){\n");
		fprintf(ss,"  hostlist = JSON.parse(json_string);\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function goto_url(url){\n");
		fprintf(ss," window.open(url);\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function go_main(){\n");
		fprintf(ss," location = '/';\n");
		fprintf(ss,"}\n");	

		fprintf(ss,"function start_scan(){\n");
		fprintf(ss," var start_digits = window.document.getElementById('IPSCAN_START').value.trim().split('.');\n");
		fprintf(ss," var end_digits = window.document.getElementById('IPSCAN_END').value.trim().split('.');\n");
		fprintf(ss," window.document.getElementById('IPSCAN_START').setAttribute('class','input2s');\n");
		fprintf(ss," window.document.getElementById('IPSCAN_END').setAttribute('class','input2s');\n");
		fprintf(ss," if ( start_digits.length != 4 ){ alert('Please enter valid Start-Address'); window.document.getElementById('IPSCAN_START').setAttribute('class','input2serror'); return;}\n");
		fprintf(ss," if ( end_digits.length != 4 ){ alert('Please enter valid End-Address'); window.document.getElementById('IPSCAN_END').setAttribute('class','input2serror'); return;}\n");
		fprintf(ss," console.log('START_DIGITS consists of [' + start_digits.length + ']');\n");
		fprintf(ss," console.log('END_DIGITS consists of [' + end_digits.length + ']');\n");
		fprintf(ss," for ( i = 0; i < start_digits.length; i++ ){\n");
		fprintf(ss,"  start_digits[i] = parseInt(start_digits[i]);\n");
		fprintf(ss,"  if ( isNaN(start_digits[i]) ){ alert('Please enter valid Start-Address Error at: [' + i + ']'); window.document.getElementById('IPSCAN_START').setAttribute('class','input2serror'); return;}\n");
		fprintf(ss,"  if ( start_digits[i] < 0 || start_digits[i] > 255 ){ alert('Please enter valid Start-Address Range-Error at: [' + i + ']'); window.document.getElementById('IPSCAN_START').setAttribute('class','input2serror'); return;}\n");
		fprintf(ss," }\n");
		fprintf(ss," for ( i = 0; i < end_digits.length; i++ ){\n");
		fprintf(ss,"  end_digits[i] = parseInt(end_digits[i]);\n");
		fprintf(ss,"  if ( isNaN(end_digits[i]) ){ alert('Please enter valid End-Address Error at: [' + i + ']'); window.document.getElementById('IPSCAN_END').setAttribute('class','input2serror'); return;}\n");
		fprintf(ss,"  if ( end_digits[i] < 0 || end_digits[i] > 255 ){ alert('Please enter valid End-Address Range-Error at: [' + i + ']'); window.document.getElementById('IPSCAN_END').setAttribute('class','input2serror'); return;}\n");
		fprintf(ss," }\n");
		fprintf(ss," var start_long = start_digits[0] * 256 * 256 * 256 + start_digits[1] * 256 * 256 +  start_digits[2] * 256  + start_digits[3];\n");
		fprintf(ss," var end_long = end_digits[0] * 256 * 256 * 256 + end_digits[1] * 256 * 256 +  end_digits[2] * 256  + end_digits[3];\n");
		fprintf(ss," console.log('Will scan [' + ((end_long - start_long) + 1) + '] Addesses');\n");
		fprintf(ss," for ( var addr = start_long; addr <= end_long; addr++ ){\n");
		fprintf(ss,"  var addr_c = addr;\n");
		fprintf(ss,"  var a0 = Math.floor(addr_c / (256*256*256));\n");
		fprintf(ss,"  addr_c = addr_c - a0 * (256*256*256);\n");
		fprintf(ss,"  var a1 = Math.floor(addr_c / (256*256));\n");
		fprintf(ss,"  addr_c = addr_c - a1 * (256*256);\n");
		fprintf(ss,"  var a2 = Math.floor(addr_c / (256));\n");
		fprintf(ss,"  addr_c = addr_c - a2 * (256);\n");
		fprintf(ss,"  var a3 = addr_c;\n");
		// fprintf(ss,"  console.log('Scanning: [' + a0 + '.' + a1 + '.' + a2 + '.' + a3 + ']');\n");
		fprintf(ss,"  scan_ip(a0 + '.' + a1 + '.' + a2 + '.' + a3,'9000' );\n");
		fprintf(ss,"  scan_ip(a0 + '.' + a1 + '.' + a2 + '.' + a3,'9887' );\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function scan_ip(addr,port){\n");
		fprintf(ss," console.log('Start of scan at: [' + addr + ']');\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," request.gix_inetd_addr = addr;\n");
		fprintf(ss," request.gix_inetd_port = port;\n");
		fprintf(ss," request.onreadystatechange = scan_ip_callback;\n");
		fprintf(ss," request.open('GET','http://' + addr + ':' + port + '/version',true);\n");
		fprintf(ss," request.send();\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function scan_ip_callback(q){\n");
		fprintf(ss," var req = this;\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status != 200 ) return;\n");
		fprintf(ss," if ( req.responseText.charAt(0) == 'O' ){\n");
		fprintf(ss,"  var info = JSON.parse(extract_bracket_val(req.responseText));\n");
		fprintf(ss,"  for ( var idx = 0; idx < hostlist.length; idx ++ ){\n");
		fprintf(ss,"   if ( hostlist[idx].url == 'http://' + req.gix_inetd_addr + ':' + req.gix_inetd_port ) break;\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  if ( hostlist.length != 0 &&  idx != hostlist.length ) return;\n");
		fprintf(ss,"  console.log('Adding [' + req.gix_inetd_addr + ':' + req.gix_inetd_port + '] Response: [' + req.responseText + '] Current hostlist-length: [' + hostlist.length + ']');\n");
		fprintf(ss,"  hostlist[hostlist.length] = Object.create(hostentry);\n");
		fprintf(ss,"  hostlist[hostlist.length-1].url = 'http://' + req.gix_inetd_addr + ':' + req.gix_inetd_port;\n");
		fprintf(ss,"  hostlist[hostlist.length-1].name = info.hostname;\n");
		fprintf(ss,"  hostlist[hostlist.length-1].version = info.version;\n");
		fprintf(ss,"  hostlist[hostlist.length-1].username = 'derDaniel';\n");
		fprintf(ss,"  hostlist[hostlist.length-1].password = '';\n");
		fprintf(ss,"  hostlist[hostlist.length-1].remark = '';\n");
		fprintf(ss,"  hostlist[hostlist.length-1].active = true;\n");
		fprintf(ss,"  update_hostlist();\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function update_end_field(){\n");
		fprintf(ss," var id_start = window.document.getElementById('IPSCAN_START');\n");
		fprintf(ss," var id_end   = window.document.getElementById('IPSCAN_END');\n");
		fprintf(ss," if ( id_end.value.length < 1 )  id_end.value = id_start.value;\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function extract_bracket_val(msg){\n");
		fprintf(ss,"  var returner = '';\n");
		fprintf(ss,"  var n1 = msg.indexOf('[');\n");
		fprintf(ss,"  n1++;\n");
		fprintf(ss,"  var n2 = msg.lastIndexOf(']');\n");
		fprintf(ss,"  returner = msg.substring(n1,n2);\n");
		fprintf(ss,"  return(returner);\n");
		fprintf(ss," }\n");
		fprintf(ss," function extract_bracket_val2(msg,index){\n");
		fprintf(ss,"  var xx = extract_bracket_val(msg);\n");
		fprintf(ss,"  var i = 0;\n");
		fprintf(ss,"  var idx = 0;\n");
		fprintf(ss,"  while ( 1 ){\n");
		fprintf(ss,"   var returner = '';\n");
		fprintf(ss,"   for ( ; i < xx.length; i++ ){\n");
		fprintf(ss,"    var j = 0;\n");
		fprintf(ss,"    if ( xx.charAt(i) == ',' ){ i++; break;}\n");
		fprintf(ss,"    returner = returner + xx.charAt(i);  \n");
		fprintf(ss,"   }\n");
		fprintf(ss,"   if ( idx >= index ) return(returner);\n");
		fprintf(ss,"   idx++;\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  return('');\n");
		fprintf(ss," }\n");
		fprintf(ss,"\n");
		fprintf(ss," function extract_bracket_val3(msg,index){\n");
		fprintf(ss,"  var xx = msg;\n");
		fprintf(ss,"  var i = 0;\n");
		fprintf(ss,"  var idx = 0;\n");
		fprintf(ss,"  while ( 1 ){\n");
		fprintf(ss,"   var returner = '';\n");
		fprintf(ss,"   for ( ; i < xx.length; i++ ){\n");
		fprintf(ss,"    var j = 0;\n");
		fprintf(ss,"    if ( xx.charAt(i) == ';' ){ i++; break;}\n");
		fprintf(ss,"    returner = returner + xx.charAt(i);  \n");
		fprintf(ss,"   }\n");
		fprintf(ss,"   if ( idx >= index ) return(returner);\n");
		fprintf(ss,"   idx++;\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  return('');\n");
		fprintf(ss," }\n");
		fprintf(ss,"</SCRIPT>\n");
	}
	
	if ( type_req == TYPE_HTML && html_done == 0 ){
		int i;
		fprintf(ss,"Content-Type: %s\r\n\r\n",HTML_MIME);
		fprintf(ss,"<HEAD><meta CHARSET=\"UTF-8\"><LINK REL=\"stylesheet\" TYPE=\"text/css\" HREF=\"/style.css\"></HEAD>\n");
		fprintf(ss,"<BODY CLASS='mainbody' onload=init_all()>");
		fprintf(ss,"<DIV CLASS='headline'><TABLE BORDER=0 WIDTH=100%%><TR><TD ALIGN=LEFT WIDTH=33%%><IMG CLASS=l_image onclick=go_supervisor() SRC=/gix_logo.png></TD><TD WIDTH=33%%><CENTER><SPAN CLASS=headliner>%s @ %s</SPAN></TD><TD ALIGN=RIGHT WIDTH=33%%><TABLE BORDER=0><TR><TD ALIGN=RIGHT>You:</TD><TD ALIGN=LEFT><B>%s</B></TD></TR><TR><TD ALIGN=RIGHT>Me:</TD><TD ALIGN=LEFT><B>%s</B></TD></TR></TABLE></TD></TR></TABLE>",
			GIX_INETD_VERSION,my_hostname,  CCON.source, CCON.target);
		fprintf(ss,"<CENTER><INPUT TYPE=BUTTON CLASS=standard_button onclick=reset_counters() VALUE=\"Reset counters\">&nbsp;<SPAN ID=GIGA_ROTATOR><IMG SRC=/empty.gif HEIGHT=32></SPAN>&nbsp;<INPUT TYPE=BUTTON CLASS=standard_button onclick=toggle_giga_refresh()  VALUE='Enable Auto-Refresh' ID=REFRESH_GIGA_BUTTON></DIV>");

		fprintf(ss,"<SCRIPT LANGUAGE=JavaScript>\n");
		fprintf(ss,"function go_supervisor(){\n");
		fprintf(ss," location = '/supervisor';\n");
		fprintf(ss,"}\n");
		fprintf(ss,"</SCRIPT>\n");

		fprintf(ss,"<DIV CLASS=footer><CENTER>(C) Ing. Andy Paumann, globedom Bulgaria</DIV>");

		fprintf(ss,"<DIV ID='MAIN' CLASS=mainscreen>\n");
		fprintf(ss,"<CENTER>");
		fprintf(ss,"<TABLE BORDER=0>");
		fprintf(ss,"<TR><TD VALIGN=TOP>");
		fprintf(ss,"<CENTER>");
		fprintf(ss,"<TABLE CELLSPACING=1 BORDER=0 BGCOLOR=black>\n");
		fprintf(ss,"<TR><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>Uptime(1 min)</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s ID=LOAD1></SPAN></TD><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>(5 min)</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s ID=LOAD5></SPAN></TD><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>(15 min)</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s ID=LOAD15></SPAN></TD></TR>");
		fprintf(ss,"<TR><TD BGCOLOR=white COLSPAN=6><CENTER><DIV ID=FSINFO></DIV></TD></TR>\n");
		fprintf(ss,"<TR><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>Uptime</SPAN></TD><TD COLSPAN=5 BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s ID=UPTIME></SPAN></TD></TR>");
		fprintf(ss,"<TR><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>Processes</SPAN></TD><TD COLSPAN=5 BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s ID=SYS_PROCS></SPAN></TD></TR>");
		fprintf(ss,"<TR><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>CPU-count</SPAN></TD><TD COLSPAN=5 BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s ID=CPU_COUNT></SPAN></TD></TR>");
		fprintf(ss,"<TR><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>CPU-Usage (sys + usr)</SPAN></TD><TD COLSPAN=5 BGCOLOR=white ALIGN=LEFT><DIV ID=CPU_INFO></DIV></TD></TR>");
		fprintf(ss,"<TR><TD COLSPAN=6 BGCOLOR=black><DIV ID=PROCINFO></DIV></TD></TR>");
		fprintf(ss,"</TABLE>");
		// fprintf(ss,"<P><INPUT TYPE=BUTTON CLASS=standard_button onclick=reset_counters() VALUE=\"Reset counters\">&nbsp;<SPAN ID=GIGA_ROTATOR><IMG SRC=/empty.gif HEIGHT=32></SPAN>&nbsp;<INPUT TYPE=BUTTON CLASS=standard_button onclick=toggle_giga_refresh()  VALUE='Enable Auto-Refresh' ID=REFRESH_GIGA_BUTTON></P>\n");
		fprintf(ss,"</CENTER>");
		fprintf(ss,"</TD><TD VALIGN=TOP><CENTER>");
		fprintf(ss,"<TABLE BORDER=0 CELLSPACING=1 BGCOLOR=black>\n");
		fprintf(ss,"<TR><TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Slot</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>IP-Verion</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>IP-Port</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Command</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Max-Connections</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Total-Timeout (Seconds)</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Idle-Timeout (Seconds)</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Active connections</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Total connections</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Last reset (counters)</SPAN></CENTER></TD>");
		fprintf(ss,"<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Process ID</SPAN></CENTER></TD>");
		fprintf(ss,"</TR>");
		for ( i = 0; i < entries; i++ ){
			char *color;
			if ( i % 2 ){
				color = "yellow";
			} else {
				color = "lightblue";
			}
			fprintf(ss,"<TR>");
			fprintf(ss,"<TD BGCOLOR=%s><CENTER><SPAN CLASS=thead2s>%d</SPAN></TD>",color,i);
			fprintf(ss,"<TD BGCOLOR=%s><CENTER>",color);
			fprintf(ss,"<SPAN CLASS=thead2s>%s</SPAN>", servlist[i].family == AF_INET6 ? "IPv6" : "IPv4");
			fprintf(ss,"</CENTER></TD>");
			fprintf(ss,"<TD BGCOLOR=%s ALIGN=right>",color);
			fprintf(ss,"<SPAN CLASS=thead2s>%d</SPAN>", servlist[i].port);
			fprintf(ss,"</TD>");
			if ( strncmp(servlist[i].cmdline,"ADMIN",5) == 0 ){
				fprintf(ss,"<TD BGCOLOR=%s ALIGN=center>",color);
				fprintf(ss,"<SPAN CLASS=thead30s onclick=conns_list(%d,-1)>ADMIN</SPAN>",i);
				fprintf(ss,"</TD>");
			} else {
				fprintf(ss,"<TD BGCOLOR=%s ALIGN=right>",color);
				fprintf(ss,"<SPAN CLASS=thead20s onclick=conns_list(%d,-1)>%s</SPAN>",i, servlist[i].cmdline);
				fprintf(ss,"</TD>");
			}
			fprintf(ss,"<TD BGCOLOR=%s ALIGN=RIGHT>",color);
			fprintf(ss,"<SPAN CLASS=thead2s>%d</SPAN>", servlist[i].max_conns);
			fprintf(ss,"</TD>");
			if ( servlist[i].timeout == -1 ){
				fprintf(ss,"<TD BGCOLOR=%s ALIGN=center>",color);
				fprintf(ss,"<SPAN CLASS=thead30s>No timeout</SPAN>");
				fprintf(ss,"</TD>");
			} else {
				fprintf(ss,"<TD BGCOLOR=%s ALIGN=right>",color);
				fprintf(ss,"<SPAN CLASS=thead2s>%d</SPAN>", servlist[i].timeout);
				fprintf(ss,"</TD>");
			}
			if ( servlist[i].data_timeout == -1 ){
				fprintf(ss,"<TD BGCOLOR=%s ALIGN=center>",color);
				fprintf(ss,"<SPAN CLASS=thead30s>No timeout</SPAN>");
				fprintf(ss,"</TD>");
			} else {
				fprintf(ss,"<TD BGCOLOR=%s ALIGN=right>",color);
				fprintf(ss,"<SPAN CLASS=thead2s>%d</SPAN>", servlist[i].data_timeout);
				fprintf(ss,"</TD>");
			}
			fprintf(ss,"<TD BGCOLOR=%s ALIGN=RIGHT>",color);
			fprintf(ss,"<SPAN CLASS=thead2s ID=CONNECTIONS_%d></SPAN>", i);
			fprintf(ss,"</TD>");
			fprintf(ss,"<TD BGCOLOR=%s ALIGN=RIGHT>",color);
			fprintf(ss,"<SPAN CLASS=thead2s ID=TOTAL_COUNT_%d></SPAN>", i);
			fprintf(ss,"</TD>");
			fprintf(ss,"<TD BGCOLOR=%s ALIGN=RIGHT>",color);
			fprintf(ss,"<SPAN CLASS=thead2s ID=RESET_%d></SPAN>", i);
			fprintf(ss,"</TD>");
			fprintf(ss,"<TD BGCOLOR=%s ALIGN=RIGHT>",color);
			fprintf(ss,"<SPAN CLASS=thead2links ID=PID_%d onclick=show_proc_info('PID_%d')></SPAN>", i,i);
			fprintf(ss,"</TD>");
			fprintf(ss,"</TR>");
		}
		fprintf(ss,"</TABLE>\n");
		fprintf(ss,"<P>");
		fprintf(ss,"<DIV ID=ETHLIST CLASS=ethlist>init</DIV>");
		fprintf(ss,"</P>");
		fprintf(ss,"</TD></TR></TABLE>");
		fprintf(ss,"</DIV>\n");

		fprintf(ss,"<SCRIPT LANGUAGE=JavaScript>\n");

		fprintf(ss,"var megatimer = null;\n");
		fprintf(ss,"var gigatimer = null;\n");
		fprintf(ss,"var megatimer_active = false;\n");
		fprintf(ss,"var gigatimer_active = false;\n");
		fprintf(ss,"var gigatimer_stored = false;\n");
		fprintf(ss,"var leth = null;\n");




		fprintf(ss,"function show_proc_info(diver){\n");
		fprintf(ss," diver_id = document.getElementById(diver);\n");
		fprintf(ss," console.log('DIVER_ID: [' + diver_id.innerHTML + '] Text: [' + diver_id.innerText + ']');\n");
		fprintf(ss," var pid = parseInt(diver_id.innerHTML);\n");
		fprintf(ss," if ( isNaN(pid) || pid == 0 ) pid = parseInt(diver_id.innerText);\n");
		fprintf(ss," process_detail(pid);\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function extract_bracket_val(msg){\n");
		fprintf(ss,"  var returner = '';\n");
		fprintf(ss,"  var n1 = msg.indexOf('[');\n");
		fprintf(ss,"  n1++;\n");
		fprintf(ss,"  var n2 = msg.lastIndexOf(']');\n");
		fprintf(ss,"  returner = msg.substring(n1,n2);\n");
		fprintf(ss,"  return(returner);\n");
		fprintf(ss," }\n");
		fprintf(ss," function extract_bracket_val2(msg,index){\n");
		fprintf(ss,"  var xx = extract_bracket_val(msg);\n");
		fprintf(ss,"  var i = 0;\n");
		fprintf(ss,"  var idx = 0;\n");
		fprintf(ss,"  while ( 1 ){\n");
		fprintf(ss,"   var returner = '';\n");
		fprintf(ss,"   for ( ; i < xx.length; i++ ){\n");
		fprintf(ss,"    var j = 0;\n");
		fprintf(ss,"    if ( xx.charAt(i) == ',' ){ i++; break;}\n");
		fprintf(ss,"    returner = returner + xx.charAt(i);  \n");
		fprintf(ss,"   }\n");
		fprintf(ss,"   if ( idx >= index ) return(returner);\n");
		fprintf(ss,"   idx++;\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  return('');\n");
		fprintf(ss," }\n");
		fprintf(ss,"\n");
		fprintf(ss," function extract_bracket_val3(msg,index){\n");
		fprintf(ss,"  var xx = msg;\n");
		fprintf(ss,"  var i = 0;\n");
		fprintf(ss,"  var idx = 0;\n");
		fprintf(ss,"  while ( 1 ){\n");
		fprintf(ss,"   var returner = '';\n");
		fprintf(ss,"   for ( ; i < xx.length; i++ ){\n");
		fprintf(ss,"    var j = 0;\n");
		fprintf(ss,"    if ( xx.charAt(i) == ';' ){ i++; break;}\n");
		fprintf(ss,"    returner = returner + xx.charAt(i);  \n");
		fprintf(ss,"   }\n");
		fprintf(ss,"   if ( idx >= index ) return(returner);\n");
		fprintf(ss,"   idx++;\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  return('');\n");
		fprintf(ss," }\n");



		fprintf(ss,"function reset_counters(){\n");
		fprintf(ss," console.log('Requesting RESET of counters!');\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," request.onreadystatechange = function() { reset_counters_callback(request); };\n");
		fprintf(ss," request.open('GET','/ajax/RESET/0',true);\n");
		fprintf(ss," request.send();\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function reset_counters_callback(req){\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status != 200 ) return;\n");
		fprintf(ss," console.log('Callback for RESET -> Response: [' + req.responseText + ']');\n");
		fprintf(ss," if ( req.responseText.charAt(0) != 'O' ){\n");
		fprintf(ss,"  alert('Could not reset');\n");
		fprintf(ss," }\n");
		fprintf(ss," if ( gigatimer_active == false ) update_connections();\n");
		fprintf(ss,"}\n");




		fprintf(ss,"function update_conns_display(inl){\n");
		fprintf(ss," for ( idx = 0; idx < inl.length; idx++ ){\n");
		fprintf(ss,"  var id = document.getElementById('CONNECTIONS_' + idx);\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = inl[idx].connections;\n");
		fprintf(ss,"  var id = document.getElementById('RESET_' + idx);\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = inl[idx].reset;\n");
		fprintf(ss,"  var id = document.getElementById('TOTAL_COUNT_' + idx);\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = inl[idx].total_count;\n");
		fprintf(ss,"  var id = document.getElementById('PID_' + idx);\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = inl[idx].pid;\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function update_connections(){\n");
		fprintf(ss," document.getElementById('GIGA_ROTATOR').innerHTML = '<IMG SRC=/new_rotator_big.gif HEIGHT=32>';\n");
		fprintf(ss,"  if ( gigatimer != null ) clearInterval(gigatimer);\n");
		fprintf(ss,"  var request = new XMLHttpRequest();\n");
		fprintf(ss,"  request.onreadystatechange = function() { update_connections_callback(request); };\n");
		fprintf(ss,"  request.open('GET','/ajax/PROCLIST/0' ,true);\n");
		fprintf(ss,"  request.send();\n");
		fprintf(ss,"}\n");
		


		fprintf(ss,"function display_proclist(proclist){\n");
		fprintf(ss," var cpu_count_id = document.getElementById('CPU_COUNT');\n");
		fprintf(ss," cpu_count_id.innerHTML = proclist.cpu_count;\n");

		fprintf(ss," var cpu_info_id = document.getElementById('CPU_INFO');\n");
		fprintf(ss," var result = '<TABLE CELLSPACING=1 BORDER=0 BGCOLOR=blue>';\n");
		fprintf(ss," for ( var idx = 0; idx < proclist.cpu_count; idx++ ){\n");
		fprintf(ss,"  if ( idx && !(idx %% 4 )) result += '</TR>';\n");
		fprintf(ss,"  if (  !(idx %% 4 ) ) result += '<TR>';\n");
		fprintf(ss,"  if ( proclist.ul[idx].total > 50.0 ){\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s><B>CPU-' + idx + '</B></SPAN></TD><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead1s><B>' + proclist.ul[idx].total + '%%</B></SPAN></TD>';\n");
		fprintf(ss,"  } else {\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s><B>CPU-' + idx + '</B></SPAN></TD><TD BGCOLOR=white ALIGN=RIGHT><SPAN CLASS=thead2s>' + proclist.ul[idx].total + '%%</SPAN></TD>';\n");
		fprintf(ss,"  }\n");
		fprintf(ss," }\n");
		fprintf(ss," result += '</TR></TABLE>';\n");
		fprintf(ss," cpu_info_id.innerHTML = result;\n");
		fprintf(ss," var div_id = document.getElementById('PROCINFO');\n");
		fprintf(ss," div_id.setAttribute('class','procinfo');\n");
		fprintf(ss," var result = '<TABLE CELLSPACING=1 BGCOLOR=black>';\n");
		fprintf(ss," result += '<TR>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>PID</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>PPID</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>CPU</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Trs.</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Command</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>V-Size</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>RSS</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Started</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Load</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Time</SPAN></TD>';\n");
		fprintf(ss," result += '</TR>';\n");
		fprintf(ss," for ( var i = 0; i < proclist.pl.length; i++ ){\n");
		fprintf(ss,"  var color = 'lightblue';\n");
		fprintf(ss,"  if ( i %% 2 ) color = 'yellow';\n");
		fprintf(ss,"  result += '<TR>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead3s onclick=process_detail1(' + proclist.pl[i].pid + ')>' + proclist.pl[i].pid + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead3s onclick=process_detail1(' + proclist.pl[i].ppid + ')>' + proclist.pl[i].ppid + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].cpu + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].num_threads + '</SPAN></TD>';\n");
		// fprintf(ss,"  console.log('PID: [' + proclist.pl[i].pid + '] Slot: [' + proclist.pl[i].slot + '] Index: [' + proclist.pl[i].index + ']');\n");
		fprintf(ss,"  if ( proclist.pl[i].slot > -1 && proclist.pl[i].index > -1 ){\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead3s onclick=conns_list1(' + proclist.pl[i].slot + ',' + proclist.pl[i].index + ')>' + proclist.pl[i].prg + '</SPAN></TD>';\n");
		fprintf(ss,"  } else {\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].prg + '</SPAN></TD>';\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].vmsize + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].rss + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].stime + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].cpu_usage + '%%</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + proclist.pl[i].ptime + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '</TR>';\n");
		fprintf(ss," }\n");
		fprintf(ss," result += '</TABLE>';\n");
		fprintf(ss," div_id.innerHTML = result;\n");
		fprintf(ss,"}\n");


		fprintf(ss,"rawdata_obj = {\n");
		fprintf(ss," name: '',\n");
		fprintf(ss," timestamp: 0,\n");
		fprintf(ss," bytes_in: 0,\n");
		fprintf(ss," bytes_out: 0\n");
		fprintf(ss,"}\n");

		fprintf(ss,"ilist_obj = {\n");
		fprintf(ss," rawdata: null,\n");
		fprintf(ss," array_in: null,\n");
		fprintf(ss," array_out: null,\n");
		fprintf(ss," canvas_in: null,\n");
		fprintf(ss," canvas_out: null,\n");
		fprintf(ss," ifname: ''\n");
		fprintf(ss,"}\n");

		fprintf(ss,"eth_obj = {\n");
		fprintf(ss," ilist: []\n");
		fprintf(ss,"}\n");

		fprintf(ss,"var colorarray = [ 'red', 'blue','green' ];\n");

		fprintf(ss,"GIXGraph = {\n");
		fprintf(ss," id: null,\n");
		fprintf(ss," color: 'blue',\n");
		fprintf(ss," bgcolor: 'black',\n");
		fprintf(ss," tcolor: 'green',\n");
		fprintf(ss," x_caption: '',\n");
		fprintf(ss," y_caption: '',\n");
		fprintf(ss," x_start_label: '',\n");
		fprintf(ss," x_end_label: '',\n");
		fprintf(ss," y_caption: '',\n");
		fprintf(ss," headline: 'Head',\n");
		fprintf(ss," samples: '',\n");
		fprintf(ss," canvas_width: 0,\n");
		fprintf(ss," canvas_height: 0,\n");
		fprintf(ss," canvas_offset_x: 1,\n");
		fprintf(ss," canvas_offset_y: 1,\n");
		fprintf(ss," script_size: 10,\n");
		fprintf(ss," ctx: null,\n");
		fprintf(ss," init: function(_id, _color,_bgcolor,_tcolor,_headline,_x_caption,_y_caption){\n"); // _samples is an array of values with X and Y values 
		fprintf(ss,"  if ( _id == undefined ) return(false);\n");
		fprintf(ss,"  this.id = window.document.getElementById(_id);\n");
		fprintf(ss,"  if ( this.id == undefined || this.id == null ) return false;\n");
		fprintf(ss,"  this.canvas_width = parseInt(this.id.getBoundingClientRect().width) - this.canvas_offset_x * 2;\n");
		fprintf(ss,"  this.canvas_height = parseInt(this.id.getBoundingClientRect().height) - this.canvas_offset_y * 2;\n");
		fprintf(ss,"  console.log('CANVAS-SIZE: [' + this.canvas_width + ' x ' + this.canvas_height + '] BORDER: [' + this.id.style.border + ']');\n");
		fprintf(ss,"  if ( _color != undefined ) this.color = _color;\n");
		fprintf(ss,"  if ( _bgcolor != undefined ) this.bgcolor = _bgcolor;\n");
		fprintf(ss,"  if ( _tcolor != undefined ) this.tcolor = _tcolor;\n");
		fprintf(ss,"  if ( _headline != undefined ) this.headline = _headline;\n");
		fprintf(ss,"  if ( _x_caption != undefined ) this.x_caption = _x_caption;\n");
		fprintf(ss,"  if ( _y_caption != undefined ) this.y_caption = _y_caption;\n");
		fprintf(ss,"  if ( (this.ctx = this.id.getContext(\"2d\")) == undefined || this.ctx == null ) return false;\n");
		fprintf(ss,"  return true;\n");
		fprintf(ss," },\n");
		fprintf(ss," draw_graph: function(_samples,_x_start_label,_x_end_label){\n");
		fprintf(ss,"  this.ctx.clearRect(0,0,this.id.width, this.id.height);\n");
		fprintf(ss,"  if ( _x_start_label != undefined ) this.x_start_label = _x_start_label;\n");
		fprintf(ss,"  if ( _x_end_label != undefined ) this.x_end_label = _x_end_label;\n");
		fprintf(ss,"  this.samples = _samples;\n");
		fprintf(ss,"  if ( this.samples.length < 1 ) return;\n");
		fprintf(ss,"  var draw_width = this.canvas_width - 2 * this.canvas_offset_x;\n");
		fprintf(ss,"  var draw_height = this.canvas_height - (2 * this.canvas_offset_y + this.script_size + 2);\n");
		fprintf(ss,"  var max = this.samples[0];\n");
		fprintf(ss,"  var min = this.samples[0];\n");
		fprintf(ss,"  var sum = 0.0;\n");
		fprintf(ss,"  for ( idx = 0; idx < this.samples.length; idx++ ){\n");
		fprintf(ss,"   if ( this.samples[idx] > max ) max = this.samples[idx];\n");
		fprintf(ss,"   if ( this.samples[idx] < min ) min = this.samples[idx];\n");
		fprintf(ss,"   sum += this.samples[idx];\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  var min_word = this.roundup(min) + ' ' + this.y_caption;\n");
		fprintf(ss,"  if ( min > 1024 ) min_word = this.roundup(min/1024) + ' k' +  this.y_caption;\n");
		fprintf(ss,"  if ( min > (1024*1024) ) min_word = this.roundup(min/(1024*1024)) + ' M' +  this.y_caption;\n");
		fprintf(ss,"  if ( min > (1024*1024*1024) ) min_word = this.roundup(min/(1024*1024*1024)) + ' G' +  this.y_caption;\n");
		fprintf(ss,"  if ( min > (1024*1024*1024*1024) ) min_word = this.roundup(min/(1024*1024*1024*1024)) + ' T' +  this.y_caption;\n");
		fprintf(ss,"  var max_word = this.roundup(max) + ' ' + this.y_caption;\n");
		fprintf(ss,"  if ( max > 1024 ) max_word = this.roundup(max/1024) + ' k' +  this.y_caption;\n");
		fprintf(ss,"  if ( max > (1024*1024) ) max_word = this.roundup(max/(1024*1024)) + ' M' +  this.y_caption;\n");
		fprintf(ss,"  if ( max > (1024*1024*1024) ) max_word = this.roundup(max/(1024*1024*1024)) + ' G' +  this.y_caption;\n");
		fprintf(ss,"  if ( max > (1024*1024*1024*1024) ) max_word = this.roundup(max/(1024*1024*1024*1024)) + ' T'  + this.y_caption;\n");
		fprintf(ss,"  var y_factor = draw_height / (max - min);\n");
		fprintf(ss,"  var x_factor = draw_width / this.samples.length;\n");
		fprintf(ss,"  console.log('Min-Value: [' + min + '] Max: [' + max + '] Sum: [' + sum + '] Y-Factor: [' + y_factor + '] X-Factor: [' + x_factor + ']');\n");
		fprintf(ss,"  for ( var idx = 0; idx < this.samples.length; idx++ ){\n");
		fprintf(ss,"   var sample_value = this.samples[idx] - min;\n");
		fprintf(ss,"   var draw_height = sample_value * y_factor;\n");
		fprintf(ss,"   var x_start = idx * x_factor + this.canvas_offset_x;\n");
		fprintf(ss,"   var x_end = x_factor;\n");
		fprintf(ss,"   var y_start = this.canvas_height - (this.canvas_offset_y +  this.canvas_offset_y + this.script_size + 2);\n");
		fprintf(ss,"   var y_end   =  draw_height  * (-1) ;\n");
		fprintf(ss,"   if ( y_end >= 0 ) y_end = -1;\n");
		fprintf(ss,"   var color = colorarray[idx %% colorarray.length];\n");
		// fprintf(ss,"   console.log('VALUE[' + idx  + ']: [' + sample_value + '] X_START: [' + x_start + '] X_END: [' + x_end + '] Draw_HEIGHT: ['  + draw_height + '] Y_START: [' + y_start + '] Y_END: [' + y_end + '] COLOR: [' + color + ']');\n");
		fprintf(ss,"   this.ctx.fillStyle = this.color;\n");
		fprintf(ss,"   this.ctx.fillRect(x_start,y_start,x_end,y_end);\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  this.ctx.font = this.script_size + 'px monospace';\n");
		fprintf(ss,"  this.ctx.strokeStyle =  this.tcolor;\n");
		fprintf(ss,"  this.ctx.strokeText(max_word,this.canvas_offset_x ,this.script_size + 2);\n");
		fprintf(ss,"  this.ctx.strokeText(min_word,this.canvas_offset_x ,this.canvas_height - (this.canvas_offset_y +  this.canvas_offset_y + this.script_size + 6));\n");
		fprintf(ss,"  this.ctx.strokeText(this.headline,this.canvas_width / 2 ,this.script_size + 2);\n");
		fprintf(ss,"  this.ctx.strokeText(this.x_start_label,this.canvas_offset_x,this.canvas_height - this.canvas_offset_y -1);\n"); 
		fprintf(ss,"  this.ctx.strokeText(this.x_end_label,this.canvas_width - ( this.canvas_offset_x + (this.script_size - 3) * this.x_end_label.length),this.canvas_height - this.canvas_offset_y - 1);\n"); 
		fprintf(ss," },\n");
		fprintf(ss," roundup: function(x){\n");
		fprintf(ss,"  return(Math.round(x*100)/100);\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");

		fprintf(ss,"var testarray = [ 10,2048,1230,1350,14,-40,12,1234,900,1299 ];\n");	
		

		fprintf(ss,"function display_int_info(ethlist){\n");
		fprintf(ss," console.log('ETHLIST-LEN: ['  + ethlist.length + '] ETH-Length: [' + leth.ilist.length + ']');\n");
		fprintf(ss," for ( var j = 0; j < ethlist.length; j++ ){\n");
		fprintf(ss,"  console.log('ETHLIST-Index: [' + j + '] Name: ['  + ethlist[j].ifname + ']');\n");
		fprintf(ss,"  for ( var i = 0; i < leth.ilist.length; i++ ){\n");
		fprintf(ss,"   if ( leth.ilist[i].ifname == ethlist[j].ifname ){\n");
		fprintf(ss,"    var rawdata_len = leth.ilist[i].rawdata.length;\n");
		fprintf(ss,"    console.log('[' + j + '] Updating [' + i + '] NAME: [' + leth.ilist[i].ifname + '] Size currently: [' + rawdata_len + '] Name: [' + leth.ilist[i].rawdata[0].name + ']');\n");
		fprintf(ss,"    leth.ilist[i].rawdata[rawdata_len] = Object.create(rawdata_obj);\n");
		fprintf(ss,"    leth.ilist[i].rawdata[rawdata_len].timestamp = ethlist[j].timestamp;\n");
		fprintf(ss,"    leth.ilist[i].rawdata[rawdata_len].bytes_in = ethlist[j].bytes_in;\n");
		fprintf(ss,"    leth.ilist[i].rawdata[rawdata_len].bytes_out = ethlist[j].bytes_out;\n");
		fprintf(ss,"    var canvas_array_length = leth.ilist[i].array_in.length;\n");
		fprintf(ss,"    leth.ilist[i].array_in[canvas_array_length] = (leth.ilist[i].rawdata[rawdata_len].bytes_in - leth.ilist[i].rawdata[rawdata_len-1].bytes_in) / (leth.ilist[i].rawdata[rawdata_len].timestamp - leth.ilist[i].rawdata[rawdata_len-1].timestamp);\n");
		fprintf(ss,"    leth.ilist[i].array_out[canvas_array_length] = (leth.ilist[i].rawdata[rawdata_len].bytes_out - leth.ilist[i].rawdata[rawdata_len-1].bytes_out) / (leth.ilist[i].rawdata[rawdata_len].timestamp - leth.ilist[i].rawdata[rawdata_len-1].timestamp);\n");
		fprintf(ss,"    var date = new Date(parseInt(leth.ilist[i].rawdata[0].timestamp * 1000));\n");
		fprintf(ss,"    var hours = '0' + date.getHours();\n");
		fprintf(ss,"    var mins = '0' + date.getMinutes();\n");
		fprintf(ss,"    var secs = '0' + date.getSeconds();\n");
		fprintf(ss,"    var start_date = hours.substr(-2) + ':' + mins.substr(-2) + ':' + secs.substr(-2);\n");
		fprintf(ss,"    var date = new Date(parseInt(leth.ilist[i].rawdata[rawdata_len].timestamp * 1000));\n");
		fprintf(ss,"    hours = '0' + date.getHours();\n");
		fprintf(ss,"    mins = '0' + date.getMinutes();\n");
		fprintf(ss,"    secs = '0' + date.getSeconds();\n");
		fprintf(ss,"    var end_date = hours.substr(-2) + ':' + mins.substr(-2) + ':' + secs.substr(-2);\n");
		fprintf(ss,"    leth.ilist[i].canvas_in.draw_graph(leth.ilist[i].array_in,start_date,end_date);\n");
		fprintf(ss,"    leth.ilist[i].canvas_out.draw_graph(leth.ilist[i].array_out,start_date,end_date);\n");
		fprintf(ss,"    console.log('Updated [' + i + '] NAME: [' + leth.ilist[i].ifname + '] Size currently: [' + leth.ilist[i].rawdata.length + ']');\n");
		fprintf(ss,"    break;\n");
		fprintf(ss,"   }\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  console.log('[' + j + '] ILIST-INDEX: [' + i + '/' + leth.ilist.length + '] ETHLIST-INDEX: [' + j + ']');\n");
		fprintf(ss,"  if ( i == leth.ilist.length ){\n");
		fprintf(ss,"   var ilist_length = leth.ilist.length;\n");
		fprintf(ss,"   console.log('Creating object [' + ilist_length + ']');\n");
		fprintf(ss,"   leth.ilist[ilist_length] = Object.create(ilist_obj);\n");
		fprintf(ss,"   leth.ilist[ilist_length].ifname = ethlist[j].ifname;\n");
		fprintf(ss,"   leth.ilist[ilist_length].array_in  = [];\n");
		fprintf(ss,"   leth.ilist[ilist_length].array_out = [];\n");
		fprintf(ss,"   leth.ilist[ilist_length].rawdata   = [];\n");
		fprintf(ss,"   leth.ilist[ilist_length].rawdata[0] = Object.create(rawdata_obj);\n");
		fprintf(ss,"   leth.ilist[ilist_length].rawdata[0].name = ethlist[j].ifname;\n");
		fprintf(ss,"   leth.ilist[ilist_length].rawdata[0].timestamp = ethlist[j].timestamp;\n");
		fprintf(ss,"   leth.ilist[ilist_length].rawdata[0].bytes_in = ethlist[j].bytes_in;\n");
		fprintf(ss,"   leth.ilist[ilist_length].rawdata[0].bytes_out = ethlist[j].bytes_out;\n");
		fprintf(ss,"   leth.ilist[ilist_length].canvas_in = Object.create(GIXGraph);\n");
		fprintf(ss,"   leth.ilist[ilist_length].canvas_out = Object.create(GIXGraph);\n");
		fprintf(ss,"   console.log('Created object [' + ilist_length + '] Name: [' + leth.ilist[ilist_length].ifname + ']');\n");
		fprintf(ss,"  }\n");
		fprintf(ss," }\n");
		fprintf(ss," for ( var i = 0; i < leth.ilist.length; i++ ){\n");
		fprintf(ss,"   console.log('Final object [' + i + '] Name: [' + leth.ilist[i].ifname + '] Raw-Data[0] [' + leth.ilist[i].rawdata[0].name + ']');\n");
		fprintf(ss," }\n");
		fprintf(ss," var divvy = document.getElementById('ETHLIST');\n");
		fprintf(ss," console.log('Processing ETH-Display for ' + ethlist.length + ' Interfaces');\n");
		fprintf(ss," if ( divvy.innerHTML == 'init' ){\n");
		fprintf(ss,"  console.log('Initializing ETH-Display');\n");
		fprintf(ss,"  var result = '<TABLE CELLSPACING=1 BORDER=0 BGCOLOR=black>';\n");
		fprintf(ss,"  result += '<TR><TD BGCOLOR=white COLSPAN=4><CENTER><SPAN CLASS=thead1><B>Network-Interfaces</B></SPAN></TD></TR>';\n");
		fprintf(ss,"  result += '<TR><TD BGCOLOR=white COLSPAN=2><SPAN CLASS=thead2>Total Samples:</SPAN></TD><TD COLSPAN=2 BGCOLOR=white><SPAN CLASS=thead2 ID=TOTAL_SAMPLES></SPAN></TD></TR>';\n");
		fprintf(ss,"  result += '</TR>';\n");
		fprintf(ss,"  for ( var x = 0; x < ethlist.length; x++ ){\n");
		fprintf(ss,"   var color = 'yellow';\n");
		fprintf(ss,"   if ( x %% 2 ) color = 'lightblue';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ROWSPAN=11 VALIGN=TOP><SPAN CLASS=thead2><B>' + ethlist[x].ifname + '</B></SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>Bytes in:</SPAN></TD><TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s ID=BYTES_SEC_IN_' + x + '>' + ethlist[x].bytes_in_sec + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ROWSPAN=11><CANVAS WIDTH=500 HEIGHT=100 ID=C_RECEIVE_' + x + ' CLASS=gcanvas1></CANVAS><BR><CANVAS  WIDTH=500 HEIGHT=100 CLASS=gcanvas1 ID=C_TRANSMIT_' + x + '></CANVAS></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>Bytes out:</SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s ID=BYTES_SEC_OUT_' + x + '>' + ethlist[x].bytes_out_sec + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>Total Bytes in:</SPAN></TD><TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s ID=BYTES_IN_T_' + x + '>' + ethlist[x].bytes_in_t + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>Total Bytes out:</SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s ID=BYTES_OUT_T_' + x + '>' + ethlist[x].bytes_out_t + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>Packets in:</SPAN></TD><TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s ID=PACKETS_SEC_IN_' + x + '>' + ethlist[x].packets_in_sec + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead1s>Packets out:</SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s ID=PACKETS_SEC_OUT_' + x + '>' + ethlist[x].packets_out_sec + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>Total Packets in:</SPAN></TD><TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s ID=PACKETS_IN_T_' + x + '>' + ethlist[x].packets_in_t + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>Total Packets out:</SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s ID=PACKETS_OUT_T_' + x + '>' + ethlist[x].packets_out_t + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>MAC-Address</SPAN></TD><TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + ethlist[x].mac_addr + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>IPv4</SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + ethlist[x].ipv4_addr + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"   result += '<TR>';\n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead1s>IPv6</SPAN></TD>';\n");
		fprintf(ss,"   result += '<TD ALIGN=RIGHT BGCOLOR=' + color + '><SPAN CLASS=thead2s>' + ethlist[x].ipv6_addr + '</SPAN></TD>';\n");
		fprintf(ss,"   result += '</TR>';\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  result += '</TABLE>';\n");
		fprintf(ss,"  divvy.innerHTML = result;\n");
		fprintf(ss,"  var id = document.getElementById('TOTAL_SAMPLES');\n");
		fprintf(ss,"  console.log('Total Samples: [' + leth.ilist[0].rawdata.length + ']');\n");
		fprintf(ss,"  if ( id != undefined ) id.innerHTML = leth.ilist[0].rawdata.length;\n");
		fprintf(ss,"  for ( var idx = 0; idx < leth.ilist.length; idx++ ){\n");
		fprintf(ss,"   leth.ilist[idx].canvas_in.init('C_RECEIVE_' + idx, 'green','red','black','Bytes in','','Bytes/s');\n");
		fprintf(ss,"   leth.ilist[idx].canvas_out.init('C_TRANSMIT_' + idx, 'green','red','black','Bytes out','','Bytes/s');\n");
		fprintf(ss,"  }\n");
		fprintf(ss," } else {\n"); // Just update
		fprintf(ss,"  console.log('Total Samples: [' + leth.ilist[0].rawdata.length + ']');\n");
		fprintf(ss,"  var id = document.getElementById('TOTAL_SAMPLES');\n");
		fprintf(ss,"  if ( id != undefined ) id.innerHTML = leth.ilist[0].rawdata.length;\n");
		fprintf(ss,"  for ( var x = 0; x < ethlist.length; x++ ){\n");
		fprintf(ss,"   var id = document.getElementById('BYTES_SEC_IN_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].bytes_in_sec;\n");
		fprintf(ss,"   var id = document.getElementById('BYTES_SEC_OUT_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].bytes_out_sec;\n");
		fprintf(ss,"   var id = document.getElementById('PACKETS_SEC_IN_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].packets_in_sec;\n");
		fprintf(ss,"   var id = document.getElementById('PACKETS_SEC_OUT_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].packets_out_sec;\n");
		fprintf(ss,"   var id = document.getElementById('BYTES_IN_T_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].bytes_in_t;\n");
		fprintf(ss,"   var id = document.getElementById('BYTES_OUT_T_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].bytes_out_t;\n");
		fprintf(ss,"   var id = document.getElementById('PACKETS_IN_T_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].packets_in_t;\n");
		fprintf(ss,"   var id = document.getElementById('PACKETS_OUT_T_' + x);\n");
		fprintf(ss,"   if ( id != undefined ) id.innerHTML = ethlist[x].packets_out_t;\n");
		fprintf(ss,"  }\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function display_fs_info(fsinfo){\n");
		fprintf(ss," console.log('Displaying info for [' + fsinfo.length + '] Filesystems');\n");
		fprintf(ss," var id = document.getElementById('FSINFO');\n");
		fprintf(ss," var result = '<TABLE CELLSPACING=1 BORDER=0 BGCOLOR=black>';\n");
		fprintf(ss," result += '<TR>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Device</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Path</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Total Size</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Avail Size</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Used Size(%%)</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Total Inodes</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Free Inodes</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><SPAN CLASS=thead1s>Used Inodes(%%)</SPAN></TD>';\n");
		fprintf(ss," result += '</TR>';\n");
		fprintf(ss," for ( var i = 0; i < fsinfo.length; i++ ){\n");
		fprintf(ss,"  var color = 'lightblue';\n");
		fprintf(ss,"  if ( i %% 2 ) color = 'yellow';\n");
		fprintf(ss,"  var b_percent_size = Math.round((100.0 - (fsinfo[i].b_avail * 100) / fsinfo[i].b_total)*100)/100;\n");
		fprintf(ss,"  var i_percent_size = Math.round((100.0 - (fsinfo[i].i_free * 100) / fsinfo[i].i_total)*100)/100;\n");
		fprintf(ss,"  console.log('PATH: [' + fsinfo[i].path	 + '] Percent Blocks: [' + b_percent_size + '] Percent Inodes: [' + i_percent_size + ']');\n");
		fprintf(ss,"  result += '<TR>';\n");
		fprintf(ss,"  var bgcolor = color;\n");
		fprintf(ss,"  var bolder = '';\n");
		fprintf(ss,"  var endbolder = '';\n");
		fprintf(ss,"  if ( b_percent_size > 60 || i_percent_size > 60 ){ bolder = '<B>'; endbolder = '</B>'; bgcolor = 'orange'; }\n");
		fprintf(ss,"  if ( b_percent_size > 95 || i_percent_size > 95 ){ bolder = '<B>'; endbolder = '</B>'; bgcolor = 'red'; }\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + '/dev/' + fsinfo[i].dev_name + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + fsinfo[i].path + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + fsinfo[i].b_total_t + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + fsinfo[i].b_avail_t + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + b_percent_size + '%%' + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + fsinfo[i].i_free_t + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + fsinfo[i].i_free_t + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD ALIGN=LEFT BGCOLOR=' + bgcolor + '><SPAN CLASS=thead2s>' + bolder + i_percent_size + '%%' + endbolder + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '</TR>';\n");
		fprintf(ss," }\n");
		fprintf(ss," result += '</TABLE>';\n");
		fprintf(ss," id.innerHTML = result;\n");	
		fprintf(ss,"}\n");


		fprintf(ss,"function update_connections_callback(req){\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status != 200 ) return;\n");
		fprintf(ss," if ( req.responseText.charAt(0) == 'O' ){\n");
		fprintf(ss,"  console.log('JSON-REPLY: ' + req.responseText);\n");
		fprintf(ss,"  var proclist = JSON.parse(extract_bracket_val(req.responseText));\n");
		fprintf(ss,"  display_proclist(proclist);\n"); 
		fprintf(ss,"  display_int_info(proclist.eth);\n");
		fprintf(ss,"  display_fs_info(proclist.fs);\n");
		fprintf(ss," }\n");
		// fprintf(ss,"  for ( var i = 0; i < %d; i++ ){\n",entries);
		// fprintf(ss,"   get_conns(i);\n");
		// fprintf(ss,"  }\n");
		fprintf(ss,"  var request = new XMLHttpRequest();\n");
		fprintf(ss,"  request.onreadystatechange = function() { update_connections_callback_callback(request); };\n");
		fprintf(ss,"  request.open('GET','/ajax/SYSINFO/0' ,true);\n");
		fprintf(ss,"  request.send();\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function update_connections_callback_callback(req){\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status != 200 ) return;\n");
		// fprintf(ss," console.log('Callback for SYSINFO ->  Response: [' + req.responseText + ']');\n");
		fprintf(ss," if ( req.responseText.charAt(0) == 'O' ){\n");
		fprintf(ss,"  var jresp = JSON.parse(extract_bracket_val(req.responseText));\n");
		fprintf(ss,"  var id = document.getElementById('LOAD1');\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = jresp.load1;\n");
		fprintf(ss,"  var id = document.getElementById('LOAD5');\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = jresp.load5;\n");
		fprintf(ss,"  var id = document.getElementById('LOAD15');\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = jresp.load15;\n");
		fprintf(ss,"  var id = document.getElementById('UPTIME');\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = jresp.uptime;\n");
		fprintf(ss,"  var id = document.getElementById('SYS_PROCS');\n");
		fprintf(ss,"  if ( id != undefined && id != null ) id.innerHTML = jresp.sys_procs;\n");
		fprintf(ss," }\n");
		fprintf(ss," update_conns_display(jresp.inetlist);\n");
		fprintf(ss," document.getElementById('GIGA_ROTATOR').innerHTML = '<IMG SRC=/empty.gif HEIGHT=32>';\n");
		fprintf(ss," if ( gigatimer_active ) gigatimer = setInterval(update_connections,2000);\n");
		fprintf(ss,"}\n");




		fprintf(ss,"function toggle_giga_refresh(){\n");
		fprintf(ss," if ( gigatimer_active ){\n");
		fprintf(ss,"  document.getElementById('REFRESH_GIGA_BUTTON').value = 'Enable Auto-Refresh';\n");
		fprintf(ss,"  gigatimer_active = false;\n");
		fprintf(ss,"  if ( gigatimer != null ){ clearInterval(gigatimer); }\n");
		fprintf(ss," } else {\n");
		fprintf(ss,"  document.getElementById('REFRESH_GIGA_BUTTON').value = 'Stop Auto-Refresh';\n");
		fprintf(ss,"  gigatimer_active = true;\n");
		fprintf(ss,"  update_connections();\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");



		fprintf(ss,"function show_info_rotator(){\n");
		// fprintf(ss," var refresh_button = document.getElementById('REFRESH_BUTTON');\n");
		fprintf(ss," var rotator_id = document.getElementById('ROTATOR');\n");
		// fprintf(ss," refresh_button.style.visibility = 'hidden';\n");
		fprintf(ss," rotator_id.innerHTML = '<IMG SRC=/new_rotator_big.gif HEIGHT=32>';\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function hide_info_rotator(){\n");
		// fprintf(ss," var refresh_button = document.getElementById('REFRESH_BUTTON');\n");
		fprintf(ss," var rotator_id = document.getElementById('ROTATOR');\n");
		// fprintf(ss," refresh_button.style.visibility = 'visible';\n");
		fprintf(ss," rotator_id.innerHTML = '<IMG SRC=/empty.gif HEIGHT=32>';\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function process_detail1(pid){\n");
		fprintf(ss," if ( gigatimer_active ) { toggle_giga_refresh(); }\n");
		fprintf(ss," if ( megatimer != null ) clearInterval(megatimer);\n");
		fprintf(ss," megatimer_active = false;\n");
		fprintf(ss," process_detail(pid);\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function process_detail(pid){\n");
		fprintf(ss," close_info_window();\n");
		fprintf(ss," var main = document.getElementById('MAIN');\n");
		fprintf(ss," var newdiv = document.createElement('DIV');\n");
		fprintf(ss," newdiv.setAttribute('class','info_div');\n");
		fprintf(ss," newdiv.id = 'NEWDIV';\n");
		fprintf(ss," var closer_span = document.createElement('SPAN');\n");
		fprintf(ss," closer_span.setAttribute('class','filemanagerclose2');\n");
		fprintf(ss," closer_span.style.styleFloat = 'right';\n");
		fprintf(ss," closer_span.style.cssFloat = 'right';\n");
		fprintf(ss," closer_span.innerHTML = '&times';\n");
		fprintf(ss," closer_span.id = 'CLOSER';\n");
		fprintf(ss," var refresh_button = document.createElement('BUTTON');\n");
		fprintf(ss," refresh_button.id = 'REFRESH_BUTTON';\n");
		fprintf(ss," refresh_button.setAttribute('class','standard_button');\n");
		fprintf(ss," refresh_button.innerHTML = 'Enable Auto-Refresh';\n");
		fprintf(ss," newdiv.appendChild(closer_span);\n");
		fprintf(ss," var rotator_id = document.createElement('SPAN');\n");
		fprintf(ss," rotator_id.id = 'ROTATOR';\n");
		fprintf(ss," rotator_id.setAttribute('class','rotator_div');\n");
		fprintf(ss," rotator_id.innerHTML = '<IMG SRC=/empty.gif HEIGHT=32>';\n");
		fprintf(ss," newdiv.appendChild(rotator_id);\n");
		fprintf(ss," newdiv.appendChild(refresh_button);\n");
		fprintf(ss," var tdiv = document.createElement('DIV');\n");
		fprintf(ss," closer_span.addEventListener('click',function() { close_info_window(); });\n");
		fprintf(ss," refresh_button.addEventListener('click',function() { process_detail_refresh_toggle(pid,tdiv); });\n");
		fprintf(ss," tdiv.setAttribute('class','table_list2');\n");
		fprintf(ss," tdiv.id = 'TDIV';\n");
		fprintf(ss," tdiv.style.backgroundColor = 'black';\n");
		fprintf(ss," newdiv.appendChild(tdiv);\n");
		fprintf(ss," main.appendChild(newdiv);\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," show_info_rotator();\n");
		fprintf(ss," request.onreadystatechange = function() { process_detail_callback(request,pid,tdiv); };\n");
		fprintf(ss," request.open('GET','/ajax/PROCDETAIL/' + pid, true);\n");
		fprintf(ss," request.send();\n");
		fprintf(ss," if ( megatimer_active ) megatimer = setInterval(function() { process_detail_refresh(pid,tdiv); },2000);\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function process_detail_refresh_toggle(pid,tdiv){\n");
		fprintf(ss," var id = document.getElementById('REFRESH_BUTTON');\n");
		fprintf(ss," if ( megatimer_active ){\n");
		fprintf(ss,"  if ( megatimer != null ) { clearInterval(megatimer); megatimer = null; };\n");
		fprintf(ss,"  id.innerHTML = 'Enable Auto-Refresh';\n");
		fprintf(ss,"  megatimer_active = false;\n");
		fprintf(ss," } else {\n");
		fprintf(ss,"  if ( megatimer != null ) { clearInterval(megatimer); megatimer = null; };\n");
		fprintf(ss,"  megatimer = setInterval(function() { process_detail_refresh(pid,tdiv); },2000);\n");
		fprintf(ss,"  id.innerHTML = 'Stop Auto-Refresh';\n");
		fprintf(ss,"  process_detail_refresh(pid,tdiv);\n");
		fprintf(ss,"  megatimer_active = true;\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function process_detail_refresh(pid,tdiv){\n");
		fprintf(ss," if ( megatimer != null ) clearInterval(megatimer);\n");
		fprintf(ss," show_info_rotator();\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," request.onreadystatechange = function() { process_detail_callback(request,pid,tdiv); };\n");
		fprintf(ss," request.open('GET','/ajax/PROCDETAIL/' + pid, true);\n");
		fprintf(ss," request.send();\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function process_detail_callback(req,pid,tdiv){\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status != 200 ) return;\n");
		fprintf(ss," console.log('Callback for PROCESS_DETAIL(' + pid + ') ->  Response: [' + req.responseText + ']');\n");
		fprintf(ss," hide_info_rotator();\n");
		fprintf(ss," var result = '<CENTER>';\n");
		fprintf(ss," result += '<P><SPAN CLASS=theadbig>Information for Process: <B>' + pid + '</B></SPAN></P>';\n");
		fprintf(ss," if ( req.responseText.charAt(0) != 'O' ){\n");
		fprintf(ss,"  tdiv.innerHTML = result;\n");
		fprintf(ss,"  alert('Could not get process details [' + extract_bracket_val(req.responseText) + ']');\n");
		fprintf(ss,"  close_info_window();\n");
		fprintf(ss,"  return;\n");
		fprintf(ss," }\n");
		fprintf(ss," var pd = JSON.parse(extract_bracket_val(req.responseText));\n");
		fprintf(ss," result += '<P>';\n");
		fprintf(ss," result += '<TABLE CELLSPACING=1 BORDER=0 BGCOLOR=black>';\n");
		fprintf(ss," result += '<TR><TD VALIGN=TOP>';\n");
		fprintf(ss," result += '<TABLE CELLSPACING=1 BORDER=0 BGCOLOR=blue>';\n");
		fprintf(ss," if ( pd.ppid == 0 ){\n");
		fprintf(ss,"  result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Parent-PID:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>No parent</SPAN></TD></TR>';\n");
		fprintf(ss," } else {\n");
		fprintf(ss,"  result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Parent-PID:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2slink onclick=process_detail1(' + pd.ppid + ')>' + pd.ppid + '</SPAN></TD></TR>';\n");
		fprintf(ss," }\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Process-state:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.full_state + '</B></SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Real-UID:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.r_uid + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Real-GID:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.r_gid + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Effective-UID:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.e_uid + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Effective-GID:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.e_gid + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Name:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.name + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Executeable-path:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.full_exe + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Working-directory:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.full_cwd + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Commandline:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.commandline + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>CPU-Usage (sys):</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.cpu_usage_sys + '%%</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>CPU-Time (sys):</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.sys_time + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>CPU-Usage (usr):</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.cpu_usage_usr + '%%</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>CPU-Time (usr):</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.usr_time + '</SPAN></TD></TR>';\n");
		fprintf(ss," if ( pd.slot > -1 && pd.index > -1 ){\n");
		fprintf(ss,"  result += '<TR><TD ALIGN=CENTER BGCOLOR=white COLSPAN=2><INPUT TYPE=BUTTON CLASS=standard_button VALUE=\"Show GINETD-Connection\" onclick=conns_list1(' + pd.slot + ',' + pd.index + ')></TD></TR>';\n");
		fprintf(ss," }\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Process-started:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.p_start + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Virtual memory:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.vm_size + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Real memory:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.rss + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Threads:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.num_threads + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>CPU:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.cpu + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '<TR><TD ALIGN=RIGHT BGCOLOR=white><SPAN CLASS=thead2s>Count of fds:</SPAN></TD><TD BGCOLOR=white ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.fds.length + '</SPAN></TD></TR>';\n");
		fprintf(ss," result += '</TABLE>';\n");
		fprintf(ss," result += '</TD>';\n");
		fprintf(ss," result += '<TD VALIGN=TOP>';\n");
		fprintf(ss," result += '<DIV CLASS=fd_div>';\n");
		fprintf(ss," result += '<TABLE CELLSPACING=1 BGCOLOR=blue>';\n");
		fprintf(ss," result += '<TR><TD BGCOLOR=white><SPAN CLASS=thead1>FD</SPAN></TD><TD BGCOLOR=white><SPAN CLASS=thead1>Type</SPAN></TD><TD BGCOLOR=white><SPAN CLASS=thead1>Name</SPAN></TD></TR>';\n");
		fprintf(ss," for ( var ix = 0; ix < pd.fds.length; ix++ ){\n");
		fprintf(ss,"  var color = 'yellow';\n");
		fprintf(ss,"  if ( ix %% 2 ) color = 'lightblue';\n");
		fprintf(ss,"  result += '<TR>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + pd.fds[ix].fd + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + pd.fds[ix].type + '</SPAN></TD>';\n");
		fprintf(ss,"  if ( pd.fds[ix].valid_addr == true ){\n");
		fprintf(ss,"   var status = 'unknown&nbsp;' + pd.fds[ix].state;\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 1 ) status = 'ESTABLISHED';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 2 ) status = 'SYN_SENT';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 3 ) status = 'SYN_RECV';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 4 ) status = 'FIN_WAIT1';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 5 ) status = 'FIN_WAIT2';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 6 ) status = 'TIME_WAIT(' + pd.fds[ix].timer_value + ')';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 7 ) status = 'CLOSE';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 8 ) status = 'CLOSE_WAIT(' + pd.fds[ix].timer_value + ')';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 9 ) status = 'LAST_ACK';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 10 ) status = 'LISTEN';\n");
		fprintf(ss,"   if ( pd.fds[ix].state == 11 ) status = 'CLOSING';\n");
		fprintf(ss,"   var family = 'unknown&nbsp;' + pd.fds[ix].family;\n");
		fprintf(ss,"   if ( pd.fds[ix].family == %d ) family = 'IPv6';\n",AF_INET6);
		fprintf(ss,"   if ( pd.fds[ix].family == %d ) family = 'IPv4';\n",AF_INET);
		fprintf(ss,"   if ( pd.fds[ix].family == %d ) family = 'unix';\n",AF_UNIX);
		fprintf(ss,"   var protocol = 'unknown&nbsp;' + pd.fds[ix].protocol;\n");
		fprintf(ss,"   if ( pd.fds[ix].protocol == %d ) protocol = 'TCP';\n",SOCK_STREAM);
		fprintf(ss,"   if ( pd.fds[ix].protocol == %d ) protocol = 'UDP';\n",SOCK_DGRAM);
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=LEFT><SPAN CLASS=thead2s>[' + family + '][' + protocol + '] [' + pd.fds[ix].local_addr + ']:' + pd.fds[ix].local_port + ' - [' + pd.fds[ix].remote_addr + ']:' + pd.fds[ix].remote_port + ' (' + status + ')</SPAN></TD>';\n");
		fprintf(ss,"  } else { \n");
		fprintf(ss,"   result += '<TD BGCOLOR=' + color + ' ALIGN=LEFT><SPAN CLASS=thead2s>' + pd.fds[ix].name + '</SPAN></TD>';\n");
		fprintf(ss,"  }\n");
		fprintf(ss,"  result += '</TR>';\n");
		fprintf(ss," }\n");
		fprintf(ss," result += '</TABLE>';\n");
		fprintf(ss," result += '</DIV>';\n");
		fprintf(ss," result += '</TD>';\n");
		fprintf(ss," result += '</TR>';\n");
		fprintf(ss," result += '</TABLE>';\n");
		fprintf(ss," result += '</P>';\n");
		fprintf(ss," tdiv.innerHTML = result;\n");
		fprintf(ss," if ( megatimer_active ) megatimer = setInterval(function() { process_detail_refresh(pid,tdiv); },2000);\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function conns_list1(idx,item){\n");
		fprintf(ss," if ( gigatimer_active ) { toggle_giga_refresh(); }\n");
		fprintf(ss," if ( megatimer != null ) clearInterval(megatimer);\n");
		fprintf(ss," megatimer_active = false;\n");
		fprintf(ss," conns_list(idx,item);\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function  conns_list(idx,item){\n");
		fprintf(ss," close_info_window();\n");
		fprintf(ss," var main = document.getElementById('MAIN');\n");
		fprintf(ss," var newdiv = document.createElement('DIV');\n");
		fprintf(ss," newdiv.setAttribute('class','info_div');\n");
		fprintf(ss," newdiv.id = 'NEWDIV';\n");
		fprintf(ss," var closer_span = document.createElement('SPAN');\n");
		fprintf(ss," closer_span.setAttribute('class','filemanagerclose2');\n");
		fprintf(ss," closer_span.style.styleFloat = 'right';\n");
		fprintf(ss," closer_span.style.cssFloat = 'right';\n");
		fprintf(ss," closer_span.innerHTML = '&times';\n");
		fprintf(ss," closer_span.id = 'CLOSER';\n");
		fprintf(ss," var refresh_button = document.createElement('BUTTON');\n");
		fprintf(ss," refresh_button.id = 'REFRESH_BUTTON';\n");
		fprintf(ss," refresh_button.setAttribute('class','standard_button');\n");
		fprintf(ss," refresh_button.innerHTML = 'Enable Auto-Refresh';\n");
		fprintf(ss," newdiv.appendChild(closer_span);\n");
		fprintf(ss," var rotator_id = document.createElement('SPAN');\n");
		fprintf(ss," rotator_id.id = 'ROTATOR';\n");
		fprintf(ss," rotator_id.setAttribute('class','rotator_div');\n");
		fprintf(ss," newdiv.appendChild(rotator_id);\n");
		fprintf(ss," newdiv.appendChild(refresh_button);\n");
		fprintf(ss," var tdiv = document.createElement('DIV');\n");
		fprintf(ss," closer_span.addEventListener('click',function() { close_info_window(); });\n");
		fprintf(ss," refresh_button.addEventListener('click',function() { reload_conns_list_toggle(idx,item); });\n");
		fprintf(ss," tdiv.setAttribute('class','table_list');\n");
		fprintf(ss," tdiv.id = 'TDIV';\n");
		fprintf(ss," newdiv.appendChild(tdiv);\n");
		fprintf(ss," main.appendChild(newdiv);\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," show_info_rotator();\n");
		fprintf(ss," request.onreadystatechange = function() { conns_list_callback(request,idx,item); };\n");
		fprintf(ss," request.open('GET','/ajax/CONNSLIST/' + idx, true);\n");
		fprintf(ss," request.send();\n");
		fprintf(ss," if ( megatimer_active ) megatimer = setInterval(function() { reload_conns_list(idx,item); },1000);\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function reload_conns_list_toggle(idx,item){\n");
		fprintf(ss," var id = document.getElementById('REFRESH_BUTTON');\n");
		fprintf(ss," if ( megatimer_active ){\n");
		fprintf(ss,"  if ( megatimer != null ) { clearInterval(megatimer); megatimer = null; };\n");
		fprintf(ss,"  id.innerHTML = 'Enable Auto-Refresh';\n");
		fprintf(ss,"  megatimer_active = false;\n");
		fprintf(ss," } else {\n");
		fprintf(ss,"  if ( megatimer != null ) { clearInterval(megatimer); megatimer = null; };\n");
		fprintf(ss,"  megatimer = setInterval(function() { reload_conns_list(idx,item); },1000);\n");
		fprintf(ss,"  id.innerHTML = 'Stop Auto-Refresh';\n");
		fprintf(ss,"  reload_conns_list(idx,item);\n");
		fprintf(ss,"  megatimer_active = true;\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function reload_conns_list(idx,item){\n");
		fprintf(ss," if ( megatimer != null ) clearInterval(megatimer);\n");
		fprintf(ss," show_info_rotator();\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," request.onreadystatechange = function() { conns_list_callback(request,idx,item); };\n");
		fprintf(ss," request.open('GET','/ajax/CONNSLIST/' + idx, true);\n");
		fprintf(ss," request.send();\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function conns_list_callback(req,idx,item){\n");
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status != 200 ) return;\n");
		fprintf(ss," console.log('Callback for CONNSLIST ->  Response: [' + req.responseText + ']');\n");
		fprintf(ss," hide_info_rotator();\n");
		fprintf(ss," if ( req.responseText.charAt(0) != 'O' ){\n");
		fprintf(ss,"  alert('Could not get list of connections');\n");
		fprintf(ss,"  return;\n");
		fprintf(ss," }\n");
		fprintf(ss," var connection = JSON.parse(extract_bracket_val(req.responseText));\n");
		fprintf(ss," console.log('Found [' + connection.length + '] records');\n");
		fprintf(ss," var cid = document.getElementById('TDIV');\n");
		fprintf(ss," var result = '<TABLE CELLSPACING=1 BORDER=0 BGCOLOR=black><TR><TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Index</SPAN></TD><TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Source</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Target</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>PID</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Prog&nbsp;PID</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Created</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>CWD</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Data</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Stack</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Exe</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>Libs</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>IO-Read</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>IO-Write</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>TCP&nbsp;State</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>TCP&nbsp;Timeout</SPAN></TD>';\n");
		fprintf(ss," result += '<TD BGCOLOR=white><CENTER><SPAN CLASS=thead1>&nbsp;</SPAN></TD>';\n");
		fprintf(ss," result += '</TR>';\n");
		fprintf(ss," for ( var i = 0; i < connection.length; i++ ){\n");
		fprintf(ss,"  var color = 'lightblue';\n");
		fprintf(ss,"  if ( i % 2 ) color = 'yellow';\n");
		fprintf(ss,"  if ( i == item ) color = 'orange';\n");
		fprintf(ss,"  result += '<TR>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' +  connection[i].slot +  '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + '><SPAN CLASS=thead2s><B>' + connection[i].source + '</B>:' + connection[i].source_port + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + '><SPAN CLASS=thead2s><B>' + connection[i].target + '</B>:' + connection[i].target_port + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2links onclick=process_detail1(' + connection[i].pid + ')>' + connection[i].pid + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2links onclick=process_detail1(' + connection[i].cpid + ')>' + connection[i].cpid + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].created + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].cwd + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].vm_data + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].vm_stack + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].vm_exe + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].vm_lib + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].io_read + '(' + connection[i].io_read_sec + ')</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].io_write + '(' + connection[i].io_write_sec + ')</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].tcp_state + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=RIGHT><SPAN CLASS=thead2s>' + connection[i].tcp_timeout + '</SPAN></TD>';\n");
		fprintf(ss,"  result += '<TD BGCOLOR=' + color + ' ALIGN=CENTER><INPUT TYPE=BUTTON CLASS=standard_button onclick=kill_connection(' + connection[i].cpid + ',' + idx + ',' + i + ') VALUE=\"Disconnect\"></TD>';\n");
		fprintf(ss,"  result += '</TR>';\n");
		fprintf(ss," }\n");
		fprintf(ss," cid.innerHTML = result;\n");
		fprintf(ss," if ( megatimer )  megatimer = setInterval(function() { reload_conns_list(idx,item); },1000);\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function kill_connection(pid, main_idx, co_index){\n");
		fprintf(ss," var request = new XMLHttpRequest();\n");
		fprintf(ss," request.onreadystatechange = function() { kill_connection_callback(request,pid,main_idx,co_index); };\n");
		fprintf(ss," request.open('GET','/ajax/KILLTCP/' + main_idx + '/' + co_index, true);\n");
		fprintf(ss," request.send();\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function kill_connection_callback(req,pid,main_idx,co_idx){\n"); 
		fprintf(ss," if ( req.readyState != 4 ) return;\n");
		fprintf(ss," if ( req.status != 200 ) return;\n");
		fprintf(ss," if ( req.responseText.charAt(0) != 'O' ){\n");
		fprintf(ss,"  alert('Could kill connection');\n");
		fprintf(ss,"  return;\n");
		fprintf(ss," } else {\n");
		fprintf(ss,"  alert('Connection received kill');\n");
		fprintf(ss,"  return;\n");
		fprintf(ss," }\n");
		fprintf(ss,"}\n");


		fprintf(ss,"function close_info_window(){\n");
		fprintf(ss,"var newdiv =  document.getElementById('NEWDIV');\n");
		fprintf(ss,"var rotator = document.getElementById('ROTATOR');\n");
		fprintf(ss,"var closer =  document.getElementById('CLOSER');\n");
		fprintf(ss,"var main =    document.getElementById('MAIN');\n");
		fprintf(ss,"var tdiv =    document.getElementById('TDIV');\n");
		fprintf(ss," if ( megatimer != undefined && megatimer != null ){ clearInterval(megatimer); megatimer = null; } \n");
		fprintf(ss," if ( newdiv != undefined && rotator != undefined ) newdiv.removeChild(rotator);\n");
		fprintf(ss," if ( newdiv != undefined && closer != undefined )  newdiv.removeChild(closer);\n");
		fprintf(ss," if ( newdiv != undefined && tdiv != undefined )    newdiv.removeChild(tdiv);\n");
		fprintf(ss," if ( main != undefined && newdiv != undefined )    main.removeChild(newdiv);\n");
		fprintf(ss," megatimer_active = false;\n");
		fprintf(ss," if ( megatimer ) { clearInterval(megatimer); megatimer = null; }\n");
		fprintf(ss,"}\n");

		fprintf(ss,"function init_all(){\n");
		fprintf(ss," console.log('Initializing everything');\n");
		fprintf(ss," megatimer = null;\n");
		fprintf(ss," gigatimer = null;\n");
		fprintf(ss," megatimer_active = false;\n");
		fprintf(ss," gigatimer_active = false;\n");
		fprintf(ss," gigatimer_stored = false;\n");
		fprintf(ss," leth = Object.create(eth_obj);\n");
		fprintf(ss," update_connections();\n"); // Initial call
		fprintf(ss,"}\n");

		fprintf(ss,"</SCRIPT>\n");
	}




	if ( type_req == TYPE_HTML ){
		fprintf(ss,"</BODY>\n");
		fflush(ss);
		shutdown(sock,SHUT_RDWR);
		fclose(ss);
		return;
	}
		
	shutdown(sock,SHUT_RDWR);
	fclose(ss);
	return;
}


void process_client(int index){
	char nprefix[256];
	long safe_fd;
	struct pollfd polly[2];
	unsigned char buffer[MAX_BUFFER];
	int pid;
	connection_index = index;
	sprintf(nprefix,"%s IDX:%d [%s:%d] [%s]",prefix,index,CCON.source,CCON.port,CSERVER.cmdline);
	strcpy(prefix,nprefix);
	// logger(prefix,"STARTING\n");

	
	{
		struct sigaction act;
		bzero(&act,sizeof(act));
		act.sa_sigaction = &slave_reaper;
		act.sa_flags = SA_SIGINFO | SA_RESTART;
		sigaction(SIGCHLD,&act,NULL);
		// signal(SIGCHLD,server_reaper);
	}
	// logger(prefix,"About to start: [%s]\n",CSERVER.cmdline);
	if ( (pid = fork()) == 0 ){
		char **pp;
		char *cmd;
		char *prg;
		char *ptr;
		int args;
		pp = NULL;

		if ( strncmp(CSERVER.cmdline,"ADMIN",5) == 0 ){
			char pwd[128];
			ptr = &(CSERVER.cmdline)[5];
			while ( *ptr && ( *ptr == ' ' || *ptr == '\t' )) ptr++;
			strcpy(pwd,ptr);
			ptr = &pwd[strlen(pwd)-1];
			while ( ptr > pwd && ( *ptr == ' ' || *ptr == '\t' || *ptr == '\r' || *ptr == '\n' )) ptr--;
			strcat(prefix,"{ADMIN}");
			call_webserver(CCON.sock,pwd);
			exit(0);
		}


		cmd = strdup(CSERVER.cmdline);
		args = 0;
		while ( (ptr = strtok(cmd," \t\r\n")) != NULL ){
			cmd = NULL;
			if ( args == 0 ){
				prg = strdup(ptr);	
			}
			pp = (char **)realloc(pp,sizeof(char *) * (args+1));
			pp[args++] = strdup(ptr);
			pp[args] = NULL;
		}
		logger(prefix,"Will execute [%s] with %d args PID: %d\n",prg,args,getpid());
		dup2(CCON.sock, fileno(stdin));
		dup2(CCON.sock, fileno(stdout));
		execvp(prg,pp);
		logger(prefix,"Cannot execute: [%s]\n",prg);
		exit(9);
		
	} 
	CCON.cpid = pid;



	/*	
	// Make everything non-blocking
	safe_fd = fcntl(CCON.sock,F_GETFL);
	safe_fd |= O_NONBLOCK;
	if ( fcntl(CCON.sock,F_SETFL,safe_fd) < 0){
		logger(prefix,"Cannot set socket non-blocking!\n");
		kill(CCON.cpid,9);
		exit(0);
	}
	*/

	while(1){
		int received;
		int fat_timeout;
		struct timespec tmo_p;
		sigset_t mask;

		polly[0].fd     = CCON.sock;
		polly[0].events =  POLLHUP | POLLERR | POLLRDHUP;
		if ( CSERVER.data_timeout > 0 ) polly[0].events |=  POLLIN;

		if ( CSERVER.timeout < 0  ){
			fat_timeout = CSERVER.data_timeout;
		} else {
			if ( CSERVER.data_timeout < 0 ){
				fat_timeout = CSERVER.timeout;
			} else {
				if ( CSERVER.data_timeout < CSERVER.timeout ){
					fat_timeout = CSERVER.data_timeout;
				} else {
					fat_timeout = CSERVER.timeout;
				}
			}
		}
		// logger(prefix,"POLLING...\n");	
		if ( fat_timeout <= 0 ){
			tmo_p.tv_sec = 31536000;
		} else {
			tmo_p.tv_sec = fat_timeout;
		}
		tmo_p.tv_nsec = 0;
		sigemptyset(&mask);
		// sigaddset(&mask,SIGTERM);
		// sigaddset(&mask,SIGHUP);
		// sigaddset(&mask,SIGCHLD);
		sigaddset(&mask,SIGPIPE);
		sigaddset(&mask,SIGINT);
		sigaddset(&mask,SIGUSR1);
		sigaddset(&mask,SIGUSR2);
		/* if ( (received =  ppoll(polly,1,&tmo_p,&mask)) < 1 ) */
		if ( (received =  ppoll(polly,1,&tmo_p,NULL)) < 1 ){
		
			if ( CSERVER.timeout > 0 && (CSERVER.timeout + CCON.created) <= time(NULL) ){
				logger(prefix,"Connection ran into timeout (%d Seconds)\n", CSERVER.timeout);
				if ( CCON.cpid ) kill(CCON.cpid,9);
				exit(0);
			} else { // A data-timeout
				if ( CSERVER.data_timeout > 0 ){
					if ( (CCON.lastin + CSERVER.data_timeout) <= time(NULL) ){
						logger(prefix,"Connection canceled because of data-timeout (%d Seconds) [Total-Session-time: %d]\n", CSERVER.data_timeout,time(NULL) - CCON.created);
						close(CCON.sock);
						if ( CCON.cpid ) m_kill(CCON.cpid,9);
						exit(0);
					}
				}
			}
		}
		
		logger(prefix,"POLL[SOCKET]: [%s,%s,%s,%s,%s]\n",
			polly[0].revents & POLLNVAL ? "NVAL" : "",
			polly[0].revents & POLLIN ? "IN" : "",
			polly[0].revents & POLLHUP ? "HUP" : "",
			polly[0].revents & POLLRDHUP ? "RDHUP" : "",
			polly[0].revents & POLLERR ? "ERR" : "");
		if ( (polly[0].revents & POLLHUP) || (polly[0].revents & POLLRDHUP) ){
				logger(prefix,"SOCKET finished connection (%d Seconds active) Socket-ID: %d\n", time(NULL) - CCON.created,CCON.sock);
				close(CCON.sock);
				if ( CCON.cpid ) m_kill(CCON.cpid,9);
				exit(0);
		}
		if ( (polly[0].revents & POLLIN) ){
			CCON.lastin = time(NULL);
		}
		if ( CSERVER.data_timeout > 0 ){
			if ( (CCON.lastin + CSERVER.data_timeout) <= time(NULL) ){
				logger(prefix,"Connection canceled because of data-timeout (%d Seconds) [Total-Session-time: %d]\n", CSERVER.data_timeout,time(NULL) - CCON.created);
				close(CCON.sock);
				if ( CCON.cpid ) m_kill(CCON.cpid,9);
				exit(0);
			}
		}
	}	
	close(CCON.sock);
	exit(0);	
}



void start_server(int index){
	int sock;
	int on;
	struct sockaddr *saddr;
	int saddr_len;
	struct sockaddr_in sock4;
	struct sockaddr_in6 sock6;

	global_index = index;
	servlist = (struct server *)shmat(shm_id,NULL,0);
	if ( servlist == NULL ){
		logger("MAIN","FATAL(%s:%d) Cannot attach shared-memory\n",__FILE__,__LINE__);
		exit(3);
	}
	sprintf(prefix,"[%d] S-PORT %d [%s]",index,servlist[index].port,servlist[index].family == AF_INET6 ? "IPv6" : "IPv4");
	logger(prefix,"Initializing...\n");
	sock = socket(CSERVER.family,SOCK_STREAM,0);
	if ( sock < 0 ){
		logger	(prefix,"FATAL(%s:%d) Cannot create socket\n",__FILE__,__LINE__);
		exit(3);
	}
	on = 1;
	if ( setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on)) < 0 ){
		logger	(prefix,"FATAL(%s:%d) Cannot SO_REUSEADDR socket\n",__FILE__,__LINE__);
		exit(3);
	}
	if ( CSERVER.family == AF_INET ){
		sock4.sin_family = AF_INET;
		sock4.sin_addr.s_addr = INADDR_ANY;
		sock4.sin_port = htons(CSERVER.port);
		saddr = (struct sockaddr *)&sock4;
		saddr_len = sizeof(sock4);
	} else {
		if ( setsockopt(sock,IPPROTO_IPV6, IPV6_V6ONLY,&on,sizeof(on)) < 0 ){
			logger	(prefix,"FATAL(%s:%d) Cannot IPV6_V6ONLY socket\n",__FILE__,__LINE__);
			exit(3);
		}
		sock6.sin6_family = AF_INET6;
		sock6.sin6_port   = htons(CSERVER.port);
		sock6.sin6_addr   = in6addr_any;
		saddr = (struct sockaddr *)&sock6;
		saddr_len = sizeof(sock6);
	}	
	if ( bind(sock,saddr,saddr_len) < 0 ){
		logger	(prefix,"FATAL(%s:%d) Cannot bind socket\n",__FILE__,__LINE__);
		exit(3);
	}
	listen(sock,MAX_BACKLOG);
	semid2 = semget(INETD_KEY2 + global_index,1,0);
	if ( semid2 >= 0 ) semctl(semid2,IPC_RMID,0);
	semid2 = semget(INETD_KEY2 + global_index,1,0600|IPC_CREAT);
	semctl(semid2,0,SETVAL,1);
	semid = semget(INETD_KEY + global_index,1,0);
	if ( semid >= 0 ) semctl(semid,IPC_RMID,0);
	semid = semget(INETD_KEY + global_index,1,0600|IPC_CREAT);
	semctl(semid,0,SETVAL,1);
	sem_set(semid,CSERVER.max_conns-1);	
	msg_id = msgget(INETD_KEY + global_index,0);
	if ( msg_id >= 0 ) msgctl(msg_id,IPC_RMID,0);
	msg_id = msgget(INETD_KEY + global_index,IPC_CREAT | 0600);
	signal(SIGCHLD,SIG_IGN);
	if ( fork() == 0 ){
		server_reaper_process();
		exit(0);
	}
	{
		struct sigaction act;
		bzero(&act,sizeof(act));
		act.sa_sigaction = &server_reaper;
		act.sa_flags = SA_SIGINFO | SA_RESTART;
		sigaction(SIGCHLD,&act,NULL);
		// signal(SIGCHLD,server_reaper);
	}
	while ( 1 ){
		sem_lock(semid);
		if ( CSERVER.connections > CSERVER.max_conns ){
			logger(prefix,"Cannot  handle connection semaphore (Goint to accept %d/%d)\n",CSERVER.connections+1, CSERVER.max_conns);
			continue;
		}
		{
			int newsock;
			struct sockaddr from_addr;
			int from_addr_len;	
			if ( CSERVER.family == AF_INET )
				from_addr_len = sizeof(sock4);
			else	
				from_addr_len = sizeof(sock6);
			newsock = accept(sock,&from_addr,&from_addr_len);
			if ( newsock > 0 ){
				char ip_name[256];
				char ips_name[256];
				int  ip_port;
				int  ips_port;
				int pid;
				int i;
				if ( CSERVER.family == AF_INET ){
					struct sockaddr_in *s;	
					s = (struct sockaddr_in *)&from_addr;
					ip_port = ntohs(s->sin_port);
					sprintf(ip_name,"%s",inet_ntoa(s->sin_addr));
				} else {
					struct sockaddr_in6 *s;	
					s = (struct sockaddr_in6 *)&from_addr;
					ip_port = ntohs(s->sin6_port);
					inet_ntop(AF_INET6,&(s->sin6_addr),ip_name,256);	
				}
				logger(prefix,"New connection from: [%s:%d]\n",ip_name,ip_port);
				// Find slot :-)
				sem_lock(semid2);	
				for ( i = 0; i < MAX_CONNS; i++ ){
					if ( CSERVER.co[i].port == 0 ) break;
				}
				if ( i == MAX_CONNS ){ // We have to kick out the connection
					sem_unlock(semid2);	
					logger(prefix,"System-Limit reached (more than %d connections) --> closing connection\n",MAX_CONNS);
					close(newsock);
					continue;
				}
				CSERVER.co[i].sock      = newsock;
				CSERVER.co[i].port      = ip_port;
				CSERVER.co[i].created   = time(NULL);
				CSERVER.connections++;
				CSERVER.total_count++;
				if ( CSERVER.family == AF_INET ) {
					struct sockaddr_in _s;	
					struct sockaddr_in *s;	
					int s_len;
					s_len = sizeof(_s);
					getsockname(newsock,(struct sockaddr *)&_s,&s_len);
					s = (struct sockaddr_in *)&_s;
					ips_port = ntohs(s->sin_port);
					sprintf(ips_name,"%s",inet_ntoa(s->sin_addr));
				}
				if ( CSERVER.family == AF_INET6 ) {
					struct sockaddr_in6 _s;	
					struct sockaddr_in6 *s;	
					int s_len;
					s_len = sizeof(_s);
					getsockname(newsock,(struct sockaddr *)&_s,&s_len);
					s = (struct sockaddr_in6 *)&_s;
					ips_port = ntohs(s->sin6_port);
					inet_ntop(AF_INET6,&(s->sin6_addr),ips_name,256);	
				}
				strcpy(CSERVER.co[i].target,ips_name);
				CSERVER.co[i].t_port      = ips_port;
				strcpy(CSERVER.co[i].source,ip_name);
				sem_unlock(semid2);	
				pid = fork();
				if ( pid == 0 ){
					process_client(i);
					exit(0);
				} else {
					close(newsock);
					CSERVER.co[i].pid = pid;
				}
			} else {
				logger(prefix,"ACCEPT FAILED! (%s)\n",strerror(errno));
			}
			garbage_collect();
		}
		
	}

	exit(0);
}

void terminator(){
	int i,j;
	logger(prefix,"*** TERMINATOR Terminating all childs...\n");
	for ( i  = 0; i < entries; i++ ){
		for ( j = 0; j < MAX_CONNS; j++ ){
			if ( servlist[i].co[j].port != 0 && servlist[i].co[j].cpid != 0 ){ 
				m_kill(servlist[i].co[j].cpid,SIGTERM); 
				m_kill(servlist[i].co[j].cpid,SIGHUP); 
				m_kill(servlist[i].co[j].cpid,SIGKILL); 
				logger(prefix,"*** TERMINATOR Killed connection: [%s]:%d <--> [%s]:%d PID: %d\n",servlist[i].co[j].source,servlist[i].co[j].port, servlist[i].co[j].target, servlist[i].co[j].t_port, servlist[i].co[j].cpid);
				if ( servlist[i].co[j].pid != 0 ){
					m_kill(servlist[i].co[j].pid,SIGTERM); 
				}
			}
		}	
	}
	exit(0);
}


void main(int argc, char **argv){
        FILE *fp;
        char buf[1024];
	int idx;
	int i;
	int semmel;

	
	if ( gethostname(my_hostname,1024) < 0 )strcpy(my_hostname,"unknown");



	mkdir("/big/GIX_INETD/logs",00777);
	mkdir("/big/GIX_INETD/conf",00777);

	// Cleanup a little bit :-)
	for ( i = 0; i < 8192; i++ ){
		semmel = semget(INETD_KEY + i,1,0);
		if ( semmel >= 0 ) semctl(semmel,IPC_RMID,0);
		semmel = semget(INETD_KEY2 + i,1,0);
		if ( semmel >= 0 ) semctl(semmel,IPC_RMID,0);
		semmel = msgget(INETD_KEY + i,0);
		if ( semmel >= 0 ) msgctl(semmel,IPC_RMID,0);
	}
	semmel = shmget(INETD_KEY,0,0);
	if ( semmel >= 0 ) shmctl(semmel,IPC_RMID,0);

	semmel = shmget(INETD_OPTIONS,0,0);
	if ( semmel >= 0 ) shmctl(semmel,IPC_RMID,0);


	strcpy(prefix,"MAIN");

	logger(prefix,"Server starting at: [%s]\n",my_hostname);

	if_count = get_interfaces(&if_config);
	for ( i = 0; i < if_count; i++ ){
		logger(prefix,"[%d] [%s] --> [%s]\n",i,if_config[i].ethname,if_config[i].addr);
	}
	
	
	shmid_options = shmget(INETD_OPTIONS,sizeof(struct gix_inetd_options),0600|IPC_CREAT);
	if ( shmid_options < 0 ){
		logger(prefix,"FATAL(%s:%d) Cannot allocate shared-memory\n",__FILE__,__LINE__);
		exit(0);
	}
	gix_options = (struct gix_inetd_options *)shmat(shmid_options,NULL,0);
	if ( gix_options == NULL ){
		logger(prefix,"FATAL(%s:%d) Cannot attach shared-memory\n",__FILE__,__LINE__);
		exit(0);
	}


        fp = fopen(CONFIG_FILE,"r");
        if ( fp == NULL ){
                logger(prefix,"%s: Cannot open '%s'\n",argv[0],CONFIG_FILE);
                exit(2);
        }
        entries = 0;
        while ( fgets(buf,1024,fp) != NULL ){
		if ( buf[0] == '[' ) continue;
		if ( strlen(buf) < 4 || buf[0] == '#' || buf[0] == ';' ) continue;
                entries++;
        }
        rewind(fp);
	shm_id = shmget(INETD_KEY,0,0);
	if ( shm_id >= 0 ){
		shmctl(shm_id,IPC_RMID,0);
	}
	shm_id = shmget(INETD_KEY,sizeof(struct server) * (entries *2),0600|IPC_CREAT);
	if ( shm_id < 0 ){
		logger(prefix,"FATAL(%s:%d) Cannot allocate shared-memory\n",__FILE__,__LINE__);
		exit(0);
	}
	servlist = (struct server *)shmat(shm_id,NULL,0);
	if ( servlist == NULL ){
		logger(prefix,"FATAL(%s:%d) Cannot attach shared-memory\n",__FILE__,__LINE__);
		exit(0);
	}
	bzero((void *)servlist,sizeof(struct server) * entries * 2);
	bzero((void *)gix_options,sizeof(struct gix_inetd_options));
	idx = 0;
	while ( fgets(buf,1024,fp) != NULL ){
		int port;
		int max_conns;
		int timeout;
		int data_timeout;
		char *ptr;
		char cmdline[1024];

		if ( strncmp(buf,"[TFTP=yes]",strlen("[TFTP=yes]")) == 0 ){
			gix_options->tftp_enabled = 1;
			if ( strlen(gix_options->tftp_root) == 0 ){
				strcpy(gix_options->tftp_root,"/TFTP");
			}
			logger(prefix,"TFTP-->ENABLED\n");
			continue;
		}
		if ( strncmp(buf,"[TFTP_DIR=",strlen("[TFTP_DIR=")) == 0 ){
			char *ptr;
			strcpy(gix_options->tftp_root,&buf[strlen("[TFTP_DIR=")]);
			ptr = gix_options->tftp_root;
			while ( *ptr ){
				if ( *ptr == ']' ){ *ptr = '\0'; break; }
				ptr++;
			}	
		}
		if ( strncmp(buf,"[TFTPREADONLY=yes]",strlen("[TFTPREADONLY=yes]")) == 0 ){
			gix_options->tftp_readonly = 1;
			continue;
		}

		if ( strlen(buf) < 4 || buf[0] == '#' || buf[0] == ';' ) continue;
		port = atoi(buf);
		ptr = buf;
		while ( *ptr && *ptr != ' ' && *ptr != '\t' ) ptr++;
		if ( *ptr == '\0' ) continue;

		while ( *ptr && ( *ptr == ' ' ||  *ptr == '\t' ) ) ptr++;
		if ( *ptr == '\0' ) continue;
		max_conns = atoi(ptr);

		while ( *ptr && *ptr != ' ' && *ptr != '\t' ) ptr++;
		if ( *ptr == '\0' ) continue;

		while ( *ptr && ( *ptr == ' ' ||  *ptr == '\t' ) ) ptr++;
		if ( *ptr == '\0' ) continue;

		timeout = atoi(ptr);
		while ( *ptr && *ptr != ' ' && *ptr != '\t' ) ptr++;
		if ( *ptr == '\0' ) continue;

		while ( *ptr && ( *ptr == ' ' ||  *ptr == '\t' ) ) ptr++;
		if ( *ptr == '\0' ) continue;

		data_timeout = atoi(ptr);
		while ( *ptr && *ptr != ' ' && *ptr != '\t' ) ptr++;
		if ( *ptr == '\0' ) continue;
		while ( *ptr && ( *ptr == ' ' ||  *ptr == '\t' ) ) ptr++;
		if ( *ptr == '\0' ) continue;
		strcpy(cmdline,ptr);

		if ( strlen(cmdline) < 2 ) continue;
		if ( cmdline[strlen(cmdline)-1] == '\r' || cmdline[strlen(cmdline)-1] == '\n' ) cmdline[strlen(cmdline)-1] = '\0';
		if ( cmdline[strlen(cmdline)-1] == '\r' || cmdline[strlen(cmdline)-1] == '\n' ) cmdline[strlen(cmdline)-1] = '\0';
		if ( max_conns <= 0 ) max_conns = MAX_CONNS;
		logger("MAIN","[%d] Port: %d, Max-Connections: %d, Timeout: %d, Data-Timeout: %d, Command: [%s]\n",idx,port,max_conns,timeout,data_timeout,cmdline);
		servlist[idx].port = port;
		servlist[idx].max_conns = max_conns;			
		servlist[idx].timeout = timeout;			
		servlist[idx].data_timeout = data_timeout;			
		servlist[idx].family = AF_INET;
		servlist[idx].reset = time(NULL);
		strcpy(servlist[idx].cmdline,cmdline);
		idx++;
		servlist[idx].port = port;
		servlist[idx].max_conns = max_conns;			
		servlist[idx].timeout = timeout;			
		servlist[idx].data_timeout = data_timeout;			
		servlist[idx].family = AF_INET6;
		servlist[idx].reset = time(NULL);
		strcpy(servlist[idx].cmdline,cmdline);
		idx++;
	}
        fclose(fp);
	entries = idx;
        logger(prefix,"Starting servers with %d entries\n",entries);
	logger(prefix,"TFTP-Enabled: %d, TFTP-Root-PATH: [%s], TFTP-READONLY: %d\n",gix_options->tftp_enabled, gix_options->tftp_root, gix_options->tftp_readonly);
	signal(SIGCHLD,SIG_IGN);
	for ( i = 0; i < idx; i++ ){
		int pid;
		if ( (pid = fork()) == 0 ){
			start_server(i);
			exit(0);
		} else {
			servlist[i].pid = pid;
		}
	}
	signal(SIGTERM,terminator);
	while(1){ 
		sleep(1);
	}
}
