Beispiel #1
0
/**
 * g_mkdir_with_parents:
 * @pathname: a pathname in the GLib file name encoding
 * @mode: permissions to use for newly created directories
 *
 * Create a directory if it doesn't already exist. Create intermediate
 * parent directories as needed, too.
 *
 * Returns: 0 if the directory already exists, or was successfully
 * created. Returns -1 if an error occurred, with errno set.
 *
 * Since: 2.8
 */
int
g_mkdir_with_parents (const gchar *pathname,
		      int          mode)
{
  gchar *fn, *p;

  if (pathname == NULL || *pathname == '\0')
    {
      errno = EINVAL;
      return -1;
    }

  fn = g_strdup (pathname);

  if (g_path_is_absolute (fn))
    p = (gchar *) g_path_skip_root (fn);
  else
    p = fn;

  do
    {
      while (*p && !G_IS_DIR_SEPARATOR (*p))
	p++;
      
      if (!*p)
	p = NULL;
      else
	*p = '\0';
      
      if (!g_file_test (fn, G_FILE_TEST_EXISTS))
	{
	  if (g_mkdir (fn, mode) == -1)
	    {
	      int errno_save = errno;
	      g_free (fn);
	      errno = errno_save;
	      return -1;
	    }
	}
      else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
	{
	  g_free (fn);
	  errno = ENOTDIR;
	  return -1;
	}
      if (p)
	{
	  *p++ = G_DIR_SEPARATOR;
	  while (*p && G_IS_DIR_SEPARATOR (*p))
	    p++;
	}
    }
  while (p);

  g_free (fn);

  return 0;
}
Beispiel #2
0
static int
pathnamecmp (const char *a,
	     const char *b)
{
  while (*a && *b &&
	 ((G_IS_DIR_SEPARATOR (*a) && G_IS_DIR_SEPARATOR (*b)) ||
	  g_ascii_toupper (*a) == g_ascii_toupper (*b)))
    {
      a++;
      b++;
    }
  return g_ascii_toupper (*a) - g_ascii_toupper (*b);
}
Beispiel #3
0
/**
 * g_stat:
 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
 * @buf: a pointer to a <structname>stat</structname> struct, which
 *    will be filled with the file information
 *
 * A wrapper for the POSIX stat() function. The stat() function
 * returns information about a file.
 *
 * See the C library manual for more details about stat().
 *
 * Returns: 0 if the information was successfully retrieved, -1 if an error
 *    occurred
 *
 * Since: 2.6
 */
int
ws_stdio_stat64 (const gchar *filename,
	ws_statb64 *buf)
{
      wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
      int retval;
      int save_errno;
      size_t len;

      if (wfilename == NULL)
	{
	  errno = EINVAL;
	  return -1;
	}

      len = wcslen (wfilename);
      while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
	len--;
      if (len > 0 &&
	  (!g_path_is_absolute (filename) || len > (size_t) (g_path_skip_root (filename) - filename)))
	wfilename[len] = '\0';

      retval = _wstati64 (wfilename, buf);
      save_errno = errno;

      g_free (wfilename);

      errno = save_errno;
      return retval;
}
Beispiel #4
0
/**
 * g_stat:
 * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
 * @buf: a pointer to a <structname>stat</structname> struct, which
 *    will be filled with the file information
 *
 * A wrapper for the POSIX stat() function. The stat() function
 * returns information about a file. On Windows the stat() function in
 * the C library checks only the FAT-style READONLY attribute and does
 * not look at the ACL at all. Thus on Windows the protection bits in
 * the st_mode field are a fabrication of little use.
 *
 * On Windows the Microsoft C libraries have several variants of the
 * <structname>stat</structname> struct and stat() function with names
 * like "_stat", "_stat32", "_stat32i64" and "_stat64i32". The one
 * used here is for 32-bit code the one with 32-bit size and time
 * fields, specifically called "_stat32".
 *
 * In Microsoft's compiler, by default "struct stat" means one with
 * 64-bit time fields while in MinGW "struct stat" is the legacy one
 * with 32-bit fields. To hopefully clear up this messs, the gstdio.h
 * header defines a type GStatBuf which is the appropriate struct type
 * depending on the platform and/or compiler being used. On POSIX it
 * is just "struct stat", but note that even on POSIX platforms,
 * "stat" might be a macro.
 *
 * See your C library manual for more details about stat().
 *
 * Returns: 0 if the information was successfully retrieved, -1 if an error
 *    occurred
 *
 * Since: 2.6
 */
int
g_stat (const gchar *filename,
        GStatBuf    *buf)
{
#ifdef G_OS_WIN32
    wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
    int retval;
    int save_errno;
    int len;

    if (wfilename == NULL)
    {
        errno = EINVAL;
        return -1;
    }

    len = wcslen (wfilename);
    while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
        len--;
    if (len > 0 &&
            (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename))
        wfilename[len] = '\0';

    retval = _wstat (wfilename, buf);
    save_errno = errno;

    g_free (wfilename);

    errno = save_errno;
    return retval;
#else
    return stat (filename, buf);
#endif
}
Beispiel #5
0
static gboolean
running_in_tree (void)
{
	const char *argv0 = g_get_prgname ();

	if (!argv0)
		return FALSE;

	/* Sometime we see, e.g., "lt-gnumeric" as basename.  */
	{
		char *base = g_path_get_basename (argv0);
		gboolean has_lt_prefix = (strncmp (base, "lt-", 3) == 0);
		g_free (base);
		if (has_lt_prefix)
			return TRUE;
	}

	/* Look for ".libs" as final path element.  */
	{
		const char *dotlibs = strstr (argv0, ".libs/");
		if (dotlibs &&
		    (dotlibs == argv0 || G_IS_DIR_SEPARATOR (dotlibs[-1])) &&
		    strchr (dotlibs + 6, G_DIR_SEPARATOR) == NULL)
			return TRUE;
	}

	return FALSE;
}
Beispiel #6
0
char *
map_fs_to_utf8(const char *path_fs)
{
	if (music_dir != NULL &&
	    strncmp(path_fs, music_dir, music_dir_length) == 0 &&
	    G_IS_DIR_SEPARATOR(path_fs[music_dir_length]))
		/* remove musicDir prefix */
		path_fs += music_dir_length + 1;
	else if (G_IS_DIR_SEPARATOR(path_fs[0]))
		/* not within musicDir */
		return NULL;

	while (path_fs[0] == G_DIR_SEPARATOR)
		++path_fs;

	return fs_charset_to_utf8(path_fs);
}
static void
do_cd (void)
{
	char *p;

	p = arg_data [arg_cur++];

	if (!p) {
		fprintf (vfserr, "Takes a directory argument\n");
		return;
	}

	if (!g_ascii_strcasecmp (p, "..")) {
		guint lp;
		char **tmp;
		GString *newp = g_string_new ("");
		const char *ptr = g_path_skip_root (cur_dir);

		g_string_append_len (newp, cur_dir, ptr - cur_dir);

		tmp = g_strsplit_set (ptr, DIR_SEPARATORS, -1);
		lp  = 0;
		if (!tmp [lp])
			return;

		while (tmp [lp + 1] && strlen (tmp [lp + 1]) > 0) {
			g_string_append_printf (newp, "%s" G_DIR_SEPARATOR_S, tmp [lp]);
			lp++;
		}
		cur_dir = newp->str;
		g_string_free (newp, FALSE);
	} else if (!g_ascii_strcasecmp (p, ".")) {
	} else {
		char *newpath;

		if (g_path_is_absolute (p)) {
			if (!G_IS_DIR_SEPARATOR (p [strlen (p) - 1]))
				newpath = g_strconcat (p, G_DIR_SEPARATOR_S, NULL);
			else
				newpath = g_strdup (p);
		} else {
			char *ptr;
			
			ptr = get_regexp_name (p, cur_dir, TRUE);
			if (!ptr) {
				fprintf (vfserr, "Can't find '%s'\n", p);
				return;
			}

			newpath = g_strconcat (cur_dir, ptr, G_DIR_SEPARATOR_S, NULL);
		}

		if (validate_path (newpath)) {
			cur_dir = newpath;
		} else
			fprintf (vfserr, "Invalid path %s\n", newpath);
	}
}
Beispiel #8
0
const char *
map_to_relative_path(const char *path_utf8)
{
	return music_dir != NULL &&
		memcmp(path_utf8, music_dir, music_dir_length) == 0 &&
		G_IS_DIR_SEPARATOR(path_utf8[music_dir_length])
		? path_utf8 + music_dir_length + 1
		: path_utf8;
}
static gboolean
is_basename (const char *filename)
{
	if (*filename == '\0')
		return FALSE; /* no empty strings, please */

	for (; *filename; filename++)
		if (G_IS_DIR_SEPARATOR (*filename))
			return FALSE;

	return TRUE;
}
static gboolean
load_extractor_rule (GKeyFile  *key_file,
                     GError   **error)
{
	gchar *module_path, **mimetypes;
	gsize n_mimetypes, i;
	RuleInfo rule = { 0 };

	module_path = g_key_file_get_string (key_file, "ExtractorRule", "ModulePath", error);

	if (!module_path) {
		return FALSE;
	}

	if (!G_IS_DIR_SEPARATOR (module_path[0])) {
		gchar *tmp;

		tmp = g_build_filename (TRACKER_EXTRACTORS_DIR, module_path, NULL);
		g_free (module_path);
		module_path = tmp;
	}

	mimetypes = g_key_file_get_string_list (key_file, "ExtractorRule", "MimeTypes", &n_mimetypes, error);

	if (!mimetypes) {
		g_free (module_path);
		return FALSE;
	}

	rule.fallback_rdf_type = g_key_file_get_string (key_file, "ExtractorRule", "FallbackRdfType", NULL);

	/* Construct the rule */
	rule.module_path = g_intern_string (module_path);

	for (i = 0; i < n_mimetypes; i++) {
		GPatternSpec *pattern;

		pattern = g_pattern_spec_new (mimetypes[i]);
		rule.patterns = g_list_prepend (rule.patterns, pattern);
	}

	if (G_UNLIKELY (!rules)) {
		rules = g_array_new (FALSE, TRUE, sizeof (RuleInfo));
	}

	g_array_append_val (rules, rule);
	g_strfreev (mimetypes);
	g_free (module_path);

	return TRUE;
}
Beispiel #11
0
/**
 * go_gtk_url_is_writeable:
 * @parent : #GtkWindow
 * @uri :
 * @overwrite_by_default :
 *
 * Check if it makes sense to try saving.
 * If it's an existing file and writable for us, ask if we want to overwrite.
 * We check for other problems, but if we miss any, the saver will report.
 * So it doesn't have to be bulletproof.
 *
 * FIXME: The message boxes should really be children of the file selector,
 * not the workbook.
 **/
