nautilus-file-utilities.c 19.1 KB
Newer Older
1 2
/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */

3
/* nautilus-file-utilities.c - implementation of file manipulation routines.
4

5
   Copyright (C) 1999, 2000, 2001 Eazel, Inc.
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24

   The Gnome Library is free software; you can redistribute it and/or
   modify it under the terms of the GNU Library General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.

   The Gnome Library 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
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public
   License along with the Gnome Library; see the file COPYING.LIB.  If not,
   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.

   Authors: John Sullivan <sullivan@eazel.com>
*/

25
#include <config.h>
26
#include "nautilus-file-utilities.h"
27

28
#include "nautilus-global-preferences.h"
29
#include "nautilus-lib-self-check-functions.h"
30
#include "nautilus-metadata.h"
31
#include "nautilus-metafile.h"
32
#include "nautilus-file.h"
33
#include "nautilus-search-directory.h"
34
#include "nautilus-signaller.h"
Ramiro Estrugo's avatar
Ramiro Estrugo committed
35 36
#include <eel/eel-glib-extensions.h>
#include <eel/eel-string.h>
37
#include <eel/eel-debug.h>
38
#include <libgnome/gnome-util.h>
39
#include <glib/gi18n.h>
40
#include <gio/gio.h>
41
#include <unistd.h>
42
#include <stdlib.h>
43

Darin Adler's avatar
Darin Adler committed
44 45 46
#define NAUTILUS_USER_DIRECTORY_NAME ".nautilus"
#define DEFAULT_NAUTILUS_DIRECTORY_MODE (0755)

Alexander Larsson's avatar
Alexander Larsson committed
47 48
#define DESKTOP_DIRECTORY_NAME "Desktop"
#define LEGACY_DESKTOP_DIRECTORY_NAME ".gnome-desktop"
Darin Adler's avatar
Darin Adler committed
49 50
#define DEFAULT_DESKTOP_DIRECTORY_MODE (0755)

51 52 53 54
static void update_xdg_dir_cache (void);
static void schedule_user_dirs_changed (void);
static void desktop_dir_changed (void);

55 56

char *
Alexander Larsson's avatar
Alexander Larsson committed
57
nautilus_compute_title_for_location (GFile *location)
58 59
{
	NautilusFile *file;
Alexander Larsson's avatar
Alexander Larsson committed
60
	char *title;
61

Alexander Larsson's avatar
Alexander Larsson committed
62 63 64 65 66 67 68
	/* TODO-gio: This doesn't really work all that great if the
	   info about the file isn't known atm... */
	
	title = NULL;
	if (location) {
		file = nautilus_file_get (location);
		title = nautilus_file_get_display_name (file);
69
		nautilus_file_unref (file);
Alexander Larsson's avatar
Alexander Larsson committed
70 71 72
	}

	if (title == NULL) {
73 74 75 76 77 78 79
		title = g_strdup ("");
	}
	
	return title;
}


80
/**
Darin Adler's avatar
Darin Adler committed
81
 * nautilus_get_user_directory:
82 83 84 85 86
 * 
 * Get the path for the directory containing nautilus settings.
 *
 * Return value: the directory path.
 **/
87
char *
Darin Adler's avatar
Darin Adler committed
88
nautilus_get_user_directory (void)
89
{
90
	char *user_directory = NULL;
91

92 93 94
	user_directory = g_build_filename (g_get_home_dir (),
					   NAUTILUS_USER_DIRECTORY_NAME,
					   NULL);
Alexander Larsson's avatar
Alexander Larsson committed
95
	
96
	if (!g_file_test (user_directory, G_FILE_TEST_EXISTS)) {
97
		mkdir (user_directory, DEFAULT_NAUTILUS_DIRECTORY_MODE);
98
		/* FIXME bugzilla.gnome.org 41286: 
99 100 101 102 103 104
		 * How should we handle the case where this mkdir fails? 
		 * Note that nautilus_application_startup will refuse to launch if this 
		 * directory doesn't get created, so that case is OK. But the directory 
		 * could be deleted after Nautilus was launched, and perhaps
		 * there is some bad side-effect of not handling that case.
		 */
105 106 107 108
	}

	return user_directory;
}
109

