/*
* 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);
}
syntax highlighted by Code2HTML, v. 0.9.1