gboolean
go_gtk_url_is_writeable (GtkWindow *parent, char const *uri,
			 gboolean overwrite_by_default)
{
	gboolean result = TRUE;
	char *filename;

	if (uri == NULL || uri[0] == '\0')
		result = FALSE;

	filename = go_filename_from_uri (uri);
	if (!filename)
		return TRUE;  /* Just assume writable.  */

	if (G_IS_DIR_SEPARATOR (filename [strlen (filename) - 1]) ||
	    g_file_test (filename, G_FILE_TEST_IS_DIR)) {
		go_gtk_notice_dialog (parent, GTK_MESSAGE_ERROR,
				      _("%s\nis a directory name"), uri);
		result = FALSE;
	} else if (go_file_access (uri, W_OK) != 0 && errno != ENOENT) {
		go_gtk_notice_dialog (parent, GTK_MESSAGE_ERROR,
				      _("You do not have permission to save to\n%s"),
				      uri);
		result = FALSE;
	} else if (g_file_test (filename, G_FILE_TEST_EXISTS)) {
		char *dirname = go_dirname_from_uri (uri, TRUE);
		char *basename = go_basename_from_uri (uri);
		char *msg = g_markup_printf_escaped (
			_("A file called <i>%s</i> already exists in %s.\n\n"
			  "Do you want to save over it?"),
			basename, dirname);
		GtkWidget *dialog = gtk_message_dialog_new_with_markup (parent,
			 GTK_DIALOG_DESTROY_WITH_PARENT,
			 GTK_MESSAGE_WARNING,
			 GTK_BUTTONS_OK_CANCEL,
			 msg);
		gtk_dialog_set_default_response (GTK_DIALOG (dialog),
			overwrite_by_default ? GTK_RESPONSE_OK : GTK_RESPONSE_CANCEL);
		result = GTK_RESPONSE_OK ==
			go_gtk_dialog_run (GTK_DIALOG (dialog), parent);
		g_free (dirname);
		g_free (basename);
		g_free (msg);
	}

	g_free (filename);
	return result;
}
static void
entry_changed(GtkWidget *entry, struct _save_data *data)
{
	char *path;
	char *basename = NULL;
	const char *file;

	path = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (data->entry));
	if (path == NULL
	    || G_IS_DIR_SEPARATOR (path[strlen(path)-1])
	    || (basename = g_path_get_basename(path)) == NULL
	    || (basename[0] == '.' && basename[1] == '\0')
	    || (g_file_test(path, G_FILE_TEST_IS_DIR)))
		file = "attachment";
	else
		file = basename;

	gtk_tree_model_foreach((GtkTreeModel *)data->model, entry_changed_update, (void *)file);
	g_free(path);
	g_free(basename);
}
Beispiel #13
0
static gpointer
pk_backend_pattern_chroot (PkBackend *backend, const gchar *needle, GError **error)
{
	PkBackendAlpmPrivate *priv = pk_backend_get_user_data (backend);
	g_return_val_if_fail (needle != NULL, NULL);

	if (G_IS_DIR_SEPARATOR (*needle)) {
		const gchar *file = needle, *root = alpm_option_get_root (priv->alpm);

		/* adjust needle to the correct prefix */
		for (; *file == *root; ++file, ++root) {
			if (*root == '\0') {
				needle = file - 1;
				break;
			} else if (*file == '\0') {
				break;
			}
		}
	}

	return (gpointer) needle;
}
Beispiel #14
0
static gboolean
pk_backend_match_file (alpm_pkg_t *pkg, const gchar *needle)
{
	alpm_filelist_t *files;
	gsize i;

	g_return_val_if_fail (pkg != NULL, FALSE);
	g_return_val_if_fail (needle != NULL, FALSE);

	files = alpm_pkg_get_files (pkg);

	/* match any file the package contains */
	if (G_IS_DIR_SEPARATOR (*needle)) {
		for (i = 0; i < files->count; ++i) {
			const gchar *file = files->files[i].name;
			/* match the full path of file */
			if (g_strcmp0 (file, needle + 1) == 0)
				return TRUE;
		}
	} else {
		for (i = 0; i < files->count; ++i) {
			const gchar *file = files->files[i].name;
			const gchar *name = strrchr (file, G_DIR_SEPARATOR);

			if (name == NULL) {
				name = file;
			} else {
				++name;
			}

			/* match the basename of file */
			if (g_strcmp0 (name, needle) == 0)
				return TRUE;
		}
	}

	return FALSE;
}
Beispiel #15
0
static int
_g_win32_stat_utf8 (const gchar       *filename,
                    GWin32PrivateStat *buf,
                    gboolean           for_symlink)
{
  wchar_t *wfilename;
  int result;
  gsize len;

  if (filename == NULL)
    {
      errno = EINVAL;
      return -1;
    }

  len = strlen (filename);

  while (len > 0 && G_IS_DIR_SEPARATOR (filename[len - 1]))
    len--;

  if (len <= 0 ||
      (g_path_is_absolute (filename) && len <= g_path_skip_root (filename) - filename))
    len = strlen (filename);

  wfilename = g_utf8_to_utf16 (filename, len, NULL, NULL, NULL);

  if (wfilename == NULL)
    {
      errno = EINVAL;
      return -1;
    }

  result = _g_win32_stat_utf16_no_trailing_slashes (wfilename, -1, buf, for_symlink);

  g_free (wfilename);

  return result;
}
Beispiel #16
0
/**
 * g_file_open_tmp:
 * @tmpl: Template for file name, as in g_mkstemp(), basename only
 * @name_used: location to store actual name used
 * @error: return location for a #GError
 *
 * Opens a file for writing in the preferred directory for temporary
 * files (as returned by g_get_tmp_dir()). 
 *
 * @tmpl should be a string in the GLib file name encoding ending with
 * six 'X' characters, as the parameter to g_mkstemp() (or mkstemp()).
 * However, unlike these functions, the template should only be a
 * basename, no directory components are allowed. If template is
 * %NULL, a default template is used.
 *
 * Note that in contrast to g_mkstemp() (and mkstemp()) 
 * @tmpl is not modified, and might thus be a read-only literal string.
 *
 * The actual name used is returned in @name_used if non-%NULL. This
 * string should be freed with g_free() when not needed any longer.
 * The returned name is in the GLib file name encoding.
 *
 * Return value: A file handle (as from open()) to 
 * the file opened for reading and writing. The file is opened in binary 
 * mode on platforms where there is a difference. The file handle should be
 * closed with close(). In case of errors, -1 is returned 
 * and @error will be set.
 **/
