Logo Search packages:      
Sourcecode: dcgui version File versions  Download package

global_user.c

/* dc_gui2 - a GTK+2 GUI for DCTC
 * Copyright (C) 2002 Eric Prevoteau
 *
 * global_user.c: Copyright (C) Eric Prevoteau <www@a2pb.gotdns.org>
 *
 * 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.
 */
/*
$Id: global_user.c,v 1.18 2004/01/02 19:53:06 ericprev Exp $
*/

#ifdef HAVE_CONFIG_H
#  include <config.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <gtk/gtk.h>

#include "global_user.h"
#include "main.h"

static GHashTable *glob_user=NULL;

static void gu_free_entry(GLOB_USER *gu);

/**********************************/
/* return the structure of a user */
/**********************************/
GLOB_USER *gu_get_user(const char *nickname)
{
      return gu_add_user(nickname,FALSE,NULL);
}

/***********************************************************/
/* return the structure of a user or create it if required */
/*********************************************************************************/
/* input: nickname to find/add                                                   */
/*        if with_creation is TRUE, when a nick is not found, it is created      */
/* output: GLOB_USER (always !=NULL)                                             */
/*         if was_created is not NULL, it is set to TRUE if the user was created */
/*********************************************************************************/
GLOB_USER *gu_add_user(const char *unfmt_nick, gboolean with_creation, gboolean *was_created)
{
      if(glob_user!=NULL)
      {
            GLOB_USER *gu;

            gu=g_hash_table_lookup(glob_user,unfmt_nick);
            if(gu!=NULL)
            {
                  if(was_created!=NULL)
                        *was_created=FALSE;
                  return gu;
            }
      }

      if(with_creation==FALSE)
      {
            if(was_created!=NULL)
                  *was_created=FALSE;
            return NULL;                  /* no user and no creation allowed */
      }
      else
      {
            GLOB_USER *ngu;

            if(glob_user==NULL)
            {
                  glob_user=g_hash_table_new_full(g_str_hash,g_str_equal,NULL,(gpointer)gu_free_entry);
            }

            ngu=g_malloc(sizeof(GLOB_USER));

            if(was_created!=NULL)
                  *was_created=TRUE;

            ngu->unfmt_nick=g_strdup(unfmt_nick);
            ngu->unfmt_email=NULL;
            ngu->unfmt_desc=NULL;
            ngu->unfmt_size=0;
            ngu->is_op=FALSE;
            ngu->cnx_type="";
            ngu->flags=0;
            ngu->is_connected=FALSE;

            if(utf8_mode==TRUE)
            {
                  ngu->fmt_nick=g_strdup(ngu->unfmt_nick);
            }
            else
            {
                  ngu->fmt_nick=g_locale_to_utf8(ngu->unfmt_nick,-1,NULL,NULL,NULL);
                  if(ngu->fmt_nick==NULL)
                  {
                        ngu->fmt_nick=g_strdup(ngu->unfmt_nick);  /* in case of impossible translation, we must be sure */
                                                                                                            /* to not have fmt_nick=NULL */
                  }
            }
            ngu->fmt_email=NULL;
            ngu->fmt_desc=NULL;
            ngu->fmt_size=NULL;
            ngu->front_color=NULL;
            ngu->back_color=NULL;
            ngu->fast_color=NULL;
            ngu->back_present_color=NULL;

            ngu->gu_ref=g_array_new(FALSE,FALSE,sizeof(GLOB_USER_REF));
            ngu->dirty=TRUE;

            g_hash_table_insert(glob_user,ngu->unfmt_nick,ngu);
            return ngu;
      }
}