110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214
typedef struct {
	char *type;
	char *path;
	NautilusFile *file;
} XdgDirEntry;


static XdgDirEntry *
parse_xdg_dirs (const char *config_file)
{
  GArray *array;
  char *config_file_free = NULL;
  XdgDirEntry dir;
  char *data;
  char **lines;
  char *p, *d;
  int i;
  char *type_start, *type_end;
  char *value, *unescaped;
  gboolean relative;

  array = g_array_new (TRUE, TRUE, sizeof (XdgDirEntry));
  
  if (config_file == NULL)
    {
      config_file_free = g_build_filename (g_get_user_config_dir (),
					   "user-dirs.dirs", NULL);
      config_file = (const char *)config_file_free;
    }

  if (g_file_get_contents (config_file, &data, NULL, NULL))
    {
      lines = g_strsplit (data, "\n", 0);
      g_free (data);
      for (i = 0; lines[i] != NULL; i++)
	{
	  p = lines[i];
	  while (g_ascii_isspace (*p))
	    p++;
      
	  if (*p == '#')
	    continue;
      
	  value = strchr (p, '=');
	  if (value == NULL)
	    continue;
	  *value++ = 0;
      
	  g_strchug (g_strchomp (p));
	  if (!g_str_has_prefix (p, "XDG_"))
	    continue;
	  if (!g_str_has_suffix (p, "_DIR"))
	    continue;
	  type_start = p + 4;
	  type_end = p + strlen (p) - 4;
      
	  while (g_ascii_isspace (*value))
	    value++;
      
	  if (*value != '"')
	    continue;
	  value++;
      
	  relative = FALSE;
	  if (g_str_has_prefix (value, "$HOME"))
	    {
	      relative = TRUE;
	      value += 5;
	      while (*value == '/')
		      value++;
	    }
	  else if (*value != '/')
	    continue;
	  
	  d = unescaped = g_malloc (strlen (value) + 1);
	  while (*value && *value != '"')
	    {
	      if ((*value == '\\') && (*(value + 1) != 0))
		value++;
	      *d++ = *value++;
	    }
	  *d = 0;
      
	  *type_end = 0;
	  dir.type = g_strdup (type_start);
	  if (relative)
	    {
	      dir.path = g_build_filename (g_get_home_dir (), unescaped, NULL);
	      g_free (unescaped);
	    }
	  else 
	    dir.path = unescaped;
      
	  g_array_append_val (array, dir);
	}
      
      g_strfreev (lines);
    }
  
  g_free (config_file_free);
  
  return (XdgDirEntry *)g_array_free (array, FALSE);
}

static XdgDirEntry *cached_xdg_dirs = NULL;
Alexander Larsson's avatar
Alexander Larsson committed
215
static GFileMonitor *cached_xdg_dirs_monitor = NULL;
216 217 218 219 220