gint
g_file_open_tmp (const gchar *tmpl,
		 gchar      **name_used,
		 GError     **error)
{
  int retval;
  const char *tmpdir;
  char *sep;
  char *fulltemplate;
  const char *slash;

  if (tmpl == NULL)
    tmpl = ".XXXXXX";

  if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
#ifdef G_OS_WIN32
      || (strchr (tmpl, '/') != NULL && (slash = "/"))
#endif
      )
    {
      gchar *display_tmpl = g_filename_display_name (tmpl);
      char c[2];
      c[0] = *slash;
      c[1] = '\0';

      g_set_error (error,
		   G_FILE_ERROR,
		   G_FILE_ERROR_FAILED,
		   _("Template '%s' invalid, should not contain a '%s'"),
		   display_tmpl, c);
      g_free (display_tmpl);

      return -1;
    }
  
  if (strlen (tmpl) < 6 ||
      strcmp (tmpl + strlen (tmpl) - 6, "XXXXXX") != 0)
    {
      gchar *display_tmpl = g_filename_display_name (tmpl);
      g_set_error (error,
		   G_FILE_ERROR,
		   G_FILE_ERROR_FAILED,
		   _("Template '%s' doesn't end with XXXXXX"),
		   display_tmpl);
      g_free (display_tmpl);
      return -1;
    }

  tmpdir = g_get_tmp_dir ();

  if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
    sep = "";
  else
    sep = G_DIR_SEPARATOR_S;

  fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);

  retval = g_mkstemp (fulltemplate);

  if (retval == -1)
    {
      gchar *display_fulltemplate = g_filename_display_name (fulltemplate);
      g_set_error (error,
		   G_FILE_ERROR,
		   g_file_error_from_errno (errno),
		   _("Failed to create file '%s': %s"),
		   display_fulltemplate, g_strerror (errno));
      g_free (display_fulltemplate);
      g_free (fulltemplate);
      return -1;
    }

  if (name_used)
    *name_used = fulltemplate;
  else
    g_free (fulltemplate);

  return retval;
}
int
main (int argc, char **argv)
{
	int exit = 0;
	char *buffer = g_new (char, 1024) ;
	GIOChannel *ioc;
	guint watch_id = 0;
	GOptionContext *ctx = NULL;
	GError *error = NULL;

	/* default to interactive on a terminal */
	interactive = isatty (0);

	ctx = g_option_context_new("test-vfs");
	g_option_context_add_main_entries(ctx, options, NULL);

	if (!g_option_context_parse(ctx, &argc, &argv, &error)) {
		g_printerr("main: %s\n", error->message);

		g_error_free(error);
		g_option_context_free(ctx);
		return 1;
	}

	g_option_context_free(ctx);

	files = g_hash_table_new (g_str_hash, g_str_equal);

	if (noninteractive)
		interactive = FALSE;

	if (interactive)
		vfserr = stderr;
	else
		vfserr = stdout;

	if (!mate_vfs_init ()) {
		fprintf (vfserr, "Cannot initialize mate-vfs.\n");
		return 1;
	}
	mate_vfs_module_callback_push
		(MATE_VFS_MODULE_CALLBACK_AUTHENTICATION,
		 authentication_callback, NULL, NULL);

	if (argc == 1)
		cur_dir = g_get_current_dir ();
	else
		cur_dir = g_strdup(argv[1]);

	if (cur_dir && !G_IS_DIR_SEPARATOR (cur_dir [strlen (cur_dir) - 1]))
		cur_dir = g_strconcat (cur_dir, G_DIR_SEPARATOR_S, NULL);

	if (interactive == TRUE) {
		main_loop = g_main_loop_new (NULL, TRUE);
		ioc = g_io_channel_unix_new (0 /* stdin */);
		g_io_channel_set_encoding (ioc, NULL, NULL);
		g_io_channel_set_buffered (ioc, FALSE);
		watch_id = g_io_add_watch (ioc,
					   G_IO_IN | G_IO_HUP | G_IO_ERR,
					   callback, buffer);
		g_io_channel_unref (ioc);
	}

	while (!exit) {
		char *ptr;

		if (interactive) {
			fprintf (stdout,"\n%s > ", cur_dir);
			fflush (stdout);

			strcpy (buffer, "");
			g_main_loop_run (main_loop);
		} else {
			/* In non-interactive mode we just do this evil
			 * thingie */
			buffer[0] = '\0';
			fgets (buffer, 1023, stdin);
			if (!buffer [0]) {
				exit = 1;
				continue;
			}
		}

		if (!buffer || buffer [0] == '#')
			continue;

		arg_data = g_strsplit (g_strchomp (buffer), delim, -1);
		arg_cur  = 0;
		if ((!arg_data || !arg_data[0]) && interactive) continue;
		if (!interactive)
			printf ("Command : '%s'\n", arg_data [0]);
		ptr = arg_data[arg_cur++];
		if (!ptr)
			continue;

		if (g_ascii_strcasecmp (ptr, "ls") == 0)
			do_ls ();
		else if (g_ascii_strcasecmp (ptr, "cd") == 0)
			do_cd ();
		else if (g_ascii_strcasecmp (ptr, "dump") == 0)
			do_dump ();
		else if (g_ascii_strcasecmp (ptr, "type") == 0 ||
			 g_ascii_strcasecmp (ptr, "cat") == 0)
			do_cat ();
		else if (g_ascii_strcasecmp (ptr, "cp") == 0)
			do_cp ();
		else if (g_ascii_strcasecmp (ptr, "rm") == 0)
			do_rm ();
		else if (g_ascii_strcasecmp (ptr, "mkdir") == 0)
			do_mkdir ();
		else if (g_ascii_strcasecmp (ptr, "rmdir") == 0)
			do_rmdir ();
		else if (g_ascii_strcasecmp (ptr, "mv") == 0)
			do_mv ();
		else if (g_ascii_strcasecmp (ptr, "info") == 0 ||
			 g_ascii_strcasecmp (ptr, "stat") == 0)
			do_info ();
		else if (g_ascii_strcasecmp (ptr, "findtrash") == 0)
			do_findtrash ();
		else if (g_ascii_strcasecmp (ptr, "ssl") == 0)
			do_ssl ();
		else if (g_ascii_strcasecmp (ptr, "sync") == 0)
			fprintf (vfserr, "a shell is like a boat, it lists or syncs (RMS)\n");
		else if (g_ascii_strcasecmp (ptr,"help") == 0 ||
			 g_ascii_strcasecmp (ptr,"?")    == 0 ||
			 g_ascii_strcasecmp (ptr,"info") == 0 ||
			 g_ascii_strcasecmp (ptr,"man")  == 0)
			list_commands ();
		else if (g_ascii_strcasecmp (ptr,"exit") == 0 ||
			 g_ascii_strcasecmp (ptr,"quit") == 0 ||
			 g_ascii_strcasecmp (ptr,"q")    == 0 ||
			 g_ascii_strcasecmp (ptr,"bye") == 0)
			exit = 1;

		/* File ops */
		else if (g_ascii_strcasecmp (ptr, "open") == 0)
			do_open ();
		else if (g_ascii_strcasecmp (ptr, "create") == 0)
			do_create ();
		else if (g_ascii_strcasecmp (ptr, "close") == 0)
			do_close ();
		else if (g_ascii_strcasecmp (ptr, "handleinfo") == 0)
			do_handleinfo ();
		else if (g_ascii_strcasecmp (ptr, "read") == 0)
			do_read ();
		else if (g_ascii_strcasecmp (ptr, "seek") == 0)
			do_seek ();
		
		else
			fprintf (vfserr, "Unknown command '%s'", ptr);

		g_strfreev (arg_data);
		arg_data = NULL;
	}

	if (interactive) {
		g_source_remove (watch_id);
		g_main_loop_unref (main_loop);
		main_loop = NULL;
	}

	g_free (buffer);
	g_free (cur_dir);

	close_files ();

	return 0;
}
Beispiel #18
0
static void
gwy_recent_file_update_thumbnail(GwyRecentFile *rf,
                                 GwyContainer *data,
                                 gint hint,
                                 GdkPixbuf *use_this_pixbuf)
{
    GwyDataField *dfield;
    GdkPixbuf *pixbuf;
    GStatBuf st;
    gchar *fnm;
    GwySIUnit *siunit;
    GwySIValueFormat *vf;
    gdouble xreal, yreal;
    gchar str_mtime[22];
    gchar str_size[22];
    gchar str_width[22];
    gchar str_height[22];
    GError *err = NULL;
    GQuark quark;
    gint id;

    g_return_if_fail(GWY_CONTAINER(data));

    if (use_this_pixbuf) {
        /* If we are given a pixbuf, hint must be the ultimate channel id.
         * We also ignore the thnumbnail state then. */
        g_return_if_fail(GDK_IS_PIXBUF(use_this_pixbuf));
        id = hint;
        pixbuf = g_object_ref(use_this_pixbuf);
    }
    else {
        pixbuf = NULL;
        id = gwy_recent_file_find_some_channel(data, hint);

        if (rf->file_state == FILE_STATE_UNKNOWN)
            gwy_app_recent_file_try_load_thumbnail(rf);
    }

    /* Find channel with the lowest id not smaller than hint */
    if (id == G_MAXINT) {
        gwy_debug("There is no channel in the file, cannot make thumbnail.");
        return;
    }

    if (g_stat(rf->file_sys, &st) != 0) {
        g_warning("File <%s> was just loaded or saved, but it doesn't seem to "
                  "exist any more: %s",
                  rf->file_utf8, g_strerror(errno));
        return;
    }

    if ((gulong)rf->file_mtime == (gulong)st.st_mtime)
        return;

    quark = gwy_app_get_data_key_for_id(id);
    dfield = GWY_DATA_FIELD(gwy_container_get_object(data, quark));
    g_return_if_fail(GWY_IS_DATA_FIELD(dfield));
    rf->file_mtime = st.st_mtime;
    rf->file_size = st.st_size;
    rf->image_width = gwy_data_field_get_xres(dfield);
    rf->image_height = gwy_data_field_get_yres(dfield);
    xreal = gwy_data_field_get_xreal(dfield);
    yreal = gwy_data_field_get_yreal(dfield);
    siunit = gwy_data_field_get_si_unit_xy(dfield);
    vf = gwy_si_unit_get_format(siunit, GWY_SI_UNIT_FORMAT_VFMARKUP,
                                sqrt(xreal*yreal), NULL);
    g_free(rf->image_real_size);
    rf->image_real_size
        = g_strdup_printf("%.*f×%.*f%s%s",
                          vf->precision, xreal/vf->magnitude,
                          vf->precision, yreal/vf->magnitude,
                          (vf->units && *vf->units) ? " " : "", vf->units);
    rf->file_state = FILE_STATE_OK;
    gwy_si_unit_value_format_free(vf);

    if (g_str_has_prefix(rf->file_sys, gwy_recent_file_thumbnail_dir())) {
        gchar c;

        c = rf->file_sys[strlen(gwy_recent_file_thumbnail_dir())];
        if (!c || G_IS_DIR_SEPARATOR(c))
            return;
    }

    if (!pixbuf)
        pixbuf = gwy_app_get_channel_thumbnail(data, id,
                                               TMS_NORMAL_THUMB_SIZE,
                                               TMS_NORMAL_THUMB_SIZE);

    g_snprintf(str_mtime, sizeof(str_mtime), "%lu", rf->file_mtime);
    g_snprintf(str_size, sizeof(str_size), "%lu", rf->file_size);
    g_snprintf(str_width, sizeof(str_width), "%d", rf->image_width);
    g_snprintf(str_height, sizeof(str_height), "%d", rf->image_height);

    /* invent an unique temporary name for atomic save
     * FIXME: rough, but works on Win32 */
    fnm = g_strdup_printf("%s.%u", rf->thumb_sys, getpid());
    if (!gdk_pixbuf_save(pixbuf, fnm, "png", &err,
                         KEY_SOFTWARE, PACKAGE_NAME,
                         KEY_THUMB_URI, rf->file_uri,
                         KEY_THUMB_MTIME, str_mtime,
                         KEY_THUMB_FILESIZE, str_size,
                         KEY_THUMB_IMAGE_WIDTH, str_width,
                         KEY_THUMB_IMAGE_HEIGHT, str_height,
                         KEY_THUMB_GWY_REAL_SIZE, rf->image_real_size,
                         NULL)) {
        g_clear_error(&err);
        rf->thumb_state = FILE_STATE_FAILED;
    }
#ifndef G_OS_WIN32
    chmod(fnm, 0600);
#endif
    g_unlink(rf->thumb_sys);
    if (g_rename(fnm, rf->thumb_sys) != 0) {
        g_unlink(fnm);
        rf->thumb_state = FILE_STATE_FAILED;
        rf->thumb_mtime = 0;
    }
    else {
        rf->thumb_state = FILE_STATE_UNKNOWN;  /* force reload */
        rf->thumb_mtime = rf->file_mtime;
    }
    g_free(fnm);

    gwy_object_unref(rf->pixbuf);
    g_object_unref(pixbuf);
}
Beispiel #19
0
void
xp_theme_init (void)
{
  char *buf;
  char dummy;
  int n, k;

  if (uxtheme_dll)
    return;

  memset (open_themes, 0, sizeof (open_themes));

  n = GetSystemDirectory (&dummy, 0);

  if (n <= 0)
    return;

  buf = g_malloc (n + 1 + strlen (UXTHEME_DLL));
  k = GetSystemDirectory (buf, n);
  
  if (k == 0 || k > n)
    {
      g_free (buf);
      return;
    }

  if (!G_IS_DIR_SEPARATOR (buf[strlen (buf) -1]))
    strcat (buf, G_DIR_SEPARATOR_S);
  strcat (buf, UXTHEME_DLL);

  uxtheme_dll = LoadLibrary (buf);
  g_free (buf);

  if (!uxtheme_dll)
    return;

  is_app_themed_func = (IsAppThemedFunc) GetProcAddress (uxtheme_dll, "IsAppThemed");

  if (is_app_themed_func)
    {
      is_theme_active_func = (IsThemeActiveFunc) GetProcAddress (uxtheme_dll, "IsThemeActive");
      open_theme_data_func = (OpenThemeDataFunc) GetProcAddress (uxtheme_dll, "OpenThemeData");
      close_theme_data_func = (CloseThemeDataFunc) GetProcAddress (uxtheme_dll, "CloseThemeData");
      draw_theme_background_func = (DrawThemeBackgroundFunc) GetProcAddress (uxtheme_dll, "DrawThemeBackground");
      enable_theme_dialog_texture_func = (EnableThemeDialogTextureFunc) GetProcAddress (uxtheme_dll, "EnableThemeDialogTexture");
      get_theme_sys_font_func = (GetThemeSysFontFunc) GetProcAddress (uxtheme_dll, "GetThemeSysFont");
      get_theme_sys_color_func = (GetThemeSysColorFunc) GetProcAddress (uxtheme_dll, "GetThemeSysColor");
      get_theme_sys_metric_func = (GetThemeSysSizeFunc) GetProcAddress (uxtheme_dll, "GetThemeSysSize");
      is_theme_partially_transparent_func = (IsThemeBackgroundPartiallyTransparentFunc) GetProcAddress (uxtheme_dll, "IsThemeBackgroundPartiallyTransparent");
      draw_theme_parent_background_func = (DrawThemeParentBackgroundFunc) GetProcAddress (uxtheme_dll, "DrawThemeParentBackground");
      get_theme_part_size_func = (GetThemePartSizeFunc) GetProcAddress (uxtheme_dll, "GetThemePartSize");
    }

  if (is_app_themed_func && is_theme_active_func)
    {
      use_xp_theme = (is_app_themed_func () && is_theme_active_func ());
    }
  else
    {
      use_xp_theme = FALSE;
    }
}
Beispiel #20
0
static void
_gdk_input_wintab_init_check (GdkDeviceManagerWin32 *device_manager)
{
  static gboolean wintab_initialized = FALSE;
  GdkDeviceWintab *device;
  GdkWindowAttr wa;
  WORD specversion;
  HCTX *hctx;
  UINT ndevices, ncursors, ncsrtypes, firstcsr, hardware;
  BOOL active;
  DWORD physid;
  AXIS axis_x, axis_y, axis_npressure, axis_or[3];
  int i, devix, cursorix, num_axes = 0;
  wchar_t devname[100], csrname[100];
  gchar *devname_utf8, *csrname_utf8, *device_name;
  BOOL defcontext_done;
  HMODULE wintab32;
  char *wintab32_dll_path;
  char dummy;
  int n, k;

  if (wintab_initialized)
    return;

  wintab_initialized = TRUE;

  wintab_contexts = NULL;

  if (_gdk_input_ignore_wintab)
    return;

  n = GetSystemDirectory (&dummy, 0);

  if (n <= 0)
    return;

  wintab32_dll_path = g_malloc (n + 1 + strlen (WINTAB32_DLL));
  k = GetSystemDirectory (wintab32_dll_path, n);
  
  if (k == 0 || k > n)
    {
      g_free (wintab32_dll_path);
      return;
    }

  if (!G_IS_DIR_SEPARATOR (wintab32_dll_path[strlen (wintab32_dll_path) -1]))
    strcat (wintab32_dll_path, G_DIR_SEPARATOR_S);
  strcat (wintab32_dll_path, WINTAB32_DLL);

  if ((wintab32 = LoadLibrary (wintab32_dll_path)) == NULL)
    return;

  if ((p_WTInfoA = (t_WTInfoA) GetProcAddress (wintab32, "WTInfoA")) == NULL)
    return;
  if ((p_WTInfoW = (t_WTInfoW) GetProcAddress (wintab32, "WTInfoW")) == NULL)
    return;
  if ((p_WTEnable = (t_WTEnable) GetProcAddress (wintab32, "WTEnable")) == NULL)
    return;
  if ((p_WTOpenA = (t_WTOpenA) GetProcAddress (wintab32, "WTOpenA")) == NULL)
    return;
  if ((p_WTOverlap = (t_WTOverlap) GetProcAddress (wintab32, "WTOverlap")) == NULL)
    return;
  if ((p_WTPacket = (t_WTPacket) GetProcAddress (wintab32, "WTPacket")) == NULL)
    return;
  if ((p_WTQueueSizeSet = (t_WTQueueSizeSet) GetProcAddress (wintab32, "WTQueueSizeSet")) == NULL)
    return;

  if (!(*p_WTInfoA) (0, 0, NULL))
    return;

  (*p_WTInfoA) (WTI_INTERFACE, IFC_SPECVERSION, &specversion);
  GDK_NOTE (INPUT, g_print ("Wintab interface version %d.%d\n",
			    HIBYTE (specversion), LOBYTE (specversion)));
  (*p_WTInfoA) (WTI_INTERFACE, IFC_NDEVICES, &ndevices);
  (*p_WTInfoA) (WTI_INTERFACE, IFC_NCURSORS, &ncursors);
#if DEBUG_WINTAB
  GDK_NOTE (INPUT, g_print ("NDEVICES: %d, NCURSORS: %d\n",
			    ndevices, ncursors));
#endif
  /* Create a dummy window to receive wintab events */
  wa.wclass = GDK_INPUT_OUTPUT;
  wa.event_mask = GDK_ALL_EVENTS_MASK;
  wa.width = 2;
  wa.height = 2;
  wa.x = -100;
  wa.y = -100;
  wa.window_type = GDK_WINDOW_TOPLEVEL;
  if ((wintab_window = gdk_window_new (NULL, &wa, GDK_WA_X|GDK_WA_Y)) == NULL)
    {
      g_warning ("gdk_input_wintab_init: gdk_window_new failed");
      return;
    }
  g_object_ref (wintab_window);

  for (devix = 0; devix < ndevices; devix++)
    {
      LOGCONTEXT lc;

      /* We open the Wintab device (hmm, what if there are several, or
       * can there even be several, probably not?) as a system
       * pointing device, i.e. it controls the normal Windows
       * cursor. This seems much more natural.
       */

      (*p_WTInfoW) (WTI_DEVICES + devix, DVC_NAME, devname);
      devname_utf8 = g_utf16_to_utf8 (devname, -1, NULL, NULL, NULL);
#ifdef DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("Device %d: %s\n", devix, devname_utf8)));
#endif
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NCSRTYPES, &ncsrtypes);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_FIRSTCSR, &firstcsr);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_HARDWARE, &hardware);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_X, &axis_x);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_Y, &axis_y);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_NPRESSURE, &axis_npressure);
      (*p_WTInfoA) (WTI_DEVICES + devix, DVC_ORIENTATION, axis_or);

      defcontext_done = FALSE;
      if (HIBYTE (specversion) > 1 || LOBYTE (specversion) >= 1)
        {
          /* Try to get device-specific default context */
          /* Some drivers, e.g. Aiptek, don't provide this info */
          if ((*p_WTInfoA) (WTI_DSCTXS + devix, 0, &lc) > 0)
            defcontext_done = TRUE;
#if DEBUG_WINTAB
          if (defcontext_done)
            GDK_NOTE (INPUT, (g_print("Using device-specific default context\n")));
          else
            GDK_NOTE (INPUT, (g_print("Note: Driver did not provide device specific default context info despite claiming to support version 1.1\n")));
#endif
        }

      if (!defcontext_done)
        (*p_WTInfoA) (WTI_DEFSYSCTX, 0, &lc);