/*********************************************************/
/* modify a GLOB_USER entry with possible display update */
/*********************************************************/
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* unfmt_email can be NULL */
gboolean gu_set_email(GLOB_USER *gu, const char *unfmt_email, gboolean with_display_update)
{
      if(gu->unfmt_email)
      {
            if(unfmt_email)
            {
                  if(!strcmp(gu->unfmt_email,unfmt_email))
                        return FALSE;           /* no change */
                  g_free(gu->unfmt_email);
            }
      }
      else
      {
            if(unfmt_email==NULL)
                  return FALSE;           /* no change, both are NULL */
      }

      if(gu->fmt_email)
            g_free(gu->fmt_email);

      if(unfmt_email!=NULL)
      {
            gu->unfmt_email=g_strdup(unfmt_email);

            if(utf8_mode==TRUE)
            {
                  gu->fmt_email=g_strdup(gu->unfmt_email);
            }
            else
            {
                  gu->fmt_email=g_locale_to_utf8(gu->unfmt_email,-1,NULL,NULL,NULL);
            }
      }
      else
      {
            gu->unfmt_email=NULL;
            gu->fmt_email=NULL;
      }
      gu->dirty=TRUE;

      if(with_display_update)
            gu_do_user_row_update(gu);
      return TRUE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* unfmt_desc can be NULL */
gboolean gu_set_desc(GLOB_USER *gu, const char *unfmt_desc, gboolean with_display_update)
{
      if(gu->unfmt_desc)
      {
            if(unfmt_desc)
            {
                  if(!strcmp(gu->unfmt_desc,unfmt_desc))
                        return FALSE;           /* no change */
                  g_free(gu->unfmt_desc);
            }
      }
      else
      {
            if(unfmt_desc==NULL)
                  return FALSE;           /* no change, both are NULL */
      }
      if(gu->fmt_desc)
            g_free(gu->fmt_desc);

      if(unfmt_desc!=NULL)
      {
            gu->unfmt_desc=g_strdup(unfmt_desc);

            if(utf8_mode==TRUE)
            {
                  gu->fmt_desc=g_strdup(gu->unfmt_desc);
            }
            else
            {
                  gu->fmt_desc=g_locale_to_utf8(gu->unfmt_desc,-1,NULL,NULL,NULL);
            }
      }
      else
      {
            gu->unfmt_desc=NULL;
            gu->fmt_desc=NULL;
      }
      gu->dirty=TRUE;

      if(with_display_update)
            gu_do_user_row_update(gu);
      return TRUE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
gboolean gu_set_size(GLOB_USER *gu, const guint64 unfmt_size, gboolean with_display_update)
{
      GString *fsize;
      double vsize;

      if(gu->unfmt_size==unfmt_size)
            return FALSE;           /* no changes ? */
      
      gu->unfmt_size=unfmt_size;

      fsize=g_string_new("");
      vsize=unfmt_size;

      if(vsize>(1024.0*1024.0*1024.0))
#ifndef NO_PRINTF_LOCALE
            g_string_sprintf(fsize,"%'.2fGB",vsize/(1024.0*1024.0*1024.0));   /* NO_PRINTF_LOCAL support added */
#else
            g_string_sprintf(fsize,"%.2fGB",vsize/(1024.0*1024.0*1024.0));          
#endif
      else if(vsize>(1024.0*1024.0))
            g_string_sprintf(fsize,"%.2fMB",vsize/(1024.0*1024.0));
      else if(vsize>(1024.0))
            g_string_sprintf(fsize,"%.2fKB",vsize/(1024.0));
      else
            g_string_sprintf(fsize,"%.2fB",vsize);

      if(gu->fmt_size==NULL)
      {
            gu->fmt_size=g_strdup(fsize->str);
            gu->dirty=TRUE;
      }
      else
      {
            if(strcmp(fsize->str,gu->fmt_size))
            {
                  g_free(gu->fmt_size);
                  gu->fmt_size=g_strdup(fsize->str);
                  gu->dirty=TRUE;
            }
            else
                  with_display_update=FALSE;          /* no visible change */
      }
      g_string_free(fsize,TRUE);

      if(with_display_update)
            gu_do_user_row_update(gu);
      return TRUE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
gboolean gu_set_op_flag(GLOB_USER *gu, const gboolean is_op, gboolean with_display_update)
{
      if(gu->is_op==is_op)
            return FALSE;           /* no change */

      gu->is_op=is_op;
      if(gu->is_op)
            gu->front_color="red";
      else
            gu->front_color=NULL;
      gu->dirty=TRUE;

      if(with_display_update)
            gu_do_user_row_update(gu);
      return TRUE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static const char *lst_cnx_type[]=
                                                      {
                                                            "56Kbps",
                                                            "33.6Kbps",
                                                            "28.8Kbps",
                                                            "Satellite",            /* according to DC, passive mode is required here */
                                                            "ISDN",
                                                            "DSL",
                                                            "Cable",
                                                            "LAN(T1)",
                                                            "LAN(T3)",
                                                            NULL
                                                      };

static const char *get_const_cnx_type(const char *cnx_type)
{
      int i;

      i=0;
      while(lst_cnx_type[i]!=NULL)
      {
            if(!strcmp(cnx_type,lst_cnx_type[i]))
                  return lst_cnx_type[i];
            i++;
      }
      return "Invalid";
}

gboolean gu_set_cnx_type(GLOB_USER *gu, const char *cnx_type, gboolean with_display_update)
{
      if((gu->cnx_type!=NULL)&&(!strcmp(gu->cnx_type,cnx_type)))
            return FALSE;

      gu->cnx_type=get_const_cnx_type(cnx_type);
      gu->dirty=TRUE;

      if(with_display_update)
            gu_do_user_row_update(gu);
      return TRUE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
gboolean gu_set_flags(GLOB_USER *gu, const guint flags, gboolean with_display_update)
{
      if(gu->flags==flags)
            return FALSE;           /* no change */

      gu->flags=flags;
      if(gu->flags&2)         /* away flag */
            gu->back_color="grey87";
      else
            gu->back_color=NULL;

      if(gu->flags&8)         /* fast flag */
            gu->fast_color="green";
      else
            gu->fast_color=gu->back_color;
      gu->dirty=TRUE;

      if(with_display_update)
            gu_do_user_row_update(gu);
      return TRUE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
gboolean gu_set_is_connected(GLOB_USER *gu, const gboolean is_connected, gboolean with_display_update)
{
      if(gu->is_connected==is_connected)
            return FALSE;           /* no change */

      gu->is_connected=is_connected;

      if(gu->is_connected==TRUE)
            gu->back_present_color="green";
      else
            gu->back_present_color=NULL;
      gu->dirty=TRUE;

      if(with_display_update)
            gu_do_user_row_update(gu);
      return TRUE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/***************************************/
/* force a redisplay of the given user */
/***************************************/
void gu_do_user_row_update(GLOB_USER *gu)
{
      int i;

      if((gu==NULL)||(gu->gu_ref->len==0))
            return;           /* nothing to update */

      for(i=gu->gu_ref->len-1;i>=0;i--)
      {
            GLOB_USER_REF *gur;

            gur=&(g_array_index(gu->gu_ref,GLOB_USER_REF,i));

            if(gtk_tree_row_reference_valid(gur->gtrr))
            {
                  GtkTreePath *gur_path;
                  GtkTreeIter gur_iter;

                  gur_path=gtk_tree_row_reference_get_path(gur->gtrr);
                  if(gtk_tree_model_get_iter(gur->gtm,&gur_iter,gur_path))
                  {
                        /* notify the row changes to the tree model */
                        gtk_tree_model_row_changed(gur->gtm,gur_path,&gur_iter);
                  }

                  gtk_tree_path_free(gur_path);
            }
            else
            {
                  /* invalid reference => remove it */
                  gtk_tree_row_reference_free(gur->gtrr);
                  g_array_remove_index_fast(gu->gu_ref,i);
            }
      }
      gu->dirty=FALSE;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*********************************/
/* reference a new displayed row */
/********************************************/
/* input: the GtkTreeRowReference is stolen */
/********************************************/
void gu_ref(GLOB_USER *gu, GtkTreeModel *gtm, GtkTreeRowReference *gtrr)
{
      GLOB_USER_REF ngur;

      ngur.gtm=gtm;
      ngur.gtrr=gtrr;

      g_array_append_val(gu->gu_ref,ngur);
}

/************************************************/
/* reference a new displayed row using its iter */
/************************************************/
void gu_ref_from_iter(GLOB_USER *gu, GtkTreeModel *gtm, GtkTreeIter *giter)
{
      GLOB_USER_REF ngur;
      GtkTreePath *gtp;

      gtp=gtk_tree_model_get_path(gtm,giter);

      ngur.gtm=gtm;
      ngur.gtrr=gtk_tree_row_reference_new(gtm,gtp);

      g_array_append_val(gu->gu_ref,ngur);

      gtk_tree_path_free(gtp);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/***********************************/
/* unreference a new displayed row */
/***********************************/
void gu_unref(GLOB_USER *gu, GtkTreeModel *gtm, GtkTreeRowReference *gtrr)
{
      int i;
      GtkTreePath *gtp;

      gtp=gtk_tree_row_reference_get_path(gtrr);

      for(i=0;i<gu->gu_ref->len;i++)
      {
            GLOB_USER_REF *gur;

            gur=&(g_array_index(gu->gu_ref,GLOB_USER_REF,i));
            if(gur->gtm==gtm)
            {
                  GtkTreePath *gur_path;

                  gur_path=gtk_tree_row_reference_get_path(gur->gtrr);
                  if(!gtk_tree_path_compare(gur_path,gtp))
                  {
                        gtk_tree_path_free(gur_path);
                        gtk_tree_row_reference_free(gur->gtrr);
                        g_array_remove_index_fast(gu->gu_ref,i);
                        break;
                  }
                  gtk_tree_path_free(gur_path);
            }
      }

      gtk_tree_path_free(gtp);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/**************************************************/
/* unreference a new displayed row using its iter */
/**************************************************/
void gu_unref_from_iter(GLOB_USER *gu, GtkTreeModel *gtm, GtkTreeIter *iter)
{
      int i;
      GtkTreePath *gtp;

      gtp=gtk_tree_model_get_path(gtm,iter);

      for(i=0;i<gu->gu_ref->len;i++)
      {
            GLOB_USER_REF *gur;

            gur=&(g_array_index(gu->gu_ref,GLOB_USER_REF,i));
            if(gur->gtm==gtm)
            {
                  GtkTreePath *gur_path;

                  gur_path=gtk_tree_row_reference_get_path(gur->gtrr);
                  if(!gtk_tree_path_compare(gur_path,gtp))
                  {
                        gtk_tree_path_free(gur_path);
                        gtk_tree_row_reference_free(gur->gtrr);
                        g_array_remove_index_fast(gu->gu_ref,i);
                        break;
                  }
                  gtk_tree_path_free(gur_path);
            }
      }

      gtk_tree_path_free(gtp);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
static GLOB_USER_REF *get_gur_by_model(GArray *guguref,GtkTreeModel *gtm)
{
      int i;

      for(i=0;i<guguref->len;i++)
      {
            GLOB_USER_REF *gur;

            gur=&(g_array_index(guguref,GLOB_USER_REF,i));
            if(gur->gtm==gtm)
                  return gur;
      }
      return NULL;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*******************************************************************/
/* search inside the given user for a reference on the given model */
/*******************************************************************/
/* output: NULL= not found else a TreePath (to free) */
/*****************************************************/
GtkTreePath *gu_user_get_path_for_model(GLOB_USER *gu, GtkTreeModel *gtm)
{
      GtkTreePath *gtp=NULL;
      GLOB_USER_REF *gur;

      gur=get_gur_by_model(gu->gu_ref,gtm);
      if(gur)
            gtp=gtk_tree_row_reference_get_path(gur->gtrr);
      return gtp;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*******************************************************************/
/* search inside the given user for a reference on the given model */
/*******************************************************************/
/* output: TRUE if the iter is valid and "giter" is populated */
/**************************************************************/
gboolean gu_user_get_iter_for_model(GLOB_USER *gu, GtkTreeModel *gtm, GtkTreeIter *iter)
{
      gboolean output=FALSE;
      GLOB_USER_REF *gur;

      gur=get_gur_by_model(gu->gu_ref,gtm);
      if(gur)
      {
            GtkTreePath *gtp;

            gtp=gtk_tree_row_reference_get_path(gur->gtrr);

            output=gtk_tree_model_get_iter(gtm,iter,gtp);
            gtk_tree_path_free(gtp);
      }
      return output;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*******************************************************************/
/* search inside the given user for a reference on the given model */
/***********************************************************************/
/* output: NULL= not found else a TreeRowReference (must not be freed) */
/***********************************************************************/
GtkTreeRowReference *gu_user_get_reference_for_model(GLOB_USER *gu, GtkTreeModel *gtm)
{
      GtkTreeRowReference *gtrr=NULL;
      GLOB_USER_REF *gur;

      gur=get_gur_by_model(gu->gu_ref,gtm);
      if(gur)
            return gur->gtrr;
      return gtrr;
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*******************************************************/
/* free allocated memory and destroy a GLOB_USER entry */
/*******************************************************/
static void gu_free_entry(GLOB_USER *gu)
{
      if(gu->unfmt_nick) g_free(gu->unfmt_nick);
      if(gu->unfmt_email) g_free(gu->unfmt_email);
      if(gu->unfmt_desc) g_free(gu->unfmt_desc);
      if(gu->fmt_nick) g_free(gu->fmt_nick);
      if(gu->fmt_email) g_free(gu->fmt_email);
      if(gu->fmt_desc) g_free(gu->fmt_desc);
      if(gu->fmt_size) g_free(gu->fmt_size);

      g_array_free(gu->gu_ref,TRUE);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/********************************************************************************/
/* return TRUE if the entry has no reference (ready to be destroyed) else FALSE */
/* input: only the value is meaning full, it is a GLOB_USER*                    */
/********************************************************************************/
static gboolean has_no_ref(gpointer key, gpointer value, gpointer user_data)
{
      return (((GLOB_USER *)value)->gu_ref->len==0);        /* destroy empty entry */
}

/*********************************************/
/* purge GLOB_USER entries without reference */
/*********************************************/
void gu_purge(void)
{
      if(glob_user==NULL)
            return;

      g_hash_table_foreach_remove(glob_user,has_no_ref,NULL);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/***********************************************************************************/
/* remove any reference to the given model and clear the entry is not used anymore */
/* input: value = GLOB_USER *                                                      */
/*        user_data = GtkTreeModel * (to compare)                                  */
/* output: TRUE: entry to remove, FALSE: entry to keep                             */
/***********************************************************************************/
static gboolean unref_model_and_clean(gpointer key, gpointer value, gpointer user_data)
{
      GLOB_USER *gu=value;
      GtkTreeModel *gtm=user_data;
      int j;

      for(j=gu->gu_ref->len-1;j>=0;j--)
      {
            GLOB_USER_REF *gur;

            gur=&(g_array_index(gu->gu_ref,GLOB_USER_REF,j));
            if(gur->gtm==gtm)
            {
                  gtk_tree_row_reference_free(gur->gtrr);
                  g_array_remove_index_fast(gu->gu_ref,j);
            }
      }

      return (gu->gu_ref->len==0);        /* destroy empty entry */
}

/************************************************/
/* remove all reference to a model on all users */
/************************************************/
/* useful after/before a gtk_store_clear() */
/*******************************************/
void gu_unref_model(GtkTreeModel *gtm)
{
      if(glob_user==NULL)
            return;

      g_hash_table_foreach_remove(glob_user,unref_model_and_clean,gtm);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/***********************************************************************************/
/* remove any reference to the given model and clear the entry is not used anymore */
/* input: value = GLOB_USER *                                                      */
/*        user_data = GtkTreeModel * (to compare)                                  */
/* output: TRUE: entry to remove, FALSE: entry to keep                             */
/***********************************************************************************/
static gboolean unref_model_disconnect_and_clean(gpointer key, gpointer value, gpointer user_data)
{
      GLOB_USER *gu=value;
      GtkTreeModel *gtm=user_data;
      gboolean modified=FALSE;
      int j;

      for(j=gu->gu_ref->len-1;j>=0;j--)
      {
            GLOB_USER_REF *gur;

            gur=&(g_array_index(gu->gu_ref,GLOB_USER_REF,j));
            if(gur->gtm==gtm)
            {
                  gtk_tree_row_reference_free(gur->gtrr);
                  g_array_remove_index_fast(gu->gu_ref,j);
                  modified=TRUE;
            }
      }

      if(modified)
      {
            if(gu->gu_ref->len==0)  /* destroy empty entry */
                  return TRUE;

            gu_set_is_connected(gu,FALSE,TRUE); /* mark user as disconnected and do redisplay */
      }
      return FALSE;
}

/************************************************/
/* remove all reference to a model on all users */
/* and mark updated user as disconnected        */
/************************************************/
/* useful before a gtk_store_clear() */
/*************************************/
void gu_unref_model_and_disconnect(GtkTreeModel *gtm)
{
      if(glob_user==NULL)
            return;

      g_hash_table_foreach_remove(glob_user,unref_model_disconnect_and_clean,gtm);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/*************************************************************/
/* clear the dirty flag of each entry                        */
/* input: only the value is meaning full, it is a GLOB_USER* */
/*************************************************************/
static void set_gu_dirty_to_false(gpointer key, gpointer value, gpointer user_data)
{
      ((GLOB_USER*)value)->dirty=FALSE;
}

/*********************************************/
/* clear dirty flag of all GLOB_USER entries */
/*********************************************/
void gu_clear_dirty_flags(void)
{
      if(glob_user==NULL)
            return;

      g_hash_table_foreach(glob_user,set_gu_dirty_to_false,NULL);
}

/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
/* -------------------------------------------------------------------------- */
typedef struct
{
      guint64 shs;
      guint32 nb_users;
} USER_ACCOUNTING;

/***************************************/
/* clear the dirty flag of each entry  */
/* input: value = GLOB_USER*           */
/*        user_data= USER_ACCOUNTING * */
/***************************************/
static void gu_user_accounting(gpointer key, gpointer value, gpointer user_data)
{
      GLOB_USER *gu=value;
      USER_ACCOUNTING *ac=user_data;

      if(gu->is_connected==TRUE)
      {
            ac->nb_users++;
            ac->shs+=gu->unfmt_size;
      }
}

/************************************************************/
/* compute the number of online users and their shared size */
/************************************************************/
guint32 compute_online_nb_users_and_share_size(guint64 *share_size)
{
      USER_ACCOUNTING ac;

      ac.shs=0;
      ac.nb_users=0;

      if(glob_user!=NULL)
            g_hash_table_foreach(glob_user,gu_user_accounting,&ac);

      *share_size=ac.shs;
      return ac.nb_users;
}


Generated by  Doxygen 1.6.0   Back to index