3 YAWMPPP - PPP dock app/helper for WindowMaker
6 Author: Felipe Bergo (bergo@seul.org)
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 $Id: loglist.c,v 1.1.1.1 2001/02/22 07:35:59 bergo Exp $
30 #include <sys/types.h>
36 #include "status_error.xpm"
37 #include "status_crash.xpm"
38 #include "status_ok.xpm"
39 #include "stepphone.xpm"
41 GtkWidget
*applet
,*loglist
,*lresume
[2],*hgraph
,*wgraph
;
42 GdkPixmap
*iconmap
[3];
43 GdkBitmap
*maskmap
[3];
45 GdkPixmap
*hcanvas
=NULL
;
46 GdkPixmap
*wcanvas
=NULL
;
50 /* start end difftime statuspix staustext handle name phone user */
51 static int colsize
[8]={160,160,64,54,45,110,64,64};
53 static char *resumeo
[]=
67 static char *titles
[8]={"Start time",
76 static char *wdays
[]={
77 "Sun","Mon","Tue","Wed","Thu","Fri","Sat"
80 static long hourly
[24],weekly
[7];
93 main(int argc
,char **argv
)
108 gtk_init(&argc
,&argv
);
121 gdk_pixmap_unref(iconmap
[i
]);
130 GtkWidget
*mvb
,*sw
,*dhb
,*dhw
[30];
137 applet
=gtk_window_new(GTK_WINDOW_TOPLEVEL
);
138 gtk_window_set_default_size(GTK_WINDOW(applet
),780,510);
139 gtk_window_set_title (GTK_WINDOW (applet
), "YAWMPPP Connection Log");
140 gtk_window_set_wmclass(GTK_WINDOW(applet
),"yawmppp","log");
141 gtk_container_set_border_width(GTK_CONTAINER(applet
),4);
142 gtk_widget_show (applet
);
144 style
=gtk_widget_get_style(applet
);
145 myicon
= gdk_pixmap_create_from_xpm_d (applet
->window
, &mask
,
146 &style
->bg
[GTK_STATE_NORMAL
],
147 (gchar
**) stepphone_xpm
);
148 gdk_window_set_icon (applet
->window
, NULL
, myicon
, mask
);
149 gdk_window_set_icon_name(applet
->window
,"The Log");
151 mvb
=gtk_vbox_new(FALSE
,0);
152 gtk_container_add(GTK_CONTAINER(applet
),mvb
);
154 dhb
=gtk_hbox_new(FALSE
,0);
155 gtk_box_pack_start(GTK_BOX(mvb
),dhb
,FALSE
,TRUE
,0);
158 dhw
[0]=gtk_label_new("Show summary for:");
159 gtk_box_pack_start(GTK_BOX(dhb
),dhw
[0],FALSE
,FALSE
,4);
161 dhw
[1]=gtk_option_menu_new();
162 gtk_box_pack_start(GTK_BOX(dhb
),dhw
[1],FALSE
,FALSE
,2);
164 dhw
[2]=gtk_menu_new();
167 dhw
[3]=gtk_menu_item_new_with_label(resumeo
[i
]);
168 gtk_signal_connect(GTK_OBJECT(dhw
[3]),"activate",
169 GTK_SIGNAL_FUNC(time_menu
),&nsrc
[i
]);
170 gtk_menu_append(GTK_MENU(dhw
[2]),dhw
[3]);
171 gtk_widget_show(dhw
[3]);
174 gtk_option_menu_set_menu(GTK_OPTION_MENU(dhw
[1]),dhw
[2]);
176 dhw
[12]=gtk_label_new("include entries from");
177 gtk_box_pack_start(GTK_BOX(dhb
),dhw
[12],FALSE
,FALSE
,4);
178 dhw
[13]=gtk_option_menu_new();
179 gtk_box_pack_start(GTK_BOX(dhb
),dhw
[13],FALSE
,FALSE
,2);
181 dhw
[14]=gtk_menu_new();
183 for(i
=0,pt
=isps
;pt
!=NULL
;pt
=g_list_next(pt
),i
++) {
184 dhw
[3]=gtk_menu_item_new_with_label((char *)(pt
->data
));
185 gtk_signal_connect(GTK_OBJECT(dhw
[3]),"activate",
186 GTK_SIGNAL_FUNC(isp_menu
),&nsrc
[i
]);
187 gtk_menu_append(GTK_MENU(dhw
[14]),dhw
[3]);
188 gtk_widget_show(dhw
[3]);
191 gtk_option_menu_set_menu(GTK_OPTION_MENU(dhw
[13]),dhw
[14]);
194 dhw
[15]=gtk_label_new("include connections as");
195 gtk_box_pack_start(GTK_BOX(dhb
),dhw
[15],FALSE
,FALSE
,4);
196 dhw
[16]=gtk_option_menu_new();
197 gtk_box_pack_start(GTK_BOX(dhb
),dhw
[16],FALSE
,FALSE
,2);
199 dhw
[17]=gtk_menu_new();
201 for(i
=0,pt
=users
;pt
!=NULL
;pt
=g_list_next(pt
),i
++) {
202 dhw
[3]=gtk_menu_item_new_with_label((char *)(pt
->data
));
203 gtk_signal_connect(GTK_OBJECT(dhw
[3]),"activate",
204 GTK_SIGNAL_FUNC(user_menu
),&nsrc
[i
]);
205 gtk_menu_append(GTK_MENU(dhw
[17]),dhw
[3]);
206 gtk_widget_show(dhw
[3]);
209 gtk_option_menu_set_menu(GTK_OPTION_MENU(dhw
[16]),dhw
[17]);
211 dhw
[5]=gtk_hseparator_new();
212 gtk_box_pack_start(GTK_BOX(mvb
),dhw
[5],FALSE
,FALSE
,3);
214 dhw
[3]=gtk_hbox_new(FALSE
,4);
215 gtk_box_pack_start(GTK_BOX(mvb
),dhw
[3],FALSE
,TRUE
,3);
217 dhw
[4]=lresume
[0]=gtk_label_new("\n\n\n\n\n");
218 dhw
[6]=lresume
[1]=gtk_label_new("\n\n\n\n\n");
221 gtk_label_set_justify(GTK_LABEL(lresume
[i
]),GTK_JUSTIFY_LEFT
);
223 gtk_box_pack_start(GTK_BOX(dhw
[3]),dhw
[4],FALSE
,TRUE
,4);
224 gtk_box_pack_start(GTK_BOX(dhw
[3]),dhw
[6],FALSE
,TRUE
,4);
226 hgraph
=dhw
[7]=gtk_drawing_area_new();
227 gtk_drawing_area_size(GTK_DRAWING_AREA(dhw
[7]),24*9+2,120);
228 gtk_widget_set_events(dhw
[7],GDK_EXPOSURE_MASK
);
230 gtk_box_pack_start(GTK_BOX(dhw
[3]),dhw
[7],FALSE
,FALSE
,4);
232 wgraph
=dhw
[8]=gtk_drawing_area_new();
233 gtk_drawing_area_size(GTK_DRAWING_AREA(dhw
[8]),7*20+2,120);
234 gtk_widget_set_events(dhw
[8],GDK_EXPOSURE_MASK
);
236 gtk_box_pack_start(GTK_BOX(dhw
[3]),dhw
[8],FALSE
,FALSE
,4);
238 dhw
[11]=gtk_hseparator_new();
239 gtk_box_pack_start(GTK_BOX(mvb
),dhw
[11],FALSE
,FALSE
,4);
241 dhw
[9]=gtk_hbox_new(FALSE
,2);
242 dhw
[10]=gtk_label_new("Raw log listing (unfiltered):");
244 gtk_box_pack_start(GTK_BOX(mvb
),dhw
[9],FALSE
,FALSE
,4);
245 gtk_box_pack_start(GTK_BOX(dhw
[9]),dhw
[10],FALSE
,FALSE
,2);
249 sw
=gtk_scrolled_window_new(NULL
,NULL
);
250 gtk_box_pack_start(GTK_BOX(mvb
),sw
,TRUE
,TRUE
,4);
252 gtk_container_set_border_width(GTK_CONTAINER(sw
),0);
254 loglist
=gtk_clist_new(8);
255 gtk_clist_set_shadow_type(GTK_CLIST(loglist
),GTK_SHADOW_IN
);
256 gtk_clist_set_selection_mode(GTK_CLIST(loglist
),GTK_SELECTION_SINGLE
);
258 gtk_clist_set_column_title(GTK_CLIST(loglist
),i
,titles
[i
]);
259 gtk_clist_set_column_width(GTK_CLIST(loglist
),i
,colsize
[i
]);
261 gtk_clist_column_titles_passive(GTK_CLIST(loglist
));
262 gtk_clist_column_titles_show(GTK_CLIST(loglist
));
263 gtk_clist_set_row_height(GTK_CLIST(loglist
),16);
264 gtk_clist_set_column_auto_resize(GTK_CLIST(loglist
),1,FALSE
);
265 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw
),
266 GTK_POLICY_AUTOMATIC
,
268 gtk_container_add(GTK_CONTAINER(sw
),loglist
);
269 gtk_widget_show(loglist
);
273 dhw
[18]=gtk_hseparator_new();
274 gtk_box_pack_start(GTK_BOX(mvb
),dhw
[18],FALSE
,FALSE
,4);
276 dhw
[19]=gtk_table_new(1,6,TRUE
);
277 dhw
[21]=gtk_button_new_with_label(" About... ");
278 dhw
[22]=gtk_button_new_with_label(" Close ");
280 dhw
[23]=gtk_hbox_new(TRUE
,6);
282 gtk_box_pack_start(GTK_BOX(mvb
),dhw
[19],FALSE
,FALSE
,4);
284 gtk_table_attach_defaults(GTK_TABLE(dhw
[19]),dhw
[23],4,6,0,1);
286 gtk_box_pack_start(GTK_BOX(dhw
[23]),dhw
[21],FALSE
,TRUE
,4);
287 gtk_box_pack_start(GTK_BOX(dhw
[23]),dhw
[22],FALSE
,TRUE
,4);
291 gtk_widget_show(dhw
[i
]);
292 gtk_widget_show(dhb
);
293 gtk_widget_show(mvb
);
295 iconmap
[0] = gdk_pixmap_create_from_xpm_d (applet
->window
, &maskmap
[0],
296 &style
->bg
[GTK_STATE_NORMAL
],
297 (gchar
**) status_ok_xpm
);
298 iconmap
[1] = gdk_pixmap_create_from_xpm_d (applet
->window
, &maskmap
[1],
299 &style
->bg
[GTK_STATE_NORMAL
],
300 (gchar
**) status_error_xpm
);
301 iconmap
[2] = gdk_pixmap_create_from_xpm_d (applet
->window
, &maskmap
[2],
302 &style
->bg
[GTK_STATE_NORMAL
],
303 (gchar
**) status_crash_xpm
);
305 /* signal plumbing */
306 gtk_signal_connect (GTK_OBJECT (applet
), "delete_event",
307 GTK_SIGNAL_FUNC (applet_kill
), NULL
);
308 gtk_signal_connect (GTK_OBJECT (applet
), "destroy",
309 GTK_SIGNAL_FUNC (applet_destroy
), NULL
);
310 gtk_signal_connect (GTK_OBJECT (hgraph
), "expose_event",
311 GTK_SIGNAL_FUNC (hgra_expose
), NULL
);
312 gtk_signal_connect (GTK_OBJECT (hgraph
), "configure_event",
313 GTK_SIGNAL_FUNC (hgra_configure
), NULL
);
314 gtk_signal_connect (GTK_OBJECT (wgraph
), "expose_event",
315 GTK_SIGNAL_FUNC (wgra_expose
), NULL
);
316 gtk_signal_connect (GTK_OBJECT (wgraph
), "configure_event",
317 GTK_SIGNAL_FUNC (wgra_configure
), NULL
);
319 gtk_signal_connect (GTK_OBJECT (dhw
[21]), "clicked",
320 GTK_SIGNAL_FUNC (applet_about
),
321 (gpointer
)GTK_WINDOW(applet
));
322 gtk_signal_connect (GTK_OBJECT (dhw
[22]), "clicked",
323 GTK_SIGNAL_FUNC (applet_destroy
), NULL
);
331 char temp
[256],aux
[256];
342 users
=g_list_append(users
,"All users");
343 isps
=g_list_append(isps
,"All ISPs");
346 sprintf(temp
,"%s/.yawmppp2/logfile",p
);
355 while(fgets(aux
,255,f
))
356 prepend_log_entry(aux
);
360 for(pt
=log
;pt
!=NULL
;pt
=g_list_next(pt
)) {
361 le
=(struct logentry
*)(pt
->data
);
363 if (!already_exists(le
->user
,users
)) {
364 users
=g_list_append(users
,(gpointer
)(le
->user
));
367 if (!already_exists(le
->shortname
,isps
))
368 isps
=g_list_append(isps
,(gpointer
)(le
->shortname
));
373 prepend_log_entry(char *logline
)
378 le
=(struct logentry
*)g_malloc0(sizeof(struct logentry
));
380 if ((p
=strtok(logline
,"\t\n"))==NULL
) { g_free(le
); return; }
381 le
->start
=(time_t)atol(p
);
383 if ((p
=strtok(NULL
,"\t\n"))==NULL
) { g_free(le
); return; }
384 le
->end
=(time_t)atol(p
);
386 if ((p
=strtok(NULL
,"\t\n"))==NULL
) { g_free(le
); return; }
389 if ((p
=strtok(NULL
,"\t\n"))==NULL
) { g_free(le
); return; }
390 strncpy(le
->longname
,p
,128);
392 if ((p
=strtok(NULL
,"\t\n"))==NULL
) { g_free(le
); return; }
393 strncpy(le
->shortname
,p
,16);
395 if ((p
=strtok(NULL
,"\t\n"))==NULL
) { g_free(le
); return; }
396 strncpy(le
->phone
,p
,32);
398 if ((p
=strtok(NULL
,"\t\n"))==NULL
) { g_free(le
); return; }
399 strncpy(le
->user
,p
,32);
401 log
=g_list_prepend(log
,(gpointer
)(le
));
409 for(pt
=log
;pt
!=NULL
;pt
=g_list_next(pt
))
426 gtk_clist_freeze(GTK_CLIST(loglist
));
427 gtk_clist_clear(GTK_CLIST(loglist
));
432 for(lc
=0,pt
=log
;pt
!=NULL
;pt
=g_list_next(pt
),lc
++) {
433 le
=(struct logentry
*)(pt
->data
);
434 strcpy(tmp
[0],ctime(&(le
->start
)));
435 strcpy(tmp
[1],ctime(&(le
->end
)));
436 ontime
=(int)(le
->end
- le
->start
);
442 sprintf(tmp
[2],"%.4d:%.2d:%.2d",h
,m
,s
);
448 strcpy(tmp
[3],"Error");
451 strcpy(tmp
[3],"Crash");
453 strcpy(tmp
[4],le
->shortname
);
454 strcpy(tmp
[5],le
->longname
);
455 strcpy(tmp
[6],le
->phone
);
456 strcpy(tmp
[7],le
->user
);
458 gtk_clist_append(GTK_CLIST(loglist
),pp
);
459 gtk_clist_set_pixtext(GTK_CLIST(loglist
),lc
,3,
461 iconmap
[le
->status
%3],
462 maskmap
[le
->status
%3]);
465 gtk_clist_thaw(GTK_CLIST(loglist
));
470 applet_kill (GtkWidget
* widget
, GdkEvent
* event
, gpointer data
)
476 applet_destroy (GtkWidget
* widget
, gpointer data
)
484 static char temp
[1024],aux
[256];
486 long olt
,ldiff
,avg
,maior
,menor
;
500 strcpy(temp
,"Summary:\n\n");
506 menor
=time(NULL
); /* unless you've been wired since
507 Jan 1 1970 this will work... ;-) */
508 for(pt
=log
;pt
!=NULL
;pt
=g_list_next(pt
)) {
509 le
=(struct logentry
*)(pt
->data
);
512 if ((le
->end
< time_cons
[0])||(le
->start
> time_cons
[1]))
515 if (strcmp((char *)(g_list_nth_data(users
,useridx
)),le
->user
))
518 if (strcmp((char *)(g_list_nth_data(isps
,ispidx
)),le
->shortname
))
522 ldiff
=(le
->end
- le
->start
);
525 add_hourly(le
->start
,le
->end
);
526 add_weekly(le
->start
,le
->end
);
534 sprintf(aux
,"Connections: %d\n"\
535 "Disconnected OK: %d\n"\
536 "Disconnected Error: %d\n"\
537 "Disconnected Crash: %d\n",ec
,sv
[0],sv
[1],sv
[2]);
540 gtk_label_set_text(GTK_LABEL(lresume
[0]),temp
);
572 sprintf(aux
,"Online time: %.4d:%.2d:%.2d\n"\
573 "Average connection length: %.4d:%.2d:%.2d\n"\
574 "Longer connection: %.4d:%.2d:%.2d\n"\
575 "Shorter connection: %.4d:%.2d:%.2d\n",
582 gtk_label_set_text(GTK_LABEL(lresume
[1]),temp
);
583 gtk_widget_queue_resize(hgraph
);
584 gtk_widget_queue_resize(wgraph
);
588 add_hourly(long s
,long e
)
593 for(t
=s
;t
<=e
;t
+=30) {
597 hourly
[st
->tm_hour
]++;
602 add_weekly(long s
,long e
)
607 for(t
=s
;t
<=e
;t
+=30) {
611 weekly
[st
->tm_wday
]++;
616 hgra_expose(GtkWidget
*widget
,GdkEventExpose
*ee
,gpointer data
)
618 gdk_draw_pixmap(widget
->window
,
619 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
621 ee
->area
.x
, ee
->area
.y
,
622 ee
->area
.x
, ee
->area
.y
,
623 ee
->area
.width
, ee
->area
.height
);
628 hgra_configure(GtkWidget
*widget
,GdkEventConfigure
*ee
,gpointer data
)
639 gdk_pixmap_unref(hcanvas
);
641 mygc
=gdk_gc_new(widget
->window
);
643 hcanvas
=gdk_pixmap_new(widget
->window
,x
=widget
->allocation
.width
,
644 y
=widget
->allocation
.height
,-1);
645 gdk_draw_rectangle(hcanvas
,widget
->style
->white_gc
,TRUE
,0,0,x
,y
);
646 gdk_draw_rectangle(hcanvas
,widget
->style
->black_gc
,FALSE
,0,0,x
-1,y
-1);
654 fac
=((float)(y
-18-16))/((float)max
);
658 fn
=gdk_font_load("-*-helvetica-medium-r-*-*-8-*-*-*-*-*-*-*");
660 v
=(int)(((float)hourly
[i
])*fac
);
661 gdk_rgb_gc_set_foreground(mygc
,0xc0c0c0);
662 gdk_draw_line(hcanvas
,mygc
,cx
,1,cx
,y
-2);
663 gdk_rgb_gc_set_foreground(mygc
,0x004080);
664 gdk_draw_rectangle(hcanvas
,mygc
,TRUE
,cx
,y
-18-v
,xs
,v
);
668 gdk_rgb_gc_set_foreground(mygc
,0x000000);
669 for(cx
=1,i
=0;i
<24;i
+=2) {
670 sprintf(tmp
,"%2d",i
);
671 gdk_draw_string(hcanvas
,fn
,mygc
,cx
,y
-6,tmp
);
675 gdk_draw_line(hcanvas
,widget
->style
->black_gc
,0,y
-18,x
-1,y
-18);
677 gdk_rgb_gc_set_foreground(mygc
,0xffffff);
678 gdk_draw_rectangle(hcanvas
,mygc
,TRUE
,0,0,22*4,13);
679 gdk_rgb_gc_set_foreground(mygc
,0x000000);
680 gdk_draw_rectangle(hcanvas
,mygc
,FALSE
,0,0,22*4,13);
683 fn
=gdk_font_load("-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*");
685 gdk_draw_string(hcanvas
,fn
,mygc
,5,10,"hourly summary");
688 gdk_gc_destroy(mygc
);
694 wgra_expose(GtkWidget
*widget
,GdkEventExpose
*ee
,gpointer data
)
696 gdk_draw_pixmap(widget
->window
,
697 widget
->style
->fg_gc
[GTK_WIDGET_STATE (widget
)],
699 ee
->area
.x
, ee
->area
.y
,
700 ee
->area
.x
, ee
->area
.y
,
701 ee
->area
.width
, ee
->area
.height
);
706 wgra_configure(GtkWidget
*widget
,GdkEventConfigure
*ee
,gpointer data
)
716 gdk_pixmap_unref(wcanvas
);
718 mygc
=gdk_gc_new(widget
->window
);
720 wcanvas
=gdk_pixmap_new(widget
->window
,x
=widget
->allocation
.width
,
721 y
=widget
->allocation
.height
,-1);
722 gdk_draw_rectangle(wcanvas
,widget
->style
->white_gc
,TRUE
,0,0,x
,y
);
723 gdk_draw_rectangle(wcanvas
,widget
->style
->black_gc
,FALSE
,0,0,x
-1,y
-1);
731 fac
=((float)(y
-18-16))/((float)max
);
735 fn
=gdk_font_load("-*-helvetica-medium-r-*-*-8-*-*-*-*-*-*-*");
737 v
=(int)(((float)weekly
[i
])*fac
);
738 gdk_rgb_gc_set_foreground(mygc
,0xc0c0c0);
739 gdk_draw_line(wcanvas
,mygc
,cx
,1,cx
,y
-2);
740 gdk_rgb_gc_set_foreground(mygc
,0x004080);
741 gdk_draw_rectangle(wcanvas
,mygc
,TRUE
,cx
,y
-18-v
,xs
,v
);
742 gdk_rgb_gc_set_foreground(mygc
,0x000000);
743 gdk_draw_string(wcanvas
,fn
,mygc
,cx
,y
-6,wdays
[i
]);
747 gdk_draw_line(wcanvas
,widget
->style
->black_gc
,0,y
-18,x
-1,y
-18);
749 gdk_rgb_gc_set_foreground(mygc
,0xffffff);
750 gdk_draw_rectangle(wcanvas
,mygc
,TRUE
,0,0,23*4,13);
751 gdk_rgb_gc_set_foreground(mygc
,0x000000);
752 gdk_draw_rectangle(wcanvas
,mygc
,FALSE
,0,0,23*4,13);
755 fn
=gdk_font_load("-*-helvetica-medium-r-*-*-10-*-*-*-*-*-*-*");
757 gdk_draw_string(wcanvas
,fn
,mygc
,5,10,"weekday summary");
760 gdk_gc_destroy(mygc
);
766 time_menu(GtkMenuItem
*gmi
,gpointer data
)
779 time_cons
[0]=time_cons
[1]=0;
785 time_cons
[0]=mktime(his
);
789 time_cons
[1]=mktime(his
);
791 case 2: /* yesterday */
797 time_cons
[0]=mktime(his
);
801 time_cons
[1]=mktime(his
);
803 case 3: /* this week */
804 t
-=((long)(24*3600))*((long)(his
->tm_wday
));
809 time_cons
[0]=mktime(his
);
810 time_cons
[1]=time(NULL
);
812 case 4: /* this month */
813 t
-=((long)(24*3600))*((long)(his
->tm_mday
));
818 time_cons
[0]=mktime(his
);
819 time_cons
[1]=time(NULL
);
821 case 5: /* this year */
822 t
-=((long)(24*3600))*((long)(his
->tm_yday
));
827 time_cons
[0]=mktime(his
);
828 time_cons
[1]=time(NULL
);
830 case 6: /* Last 24 hours */
831 time_cons
[0]=t
-24*3600;
834 case 7: /* Last 7 days */
835 time_cons
[0]=t
-7*24*3600;
838 case 8: /* Last 30 days */
839 time_cons
[0]=t
-30*24*3600;
843 time_cons
[0]=t
-365*24*3600;
853 user_menu(GtkMenuItem
*gmi
,gpointer data
)
855 useridx
=*((int *)data
);
860 isp_menu(GtkMenuItem
*gmi
,gpointer data
)
862 ispidx
=*((int *)data
);
867 already_exists(char *s
,GList
*pt
)
870 for(w
=pt
;w
!=NULL
;w
=g_list_next(w
)) {
871 if (!strcmp((char *)(w
->data
),s
))