static void
xdg_dir_changed (NautilusFile *file,
		 XdgDirEntry *dir)
{
Alexander Larsson's avatar
Alexander Larsson committed
221
	GFile *location, *dir_location;
222
	char *path;
Alexander Larsson's avatar
Alexander Larsson committed
223 224 225 226 227

	location = nautilus_file_get_location (file);
	dir_location = g_file_new_for_path (dir->path);
	if (!g_file_equal (location, dir_location)) {
		path = g_file_get_path (location);
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257

		if (path) {
			char *argv[5];
			int i;
			
			g_free (dir->path);
			dir->path = path;

			i = 0;
			argv[i++] = "xdg-user-dirs-update";
			argv[i++] = "--set";
			argv[i++] = dir->type;
			argv[i++] = dir->path;
			argv[i++] = NULL;

			/* We do this sync, to avoid possible race-conditions
			   if multiple dirs change at the same time. Its
			   blocking the main thread, but these updates should
			   be very rare and very fast. */
			g_spawn_sync (NULL, 
				      argv, NULL,
				      G_SPAWN_SEARCH_PATH |
				      G_SPAWN_STDOUT_TO_DEV_NULL |
				      G_SPAWN_STDERR_TO_DEV_NULL,
				      NULL, NULL,
				      NULL, NULL, NULL, NULL);
			schedule_user_dirs_changed ();
			desktop_dir_changed ();
		}
	}
Alexander Larsson's avatar
Alexander Larsson committed
258 259
	g_object_unref (location);
	g_object_unref (dir_location);
260 261 262
}

static void 
Alexander Larsson's avatar
Alexander Larsson committed
263 264 265 266 267 268 269
xdg_dir_cache_changed_cb (GFileMonitor  *monitor,
			  GFile *file,
			  GFile *other_file,
			  GFileMonitorEvent event_type)
{
	if (event_type == G_FILE_MONITOR_EVENT_CHANGED ||
	    event_type == G_FILE_MONITOR_EVENT_CREATED) {
270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293
		update_xdg_dir_cache ();
	}
}

static int user_dirs_changed_tag = 0;

static gboolean
emit_user_dirs_changed_idle (gpointer data)
{
	g_signal_emit_by_name (nautilus_signaller_get_current (),
			       "user_dirs_changed");
	user_dirs_changed_tag = 0;
	return FALSE;
}

static void
schedule_user_dirs_changed (void)
{
	if (user_dirs_changed_tag == 0) {
		user_dirs_changed_tag = g_idle_add (emit_user_dirs_changed_idle, NULL);
	}
}

static void
294 295 296 297 298 299 300 301 302 303
unschedule_user_dirs_changed (void)
{
	if (user_dirs_changed_tag != 0) {
		g_source_remove (user_dirs_changed_tag);
		user_dirs_changed_tag = 0;
	}
}

static void
free_xdg_dir_cache (void)
304 305 306
{
	int i;

307 308
	if (cached_xdg_dirs != NULL) {
		for (i = 0; cached_xdg_dirs[i].type != NULL; i++) {
309 310 311 312 313 314 315 316 317 318 319 320 321
			if (cached_xdg_dirs[i].file != NULL) {
				nautilus_file_monitor_remove (cached_xdg_dirs[i].file,
							      &cached_xdg_dirs[i]);
				g_signal_handlers_disconnect_by_func (cached_xdg_dirs[i].file,
								      G_CALLBACK (xdg_dir_changed),
								      &cached_xdg_dirs[i]);
				nautilus_file_unref (cached_xdg_dirs[i].file);
			}
			g_free (cached_xdg_dirs[i].type);
			g_free (cached_xdg_dirs[i].path);
		}
		g_free (cached_xdg_dirs);
	}
322
}
323

324 325 326 327 328 329 330
static void
destroy_xdg_dir_cache (void)
{
	free_xdg_dir_cache ();
	unschedule_user_dirs_changed ();
	desktop_dir_changed ();

Alexander Larsson's avatar
Alexander Larsson committed
331 332 333
	if (cached_xdg_dirs_monitor != NULL) {
		g_object_unref  (cached_xdg_dirs_monitor);
		cached_xdg_dirs_monitor = NULL;
334
	}
335 336 337 338 339
}

