/** * 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; }
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); }
/** * 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; }
/** * 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 }
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; }
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); } }
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; }
/** * 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); }
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; }
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; }
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; }
/** * 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; }
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); }
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; } }
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); } }
/* 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; }
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); }
/*! \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 }
/** * 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; }