Ejemplo n.º 1
0
mc_config_t *
mc_config_init (const gchar * ini_path)
{
    mc_config_t *mc_config;
    struct stat st;

    mc_config = g_try_malloc0 (sizeof (mc_config_t));

    if (mc_config == NULL)
        return NULL;

    mc_config->handle = g_key_file_new ();
    if (mc_config->handle == NULL) {
        g_free (mc_config);
        return NULL;
    }
    if (!ini_path || !exist_file (ini_path)) {
        return mc_config;
    }

    if (!mc_stat (ini_path, &st) && st.st_size) {
        /* file present and not empty */
        g_key_file_load_from_file (mc_config->handle, ini_path, G_KEY_FILE_KEEP_COMMENTS, NULL);
    }

    mc_config->ini_path = g_strdup (ini_path);
    return mc_config;
}
Ejemplo n.º 2
0
Archivo: chmod.c Proyecto: BrEacK/mc
static void
apply_mask (struct stat *sf)
{
    need_update = TRUE;
    end_chmod = TRUE;

    do_chmod (sf);

    do
    {
        char *fname;
        vfs_path_t *vpath;
        gboolean ok;

        fname = next_file ();
        vpath = vfs_path_from_str (fname);
        ok = (mc_stat (vpath, sf) == 0);
        vfs_path_free (vpath);
        if (!ok)
            return;

        c_stat = sf->st_mode;

        do_chmod (sf);
    }
    while (current_panel->marked != 0);
}
Ejemplo n.º 3
0
Archivo: execute.c Proyecto: LubkaB/mc
static gboolean
execute_prepare_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath,
                              time_t * mtime)
{
    struct stat st;

    /* Simplest case, this file is local */
    if ((filename_vpath == NULL && vfs_file_is_local (vfs_get_raw_current_dir ()))
        || vfs_file_is_local (filename_vpath))
        return TRUE;

    /* FIXME: Creation of new files on VFS is not supported */
    if (filename_vpath == NULL)
        return FALSE;

    *localcopy_vpath = mc_getlocalcopy (filename_vpath);
    if (*localcopy_vpath == NULL)
    {
        message (D_ERROR, MSG_ERROR, _("Cannot fetch a local copy of %s"),
                 vfs_path_as_str (filename_vpath));
        return FALSE;
    }

    mc_stat (*localcopy_vpath, &st);
    *mtime = st.st_mtime;
    return TRUE;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
0
void *tar_super_check(vfs *me, char *archive_name, char *op)
{
    static struct stat stat_buf;
    if (mc_stat (archive_name, &stat_buf))
	return NULL;
    return &stat_buf;
}
Ejemplo n.º 6
0
gboolean
if_link_is_exe (const vfs_path_t * full_name_vpath, const file_entry_t * file)
{
    struct stat b;

    if (S_ISLNK (file->st.st_mode) && mc_stat (full_name_vpath, &b) == 0)
        return is_exe (b.st_mode);
    return TRUE;
}
Ejemplo n.º 7
0
/* If not copy the default */
static int
check_for_default(char *default_file, char *file)
{
    struct stat s;
    off_t  count = 0;
    double bytes = 0;
    FileOpContext *ctx;
    
    if (mc_stat (file, &s)){
	if (mc_stat (default_file, &s)){
	    return -1;
	}
	ctx = file_op_context_new (OP_COPY);
	file_op_context_create_ui (ctx, 0);
	copy_file_file (ctx, default_file, file, 1, &count, &bytes, 1);
	file_op_context_destroy (ctx);
    }
    return 0;
}
Ejemplo n.º 8
0
/*
 * Execute command on a filename that can be on VFS.
 * Errors are reported to the user.
 */
void
execute_with_vfs_arg (const char *command, const char *filename)
{
    char *localcopy;
    char *fn;
    struct stat st;
    time_t mtime;

    /* Simplest case, this file is local */
    if (!filename || vfs_file_is_local (filename)) {
	do_execute (command, filename, EXECUTE_INTERNAL);
	return;
    }

    /* FIXME: Creation of new files on VFS is not supported */
    if (!*filename)
	return;

    localcopy = mc_getlocalcopy (filename);
    if (localcopy == NULL) {
	message (1, MSG_ERROR, _(" Cannot fetch a local copy of %s "),
		 filename);
	return;
    }

    /*
     * filename can be an entry on panel, it can be changed by executing
     * the command, so make a copy.  Smarter VFS code would make the code
     * below unnecessary.
     */
    fn = g_strdup (filename);
    mc_stat (localcopy, &st);
    mtime = st.st_mtime;
    do_execute (command, localcopy, EXECUTE_INTERNAL);
    mc_stat (localcopy, &st);
    mc_ungetlocalcopy (fn, localcopy, mtime != st.st_mtime);
    g_free (localcopy);
    g_free (fn);
}
Ejemplo n.º 9
0
Archivo: dir.c Proyecto: 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;
}
Ejemplo n.º 10
0
Archivo: extfs.c Proyecto: dborca/mc
static void extfs_free_archive (struct archive *archive)
{
    extfs_free_entry (archive->root_entry);
    if (archive->local_name != NULL) {
        struct stat my;
        
        mc_stat (archive->local_name, &my);
        mc_ungetlocalcopy (archive->name, archive->local_name, 
            archive->local_stat.st_mtime != my.st_mtime);
        g_free(archive->local_name);
    }
    g_free (archive->name);
    g_free (archive);
}
Ejemplo n.º 11
0
/* Returns fd of the open tar file */
static int tar_open_archive (vfs *me, char *name, vfs_s_super *archive)
{
    int result, type;
    long size;
    mode_t mode;
    struct vfs_s_inode *root;
    
    result = mc_open (name, O_RDONLY);
    if (result == -1) {
        message_2s (1, MSG_ERROR, _("Couldn't open tar archive\n%s"), name);
	ERRNOR (ENOENT, -1);
    }
    
    archive->name = strdup (name);
    mc_stat (name, &(archive->u.tar.tarstat));
    archive->u.tar.fd = -1;

    /* Find out the method to handle this tar file */
    size = is_gunzipable (result, &type);
    mc_lseek (result, 0, SEEK_SET);
    if (size > 0) {
	char *s;
	mc_close( result );
	s = copy_strings( archive->name, decompress_extension (type), NULL );
	result = mc_open (s, O_RDONLY);
	if (result == -1) 
	    message_2s (1, MSG_ERROR, _("Couldn't open tar archive\n%s"), s);
	free(s);
	if (result == -1)
	    ERRNOR (ENOENT, -1);
    }
   
    archive->u.tar.fd = result;
    mode = archive->u.tar.tarstat.st_mode & 07777;
    if (mode & 0400) mode |= 0100;
    if (mode & 0040) mode |= 0010;
    if (mode & 0004) mode |= 0001;
    mode |= S_IFDIR;

    root = vfs_s_new_inode (me, archive, &archive->u.tar.tarstat);
    root->st.st_mode = mode;
    root->u.tar.data_offset = -1;
    root->st.st_nlink++;
    root->st.st_dev = MEDATA->rdev++;

    vfs_s_add_dots (me, root, NULL);
    archive->root = root;

    return result;
}
Ejemplo n.º 12
0
Archivo: achown.c Proyecto: jskDr/mc
static void
apply_advanced_chowns (struct stat *sf)
{
    vfs_path_t *vpath;
    char *lc_fname;
    gid_t a_gid = sf->st_gid;
    uid_t a_uid = sf->st_uid;

    lc_fname = current_panel->dir.list[current_file].fname;
    vpath = vfs_path_from_str (lc_fname);
    need_update = end_chown = TRUE;
    if (mc_chmod (vpath, get_mode ()) == -1)
        message (D_ERROR, MSG_ERROR, _("Cannot chmod \"%s\"\n%s"),
                 lc_fname, unix_error_string (errno));
    /* call mc_chown only, if mc_chmod didn't fail */
    else if (mc_chown (vpath, (ch_flags[9] == '+') ? sf->st_uid : (uid_t) (-1),
                       (ch_flags[10] == '+') ? sf->st_gid : (gid_t) (-1)) == -1)
        message (D_ERROR, MSG_ERROR, _("Cannot chown \"%s\"\n%s"),
                 lc_fname, unix_error_string (errno));
    do_file_mark (current_panel, current_file, 0);
    vfs_path_free (vpath);

    do
    {
        lc_fname = next_file ();
        vpath = vfs_path_from_str (lc_fname);

        if (mc_stat (vpath, sf) != 0)
        {
            vfs_path_free (vpath);
            break;
        }

        ch_cmode = sf->st_mode;

        if (mc_chmod (vpath, get_mode ()) == -1)
            message (D_ERROR, MSG_ERROR, _("Cannot chmod \"%s\"\n%s"),
                     lc_fname, unix_error_string (errno));
        /* call mc_chown only, if mc_chmod didn't fail */
        else if (mc_chown (vpath, (ch_flags[9] == '+') ? a_uid : (uid_t) (-1),
                           (ch_flags[10] == '+') ? a_gid : (gid_t) (-1)) == -1)
            message (D_ERROR, MSG_ERROR, _("Cannot chown \"%s\"\n%s"),
                     lc_fname, unix_error_string (errno));

        do_file_mark (current_panel, current_file, 0);
        vfs_path_free (vpath);
    }
    while (current_panel->marked != 0);
}
Ejemplo n.º 13
0
static vfs_path_t *
mc_def_getlocalcopy (const vfs_path_t * filename_vpath)
{
    vfs_path_t *tmp_vpath = NULL;
    int fdin = -1, fdout = -1;
    ssize_t i;
    char buffer[BUF_1K * 8];
    struct stat mystat;

    fdin = mc_open (filename_vpath, O_RDONLY | O_LINEAR);
    if (fdin == -1)
        goto fail;

    fdout = vfs_mkstemps (&tmp_vpath, "vfs", vfs_path_get_last_path_str (filename_vpath));
    if (fdout == -1)
        goto fail;

    while ((i = mc_read (fdin, buffer, sizeof (buffer))) > 0)
    {
        if (write (fdout, buffer, i) != i)
            goto fail;
    }
    if (i == -1)
        goto fail;
    i = mc_close (fdin);
    fdin = -1;
    if (i == -1)
        goto fail;
    i = close (fdout);
    fdout = -1;
    if (i == -1)
    {
        fdout = -1;
        goto fail;
    }

    if (mc_stat (filename_vpath, &mystat) != -1)
        mc_chmod (tmp_vpath, mystat.st_mode);

    return tmp_vpath;

  fail:
    vfs_path_free (tmp_vpath);
    if (fdout != -1)
        close (fdout);
    if (fdin != -1)
        mc_close (fdin);
    return NULL;
}
Ejemplo n.º 14
0
static void
tree_move (WTree * tree, const char *default_dest)
{
    char msg[BUF_MEDIUM];
    char *dest;
    struct stat buf;
    file_op_context_t *ctx;
    file_op_total_context_t *tctx;
    vfs_path_t *dest_vpath = NULL;

    if (tree->selected_ptr == NULL)
        return;

    g_snprintf (msg, sizeof (msg), _("Move \"%s\" directory to:"),
                str_trunc (vfs_path_as_str (tree->selected_ptr->name), 50));
    dest =
        input_expand_dialog (Q_ ("DialogTitle|Move"), msg, MC_HISTORY_FM_TREE_MOVE, default_dest,
                             INPUT_COMPLETE_FILENAMES | INPUT_COMPLETE_CD);

    if (dest == NULL || *dest == '\0')
        goto ret;

    dest_vpath = vfs_path_from_str (dest);

    if (mc_stat (dest_vpath, &buf))
    {
        message (D_ERROR, MSG_ERROR, _("Cannot stat the destination\n%s"),
                 unix_error_string (errno));
        goto ret;
    }

    if (!S_ISDIR (buf.st_mode))
    {
        file_error (_("Destination \"%s\" must be a directory\n%s"), dest);
        goto ret;
    }

    ctx = file_op_context_new (OP_MOVE);
    tctx = file_op_total_context_new ();
    file_op_context_create_ui (ctx, FALSE, FILEGUI_DIALOG_ONE_ITEM);
    move_dir_dir (tctx, ctx, vfs_path_as_str (tree->selected_ptr->name), dest);
    file_op_total_context_destroy (tctx);
    file_op_context_destroy (ctx);

  ret:
    vfs_path_free (dest_vpath);
    g_free (dest);
}
Ejemplo n.º 15
0
static void apply_mask (struct stat *sf)
{
    char *fname;

    need_update = end_chmod = 1;
    do_chmod (sf);

    do {
        fname = next_file ();
        if (mc_stat (fname, sf) != 0)
            return;
        c_stat = sf->st_mode;

        do_chmod (sf);
    } while (current_panel->marked);
}
Ejemplo n.º 16
0
Archivo: ext.c Proyecto: inso/mc
static void
exec_cleanup_file_name (const vfs_path_t * filename_vpath, gboolean has_changed)
{
    if (localfilecopy_vpath == NULL)
        return;

    if (has_changed)
    {
        struct stat mystat;

        mc_stat (localfilecopy_vpath, &mystat);
        has_changed = localmtime != mystat.st_mtime;
    }
    mc_ungetlocalcopy (filename_vpath, localfilecopy_vpath, has_changed);
    vfs_path_free (localfilecopy_vpath);
    localfilecopy_vpath = NULL;
}
Ejemplo n.º 17
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));
}
Ejemplo n.º 18
0
Archivo: execute.c Proyecto: LubkaB/mc
static void
execute_cleanup_with_vfs_arg (const vfs_path_t * filename_vpath, vfs_path_t ** localcopy_vpath,
                              time_t * mtime)
{
    if (*localcopy_vpath != NULL)
    {
        struct stat st;

        /*
         * filename can be an entry on panel, it can be changed by executing
         * the command, so make a copy.  Smarter VFS code would make the code
         * below unnecessary.
         */
        mc_stat (*localcopy_vpath, &st);
        mc_ungetlocalcopy (filename_vpath, *localcopy_vpath, *mtime != st.st_mtime);
        vfs_path_free (*localcopy_vpath);
        *localcopy_vpath = NULL;
    }
}
Ejemplo n.º 19
0
Archivo: ext.c Proyecto: inso/mc
static char *
exec_get_file_name (const vfs_path_t * filename_vpath)
{
    if (!do_local_copy)
        return quote_func (vfs_path_get_last_path_str (filename_vpath), 0);

    if (localfilecopy_vpath == NULL)
    {
        struct stat mystat;
        localfilecopy_vpath = mc_getlocalcopy (filename_vpath);
        if (localfilecopy_vpath == NULL)
            return NULL;

        mc_stat (localfilecopy_vpath, &mystat);
        localmtime = mystat.st_mtime;
    }

    return quote_func (vfs_path_get_last_path_str (localfilecopy_vpath), 0);
}
Ejemplo n.º 20
0
Archivo: common.c Proyecto: Chainie/mc
mc_config_t *
mc_config_init (const gchar * ini_path, gboolean read_only)
{
    mc_config_t *mc_config;
    struct stat st;

    mc_config = g_try_malloc0 (sizeof (mc_config_t));

    if (mc_config == NULL)
        return NULL;

    mc_config->handle = g_key_file_new ();
    if (mc_config->handle == NULL)
    {
        g_free (mc_config);
        return NULL;
    }
    if (ini_path == NULL)
        return mc_config;

    if (exist_file (ini_path))
    {
        vfs_path_t *vpath;

        vpath = vfs_path_from_str (ini_path);
        if (mc_stat (vpath, &st) == 0 && st.st_size != 0)
        {
            GKeyFileFlags flags = G_KEY_FILE_NONE;

            if (!read_only)
                flags |= G_KEY_FILE_KEEP_COMMENTS;

            /* file exists and not empty */
            g_key_file_load_from_file (mc_config->handle, ini_path, flags, NULL);
        }
        vfs_path_free (vpath);
    }

    mc_config->ini_path = g_strdup (ini_path);
    return mc_config;
}
Ejemplo n.º 21
0
Archivo: dir.c Proyecto: 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;
}
Ejemplo n.º 22
0
static gboolean
dir_get_dotdot_stat (const vfs_path_t * vpath, struct stat *st)
{
    gboolean ret = FALSE;

    if ((vpath != NULL) && (st != NULL))
    {
        const char *path;

        path = vfs_path_get_by_index (vpath, 0)->path;
        if (path != NULL && *path != '\0')
        {
            vfs_path_t *tmp_vpath;

            tmp_vpath = vfs_path_append_new (vpath, "..", (char *) NULL);
            ret = mc_stat (tmp_vpath, st) == 0;
            vfs_path_free (tmp_vpath);
        }
    }

    return ret;
}
Ejemplo n.º 23
0
static void apply_advanced_chowns (struct stat *sf)
{
    char *fname;
    gid_t a_gid = sf->st_gid;
    uid_t a_uid = sf->st_uid;

    fname = current_panel->dir.list[current_file].fname;
    need_update = end_chown = 1;
    if (mc_chmod (fname, get_mode ()) == -1)
	message (D_ERROR, MSG_ERROR, _(" Cannot chmod \"%s\" \n %s "),
		 fname, unix_error_string (errno));
    /* call mc_chown only, if mc_chmod didn't fail */
    else if (mc_chown (fname, (ch_flags[9] == '+') ? sf->st_uid : (uid_t) -1,
		       (ch_flags[10] == '+') ? sf->st_gid : (gid_t) -1) == -1)
	message (D_ERROR, MSG_ERROR, _(" Cannot chown \"%s\" \n %s "),
		 fname, unix_error_string (errno));
    do_file_mark (current_panel, current_file, 0);

    do {
	fname = next_file ();

	if (mc_stat (fname, sf) != 0)
	    break;
	ch_cmode = sf->st_mode;
	if (mc_chmod (fname, get_mode ()) == -1)
	    message (D_ERROR, MSG_ERROR, _(" Cannot chmod \"%s\" \n %s "),
		     fname, unix_error_string (errno));
	/* call mc_chown only, if mc_chmod didn't fail */
	else if (mc_chown (fname, (ch_flags[9] == '+') ? a_uid : (uid_t) -1,
	                   (ch_flags[10] == '+') ? a_gid : (gid_t) -1) == -1)
	    message (D_ERROR, MSG_ERROR, _(" Cannot chown \"%s\" \n %s "),
		     fname, unix_error_string (errno));

	do_file_mark (current_panel, current_file, 0);
    } while (current_panel->marked);
}
Ejemplo n.º 24
0
void chmod_cmd (void)
{
    char buffer [BUF_TINY];
    char *fname;
    int i;
    struct stat sf_stat;
    Dlg_head *ch_dlg;

    do {			/* do while any files remaining */
        ch_dlg = init_chmod ();
        if (current_panel->marked)
            fname = next_file ();	/* next marked file */
        else
            fname = selection (current_panel)->fname;	/* single file */

        if (mc_stat (fname, &sf_stat) != 0) {	/* get status of file */
            destroy_dlg (ch_dlg);
            break;
        }

        c_stat = sf_stat.st_mode;
        mode_change = 0;	/* clear changes flag */

        /* set check buttons */
        for (i = 0; i < PERMISSIONS; i++) {
            check_perm[i].check->state = (c_stat & check_perm[i].mode) ? 1 : 0;
            check_perm[i].selected = 0;
        }

        /* Set the labels */
        c_fname = name_trunc (fname, 21);
        add_widget (ch_dlg, label_new (FY+2, FX+2, c_fname));
        c_fown = name_trunc (get_owner (sf_stat.st_uid), 21);
        add_widget (ch_dlg, label_new (FY+6, FX+2, c_fown));
        c_fgrp = name_trunc (get_group (sf_stat.st_gid), 21);
        add_widget (ch_dlg, label_new (FY+8, FX+2, c_fgrp));
        g_snprintf (buffer, sizeof (buffer), "%o", c_stat);
        statl = label_new (FY+4, FX+2, buffer);
        add_widget (ch_dlg, statl);

        run_dlg (ch_dlg);	/* retrieve an action */

        /* do action */
        switch (ch_dlg->ret_value) {
        case B_ENTER:
            if (mode_change)
                if (mc_chmod (fname, c_stat) == -1)
                    message (1, MSG_ERROR, _(" Cannot chmod \"%s\" \n %s "),
                             fname, unix_error_string (errno));
            need_update = 1;
            break;

        case B_CANCEL:
            end_chmod = 1;
            break;

        case B_ALL:
        case B_MARKED:
            and_mask = or_mask = 0;
            and_mask = ~and_mask;

            for (i = 0; i < PERMISSIONS; i++) {
                if (check_perm[i].selected || ch_dlg->ret_value == B_ALL) {
                    if (check_perm[i].check->state & C_BOOL)
                        or_mask |= check_perm[i].mode;
                    else
                        and_mask &= ~check_perm[i].mode;
                }
            }

            apply_mask (&sf_stat);
            break;

        case B_SETMRK:
            and_mask = or_mask = 0;
            and_mask = ~and_mask;

            for (i = 0; i < PERMISSIONS; i++) {
                if (check_perm[i].selected)
                    or_mask |= check_perm[i].mode;
            }

            apply_mask (&sf_stat);
            break;
        case B_CLRMRK:
            and_mask = or_mask = 0;
            and_mask = ~and_mask;

            for (i = 0; i < PERMISSIONS; i++) {
                if (check_perm[i].selected)
                    and_mask &= ~check_perm[i].mode;
            }

            apply_mask (&sf_stat);
            break;
        }

        if (current_panel->marked && ch_dlg->ret_value!=B_CANCEL) {
            do_file_mark (current_panel, c_file, 0);
            need_update = 1;
        }
        destroy_dlg (ch_dlg);
    } while (current_panel->marked && !end_chmod);
    chmod_done ();
}
Ejemplo n.º 25
0
Archivo: filegui.c Proyecto: artzub/mc
char *
file_mask_dialog (FileOpContext * ctx, FileOperation operation,
                  gboolean only_one,
                  const char *format, const void *text,
                  const char *def_text, gboolean * do_bg)
{
    const size_t FMDY = 13;
    const size_t FMDX = 68;
    size_t fmd_xlen;

    /* buttons */
    const size_t gap = 1;
    size_t b0_len, b2_len;
    size_t b1_len = 0;

    int source_easy_patterns = easy_patterns;
    size_t i, len;
    char fmd_buf[BUF_MEDIUM];
    char *source_mask, *orig_mask, *dest_dir, *tmp;
    char *def_text_secure;
    int val;

    QuickWidget fmd_widgets[] = {
        /* 0 */ QUICK_BUTTON (42, 64, 10, FMDY, N_("&Cancel"), B_CANCEL, NULL),
#ifdef WITH_BACKGROUND
        /* 1 */ QUICK_BUTTON (25, 64, 10, FMDY, N_("&Background"), B_USER, NULL),
#define OFFSET 0
#else
#define OFFSET 1
#endif /* WITH_BACKGROUND */
        /*  2 - OFFSET */
        QUICK_BUTTON (14, FMDX, 10, FMDY, N_("&OK"), B_ENTER, NULL),
        /*  3 - OFFSET */
        QUICK_CHECKBOX (42, FMDX, 8, FMDY, N_("&Stable Symlinks"), &ctx->stable_symlinks),
        /*  4 - OFFSET */
        QUICK_CHECKBOX (31, FMDX, 7, FMDY, N_("Di&ve into subdir if exists"),
                        &ctx->dive_into_subdirs),
        /*  5 - OFFSET */
        QUICK_CHECKBOX (3, FMDX, 8, FMDY, N_("Preserve &attributes"), &ctx->op_preserve),
        /*  6 - OFFSET */
        QUICK_CHECKBOX (3, FMDX, 7, FMDY, N_("Follow &links"), &ctx->follow_links),
        /*  7 - OFFSET */
        QUICK_INPUT (3, FMDX, 6, FMDY, "", 58, 0, "input2", &dest_dir),
        /*  8 - OFFSET */
        QUICK_LABEL (3, FMDX, 5, FMDY, N_("to:")),
        /*  9 - OFFSET */
        QUICK_CHECKBOX (37, FMDX, 4, FMDY, N_("&Using shell patterns"), &source_easy_patterns),
        /* 10 - OFFSET */
        QUICK_INPUT (3, FMDX, 3, FMDY, easy_patterns ? "*" : "^(.*)$", 58, 0, "input-def",
                     &source_mask),
        /* 11 - OFFSET */
        QUICK_LABEL (3, FMDX, 2, FMDY, fmd_buf),
        QUICK_END
    };

    g_return_val_if_fail (ctx != NULL, NULL);

#ifdef ENABLE_NLS
    /* buttons */
    for (i = 0; i <= 2 - OFFSET; i++)
        fmd_widgets[i].u.button.text = _(fmd_widgets[i].u.button.text);

    /* checkboxes */
    for (i = 3 - OFFSET; i <= 9 - OFFSET; i++)
        if (i != 7 - OFFSET)
            fmd_widgets[i].u.checkbox.text = _(fmd_widgets[i].u.checkbox.text);
#endif /* !ENABLE_NLS */

    fmd_xlen = max (FMDX, (size_t) COLS * 2 / 3);

    len = str_term_width1 (fmd_widgets[6 - OFFSET].u.checkbox.text)
        + str_term_width1 (fmd_widgets[4 - OFFSET].u.checkbox.text) + 15;
    fmd_xlen = max (fmd_xlen, len);

    len = str_term_width1 (fmd_widgets[5 - OFFSET].u.checkbox.text)
        + str_term_width1 (fmd_widgets[3 - OFFSET].u.checkbox.text) + 15;
    fmd_xlen = max (fmd_xlen, len);

    /* buttons */
    b2_len = str_term_width1 (fmd_widgets[2 - OFFSET].u.button.text) + 6 + gap; /* OK */
#ifdef WITH_BACKGROUND
    b1_len = str_term_width1 (fmd_widgets[1].u.button.text) + 4 + gap;  /* Background */
#endif
    b0_len = str_term_width1 (fmd_widgets[0].u.button.text) + 4;        /* Cancel */
    len = b0_len + b1_len + b2_len;
    fmd_xlen = min (max (fmd_xlen, len + 6), (size_t) COLS);

    if (only_one)
    {
        int flen;

        flen = str_term_width1 (format);
        i = fmd_xlen - flen - 4;        /* FIXME */
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, str_trunc ((const char *) text, i));
    }
    else
    {
        g_snprintf (fmd_buf, sizeof (fmd_buf), format, *(const int *) text);
        fmd_xlen = max (fmd_xlen, (size_t) str_term_width1 (fmd_buf) + 6);
    }

    for (i = sizeof (fmd_widgets) / sizeof (fmd_widgets[0]); i > 0;)
        fmd_widgets[--i].x_divisions = fmd_xlen;

    i = (fmd_xlen - len) / 2;
    /* OK button */
    fmd_widgets[2 - OFFSET].relative_x = i;
    i += b2_len;