#if DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("Default context:\n"), print_lc(&lc)));
#endif
      lc.lcOptions |= CXO_MESSAGES;
      lc.lcStatus = 0;
      lc.lcMsgBase = WT_DEFBASE;
      lc.lcPktRate = 0;
      lc.lcPktData = PACKETDATA;
      lc.lcPktMode = PACKETMODE;
      lc.lcMoveMask = PACKETDATA;
      lc.lcBtnUpMask = lc.lcBtnDnMask = ~0;
      lc.lcOutOrgX = axis_x.axMin;
      lc.lcOutOrgY = axis_y.axMin;
      lc.lcOutExtX = axis_x.axMax - axis_x.axMin;
      lc.lcOutExtY = axis_y.axMax - axis_y.axMin;
      lc.lcOutExtY = -lc.lcOutExtY; /* We want Y growing downward */
#if DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("context for device %d:\n", devix),
			print_lc(&lc)));
#endif
      hctx = g_new (HCTX, 1);
      if ((*hctx = (*p_WTOpenA) (GDK_WINDOW_HWND (wintab_window), &lc, TRUE)) == NULL)
        {
          g_warning ("gdk_input_wintab_init: WTOpen failed");
          return;
        }
      GDK_NOTE (INPUT, g_print ("opened Wintab device %d %p\n",
                                devix, *hctx));

      wintab_contexts = g_list_append (wintab_contexts, hctx);
