diff options
Diffstat (limited to 'src/vfs/undelfs')
-rw-r--r-- | src/vfs/undelfs/Makefile.am | 7 | ||||
-rw-r--r-- | src/vfs/undelfs/Makefile.in | 735 | ||||
-rw-r--r-- | src/vfs/undelfs/undelfs.c | 844 | ||||
-rw-r--r-- | src/vfs/undelfs/undelfs.h | 18 |
4 files changed, 1604 insertions, 0 deletions
diff --git a/src/vfs/undelfs/Makefile.am b/src/vfs/undelfs/Makefile.am new file mode 100644 index 0000000..4e7a77d --- /dev/null +++ b/src/vfs/undelfs/Makefile.am @@ -0,0 +1,7 @@ + +AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) + +noinst_LTLIBRARIES = libvfs-undelfs.la + +libvfs_undelfs_la_SOURCES = \ + undelfs.c undelfs.h diff --git a/src/vfs/undelfs/Makefile.in b/src/vfs/undelfs/Makefile.in new file mode 100644 index 0000000..4f258d7 --- /dev/null +++ b/src/vfs/undelfs/Makefile.in @@ -0,0 +1,735 @@ +# Makefile.in generated by automake 1.16.5 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2021 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = src/vfs/undelfs +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/gettext.m4 \ + $(top_srcdir)/m4/iconv.m4 $(top_srcdir)/m4/intlmacosx.m4 \ + $(top_srcdir)/m4/lib-ld.m4 $(top_srcdir)/m4/lib-link.m4 \ + $(top_srcdir)/m4/lib-prefix.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/longlong.m4 $(top_srcdir)/m4/ltoptions.m4 \ + $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ + $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/nls.m4 \ + $(top_srcdir)/m4/po.m4 $(top_srcdir)/m4/progtest.m4 \ + $(top_srcdir)/acinclude.m4 \ + $(top_srcdir)/m4.include/gnulib/mode_t.m4 \ + $(top_srcdir)/m4.include/gnulib/stat-size.m4 \ + $(top_srcdir)/m4.include/gnulib/fstypename.m4 \ + $(top_srcdir)/m4.include/gnulib/fsusage.m4 \ + $(top_srcdir)/m4.include/gnulib/mountlist.m4 \ + $(top_srcdir)/m4.include/gnulib/windows-stat-inodes.m4 \ + $(top_srcdir)/m4.include/gnulib/sys_types_h.m4 \ + $(top_srcdir)/m4.include/ax_path_lib_pcre.m4 \ + $(top_srcdir)/m4.include/ax_check_pcre2.m4 \ + $(top_srcdir)/m4.include/dx_doxygen.m4 \ + $(top_srcdir)/m4.include/ax_require_defined.m4 \ + $(top_srcdir)/m4.include/ax_check_compile_flag.m4 \ + $(top_srcdir)/m4.include/ax_append_flag.m4 \ + $(top_srcdir)/m4.include/ax_append_compile_flags.m4 \ + $(top_srcdir)/m4.include/mc-cflags.m4 \ + $(top_srcdir)/m4.include/ax_gcc_func_attribute.m4 \ + $(top_srcdir)/m4.include/mc-check-search-type.m4 \ + $(top_srcdir)/m4.include/mc-get-fs-info.m4 \ + $(top_srcdir)/m4.include/mc-with-x.m4 \ + $(top_srcdir)/m4.include/mc-use-termcap.m4 \ + $(top_srcdir)/m4.include/mc-with-screen.m4 \ + $(top_srcdir)/m4.include/mc-with-screen-ncurses.m4 \ + $(top_srcdir)/m4.include/mc-with-screen-slang.m4 \ + $(top_srcdir)/m4.include/mc-with-internal-edit.m4 \ + $(top_srcdir)/m4.include/mc-subshell.m4 \ + $(top_srcdir)/m4.include/mc-background.m4 \ + $(top_srcdir)/m4.include/mc-ext2fs-attr.m4 \ + $(top_srcdir)/m4.include/mc-glib.m4 \ + $(top_srcdir)/m4.include/mc-vfs.m4 \ + $(top_srcdir)/m4.include/vfs/rpc.m4 \ + $(top_srcdir)/m4.include/vfs/socket.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-extfs.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-sfs.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-ftp.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-sftp.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-fish.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-undelfs.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-tarfs.m4 \ + $(top_srcdir)/m4.include/vfs/mc-vfs-cpiofs.m4 \ + $(top_srcdir)/m4.include/mc-version.m4 \ + $(top_srcdir)/m4.include/mc-tests.m4 \ + $(top_srcdir)/m4.include/mc-i18n.m4 \ + $(top_srcdir)/m4.include/mc-assert.m4 \ + $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +LTLIBRARIES = $(noinst_LTLIBRARIES) +libvfs_undelfs_la_LIBADD = +am_libvfs_undelfs_la_OBJECTS = undelfs.lo +libvfs_undelfs_la_OBJECTS = $(am_libvfs_undelfs_la_OBJECTS) +AM_V_lt = $(am__v_lt_@AM_V@) +am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) +am__v_lt_0 = --silent +am__v_lt_1 = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/config/depcomp +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/undelfs.Plo +am__mv = mv -f +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = +SOURCES = $(libvfs_undelfs_la_SOURCES) +DIST_SOURCES = $(libvfs_undelfs_la_SOURCES) +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +# Read a list of newline-separated strings from the standard input, +# and print each of them once, without duplicates. Input order is +# *not* preserved. +am__uniquify_input = $(AWK) '\ + BEGIN { nonempty = 0; } \ + { items[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in items) print i; }; } \ +' +# Make sure the list of sources is unique. This is necessary because, +# e.g., the same source file might be shared among _SOURCES variables +# for different programs/libraries. +am__define_uniq_tagged_files = \ + list='$(am__tagged_files)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | $(am__uniquify_input)` +am__DIST_COMMON = $(srcdir)/Makefile.in $(top_srcdir)/config/depcomp +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CHECK_CFLAGS = @CHECK_CFLAGS@ +CHECK_LIBS = @CHECK_LIBS@ +COM_ERR_CFLAGS = @COM_ERR_CFLAGS@ +COM_ERR_LIBS = @COM_ERR_LIBS@ +CP1251 = @CP1251@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CSCOPE = @CSCOPE@ +CTAGS = @CTAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DOC_LINGUAS = @DOC_LINGUAS@ +DOXYGEN_PAPER_SIZE = @DOXYGEN_PAPER_SIZE@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +DX_CONFIG = @DX_CONFIG@ +DX_DOCDIR = @DX_DOCDIR@ +DX_DOT = @DX_DOT@ +DX_DOXYGEN = @DX_DOXYGEN@ +DX_DVIPS = @DX_DVIPS@ +DX_EGREP = @DX_EGREP@ +DX_ENV = @DX_ENV@ +DX_FLAG_chi = @DX_FLAG_chi@ +DX_FLAG_chm = @DX_FLAG_chm@ +DX_FLAG_doc = @DX_FLAG_doc@ +DX_FLAG_dot = @DX_FLAG_dot@ +DX_FLAG_html = @DX_FLAG_html@ +DX_FLAG_man = @DX_FLAG_man@ +DX_FLAG_pdf = @DX_FLAG_pdf@ +DX_FLAG_ps = @DX_FLAG_ps@ +DX_FLAG_rtf = @DX_FLAG_rtf@ +DX_FLAG_xml = @DX_FLAG_xml@ +DX_HHC = @DX_HHC@ +DX_LATEX = @DX_LATEX@ +DX_MAKEINDEX = @DX_MAKEINDEX@ +DX_PDFLATEX = @DX_PDFLATEX@ +DX_PERL = @DX_PERL@ +DX_PROJECT = @DX_PROJECT@ +E2P_CFLAGS = @E2P_CFLAGS@ +E2P_LIBS = @E2P_LIBS@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +ETAGS = @ETAGS@ +EXEEXT = @EXEEXT@ +EXT2FS_CFLAGS = @EXT2FS_CFLAGS@ +EXT2FS_LIBS = @EXT2FS_LIBS@ +EXTHELPERSDIR = @EXTHELPERSDIR@ +FGREP = @FGREP@ +FILECMD = @FILECMD@ +GETTEXT_MACRO_VERSION = @GETTEXT_MACRO_VERSION@ +GLIB_CFLAGS = @GLIB_CFLAGS@ +GLIB_LIBS = @GLIB_LIBS@ +GMODULE_CFLAGS = @GMODULE_CFLAGS@ +GMODULE_LIBS = @GMODULE_LIBS@ +GMSGFMT = @GMSGFMT@ +GMSGFMT_015 = @GMSGFMT_015@ +GREP = @GREP@ +HAVE_FILECMD = @HAVE_FILECMD@ +HAVE_ZIPINFO = @HAVE_ZIPINFO@ +HAVE_nroff = @HAVE_nroff@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +INTLLIBS = @INTLLIBS@ +INTL_MACOSX_LIBS = @INTL_MACOSX_LIBS@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBICONV = @LIBICONV@ +LIBINTL = @LIBINTL@ +LIBMC_RELEASE = @LIBMC_RELEASE@ +LIBMC_VERSION = @LIBMC_VERSION@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBSSH_CFLAGS = @LIBSSH_CFLAGS@ +LIBSSH_LIBS = @LIBSSH_LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBICONV = @LTLIBICONV@ +LTLIBINTL = @LTLIBINTL@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MANDOC = @MANDOC@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MAN_DATE = @MAN_DATE@ +MAN_FLAGS = @MAN_FLAGS@ +MAN_VERSION = @MAN_VERSION@ +MCLIBS = @MCLIBS@ +MKDIR_P = @MKDIR_P@ +MSGFMT = @MSGFMT@ +MSGFMT_015 = @MSGFMT_015@ +MSGMERGE = @MSGMERGE@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PCRE_CFLAGS = @PCRE_CFLAGS@ +PCRE_LIBS = @PCRE_LIBS@ +PERL = @PERL@ +PERL_FOR_BUILD = @PERL_FOR_BUILD@ +PKG_CONFIG = @PKG_CONFIG@ +PKG_CONFIG_LIBDIR = @PKG_CONFIG_LIBDIR@ +PKG_CONFIG_PATH = @PKG_CONFIG_PATH@ +POSUB = @POSUB@ +PYTHON = @PYTHON@ +RANLIB = @RANLIB@ +RUBY = @RUBY@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +SLANG_CFLAGS = @SLANG_CFLAGS@ +SLANG_LIBS = @SLANG_LIBS@ +STRIP = @STRIP@ +TESTS_LDFLAGS = @TESTS_LDFLAGS@ +UNZIP = @UNZIP@ +USE_NLS = @USE_NLS@ +VERSION = @VERSION@ +X11_WWW = @X11_WWW@ +XGETTEXT = @XGETTEXT@ +XGETTEXT_015 = @XGETTEXT_015@ +XGETTEXT_EXTRA_OPTIONS = @XGETTEXT_EXTRA_OPTIONS@ +XMKMF = @XMKMF@ +X_CFLAGS = @X_CFLAGS@ +X_EXTRA_LIBS = @X_EXTRA_LIBS@ +X_LIBS = @X_LIBS@ +X_PRE_LIBS = @X_PRE_LIBS@ +ZIP = @ZIP@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +AM_CPPFLAGS = $(GLIB_CFLAGS) -I$(top_srcdir) +noinst_LTLIBRARIES = libvfs-undelfs.la +libvfs_undelfs_la_SOURCES = \ + undelfs.c undelfs.h + +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu src/vfs/undelfs/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --gnu src/vfs/undelfs/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +clean-noinstLTLIBRARIES: + -test -z "$(noinst_LTLIBRARIES)" || rm -f $(noinst_LTLIBRARIES) + @list='$(noinst_LTLIBRARIES)'; \ + locs=`for p in $$list; do echo $$p; done | \ + sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \ + sort -u`; \ + test -z "$$locs" || { \ + echo rm -f $${locs}; \ + rm -f $${locs}; \ + } + +libvfs-undelfs.la: $(libvfs_undelfs_la_OBJECTS) $(libvfs_undelfs_la_DEPENDENCIES) $(EXTRA_libvfs_undelfs_la_DEPENDENCIES) + $(AM_V_CCLD)$(LINK) $(libvfs_undelfs_la_OBJECTS) $(libvfs_undelfs_la_LIBADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/undelfs.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.c.o: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ $< + +.c.obj: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(COMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(AM_V_CC)$(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ $(AM_V_CC)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(AM_V_CC@am__nodep@)$(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(am__tagged_files) + $(am__define_uniq_tagged_files); mkid -fID $$unique +tags: tags-am +TAGS: tags + +tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + set x; \ + here=`pwd`; \ + $(am__define_uniq_tagged_files); \ + shift; \ + if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + if test $$# -gt 0; then \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + "$$@" $$unique; \ + else \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$unique; \ + fi; \ + fi +ctags: ctags-am + +CTAGS: ctags +ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files) + $(am__define_uniq_tagged_files); \ + test -z "$(CTAGS_ARGS)$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && $(am__cd) $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) "$$here" +cscopelist: cscopelist-am + +cscopelist-am: $(am__tagged_files) + list='$(am__tagged_files)'; \ + case "$(srcdir)" in \ + [\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \ + *) sdir=$(subdir)/$(srcdir) ;; \ + esac; \ + for i in $$list; do \ + if test -f "$$i"; then \ + echo "$(subdir)/$$i"; \ + else \ + echo "$$sdir/$$i"; \ + fi; \ + done >> $(top_builddir)/cscope.files + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags +distdir: $(BUILT_SOURCES) + $(MAKE) $(AM_MAKEFLAGS) distdir-am + +distdir-am: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile $(LTLIBRARIES) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ + mostlyclean-am + +distclean: distclean-am + -rm -f ./$(DEPDIR)/undelfs.Plo + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f ./$(DEPDIR)/undelfs.Plo + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags distdir dvi \ + dvi-am html html-am info info-am install install-am \ + install-data install-data-am install-dvi install-dvi-am \ + install-exec install-exec-am install-html install-html-am \ + install-info install-info-am install-man install-pdf \ + install-pdf-am install-ps install-ps-am install-strip \ + installcheck installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/src/vfs/undelfs/undelfs.c b/src/vfs/undelfs/undelfs.c new file mode 100644 index 0000000..de54440 --- /dev/null +++ b/src/vfs/undelfs/undelfs.c @@ -0,0 +1,844 @@ +/* + UnDel File System: Midnight Commander file system. + + This file system is intended to be used together with the + ext2fs library to recover files from ext2fs file systems. + + Parts of this program were taken from the lsdel.c and dump.c files + written by Ted Ts'o (tytso@mit.edu) for the ext2fs package. + + Copyright (C) 1995-2023 + Free Software Foundation, Inc. + + Written by: + Miguel de Icaza, 1995 + Norbert Warmuth, 1997 + Pavel Machek, 2000 + + This file is part of the Midnight Commander. + + The Midnight Commander is free software: you can redistribute it + and/or modify it under the terms of the GNU General Public License as + published by the Free Software Foundation, either version 3 of the License, + or (at your option) any later version. + + The Midnight Commander is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +/** + * \file + * \brief Source: UnDel File System + * + * Assumptions: + * + * 1. We don't handle directories (thus undelfs_get_path is easy to write). + * 2. Files are on the local file system (we do not support vfs files + * because we would have to provide an io_manager for the ext2fs tools, + * and I don't think it would be too useful to undelete files + */ + +#include <config.h> + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> /* memset() */ +#include <ext2fs/ext2_fs.h> +#include <ext2fs/ext2fs.h> +#include <ctype.h> + +#include "lib/global.h" + +#include "lib/util.h" +#include "lib/widget.h" /* message() */ +#include "lib/vfs/xdirentry.h" +#include "lib/vfs/utilvfs.h" +#include "lib/vfs/vfs.h" + +#include "undelfs.h" + +/*** global variables ****************************************************************************/ + +/*** file scope macro definitions ****************************************************************/ + +/* To generate the . and .. entries use -2 */ +#define READDIR_PTR_INIT 0 + +#define undelfs_stat undelfs_lstat + +/*** file scope type declarations ****************************************************************/ + +struct deleted_info +{ + ext2_ino_t ino; + unsigned short mode; + unsigned short uid; + unsigned short gid; + unsigned long size; + time_t dtime; + int num_blocks; + int free_blocks; +}; + +struct lsdel_struct +{ + ext2_ino_t inode; + int num_blocks; + int free_blocks; + int bad_blocks; +}; + +typedef struct +{ + int f_index; /* file index into delarray */ + char *buf; + int error_code; /* */ + off_t pos; /* file position */ + off_t current; /* used to determine current position in itereate */ + gboolean finished; + ext2_ino_t inode; + int bytes_read; + off_t size; + + /* Used by undelfs_read: */ + char *dest_buffer; /* destination buffer */ + size_t count; /* bytes to read */ +} undelfs_file; + +/*** forward declarations (file scope functions) *************************************************/ + +/*** file scope variables ************************************************************************/ + +/* We only allow one opened ext2fs */ +static char *ext2_fname; +static ext2_filsys fs = NULL; +static struct lsdel_struct lsd; +static struct deleted_info *delarray; +static int num_delarray, max_delarray; +static char *block_buf; +static const char *undelfserr = N_("undelfs: error"); +static int readdir_ptr; +static int undelfs_usage; + +static struct vfs_s_subclass undelfs_subclass; +static struct vfs_class *vfs_undelfs_ops = VFS_CLASS (&undelfs_subclass); + +/* --------------------------------------------------------------------------------------------- */ +/*** file scope functions ************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ + +static void +undelfs_shutdown (void) +{ + if (fs) + ext2fs_close (fs); + fs = NULL; + MC_PTR_FREE (ext2_fname); + MC_PTR_FREE (delarray); + MC_PTR_FREE (block_buf); +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +undelfs_get_path (const vfs_path_t * vpath, char **fsname, char **file) +{ + const char *p, *dirname; + + dirname = vfs_path_get_last_path_str (vpath); + + /* To look like filesystem, we have virtual directories + undel://XXX, which have no subdirectories. XXX is replaced with + hda5, sdb8 etc, which is assumed to live under /dev. + -- pavel@ucw.cz */ + + *fsname = NULL; + + if (strncmp (dirname, "undel://", 8) != 0) + return; + + dirname += 8; + + /* Since we don't allow subdirectories, it's easy to get a filename, + * just scan backwards for a slash */ + if (*dirname == '\0') + return; + + p = dirname + strlen (dirname); +#if 0 + /* Strip trailing ./ + */ + if (p - dirname > 2 && IS_PATH_SEP (p[-1]) && p[-2] == '.') + *(p = p - 2) = 0; +#endif + + while (p > dirname) + { + if (IS_PATH_SEP (*p)) + { + char *tmp; + + *file = g_strdup (p + 1); + tmp = g_strndup (dirname, p - dirname); + *fsname = g_strconcat ("/dev/", tmp, (char *) NULL); + g_free (tmp); + return; + } + p--; + } + *file = g_strdup (""); + *fsname = g_strconcat ("/dev/", dirname, (char *) NULL); +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_lsdel_proc (ext2_filsys _fs, blk_t * block_nr, int blockcnt, void *private) +{ + struct lsdel_struct *_lsd = (struct lsdel_struct *) private; + (void) blockcnt; + _lsd->num_blocks++; + + if (*block_nr < _fs->super->s_first_data_block || *block_nr >= _fs->super->s_blocks_count) + { + _lsd->bad_blocks++; + return BLOCK_ABORT; + } + + if (!ext2fs_test_block_bitmap (_fs->block_map, *block_nr)) + _lsd->free_blocks++; + + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ +/** + * Load information about deleted files. + * Don't abort if there is not enough memory - load as much as we can. + */ + +static int +undelfs_loaddel (void) +{ + int retval, count; + ext2_ino_t ino; + struct ext2_inode inode; + ext2_inode_scan scan; + + max_delarray = 100; + num_delarray = 0; + delarray = g_try_malloc (sizeof (struct deleted_info) * max_delarray); + if (!delarray) + { + message (D_ERROR, undelfserr, "%s", _("not enough memory")); + return 0; + } + block_buf = g_try_malloc (fs->blocksize * 3); + if (!block_buf) + { + message (D_ERROR, undelfserr, "%s", _("while allocating block buffer")); + goto free_delarray; + } + retval = ext2fs_open_inode_scan (fs, 0, &scan); + if (retval != 0) + { + message (D_ERROR, undelfserr, _("open_inode_scan: %d"), retval); + goto free_block_buf; + } + retval = ext2fs_get_next_inode (scan, &ino, &inode); + if (retval != 0) + { + message (D_ERROR, undelfserr, _("while starting inode scan %d"), retval); + goto error_out; + } + count = 0; + while (ino) + { + if ((count++ % 1024) == 0) + vfs_print_message (_("undelfs: loading deleted files information %d inodes"), count); + if (inode.i_dtime == 0) + goto next; + + if (S_ISDIR (inode.i_mode)) + goto next; + + lsd.inode = ino; + lsd.num_blocks = 0; + lsd.free_blocks = 0; + lsd.bad_blocks = 0; + + retval = ext2fs_block_iterate (fs, ino, 0, block_buf, undelfs_lsdel_proc, &lsd); + if (retval) + { + message (D_ERROR, undelfserr, _("while calling ext2_block_iterate %d"), retval); + goto next; + } + if (lsd.free_blocks && !lsd.bad_blocks) + { + if (num_delarray >= max_delarray) + { + struct deleted_info *delarray_new = g_try_realloc (delarray, + sizeof (struct deleted_info) * + (max_delarray + 50)); + if (!delarray_new) + { + message (D_ERROR, undelfserr, "%s", + _("no more memory while reallocating array")); + goto error_out; + } + delarray = delarray_new; + max_delarray += 50; + } + + delarray[num_delarray].ino = ino; + delarray[num_delarray].mode = inode.i_mode; + delarray[num_delarray].uid = inode.i_uid; + delarray[num_delarray].gid = inode.i_gid; + delarray[num_delarray].size = inode.i_size; + delarray[num_delarray].dtime = inode.i_dtime; + delarray[num_delarray].num_blocks = lsd.num_blocks; + delarray[num_delarray].free_blocks = lsd.free_blocks; + num_delarray++; + } + + next: + retval = ext2fs_get_next_inode (scan, &ino, &inode); + if (retval) + { + message (D_ERROR, undelfserr, _("while doing inode scan %d"), retval); + goto error_out; + } + } + readdir_ptr = READDIR_PTR_INIT; + ext2fs_close_inode_scan (scan); + return 1; + + error_out: + ext2fs_close_inode_scan (scan); + free_block_buf: + MC_PTR_FREE (block_buf); + free_delarray: + MC_PTR_FREE (delarray); + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +static void * +undelfs_opendir (const vfs_path_t * vpath) +{ + char *file, *f = NULL; + const char *class_name; + + class_name = vfs_path_get_last_path_vfs (vpath)->name; + undelfs_get_path (vpath, &file, &f); + if (file == NULL) + { + g_free (f); + return 0; + } + + /* We don't use the file name */ + g_free (f); + + if (!ext2_fname || strcmp (ext2_fname, file)) + { + undelfs_shutdown (); + ext2_fname = file; + } + else + { + /* To avoid expensive re-scannings */ + readdir_ptr = READDIR_PTR_INIT; + g_free (file); + return fs; + } + + if (ext2fs_open (ext2_fname, 0, 0, 0, unix_io_manager, &fs)) + { + message (D_ERROR, undelfserr, _("Cannot open file %s"), ext2_fname); + return 0; + } + vfs_print_message ("%s", _("undelfs: reading inode bitmap...")); + if (ext2fs_read_inode_bitmap (fs)) + { + message (D_ERROR, undelfserr, _("Cannot load inode bitmap from:\n%s"), ext2_fname); + goto quit_opendir; + } + vfs_print_message ("%s", _("undelfs: reading block bitmap...")); + if (ext2fs_read_block_bitmap (fs)) + { + message (D_ERROR, undelfserr, _("Cannot load block bitmap from:\n%s"), ext2_fname); + goto quit_opendir; + } + /* Now load the deleted information */ + if (!undelfs_loaddel ()) + goto quit_opendir; + vfs_print_message (_("%s: done."), class_name); + return fs; + quit_opendir: + vfs_print_message (_("%s: failure"), class_name); + ext2fs_close (fs); + fs = NULL; + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +static struct vfs_dirent * +undelfs_readdir (void *vfs_info) +{ + struct vfs_dirent *dirent; + + if (vfs_info != fs) + { + message (D_ERROR, undelfserr, "%s", _("vfs_info is not fs!")); + return NULL; + } + if (readdir_ptr == num_delarray) + return NULL; + if (readdir_ptr < 0) + dirent = vfs_dirent_init (NULL, readdir_ptr == -2 ? "." : "..", 0); /* FIXME: inode */ + else + { + char dirent_dest[MC_MAXPATHLEN]; + + g_snprintf (dirent_dest, MC_MAXPATHLEN, "%ld:%d", + (long) delarray[readdir_ptr].ino, delarray[readdir_ptr].num_blocks); + dirent = vfs_dirent_init (NULL, dirent_dest, 0); /* FIXME: inode */ + } + readdir_ptr++; + + return dirent; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_closedir (void *vfs_info) +{ + (void) vfs_info; + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ +/* We do not support lseek */ + +static void * +undelfs_open (const vfs_path_t * vpath, int flags, mode_t mode) +{ + char *file, *f = NULL; + ext2_ino_t inode, i; + undelfs_file *p = NULL; + (void) flags; + (void) mode; + + /* Only allow reads on this file system */ + undelfs_get_path (vpath, &file, &f); + if (file == NULL) + { + g_free (f); + return 0; + } + + if (!ext2_fname || strcmp (ext2_fname, file)) + { + message (D_ERROR, undelfserr, "%s", _("You have to chdir to extract files first")); + g_free (file); + g_free (f); + return 0; + } + inode = atol (f); + + /* Search the file into delarray */ + for (i = 0; i < (ext2_ino_t) num_delarray; i++) + { + if (inode != delarray[i].ino) + continue; + + /* Found: setup all the structures needed by read */ + p = (undelfs_file *) g_try_malloc (((gsize) sizeof (undelfs_file))); + if (!p) + { + g_free (file); + g_free (f); + return 0; + } + p->buf = g_try_malloc (fs->blocksize); + if (!p->buf) + { + g_free (p); + g_free (file); + g_free (f); + return 0; + } + p->inode = inode; + p->finished = FALSE; + p->f_index = i; + p->error_code = 0; + p->pos = 0; + p->size = delarray[i].size; + } + g_free (file); + g_free (f); + undelfs_usage++; + return p; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_close (void *vfs_info) +{ + undelfs_file *p = vfs_info; + g_free (p->buf); + g_free (p); + undelfs_usage--; + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_dump_read (ext2_filsys param_fs, blk_t * blocknr, int blockcnt, void *private) +{ + int copy_count; + undelfs_file *p = (undelfs_file *) private; + + if (blockcnt < 0) + return 0; + + if (*blocknr) + { + p->error_code = io_channel_read_blk (param_fs->io, *blocknr, 1, p->buf); + if (p->error_code) + return BLOCK_ABORT; + } + else + memset (p->buf, 0, param_fs->blocksize); + + if (p->pos + (off_t) p->count < p->current) + { + p->finished = TRUE; + return BLOCK_ABORT; + } + if (p->pos > p->current + param_fs->blocksize) + { + p->current += param_fs->blocksize; + return 0; /* we have not arrived yet */ + } + + /* Now, we know we have to extract some data */ + if (p->pos >= p->current) + { + + /* First case: starting pointer inside this block */ + if (p->pos + (off_t) p->count <= p->current + param_fs->blocksize) + { + /* Fully contained */ + copy_count = p->count; + p->finished = (p->count != 0); + } + else + { + /* Still some more data */ + copy_count = param_fs->blocksize - (p->pos - p->current); + } + memcpy (p->dest_buffer, p->buf + (p->pos - p->current), copy_count); + } + else + { + /* Second case: we already have passed p->pos */ + if (p->pos + (off_t) p->count < p->current + param_fs->blocksize) + { + copy_count = (p->pos + p->count) - p->current; + p->finished = (p->count != 0); + } + else + { + copy_count = param_fs->blocksize; + } + memcpy (p->dest_buffer, p->buf, copy_count); + } + p->dest_buffer += copy_count; + p->current += param_fs->blocksize; + if (p->finished) + { + return BLOCK_ABORT; + } + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +static ssize_t +undelfs_read (void *vfs_info, char *buffer, size_t count) +{ + undelfs_file *p = vfs_info; + int retval; + + p->dest_buffer = buffer; + p->current = 0; + p->finished = FALSE; + p->count = count; + + if (p->pos + (off_t) p->count > p->size) + { + p->count = p->size - p->pos; + } + retval = ext2fs_block_iterate (fs, p->inode, 0, NULL, undelfs_dump_read, p); + if (retval) + { + message (D_ERROR, undelfserr, "%s", _("while iterating over blocks")); + return -1; + } + if (p->error_code && !p->finished) + return 0; + p->pos = p->pos + (p->dest_buffer - buffer); + return p->dest_buffer - buffer; +} + +/* --------------------------------------------------------------------------------------------- */ + +static long +undelfs_getindex (char *path) +{ + ext2_ino_t inode = atol (path); + int i; + + for (i = 0; i < num_delarray; i++) + { + if (delarray[i].ino == inode) + return i; + } + return -1; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_stat_int (int inode_index, struct stat *buf) +{ + buf->st_dev = 0; + buf->st_ino = delarray[inode_index].ino; + buf->st_mode = delarray[inode_index].mode; + buf->st_nlink = 1; + buf->st_uid = delarray[inode_index].uid; + buf->st_gid = delarray[inode_index].gid; + buf->st_size = delarray[inode_index].size; + buf->st_atime = delarray[inode_index].dtime; + buf->st_ctime = delarray[inode_index].dtime; + buf->st_mtime = delarray[inode_index].dtime; +#ifdef HAVE_STRUCT_STAT_ST_MTIM + buf->st_atim.tv_nsec = buf->st_mtim.tv_nsec = buf->st_ctim.tv_nsec = 0; +#endif + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_lstat (const vfs_path_t * vpath, struct stat *buf) +{ + int inode_index; + char *file, *f = NULL; + + undelfs_get_path (vpath, &file, &f); + if (file == NULL) + { + g_free (f); + return 0; + } + + /* When called from save_cwd_stats we get an incorrect file and f here: + e.g. incorrect correct + path = "undel:/dev/sda1" path="undel:/dev/sda1/401:1" + file = "/dev" file="/dev/sda1" + f = "sda1" f ="401:1" + If the first char in f is no digit -> return error */ + if (!isdigit (*f)) + { + g_free (file); + g_free (f); + return -1; + } + + if (!ext2_fname || strcmp (ext2_fname, file)) + { + g_free (file); + g_free (f); + message (D_ERROR, undelfserr, "%s", _("You have to chdir to extract files first")); + return 0; + } + inode_index = undelfs_getindex (f); + g_free (file); + g_free (f); + + if (inode_index == -1) + return -1; + + return undelfs_stat_int (inode_index, buf); +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_fstat (void *vfs_info, struct stat *buf) +{ + undelfs_file *p = vfs_info; + + return undelfs_stat_int (p->f_index, buf); +} + +/* --------------------------------------------------------------------------------------------- */ + +static int +undelfs_chdir (const vfs_path_t * vpath) +{ + char *file, *f = NULL; + int fd; + + undelfs_get_path (vpath, &file, &f); + if (file == NULL) + { + g_free (f); + return (-1); + } + + /* We may use access because ext2 file systems are local */ + /* this could be fixed by making an ext2fs io manager to use */ + /* our vfs, but that is left as an exercise for the reader */ + fd = open (file, O_RDONLY); + if (fd == -1) + { + message (D_ERROR, undelfserr, _("Cannot open file \"%s\""), file); + g_free (f); + g_free (file); + return -1; + } + close (fd); + g_free (f); + g_free (file); + return 0; +} + +/* --------------------------------------------------------------------------------------------- */ + +/* this has to stay here for now: vfs layer does not know how to emulate it */ +static off_t +undelfs_lseek (void *vfs_info, off_t offset, int whence) +{ + (void) vfs_info; + (void) offset; + (void) whence; + + return -1; +} + +/* --------------------------------------------------------------------------------------------- */ + +static vfsid +undelfs_getid (const vfs_path_t * vpath) +{ + char *fname = NULL, *fsname; + gboolean ok; + + undelfs_get_path (vpath, &fsname, &fname); + ok = fsname != NULL; + + g_free (fname); + g_free (fsname); + + return ok ? (vfsid) fs : NULL; +} + +/* --------------------------------------------------------------------------------------------- */ + +static gboolean +undelfs_nothingisopen (vfsid id) +{ + (void) id; + + return (undelfs_usage == 0); +} + +/* --------------------------------------------------------------------------------------------- */ + +static void +undelfs_free (vfsid id) +{ + (void) id; + + undelfs_shutdown (); +} + +/* --------------------------------------------------------------------------------------------- */ + +#ifdef ENABLE_NLS +static int +undelfs_init (struct vfs_class *me) +{ + (void) me; + + undelfserr = _(undelfserr); + return 1; +} +#else +#define undelfs_init NULL +#endif + +/* --------------------------------------------------------------------------------------------- */ +/*** public functions ****************************************************************************/ +/* --------------------------------------------------------------------------------------------- */ +/** + * This function overrides com_err() from libcom_err library. + * It is used in libext2fs to report errors. + */ + +void +com_err (const char *whoami, long err_code, const char *fmt, ...) +{ + va_list ap; + char *str; + + va_start (ap, fmt); + str = g_strdup_vprintf (fmt, ap); + va_end (ap); + + message (D_ERROR, _("Ext2lib error"), "%s (%s: %ld)", str, whoami, err_code); + g_free (str); +} + +/* --------------------------------------------------------------------------------------------- */ + +void +vfs_init_undelfs (void) +{ + /* NULLize vfs_s_subclass members */ + memset (&undelfs_subclass, 0, sizeof (undelfs_subclass)); + + vfs_init_class (vfs_undelfs_ops, "undelfs", VFSF_UNKNOWN, "undel"); + vfs_undelfs_ops->init = undelfs_init; + vfs_undelfs_ops->open = undelfs_open; + vfs_undelfs_ops->close = undelfs_close; + vfs_undelfs_ops->read = undelfs_read; + vfs_undelfs_ops->opendir = undelfs_opendir; + vfs_undelfs_ops->readdir = undelfs_readdir; + vfs_undelfs_ops->closedir = undelfs_closedir; + vfs_undelfs_ops->stat = undelfs_stat; + vfs_undelfs_ops->lstat = undelfs_lstat; + vfs_undelfs_ops->fstat = undelfs_fstat; + vfs_undelfs_ops->chdir = undelfs_chdir; + vfs_undelfs_ops->lseek = undelfs_lseek; + vfs_undelfs_ops->getid = undelfs_getid; + vfs_undelfs_ops->nothingisopen = undelfs_nothingisopen; + vfs_undelfs_ops->free = undelfs_free; + vfs_register_class (vfs_undelfs_ops); +} + +/* --------------------------------------------------------------------------------------------- */ diff --git a/src/vfs/undelfs/undelfs.h b/src/vfs/undelfs/undelfs.h new file mode 100644 index 0000000..9e32458 --- /dev/null +++ b/src/vfs/undelfs/undelfs.h @@ -0,0 +1,18 @@ +#ifndef MC__VFS_UNDELFS_H +#define MC__VFS_UNDELFS_H + +/*** typedefs(not structures) and defined constants **********************************************/ + +/*** enums ***************************************************************************************/ + +/*** structures declarations (and typedefs of structures)*****************************************/ + +/*** global variables defined in .c file *********************************************************/ + +/*** declarations of public functions ************************************************************/ + +void vfs_init_undelfs (void); + +/*** inline functions ****************************************************************************/ + +#endif /* MC__VFS_UNDELFS_H */ |