+/**
+ * Write a full block of data over the sources at the offset
+ */
+static int write_block(off_t off,const char *buf,size_t size) {
+#if DEBUG
+ fprintf( stderr, "write_block( %ld, ?, %ld )\n", off, size );
+#endif
+ while ( size > 0 ) {
+ int index = find_source( off ); // index of source file
+ if ( index < 0 ) {
+ return -EIO; // past EOF
+ }
+ struct Source *source = &sources.array[ index ];
+ off_t from = off - source->start;
+ off_t max = source->to - source->from - from;
+ if ( lseek( source->fd, from, SEEK_SET ) < 0 ) {
+ return -EIO;
+ }
+ ssize_t todo = ( size < max )? size : max;
+ while ( todo > 0 ) {
+ times.mtime = time( 0 );
+ ssize_t n = write( source->fd, buf, todo );
+ if ( n <= 0 ) {
+ return -EIO; // Something wrong
+ }
+ buf += n;
+ todo -= n;
+ size -= n;
+ off += n;
+ }
+ }
+ return 0;
+}
+
+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;
+ }
+
+ size_t size = 0;
+ int i;
+ 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;
+ }
+ if ( write_block( off, (char*) p->mem, p->size ) < 0 ) {
+ return -EIO;
+ }
+ size += p->size;
+ }
+#if DEBUG
+ fprintf( stderr, "fusefile_write_buf written %ld\n", size );
+#endif
+ return size;
+}
+
+/**
+ * Write a fragment at <off>. This overwrites files.
+ */
+static int fusefile_write(const char *path, const char *buf, size_t size,
+ off_t off, struct fuse_file_info *fi)
+{
+#if DEBUG
+ fprintf( stderr, "fusefile_write( %s %ld )\n", path, size );
+#endif
+ if ( strcmp( path, "/" ) != 0 ) {
+ return -ENOENT;
+ }
+
+ if ( write_block( off, buf, size ) < 0 ) {
+ return -EIO;
+ }
+ return size;
+}
+