Пример #1
0
gboolean
mcview_hexedit_save_changes (mcview_t * view)
{
    int answer = 0;

    if (view->change_list == NULL)
        return TRUE;

    while (answer == 0)
    {
        int fp;
        char *text;
        struct hexedit_change_node *curr, *next;

#ifdef HAVE_ASSERT_H
        assert (view->filename_vpath != NULL);
#endif

        fp = mc_open (view->filename_vpath, O_WRONLY);
        if (fp != -1)
        {
            for (curr = view->change_list; curr != NULL; curr = next)
            {
                next = curr->next;

                if (mc_lseek (fp, curr->offset, SEEK_SET) == -1
                    || mc_write (fp, &(curr->value), 1) != 1)
                    goto save_error;

                /* delete the saved item from the change list */
                view->change_list = next;
                view->dirty++;
                mcview_set_byte (view, curr->offset, curr->value);
                g_free (curr);
            }

            view->change_list = NULL;

            if (view->locked)
                view->locked = unlock_file (view->filename_vpath);

            if (mc_close (fp) == -1)
                message (D_ERROR, _("Save file"),
                         _("Error while closing the file:\n%s\n"
                           "Data may have been written or not"), unix_error_string (errno));

            view->dirty++;
            return TRUE;
        }

      save_error:
        text = g_strdup_printf (_("Cannot save file:\n%s"), unix_error_string (errno));
        (void) mc_close (fp);

        answer = query_dialog (_("Save file"), text, D_ERROR, 2, _("&Retry"), _("&Cancel"));
        g_free (text);
    }

    return FALSE;
}
Пример #2
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;
}
Пример #3
0
/*static */
void
mcview_file_load_data (mcview_t * view, off_t byte_index)
{
    off_t blockoffset;
    ssize_t res;
    size_t bytes_read;

#ifdef HAVE_ASSERT_H
    assert (view->datasource == DS_FILE);
#endif

    if (mcview_already_loaded (view->ds_file_offset, byte_index, view->ds_file_datalen))
        return;

    if (byte_index >= view->ds_file_filesize)
        return;

    blockoffset = mcview_offset_rounddown (byte_index, view->ds_file_datasize);
    if (mc_lseek (view->ds_file_fd, blockoffset, SEEK_SET) == -1)
        goto error;

    bytes_read = 0;
    while (bytes_read < view->ds_file_datasize)
    {
        res =
            mc_read (view->ds_file_fd, view->ds_file_data + bytes_read,
                     view->ds_file_datasize - bytes_read);
        if (res == -1)
            goto error;
        if (res == 0)
            break;
        bytes_read += (size_t) res;
    }
    view->ds_file_offset = blockoffset;
    if ((off_t) bytes_read > view->ds_file_filesize - view->ds_file_offset)
    {
        /* the file has grown in the meantime -- stick to the old size */
        view->ds_file_datalen = view->ds_file_filesize - view->ds_file_offset;
    }
    else
    {
        view->ds_file_datalen = bytes_read;
    }
    return;

  error:
    view->ds_file_datalen = 0;
}
Пример #4
0
/* This function returns 0 if the file is not in not compressed by
 * one of the supported compressors (gzip, bzip, bzip2).  Otherwise,
 * the compression type is returned, as defined in util.h
 * Warning: this function moves the current file pointer */