static void
update_xdg_dir_cache (void)
{
Alexander Larsson's avatar
Alexander Larsson committed
340
	GFile *file;
341 342 343 344 345 346 347
	char *config_file, *uri;
	int i;

	free_xdg_dir_cache ();
	schedule_user_dirs_changed ();
	desktop_dir_changed ();

348 349 350 351 352
	cached_xdg_dirs = parse_xdg_dirs (NULL);
	
	for (i = 0 ; cached_xdg_dirs[i].type != NULL; i++) {
		cached_xdg_dirs[i].file = NULL;
		if (strcmp (cached_xdg_dirs[i].path, g_get_home_dir ()) != 0) {
Alexander Larsson's avatar
Alexander Larsson committed
353 354
			uri = g_filename_to_uri (cached_xdg_dirs[i].path, NULL, NULL);
			cached_xdg_dirs[i].file = nautilus_file_get_by_uri (uri);
355 356
			nautilus_file_monitor_add (cached_xdg_dirs[i].file,
						   &cached_xdg_dirs[i],
Alexander Larsson's avatar
Alexander Larsson committed
357
						   NAUTILUS_FILE_ATTRIBUTE_INFO);
358 359 360 361 362
			g_signal_connect (cached_xdg_dirs[i].file,
					  "changed", G_CALLBACK (xdg_dir_changed), &cached_xdg_dirs[i]);
			g_free (uri);
		}
	}
363

Alexander Larsson's avatar
Alexander Larsson committed
364
	if (cached_xdg_dirs_monitor == NULL) {
365 366
		config_file = g_build_filename (g_get_user_config_dir (),
						     "user-dirs.dirs", NULL);
Alexander Larsson's avatar
Alexander Larsson committed
367 368 369 370 371
		file = g_file_new_for_path (config_file);
		cached_xdg_dirs_monitor = g_file_monitor_file (file, 0, NULL);
		g_signal_connect (cached_xdg_dirs_monitor, "changed",
				  G_CALLBACK (xdg_dir_cache_changed_cb), NULL);
		g_object_unref (file);
372 373 374 375
		g_free (config_file);

		eel_debug_call_at_shutdown (destroy_xdg_dir_cache); 
	}
376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401
}

char *
nautilus_get_xdg_dir (const char *type)
{
	int i;

	if (cached_xdg_dirs == NULL) {
		update_xdg_dir_cache ();
	}

	for (i = 0 ; cached_xdg_dirs != NULL && cached_xdg_dirs[i].type != NULL; i++) {
		if (strcmp (cached_xdg_dirs[i].type, type) == 0) {
			return g_strdup (cached_xdg_dirs[i].path);
		}
	}
	if (strcmp ("DESKTOP", type) == 0) {
		return g_build_filename (g_get_home_dir (), DESKTOP_DIRECTORY_NAME, NULL);
	}
	if (strcmp ("TEMPLATES", type) == 0) {
		return g_build_filename (g_get_home_dir (), "Templates", NULL);
	}
	
	return g_strdup (g_get_home_dir ());
}

402 403 404 405 406 407
static char *
get_desktop_path (void)
{
	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR)) {
		return g_strdup (g_get_home_dir());
	} else {
408
		return nautilus_get_xdg_dir ("DESKTOP");
409 410 411
	}
}

Darin Adler's avatar
Darin Adler committed
412
/**
Darin Adler's avatar
Darin Adler committed
413
 * nautilus_get_desktop_directory:
Darin Adler's avatar
Darin Adler committed
414 415 416 417 418
 * 
 * Get the path for the directory containing files on the desktop.
 *
 * Return value: the directory path.
 **/
419
char *
Darin Adler's avatar
Darin Adler committed
420 421
nautilus_get_desktop_directory (void)
{
422
	char *desktop_directory;
423 424
	
	desktop_directory = get_desktop_path ();
Darin Adler's avatar
Darin Adler committed
425

426 427
	/* Don't try to create a home directory */
	if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR)) {
428
		if (!g_file_test (desktop_directory, G_FILE_TEST_EXISTS)) {
429
			mkdir (desktop_directory, DEFAULT_DESKTOP_DIRECTORY_MODE);
430
			/* FIXME bugzilla.gnome.org 41286: 
431 432 433 434 435 436 437
			 * How should we handle the case where this mkdir fails? 
			 * Note that nautilus_application_startup will refuse to launch if this 
			 * directory doesn't get created, so that case is OK. But the directory 
			 * could be deleted after Nautilus was launched, and perhaps
			 * there is some bad side-effect of not handling that case.
			 */
		}
Darin Adler's avatar
Darin Adler committed
438 439 440 441 442
	}

	return desktop_directory;
}

