/* PureAdmin
* Copyright (C) 2003 Isak Savo
*
* 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.
*/
/*
* Logfile-functions incl. callbacks to manage the logfile-viewer
*
* Copyright (C) 2003 Isak Savo
*/
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <gtk/gtk.h>
#include <time.h>
#include <errno.h>
#include "globals.h"
#include "cfg.h"
#include "helper.h"
#include "gui_helper.h"
#include "logfile.h"
#include "famwrap.h"
FILE *logfile = NULL;
GtkWidget *logview = NULL;
GtkTextBuffer *viewbuffer = NULL;
GtkTextTag *logview_tags[NUM_LOGTAGS];
static gchar cur_logfile[FILEPATH_MAX];
#define LOG_BUF_LEN 1024
/* Appends a line to the logview. 'buf' must be valid UTF-8 */
static
void logview_append_line (const gchar *buf, log_textview_mode mode)
{
GtkTextIter iter;
static GtkTextMark *mark = NULL;
gtk_text_buffer_get_end_iter (viewbuffer, &iter);
gtk_text_buffer_insert_with_tags (viewbuffer, &iter, buf, -1, logview_tags[mode], NULL);
if (!mark)
mark = gtk_text_buffer_create_mark (viewbuffer, "last_line", &iter, FALSE);
else
gtk_text_buffer_move_mark (viewbuffer, mark, &iter);
gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (logview), mark,
0, TRUE, 0, 1);
}
static
log_textview_mode get_logline_mode (const gchar *line)
{
log_textview_mode mode = LOG_INFO;
if (strstr (line, "[NOTICE]"))
mode = LOG_NOTICE;
else if (strstr (line, "[WARNING]"))
mode = LOG_WARNING;
else if (strstr (line, "[ERROR]"))
mode = LOG_ERROR;
else if (strstr (line, "[DEBUG]"))
mode = LOG_DEBUG;
return mode;
}
/** GLOBAL FUNCTIONS **/
/* init_logfile: Initializes the logwindow
*
* Returns: TRUE if everything is setup correctly
* FALSE if something went wrong (or if FAM is disabled)
*/
gboolean init_logfile (void)
{
static GtkWidget *lbl = NULL;
PangoFontDescription *font_desc;
if (!logview)
{
logview = MW("logview");
if (!logview)
return FALSE;
font_desc = pango_font_description_new ();
pango_font_description_set_family_static (font_desc, "monospace");
gtk_widget_modify_font (logview, font_desc);
pango_font_description_free (font_desc);
viewbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (logview));
}
/* This shouldn't even be called when not defined, but let's check it anyway... */
#ifndef HAVE_LIBFAM
return FALSE;
#endif
if (!lbl)
lbl = MW("lbl_logfilename");
if (!logfile)
{
if (!(logfile = fopen (cfg.logfile, "r")))
{
pur_log_wrn ("Unable to open logfile %s: %s", cfg.logfile, strerror (errno));
log_display_error_text (2);
return FALSE;
}
/* We use a local copy of the filename, in case someone changes cfg.logfile, and we want to modify the FAM-watch */
strncpy (cur_logfile, cfg.logfile, FILEPATH_MAX);
}
if (!fam_set_watch (cfg.logfile, read_logfile))
{
close_logfile ();
log_display_error_text (3);
return FALSE;
}
gtk_label_set_text (GTK_LABEL (lbl), cur_logfile);
return TRUE;
}
/* close_logfile: Closes the logfile and removes any FAM watches
* that are open. Also frees all resources allocated.
*/
void close_logfile (void)
{
#ifndef HAVE_LIBFAM
return;
#endif
if (cur_logfile && *cur_logfile)
fam_delete_watch ();
if (logfile)
fclose (logfile);
logfile = NULL;
log_clear_logview ();
}
/* log_clear_logview: Removes all text in the logview
*
*/
void log_clear_logview (void)
{
if (viewbuffer)
gtk_text_buffer_set_text (viewbuffer, "", -1);
}
/* log_display_error_text: Display an errormessage explaining why
* logfile viewer has been disabled.
*
* Argument: reason:
* 0 ==> FAM isn't installed,
* 1 ==> FAM isn't running.
* 2 ==> Couldn't open the specified logfile
*/
void log_display_error_text (gint reason)
{
GtkWidget *btn, *lbl;
GtkTextIter iter;
gchar *err_msg = NULL;
if (!logview)
{
logview = MW("logview");
if (!logview)
return;
viewbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (logview));
}
pur_log_dbg ("Displaying logfile errortext, reason: %d", reason);
lbl = MW("lbl_logfilename");
gtk_label_set_text (GTK_LABEL (lbl), _("[Logfile viewer Disabled]"));
gtk_text_buffer_get_end_iter (viewbuffer, &iter);
switch (reason)
{
case 0:
err_msg = g_strdup (_("Logfile viewer has been disabled because FAM isn't installed on this computer. "
"If you want to use the logfile viewer you need to install FAM and then recompile PureAdmin\n\n"
"Check your distribution for appropriate packages or visit "
"http://oss.sgi.com/projects/fam/ for more info about FAM."));
break;
case 1:
err_msg = g_strdup (_("Logfile viewer has been disabled because PureAdmin couldn't connect to local FAM-service.\n"
"FAM is installed so it should be sufficient to either start FAM as a separate server or run it\n"
"from inetd (Internet Super Server) by adding an entry to /etc/inetd.conf.\n\n"
"Check your configuration for FAM if you want to use the logfile viewer."));
break;
case 2:
err_msg = g_strdup (_("Logfile viewer has been disable because PureAdmin could not open the specified logfile.\n"
"Make sure that you are running as a user that has permission to open the logfile."));
break;
case 3:
default:
err_msg = g_strdup (_("Logfile viewer has been disable because PureAdmin could not watch for changes to the logfile.\n"
"Make sure that you are running as a user that has permission to access the logfile."));
break;
}
gtk_text_buffer_insert_with_tags (viewbuffer, &iter, err_msg, -1, logview_tags[LOG_ERROR], NULL);
g_free (err_msg);
btn = MW("btn_logview_clear");
gtk_widget_set_sensitive (btn, FALSE);
btn = MW("btn_logview_reread");
gtk_widget_set_sensitive (btn, FALSE);
}
/* read_logfile: Reads the newly added contents of the logfile
*/
void read_logfile (void)
{
gchar buf[LOG_BUF_LEN];
gint mode = 0;
gchar *utf8_str;
if (!logfile)
init_logfile ();
pur_log_dbg ("Reading logfile");
if (fseek (logfile, 0, SEEK_CUR) != 0)
/* To clear an invalid EOF indicator for the stream, and to verify that
there is new data to be read...*/
return;
while (!feof (logfile))
{
memset (buf, '\0', LOG_BUF_LEN);
fgets (buf, LOG_BUF_LEN, logfile);
if (misc_str_is_only_whitespace (buf))
continue;
utf8_str = NULL;
if (cfg.logmethod == LOG_SYSLOG && strstr (buf, "pure-ftpd:"))
{
utf8_str = string_to_utf8 (buf);
mode = get_logline_mode (buf);
/* Eventually filter old log-messages */
logview_append_line (utf8_str, mode);
}
else if (cfg.logmethod == LOG_CUSTOM)
{
utf8_str = string_to_utf8 (buf);
logview_append_line (utf8_str, LOG_INFO);
}
g_free (utf8_str);
}
}
syntax highlighted by Code2HTML, v. 0.9.1