log_tree_mon.c
#define _GNU_SOURCE 1
#define VSTR_COMPILE_INCLUDE 1
#include <vstr.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/time.h>
#include <time.h>
#define LTM_DEBUG 0
#define LTM_CONF_ADD_ENTERIES_PER_LOOP 250
#define FALSE 0
#define TRUE 1
#define LTM_INDENT_ON_TYPE_DEF LTM_INDENT_ON_TYPE_REQ
#define LTM_INDENT_ON_TYPE_USR 1
#define LTM_INDENT_ON_TYPE_MAIN_USR 2
#define LTM_INDENT_ON_TYPE_FRM 3
#define LTM_INDENT_ON_TYPE_REF 4
#define LTM_INDENT_ON_TYPE_MAIN_REF 5
#define LTM_INDENT_ON_TYPE_REQ 6
#define LTM_INDENT_ON_TYPE_MAIN_REQ 7
#define LTM_INDENT_ON_TYPE_RET 8
#define LTM_INDENT_ON_TYPE_FRM_GROUP 9
#define LTM_INDENT_ON_TYPE_ALL 10
#define LTM_INDENT_ON_TYPE_LAST 11
#define LTM_INDENT_ON_TYPE_END 0
#define LTM_INDENT_ON_NUM 12
#define LTM_INDENT_ON_SZ 6
static unsigned int ltm_conf_indent_on_type[LTM_INDENT_ON_SZ] =
{
LTM_INDENT_ON_TYPE_DEF,
LTM_INDENT_ON_TYPE_END,
LTM_INDENT_ON_TYPE_END,
LTM_INDENT_ON_TYPE_END,
LTM_INDENT_ON_TYPE_END,
LTM_INDENT_ON_TYPE_END,
};
static const char *ltm_conf_indent_name_map[LTM_INDENT_ON_NUM] = {
"",
"User Agent",
"User Agent, ignoring versions",
"From IP address",
"Referrer URL",
"Referrer URL, group on certain hosts",
"Request",
"Request, group certain requests",
"Return Code",
"Group clients",
"All",
};
typedef struct Ltm_vstr_pt
{
Vstr_base *vs;
size_t pos;
size_t len;
unsigned int h_val;
} Ltm_vstr_pt;
static struct
{
const char *name;
Ltm_vstr_pt pt;
unsigned int sect_num;
} ltm_readables[] =
{
#define LTM_READABLE_VAL_ALL 0
{ "All", {NULL,0,0,0},0},
#define LTM_READABLE_VAL_OTHER 1
{ "Other", {NULL,0,0,0},0},
#define LTM_READABLE_VAL_AND_ORG 2
{ "And.org", {NULL,0,0,0},0},
#define LTM_READABLE_VAL_LAST 3
{ "-- LAST --", {NULL,0,0,0},0},
{ "groups.google", {NULL,0,0,0},0},
{ "google", {NULL,0,0,0},0},
{ "search.yahoo.com", {NULL,0,0,0},0},
{ "altavista.com", {NULL,0,0,0},0},
{ "msn", {NULL,0,0,0},0},
{ "mysearch.com", {NULL,0,0,0},0},
{ "search.aol.com", {NULL,0,0,0},0},
{ "search.netscape.com", {NULL,0,0,0},0},
{ "hotbot.com", {NULL,0,0,0},0},
{ "search.com", {NULL,0,0,0},0},
{ "ask", {NULL,0,0,0},0},
{ "alltheweb.com", {NULL,0,0,0},0},
{ "and.org/vstr", {NULL,0,0,0},0},
{ "and.org/pictures", {NULL,0,0,0},0},
{ "and.org", {NULL,0,0,0},0},
{ "www.and.org", {NULL,0,0,0},0},
{ "http://www.and.org", {NULL,0,0,0},0},
{ "http://and.org", {NULL,0,0,0},0},
{ "crazylands.org", {NULL,0,0,0},0},
{ "freshmeat", {NULL,0,0,0},0},
{ "gnu.org/directory", {NULL,0,0,0},0},
{ "gnu.org/search", {NULL,0,0,0},0},
{ "sourceforge.net", {NULL,0,0,0},0},
{ "sf.net", {NULL,0,0,0},0},
{ "cuj.com", {NULL,0,0,0},0},
{ "slashdot.org", {NULL,0,0,0},0},
{ "news", {NULL,0,0,0},0},
{ "nntp", {NULL,0,0,0},0},
{ "Scooter", {NULL,0,0,0},0},
{ "Googlebot", {NULL,0,0,0},0},
{ "ia_archiver", {NULL,0,0,0},0},
{ "FAST-WebCrawler", {NULL,0,0,0},0},
{ "webcollage", {NULL,0,0,0},0},
{ "WebFilter", {NULL,0,0,0},0},
{ "fmII", {NULL,0,0,0},0},
{ "Dillo", {NULL,0,0,0},0},
{ "sitecheck.internetseer.com", {NULL,0,0,0},0},
{ "NPBot", {NULL,0,0,0},0},
{ "Slurp", {NULL,0,0,0},0},
{ "Wget", {NULL,0,0,0},0},
{ "curl", {NULL,0,0,0},0},
{ "gURLChecker", {NULL,0,0,0},0},
{ "almaden.ibm.com/cs/crawler", {NULL,0,0,0},0},
{ "/pictures/People/img_thumb", {NULL,0,0,0},0},
{ "/pictures/Animals/img_thumb", {NULL,0,0,0},0},
{ "/pictures/House/img_thumb", {NULL,0,0,0},0},
{ "/pictures/Snow/img_thumb", {NULL,0,0,0},0},
{ "/pictures/Quilts/img_thumb", {NULL,0,0,0},0},
{ "/pictures/Ridge%20Hill%20Road/img_thumb", {NULL,0,0,0},0},
{ "/pictures/Garlic%20Festival%202003/img_thumb", {NULL,0,0,0},0},
{ "/icons", {NULL,0,0,0},0},
{ NULL, {NULL,0,0,0},0},
};
#include <gtk/gtk.h>
struct Ltm_file_data
{
Vstr_base *io_r;
size_t pos;
size_t len;
size_t unparsed_len;
Vstr_sects *sects;
unsigned int skip_num;
unsigned int parsed_num;
unsigned int unknown_lines;
unsigned int idle_id;
Vstr_base *t1;
GHashTable *h_iter;
GtkTreeView *view;
GtkTreeStore *store;
GtkWidget *label;
};
#define F_DATA_DECL(x, y) x y = f_data-> y
struct Ltm_hash_data
{
GtkTreeIter parent_iter;
int sz;
int req_num;
GHashTable *h_next_iter;
};
static GHashTable *ltm_readable_strings = NULL;
#define LTM_SET_PARENT_SECTION_READABLE(x) do { \
unsigned int *ltm__local_num = g_hash_table_lookup(ltm_readable_strings, pt); \
\
if (!ltm__local_num) { \
fprintf(stderr, "Not found readable string: %s\n", \
vstr_export_cstr_ptr(pt->vs, pt->pos, pt->len)); \
break; } \
\
ltm_parent_sect_typ = (x); \
ltm_parent_sect_num = *ltm__local_num; \
} while (FALSE)
#define LTM_IS_PARENT_SECTION_READABLE(x) \
(((ltm_parent_sect_typ == (x)) || \
(ltm_parent_sect_typ == LTM_INDENT_ON_TYPE_ALL)) && ltm_parent_sect_num)
static int ltm_skip_chr(Vstr_base *io_r, size_t *pos, size_t *len, char chr)
{
if (vstr_export_chr(io_r, *pos) != chr)
return (FALSE);
*pos += 1;
*len -= 1;
return (TRUE);
}
static int ltm_add_sect_term_chr(Vstr_sects *sects,
Vstr_base *io_r, size_t *pos, size_t *len,
char chr)
{
size_t tmp = vstr_srch_chr_fwd(io_r, *pos, *len, chr);
if (!tmp)
return (FALSE);
vstr_sects_add(sects, *pos, tmp - *pos);
*len -= vstr_sc_posdiff(*pos, tmp);
*pos = tmp + 1;
return (TRUE);
}
static int ltm_add_sect_between_chrs(Vstr_sects *sects,
Vstr_base *io_r, size_t *pos, size_t *len,
char beg_chr, char end_chr, char skip_chr)
{
char buf[2];
size_t tmp = 0;
if (!ltm_skip_chr(io_r, pos, len, beg_chr))
return (FALSE);
buf[0] = end_chr;
buf[1] = skip_chr;
tmp = vstr_srch_buf_fwd(io_r, *pos, *len, buf, 2);
if (!tmp)
return (FALSE);
vstr_sects_add(sects, *pos, tmp - *pos);
*len -= vstr_sc_posdiff(*pos, tmp) + 1;
*pos = tmp + 2;
return (TRUE);
}
guint ltm_hash_gen(gconstpointer passed_pt)
{
Ltm_vstr_pt *pt = (void *)passed_pt;
Vstr_iter iter[1];
guint h = 0;
if (!pt->len) return (0);
if (pt->h_val)
return (pt->h_val);
if (!vstr_iter_fwd_beg(pt->vs, pt->pos, pt->len, iter))
g_assert_not_reached();
do
{
while (iter->len--)
{
guint val = *iter->ptr;
if ((val >= 'A') && (val <= 'Z'))
val += ('a' - 'A');
h = (h << 5) - h + val;
iter->ptr++;
}
} while (vstr_iter_fwd_nxt(iter));
pt->h_val = h;
return (h);
}
gboolean ltm_hash_eq(gconstpointer passed_pt1, gconstpointer passed_pt2)
{
const Ltm_vstr_pt *pt1 = passed_pt1;
const Ltm_vstr_pt *pt2 = passed_pt2;
return (vstr_cmp_case_eq(pt1->vs, pt1->pos, pt1->len,
pt2->vs, pt2->pos, pt2->len));
}
#define LTM_GTK_COL_T_USR 0
#define LTM_GTK_COL_T_DAT 1
#define LTM_GTK_COL_T_FRM 2
#define LTM_GTK_COL_T_SIZ 3
#define LTM_GTK_COL_T_REQ 4
#define LTM_GTK_COL_T_REF 5
#define LTM_GTK_COL_T_NUM 6
#define LTM_GTK_COL_T_CNT 7
#define LTM_GTK_COL_T_RET 8
#define LTM_GTK_COL_SZ 9
static void ltm_cell_render_int(GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
guint t_off, Vstr_base *t1)
{
const char *ptr = NULL;
int info = 0;
size_t tmp = t1->len;
gtk_tree_model_get(model, iter, t_off, &info, -1);
vstr_add_fmt(t1, tmp, "%'u", (unsigned int)info);
ptr = vstr_export_cstr_ptr(t1, tmp + 1, vstr_sc_posdiff(tmp + 1, t1->len));
g_object_set(GTK_CELL_RENDERER (cell), "text", ptr, NULL);
if (t1->len > (1024 * 4)) vstr_del(t1, 1, t1->len / 2);
}
static void ltm_cell_render_sect(GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
guint t_off, struct Ltm_file_data *f_data)
{
F_DATA_DECL(Vstr_base *, io_r);
F_DATA_DECL(Vstr_sects *, sects);
const char *ptr = NULL;
int info = 0;
gtk_tree_model_get(model, iter, t_off, &info, -1);
ptr = vstr_export_cstr_ptr(io_r,
VSTR_SECTS_NUM(sects, info)->pos,
VSTR_SECTS_NUM(sects, info)->len);
g_object_set(GTK_CELL_RENDERER (cell), "text", ptr, NULL);
}
static void ltm_cell_render_siz(GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
guint t_off, Vstr_base *t1)
{
const char *ptr = NULL;
int info = 0;
size_t tmp = t1->len;
gtk_tree_model_get(model, iter, t_off, &info, -1);
vstr_add_fmt(t1, tmp, "${BKMG.u:%u}", (unsigned int)info);
ptr = vstr_export_cstr_ptr(t1, tmp + 1, vstr_sc_posdiff(tmp + 1, t1->len));
g_object_set(GTK_CELL_RENDERER (cell), "text", ptr, NULL);
if (t1->len > (1024 * 4)) vstr_del(t1, 1, t1->len / 2);
}
static void ltm_cell_render_time(GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
guint t_off, Vstr_base *t1)
{
const char *ptr = NULL;
time_t *info = NULL;
size_t tmp = t1->len;
time_t now = time(NULL);
struct tm real_now_tm;
struct tm *now_tm = localtime(&now);
struct tm *info_tm = NULL;
gtk_tree_model_get(model, iter, t_off, &info, -1);
real_now_tm = *now_tm;
now_tm = &real_now_tm;
info_tm = localtime(info);
if ((now_tm->tm_year == info_tm->tm_year) &&
(now_tm->tm_mon == info_tm->tm_mon) &&
(now_tm->tm_mday == info_tm->tm_mday))
vstr_add_fmt(t1, t1->len, "Today %02u:%02u:%02u",
info_tm->tm_hour, info_tm->tm_min, info_tm->tm_sec);
else if (difftime(now, *info) < 0)
{
if (difftime(*info, now) < (60 * 60 * 18))
vstr_add_fmt(t1, t1->len, "Tomorrow %02u:%02u:%02u",
info_tm->tm_hour, info_tm->tm_min, info_tm->tm_sec);
else
vstr_add_fmt(t1, t1->len, "%04u-%02u-%02u %02u:%02u:%02u",
info_tm->tm_year + 1900,
info_tm->tm_mon + 1, info_tm->tm_mday,
info_tm->tm_hour, info_tm->tm_min, info_tm->tm_sec);
}
else if (difftime(now, *info) < (60 * 60 * 18))
vstr_add_fmt(t1, t1->len, "Yesterday %02u:%02u:%02u",
info_tm->tm_hour, info_tm->tm_min, info_tm->tm_sec);
else if (difftime(now, *info) < (60 * 60 * 24 * 4))
{
char day_buf[1024];
strftime(day_buf, sizeof(day_buf), "%A", info_tm);
vstr_add_fmt(t1, t1->len, "%s %02u:%02u:%02u",
day_buf,
info_tm->tm_hour, info_tm->tm_min, info_tm->tm_sec);
}
else
vstr_add_fmt(t1, t1->len, "%04u-%02u-%02u %02u:%02u:%02u",
info_tm->tm_year + 1900, info_tm->tm_mon + 1, info_tm->tm_mday,
info_tm->tm_hour, info_tm->tm_min, info_tm->tm_sec);
ptr = vstr_export_cstr_ptr(t1, tmp + 1, vstr_sc_posdiff(tmp + 1, t1->len));
g_object_set(GTK_CELL_RENDERER (cell), "text", ptr, NULL);
if (t1->len > (1024 * 4)) vstr_del(t1, 1, t1->len / 2);
}
static void __attribute__((unused)) ltm_cell_num(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_int(cell, model, iter, LTM_GTK_COL_T_NUM, data);
}
static void ltm_cell_cnt(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_int(cell, model, iter, LTM_GTK_COL_T_CNT, data);
}
static void ltm_cell_ret(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_int(cell, model, iter, LTM_GTK_COL_T_RET, data);
}
static void ltm_cell_usr(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_sect(cell, model, iter, LTM_GTK_COL_T_USR, data);
}
static void ltm_cell_dat(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_time(cell, model, iter, LTM_GTK_COL_T_DAT, data);
}
static void ltm_cell_siz(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_siz(cell, model, iter, LTM_GTK_COL_T_SIZ, data);
}
static void ltm_cell_frm(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_sect(cell, model, iter, LTM_GTK_COL_T_FRM, data);
}
static void ltm_cell_req(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_sect(cell, model, iter, LTM_GTK_COL_T_REQ, data);
}
static void ltm_cell_ref(GtkTreeViewColumn *tree_column __attribute__((unused)),
GtkCellRenderer *cell,
GtkTreeModel *model,
GtkTreeIter *iter,
gpointer data)
{
ltm_cell_render_sect(cell, model, iter, LTM_GTK_COL_T_REF, data);
}
static gint ltm_cmp_dat(GtkTreeModel *model,
GtkTreeIter *iter_a,
GtkTreeIter *iter_b,
gpointer user_data __attribute__((unused)))
{
time_t *a = NULL;
time_t *b = NULL;
gtk_tree_model_get(model, iter_a, LTM_GTK_COL_T_DAT, &a, -1);
gtk_tree_model_get(model, iter_b, LTM_GTK_COL_T_DAT, &b, -1);
if (!a && !b)
return (0);
if (!b)
return (1);
if (!a)
return (-1);
return (difftime(*a, *b));
}
static void ltm_trans_ptr_str(const GValue *src_value __attribute__((unused)),
GValue *dest_value)
{
g_value_set_static_string(dest_value, "");
}
static void ltm_hash_data_free(void *ptr)
{
struct Ltm_hash_data *h_vals = ptr;
if (h_vals->h_next_iter)
g_hash_table_destroy(h_vals->h_next_iter);
g_free(h_vals);
}
static void ltm_gtk_list(Vstr_base *io_r, struct Ltm_file_data *f_data)
{
GtkTreeStore *store;
GtkWidget *treeview;
int dum_argc = 1;
char *dum_argv1[] = { "abcd", NULL };
char **dum_argv = &dum_argv1[0];
Vstr_base *t1 = NULL;
f_data->t1 = t1 = vstr_make_base(io_r->conf);
ltm_readable_strings = g_hash_table_new_full(ltm_hash_gen, ltm_hash_eq,
(GDestroyNotify)vstr_ref_cb_free_nothing,
(GDestroyNotify)vstr_ref_cb_free_nothing);
{
unsigned int scan = 0;
while (ltm_readables[scan].name)
{
Ltm_vstr_pt *pt = <m_readables[scan].pt;
unsigned int *sect_num = <m_readables[scan].sect_num;
size_t len = strlen(ltm_readables[scan].name);
size_t pos = io_r->len + 1;
vstr_add_ptr(io_r, pos - 1, ltm_readables[scan].name, len);
vstr_sects_add(f_data->sects, pos, len);
*sect_num = f_data->sects->num;
pt->vs = io_r;
pt->pos = pos;
pt->len = len;
g_hash_table_insert(ltm_readable_strings, pt, sect_num);
++scan;
}
f_data->skip_num += scan;
f_data->parsed_num += scan;
f_data->pos = io_r->len + 1;
f_data->len = 0;
}
gtk_init(&dum_argc, &dum_argv);
g_value_register_transform_func(G_TYPE_POINTER, G_TYPE_STRING,
ltm_trans_ptr_str);
f_data->h_iter = g_hash_table_new_full(ltm_hash_gen, ltm_hash_eq,
g_free, ltm_hash_data_free);
store = gtk_tree_store_new(LTM_GTK_COL_SZ,
G_TYPE_UINT,
G_TYPE_POINTER,
G_TYPE_UINT,
G_TYPE_UINT,
G_TYPE_UINT,
G_TYPE_UINT,
G_TYPE_UINT,
G_TYPE_UINT,
G_TYPE_UINT);
gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(store), LTM_GTK_COL_T_DAT,
ltm_cmp_dat, NULL, NULL);
f_data->store = store;
treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
f_data->view = GTK_TREE_VIEW(treeview);
gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(treeview), TRUE);
gtk_tree_view_set_reorderable(GTK_TREE_VIEW(treeview), TRUE);
gtk_tree_view_set_search_column(GTK_TREE_VIEW(treeview),
LTM_GTK_COL_T_REQ);
g_object_unref(G_OBJECT(store));
{
GtkCellRenderer *renderer;
GtkTreeViewColumn *column = NULL;
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Count",
renderer,
"text", LTM_GTK_COL_T_CNT,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_cnt, t1, NULL);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_CNT);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Return Code",
renderer,
"text", LTM_GTK_COL_T_RET,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_ret, t1, NULL);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_RET);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("User-agent",
renderer,
"text", LTM_GTK_COL_T_USR,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_usr, f_data, NULL);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_USR);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Date",
renderer,
"text",
LTM_GTK_COL_T_DAT,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_dat, t1, NULL);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_DAT);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("From IP",
renderer,
"text",
LTM_GTK_COL_T_FRM,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_frm, f_data, NULL);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_FRM);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Size",
renderer,
"text",
LTM_GTK_COL_T_SIZ,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_siz, t1, NULL);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_SIZ);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Request",
renderer,
"text",
LTM_GTK_COL_T_REQ,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_req, f_data, NULL);
gtk_tree_view_column_set_resizable(column, TRUE);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_REQ);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
renderer = gtk_cell_renderer_text_new();
column = gtk_tree_view_column_new_with_attributes("Referrer",
renderer,
"text",
LTM_GTK_COL_T_REF,
NULL);
gtk_tree_view_column_set_cell_data_func(column, renderer,
ltm_cell_ref, f_data, NULL);
gtk_tree_view_column_set_sort_column_id(column, LTM_GTK_COL_T_REF);
gtk_tree_view_append_column(GTK_TREE_VIEW(treeview), column);
}
{
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *sw;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
{
size_t tmp = t1->len;
const char *ptr = NULL;
int scan = 0;
vstr_add_fmt(t1, t1->len, "Log tree monitor: %s",
ltm_conf_indent_name_map[ltm_conf_indent_on_type[0]]);
++scan;
while (ltm_conf_indent_on_type[scan] && (scan < LTM_INDENT_ON_SZ))
{
vstr_add_fmt(t1, t1->len, ", %s",
ltm_conf_indent_name_map[ltm_conf_indent_on_type[scan]]);
++scan;
}
ptr = vstr_export_cstr_ptr(t1,
tmp + 1, vstr_sc_posdiff(tmp + 1, t1->len));
gtk_window_set_title(GTK_WINDOW(window), ptr);
}
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
vbox = gtk_vbox_new(FALSE, 8);
gtk_container_add(GTK_CONTAINER(window), vbox);
f_data->label = gtk_label_new("");
gtk_box_pack_start(GTK_BOX(vbox), f_data->label, FALSE, FALSE, 0);
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(sw),
GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
GTK_POLICY_AUTOMATIC,
GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(sw), treeview);
gtk_window_set_default_size(GTK_WINDOW(window), 280, 250);
gtk_widget_show_all(window);
}
vstr_del(t1, 1, t1->len);
gtk_main();
g_hash_table_destroy(f_data->h_iter);
vstr_del(io_r, 1, io_r->len);
vstr_free_base(t1);
}
#define BEG_MATCH(x) \
(vstr_cmp_bod_cstr_eq(io_r, VSTR_SECTS_NUM(sects, sects->num)->pos, \
VSTR_SECTS_NUM(sects, sects->num)->len, (x)) && \
(VSTR_SECTS_NUM(sects, sects->num)->len >= strlen(x)))
#define BEG_SKIP(x) do { \
VSTR_SECTS_NUM(sects, sects->num)->pos += strlen(x); \
VSTR_SECTS_NUM(sects, sects->num)->len -= strlen(x); \
} while (FALSE)
#define END_MATCH(x) \
(vstr_cmp_eod_cstr_eq(io_r, VSTR_SECTS_NUM(sects, sects->num)->pos, \
VSTR_SECTS_NUM(sects, sects->num)->len, (x)) && \
(VSTR_SECTS_NUM(sects, sects->num)->len >= strlen(x)))
#define END_SKIP(x) do { \
VSTR_SECTS_NUM(sects, sects->num)->len -= strlen(x); \
} while (FALSE)
#define TST_SET_REF(x, y, z) \
else if ((tmp = vstr_srch_case_cstr_buf_fwd(io_r, pt->pos, pt->len, (x)))) \
do { \
pt->pos = tmp + (y); \
if ((z) > 0) pt->len = (z); \
else if ((z) < 0) pt->len = (strlen(x) - (y)) + (z); \
else pt->len = strlen(x) - (y); \
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_REF); \
} while (FALSE)
#define TST_BEG_SET_REF(x, y, z) \
else if ((tmp = vstr_srch_case_cstr_buf_fwd(io_r, pt->pos, pt->len, (x))) && \
(tmp == pt->pos)) \
do { \
pt->pos = tmp + (y); \
if ((z) > 0) pt->len = (z); \
else if ((z) < 0) pt->len = (strlen(x) - (y)) + (z); \
else pt->len = strlen(x) - (y); \
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_REF); \
} while (FALSE)
#define TST_SET_REQ(x, y, z) \
else if ((tmp = vstr_srch_case_cstr_buf_fwd(io_r, pt->pos, pt->len, (x)))) \
do { \
pt->pos = tmp + (y); \
if ((z) > 0) pt->len = (z); \
else if ((z) < 0) pt->len = (strlen(x) - (y)) + (z); \
else pt->len = strlen(x) - (y); \
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_REQ); \
} while (FALSE)
#define LTM_DISPLAY_ITER_DATA() \
(!h_iter && (ltm_conf_indent_on_type[scan] != LTM_INDENT_ON_TYPE_LAST))
static gboolean ltm_idle_tree_insert_cb(gpointer userdata)
{
struct Ltm_file_data *f_data = userdata;
F_DATA_DECL(Vstr_base *, io_r);
F_DATA_DECL(size_t, pos);
F_DATA_DECL(size_t, len);
F_DATA_DECL(Vstr_sects *, sects);
F_DATA_DECL(unsigned int, parsed_num);
F_DATA_DECL(Vstr_base *, t1);
F_DATA_DECL(GtkTreeStore *, store);
unsigned int count = 0;
Ltm_vstr_pt *pt = NULL;
unsigned int added_entries = 0;
if (len != f_data->unparsed_len)
{
f_data->len = f_data->unparsed_len;
return (TRUE);
}
while (len)
{
size_t loop_pos = pos;
size_t loop_len = len;
size_t del_num = 0;
if (!ltm_add_sect_term_chr(sects, io_r, &pos, &len, ' '))
goto next_0;
if (!ltm_add_sect_term_chr(sects, io_r, &pos, &len, ' '))
goto next_1;
if (!ltm_add_sect_term_chr(sects, io_r, &pos, &len, ' '))
goto next_2;
if (!ltm_add_sect_between_chrs(sects, io_r, &pos, &len, '[', ']', ' '))
goto next_3;
if (!ltm_add_sect_between_chrs(sects, io_r, &pos, &len, '"', '"', ' '))
goto next_4;
if (BEG_MATCH("GET "))
BEG_SKIP("GET ");
else if (BEG_MATCH("HEAD "))
BEG_SKIP("HEAD ");
if (END_MATCH(" HTTP/1.0"))
END_SKIP(" HTTP/1.0");
else if (END_MATCH(" HTTP/1.1"))
END_SKIP(" HTTP/1.1");
if (!ltm_add_sect_term_chr(sects, io_r, &pos, &len, ' '))
goto next_5;
if (!ltm_add_sect_term_chr(sects, io_r, &pos, &len, ' '))
goto next_6;
if (!ltm_add_sect_between_chrs(sects, io_r, &pos, &len, '"', '"', ' '))
goto next_7;
if (!ltm_add_sect_between_chrs(sects, io_r, &pos, &len, '"', '"', '\n'))
goto next_8;
continue;
next_8: ++del_num;
next_7: ++del_num;
next_6: ++del_num;
next_5: ++del_num;
next_4: ++del_num;
next_3: ++del_num;
next_2: ++del_num;
next_1: ++del_num;
next_0:
{
size_t tmp = vstr_srch_chr_fwd(io_r, pos, len, '\n');
while (del_num--)
vstr_sects_del(sects, sects->num);
if (!tmp)
{
pos = loop_pos;
len = loop_len;
break;
}
++f_data->unknown_lines;
len -= vstr_sc_posdiff(pos, tmp);
pos = tmp + 1;
}
}
g_object_freeze_notify(G_OBJECT(store));
pt = g_new(Ltm_vstr_pt, 1);
count = parsed_num;
while ((count + 8) <= sects->num)
{
const char *ptr = NULL;
size_t tmp = 0;
GtkTreeIter *parent_iter = NULL;
size_t comment_pos = 0;
int *sz = NULL;
int *req_num = NULL;
int tot_req_num = (count + 8) / 9;
GtkTreeIter iter;
F_DATA_DECL(GHashTable *, h_iter);
struct Ltm_hash_data *h_vals = NULL;
unsigned int scan = 0;
pt->vs = io_r;
while (ltm_conf_indent_on_type[scan] && (scan < LTM_INDENT_ON_SZ))
{
unsigned int ltm_parent_sect_num = 0;
unsigned int ltm_parent_sect_typ = 0;
switch (ltm_conf_indent_on_type[scan])
{
case LTM_INDENT_ON_TYPE_USR:
pt->pos = VSTR_SECTS_NUM(sects, count + 8)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 8)->len;
break;
case LTM_INDENT_ON_TYPE_MAIN_USR:
pt->pos = VSTR_SECTS_NUM(sects, count + 8)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 8)->len;
if ((comment_pos = vstr_srch_cstr_buf_fwd(io_r, pt->pos, pt->len,
" (")))
pt->len = vstr_sc_posdiff(pt->pos, comment_pos) - 1;
break;
case LTM_INDENT_ON_TYPE_FRM:
pt->pos = VSTR_SECTS_NUM(sects, count)->pos;
pt->len = VSTR_SECTS_NUM(sects, count)->len;
break;
case LTM_INDENT_ON_TYPE_REF:
pt->pos = VSTR_SECTS_NUM(sects, count + 7)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 7)->len;
break;
case LTM_INDENT_ON_TYPE_MAIN_REF:
{
pt->pos = VSTR_SECTS_NUM(sects, count + 7)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 7)->len;
pt->h_val = 0;
if (0) { }
TST_SET_REF("groups.google.at/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.be/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.ca/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.ch/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.ar/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.au/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.br/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.gr/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.hk/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.mx/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.my/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.ru/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.sg/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.tw/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.com.vn/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.co.uk/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.co.fi/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.co.fr/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.co.il/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.co.in/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.co.kr/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.co.jp/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.de/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.fi/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.fr/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.it/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.lt/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.nl/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.pl/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.pt/", 0, strlen("groups.google"));
TST_SET_REF("groups.google.ti/", 0, strlen("groups.google"));
TST_SET_REF("google.at/", 0, strlen("google"));
TST_SET_REF("google.be/", 0, strlen("google"));
TST_SET_REF("google.ca/", 0, strlen("google"));
TST_SET_REF("google.ch/", 0, strlen("google"));
TST_SET_REF("google.com/", 0, strlen("google"));
TST_SET_REF("google.com.ar/", 0, strlen("google"));
TST_SET_REF("google.com.au/", 0, strlen("google"));
TST_SET_REF("google.com.br/", 0, strlen("google"));
TST_SET_REF("google.com.gr/", 0, strlen("google"));
TST_SET_REF("google.com.hk/", 0, strlen("google"));
TST_SET_REF("google.com.mx/", 0, strlen("google"));
TST_SET_REF("google.com.my/", 0, strlen("google"));
TST_SET_REF("google.com.ru/", 0, strlen("google"));
TST_SET_REF("google.com.sg/", 0, strlen("google"));
TST_SET_REF("google.com.tw/", 0, strlen("google"));
TST_SET_REF("google.com.vn/", 0, strlen("google"));
TST_SET_REF("google.co.uk/", 0, strlen("google"));
TST_SET_REF("google.co.fi/", 0, strlen("google"));
TST_SET_REF("google.co.fr/", 0, strlen("google"));
TST_SET_REF("google.co.il/", 0, strlen("google"));
TST_SET_REF("google.co.in/", 0, strlen("google"));
TST_SET_REF("google.co.kr/", 0, strlen("google"));
TST_SET_REF("google.co.jp/", 0, strlen("google"));
TST_SET_REF("google.de/", 0, strlen("google"));
TST_SET_REF("google.fi/", 0, strlen("google"));
TST_SET_REF("google.fr/", 0, strlen("google"));
TST_SET_REF("google.it/", 0, strlen("google"));
TST_SET_REF("google.lt/", 0, strlen("google"));
TST_SET_REF("google.nl/", 0, strlen("google"));
TST_SET_REF("google.pl/", 0, strlen("google"));
TST_SET_REF("google.pt/", 0, strlen("google"));
TST_SET_REF("google.ti/", 0, strlen("google"));
TST_SET_REF("search.yahoo.com/", 0, -1);
TST_SET_REF("altavista.com/", 0, -1);
TST_SET_REF("msn.com/", 0, strlen("msn"));
TST_SET_REF("msn.nl/", 0, strlen("msn"));
TST_SET_REF("mysearch.com/", 0, -1);
TST_SET_REF("search.aol.com/", 0, -1);
TST_SET_REF("search.netscape.com/", 0, -1);
TST_SET_REF("hotbot.com/", 0, -1);
TST_SET_REF("search.com/", 0, -1);
TST_SET_REF("ask.com/", 0, strlen("ask"));
TST_SET_REF("ask.co.uk/", 0, strlen("ask"));
TST_SET_REF("alltheweb.com/", 0, -1);
TST_SET_REF("and.org/vstr", 0, 0);
TST_SET_REF("and.org/pictures", 0, 0);
TST_BEG_SET_REF("and.org", 0, 0);
TST_BEG_SET_REF("www.and.org", 0, 0);
TST_SET_REF("http://www.and.org", 0, 0);
TST_SET_REF("http://and.org", 0, 0);
TST_SET_REF("crazylands.org/", 0, -1);
TST_SET_REF("http://www.freshmeat.net", strlen("http://www."), strlen("freshmeat"));
TST_SET_REF("http://freshmeat.net", strlen("http://"), strlen("freshmeat"));
TST_SET_REF("gnu.org/directory", 0, 0);
TST_SET_REF("gnu.org/search", 0, 0);
TST_SET_REF("sourceforge.net/", 0, -1);
TST_SET_REF("sf.net/", 0, -1);
TST_SET_REF("cuj.com/", 0, -1);
TST_SET_REF("slashdot.org/", 0, -1);
TST_BEG_SET_REF("news://", 0, strlen("news"));
TST_BEG_SET_REF("nntp://", 0, strlen("nntp"));
}
break;
case LTM_INDENT_ON_TYPE_FRM_GROUP:
pt->pos = VSTR_SECTS_NUM(sects, count + 8)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 8)->len;
if ((comment_pos = vstr_srch_chr_fwd(io_r, pt->pos, pt->len, '/')))
pt->len = vstr_sc_posdiff(pt->pos, comment_pos) - 1;
if ((comment_pos = vstr_srch_chr_fwd(io_r, pt->pos, pt->len, ' ')))
pt->len = vstr_sc_posdiff(pt->pos, comment_pos) - 1;
pt->h_val = 0;
if (0) { }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "Scooter"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "Googlebot"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "ia_archiver"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "FAST-WebCrawler"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "webcollage"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "WebFilter"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "fmII"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "Dillo"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "sitecheck.internetseer.com"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else if (vstr_cmp_cstr_eq(io_r, pt->pos, pt->len, "NPBot"))
{ LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR); break; }
else
{
pt->pos = VSTR_SECTS_NUM(sects, count + 8)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 8)->len;
if (0) { }
else if ((tmp = vstr_srch_cstr_buf_fwd(io_r, pt->pos, pt->len,
"Slurp/")))
{
pt->pos = tmp;
pt->len = strlen("Slurp");
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR);
break;
}
else if ((tmp = vstr_srch_case_cstr_buf_fwd(io_r, pt->pos, pt->len,
"Wget/")))
{
pt->pos = tmp;
pt->len = strlen("Wget");
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR);
break;
}
else if ((tmp = vstr_srch_case_cstr_buf_fwd(io_r, pt->pos, pt->len,
"curl/")))
{
pt->pos = tmp;
pt->len = strlen("curl");
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR);
break;
}
else if ((tmp = vstr_srch_case_cstr_buf_fwd(io_r, pt->pos, pt->len,
"gURLChecker/")))
{
pt->pos = tmp;
pt->len = strlen("gURLChecker");
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR);
break;
}
else if ((tmp = vstr_srch_cstr_buf_fwd(io_r, pt->pos, pt->len,
"http://www.almaden.ibm.com/cs/crawler")))
{
pt->pos = tmp + strlen("http://www.");
pt->len = strlen("almaden.ibm.com/cs/crawler");
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR);
break;
}
else
{
pt->pos = VSTR_SECTS_NUM(sects, count)->pos;
pt->len = VSTR_SECTS_NUM(sects, count)->len;
if (0) { }
else if ((tmp = vstr_srch_cstr_buf_fwd(io_r, pt->pos, pt->len,
"63.113.167.33")))
{
pt->pos = ltm_readables[LTM_READABLE_VAL_AND_ORG].pt.pos;
pt->len = ltm_readables[LTM_READABLE_VAL_AND_ORG].pt.len;
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_FRM);
break;
}
}
}
pt->pos = ltm_readables[LTM_READABLE_VAL_OTHER].pt.pos;
pt->len = ltm_readables[LTM_READABLE_VAL_OTHER].pt.len;
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR);
break;
case LTM_INDENT_ON_TYPE_REQ:
pt->pos = VSTR_SECTS_NUM(sects, count + 4)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 4)->len;
break;
case LTM_INDENT_ON_TYPE_MAIN_REQ:
pt->pos = VSTR_SECTS_NUM(sects, count + 4)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 4)->len;
pt->h_val = 0;
if (0) { }
TST_SET_REQ("/pictures/People/img_thumb/", 0, -1);
TST_SET_REQ("/pictures/Animals/img_thumb/", 0, -1);
TST_SET_REQ("/pictures/House/img_thumb/", 0, -1);
TST_SET_REQ("/pictures/Snow/img_thumb/", 0, -1);
TST_SET_REQ("/pictures/Quilts/img_thumb/", 0, -1);
TST_SET_REQ("/pictures/Ridge%20Hill%20Road/img_thumb/", 0, -1);
TST_SET_REQ("/pictures/Garlic%20Festival%202003/img_thumb/", 0, -1);
TST_SET_REQ("/icons/", 0, -1);
break;
case LTM_INDENT_ON_TYPE_RET:
pt->pos = VSTR_SECTS_NUM(sects, count + 5)->pos;
pt->len = VSTR_SECTS_NUM(sects, count + 5)->len;
break;
case LTM_INDENT_ON_TYPE_ALL:
pt->pos = ltm_readables[LTM_READABLE_VAL_ALL].pt.pos;
pt->len = ltm_readables[LTM_READABLE_VAL_ALL].pt.len;
pt->h_val = 0;
LTM_SET_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_ALL);
break;
case LTM_INDENT_ON_TYPE_LAST:
pt->pos = ltm_readables[LTM_READABLE_VAL_LAST].pt.pos;
pt->len = ltm_readables[LTM_READABLE_VAL_LAST].pt.len;
break;
default:
g_assert_not_reached();
}
pt->h_val = 0;
if ((h_vals = g_hash_table_lookup(h_iter, pt)))
{
parent_iter = &h_vals->parent_iter;
sz = &h_vals->sz;
req_num = &h_vals->req_num;
h_iter = h_vals->h_next_iter;
++*req_num;
}
else
{
int nxt_scan = scan + 1;
if (ltm_conf_indent_on_type[scan] == LTM_INDENT_ON_TYPE_LAST)
iter = *parent_iter;
else
gtk_tree_store_append (store, &iter, parent_iter);
h_vals = g_new(struct Ltm_hash_data, 1);
h_vals->parent_iter = iter;
h_vals->sz = 0;
h_vals->req_num = 1;
g_hash_table_insert(h_iter, pt, h_vals);
h_iter = NULL;
if ((nxt_scan < LTM_INDENT_ON_SZ) && ltm_conf_indent_on_type[nxt_scan])
h_iter = g_hash_table_new_full(ltm_hash_gen, ltm_hash_eq, g_free,
ltm_hash_data_free);
h_vals->h_next_iter = h_iter;
parent_iter = &h_vals->parent_iter;
sz = &h_vals->sz;
req_num = &h_vals->req_num;
{
Ltm_vstr_pt *tmp_pt = g_new(Ltm_vstr_pt, 1);
memcpy(tmp_pt, pt, sizeof(Ltm_vstr_pt));
pt = tmp_pt;
}
}
if (!h_iter && (ltm_conf_indent_on_type[scan] != LTM_INDENT_ON_TYPE_LAST))
{
gtk_tree_store_append (store, &iter, parent_iter);
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_NUM, tot_req_num, -1);
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_CNT, *req_num, -1);
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_FRM, count, -1);
}
gtk_tree_store_set(store, parent_iter,
LTM_GTK_COL_T_NUM, tot_req_num, -1);
gtk_tree_store_set(store, parent_iter,
LTM_GTK_COL_T_CNT, *req_num, -1);
if (!LTM_IS_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_FRM))
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_FRM, count, -1);
else
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_FRM,
ltm_parent_sect_num, -1);
{
time_t now = time(NULL);
struct tm *tm = localtime(&now);
time_t *val = g_new(time_t, 1);
ptr = vstr_export_cstr_ptr(io_r,
VSTR_SECTS_NUM(sects, count + 3)->pos,
VSTR_SECTS_NUM(sects, count + 3)->len);
strptime(ptr, "%d/%b/%Y:%H:%M:%S", tm);
*val = mktime(tm);
if (LTM_DISPLAY_ITER_DATA())
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_DAT, val, -1);
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_DAT, val, -1);
}
if (LTM_DISPLAY_ITER_DATA())
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_REQ, count + 4, -1);
if (!LTM_IS_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_REQ))
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_REQ, count + 4, -1);
else
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_REQ,
ltm_parent_sect_num, -1);
{
unsigned int ret_code = 0;
ret_code = vstr_parse_uint(io_r,
VSTR_SECTS_NUM(sects, count + 5)->pos,
VSTR_SECTS_NUM(sects, count + 5)->len,
VSTR_FLAG_PARSE_NUM_DEF | 10,
NULL, NULL);
if (LTM_DISPLAY_ITER_DATA())
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_RET, ret_code, -1);
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_RET, ret_code, -1);
}
ptr = vstr_export_cstr_ptr(io_r,
VSTR_SECTS_NUM(sects, count + 6)->pos,
VSTR_SECTS_NUM(sects, count + 6)->len);
*sz += atoi(ptr);
if (LTM_DISPLAY_ITER_DATA())
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_SIZ, atoi(ptr), -1);
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_SIZ, *sz, -1);
if (LTM_DISPLAY_ITER_DATA())
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_REF, count + 7, -1);
if (!LTM_IS_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_REF))
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_REF, count + 7, -1);
else
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_REF,
ltm_parent_sect_num, -1);
if (LTM_DISPLAY_ITER_DATA())
gtk_tree_store_set(store, &iter, LTM_GTK_COL_T_USR, count + 8, -1);
if (!LTM_IS_PARENT_SECTION_READABLE(LTM_INDENT_ON_TYPE_USR))
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_USR, count + 8, -1);
else
gtk_tree_store_set(store, parent_iter, LTM_GTK_COL_T_USR,
ltm_parent_sect_num, -1);
++scan;
}
g_assert(!h_iter);
count += 9;
if (++added_entries >= LTM_CONF_ADD_ENTERIES_PER_LOOP)
break;
}
g_object_thaw_notify(G_OBJECT(store));
g_free(pt);
{
const char *ptr = NULL;
size_t tmp = t1->len;
unsigned int cnum = (count - f_data->skip_num) / 9;
unsigned int tnum = (sects->num - f_data->skip_num) / 9;
vstr_add_fmt(t1, t1->len, "<b>%'u</b> entries", cnum);
if (f_data->unknown_lines)
vstr_add_fmt(t1, t1->len,
", <b>%'u unknown</b> entries", f_data->unknown_lines);
if (cnum < tnum)
vstr_add_fmt(t1, t1->len,
", <b>%'u total</b> entries", sects->num / 9);
if (len)
vstr_add_fmt(t1, t1->len,
", <b>${BKMG.u:%u}</b> of data left", len);
++tmp;
ptr = vstr_export_cstr_ptr(t1, tmp, vstr_sc_posdiff(tmp, t1->len));
gtk_label_set_markup(GTK_LABEL(f_data->label), ptr);
if (t1->len > (1024 * 4)) vstr_del(t1, 1, t1->len / 2);
}
f_data->pos = pos;
f_data->unparsed_len = len;
f_data->len = len;
f_data->parsed_num = count;
if (!added_entries)
f_data->idle_id = 0;
return (!!added_entries);
}
static gboolean ltm_gio_cb(GIOChannel *source, GIOCondition condition,
gpointer userdata)
{
struct Ltm_file_data *f_data = userdata;
F_DATA_DECL(Vstr_base *, io_r);
int fd = g_io_channel_unix_get_fd(source);
size_t prev_len = io_r->len;
if (condition & (G_IO_ERR|G_IO_HUP|G_IO_NVAL))
{
if (vstr_sc_read_iov_fd(f_data->io_r, io_r->len, fd, 1024, 1024, NULL))
goto got_data;
return (FALSE);
}
if (!vstr_sc_read_iov_fd(f_data->io_r, io_r->len, fd, 1024, 1024, NULL))
return (FALSE);
got_data:
f_data->unparsed_len += io_r->len - prev_len;
if (!f_data->idle_id)
f_data->idle_id = g_idle_add(ltm_idle_tree_insert_cb, f_data);
return (TRUE);
}
int main(int argc, char *argv[])
{
Vstr_base *io_r = NULL;
Vstr_base *io_w = NULL;
int arg_count = 1;
int scan = 0;
struct Ltm_file_data *f_data = g_new0(struct Ltm_file_data, 1);
Vstr_sects *sects = NULL;
const char *ssh_usr = NULL;
f_data->pos = 1;
f_data->parsed_num = 1;
if (!vstr_init())
abort();
vstr_cntl_conf(NULL, VSTR_CNTL_CONF_SET_NUM_BUF_SZ, 4096);
io_r = vstr_make_base(NULL);
io_w = vstr_make_base(NULL);
sects = vstr_sects_make(1024);
if (!io_r || !io_w || !sects)
abort();
vstr_cntl_conf(io_w->conf, VSTR_CNTL_CONF_SET_FMT_CHAR_ESC, '$');
vstr_cntl_conf(io_w->conf, VSTR_CNTL_CONF_SET_LOC_CSTR_THOU_SEP, "_");
vstr_cntl_conf(io_w->conf, VSTR_CNTL_CONF_SET_LOC_CSTR_THOU_GRP, "\3");
vstr_sc_fmt_add_all(io_w->conf);
if (argc < 2)
{
vstr_add_fmt(io_w, io_w->len, " Usage: %s <type> <options>\n%s\n",
argv[0],
" <type>:\n"
" T:all = Group everyone\n"
" T:frm = Group on the From IP address\n"
" T:frm_group = Group on clients\n"
" T:last = Throw away all but last\n"
" T:main_ref = Group on sub sections of the Referrer URL\n"
" T:main_req = Group on sub sections of the Request\n"
" T:main_usr = Group on the User header, ignoring versions\n"
" T:ref = Group on the Referrer URL\n"
" T:req = Group on the Request\n"
" T:ret = Group on the Return code\n"
" T:usr = Group on the User header\n"
"their own groups\n");
while (io_w->len)
if (!vstr_sc_write_fd(io_w, 1, io_w->len, 2, NULL))
abort();
exit (EXIT_FAILURE);
}
while ((arg_count < argc) && (scan < LTM_INDENT_ON_SZ))
{
if (0) { }
else if (!strcmp(argv[arg_count], "T:all"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_ALL;
else if (!strcmp(argv[arg_count], "T:frm"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_FRM;
else if (!strcmp(argv[arg_count], "T:frm_group"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_FRM_GROUP;
else if (!strcmp(argv[arg_count], "T:last"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_LAST;
else if (!strcmp(argv[arg_count], "T:main_ref"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_MAIN_REF;
else if (!strcmp(argv[arg_count], "T:main_req"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_MAIN_REQ;
else if (!strcmp(argv[arg_count], "T:main_usr"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_MAIN_USR;
else if (!strcmp(argv[arg_count], "T:ref"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_REF;
else if (!strcmp(argv[arg_count], "T:req"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_REQ;
else if (!strcmp(argv[arg_count], "T:ret"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_RET;
else if (!strcmp(argv[arg_count], "T:usr"))
ltm_conf_indent_on_type[scan] = LTM_INDENT_ON_TYPE_USR;
else
break;
++arg_count;
++scan;
}
while (arg_count < argc)
{
char *spawn_argv[16];
pid_t spawn_pid = 0;
int spawn_io_1 = -1;
GIOChannel *spawn_gio = NULL;
GError *spawn_err = NULL;
unsigned int spawn_argc = 0;
size_t len = strlen(argv[arg_count]);
if (0) { }
else if ((len >= strlen("tail:")) &&
!memcmp(argv[arg_count], "tail:", strlen("tail:")))
{
argv[arg_count] += strlen("tail:");
spawn_argv[spawn_argc++] = (char *)"tail";
spawn_argv[spawn_argc++] = (char *)"Apache logfile monitor";
spawn_argv[spawn_argc++] = (char *)"-n";
spawn_argv[spawn_argc++] = (char *)"0";
spawn_argv[spawn_argc++] = (char *)"-f";
}
else if ((len >= strlen("ssh-uh:")) &&
!memcmp(argv[arg_count], "ssh-uh:", strlen("ssh-uh:")))
{
ssh_usr = argv[arg_count++];
ssh_usr += strlen("ssh-uh:");
continue;
}
else if (ssh_usr &&
(len >= strlen("ssh-file:")) &&
!memcmp(argv[arg_count], "ssh-file:", strlen("ssh-file:")))
{
argv[arg_count] += strlen("ssh-file:");
spawn_argv[spawn_argc++] = (char *)"ssh";
spawn_argv[spawn_argc++] = (char *)"Apache remote logfile monitor";
spawn_argv[spawn_argc++] = (char *)ssh_usr;
spawn_argv[spawn_argc++] = (char *)"--";
spawn_argv[spawn_argc++] = (char *)"tail";
spawn_argv[spawn_argc++] = (char *)"-n";
spawn_argv[spawn_argc++] = (char *)"0";
spawn_argv[spawn_argc++] = (char *)"-f";
}
else
{
if ((len >= strlen("file:")) &&
!memcmp(argv[arg_count], "file:", strlen("file:")))
argv[arg_count] += strlen("file:");
spawn_argv[spawn_argc++] = (char *)"cat";
spawn_argv[spawn_argc++] = (char *)"Apache logfile dumper";
}
spawn_argv[spawn_argc++] = (char *)"--";
spawn_argv[spawn_argc++] = argv[arg_count];
spawn_argv[spawn_argc++] = NULL;
g_assert(spawn_argc <= (sizeof(spawn_argv) / sizeof(spawn_argv[0])));
if (!g_spawn_async_with_pipes(".", spawn_argv, NULL,
G_SPAWN_LEAVE_DESCRIPTORS_OPEN |
G_SPAWN_SEARCH_PATH |
G_SPAWN_STDERR_TO_DEV_NULL |
G_SPAWN_CHILD_INHERITS_STDIN |
G_SPAWN_FILE_AND_ARGV_ZERO,
NULL, NULL,
&spawn_pid,
NULL, &spawn_io_1, NULL,
&spawn_err))
g_error("g_spawn: %s", spawn_err->message);
spawn_gio = g_io_channel_unix_new(spawn_io_1);
g_io_add_watch(spawn_gio, G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL,
ltm_gio_cb, f_data);
++arg_count;
}
f_data->sects = sects;
f_data->io_r = io_r;
ltm_gtk_list(io_r, f_data);
vstr_sects_free(sects);
vstr_free_base(io_r);
vstr_free_base(io_w);
vstr_exit();
g_free(f_data);
return (EXIT_SUCCESS);
}