summaryrefslogtreecommitdiff
path: root/libxdg-vfs-client
diff options
context:
space:
mode:
Diffstat (limited to 'libxdg-vfs-client')
-rw-r--r--libxdg-vfs-client/.cvsignore27
-rw-r--r--libxdg-vfs-client/AUTHORS1
-rw-r--r--libxdg-vfs-client/COPYING18
-rw-r--r--libxdg-vfs-client/ChangeLog7
-rw-r--r--libxdg-vfs-client/INSTALL236
-rw-r--r--libxdg-vfs-client/Makefile.am1
-rw-r--r--libxdg-vfs-client/Makefile.cvs6
-rw-r--r--libxdg-vfs-client/NEWS1
-rw-r--r--libxdg-vfs-client/README8
-rw-r--r--libxdg-vfs-client/configure.ac28
-rw-r--r--libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-gnome.pngbin0 -> 63444 bytes
-rw-r--r--libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-kde.pngbin0 -> 64288 bytes
-rw-r--r--libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-root.pngbin0 -> 65306 bytes
-rw-r--r--libxdg-vfs-client/doc/libxdg-vfs.html208
-rw-r--r--libxdg-vfs-client/src/.cvsignore8
-rw-r--r--libxdg-vfs-client/src/Makefile.am12
-rw-r--r--libxdg-vfs-client/src/xdg_vfs_client.c1252
-rw-r--r--libxdg-vfs-client/src/xdg_vfs_client.h491
-rw-r--r--libxdg-vfs-client/src/xdg_vfs_common.h146
-rw-r--r--libxdg-vfs-client/src/xdg_vfs_errstrs.c137
-rw-r--r--libxdg-vfs-client/src/xdg_vfs_forkexec.c100
-rw-r--r--libxdg-vfs-client/src/xdg_vfs_forkexec.h40
-rw-r--r--libxdg-vfs-client/tests/.cvsignore8
-rw-r--r--libxdg-vfs-client/tests/Makefile.am28
-rw-r--r--libxdg-vfs-client/tests/sample1_multi.c316
-rw-r--r--libxdg-vfs-client/tests/sample2_getfile.c106
-rw-r--r--libxdg-vfs-client/tests/sample3_putfile.c117
-rw-r--r--libxdg-vfs-client/tests/sample4_copy.c102
-rw-r--r--libxdg-vfs-client/tests/sample5_mount.c95
-rw-r--r--libxdg-vfs-client/tests/sample6_monitor.c105
-rw-r--r--libxdg-vfs-client/tests/test1.c63
31 files changed, 3667 insertions, 0 deletions
diff --git a/libxdg-vfs-client/.cvsignore b/libxdg-vfs-client/.cvsignore
new file mode 100644
index 0000000..6d3654f
--- /dev/null
+++ b/libxdg-vfs-client/.cvsignore
@@ -0,0 +1,27 @@
+*.la
+*.lo
+*.o
+ABOUT-NLS
+Makefile
+Makefile.in
+aclocal.m4
+autom4te.cache
+config.cache
+config.h
+config.h.in
+config.log
+config.status
+configure
+libtool
+config.guess
+config.sub
+depcomp
+install-sh
+ltmain.sh
+missing
+stamp-h1
+.libs
+.deps
+.cdtproject
+.project
+
diff --git a/libxdg-vfs-client/AUTHORS b/libxdg-vfs-client/AUTHORS
new file mode 100644
index 0000000..d76f6e9
--- /dev/null
+++ b/libxdg-vfs-client/AUTHORS
@@ -0,0 +1 @@
+Norbert Frese (nf2@scheinwelt.at) 2006
diff --git a/libxdg-vfs-client/COPYING b/libxdg-vfs-client/COPYING
new file mode 100644
index 0000000..1edf08c
--- /dev/null
+++ b/libxdg-vfs-client/COPYING
@@ -0,0 +1,18 @@
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
diff --git a/libxdg-vfs-client/ChangeLog b/libxdg-vfs-client/ChangeLog
new file mode 100644
index 0000000..ede0d5c
--- /dev/null
+++ b/libxdg-vfs-client/ChangeLog
@@ -0,0 +1,7 @@
+2005-11-21 gettextize <bug-gnu-gettext@gnu.org>
+
+ * Makefile.am (SUBDIRS): Add po.
+ (ACLOCAL_AMFLAGS): New variable.
+ (EXTRA_DIST): New variable.
+ * configure.ac (AC_OUTPUT): Add po/Makefile.in.
+
diff --git a/libxdg-vfs-client/INSTALL b/libxdg-vfs-client/INSTALL
new file mode 100644
index 0000000..23e5f25
--- /dev/null
+++ b/libxdg-vfs-client/INSTALL
@@ -0,0 +1,236 @@
+Installation Instructions
+*************************
+
+Copyright (C) 1994, 1995, 1996, 1999, 2000, 2001, 2002, 2004, 2005 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' installs the package's commands under
+`/usr/local/bin', include files under `/usr/local/include', etc. You
+can specify an installation prefix other than `/usr/local' by giving
+`configure' the option `--prefix=PREFIX'.
+
+ You can specify separate installation prefixes for
+architecture-specific files and architecture-independent files. If you
+pass the option `--exec-prefix=PREFIX' to `configure', the package uses
+PREFIX as the prefix for installing programs and libraries.
+Documentation and other data files still use the regular prefix.
+
+ In addition, if you use an unusual directory layout you can give
+options like `--bindir=DIR' 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 option `--target=TYPE' 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
+
+causes the specified `gcc' to be used as the C compiler (unless it is
+overridden in the site shell script). Here is a another example:
+
+ /bin/bash ./configure CONFIG_SHELL=/bin/bash
+
+Here the `CONFIG_SHELL=/bin/bash' operand causes subsequent
+configuration-related scripts to be executed by `/bin/bash'.
+
+`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/libxdg-vfs-client/Makefile.am b/libxdg-vfs-client/Makefile.am
new file mode 100644
index 0000000..a459377
--- /dev/null
+++ b/libxdg-vfs-client/Makefile.am
@@ -0,0 +1 @@
+SUBDIRS = src tests
diff --git a/libxdg-vfs-client/Makefile.cvs b/libxdg-vfs-client/Makefile.cvs
new file mode 100644
index 0000000..1e17bc9
--- /dev/null
+++ b/libxdg-vfs-client/Makefile.cvs
@@ -0,0 +1,6 @@
+all:
+ @libtoolize
+ @aclocal
+ @autoheader
+ @automake --add-missing
+ @autoconf
diff --git a/libxdg-vfs-client/NEWS b/libxdg-vfs-client/NEWS
new file mode 100644
index 0000000..4af1832
--- /dev/null
+++ b/libxdg-vfs-client/NEWS
@@ -0,0 +1 @@
+None \ No newline at end of file
diff --git a/libxdg-vfs-client/README b/libxdg-vfs-client/README
new file mode 100644
index 0000000..09fe2be
--- /dev/null
+++ b/libxdg-vfs-client/README
@@ -0,0 +1,8 @@
+libxdg-vfs-client
+=================
+
+C-client library for xdg-vfs
+
+
+(for examples see the 'tests'-directory)
+
diff --git a/libxdg-vfs-client/configure.ac b/libxdg-vfs-client/configure.ac
new file mode 100644
index 0000000..ac6d1e1
--- /dev/null
+++ b/libxdg-vfs-client/configure.ac
@@ -0,0 +1,28 @@
+dnl Process this file with autoconf to produce a configure script.
+
+dnl AC_INIT(src/main.c)
+AC_INIT(src/xdg_vfs_client.c)
+dnl AM_CONFIG_HEADER(config.h)
+
+PACKAGE=libxdg-vfs-client
+VERSION=0.1.8
+
+AM_INIT_AUTOMAKE($PACKAGE,$VERSION)
+
+AC_PROG_CC
+AC_STDC_HEADERS
+AC_PROG_INSTALL
+
+AC_ENABLE_SHARED(yes)
+AC_PROG_LIBTOOL
+
+dnl PKG_CHECK_MODULES(DEPS, glib-2.0 >= 2.0)
+
+AC_SUBST(DEPS_CFLAGS)
+AC_SUBST(DEPS_LIBS)
+
+AC_OUTPUT([
+Makefile
+src/Makefile
+tests/Makefile
+])
diff --git a/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-gnome.png b/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-gnome.png
new file mode 100644
index 0000000..fc95061
--- /dev/null
+++ b/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-gnome.png
Binary files differ
diff --git a/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-kde.png b/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-kde.png
new file mode 100644
index 0000000..580a99a
--- /dev/null
+++ b/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-kde.png
Binary files differ
diff --git a/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-root.png b/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-root.png
new file mode 100644
index 0000000..0f4da0e
--- /dev/null
+++ b/libxdg-vfs-client/doc/imgs/libxdg-vfs-demo-filebrowser-root.png
Binary files differ
diff --git a/libxdg-vfs-client/doc/libxdg-vfs.html b/libxdg-vfs-client/doc/libxdg-vfs.html
new file mode 100644
index 0000000..b0ba724
--- /dev/null
+++ b/libxdg-vfs-client/doc/libxdg-vfs.html
@@ -0,0 +1,208 @@
+<html>
+ <head>
+ <title>libxdg-vfs</title>
+ </head>
+ <body>
+ <h1>libxdg-vfs</h1>
+ <p><em>libxdg-vfs</em> provides a generic API to the Virtual-File-System libraries KIO and Gnome-VFS.
+ It supports the commands
+ <ul>
+ <li><em>backend</em> (obtain backend information)</li>
+ <li><em>get</em> (read file)</li>
+ <li><em>put</em> (write file)</li>
+ <li><em>cp</em> (copy file)</li>
+ <li><em>mv</em> (move file)</li>
+ <li><em>rm</em> (erase file)</li>
+ <li><em>mkdir</em> (create folder)</li>
+ <li><em>rmdir</em> (delete folder)</li>
+ <li><em>info</em> (get file-info)</li>
+ <li><em>setattrs</em> (set file attributes)</li>
+ <li><em>ls</em> (list directory)</li>
+ <li><em>openfildlg</em> (show open-file-dialog)</li>
+ <li><em>savefildlg</em> (show save-file-dialog)</li>
+ </ul>
+ </p>
+ <p>It is designed to work in synchronous as well as asynchronous context.</p>
+ <h2>Backends</h2>
+ <p>The backend executables (xdg_vfs_kde or xdg_vfs_gnome) are forked as child process and
+ the communication goes through the stdin/stdout pipes of the child-process (the <em>shell</em>-mode of the backend executables is used). The backends are in the separate packages xdg-vfs-kde.tar.gz and xdg-vfs-gnome.tar.gz.</p>
+ <h2>Sessions</h2>
+ <p>To open a session call the function:</p>
+<code>
+XdgVfsResult xdg_vfs_sess_start(XdgVfsSession ** session, char * preferredDesktop);
+</code>
+ <p>The library will launch the child-process and return a session pointer. Use "this" (or NULL) - to
+ autodetect the current desktop - or "kde" / "gnome" for the <em>preferredDesktop</em> argument.
+ </p>
+ <h2>Running Commands</h2>
+ <p>A session can run a sequence of VFS commands. Because the backends are single-threaded and synchronous
+ you can only run one command after the other in a session (for parallel commands open a second session).
+ Here are some examples:
+ </p>
+ <h3>Copying a file</h3>
+ <p>Let's see how a copying a file is done:</p>
+<code>
+XdgVfsResult r = xdg_vfs_sess_cmd_copyFile(session, "protocol://user@server/srcfile", "protocol://user@server/targetfile");
+</code>
+ <p>After calling this function you have to read the response items until you get a return value different from
+ XDGVFS_RESULT_CONTINUES. Internally the 'readItem' function has only a single 'read(incoming_fd)' call per
+ iteration. This is to prevent blocking in an async application
+ (you have to watch for read-events on the fd returned by xdg_vfs_sess_getIncomingFiledescriptor())
+ </p>
+<pre>
+XdgVfsResult r;
+XdgVfsItemType type;
+XdgVfsItem * item;
+
+while ((r = xdg_vfs_sess_readItem(session, &type, &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+{
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_COPY_HEAD:
+ {
+ XdgVfsCopyHead * head = (XdgVfsCopyHead*) item;
+ fprintf(stderr, "copying uri_src='%s' to uri_target='%s'\n",
+ head->uri_src, head->uri_target);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_PROGRESS:
+ {
+ XdgVfsProgress * progress = (XdgVfsProgress *) item;
+ fprintf(stderr, "progress: copied=%d size=%d\n", progress->copied, progress->size);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break; /* no complete item -> continue */
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+}
+if (r) { /* command failed */ }
+</pre>
+ <h3>Reading a file</h3>
+ <p>When reading a file you will receive information items and data chunks.</p>
+<pre>
+XdgVfsResult r;
+r = xdg_vfs_sess_cmd_getFile(session, "protocol://user@server/file");
+if (r) { /* command init error */ }
+
+char * buf=NULL;
+int len=0;
+XdgVfsItemType type;
+XdgVfsItem * item;
+
+while ((r = xdg_vfs_sess_readItem(session, &type, &item, &buf, &len)) == XDGVFS_RESULT_CONTINUES)
+{
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_GET_HEAD:
+ {
+ XdgVfsSimpleHead * head = (XdgVfsSimpleHead*) item;
+ fprintf(stderr, "reading file uri='%s'\n", head->uri);
+ break;
+ }
+ case XDGVFS_DATAIN:
+ {
+ fprintf(stderr, "file-data chunklen=%d\n", len);
+ fwrite (buf, 1, len, stdout); /* your file data */
+ break;
+ }
+ case XDGVFS_ITEMTYPE_DATAIN_DONE:
+ {
+ XdgVfsDataInDoneItem * dii = (XdgVfsDataInDoneItem *) item;
+ fprintf(stderr, "read done - bytecount='%d'\n", dii->bytecount);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+}
+if (r) { /* command failed */ }
+</pre>
+ <h3>Opening a file-dialog</h3>
+<pre>
+XdgVfsResult r;
+r = xdg_vfs_sess_cmd_openFileDialog(session, "protocol://user@server/directory", 0);
+if (r) { /* command init error */ }
+
+while ((r = xdg_vfs_sess_readItem(session, &type, &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+{
+ switch(type)
+ {
+ case XDGVFS_ITEMTYPE_OPENFILEDLG_RESPONSE:
+ {
+ XdgVfsOpenFileDlgResponse * dlgResp = (XdgVfsOpenFileDlgResponse*) item;
+ fprintf(stderr, "selected_uri='%s'\n", dlgResp->selected_uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+}
+if (r) { /* command failed */ }
+</pre>
+<h3>Other Commands</h3>
+<p>For the other commands see the samples in the 'tests' directory of the tarball.
+Also have a look at <em>xdg_vfs_client.h</em> and <em>xdg_vfs_common.h</em> (list of result codes).
+<h2>Async Applications</h2>
+<p>Check the filedescriptor of the sessions incoming pipe in your event loop before calling</p>
+<code>
+XdgVfsResult xdg_vfs_sess_readItem(XdgVfsSession * sess, XdgVfsItemType * typeOut,
+ XdgVfsItem ** itemOut, char ** buffer, int * len);
+</code>
+<p>and the outgoing pipes filedescriptor before calling</p>
+<code>
+XdgVfsResult xdg_vfs_sess_sendData(XdgVfsSession * sess);
+</code>
+<p>(only required when writing a file).</p>
+<h2>VFS browser demo</h2>
+<p>Libxdg-vfs-demo-filebrowser is a simple file-system-browser (written in Gtk+) which uses libxdg-vfs.
+I'm trying to find out whether libxdg-vfs could be used as backend for file-choosers (like GtkFileChooser) - especially in cases
+where you need to customize file-dialogs and the simple Open/Save file-dialogs provided by libxdg-vfs won't
+suffice.</p>
+<p><em>Root URI of the VFS-backend:</em></p>
+<p><code>XdgVfsBackendInfo</code> has a field called <code>system_uri</code>
+which points to the virtual root folder (often listed in side-panes of file-dialogs) of the VFS backend.
+Like <em>system:/</em> on KDE or <em>computer://</em> on Gnome.
+</p>
+<p><em>Icons and Icon-themes:</em></p>
+<p><code>XdgVfsBackendInfo</code> has a field called <code>file_icon_theme</code> (which is 'crystalsvg' on KDE and 'gnome' on Gnome).
+The <code>XdgVfsFileInfo</code> structure (returned when listing directories) has an <code>iconname</code> field.
+With this information we can look up the right file-icons, without even knowing which backend is running.
+</p>
+<p>Screenshot: VFS browser using KIO and Gnome-VFS backend (pointing to root folder of the VFS):</p>
+<p><img src="imgs/libxdg-vfs-demo-filebrowser-root.png"></p>
+<p>Screenshot: VFS browser using the Gnome-VFS backend:</p>
+<p><img src="imgs/libxdg-vfs-demo-filebrowser-gnome.png"></p>
+<p>Screenshot: VFS browser using the KIO backend:</p>
+<p><img src="imgs/libxdg-vfs-demo-filebrowser-kde.png"></p>
+
+<h2>Sources/Docs</h2>
+<p>Downloads: <a href="http://www.scheinwelt.at/~norbertf/dadapt/files/xdg_utils/">http://www.scheinwelt.at/~norbertf/dadapt/files/xdg_utils/</a></p>
+<p>Backend manual: <a href="http://www.scheinwelt.at/~norbertf/dadapt/files/xdg_utils/doc/xdg-vfs.html">http://www.scheinwelt.at/~norbertf/dadapt/files/xdg_utils/doc/xdg-vfs.html</a></p>
+<p>Portland VFS task: <a href="http://portland.freedesktop.org/wiki/TaskVFS">http://portland.freedesktop.org/wiki/TaskVFS</a></p>
+<p>___ n.f. 2006 ___</p>
+ </body>
+</html>
diff --git a/libxdg-vfs-client/src/.cvsignore b/libxdg-vfs-client/src/.cvsignore
new file mode 100644
index 0000000..26a73db
--- /dev/null
+++ b/libxdg-vfs-client/src/.cvsignore
@@ -0,0 +1,8 @@
+*.la
+*.lo
+*.o
+.deps
+.libs
+Makefile
+Makefile.in
+
diff --git a/libxdg-vfs-client/src/Makefile.am b/libxdg-vfs-client/src/Makefile.am
new file mode 100644
index 0000000..b6494a9
--- /dev/null
+++ b/libxdg-vfs-client/src/Makefile.am
@@ -0,0 +1,12 @@
+
+AM_CPPFLAGS = $(DEPS_CFLAGS)
+
+lib_LTLIBRARIES = libxdg_vfs_client.la
+
+libxdg_vfs_client_la_SOURCES = xdg_vfs_client.c xdg_vfs_forkexec.c xdg_vfs_errstrs.c
+libxdg_vfs_client_la_LIBADD = $(DEPS_LIBS)
+libxdg_vfs_client_la_LDFLAGS = $(all_libraries)
+
+libxdg_vfs_clientincludedir = $(includedir)
+libxdg_vfs_clientinclude_HEADERS = xdg_vfs_client.h xdg_vfs_common.h
+noinst_HEADERS = xdg_vfs_forkexec.h
diff --git a/libxdg-vfs-client/src/xdg_vfs_client.c b/libxdg-vfs-client/src/xdg_vfs_client.c
new file mode 100644
index 0000000..14730a8
--- /dev/null
+++ b/libxdg-vfs-client/src/xdg_vfs_client.c
@@ -0,0 +1,1252 @@
+/*
+# xdg_vfs_client.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include "xdg_vfs_client.h"
+#include "xdg_vfs_common.h"
+
+/* ==== utils ==== */
+
+static XdgVfsFileType _translate_filetype(char * filetype) {
+ if (strcmp (filetype, "UNKNOWN")==0)
+ return XDGVFS_FILE_TYPE_UNKNOWN;
+ if (strcmp (filetype, "REGULAR")==0)
+ return XDGVFS_FILE_TYPE_REGULAR;
+ if (strcmp (filetype, "DIRECTORY")==0)
+ return XDGVFS_FILE_TYPE_DIRECTORY;
+ if (strcmp (filetype, "FIFO")==0)
+ return XDGVFS_FILE_TYPE_FIFO;
+ if (strcmp (filetype, "SOCKET")==0)
+ return XDGVFS_FILE_TYPE_SOCKET;
+ if (strcmp (filetype, "CHARDEV")==0)
+ return XDGVFS_FILE_TYPE_CHARDEV;
+ if (strcmp (filetype, "BLOCKDEV")==0)
+ return XDGVFS_FILE_TYPE_BLOCKDEV;
+ if (strcmp (filetype, "SYMLINK")==0)
+ return XDGVFS_FILE_TYPE_SYMLINK;
+ if (strcmp (filetype, "VFSMOUNTPOINT")==0)
+ return XDGVFS_FILE_TYPE_VFSMOUNTPOINT;
+ return XDGVFS_FILE_TYPE_UNREC;
+};
+
+
+static int parse_pair(char * theLine, char ** keyName, char ** valueStr, long long int * valueLLInt) {
+ char * pValue = NULL;
+ char * tailptr;
+
+
+ *keyName = theLine;
+ *valueStr = NULL;
+ *valueLLInt = -1;
+ if (!theLine) return -1; //error
+
+ if (*theLine) {
+ int c=0;
+ while (theLine[c] != '\0') {
+ if (theLine[c] == '=') {
+ theLine[c] = '\0';
+ pValue = theLine +c +1;
+ }
+
+ c++;
+ }
+ }
+ if (!pValue) return -2;
+ *valueStr = pValue;
+ errno = 0;
+ *valueLLInt = strtoll (pValue, &tailptr, 10);
+ if (errno) {
+ *valueLLInt =0;
+ return 2;
+ }
+ return 1;
+}
+
+static int _parse_failure(char * failureStr, char ** errstr) {
+ char * pValue = failureStr + strlen(XDGVFS_TAG_FAILED);
+ char * tailptr;
+ errno = 0;
+ int errcode = strtol (pValue, &tailptr, 10);
+
+ if (errno) {
+ *errstr = NULL;
+ return -1;
+ }
+ // fprintf(stderr, "errorcode = %d\n", errcode);
+ *errstr=tailptr;
+ return errcode;
+}
+
+static void _init_job(XdgVfsSession * sess) {
+
+ sess->currentItemType = 0;
+ sess->currentItem = NULL;
+ sess->lastJobErrorCode = 0;
+ sess->lastJobErrorText = NULL;
+
+ sess->outBuf_used = 0;
+
+}
+
+static XdgVfsResult _finish_simple_job(XdgVfsSession * sess)
+{
+ XdgVfsResult r;
+ XdgVfsItemType type=0;
+ XdgVfsItem * item=NULL;
+
+ while ((r=xdg_vfs_sess_readItem(sess, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ // if (XDG_VFS_DEBUG_IPC) fprintf(stderr, "_finish simple job\n");
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "simple job - unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ return r;
+}
+
+/* =============== sessions =============== */
+
+static char * _detect_desktop() {
+ char * e;
+ e = getenv ("GNOME_DESKTOP_SESSION_ID");
+ if (e && strcmp(e, "") != 0) return "gnome";
+ e = getenv ("KDE_FULL_SESSION");
+ if (e && strcmp(e, "true") == 0) return "kde";
+ return NULL;
+}
+
+
+XdgVfsResult xdg_vfs_sess_start(XdgVfsSession ** sessOut, char * preferredDesktop) {
+ int r;
+ char * desktop;
+ char * exePrefix = "xdg_vfs_";
+ char * childArgv[] = { "xdg_vfs_client", "shell", NULL };
+
+ if (preferredDesktop && strcmp(preferredDesktop, "this") != 0)
+ desktop = preferredDesktop;
+ else
+ desktop = _detect_desktop();
+
+ if (!desktop)
+ return XDGVFS_RESULT_CANNOT_LAUNCH_BACKEND;
+
+ XdgVfsSession * newSess = malloc(sizeof(XdgVfsSession));
+
+ char executableName[strlen(exePrefix) + strlen(preferredDesktop) + 1];
+ executableName[0] = '\0';
+
+ strcat(executableName, exePrefix);
+ strcat(executableName, desktop);
+
+ //puts(executableName);
+
+ r = xdg_vfs_forkexec(executableName, childArgv, &newSess->pid, &newSess->fd_out, &newSess->fd_in);
+
+ if (r) {
+ free(newSess);
+ *sessOut = NULL;
+ return XDGVFS_RESULT_IOERR;
+ }
+ newSess->inBuf = malloc(XDGVFS_CLIENT_BUFFERSIZE+1);
+ newSess->rawBufIn = malloc(XDGVFS_CLIENT_BUFFERSIZE+1);
+ newSess->inBuf_size = XDGVFS_CLIENT_BUFFERSIZE;
+ newSess->inBuf_used = 0;
+ _init_job(newSess);
+ newSess->stateIn = XDGVFS_STATE_EXPECTING_PROMPT;
+ newSess->recurse_count = 0;
+
+ while (1) {
+ r = xdg_vfs_sess_readItem(newSess, NULL,
+ NULL, NULL, NULL);
+ /* fprintf(stderr, "readItem r=%d state=%d\n", r, newSess->stateIn); */
+
+ if (newSess->stateIn == XDGVFS_STATE_READY) break;
+ if (r!=XDGVFS_RESULT_CONTINUES) {
+ xdg_vfs_sess_close(newSess);
+ return XDGVFS_RESULT_CANNOT_LAUNCH_BACKEND;
+ }
+ }
+
+ *sessOut = newSess;
+
+ return XDGVFS_RESULT_OK;
+}
+
+int xdg_vfs_sess_getIncomingFiledescriptor(XdgVfsSession * sess)
+{
+ return sess->fd_in;
+}
+
+int xdg_vfs_sess_getOutgoingFiledescriptor(XdgVfsSession * sess)
+{
+ return sess->fd_out;
+}
+
+int xdg_vfs_sess_isBusy(XdgVfsSession * sess)
+{
+ return sess->stateIn != XDGVFS_STATE_READY;
+}
+
+
+XdgVfsResult xdg_vfs_sess_close(XdgVfsSession * sess) {
+ if (!sess) {
+ fprintf(stderr, "NULL pointer passed to xdg_vfs_sess_close!\n");
+ return XDGVFS_ERRORCODE_GENERIC;
+ }
+ close(sess->fd_out);
+ close(sess->fd_in);
+ free(sess->inBuf);
+ free(sess);
+ return XDGVFS_RESULT_OK;
+}
+
+/* ================ file/dir change monitoring ============ */
+
+void xdg_vfs_sess_set_monitor_callback(
+ XdgVfsSession * sess,
+ XdgVfsMonitorCallback cb,
+ void * userdata
+ )
+{
+ sess->monitor_cb = cb;
+ sess->monitor_cb_userdata=userdata;
+}
+
+/* ================ items ================= */
+
+XdgVfsItem * xdg_vfs_item_ref(XdgVfsItem * item) {
+ item->refcount++;
+ return item;
+}
+
+void xdg_vfs_item_unref(XdgVfsItem * item) {
+ if (item && --item->refcount <= 0) {
+ switch (item->type)
+ {
+ case XDGVFS_ITEMTYPE_FILEINFO:
+ {
+ XdgVfsFileInfo * _item = (XdgVfsFileInfo *) item;
+ if (_item->uri) free(_item->uri);
+ if (_item->basename) free(_item->basename);
+ if (_item->mimetype) free(_item->mimetype);
+ if (_item->user) free(_item->user);
+ if (_item->group) free(_item->group);
+ if (_item->mountpoint_id) free(_item->mountpoint_id);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_GET_HEAD:
+ case XDGVFS_ITEMTYPE_PUT_HEAD:
+ case XDGVFS_ITEMTYPE_SETATTRS_HEAD:
+ case XDGVFS_ITEMTYPE_MKDIR_HEAD:
+ case XDGVFS_ITEMTYPE_RMDIR_HEAD:
+ case XDGVFS_ITEMTYPE_RM_HEAD:
+ case XDGVFS_ITEMTYPE_LS_HEAD:
+ {
+ // fprintf(stderr,"why1\n");
+ XdgVfsSimpleHead * _item = (XdgVfsSimpleHead*) item;
+ if (_item->uri) free (_item->uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_OPENFILEDLG_RESPONSE:
+ {
+ XdgVfsOpenFileDlgResponse * _item = (XdgVfsOpenFileDlgResponse*) item;
+ if (_item->selected_localpath) free(_item->selected_localpath);
+ if (_item->selected_uri) free(_item->selected_uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_SAVEFILEDLG_RESPONSE:
+ {
+ // fprintf(stderr,"why\n");
+ XdgVfsSaveFileDlgResponse * _item = (XdgVfsSaveFileDlgResponse*) item;
+ if (_item->selected_localpath) free(_item->selected_localpath);
+ if (_item->selected_uri) free(_item->selected_uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_COPY_HEAD:
+ {
+ XdgVfsCopyHead * _item = (XdgVfsCopyHead*) item;
+ if (_item->uri_src) free(_item->uri_src);
+ if (_item->uri_target) free(_item->uri_target);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_MOVE_HEAD:
+ {
+ XdgVfsMoveHead * _item = (XdgVfsMoveHead*) item;
+ if (_item->uri_src) free(_item->uri_src);
+ if (_item->uri_target) free(_item->uri_target);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_BACKENDINFO:
+ {
+ XdgVfsBackendInfo * _item = (XdgVfsBackendInfo*) item;
+ if (_item->backend_id) free(_item->backend_id);
+ if (_item->system_uri) free(_item->system_uri);
+ if (_item->file_icon_theme) free(_item->file_icon_theme);
+ break;
+ }
+
+ }
+ free(item);
+
+ }
+
+}
+
+
+/* ================ command utils =============== */
+
+static XdgVfsResult _write_command(XdgVfsSession * sess, char * command, const char * argv[]) {
+ if (!sess)
+ {
+ fprintf(stderr, "NULL pointer passed to _write_command!\n");
+ return XDGVFS_ERRORCODE_GENERIC;
+ }
+ if (sess->stateIn != XDGVFS_STATE_READY) return XDGVFS_RESULT_BAD_STATE;
+ FILE* out = fdopen(dup(sess->fd_out), "w");
+ fputs(command, out);
+ int c=0;
+ while(argv[c] != NULL) {
+ const char * arg = argv[c];
+ fputc((int)' ', out);
+ fputc((int)'"', out);
+ fputs(arg, out); /* todo: escape double quotes! */
+ fputc((int)'"', out);
+ c++;
+ }
+ fputc(10, out);
+ fflush(out);
+ fclose(out);
+ //printf("written command!\n");
+ sess->stateIn = XDGVFS_STATE_READING_TEXT;
+ _init_job(sess);
+ return XDGVFS_RESULT_OK;
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_cancel(XdgVfsSession * sess) {
+ /* not implemented yet */
+ return XDGVFS_RESULT_OK;
+}
+
+/* ========================= Commands ========================== */
+
+XdgVfsResult xdg_vfs_sess_cmd_backendInfo(XdgVfsSession * sess)
+{
+ const char * argv[] = { NULL };
+ return _write_command(sess, "backend", argv);
+}
+
+
+XdgVfsResult xdg_vfs_sess_cmd_getFile(XdgVfsSession * sess, const char * filename)
+{
+ const char * argv[] = { filename, "-e", NULL };
+ return _write_command(sess, "get", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_putFile(XdgVfsSession * sess, const char * filename,
+ XdgVfsFlags flags)
+{
+ const char * argv[] = { filename, "-e", NULL, NULL };
+ if (flags & XDGVFS_FLAGS_OVERWRITE)
+ {
+ argv[2] = "--overwrite";
+ }
+ return _write_command(sess, "put", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_getFileInfo(XdgVfsSession * sess, const char * filename)
+{
+ const char * argv[] = { filename, NULL };
+ return _write_command(sess, "info", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_setAttrs(XdgVfsSession * sess,
+ const char * filename, int permissions, int setPermFlag, char * user, char * group)
+{
+ XdgVfsResult r;
+ int an = 1;
+ const char * argv[] = { filename, NULL, NULL, NULL, NULL };
+
+ if ((!user) && (!group) && (!setPermFlag)) return XDGVFS_RESULT_PARAMETER_ERR;
+
+ if (user)
+ {
+ char * str = calloc(256,1);
+ strncat(str, "--user=", 255);
+ strncat(str, user, 255);
+ argv[an++] = str;
+ }
+ if (group)
+ {
+ char * str = calloc(256,1);
+ strncat(str, "--group=", 255);
+ strncat(str, user, 255);
+ argv[an++] = str;
+ }
+ if (setPermFlag)
+ {
+ char * str = calloc(256,1);
+ snprintf (str, 255, "--permissions=%d\n", permissions);
+ argv[an++] = str;
+ }
+ r = _write_command(sess, "info", argv);
+
+ if (argv[1]) free((void*)argv[1]);
+ if (argv[2]) free((void*)argv[2]);
+ if (argv[3]) free((void*)argv[3]);
+ return r;
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_copyFile(XdgVfsSession * sess, const char * filename_src, const char * filename_target)
+{
+ const char * argv[] = { filename_src, filename_target, "--progress", NULL };
+ return _write_command(sess, "cp", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_moveFile(XdgVfsSession * sess, const char * filename_src, const char * filename_target)
+{
+ const char * argv[] = { filename_src, filename_target, "--progress", NULL };
+ return _write_command(sess, "mv", argv);
+}
+
+
+XdgVfsResult xdg_vfs_sess_cmd_listDirectory(XdgVfsSession * sess, const char * filename)
+{
+ const char * argv[] = { filename, "--dive-de-links", NULL };
+ return _write_command(sess, "ls", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_makeDirectory(XdgVfsSession * sess, const char * filename)
+{
+ const char * argv[] = { filename, NULL };
+ return _write_command(sess, "mkdir", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_removeDirectory(XdgVfsSession * sess, const char * filename)
+{
+ const char * argv[] = { filename, NULL };
+ return _write_command(sess, "rmdir", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_removeFile(XdgVfsSession * sess, const char * filename)
+{
+ const char * argv[] = { filename, NULL };
+ return _write_command(sess, "rm", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_mount(XdgVfsSession * sess, const char * mountpoint_id)
+{
+ const char * argv[] = { mountpoint_id, NULL };
+ return _write_command(sess, "mount", argv);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_monitorDir(XdgVfsSession * sess, const char * uri)
+{
+ const char * argv[] = { uri, NULL };
+ XdgVfsResult r = _write_command(sess, "mondir", argv);
+ if (r) return r;
+ return _finish_simple_job(sess);
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_monitorFile(XdgVfsSession * sess, const char * uri)
+{
+ const char * argv[] = { uri, NULL };
+ XdgVfsResult r = _write_command(sess, "monfile", argv);
+ if (r) return r;
+ return _finish_simple_job(sess);
+
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_removeMonitor(XdgVfsSession * sess, const char * uri)
+{
+ const char * argv[] = { uri, NULL };
+ XdgVfsResult r = _write_command(sess, "rmmon", argv);
+ if (r) return r;
+ return _finish_simple_job(sess);
+}
+
+
+XdgVfsResult xdg_vfs_sess_cmd_openFileDialog(XdgVfsSession * sess, const char * filename, XdgVfsFlags flags)
+{
+ const char * argv[] = { filename, NULL, NULL, NULL };
+
+ if (flags & XDGVFS_FLAGS_INSTANT_GET) {
+ argv[1] = "--instant-get";
+ }
+ if (flags & XDGVFS_FLAGS_QRY_FILEINFO) {
+ argv[2] = "-i";
+ }
+ return _write_command(sess, "openfiledlg", argv);
+
+}
+
+XdgVfsResult xdg_vfs_sess_cmd_saveFileDialog(XdgVfsSession * sess, const char * filename, XdgVfsFlags flags)
+{
+ const char * argv[] = { filename, NULL, NULL };
+
+ if (flags & XDGVFS_FLAGS_INSTANT_PUT) {
+ argv[1] = "--instant-put";
+ }
+ return _write_command(sess, "savefiledlg", argv);
+}
+
+/* ========================= Reading and writing ========================== */
+
+static XdgVfsResult _read_chunk(XdgVfsSession * sess)
+{
+ int i, n;
+ char * buf = sess->inBuf;
+ int used = sess->inBuf_used;
+ int size = sess->inBuf_size;
+
+ n = read (sess->fd_in, buf+used, size-used,0);
+ if (n==0)
+ {
+ return XDGVFS_RESULT_IOERR; // EOF -> child process has died
+ }
+ if (n<0)
+ {
+ printf ("reading head returns: %d\n", n);
+ perror ("error reading");
+ return XDGVFS_RESULT_IOERR; // EOF -> child process has died
+ }
+ if (XDG_VFS_DEBUG_IPC)
+ {
+ fwrite (buf+used, 1, n, stderr);
+ fflush(stderr);
+ }
+
+ sess->inBuf_used = used+n;
+ return XDGVFS_RESULT_OK;
+}
+
+static char * _get_str_blocking(XdgVfsSession * sess, int size) {
+ char * buf = sess->inBuf;
+ int used = sess->inBuf_used;
+ char * str;
+ while (sess->inBuf_used < size)
+ {
+ XdgVfsResult r = _read_chunk(sess);
+ if (r)
+ {
+ fprintf(stdout, "_get_str_blocking problem: %d\n", r);
+ return NULL;
+ }
+ }
+ str = malloc(size+1);
+ memcpy(str, buf, size);
+ str[size]='\0';
+ memcpy(buf, buf+size, used-size);
+ sess->inBuf_used = used-size;
+ return str;
+}
+
+static char * _get_next_line(XdgVfsSession * sess) {
+ char * theLine = NULL;
+ char * buf = sess->inBuf;
+ int i;
+ int used = sess->inBuf_used;
+ //buf[used+1] = '\0';
+ //fprintf(stderr, "_get_next_line used=%d buf=%s\n", used, buf);
+ for (i = 0; i < used; i++) {
+ if (buf[i] == '\n') {
+ buf[i] = '\0';
+ theLine=strdup(buf);
+ memcpy(buf, buf+i+1, used-i); /* shift data left */
+ sess->inBuf_used = used-i-1;
+ break;
+ }
+ }
+ return theLine;
+}
+
+
+
+static XdgVfsResult _xdg_vfs_sess_parseLine(XdgVfsSession * sess, XdgVfsItemType * type, XdgVfsItem ** item)
+{
+ char * theLine;
+
+ *type = XDGVFS_ITEMTYPE_NONE;
+ *item = NULL;
+
+
+ theLine = _get_next_line(sess);
+ if (!theLine)
+ {
+ XdgVfsResult r = _read_chunk(sess);
+ if (r) return r;
+ theLine = _get_next_line(sess);
+ }
+
+
+ if (XDG_VFS_DEBUG_IPC) fprintf(stdout, "t=%d line: >>%s<<\n", (sess->currentItemType), theLine);
+
+ if (theLine && theLine[0] != '\0')
+ {
+ if (theLine[0] == '[' || theLine[0] == '(' || theLine[0] == ':')
+ {
+ /* We got a new Object - thus we have to return the old one */
+ XdgVfsItem * newItem = NULL;
+
+ if (strcmp(theLine, XDGVFS_TAG_BACKEND)==0)
+ {
+ XdgVfsBackendInfo * _newItem = calloc(1, sizeof(XdgVfsBackendInfo));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_BACKENDINFO;
+ }
+ else if (strcmp(theLine, XDGVFS_TAG_GET)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_GET_HEAD;
+ }
+ else if (strcmp(theLine, XDGVFS_TAG_PUT)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_PUT_HEAD;
+ }
+ else if (strcmp(theLine, XDGVFS_TAG_ESCAPEDDATA_OUT)==0)
+ {
+ XdgVfsDataInDoneItem * _newItem = calloc(1, sizeof(XdgVfsDataInDoneItem));
+ _newItem->bytecount = 0;
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_DATAIN_DONE;
+ sess->stateIn = XDGVFS_STATE_READING_DATA;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_PUT)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_GET_HEAD;
+ }
+ else if (strcmp(theLine, XDGVFS_TAG_ESCAPEDDATA_IN)==0)
+ {
+ XdgVfsDataOutDoneItem * _newItem = calloc(1, sizeof(XdgVfsDataOutDoneItem));
+ newItem = (XdgVfsItem*) _newItem;
+ _newItem->bytecount = 0;
+ newItem->type = XDGVFS_ITEMTYPE_DATAOUT_DONE;
+ sess->stateIn = XDGVFS_STATE_WRITING_DATA;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_CP)==0)
+ {
+ XdgVfsCopyHead * _newItem = calloc(1, sizeof(XdgVfsCopyHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_COPY_HEAD;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_MV)==0)
+ {
+ XdgVfsMoveHead * _newItem = calloc(1, sizeof(XdgVfsMoveHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_MOVE_HEAD;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_PROGRESS)==0)
+ {
+ XdgVfsProgress * _newItem = calloc(1, sizeof(XdgVfsProgress));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_PROGRESS;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_FILEINFO)==0
+ || strcmp(theLine,XDGVFS_TAG_DIRENTRY)==0)
+ {
+ XdgVfsFileInfo * _newItem = calloc(1, sizeof(XdgVfsFileInfo));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_FILEINFO;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_SETATTRS)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_SETATTRS_HEAD;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_LS)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_LS_HEAD;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_MKDIR)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_MKDIR_HEAD;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_RMDIR)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_RMDIR_HEAD;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_RM)==0)
+ {
+ XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_RMDIR_HEAD;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_MOUNT)==0)
+ {
+ //XdgVfsSimpleHead * _newItem = calloc(1, sizeof(XdgVfsSimpleHead));
+ newItem = NULL;
+ //newItem->type = XDGVFS_ITEMTYPE_NONE;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_OPENFILEDLG)==0)
+ {
+ XdgVfsOpenFileDlgResponse * _newItem = calloc(1, sizeof(XdgVfsOpenFileDlgResponse));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_OPENFILEDLG_RESPONSE;
+ }
+ else if (strcmp(theLine,XDGVFS_TAG_SAVEFILEDLG)==0)
+ {
+ XdgVfsSaveFileDlgResponse * _newItem = calloc(1, sizeof(XdgVfsSaveFileDlgResponse));
+ newItem = (XdgVfsItem*) _newItem;
+ newItem->type = XDGVFS_ITEMTYPE_SAVEFILEDLG_RESPONSE;
+ }
+ /* finished? */
+ else if (strcmp(theLine,XDGVFS_TAG_DONE)==0)
+ {
+ //fprintf(stderr,"done\n");
+ sess->stateIn = XDGVFS_STATE_EXPECTING_PROMPT;
+ sess->lastJobErrorCode = XDGVFS_ERRORCODE_OK;
+ }
+ else if (strncmp(theLine,XDGVFS_TAG_FAILED, strlen(XDGVFS_TAG_FAILED)) ==0)
+ {
+ char * errstr;
+ sess->lastJobErrorCode = _parse_failure(theLine, &errstr);
+ sess->stateIn = XDGVFS_STATE_EXPECTING_PROMPT;
+ //fprintf(stderr,"failed code=%d\n", sess->lastJobErrorCode);
+ sess->currentItemType = XDGVFS_ITEMTYPE_NONE;
+ sess->currentItem = NULL; // fixme unref!
+ } else {
+ fprintf(stderr,"unexpected tag: %s\n", theLine);
+ sess->stateIn = XDGVFS_STATE_ERROR_LEAVING;
+ return XDGVFS_RESULT_IOERR;
+ }
+
+ *type = sess->currentItemType;
+ *item = sess->currentItem;
+ if (newItem) {
+ newItem->refcount = 1;
+ sess->currentItemType = newItem->type;
+ sess->currentItem = newItem;
+ } else {
+ sess->currentItemType = XDGVFS_ITEMTYPE_NONE;
+ sess->currentItem = NULL;
+ }
+
+ }
+ else if(theLine[0] == XDGVFS_TAG_MONITOREVENT [0])
+ {
+ int l = strlen(theLine);
+ if (l>2 && sess->monitor_cb)
+ {
+ char * changed_uri = strdup(theLine+2);
+ sess->monitor_cb(sess, changed_uri, sess->monitor_cb_userdata);
+ free(changed_uri);
+ }
+ else
+ fprintf(stderr, "monitorevent: line too short\n");
+ }
+ else
+ {
+ XdgVfsItem * rItem = sess->currentItem;
+ char * keyname;
+ char * valueStr;
+ long long int valueLLInt;
+ parse_pair(theLine, &keyname, &valueStr, &valueLLInt);
+ switch(sess->currentItemType)
+ {
+ case(XDGVFS_ITEMTYPE_GET_HEAD):
+ case(XDGVFS_ITEMTYPE_PUT_HEAD):
+ case(XDGVFS_ITEMTYPE_MKDIR_HEAD):
+ case(XDGVFS_ITEMTYPE_RMDIR_HEAD):
+ case(XDGVFS_ITEMTYPE_RM_HEAD):
+ case(XDGVFS_ITEMTYPE_LS_HEAD):
+ case(XDGVFS_ITEMTYPE_SETATTRS_HEAD):
+ {
+ XdgVfsSimpleHead * _rItem = (XdgVfsSimpleHead*)rItem;
+ if (strcmp(keyname, "uri")==0)
+ _rItem->uri = strdup(valueStr);
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_BACKENDINFO):
+ {
+
+ XdgVfsBackendInfo * _rItem = (XdgVfsBackendInfo*)rItem;
+ if (strcmp(keyname, "backend_id")==0)
+ _rItem->backend_id = strdup(valueStr);
+ if (strcmp(keyname, "system_uri")==0)
+ _rItem->system_uri = strdup(valueStr);
+ if (strcmp(keyname, "file_icon_theme")==0)
+ _rItem->file_icon_theme = strdup(valueStr);
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_FILEINFO):
+ {
+
+ XdgVfsFileInfo * _rItem = (XdgVfsFileInfo*)rItem;
+ if (strcmp(keyname, "basename")==0)
+ _rItem->basename = strdup(valueStr);
+ if (strcmp(keyname, "mimetype")==0)
+ _rItem->mimetype = strdup(valueStr);
+ if (strcmp(keyname, "iconname")==0)
+ _rItem->iconname = strdup(valueStr);
+ if (strcmp(keyname, "uri")==0)
+ _rItem->uri = strdup(valueStr);
+ if (strcmp(keyname, "user")==0)
+ _rItem->user = strdup(valueStr);
+ if (strcmp(keyname, "group")==0)
+ _rItem->group = strdup(valueStr);
+ if (strcmp(keyname, "linkdest")==0)
+ _rItem->linkdest = strdup(valueStr);
+ if (strcmp(keyname, "filetype")==0)
+ _rItem->filetype = _translate_filetype(valueStr);
+ if (strcmp(keyname, "mountpoint_id")==0)
+ _rItem->mountpoint_id = strdup(valueStr);
+
+ if (strcmp(keyname, "permissions")==0)
+ _rItem->permissions = valueLLInt;
+ if (strcmp(keyname, "size")==0)
+ _rItem->size = valueLLInt;
+ if (strcmp(keyname, "atime")==0)
+ _rItem->atime = valueLLInt;
+ if (strcmp(keyname, "mtime")==0)
+ _rItem->mtime = valueLLInt;
+ if (strcmp(keyname, "ctime")==0)
+ _rItem->ctime = valueLLInt;
+ if (strcmp(keyname, "is_mounted")==0)
+ _rItem->is_mounted = valueLLInt;
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_PROGRESS):
+ {
+ XdgVfsProgress * _rItem = (XdgVfsProgress*)rItem;
+ if (strcmp(keyname, "total_bytes")==0)
+ _rItem->size = valueLLInt;
+ if (strcmp(keyname, "bytes_copied")==0)
+ _rItem->copied = valueLLInt;
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_OPENFILEDLG_RESPONSE):
+ {
+ XdgVfsOpenFileDlgResponse * _rItem = (XdgVfsOpenFileDlgResponse*) rItem;
+ if (strcmp(keyname, "selected_localpath")==0)
+ _rItem->selected_localpath = strdup(valueStr);;
+ if (strcmp(keyname, "selected_uri")==0)
+ _rItem->selected_uri = strdup(valueStr);;
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_SAVEFILEDLG_RESPONSE):
+ {
+ XdgVfsSaveFileDlgResponse * _rItem = (XdgVfsSaveFileDlgResponse*) rItem;
+ if (strcmp(keyname, "selected_localpath")==0)
+ _rItem->selected_localpath = strdup(valueStr);;
+ if (strcmp(keyname, "selected_uri")==0)
+ _rItem->selected_uri = strdup(valueStr);;
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_COPY_HEAD):
+ {
+ XdgVfsCopyHead * _rItem = (XdgVfsCopyHead*) rItem;
+ if (strcmp(keyname, "uri_src")==0)
+ _rItem->uri_src = strdup(valueStr);;
+ if (strcmp(keyname, "uri_target")==0)
+ _rItem->uri_target = strdup(valueStr);;
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_MOVE_HEAD):
+ {
+ XdgVfsMoveHead * _rItem = (XdgVfsMoveHead*) rItem;
+ if (strcmp(keyname, "uri_src")==0)
+ _rItem->uri_src = strdup(valueStr);;
+ if (strcmp(keyname, "uri_target")==0)
+ _rItem->uri_target = strdup(valueStr);;
+ break;
+ }
+ case(XDGVFS_ITEMTYPE_DATAIN_DONE):
+ break;
+ }
+ //if (valueStr) free(valueStr);
+ }
+ }
+ return XDGVFS_RESULT_CONTINUES;
+}
+
+static void _debug_print_out_buffer(XdgVfsSession * sess) {
+ int i;
+ //sess->inBuf[sess->inBuf_used+1] = '\0';
+ //
+ fprintf(stderr, "buf: used=%d '", sess->inBuf_used);
+ for (i=0;i<sess->inBuf_used;i++)
+ {
+ int c = sess->inBuf[i];
+ if (c < 32 || c > 126)
+ fputc('.', stderr);
+ else
+ fputc(c, stderr);
+ }
+ fprintf(stderr, "'\n");
+}
+
+static XdgVfsResult _report_size(XdgVfsSession * sess, int len)
+{
+ if (sess->currentItemType == XDGVFS_ITEMTYPE_DATAIN_DONE)
+ {
+ XdgVfsDataInDoneItem * item = (XdgVfsDataInDoneItem *) sess->currentItem;
+ item->bytecount+=len;
+ return XDGVFS_RESULT_OK;
+
+ }
+ else
+ {
+ fprintf(stderr,"fatal: data-in-item not found!!!\n");
+ sess->stateIn = XDGVFS_STATE_ERROR_LEAVING;
+ return XDGVFS_RESULT_FATAL_ERR;
+ }
+}
+
+static XdgVfsResult _read_data(XdgVfsSession * sess, XdgVfsItemType * typeOut, char ** buffer, int * len)
+{
+ *buffer = NULL;
+ *len = 0;
+ if (sess->inBuf_used<2)
+ {
+ //fprintf(stderr, "readchunk\n");
+ XdgVfsResult r = _read_chunk(sess);
+ if (r) return r;
+ }
+
+ char * buf = sess->inBuf;
+ int used = sess->inBuf_used;
+ //fprintf(stderr, "\nlen = %d\n", used);
+ int i=0;
+ char * outptr = sess->rawBufIn;
+ while (i<used)
+ {
+ char c = buf[i];
+ if (c == '~')
+ {
+ i++;
+ if (i<used)
+ {
+ if (buf[i] == '~')
+ {
+ i++;
+ *outptr++ = '~';
+ continue;
+ }
+ else
+ if (buf[i] == '\n')
+ {
+ memcpy(buf, buf+i+1, used-i);
+ *buffer = sess->rawBufIn;
+ *len = outptr - sess->rawBufIn;
+ sess->inBuf_used = used-i-1;
+
+ _report_size(sess, *len);
+ /* fprintf(stderr, "read all data - end found len=%d\n", *len); */
+ /* _debug_print_out_buffer(sess); */
+
+ sess->stateIn = XDGVFS_STATE_READING_TEXT;
+ /* finished - switch back to text-mode */
+ *typeOut = XDGVFS_DATAIN;
+ return XDGVFS_RESULT_CONTINUES;
+ }
+ else
+ {
+ *buffer = NULL;
+ *len = 0;
+ fprintf(stderr, "unescaping error at pos=%d buffer len=%d:\n", i, used);
+ _debug_print_out_buffer(sess);
+ fprintf(stderr, "unescaped buffer:\n");
+ fwrite (sess->rawBufIn, 1, outptr - sess->rawBufIn, stdout);
+ sess->inBuf_used = 0;
+ sess->stateIn = XDGVFS_STATE_ERROR_LEAVING;
+
+ return XDGVFS_RESULT_UNESCAPING_DATA_ERR;
+ }
+ }
+ else
+ {
+ buf[0]='~'; /* cannot process this - leave escape char in buffer */
+ sess->inBuf_used = 1;
+ *buffer = sess->rawBufIn;
+ *len = outptr - sess->rawBufIn;
+ _report_size(sess, *len);
+ *typeOut = XDGVFS_DATAIN;
+ return XDGVFS_RESULT_CONTINUES;
+ }
+ }
+ else
+ {
+ i++;
+ *outptr++ = c;
+ }
+ }
+
+ *buffer = sess->rawBufIn;
+ *len = outptr - sess->rawBufIn;
+ _report_size(sess, *len);
+ sess->inBuf_used = 0;
+ *typeOut = XDGVFS_DATAIN;
+ return XDGVFS_RESULT_CONTINUES;
+}
+
+
+static XdgVfsResult _xdg_vfs_sess_readItem(XdgVfsSession * sess, XdgVfsItemType * typeOut,
+ XdgVfsItem ** itemOut, char ** buffer, int * len)
+{
+
+ if (typeOut) *typeOut = 0;
+ if (itemOut) *itemOut = NULL;
+ if (buffer) *buffer = NULL;
+ if (len) * len=0;
+
+ if (XDG_VFS_DEBUG_IPC) fprintf(stderr, "state=%d\n", sess->stateIn);
+ // _debug_print_out_buffer(sess);
+
+
+ switch(sess->stateIn)
+ {
+ case(XDGVFS_STATE_EXPECTING_PROMPT):
+
+ if (sess->inBuf_used >= 2)
+ {
+ char * prompt = _get_str_blocking(sess, 2);
+ if (prompt && strcmp(prompt, "> ")==0)
+ {
+ sess->stateIn = XDGVFS_STATE_READY;
+ free(prompt);
+ return sess->lastJobErrorCode;
+ }
+ else
+ {
+ if(prompt) free (prompt);
+ return XDGVFS_ERRORCODE_CORRUPTED_DATA;
+ }
+ }
+/* else if (sess->inBuf_used > 2)
+ {
+ return XDGVFS_ERRORCODE_CORRUPTED_DATA;
+ } */
+ else
+ {
+ XdgVfsResult r = _read_chunk(sess);
+ if (r) return r;
+ return XDGVFS_RESULT_CONTINUES;
+ }
+ break;
+ case(XDGVFS_STATE_READY):
+ {
+ XdgVfsResult r = _xdg_vfs_sess_parseLine(sess, typeOut, itemOut);
+ if (typeOut && *typeOut != XDGVFS_ITEMTYPE_NONE)
+ {
+ fprintf(stderr,
+ "WARNING: calling this function in 'ready-state' shouldn't "
+ "return anything except triggering file monitoring events!"
+ " itemType=%d\n", typeOut);
+
+ if (typeOut) *typeOut=XDGVFS_ITEMTYPE_NONE;
+ if (itemOut)
+ {
+ xdg_vfs_item_unref(*itemOut);
+ *itemOut=NULL;
+ }
+ return XDGVFS_RESULT_BAD_STATE;
+ }
+ if (r!=XDGVFS_RESULT_CONTINUES)
+ {
+ fprintf(stderr,
+ "WARNING: calling this function in 'ready-state' shouldn't"
+ " return errors!\n");
+ return r;
+ }
+ return XDGVFS_RESULT_OK;
+ }
+ case(XDGVFS_STATE_READING_TEXT):
+ return _xdg_vfs_sess_parseLine(sess, typeOut, itemOut);
+ case(XDGVFS_STATE_READING_DATA):
+ return _read_data(sess, typeOut, buffer, len);
+ case(XDGVFS_STATE_WRITING_DATA):
+ *typeOut = XDGVFS_DATAOUT;
+ return XDGVFS_RESULT_CONTINUES;
+ case(XDGVFS_STATE_ERROR_LEAVING):
+ return XDGVFS_RESULT_IOERR;
+
+ default:
+ return XDGVFS_RESULT_BAD_STATE;
+ }
+ return XDGVFS_ERRORCODE_OK;
+}
+
+XdgVfsResult xdg_vfs_sess_readItem(XdgVfsSession * sess, XdgVfsItemType * typeOut,
+ XdgVfsItem ** itemOut, char ** buffer, int * len)
+{
+ XdgVfsResult r;
+ if (sess->recurse_count > 0) {
+ fprintf(stderr, "Warning: cannot recurse readItem function!\n");
+ return XDGVFS_RESULT_BAD_STATE;
+ }
+ sess->recurse_count = sess->recurse_count+1;
+ r= _xdg_vfs_sess_readItem(sess, typeOut, itemOut, buffer, len);
+ sess->recurse_count = sess->recurse_count-1;
+ return r;
+}
+
+static int _chk_incoming(XdgVfsSession * sess)
+{
+ /* check for canceled */
+ int filedes = sess->fd_in;
+ int r;
+ fd_set set;
+ struct timeval timeout;
+
+ /* Initialize the file descriptor set. */
+ FD_ZERO (&set);
+ FD_SET (filedes, &set);
+
+ /* Initialize the timeout data structure. */
+ timeout.tv_sec = 0;
+ timeout.tv_usec = 0;
+
+ /* select returns 0 if timeout, 1 if input available, -1 if error. */
+ r= select (FD_SETSIZE, &set, NULL, NULL, &timeout);
+ if (r==0) return 0;
+ if (r==-1)
+ {
+ fprintf(stderr, "WARNING: Error when checking stdin for incoming data\n");
+ return 0;
+ }
+ else
+ {
+ return 1;
+ }
+}
+
+
+XdgVfsResult xdg_vfs_sess_sendData(XdgVfsSession * sess) {
+
+ if (_chk_incoming(sess))
+ {
+ sess->stateIn = XDGVFS_STATE_READING_TEXT;
+ return XDGVFS_RESULT_IOERR;
+ }
+
+
+ if (sess->outBuf_used - sess->outBuf_sent == 0) return XDGVFS_RESULT_GIVE_ME_DATA;
+
+ ssize_t len = write (sess->fd_out,
+ sess->outBuf + sess->outBuf_sent,
+ sess->outBuf_used - sess->outBuf_sent);
+ // fprintf(stderr, "sent %d bytes\n", len);
+ //sleep(1);
+ if (len == -1) {
+ if (errno == EAGAIN) return XDGVFS_RESULT_CALL_SENDDATA_AGAIN;
+ perror ("sending data to xdg-vfs process - IOERR");
+ return XDGVFS_RESULT_IOERR;
+ }
+ sess->outBuf_sent += len;
+
+
+ if (sess->outBuf_used - sess->outBuf_sent == 0) {
+ if (sess->outBuf_EOF) {
+ sess->stateIn = XDGVFS_STATE_READING_TEXT;
+ return XDGVFS_RESULT_OK;
+ }
+ return XDGVFS_RESULT_GIVE_ME_DATA;
+ }
+
+ return XDGVFS_RESULT_CALL_SENDDATA_AGAIN;
+
+}
+
+XdgVfsResult xdg_vfs_sess_putDataChunk(XdgVfsSession * sess, char * data, int len) {
+
+ sess->outBuf_sent = 0;
+ if (len == 0 ) { /* EOF */
+ if (data) {
+ fprintf(stderr, "WARNING: set data to NULL on EOF!!\n");
+ }
+
+ sess->outBuf[0] = '~';
+ sess->outBuf[1] = '\n';
+ sess->outBuf_used = 2;
+ sess->outBuf_EOF = 1;
+ return XDGVFS_RESULT_CALL_SENDDATA_AGAIN;
+ }
+
+ if (sess->currentItemType == XDGVFS_ITEMTYPE_DATAOUT_DONE) {
+ XdgVfsDataOutDoneItem * dii = (XdgVfsDataOutDoneItem *) sess->currentItem;
+ dii->bytecount += len;
+ }
+ else
+ {
+ fprintf(stderr, "Where is my object?\n");
+ return XDGVFS_RESULT_BAD_STATE;
+ }
+
+ if (!sess->outBuf) sess->outBuf = malloc(len*2); /* can be max twice the data size */
+ if (sess->outBuf_size < len * 2)
+ {
+ sess->outBuf = realloc (sess->outBuf, len * 2);
+ sess->outBuf_size = len * 2;
+ }
+ int i = 0;
+ char * wptr = sess->outBuf;
+ for (i = 0; i<len; i++)
+ {
+ char c = data[i];
+ if (c == '~') /* escape it */
+ {
+ *wptr++ = '~';
+ *wptr++ = '~';
+ }
+ else
+ *wptr++ = c;
+ }
+ sess->outBuf_used = wptr - sess->outBuf;
+
+ return XDGVFS_RESULT_CALL_SENDDATA_AGAIN;
+
+}
+
+
+
+
diff --git a/libxdg-vfs-client/src/xdg_vfs_client.h b/libxdg-vfs-client/src/xdg_vfs_client.h
new file mode 100644
index 0000000..6ba6f19
--- /dev/null
+++ b/libxdg-vfs-client/src/xdg_vfs_client.h
@@ -0,0 +1,491 @@
+/*
+# xdg_vfs_client.h
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+
+#ifndef XDGVFS_CLIENT_H_
+#define XDGVFS_CLIENT_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <xdg_vfs_common.h>
+
+#define XDG_VFS_DEBUG_IPC 1
+
+#define XDGVFS_CLIENT_BUFFERSIZE 8192
+
+typedef size_t XdgVfsFileSize;
+
+
+/* ====== incoming Items ======== */
+
+
+/**
+* itemtypes
+*/
+typedef enum {
+ XDGVFS_ITEMTYPE_FILEINFO = 1,
+ XDGVFS_ITEMTYPE_SETATTRS_HEAD = 2,
+ XDGVFS_ITEMTYPE_DIR_HEAD = 3,
+ XDGVFS_ITEMTYPE_DIR_ENTRY = 4,
+ XDGVFS_ITEMTYPE_PROGRESS = 5,
+ XDGVFS_ITEMTYPE_GET_HEAD = 6,
+ XDGVFS_ITEMTYPE_PUT_HEAD = 7,
+ XDGVFS_ITEMTYPE_COPY_HEAD = 8,
+ XDGVFS_ITEMTYPE_MOVE_HEAD = 9,
+ XDGVFS_ITEMTYPE_MKDIR_HEAD = 10,
+ XDGVFS_ITEMTYPE_RMDIR_HEAD = 11,
+ XDGVFS_ITEMTYPE_RM_HEAD = 12,
+ XDGVFS_ITEMTYPE_LS_HEAD = 13,
+ XDGVFS_ITEMTYPE_OPENFILEDLG_RESPONSE = 14,
+ XDGVFS_ITEMTYPE_SAVEFILEDLG_RESPONSE = 15,
+ XDGVFS_ITEMTYPE_DATAIN_DONE = 16,
+ XDGVFS_ITEMTYPE_DATAOUT_DONE = 17,
+ XDGVFS_DATAIN = 18,
+ XDGVFS_DATAOUT = 19,
+ XDGVFS_ITEMTYPE_BACKENDINFO = 20,
+
+ XDGVFS_ITEMTYPE_NONE = 0
+} XdgVfsItemType;
+
+
+typedef struct {
+ XdgVfsItemType type;
+ int refcount;
+} XdgVfsItem;
+
+typedef struct {
+ XdgVfsItem itm;
+ char * backend_id;
+ char * system_uri;
+ char * file_icon_theme;
+} XdgVfsBackendInfo;
+
+
+typedef struct {
+ XdgVfsItem itm;
+ XdgVfsFileSize bytecount;
+} XdgVfsDataInDoneItem;
+
+typedef struct {
+ XdgVfsItem itm;
+ XdgVfsFileSize bytecount;
+} XdgVfsDataOutDoneItem;
+
+typedef struct {
+ XdgVfsItem itm;
+ char * uri;
+} XdgVfsSimpleHead;
+
+/**
+* fileinfo filetypes
+*/
+typedef enum {
+ XDGVFS_FILE_TYPE_UNKNOWN = 1,
+ XDGVFS_FILE_TYPE_REGULAR = 2,
+ XDGVFS_FILE_TYPE_DIRECTORY = 3,
+ XDGVFS_FILE_TYPE_FIFO = 4,
+ XDGVFS_FILE_TYPE_SOCKET = 5,
+ XDGVFS_FILE_TYPE_CHARDEV = 6,
+ XDGVFS_FILE_TYPE_BLOCKDEV = 7,
+ XDGVFS_FILE_TYPE_SYMLINK = 8,
+ XDGVFS_FILE_TYPE_VFSMOUNTPOINT = 9,
+ XDGVFS_FILE_TYPE_UNREC = 0
+} XdgVfsFileType;
+
+/**
+* fileinfo item
+*/
+typedef struct {
+ XdgVfsItem itm;
+ char * uri;
+ char * basename;
+ char * mimetype;
+ size_t size;
+ int permissions;
+ char * user;
+ char * group;
+ int atime;
+ int ctime;
+ int mtime;
+ char * linkdest;
+ XdgVfsFileType filetype;
+ char * iconname;
+ char * mountpoint_id;
+ int is_mounted;
+} XdgVfsFileInfo;
+
+typedef struct {
+ XdgVfsItem itm;
+ char * selected_localpath;
+ char * selected_uri;
+} XdgVfsOpenFileDlgResponse;
+
+typedef struct {
+ XdgVfsItem itm;
+ char * selected_localpath;
+ char * selected_uri;
+} XdgVfsSaveFileDlgResponse;
+
+typedef struct {
+ XdgVfsItem itm;
+ char * uri_src;
+ char * uri_target;
+} XdgVfsCopyHead;
+
+typedef struct {
+ XdgVfsItem itm;
+ char * uri_src;
+ char * uri_target;
+} XdgVfsMoveHead;
+
+typedef struct {
+ XdgVfsItem itm;
+ int percent;
+ XdgVfsFileSize size;
+ XdgVfsFileSize copied;
+} XdgVfsProgress;
+
+
+/* ====== flags and return values ======== */
+
+/*
+* Command flags
+*/
+typedef enum {
+ XDGVFS_FLAGS_NONE = 0,
+ XDGVFS_FLAGS_OVERWRITE = 2,
+ XDGVFS_FLAGS_INSTANT_GET = 4,
+ XDGVFS_FLAGS_INSTANT_PUT = 8,
+ XDGVFS_FLAGS_QRY_FILEINFO = 16
+} XdgVfsFlags;
+
+/**
+* xdg-vfs return values:
+* values less than 0 are client errors.
+* values greater than 0 are XDGVFS_ERRORCODE_* errors!
+*/
+#define XDGVFS_RESULT_CANNOT_LAUNCH_BACKEND -10
+#define XDGVFS_RESULT_CALL_SENDDATA_AGAIN -9
+#define XDGVFS_RESULT_GIVE_ME_DATA -8
+#define XDGVFS_RESULT_PARAMETER_ERR -7
+#define XDGVFS_RESULT_FATAL_ERR -6
+#define XDGVFS_RESULT_UNESCAPING_DATA_ERR -5
+#define XDGVFS_RESULT_BAD_STATE -4
+#define XDGVFS_RESULT_IOERR -3
+#define XDGVFS_RESULT_NOT_POSSIBLE -2
+#define XDGVFS_RESULT_CONTINUES -1
+#define XDGVFS_RESULT_DONE 0
+#define XDGVFS_RESULT_OK 0
+
+#define XDGVFS_RESULT_CANNOT_LAUNCH_BACKEND_STR "Client: Cannot launch backend"
+#define XDGVFS_RESULT_CALL_SENDDATA_AGAIN_STR "Client: call sendData again"
+#define XDGVFS_RESULT_GIVE_ME_DATA_STR "Client: give me data"
+#define XDGVFS_RESULT_PARAMETER_ERR_STR "Client: parameter error"
+#define XDGVFS_RESULT_FATAL_ERR_STR "Client: fatal error"
+#define XDGVFS_RESULT_UNESCAPING_DATA_ERR_STR "Client: unescaping data error"
+#define XDGVFS_RESULT_BAD_STATE_STR "Client: bad state"
+#define XDGVFS_RESULT_IOERR_STR "Client: IOERR"
+#define XDGVFS_RESULT_NOT_POSSIBLE_STR "Client: operation not possible"
+#define XDGVFS_RESULT_CONTINUES_STR "Client: result continues"
+#define XDGVFS_RESULT_OK_STR "Client: OK/DONE"
+
+typedef int XdgVfsResult;
+
+/**
+* session state
+*/
+typedef enum {
+ XDGVFS_STATE_ERROR_LEAVING = -1,
+ XDGVFS_STATE_READING_DATA = 1,
+ XDGVFS_STATE_WRITING_DATA = 2,
+ XDGVFS_STATE_EXPECTING_PROMPT = 3,
+ XDGVFS_STATE_READY = 4,
+ XDGVFS_STATE_READING_TEXT = 5
+} XdgVfsState;
+
+typedef struct _XdgVfsSession XdgVfsSession;
+
+typedef void (*XdgVfsMonitorCallback)(XdgVfsSession * sess, char * uri, void * user_data);
+
+/*
+* Session Object
+* never access the members of this stuct directly (it might change)!
+*/
+struct _XdgVfsSession {
+ /* all members are private! */
+
+ /* pipes to the sub-process */
+ int fd_in;
+ int fd_out;
+
+ int pid;
+
+ /* incoming data buffers */
+ char * inBuf;
+ int inBuf_used;
+ int inBuf_size;
+ XdgVfsState stateIn;
+
+ char * rawBufIn;
+
+ /* outgoing data buffers */
+ char * outBuf;
+ int outBuf_sent;
+ int outBuf_used;
+ int outBuf_size;
+ int outBuf_EOF;
+ XdgVfsState stateOut;
+
+ /* incoming items */
+ XdgVfsItemType currentItemType;
+ XdgVfsItem * currentItem;
+
+ int lastJobErrorCode;
+ char * lastJobErrorText;
+
+ /* file/dir change monitoring */
+ XdgVfsMonitorCallback monitor_cb;
+ void * monitor_cb_userdata;
+
+ /* recursion protection */
+ int recurse_count;
+
+};
+
+
+/**
+*
+* Start Session and setup child process
+* (with a session you can run a 'session of' xdg-vfs commands (one after the other)
+* pass NULL or "this" for the current desktop or "kde"/"gnome" for preferredDesktop.
+*/
+XdgVfsResult xdg_vfs_sess_start(XdgVfsSession ** sessOut, char * preferredDesktop);
+
+/**
+* Close session and kill child process
+*
+*/
+XdgVfsResult xdg_vfs_sess_close(XdgVfsSession * sess);
+
+/**
+* Cancel the current Command
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_cancel(XdgVfsSession * sess);
+
+/**
+* Watch this fd to avoid blocking in xdgvfs_sess_readItem()
+*
+*/
+int xdg_vfs_sess_getIncomingFiledescriptor(XdgVfsSession * sess);
+
+/**
+* Watch this fd to avoid blocking in xdg_vfs_sess_sendData();
+*
+*/
+int xdg_vfs_sess_getOutgoingFiledescriptor(XdgVfsSession * sess);
+
+/**
+* Check if the session is ready for commands
+*
+*/
+int xdg_vfs_sess_isBusy(XdgVfsSession * sess);
+
+/* ============== file/dirwatch monitor ===================== */
+
+void xdg_vfs_sess_set_monitor_callback(
+ XdgVfsSession * sess,
+ XdgVfsMonitorCallback cb,
+ void * userdata
+ );
+
+/* ====================== VFS Commands =======================*/
+
+/*
+* After running a command the session will leave the READY state and
+* you have to read items from the session.
+*/
+/**
+* Command: get Backend Info
+*
+*/
+
+XdgVfsResult xdg_vfs_sess_cmd_backendInfo(XdgVfsSession * sess);
+/**
+* Command: get File
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_getFile(XdgVfsSession * sess, const char * filename);
+
+/**
+* Command: put File
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_putFile(XdgVfsSession * sess, const char * filename,
+ XdgVfsFlags flags);
+
+/**
+* Command: getFileInfo
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_getFileInfo(XdgVfsSession * sess, const char * filename);
+
+/**
+* Command: SetAttrs
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_setAttrs(XdgVfsSession * sess,
+ const char * filename, int permissions, int setPermFlag, char * user, char * group);
+
+/**
+* Command: CopyFile
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_copyFile(XdgVfsSession * sess, const char * filename_src, const char * filename_target);
+
+/**
+* Command: Move File
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_moveFile(XdgVfsSession * sess, const char * filename_src, const char * filename_target);
+
+/**
+* Command: Make Directory
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_makeDirectory(XdgVfsSession * sess, const char * filename);
+
+/**
+* Command: Remove Directory
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_removeDirectory(XdgVfsSession * sess, const char * filename);
+
+/**
+* Command: Delete File
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_removeFile(XdgVfsSession * sess, const char * filename);
+
+/**
+* Command: List Directory
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_listDirectory(XdgVfsSession * sess, const char * filename);
+
+/**
+* Command: Mount
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_mount(XdgVfsSession * sess, const char * mountpoint_id);
+
+/**
+* Command: monitor directory
+* This is a simple command, you don't have to read items to finish.
+*/
+XdgVfsResult xdg_vfs_sess_cmd_monitorDir(XdgVfsSession * sess, const char * uri);
+
+/**
+* Command: monitor file
+* This is a simple command, you don't have to read items to finish.
+*/
+XdgVfsResult xdg_vfs_sess_cmd_monitorFile(XdgVfsSession * sess, const char * uri);
+
+/**
+* Command: remove monitor
+* This is a simple command, you don't have to read items to finish.
+*/
+XdgVfsResult xdg_vfs_sess_cmd_removeMonitor(XdgVfsSession * sess, const char * uri);
+
+/**
+* Command: Show Open-File-Dialog
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_openFileDialog(XdgVfsSession * sess, const char * filename, XdgVfsFlags flags);
+
+/**
+* Command: Show Save-File-Dialog
+*
+*/
+XdgVfsResult xdg_vfs_sess_cmd_saveFileDialog(XdgVfsSession * sess, const char * filename, XdgVfsFlags flags);
+
+/* ============= READ / WRITE FUNCTIONS ============= */
+
+/**
+* Read an Item or a Chunk of File-Data. Continue reading items until
+* the return value is != XDGVFS_RESULT_CONTINUES
+*
+*/
+XdgVfsResult xdg_vfs_sess_readItem(XdgVfsSession * sess, XdgVfsItemType * typeOut,
+ XdgVfsItem ** itemOut, char ** buffer, int * len);
+
+
+/**
+* Put a Chunk of File-Data into the outgoing buffer.
+* set len = 0 on EOF
+* will return XDGVFS_RESULT_GIVE_ME_DATA (if there is no error)
+*/
+XdgVfsResult xdg_vfs_sess_putDataChunk(XdgVfsSession * sess, char * data, int len);
+
+/**
+* Send data from the outgoing buffer - repeat this on
+* XDGVFS_RESULT_CALL_SENDDATA_AGAIN until you get
+* XDGVFS_RESULT_GIVE_ME_DATA or XDGVFS_RESULT_OK (finished);
+*
+* if you want to do that nonblocking check the outgoing fd first
+*/
+XdgVfsResult xdg_vfs_sess_sendData(XdgVfsSession * sess);
+
+
+
+/* ================= XdgVfsItem ======================*/
+
+/**
+* increase reference Count
+*
+*/
+XdgVfsItem * xdg_vfs_item_ref(XdgVfsItem * item);
+
+/**
+* decrease reference Count
+*
+*/
+void xdg_vfs_item_unref(XdgVfsItem * item);
+
+/* =================== tools ========================= */
+
+char * xdg_vfs_resultToString(XdgVfsResult code);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libxdg-vfs-client/src/xdg_vfs_common.h b/libxdg-vfs-client/src/xdg_vfs_common.h
new file mode 100644
index 0000000..3963983
--- /dev/null
+++ b/libxdg-vfs-client/src/xdg_vfs_common.h
@@ -0,0 +1,146 @@
+/*
+# xdg_vfs_common.h
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#ifndef XDG_VFS_COMMON_H
+#define XDG_VFS_COMMON_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define DEFAULT_DATA_ESC_CHAR 126
+#define DEFAULT_CANCEL_CHAR (int)'!'
+
+/* error codes */
+
+#define XDGVFS_ERRORCODE_OK 0
+#define XDGVFS_ERRORCODE_CANCELED 10
+#define XDGVFS_ERRORCODE_BAD_PARAMETER 11
+#define XDGVFS_ERRORCODE_NOT_SUPPORTED 12
+#define XDGVFS_ERRORCODE_GENERIC 13
+#define XDGVFS_ERRORCODE_INIT_ERROR 14
+#define XDGVFS_ERRORCODE_DATA_ERROR 15
+#define XDGVFS_ERRORCODE_IO_ERROR 16
+#define XDGVFS_ERRORCODE_NOT_PERMITTED 17
+#define XDGVFS_ERRORCODE_MALFORMED_URL 18
+#define XDGVFS_ERRORCODE_PROTOCOL_ERROR 19
+#define XDGVFS_ERRORCODE_USR_OR_GRP_NOT_FOUND 20
+#define XDGVFS_ERRORCODE_INTERNAL 21
+#define XDGVFS_ERRORCODE_CANNOT_OPEN_FOR_WRITING 22
+#define XDGVFS_ERRORCODE_CANNOT_OPEN_FOR_READING 23
+#define XDGVFS_ERRORCODE_IS_DIRECTORY 24
+#define XDGVFS_ERRORCODE_IS_FILE 25
+#define XDGVFS_ERRORCODE_NOT_FOUND 26
+#define XDGVFS_ERRORCODE_ALREADY_EXISTS 27
+#define XDGVFS_ERRORCODE_HOST_NOT_FOUND 28
+#define XDGVFS_ERRORCODE_ACCESS_DENIED 29
+#define XDGVFS_ERRORCODE_CANNOT_ENTER_DIRECTORY 30
+#define XDGVFS_ERRORCODE_PROTOCOL_IS_NOT_A_FILESYSTEM 31
+#define XDGVFS_ERRORCODE_LOOP 32
+#define XDGVFS_ERRORCODE_COULD_NOT_CREATE_SOCKET 33
+#define XDGVFS_ERRORCODE_COULD_NOT_CONNECT 34
+#define XDGVFS_ERRORCODE_ERR_CONNECTION_BROKEN 35
+#define XDGVFS_ERRORCODE_COULD_NOT_MOUNT 36
+#define XDGVFS_ERRORCODE_COULD_NOT_UNMOUNT 37
+#define XDGVFS_ERRORCODE_SOCKET_ERROR 38
+#define XDGVFS_ERRORCODE_LOGIN_FAILED 39
+#define XDGVFS_ERRORCODE_OPERATION_FAILED 40
+#define XDGVFS_ERRORCODE_CANNOT_RESUME 41
+#define XDGVFS_ERRORCODE_OUT_OF_MEMORY 42
+#define XDGVFS_ERRORCODE_UNKNOWN_PROXY_HOST 43
+#define XDGVFS_ERRORCODE_ABORTED 44
+#define XDGVFS_ERRORCODE_TIMEOUT 45
+#define XDGVFS_ERRORCODE_SERVICE_NOT_AVAILABLE 46
+#define XDGVFS_ERRORCODE_CANNOT_DELETE_ORIGINAL 47
+#define XDGVFS_ERRORCODE_CANNOT_DELETE_PARTIAL 48
+#define XDGVFS_ERRORCODE_CANNOT_RENAME_ORIGINAL 49
+#define XDGVFS_ERRORCODE_CANNOT_RENAME_PARTIAL 50
+#define XDGVFS_ERRORCODE_NEED_PASSWD 51
+#define XDGVFS_ERRORCODE_NO_CONTENT 52
+#define XDGVFS_ERRORCODE_NO_SPACE 53
+#define XDGVFS_ERRORCODE_IDENTICAL_FILES 54
+#define XDGVFS_ERRORCODE_CORRUPTED_DATA 55
+#define XDGVFS_ERRORCODE_WRONG_FORMAT 56
+#define XDGVFS_ERRORCODE_ERROR_BAD_FILE 66
+#define XDGVFS_ERRORCODE_TOO_BIG 67
+#define XDGVFS_ERRORCODE_NOT_OPEN 68
+#define XDGVFS_ERRORCODE_INVALID_OPEN_MODE 69
+#define XDGVFS_ERRORCODE_TOO_MANY_OPEN_FILES 70
+#define XDGVFS_ERRORCODE_EOF 71
+#define XDGVFS_ERRORCODE_IN_PROGRESS 72
+#define XDGVFS_ERRORCODE_INTERRUPTED 73
+#define XDGVFS_ERRORCODE_HOST_HAS_NO_ADDRESS 74
+#define XDGVFS_ERRORCODE_DIRECTORY_NOT_EMPTY 75
+#define XDGVFS_ERRORCODE_TOO_MANY_LINKS 76
+#define XDGVFS_ERRORCODE_READ_ONLY_FILE_SYSTEM 77
+#define XDGVFS_ERRORCODE_NOT_SAME_FILE_SYSTEM 78
+#define XDGVFS_ERRORCODE_NAME_TOO_LONG 79
+#define XDGVFS_ERRORCODE_SERVICE_OBSOLETE 80
+#define XDGVFS_ERRORCODE_NO_DEFAULT 81
+#define XDGVFS_ERRORCODE_NAMESERVER 82
+#define XDGVFS_ERRORCODE_LOCKED 83
+#define XDGVFS_ERRORCODE_DEPRECATED_FUNCTION 84
+#define XDGVFS_ERRORCODE_DIRECTORY_BUSY 85
+#define XDGVFS_ERRORCODE_NOT_A_DIRECTORY 86
+
+
+/* tags (private!) */
+
+#define XDGVFS_TAG_DATA_OUT "(>>>RAW_DATA>>>)"
+#define XDGVFS_TAG_ESCAPEDDATA_OUT "(>>>ESCAPED_DATA>>>)"
+#define XDGVFS_TAG_DATA_IN "(<<<RAW_DATA<<<)"
+#define XDGVFS_TAG_ESCAPEDDATA_IN "(<<<ESCAPED_DATA<<<)"
+
+#define XDGVFS_TAG_BACKEND "[BACKEND]"
+#define XDGVFS_TAG_GET "[GET]"
+#define XDGVFS_TAG_PUT "[PUT]"
+#define XDGVFS_TAG_CP "[CP]"
+#define XDGVFS_TAG_MV "[MV]"
+#define XDGVFS_TAG_LS "[LS]"
+#define XDGVFS_TAG_FILEINFO "[FILEINFO]"
+#define XDGVFS_TAG_SETATTRS "[SETATTRS]"
+#define XDGVFS_TAG_SAVEFILEDLG "[SAVEFILEDLG]"
+#define XDGVFS_TAG_OPENFILEDLG "[OPENFILEDLG]"
+#define XDGVFS_TAG_MKDIR "[MKDIR]"
+#define XDGVFS_TAG_RMDIR "[RMDIR]"
+#define XDGVFS_TAG_RM "[RM]"
+#define XDGVFS_TAG_MOUNT "[MOUNT]"
+#define XDGVFS_TAG_MONITOREVENT "*"
+
+
+#define XDGVFS_TAG_METADATA "(METADATA)"
+#define XDGVFS_TAG_DIRENTRY "(DIRENTRY)"
+#define XDGVFS_TAG_PROGRESS "(PROGRESS)"
+
+#define XDGVFS_TAG_DONE ":-)"
+#define XDGVFS_TAG_FAILED ":-("
+
+#ifdef __cplusplus
+}
+#endif
+#endif
+
diff --git a/libxdg-vfs-client/src/xdg_vfs_errstrs.c b/libxdg-vfs-client/src/xdg_vfs_errstrs.c
new file mode 100644
index 0000000..a68326f
--- /dev/null
+++ b/libxdg-vfs-client/src/xdg_vfs_errstrs.c
@@ -0,0 +1,137 @@
+/*
+# xdg_vfs_errstrs.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include "xdg_vfs_client.h"
+#include "xdg_vfs_common.h"
+
+typedef struct
+{
+ int code;
+ char * str;
+} XdgVfsErrorToStringMapping;
+
+XdgVfsErrorToStringMapping _xdg_vfs_error2string_mapping_arr[] =
+{
+
+ { XDGVFS_ERRORCODE_OK , "OK" },
+ { XDGVFS_ERRORCODE_CANCELED , "Canceled" },
+ { XDGVFS_ERRORCODE_BAD_PARAMETER , "Bad Parameter" },
+ { XDGVFS_ERRORCODE_NOT_SUPPORTED , "Not supported" },
+ { XDGVFS_ERRORCODE_GENERIC , "Generic error" },
+ { XDGVFS_ERRORCODE_INIT_ERROR , "init error" },
+ { XDGVFS_ERRORCODE_DATA_ERROR , "Data error" },
+ { XDGVFS_ERRORCODE_IO_ERROR , "IO error" },
+ { XDGVFS_ERRORCODE_NOT_PERMITTED , "Not permitted" },
+ { XDGVFS_ERRORCODE_MALFORMED_URL , "Malformed URL" },
+ { XDGVFS_ERRORCODE_PROTOCOL_ERROR , "Protocol error" },
+ { XDGVFS_ERRORCODE_USR_OR_GRP_NOT_FOUND , "User or Group not found" },
+ { XDGVFS_ERRORCODE_INTERNAL , "Internal error" },
+ { XDGVFS_ERRORCODE_CANNOT_OPEN_FOR_WRITING , "Cannot open for writing"},
+ { XDGVFS_ERRORCODE_CANNOT_OPEN_FOR_READING , "Cannot open for reading"},
+ { XDGVFS_ERRORCODE_IS_DIRECTORY , "is directory"},
+ { XDGVFS_ERRORCODE_IS_FILE , "is file"},
+ { XDGVFS_ERRORCODE_NOT_FOUND , "not found"},
+ { XDGVFS_ERRORCODE_ALREADY_EXISTS , "already exists"},
+ { XDGVFS_ERRORCODE_HOST_NOT_FOUND , "host not found"},
+ { XDGVFS_ERRORCODE_ACCESS_DENIED , "access denied"},
+ { XDGVFS_ERRORCODE_CANNOT_ENTER_DIRECTORY , "cannot enter directory"},
+ { XDGVFS_ERRORCODE_PROTOCOL_IS_NOT_A_FILESYSTEM , "protocol is not a filesystem"},
+ { XDGVFS_ERRORCODE_LOOP , "loop"},
+ { XDGVFS_ERRORCODE_COULD_NOT_CREATE_SOCKET , "cannot create socket"},
+ { XDGVFS_ERRORCODE_COULD_NOT_CONNECT , "could not connect"},
+ { XDGVFS_ERRORCODE_ERR_CONNECTION_BROKEN , "conection broken"},
+ { XDGVFS_ERRORCODE_COULD_NOT_MOUNT , "could not mount"},
+ { XDGVFS_ERRORCODE_COULD_NOT_UNMOUNT , "could not unmount"},
+ { XDGVFS_ERRORCODE_SOCKET_ERROR , "socket error"},
+ { XDGVFS_ERRORCODE_LOGIN_FAILED , "login failed"},
+ { XDGVFS_ERRORCODE_OPERATION_FAILED , "operation failed"},
+ { XDGVFS_ERRORCODE_CANNOT_RESUME , "cannot resume"},
+ { XDGVFS_ERRORCODE_OUT_OF_MEMORY , "out of memory"},
+ { XDGVFS_ERRORCODE_UNKNOWN_PROXY_HOST , "unknown proxy host"},
+ { XDGVFS_ERRORCODE_ABORTED , "aborted"},
+ { XDGVFS_ERRORCODE_TIMEOUT , "timeout"},
+ { XDGVFS_ERRORCODE_SERVICE_NOT_AVAILABLE , "service not available"},
+ { XDGVFS_ERRORCODE_CANNOT_DELETE_ORIGINAL , "cannot delete original"},
+ { XDGVFS_ERRORCODE_CANNOT_DELETE_PARTIAL , "cannot delete partial"},
+ { XDGVFS_ERRORCODE_CANNOT_RENAME_ORIGINAL , "cannot rename original"},
+ { XDGVFS_ERRORCODE_CANNOT_RENAME_PARTIAL , "cannot rename partial"},
+ { XDGVFS_ERRORCODE_NEED_PASSWD , "need passwd"},
+ { XDGVFS_ERRORCODE_NO_CONTENT , "no content"},
+ { XDGVFS_ERRORCODE_NO_SPACE , "no space"},
+ { XDGVFS_ERRORCODE_IDENTICAL_FILES , "identical files"},
+ { XDGVFS_ERRORCODE_CORRUPTED_DATA , "corrupted data"},
+ { XDGVFS_ERRORCODE_WRONG_FORMAT , "wrong format"},
+ { XDGVFS_ERRORCODE_ERROR_BAD_FILE , "bad file"},
+ { XDGVFS_ERRORCODE_TOO_BIG , "too big"},
+ { XDGVFS_ERRORCODE_NOT_OPEN , "not open"},
+ { XDGVFS_ERRORCODE_INVALID_OPEN_MODE , "invalid open mode"},
+ { XDGVFS_ERRORCODE_TOO_MANY_OPEN_FILES , "too many open files"},
+ { XDGVFS_ERRORCODE_EOF , "End of file (EOF)"},
+ { XDGVFS_ERRORCODE_IN_PROGRESS , "In Progress" },
+ { XDGVFS_ERRORCODE_INTERRUPTED , "interrupted" },
+ { XDGVFS_ERRORCODE_HOST_HAS_NO_ADDRESS , "Host has no address" },
+ { XDGVFS_ERRORCODE_DIRECTORY_NOT_EMPTY , "Directory not empty" },
+ { XDGVFS_ERRORCODE_TOO_MANY_LINKS , "Too many links" },
+ { XDGVFS_ERRORCODE_READ_ONLY_FILE_SYSTEM , "Read only filesystem" },
+ { XDGVFS_ERRORCODE_NOT_SAME_FILE_SYSTEM , "not the same filesystem" },
+ { XDGVFS_ERRORCODE_NAME_TOO_LONG , "name too long" },
+ { XDGVFS_ERRORCODE_SERVICE_OBSOLETE , "service obsolete" },
+ { XDGVFS_ERRORCODE_NO_DEFAULT , "no default" },
+ { XDGVFS_ERRORCODE_NAMESERVER , "nameserver error" },
+ { XDGVFS_ERRORCODE_LOCKED , "locked" },
+ { XDGVFS_ERRORCODE_DEPRECATED_FUNCTION , "deprecated function" },
+ { XDGVFS_ERRORCODE_DIRECTORY_BUSY , "directory busy" },
+ { XDGVFS_ERRORCODE_NOT_A_DIRECTORY , "not a directory" }
+};
+
+char * xdg_vfs_resultToString(XdgVfsResult code)
+{
+ int i;
+ for (i=0;i<sizeof(_xdg_vfs_error2string_mapping_arr)/sizeof(XdgVfsErrorToStringMapping);i++)
+ {
+ if (_xdg_vfs_error2string_mapping_arr[i].code == code)
+ return _xdg_vfs_error2string_mapping_arr[i].str;
+ }
+
+ switch(code)
+ {
+ case(XDGVFS_RESULT_CANNOT_LAUNCH_BACKEND): return XDGVFS_RESULT_CANNOT_LAUNCH_BACKEND_STR;
+ case(XDGVFS_RESULT_CALL_SENDDATA_AGAIN): return XDGVFS_RESULT_CALL_SENDDATA_AGAIN_STR;
+ case(XDGVFS_RESULT_GIVE_ME_DATA): return XDGVFS_RESULT_GIVE_ME_DATA_STR;
+ case(XDGVFS_RESULT_PARAMETER_ERR): return XDGVFS_RESULT_PARAMETER_ERR_STR;
+ case(XDGVFS_RESULT_FATAL_ERR): return XDGVFS_RESULT_FATAL_ERR_STR;
+ case(XDGVFS_RESULT_UNESCAPING_DATA_ERR): return XDGVFS_RESULT_UNESCAPING_DATA_ERR_STR;
+ case(XDGVFS_RESULT_BAD_STATE): return XDGVFS_RESULT_BAD_STATE_STR;
+ case(XDGVFS_RESULT_IOERR): return XDGVFS_RESULT_IOERR_STR;
+ case(XDGVFS_RESULT_NOT_POSSIBLE): return XDGVFS_RESULT_NOT_POSSIBLE_STR;
+ case(XDGVFS_RESULT_CONTINUES): return XDGVFS_RESULT_CONTINUES_STR;
+ case(XDGVFS_RESULT_OK): return XDGVFS_RESULT_OK_STR;
+ }
+ return "Client: cannot translate error code to string!";
+}
+
+
diff --git a/libxdg-vfs-client/src/xdg_vfs_forkexec.c b/libxdg-vfs-client/src/xdg_vfs_forkexec.c
new file mode 100644
index 0000000..83b4747
--- /dev/null
+++ b/libxdg-vfs-client/src/xdg_vfs_forkexec.c
@@ -0,0 +1,100 @@
+/*
+# xdg_vfs_forkexec.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include <unistd.h>
+#include <stdio.h>
+#include "xdg_vfs_forkexec.h"
+
+
+int xdg_vfs_forkexec(char * filename, char ** argv, pid_t * child_pid, int * childs_stdin, int * childs_stdout)
+{
+
+ pid_t pid;
+ int child_stdin_pipe[2];
+ int child_stdout_pipe[2];
+
+
+ /* create pipes */
+ if (pipe (child_stdin_pipe))
+ {
+ fprintf (stderr, "Pipe child_stdin_pipe failed.\n");
+ return 1;
+ }
+
+ if (pipe (child_stdout_pipe))
+ {
+ fprintf (stderr, "Pipe child_stdout_pipe failed.\n");
+ return 1;
+ }
+
+
+ /* create the child process */
+ pid = fork ();
+ if (pid == (pid_t) 0)
+ {
+ int r;
+ /* this is the child process. close other ends of the pipes. */
+ close (child_stdin_pipe[1]);
+ close (child_stdout_pipe[0]);
+
+ dup2 (child_stdin_pipe[0], STDIN_FILENO);
+ dup2 (child_stdout_pipe[1], STDOUT_FILENO);
+
+ r = execvp(filename, argv);
+ if (r) {
+ close (child_stdin_pipe[0]);
+ close (child_stdout_pipe[1]);
+ fprintf(stderr, "after fork execvp(%s, argv) ", filename);
+ perror("failed");
+ exit(1);
+ }
+ exit(0);
+ }
+ else if (pid < (pid_t) 0)
+ {
+ /* the fork failed */
+ fprintf (stderr, "Fork failed.\n");
+ return 1;
+ }
+ else
+ {
+ /* this is the parent process. close other ends first. */
+ close (child_stdin_pipe[0]);
+ close (child_stdout_pipe[1]);
+ //write_to_pipe (mypipe[1]);
+
+ *childs_stdin = child_stdin_pipe[1];
+ *childs_stdout = child_stdout_pipe[0];
+
+ *child_pid = pid;
+
+ return 0;
+ }
+}
+
+
+
diff --git a/libxdg-vfs-client/src/xdg_vfs_forkexec.h b/libxdg-vfs-client/src/xdg_vfs_forkexec.h
new file mode 100644
index 0000000..de2a8a6
--- /dev/null
+++ b/libxdg-vfs-client/src/xdg_vfs_forkexec.h
@@ -0,0 +1,40 @@
+/*
+# xdg_vfs_forkexec.h
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#ifndef XDG_VFS_FORKEXEC_H
+#define XDG_VFS_FORKEXEC_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int xdg_vfs_forkexec(char * filename, char ** argv, pid_t * child_pid, int * childs_stdin, int * childs_stdout);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/libxdg-vfs-client/tests/.cvsignore b/libxdg-vfs-client/tests/.cvsignore
new file mode 100644
index 0000000..26a73db
--- /dev/null
+++ b/libxdg-vfs-client/tests/.cvsignore
@@ -0,0 +1,8 @@
+*.la
+*.lo
+*.o
+.deps
+.libs
+Makefile
+Makefile.in
+
diff --git a/libxdg-vfs-client/tests/Makefile.am b/libxdg-vfs-client/tests/Makefile.am
new file mode 100644
index 0000000..a55fa2b
--- /dev/null
+++ b/libxdg-vfs-client/tests/Makefile.am
@@ -0,0 +1,28 @@
+bin_PROGRAMS = test1 sample1_multi sample2_getfile sample3_putfile \
+ sample4_copy sample5_mount sample6_monitor
+
+test1_SOURCES = test1.c
+test1_LDADD = ../src/libxdg_vfs_client.la $(DEPS_LIBS)
+
+sample1_multi_SOURCES = sample1_multi.c
+sample1_multi_LDADD = ../src/libxdg_vfs_client.la $(DEPS_LIBS)
+
+sample2_getfile_SOURCES = sample2_getfile.c
+sample2_getfile_LDADD = ../src/libxdg_vfs_client.la $(DEPS_LIBS)
+
+sample3_putfile_SOURCES = sample3_putfile.c
+sample3_putfile_LDADD = ../src/libxdg_vfs_client.la $(DEPS_LIBS)
+
+sample4_copy_SOURCES = sample4_copy.c
+sample4_copy_LDADD = ../src/libxdg_vfs_client.la $(DEPS_LIBS)
+
+sample5_mount_SOURCES = sample5_mount.c
+sample5_mount_LDADD = ../src/libxdg_vfs_client.la $(DEPS_LIBS)
+
+sample6_monitor_SOURCES = sample6_monitor.c
+sample6_monitor_LDADD = ../src/libxdg_vfs_client.la $(DEPS_LIBS)
+
+INCLUDES = $(all_includes) -I$(top_srcdir)/src
+
+AM_CPPFLAGS = $(DEPS_CFLAGS)
+
diff --git a/libxdg-vfs-client/tests/sample1_multi.c b/libxdg-vfs-client/tests/sample1_multi.c
new file mode 100644
index 0000000..5feec20
--- /dev/null
+++ b/libxdg-vfs-client/tests/sample1_multi.c
@@ -0,0 +1,316 @@
+/*
+# sample1_multi.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include "xdg_vfs_client.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ XdgVfsResult r;
+ XdgVfsSession * session;
+
+ if (argc!=2) {
+ fprintf(stderr,"usage: %s {gnome|kde|this}\n", argv[0]);
+ exit(1);
+ }
+
+ r = xdg_vfs_sess_start(&session, argv[1]);
+
+ if (r) {
+ fprintf(stderr, " session start problem=%d\n", r);
+ return 1;
+ }
+
+ fprintf(stderr, "======= test 0 : backend info =======\n", r);
+
+ r = xdg_vfs_sess_cmd_backendInfo(session);
+
+ if (r) {
+ fprintf(stderr, "test 0 cmd problem=%d\n", r);
+ return 1;
+ }
+
+ XdgVfsItemType type;
+ XdgVfsItem * item;
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch(type)
+ {
+ case XDGVFS_ITEMTYPE_BACKENDINFO:
+ {
+ XdgVfsBackendInfo * backendInfo = (XdgVfsBackendInfo*) item;
+ fprintf(stderr, "backend_id='%s' system_uri='%s' file_icon_theme='%s'\n",
+ backendInfo->backend_id,
+ backendInfo->system_uri,
+ backendInfo->file_icon_theme);
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test 0 result=%d\n", r);
+
+ fprintf(stderr, "======= test 1 : info / =======\n", r);
+
+ r = xdg_vfs_sess_cmd_getFileInfo(session, "/");
+
+ if (r) {
+ fprintf(stderr, "test 1 cmd problem=%d\n", r);
+ return 1;
+ }
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ //fprintf(stderr, "got item type %d\n", typeOut);
+ switch(type)
+ {
+ case XDGVFS_ITEMTYPE_FILEINFO:
+ {
+ XdgVfsFileInfo * info = (XdgVfsFileInfo*) item;
+ fprintf(stderr, "got fileinfo uri='%s'\n", info->uri);
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test 1 result=%d\n", r);
+
+ fprintf(stderr, "======= test 2 : info /notexist =======\n", r);
+
+ r = xdg_vfs_sess_cmd_getFileInfo(session, "/notexist");
+ if (r) {
+ fprintf(stderr, "test 2 cmd problem=%d\n", r);
+ return 1;
+ }
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch(type)
+ {
+ case XDGVFS_ITEMTYPE_FILEINFO:
+ {
+ XdgVfsFileInfo * info = (XdgVfsFileInfo*) item;
+ fprintf(stderr, "got fileinfo uri='%s'\n", info->uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test 2 result=%d\n", r);
+
+ fprintf(stderr, "======= test 3 : ls /usr/local/bin =======\n", r);
+
+ r = xdg_vfs_sess_cmd_listDirectory(session, "/usr/local/bin");
+
+ if (r) {
+ fprintf(stderr, "test 3 cmd problem=%d\n", r);
+ return 1;
+ }
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch(type)
+ {
+ case XDGVFS_ITEMTYPE_LS_HEAD:
+ {
+ XdgVfsSimpleHead * head = (XdgVfsSimpleHead*) item;
+ fprintf(stdout, "got ls header uri='%s'\n", head->uri);
+ break;
+ }
+
+ case XDGVFS_ITEMTYPE_FILEINFO:
+ {
+ XdgVfsFileInfo * info = (XdgVfsFileInfo*) item;
+ fprintf(stdout, "got fileinfo uri='%s'\n", info->uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test 3 result=%d\n", r);
+
+ fprintf(stderr, "======= test 4 : openfiledlg =======\n", r);
+
+ r = xdg_vfs_sess_cmd_openFileDialog(session, NULL, 0);
+ if (r) {
+ fprintf(stderr, "test 4 cmd rval=%d\n", r);
+ return 1;
+ }
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch(type)
+ {
+ case XDGVFS_ITEMTYPE_OPENFILEDLG_RESPONSE:
+ {
+ XdgVfsOpenFileDlgResponse * dlgResp = (XdgVfsOpenFileDlgResponse*) item;
+ fprintf(stderr, "selected_uri='%s'\n", dlgResp->selected_uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+
+ fprintf(stderr, "test 4 result=%d\n", r);
+
+ fprintf(stderr, "======= test 5 : savefiledlg =======\n", r);
+
+ r = xdg_vfs_sess_cmd_saveFileDialog(session, "/tmp", 0);
+ if (r) {
+ fprintf(stderr, "test 5 cmd rval=%d\n", r);
+ return 1;
+ }
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch(type)
+ {
+ case XDGVFS_ITEMTYPE_SAVEFILEDLG_RESPONSE:
+ {
+ XdgVfsSaveFileDlgResponse * dlgResp = (XdgVfsSaveFileDlgResponse*) item;
+ fprintf(stderr, "selected_uri='%s'\n", dlgResp->selected_uri);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test 5 result=%d\n", r);
+
+ fprintf(stderr, "======= test 6 : get /etc/passwd =======\n", r);
+
+ r = xdg_vfs_sess_cmd_getFile(session, "/etc/passwd");
+ if (r) {
+ fprintf(stderr, "test 6 cmd rval=%d\n", r);
+ return 1;
+ }
+
+ char * buf;
+ int len;
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, &buf, &len)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_GET_HEAD:
+ {
+ XdgVfsSimpleHead * sh = (XdgVfsSimpleHead*) item;
+ fprintf(stderr, "'get' header uri='%s'\n", sh->uri);
+ break;
+ }
+ case XDGVFS_DATAIN:
+ {
+ fprintf(stderr, "'data' chunklen=%d\n", len);
+ fwrite (buf, 1, len, stderr);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_DATAIN_DONE:
+ {
+ XdgVfsDataInDoneItem * dii = (XdgVfsDataInDoneItem *) item;
+ fprintf(stderr, "data done bytecount='%d'\n", dii->bytecount);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test 6 result=%d\n", r);
+ return 1;
+
+ xdg_vfs_sess_close(session);
+ sleep (1);
+}
diff --git a/libxdg-vfs-client/tests/sample2_getfile.c b/libxdg-vfs-client/tests/sample2_getfile.c
new file mode 100644
index 0000000..92a81f3
--- /dev/null
+++ b/libxdg-vfs-client/tests/sample2_getfile.c
@@ -0,0 +1,106 @@
+/*
+# sample2_getfile.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include "xdg_vfs_client.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ XdgVfsResult r;
+ XdgVfsSession * session;
+
+ if (argc!=3) {
+ fprintf(stderr,"usage: %s {gnome|kde|this} FILENAME\n", argv[0]);
+ exit(1);
+ }
+
+ r = xdg_vfs_sess_start(&session, argv[1]);
+
+ if (r) {
+ fprintf(stderr, "start session error=%d\n", r);
+ return 1;
+ }
+
+ fprintf(stderr, "======= test : getFile -> stdout =======\n", r);
+
+ r = xdg_vfs_sess_cmd_getFile(session, argv[2]);
+
+ if (r) {
+ fprintf(stderr, "test cmd problem=%d\n", r);
+ return 1;
+ }
+
+ char * buf=NULL;
+ int len=0;
+ XdgVfsItemType type;
+ XdgVfsItem * item;
+
+ while ((r = xdg_vfs_sess_readItem(session, &type, &item, &buf, &len)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_GET_HEAD:
+ {
+ XdgVfsSimpleHead * head = (XdgVfsSimpleHead*) item;
+ fprintf(stderr, "reading file uri='%s'\n", head->uri);
+ break;
+ }
+ case XDGVFS_DATAIN:
+ {
+ fprintf(stderr, "file-data chunklen=%d\n", len);
+ fwrite (buf, 1, len, stdout); /* your file data */
+ break;
+ }
+ case XDGVFS_ITEMTYPE_DATAIN_DONE:
+ {
+ XdgVfsDataInDoneItem * dii = (XdgVfsDataInDoneItem *) item;
+ fprintf(stderr, "read done - bytecount='%d'\n", dii->bytecount);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ if (r) {
+ fprintf(stderr, "test 4 result=%d\n", r);
+ return 1;
+ }
+
+ xdg_vfs_sess_close(session);
+ sleep (1);
+}
diff --git a/libxdg-vfs-client/tests/sample3_putfile.c b/libxdg-vfs-client/tests/sample3_putfile.c
new file mode 100644
index 0000000..fa73517
--- /dev/null
+++ b/libxdg-vfs-client/tests/sample3_putfile.c
@@ -0,0 +1,117 @@
+/*
+# sample3_putfile.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include "xdg_vfs_client.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ XdgVfsResult r;
+ XdgVfsSession * session;
+
+ if (argc!=3) {
+ fprintf(stderr,"usage: %s {gnome|kde|this} FILENAME\n", argv[0]);
+ exit(1);
+ }
+
+ r = xdg_vfs_sess_start(&session, argv[1]);
+
+ if (r) {
+ fprintf(stderr, "sess start error=%d\n", r);
+ return 1;
+ }
+
+
+ fprintf(stderr, "======= test : putFile =======\n", r);
+
+ r = xdg_vfs_sess_cmd_putFile(session, argv[2], 0);
+
+ if (r) {
+ fprintf(stderr, "test cmd problem=%d\n", r);
+ return 1;
+ }
+
+ XdgVfsItemType type=0;
+ XdgVfsItem * item=NULL;
+ int n = 5;
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ // fprintf(stderr, "got item type=%d\n", typeOut);
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_PUT_HEAD:
+ {
+ XdgVfsSimpleHead * sh = (XdgVfsSimpleHead*) item;
+ fprintf(stderr, "'put' head uri='%s'\n", sh->uri);
+ break;
+ }
+ case XDGVFS_DATAOUT:
+ {
+ XdgVfsResult wr;
+
+ /* send file */
+
+ if (n--) wr = xdg_vfs_sess_putDataChunk(session, "Hello World", 10);
+ else wr = xdg_vfs_sess_putDataChunk(session, NULL, 0); /* EOF */
+
+ fprintf(stderr, "writing chunk rval=%d\n", wr);
+
+ while (wr == XDGVFS_RESULT_CALL_SENDDATA_AGAIN) {
+ wr = xdg_vfs_sess_sendData(session);
+ fprintf(stderr, "sending chunk rval=%d\n", wr);
+ }
+
+ break;
+ }
+ case XDGVFS_ITEMTYPE_DATAOUT_DONE:
+ {
+ XdgVfsDataOutDoneItem * dii = (XdgVfsDataOutDoneItem *) item;
+ fprintf(stderr, "data out done bytecount=%d\n", dii->bytecount);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test result=%d\n", r);
+
+ xdg_vfs_sess_close(session);
+
+}
diff --git a/libxdg-vfs-client/tests/sample4_copy.c b/libxdg-vfs-client/tests/sample4_copy.c
new file mode 100644
index 0000000..d6656ef
--- /dev/null
+++ b/libxdg-vfs-client/tests/sample4_copy.c
@@ -0,0 +1,102 @@
+/*
+# sample4_copy.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include "xdg_vfs_client.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ XdgVfsResult r;
+ XdgVfsSession * session;
+
+ if (argc!=4) {
+ fprintf(stderr,"usage: %s {gnome|kde|this} FILENAME FILENAME\n", argv[0]);
+ exit(1);
+ }
+
+ r = xdg_vfs_sess_start(&session, argv[1]);
+
+ if (r) {
+ fprintf(stderr, "sess start error=%d\n", r);
+ return 1;
+ }
+
+
+ fprintf(stderr, "======= test : copy file =======\n", r);
+
+
+
+ r = xdg_vfs_sess_cmd_copyFile(session, argv[2], argv[3]);
+
+ if (r) {
+ fprintf(stderr, "test cmd problem=%d\n", r);
+ return 1;
+ }
+
+ XdgVfsItemType type=0;
+ XdgVfsItem * item=NULL;
+ int n = 5;
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ // fprintf(stderr, "got item type=%d\n", typeOut);
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_COPY_HEAD:
+ {
+ XdgVfsCopyHead * head = (XdgVfsCopyHead*) item;
+ fprintf(stderr, "copying uri_src='%s' to uri_target='%s'\n",
+ head->uri_src, head->uri_target);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_PROGRESS:
+ {
+ XdgVfsProgress * progress = (XdgVfsProgress *) item;
+ fprintf(stderr, "progress: copied=%d size=%d\n", progress->copied, progress->size);
+ break;
+ }
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test result=%d\n", r);
+
+ xdg_vfs_sess_close(session);
+
+}
diff --git a/libxdg-vfs-client/tests/sample5_mount.c b/libxdg-vfs-client/tests/sample5_mount.c
new file mode 100644
index 0000000..a285d6c
--- /dev/null
+++ b/libxdg-vfs-client/tests/sample5_mount.c
@@ -0,0 +1,95 @@
+/*
+# sample5_mount.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include "xdg_vfs_client.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ XdgVfsResult r;
+ XdgVfsSession * session;
+
+ if (argc!=3) {
+ fprintf(stderr,"usage: %s {gnome|kde|this} MOUNTPOINT_ID\n", argv[0]);
+ exit(1);
+ }
+
+ r = xdg_vfs_sess_start(&session, argv[1]);
+
+ if (r) {
+ fprintf(stderr, "sess start error=%d\n", r);
+ return 1;
+ }
+
+
+ fprintf(stderr, "======= test : mount =======\n", r);
+
+
+
+ r = xdg_vfs_sess_cmd_mount(session, argv[2]);
+
+ if (r) {
+ fprintf(stderr, "test cmd problem=%d\n", r);
+ return 1;
+ }
+
+ XdgVfsItemType type=0;
+ XdgVfsItem * item=NULL;
+ int n = 5;
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_CONTINUES)
+ {
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ case XDGVFS_ITEMTYPE_FILEINFO:
+ {
+ /* lists the volumes just mounted */
+ XdgVfsFileInfo * info = (XdgVfsFileInfo*) item;
+ fprintf(stderr, "mounted as uri=%s\n", info->uri);
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+ fprintf(stderr, "test result=%d\n", r);
+
+ xdg_vfs_sess_close(session);
+
+}
diff --git a/libxdg-vfs-client/tests/sample6_monitor.c b/libxdg-vfs-client/tests/sample6_monitor.c
new file mode 100644
index 0000000..875281f
--- /dev/null
+++ b/libxdg-vfs-client/tests/sample6_monitor.c
@@ -0,0 +1,105 @@
+/*
+# sample5_mount.c
+#
+# Copyright 2006, Norbert Frese
+#
+# LICENSE:
+#
+# Permission is hereby granted, free of charge, to any person obtaining a
+# copy of this software and associated documentation files (the "Software"),
+# to deal in the Software without restriction, including without limitation
+# the rights to use, copy, modify, merge, publish, distribute, sublicense,
+# and/or sell copies of the Software, and to permit persons to whom the
+# Software is furnished to do so, subject to the following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+# OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+# ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+# OTHER DEALINGS IN THE SOFTWARE.
+#
+#---------------------------------------------*/
+
+#include "xdg_vfs_client.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+void myXdgVfsMonitorCallback(XdgVfsSession * sess, char * uri, void * user_data)
+{
+ printf("changed: %s\n", uri);
+}
+
+int main(int argc, char *argv[])
+{
+ XdgVfsResult r;
+ XdgVfsSession * session;
+
+ if (argc!=3) {
+ fprintf(stderr,"usage: %s {gnome|kde|this} MONITOR_DIR_URI\n", argv[0]);
+ exit(1);
+ }
+
+ r = xdg_vfs_sess_start(&session, argv[1]);
+
+ if (r) {
+ fprintf(stderr, "sess start error=%d\n", r);
+ return 1;
+ }
+
+ xdg_vfs_sess_set_monitor_callback(session, myXdgVfsMonitorCallback, NULL);
+
+ fprintf(stderr, "======= test : monitor =======\n", r);
+
+
+
+ r = xdg_vfs_sess_cmd_monitorDir(session, argv[2]);
+
+ if (r) {
+ fprintf(stderr, "monitor cmd problem=%d\n", r);
+ return 1;
+ }
+
+ fprintf(stderr, "Now waiting for monitor events!\n");
+
+ if(xdg_vfs_sess_isBusy(session))
+ {
+ fprintf(stderr, "We can't wait for monitor events when the session is busy!\n");
+ return 1;
+ }
+
+ /* because the session is in ready state, we will not receive XDGVFS_RESULT_CONTINUES */
+
+ XdgVfsItemType type=0;
+ XdgVfsItem * item=NULL;
+
+ while ((r=xdg_vfs_sess_readItem(session, &type,
+ &item, NULL, NULL)) == XDGVFS_RESULT_OK)
+ {
+ switch (type)
+ {
+ case XDGVFS_ITEMTYPE_NONE:
+ {
+ break;
+ }
+ default:
+ {
+ fprintf(stderr, "unexpected item - type=%d\n", type);
+ break;
+ }
+ }
+ xdg_vfs_item_unref(item);
+ }
+
+ fprintf(stderr, "cmd monitor result=%d\n", r);
+
+
+ xdg_vfs_sess_close(session);
+
+}
diff --git a/libxdg-vfs-client/tests/test1.c b/libxdg-vfs-client/tests/test1.c
new file mode 100644
index 0000000..03a51d8
--- /dev/null
+++ b/libxdg-vfs-client/tests/test1.c
@@ -0,0 +1,63 @@
+/*
+*
+* Copyright (C) 2005 Norbert Frese
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation; either
+* version 2.1 of the License, or (at your option) any later version.
+*
+* This library 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
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+*
+ */
+
+#include "xdg_vfs_client.h"
+#include "xdg_vfs_forkexec.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[])
+{
+ printf("hello world\n");
+
+ int child_pid;
+ int childs_stdin;
+ int childs_stdout;
+ int r;
+
+ // /home/norbert/work/c/xdg-vfs-gnome/src/
+ r = xdg_vfs_forkexec("xdg_vfs_gnome", argv, &child_pid, &childs_stdin, &childs_stdout);
+ printf("r=%d\n", r);
+ printf("pid=%d\n", child_pid);
+
+ FILE * fout = fdopen (childs_stdin, "w");
+
+ fprintf(fout, "info /\nquit\n");
+ fflush(fout);
+
+ puts("=====");
+
+ FILE * fin = fdopen (childs_stdout, "r");
+ if (!fin) perror("fopen");
+ int c;
+
+ while ((c =fgetc(fin)) != EOF) {
+ putchar (':'); putchar(c);
+ }
+
+ perror("reading");
+
+ int status;
+ r= waitpid(child_pid, &status, 0);
+ if (r==-1) perror("waitpid:");
+ printf("r=%d\n", r);
+}