📄 glogd.c
字号:
/* MPICH-V2 Copyright (C) 2002, 2003 Groupe Cluster et Grid, LRI, Universite de Paris Sud This file is part of MPICH-V2. MPICH-V2 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. MPICH-V2 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 MPICH-V2; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA $Id: glogd.c,v 1.1.1.1 2004/01/30 15:49:38 lemarini Exp $*/#include <errno.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <stdio.h>#include <string.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/inet.h>#include "glogd.h"#define MTU 65536static void glog_reset_all(GtkButton *b, GLogd *logd){ GList *l; for(l = g_list_first(logd->loggers); l; l = g_list_next(l) ) gtk_signal_emit_by_name( GTK_OBJECT(l->data), "reset"); for(l = g_list_first(logd->msgs); l; l = g_list_next(l) ) { free( MSG(l->data)->dta ); free( MSG(l->data) ); } g_list_free( logd->msgs ); logd->msgs = NULL;}static gboolean glogd_delete(GLogd *logd, GdkEvent *e, gpointer null){ GList *l; g_io_channel_close(logd->chan); g_source_remove(logd->watch); for(l = g_list_first(logd->loggers); l; l = g_list_next(l) ) gtk_object_destroy( GTK_OBJECT(l->data) ); for(l = g_list_first(logd->msgs); l; l = g_list_next(l) ) { free( MSG(l->data)->dta ); free( MSG(l->data)->file ); free( MSG(l->data)->func ); free( MSG(l->data) ); } g_list_free( logd->msgs ); logd->msgs = NULL; for(l = g_list_first(logd->uids); l; l = g_list_next(l)) { free(NC(l)->name); free(NC(l)); } g_list_free( logd->uids ); logd->uids = NULL; for(l = g_list_first(logd->lvls); l; l = g_list_next(l)) { free(NC(l)->name); free(NC(l)); } g_list_free( logd->lvls ); logd->lvls = NULL; return FALSE;}#define UID_INT 16382#define UID_OFF (65535-16382-8191)#define LVL_INT 16382#define LVL_OFF 8191static void glogd_get_new_color( GdkColor *c, char is_uid){ if(is_uid) { c->red = (rand()%UID_INT) + UID_OFF; c->green = (rand()%UID_INT) + UID_OFF; c->blue = (rand()%UID_INT) + UID_OFF; } else { c->red = (rand()%LVL_INT) + LVL_OFF; c->green = (rand()%LVL_INT) + LVL_OFF; c->blue = (rand()%LVL_INT) + LVL_OFF; } c->pixel = (gulong)(((int)c->red)*65536 + ((int)c->green)*256 + (int)c->blue); gdk_color_alloc(gdk_colormap_get_system(), c);}static name_color *g_list_special( GLogd *logd, GList **list, char *s ){ GList *l; name_color *nc; GtkStyle *st; int r; for(l = g_list_first( *list ); l; l = g_list_next(l) ) if( !strcmp( NC(l)->name, s) ) break; if(!l) { nc = (name_color*)malloc(sizeof(name_color)); nc->name = strdup(s); glogd_get_new_color(&nc->color, list == &logd->uids); *list = g_list_append( *list, nc ); if( list == &logd->uids ) { /* TODO : ajouter la creation d'un nouvel uid */ r = gtk_clist_append( GTK_CLIST(logd->uid_samples), &nc->name ); st = gtk_style_copy(GTK_WIDGET(logd)->style); memcpy( &(st->fg[GTK_WIDGET(logd)->state]), &st->white, sizeof(GdkColor) ); memcpy( &(st->base[GTK_WIDGET(logd)->state]), &nc->color, sizeof(GdkColor) ); gtk_clist_set_cell_style(GTK_CLIST(logd->uid_samples), r, 0, st); gtk_style_unref(st); for(l = g_list_first( logd->loggers ); l; l = g_list_next(l) ) gtk_signal_emit_by_name( GTK_OBJECT(l->data), "newuid", nc ); } else { /* TODO : ajouter la creation d'un nouveau lvl */ r = gtk_clist_append( GTK_CLIST(logd->lvl_samples), &nc->name ); st = gtk_style_copy( GTK_WIDGET(logd)->style ); memcpy( &(st->fg[GTK_WIDGET(logd)->state]), &nc->color, sizeof(GdkColor) ); gtk_clist_set_cell_style(GTK_CLIST(logd->lvl_samples), r, 0, st); gtk_style_unref(st); for(l = g_list_first( logd->loggers ); l; l = g_list_next(l) ) gtk_signal_emit_by_name( GTK_OBJECT(l->data), "newlvl", nc ); } return nc; } else return NC(l);}static gboolean glogd_socket(GIOChannel *source, GIOCondition condition, gpointer user_data){ GLogd *logd = GLOGD(user_data); static char data[MTU]; char dta[MTU]; static int data_len = 0; int nr; char *p, *q; GList *l; msg *m; int lineno, mid; char uid_s[64], lvl_s[256]; char file_s[256], func_s[256]; char addr[24]; struct timeval tv; char s; switch( g_io_channel_read(source, data + data_len, MTU, &nr) ) { case G_IO_ERROR_NONE: break; case G_IO_ERROR_AGAIN: return TRUE; default: perror("read on multiplexer"); return FALSE; } if(nr == 0) { fprintf(stderr, "connection closed by multiplexor\n"); return FALSE; } data_len += nr; *(data + data_len) = 0; while (*data != 0) { for(p = data; *p && (*p != '\n'); p++) ; if( *p == 0 ) break; *p++ = 0; if( sscanf(data, "[%ld.%ld:%[^:]:%c]", &tv.tv_sec, &tv.tv_usec, addr, &s) != 4) { fprintf(stderr, "malformed multiplexor message : %s\n", data); goto next; } m = (msg *)calloc(sizeof(msg), 1); memcpy(&m->rdate, &tv, sizeof(struct timeval)); bzero(&m->from, sizeof(struct sockaddr_in)); inet_aton(addr, &m->from.sin_addr); m->from.sin_family = AF_INET; switch(s) { case 'M': for(q = data; *q != ']'; q++) ; q++; if(sscanf(q, "%[^<]<%s %s %[^(]():%5d (%08d) %ld.%ld> %[^\1]", uid_s, lvl_s, file_s, func_s, &lineno, &mid, &tv.tv_sec, &tv.tv_usec, dta) != 9) { fprintf(stderr, "malformed client message : %s\n", data); free(m); goto next; } m->uid = g_list_special( logd, &(logd->uids), uid_s ); m->lvl = g_list_special( logd, &(logd->lvls), lvl_s ); m->file = strdup(file_s); m->func = strdup(func_s); m->lineno = lineno; m->mid = mid; m->dta = strdup(dta); m->dlen = strlen(dta); m->mlen = (p-data); memcpy(&m->edate, &tv, sizeof(struct timeval)); break; case 'E': m->uid = g_list_special( logd, &(logd->uids), "Multiplexor"); m->lvl = g_list_special( logd, &(logd->lvls), "MI"); m->file = strdup(""); m->func = strdup(""); m->lineno = -1; m->mid = 0; m->dta = strdup("Connection Established"); m->dlen = strlen(m->dta); m->mlen = 0; gettimeofday(&m->edate, NULL); break; case 'B': m->uid = g_list_special( logd, &(logd->uids), "Multiplexor"); m->lvl = g_list_special( logd, &(logd->lvls), "MI"); m->file = strdup(""); m->func = strdup(""); m->lineno = -1; m->mid = 0; m->dta = strdup("Connection Broken"); m->dlen = strlen(m->dta); m->mlen = 0; gettimeofday(&m->edate, NULL); break; case 'D': m->uid = g_list_special( logd, &(logd->uids), "Multiplexor"); m->lvl = g_list_special( logd, &(logd->lvls), "MI"); m->file = strdup(""); m->func = strdup(""); m->lineno = -1; m->mid = 0; m->dta = strdup("Connection Reset"); m->dlen = strlen(m->dta); m->mlen = 0; gettimeofday(&m->edate, NULL); break; default: fprintf(stderr, "malformed status in %s\n", data); free(m); goto next; } logd->msgs = g_list_append(logd->msgs, m); for(l = g_list_first(logd->loggers); l; l = g_list_next(l) ) gtk_signal_emit_by_name( GTK_OBJECT(l->data), "data", m ); next: if( (p-data) < data_len) memmove(data, p, data_len - (p-data)); data_len -= (p-data); } return TRUE;}static void glogd_class_init(GLogdClass *klass){ }static void glogd_init(GLogd *logd){ GtkWidget *button; GtkWidget *vbox, *hbox, *sw; char *lvl_s_titles[1] = { "LVLs" }; char *uid_s_titles[1] = { "UIDs" }; gtk_window_set_title(GTK_WINDOW(logd), "Unbound logger"); vbox = gtk_vbox_new(FALSE, 0); gtk_container_add(GTK_CONTAINER(logd), vbox); gtk_widget_show(vbox); logd->hbbox = gtk_hbutton_box_new(); gtk_box_pack_start(GTK_BOX(vbox), logd->hbbox, FALSE, FALSE, 0); gtk_hbutton_box_set_layout_default(GTK_BUTTONBOX_SPREAD); gtk_widget_show(logd->hbbox); button = gtk_button_new_with_label("Reset all"); gtk_box_pack_end(GTK_BOX(logd->hbbox), button, FALSE, FALSE, 0); gtk_widget_show(button); gtk_signal_connect(GTK_OBJECT(button), "clicked", GTK_SIGNAL_FUNC(glog_reset_all), logd); hbox = gtk_hbox_new(TRUE, 0); gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); gtk_widget_show(hbox); sw = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(hbox), sw, TRUE, TRUE, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(sw); logd->uid_samples = gtk_clist_new_with_titles(1, uid_s_titles); gtk_container_add(GTK_CONTAINER(sw), logd->uid_samples); gtk_widget_show(logd->uid_samples); sw = gtk_scrolled_window_new(NULL, NULL); gtk_box_pack_start(GTK_BOX(hbox), sw, TRUE, TRUE, 0); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); gtk_widget_show(sw); logd->lvl_samples = gtk_clist_new_with_titles(1, lvl_s_titles); gtk_container_add(GTK_CONTAINER(sw), logd->lvl_samples); gtk_widget_show(logd->lvl_samples); logd->chan = NULL; logd->loggers = NULL; logd->uids = NULL; logd->lvls = NULL; logd->watch = 0;}guint glogd_get_type(void){ static guint glogd_type = 0; if (!glogd_type) { GtkTypeInfo glogd_info = { "GLogd", sizeof (GLogd), sizeof (GLogdClass), (GtkClassInitFunc) glogd_class_init, (GtkObjectInitFunc) glogd_init, (GtkArgSetFunc) NULL, (GtkArgGetFunc) NULL }; glogd_type = gtk_type_unique (gtk_window_get_type (), &glogd_info); } return glogd_type;}GtkWidget *glogd_new(int fd){ GLogd *logd; char title[64]; logd = GLOGD( gtk_object_newv (glogd_get_type(), 0, NULL) ); logd->chan = g_io_channel_unix_new(fd); sprintf(title, "Listening logger"); gtk_window_set_title(GTK_WINDOW(logd), title); gtk_signal_connect( GTK_OBJECT(logd), "delete_event", GTK_SIGNAL_FUNC(glogd_delete), logd); logd->watch = g_io_add_watch(logd->chan, G_IO_IN, glogd_socket, logd); return GTK_WIDGET(logd);}static void glogd_logger_removed(GtkObject *o, GLogd *logd){ printf("removing %p\n", o); logd->loggers = g_list_remove(logd->loggers, o);}static void new_logger_clicked(GtkButton *b, new_logger_t nl){ GLogd *logd; GLogger *n; logd = GLOGD( gtk_object_get_user_data( GTK_OBJECT(b) ) ); n = nl(logd); logd->loggers = g_list_append( logd->loggers, n ); gtk_signal_connect(GTK_OBJECT(n), "remove", GTK_SIGNAL_FUNC(glogd_logger_removed), logd);}void glogd_register_logger(GLogd *glog, char *logger_name, new_logger_t nl){ GtkWidget *b; b = gtk_button_new_with_label(logger_name); gtk_box_pack_start(GTK_BOX(glog->hbbox), b, FALSE, FALSE, 0); gtk_widget_show(b); gtk_object_set_user_data(GTK_OBJECT(b), glog); gtk_signal_connect(GTK_OBJECT(b), "clicked", GTK_SIGNAL_FUNC(new_logger_clicked), nl); }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -