Logo Search packages:      
Sourcecode: galeon version File versions

gul-general.c

/*
 *  Copyright (C) 2000 Marco Pesenti Gritti
 *
 *  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, 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.
 */

/* Galeon includes */
#include "gul-general.h"
#include "gul-string.h"
#include "galeon-config.h"
#include "eel-gconf-extensions.h"

/* system includes */
#include <string.h>
#include <unistd.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <libgnome/gnome-exec.h>
#include <libxml/xmlmemory.h>
#include <libgnomevfs/gnome-vfs-ops.h>
#include <libgnomevfs/gnome-vfs-utils.h>

#ifdef HAVE_NEW_GNOME_VFS_MIME_API
/* http://bugzilla.gnome.org/show_bug.cgi?id=156687 */
# undef GNOME_DISABLE_DEPRECATED
# include <libgnome/gnome-desktop-item.h>
#endif

char *
gul_general_tmp_filename (const char *base,
                    const char *extension)
{
      int fd;
      char *name = g_strdup (base);
      
      fd = g_mkstemp (name);

      if (fd != -1)
      {
            unlink (name);
            close (fd);
      }
      else
      {
            return NULL;
      }

      if (extension)
      {
            char *tmp;
            tmp = g_strconcat (name, ".", 
                           extension, NULL);
            g_free (name);
            name = tmp;
      }

      return name;
}


/**
 * gul_general_switch_temp_file: Perform a safe switch of a tmp file
 * the the real filename
 */
gboolean
gul_general_switch_temp_file (const char *filename,
                        const char *filename_temp)
{
      char *old_file;
      gboolean old_exist;
      gboolean retval = TRUE;

      old_file = g_strconcat (filename, ".old", NULL);

      old_exist = g_file_test (filename, G_FILE_TEST_EXISTS);

      if (old_exist)
      {
            if (rename (filename, old_file) < 0)
            {
                  g_warning ("Failed to rename %s to %s", filename, old_file);
                  retval = FALSE;
                  goto failed;
            }
      }

      if (rename (filename_temp, filename) < 0)
      {
            g_warning ("Failed to rename %s to %s", filename_temp, filename);

            if (rename (old_file, filename) < 0)
            {
                  g_warning ("Failed to restore %s from %s",
                           filename, filename_temp);
            }
            retval = FALSE;
            goto failed;
      }

      if (old_exist)
      {
            if (unlink (old_file) < 0)
            {
                  g_warning ("Failed to delete old file %s", old_file);
            }
      }

failed:
      g_free (old_file);

      return retval;
}


/**
 * gul_general_safe_xml_save: Saves an XMLdoc in a low-disk-safe manner
 */
gboolean
gul_general_safe_xml_save    (const char *filename, xmlDocPtr doc)
{
      char *tmpfile = g_strconcat (filename, ".tmp", NULL);
      int ret = xmlSaveFormatFile (tmpfile, doc, 1);

      if (ret < 0)
      {
            g_warning ("Failed to save %s", filename);
      }
      else
      {
            gul_general_switch_temp_file (filename, tmpfile);
      }

      g_free (tmpfile);

      return ( ret < 0 ) ? FALSE : TRUE;
}


/**
 * misc_general_user_file: returns the pathname of galeon shared files
 * (e.g., galeon.glade)
 *
 * fname: just the filename with no path information
 * critical: critical file? (halt if not found)
 */
