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; }
/* 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; }
/*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; }
/* 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; }
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; }
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; }
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; }
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; }