Hello community, here is the log from the commit of package archivemount for openSUSE:Factory checked in at 2015-11-12 19:41:28 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/archivemount (Old) and /work/SRC/openSUSE:Factory/.archivemount.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "archivemount" Changes: -------- --- /work/SRC/openSUSE:Factory/archivemount/archivemount.changes 2015-03-25 10:00:28.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.archivemount.new/archivemount.changes 2015-11-12 19:41:34.000000000 +0100 @@ -1,0 +2,8 @@ +Wed Nov 11 18:44:05 UTC 2015 - [email protected] + +- Update to version 0.8.5 + * FormatRaw optimization + * bugfix : use of off_t to support 64bits +- Update archivemount-0.8.4.dif > archivemount.dif + +------------------------------------------------------------------- Old: ---- archivemount-0.8.4.dif archivemount-0.8.4.tar.gz New: ---- archivemount-0.8.5.tar.gz archivemount.dif ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ archivemount.spec ++++++ --- /var/tmp/diff_new_pack.AqXHeZ/_old 2015-11-12 19:41:35.000000000 +0100 +++ /var/tmp/diff_new_pack.AqXHeZ/_new 2015-11-12 19:41:35.000000000 +0100 @@ -17,14 +17,14 @@ Name: archivemount -Version: 0.8.4 +Version: 0.8.5 Release: 0 Summary: Mounts an archive for access as a file system License: LGPL-2.1+ and BSD-2-Clause Group: Productivity/Archiving/Compression Url: http://www.cybernoia.de/software/archivemount/ Source: http://www.cybernoia.de/software/archivemount/%{name}-%{version}.tar.gz -Patch0: archivemount-%{version}.dif +Patch0: archivemount.dif BuildRequires: autoconf BuildRequires: automake BuildRequires: fuse-devel ++++++ archivemount-0.8.4.tar.gz -> archivemount-0.8.5.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/archivemount-0.8.4/CHANGELOG new/archivemount-0.8.5/CHANGELOG --- old/archivemount-0.8.4/CHANGELOG 2015-02-27 11:13:29.000000000 +0100 +++ new/archivemount-0.8.5/CHANGELOG 2015-06-28 18:04:43.000000000 +0200 @@ -1,3 +1,7 @@ +* 0.8.5 - fixed stat'ing of hardlinks in ar_readdir + - contributions by Alain Parmentier: + * FormatRaw optimization + * bugfix : use of off_t to support 64bits * 0.8.4 - added option -o formatraw for readonly support of the FormatRaw archive files supported by libarchive (kudos to Lee Leahu) - bugfix: do not do the fuse mount when the archive cannot be read diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/archivemount-0.8.4/Makefile.am new/archivemount-0.8.5/Makefile.am --- old/archivemount-0.8.4/Makefile.am 2013-10-20 12:52:39.000000000 +0200 +++ new/archivemount-0.8.5/Makefile.am 2015-06-27 18:47:35.000000000 +0200 @@ -1,7 +1,7 @@ bin_PROGRAMS = archivemount archivemount_SOURCES = archivemount.c uthash.h archivemount_LDADD = $(ARCHIVE_LIBS) $(FUSE_LIBS) -archivemount_CFLAGS = $(FUSE_CFLAGS) +archivemount_CFLAGS = $(FUSE_CFLAGS) -D_FILE_OFFSET_BITS=64 if DEBUG archivemount_CFLAGS += -g else diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/archivemount-0.8.4/Makefile.in new/archivemount-0.8.5/Makefile.in --- old/archivemount-0.8.4/Makefile.in 2015-02-27 11:07:24.000000000 +0100 +++ new/archivemount-0.8.5/Makefile.in 2015-06-27 18:48:09.000000000 +0200 @@ -307,7 +307,8 @@ top_srcdir = @top_srcdir@ archivemount_SOURCES = archivemount.c uthash.h archivemount_LDADD = $(ARCHIVE_LIBS) $(FUSE_LIBS) -archivemount_CFLAGS = $(FUSE_CFLAGS) $(am__append_1) $(am__append_2) +archivemount_CFLAGS = $(FUSE_CFLAGS) -D_FILE_OFFSET_BITS=64 \ + $(am__append_1) $(am__append_2) dist_man_MANS = archivemount.1 EXTRA_DIST = CHANGELOG all: config.h diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/archivemount-0.8.4/archivemount.1 new/archivemount-0.8.5/archivemount.1 --- old/archivemount-0.8.4/archivemount.1 2015-02-27 11:19:19.000000000 +0100 +++ new/archivemount-0.8.5/archivemount.1 2015-06-28 18:06:51.000000000 +0200 @@ -1,7 +1,7 @@ \" Process this file with .\" groff -man -Tascii archivemount.1 .\" -.TH ARCHIVEMOUNT "1" "15 August 2013" "ARCHIVEMOUNT version 0.8.4" "User Commands" +.TH ARCHIVEMOUNT "1" "15 August 2013" "ARCHIVEMOUNT version 0.8.5" "User Commands" .SH NAME archivemount \- mounts an archive for access as a file system .SH SYNOPSIS diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/archivemount-0.8.4/archivemount.c new/archivemount-0.8.5/archivemount.c --- old/archivemount-0.8.4/archivemount.c 2015-02-27 11:16:23.000000000 +0100 +++ new/archivemount-0.8.5/archivemount.c 2015-06-28 18:03:24.000000000 +0200 @@ -8,9 +8,12 @@ Based on: fusexmp.c and sshfs.c by Miklos Szeredi <[email protected]> Contributions by: Niels de Vos <[email protected]> - Thomas J. Duck - Andrew Brampton <me at bramp dot net> - + Thomas J. Duck + Andrew Brampton <me at bramp dot net> + Tomáš Čech <sleep_walker at suse dot cz> + Timothy Hobbs <timothyhobbs at seznam dot cz> + Lee Leahu + Alain Parmentier <pa at infodata.lu> */ #ifdef linux @@ -90,8 +93,14 @@ int formatraw; }; -enum -{ +typedef struct formatraw_cache { + struct stat st; + struct archive *archive; + int opened; + off_t offset_uncompressed; +} FORMATRAW_CACHE; + +enum { KEY_VERSION, KEY_HELP, }; @@ -106,10 +115,10 @@ AR_OPT("subtree=%s", subtree_filter, 1), AR_OPT("formatraw", formatraw, 1), - FUSE_OPT_KEY("-V", KEY_VERSION), + FUSE_OPT_KEY("-V", KEY_VERSION), FUSE_OPT_KEY("--version", KEY_VERSION), - FUSE_OPT_KEY("-h", KEY_HELP), - FUSE_OPT_KEY("--help", KEY_HELP), + FUSE_OPT_KEY("-h", KEY_HELP), + FUSE_OPT_KEY("--help", KEY_HELP), FUSE_OPT_END }; @@ -124,6 +133,7 @@ static int archiveModified = 0; static int archiveWriteable = 0; static NODE *root; +static FORMATRAW_CACHE *rawcache; struct options options; char *mtpt = NULL; char *archiveFile = NULL; @@ -151,30 +161,30 @@ "usage: %s archivepath mountpoint [options]\n" "\n" "general options:\n" - " -o opt,[opt...] mount options\n" - " -h --help print help\n" - " -V --version print version\n" + " -o opt,[opt...] mount options\n" + " -h --help print help\n" + " -V --version print version\n" "\n" "archivemount options:\n" - " -o readonly disable write support\n" - " -o nobackup remove archive file backups\n" - " -o nosave do not save changes upon unmount.\n" - " Good if you want to change something\n" - " and save it as a diff,\n" - " or use a format for saving which is\n" - " not supported by archivemount.\n" + " -o readonly disable write support\n" + " -o nobackup remove archive file backups\n" + " -o nosave do not save changes upon unmount.\n" + " Good if you want to change something\n" + " and save it as a diff,\n" + " or use a format for saving which is\n" + " not supported by archivemount.\n" "\n" " -o subtree=<regexp> use only subtree matching ^\\.\\?<regexp> from archive\n" - " it implies readonly\n" + " it implies readonly\n" "\n" - " -o formatraw treat input as a single element archive\n" - " it implies readonly\n" + " -o formatraw treat input as a single element archive\n" + " it implies readonly\n" "\n",progname); } static struct fuse_operations ar_oper; -static int +static int ar_opt_proc(void *data, const char *arg, int key, struct fuse_args *outargs) { (void) data; @@ -239,6 +249,23 @@ return node; } +static FORMATRAW_CACHE * +init_rawcache( ) +{ + FORMATRAW_CACHE *rawcache; + + if( (rawcache = malloc( sizeof( FORMATRAW_CACHE ) ) ) == NULL ) { + log( "Out of memory" ); + return NULL; + } + + memset(&rawcache->st, 0, sizeof(rawcache->st)); + memset(&rawcache->archive, 0, sizeof(rawcache->archive)); + rawcache->opened=0; + rawcache->offset_uncompressed=0; + return rawcache; +} + static void free_node(NODE *node) { @@ -256,6 +283,12 @@ free(node); } +static void +free_rawcache(FORMATRAW_CACHE *rawcache) +{ + free(rawcache); +} + static void remove_child( NODE *node ) @@ -396,7 +429,7 @@ log( "Out of memory" ); return -ENOMEM; } - if( archive_read_support_compression_all( archive ) != ARCHIVE_OK ) { + if( archive_read_support_filter_all( archive ) != ARCHIVE_OK ) { fprintf( stderr, "%s\n", archive_error_string( archive ) ); return archive_errno( archive ); } @@ -418,7 +451,9 @@ } /* check if format or compression prohibits writability */ format = archive_format( archive ); - compression = archive_compression( archive ); +// log("FORMAT=%s",archive_format_name(archive)); + compression = archive_filter_code( archive, 0 ); +// log("COMPRESSION=%s",archive_compression_name(archive)); if( format & ARCHIVE_FORMAT_ISO9660 || format & ARCHIVE_FORMAT_ISO9660_ROCKRIDGE || format & ARCHIVE_FORMAT_ZIP @@ -517,7 +552,7 @@ free_node(cur); /* close archive */ - archive_read_finish( archive ); + archive_read_free( archive ); lseek( archiveFd, 0, SEEK_SET ); if ( options.subtree_filter ) { regfree( &subtree ); @@ -579,7 +614,7 @@ //log( "get_node_for_path path: '%s' start: '%s'", path, start->name ); /* Check if start is a perfect match */ - if( strcmp( path, start->name ) == 0 ) { + if( strcmp( path, start->name + (*path=='/'?0:1) ) == 0 ) { //log( " get_node_for_path path: '%s' start: '%s' return: '%s'", path, start->name, start->name ); return start; } @@ -590,7 +625,7 @@ const char * baseend; /* Find the part of the path we are now looking for */ - basename = path + strlen(start->name); + basename = path + strlen(start->name) - (*path=='/'?0:1); if (*basename == '/') basename++; @@ -606,7 +641,7 @@ } //log( " get_node_for_path path: '%s' start: '%s' return: '%s'", path, start->name, ret == NULL ? "(null)" : ret->name ); - return ret; + return ret; } @@ -862,7 +897,7 @@ log( "Out of memory" ); return -ENOMEM; } - if( archive_read_support_compression_all( oldarc ) != ARCHIVE_OK ) { + if( archive_read_support_filter_all( oldarc ) != ARCHIVE_OK ) { log( "%s", archive_error_string( oldarc ) ); return archive_errno( oldarc ); } @@ -875,7 +910,7 @@ return archive_errno( oldarc ); } format = archive_format( oldarc ); - compression = archive_compression( oldarc ); + compression = archive_filter_code( oldarc, 0 ); /* log( "format of old archive is %s (%d)", archive_format_name( oldarc ), @@ -891,15 +926,15 @@ } switch( compression ) { case ARCHIVE_COMPRESSION_GZIP: - archive_write_set_compression_gzip( newarc ); + archive_write_add_filter_gzip( newarc ); break; case ARCHIVE_COMPRESSION_BZIP2: - archive_write_set_compression_bzip2( newarc ); + archive_write_add_filter_bzip2( newarc ); break; case ARCHIVE_COMPRESSION_COMPRESS: case ARCHIVE_COMPRESSION_NONE: default: - archive_write_set_compression_none( newarc ); + archive_write_add_filter_none( newarc ); break; } #if 0 @@ -1028,8 +1063,8 @@ write_new_modded_file( node, node->entry, newarc ); } /* clean up, re-open the new archive for reading */ - archive_read_finish( oldarc ); - archive_write_finish( newarc ); + archive_read_free( oldarc ); + archive_write_free( newarc ); close( tempfile ); close( archiveFd ); archiveFd = open( archiveFile, O_RDONLY ); @@ -1049,7 +1084,81 @@ /*****************/ static int -_ar_read( const char *path, char *buf, size_t size, off_t offset, +_ar_open_raw( void ) +//_ar_open_raw( const char *path, struct fuse_file_info *fi ) +{ + // open archive and search first entry + + const char path[] = "/data"; + + int ret = -1; + const char *realpath; + NODE *node; + // log( "_ar_open_raw called, path: '%s'", path); + + + if(rawcache->opened!=0) { + // log("already opened"); + return 0; + } + + options.readonly = 1; + + /* find node */ + + node = get_node_for_path( root, path ); + if( ! node ) { + log("get_node_for_path error"); + return -ENOENT; + } + + // struct archive *archive; + struct archive_entry *entry; + int archive_ret; + /* search file in archive */ + realpath = archive_entry_pathname( node->entry ); + if( (rawcache->archive = archive_read_new()) == NULL ) { + log( "Out of memory" ); + return -ENOMEM; + } + archive_ret = archive_read_support_filter_all( rawcache->archive ); + if( archive_ret != ARCHIVE_OK ) { + log( "archive_read_support_filter_all(): %s (%d)\n", + archive_error_string( rawcache->archive ), archive_ret ); + return -EIO; + } + + archive_ret = archive_read_support_format_raw( rawcache->archive ); + if( archive_ret != ARCHIVE_OK ) { + log( "archive_read_support_format_raw(): %s (%d)\n", + archive_error_string( rawcache->archive ), archive_ret ); + return -EIO; + } + + archive_ret = archive_read_open_fd( rawcache->archive, archiveFd, 10240 ); + if( archive_ret != ARCHIVE_OK ) { + log( "archive_read_open_fd(): %s (%d)\n", + archive_error_string( rawcache->archive ), archive_ret ); + return -EIO; + } + /* search for file to read - "/data" must be the first entry */ + while( ( archive_ret = archive_read_next_header( + rawcache->archive, &entry )) == ARCHIVE_OK ) { + const char *name; + name = archive_entry_pathname( entry ); + if( strcmp( realpath, name ) == 0 ) { + break; + } + + } + rawcache->opened=1; + rawcache->offset_uncompressed=0; + + return ret; +} + +static int +_ar_read_raw( const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi ) { int ret = -1; @@ -1063,6 +1172,81 @@ if( ! node ) { return -ENOENT; } + + if ( offset < rawcache->offset_uncompressed ) { + //rewind archive + + /* close archive */ + archive_read_free( rawcache->archive ); + lseek( archiveFd, 0, SEEK_SET ); + + rawcache->opened=0; + + /* reopen */ + _ar_open_raw(); + } + + void *trash; + if( ( trash = malloc( MAXBUF ) ) == NULL ) { + log( "Out of memory" ); + return -ENOMEM; + } + /* skip offset */ + offset-=rawcache->offset_uncompressed; + + while( offset > 0 ) { + int skip = offset > MAXBUF ? MAXBUF : offset; + ret = archive_read_data( + rawcache->archive, trash, skip ); + if( ret == ARCHIVE_FATAL + || ret == ARCHIVE_WARN + || ret == ARCHIVE_RETRY ) + { + log( "ar_read_raw (skipping offset): %s", + archive_error_string( rawcache->archive ) ); + errno = archive_errno( rawcache->archive ); + ret = -1; + break; + } + rawcache->offset_uncompressed+=skip; + offset -= skip; + } + free( trash ); + + if( offset ) { + /* there was an error */ + log("ar_read_raw (offset!=0)"); + return -EIO; + } + /* read data */ + ret = archive_read_data( rawcache->archive, buf, size ); + if( ret == ARCHIVE_FATAL + || ret == ARCHIVE_WARN + || ret == ARCHIVE_RETRY ) + { + log( "ar_read_raw (reading data): %s", + archive_error_string( rawcache->archive ) ); + errno = archive_errno( rawcache->archive ); + ret = -1; + } + rawcache->offset_uncompressed +=size; + return ret; +} + +static int +_ar_read( const char *path, char *buf, size_t size, off_t offset, + struct fuse_file_info *fi ) +{ + int ret = -1; + const char *realpath; + NODE *node; + ( void )fi; + //log( "read called, path: '%s'", path ); + /* find node */ + node = get_node_for_path( root, path ); + if( ! node ) { + return -ENOENT; + } if( archive_entry_hardlink( node->entry ) ) { /* file is a hardlink, recurse into it */ return _ar_read( archive_entry_hardlink( node->entry ), @@ -1102,9 +1286,9 @@ log( "Out of memory" ); return -ENOMEM; } - archive_ret = archive_read_support_compression_all( archive ); + archive_ret = archive_read_support_filter_all( archive ); if( archive_ret != ARCHIVE_OK ) { - log( "archive_read_support_compression_all(): %s (%d)\n", + log( "archive_read_support_filter_all(): %s (%d)\n", archive_error_string( archive ), archive_ret ); return -EIO; } @@ -1131,7 +1315,7 @@ return -EIO; } /* search for file to read */ - while( ( archive_ret = archive_read_next_header( + while( ( archive_ret = archive_read_next_header( archive, &entry )) == ARCHIVE_OK ) { const char *name; name = archive_entry_pathname( entry ); @@ -1179,7 +1363,7 @@ archive_read_data_skip( archive ); } /* close archive */ - archive_read_finish( archive ); + archive_read_free( archive ); lseek( archiveFd, 0, SEEK_SET ); } return ret; @@ -1194,24 +1378,109 @@ log( "failed to get lock: %s\n", strerror(ret)); return -EIO; } else { - ret = _ar_read( path, buf, size, offset, fi ); + if ( options.formatraw) { + ret = _ar_read_raw( path, buf, size, offset, fi ); + } else { + ret = _ar_read( path, buf, size, offset, fi ); + } pthread_mutex_unlock(&lock); } return ret; } -static int +static off_t _ar_getsizeraw(const char *path) { size_t bufsize = 1024 * 1024; char *buf = malloc(bufsize+1); off_t offset = 0, ret; - for (;;) { - ret = _ar_read( path, buf, bufsize, offset, NULL ); - if (ret <= 0) - break; - offset += ret; + NODE *node; + const char *realpath; + + /* find node */ + node = get_node_for_path( root, path ); + if( ! node ) { + return -ENOENT; + } + + struct archive *archive; + struct archive_entry *entry; + int archive_ret; + /* search file in archive */ + realpath = archive_entry_pathname( node->entry ); + + if( (archive = archive_read_new()) == NULL ) { + log( "Out of memory" ); + return -ENOMEM; + } + + archive_ret = archive_read_support_filter_all( archive ); + + if( archive_ret != ARCHIVE_OK ) { + log( "archive_read_support_filter_all(): %s (%d)\n", + archive_error_string( archive ), archive_ret ); + return -EIO; } + + if ( options.formatraw ) { + archive_ret = archive_read_support_format_raw( archive ); + if( archive_ret != ARCHIVE_OK ) { + log( "archive_read_support_format_raw(): %s (%d)\n", + archive_error_string( archive ), archive_ret ); + return -EIO; + } + options.readonly = 1; + options.formatraw = 1; + } + + archive_ret = archive_read_open_fd( archive, archiveFd, 10240 ); + if( archive_ret != ARCHIVE_OK ) { + log( "archive_read_open_fd(): %s (%d)\n", + archive_error_string( archive ), archive_ret ); + return -EIO; + } + + /* search for file to read */ + while( ( archive_ret = archive_read_next_header( + archive, &entry )) == ARCHIVE_OK ) + { + const char *name; + name = archive_entry_pathname( entry ); + if( strcmp( realpath, name ) == 0 ) { + void *trash; + if( ( trash = malloc( MAXBUF ) ) == NULL ) { + log( "Out of memory" ); + return -ENOMEM; + } + /* read until no more data */ + ssize_t readed=MAXBUF; + while( readed != 0 ) { + ret = archive_read_data( + archive, trash, MAXBUF ); + readed=ret; + + if( ret == ARCHIVE_FATAL + || ret == ARCHIVE_WARN + || ret == ARCHIVE_RETRY ) + { + log( "ar_read (skipping offset): %s", + archive_error_string( archive ) ); + errno = archive_errno( archive ); + ret = -1; + break; + } + offset += ret; + // log("tmp offset =%ld (%ld)",offset,offset/1024/1024); + } + free( trash ); + break; + } + archive_read_data_skip( archive ); + } // end of search for file to read + /* close archive */ + archive_read_free( archive ); + lseek( archiveFd, 0, SEEK_SET ); + return offset; } @@ -1220,7 +1489,7 @@ { NODE *node; int ret; - int size; + off_t size; //log( "getattr called, path: '%s'", path ); node = get_node_for_path( root, path ); @@ -1235,9 +1504,8 @@ } if ( options.formatraw && ! node->child ) { fstat( archiveFd, stbuf ); - size = _ar_getsizeraw(path); - if (size < 0) - return -1; + size=rawcache->st.st_size; + if( size < 0 ) return -1; stbuf->st_size = size; } else { memcpy( stbuf, archive_entry_stat( node->entry ), @@ -1453,7 +1721,7 @@ /* a name was found for the uid */ archive_entry_set_uname( node->entry, strdup( pwd->pw_name ) ); } else { - if( errno == EINTR || errno == EIO || errno == EMFILE || + if( errno == EINTR || errno == EIO || errno == EMFILE || errno == ENFILE || errno == ENOMEM || errno == ERANGE ) { @@ -1470,7 +1738,7 @@ /* a name was found for the uid */ archive_entry_set_gname( node->entry, strdup( grp->gr_name ) ); } else { - if( errno == EINTR || errno == EIO || errno == EMFILE || + if( errno == EINTR || errno == EIO || errno == EMFILE || errno == ENFILE || errno == ENOMEM || errno == ERANGE ) { @@ -1548,7 +1816,7 @@ /* a name was found for the uid */ archive_entry_set_uname( node->entry, strdup( pwd->pw_name ) ); } else { - if( errno == EINTR || errno == EIO || errno == EMFILE || + if( errno == EINTR || errno == EIO || errno == EMFILE || errno == ENFILE || errno == ENOMEM || errno == ERANGE ) { @@ -1565,7 +1833,7 @@ /* a name was found for the uid */ archive_entry_set_gname( node->entry, strdup( grp->gr_name ) ); } else { - if( errno == EINTR || errno == EIO || errno == EMFILE || + if( errno == EINTR || errno == EIO || errno == EMFILE || errno == ENFILE || errno == ENOMEM || errno == ERANGE ) { @@ -2085,7 +2353,7 @@ static int ar_statfs( const char *path, struct statvfs *stbuf ) { - ( void )path; + ( void )path; //log( "statfs called, %s", path ); @@ -2191,7 +2459,7 @@ tmp = archive_entry_symlink( node->entry ); snprintf( buf, size, "%s", tmp ); pthread_mutex_unlock( &lock ); - + return 0; } @@ -2220,6 +2488,8 @@ /* no need to recurse into links since function doesn't do anything */ /* no need to save a handle here since archives are stream based */ fi->fh = 0; + if(options.formatraw) + _ar_open_raw(); pthread_mutex_unlock( &lock ); return 0; } @@ -2240,7 +2510,7 @@ (void) offset; (void) fi; - log( "readdir called, path: '%s' offset: %d", path, offset ); + //log( "readdir called, path: '%s' offset: %d", path, offset ); int ret = -EIO; if ( pthread_mutex_lock( &lock ) ) { log( "could not acquire lock for archive: %s\n", strerror(ret)); @@ -2259,9 +2529,19 @@ node = node->child; while( node ) { + const struct stat *st; struct stat st_copy; - const struct stat *st = archive_entry_stat( node->entry ); - + if( archive_entry_hardlink( node->entry ) ) { + /* file is a hardlink, stat'ing it somehow does not + * work; stat the original instead */ + NODE *orig = get_node_for_path( root, archive_entry_hardlink( node->entry ) ); + if( ! orig ) { + return -ENOENT; + } + st = archive_entry_stat( orig->entry ); + } else { + st = archive_entry_stat( node->entry ); + } /* Make a copy so we can set blocks/blksize. These are not * set by libarchive. Issue 191 */ memcpy(&st_copy, st, sizeof(st_copy)); @@ -2377,7 +2657,7 @@ .read = ar_read, .write = ar_write, .statfs = ar_statfs, - //.flush = ar_flush, // int(*flush )(const char *, struct fuse_file_info *) + //.flush = ar_flush, // int(*flush )(const char *, struct fuse_file_info *) .release = ar_release, .fsync = ar_fsync, /* @@ -2388,26 +2668,26 @@ .removexattr = ar_removexattr, #endif */ - //.opendir = ar_opendir, // int(*opendir )(const char *, struct fuse_file_info *) + //.opendir = ar_opendir, // int(*opendir )(const char *, struct fuse_file_info *) .readdir = ar_readdir, - //.releasedir = ar_releasedir, // int(*releasedir )(const char *, struct fuse_file_info *) - //.fsyncdir = ar_fsyncdir, // int(*fsyncdir )(const char *, int, struct fuse_file_info *) - //.init = ar_init, // void *(*init )(struct fuse_conn_info *conn) - //.destroy = ar_destroy, // void(*destroy )(void *) - //.access = ar_access, // int(*access )(const char *, int) - .create = ar_create, - //.ftruncate = ar_ftruncate, // int(*ftruncate )(const char *, off_t, struct fuse_file_info *) - //.fgetattr = ar_fgetattr, // int(*fgetattr )(const char *, struct stat *, struct fuse_file_info *) - //.lock = ar_lock, // int(*lock )(const char *, struct fuse_file_info *, int cmd, struct flock *) - //.utimens = ar_utimens, // int(*utimens )(const char *, const struct timespec tv[2]) - //.bmap = ar_bmap, // int(*bmap )(const char *, size_t blocksize, uint64_t *idx) + //.releasedir = ar_releasedir, // int(*releasedir )(const char *, struct fuse_file_info *) + //.fsyncdir = ar_fsyncdir, // int(*fsyncdir )(const char *, int, struct fuse_file_info *) + //.init = ar_init, // void *(*init )(struct fuse_conn_info *conn) + //.destroy = ar_destroy, // void(*destroy )(void *) + //.access = ar_access, // int(*access )(const char *, int) + .create = ar_create, + //.ftruncate = ar_ftruncate, // int(*ftruncate )(const char *, off_t, struct fuse_file_info *) + //.fgetattr = ar_fgetattr, // int(*fgetattr )(const char *, struct stat *, struct fuse_file_info *) + //.lock = ar_lock, // int(*lock )(const char *, struct fuse_file_info *, int cmd, struct flock *) + //.utimens = ar_utimens, // int(*utimens )(const char *, const struct timespec tv[2]) + //.bmap = ar_bmap, // int(*bmap )(const char *, size_t blocksize, uint64_t *idx) }; void showUsage() { fprintf( stderr, "Usage: archivemount <fuse-options> <archive> <mountpoint>\n" ); - fprintf( stderr, "Usage: (-v|--version)\n" ); + fprintf( stderr, "Usage: (-v|--version)\n" ); } int @@ -2466,6 +2746,15 @@ exit( EXIT_FAILURE ); } + if(options.formatraw) { + /* create rawcache */ + if ( (rawcache=init_rawcache()) == NULL ) + return -ENOMEM; + fprintf(stderr,"Calculating uncompressed file size. Please wait.\n"); + rawcache->st.st_size=_ar_getsizeraw("/data"); + //log("cache st_size = %ld",rawcache->st.st_size); + } + /* save directory this was started from */ oldpwd = open( ".", 0 ); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/archivemount-0.8.4/configure new/archivemount-0.8.5/configure --- old/archivemount-0.8.4/configure 2015-02-27 11:07:22.000000000 +0100 +++ new/archivemount-0.8.5/configure 2015-06-27 18:48:08.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for archivemount 0.8.4. +# Generated by GNU Autoconf 2.69 for archivemount 0.8.5. # # Report bugs to <[email protected]>. # @@ -580,8 +580,8 @@ # Identity of this package. PACKAGE_NAME='archivemount' PACKAGE_TARNAME='archivemount' -PACKAGE_VERSION='0.8.4' -PACKAGE_STRING='archivemount 0.8.4' +PACKAGE_VERSION='0.8.5' +PACKAGE_STRING='archivemount 0.8.5' PACKAGE_BUGREPORT='[email protected]' PACKAGE_URL='' @@ -1280,7 +1280,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures archivemount 0.8.4 to adapt to many kinds of systems. +\`configure' configures archivemount 0.8.5 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1346,7 +1346,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of archivemount 0.8.4:";; + short | recursive ) echo "Configuration of archivemount 0.8.5:";; esac cat <<\_ACEOF @@ -1445,7 +1445,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -archivemount configure 0.8.4 +archivemount configure 0.8.5 generated by GNU Autoconf 2.69 Copyright (C) 2012 Free Software Foundation, Inc. @@ -1747,7 +1747,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by archivemount $as_me 0.8.4, which was +It was created by archivemount $as_me 0.8.5, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -2610,7 +2610,7 @@ # Define the identity of the package. PACKAGE='archivemount' - VERSION='0.8.4' + VERSION='0.8.5' cat >>confdefs.h <<_ACEOF @@ -5008,7 +5008,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by archivemount $as_me 0.8.4, which was +This file was extended by archivemount $as_me 0.8.5, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -5074,7 +5074,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" ac_cs_version="\\ -archivemount config.status 0.8.4 +archivemount config.status 0.8.5 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/archivemount-0.8.4/configure.ac new/archivemount-0.8.5/configure.ac --- old/archivemount-0.8.4/configure.ac 2015-02-27 11:06:55.000000000 +0100 +++ new/archivemount-0.8.5/configure.ac 2015-06-27 18:48:02.000000000 +0200 @@ -1,6 +1,6 @@ # Process this file with autoconf to produce a configure script -AC_INIT([archivemount],[0.8.4], [[email protected]]) +AC_INIT([archivemount],[0.8.5], [[email protected]]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC ++++++ archivemount-0.8.4.dif -> archivemount.dif ++++++ --- /work/SRC/openSUSE:Factory/archivemount/archivemount-0.8.4.dif 2015-03-25 10:00:28.000000000 +0100 +++ /work/SRC/openSUSE:Factory/.archivemount.new/archivemount.dif 2015-11-12 19:41:34.000000000 +0100 @@ -17,7 +17,7 @@ --- configure.ac.orig +++ configure.ac @@ -3,6 +3,7 @@ - AC_INIT([archivemount],[0.8.4], [[email protected]]) + AC_INIT([archivemount],[0.8.5], [[email protected]]) AM_INIT_AUTOMAKE([-Wall -Werror foreign]) AC_PROG_CC +AM_PROG_CC_C_O
