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

misc.c

/* dc_gui2 - a GTK+2 GUI for DCTC
 * Copyright (C) 2002 Eric Prevoteau
 *
 * misc.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: misc.c,v 1.11 2003/12/30 07:50:51 ericprev Exp $
*/

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

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/param.h>
#include <ctype.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <glib.h>
#include <gnome.h>

#include "misc.h"

/***********************************************************/
/* routine copiant par troncature une chaine de caracteres */
/***********************************************************/
void strncpy_max(char *destination, const char *source, int max_byte)
{
      strncpy(destination,source,max_byte-1);
      destination[max_byte-1]='\0';
}

/************************************************************************/
/* check if the given pattern exists inside filename (case insensitive) */
/************************************************************************/
/* output: address of the pattern or NULL */
/******************************************/
char *my_strcasestr(GString *pattern, char *filename)
{
      int max_pos;
      int i;

      max_pos=strlen(filename)-pattern->len;
      if(max_pos<0)                        /* filename length < pattern length ? */
            return NULL;                        /* no match */

      for(i=0;i<=max_pos;i++)
      {
            if(!strncasecmp(pattern->str,filename+i,pattern->len))
                  return filename+i;
      }

      return NULL;                              /* no match */
}

/***************************************************/
/* compute the size of a NULL terminated ptr array */
/***************************************************/
int size_of_null_array(void **array) 
{
      int nb=0;

      if(array!=NULL)
      {
            while(*array!=NULL)
            {
                  nb++;
                  array++;
            }
      }
      return nb;
}

/*
----------------------
----------------------
*/

static guint8 ascii1_to_hex(unsigned char v)
{
   if((v>='0')&&(v<='9'))
      return v-'0';
   else
      return toupper(v)-'A'+10;
}

/******************************************/
/* convert 2 ascii hexdigit into 1 guint8 */
/******************************************/
guint8 ascii2_to_bin1(unsigned char *asc)
{
   return ((ascii1_to_hex(asc[0]))<<4)|(ascii1_to_hex(asc[1]));
}

/*************************************************************/
/* build any required directory from the given absolute path */
/*************************************************************/
static int recursive_build_directory(GString *dir)
{
      struct stat st;

      if(stat(dir->str,&st)==0)
      {
            return 0;
      }
      else
      {
            GString *new_dir;
            char *t;
            int ret;

            new_dir=g_string_new(dir->str);
            t=strrchr(new_dir->str,'/');
            if(t==NULL)
            {
                  g_string_free(new_dir,TRUE);
                  return ENOTDIR;
            }

            new_dir=g_string_truncate(new_dir,t-new_dir->str);
            ret=recursive_build_directory(new_dir);
            g_string_free(new_dir,TRUE);

            if(ret!=0)
                  return ret;

            if(stat(dir->str,&st)==0)
            {     /* it can look stupid to check if the directory we want to create already exist */
                  /* because we just have created its parent however, if the directory we want to create is "xxx/yyy/." */
                  /* creating "xxx/yyy" has already created the "." directory. */
                  return 0;
            }

            if(mkdir(dir->str,0777))
            {
                  return errno;
            }
            return 0;
      }
}

/******************************************************/
/* create the given directory (it can start with a /) */
/******************************************************/
/* output: 0=ok else errno */
/***************************/
int recursive_mkdir(GString *directory_name)
{
      GString *final_name;
      int ret;

      if(directory_name->str[0]=='/')
            final_name=g_string_new(directory_name->str);
      else
      {
            char the_cwd[MAXPATHLEN];
            if(getcwd(the_cwd,sizeof(the_cwd)-1)==NULL)
            {
                  return errno;
            }

            final_name=g_string_new(the_cwd); 
            if(final_name->str[final_name->len-1]!='/')
                  final_name=g_string_append_c(final_name,'/'); 
            final_name=g_string_append(final_name,directory_name->str);
      }

      /* now, final_name is an absolute path */
      ret=recursive_build_directory(final_name);

      g_string_free(final_name,TRUE);

      return ret;
}

/*********************************************/
/* check if the given program is in the path */
/*********************************************/
/* output: TRUE=yes, FALSE=no */
/******************************/
gboolean check_prog_in_path(const char *progname)
{
      gchar *real_path;

      real_path=g_find_program_in_path(progname);
      if(real_path==NULL)
            return FALSE;
      g_free(real_path);
      return TRUE;
}

