* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <ftw.h>
-static struct stat cache_stat;
+static GStatBuf cache_stat;
static gboolean cache_up_to_date;
static int check_dir_mtime (const char *dir,
- const struct stat *sb,
+ const GStatBuf *sb,
int tf)
{
if (tf != FTW_NS && sb->st_mtime > cache_stat.st_mtime)
return 0;
}
- gboolean
- is_cache_up_to_date (const gchar *path)
- {
+static gboolean
+is_cache_up_to_date (const gchar *path)
+{
gchar *cache_path;
gint retval;
gboolean
is_cache_up_to_date (const gchar *path)
{
- struct stat path_stat, cache_stat;
+ GStatBuf path_stat, cache_stat;
gchar *cache_path;
int retval;
idata2 = g_hash_table_lookup (image_data_hash, path2);
if (idata && idata2 && idata != idata2)
- g_error (_("different idatas found for symlinked '%s' and '%s'\n"),
+ g_error ("different idatas found for symlinked '%s' and '%s'\n",
path, path2);
if (idata && !idata2)
idata2 = g_hash_table_lookup (icon_data_hash, path2);
if (idata && idata2 && idata != idata2)
- g_error (_("different idatas found for symlinked '%s' and '%s'\n"),
+ g_error ("different idatas found for symlinked '%s' and '%s'\n",
path, path2);
if (idata && !idata2)
int name_offset;
int name_size;
int image_list_offset;
- int tmp;
int i, len;
GList *list;
g_assert (*offset == ftell (cache));
node->offset = *offset;
-
+
get_single_node_size (node, &node_size, &image_data_size);
g_assert (node_size % 4 == 0);
g_assert (image_data_size % 4 == 0);
next_offset = *offset + node_size + image_data_size;
/* Chain offset */
if (node->next != NULL)
- {
- if (!write_card32 (cache, next_offset))
- return FALSE;
- }
+ {
+ if (!write_card32 (cache, next_offset))
+ return FALSE;
+ }
else
- {
- if (!write_card32 (cache, 0xffffffff))
- return FALSE;
- }
-
+ {
+ if (!write_card32 (cache, 0xffffffff))
+ return FALSE;
+ }
+
name_size = 0;
name_offset = find_string (node->name);
if (name_offset <= 0)
add_string (node->name, name_offset);
}
if (!write_card32 (cache, name_offset))
- return FALSE;
-
+ return FALSE;
+
image_list_offset = *offset + 12 + name_size;
if (!write_card32 (cache, image_list_offset))
- return FALSE;
-
+ return FALSE;
+
/* Icon name */
if (name_size > 0)
{
if (!write_string (cache, node->name))
- return FALSE;
+ return FALSE;
}
/* Image list */
len = g_list_length (node->image_list);
if (!write_card32 (cache, len))
- return FALSE;
-
- /* Image data goes right after the image list */
- tmp = image_list_offset + 4 + len * 8;
+ return FALSE;
list = node->image_list;
data_offset = image_data_offset;
for (i = 0; i < len; i++)
- {
- Image *image = list->data;
- int image_data_size = get_image_data_size (image);
+ {
+ Image *image = list->data;
+ int image_data_size = get_image_data_size (image);
- /* Directory index */
- if (!write_card16 (cache, image->dir_index))
- return FALSE;
-
- /* Flags */
- if (!write_card16 (cache, image->flags))
- return FALSE;
+ /* Directory index */
+ if (!write_card16 (cache, image->dir_index))
+ return FALSE;
- /* Image data offset */
- if (image_data_size > 0)
- {
- if (!write_card32 (cache, data_offset))
- return FALSE;
- data_offset += image_data_size;
- }
- else
- {
- if (!write_card32 (cache, 0))
- return FALSE;
- }
+ /* Flags */
+ if (!write_card16 (cache, image->flags))
+ return FALSE;
- list = list->next;
- }
+ /* Image data offset */
+ if (image_data_size > 0)
+ {
+ if (!write_card32 (cache, data_offset))
+ return FALSE;
+ data_offset += image_data_size;
+ }
+ else
+ {
+ if (!write_card32 (cache, 0))
+ return FALSE;
+ }
+
+ list = list->next;
+ }
/* Now write the image data */
list = node->image_list;
for (i = 0; i < len; i++, list = list->next)
- {
- Image *image = list->data;
- int pixel_data_size = get_image_pixel_data_size (image);
- int meta_data_size = get_image_meta_data_size (image);
+ {
+ Image *image = list->data;
+ int pixel_data_size = get_image_pixel_data_size (image);
+ int meta_data_size = get_image_meta_data_size (image);
- if (get_image_data_size (image) == 0)
- continue;
+ if (get_image_data_size (image) == 0)
+ continue;
- /* Pixel data */
- if (pixel_data_size > 0)
- {
- image->image_data->offset = image_data_offset + 8;
- if (!write_card32 (cache, image->image_data->offset))
- return FALSE;
- }
- else
- {
- if (!write_card32 (cache, (guint32) (image->image_data ? image->image_data->offset : 0)))
- return FALSE;
- }
+ /* Pixel data */
+ if (pixel_data_size > 0)
+ {
+ image->image_data->offset = image_data_offset + 8;
+ if (!write_card32 (cache, image->image_data->offset))
+ return FALSE;
+ }
+ else
+ {
+ if (!write_card32 (cache, (guint32) (image->image_data ? image->image_data->offset : 0)))
+ return FALSE;
+ }
- if (meta_data_size > 0)
- {
- image->icon_data->offset = image_data_offset + pixel_data_size + 8;
- if (!write_card32 (cache, image->icon_data->offset))
- return FALSE;
- }
- else
- {
- if (!write_card32 (cache, image->icon_data ? image->icon_data->offset : 0))
- return FALSE;
- }
+ if (meta_data_size > 0)
+ {
+ image->icon_data->offset = image_data_offset + pixel_data_size + 8;
+ if (!write_card32 (cache, image->icon_data->offset))
+ return FALSE;
+ }
+ else
+ {
+ if (!write_card32 (cache, image->icon_data ? image->icon_data->offset : 0))
+ return FALSE;
+ }
- if (pixel_data_size > 0)
- {
- if (!write_image_data (cache, image->image_data, image->image_data->offset))
- return FALSE;
- }
-
- if (meta_data_size > 0)
- {
+ if (pixel_data_size > 0)
+ {
+ if (!write_image_data (cache, image->image_data, image->image_data->offset))
+ return FALSE;
+ }
+
+ if (meta_data_size > 0)
+ {
if (!write_icon_data (cache, image->icon_data, image->icon_data->offset))
return FALSE;
}
- image_data_offset += pixel_data_size + meta_data_size + 8;
- }
-
+ image_data_offset += pixel_data_size + meta_data_size + 8;
+ }
+
*offset = next_offset;
node = node->next;
}
-
+
return TRUE;
}
if (!_gtk_icon_cache_validate (&info))
{
- g_mapped_file_free (map);
+ g_mapped_file_unref (map);
return FALSE;
}
- g_mapped_file_free (map);
+ g_mapped_file_unref (map);
return TRUE;
}
+/**
+ * safe_fclose:
+ * @f: A FILE* stream, must have underlying fd
+ *
+ * Unix defaults for data preservation after system crash
+ * are unspecified, and many systems will eat your data
+ * in this situation unless you explicitly fsync().
+ *
+ * Returns: %TRUE on success, %FALSE on failure, and will set errno()
+ */
+static gboolean
+safe_fclose (FILE *f)
+{
+ int fd = fileno (f);
+ g_assert (fd >= 0);
+ if (fflush (f) == EOF)
+ return FALSE;
+#ifndef G_OS_WIN32
+ if (fsync (fd) < 0)
+ return FALSE;
+#endif
+ if (fclose (f) == EOF)
+ return FALSE;
+ return TRUE;
+}
+
static void
build_cache (const gchar *path)
{
gchar *bak_cache_path = NULL;
#endif
GHashTable *files;
- gboolean retval;
FILE *cache;
- struct stat path_stat, cache_stat;
+ GStatBuf path_stat, cache_stat;
struct utimbuf utime_buf;
GList *directories = NULL;
int fd;
}
/* FIXME: Handle failure */
- retval = write_file (cache, files, directories);
- fclose (cache);
+ if (!write_file (cache, files, directories))
+ {
+ g_unlink (tmp_cache_path);
+ exit (1);
+ }
- g_list_foreach (directories, (GFunc)g_free, NULL);
- g_list_free (directories);
-
- if (!retval)
+ if (!safe_fclose (cache))
{
+ g_printerr (_("Failed to write cache file: %s\n"), g_strerror (errno));
g_unlink (tmp_cache_path);
exit (1);
}
+ cache = NULL;
+
+ g_list_free_full (directories, g_free);
if (!validate_file (tmp_cache_path))
{
g_unlink (bak_cache_path);
if (g_rename (cache_path, bak_cache_path) == -1)
{
+ int errsv = errno;
+
g_printerr (_("Could not rename %s to %s: %s, removing %s then.\n"),
cache_path, bak_cache_path,
- g_strerror (errno),
+ g_strerror (errsv),
cache_path);
g_unlink (cache_path);
bak_cache_path = NULL;
if (g_rename (tmp_cache_path, cache_path) == -1)
{
+ int errsv = errno;
+
g_printerr (_("Could not rename %s to %s: %s\n"),
tmp_cache_path, cache_path,
- g_strerror (errno));
+ g_strerror (errsv));
g_unlink (tmp_cache_path);
#ifdef G_OS_WIN32
if (bak_cache_path != NULL)
if (g_rename (bak_cache_path, cache_path) == -1)
- g_printerr (_("Could not rename %s back to %s: %s.\n"),
- bak_cache_path, cache_path,
- g_strerror (errno));
+ {
+ errsv = errno;
+
+ g_printerr (_("Could not rename %s back to %s: %s.\n"),
+ bak_cache_path, cache_path,
+ g_strerror (errsv));
+ }
#endif
exit (1);
}
setlocale (LC_ALL, "");
+#ifdef ENABLE_NLS
bindtextdomain (GETTEXT_PACKAGE, GTK_LOCALEDIR);
+#ifdef HAVE_BIND_TEXTDOMAIN_CODESET
bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#endif
+#endif
context = g_option_context_new ("ICONPATH");
g_option_context_add_main_entries (context, args, GETTEXT_PACKAGE);
{
if (path)
{
- g_printerr (_("No theme index file."));
+ g_printerr (_("No theme index file.\n"));
}
else
{
if (!force_update && is_cache_up_to_date (path))
return 0;
- g_type_init ();
build_cache (path);
if (strcmp (var_name, "-") != 0)