Exemple #1
0
gboolean
mcview_load_command_output (mcview_t * view, const char *command)
{
    FILE *fp;

    mcview_close_datasource (view);

    open_error_pipe ();
    fp = popen (command, "r");
    if (fp == NULL)
    {
        /* Avoid two messages.  Message from stderr has priority.  */
        mcview_display (view);
        if (!close_error_pipe (mcview_is_in_panel (view) ? -1 : D_ERROR, NULL))
            mcview_show_error (view, _("Cannot spawn child process"));
        return FALSE;
    }

    /* First, check if filter produced any output */
    mcview_set_datasource_stdio_pipe (view, fp);
    if (!mcview_get_byte (view, 0, NULL))
    {
        mcview_close_datasource (view);

        /* Avoid two messages.  Message from stderr has priority.  */
        mcview_display (view);
        if (!close_error_pipe (mcview_is_in_panel (view) ? -1 : D_ERROR, NULL))
            mcview_show_error (view, _("Empty output from child filter"));
        return FALSE;
    }
    else
    {
        /*
         * At least something was read correctly. Close stderr and let
         * program die if it will try to write something there.
         *
         * Ideally stderr should be read asynchronously to prevent programs
         * from blocking (poll/select multiplexor).
         */
        close_error_pipe (D_NORMAL, NULL);
    }
    return TRUE;
}
Exemple #2
0
void
mcview_close_datasource (mcview_t * view)
{
    switch (view->datasource)
    {
    case DS_NONE:
        break;
    case DS_STDIO_PIPE:
        if (view->ds_stdio_pipe != NULL)
        {
            (void) pclose (view->ds_stdio_pipe);
            mcview_display (view);
            close_error_pipe (D_NORMAL, NULL);
            view->ds_stdio_pipe = NULL;
        }
        mcview_growbuf_free (view);
        break;
    case DS_VFS_PIPE:
        if (view->ds_vfs_pipe != -1)
        {
            (void) mc_close (view->ds_vfs_pipe);
            view->ds_vfs_pipe = -1;
        }
        mcview_growbuf_free (view);
        break;
    case DS_FILE:
        (void) mc_close (view->ds_file_fd);
        view->ds_file_fd = -1;
        MC_PTR_FREE (view->ds_file_data);
        break;
    case DS_STRING:
        MC_PTR_FREE (view->ds_string_data);
        break;
    default:
#ifdef HAVE_ASSERT_H
        assert (!"Unknown datasource type")
#endif
            ;
    }
    view->datasource = DS_NONE;
}
Exemple #3
0
/*
 * Main loop for reading an archive.
 * Return 0 on success, -1 on error.
 */