#ifdef WITH_BACKGROUND
    /* Background button */
    fmd_widgets[1].relative_x = i;
    i += b1_len;
#endif
    /* Cancel button */
    fmd_widgets[0].relative_x = i;

#define chkbox_xpos(i) \
    fmd_widgets [i].relative_x = fmd_xlen - str_term_width1 (fmd_widgets [i].u.checkbox.text) - 6
    chkbox_xpos (3 - OFFSET);
    chkbox_xpos (4 - OFFSET);
    chkbox_xpos (9 - OFFSET);
#undef chkbox_xpos

    /* inputs */
    fmd_widgets[7 - OFFSET].u.input.len = fmd_widgets[10 - OFFSET].u.input.len = fmd_xlen - 6;

    /* unselect checkbox if target filesystem don't support attributes */
    ctx->op_preserve = filegui__check_attrs_on_fs (def_text);

    /* filter out a possible password from def_text */
    tmp = strip_password (g_strdup (def_text), 1);
    if (source_easy_patterns)
        def_text_secure = strutils_glob_escape (tmp);
    else
        def_text_secure = strutils_regex_escape (tmp);
    g_free (tmp);

    /* destination */
    fmd_widgets[7 - OFFSET].u.input.text = def_text_secure;

    ctx->stable_symlinks = FALSE;
    *do_bg = FALSE;

    {
        struct stat buf;

        QuickDialog Quick_input = {
            fmd_xlen, FMDY, -1, -1, op_names[operation],
            "[Mask Copy/Rename]", fmd_widgets, NULL, TRUE
        };

      ask_file_mask:
        val = quick_dialog_skip (&Quick_input, 4);

        if (val == B_CANCEL)
        {
            g_free (def_text_secure);
            return NULL;
        }

        if (ctx->follow_links)
            ctx->stat_func = mc_stat;
        else
            ctx->stat_func = mc_lstat;

        if (ctx->op_preserve)
        {
            ctx->preserve = TRUE;
            ctx->umask_kill = 0777777;
            ctx->preserve_uidgid = (geteuid () == 0);
        }
        else
        {
            int i2;
            ctx->preserve = ctx->preserve_uidgid = FALSE;
            i2 = umask (0);
            umask (i2);
            ctx->umask_kill = i2 ^ 0777777;
        }

        if ((dest_dir == NULL) || (*dest_dir == '\0'))
        {
            g_free (def_text_secure);
            g_free (source_mask);
            return dest_dir;
        }

        ctx->search_handle = mc_search_new (source_mask, -1);

        if (ctx->search_handle == NULL)
        {
            message (D_ERROR, MSG_ERROR, _("Invalid source pattern `%s'"), source_mask);
            g_free (dest_dir);
            g_free (source_mask);
            goto ask_file_mask;
        }

        g_free (def_text_secure);
        g_free (source_mask);

        ctx->search_handle->is_case_sensitive = TRUE;
        if (source_easy_patterns)
            ctx->search_handle->search_type = MC_SEARCH_T_GLOB;
        else
            ctx->search_handle->search_type = MC_SEARCH_T_REGEX;

        tmp = dest_dir;
        dest_dir = tilde_expand (tmp);
        g_free (tmp);

        ctx->dest_mask = strrchr (dest_dir, PATH_SEP);
        if (ctx->dest_mask == NULL)
            ctx->dest_mask = dest_dir;
        else
            ctx->dest_mask++;
        orig_mask = ctx->dest_mask;
        if (!*ctx->dest_mask
            || (!ctx->dive_into_subdirs && !is_wildcarded (ctx->dest_mask)
                && (!only_one
                    || (!mc_stat (dest_dir, &buf) && S_ISDIR (buf.st_mode))))
            || (ctx->dive_into_subdirs
                && ((!only_one && !is_wildcarded (ctx->dest_mask))
                    || (only_one && !mc_stat (dest_dir, &buf) && S_ISDIR (buf.st_mode)))))
            ctx->dest_mask = g_strdup ("\\0");
        else
        {
            ctx->dest_mask = g_strdup (ctx->dest_mask);
            *orig_mask = '\0';
        }
        if (!*dest_dir)
        {
            g_free (dest_dir);
            dest_dir = g_strdup ("./");
        }
        if (val == B_USER)
            *do_bg = TRUE;
    }

    return dest_dir;
}
Ejemplo n.º 26
0
Archivo: extfs.c Proyecto: dborca/mc
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;
}
Ejemplo n.º 27
0
Archivo: chown.c Proyecto: LubkaB/mc
void
chown_cmd (void)
{
    char *fname;
    struct stat sf_stat;
    uid_t new_user;
    gid_t new_group;
    char buffer[BUF_TINY];

    chown_i18n ();

    do
    {                           /* do while any files remaining */
        vfs_path_t *vpath;
        WDialog *ch_dlg;

        ch_dlg = init_chown ();
        new_user = new_group = -1;

        if (current_panel->marked)
            fname = next_file ();       /* next marked file */
        else
            fname = selection (current_panel)->fname;   /* single file */

        vpath = vfs_path_from_str (fname);
        if (mc_stat (vpath, &sf_stat) != 0)
        {                       /* get status of file */
            dlg_destroy (ch_dlg);
            vfs_path_free (vpath);
            break;
        }
        vfs_path_free (vpath);

        /* select in listboxes */
        listbox_select_entry (l_user, listbox_search_text (l_user, get_owner (sf_stat.st_uid)));
        listbox_select_entry (l_group, listbox_search_text (l_group, get_group (sf_stat.st_gid)));

        chown_label (0, str_trunc (fname, GW - 4));
        chown_label (1, str_trunc (get_owner (sf_stat.st_uid), GW - 4));
        chown_label (2, str_trunc (get_group (sf_stat.st_gid), GW - 4));
        size_trunc_len (buffer, GW - 4, sf_stat.st_size, 0, panels_options.kilobyte_si);
        chown_label (3, buffer);
        chown_label (4, string_perm (sf_stat.st_mode));

        switch (dlg_run (ch_dlg))
        {
        case B_CANCEL:
            end_chown = 1;
            break;

        case B_SETUSR:
            {
                struct passwd *user;
                char *text;

                listbox_get_current (l_user, &text, NULL);
                user = getpwnam (text);
                if (user)
                {
                    new_user = user->pw_uid;
                    apply_chowns (new_user, new_group);
                }
                break;
            }

        case B_SETGRP:
            {
                struct group *grp;
                char *text;

                listbox_get_current (l_group, &text, NULL);
                grp = getgrnam (text);
                if (grp)
                {
                    new_group = grp->gr_gid;
                    apply_chowns (new_user, new_group);
                }
                break;
            }

        case B_SETALL:
        case B_ENTER:
            {
                struct group *grp;
                struct passwd *user;
                char *text;

                listbox_get_current (l_group, &text, NULL);
                grp = getgrnam (text);
                if (grp)
                    new_group = grp->gr_gid;
                listbox_get_current (l_user, &text, NULL);
                user = getpwnam (text);
                if (user)
                    new_user = user->pw_uid;
                if (ch_dlg->ret_value == B_ENTER)
                {
                    vfs_path_t *fname_vpath;

                    fname_vpath = vfs_path_from_str (fname);
                    need_update = 1;
                    if (mc_chown (fname_vpath, new_user, new_group) == -1)
                        message (D_ERROR, MSG_ERROR, _("Cannot chown \"%s\"\n%s"),
                                 fname, unix_error_string (errno));
                    vfs_path_free (fname_vpath);
                }
                else
                    apply_chowns (new_user, new_group);
                break;
            }
        }                       /* switch */

        if (current_panel->marked && ch_dlg->ret_value != B_CANCEL)
        {
            do_file_mark (current_panel, current_file, 0);
            need_update = 1;
        }

        dlg_destroy (ch_dlg);
    }
    while (current_panel->marked && !end_chown);

    chown_done ();
}
Ejemplo n.º 28
0
static char *
filename_completion_function (const char *text, int state, input_complete_t flags)
{
    static DIR *directory = NULL;
    static char *filename = NULL;
    static char *dirname = NULL;
    static char *users_dirname = NULL;
    static size_t filename_len;
    int isdir = 1, isexec = 0;
    static vfs_path_t *dirname_vpath = NULL;

    struct dirent *entry = NULL;

    SHOW_C_CTX ("filename_completion_function");

    if (text && (flags & INPUT_COMPLETE_SHELL_ESC))
    {
        char *u_text;
        char *result;
        char *e_result;

        u_text = strutils_shell_unescape (text);

        result = filename_completion_function (u_text, state, flags & (~INPUT_COMPLETE_SHELL_ESC));
        g_free (u_text);

        e_result = strutils_shell_escape (result);
        g_free (result);

        return e_result;
    }

    /* If we're starting the match process, initialize us a bit. */
    if (state == 0)
    {
        const char *temp;

        g_free (dirname);
        g_free (filename);
        g_free (users_dirname);
        vfs_path_free (dirname_vpath);

        if ((*text != '\0') && (temp = strrchr (text, PATH_SEP)) != NULL)
        {
            filename = g_strdup (++temp);
            dirname = g_strndup (text, temp - text);
        }
        else
        {
            dirname = g_strdup (".");
            filename = g_strdup (text);
        }

        /* We aren't done yet.  We also support the "~user" syntax. */

        /* Save the version of the directory that the user typed. */
        users_dirname = dirname;
        dirname = tilde_expand (dirname);
        canonicalize_pathname (dirname);
        dirname_vpath = vfs_path_from_str (dirname);

        /* Here we should do something with variable expansion
           and `command`.
           Maybe a dream - UNIMPLEMENTED yet. */

        directory = mc_opendir (dirname_vpath);
        filename_len = strlen (filename);
    }

    /* Now that we have some state, we can read the directory. */

    while (directory && (entry = mc_readdir (directory)))
    {
        if (!str_is_valid_string (entry->d_name))
            continue;

        /* Special case for no filename.
           All entries except "." and ".." match. */
        if (filename_len == 0)
        {
            if (DIR_IS_DOT (entry->d_name) || DIR_IS_DOTDOT (entry->d_name))
                continue;
        }
        else
        {
            /* Otherwise, if these match up to the length of filename, then
               it may be a match. */
            if ((entry->d_name[0] != filename[0]) ||
                ((NLENGTH (entry)) < filename_len) ||
                strncmp (filename, entry->d_name, filename_len))
                continue;
        }
        isdir = 1;
        isexec = 0;
        {
            struct stat tempstat;
            vfs_path_t *tmp_vpath;

            tmp_vpath = vfs_path_build_filename (dirname, entry->d_name, (char *) NULL);

            /* Unix version */
            if (mc_stat (tmp_vpath, &tempstat) == 0)
            {
                uid_t my_uid = getuid ();
                gid_t my_gid = getgid ();

                if (!S_ISDIR (tempstat.st_mode))
                {
                    isdir = 0;
                    if ((!my_uid && (tempstat.st_mode & 0111)) ||
                        (my_uid == tempstat.st_uid && (tempstat.st_mode & 0100)) ||
                        (my_gid == tempstat.st_gid && (tempstat.st_mode & 0010)) ||
                        (tempstat.st_mode & 0001))
                        isexec = 1;
                }
            }
            else
            {
                /* stat failed, strange. not a dir in any case */
                isdir = 0;
            }
            vfs_path_free (tmp_vpath);
        }
        if ((flags & INPUT_COMPLETE_COMMANDS) && (isexec || isdir))
            break;
        if ((flags & INPUT_COMPLETE_CD) && isdir)
            break;
        if (flags & (INPUT_COMPLETE_FILENAMES))
            break;
    }

    if (entry == NULL)
    {
        if (directory)
        {
            mc_closedir (directory);
            directory = NULL;
        }
        g_free (dirname);
        dirname = NULL;
        vfs_path_free (dirname_vpath);
        dirname_vpath = NULL;
        g_free (filename);
        filename = NULL;
        g_free (users_dirname);
        users_dirname = NULL;
        return NULL;
    }

    {
        GString *temp;

        temp = g_string_sized_new (16);

        if (users_dirname != NULL && (users_dirname[0] != '.' || users_dirname[1] != '\0'))
        {
            g_string_append (temp, users_dirname);

            /* We need a '/' at the end. */
            if (temp->str[temp->len - 1] != PATH_SEP)
                g_string_append_c (temp, PATH_SEP);
        }
        g_string_append (temp, entry->d_name);
        if (isdir)
            g_string_append_c (temp, PATH_SEP);

        return g_string_free (temp, FALSE);
    }
}
Ejemplo n.º 29
0
/* The second argument is action, i.e. Open, View or Edit
 *
 * This function returns:
 *
 * -1 for a failure or user interrupt
 * 0 if no command was run
 * 1 if some command was run
 *
 * If action == "View" then a parameter is checked in the form of "View:%d",
 * if the value for %d exists, then the viewer is started up at that line number.
 */
