#include <config.h>
+#ifdef HAVE_SYS_TIME_H
#include <sys/time.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>
#include <string.h>
+#ifdef HAVE_UNISTD_H
#include <unistd.h>
+#endif
#include <fcntl.h>
#include <errno.h>
#ifdef HAVE_GRP_H
#include <glib/gstdio.h>
#include <glib/gchecksum.h>
+#include <gfileattribute-priv.h>
#include "glibintl.h"
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <io.h>
+#ifndef W_OK
+#define W_OK 2
+#endif
+#ifndef R_OK
+#define R_OK 4
+#endif
+#ifndef X_OK
+#define X_OK 0 /* not really */
+#endif
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
+#endif
+#ifndef S_ISDIR
+#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
+#endif
+#ifndef S_IXUSR
+#define S_IXUSR _S_IEXEC
+#endif
+#endif
+
#include "glocalfileinfo.h"
#include "gioerror.h"
#include "gthemedicon.h"
guint32 bits[2];
unsigned char in[64];
};
-
+#ifndef G_OS_WIN32
typedef struct {
char *user_name;
char *real_name;
} UidData;
-
+#endif
G_LOCK_DEFINE_STATIC (uid_cache);
static GHashTable *uid_cache = NULL;
#ifdef HAVE_SELINUX
char *context;
- if (!g_file_attribute_matcher_matches (attribute_matcher, "selinux:context"))
+ if (!g_file_attribute_matcher_matches (attribute_matcher, "selinux::context"))
return;
if (is_selinux_enabled ())
if (context)
{
- g_file_info_set_attribute_string (info, "selinux:context", context);
+ g_file_info_set_attribute_string (info, "selinux::context", context);
freecon(context);
}
}
if (user)
{
escaped_attr = hex_escape_string (attr + 5, &free_escaped_attr);
- gio_attr = g_strconcat ("xattr:", escaped_attr, NULL);
+ gio_attr = g_strconcat ("xattr::", escaped_attr, NULL);
}
else
{
escaped_attr = hex_escape_string (attr, &free_escaped_attr);
- gio_attr = g_strconcat ("xattr_sys:", escaped_attr, NULL);
+ gio_attr = g_strconcat ("xattr-sys::", escaped_attr, NULL);
}
if (free_escaped_attr)
if (user)
all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr");
else
- all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr_sys");
+ all = g_file_attribute_matcher_enumerate_namespace (matcher, "xattr-sys");
if (all)
{
if (user)
{
escaped_attr = hex_escape_string (attr + 5, &free_escaped_attr);
- gio_attr = g_strconcat ("xattr:", escaped_attr, NULL);
+ gio_attr = g_strconcat ("xattr::", escaped_attr, NULL);
}
else
{
escaped_attr = hex_escape_string (attr, &free_escaped_attr);
- gio_attr = g_strconcat ("xattr_sys:", escaped_attr, NULL);
+ gio_attr = g_strconcat ("xattr-sys::", escaped_attr, NULL);
}
if (free_escaped_attr)
return FALSE;
}
- if (g_str_has_prefix (escaped_attribute, "xattr:"))
+ if (g_str_has_prefix (escaped_attribute, "xattr::"))
{
escaped_attribute += 6;
is_user = TRUE;
}
else
{
- g_assert (g_str_has_prefix (escaped_attribute, "xattr_sys:"));
+ g_warn_if_fail (g_str_has_prefix (escaped_attribute, "xattr-sys::"));
escaped_attribute += 10;
is_user = FALSE;
}
*/
if (res == 0)
{
+#ifdef S_ISVTX
parent_info->is_sticky = (statbuf.st_mode & S_ISVTX) != 0;
+#else
+ parent_info->is_sticky = FALSE;
+#endif
parent_info->owner = statbuf.st_uid;
parent_info->device = statbuf.st_dev;
}
{
if (parent_info->is_sticky)
{
+#ifndef G_OS_WIN32
uid_t uid = geteuid ();
if (uid == statbuf->st_uid ||
uid == parent_info->owner ||
uid == 0)
+#endif
writable = TRUE;
}
else
file_type = G_FILE_TYPE_REGULAR;
else if (S_ISDIR (statbuf->st_mode))
file_type = G_FILE_TYPE_DIRECTORY;
+#ifndef G_OS_WIN32
else if (S_ISCHR (statbuf->st_mode) ||
S_ISBLK (statbuf->st_mode) ||
S_ISFIFO (statbuf->st_mode)
#endif
)
file_type = G_FILE_TYPE_SPECIAL;
+#endif
#ifdef S_ISLNK
else if (S_ISLNK (statbuf->st_mode))
file_type = G_FILE_TYPE_SYMBOLIC_LINK;
}
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_ID_FS))
+ G_FILE_ATTRIBUTE_ID_FILESYSTEM))
{
char *id = _g_local_file_info_create_fs_id (statbuf);
- g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ID_FS, id);
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_ID_FILESYSTEM, id);
g_free (id);
}
}
g_string_append (string, remainder);
- g_assert (g_utf8_validate (string->str, -1, NULL));
+ g_warn_if_fail (g_utf8_validate (string->str, -1, NULL));
return g_string_free (string, FALSE);
}
return utf8_string;
}
-
+#ifndef G_OS_WIN32
static void
uid_data_free (UidData *data)
{
return res;
}
-
/* called with lock held */
static char *
lookup_gid_name (gid_t gid)
G_UNLOCK (gid_cache);
return res;
}
+#endif /* !G_OS_WIN32 */
static char *
get_content_type (const char *basename,
return g_strdup ("inode/symlink");
else if (S_ISDIR(statbuf->st_mode))
return g_strdup ("inode/directory");
+#ifndef G_OS_WIN32
else if (S_ISCHR(statbuf->st_mode))
return g_strdup ("inode/chardevice");
else if (S_ISBLK(statbuf->st_mode))
return g_strdup ("inode/blockdevice");
else if (S_ISFIFO(statbuf->st_mode))
return g_strdup ("inode/fifo");
+#endif
#ifdef S_ISSOCK
else if (S_ISSOCK(statbuf->st_mode))
return g_strdup ("inode/socket");
uri = g_filename_to_uri (path, NULL, NULL);
checksum = g_checksum_new (G_CHECKSUM_MD5);
- g_checksum_update (checksum, (const gchar *) uri, strlen (uri));
+ g_checksum_update (checksum, (const guchar *) uri, strlen (uri));
basename = g_strconcat (g_checksum_get_string (checksum), ".png", NULL);
g_checksum_free (checksum);
g_free (filename);
}
+#ifdef G_OS_WIN32
+static void
+win32_get_file_user_info (const gchar* filename,
+ gchar **group_name,
+ gchar **user_name,
+ gchar **real_name)
+{
+ PSECURITY_DESCRIPTOR psd = NULL;
+ DWORD sd_size = 0; /* first call calculates the size required */
+
+ wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ if ((GetFileSecurityW (wfilename,
+ GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
+ NULL,
+ sd_size,
+ &sd_size) || (ERROR_INSUFFICIENT_BUFFER == GetLastError())) &&
+ (psd = g_try_malloc (sd_size)) != NULL &&
+ GetFileSecurityW (wfilename,
+ GROUP_SECURITY_INFORMATION | OWNER_SECURITY_INFORMATION,
+ psd,
+ sd_size,
+ &sd_size))
+ {
+ PSID psid = 0;
+ BOOL defaulted;
+ SID_NAME_USE name_use = 0; /* don't care? */
+ wchar_t *name = NULL;
+ wchar_t *domain = NULL;
+ DWORD name_len = 0;
+ DWORD domain_len = 0;
+ /* get the user name */
+ do {
+ if (!user_name)
+ break;
+ if (!GetSecurityDescriptorOwner (psd, &psid, &defaulted))
+ break;
+ if (!LookupAccountSidW (NULL, /* local machine */
+ psid,
+ name, &name_len,
+ domain, &domain_len, /* no domain info yet */
+ &name_use) && (ERROR_INSUFFICIENT_BUFFER != GetLastError()))
+ break;
+ name = g_try_malloc (name_len*sizeof(wchar_t));
+ domain = g_try_malloc (domain_len*sizeof(wchar_t));
+ if (name && domain &&
+ LookupAccountSidW (NULL, /* local machine */
+ psid,
+ name, &name_len,
+ domain, &domain_len, /* no domain info yet */
+ &name_use))
+ {
+ *user_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
+ }
+ g_free (name);
+ g_free (domain);
+ } while (FALSE);
+
+ /* get the group name */
+ do {
+ if (!group_name)
+ break;
+ if (!GetSecurityDescriptorGroup (psd, &psid, &defaulted))
+ break;
+ if (!LookupAccountSidW (NULL, /* local machine */
+ psid,
+ name, &name_len,
+ domain, &domain_len, /* no domain info yet */
+ &name_use) && (ERROR_INSUFFICIENT_BUFFER != GetLastError()))
+ break;
+ name = g_try_malloc (name_len*sizeof(wchar_t));
+ domain = g_try_malloc (domain_len*sizeof(wchar_t));
+ if (name && domain &&
+ LookupAccountSidW (NULL, /* local machine */
+ psid,
+ name, &name_len,
+ domain, &domain_len, /* no domain info yet */
+ &name_use))
+ {
+ *group_name = g_utf16_to_utf8 (name, -1, NULL, NULL, NULL);
+ }
+ g_free (name);
+ g_free (domain);
+ } while (FALSE);
+
+ /* TODO: get real name */
+
+ g_free (psd);
+ }
+ g_free (wfilename);
+}
+#endif /* G_OS_WIN32 */
GFileInfo *
_g_local_file_info_get (const char *basename,
g_file_info_set_is_hidden (info, TRUE);
if (basename != NULL && basename[strlen (basename) -1] == '~')
- g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STD_IS_BACKUP, TRUE);
+ g_file_info_set_attribute_boolean (info, G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP, TRUE);
if (is_symlink &&
g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET))
+ G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET))
{
char *link = read_link (path);
g_file_info_set_symlink_target (info, link);
}
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_DISPLAY_NAME))
+ G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME))
{
char *display_name = g_filename_display_basename (path);
}
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_EDIT_NAME))
+ G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME))
{
char *edit_name = g_filename_display_basename (path);
g_file_info_set_edit_name (info, edit_name);
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_COPY_NAME))
+ G_FILE_ATTRIBUTE_STANDARD_COPY_NAME))
{
char *copy_name = g_filename_to_utf8 (basename, -1, NULL, NULL, NULL);
if (copy_name)
- g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STD_COPY_NAME, copy_name);
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_COPY_NAME, copy_name);
g_free (copy_name);
}
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_CONTENT_TYPE) ||
+ G_FILE_ATTRIBUTE_STANDARD_CONTENT_TYPE) ||
g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_ICON))
+ G_FILE_ATTRIBUTE_STANDARD_ICON))
{
char *content_type = get_content_type (basename, path, &statbuf, is_symlink, symlink_broken, flags, FALSE);
g_file_info_set_content_type (info, content_type);
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_ICON))
+ G_FILE_ATTRIBUTE_STANDARD_ICON))
{
char *mimetype_icon, *generic_mimetype_icon, *type_icon, *p;
char *icon_names[3];
}
if (g_file_attribute_matcher_matches (attribute_matcher,
- G_FILE_ATTRIBUTE_STD_FAST_CONTENT_TYPE))
+ G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE))
{
char *content_type = get_content_type (basename, path, &statbuf, is_symlink, symlink_broken, flags, TRUE);
if (content_type)
{
- g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STD_FAST_CONTENT_TYPE, content_type);
+ g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_STANDARD_FAST_CONTENT_TYPE, content_type);
g_free (content_type);
}
}
if (g_file_attribute_matcher_matches (attribute_matcher,
G_FILE_ATTRIBUTE_OWNER_USER))
{
- char *name;
+ char *name = NULL;
+#ifdef G_OS_WIN32
+ win32_get_file_user_info (path, NULL, &name, NULL);
+#else
name = get_username_from_uid (statbuf.st_uid);
+#endif
if (name)
g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER, name);
g_free (name);
if (g_file_attribute_matcher_matches (attribute_matcher,
G_FILE_ATTRIBUTE_OWNER_USER_REAL))
{
- char *name;
-
+ char *name = NULL;
+#ifdef G_OS_WIN32
+ win32_get_file_user_info (path, NULL, NULL, &name);
+#else
name = get_realname_from_uid (statbuf.st_uid);
+#endif
if (name)
g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_USER_REAL, name);
g_free (name);
if (g_file_attribute_matcher_matches (attribute_matcher,
G_FILE_ATTRIBUTE_OWNER_GROUP))
{
- char *name;
-
+ char *name = NULL;
+#ifdef G_OS_WIN32
+ win32_get_file_user_info (path, &name, NULL, NULL);
+#else
name = get_groupname_from_gid (statbuf.st_gid);
+#endif
if (name)
g_file_info_set_attribute_string (info, G_FILE_ATTRIBUTE_OWNER_GROUP, name);
g_free (name);
gboolean
_g_local_file_info_set_attribute (char *filename,
const char *attribute,
- const GFileAttributeValue *value,
+ GFileAttributeType type,
+ gpointer value_p,
GFileQueryInfoFlags flags,
GCancellable *cancellable,
GError **error)
{
+ GFileAttributeValue value = { 0 };
+
+ _g_file_attribute_value_set_from_pointer (&value, type, value_p, FALSE);
+
if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_MODE) == 0)
- return set_unix_mode (filename, value, error);
+ return set_unix_mode (filename, &value, error);
#ifdef HAVE_CHOWN
else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_UID) == 0)
- return set_unix_uid_gid (filename, value, NULL, flags, error);
+ return set_unix_uid_gid (filename, &value, NULL, flags, error);
else if (strcmp (attribute, G_FILE_ATTRIBUTE_UNIX_GID) == 0)
- return set_unix_uid_gid (filename, NULL, value, flags, error);
+ return set_unix_uid_gid (filename, NULL, &value, flags, error);
#endif
#ifdef HAVE_SYMLINK
- else if (strcmp (attribute, G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET) == 0)
- return set_symlink (filename, value, error);
+ else if (strcmp (attribute, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET) == 0)
+ return set_symlink (filename, &value, error);
#endif
#ifdef HAVE_UTIMES
else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_MODIFIED) == 0)
- return set_mtime_atime (filename, value, NULL, NULL, NULL, error);
+ return set_mtime_atime (filename, &value, NULL, NULL, NULL, error);
else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC) == 0)
- return set_mtime_atime (filename, NULL, value, NULL, NULL, error);
+ return set_mtime_atime (filename, NULL, &value, NULL, NULL, error);
else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_ACCESS) == 0)
- return set_mtime_atime (filename, NULL, NULL, value, NULL, error);
+ return set_mtime_atime (filename, NULL, NULL, &value, NULL, error);
else if (strcmp (attribute, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC) == 0)
- return set_mtime_atime (filename, NULL, NULL, NULL, value, error);
+ return set_mtime_atime (filename, NULL, NULL, NULL, &value, error);
#endif
#ifdef HAVE_XATTR
- else if (g_str_has_prefix (attribute, "xattr:"))
- return set_xattr (filename, attribute, value, error);
- else if (g_str_has_prefix (attribute, "xattr_sys:"))
- return set_xattr (filename, attribute, value, error);
+ else if (g_str_has_prefix (attribute, "xattr::"))
+ return set_xattr (filename, attribute, &value, error);
+ else if (g_str_has_prefix (attribute, "xattr-sys::"))
+ return set_xattr (filename, attribute, &value, error);
#endif
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
/* Set symlink first, since this recreates the file */
#ifdef HAVE_SYMLINK
- value = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_STD_SYMLINK_TARGET);
+ value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_STANDARD_SYMLINK_TARGET);
if (value)
{
if (!set_symlink (filename, value, error))
* Change ownership before permissions, since ownership changes can
change permissions (e.g. setuid)
*/
- uid = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_UNIX_UID);
- gid = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_UNIX_GID);
+ uid = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_UID);
+ gid = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_GID);
if (uid || gid)
{
}
#endif
- value = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_UNIX_MODE);
+ value = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_UNIX_MODE);
if (value)
{
if (!set_unix_mode (filename, value, error))
* Change times as the last thing to avoid it changing due to metadata changes
*/
- mtime = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
- mtime_usec = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
- atime = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
- atime_usec = g_file_info_get_attribute (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
+ mtime = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_MODIFIED);
+ mtime_usec = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_MODIFIED_USEC);
+ atime = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_ACCESS);
+ atime_usec = _g_file_info_get_attribute_value (info, G_FILE_ATTRIBUTE_TIME_ACCESS_USEC);
if (mtime || mtime_usec || atime || atime_usec)
{