int get_compression_type (int fd)
{
    unsigned char magic[4];

    /* Read the magic signature */
    if (mc_read (fd, (char *) magic, 4) != 4)
	return COMPRESSION_NONE;

    /* GZIP_MAGIC and OLD_GZIP_MAGIC */
    if (magic[0] == 037 && (magic[1] == 0213 || magic[1] == 0236)) {
	return COMPRESSION_GZIP;
    }

    /* PKZIP_MAGIC */
    if (magic[0] == 0120 && magic[1] == 0113 && magic[2] == 003
	&& magic[3] == 004) {
	/* Read compression type */
	mc_lseek (fd, 8, SEEK_SET);
	if (mc_read (fd, (char *) magic, 2) != 2)
	    return COMPRESSION_NONE;

	/* Gzip can handle only deflated (8) or stored (0) files */
	if ((magic[0] != 8 && magic[0] != 0) || magic[1] != 0)
	    return COMPRESSION_NONE;

	/* Compatible with gzip */
	return COMPRESSION_GZIP;
    }

    /* PACK_MAGIC and LZH_MAGIC and compress magic */
    if (magic[0] == 037
	&& (magic[1] == 036 || magic[1] == 0240 || magic[1] == 0235)) {
	/* Compatible with gzip */
	return COMPRESSION_GZIP;
    }

    /* BZIP and BZIP2 files */
    if ((magic[0] == 'B') && (magic[1] == 'Z') &&
	(magic[3] >= '1') && (magic[3] <= '9')) {
	switch (magic[2]) {
	case '0':
	    return COMPRESSION_BZIP;
	case 'h':
	    return COMPRESSION_BZIP2;
	}
    }
    return 0;
}
Пример #5
0
static int tar_read (void *fh, char *buffer, int count)
{
    off_t begin = FH->ino->u.tar.data_offset;
    int fd = FH_SUPER->u.tar.fd;
    vfs *me = FH_SUPER->me;

    if (mc_lseek (fd, begin + FH->pos, SEEK_SET) != 
        begin + FH->pos) ERRNOR (EIO, -1);

    count = VFS_MIN(count, FH->ino->st.st_size - FH->pos);

    if ((count = mc_read (fd, buffer, count)) == -1) ERRNOR (errno, -1);

    FH->pos += count;
    return count;
}
Пример #6
0
Файл: util.c Проект: JBurant/mc
enum compression_type
get_compression_type (int fd, const char *name)
{
    unsigned char magic[16];
    size_t str_len;

    /* Read the magic signature */
    if (mc_read (fd, (char *) magic, 4) != 4)
        return COMPRESSION_NONE;

    /* GZIP_MAGIC and OLD_GZIP_MAGIC */
    if (magic[0] == 037 && (magic[1] == 0213 || magic[1] == 0236))
    {
        return COMPRESSION_GZIP;
    }

    /* PKZIP_MAGIC */
    if (magic[0] == 0120 && magic[1] == 0113 && magic[2] == 003 && magic[3] == 004)
    {
        /* Read compression type */
        mc_lseek (fd, 8, SEEK_SET);
        if (mc_read (fd, (char *) magic, 2) != 2)
            return COMPRESSION_NONE;

        /* Gzip can handle only deflated (8) or stored (0) files */
        if ((magic[0] != 8 && magic[0] != 0) || magic[1] != 0)
            return COMPRESSION_NONE;

        /* Compatible with gzip */
        return COMPRESSION_GZIP;
    }

    /* PACK_MAGIC and LZH_MAGIC and compress magic */
    if (magic[0] == 037 && (magic[1] == 036 || magic[1] == 0240 || magic[1] == 0235))
    {
        /* Compatible with gzip */
        return COMPRESSION_GZIP;
    }

    /* BZIP and BZIP2 files */
    if ((magic[0] == 'B') && (magic[1] == 'Z') && (magic[3] >= '1') && (magic[3] <= '9'))
    {
        switch (magic[2])
        {
        case '0':
            return COMPRESSION_BZIP;
        case 'h':
            return COMPRESSION_BZIP2;
        default:
            break;
        }
    }

    /* LZ4 format - v1.5.0 - 0x184D2204 (little endian) */
    if (magic[0] == 0x04 && magic[1] == 0x22 && magic[2] == 0x4d && magic[3] == 0x18)
        return COMPRESSION_LZ4;

    if (mc_read (fd, (char *) magic + 4, 2) != 2)
        return COMPRESSION_NONE;

    /* LZIP files */
    if (magic[0] == 'L'
        && magic[1] == 'Z'
        && magic[2] == 'I' && magic[3] == 'P' && (magic[4] == 0x00 || magic[4] == 0x01))
        return COMPRESSION_LZIP;

    /* Support for LZMA (only utils format with magic in header).
     * This is the default format of LZMA utils 4.32.1 and later. */
    if (magic[0] == 0xFF
        && magic[1] == 'L'
        && magic[2] == 'Z' && magic[3] == 'M' && magic[4] == 'A' && magic[5] == 0x00)
        return COMPRESSION_LZMA;

    /* XZ compression magic */
    if (magic[0] == 0xFD
        && magic[1] == 0x37
        && magic[2] == 0x7A && magic[3] == 0x58 && magic[4] == 0x5A && magic[5] == 0x00)
        return COMPRESSION_XZ;

    str_len = strlen (name);
    /* HACK: we must belive to extension of LZMA file :) ... */
    if ((str_len > 5 && strcmp (&name[str_len - 5], ".lzma") == 0) ||
        (str_len > 4 && strcmp (&name[str_len - 4], ".tlz") == 0))
        return COMPRESSION_LZMA;

    return COMPRESSION_NONE;
}
Пример #7
0
gboolean
mcview_load (mcview_t * view, const char *command, const char *file, int start_line)
{
    gboolean retval = FALSE;
    vfs_path_t *vpath = NULL;

#ifdef HAVE_ASSERT_H
    assert (view->bytes_per_line != 0);
#endif

    view->filename_vpath = vfs_path_from_str (file);

    /* get working dir */
    if (file != NULL && file[0] != '\0')
    {
        vfs_path_free (view->workdir_vpath);

        if (!g_path_is_absolute (file))
        {
            vfs_path_t *p;

            p = vfs_path_clone (vfs_get_raw_current_dir ());
            view->workdir_vpath = vfs_path_append_new (p, file, (char *) NULL);
            vfs_path_free (p);
        }
        else
        {
            /* try extract path form filename */
            const char *fname;
            char *dir;

            fname = x_basename (file);
            dir = g_strndup (file, (size_t) (fname - file));
            view->workdir_vpath = vfs_path_from_str (dir);
            g_free (dir);
        }
    }

    if (!mcview_is_in_panel (view))
        view->dpy_text_column = 0;

    mcview_set_codeset (view);

    if (command != NULL && (view->magic_mode || file == NULL || file[0] == '\0'))
        retval = mcview_load_command_output (view, command);
    else if (file != NULL && file[0] != '\0')
    {
        int fd;
        char tmp[BUF_MEDIUM];
        struct stat st;

        /* Open the file */
        vpath = vfs_path_from_str (file);
        fd = mc_open (vpath, O_RDONLY | O_NONBLOCK);
        if (fd == -1)
        {
            g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\"\n%s"),
                        file, unix_error_string (errno));
            mcview_show_error (view, tmp);
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        /* Make sure we are working with a regular file */
        if (mc_fstat (fd, &st) == -1)
        {
            mc_close (fd);
            g_snprintf (tmp, sizeof (tmp), _("Cannot stat \"%s\"\n%s"),
                        file, unix_error_string (errno));
            mcview_show_error (view, tmp);
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        if (!S_ISREG (st.st_mode))
        {
            mc_close (fd);
            mcview_show_error (view, _("Cannot view: not a regular file"));
            vfs_path_free (view->filename_vpath);
            view->filename_vpath = NULL;
            vfs_path_free (view->workdir_vpath);
            view->workdir_vpath = NULL;
            goto finish;
        }

        if (st.st_size == 0 || mc_lseek (fd, 0, SEEK_SET) == -1)
        {
            /* Must be one of those nice files that grow (/proc) */
            mcview_set_datasource_vfs_pipe (view, fd);
        }
        else
        {
            int type;

            type = get_compression_type (fd, file);

            if (view->magic_mode && (type != COMPRESSION_NONE))
            {
                char *tmp_filename;
                vfs_path_t *vpath1;
                int fd1;

                tmp_filename = g_strconcat (file, decompress_extension (type), (char *) NULL);
                vpath1 = vfs_path_from_str (tmp_filename);
                fd1 = mc_open (vpath1, O_RDONLY | O_NONBLOCK);
                if (fd1 == -1)
                {
                    g_snprintf (tmp, sizeof (tmp), _("Cannot open \"%s\" in parse mode\n%s"),
                                file, unix_error_string (errno));
                    mcview_show_error (view, tmp);
                }
                else
                {
                    mc_close (fd);
                    fd = fd1;
                    mc_fstat (fd, &st);
                }
                vfs_path_free (vpath1);

                g_free (tmp_filename);
            }
            mcview_set_datasource_file (view, fd, &st);
        }
        retval = TRUE;
    }

  finish:
    view->command = g_strdup (command);
    view->dpy_start = 0;
    view->search_start = 0;
    view->search_end = 0;
    view->dpy_text_column = 0;

    mcview_compute_areas (view);
    mcview_update_bytes_per_line (view);

    if (mcview_remember_file_position && view->filename_vpath != NULL && start_line == 0)
    {
        long line, col;
        off_t new_offset, max_offset;

        load_file_position (view->filename_vpath, &line, &col, &new_offset, &view->saved_bookmarks);
        max_offset = mcview_get_filesize (view) - 1;
        if (max_offset < 0)
            new_offset = 0;
        else
            new_offset = min (new_offset, max_offset);
        if (!view->hex_mode)
            view->dpy_start = mcview_bol (view, new_offset, 0);
        else
        {
            view->dpy_start = new_offset - new_offset % view->bytes_per_line;
            view->hex_cursor = new_offset;
        }
    }
    else if (start_line > 0)
        mcview_moveto (view, start_line - 1, 0);

    view->hexedit_lownibble = FALSE;
    view->hexview_in_text = FALSE;
    view->change_list = NULL;
    vfs_path_free (vpath);
    return retval;
}
Пример #8
0
static void skip_n_records (vfs_s_super *archive, int tard, int n)
{
    mc_lseek (tard, n * RECORDSIZE, SEEK_CUR);
    current_tar_position += n * RECORDSIZE;
}