gchar *
gul_general_user_file (const char *fname, gboolean critical)
{
      static GHashTable *already_found = NULL;
      gchar *alternative[6];
      gchar *file;
      gint i;
      
      /* create cache hash table if it doesnt already exist */
      if (already_found == NULL)
      {
            already_found = g_hash_table_new_full (g_str_hash, g_str_equal,
                                           g_free, g_free);
      }

        /* Have we already found this? */
      file = g_hash_table_lookup (already_found, fname);
      if (file != NULL)
      {
            if (g_file_test (file, G_FILE_TEST_EXISTS))
            {
                  return g_strdup (file);
            }
            else
            {
                  g_hash_table_remove (already_found, fname);
            }
      }

      /* try the default */
      file = g_build_filename (g_get_home_dir (), GALEON_DIR, fname, NULL);
      
      /* success? */
      if (g_file_test (file, G_FILE_TEST_EXISTS))
      {
            /* add it to the set of found files */
            g_hash_table_insert (already_found, g_strdup (fname), 
                             g_strdup (file));
            return file;
      }
      g_free(file);

      /* specify alternate locations in order of precedence */
      i = 0;
      alternative[i++] = g_strdup (fname);
#ifdef MAINTAINER_MODE
      /* generally only developers have any use for these */
      alternative[i++] = g_build_filename ("..", fname, NULL);
      alternative[i++] = g_build_filename ("ui", fname, NULL);
      alternative[i++] = g_build_filename ("..", "ui", fname, NULL);
#endif
      alternative[i++] = g_build_filename (SHARE_DIR, fname, NULL);
      alternative[i++] = NULL;  /* NULL terminator needed */
      
      /* select one of the alternatives */
      file = NULL;
      for (i = 0; alternative[i] != NULL; i++)
      {
            if (file == NULL && g_file_test (alternative[i], G_FILE_TEST_EXISTS)) 
            {
                  file = alternative[i];
            }
            else
            {
                  /* free unused string */
                  g_free (alternative[i]);
            }
      }

      /* check for success */
      if (file != NULL)
      {
            /* warn if we're using other than the install default */
            if (!g_path_is_absolute (file))
            {
                  gchar * cwd, *file1;
                  g_message ("Using %s (usually OK)", file);

                  /* Make it absolute */
                  cwd = g_get_current_dir();
                  file1 = g_build_filename (cwd, file, NULL);
                  g_free (file);
                  g_free (cwd);
                  file = file1;
            }

            /* add it to the set of found files */
            g_hash_table_insert (already_found, g_strdup (fname), 
                             g_strdup (file));
      }
      /* if nothing then theres an error */
      else if (critical)
      {
            g_error(_("%s not found"), fname);
      }

      /* return result */
      return file;
}

/**
 * xmlGetIntProp:
 */
gint
xmlGetIntProp (xmlNodePtr node, const gchar *attribute)
{
      char *string_value;
      int value = -1;

      /* get the attribute as a string */
      string_value = xmlGetProp (node, attribute);
      
      if (string_value)
      {
            /* convert to integer */
            value = strtol (string_value, NULL, 10);

            /* free allocated string */
            xmlFree (string_value);
      }

      /* return discovered value */
      return value;
}

/**
 * Renames new as fname, keeping the last num_backups versions of fname.
 * returns TRUE if ok
 */
gboolean
gul_backup_file (const char *fname, guint num_backups, const gchar *new)
{
      GnomeVFSURI *temp_uri;
      gboolean ret;

      temp_uri = gnome_vfs_uri_new (new);

      /* if the file was written... */
      if (gnome_vfs_uri_exists (temp_uri))
      {
            GnomeVFSResult result;
            gint i;

            /* backup/rotate */
            for (i = num_backups - 1; i >= 0; i--)
            {
                  gchar *src_ext, *dest_ext;
                  gchar *src_filename, *dest_filename;
                  GnomeVFSURI *src_uri, *dest_uri;
                  
                  /* get the extensions */
                  src_ext = i > 0 ? g_strdup_printf (".%d", i - 1) : NULL;
                  dest_ext = g_strdup_printf (".%d", i);
                  
                  /* create the filenames */
                  src_filename = g_strconcat (fname, src_ext, NULL);
                  dest_filename = g_strconcat (fname, dest_ext, NULL);
                  
                  /* create uris from the filenames */
                  src_uri = gnome_vfs_uri_new (src_filename);
                  dest_uri = gnome_vfs_uri_new (dest_filename);
                  
                  /* move the file */
                  if (gnome_vfs_uri_exists (src_uri))
                  {
                        gnome_vfs_move_uri (src_uri, dest_uri, TRUE);
                  }
                  
                  /* free stuff */
                  g_free (src_ext);
                  g_free (dest_ext);
                  g_free (src_filename);
                  g_free (dest_filename);
                  gnome_vfs_uri_unref (src_uri);
                  gnome_vfs_uri_unref (dest_uri);
            }
            
            /* move the temp file to the normal location */
            result = gnome_vfs_move (new, fname, TRUE);

            /* make sure the move went okay */
            if (result == GNOME_VFS_OK)
            {
                  ret = TRUE;
            }
            else
            {
                  ret = FALSE;
            }
      }
      else
      {
            ret = FALSE;;
      }

      /* free the temp file stuff */
      gnome_vfs_uri_unref (temp_uri);

      return ret;

}

/**
 * misc_general_read_line_from_file: reads a line from an opened file and
 * returns it in a new allocated string
 */
