ssize_t size;
} sources;
+static struct {
+ time_t atime;
+ time_t mtime;
+ time_t ctime;
+} times;
+
#define SOURCEARRAYP(i) ((void*)&sources.array[ i ])
/**
}
stbuf->st_nlink = 1;
stbuf->st_size = sources.size;
- time_t now = time( 0 );
- stbuf->st_atime = now;
- stbuf->st_mtime = now;
- stbuf->st_ctime = now;
+ stbuf->st_atime = times.atime;
+ stbuf->st_mtime = times.mtime;
+ stbuf->st_ctime = times.ctime;
stbuf->st_uid = getuid();
stbuf->st_gid = getgid();
return 0;
return -ENOENT;
}
// set O-CLOEXEC for this opening?
+ times.atime = time( 0 );
return 0;
}
if ( offset > sources.size ) {
return -1;
}
- while ( lo < hi ) {
+ while ( lo + 1 < hi ) {
int m = ( lo + hi ) / 2;
- if ( sources.array[m].start > offset ) {
+ if ( offset < sources.array[ m ].start ) {
hi = m;
- } else if ( m+1 < hi && sources.array[m+1].start < offset ) {
- lo = m+1;
} else {
- return m;
+ lo = m;
}
}
return lo;
*/
static int insert_source(struct Source *source,size_t off) {
int index = find_source( off );
+ int i;
// Ensure at least 5 "free" Sources in <source.array>
// and allocate space for 20 new otherwise.
if ( sources.count + 5 > sources.limit ) {
sources.array = new;
sources.limit = size;
}
+#if DEBUG
+ fprintf( stderr, "index=%d\n", index );
+#endif
if ( index < sources.count ) {
ssize_t b = ( sources.count - index ) * sizeof(struct Source);
+#if DEBUG
+ fprintf( stderr, "b=%ld\n", b );
+#endif
if ( sources.array[ index ].start < off ) {
// Split the <index> record at <off>
// and adjust index
- b *= 2;
memcpy( SOURCEARRAYP( index+2 ), SOURCEARRAYP( index ), b );
sources.count += 2;
b = off - sources.array[ index ].start;
sources.array[ index + 2 ].from += b; // adjust tail fragment
sources.array[ index++ ].to = b; // adjust head fragment
+#if DEBUG
+ print_source( &sources.array[ index-1 ] );
+ print_source( &sources.array[ index ] );
+ print_source( &sources.array[ index+1 ] );
+ fprintf( stderr, "---\n");
+#endif
} else {
// Insert the new source at <index>
memcpy( SOURCEARRAYP( index+1 ), SOURCEARRAYP( index ), b );
sources.array[ index ].fd = source->fd;
sources.array[ index ].from = source->from;
sources.array[ index ].to = source->to;
- for ( ; index < sources.count; index++ ) {
- sources.array[ index ].start = off;
- off += sources.array[ index ].to - sources.array[ index ].from;
+ for ( i = index; i < sources.count; i++ ) {
+ sources.array[ i ].start = off;
+ off += sources.array[ i ].to - sources.array[ i ].from;
+#if DEBUG
+ print_source( &sources.array[ i ] );
+#endif
}
sources.size = off;
+#if DEBUG
+ fprintf( stderr, "count=%d size=%ld\n", sources.count, sources.size );
+#endif
return index;
}
off += r;
size -= r;
}
+ times.atime = time( 0 );
return rr;
}
if ( n <= 0 ) {
return n;
}
+ buf += n;
+ size -= n;
}
return orig;
}
+static int fusefile_write_buf(const char *path, struct fuse_bufvec *buf,
+ off_t off, struct fuse_file_info *fi) {
+#if DEBUG
+ fprintf( stderr, "fusefile_write_buf( %s )\n", path );
+#endif
+ if ( strcmp( path, "/" ) != 0 ) {
+ return -ENOENT;
+ }
+
+ // Ensure a pad was nominated
+ if ( pad.filename == 0 ) {
+ return 1;
+ }
+
+ // Determine total size
+ size_t size = 0;
+ int i;
+#if DEBUG
+ fprintf( stderr, "count = %ld\n", buf->count );
+#endif
+ for ( i = 0; i < buf->count; i++ ) {
+ struct fuse_buf *p = &buf->buf[ i ];
+ size += p->size;
+ }
+ static char meta[ 100 ];
+ sprintf( meta, "%ld\n%ld\n", off, size );
+#if DEBUG
+ fprintf( stderr, "meta( %ld %ld )\n", off, size );
+#endif
+ if ( write_block( pad.fd, meta, strlen( meta ) ) <= 0 ) {
+ perror( pad.filename );
+ return -EIO;
+ }
+ struct Source source = {
+ .filename = pad.filename,
+ .fd = pad.fd,
+ .from = lseek( pad.fd, 0, SEEK_END ),
+ .to = 0,
+ .start = 0
+ };
+ for ( i = 0; i < buf->count; i++ ) {
+ struct fuse_buf *p = &buf->buf[i];
+ if ( p->flags & FUSE_BUF_IS_FD ) {
+#if DEBUG
+ fprintf( stderr, "Content held in a file ... HELP!!\n" );
+#endif
+ return -EIO;
+ } else {
+ ssize_t n = write_block( pad.fd, (char*) p->mem, p->size );
+ if ( n != p->size ) {
+ return -EIO;
+ }
+ }
+ }
+ source.to = source.from + size;
+ insert_source( &source, off );
+ times.mtime = time( 0 );
+ return size;
+}
+
/**
* Insert a fragment at <off>. The data is appended to the pad file,
* and a descriptor is inserted; the fragment containing <off> is
off_t off, struct fuse_file_info *fi)
{
#if DEBUG
- fprintf( stderr, "fusefile_write( %s )\n", path );
+ fprintf( stderr, "fusefile_write( %s %ld )\n", path, size );
#endif
if ( strcmp( path, "/" ) != 0 ) {
return -ENOENT;
}
-#if DEBUG
- fprintf( stderr, "write %ld %ld\n", off, size );
-#endif
+
// Ensure a pad was nominated
if ( pad.filename == 0 ) {
return 1;
}
source.to = source.from + size;
insert_source( &source, off );
+ times.mtime = time( 0 );
return size;
}
return 0;
}
+/**
+ *
+ */
+static int fusefile_truncate(const char *path, off_t len) {
+#if DEBUG
+ fprintf( stderr, "fusefile_truncate( %s, %ld )\n", path, len );
+#endif
+ if ( strcmp( path, "/" ) != 0 ) {
+ return -ENOENT;
+ }
+ return -EIO;
+}
+
static struct fuse_operations fusefile_oper = {
.getattr = fusefile_getattr,
.open = fusefile_open,
.read = fusefile_read,
.write = fusefile_write,
+ .write_buf = fusefile_write_buf,
.destroy = fusefile_destroy,
.flush = fusefile_flush,
.release = fusefile_release,
.fsync = fusefile_fsync,
- //void *(*init) (struct fuse_conn_info *conn);
- //int (*write_buf) (const char *, struct fuse_bufvec *buf, off_t off,
- // struct fuse_file_info *);
+ .truncate = fusefile_truncate,
//.truncate = fusefile_truncate,
- //.flush = fusefile_flush,
//.release = fusefile_release,
+ //void *(*init) (struct fuse_conn_info *conn);
};
static void usage() {
perror( mnt );
return 1;
}
+ time_t now = time( 0 );
+ times.atime = now;
+ times.mtime = now;
+ times.ctime = now;
temporary = 1;
close( fd );
} else if ( ! S_ISREG( stbuf.st_mode ) ) {
fprintf( stderr, "mountpoint is not a regular file\n" );
return 1;
+ } else {
+ times.atime = stbuf.st_atime;
+ times.mtime = stbuf.st_mtime;
+ times.ctime = stbuf.st_ctime;
}
+
fuseargc = setup_argv( fuseargc, &argv );
struct fuse_args args = FUSE_ARGS_INIT( fuseargc, argv );
if ( fuse_parse_cmdline( &args, &mnt, &mt, &fg ) ) {