Alexander Larsson's avatar
Alexander Larsson committed
443 444 445 446 447 448 449 450 451 452 453 454 455
GFile *
nautilus_get_desktop_location (void)
{
	char *desktop_directory;
	GFile *res;
	
	desktop_directory = get_desktop_path ();

	res = g_file_new_for_path (desktop_directory);
	g_free (desktop_directory);
	return res;
}

Alexander Larsson's avatar
Alexander Larsson committed
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470

/**
 * nautilus_get_desktop_directory_uri:
 * 
 * Get the uri for the directory containing files on the desktop.
 *
 * Return value: the directory path.
 **/
char *
nautilus_get_desktop_directory_uri (void)
{
	char *desktop_path;
	char *desktop_uri;
	
	desktop_path = nautilus_get_desktop_directory ();
Alexander Larsson's avatar
Alexander Larsson committed
471
	desktop_uri = g_filename_to_uri (desktop_path, NULL, NULL);
472 473 474 475 476 477 478 479 480 481 482 483
	g_free (desktop_path);

	return desktop_uri;
}

char *
nautilus_get_desktop_directory_uri_no_create (void)
{
	char *desktop_path;
	char *desktop_uri;
	
	desktop_path = get_desktop_path ();
Alexander Larsson's avatar
Alexander Larsson committed
484
	desktop_uri = g_filename_to_uri (desktop_path, NULL, NULL);
Alexander Larsson's avatar
Alexander Larsson committed
485 486 487 488 489
	g_free (desktop_path);

	return desktop_uri;
}

490 491 492
char *
nautilus_get_home_directory_uri (void)
{
Alexander Larsson's avatar
Alexander Larsson committed
493
	return  g_filename_to_uri (g_get_home_dir (), NULL, NULL);
494 495 496
}


497 498 499 500 501 502 503 504 505 506 507 508
gboolean
nautilus_should_use_templates_directory (void)
{
	char *dir;
	gboolean res;
	
	dir = nautilus_get_xdg_dir ("TEMPLATES");
	res = strcmp (dir, g_get_home_dir ()) != 0;
	g_free (dir);
	return res;
}

509 510 511
char *
nautilus_get_templates_directory (void)
{
512
	return nautilus_get_xdg_dir ("TEMPLATES");
513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532
}

void
nautilus_create_templates_directory (void)
{
	char *dir;

	dir = nautilus_get_templates_directory ();
	if (!g_file_test (dir, G_FILE_TEST_EXISTS)) {
		mkdir (dir, DEFAULT_NAUTILUS_DIRECTORY_MODE);
	}
	g_free (dir);
}

char *
nautilus_get_templates_directory_uri (void)
{
	char *directory, *uri;

	directory = nautilus_get_templates_directory ();
Alexander Larsson's avatar
Alexander Larsson committed
533
	uri = g_filename_to_uri (directory, NULL, NULL);
534 535 536
	g_free (directory);
	return uri;
}
Alexander Larsson's avatar
Alexander Larsson committed
537

538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553
char *
nautilus_get_searches_directory (void)
{
	char *user_dir;
	char *searches_dir;

	user_dir = nautilus_get_user_directory ();
	searches_dir = g_build_filename (user_dir, "searches", NULL);
	g_free (user_dir);
	
	if (!g_file_test (searches_dir, G_FILE_TEST_EXISTS))
		mkdir (searches_dir, DEFAULT_NAUTILUS_DIRECTORY_MODE);

	return searches_dir;
}

