/*
 * GProFTPD - A GTK+ frontend for the ProFTPD standalone server.
 * Copyright (C) 2001 - 2006 Magnus Loef (Magnus-swe) <magnus-swe@telia.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
 *
 */


#include "../config.h"
#include <gtk/gtk.h>
#include "support.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "allocate.h"
#include "widgets.h"
#include <dirent.h>
#include "chars_are_digits.h"
#include "commands.h"
#include "status_update.h"
#include "show_info.h"

extern int activated;
extern int MAX_READ_POPEN;



char * get_process_pid(char process[1024], char extmatch[1024])
{
    FILE *fp;
    long num, file_size = 4000;
    char *line, *sub_proc_path, *pid;
    int x=0;
    struct dirent **namelist;

    pid = allocate(1024);
    strcpy(pid, "0");
    
    sub_proc_path = allocate(1024);

    num = scandir(PROC_PATH, &namelist, 0, alphasort);
    if( num < 0 )
    {
        perror("scandir");
        return pid;
    }
    else
    {
        /* List all directories in PROC_PATH */
        for(x=0; x<num; x++)
        {
	    /* Now list PROC_PATH/24207/cmdline */
	    snprintf(sub_proc_path, 1000, "%s/%s/cmdline", PROC_PATH, namelist[x]->d_name);

	    if((fp=fopen(sub_proc_path, "r"))==NULL)
	    {
        	free(namelist[x]);
	        continue;
	    }
	    line = allocate(file_size+1);
	    
	    if( file_size > 1 )
	    while(fgets(line, file_size, fp)!=NULL)
	    {
		/* If the following strings are detected in this file its running */
		if( strstr(line, process) && strstr(line, extmatch) )
		{
		    snprintf(pid, 1000, "%s", namelist[x]->d_name);
		    break;
		}
	    }
	    fclose(fp);
	    free(line);
            free(namelist[x]);
	}
    }
    free(namelist);
    free(sub_proc_path);

    return pid;
}



