Beispiel #1
0
gboolean
handle_path (const char *path, struct stat * buf1, int *link_to_dir, int *stale_link)
{
    vfs_path_t *vpath;

    if (DIR_IS_DOT (path) || DIR_IS_DOTDOT (path))
        return FALSE;

    vpath = vfs_path_from_str (path);
    if (mc_lstat (vpath, buf1) == -1)
    {
        vfs_path_free (vpath);
        return FALSE;
    }

    if (S_ISDIR (buf1->st_mode))
        tree_store_mark_checked (path);

    /* A link to a file or a directory? */
    *link_to_dir = 0;
    *stale_link = 0;
    if (S_ISLNK (buf1->st_mode))
    {
        struct stat buf2;

        if (mc_stat (vpath, &buf2) == 0)
            *link_to_dir = S_ISDIR (buf2.st_mode) != 0;
        else
            *stale_link = 1;
    }

    vfs_path_free (vpath);

    return TRUE;
}
Beispiel #2
0
Datei: dir.c Projekt: Chainie/mc
static int
handle_dirent (dir_list * list, const char *fltr, struct dirent *dp,
               struct stat *buf1, int next_free, int *link_to_dir, int *stale_link)
{
    vfs_path_t *vpath;

    if (dp->d_name[0] == '.' && dp->d_name[1] == 0)
        return 0;
    if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0)
        return 0;
    if (!panels_options.show_dot_files && (dp->d_name[0] == '.'))
        return 0;
    if (!panels_options.show_backups && dp->d_name[NLENGTH (dp) - 1] == '~')
        return 0;

    vpath = vfs_path_from_str (dp->d_name);
    if (mc_lstat (vpath, buf1) == -1)
    {
        /*
         * lstat() fails - such entries should be identified by
         * buf1->st_mode being 0.
         * It happens on QNX Neutrino for /fs/cd0 if no CD is inserted.
         */
        memset (buf1, 0, sizeof (*buf1));
    }

    if (S_ISDIR (buf1->st_mode))
        tree_store_mark_checked (dp->d_name);

    /* A link to a file or a directory? */
    *link_to_dir = 0;
    *stale_link = 0;
    if (S_ISLNK (buf1->st_mode))
    {
        struct stat buf2;
        if (mc_stat (vpath, &buf2) == 0)
            *link_to_dir = S_ISDIR (buf2.st_mode) != 0;
        else
            *stale_link = 1;
    }
    vfs_path_free (vpath);
    if (!(S_ISDIR (buf1->st_mode) || *link_to_dir) && (fltr != NULL)
        && !mc_search (fltr, dp->d_name, MC_SEARCH_T_GLOB))
        return 0;

    /* Need to grow the *list? */
    if (next_free == list->size && !grow_list (list))
        return -1;

    return 1;
}
Beispiel #3
0
static gboolean
handle_dirent (struct dirent *dp, const char *fltr, struct stat *buf1, int *link_to_dir,
               int *stale_link)
{
    vfs_path_t *vpath;

    if (DIR_IS_DOT (dp->d_name) || DIR_IS_DOTDOT (dp->d_name))
        return FALSE;
    if (!panels_options.show_dot_files && (dp->d_name[0] == '.'))
        return FALSE;
    if (!panels_options.show_backups && dp->d_name[strlen (dp->d_name) - 1] == '~')
        return FALSE;

    vpath = vfs_path_from_str (dp->d_name);
    if (mc_lstat (vpath, buf1) == -1)
    {
        /*
         * lstat() fails - such entries should be identified by
         * buf1->st_mode being 0.
         * It happens on QNX Neutrino for /fs/cd0 if no CD is inserted.
         */
        memset (buf1, 0, sizeof (*buf1));
    }

    if (S_ISDIR (buf1->st_mode))
        tree_store_mark_checked (dp->d_name);

    /* A link to a file or a directory? */
    *link_to_dir = 0;
    *stale_link = 0;
    if (S_ISLNK (buf1->st_mode))
    {
        struct stat buf2;

        if (mc_stat (vpath, &buf2) == 0)
            *link_to_dir = S_ISDIR (buf2.st_mode) != 0;
        else
            *stale_link = 1;
    }

    vfs_path_free (vpath);

    return (S_ISDIR (buf1->st_mode) || *link_to_dir != 0 || fltr == NULL
            || mc_search (fltr, NULL, dp->d_name, MC_SEARCH_T_GLOB));
}
Beispiel #4
0
Datei: dir.c Projekt: Chainie/mc
int
handle_path (dir_list * list, const char *path,
             struct stat *buf1, int next_free, int *link_to_dir, int *stale_link)
{
    vfs_path_t *vpath;