int
regex_command (const char *filename, const char *action, int *move_dir)
{
    char *p, *q, *r, c;
    int file_len = strlen (filename);
    int found = 0;
    int error_flag = 0;
    int ret = 0;
    struct stat mystat;
    int view_at_line_number;
    char *include_target;
    int include_target_len;
    int have_type = 0;		/* Flag used by regex_check_type() */

    /* Check for the special View:%d parameter */
    if (strncmp (action, "View:", 5) == 0) {
	view_at_line_number = atoi (action + 5);
	action = "View";
    } else {
	view_at_line_number = 0;
    }

    if (data == NULL) {
	char *extension_file;
	int mc_user_ext = 1;
	int home_error = 0;

	extension_file = concat_dir_and_file (home_dir, MC_USER_EXT);
	if (!exist_file (extension_file)) {
	    g_free (extension_file);
	  check_stock_mc_ext:
	    extension_file = concat_dir_and_file (mc_home, MC_LIB_EXT);
	    mc_user_ext = 0;
	}
	data = load_file (extension_file);
	g_free (extension_file);
	if (data == NULL)
	    return 0;

	if (!strstr (data, "default/")) {
	    if (!strstr (data, "regex/") && !strstr (data, "shell/")
		&& !strstr (data, "type/")) {
		g_free (data);
		data = NULL;
		if (mc_user_ext) {
		    home_error = 1;
		    goto check_stock_mc_ext;
		} else {
		    char *msg;
		    char *msg2;
		    msg =
			g_strconcat (" ", mc_home, MC_LIB_EXT,
				     _(" file error "), (char *) NULL);
		    msg2 =
			g_strconcat (_("Format of the "), mc_home,
				     _("mc.ext file has changed\n"
				       "with version 3.0. It seems that installation\n"
				       "failed. Please fetch a fresh new copy from the\n"
				       "Midnight Commander package."),
				     (char *) NULL);
		    message (1, msg, "%s", msg2);
		    g_free (msg);
		    g_free (msg2);
		    return 0;
		}
	    }
	}
	if (home_error) {
	    char *msg;
	    char *msg2;
	    msg =
		g_strconcat (" ~/", MC_USER_EXT, _(" file error "), (char *) NULL);
	    msg2 =
		g_strconcat (_("Format of the "), "~/", MC_USER_EXT,
			     _(" file has changed\n"
			       "with version 3.0. You may want either to\n"
			       "copy it from "), mc_home,
			     _("mc.ext or use that\n"
			       "file as an example of how to write it.\n"),
			     mc_home,
			     _("mc.ext will be used for this moment."),
			     (char *) NULL);
	    message (1, msg, "%s", msg2);
	    g_free (msg);
	    g_free (msg2);
	}
    }
    mc_stat (filename, &mystat);

    include_target = NULL;
    include_target_len = 0;
    for (p = data; *p; p++) {
	for (q = p; *q == ' ' || *q == '\t'; q++);
	if (*q == '\n' || !*q)
	    p = q;		/* empty line */
	if (*p == '#')		/* comment */
	    while (*p && *p != '\n')
		p++;
	if (*p == '\n')
	    continue;
	if (!*p)
	    break;
	if (p == q) {		/* i.e. starts in the first column, should be
				 * keyword/descNL
				 */
	    found = 0;
	    q = strchr (p, '\n');
	    if (q == NULL)
		q = strchr (p, 0);
	    c = *q;
	    *q = 0;
	    if (include_target) {
		if ((strncmp (p, "include/", 8) == 0)
		    && (strncmp (p + 8, include_target, include_target_len)
			== 0))
		    found = 1;
	    } else if (!strncmp (p, "regex/", 6)) {
		p += 6;
		/* Do not transform shell patterns, you can use shell/ for
		 * that
		 */
		if (regexp_match (p, filename, match_regex))
		    found = 1;
	    } else if (!strncmp (p, "directory/", 10)) {
		if (S_ISDIR (mystat.st_mode)
		    && regexp_match (p + 10, filename, match_regex))
		    found = 1;
	    } else if (!strncmp (p, "shell/", 6)) {
		p += 6;
		if (*p == '.' && file_len >= (q - p)) {
		    if (!strncmp (p, filename + file_len - (q - p), q - p))
			found = 1;
		} else {
		    if (q - p == file_len && !strncmp (p, filename, q - p))
			found = 1;
		}
	    } else if (!strncmp (p, "type/", 5)) {
		int res;
		p += 5;
		res = regex_check_type (filename, p, &have_type);
		if (res == 1)
		    found = 1;
		if (res == -1)
		    error_flag = 1;	/* leave it if file cannot be opened */
	    } else if (!strncmp (p, "default/", 8)) {
		found = 1;
	    }
	    *q = c;
	    p = q;
	    if (!*p)
		break;
	} else {		/* List of actions */
	    p = q;
	    q = strchr (p, '\n');
	    if (q == NULL)
		q = strchr (p, 0);
	    if (found && !error_flag) {
		r = strchr (p, '=');
		if (r != NULL) {
		    c = *r;
		    *r = 0;
		    if (strcmp (p, "Include") == 0) {
			char *t;

			include_target = p + 8;
			t = strchr (include_target, '\n');
			if (t)
			    *t = 0;
			include_target_len = strlen (include_target);
			if (t)
			    *t = '\n';

			*r = c;
			p = q;
			found = 0;

			if (!*p)
			    break;
			continue;
		    }
		    if (!strcmp (action, p)) {
			*r = c;
			for (p = r + 1; *p == ' ' || *p == '\t'; p++);

			/* Empty commands just stop searching
			 * through, they don't do anything
			 *
			 * We need to copy the filename because exec_extension
			 * may end up invoking update_panels thus making the
			 * filename parameter invalid (ie, most of the time,
			 * we get filename as a pointer from current_panel->dir).
			 */
			if (p < q) {
			    char *filename_copy = g_strdup (filename);

			    exec_extension (filename_copy, r + 1, move_dir,
					    view_at_line_number);
			    g_free (filename_copy);

			    ret = 1;
			}
			break;
		    } else
			*r = c;
		}
	    }
	    p = q;
	    if (!*p)
		break;
	}
    }
    if (error_flag)
	return -1;
    return ret;
}
Ejemplo n.º 30
0
static void
exec_extension (const char *filename, const char *data, int *move_dir,
		int start_line)
{
    char *file_name;
    int cmd_file_fd;
    FILE *cmd_file;
    char *cmd = NULL;
    int expand_prefix_found = 0;
    int parameter_found = 0;
    char prompt[80];
    int run_view = 0;
    int def_hex_mode = default_hex_mode, changed_hex_mode = 0;
    int def_nroff_flag = default_nroff_flag, changed_nroff_flag = 0;
    int written_nonspace = 0;
    int is_cd = 0;
    char buffer[1024];
    char *p = 0;
    char *localcopy = NULL;
    int do_local_copy;
    time_t localmtime = 0;
    struct stat mystat;
    quote_func_t quote_func = name_quote;

    g_return_if_fail (filename != NULL);
    g_return_if_fail (data != NULL);

    /* Avoid making a local copy if we are doing a cd */
    if (!vfs_file_is_local (filename))
	do_local_copy = 1;
    else
	do_local_copy = 0;

    /*
     * All commands should be run in /bin/sh regardless of user shell.
     * To do that, create temporary shell script and run it.
     * Sometimes it's not needed (e.g. for %cd and %view commands),
     * but it's easier to create it anyway.
     */
    cmd_file_fd = mc_mkstemps (&file_name, "mcext", SCRIPT_SUFFIX);

    if (cmd_file_fd == -1) {
	message (1, MSG_ERROR,
		 _(" Cannot create temporary command file \n %s "),
		 unix_error_string (errno));
	return;
    }
    cmd_file = fdopen (cmd_file_fd, "w");
    fputs ("#! /bin/sh\n", cmd_file);

    prompt[0] = 0;
    for (; *data && *data != '\n'; data++) {
	if (parameter_found) {
	    if (*data == '}') {
		char *parameter;
		parameter_found = 0;
		parameter = input_dialog (_(" Parameter "), prompt, "");
		if (!parameter) {
		    /* User canceled */
		    fclose (cmd_file);
		    unlink (file_name);
		    if (localcopy) {
			mc_ungetlocalcopy (filename, localcopy, 0);
			g_free (localcopy);
		    }
		    g_free (file_name);
		    return;
		}
		fputs (parameter, cmd_file);
		written_nonspace = 1;
		g_free (parameter);
	    } else {
		size_t len = strlen (prompt);

		if (len < sizeof (prompt) - 1) {
		    prompt[len] = *data;
		    prompt[len + 1] = 0;
		}
	    }
	} else if (expand_prefix_found) {
	    expand_prefix_found = 0;
	    if (*data == '{')
		parameter_found = 1;
	    else {
		int i = check_format_view (data);
		char *v;

		if (i) {
		    data += i - 1;
		    run_view = 1;
		} else if ((i = check_format_cd (data)) > 0) {
		    is_cd = 1;
		    quote_func = fake_name_quote;
		    do_local_copy = 0;
		    p = buffer;
		    data += i - 1;
		} else if ((i = check_format_var (data, &v)) > 0 && v) {
		    fputs (v, cmd_file);
		    g_free (v);
		    data += i;
		} else {
		    char *text;

		    if (*data == 'f') {
			if (do_local_copy) {
			    localcopy = mc_getlocalcopy (filename);
			    if (localcopy == NULL) {
				fclose (cmd_file);
				unlink (file_name);
				g_free (file_name);
				return;
			    }
			    mc_stat (localcopy, &mystat);
			    localmtime = mystat.st_mtime;
			    text = (*quote_func) (localcopy, 0);
			} else {
			    text = (*quote_func) (filename, 0);
			}
		    } else
			text = expand_format (NULL, *data, !is_cd);
		    if (!is_cd)
			fputs (text, cmd_file);
		    else {
			strcpy (p, text);
			p = strchr (p, 0);
		    }
		    g_free (text);
		    written_nonspace = 1;
		}
	    }
	} else {
	    if (*data == '%')
		expand_prefix_found = 1;
	    else {
		if (*data != ' ' && *data != '\t')
		    written_nonspace = 1;
		if (is_cd)
		    *(p++) = *data;
		else
		    fputc (*data, cmd_file);
	    }
	}
    }				/* for */

    /*
     * Make the script remove itself when it finishes.
     * Don't do it for the viewer - it may need to rerun the script,
     * so we clean up after calling view().
     */
    if (!run_view) {
	fprintf (cmd_file, "\n/bin/rm -f %s\n", file_name);
    }

    fclose (cmd_file);

    if ((run_view && !written_nonspace) || is_cd) {
	unlink (file_name);
	g_free (file_name);
	file_name = NULL;
    } else {
	/* Set executable flag on the command file ... */
	chmod (file_name, S_IRWXU);
	/* ... but don't rely on it - run /bin/sh explicitly */
	cmd = g_strconcat ("/bin/sh ", file_name, (char *) NULL);
    }

    if (run_view) {
	altered_hex_mode = 0;
	altered_nroff_flag = 0;
	if (def_hex_mode != default_hex_mode)
	    changed_hex_mode = 1;
	if (def_nroff_flag != default_nroff_flag)
	    changed_nroff_flag = 1;

	/* If we've written whitespace only, then just load filename
	 * into view
	 */
	if (written_nonspace) {
	    view (cmd, filename, move_dir, start_line);
	    unlink (file_name);
	} else {
	    view (0, filename, move_dir, start_line);
	}
	if (changed_hex_mode && !altered_hex_mode)
	    default_hex_mode = def_hex_mode;
	if (changed_nroff_flag && !altered_nroff_flag)
	    default_nroff_flag = def_nroff_flag;
	repaint_screen ();
    } else if (is_cd) {
	char *q;
	*p = 0;
	p = buffer;
/*	while (*p == ' ' && *p == '\t')
 *	    p++;
 */
	/* Search last non-space character. Start search at the end in order
	   not to short filenames containing spaces. */
	q = p + strlen (p) - 1;
	while (q >= p && (*q == ' ' || *q == '\t'))
	    q--;
	q[1] = 0;
	do_cd (p, cd_parse_command);
    } else {
	shell_execute (cmd, EXECUTE_INTERNAL);
	if (console_flag) {
	    handle_console (CONSOLE_SAVE);
	    if (output_lines && keybar_visible) {
		show_console_contents (output_start_y,
				       LINES - keybar_visible -
				       output_lines - 1,
				       LINES - keybar_visible - 1);

	    }
	}
    }

    g_free (file_name);
    g_free (cmd);

    if (localcopy) {
	mc_stat (localcopy, &mystat);
	mc_ungetlocalcopy (filename, localcopy,
			   localmtime != mystat.st_mtime);
	g_free (localcopy);
    }
}