From 2748d5f2fc00e49bf83fe9f8284f3911694ea9bd Mon Sep 17 00:00:00 2001 From: short <> Date: Sun, 31 Aug 2003 13:59:02 +0000 Subject: [PATCH] Bootstrap. --- .vimrc | 2 + AUTHORS | 3 + INSTALL | 229 ++++++++++++++ Makefile-head.am | 20 ++ Makefile.am | 53 ++++ NEWS | 7 + README | 36 +++ TODO | 7 + autogen.pl | 40 +++ configure.ac | 62 ++++ cvs2cl-usermap | 2 + ntfsprogs-gnomevfs.spec.in | 66 +++++ src/Makefile.am | 33 +++ src/gnome-vfs-method.c | 722 +++++++++++++++++++++++++++++++++++++++++++++ src/gnome-vfs-method.h | 35 +++ src/gnome-vfs-module.c | 75 +++++ src/gnome-vfs-module.h | 35 +++ src/libntfs.conf.in | 1 + 18 files changed, 1428 insertions(+) create mode 100644 .vimrc create mode 100644 AUTHORS create mode 100644 INSTALL create mode 100644 Makefile-head.am create mode 100644 Makefile.am create mode 100644 NEWS create mode 100644 README create mode 100644 TODO create mode 100755 autogen.pl create mode 100644 configure.ac create mode 100644 cvs2cl-usermap create mode 100644 ntfsprogs-gnomevfs.spec.in create mode 100644 src/Makefile.am create mode 100644 src/gnome-vfs-method.c create mode 100644 src/gnome-vfs-method.h create mode 100644 src/gnome-vfs-module.c create mode 100644 src/gnome-vfs-module.h create mode 100644 src/libntfs.conf.in diff --git a/.vimrc b/.vimrc new file mode 100644 index 0000000..a847f58 --- /dev/null +++ b/.vimrc @@ -0,0 +1,2 @@ +set ts=2 +set sw=2 diff --git a/AUTHORS b/AUTHORS new file mode 100644 index 0000000..1387996 --- /dev/null +++ b/AUTHORS @@ -0,0 +1,3 @@ +Author of "ntfsprogs-gnomevfs": +Jan Kratochvil + http://www.jankratochvil.net/ diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..a4b3414 --- /dev/null +++ b/INSTALL @@ -0,0 +1,229 @@ +Copyright 1994, 1995, 1996, 1999, 2000, 2001, 2002 Free Software +Foundation, Inc. + + This file is free documentation; the Free Software Foundation gives +unlimited permission to copy, distribute and modify it. + +Basic Installation +================== + + These are generic installation instructions. + + The `configure' shell script attempts to guess correct values for +various system-dependent variables used during compilation. It uses +those values to create a `Makefile' in each directory of the package. +It may also create one or more `.h' files containing system-dependent +definitions. Finally, it creates a shell script `config.status' that +you can run in the future to recreate the current configuration, and a +file `config.log' containing compiler output (useful mainly for +debugging `configure'). + + It can also use an optional file (typically called `config.cache' +and enabled with `--cache-file=config.cache' or simply `-C') that saves +the results of its tests to speed up reconfiguring. (Caching is +disabled by default to prevent problems with accidental use of stale +cache files.) + + If you need to do unusual things to compile the package, please try +to figure out how `configure' could check whether to do them, and mail +diffs or instructions to the address given in the `README' so they can +be considered for the next release. If you are using the cache, and at +some point `config.cache' contains results you don't want to keep, you +may remove or edit it. + + The file `configure.ac' (or `configure.in') is used to create +`configure' by a program called `autoconf'. You only need +`configure.ac' if you want to change it or regenerate `configure' using +a newer version of `autoconf'. + +The simplest way to compile this package is: + + 1. `cd' to the directory containing the package's source code and type + `./configure' to configure the package for your system. If you're + using `csh' on an old version of System V, you might need to type + `sh ./configure' instead to prevent `csh' from trying to execute + `configure' itself. + + Running `configure' takes awhile. While running, it prints some + messages telling which features it is checking for. + + 2. Type `make' to compile the package. + + 3. Optionally, type `make check' to run any self-tests that come with + the package. + + 4. Type `make install' to install the programs and any data files and + documentation. + + 5. You can remove the program binaries and object files from the + source code directory by typing `make clean'. To also remove the + files that `configure' created (so you can compile the package for + a different kind of computer), type `make distclean'. There is + also a `make maintainer-clean' target, but that is intended mainly + for the package's developers. If you use it, you may have to get + all sorts of other programs in order to regenerate files that came + with the distribution. + +Compilers and Options +===================== + + Some systems require unusual options for compilation or linking that +the `configure' script does not know about. Run `./configure --help' +for details on some of the pertinent environment variables. + + You can give `configure' initial values for configuration parameters +by setting variables in the command line or in the environment. Here +is an example: + + ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix + + *Note Defining Variables::, for more details. + +Compiling For Multiple Architectures +==================================== + + You can compile the package for more than one kind of computer at the +same time, by placing the object files for each architecture in their +own directory. To do this, you must use a version of `make' that +supports the `VPATH' variable, such as GNU `make'. `cd' to the +directory where you want the object files and executables to go and run +the `configure' script. `configure' automatically checks for the +source code in the directory that `configure' is in and in `..'. + + If you have to use a `make' that does not support the `VPATH' +variable, you have to compile the package for one architecture at a +time in the source code directory. After you have installed the +package for one architecture, use `make distclean' before reconfiguring +for another architecture. + +Installation Names +================== + + By default, `make install' will install the package's files in +`/usr/local/bin', `/usr/local/man', etc. You can specify an +installation prefix other than `/usr/local' by giving `configure' the +option `--prefix=PATH'. + + You can specify separate installation prefixes for +architecture-specific files and architecture-independent files. If you +give `configure' the option `--exec-prefix=PATH', the package will use +PATH as the prefix for installing programs and libraries. +Documentation and other data files will still use the regular prefix. + + In addition, if you use an unusual directory layout you can give +options like `--bindir=PATH' to specify different values for particular +kinds of files. Run `configure --help' for a list of the directories +you can set and what kinds of files go in them. + + If the package supports it, you can cause programs to be installed +with an extra prefix or suffix on their names by giving `configure' the +option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. + +Optional Features +================= + + Some packages pay attention to `--enable-FEATURE' options to +`configure', where FEATURE indicates an optional part of the package. +They may also pay attention to `--with-PACKAGE' options, where PACKAGE +is something like `gnu-as' or `x' (for the X Window System). The +`README' should mention any `--enable-' and `--with-' options that the +package recognizes. + + For packages that use the X Window System, `configure' can usually +find the X include and library files automatically, but if it doesn't, +you can use the `configure' options `--x-includes=DIR' and +`--x-libraries=DIR' to specify their locations. + +Specifying the System Type +========================== + + There may be some features `configure' cannot figure out +automatically, but needs to determine by the type of machine the package +will run on. Usually, assuming the package is built to be run on the +_same_ architectures, `configure' can figure that out, but if it prints +a message saying it cannot guess the machine type, give it the +`--build=TYPE' option. TYPE can either be a short name for the system +type, such as `sun4', or a canonical name which has the form: + + CPU-COMPANY-SYSTEM + +where SYSTEM can have one of these forms: + + OS KERNEL-OS + + See the file `config.sub' for the possible values of each field. If +`config.sub' isn't included in this package, then this package doesn't +need to know the machine type. + + If you are _building_ compiler tools for cross-compiling, you should +use the `--target=TYPE' option to select the type of system they will +produce code for. + + If you want to _use_ a cross compiler, that generates code for a +platform different from the build platform, you should specify the +"host" platform (i.e., that on which the generated programs will +eventually be run) with `--host=TYPE'. + +Sharing Defaults +================ + + If you want to set default values for `configure' scripts to share, +you can create a site shell script called `config.site' that gives +default values for variables like `CC', `cache_file', and `prefix'. +`configure' looks for `PREFIX/share/config.site' if it exists, then +`PREFIX/etc/config.site' if it exists. Or, you can set the +`CONFIG_SITE' environment variable to the location of the site script. +A warning: not all `configure' scripts look for a site script. + +Defining Variables +================== + + Variables not defined in a site shell script can be set in the +environment passed to `configure'. However, some packages may run +configure again during the build, and the customized values of these +variables may be lost. In order to avoid this problem, you should set +them in the `configure' command line, using `VAR=value'. For example: + + ./configure CC=/usr/local2/bin/gcc + +will cause the specified gcc to be used as the C compiler (unless it is +overridden in the site shell script). + +`configure' Invocation +====================== + + `configure' recognizes the following options to control how it +operates. + +`--help' +`-h' + Print a summary of the options to `configure', and exit. + +`--version' +`-V' + Print the version of Autoconf used to generate the `configure' + script, and exit. + +`--cache-file=FILE' + Enable the cache: use and save the results of the tests in FILE, + traditionally `config.cache'. FILE defaults to `/dev/null' to + disable caching. + +`--config-cache' +`-C' + Alias for `--cache-file=config.cache'. + +`--quiet' +`--silent' +`-q' + Do not print messages saying which checks are being made. To + suppress all normal output, redirect it to `/dev/null' (any error + messages will still be shown). + +`--srcdir=DIR' + Look for the package's source code in directory DIR. Usually + `configure' can determine that directory automatically. + +`configure' also accepts some other, not widely useful, options. Run +`configure --help' for more details. + diff --git a/Makefile-head.am b/Makefile-head.am new file mode 100644 index 0000000..81a3b76 --- /dev/null +++ b/Makefile-head.am @@ -0,0 +1,20 @@ +# $Id$ +# dummy automake include file for macros/Makefile.am +# Copyright (C) 2003 Jan Kratochvil +# +# This program 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; exactly version 2 of June 1991 is required +# +# This program 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +EXTRA_DIST= +MAINTAINERCLEANFILES= diff --git a/Makefile.am b/Makefile.am new file mode 100644 index 0000000..c666af5 --- /dev/null +++ b/Makefile.am @@ -0,0 +1,53 @@ +# $Id$ +# automake source for the toplevel Makefile +# Copyright (C) 2003 Jan Kratochvil +# +# This program 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; exactly version 2 of June 1991 is required +# +# This program 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +include $(top_srcdir)/Makefile-head.am + +AUTOMAKE_OPTIONS=gnu +SUBDIRS=macros src +## to automatically rebuild aclocal.m4 if any of the macros in +## `macros/' change +@MAINT@include macros/macros.dep +@MAINT@macros/macros.dep: macros/Makefile.am +@MAINT@ cd macros && $(MAKE) macros.dep + +EXTRA_DIST+= \ + INSTALL \ + mkinstalldirs \ + ntfsprogs-gnomevfs.spec.in \ + autogen.pl \ + .vimrc \ + ChangeLog \ + Makefile-head.am \ + cvs2cl-usermap + +MAINTAINERCLEANFILES+= \ + ChangeLog + +CLEANFILES= \ + ChangeLog.bak + +if MAINTAINER_MODE +ChangeLog: + cvs2cl --usermap cvs2cl-usermap --window 3600 --separate-header --no-wrap --file $@ . + +else +ChangeLog: + touch $@ + +endif diff --git a/NEWS b/NEWS new file mode 100644 index 0000000..d4627fc --- /dev/null +++ b/NEWS @@ -0,0 +1,7 @@ +$Id$ + + +NEWS for ntfsprogs-gnomevfs-1.0 +------------------------------- + +* Bootstrap diff --git a/README b/README new file mode 100644 index 0000000..400abbb --- /dev/null +++ b/README @@ -0,0 +1,36 @@ +$Id$ + + +NTFS filesystem library GNOME virtual file-system interface +----------------------------------------------------------- + +NTFS filesystem library provides mostly read/only access to NTFS disks. +The GNOME virtual file-system provides universal access to diffent filesystems. +This package enables GNOME virtual file-system clients to seamlessly +utilize NTFS filesystem library. + + +Bleeding Edge +------------- + +cvs -d :pserver:pserver@cvs.jankratochvil.net:/cvs login + Just hit ENTER (empty password) +cvs -d :pserver:pserver@cvs.jankratochvil.net:/cvs -z3 checkout ntfsprogs-gnomevfs +cd ntfsprogs-gnomevfs +./autogen.pl +make +make install + +gnome-vfs-2.x.y/test/test-xfer 'file:///dev/hda1#libntfs:/autoexec.bat' /tmp/autoexec.bat-ntfs + + +Installation +------------ + +See the file 'INSTALL'. + + +Copyright +--------- + +See the file 'COPYING' and 'AUTHORS'. diff --git a/TODO b/TODO new file mode 100644 index 0000000..ec8e8c7 --- /dev/null +++ b/TODO @@ -0,0 +1,7 @@ +$Id$ + + +TODO +---- + +Be generic GnomeVFS filter; how to redirect ntfs_mount(3) to GnomeVFS parent? diff --git a/autogen.pl b/autogen.pl new file mode 100755 index 0000000..21cd97f --- /dev/null +++ b/autogen.pl @@ -0,0 +1,40 @@ +#! /usr/bin/perl +# +# $Id$ +# Run to generate the initial Makefiles etc. after CVS checkout. +# Copyright (C) 2002 Jan Kratochvil +# +# This program 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; exactly version 2 of June 1991 is required +# +# This program 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +require 5.6.0; # at least 'use warnings;' but we need some 5.6.0+ modules anyway +use vars qw($VERSION); +$VERSION=do { my @r=(q$Revision$=~/\d+/g); sprintf "%d.".("%03d"x$#r),@r; }; +use strict; +use warnings; + +use lib "./macros/"; +use AutoGen; + +use Carp qw(cluck confess); + + +AutoGen->run( + "name"=>"ntfsprogs-gnomevfs", + "COPYRIGHT_HOLDER"=>'Jan Kratochvil ', + "ARGV"=>\@ARGV, + "clean"=>[qw( + ./src/libntfs.conf + )], + ); diff --git a/configure.ac b/configure.ac new file mode 100644 index 0000000..e18d40b --- /dev/null +++ b/configure.ac @@ -0,0 +1,62 @@ +# $Id$ +# Source file to generate "./configure" to prepare package for compilation +# Copyright (C) 2003 Jan Kratochvil +# +# This program 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; exactly version 2 of June 1991 is required +# +# This program 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +AC_INIT(src/libntfs.conf.in) +AM_INIT_AUTOMAKE(ntfsprogs-gnomevfs,1.0cvs) +AM_CONFIG_HEADER(config.h) +AM_MAINTAINER_MODE +AM_ENABLE_SHARED +AM_DISABLE_STATIC +AM_PROG_LIBTOOL + +dnl Do not discard 'CFLAGS' settings as they may have been passed us by rpmbuild(8) + +dnl Define MAINTAINER_MODE in config.h. +if test "$USE_MAINTAINER_MODE" = "yes";then + CFLAGS="$CFLAGS -ggdb3 -Wall -Wstrict-prototypes -Wsign-compare" ## FIXME: fix all sources: -Wsign-compare + fi + + +AM_PATH_GLIB_2_0(,,[AC_MSG_ERROR([Captive requires glib-2.0 library.])],[gmodule gobject]) +dnl Force glib-2.0 for the whole package +CFLAGS="$CFLAGS $GLIB_CFLAGS" +LIBS="$LIBS $GLIB_LIBS" + +PKG_CHECK_MODULES(GNOME_VFS_MODULE,gnome-vfs-module-2.0) +dnl Force gnome-vfs-module-2.0 for the whole package +CFLAGS="$CFLAGS $GNOME_VFS_MODULE_CFLAGS" +LIBS="$LIBS $GNOME_VFS_MODULE_LIBS" + +AC_CHECK_LIB(ntfs,ntfs_mount, + [ LIBS="$LIBS -lntfs" ], + [ AC_MSG_ERROR([ntfsprogs-devel package requires for this program.]) ]) + + +AC_SUBST(CFLAGS) +AC_SUBST(LIBS) + +dnl "Makefile" output files MUST have pathnames incl./excl. "./" prefix as specified! +AC_OUTPUT([ +ntfsprogs-gnomevfs.spec +./src/libntfs.conf +Makefile +./macros/Makefile +./src/Makefile +]) + +echo done. diff --git a/cvs2cl-usermap b/cvs2cl-usermap new file mode 100644 index 0000000..a2fb6d8 --- /dev/null +++ b/cvs2cl-usermap @@ -0,0 +1,2 @@ +short:Jan Kratochvil +lace:Jan Kratochvil diff --git a/ntfsprogs-gnomevfs.spec.in b/ntfsprogs-gnomevfs.spec.in new file mode 100644 index 0000000..b51292b --- /dev/null +++ b/ntfsprogs-gnomevfs.spec.in @@ -0,0 +1,66 @@ +# $Id$ +# rpm package description file for building +# Copyright (C) 2003 Jan Kratochvil +# +# This program 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; exactly version 2 of June 1991 is required +# +# This program 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +Summary: NTFS filesystem library GNOME virtual file-system interface +Name: @PACKAGE@ +%define release 0 +Version: @VERSION@ +Release: %{release} +Group: System Environment/Base +Source: http://www.jankratochvil.net/project/captive/@PACKAGE@-@VERSION@.tar.gz +Copyright: GPL +BuildRoot: /var/tmp/@PACKAGE@-@VERSION@-%{release}-root +BuildRequires: glib2-devel +Requires: glib2 +BuildRequires: ntfsprogs-devel +Requires: ntfsprogs +BuildRequires: gnome-vfs2-devel +Requires: gnome-vfs2 + +%description +NTFS filesystem library provides mostly read/only access to NTFS disks. +The GNOME virtual file-system provides universal access to diffent filesystems. +This package enables GNOME virtual file-system clients to seamlessly +utilize NTFS filesystem library. + +%prep +%setup + +%build +%configure +make + +%install +make DESTDIR=$RPM_BUILD_ROOT install-strip +rm -f $RPM_BUILD_ROOT/%{_libdir}/gnome-vfs-2.0/modules/liblibntfs-gnomevfs.la + +%clean +rm -rf $RPM_BUILD_ROOT + +%post +/sbin/ldconfig + +%postun +/sbin/ldconfig + +%files +%defattr(-,root,root) +%doc README NEWS AUTHORS TODO +%{_libdir}/gnome-vfs-2.0/modules/liblibntfs-gnomevfs-@VERSION@.so +%{_libdir}/gnome-vfs-2.0/modules/liblibntfs-gnomevfs.so +%{_sysconfdir}/gnome-vfs-2.0/modules/libntfs.conf diff --git a/src/Makefile.am b/src/Makefile.am new file mode 100644 index 0000000..ea73a44 --- /dev/null +++ b/src/Makefile.am @@ -0,0 +1,33 @@ +# $Id$ +# automake source for the gnomevfs module for gnome-vfs2 Makefile +# Copyright (C) 2002-2003 Jan Kratochvil +# +# This program 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; exactly version 2 of June 1991 is required +# +# This program 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, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + + +include $(top_srcdir)/Makefile-head.am + +gnomevfsmoduleslibdir=$(libdir)/gnome-vfs-2.0/modules +gnomevfsmoduleslib_LTLIBRARIES=liblibntfs-gnomevfs.la + +liblibntfs_gnomevfs_la_LDFLAGS=-release $(VERSION) +liblibntfs_gnomevfs_la_SOURCES= \ + gnome-vfs-method.c \ + gnome-vfs-method.h \ + gnome-vfs-module.c \ + gnome-vfs-module.h + +gnomevfsmodulesconfdir=$(sysconfdir)/gnome-vfs-2.0/modules +gnomevfsmodulesconf_DATA=libntfs.conf +EXTRA_DIST+=libntfs.conf.in diff --git a/src/gnome-vfs-method.c b/src/gnome-vfs-method.c new file mode 100644 index 0000000..21e97c2 --- /dev/null +++ b/src/gnome-vfs-method.c @@ -0,0 +1,722 @@ +/* $Id$ + * gnome-vfs init/shutdown implementation of interface to libntfs + * Copyright (C) 2003 Jan Kratochvil + * + * This program 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; exactly version 2 of June 1991 is required + * + * This program 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "config.h" + +#undef FALSE +#undef TRUE +#include /* for 'FALSE'/'TRUE' libntfs definition */ +#define FALSE FALSE +#define TRUE TRUE + +#include "gnome-vfs-method.h" /* self */ +#include +#include +#include "gnome-vfs-module.h" +#include +#include + +#include +#include + + +static GnomeVFSMethod GnomeVFSMethod_static; +G_LOCK_DEFINE_STATIC(GnomeVFSMethod_static); + + +/* map: (gchar *)method_name -> (struct method_name_info *) */ +static GHashTable *method_name_hash; +G_LOCK_DEFINE_STATIC(method_name_hash); + +struct method_name_info { + gchar *args; + }; + +static void method_name_hash_key_destroy_func(gchar *key) +{ + g_return_if_fail(key!=NULL); + + g_free(key); +} + +static void method_name_hash_value_destroy_func(struct method_name_info *value) +{ + g_return_if_fail(value!=NULL); + + g_free(value->args); + g_free(value); +} + +static void method_name_hash_init(void) +{ + G_LOCK(method_name_hash); + if (!method_name_hash) { + method_name_hash=g_hash_table_new_full( + g_str_hash, /* hash_func */ + g_str_equal, /* key_equal_func */ + (GDestroyNotify)method_name_hash_key_destroy_func, /* key_destroy_func */ + (GDestroyNotify)method_name_hash_value_destroy_func); /* value_destroy_func */ + } + G_UNLOCK(method_name_hash); +} + + +/* map: (gchar *)uri_parent_string "method_name:uri_parent" -> (ntfs_volume *) */ +static GHashTable *uri_parent_string_hash; +G_LOCK_DEFINE_STATIC(uri_parent_string_hash); + +static void uri_parent_string_hash_key_destroy_func(gchar *key) +{ + g_return_if_fail(key!=NULL); + + g_free(key); +} + +static void uri_parent_string_hash_value_destroy_func(ntfs_volume *value) +{ + g_return_if_fail(value!=NULL); + + ntfs_umount( /* errors ignored */ + value, /* vol */ + TRUE); /* force; possibly loose modifications */ +} + +static void uri_parent_string_hash_init(void) +{ + G_LOCK(uri_parent_string_hash); + if (!uri_parent_string_hash) { + uri_parent_string_hash=g_hash_table_new_full( + g_str_hash, /* hash_func */ + g_str_equal, /* key_equal_func */ + (GDestroyNotify)uri_parent_string_hash_key_destroy_func, /* key_destroy_func */ + (GDestroyNotify)uri_parent_string_hash_value_destroy_func); /* value_destroy_func */ + } + G_UNLOCK(uri_parent_string_hash); +} + + +static GnomeVFSResult libntfs_gnomevfs_uri_parent_init(ntfs_volume **volume_return,GnomeVFSURI *uri) +{ +gchar *uri_parent_string; +gchar *uri_parent_string_parent; +ntfs_volume *volume; + + g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_INVALID_URI); + g_return_val_if_fail(volume_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + uri_parent_string_hash_init(); + + if (!uri->parent) + return GNOME_VFS_ERROR_INVALID_URI; + if (!uri->text) /* not needed here but we don't permit non-specific fs-image reference */ + return GNOME_VFS_ERROR_INVALID_URI; + uri_parent_string_parent=gnome_vfs_uri_to_string(uri->parent,GNOME_VFS_URI_HIDE_NONE); + g_assert(uri_parent_string_parent!=NULL); + + uri_parent_string=g_strdup_printf("%s:%s",uri->method_string,uri_parent_string_parent); + g_assert(uri_parent_string!=NULL); + + G_LOCK(uri_parent_string_hash); + volume=g_hash_table_lookup(uri_parent_string_hash,uri_parent_string); + G_UNLOCK(uri_parent_string_hash); + if (!volume) { +struct method_name_info *method_name_info; + + G_LOCK(method_name_hash); + method_name_info=g_hash_table_lookup(method_name_hash,uri->method_string); + G_UNLOCK(method_name_hash); + if (!method_name_info) + g_return_val_if_reached(GNOME_VFS_ERROR_INVALID_URI); /* should not happend */ + + if (strcmp(uri->parent->method_string,"file")) { /* TODO: Generic GnomeVFS filter. */ + g_free(uri_parent_string); + return GNOME_VFS_ERROR_INVALID_URI; + } + + if (!(volume=ntfs_mount(uri->parent->text,MS_RDONLY))) { + g_free(uri_parent_string); + return GNOME_VFS_ERROR_WRONG_FORMAT; + } + + G_LOCK(uri_parent_string_hash); + g_hash_table_insert(uri_parent_string_hash,g_strdup(uri_parent_string),volume); + G_UNLOCK(uri_parent_string_hash); + } + g_free(uri_parent_string); + + *volume_return=volume; + return GNOME_VFS_OK; +} + + +static GnomeVFSResult inode_open_by_pathname(ntfs_inode **inode_return,ntfs_volume *volume,const gchar *pathname) +{ +MFT_REF mref; +ntfs_inode *inode; +gchar *pathname_parse,*pathname_next; +int errint; + + g_return_val_if_fail(inode_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(volume!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(pathname!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + pathname=g_path_skip_root(pathname); + pathname_parse=g_alloca(strlen(pathname)+1); + strcpy(pathname_parse,pathname); + mref=FILE_root; + for (;;) { +uchar_t *pathname_parse_ucs2; +int i; + + G_LOCK(libntfs); + inode=ntfs_inode_open(volume,mref); + G_UNLOCK(libntfs); + if (!inode) + return GNOME_VFS_ERROR_NOT_FOUND; + if (!*pathname_parse) { + *inode_return=inode; + return GNOME_VFS_OK; + } + for (pathname_next=pathname_parse;*pathname_next && *pathname_next!=G_DIR_SEPARATOR;pathname_next++); + if (*pathname_next) + *pathname_next++='\0'; /* terminate current path element */ + while (*pathname_next==G_DIR_SEPARATOR) + pathname_next++; + /* FIXME: Is 'pathname' utf8? */ + libntfs_newn(pathname_parse_ucs2,strlen(pathname_parse)+1); + for (i=0;pathname_parse[i];i++) + pathname_parse_ucs2[i]=pathname_parse[i]; + pathname_parse_ucs2[i]=0; + G_LOCK(libntfs); + mref=ntfs_inode_lookup_by_name(inode,pathname_parse_ucs2,i); + G_UNLOCK(libntfs); + g_free(pathname_parse_ucs2); + if ((MFT_REF)-1==mref) + return GNOME_VFS_ERROR_NOT_FOUND; + G_LOCK(libntfs); + errint=ntfs_inode_close(inode); + G_UNLOCK(libntfs); + if (errint) + g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); + pathname_parse=pathname_next; + } + /* NOTREACHED */ +} + + +struct libntfs_directory { + ntfs_inode *inode; + GList *file_info_list; /* of (GnomeVFSFileInfo *); last item has ->data==NULL */ + }; + +static GnomeVFSResult libntfs_gnomevfs_open_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle,GnomeVFSURI *uri,GnomeVFSFileInfoOptions options,GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +ntfs_volume *volume; +ntfs_inode *inode; +struct libntfs_directory *libntfs_directory; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(method_handle!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri); + g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + + if (GNOME_VFS_OK!=(errvfsresult=inode_open_by_pathname(&inode,volume,uri->text))) + return errvfsresult; + + libntfs_new(libntfs_directory); + libntfs_directory->inode=inode; + libntfs_directory->file_info_list=NULL; + + *method_handle=(GnomeVFSMethodHandle *)libntfs_directory; + return errvfsresult; +} + + +static GnomeVFSResult libntfs_gnomevfs_close_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle,GnomeVFSContext *context) +{ +struct libntfs_directory *libntfs_directory; +int errint; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_directory=(struct libntfs_directory *)method_handle; + g_return_val_if_fail(libntfs_directory!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + G_LOCK(libntfs); + errint=ntfs_inode_close(libntfs_directory->inode); + G_UNLOCK(libntfs); + if (errint) + g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); + + gnome_vfs_file_info_list_free(libntfs_directory->file_info_list); + + g_free(libntfs_directory); + + return GNOME_VFS_OK; +} + + +static gchar *libntfs_uchar_to_utf8(const uchar_t *name,const int name_len) +{ +GString *gstring; +int i; + + gstring=g_string_sized_new(name_len); + for (i=0;i=0,-1); + g_return_val_if_fail(pos>=0,-1); + + file_info=gnome_vfs_file_info_new(); + file_info->name=libntfs_uchar_to_utf8(name,name_len); + file_info->valid_fields=0; + + switch (dt_type) { + case NTFS_DT_FIFO: file_info->type=GNOME_VFS_FILE_TYPE_FIFO; break; + case NTFS_DT_CHR: file_info->type=GNOME_VFS_FILE_TYPE_CHARACTER_DEVICE; break; + case NTFS_DT_DIR: file_info->type=GNOME_VFS_FILE_TYPE_DIRECTORY; break; + case NTFS_DT_BLK: file_info->type=GNOME_VFS_FILE_TYPE_BLOCK_DEVICE; break; + case NTFS_DT_REG: file_info->type=GNOME_VFS_FILE_TYPE_REGULAR; break; + case NTFS_DT_LNK: file_info->type=GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK; break; + case NTFS_DT_SOCK: file_info->type=GNOME_VFS_FILE_TYPE_SOCKET; break; + /* FIXME: What is 'NTFS_DT_WHT'? */ + default: file_info->type=GNOME_VFS_FILE_TYPE_UNKNOWN; + } + if (file_info->type!=GNOME_VFS_FILE_TYPE_UNKNOWN) + file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE; + + libntfs_directory->file_info_list=g_list_prepend(libntfs_directory->file_info_list,file_info); + + return 0; /* continue traversal */ +} + + +static GnomeVFSResult libntfs_gnomevfs_read_directory(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle,GnomeVFSFileInfo *file_info,GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +struct libntfs_directory *libntfs_directory; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_directory=(struct libntfs_directory *)method_handle; + g_return_val_if_fail(libntfs_directory!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (!libntfs_directory->file_info_list) { +int errint; +s64 pos; + + pos=0; /* read from the start; incl. "." and ".." entries */ + G_LOCK(libntfs); + errint=ntfs_readdir( + libntfs_directory->inode, /* dir_ni */ + &pos, /* pos */ + libntfs_directory, /* dirent */ + (ntfs_filldir_t)libntfs_gnomevfs_read_directory_filldir); /* filldir */ + G_UNLOCK(libntfs); + if (errint) + return GNOME_VFS_ERROR_INTERNAL; + + libntfs_directory->file_info_list=g_list_prepend(libntfs_directory->file_info_list,NULL); /* EOF */ + libntfs_directory->file_info_list=g_list_reverse(libntfs_directory->file_info_list); + } + + if (!libntfs_directory->file_info_list->data) { + g_assert(libntfs_directory->file_info_list->next==NULL); + errvfsresult=GNOME_VFS_ERROR_EOF; + } + else { + /* Cut first list item. */ + gnome_vfs_file_info_copy( + file_info, /* dest */ + libntfs_directory->file_info_list->data); /* src */ + gnome_vfs_file_info_unref(libntfs_directory->file_info_list->data); + errvfsresult=GNOME_VFS_OK; + } + libntfs_directory->file_info_list=g_list_delete_link( + libntfs_directory->file_info_list,libntfs_directory->file_info_list); + return errvfsresult; +} + + +struct libntfs_file { + ntfs_inode *inode; + ntfs_attr *attr; + s64 pos; + }; + +static GnomeVFSResult libntfs_open_attr(struct libntfs_file *libntfs_file) +{ + g_return_val_if_fail(libntfs_file!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(libntfs_file->inode!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (!libntfs_file->attr) { + G_LOCK(libntfs); + libntfs_file->attr=ntfs_attr_open( + libntfs_file->inode, /* ni */ + AT_DATA, /* type */ + NULL, /* name */ + 0); /* name_len */ + G_UNLOCK(libntfs); + if (!libntfs_file->attr) + return GNOME_VFS_ERROR_BAD_FILE; + libntfs_file->pos=0; + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult libntfs_gnomevfs_open(GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return,GnomeVFSURI *uri,GnomeVFSOpenMode mode,GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +ntfs_volume *volume; +ntfs_inode *inode; +struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(method_handle_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri); + g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + + if (mode & GNOME_VFS_OPEN_WRITE) + return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; + + if (GNOME_VFS_OK!=(errvfsresult=inode_open_by_pathname(&inode,volume,uri->text))) + return errvfsresult; + + libntfs_new(libntfs_file); + libntfs_file->inode=inode; + libntfs_file->attr=NULL; + + *method_handle_return=(GnomeVFSMethodHandle *)libntfs_file; + return errvfsresult; +} + + +static GnomeVFSResult libntfs_gnomevfs_create(GnomeVFSMethod *method, + GnomeVFSMethodHandle **method_handle_return,GnomeVFSURI *uri,GnomeVFSOpenMode mode,gboolean exclusive,guint perm, + GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +ntfs_volume *volume; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(method_handle_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume,uri); + g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + + return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM; +} + + +static GnomeVFSResult libntfs_gnomevfs_close(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle,GnomeVFSContext *context) +{ +struct libntfs_file *libntfs_file; +int errint; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file=(struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (libntfs_file->attr) { + G_LOCK(libntfs); + ntfs_attr_close(libntfs_file->attr); + G_UNLOCK(libntfs); + } + G_LOCK(libntfs); + errint=ntfs_inode_close(libntfs_file->inode); + G_UNLOCK(libntfs); + if (errint) + g_return_val_if_reached(GNOME_VFS_ERROR_INTERNAL); + + g_free(libntfs_file); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult libntfs_gnomevfs_read(GnomeVFSMethod *method,GnomeVFSMethodHandle *method_handle, + gpointer buffer,GnomeVFSFileSize num_bytes,GnomeVFSFileSize *bytes_read_return,GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +struct libntfs_file *libntfs_file; +s64 count_s64,got; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file=(struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(buffer!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(bytes_read_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK!=(errvfsresult=libntfs_open_attr(libntfs_file))) + return errvfsresult; + + count_s64=num_bytes; + g_assert((GnomeVFSFileSize)count_s64==num_bytes); + G_LOCK(libntfs); + got=ntfs_attr_pread(libntfs_file->attr,libntfs_file->pos,count_s64,buffer); + G_UNLOCK(libntfs); + if (got==-1) + return GNOME_VFS_ERROR_IO; + + libntfs_file->pos+=got; + *bytes_read_return=got; + g_assert((s64)*bytes_read_return==got); + + return GNOME_VFS_OK; +} + + +static GnomeVFSResult libntfs_gnomevfs_seek(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle,GnomeVFSSeekPosition whence,GnomeVFSFileOffset offset,GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file=(struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK!=(errvfsresult=libntfs_open_attr(libntfs_file))) + return errvfsresult; + + switch (whence) { + case GNOME_VFS_SEEK_START: + libntfs_file->pos=offset; + break; + case GNOME_VFS_SEEK_CURRENT: + libntfs_file->pos+=offset; + break; + case GNOME_VFS_SEEK_END: + g_return_val_if_reached(GNOME_VFS_ERROR_BAD_PARAMETERS); /* FIXME: NOT IMPLEMENTED YET */ + default: g_assert_not_reached(); + } + + return GNOME_VFS_OK; +} + +static GnomeVFSResult libntfs_gnomevfs_tell(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle,GnomeVFSFileOffset *offset_return) +{ +GnomeVFSResult errvfsresult; +struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file=(struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(offset_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + if (GNOME_VFS_OK!=(errvfsresult=libntfs_open_attr(libntfs_file))) + return errvfsresult; + + *offset_return=libntfs_file->pos; + g_assert(*offset_return==libntfs_file->pos); + + return errvfsresult; +} + + +static gboolean libntfs_gnomevfs_is_local(GnomeVFSMethod *method,const GnomeVFSURI *uri) +{ + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(uri!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + return gnome_vfs_uri_is_local(uri->parent); +} + + +GnomeVFSResult libntfs_gnomevfs_get_file_info_from_handle(GnomeVFSMethod *method, + GnomeVFSMethodHandle *method_handle,GnomeVFSFileInfo *file_info,GnomeVFSFileInfoOptions options,GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +struct libntfs_file *libntfs_file; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + libntfs_file=(struct libntfs_file *)method_handle; + g_return_val_if_fail(libntfs_file!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ + + if (GNOME_VFS_OK!=(errvfsresult=libntfs_open_attr(libntfs_file))) + return errvfsresult; + + file_info->valid_fields=0; + file_info->name=NULL; /* FIXME: It is complicated to read filename of open 'ntfs_inode'. */ + + file_info->size=libntfs_file->attr->data_size; /* FIXME: Is 'data_size' the right field? */ + file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_SIZE; + + /* FIXME: We do not really know the type of 'libntfs_file' + * but gnome-vfs-xfer.c/copy_items() requires 'GNOME_VFS_FILE_TYPE_REGULAR' + * to copy it. + */ + file_info->type=GNOME_VFS_FILE_TYPE_REGULAR; + /* Do not: file_info->valid_fields|=GNOME_VFS_FILE_INFO_FIELDS_TYPE; + * as gnome-vfs-xfer.c/copy_items() does not check 'GNOME_VFS_FILE_INFO_FIELDS_TYPE' + * and we are just bluffing we know it. + */ + + return errvfsresult; +} + + +static GnomeVFSResult libntfs_gnomevfs_get_file_info(GnomeVFSMethod *method, + GnomeVFSURI *uri,GnomeVFSFileInfo *file_info,GnomeVFSFileInfoOptions options,GnomeVFSContext *context) +{ +GnomeVFSResult errvfsresult; +GnomeVFSMethodHandle *method_handle; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(file_info!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + /* handle 'options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE'? */ + + if (GNOME_VFS_OK!=(errvfsresult=libntfs_gnomevfs_open(method,&method_handle,uri,GNOME_VFS_OPEN_READ,context))) + return errvfsresult; + if (GNOME_VFS_OK!=(errvfsresult=libntfs_gnomevfs_get_file_info_from_handle(method,method_handle,file_info,options,context))) + return errvfsresult; + if (GNOME_VFS_OK!=(errvfsresult=libntfs_gnomevfs_close(method,method_handle,context))) + return errvfsresult; + + return GNOME_VFS_OK; +} + + +GnomeVFSResult libntfs_gnomevfs_check_same_fs(GnomeVFSMethod *method, + GnomeVFSURI *a,GnomeVFSURI *b,gboolean *same_fs_return,GnomeVFSContext *context) +{ +ntfs_volume *volume_a; +ntfs_volume *volume_b; +GnomeVFSResult errvfsresult; + + g_return_val_if_fail(method==&GnomeVFSMethod_static,GNOME_VFS_ERROR_BAD_PARAMETERS); + g_return_val_if_fail(same_fs_return!=NULL,GNOME_VFS_ERROR_BAD_PARAMETERS); + + errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume_a,a); + g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + + errvfsresult=libntfs_gnomevfs_uri_parent_init(&volume_b,b); + g_return_val_if_fail(errvfsresult==GNOME_VFS_OK,errvfsresult); + + *same_fs_return=(volume_a==volume_b); + + return GNOME_VFS_OK; +} + + +/** + * libntfs_gnomevfs_init: + * + * Returns: Initialized structure of #GnomeVFSMethod with static methods of libntfs-gnomevfs. + */ +GnomeVFSMethod *libntfs_gnomevfs_method_init(const gchar *method_name,const gchar *args) +{ +struct method_name_info *method_name_info; + + g_return_val_if_fail(method_name!=NULL,NULL); + /* 'args' may be NULL if not supplied. */ + + method_name_hash_init(); + + G_LOCK(method_name_hash); + method_name_info=g_hash_table_lookup(method_name_hash,method_name); + if (method_name_info && strcmp(method_name_info->args,args)) + method_name_info=NULL; + G_UNLOCK(method_name_hash); + if (!method_name_info) { + libntfs_new(method_name_info); + method_name_info->args=g_strdup(args); + G_LOCK(method_name_hash); + g_hash_table_replace(method_name_hash,g_strdup(method_name),method_name_info); + G_UNLOCK(method_name_hash); + } + + G_LOCK(GnomeVFSMethod_static); + LIBNTFS_MEMZERO(&GnomeVFSMethod_static); + GnomeVFSMethod_static.method_table_size=sizeof(GnomeVFSMethod_static); + GnomeVFSMethod_static.open =libntfs_gnomevfs_open; /* mandatory */ + GnomeVFSMethod_static.create =libntfs_gnomevfs_create; /* mandatory */ + GnomeVFSMethod_static.close =libntfs_gnomevfs_close; + GnomeVFSMethod_static.read =libntfs_gnomevfs_read; + GnomeVFSMethod_static.seek =libntfs_gnomevfs_seek; + GnomeVFSMethod_static.tell =libntfs_gnomevfs_tell; + GnomeVFSMethod_static.open_directory =libntfs_gnomevfs_open_directory; + GnomeVFSMethod_static.close_directory =libntfs_gnomevfs_close_directory; + GnomeVFSMethod_static.read_directory =libntfs_gnomevfs_read_directory; + GnomeVFSMethod_static.get_file_info =libntfs_gnomevfs_get_file_info; /* mandatory */ + GnomeVFSMethod_static.get_file_info_from_handle=libntfs_gnomevfs_get_file_info_from_handle; + GnomeVFSMethod_static.is_local =libntfs_gnomevfs_is_local; /* mandatory */ + GnomeVFSMethod_static.check_same_fs =libntfs_gnomevfs_check_same_fs; + /* TODO: GnomeVFSMethodFindDirectoryFunc find_directory; */ + /* TODO: GnomeVFSMethodFileControlFunc file_control; */ + /* R/W: GnomeVFSMethodCreateSymbolicLinkFunc create_symbolic_link; */ + /* R/W: GnomeVFSMethodMonitorAddFunc monitor_add; */ + /* R/W: GnomeVFSMethodMonitorCancelFunc monitor_cancel; */ + /* R/W: GnomeVFSMethod_static.write; */ + /* R/W: GnomeVFSMethod_static.truncate_handle; */ + /* R/W: GnomeVFSMethod_static.make_directory; */ + /* R/W: GnomeVFSMethod_static.remove_directory; */ + /* R/W: GnomeVFSMethod_static.move; */ + /* R/W: GnomeVFSMethod_static.unlink; */ + /* R/W: GnomeVFSMethod_static.set_file_info; */ + /* R/W: GnomeVFSMethod_static.truncate; */ + G_UNLOCK(GnomeVFSMethod_static); + + return &GnomeVFSMethod_static; +} + + +/** + * libntfs_gnomevfs_method_shutdown: + * + * Shutdowns libntfs-gnomevfs successfuly flushing all caches. + * + * Sad note about gnome-vfs-2.1.5 is that it never calls this function. :-) + */ +void libntfs_gnomevfs_method_shutdown(void) +{ + uri_parent_string_hash_init(); + G_LOCK(uri_parent_string_hash); + g_hash_table_destroy(uri_parent_string_hash); + uri_parent_string_hash=NULL; + G_UNLOCK(uri_parent_string_hash); + + method_name_hash_init(); + G_LOCK(method_name_hash); + g_hash_table_destroy(method_name_hash); + method_name_hash=NULL; + G_UNLOCK(method_name_hash); +} diff --git a/src/gnome-vfs-method.h b/src/gnome-vfs-method.h new file mode 100644 index 0000000..5a895f1 --- /dev/null +++ b/src/gnome-vfs-method.h @@ -0,0 +1,35 @@ +/* $Id$ + * gnome-vfs init/shutdown implementation of interface to libntfs + * Copyright (C) 2002-2003 Jan Kratochvil + * + * This program 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; exactly version 2 of June 1991 is required + * + * This program 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _LIBNTFS_GNOMEVFS_GNOME_VFS_METHOD_H +#define _LIBNTFS_GNOMEVFS_GNOME_VFS_METHOD_H 1 + + +#include + + +G_BEGIN_DECLS + +GnomeVFSMethod *libntfs_gnomevfs_method_init(const gchar *method_name,const gchar *args); +void libntfs_gnomevfs_method_shutdown(void); + +G_END_DECLS + + +#endif /* _LIBNTFS_GNOMEVFS_GNOME_VFS_METHOD_H */ diff --git a/src/gnome-vfs-module.c b/src/gnome-vfs-module.c new file mode 100644 index 0000000..d484249 --- /dev/null +++ b/src/gnome-vfs-module.c @@ -0,0 +1,75 @@ +/* $Id$ + * gnome-vfs init/shutdown implementation of interface to libntfs + * Copyright (C) 2003 Jan Kratochvil + * + * This program 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; exactly version 2 of June 1991 is required + * + * This program 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#include "config.h" + +#include "gnome-vfs-method.h" +#include +#include +#include /* for g_atexit() */ + + +/* filesystem-module-scope lock for _any_ libntfs access */ +G_LOCK_DEFINE(libntfs); + + +static void vfs_module_shutdown_atexit(void); + + +/** + * vfs_module_init: + * @method_name: FIXME + * @args: FIXME + * + * FIXME + * + * Returns: FIXME + */ +GnomeVFSMethod *vfs_module_init(const char *method_name,const char *args) +{ +GnomeVFSMethod *libntfs_gnomevfs_method_ptr; + + g_return_val_if_fail(method_name!=NULL,NULL); + /* 'args' may be NULL if not supplied. */ + + libntfs_gnomevfs_method_ptr=libntfs_gnomevfs_method_init( + method_name, /* method_name */ + args); /* args */ + + g_atexit(vfs_module_shutdown_atexit); + + return libntfs_gnomevfs_method_ptr; +} + + +/** + * vfs_module_shutdown: + */ +void vfs_module_shutdown(GnomeVFSMethod *method) +{ + /* 'method' may be NULL iff we are called from vfs_module_shutdown_atexit() */ + + libntfs_gnomevfs_method_shutdown(); +} + + +static void vfs_module_shutdown_atexit(void) +{ + vfs_module_shutdown(NULL); +} diff --git a/src/gnome-vfs-module.h b/src/gnome-vfs-module.h new file mode 100644 index 0000000..b24a9aa --- /dev/null +++ b/src/gnome-vfs-module.h @@ -0,0 +1,35 @@ +/* $Id$ + * gnome-vfs init/shutdown implementation of interface to libntfs + * Copyright (C) 2003 Jan Kratochvil + * + * This program 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; exactly version 2 of June 1991 is required + * + * This program 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, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + + +#ifndef _LIBNTFS_GNOMEVFS_GNOME_VFS_MODULE_H +#define _LIBNTFS_GNOMEVFS_GNOME_VFS_MODULE_H 1 + + +G_BEGIN_DECLS + +G_LOCK_EXTERN(libntfs); + +#define libntfs_newn(objp,n) ((objp)=g_new(typeof(*(objp)),(n))) +#define libntfs_new(objp) (libntfs_newn((objp),1)) +#define LIBNTFS_MEMZERO(objp) (memset((objp),0,sizeof(*(objp)))) + +G_END_DECLS + + +#endif /* _LIBNTFS_GNOMEVFS_GNOME_VFS_MODULE_H */ diff --git a/src/libntfs.conf.in b/src/libntfs.conf.in new file mode 100644 index 0000000..7336ce0 --- /dev/null +++ b/src/libntfs.conf.in @@ -0,0 +1 @@ +libntfs: liblibntfs -- 1.8.3.1