    if (path[0] == '.' && path[1] == 0)
        return 0;
    if (path[0] == '.' && path[1] == '.' && path[2] == 0)
        return 0;

    vpath = vfs_path_from_str (path);
    if (mc_lstat (vpath, buf1) == -1)
    {
        vfs_path_free (vpath);
        return 0;
    }

    if (S_ISDIR (buf1->st_mode))
        tree_store_mark_checked (path);

    /* A link to a file or a directory? */
    *link_to_dir = 0;
    *stale_link = 0;
    if (S_ISLNK (buf1->st_mode))
    {
        struct stat buf2;
        if (mc_stat (vpath, &buf2) == 0)
            *link_to_dir = S_ISDIR (buf2.st_mode) != 0;
        else
            *stale_link = 1;
    }

    vfs_path_free (vpath);

    /* Need to grow the *list? */
    if (next_free == list->size && !grow_list (list))
        return -1;

    return 1;
}
Beispiel #5
0
Datei: util.c Projekt: JBurant/mc
static char *
resolve_symlinks (const vfs_path_t * vpath)
{
    char *p, *p2;
    char *buf, *buf2, *q, *r, c;
    struct stat mybuf;

    if (vpath->relative)
        return NULL;

    p = p2 = g_strdup (vfs_path_as_str (vpath));
    r = buf = g_malloc (MC_MAXPATHLEN);
    buf2 = g_malloc (MC_MAXPATHLEN);
    *r++ = PATH_SEP;
    *r = 0;

    do
    {
        q = strchr (p + 1, PATH_SEP);
        if (!q)
        {
            q = strchr (p + 1, 0);
            if (q == p + 1)
                break;
        }
        c = *q;
        *q = 0;
        if (mc_lstat (vpath, &mybuf) < 0)
        {
            MC_PTR_FREE (buf);
            goto ret;
        }
        if (!S_ISLNK (mybuf.st_mode))
            strcpy (r, p + 1);
        else
        {
            int len;

            len = mc_readlink (vpath, buf2, MC_MAXPATHLEN - 1);
            if (len < 0)
            {
                MC_PTR_FREE (buf);
                goto ret;
            }
            buf2[len] = 0;
            if (IS_PATH_SEP (*buf2))
                strcpy (buf, buf2);
            else
                strcpy (r, buf2);
        }
        canonicalize_pathname (buf);
        r = strchr (buf, 0);
        if (*r == '\0' || !IS_PATH_SEP (r[-1]))
            /* FIXME: this condition is always true because r points to the EOL */
        {
            *r++ = PATH_SEP;
            *r = '\0';
        }
        *q = c;
        p = q;
    }
    while (c != '\0');

    if (*buf == '\0')
        strcpy (buf, PATH_SEP_STR);
    else if (IS_PATH_SEP (r[-1]) && r != buf + 1)
        r[-1] = '\0';

  ret:
    g_free (buf2);
    g_free (p2);
    return buf;
}
Beispiel #6
0
/* Bring this item's structure uptodate.
 * 'parent' is optional; it saves one stat() for directories.
 */