554
/* These need to be reset to NULL when desktop_is_home_dir changes */
Alexander Larsson's avatar
Alexander Larsson committed
555 556 557
static GFile *desktop_dir = NULL;
static GFile *desktop_dir_dir = NULL;
static char *desktop_dir_filename = NULL;
558 559
static gboolean desktop_dir_changed_callback_installed = FALSE;

560

561
static void
562
desktop_dir_changed (void)
563
{
Alexander Larsson's avatar
Alexander Larsson committed
564 565 566 567 568 569 570 571 572 573
	if (desktop_dir) {
		g_object_unref (desktop_dir);
	}
	if (desktop_dir_dir) {
		g_object_unref (desktop_dir_dir);
	}
	g_free (desktop_dir_filename);
	desktop_dir = NULL;
	desktop_dir_dir = NULL;
	desktop_dir_filename = NULL;
574 575
}

576 577 578 579 580 581
static void
desktop_dir_changed_callback (gpointer callback_data)
{
	desktop_dir_changed ();
}

582 583
static void
update_desktop_dir (void)
584
{
Alexander Larsson's avatar
Alexander Larsson committed
585 586
	char *path;
	char *dirname;
587

588
	path = get_desktop_path ();
Alexander Larsson's avatar
Alexander Larsson committed
589
	desktop_dir = g_file_new_for_path (path);
590
	
Alexander Larsson's avatar
Alexander Larsson committed
591 592 593 594 595 596 597 598 599 600 601 602 603 604
	dirname = g_path_get_dirname (path);
	desktop_dir_dir = g_file_new_for_path (dirname);
	g_free (dirname);
	desktop_dir_filename = g_path_get_basename (path);
	g_free (path);
}

gboolean
nautilus_is_home_directory_file (GFile *dir,
				 const char *filename)
{
	char *dirname;
	static GFile *home_dir_dir = NULL;
	static char *home_dir_filename = NULL;
605
	
Alexander Larsson's avatar
Alexander Larsson committed
606 607 608 609 610 611 612 613 614
	if (home_dir_dir == NULL) {
		dirname = g_path_get_dirname (g_get_home_dir ());
		home_dir_dir = g_file_new_for_path (dirname);
		g_free (dirname);
		home_dir_filename = g_path_get_basename (g_get_home_dir ());
	}

	return (g_file_equal (dir, home_dir_dir) &&
		strcmp (filename, home_dir_filename) == 0);
615 616
}

617
gboolean
Alexander Larsson's avatar
Alexander Larsson committed
618
nautilus_is_home_directory (GFile *dir)
619
{
Alexander Larsson's avatar
Alexander Larsson committed
620
	static GFile *home_dir = NULL;
621
	
Alexander Larsson's avatar
Alexander Larsson committed
622 623 624
	if (home_dir == NULL) {
		home_dir = g_file_new_for_path (g_get_home_dir ());
	}
625

Alexander Larsson's avatar
Alexander Larsson committed
626 627
	return g_file_equal (dir, home_dir);
}
628

Alexander Larsson's avatar
Alexander Larsson committed
629 630 631 632 633 634 635
gboolean
nautilus_is_root_directory (GFile *dir)
{
	static GFile *root_dir = NULL;
	
	if (root_dir == NULL) {
		root_dir = g_file_new_for_path ("/");
636 637
	}

Alexander Larsson's avatar
Alexander Larsson committed
638
	return g_file_equal (dir, root_dir);
639
}
Alexander Larsson's avatar
Alexander Larsson committed
640 641
		
		
642
gboolean
Alexander Larsson's avatar
Alexander Larsson committed
643 644
nautilus_is_desktop_directory_file (GFile *dir,
				    const char *file)
645 646 647 648 649 650 651 652 653
{

	if (!desktop_dir_changed_callback_installed) {
		eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR,
					      desktop_dir_changed_callback,
					      NULL);
		desktop_dir_changed_callback_installed = TRUE;
	}
		
