[Pkg-owncloud-commits] [ocsync] 01/07: Imported Upstream version 0.90.2

Sandro Knauß hefee-guest at alioth.debian.org
Thu Sep 26 17:50:02 UTC 2013


This is an automated email from the git hooks/post-receive script.

hefee-guest pushed a commit to branch master
in repository ocsync.

commit b2fecc934085ecb4db706def77e6ee1626100a48
Author: Sandro Knauß <bugs at sandroknauss.de>
Date:   Thu Sep 26 18:57:57 2013 +0200

    Imported Upstream version 0.90.2
---
 .tag                                    |    2 +-
 AUTHORS                                 |    1 +
 CMakeLists.txt                          |    2 +-
 ChangeLog                               |   12 +-
 doc/ocsync.1                            |  221 ++++++-------------------------
 doc/ocsync.1.txt                        |   22 +--
 doc/ocsync.txt                          |    2 +-
 doc/userguide/csync.html                |    2 +-
 modules/csync_owncloud.c                |   70 ++++++----
 src/CMakeLists.txt                      |    2 +-
 src/csync_exclude.c                     |  108 ++++++++++++---
 src/csync_exclude.h                     |    2 +-
 src/csync_misc.c                        |    1 +
 src/csync_misc.h                        |   11 ++
 src/csync_propagate.c                   |    2 +-
 src/csync_propagate.h                   |    2 +-
 src/csync_update.c                      |   33 ++---
 src/csync_util.c                        |    9 +-
 src/httpbf/src/httpbf.c                 |   22 ++-
 src/httpbf/src/httpbf.h                 |    1 +
 tests/csync_tests/check_csync_exclude.c |   64 +++++++--
 21 files changed, 317 insertions(+), 274 deletions(-)

diff --git a/.tag b/.tag
index c1a8fe0..bba4e2b 100644
--- a/.tag
+++ b/.tag
@@ -1 +1 @@
-12b9b87c6100fc75b62d7ad68ad97d917bca08b6
+8f1e318cde86a74873e28ec53c88753d03a7c240
diff --git a/AUTHORS b/AUTHORS
index 77f802e..5fd81c0 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -1,2 +1,3 @@
 Andreas Schneider <asn at cryptomilk.org>
 Klaas Freitag <freitag at owncloud.com>
+Olivier Goffart <olivier>
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 04077ff..b4634ef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -8,7 +8,7 @@ set(APPLICATION_NAME ${PROJECT_NAME})
 
 set(APPLICATION_VERSION_MAJOR "0")
 set(APPLICATION_VERSION_MINOR "90")
-set(APPLICATION_VERSION_PATCH "0")
+set(APPLICATION_VERSION_PATCH "2")
 
 set(APPLICATION_VERSION "${APPLICATION_VERSION_MAJOR}.${APPLICATION_VERSION_MINOR}.${APPLICATION_VERSION_PATCH}")
 
diff --git a/ChangeLog b/ChangeLog
index 0cdf741..59be24d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,6 +1,16 @@
 ChangeLog
 ==========