void diritem_restat(const guchar *path, DirItem *item, struct stat *parent)
{
	struct stat	info;

	if (item->_image)
	{
		g_object_unref(item->_image);
		item->_image = NULL;
	}
	item->flags = 0;
	item->mime_type = NULL;

	if (mc_lstat(path, &info) == -1)
	{
		item->lstat_errno = errno;
		item->base_type = TYPE_ERROR;
		item->size = 0;
		item->mode = 0;
		item->mtime = item->ctime = item->atime = 0;
		item->uid = (uid_t) -1;
		item->gid = (gid_t) -1;
	}
	else
	{
		guchar *target_path;

		item->lstat_errno = 0;
		item->size = info.st_size;
		item->mode = info.st_mode;
		item->atime = info.st_atime;
		item->ctime = info.st_ctime;
		item->mtime = info.st_mtime;
		item->uid = info.st_uid;
		item->gid = info.st_gid;
		if (ABOUT_NOW(item->mtime) || ABOUT_NOW(item->ctime))
			item->flags |= ITEM_FLAG_RECENT;

		if (xattr_have(path))
			item->flags |= ITEM_FLAG_HAS_XATTR;

		item->label = xlabel_get(path);

		if (S_ISLNK(info.st_mode))
		{
			if (mc_stat(path, &info))
				item->base_type = TYPE_ERROR;
			else
				item->base_type =
					mode_to_base_type(info.st_mode);

			item->flags |= ITEM_FLAG_SYMLINK;

			target_path = pathdup(path);
		}
		else
		{
			item->base_type = mode_to_base_type(info.st_mode);
			target_path = (guchar *) path;
		}

		if (item->base_type == TYPE_DIRECTORY)
		{
			if (mount_is_mounted(target_path, &info,
					target_path == path ? parent : NULL))
				item->flags |= ITEM_FLAG_MOUNT_POINT
						| ITEM_FLAG_MOUNTED;
			else if (g_hash_table_lookup(fstab_mounts,
							target_path))
				item->flags |= ITEM_FLAG_MOUNT_POINT;
		}

		if (path != target_path)
			g_free(target_path);
	}

	if (item->base_type == TYPE_DIRECTORY)
	{
		/* KRJW: info.st_uid will be the uid of the dir, regardless
		 * of whether `path' is a dir or a symlink to one.  Note that
		 * if path is a symlink to a dir, item->uid will be the uid
		 * of the *symlink*, but we really want the uid of the dir
		 * to which the symlink points.
		 */
		examine_dir(path, item, &info);
	}
	else if (item->base_type == TYPE_FILE)
	{
		if (item->flags & ITEM_FLAG_SYMLINK)
		{
			guchar *link_path;
			link_path = pathdup(path);
			item->mime_type = type_from_path(link_path
					? link_path
					: path);
			g_free(link_path);
		}
		else
			item->mime_type = type_from_path(path);
	
		/* Note: for symlinks we need the mode of the target */
		if (info.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH))
		{
			/* Note that the flag is set for ALL executable
			 * files, but the mime_type must also be executable
			 * for clicking on the file to run it.
			 */
			item->flags |= ITEM_FLAG_EXEC_FILE;

			if (item->mime_type == NULL ||
			    item->mime_type == application_octet_stream)
			{
				item->mime_type = application_executable;
			}
			else if (item->mime_type == text_plain &&
			         !strchr(item->leafname, '.'))
			{
				item->mime_type = application_x_shellscript;
			}
		}		
		else if (item->mime_type == application_x_desktop)
		{
			item->flags |= ITEM_FLAG_EXEC_FILE;
		}

		if (!item->mime_type)
			item->mime_type = text_plain;

		check_globicon(path, item);

		if (item->mime_type == application_x_desktop && item->_image == NULL)
		{
			item->_image = g_fscache_lookup(desktop_icon_cache, path);
		}
	}
	else
		check_globicon(path, item);

	if (!item->mime_type)
		item->mime_type = mime_type_from_base_type(item->base_type);
}
Beispiel #7
0
/* Fill in more details of the DirItem for a directory item.
 * - Looks for an image (but maybe still NULL on error)
 * - Updates ITEM_FLAG_APPDIR
 *
 * link_target contains stat info for the link target for symlinks (or for the
 * item itself if not a link).
 */
static void examine_dir(const guchar *path, DirItem *item,
			struct stat *link_target)
{
	struct stat info;
	static GString *tmp = NULL;
	uid_t uid = link_target->st_uid;

	if (!tmp)
		tmp = g_string_new(NULL);

	check_globicon(path, item);

	if (item->flags & ITEM_FLAG_MOUNT_POINT)
	{
		item->mime_type = inode_mountpoint;
		return;		/* Try to avoid automounter problems */
	}

	if (link_target->st_mode & S_IWOTH)
		return;		/* Don't trust world-writable dirs */