Alexander Larsson's avatar
Alexander Larsson committed
654
	if (desktop_dir == NULL) {
655 656 657
		update_desktop_dir ();
	}

Alexander Larsson's avatar
Alexander Larsson committed
658 659
	return (g_file_equal (dir, desktop_dir_dir) &&
		strcmp (file, desktop_dir_filename) == 0);
660 661 662
}

gboolean
Alexander Larsson's avatar
Alexander Larsson committed
663
nautilus_is_desktop_directory (GFile *dir)
664 665
{

666 667 668 669 670 671 672
	if (!desktop_dir_changed_callback_installed) {
		eel_preferences_add_callback (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR,
					      desktop_dir_changed_callback,
					      NULL);
		desktop_dir_changed_callback_installed = TRUE;
	}
		
Alexander Larsson's avatar
Alexander Larsson committed
673
	if (desktop_dir == NULL) {
674
		update_desktop_dir ();
675 676
	}

Alexander Larsson's avatar
Alexander Larsson committed
677
	return g_file_equal (dir, desktop_dir);
678 679 680
}


681 682 683 684 685 686 687 688 689 690
/**
 * nautilus_get_gmc_desktop_directory:
 * 
 * Get the path for the directory containing the legacy gmc desktop.
 *
 * Return value: the directory path.
 **/
char *
nautilus_get_gmc_desktop_directory (void)
{
Alexander Larsson's avatar
Alexander Larsson committed
691
	return g_build_filename (g_get_home_dir (), LEGACY_DESKTOP_DIRECTORY_NAME, NULL);
692 693
}

Darin Adler's avatar
Darin Adler committed
694 695 696 697 698 699 700
/**
 * nautilus_get_pixmap_directory
 * 
 * Get the path for the directory containing Nautilus pixmaps.
 *
 * Return value: the directory path.
 **/
701
char *
Darin Adler's avatar
Darin Adler committed
702 703
nautilus_get_pixmap_directory (void)
{
704
	return g_strdup (DATADIR "/pixmaps/nautilus");
Darin Adler's avatar
Darin Adler committed
705 706
}

707
/* FIXME bugzilla.gnome.org 42423: 
708
 * Callers just use this and dereference so we core dump if
Darin Adler's avatar
Darin Adler committed
709 710 711 712 713 714 715
 * pixmaps are missing. That is lame.
 */
char *
nautilus_pixmap_file (const char *partial_path)
{
	char *path;

716
	path = g_build_filename (DATADIR "/pixmaps/nautilus", partial_path, NULL);
717
	if (g_file_test (path, G_FILE_TEST_EXISTS)) {
Darin Adler's avatar
Darin Adler committed
718
		return path;
719 720 721 722 723
	} else {
		char *tmp;
		tmp = nautilus_get_pixmap_directory ();
		g_debug ("Failed to locate \"%s\" in Nautilus pixmap path \"%s\". Incomplete installation?", partial_path, tmp);
		g_free (tmp);
Darin Adler's avatar
Darin Adler committed
724
	}
725 726
	g_free (path);
	return NULL;
Darin Adler's avatar
Darin Adler committed
727
}
728

729 730 731 732 733 734 735 736
char *
nautilus_get_data_file_path (const char *partial_path)
{
	char *path;
	char *user_directory;

	/* first try the user's home directory */
	user_directory = nautilus_get_user_directory ();
737
	path = g_build_filename (user_directory, partial_path, NULL);
738
	g_free (user_directory);
739
	if (g_file_test (path, G_FILE_TEST_EXISTS)) {
740 741 742 743 744
		return path;
	}
	g_free (path);
	
	/* next try the shared directory */
745
	path = g_build_filename (NAUTILUS_DATADIR, partial_path, NULL);
746
	if (g_file_test (path, G_FILE_TEST_EXISTS)) {
747 748 749 750 751 752 753
		return path;
	}
	g_free (path);

	return NULL;
}