#if 0
      (*p_WTEnable) (*hctx, TRUE);
#endif
      (*p_WTOverlap) (*hctx, TRUE);

#if DEBUG_WINTAB
      GDK_NOTE (INPUT, (g_print("context for device %d after WTOpen:\n", devix),
			print_lc(&lc)));
#endif
      /* Increase packet queue size to reduce the risk of lost packets.
       * According to the specs, if the function fails we must try again
       * with a smaller queue size.
       */
      GDK_NOTE (INPUT, g_print("Attempting to increase queue size\n"));
      for (i = 32; i >= 1; i >>= 1)
        {
          if ((*p_WTQueueSizeSet) (*hctx, i))
            {
              GDK_NOTE (INPUT, g_print("Queue size set to %d\n", i));
              break;
            }
        }
      if (!i)
        GDK_NOTE (INPUT, g_print("Whoops, no queue size could be set\n"));
      for (cursorix = firstcsr; cursorix < firstcsr + ncsrtypes; cursorix++)
        {
#ifdef DEBUG_WINTAB
          GDK_NOTE (INPUT, (g_print("Cursor %d:\n", cursorix), print_cursor (cursorix)));
#endif
          active = FALSE;
          (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_ACTIVE, &active);
          if (!active)
            continue;

          /* Wacom tablets seem to report cursors corresponding to
           * nonexistent pens or pucks. At least my ArtPad II reports
           * six cursors: a puck, pressure stylus and eraser stylus,
           * and then the same three again. I only have a
           * pressure-sensitive pen. The puck instances, and the
           * second instances of the styluses report physid zero. So
           * at least for Wacom, skip cursors with physid zero.
           */
          (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PHYSID, &physid);
          if (wcscmp (devname, L"WACOM Tablet") == 0 && physid == 0)
            continue;

          (*p_WTInfoW) (WTI_CURSORS + cursorix, CSR_NAME, csrname);
          csrname_utf8 = g_utf16_to_utf8 (csrname, -1, NULL, NULL, NULL);
          device_name = g_strconcat (devname_utf8, " ", csrname_utf8, NULL);

          device = g_object_new (GDK_TYPE_DEVICE_WINTAB,
                                 "name", device_name,
                                 "type", GDK_DEVICE_TYPE_SLAVE,
                                 "source", GDK_SOURCE_PEN,
                                 "mode", GDK_MODE_SCREEN,
                                 "has-cursor", FALSE,
                                 "display", _gdk_display,
                                 "device-manager", device_manager,
                                 NULL);

          g_free (csrname_utf8);

          device->hctx = *hctx;
          device->cursor = cursorix;
          (*p_WTInfoA) (WTI_CURSORS + cursorix, CSR_PKTDATA, &device->pktdata);

          if (device->pktdata & PK_X)
            {
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_X,
                                    axis_x.axMin,
                                    axis_x.axMax,
                                    axis_x.axResolution / 65535);
              num_axes++;
            }

          if (device->pktdata & PK_Y)
            {
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_Y,
                                    axis_y.axMin,
                                    axis_y.axMax,
                                    axis_y.axResolution / 65535);
              num_axes++;
            }


          if (device->pktdata & PK_NORMAL_PRESSURE)
            {
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_PRESSURE,
                                    axis_npressure.axMin,
                                    axis_npressure.axMax,
                                    axis_npressure.axResolution / 65535);
              num_axes++;
            }

          /* The wintab driver for the Wacom ArtPad II reports
           * PK_ORIENTATION in CSR_PKTDATA, but the tablet doesn't
           * actually sense tilt. Catch this by noticing that the
           * orientation axis's azimuth resolution is zero.
           */
          if ((device->pktdata & PK_ORIENTATION) && axis_or[0].axResolution == 0)
            {
              device->orientation_axes[0] = axis_or[0];
              device->orientation_axes[1] = axis_or[1];

              /* Wintab gives us aximuth and altitude, which
               * we convert to x and y tilt in the -1000..1000 range
               */
              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_XTILT,
                                    -1000,
                                    1000,
                                    1000);

              _gdk_device_add_axis (GDK_DEVICE (device),
                                    GDK_NONE,
                                    GDK_AXIS_YTILT,
                                    -1000,
                                    1000,
                                    1000);
              num_axes += 2;
            }

          device->last_axis_data = g_new (gint, num_axes);

          GDK_NOTE (INPUT, g_print ("device: (%d) %s axes: %d\n",
                                    cursorix,
                                    device_name,
                                    num_axes));