	/* Finding the icon:
	 *
	 * - If it contains a .DirIcon then that's the icon
	 * - If it contains an AppRun then it's an application
	 * - If it contains an AppRun but no .DirIcon then try to
	 *   use AppIcon.xpm as the icon.
	 *
	 * .DirIcon and AppRun must have the same owner as the
	 * directory itself, to prevent abuse of /tmp, etc.
	 * For symlinks, we want the symlink's owner.
	 */

	g_string_printf(tmp, "%s/.DirIcon", path);

	if (item->_image)
		goto no_diricon;	/* Already got an icon */

	if (mc_lstat(tmp->str, &info) != 0 || info.st_uid != uid)
		goto no_diricon;	/* Missing, or wrong owner */

	if (S_ISLNK(info.st_mode) && mc_stat(tmp->str, &info) != 0)
		goto no_diricon;	/* Bad symlink */

	if (info.st_size > MAX_ICON_SIZE || !S_ISREG(info.st_mode))
		goto no_diricon;	/* Too big, or non-regular file */

	/* Try to load image; may still get NULL... */
	item->_image = g_fscache_lookup(pixmap_cache, tmp->str);

no_diricon:

	/* Try to find AppRun... */
	g_string_truncate(tmp, tmp->len - 8);
	g_string_append(tmp, "AppRun");

	if (mc_lstat(tmp->str, &info) != 0 || info.st_uid != uid)
		goto out;	/* Missing, or wrong owner */
		
	if (!(info.st_mode & (S_IXUSR | S_IXGRP | S_IXOTH)))
		goto out;	/* Not executable */

	item->flags |= ITEM_FLAG_APPDIR;

	/* Try to load AppIcon.xpm... */

	if (item->_image)
		goto out;	/* Already got an icon */

	g_string_truncate(tmp, tmp->len - 3);
	g_string_append(tmp, "Icon.xpm");

	/* Note: since AppRun is valid we don't need to check AppIcon.xpm
	 *	 so carefully.
	 */

	if (mc_stat(tmp->str, &info) != 0)
		goto out;	/* Missing, or broken symlink */

	if (info.st_size > MAX_ICON_SIZE || !S_ISREG(info.st_mode))
		goto out;	/* Too big, or non-regular file */

	/* Try to load image; may still get NULL... */
	item->_image = g_fscache_lookup(pixmap_cache, tmp->str);

out:

	if ((item->flags & ITEM_FLAG_APPDIR) && !item->_image)
	{
		/* This is an application without an icon */
		item->_image = im_appdir;
		g_object_ref(item->_image);
	}
}
Beispiel #8
0
static char *
resolve_symlinks (const char *path)
{
    char *buf, *buf2, *q, *r, c;
    int len;
    struct stat mybuf;
    const char *p;

    if (*path != PATH_SEP)
        return NULL;
    r = buf = g_malloc (MC_MAXPATHLEN);
    buf2 = g_malloc (MC_MAXPATHLEN);
    *r++ = PATH_SEP;
    *r = 0;
    p = path;
    for (;;)
    {
        q = strchr (p + 1, PATH_SEP);
        if (!q)
        {
            q = strchr (p + 1, 0);
            if (q == p + 1)
                break;
        }
        c = *q;
        *q = 0;
        if (mc_lstat (path, &mybuf) < 0)
        {
            g_free (buf);
            g_free (buf2);
            *q = c;
            return NULL;
        }
        if (!S_ISLNK (mybuf.st_mode))
            strcpy (r, p + 1);
        else
        {
            len = mc_readlink (path, buf2, MC_MAXPATHLEN - 1);
            if (len < 0)
            {
                g_free (buf);
                g_free (buf2);
                *q = c;
                return NULL;
            }
            buf2[len] = 0;
            if (*buf2 == PATH_SEP)
                strcpy (buf, buf2);
            else
                strcpy (r, buf2);
        }
        canonicalize_pathname (buf);
        r = strchr (buf, 0);
        if (!*r || *(r - 1) != PATH_SEP)
        {
            *r++ = PATH_SEP;
            *r = 0;
        }
        *q = c;
        p = q;
        if (!c)
            break;
    }
    if (!*buf)
        strcpy (buf, PATH_SEP_STR);
    else if (*(r - 1) == PATH_SEP && r != buf + 1)
        *(r - 1) = 0;
    g_free (buf2);
    return buf;
}