int status_update(struct w *widgets)
{
    /* Status update for ftpwho, total transfer rates and activated/deactivated status. */
    FILE *fp;
    GtkTextBuffer *transfer_textbuffer;
    GtkTextMark *mark;
    gchar *mark_name=NULL;
    GtkTextIter transfer_iter;
    long in_val=0, out_val=0, inxfer=0, outxfer=0, totalxfer=0;
    int incoming=0, outgoing=0;
    char *read_buffer, *get_buffer;
    gchar *info, *path, *cmd, *utf8=NULL;

    char *pid;
    pid = get_process_pid("proftpd", "accepting connections");

    if( ! strcmp(pid, "0") )
    {
	activated = 0;
	info = g_strdup_printf(_("Status: Deactivated"));
	utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
	gtk_label_set_text(GTK_LABEL(widgets->status_label), utf8);
	g_free(info);

	/* Show non ftp usage */    
        info = g_strdup_printf(_("The server is deactivated.\n"));
	utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
	transfer_textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widgets->transfer_textview));
	gtk_text_buffer_set_text(transfer_textbuffer, utf8, strlen(utf8));
	g_free(info);
	return (TRUE);
    }
    else
      {
	  activated = 1;
	  /* printf("Proftpd is running as pid: %s\n", pid); */
	  info = g_strdup_printf(_("Status: Activated"));
    	  utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
    	  gtk_label_set_text(GTK_LABEL(widgets->status_label), utf8);
	  g_free(info);
      }
    free(pid);



    /* The server is activated, insert ftpwho information in the textview */
    get_buffer = allocate(MAX_READ_POPEN+1);
    
    /* Add the scoreboard file if its missing to avoid useless message */
    path = g_strdup_printf("%s/%s", GP_VARDIR, "run/proftpd");
    if( file_exists(path) )
    {
        g_free(path);

	path = g_strdup_printf("%s/%s", GP_VARDIR, "run/proftpd/proftpd.scoreboard");
        if( ! file_exists(path) )
        {
            cmd = g_strdup_printf("echo \"NOTHING\" > %s/%s", GP_VARDIR, "run/proftpd/proftpd.scoreboard");
            run_command(cmd);
            g_free(cmd);
        }
    }
    g_free(path);

    /* Again in another common location */
    path = g_strdup_printf("%s/%s", GP_VARDIR, "proftpd");
    if( file_exists(path) )
    {
        g_free(path);

        path = g_strdup_printf("%s/%s", GP_VARDIR, "proftpd/proftpd.scoreboard");
        if( ! file_exists(path) )
        {
            cmd = g_strdup_printf("echo \"NOTHING\" > %s/%s", GP_VARDIR, "proftpd/proftpd.scoreboard");
            run_command(cmd);
            g_free(cmd);
        }
    }
    g_free(path);



    /* FTP who update and total xferrates */
    cmd = g_strdup_printf("%s -v", FTPWHO_BINARY);
    if((fp=popen(cmd, "r"))==NULL)
    {
        g_free(cmd);

	/* Show ftpwho error information in the textview */    
        info = g_strdup_printf(_("Error running ftpwho -v.\n"));
	utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
	transfer_textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widgets->transfer_textview));
	gtk_text_buffer_set_text(transfer_textbuffer, utf8, strlen(utf8));
	g_free(info);
        return(TRUE);
    }
    g_free(cmd);
    fflush(fp);

    read_buffer = allocate(MAX_READ_POPEN+1);
    while(fgets(read_buffer, MAX_READ_POPEN, fp)!=NULL)
    {	
        strcat(get_buffer, read_buffer);
        /* Total Xferrates incoming/outgoing/total bandwidth usage */
        /* Assumes that the ftpwho output shows stor retr appe and on the next line KB/s */
		
        /* Incoming transfers */
        if( strstr(read_buffer, "KB/s: ") && incoming == 1 
        && ! strstr(read_buffer, "inf") && ! strstr(read_buffer, "nan") )
        {
	    if( chars_are_digits(&read_buffer[7]) )
	      sscanf(read_buffer, "%*s %li", &in_val);

	    if( in_val > 0 )
	    {
		inxfer = inxfer+in_val;
		totalxfer = totalxfer+in_val;
	    }
	}

	if( strstr(read_buffer, " STOR ") || strstr(read_buffer, " STOU ")
	|| strstr(read_buffer, " APPE ") )
	  incoming++;
	else
	  incoming = 0;
	
	/* Outgoing transfers */
	if( strstr(read_buffer, "KB/s: ") && outgoing == 1 
	&& ! strstr(read_buffer, "inf") && ! strstr(read_buffer, "nan") )
	{
	    if( chars_are_digits(&read_buffer[7]) )
	      sscanf(read_buffer, "%*s %li", &out_val);

	    if( out_val > 0 )
	    {
	        outxfer = outxfer+out_val;
	        totalxfer = totalxfer+out_val;
	    }
	}

	if( strstr(read_buffer, " RETR ") )
	  outgoing++;
	else
	  outgoing = 0;
    }
    pclose(fp);
    free(read_buffer);

    
    /* Total bandwidth usage */
    if( totalxfer >= 0 )
    {
	info = g_strdup_printf("%li %s", totalxfer, "KB/s");
        utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
	gtk_entry_set_text(GTK_ENTRY(widgets->total_bandwidth_entry), utf8);
	g_free(info);
    }

    /* Total incoming xfers */
    if( inxfer >= 0 )
    {    
        info = g_strdup_printf("%li %s", inxfer, "KB/s");
        utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
        gtk_entry_set_text(GTK_ENTRY(widgets->total_incoming_entry), utf8);
        g_free(info);
    }

    /* Total outgoing xfers */
    if( outxfer >= 0 )
    {
        info = g_strdup_printf("%li %s", outxfer, "KB/s");
        utf8 = g_locale_to_utf8(info, strlen(info), NULL, NULL, NULL);
        gtk_entry_set_text(GTK_ENTRY(widgets->total_outgoing_entry), utf8);
	g_free(info);
    }


    /* Show ftp usage in the textview */
    utf8 = g_locale_to_utf8(get_buffer, strlen(get_buffer), NULL, NULL, NULL);
    free(get_buffer);

    transfer_textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widgets->transfer_textview));
    gtk_text_buffer_set_text(transfer_textbuffer, utf8, strlen(utf8));
    /* Get the start iter from the buffer */
    gtk_text_buffer_get_start_iter(GTK_TEXT_BUFFER(transfer_textbuffer), &transfer_iter);
    /* Create a mark at the start of the buffer specified by xfer_iter */
    mark = gtk_text_buffer_create_mark(GTK_TEXT_BUFFER(transfer_textbuffer), mark_name, &transfer_iter, FALSE);
    /* Move the mark on screen then scroll to it */
    gtk_text_view_move_mark_onscreen(GTK_TEXT_VIEW(widgets->transfer_textview), mark);
    gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(widgets->transfer_textview), mark, 0.4, TRUE, 0.0, 0.0);
    gtk_text_buffer_delete_mark(GTK_TEXT_BUFFER(transfer_textbuffer), mark);

    if( utf8!=NULL )
      g_free(utf8);

    return(TRUE);
}