#if 0
          for (i = 0; i < gdkdev->info.num_axes; i++)
            GDK_NOTE (INPUT, g_print ("... axis %d: %d--%d@%d\n",
                                      i,
                                      gdkdev->axes[i].min_value,
                                      gdkdev->axes[i].max_value,
                                      gdkdev->axes[i].resolution));
#endif

          device_manager->wintab_devices = g_list_append (device_manager->wintab_devices,
                                                          device);

          g_free (device_name);
        }

      g_free (devname_utf8);
    }
}
Beispiel #21
0
/* Open a file for writing. Opening the file ourselves and using fdsink has
 * the advantage over filesink of being able to use O_EXCL when we want to
 * avoid overwriting* an existing file. Returns -1 if the file couldn't
 * be opened.
 */
static int
recorder_open_outfile (ShellRecorder  *recorder,
                       char          **outfilename)
{
  const char *pattern;
  int flags;
  int outfile = -1;

  pattern = recorder->file_template;
  if (!pattern)
    return -1;

  while (TRUE)
    {
      GString *filename = g_string_new (NULL);
      const char *p;
      char *path;

      for (p = pattern; *p; p++)
        {
          if (*p == '%')
            {
              switch (*(p + 1))
                {
                case '%':
                case '\0':
                  g_string_append_c (filename, '%');
                  break;
                case 'd':
                  {
                    /* Appends date according to locale */
                    GDateTime *datetime = g_date_time_new_now_local ();
                    char *date_str = g_date_time_format (datetime, "%0x");
                    char *s;

                    for (s = date_str; *s; s++)
                      if (G_IS_DIR_SEPARATOR (*s))
                          *s = '-';

                    g_string_append (filename, date_str);
                    g_free (date_str);
                    g_date_time_unref (datetime);
                  }
                  break;
                case 't':
                  {
                    /* Appends time according to locale */
                    GDateTime *datetime = g_date_time_new_now_local ();
                    char *time_str = g_date_time_format (datetime, "%0X");
                    char *s;

                    for (s = time_str; *s; s++)
                      if (G_IS_DIR_SEPARATOR (*s))
                          *s = ':';

                    g_string_append (filename, time_str);
                    g_free (time_str);
                    g_date_time_unref (datetime);
                  }
                  break;
                default:
                  g_warning ("Unknown escape %%%c in filename", *(p + 1));
                  goto out;
                }

              p++;
            }
          else
            g_string_append_c (filename, *p);
        }

      /* If a filename is explicitly specified without %u then we assume the user
       * is fine with over-writing the old contents; putting %u in the default
       * should avoid problems with malicious symlinks.
       */
      flags = O_WRONLY | O_CREAT | O_TRUNC;

      path = get_absolute_path (filename->str);
      outfile = open (path, flags, 0666);
      if (outfile != -1)
        {
          g_printerr ("Recording to %s\n", path);

          if (outfilename != NULL)
            *outfilename = path;
          else
            g_free (path);
          g_string_free (filename, TRUE);

          goto out;
        }

      if (outfile == -1 && errno != EEXIST)
        {
          g_warning ("Cannot open output file '%s': %s", path, g_strerror (errno));
          g_string_free (filename, TRUE);
          g_free (path);
          goto out;
        }

      g_string_free (filename, TRUE);
      g_free (path);
    }

 out:

  return outfile;
}
Beispiel #22
0
static void
parse_line (Package *pkg, const char *untrimmed, const char *path,
	    gboolean ignore_requires, gboolean ignore_private_libs,
	    gboolean ignore_requires_private)
{
  char *str;
  char *p;
  char *tag;

  debug_spew ("  line>%s\n", untrimmed);
  
  str = trim_string (untrimmed);
  
  if (*str == '\0') /* empty line */
    {
      g_free(str);
      return;
    }
  
  p = str;

  /* Get first word */
  while ((*p >= 'A' && *p <= 'Z') ||
	 (*p >= 'a' && *p <= 'z') ||
	 (*p >= '0' && *p <= '9') ||
	 *p == '_' || *p == '.')
    p++;

  tag = g_strndup (str, p - str);
  
  while (*p && isspace ((guchar)*p))
    ++p;

  if (*p == ':')
    {
      /* keyword */
      ++p;
      while (*p && isspace ((guchar)*p))
        ++p;

      if (strcmp (tag, "Name") == 0)
        parse_name (pkg, p, path);
      else if (strcmp (tag, "Description") == 0)
        parse_description (pkg, p, path);
      else if (strcmp (tag, "Version") == 0)
        parse_version (pkg, p, path);
      else if (strcmp (tag, "Requires.private") == 0)
	{
	  if (!ignore_requires_private)
	    parse_requires_private (pkg, p, path);
	}
      else if (strcmp (tag, "Requires") == 0)
	{
          if (ignore_requires == FALSE)
	    parse_requires (pkg, p, path);
          else
	    goto cleanup;
        }
      else if ((strcmp (tag, "Libs.private") == 0) && 
               ignore_private_libs == FALSE)
        parse_libs_private (pkg, p, path);
      else if (strcmp (tag, "Libs") == 0)
        parse_libs (pkg, p, path);
      else if (strcmp (tag, "Cflags") == 0 ||
               strcmp (tag, "CFlags") == 0)
        parse_cflags (pkg, p, path);
      else if (strcmp (tag, "Conflicts") == 0)
        parse_conflicts (pkg, p, path);
      else if (strcmp (tag, "URL") == 0)
        parse_url (pkg, p, path);
      else
        {
	  /* we don't error out on unknown keywords because they may
	   * represent additions to the .pc file format from future
	   * versions of pkg-config.  We do make a note of them in the
	   * debug spew though, in order to help catch mistakes in .pc
	   * files. */
          debug_spew ("Unknown keyword '%s' in '%s'\n",
		      tag, path);
        }
    }
  else if (*p == '=')
    {
      /* variable */
      char *varname;
      char *varval;
      
      ++p;
      while (*p && isspace ((guchar)*p))
        ++p;
      
      if (pkg->vars == NULL)
        pkg->vars = g_hash_table_new (g_str_hash, g_str_equal);

#ifdef G_OS_WIN32
      if (!dont_define_prefix && strcmp (tag, prefix_variable) == 0)
	{
	  /* This is the prefix variable. Try to guesstimate a value for it
	   * for this package from the location of the .pc file.
	   */

	  gchar *prefix = pkg->pcfiledir;
	  const int prefix_len = strlen (prefix);
	  const char *const lib_pkgconfig = "\\lib\\pkgconfig";
	  const char *const share_pkgconfig = "\\share\\pkgconfig";
	  const int lib_pkgconfig_len = strlen (lib_pkgconfig);
	  const int share_pkgconfig_len = strlen (share_pkgconfig);

	  if ((strlen (prefix) > lib_pkgconfig_len &&
	       pathnamecmp (prefix + prefix_len - lib_pkgconfig_len, lib_pkgconfig) == 0) ||
	      (strlen (prefix) > share_pkgconfig_len &&
	       pathnamecmp (prefix + prefix_len - share_pkgconfig_len, share_pkgconfig) == 0))
	    {
	      /* It ends in lib\pkgconfig or share\pkgconfig. Good. */
	      
	      gchar *q;
	      
	      orig_prefix = g_strdup (p);

	      prefix = g_strdup (prefix);
	      if (strlen (prefix) > lib_pkgconfig_len &&
		  pathnamecmp (prefix + prefix_len - lib_pkgconfig_len, lib_pkgconfig) == 0)
		prefix[prefix_len - lib_pkgconfig_len] = '\0';
	      else
		prefix[prefix_len - share_pkgconfig_len] = '\0';
	      
	      /* Turn backslashes into slashes or
	       * poptParseArgvString() will eat them when ${prefix}
	       * has been expanded in parse_libs().
	       */
	      q = prefix;
	      while (*q)
		{
		  if (*q == '\\')
		    *q = '/';
		  q++;
		}
	      varname = g_strdup (tag);
	      debug_spew (" Variable declaration, '%s' overridden with '%s'\n",
			  tag, prefix);
	      g_hash_table_insert (pkg->vars, varname, prefix);
	      goto cleanup;
	    }
	}
      else if (!dont_define_prefix &&
	       orig_prefix != NULL &&
	       strncmp (p, orig_prefix, strlen (orig_prefix)) == 0 &&
	       G_IS_DIR_SEPARATOR (p[strlen (orig_prefix)]))
	{
	  char *oldstr = str;

	  p = str = g_strconcat (g_hash_table_lookup (pkg->vars, prefix_variable), p + strlen (orig_prefix), NULL);
	  g_free (oldstr);
	}
#endif

      if (g_hash_table_lookup (pkg->vars, tag))
        {
          verbose_error ("Duplicate definition of variable '%s' in '%s'\n",
                         tag, path);

          exit (1);
        }

      varname = g_strdup (tag);
      varval = trim_and_sub (pkg, p, path);     

      debug_spew (" Variable declaration, '%s' has value '%s'\n",
                  varname, varval);
      g_hash_table_insert (pkg->vars, varname, varval);
  
    }

 cleanup:  
  g_free (str);
  g_free (tag);
}
Beispiel #23
0
/*! \brief Builds an absolute pathname.
 *  \par Function Description
 *  This function derives an absolute pathname for the pathname
 *  pointed to by \a name with '.' and '..' resolved. It does not
 *  resolve symbolic links.
 *
 *  It returns NULL and sets the \a error (if not NULL) if it failed
 *  to build the pathname or the pathname does not exists.
 *
 *  \note
 *  The code for this function is derived from the realpath() of
 *  the GNU C Library (Copyright (C) 1996-2002, 2004, 2005, 2006 Free
 *  Software Foundation, Inc. / LGPL 2.1 or later).
 *
 *  The part for the resolution of symbolic links has been discarded
 *  and it has been adapted for glib and for use on Windows.
 *
 *  \param [in]     name  A character string containing the pathname
 *                        to resolve.
 *  \param [in,out] error Return location for a GError, or NULL.
 *  \return A newly-allocated string with the resolved absolute
 *  pathname on success, NULL otherwise.
 */