/***************************************************************/
/* check if named socket can be created in the given directory */
/***************************************************************/
/* input: directory= directory to check                */
/*        possible= name of a possibly existing socket */
/*        attempt= name of the socket to try to create */
/*******************************************************/
/* output: TRUE=usable, FALSE=pb */
/*********************************/
gboolean check_socket_creation_in_directory(const char *directory, const char *possible, const char *attempt)
{
      struct stat st;
      GString *str;

      str=g_string_new(directory);
      g_string_append_c(str,'/');
      g_string_append(str,possible);

      if(stat(str->str,&st)==0)
      {
            if(S_ISSOCK(st.st_mode))
            {
                  /* the possible socket exist in the directory */
                  g_string_free(str,TRUE);
                  return TRUE;
            }
      }

      /* the possible name either does not exist or is not a socket */
      g_string_assign(str,directory);
      g_string_append_c(str,'/');
      g_string_append(str,attempt);
      if(stat(str->str,&st)==0)
      {
            if(S_ISSOCK(st.st_mode))
            {
                  /* the possible socket exist in the directory */
                  g_string_free(str,TRUE);
                  return TRUE;
            }
            unlink(str->str);       /* remove the 'attempt' name if it is not a socket */
      }

      {
            struct sockaddr_un name;
            int sock_fd;

            sock_fd=socket(AF_UNIX,SOCK_DGRAM,0);
            if(sock_fd==-1)
            {
                  perror("check_socket_creation_in_directory");
                  g_string_free(str,TRUE);
                  return FALSE;
            }

            name.sun_family=AF_UNIX;
            strcpy(name.sun_path,str->str);

            if(bind(sock_fd,(void *)&name,sizeof(struct sockaddr_un))==0)
            {
                  close(sock_fd);
                  unlink(str->str);
                  g_string_free(str,TRUE);
                  return TRUE;            /* creation is successful */
            }
            close(sock_fd);
      }
      
      g_string_free(str,TRUE);
      return FALSE;
}

static const char *scale_factor_name[]=
                                          {
                                          "",               /* <scale */
                                          "K",              /* <scale^2 (kilo) */
                                          "M",              /* <scale^3 (mega) */
                                          "G",              /* <scale^4 (giga) */
                                          "T",              /* <scale^5 (tera) */
                                          "P",              /* <scale^6 (peta) */
                                          "E",              /* <scale^7 (exa) */
                                          "Z",              /* <scale^8 (zetta) */
                                          "Y",              /* <scale^9 (yotta) */
                                          NULL
                                          };

/*************************************************/
/* convert a value into a "human readable" value */
/**************************************************************/
/* input: value= the value to process                         */
/*        scale= 1000 for normal values, 1024 for pow2 values */
/**************************************************************/
/* output: human readable string (to free) */
/*******************************************/
GString *value_to_readable(double value, double scale)
{
      GString *str;
      int idx;
      
      str=g_string_new("");

      idx=0;
      while(scale_factor_name[idx]!=NULL)
      {
            if(value<scale)
            {
#ifndef NO_PRINTF_LOCALE
                  g_string_sprintf(str,"%'.2f",value);   /* NO_PRINTF_LOCAL support added */
#else
                  g_string_sprintf(str,"%.2f",value);    
#endif
                  g_string_append(str,scale_factor_name[idx]);
                  break;
            }
            value/=scale;
            idx++;
      }
      return str;
}

typedef struct
{
      const char *unit;
      guint64 factor;
} DURATION_SCALE;

static DURATION_SCALE duration_scale[]={
                                                                                    {"\"",60},        /* seconds */
                                                                                    {"'",60},         /* minutes */
                                                                                    {":",24},         /* hours */
                                                                                    {"d",30},   /* days */
                                                                                    {"m",12},   /* months */
                                                                                    {NULL,0}
                                                                              };

/****************************************************/
/* convert a duration into a "human readable" value */
/****************************************************/
/* input: duration */
/*******************************************/
/* output: human readable string (to free) */
/*******************************************/
GString *duration_to_readable(guint64 duration)
{
      GString *str;
      int idx;
      
      if(duration==0)
            return g_string_new("0\"");

      str=g_string_new("");

      idx=0;
      while(duration_scale[idx].unit!=NULL)
      {
            unsigned int rem;
            char buf[128];

            rem=duration%duration_scale[idx].factor;
            duration/=duration_scale[idx].factor;

            if(duration==0)
                  sprintf(buf,"%u%s",rem,duration_scale[idx].unit);           /* nothing in from of this */
            else
                  sprintf(buf,"%02u%s",rem,duration_scale[idx].unit);   /* we have something in front of this (always display 2 digits) */
            g_string_prepend(str,buf);

            if(duration==0)
                  break;
            idx++;
      }

      if(duration!=0)               /* if we reach year, it is the eternity :) */
      {
            g_string_assign(str,_("eternity"));
      }
      
      return str;
}



Generated by  Doxygen 1.6.0   Back to index