/*
* SambaSentinel.c
*
* (C) 2001 Robert Kling
* robkli-8@student.luth.se
* http://boombox.campus.luth.se
*
* 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.
*
*
* See INSTALL file for instructions on compiling this program.
*/
#include <gtk/gtk.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
#include "gtk_common.h"
#include "pixmaps/network.xpm"
#include "pixmaps/doc.xpm"
#include "pixmaps/sound.xpm"
#include "pixmaps/search.xpm"
#include "pixmaps/exe.xpm"
#include "pixmaps/none.xpm"
#include "pixmaps/txt.xpm"
#include "pixmaps/offline.xpm"
#define LIVE_BUILD 1
#define DEBUG_PARSING 0
#define GREP_PROCS "smbstatus -S | grep -E \"\\([[:digit:]]{1,3}\\.[[:digit:]]{1,3}\\.\""
#define GREP_FILES "smbstatus -L | grep DENY"
#define VERSION "0.1"
#define REV_DATE "2001-02-26"
#define KILL_SIGNAL 9
#define MAX_PROCS 20
#define MAX_FILES 100
#define NOF_COLUMNS 7
/** GTK callback functions **/
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data);
gint kill_process(GtkMenuItem *item, gpointer *data);
gint add_ban_menu_item(GtkMenuItem *item, gpointer *data);
gint remove_ban_callback(GtkMenuItem *item, gpointer *data);
gint browse_with_jags(GtkMenuItem *item, gpointer *data);
gint about_dialog(GtkMenuItem *item, gpointer *data);
gint select_row(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data);
gint hs_files(GtkWidget *widget, GdkEvent *event, gpointer data);
/** Other functions **/
void print_help_and_exit();
void setup_main_window();
void setup_popup_menu();
void select_row_with_pid(GtkWidget *widget, int pid);
int f_skip_forward(FILE *which_file, int nof_tokens);
void *status_thread(void *);
typedef struct {
unsigned pid;
char service[64];
char machine_name[128];
char machine_ip[20];
char uid[64];
char gid[64];
int file_cnt;
char *files[MAX_FILES];
} samba_proc;
char *titles[NOF_COLUMNS] = {"PID", "Computer", "IP", "UID", "GID", "Share", "Files"};
char cwidths[NOF_COLUMNS] = { 40 , 75 , 95 , 65 , 65 , 55 , 35 };
char *rowptr[NOF_COLUMNS];
char *file_title[1] = { "Files" };
pthread_t t_status_thread;
pthread_mutex_t mutex;
/**
** The following variables MUST ONLY be accessed WITHIN a mutex
** lock or before the status thread is started.
**/
samba_proc *proc_list[MAX_PROCS];
char *ban_list[20];
int ban_cnt;
int proc_cnt, time_to_die;
int selected_pid, update_int = 5;
/**
** End of "mutex-variables".
**/
int selected_row;
GtkWidget *window, *button, *hbox, *vbox, *clist_procs, *clist_files;
GtkWidget *statusbar, *scr_win_procs, *scr_win_files, *box;
GtkWidget *popup_menu, *ban_popup_menu, *kill_menu_item, *ban_menu_item, *menuitem;
GtkWidget *remove_ban_menu_item, *about_menu_item, *jags_menu_item;
GdkPixmap *proc_pixmap, *sound_pixmap, *file_pixmap;
GdkBitmap *proc_mask, *sound_mask, *file_mask;
GtkStyle *style;
/***
*** Main
***/
int main(int argc, char **argv) {
if (argc > 1) {
update_int = atoi(argv[1]);
if (update_int < 1) print_help_and_exit();
}
pthread_mutex_init(&mutex, NULL);
g_thread_init(NULL);
gtk_init(&argc, &argv);
setup_main_window();
setup_popup_menu();
/** Start t_status_thread that runs smbstatus **/
pthread_create(&t_status_thread, NULL, (void *) status_thread, NULL);
/** gtk_main is where the program will be until the user quits **/
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
/** Tell t_status_thread that its time to quit and wait for it to do so **/
pthread_mutex_lock(&mutex);
time_to_die = 1;
pthread_mutex_unlock(&mutex);
printf("\nSAMBA_SENTINEL: Graciously waiting for t_status_thread to exit: "); fflush(stdout);
pthread_join(t_status_thread, NULL);
printf("done.\n");
return 0;
}
/***
*** Print help and exit (if faulty commandline parameter(s))
***/
void print_help_and_exit() {
printf("\nSambaSentinel v%s (%s)\n\nUsage: SambaSentinel [seconds between updates]\n\n", VERSION, REV_DATE);
exit(0);
}
/***
*** Setup and draw the main window
***/
void setup_main_window() {
GtkWidget *test;
int i, j;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_signal_connect(GTK_OBJECT(window), "delete_event", GTK_SIGNAL_FUNC(gtk_main_quit), NULL);
gtk_widget_set_usize( GTK_WIDGET (window), 500, 150);
gtk_window_set_title(GTK_WINDOW (window), "SambaSentinel v0.1");
gtk_container_set_border_width(GTK_CONTAINER (window), 3);
/** Vertical Pack Box **/
vbox = gtk_vbox_new(FALSE, 1);
gtk_container_add(GTK_CONTAINER (window), vbox);
gtk_widget_show(vbox);
/** Scrolled Window (for clist_procs) **/
scr_win_procs = gtk_scrolled_window_new(NULL, NULL);
gtk_container_set_border_width (GTK_CONTAINER (scr_win_procs), 0);
gtk_widget_set_usize(scr_win_procs, 100, 50);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scr_win_procs), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox), scr_win_procs, TRUE, TRUE, 0);
gtk_widget_show(scr_win_procs);
/** CList (for procs) **/
clist_procs = gtk_clist_new_with_titles(NOF_COLUMNS, titles);
gtk_container_set_border_width (GTK_CONTAINER (clist_procs), 0);
gtk_clist_set_button_actions(GTK_CLIST(clist_procs), 2, 1);
gtk_signal_connect(GTK_OBJECT(clist_procs), "select_row", GTK_SIGNAL_FUNC(select_row), NULL);
gtk_signal_connect(GTK_OBJECT(clist_procs), "unselect_row", GTK_SIGNAL_FUNC(select_row), NULL);
gtk_clist_column_titles_passive(GTK_CLIST(clist_procs));
gtk_clist_set_row_height(GTK_CLIST(clist_procs), 14);
gtk_clist_set_shadow_type(GTK_CLIST(clist_procs), GTK_SHADOW_IN);
for (i = 0; i < NOF_COLUMNS; i++) {
//gtk_clist_set_column_auto_resize(GTK_CLIST(clist_procs), i, TRUE);
gtk_clist_set_column_width(GTK_CLIST(clist_procs), i, cwidths[i]);
}
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scr_win_procs), clist_procs);
gtk_widget_show(clist_procs);
/** Scrolled Window (for clist_files) **/
scr_win_files = gtk_scrolled_window_new(NULL, NULL);
gtk_container_set_border_width (GTK_CONTAINER (scr_win_files), 0);
gtk_widget_set_usize(scr_win_files, 100, 50);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW(scr_win_files), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_box_pack_start(GTK_BOX(vbox), scr_win_files, TRUE, TRUE, 0);
gtk_widget_show(scr_win_files);
/** CList (for files) **/
clist_files = gtk_clist_new_with_titles(1,file_title);
gtk_clist_set_button_actions(GTK_CLIST(clist_files), 0, 0);
gtk_clist_set_button_actions(GTK_CLIST(clist_files), 1, 0);
gtk_clist_set_button_actions(GTK_CLIST(clist_files), 2, 0);
gtk_container_set_border_width (GTK_CONTAINER (clist_files), 0);
gtk_clist_column_titles_passive(GTK_CLIST(clist_files));
gtk_clist_set_row_height(GTK_CLIST(clist_files), 14);
gtk_clist_set_shadow_type(GTK_CLIST(clist_files), GTK_SHADOW_ETCHED_IN);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scr_win_files), clist_files);
gtk_widget_show(clist_files);
/** Horizontal Pack Box **/
hbox = gtk_hbox_new(TRUE, 1);
gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show(hbox);
/** Show/Hide files Button **/
//button = gtk_button_new_with_label ("Show/Hide files");
button = gtk_button_new_with_label_with_pixmap("Hide/Show files", doc_xpm);
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (hs_files), (gpointer) "Show/Hide files");
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_widget_set_usize(button, 100, 23);
gtk_widget_show(button);
/** Kill Button **/
//button = gtk_button_new_with_label ("Kill process");
button = gtk_button_new_with_label_with_pixmap("Kill process", exe_xpm);
gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (kill_process), NULL);
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_widget_show(button);
/** Ban Button **/
//button = gtk_button_new_with_label ("Ban user");
button = gtk_button_new_with_label_with_pixmap("Ban user", exe_xpm);
//gtk_signal_connect (GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (delete_event), (gpointer) "Quit");
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_widget_set_sensitive(button, FALSE);
gtk_widget_show(button);
/** Quit Button **/
//button = gtk_button_new_with_label ("Quit");
button = gtk_button_new_with_label_with_pixmap("Quit", offline_xpm);
gtk_signal_connect(GTK_OBJECT (button), "clicked", GTK_SIGNAL_FUNC (delete_event), (gpointer) "Quit");
gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, TRUE, 0);
gtk_widget_show(button);
/** Statusbar **/
statusbar = gtk_statusbar_new();
gtk_box_pack_start(GTK_BOX(vbox), statusbar, FALSE, FALSE, 0);
gtk_widget_set_usize(statusbar, 100, 20);
gtk_widget_show(statusbar);
/** Pretty much done.. so just show everything. **/
gtk_widget_show(window);
/** Create the pixmaps for computer and files **/
style = gtk_widget_get_style( window );
//proc_pixmap = gdk_pixmap_create_from_xpm(window->window, &proc_mask, &proc_style->bg[GTK_STATE_NORMAL], "network.xpm" );
proc_pixmap = gdk_pixmap_create_from_xpm_d(window->window, &proc_mask, &style->bg[GTK_STATE_NORMAL], network_xpm );
//file_style = gtk_widget_get_style( window );
//file_pixmap = gdk_pixmap_create_from_xpm(window->window, &file_mask, &file_style->bg[GTK_STATE_NORMAL], "doc.xpm" );
file_pixmap = gdk_pixmap_create_from_xpm_d(window->window, &file_mask, &style->bg[GTK_STATE_NORMAL], doc_xpm );
//sound_style = gtk_widget_get_style( window );
//sound_pixmap = gdk_pixmap_create_from_xpm(window->window, &sound_mask, &sound_style->bg[GTK_STATE_NORMAL], "sound.xpm" );
sound_pixmap = gdk_pixmap_create_from_xpm_d(window->window, &sound_mask, &style->bg[GTK_STATE_NORMAL], sound_xpm );
}
/***
*** Setup the right-mouse-button-clicked-on-process popup-menu
***/
void setup_popup_menu() {
popup_menu = gtk_menu_new();
ban_popup_menu = gtk_menu_new();
menuitem = gtk_menu_item_new_with_label_with_pixmap("SambaSentinel", none_xpm);
gtk_widget_show (menuitem);
gtk_container_add (GTK_CONTAINER (popup_menu), menuitem);
gtk_widget_set_sensitive (menuitem, FALSE);
menuitem = gtk_menu_item_new();
gtk_widget_show (menuitem);
gtk_container_add (GTK_CONTAINER (popup_menu), menuitem);
gtk_widget_set_sensitive(menuitem, FALSE);
kill_menu_item = gtk_menu_item_new_with_label_with_pixmap("Kill process", exe_xpm);
gtk_widget_show (kill_menu_item);
gtk_container_add (GTK_CONTAINER(popup_menu), kill_menu_item);
gtk_signal_connect (GTK_OBJECT(kill_menu_item), "activate", GTK_SIGNAL_FUNC (kill_process), NULL);
ban_menu_item = gtk_menu_item_new_with_label_with_pixmap("Ban computer", none_xpm);
gtk_widget_show (ban_menu_item);
gtk_container_add (GTK_CONTAINER (popup_menu), ban_menu_item);
gtk_signal_connect(GTK_OBJECT(ban_menu_item), "activate", GTK_SIGNAL_FUNC (add_ban_menu_item), NULL);
gtk_widget_set_sensitive(ban_menu_item, FALSE);
//remove_ban_menu_item = gtk_menu_item_new_with_label("Un-ban computer");
remove_ban_menu_item = gtk_menu_item_new_with_label_with_pixmap("Un-ban computer", none_xpm);
gtk_widget_show (remove_ban_menu_item);
gtk_container_add (GTK_CONTAINER (popup_menu), remove_ban_menu_item);
gtk_menu_item_set_submenu(GTK_MENU_ITEM(remove_ban_menu_item), ban_popup_menu);
gtk_widget_set_sensitive(remove_ban_menu_item, FALSE);
jags_menu_item = gtk_menu_item_new_with_label_with_pixmap("Browse with Jags", search_xpm);
gtk_widget_show (jags_menu_item);
gtk_container_add (GTK_CONTAINER (popup_menu), jags_menu_item);
gtk_signal_connect (GTK_OBJECT(jags_menu_item), "activate", GTK_SIGNAL_FUNC (browse_with_jags), NULL);
about_menu_item = gtk_menu_item_new_with_label_with_pixmap("About", txt_xpm);
gtk_widget_show(about_menu_item);
gtk_container_add(GTK_CONTAINER (popup_menu), about_menu_item);
gtk_signal_connect(GTK_OBJECT(about_menu_item), "activate", GTK_SIGNAL_FUNC (about_dialog), NULL);
}
/***
*** Main program quit callback
***/
gint delete_event(GtkWidget *widget, GdkEvent *event, gpointer data) {
gtk_main_quit();
return FALSE;
}
/***
*** Add a computer to the ban-list and sub-popup-menu (not active yet)
***/
gint add_ban_menu_item(GtkMenuItem *item, gpointer *data) {
GtkWidget *new_menu_item;
char str[64];
gtk_clist_remove(GTK_CLIST(clist_procs), selected_row);
gtk_clist_clear(GTK_CLIST(clist_files));
pthread_mutex_lock(&mutex);
strncpy(str, proc_list[selected_row]->machine_name, 63);
pthread_mutex_unlock(&mutex);
ban_list[ban_cnt] = malloc(strlen(str)+1);
strcpy(ban_list[ban_cnt], str);
new_menu_item = gtk_menu_item_new_with_label(str);
gtk_widget_show(new_menu_item);
gtk_container_add(GTK_CONTAINER (ban_popup_menu), GTK_WIDGET(new_menu_item));
gtk_signal_connect (GTK_OBJECT(new_menu_item), "activate", GTK_SIGNAL_FUNC(remove_ban_callback), ban_list[ban_cnt++]);
return TRUE;
}
/***
*** Remove a computer from the ban-list and sub-popup-menu (not active yet)
***/
gint remove_ban_callback(GtkMenuItem *item, gpointer *data) {
int i;
pthread_mutex_lock(&mutex);
for (i = 0; i < ban_cnt; i++)
if (strcmp(ban_list[i], (char *)data) == 0) {
free(ban_list[i]);
for (i; i < ban_cnt; i++) ban_list[i] = ban_list[i+1];
ban_cnt--;
break;
}
pthread_mutex_unlock(&mutex);
gtk_widget_destroy(GTK_WIDGET(item));
return TRUE;
}
/***
*** Popup the about dialog-window
***/
gint about_dialog(GtkMenuItem *item, gpointer *data) {
char str[356];
sprintf(str,"SambaSentinel v%s\n\n"
"Copyright (C) 2001 Robert Kling\n"
"http://boombox.campus.luth.se", VERSION, REV_DATE);
popup_dialog(130, FALSE, "About", str, "Close");
return TRUE;
}
/***
*** Browse with Jags callback, check for availibilty etc.
***/
gint browse_with_jags(GtkMenuItem *item, gpointer *data) {
char str[128] = { "jags --help 1> /dev/null" };
int sysret;
sysret = system(str);
switch (sysret) {
case 0:
pthread_mutex_unlock(&mutex);
sprintf(str,"jags -c %s 1> /dev/null &", proc_list[selected_row]->machine_name);
pthread_mutex_unlock(&mutex);
system(str);
break;
case -1:
popup_dialog(100, TRUE, "(SambaSentinel) Browse with Jags",
"An unknown error occured when trying to start Jags.",
"Close");
break;
default:
popup_dialog(100, TRUE, "(SambaSentinel) Browse with Jags",
"There appear to be a problem starting Jags. Are you sure you have it installed?",
"Close");
break;
}
return TRUE;
}
/***
*** Kill process callback
***/
gint kill_process(GtkMenuItem *item, gpointer *data) {
char str[128];
int sysret;
if (selected_pid != 0) {
sysret = kill(selected_pid, KILL_SIGNAL);
if (sysret) {
switch (errno) {
case EINVAL:
sprintf(str,"ERROR: kill signal %d is not allowed on your system..",KILL_SIGNAL);
popup_dialog(100, TRUE, "(SambaSentinel) Kill process", str, "Close");
break;
case ESRCH:
sprintf(str,"ERROR: process %d does not exist.",selected_pid);
popup_dialog(100, TRUE, "(SambaSentinel) Kill process", str, "Close");
break;
case EPERM:
sprintf(str,"ERROR: You dont have permission to kill the selected process.");
popup_dialog(100, TRUE, "(SambaSentinel) Kill process", str, "Close");
break;
}
} else {
gtk_clist_remove(GTK_CLIST(clist_procs), selected_row);
gtk_clist_clear(GTK_CLIST(clist_files));
}
}
return TRUE;
}
/***
*** Select row callback (for processes)
***/
gint select_row(GtkWidget *widget, gint row, gint column, GdkEventButton *event, gpointer data) {
char newtitle[64] = "File accesses by ";
char *ptr[1];
int j;
pthread_mutex_lock(&mutex);
gtk_clist_freeze(GTK_CLIST(clist_files));
gtk_clist_clear(GTK_CLIST(clist_files));
strncat(newtitle, proc_list[row]->machine_name, 42);
gtk_clist_set_column_title( GTK_CLIST(clist_files), 0, newtitle);
selected_pid = proc_list[row]->pid;
selected_row = row;
for (j = 0; j < proc_list[row]->file_cnt; j++) {
ptr[0] = proc_list[row]->files[j];
gtk_clist_append(GTK_CLIST(clist_files), ptr);
if ((char *)strstr(ptr[0], ".mp3") != NULL)
gtk_clist_set_pixtext(GTK_CLIST(clist_files), j, 0, ptr[0], 5, sound_pixmap, sound_mask );
else
gtk_clist_set_pixtext(GTK_CLIST(clist_files), j, 0, ptr[0], 5, file_pixmap, file_mask );
}
gtk_clist_thaw(GTK_CLIST(clist_files));
pthread_mutex_unlock(&mutex);
if ((event != NULL) && (event->button == 3)) {
gtk_menu_popup(GTK_MENU(popup_menu), NULL, NULL, NULL, NULL, 0, event->time);
// Does anybody know how to give the popup focus so that menuitems 'react' when the mouse is over them?
//gtk_widget_grab_focus(GTK_WIDGET(popup_menu));
}
return TRUE;
}
/***
*** Hide and show files callback
***/
gint hs_files(GtkWidget *widget, GdkEvent *event, gpointer data) {
static int files_visible = 1;
if (files_visible) {
gtk_widget_hide(scr_win_files);
files_visible = 0;
}
else {
gtk_widget_show(scr_win_files);
files_visible = 1;
}
return TRUE;
}
/***
*** The status thread that continously runs smbstatus and updates the lists
***/
void *status_thread(void *arg) {
int i, j, id;
char slask[256], slask2[256], name[256];
FILE *fp;
while (1) {
#if LIVE_BUILD
strcpy(slask2, GREP_PROCS);
strcat(slask2, " >");
strcpy(slask, getenv("HOME"));
strcat(slask, "/.smbprocs.tmp");
strcat(slask2, slask);
system(slask2);
if ((fp = fopen(slask,"r")) == NULL) exit(0);
#else
if ((fp = fopen("procs.txt","r")) == NULL) exit(0);
#endif
proc_cnt = 0;
pthread_mutex_lock(&mutex);
while (!feof(fp) && (proc_cnt < MAX_PROCS)) {
if (proc_list[proc_cnt] != NULL) {
for (i = 0; i < proc_list[proc_cnt]->file_cnt; i++) free(proc_list[proc_cnt]->files[i]);
free(proc_list[proc_cnt]);
}
proc_list[proc_cnt] = (samba_proc *)calloc(1,sizeof(samba_proc));
proc_list[proc_cnt]->file_cnt = 0;
fscanf(fp,"%s",slask); if (feof(fp)) break;
strncpy(proc_list[proc_cnt]->service, slask, 64);
//printf("\n%s",slask);
fscanf(fp,"%s",slask);
strncpy(proc_list[proc_cnt]->uid, slask, 64);
//printf("\n%s",slask);
fscanf(fp,"%s",slask);
strncpy(proc_list[proc_cnt]->gid, slask, 64);
//printf("\n%s",slask);
fscanf(fp,"%s",slask);
proc_list[proc_cnt]->pid = atoi(slask);
//printf("\n%s",slask);
fscanf(fp,"%s",slask);
strncpy(proc_list[proc_cnt]->machine_name, slask, 128);
//printf("\n%s",slask);
fscanf(fp,"%s",slask);
strncpy(proc_list[proc_cnt]->machine_ip, slask+1, 20);
proc_list[proc_cnt]->machine_ip[strlen(proc_list[proc_cnt]->machine_ip)-1] = 0;
//printf("\n%s",slask);
f_skip_forward(fp,5);
proc_cnt++;
}
fclose(fp);
#if LIVE_BUILD
strcpy(slask2, GREP_FILES);
strcat(slask2, " >");
//strcpy(slask2, "smbstatus -L | grep DENY > ");
strcpy(slask, getenv("HOME"));
strcat(slask, "/.smbfiles.tmp");
strcat(slask2, slask);
system(slask2);
if ((fp = fopen(slask,"r")) == NULL) exit(0);
#else
if ((fp = fopen("files.txt","r")) == NULL) exit(0);
#endif
while (!feof(fp)) {
fscanf(fp,"%s",slask);
//printf("\n%s",slask);
for (i = 0; i < proc_cnt; i++)
if (atoi(slask) == proc_list[i]->pid) break;
for (j = 1; j < 4; j++) {
fscanf(fp,"%s",slask);
//printf("\nj = %d %s",j,slask);
}
fscanf(fp,"%s",name);
fgets(slask, 255, fp);
strcat(name,slask);
name[strlen(name)-1] = 0;
//printf("\n%s",name);
if ((i < proc_cnt) && (proc_list[i]->file_cnt < MAX_FILES)) {
proc_list[i]->files[proc_list[i]->file_cnt] = (char *)malloc(strlen(name)+1);
strcpy(proc_list[i]->files[proc_list[i]->file_cnt], name);
proc_list[i]->file_cnt++;
}
}
fclose(fp);
gdk_threads_enter();
id = gtk_statusbar_get_context_id(GTK_STATUSBAR(statusbar), "");
gtk_statusbar_push(GTK_STATUSBAR(statusbar), id, "Updating list.." );
gtk_clist_freeze(GTK_CLIST(clist_procs));
gtk_clist_clear(GTK_CLIST(clist_procs));
for (i = 0; i < proc_cnt; i++) {
#if DEBUG_PARSING
printf("\n\nService: %s",proc_list[i]->service);
printf("\nPID : %d",proc_list[i]->pid);
printf("\nMachine: %s",proc_list[i]->machine_name);
printf("\nIP : %s",proc_list[i]->machine_ip);
printf("\nFiles :\n");
for (j = 0; j < proc_list[i]->file_cnt; j++) printf("%s\n",proc_list[i]->files[j]);
#endif
sprintf(slask,"%d",proc_list[i]->pid);
rowptr[0] = slask;
rowptr[1] = proc_list[i]->machine_name;
rowptr[2] = proc_list[i]->machine_ip;
rowptr[3] = proc_list[i]->uid;
rowptr[4] = proc_list[i]->gid;
rowptr[5] = proc_list[i]->service;
sprintf(slask2,"%d",proc_list[i]->file_cnt);
rowptr[6] = slask2;
gtk_clist_append(GTK_CLIST(clist_procs), rowptr);
gtk_clist_set_pixtext(GTK_CLIST(clist_procs), i, 1, rowptr[1], 5, proc_pixmap, proc_mask );
}
gtk_clist_thaw(GTK_CLIST(clist_procs));
for (i = 0; i < proc_cnt; i++)
if (proc_list[i]->pid == selected_pid) {
pthread_mutex_unlock(&mutex);
select_row_with_pid(clist_procs, selected_pid);
break;
}
else if (i == proc_cnt-1) selected_pid = 0;
gdk_threads_leave();
pthread_mutex_unlock(&mutex);
for (i = 0; i < update_int; i++) {
usleep(1000000);
if (i == 0) gtk_statusbar_pop(GTK_STATUSBAR(statusbar), id);
pthread_mutex_lock(&mutex);
if (time_to_die) {
pthread_mutex_unlock(&mutex);
pthread_exit(NULL);
} else
pthread_mutex_unlock(&mutex);
}
} // end of while
}
/***
*** A function to select the process with a given pid (called after update)
***/
void select_row_with_pid(GtkWidget *widget, int pid) {
char *test;
int i = 0, j;
for (i = 0; i < proc_cnt; i++) {
gtk_clist_get_text( GTK_CLIST(widget), i, 0, &test);
sscanf(test, "%d", &j);
if (j == pid) {
gtk_clist_select_row(GTK_CLIST(clist_procs), i, 0);
break;
}
}
}
/***
*** Skip nof_tokes in a file
***/
int f_skip_forward(FILE *which_file, int nof_tokens) {
int i = 0;
char slask[128];
while (!feof(which_file) && (i++ < nof_tokens)) fscanf(which_file,"%s",slask);
if (i == nof_tokens) return 1; else return 0;
}
syntax highlighted by Code2HTML, v. 0.9.1