/* * GProFTPD - A GTK+ frontend for the ProFTPD standalone server. * Copyright (C) 2001 - 2006 Magnus Loef (Magnus-swe) * * 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 #include "support.h" #include #include #include #include #include "allocate.h" #include "widgets.h" #include #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; xd_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); }