754 755 756 757 758
char *
nautilus_ensure_unique_file_name (const char *directory_uri,
				  const char *base_name,
				  const char *extension)
{
Alexander Larsson's avatar
Alexander Larsson committed
759 760 761
	GFileInfo *info;
	char *filename;
	GFile *dir, *child;
762
	int copy;
Alexander Larsson's avatar
Alexander Larsson committed
763
	char *res;
764

Alexander Larsson's avatar
Alexander Larsson committed
765
	dir = g_file_new_for_uri (directory_uri);
766

Alexander Larsson's avatar
Alexander Larsson committed
767 768 769 770 771 772
	info = g_file_query_info (dir, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL);
	if (info == NULL) {
		g_object_unref (dir);
		return NULL;
	}
	g_object_unref (info);
773

Alexander Larsson's avatar
Alexander Larsson committed
774 775 776 777 778 779
	filename = g_strdup_printf ("%s%s",
				    base_name,
				    extension);
	child = g_file_get_child (dir, filename);
	g_free (filename);
	
780
	copy = 1;
Alexander Larsson's avatar
Alexander Larsson committed
781 782 783 784 785 786 787 788 789 790 791
	while ((info = g_file_query_info (child, G_FILE_ATTRIBUTE_STD_TYPE, 0, NULL, NULL)) != NULL) {
		g_object_unref (info);
		g_object_unref (child);
		
		filename = g_strdup_printf ("%s-%d%s",
					    base_name,
					    copy,
					    extension);
		child = g_file_get_child (dir, filename);
		g_free (filename);
		
792 793 794
		copy++;
	}

Alexander Larsson's avatar
Alexander Larsson committed
795 796 797 798 799
	res = g_file_get_uri (child);
	g_object_unref (child);
	g_object_unref (dir);
	
	return res;
800 801
}

802 803 804 805 806
char *
nautilus_unique_temporary_file_name (void)
{
	const char *prefix = "/tmp/nautilus-temp-file";
	char *file_name;
807
	int fd;
808 809 810

	file_name = g_strdup_printf ("%sXXXXXX", prefix);

811 812
	fd = mkstemp (file_name); 
	if (fd == -1) {
813
		g_free (file_name);
814 815 816
		file_name = NULL;
	} else {
		close (fd);
817
	}
818
	
819 820 821
	return file_name;
}

Alexander Larsson's avatar
Alexander Larsson committed
822 823
GFile *
nautilus_find_existing_uri_in_hierarchy (GFile *location)
824
{
Alexander Larsson's avatar
Alexander Larsson committed
825 826
	GFileInfo *info;
	GFile *tmp;
827

Alexander Larsson's avatar
Alexander Larsson committed
828
	g_assert (location != NULL);
829

Alexander Larsson's avatar
Alexander Larsson committed
830 831 832
	location = g_object_ref (location);
	while (location != NULL) {
		info = g_file_query_info (location,
833
					  "std::name",
Alexander Larsson's avatar
Alexander Larsson committed
834 835 836 837
					  0, NULL, NULL);
		g_object_unref (info);
		if (info != NULL) {
			return location;
838
		}
Alexander Larsson's avatar
Alexander Larsson committed
839 840 841
		tmp = location;
		location = g_file_get_parent (location);
		g_object_unref (tmp);
Alexander Larsson's avatar
Alexander Larsson committed
842
	}
Alexander Larsson's avatar
Alexander Larsson committed
843
	
Alexander Larsson's avatar
Alexander Larsson committed
844
	return location;
Alexander Larsson's avatar
Alexander Larsson committed
845 846
}

847 848 849 850 851 852 853 854
#if !defined (NAUTILUS_OMIT_SELF_CHECK)

void
nautilus_self_check_file_utilities (void)
{
}

#endif /* !NAUTILUS_OMIT_SELF_CHECK */