gchar *f_normalize_filename (const gchar *name, GError **error)
{
#if defined (_WIN32)
    char buf[MAX_PATH];
#else
    GString *rpath;
    const char *start, *end;
#endif

  if (name == NULL) {
    g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_INVAL,
                 "%s", g_strerror (EINVAL));
    return NULL;
  }

  if (*name == '\0') {
    g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_NOENT,
                 "%s", g_strerror (ENOENT));
    return NULL;
  }

#if defined (_WIN32)
  /* Windows method (modified) from libiberty's lrealpath.c, GPL V2+
   *
   * We assume we don't have symlinks and just canonicalize to a
   * Windows absolute path.  GetFullPathName converts ../ and ./ in
   * relative paths to absolute paths, filling in current drive if
   * one is not given or using the current directory of a specified
   * drive (eg, "E:foo"). It also converts all forward slashes to
   * back slashes.
   */
  DWORD len = GetFullPathName (name, MAX_PATH, buf, NULL);
  if (len == 0 || len > MAX_PATH - 1) {
    return g_strdup (name);
  } else {
    /* The file system is case-preserving but case-insensitive,
     * canonicalize to lowercase, using the codepage associated
     * with the process locale.  */
    CharLowerBuff (buf, len);
    return g_strdup (buf);
  }
#else
#define ROOT_MARKER_LEN 1

  rpath = g_string_sized_new (strlen (name));

  /* if relative path, prepend current dir */
  if (!g_path_is_absolute (name)) {
    gchar *cwd = g_get_current_dir ();
    g_string_append (rpath, cwd);
    g_free (cwd);
    if (!G_IS_DIR_SEPARATOR (rpath->str[rpath->len - 1])) {
      g_string_append_c (rpath, G_DIR_SEPARATOR);
    }
  } else {
    g_string_append_len (rpath, name, ROOT_MARKER_LEN);
    /* move to first path separator */
    name += ROOT_MARKER_LEN - 1;
  }

  for (start = end = name; *start != '\0'; start = end) {
    /* skip sequence of multiple path-separators */
    while (G_IS_DIR_SEPARATOR (*start)) {
      ++start;
    }

    /* find end of path component */
    for (end = start; *end != '\0' && !G_IS_DIR_SEPARATOR (*end); ++end);

    if (end - start == 0) {
      break;
    } else if (end - start == 1 && start[0] == '.') {
      /* nothing */;
    } else if (end - start == 2 && start[0] == '.' && start[1] == '.') {
      /* back up to previous component, ignore if at root already.  */
      if (rpath->len > ROOT_MARKER_LEN) {
        while (!G_IS_DIR_SEPARATOR (rpath->str[(--rpath->len) - 1]));
        g_string_set_size (rpath, rpath->len);
      }
    } else {
      /* path component, copy to new path */
      if (!G_IS_DIR_SEPARATOR (rpath->str[rpath->len - 1])) {
        g_string_append_c (rpath, G_DIR_SEPARATOR);
      }

      g_string_append_len (rpath, start, end - start);

      if (!g_file_test (rpath->str, G_FILE_TEST_EXISTS)) {
        g_set_error (error,G_FILE_ERROR, G_FILE_ERROR_NOENT,
                     "%s", g_strerror (ENOENT));
        goto error;
      } else if (!g_file_test (rpath->str, G_FILE_TEST_IS_DIR) &&
                 *end != '\0') {
        g_set_error (error,G_FILE_ERROR, G_FILE_ERROR_NOTDIR,
                     "%s", g_strerror (ENOTDIR));
        goto error;
      }
    }
  }

  if (G_IS_DIR_SEPARATOR (rpath->str[rpath->len - 1]) &&
      rpath->len > ROOT_MARKER_LEN) {
    g_string_set_size (rpath, rpath->len - 1);
  }

  return g_string_free (rpath, FALSE);

