Hello. This is Debian Bug #1005943 and this is the full URL for the bug:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1005943
Follows a summary of the bug
Marcin Owsiany writes:
How to reproduce:
Prep phase:
porridge@butla:~/tmp$ mkdir dir
porridge@butla:~/tmp$ echo foo > dir/file
porridge@butla:~/tmp$ ln -s file dir/link
porridge@butla:~/tmp$ find dir -ls
50725398 4 drwxrwxr-x 2 porridge porridge 4096 lut 17 18:01 dir
50725399 4 -rw-rw-r-- 1 porridge porridge 4 lut 17 18:01 dir/file
50725400 0 lrwxrwxrwx 1 porridge porridge 4 lut 17 18:01 dir/link -> file
porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir
adding: dir/ (in=0) (out=0) (stored 0%)
adding: dir/file (in=4) (out=4) (stored 0%)
adding: dir/link (in=4) (out=4) (stored 0%)
total bytes=8, compressed=8 -> 0% savings
porridge@butla:~/tmp$
So far so good, now the unexpected part:
porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir
ok: dir/
ok: dir/file
updating: dir/link (in=4) (out=4) (stored 0%)
total bytes=8, compressed=8 -> 0% savings
porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir
ok: dir/
ok: dir/file
updating: dir/link (in=4) (out=4) (stored 0%)
total bytes=8, compressed=8 -> 0% savings
porridge@butla:~/tmp$
As you can see, the symlink is always considered to be in need of update.
While the expected behaviour would be:
porridge@butla:~/tmp$ zip --verbose --symlink --recurse-paths --filesync dir.zip dir
Archive is current
porridge@butla:~/tmp$
I managed to produce the following patch which seems to fix the issue. It
basically changes the UNIX-specific implementation of the filetime() function to retrieve the size not just for regular files, but also for symlinks. This way the `current` flag is set to 1 in zip.c:6018 like for regular files.
The above (expected) behaviour is for a zip package built with this patch.
--- zip-3.0.orig/unix/unix.c
+++ zip-3.0/unix/unix.c
@@ -423,7 +423,7 @@ ulg filetime(f, a, n, t)
}
}
if (n != NULL)
- *n = (s.st_mode & S_IFMT) == S_IFREG ? s.st_size : -1L;
+ *n = ((s.st_mode & S_IFMT) == S_IFREG || (s.st_mode & S_IFMT) == S_IFLNK) ? s.st_size : -1L;
if (t != NULL) {
t->atime = s.st_atime;
t->mtime = s.st_mtime;