gchar *
gul_general_read_line_from_file (FILE *f)
{
      gchar *line = g_strdup ("");
      gchar *t;
      gchar *buf = g_new0 (gchar, 256);
      while ( ! ( strchr (buf, '\n') || feof (f) ) ) {
            fgets(buf, 256, f);
            t = line;
            line = g_strconcat (line, buf, NULL);
            g_free (t);
      }
      g_free (buf);
      return line;
}

GnomeVFSResult
gul_general_launch_application (GnomeVFSMimeApplication *application,
                        const char              *parameter,
                        guint32 user_time)
{
      GList         *uris;
      GnomeVFSResult rv;
#ifdef HAVE_NEW_GNOME_VFS_MIME_API
      const char *desktop_file;
      GnomeDesktopItem *desktop_item;
      int ret;
#endif
      g_return_val_if_fail (application != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);
      g_return_val_if_fail (parameter != NULL, GNOME_VFS_ERROR_BAD_PARAMETERS);

      uris = g_list_prepend (NULL, gnome_vfs_make_uri_canonical (parameter));

#ifdef HAVE_NEW_GNOME_VFS_MIME_API
      desktop_file = gnome_vfs_mime_application_get_desktop_file_path (application);
      desktop_item = gnome_desktop_item_new_from_file (desktop_file,
                                           GNOME_DESKTOP_ITEM_LOAD_NO_TRANSLATIONS,
                                           NULL);
      if (!desktop_item)
      {
            return GNOME_VFS_ERROR_INTERNAL;
      }

      gnome_desktop_item_set_launch_time (desktop_item, user_time);
      ret = gnome_desktop_item_launch (desktop_item, uris,
                               GNOME_DESKTOP_ITEM_LAUNCH_APPEND_PATHS, NULL);

      gnome_desktop_item_unref (desktop_item);

      return ret == -1 ? GNOME_VFS_OK : GNOME_VFS_ERROR_GENERIC;
#else

      rv = gnome_vfs_mime_application_launch (application, uris);

      g_list_foreach (uris, (GFunc)g_free, NULL);
      g_list_free (uris);
#endif

      return rv;
}

static void
gul_find_file_recursive  (const char *path, 
                    const char *fname, GSList **l, 
                    gint depth, gint maxdepth)
{
      GDir *d = g_dir_open (path, 0, NULL);
      const gchar *f;
      if (d)
      {
            while ((f = g_dir_read_name (d)))
            {
                  char *new_path = g_build_filename (path, f, NULL);
                  if (depth < maxdepth)
                  {
                        gul_find_file_recursive (new_path, fname, l, 
                                           depth + 1, maxdepth);
                  }
                  if (!strcmp (f, fname))
                  {
                        *l = g_slist_prepend (*l, new_path);
                  }
                  else
                  {
                        g_free (new_path);
                  }
            }
            g_dir_close (d);
      }

}

/**
 * Looks for a file in a directory, recursively.
 */
GSList *
gul_find_file (const char *path, 
             const char *fname, 
             gint maxdepth)
{
      GSList *ret = NULL;
      gul_find_file_recursive (path, fname, &ret, 0, maxdepth);
      return ret;
}

gboolean
gul_copy_file (const char *orig,
             const char *dest)
{
      FILE *forig;
      FILE *fdest;

      forig = fopen (orig, "r");
      if (!forig) 
      {
            return FALSE;
      }
      
      fdest = fopen (dest, "w");
      if (!fdest) 
      {
            fclose (forig);
            return FALSE;
      }

      while (! feof (forig))
      {
            char buffer[4096];
            int n;

            n = fread (buffer, sizeof (char), 4096, forig);
            
            if (ferror (forig))
            {
                  fclose (forig);
                  fclose (fdest);
                  return FALSE;
            }
            
            fwrite (buffer, sizeof (char), n, fdest);

            if (ferror (fdest))
            {
                  fclose (forig);
                  fclose (fdest);
                  return FALSE;
            }
      }
      
      fclose (forig);
      fclose (fdest);
      
      return TRUE;
}

GSList *
gul_slist_filter (const GSList *l, GulFilterFunc f, gpointer data)
{
      GSList *ret = NULL;
      const GSList *li;

      for (li = l; li; li = li->next)
      {
            if (f (li->data, data))
            {
                  ret = g_slist_prepend (ret, li->data);
            }
      }

      return g_slist_reverse (ret);
}


Generated by  Doxygen 1.6.0   Back to index