static int
extfs_read_archive (int fstype, const char *name, struct archive **pparc)
{
    FILE *extfsd;
    char *buffer;
    struct archive *current_archive;
    char *current_file_name, *current_link_name;

    if ((extfsd =
	 extfs_open_archive (fstype, name, &current_archive)) == NULL) {
	message (1, MSG_ERROR, _("Cannot open %s archive\n%s"),
		 extfs_prefixes[fstype], name);
	return -1;
    }

    buffer = g_malloc (4096);
    while (fgets (buffer, 4096, extfsd) != NULL) {
	struct stat hstat;

	current_link_name = NULL;
	if (vfs_parse_ls_lga
	    (buffer, &hstat, &current_file_name, &current_link_name)) {
	    struct entry *entry, *pent;
	    struct inode *inode;
	    char *p, *q, *cfn = current_file_name;

	    if (*cfn) {
		if (*cfn == '/')
		    cfn++;
		p = strchr (cfn, 0);
		if (p != cfn && *(p - 1) == '/')
		    *(p - 1) = 0;
		p = strrchr (cfn, '/');
		if (p == NULL) {
		    p = cfn;
		    q = strchr (cfn, 0);
		} else {
		    *(p++) = 0;
		    q = cfn;
		}
		if (S_ISDIR (hstat.st_mode)
		    && (!strcmp (p, ".") || !strcmp (p, "..")))
		    goto read_extfs_continue;
		pent =
		    extfs_find_entry (current_archive->root_entry, q, 1,
				      0);
		if (pent == NULL) {
		    /* FIXME: Should clean everything one day */
		    g_free (buffer);
		    pclose (extfsd);
		    close_error_pipe (1, _("Inconsistent extfs archive"));
		    return -1;
		}
		entry = g_new (struct entry, 1);
		entry->name = g_strdup (p);
		entry->next_in_dir = NULL;
		entry->dir = pent;
		if (pent->inode->last_in_subdir) {
		    pent->inode->last_in_subdir->next_in_dir = entry;
		    pent->inode->last_in_subdir = entry;
		}
		if (!S_ISLNK (hstat.st_mode) && current_link_name != NULL) {
		    pent =
			extfs_find_entry (current_archive->root_entry,
					  current_link_name, 0, 0);
		    if (pent == NULL) {
			/* FIXME: Should clean everything one day */
			g_free (buffer);
			pclose (extfsd);
			close_error_pipe (1,
					  _("Inconsistent extfs archive"));
			return -1;
		    } else {
			entry->inode = pent->inode;
			pent->inode->nlink++;
		    }
		} else {
		    inode = g_new (struct inode, 1);
		    entry->inode = inode;
		    inode->local_filename = NULL;
		    inode->inode = (current_archive->inode_counter)++;
		    inode->nlink = 1;
		    inode->dev = current_archive->rdev;
		    inode->archive = current_archive;
		    inode->mode = hstat.st_mode;
#ifdef HAVE_STRUCT_STAT_ST_RDEV
		    inode->rdev = hstat.st_rdev;
#else
		    inode->rdev = 0;
#endif
		    inode->uid = hstat.st_uid;
		    inode->gid = hstat.st_gid;
		    inode->size = hstat.st_size;
		    inode->mtime = hstat.st_mtime;
		    inode->atime = hstat.st_atime;
		    inode->ctime = hstat.st_ctime;
		    inode->first_in_subdir = NULL;
		    inode->last_in_subdir = NULL;
		    if (current_link_name != NULL
			&& S_ISLNK (hstat.st_mode)) {
			inode->linkname = current_link_name;
			current_link_name = NULL;
		    } else {
			if (S_ISLNK (hstat.st_mode))
			    inode->mode &= ~S_IFLNK;	/* You *DON'T* want to do this always */
			inode->linkname = NULL;
		    }
		    if (S_ISDIR (hstat.st_mode))
			extfs_make_dots (entry);
		}
	    }
	  read_extfs_continue:
	    g_free (current_file_name);
	    g_free (current_link_name);
	}
    }
    g_free (buffer);

    /* Check if extfs 'list' returned 0 */
    if (pclose (extfsd) != 0) {
	extfs_free (current_archive);
	close_error_pipe (1, _("Inconsistent extfs archive"));
	return -1;
    }

    close_error_pipe (1, NULL);
    *pparc = current_archive;
    return 0;
}
Exemple #4
0
static FILE *
extfs_open_archive (int fstype, const char *name, struct archive **pparc)
{
    static dev_t archive_counter = 0;
    FILE *result;
    mode_t mode;
    char *cmd;
    char *mc_extfsdir;
    struct stat mystat;
    struct archive *current_archive;
    struct entry *root_entry;
    char *local_name = NULL, *tmp = 0;
    int uses_archive = extfs_need_archive[fstype];

    if (uses_archive) {
	if (mc_stat (name, &mystat) == -1)
	    return NULL;
	if (!vfs_file_is_local (name)) {
	    local_name = mc_getlocalcopy (name);
	    if (local_name == NULL)
		return NULL;
	}
	tmp = name_quote (name, 0);
    }

    mc_extfsdir = concat_dir_and_file (mc_home, "extfs" PATH_SEP_STR);
    cmd =
	g_strconcat (mc_extfsdir, extfs_prefixes[fstype], " list ",
		     local_name ? local_name : tmp, (char *) NULL);
    g_free (tmp);
    g_free (mc_extfsdir);
    open_error_pipe ();
    result = popen (cmd, "r");
    g_free (cmd);
    if (result == NULL) {
	close_error_pipe (1, NULL);
	if (local_name) {
	    mc_ungetlocalcopy (name, local_name, 0);
	    g_free(local_name);
	}
	return NULL;
    } 
#ifdef ___QNXNTO__    
    setvbuf (result, NULL, _IONBF, 0);
#endif    

    current_archive = g_new (struct archive, 1);
    current_archive->fstype = fstype;
    current_archive->name = name ? g_strdup (name) : NULL;
    current_archive->local_name = local_name;

    if (local_name != NULL)
	mc_stat (local_name, &current_archive->local_stat);
    current_archive->inode_counter = 0;
    current_archive->fd_usage = 0;
    current_archive->rdev = archive_counter++;
    current_archive->next = first_archive;
    first_archive = current_archive;
    mode = mystat.st_mode & 07777;
    if (mode & 0400)
	mode |= 0100;
    if (mode & 0040)
	mode |= 0010;
    if (mode & 0004)
	mode |= 0001;
    mode |= S_IFDIR;
    root_entry = extfs_generate_entry (current_archive, "/", NULL, mode);
    root_entry->inode->uid = mystat.st_uid;
    root_entry->inode->gid = mystat.st_gid;
    root_entry->inode->atime = mystat.st_atime;
    root_entry->inode->ctime = mystat.st_ctime;
    root_entry->inode->mtime = mystat.st_mtime;
    current_archive->root_entry = root_entry;

    *pparc = current_archive;

    return result;
}
Exemple #5
0
void
mcview_growbuf_read_until (mcview_t * view, off_t ofs)
{
    ssize_t nread;
    byte *p;
    size_t bytesfree;
    gboolean short_read;

    assert (view->growbuf_in_use);

    if (view->growbuf_finished)
        return;

    short_read = FALSE;
    while (mcview_growbuf_filesize (view) < ofs || short_read)
    {
        if (view->growbuf_lastindex == VIEW_PAGE_SIZE)
        {
            /* Append a new block to the growing buffer */
            byte *newblock = g_try_malloc (VIEW_PAGE_SIZE);
            if (newblock == NULL)
                return;

            g_ptr_array_add (view->growbuf_blockptr, newblock);
            view->growbuf_lastindex = 0;
        }
        p = g_ptr_array_index (view->growbuf_blockptr,
                               view->growbuf_blockptr->len - 1) + view->growbuf_lastindex;

        bytesfree = VIEW_PAGE_SIZE - view->growbuf_lastindex;

        if (view->datasource == DS_STDIO_PIPE)
        {
            nread = fread (p, 1, bytesfree, view->ds_stdio_pipe);
            if (nread == 0)
            {
                view->growbuf_finished = TRUE;
                (void) pclose (view->ds_stdio_pipe);
                mcview_display (view);
                close_error_pipe (D_NORMAL, NULL);
                view->ds_stdio_pipe = NULL;
                return;
            }
        }
        else
        {
            assert (view->datasource == DS_VFS_PIPE);
            do
            {
                nread = mc_read (view->ds_vfs_pipe, p, bytesfree);
            }
            while (nread == -1 && errno == EINTR);
            if (nread == -1 || nread == 0)
            {
                view->growbuf_finished = TRUE;
                (void) mc_close (view->ds_vfs_pipe);
                view->ds_vfs_pipe = -1;
                return;
            }
        }
        short_read = ((size_t) nread < bytesfree);
        view->growbuf_lastindex += nread;
    }
}
Exemple #6
0
Fichier : sfs.c Projet : dborca/mc
static int
sfs_vfmake (struct vfs_class *me, const char *name, char *cache)
{
    char *inpath, *op;
    int w;
    char pad[10240];
    char *s, *t = pad;
    int was_percent = 0;
    char *pname;	/* name of parent archive */
    char *pqname;	/* name of parent archive, quoted */

    pname = g_strdup (name);
    vfs_split (pname, &inpath, &op);
    if ((w = (*me->which) (me, op)) == -1)
	vfs_die ("This cannot happen... Hopefully.\n");

    if (!(sfs_flags[w] & F_1) && strcmp (pname, "/")) {
	g_free (pname);
	return -1;
    }

    /*    if ((sfs_flags[w] & F_2) || (!inpath) || (!*inpath)); else return -1; */
    if (!(sfs_flags[w] & F_NOLOCALCOPY)) {
	s = mc_getlocalcopy (pname);
	if (!s) {
	    g_free (pname);
	    return -1;
	}
	pqname = name_quote (s, 0);
	g_free (s);
    } else {
	pqname = name_quote (pname, 0);
    }
    g_free (pname);

#define COPY_CHAR \
    if ((size_t) (t-pad) > sizeof(pad)) { \
	g_free (pqname); \
	return -1; \
    } \
    else \
	*t++ = *s;

#define COPY_STRING(a) \
    if ((t-pad)+strlen(a)>sizeof(pad)) { \
	g_free (pqname); \
	return -1; \
    } else { \
	strcpy (t, a); \
	t+= strlen(a); \
    }

    for (s = sfs_command[w]; *s; s++) {
	if (was_percent) {

	    const char *ptr = NULL;
	    was_percent = 0;

	    switch (*s) {
	    case '1':
		ptr = pqname;
		break;
	    case '2':
		ptr = op + strlen (sfs_prefix[w]);
		break;
	    case '3':
		ptr = cache;
		break;
	    case '%':
		COPY_CHAR;
		continue;
	    }
	    COPY_STRING (ptr);
	} else {
	    if (*s == '%')
		was_percent = 1;
	    else
		COPY_CHAR;
	}
    }

    g_free (pqname);
    open_error_pipe ();
    if (my_system (EXECUTE_AS_SHELL, "/bin/sh", pad)) {
	close_error_pipe (1, NULL);
	return -1;
    }

    close_error_pipe (0, NULL);
    return 0;			/* OK */
}