-version 0.90.0  (released 2013-09-04, ownCloud Client 1.4)
+version 0.90.1  (released 2013-09-24, ownCloud Client 1.4.1)
+  * no more check on the local inode in updater for win32 (bug #779)
+  * detect if server does not send an etag after an upload 
+    completed.
+  * fix crash in case of network timeout, reported as
+    https://github.com/owncloud/mirall/issues/1010
+  * compile and cmake fixes for win32
+  * fixed behaviour of csync_exclude
+  * documentation and spelling fixes.
+
+version 0.90.0  (released 2013-09-04, ownCloud Client 1.4.0)
   * Added API to get progress information from csync.
   * Added c_rename function to csync std.
   * Fix: Do renames of files before any puts.
diff --git a/doc/makeguide.sh b/doc/makeguide.sh
old mode 100755
new mode 100644
diff --git a/doc/makeman.sh b/doc/makeman.sh
old mode 100755
new mode 100644
diff --git a/doc/ocsync.1 b/doc/ocsync.1
index 9d2f7e1..ce10b7e 100644
--- a/doc/ocsync.1
+++ b/doc/ocsync.1
@@ -1,161 +1,22 @@
-.\"     Title: csync
+'\" t
+.\"     Title: ocsync
 .\"    Author: [see the "AUTHORS" section]
-.\" Generator: DocBook XSL Stylesheets v1.74.0 <http://docbook.sf.net/>
-.\"      Date: 12/13/2008
-.\"    Manual: [FIXME: manual]
-.\"    Source: [FIXME: source]
+.\" Generator: DocBook XSL Stylesheets v1.76.1 <http://docbook.sf.net/>
+.\"      Date: 12/22/2012
+.\"    Manual: \ \&
+.\"    Source: \ \&
 .\"  Language: English
 .\"
-.TH "CSYNC" "1" "12/13/2008" "[FIXME: source]" "[FIXME: manual]"
+.TH "OCSYNC" "1" "12/22/2012" "\ \&" "\ \&"
 .\" -----------------------------------------------------------------
-.\" * (re)Define some macros
+.\" * Define some portability stuff
 .\" -----------------------------------------------------------------
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.\" toupper - uppercase a string (locale-aware)
+.\" http://bugs.debian.org/507673
+.\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html
 .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.de toupper
-.tr aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
-\\$*
-.tr aabbccddeeffgghhiijjkkllmmnnooppqqrrssttuuvvwwxxyyzz
-..
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.\" SH-xref - format a cross-reference to an SH section
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.de SH-xref
-.ie n \{\
-.\}
-.toupper \\$*
-.el \{\
-\\$*
-.\}
-..
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.\" SH - level-one heading that works better for non-TTY output
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.de1 SH
-.\" put an extra blank line of space above the head in non-TTY output
-.if t \{\
-.sp 1
-.\}
-.sp \\n[PD]u
-.nr an-level 1
-.set-an-margin
-.nr an-prevailing-indent \\n[IN]
-.fi
-.in \\n[an-margin]u
-.ti 0
-.HTML-TAG ".NH \\n[an-level]"
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-\." make the size of the head bigger
-.ps +3
-.ft B
-.ne (2v + 1u)
-.ie n \{\
-.\" if n (TTY output), use uppercase
-.toupper \\$*
-.\}
-.el \{\
-.nr an-break-flag 0
-.\" if not n (not TTY), use normal case (not uppercase)
-\\$1
-.in \\n[an-margin]u
-.ti 0
-.\" if not n (not TTY), put a border/line under subheading
-.sp -.6
-\l'\n(.lu'
-.\}
-..
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.\" SS - level-two heading that works better for non-TTY output
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.de1 SS
-.sp \\n[PD]u
-.nr an-level 1
-.set-an-margin
-.nr an-prevailing-indent \\n[IN]
-.fi
-.in \\n[IN]u
-.ti \\n[SN]u
-.it 1 an-trap
-.nr an-no-space-flag 1
-.nr an-break-flag 1
-.ps \\n[PS-SS]u
-\." make the size of the head bigger
-.ps +2
-.ft B
-.ne (2v + 1u)
-.if \\n[.$] \&\\$*
-..
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.\" BB/BE - put background/screen (filled box) around block of text
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.de BB
-.if t \{\
-.sp -.5
-.br
-.in +2n
-.ll -2n
-.gcolor red
-.di BX
-.\}
-..
-.de EB
-.if t \{\
-.if "\\$2"adjust-for-leading-newline" \{\
-.sp -1
-.\}
-.br
-.di
-.in
-.ll
-.gcolor
-.nr BW \\n(.lu-\\n(.i
-.nr BH \\n(dn+.5v
-.ne \\n(BHu+.5v
-.ie "\\$2"adjust-for-leading-newline" \{\
-\M[\\$1]\h'1n'\v'+.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[]
-.\}
-.el \{\
-\M[\\$1]\h'1n'\v'-.5v'\D'P \\n(BWu 0 0 \\n(BHu -\\n(BWu 0 0 -\\n(BHu'\M[]
-.\}
-.in 0
-.sp -.5v
-.nf
-.BX
-.in
-.sp .5v
-.fi
-.\}
-..
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.\" BM/EM - put colored marker in margin next to block of text
-.\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-.de BM
-.if t \{\
-.br
-.ll -2n
-.gcolor red
-.di BX
-.\}
-..
-.de EM
-.if t \{\
-.br
-.di
-.ll
-.gcolor
-.nr BH \\n(dn
-.ne \\n(BHu
-\M[\\$1]\D'P -.75n 0 0 \\n(BHu -(\\n[.i]u - \\n(INu - .75n) 0 0 -\\n(BHu'\M[]
-.in 0
-.nf
-.BX
-.in
-.fi
-.\}
-..
+.ie \n(.g .ds Aq \(aq
+.el       .ds Aq '
 .\" -----------------------------------------------------------------
 .\" * set default formatting
 .\" -----------------------------------------------------------------
@@ -166,16 +27,16 @@
 .\" -----------------------------------------------------------------
 .\" * MAIN CONTENT STARTS HERE *
 .\" -----------------------------------------------------------------
-.SH "Name"
-csync \- A commandline frontent for csync a user level bidirectional file synchronizer\&.
-.SH "Synopsis"
+.SH "NAME"
+ocsync \- A commandline frontent for csync a user level bidirectional file synchronizer\&.
+.SH "SYNOPSIS"
 .sp
-\fBcsync\fR [\fIOPTION\fR\&...] \fISOURCE\fR \fIDESTINATION\fR
+\fBocsync\fR [\fIOPTION\fR\&...] \fISOURCE\fR \fIDESTINATION\fR
 .SH "DESCRIPTION"
 .sp
-csync is a client only bidirectional file synchronizer\&. It synchronizes the content of \fISOURCE\fR with \fIDESTINATION\fR and vice versa\&. The \fIDESTINATION\fR can be a local directory or a remote file server\&.
+ocsync is a client only bidirectional file synchronizer\&. It synchronizes the content of \fISOURCE\fR with \fIDESTINATION\fR and vice versa\&. The \fIDESTINATION\fR can be a local directory or a remote file server\&.
 .sp
-You can use csync for different things\&. The intention is to provide Roaming Home Directories for Linux but you can use it to synchronize your music collection or create a backup of a directory\&.
+You can use ocsync for different things\&. The intention is to provide Roaming Home Directories for Linux but you can use it to synchronize your music collection or create a backup of a directory\&.
 .SH "OPTIONS"
 .PP
 \fB\-\-create\-statedb\fR
@@ -233,20 +94,14 @@ Failure (syntax or usage error; configuration error; unexpected error)\&.
 .sp -1
 .IP \(bu 2.3
 .\}
-csync /home/user /backup/home/user
+ocsync /home/user /backup/home/user
 .sp
 .if n \{\
 .RS 4
 .\}
-.fam C
-.ps -1
 .nf
-.BB lightgray
 Synchronizer two local directories\&.
-.EB lightgray
 .fi
-.fam
-.ps +1
 .if n \{\
 .RE
 .\}
@@ -260,20 +115,14 @@ Synchronizer two local directories\&.
 .sp -1
 .IP \(bu 2.3
 .\}
-csync /home/user smb://server/share/user
+ocsync /home/user smb://server/share/user
 .sp
 .if n \{\
 .RS 4
 .\}
-.fam C
-.ps -1
 .nf
-.BB lightgray
 Synchronize a home directory with a SMB share\&.
-.EB lightgray
 .fi
-.fam
-.ps +1
 .if n \{\
 .RE
 .\}
@@ -287,21 +136,15 @@ Synchronize a home directory with a SMB share\&.
 .sp -1
 .IP \(bu 2.3
 .\}
-csync /home/user smb://user:password@server/share/user
+ocsync /home/user smb://user:password@server/share/user
 .sp
 .if n \{\
 .RS 4
 .\}
-.fam C
-.ps -1
 .nf
-.BB lightgray
 Synchronize a home directory with a SMB share and provide username and
 password directly\&.
-.EB lightgray
 .fi
-.fam
-.ps +1
 .if n \{\
 .RE
 .\}
@@ -311,10 +154,30 @@ password directly\&.
 Please report bugs at https://dev\&.csync\&.org/\&.
 .SH "SEE ALSO"
 .sp
-\fBlibcsync\fR(7)
+\fBlibocsync\fR(7)
 .SH "AUTHORS"
 .sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
 Andreas Schneider <mail at cynapses\&.org>
+.RE
+.sp
+.RS 4
+.ie n \{\
+\h'-04'\(bu\h'+03'\c
+.\}
+.el \{\
+.sp -1
+.IP \(bu 2.3
+.\}
+Klaas Freitag <freitag at owncloud\&.com>
+.RE
 .SH "COPYING"
 .sp
 Copyright \e(c) 2006\-2008 Andreas Schneider\&. Free use of this software is granted under the terms of the GNU General Public License (GPL)\&.
diff --git a/doc/ocsync.1.txt b/doc/ocsync.1.txt
index a00dc84..9364d46 100644
--- a/doc/ocsync.1.txt
+++ b/doc/ocsync.1.txt
@@ -1,27 +1,27 @@
-csync(1)
+ocsync(1)
 ========
 
 NAME
 ----
 
-csync - A commandline frontent for csync a user level bidirectional file
+ocsync - A commandline frontent for csync a user level bidirectional file
 synchronizer.
 
 
 SYNOPSIS
 --------
 
-*csync* ['OPTION'...] 'SOURCE' 'DESTINATION'
+*ocsync* ['OPTION'...] 'SOURCE' 'DESTINATION'
 
 
 DESCRIPTION
 -----------
 
-csync is a client only bidirectional file synchronizer. It synchronizes the
+ocsync is a client only bidirectional file synchronizer. It synchronizes the
 content of 'SOURCE' with 'DESTINATION' and vice versa. The 'DESTINATION' can
 be a local directory or a remote file server.
 
-You can use csync for different things. The intention is to provide Roaming
+You can use ocsync for different things. The intention is to provide Roaming
 Home Directories for Linux but you can use it to synchronize your music
 collection or create a backup of a directory.
 
@@ -66,15 +66,15 @@ EXIT STATUS
 EXAMPLES
 --------
 
-* csync /home/user /backup/home/user
+* ocsync /home/user /backup/home/user
 
   Synchronizer two local directories.
 
-* csync /home/user smb://server/share/user
+* ocsync /home/user smb://server/share/user
 
   Synchronize a home directory with a SMB share.
 
-* csync /home/user smb://user:password@server/share/user
+* ocsync /home/user smb://user:password@server/share/user
 
   Synchronize a home directory with a SMB share and provide username and
   password directly.
@@ -88,14 +88,14 @@ Please report bugs at https://dev.csync.org/.
 SEE ALSO
 --------
 
-*libcsync*(7)
+*libocsync*(7)
 
 
 AUTHORS
 -------
 
-Andreas Schneider <mail at cynapses.org>
-
+* Andreas Schneider <mail at cynapses.org>
+* Klaas Freitag <freitag at owncloud.com>
 
 COPYING
 -------
diff --git a/doc/ocsync.txt b/doc/ocsync.txt
index a971624..7d314f8 100644
--- a/doc/ocsync.txt
+++ b/doc/ocsync.txt
@@ -157,7 +157,7 @@ filesystem operation.
 
 In the first phase we copy the file to a temporary file on the opposite
 replica. This has the advantage that we can check if the file which has been
-copied to the opposite replica has been transfered successfully. If the
+copied to the opposite replica has been transferred successfully. If the
 connection gets interrupted during the transfer we still have the original
 states of the file. This means no data will be lost.
 
diff --git a/doc/userguide/csync.html b/doc/userguide/csync.html
index a9aa01c..8cbab60 100644
--- a/doc/userguide/csync.html
+++ b/doc/userguide/csync.html
@@ -933,7 +933,7 @@ calculated records to apply them on the current replica.</p></div>
 filesystem operation.</p></div>
 <div class="paragraph"><p>In the first phase we copy the file to a temporary file on the opposite
 replica. This has the advantage that we can check if the file which has been
-copied to the opposite replica has been transfered successfully. If the
+copied to the opposite replica has been transferred successfully. If the
 connection gets interrupted during the transfer we still have the original
 states of the file. This means no data will be lost.</p></div>
 <div class="paragraph"><p>In the second phase the file on the opposite replica will be overwritten by
diff --git a/modules/csync_owncloud.c b/modules/csync_owncloud.c
index a37c6e0..cec0e17 100644
--- a/modules/csync_owncloud.c
+++ b/modules/csync_owncloud.c
@@ -1099,6 +1099,13 @@ static const char* owncloud_file_id( const char *path )
             cbuf = c_strdup(header);
         }
     }
+
+    /* fix server problem: If we end up with an empty string, set something strange... */
+    if( c_streq(cbuf, "") || c_streq(cbuf, "\"\"") ) {
+        SAFE_FREE(cbuf);
+        cbuf = c_strdup("empty_etag");
+    }
+
     DEBUG_WEBDAV("Get file ID for %s: %s", path, cbuf ? cbuf:"<null>");
     if( fs ) csync_vio_file_stat_destroy(fs);
     if( req ) ne_request_destroy(req);
@@ -1385,48 +1392,63 @@ static int owncloud_sendfile(csync_vio_method_handle_t *src, csync_vio_method_ha
         ne_hook_post_headers( dav_session.ctx, install_content_reader, write_ctx );
 
         neon_stat = ne_request_dispatch(write_ctx->req );
+
+        /* delete the hook again, otherwise they get chained as they are with the session */
+        ne_unhook_post_headers( dav_session.ctx, install_content_reader, write_ctx );
+
+        /* if the compression handle is set through the post_header hook, delete it. */
+        if( write_ctx->decompress ) {
+            ne_decompress_destroy( write_ctx->decompress );
+        }
         /* possible return codes are:
          *  NE_OK, NE_AUTH, NE_CONNECT, NE_TIMEOUT, NE_ERROR (from ne_request.h)
          */
 
+        status = ne_get_status( write_ctx->req );
+
         if( neon_stat != NE_OK ) {
-            if (neon_stat == NE_TIMEOUT && (++retry) < 3)
+            /* If a timeout happened try again for three times */
+            if (neon_stat == NE_TIMEOUT && (++retry) < 3) {
                 continue;
+            }
 
             set_errno_from_neon_errcode(neon_stat);
             DEBUG_WEBDAV("Error GET: Neon: %d, errno %d", neon_stat, errno);
             error_code = errno;
+            if( status != NULL ) {
+                SAFE_FREE(dav_session.error_string);
+                dav_session.error_string = c_strdup(status->reason_phrase);
+            }
             rc = 1;
         } else {
-            status = ne_get_status( write_ctx->req );
-            DEBUG_WEBDAV("GET http result %d (%s)", status->code, status->reason_phrase ? status->reason_phrase : "<empty");
-            if( status->klass != 2 ) {
-                DEBUG_WEBDAV("sendfile request failed with http status %d!", status->code);
-                set_errno_from_http_errcode( status->code );
-                /* decide if soft error or hard error that stops the whole sync. */
-                /* Currently all problems concerning one file are soft errors */
-                if( status->klass == 4 /* Forbidden and stuff, soft error */ ) {
-                    rc = 1;
-                } else if( status->klass == 5 /* Server errors and such */ ) {
-                    rc = 1; /* No Abort on individual file errors. */
+            if( status != NULL ) {
+                DEBUG_WEBDAV("GET http result %d (%s)", status->code, status->reason_phrase ? status->reason_phrase : "<empty");
+                if( status->klass != 2 ) {
+                    DEBUG_WEBDAV("sendfile request failed with http status %d!", status->code);
+                    set_errno_from_http_errcode( status->code );
+                    /* decide if soft error or hard error that stops the whole sync. */
+                    /* Currently all problems concerning one file are soft errors */
+                    if( status->klass == 4 /* Forbidden and stuff, soft error */ ) {
+                        rc = 1;
+                    } else if( status->klass == 5 /* Server errors and such */ ) {
+                        rc = 1; /* No Abort on individual file errors. */
+                    } else {
+                        rc = 1;
+                    }
+                    error_code = status->code;
+                    SAFE_FREE(dav_session.error_string);
+                    dav_session.error_string = c_strdup(status->reason_phrase);
                 } else {
-                    rc = 1;
+                    DEBUG_WEBDAV("http request all cool, result code %d", status->code);
                 }
-                error_code = status->code;
-                SAFE_FREE(dav_session.error_string);
-                dav_session.error_string = c_strdup(status->reason_phrase);
             } else {
-                DEBUG_WEBDAV("http request all cool, result code %d", status->code);
+                /* No status but still a problem */
+                DEBUG_WEBDAV("GET failed, but no neon status available.");
+                error_code = 400;
+                rc = 1;
             }
         }
 
-        /* delete the hook again, otherwise they get chained as they are with the session */
-        ne_unhook_post_headers( dav_session.ctx, install_content_reader, write_ctx );
-
-        /* if the compression handle is set through the post_header hook, delete it. */
-        if( write_ctx->decompress ) {
-            ne_decompress_destroy( write_ctx->decompress );
-        }
         break;
       } while (1);
 
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index f64ef32..5dfca9d 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -79,7 +79,7 @@ set(csync_SRCS
   vio/csync_vio_local.c
 )
 
-configure_file(csync_version.h.in csync_version.h)
+configure_file(csync_version.h.in ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h)
 
 set(csync_HDRS
   ${CMAKE_CURRENT_BINARY_DIR}/csync_version.h
diff --git a/src/csync_exclude.c b/src/csync_exclude.c
index 792d36c..d75b291 100644
--- a/src/csync_exclude.c
+++ b/src/csync_exclude.c
@@ -129,14 +129,15 @@ void csync_exclude_destroy(CSYNC *ctx) {
   c_strlist_destroy(ctx->excludes);
 }
 
-CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path) {
-  size_t i;
-  const char *p;
-  char *bname;
-  int rc;
+CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype) {
+  size_t i = 0;
+  const char *p = NULL;
+  char *bname = NULL;
+  char *dname = NULL;
+  char *prev_dname = NULL;
+  int rc = -1;
   CSYNC_EXCLUDE_TYPE match = CSYNC_NOT_EXCLUDED;
   CSYNC_EXCLUDE_TYPE type  = CSYNC_NOT_EXCLUDED;
-  const char *it;
 
   /* exclude the lock file */
   if (c_streq( path, CSYNC_LOCK_FILE )) {
@@ -161,43 +162,112 @@ CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path) {
     }
   }
 
+  /* split up the path */
+  dname = c_dirname(path);
   bname = c_basename(path);
-  if (bname == NULL) {
-      return CSYNC_NOT_EXCLUDED;
+
+  if (bname == NULL || dname == NULL) {
+      match = CSYNC_NOT_EXCLUDED;
+      SAFE_FREE(bname);
+      SAFE_FREE(dname);
+      goto out;
   }
 
   rc = csync_fnmatch(".csync_journal.db*", bname, 0);
   if (rc == 0) {
       match = CSYNC_FILE_SILENTLY_EXCLUDED;
+      SAFE_FREE(bname);
+      SAFE_FREE(dname);
       goto out;
   }
+  SAFE_FREE(bname);
+  SAFE_FREE(dname);
 
   if (ctx->excludes == NULL) {
       goto out;
   }
 
+  /* Loop over all exclude patterns and evaluate the given path */
   for (i = 0; match == CSYNC_NOT_EXCLUDED && i < ctx->excludes->count; i++) {
-      it = ctx->excludes->vector[i];
+      bool match_dirs_only = false;
+      char *pattern_stored = c_strdup(ctx->excludes->vector[i]);
+      char* pattern = pattern_stored;
+
       type = CSYNC_FILE_EXCLUDE_LIST;
+      if (strlen(pattern) < 1) {
+          continue;
+      }
       /* Ecludes starting with ']' means it can be cleanup */
-      if (it[0] == ']') {
-        ++it;
-        type = CSYNC_FILE_EXCLUDE_AND_REMOVE;
+      if (pattern[0] == ']') {
+          ++pattern;
+          if (filetype == CSYNC_FTW_TYPE_FILE) {
+              type = CSYNC_FILE_EXCLUDE_AND_REMOVE;
+          }
+      }
+      /* Check if the pattern applies to pathes only. */
+      if (pattern[strlen(pattern)-1] == '/') {
+          match_dirs_only = true;
+          pattern[strlen(pattern)-1] = '\0'; /* Cut off the slash */
       }
 
-      rc = csync_fnmatch(it, path, 0);
-      if (rc == 0) {
-          match = type;
+      /* check if the pattern contains a / and if, compare to the whole path */
+      if (strchr(pattern, '/')) {
+          rc = csync_fnmatch(pattern, path, FNM_PATHNAME);
+          if( rc == 0 ) {
+              match = type;
+          }
+          /* if the pattern requires a dir, but path is not, its still not excluded. */
+          if (match_dirs_only && filetype != CSYNC_FTW_TYPE_DIR) {
+              match = CSYNC_NOT_EXCLUDED;
+          }
       }
 
-      rc = csync_fnmatch(it, bname, 0);
-      if (rc == 0) {
-          match = type;
+      /* if still not excluded, check each component of the path */
+      if (match == CSYNC_NOT_EXCLUDED) {
+          int trailing_component = 1;
+          dname = c_dirname(path);
+          bname = c_basename(path);
+
+          if (bname == NULL || dname == NULL) {
+              match = CSYNC_NOT_EXCLUDED;
+              goto out;
+          }
+
+          /* Check each component of the path */
+          do {
+              /* Do not check the bname if its a file and the pattern matches dirs only. */
+              if ( !(trailing_component == 1 /* it is the trailing component */
+                     && match_dirs_only      /* but only directories are matched by the pattern */
+                     && filetype == CSYNC_FTW_TYPE_FILE) ) {
+                  /* Check the name component against the pattern */
+                  rc = csync_fnmatch(pattern, bname, 0);
+                  if (rc == 0) {
+                      match = type;
+                  }
+              }
+              if (!(c_streq(dname, ".") || c_streq(dname, "/"))) {
+                  rc = csync_fnmatch(pattern, dname, 0);
+                  if (rc == 0) {
+                      match = type;
+                  }
+              }
+              trailing_component = 0;
+              prev_dname = dname;
+              SAFE_FREE(bname);
+              bname = c_basename(prev_dname);
+              dname = c_dirname(prev_dname);
+              SAFE_FREE(prev_dname);
+
+          } while( match == CSYNC_NOT_EXCLUDED && !c_streq(dname, ".")
+                     && !c_streq(dname, "/") );
       }
+      SAFE_FREE(pattern_stored);
+      SAFE_FREE(bname);
+      SAFE_FREE(dname);
   }
 
 out:
-  free(bname);
+
   return match;
 }
 
diff --git a/src/csync_exclude.h b/src/csync_exclude.h
index fdafc5f..c2c6729 100644
--- a/src/csync_exclude.h
+++ b/src/csync_exclude.h
@@ -63,7 +63,7 @@ void csync_exclude_destroy(CSYNC *ctx);
  *
  * @return  2 if excluded and needs cleanup, 1 if excluded, 0 if not.
  */
-CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path);
+CSYNC_EXCLUDE_TYPE csync_excluded(CSYNC *ctx, const char *path, int filetype);
 
 #endif /* _CSYNC_EXCLUDE_H */
 
diff --git a/src/csync_misc.c b/src/csync_misc.c
index 6d6f97b..6a22f28 100644
--- a/src/csync_misc.c
+++ b/src/csync_misc.c
@@ -147,6 +147,7 @@ int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) {
 #include <shlwapi.h>
 int csync_fnmatch(__const char *__pattern, __const char *__name, int __flags) {
     (void) __flags;
+    /* FIXME check if we rather should use the PathMatchSpecW variant here? */
     if(PathMatchSpec(__name, __pattern))
         return 0;
     else
diff --git a/src/csync_misc.h b/src/csync_misc.h
index 36867c9..40648ed 100644
--- a/src/csync_misc.h
+++ b/src/csync_misc.h
@@ -21,8 +21,19 @@
 #ifndef _CSYNC_MISC_H
 #define _CSYNC_MISC_H
 
+#include "config.h"
 #include "csync.h"
 
+#ifdef HAVE_FNMATCH
+#include <fnmatch.h>
+#else
+/* Steal this define to make csync_exclude compile. Note that if fnmatch
+ * is not defined it's probably Win32 which uses a different implementation
+ * than fmmatch anyway, which does not care for flags.
+ **/
+#define FNM_PATHNAME    (1 << 0) /* No wildcard can ever match `/'.  */
+#endif
+
 char *csync_get_user_home_dir(void);
 char *csync_get_local_username(void);
 
diff --git a/src/csync_propagate.c b/src/csync_propagate.c
index 767a69e..8c09858 100644
--- a/src/csync_propagate.c
+++ b/src/csync_propagate.c
@@ -68,7 +68,7 @@ static void _csync_file_stat_set_error(csync_file_stat_t *st, const char *error)
     st->error_string = c_strdup(error);
 }
 
-/* Recursively mark the parent flder as an error */
+/* Recursively mark the parent folder as an error */
 static void _csync_report_parent_error(CSYNC *ctx, csync_file_stat_t *st) {
     const char *dir = NULL;
     uint64_t h;
diff --git a/src/csync_propagate.h b/src/csync_propagate.h
index 088a36a..3745385 100644
--- a/src/csync_propagate.h
+++ b/src/csync_propagate.h
@@ -34,7 +34,7 @@
  *
  * In the first phase we copy the file to a temporary file on the opposite
  * replica. This has the advantage that we can check if file which has been
- * copied to the opposite replica has been transfered successfully. If the
+ * copied to the opposite replica has been transferred successfully. If the
  * connection gets interrupted during the transfer we still have the original
  * states of the file. This means no data will be lost.
  *
diff --git a/src/csync_update.c b/src/csync_update.c
index 917c619..e667d29 100644
--- a/src/csync_update.c
+++ b/src/csync_update.c
@@ -117,7 +117,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
   len = strlen(path);
 
   /* Check if file is excluded */
-  excluded = csync_excluded(ctx, path);
+  excluded = csync_excluded(ctx, path,type);
   if (excluded != CSYNC_NOT_EXCLUDED) {
     CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "%s excluded  (%d)", path, excluded);
     if (excluded == CSYNC_FILE_EXCLUDE_AND_REMOVE) {
@@ -195,18 +195,7 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
    */
   if (csync_get_statedb_exists(ctx)) {
     tmp = csync_statedb_get_stat_by_hash(ctx, h);
-#if 0
-    /* this code could possibly replace the one in csync_vio.c stat and would be more efficient */
-    if(tmp) {
-        if( ctx->current == LOCAL_REPLICA ) {
-            if(fs->mtime == tmp->modtime && fs->size == tmp->size) {
-                /* filesystem modtime is still the same as the db mtime
-                 * thus the md5 sum is still valid. */
-                fs->md5 = c_strdup( tmp->md5 );
-            }
-        }
-    }
-#endif
+
     if(tmp && tmp->phash == h ) { /* there is an entry in the database */
         /* we have an update! */
         CSYNC_LOG(CSYNC_LOG_PRIORITY_TRACE, "Database entry found, compare: %" PRId64 " <-> %" PRId64 ", md5: %s <-> %s, inode: %" PRId64 " <-> %" PRId64,
@@ -216,8 +205,22 @@ static int _csync_detect_update(CSYNC *ctx, const char *file,
             goto out;
         }
         if((ctx->current == REMOTE_REPLICA && !c_streq(fs->md5, tmp->md5 ))
-            || (ctx->current == LOCAL_REPLICA && (fs->mtime != tmp->modtime || fs->inode != tmp->inode))) {
-            // if (!fs->mtime > tmp->modtime) {
+            || (ctx->current == LOCAL_REPLICA && (fs->mtime != tmp->modtime
+#ifndef _WIN32
+                                                  || fs->inode != tmp->inode
+#endif
+                                                  ))) {
+            /* Comparison of the local inode is disabled because people reported problems
+             * on windows with flacky inode values, see github bug #779
+             *
+             * The inode needs to be observed because:
+             * $>  echo a > a.txt ; echo b > b.txt
+             * both files have the same mtime
+             * sync them.
+             * $> rm a.txt && mv b.txt a.txt
+             * makes b.txt appearing as a.txt yet a sync is not performed because
+             * both have the same modtime as mv does not change that.
+             */
             st->instruction = CSYNC_INSTRUCTION_EVAL;
             goto out;
         }
diff --git a/src/csync_util.c b/src/csync_util.c
index cc6cef6..9ac9b9a 100644
--- a/src/csync_util.c
+++ b/src/csync_util.c
@@ -153,12 +153,15 @@ static int _merge_file_trees_visitor(void *obj, void *data) {
       goto out;
     }
     new_stat = memcpy(new_stat, fs, sizeof(csync_file_stat_t) + fs->pathlen + 1);
-    if (fs->md5)
+    if (fs->md5) {
         new_stat->md5 = c_strdup(fs->md5);
-    if (fs->destpath)
+    }
+    if (fs->destpath) {
         new_stat->destpath = c_strdup(fs->destpath);
-    if (fs->error_string)
+    }
+    if (fs->error_string) {
         new_stat->error_string = c_strdup(fs->error_string);
+    }
 
     if (c_rbtree_insert(tree, new_stat) < 0) {
       C_STRERROR(errno, errbuf, sizeof(errbuf));
diff --git a/src/httpbf/src/httpbf.c b/src/httpbf/src/httpbf.c
index aeed142..83c9466 100644
--- a/src/httpbf/src/httpbf.c
+++ b/src/httpbf/src/httpbf.c
@@ -184,7 +184,7 @@ Hbf_State hbf_splitlist(hbf_transfer_t *transfer, int fd ) {
           /* store the block data into the result array in the transfer */
           *((transfer->block_arr)+cnt) = block;
 
-          DEBUG_HBF("hbf_splitlist: created block %d   (start: %" PRId64 "  size: %" PRId64 ")\n", cnt, block->start, block->size );
+          DEBUG_HBF("hbf_splitlist: created block %d   (start: %" PRId64 "  size: %" PRId64 ")", cnt, block->start, block->size );
       }
 
 #ifndef NDEBUG
@@ -285,7 +285,7 @@ static int _hbf_dav_request(hbf_transfer_t *transfer, ne_request *req, int fd, h
     if( ! (blk && req) ) return HBF_PARAM_FAIL;
 
     ne_set_request_body_fd(req, fd, blk->start, blk->size);
-    DEBUG_HBF("HBF: Block: %d , Start: %" PRId64 " and Size: %" PRId64 "\n", blk->seq_number, blk->start, blk->size );
+    DEBUG_HBF("HBF: Block: %d , Start: %" PRId64 " and Size: %" PRId64 "", blk->seq_number, blk->start, blk->size );
     res = ne_request_dispatch(req);
 
     req_status = ne_get_status( req );
@@ -311,6 +311,8 @@ static int _hbf_dav_request(hbf_transfer_t *transfer, ne_request *req, int fd, h
                 } else {
                     blk->etag = strdup( etag );
                 }
+            } else {
+                /* DEBUG_HBF("OOOOOOOO No etag returned!"); */
             }
         }
         break;
@@ -503,6 +505,10 @@ Hbf_State hbf_transfer( ne_session *session, hbf_transfer_t *transfer, const cha
     /* do the source file validation finally (again). */
     if( state == HBF_SUCCESS ) {
         state = validate_source_file(transfer);
+    } else if( state == HBF_TRANSFER_SUCCESS ) {
+        /* This means that no etag was returned on one of the chunks to indicate
+         * that the upload was finished. */
+        state = HBF_TRANSFER_NOT_ACKED;
     }
 
     return state;
@@ -537,7 +543,7 @@ const char *hbf_error_string(hbf_transfer_t *transfer, Hbf_State state)
         re = "Block was not yet tried to transfer.";
         break;
     case HBF_TRANSFER:         /* transfer currently running  */
-        re = "Block is currently transfered.";
+        re = "Block is currently transferred.";
         break;
     case HBF_TRANSFER_FAILED:  /* transfer tried but failed   */
         re = "Block transfer failed.";
@@ -572,10 +578,18 @@ const char *hbf_error_string(hbf_transfer_t *transfer, Hbf_State state)
     case HBF_MEMORY_FAIL:
         re = "Out of memory.";
         break;
+    case HBF_STAT_FAIL:
+        re = "Filesystem stat on file failed.";
+        break;
     case HBF_SOURCE_FILE_CHANGE:
       re = "Source file changed too often during upload.";
       break;
-
+    case HBF_USER_ABORTED:
+        re = "Transmission aborted by user.";
+        break;
+    case HBF_TRANSFER_NOT_ACKED:
+        re = "The server did not provide an Etag.";
+        break;
     case HBF_FAIL:
     default:
         for( cnt = 0; cnt < transfer->block_cnt; cnt++ ) {
diff --git a/src/httpbf/src/httpbf.h b/src/httpbf/src/httpbf.h
index fb379fa..e621ffa 100644
--- a/src/httpbf/src/httpbf.h
+++ b/src/httpbf/src/httpbf.h
@@ -52,6 +52,7 @@ enum hbf_state_e {
     HBF_STAT_FAIL,
     HBF_SOURCE_FILE_CHANGE,
     HBF_USER_ABORTED,
+    HBF_TRANSFER_NOT_ACKED,
     HBF_FAIL
 };
 
diff --git a/tests/csync_tests/check_csync_exclude.c b/tests/csync_tests/check_csync_exclude.c
index dab7492..9e96bd6 100644
--- a/tests/csync_tests/check_csync_exclude.c
+++ b/tests/csync_tests/check_csync_exclude.c
@@ -75,35 +75,79 @@ static void check_csync_excluded(void **state)
     CSYNC *csync = *state;
     int rc;
 
-    rc = csync_excluded(csync, ".kde/share/config/kwin.eventsrc");
+    rc = csync_excluded(csync, "krawel_krawel", CSYNC_FTW_TYPE_FILE);
     assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
-    rc = csync_excluded(csync, ".kde4/cache-maximegalon/cache1.txt");
+    rc = csync_excluded(csync, ".kde/share/config/kwin.eventsrc", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
+    rc = csync_excluded(csync, ".kde4/cache-maximegalon/cache1.txt", CSYNC_FTW_TYPE_FILE);
     assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
-    rc = csync_excluded(csync, ".mozilla/plugins");
+    rc = csync_excluded(csync, ".mozilla/plugins", CSYNC_FTW_TYPE_DIR);
     assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
 
     /*
      * Test for patterns in subdirs. '.beagle' is defined as a pattern and has
      * to be found in top dir as well as in directories underneath.
      */
-    rc = csync_excluded(csync, ".beagle");
+    rc = csync_excluded(csync, ".beagle", CSYNC_FTW_TYPE_DIR);
     assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
-    rc = csync_excluded(csync, "foo/.beagle");
+    rc = csync_excluded(csync, "foo/.beagle", CSYNC_FTW_TYPE_DIR);
     assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
-    rc = csync_excluded(csync, "foo/bar/.beagle");
+    rc = csync_excluded(csync, "foo/bar/.beagle", CSYNC_FTW_TYPE_DIR);
     assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
 
-    rc = csync_excluded(csync, ".csync_journal.db");
+    /*
+     * Pattern: .java/
+     * A file wont be excluded but a directory .java will be.
+     */
+    rc = csync_excluded(csync, ".java", CSYNC_FTW_TYPE_DIR);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
+    rc = csync_excluded(csync, ".java", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
+
+    /* Files in the ignored dir .java will also be ignored. */
+    rc = csync_excluded(csync, ".java/totally_amazing.jar", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
+
+    /* and also in subdirs */
+    rc = csync_excluded(csync, "projects/.java/totally_amazing.jar", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
+
+    /* csync-journal is ignored in general silently. */
+    rc = csync_excluded(csync, ".csync_journal.db", CSYNC_FTW_TYPE_FILE);
     assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
-    rc = csync_excluded(csync, ".csync_journal.db.ctmp");
+    rc = csync_excluded(csync, ".csync_journal.db.ctmp", CSYNC_FTW_TYPE_FILE);
     assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
-    rc = csync_excluded(csync, "subdir/.csync_journal.db");
+    rc = csync_excluded(csync, "subdir/.csync_journal.db", CSYNC_FTW_TYPE_FILE);
     assert_int_equal(rc, CSYNC_FILE_SILENTLY_EXCLUDED);
 
-    rc = csync_excluded(csync, "my.directory");
+    /* pattern ]*.directory - ignore and remove */
+    rc = csync_excluded(csync, "my.directory", CSYNC_FTW_TYPE_FILE);
     assert_int_equal(rc, CSYNC_FILE_EXCLUDE_AND_REMOVE);
+
+    rc = csync_excluded(csync, "/a_folder/my.directory", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_AND_REMOVE);
+
+    /* Not excluded because the pattern .netscape/cache requires directory. */
+    rc = csync_excluded(csync, ".netscape/cache", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_NOT_EXCLUDED);
+
+    rc = csync_excluded(csync, ".netscape/cache", CSYNC_FTW_TYPE_DIR);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
+
+    /* Excluded because the parent dir .netscape/cache is ingored. */
+    rc = csync_excluded(csync, ".netscape/cache/foo", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
+
+    rc = csync_excluded(csync, ".netscape/cache/bar.txt", CSYNC_FTW_TYPE_FILE);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
+
+    rc = csync_excluded(csync, ".netscape/cache/longrun", CSYNC_FTW_TYPE_DIR);
+    assert_int_equal(rc, CSYNC_FILE_EXCLUDE_LIST);
+
+
 }
 
+
 int torture_run_tests(void)
 {
     const UnitTest tests[] = {

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-owncloud/ocsync.git



More information about the Pkg-owncloud-commits mailing list