error:
  g_string_free (rpath, TRUE);
  return NULL;
#undef ROOT_MARKER_LEN
#endif
}
static bool
skip_symlink(const struct directory *directory, const char *utf8_name)
{
#ifndef WIN32
	char buffer[MPD_PATH_MAX];
	char *path_fs;
	const char *p;
	ssize_t ret;

	path_fs = map_directory_child_fs(directory, utf8_name);
	if (path_fs == NULL)
		return true;

	ret = readlink(path_fs, buffer, sizeof(buffer));
	g_free(path_fs);
	if (ret < 0)
		/* don't skip if this is not a symlink */
		return errno != EINVAL;

	if (!follow_inside_symlinks && !follow_outside_symlinks) {
		/* ignore all symlinks */
		return true;
	} else if (follow_inside_symlinks && follow_outside_symlinks) {
		/* consider all symlinks */
		return false;
	}

	if (buffer[0] == '/')
		return !follow_outside_symlinks;

	p = buffer;
	while (*p == '.') {
		if (p[1] == '.' && G_IS_DIR_SEPARATOR(p[2])) {
			/* "../" moves to parent directory */
			directory = directory->parent;
			if (directory == NULL) {
				/* we have moved outside the music
				   directory - skip this symlink
				   if such symlinks are not allowed */
				return !follow_outside_symlinks;
			}
			p += 3;
		} else if (G_IS_DIR_SEPARATOR(p[1]))
			/* eliminate "./" */
			p += 2;
		else
			break;
	}

	/* we are still in the music directory, so this symlink points
	   to a song which is already in the database - skip according
	   to the follow_inside_symlinks param*/
	return !follow_inside_symlinks;
#else
	/* no symlink checking on WIN32 */

	(void)directory;
	(void)utf8_name;

	return false;
#endif
}
Beispiel #25
0
/**
 * repository_ipod_init:
 *
 * Ask for the iPod model and mountpoint and then create the directory
 * structure on the iPod.
 *
 * @itdb: itdb from where to extract the mountpoint. After
 * initialisation the model number is set.
 */
gboolean repository_ipod_init(iTunesDB *itdb) {
    IpodInit *ii;
    gint response;
    gboolean result = FALSE;
    gchar *mountpoint, *new_mount, *name, *model;
    GError *error = NULL;
    gchar buf[PATH_MAX];
    GtkComboBox *cb;
    const IpodInfo *info;
    GtkTreeIter iter;

    g_return_val_if_fail (itdb, FALSE);

    /* Create window */
    ii = g_new0 (IpodInit, 1);
    ii->itdb = itdb;

    ii->builder = init_repository_builder();

    ii->window = gtkpod_builder_xml_get_widget(ii->builder, "ipod_init_dialog");
    g_return_val_if_fail (ii->window, FALSE);

    /* Set mountpoint */
    mountpoint = get_itdb_prefs_string(itdb, KEY_MOUNTPOINT);
    if (mountpoint) {
        gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(GET_WIDGET (ii->builder, IID_MOUNTPOINT_CHOOSER)), mountpoint);
    }

    /* Setup model number combo */
    cb = GTK_COMBO_BOX (GET_WIDGET (ii->builder, IID_MODEL_COMBO));
    repository_init_model_number_combo(cb);

    /* If available set current model number, otherwise indicate that
     none is available */
    info = itdb_device_get_ipod_info(itdb->device);
    if (info && (info->ipod_generation != ITDB_IPOD_GENERATION_UNKNOWN)) {
        g_snprintf(buf, PATH_MAX, "x%s", info->model_number);
    }
    else {
        model = get_itdb_prefs_string(itdb, KEY_IPOD_MODEL);
        if (model && (strlen(g_strstrip (model)) != 0)) {
            g_snprintf(buf, PATH_MAX, "%s", model);
            g_free(model);
        }
        else {
            g_snprintf(buf, PATH_MAX, "%s", gettext (SELECT_OR_ENTER_YOUR_MODEL));
        }
    }

    /* Try and set buf as the active selection in the combo box */
    _model_combo_set_active_iter(cb, buf);

    gtk_window_set_transient_for(GTK_WINDOW (ii->window), GTK_WINDOW (gtkpod_app));
    response = gtk_dialog_run(GTK_DIALOG (ii->window));

    switch (response) {
    case GTK_RESPONSE_OK:
        new_mount = g_strdup(gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(GET_WIDGET (ii->builder, IID_MOUNTPOINT_CHOOSER))));
        if (!new_mount || (strlen(new_mount) == 0)) {
            gtkpod_statusbar_message("No mount point has been selected");
            return FALSE;
        }

        if (!gtk_combo_box_get_has_entry(cb)) {
            gtkpod_statusbar_message("No model has been selected");
            return FALSE;
        }

        /* remove trailing '/' in case it's present. */
        if (mountpoint && (strlen(mountpoint) > 0)) {
            if (G_IS_DIR_SEPARATOR(mountpoint[strlen(mountpoint) - 1])) {
                mountpoint[strlen(mountpoint) - 1] = 0;
            }
        }
        if (new_mount && (strlen(new_mount) > 0)) {
            if (G_IS_DIR_SEPARATOR(new_mount[strlen(new_mount) - 1])) {
                new_mount[strlen(new_mount) - 1] = 0;
            }
        }
        if (!(mountpoint && new_mount && (strcmp(mountpoint, new_mount) == 0))) { /* mountpoint has changed */
            g_free(mountpoint);
            mountpoint = new_mount;
            new_mount = NULL;
            set_itdb_prefs_string(itdb, KEY_MOUNTPOINT, mountpoint);
            call_script("gtkpod.load", mountpoint, NULL);
            itdb_set_mountpoint(itdb, mountpoint);
        }
        else {
            g_free(new_mount);
            new_mount = NULL;
        }

        g_return_val_if_fail(gtk_combo_box_get_active_iter(cb, &iter), FALSE);
        gtk_tree_model_get(gtk_combo_box_get_model(cb), &iter, COL_STRING, &model, -1);
        g_return_val_if_fail(model, FALSE);

        if ((strcmp(model, gettext(SELECT_OR_ENTER_YOUR_MODEL)) == 0) || (strlen(model) == 0)) { /* User didn't choose a model */
            g_free(model);
            model = NULL;
        }

        /* Set model in the prefs system */
        set_itdb_prefs_string(itdb, KEY_IPOD_MODEL, model);

        name = get_itdb_prefs_string(itdb, "name");
        result = itdb_init_ipod(mountpoint, model, name, &error);

        /* Set the model in the sysinfo of the itdb */
        itdb_device_set_sysinfo(itdb->device, "ModelNumStr", model);

        if (!result) {
            if (error) {
                gtkpod_warning(_("Error initialising iPod: %s\n"), error->message);
                g_error_free(error);
                error = NULL;
            }
            else {
                gtkpod_warning(_("Error initialising iPod, unknown error\n"));
            }
        }
        else {
            /* Should write the extended info file */
            result = gp_create_extended_info(itdb);
        }

        g_free(name);
        g_free(model);
        break;
    default:
        /* canceled -- do nothing */
        break;
    }

    gtk_widget_destroy(ii->window);

    g_free(mountpoint);

    g_free(ii);

    return result;
}