stfufs-1.0/ChangeLog stfufs-1.1/ChangeLog
12008-01-20  Tomi Ollila
2 
3        * Release 1.1 (beta quality, more tests needed to ensure stability)
4 
5        * Added single element read and write caches
6 
7        * Updated protocol version to 2 (added release() operation)
8 
9        * Fixed user@host: handling
10 
11        * Added -v (version) option
12 
13        * Some code cleanup/rationalization
14 
15        * Updated Makefile(s): separate debug/ndebug object files.
16          more/updated targets (install, snapshot, release (was dist), depend)
17 
12008-01-19  Tomi Ollila182008-01-19  Tomi Ollila
219
3        * Release 1.0 (ranked as beta, though -- all known bugs fixed)20        * Release 1.0 (ranked as beta, though -- all known bugs fixed)
5        * Fixed critical bug in stfufs_buffer_reserve() (buffer overflew)22        * Fixed critical bug in stfufs_buffer_reserve() (buffer overflew)
623
7        * Added conaries around BUFFER.b for testing it's over/underflows24        * Added conaries around BUFFER.b for testing it's over/underflows
8          (used in debug mode).25          (used in debug mode)
926
102008-01-18  Tomi Ollila272008-01-18  Tomi Ollila
1128

stfufs-1.0/Makefile stfufs-1.1/Makefile
1 
2SW=stfufs
3VER=1.0
4SW_VER=$(SW)-$(VER)
5 
6# Edit pretocol.c when changing version info above (fixme: take from .h file).
71
8.DEFAULT:2.DEFAULT:
9         $(MAKE) -f Makefile.build $@3         $(MAKE) -f Makefile.build $@ OD=_obj
104
11ohje:5ohje:
12ohje:6ohje:
23#+#  Server does not (see devel/genxtypes.sh for missing types, if any).17#+#  Server does not (see devel/genxtypes.sh for missing types, if any).
24#+#18#+#
2519
20debug:
21         $(MAKE) -f Makefile.build __debug OD=_obj_dbg DEBUG=1 DEP=_depend_dbg
2622
23 
24snapshot: ver=$$ver-`date +%Y%m%d`
25snapshot: _dist
26 
27release: ver=$$ver
28release: _dist
29 
27dist:30_dist:
28        { echo 755 root root . $(SW_VER) /; \31        case '$(ver)' in '') echo "xxx"; false ;; esac
32        ver=`sed -n '/VERSION /{s/.*VERSION *"//;s/".*//;p;}' version.h`; \
33        ver=stfufs-$(ver); { echo 755 root root . $$ver /; \
29          grep '^#,#' Makefile | while read _ f x; do p=755; d=$$f; \34        grep '^#,#' Makefile | while read _ f x; do p=755; d=$$f; \
30                test -d $$f && d=/ || case $$x in '') p=644;; esac; \35                test -d $$f && d=/ || case $$x in '') p=644;; esac; \
31                echo $$p root root . $(SW_VER)/$$f $$d; done; } \36                echo $$p root root . $$ver/$$f $$d; done; } \
32        | tarlisted -Vz -o $(SW_VER).tar.gz37        | tarlisted -Vz -o $$ver.tar.gz
3338
34#,#  ChangeLog39#,#  ChangeLog
35#,#  README.brief40#,#  README.brief
55#,#  stfufs-server-fs.c60#,#  stfufs-server-fs.c
56#,#  util.c61#,#  util.c
57#,#  util.h62#,#  util.h
63#,#  version.h
5864
59#,#  devel65#,#  devel
60#,#  devel/dbgsetup.sh  x66#,#  devel/dbgsetup.sh  x
61#,#  devel/genxtypes.sh  x67#,#  devel/genxtypes.sh  x
62#,#  devel/mkdep.perl x
63#,#  devel/speedtest-ia32.c68#,#  devel/speedtest-ia32.c
64#,#  devel/stfufs-server-dbgwrapper.sh  x69#,#  devel/stfufs-server-dbgwrapper.sh  x
65#,#  devel/testoperations.sh  x70#,#  devel/testoperations.sh  x
6873
6974
70clean distclean:75clean distclean:
71        touch depend76        touch _depend
72        $(MAKE) -f Makefile.build $@77        $(MAKE) -f Makefile.build $@
73 

stfufs-1.0/Makefile.build stfufs-1.1/Makefile.build
1313
14O64= -DLARGEFILE_SOURCE -D_FILE_OFFSET_BITS=6414O64= -DLARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
1515
16DF= -O2 -DDEBUG=016OD    ?= /dev/null
17 17DEBUG ?= 0
18OPT= $(O64) $(DF)18DEP   ?= _depend
1919
20TRGS=stfufs-server stfufs20TRGS=stfufs-server stfufs
2121
22all:  $(TRGS)22all:  $(TRGS)
2323
24DF= -O2
25 
24debug: DF= -ggdb -DDEBUG=1 -fstack-protector -Wstack-protector26__debug: DF= -ggdb -fstack-protector -Wstack-protector
25debug: $(TRGS)27__debug: $(TRGS)
28 
29OPT= $(O64) $(DF) -DDEBUG=$(DEBUG)
2630
27client: stfufs31client: stfufs
28server: stfufs-server32server: stfufs-server
35CLIONLY=stfufs-client.o stfufs-client-fuse.o \39CLIONLY=stfufs-client.o stfufs-client-fuse.o \
36        stfufs-client-buffer.o stfufs-client-errmap.o40        stfufs-client-buffer.o stfufs-client-errmap.o
3741
38SRVOBJS=$(SRVONLY) $(COBJS)42SRVOBJS0=$(SRVONLY) $(COBJS)
43SRVOBJS=$(SRVOBJS0:%=$(OD)/%)
39CLIOBJS=$(CLIONLY) $(COBJS)44CLIOBJS0=$(CLIONLY) $(COBJS)
45CLIOBJS=$(CLIOBJS0:%=$(OD)/%)
4046
41ALLOBJS=$(SRVONLY) $(CLIONLY) $(COBJS)47ALLOBJS=$(SRVONLY) $(CLIONLY) $(COBJS)
4248
43stfufs-server: $(SRVOBJS) depend49stfufs-server: $(SRVOBJS)
44        $(CC) -o $@ $(SRVOBJS)50        $(CC) -o $@ $(SRVOBJS)
4551
46stfufs: $(CLIOBJS) depend52stfufs: $(CLIOBJS)
47        $(CC) -o $@ $(CLIOBJS) `pkg-config --libs fuse`53        $(CC) -o $@ $(CLIOBJS) `pkg-config --libs fuse`
54 
55ODS = $(OD)/stamp
56 
57$(ODS):
58        test -d $(OD) || mkdir $(OD)
59        touch $@
4860
49stfufs-client-fuse.o: stfufs-client-fuse.c61stfufs-client-fuse.o: stfufs-client-fuse.c
50        $(CC) -o $@ -c $< `pkg-config --cflags fuse` $(OPT) $(WOPTS)62        $(CC) -o $@ -c $< `pkg-config --cflags fuse` $(OPT) $(WOPTS)
5163
52.c.o:   depend64$(OD)/%.o: %.c $(ODS) $(DEP)
53        $(CC) -o $@ -c $<  $(OPT) $(WOPTS)65        $(CC) -o $@ -c $<  $(OPT) $(WOPTS)
5466
55stfufs-client-buffer.o: stfufs-buffer.c67$(OD)/stfufs-client-buffer.o: stfufs-buffer.c $(ODS) $(DEP)
56        $(CC) -o $@ -c $<  $(OPT) $(WOPTS) -DSTFUFS_CLIENT68        $(CC) -o $@ -c $<  $(OPT) $(WOPTS) -DSTFUFS_CLIENT
5769
58stfufs-server-buffer.o: stfufs-buffer.c70$(OD)/stfufs-server-buffer.o: stfufs-buffer.c $(ODS) $(DEP)
59        $(CC) -o $@ -c $<  $(OPT) $(WOPTS) -DSTFUFS_SERVER71        $(CC) -o $@ -c $<  $(OPT) $(WOPTS) -DSTFUFS_SERVER
6072
61# This is not currently cross-compiler compatible. Sorry.73# This is not currently cross-compiler compatible. Sorry.
66        ./gen-srv-errmap > $@78        ./gen-srv-errmap > $@
67        rm ./gen-srv-errmap79        rm ./gen-srv-errmap
6880
69depend: Makefile.build81$(DEP): Makefile.build
70        echo; devel/mkdep.perl $(CC) "$(OPT) -E" $(ALLOBJS) | tee depend; echo82        for i in *.c; do gcc -MM $(OPT) $$i; done \
83          | sed -e '/^[a-z]/ s|^|$(OD)/|' -e \
84                's|buffer.o:|client-buffer.o $(OD)/stfufs-server-buffer.o:|' \
85          > $(DEP)
7186
72include depend87include $(DEP)
88 
89install: $(TRGS) chkprefix
90        cp $(TRGS) $(PREFIX)/bin
91 
92chkprefix: ALWAYS
93        @[ x"$(PREFIX)" != x ] \
94                || { sed -n 's/^#prfx: \?/   /p;' Makefile.build; false; }
95        @[ -d "$(PREFIX)/bin" ] || { set -x; mkdir -m 755 -p "$(PREFIX)/bin"; }
96 
97#prfx:
98#prfx: Can not install: PREFIX missing.
99#prfx:
100#prfx: Try for example: 'make install PREFIX=/usr' or 'make install PREFIX=/usr/
 local'
101#prfx:
102 
103 
104.PHONY: ALWAYS
73105
74106
75tags:107tags:
76        etags *.c *.h108        etags *.c *.h
77109
78clean:110clean:
79        rm -f $(ALLOBJS) stfufs-server-errmap.c depend TAGS *~111        rm -rf stfufs-server-errmap.c TAGS _depend* _obj* *~
80 
81112
82distclean: clean113distclean: clean
83        rm -f $(TRGS)114        rm -f $(TRGS)

stfufs-1.0/README.brief stfufs-1.1/README.brief
3===========================3===========================
44
5---5---
61.061.1
7---7---
88
9Very brief for now, more to come if there is enough interest.9Very brief for now, more to come if there is enough interest.
1010
11**Note: Communication protocol in 1.1 is incompatible with 1.0 versions.**
12Connection attempt will fail if using mixed versions.
1113
12Brief Intro14Brief Intro
13===========15===========
47Enter ``make client`` or ``make server`` to compile either component.49Enter ``make client`` or ``make server`` to compile either component.
4850
49For developers/testers: Enter ``make debug`` to compile debug build.51For developers/testers: Enter ``make debug`` to compile debug build.
50Enter ``make clean all`` and ``make clean all`` to switch between debug
51and non-debug test versions.
52 
5352
54After client compilation on "local" machine (where directory is to be mounted)53After client compilation on "local" machine (where directory is to be mounted)
55and server compilation on "remote" machine (from where directory is mounted),54and server compilation on "remote" machine (from where directory is mounted),
142::141::
143142
144  protocol docs143  protocol docs
145  caching (single element or more, client/server side stuff)144  caching (single element is there now, maybe more, client/server side stuff)
146  more docs in general145  more docs in general
147  protocol updates for smarter stuff146  protocol updates for smarter stuff
148  pretocol using stfufs-buffer code (maybe)147  pretocol using stfufs-buffer code (maybe)
149  more.148  more
150149
151Thanks150Thanks
152======151======
153152
154- fuse_153- fuse_
155- sshfs_  (reference when doing arg parsing etc.)154- sshfs_  (reference when doing arg parsing etc.)
156- ltspfs_ (reference when creating this "minimal" first implementation)155- ltspfs_ (reference when creating "minimal" first implementation)
157156
158157
159Send comments and suggestions (and bug reports/patches) to too at iki dot fi158Send comments and suggestions (and bug reports/patches) to too at iki dot fi

Only in stfufs-1.0/devel: mkdep.perl

stfufs-1.0/pretocol.c stfufs-1.1/pretocol.c
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Sun Aug 26 19:08:59 EEST 2007 too9 * Created: Sun Aug 26 19:08:59 EEST 2007 too
10 * Last modified: Sat Jan 19 14:20:55 EET 2008 too10 * Last modified: Sun Jan 20 22:10:59 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
23#include <string.h>23#include <string.h>
2424
25#include "util.h"25#include "util.h"
26 
27#include "version.h"
2628
27int readwt(int fd, unsigned char * buf, int len, int timeout)29int readwt(int fd, unsigned char * buf, int len, int timeout)
28{30{
49}51}
5052
51/*                    123456789012345678901234567 */53/*                    123456789012345678901234567 */
52const char ident[] = "Simple TCP FUSE filesystem 1.0 protocol version 1\n";54const char ident[] = "Simple TCP FUSE filesystem " VERSION " protocol version 2\
 n";
5355
54void sendident(int fd)56void sendident(int fd)
55{57{
74    d0(("%d %s -%c %c-", l, buf, p[-3], p[-2]));76    d0(("%d %s -%c %c-", l, buf, p[-3], p[-2]));
7577
76    if (l == 0 || memcmp(buf, ident, 27) != 078    if (l == 0 || memcmp(buf, ident, 27) != 0
77        || p[-3] != ' ' || p[-2] != '1')79        || p[-3] != ' ' || p[-2] != '2')
78        die("Received ident mismatch"); /* XXX show ident. */80        die("Received ident mismatch"); /* XXX show ident. */
7981
80    if (i > 0) /* ack already in buffer */82    if (i > 0) /* ack already in buffer */
165167
166    remote = gethostbyname(host);168    remote = gethostbyname(host);
167    if (remote == null)169    if (remote == null)
168        die("gethostbyname on '%s' returned no value");170        die("gethostbyname on '%s' returned no value", host);
169171
170    memcpy(&addr.sin_addr, remote->h_addr, sizeof addr.sin_addr);172    memcpy(&addr.sin_addr, remote->h_addr, sizeof addr.sin_addr);
171173

stfufs-1.0/stfufs-buffer.c stfufs-1.1/stfufs-buffer.c
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Thu Dec 27 17:55:12 EET 2007 too9 * Created: Thu Dec 27 17:55:12 EET 2007 too
10 * Last modified: Sat Jan 19 14:47:15 EET 2008 too10 * Last modified: Sun Jan 20 16:15:17 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
1818
19#include "stfufs-buffer.h"19#include "stfufs-buffer.h"
2020
21#if STFUFS_CLIENT
22#define STFUFS_DATABUFSIZE 4116 /* 4096 + 16 + 4 */
23#elif STFUFS_SERVER21#if STFUFS_SERVER
24#define STFUFS_DATABUFSIZE 36892 /* 32768 + 4096 + 12 + 16 */22#define STFUFS_DATABUFSIZE 36892 /* 32768 + 4096 + 12 + 16 */
25#else23#else
26#error fixme24#define STFUFS_DATABUFSIZE 4116 /* 4096 + 16 + 4 */
27#endif25#endif
2826
29struct {27struct {

stfufs-1.0/stfufs-client-fuse.c stfufs-1.1/stfufs-client-fuse.c
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Tue Aug 28 21:47:30 EEST 2007 too9 * Created: Tue Aug 28 21:47:30 EEST 2007 too
10 * Last modified: Sat Jan 19 09:56:24 EET 2008 too10 * Last modified: Sun Jan 20 22:05:37 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
3434
35#define AMIGA_LIST_INLINE35#define AMIGA_LIST_INLINE
36#include "amiga_list.h"36#include "amiga_list.h"
37 
38#include "version.h"
3739
38#ifndef null40#ifndef null
39#define null ((void *)0)41#define null ((void *)0)
56/* #define  stfufs_open  null */58/* #define  stfufs_open  null */
57/* #define  stfufs_read  null */59/* #define  stfufs_read  null */
58/* #define  stfufs_write  null */60/* #define  stfufs_write  null */
59/*#define  stfufs_statfs  null */61/* #define  stfufs_statfs  null */
60#define  stfufs_flush  null62#define  stfufs_flush  null
61#define  stfufs_release  null63/* #define  stfufs_release  null */
62#define  stfufs_fsync  null64#define  stfufs_fsync  null
63#define  stfufs_setxattr  null65#define  stfufs_setxattr  null
64#define  stfufs_getxattr  null66#define  stfufs_getxattr  null
997999
998    return stfufs_client_request_handle(STFUFS__STATFS, iov, iovlen, alen,1000    return stfufs_client_request_handle(STFUFS__STATFS, iov, iovlen, alen,
999                                        stfufs_statfs_cb, (void*)stbuf);1001                                        stfufs_statfs_cb, (void*)stbuf);
1002}
1003 
1004 
1005/* like mkdir. refactor */
1006static int stfufs_release(const char * path, struct fuse_file_info * fi)
1007{
1008    uint8_t buf[32];
1009    struct iovec iov[3];
1010    int iovlen;
1011    int plen = strlen(path) + 1;
1012    int alen = (plen + 3) & ~3;
1013 
1014    d1(("--- %s(\"%s\", %p)", __func__, path, fi));
1015 
1016    iov[0].iov_base = buf; /* stfufs_client_request_handle() will fill this */
1017    iov[0].iov_len = REQUEST_HEADER_LEN;
1018    iov[1].iov_base = str_unconst(path); /* const void * when writing... */
1019    iov[1].iov_len = plen;
1020 
1021    if (plen != alen) {
1022        iov[2].iov_base = str_unconst(G_pad000); /*const void * when writing */
1023        iov[2].iov_len = alen - plen;
1024        iovlen = 3;
1025    }
1026    else iovlen = 2;
1027 
1028    return stfufs_client_request_handle(STFUFS__RELEASE, iov, iovlen, alen,
1029                                        stfufs_ok_cb, null);
1000}1030}
10011031
10021032
11331163
1134void usage(char * progname)1164void usage(char * progname)
1135{1165{
1136    fprintf(stderr, "\nUsage: %s host:path mountpoint [options]\n",1166    fprintf(stderr, "\nUsage: %s [user@]host:path mountpoint [options]\n",
1137            progname);1167            progname);
11381168
1139    fprintf(stderr, "\n    Options:\n\n"1169    fprintf(stderr, "\n    Options:\n\n"
1141            "\t -b port           -- bind to port so server can connect back the1171            "\t -b port           -- bind to port so server can connect back the
re\n"re\n"
1142            "\t -p [host:][port]  -- proxy traffic via this host/port\n"1172            "\t -p [host:][port]  -- proxy traffic via this host/port\n"
1143            "\n\t Without any of the above options given server\n"1173            "\n\t Without any of the above options given server\n"
1144            "\t chooses suitable port for client to connect.\n"1174            "\t chooses suitable port for client to connect.\n\n"
1175            "\t -v                -- stfufs version information\n"
1145        );1176        );
1146    fprintf(stderr, "\n    Example: %s ssh://too@remote:Mail remoteMail\n\n",1177    fprintf(stderr, "\n    Example: %s too@remote:Mail remoteMail\n\n",
1147            progname);1178            progname);
11481179
1149}1180}
11501181
11511182
1152enum { KEY_CONN = 1, KEY_BIND, KEY_PROXY, KEY_HELP };1183enum { KEY_CONN = 1, KEY_BIND, KEY_PROXY, KEY_HELP, KEY_VERSION };
11531184
1154static int stfufs_handle_args(void * data, const char * arg, int key,1185static int stfufs_handle_args(void * data, const char * arg, int key,
1155                              struct fuse_args * outargs)1186                              struct fuse_args * outargs)
1175        fuse_opt_add_arg(outargs, "-ho");1206        fuse_opt_add_arg(outargs, "-ho");
1176        fuse_main(outargs->argc, outargs->argv, &stfufs_operations, null);1207        fuse_main(outargs->argc, outargs->argv, &stfufs_operations, null);
1177        exit(1);1208        exit(1);
1209    case KEY_VERSION:
1210    {   extern const char ident[]; /* XXX from proper header, please */
1211        fprintf(stderr, "\n %s\n", ident); }
1212        exit(0);
1178    default:1213    default:
1179        die("arg parse internal error: key %d:%s", key, arg);1214        die("arg parse internal error: key %d:%s", key, arg);
1180    }1215    }
1186    FUSE_OPT_KEY("-p ", KEY_PROXY),1221    FUSE_OPT_KEY("-p ", KEY_PROXY),
1187    FUSE_OPT_KEY("-h", KEY_HELP),1222    FUSE_OPT_KEY("-h", KEY_HELP),
1188    FUSE_OPT_KEY("--help", KEY_HELP),1223    FUSE_OPT_KEY("--help", KEY_HELP),
1224    FUSE_OPT_KEY("-v", KEY_VERSION),
1189    { null, 0, 0 }1225    { null, 0, 0 }
1190    /* FUSE_OPT_END */1226    /* FUSE_OPT_END */
1191};1227};

stfufs-1.0/stfufs-client.c stfufs-1.1/stfufs-client.c
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Sun 26 Aug 2007 08:14:57 AM EEST too9 * Created: Sun 26 Aug 2007 08:14:57 AM EEST too
10 * Last modified: Sat Jan 12 16:32:47 EET 2008 too10 * Last modified: Sun Jan 20 22:13:38 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
264        char * tcphost = strrchr(cargs->sshhost, '@');264        char * tcphost = strrchr(cargs->sshhost, '@');
265        if (tcphost == null)265        if (tcphost == null)
266            tcphost = cargs->sshhost;266            tcphost = cargs->sshhost;
267        else
268            tcphost++;
267        if (cargs->proxyport) {269        if (cargs->proxyport) {
268            if (cargs->proxyhost == null)270            if (cargs->proxyhost == null)
269                fd = doconnect(buf, tcphost, cargs->proxyport);271                fd = doconnect(buf, tcphost, cargs->proxyport);

stfufs-1.0/stfufs-server-fs.c stfufs-1.1/stfufs-server-fs.c
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Tue Aug 28 21:47:42 EEST 2007 too9 * Created: Tue Aug 28 21:47:42 EEST 2007 too
10 * Last modified: Thu Jan 17 19:31:44 EET 2008 too10 * Last modified: Sun Jan 20 19:59:47 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
459    return ll;459    return ll;
460}460}
461461
462struct SEC4RW /* single element cache for read/write */
463{
464    uint32_t path[4100];
465    int fd;
466    off_t offset;
467};
468 
469struct SEC4RW readsec;
470 
462static uint8_t * stfufs_server_read(uint8_t * p,471static uint8_t * stfufs_server_read(uint8_t * p,
463                                    uint32_t type, uint32_t id, int clen)472                                    uint32_t type, uint32_t id, int clen)
464{473{
467    uint32_t size;476    uint32_t size;
468    off_t offset;477    off_t offset;
469    uint8_t buf[32768 + 16];478    uint8_t buf[32768 + 16];
479    uint8_t * filename;
480    off_t cacheoffset;
470481
471    d1(("--- stfufs_server_read(%p, %x, %d, %d)", p, type, id, clen));482    d1(("--- stfufs_server_read(%p, %x, %d, %d)", p, type, id, clen));
472483
478    size = xdecode_uint32(&p);489    size = xdecode_uint32(&p);
479    offset = xdecode_uint64(&p);490    offset = xdecode_uint64(&p);
480491
492    if (memcmp(readsec.path, p, clen - 12) == 0) {
493        fd = readsec.fd;
494        cacheoffset = readsec.offset;
495    }
496    else {
481    if ((fd = open(_mypath(p), O_RDONLY, 0)) < 0) {497        if ((fd = open(_mypath(p), O_RDONLY, 0)) < 0) {
482        _write_status(type, id, errno);498            _write_status(type, id, errno);
483        return r;499            return r;
500        }
501        cacheoffset = -1;
484    }502    }
503    if (cacheoffset == offset)
504        d1(("Optimal cache hit at offset %lld", offset));
505    else {
485    if (lseek(fd, offset, SEEK_SET) < 0) {506        if (lseek(fd, offset, SEEK_SET) < 0) {
486        _write_status(type, id, errno);507            _write_status(type, id, errno);
508            if (cacheoffset < 0)
487        close(fd);509                close(fd);
488        return r;510            return r;
489    }511        }}
512    filename = p;
513 
490    if (size > 32768)514    if (size > 32768)
491        size = 32768;515        size = 32768;
492516
493    len = areadfully(fd, buf + 16, size);517    len = areadfully(fd, buf + 16, size);
494    d1(("%d = read(%d, %p, %d)", len, fd, buf + 16, size));518    d1(("%d = read(%d, %p, %d)", len, fd, buf + 16, size));
495519
496    close(fd);
497    if (len < 0) {520    if (len < 0) {
498        _write_status(type, id, errno);521        _write_status(type, id, errno);
522        if (cacheoffset < 0)
523            close(fd);
499        return r;524        return r;
500    }525    }
526 
527    if (cacheoffset < 0) {
528        if (clen - 12 > sizeof readsec.path)
529            close(fd);
530        else {
531            if (readsec.fd >= 0)
532                close(readsec.fd);
533            memcpy(readsec.path, filename, clen - 12);
534            readsec.fd = fd;
535            d1(("--- read path '%s'", p));
536        }}
537    readsec.offset = offset + len;
501538
502    p = buf;539    p = buf;
503    p = xencode_uint32(p, type);540    p = xencode_uint32(p, type);
510    return r;547    return r;
511}548}
512549
550struct SEC4RW writesec;
551 
513static uint8_t * stfufs_server_write(uint8_t * p,552static uint8_t * stfufs_server_write(uint8_t * p,
514                                     uint32_t type, uint32_t id, int clen)553                                     uint32_t type, uint32_t id, int clen)
515{554{
518    int fd;557    int fd;
519    uint32_t size, palen, len;558    uint32_t size, palen, len;
520    off_t offset;559    off_t offset;
560    uint8_t * filename;
561    off_t cacheoffset;
521562
522    d1(("stfufs_server_write(%p, %x, %d, %d)", p, type, id, clen));563    d1(("stfufs_server_write(%p, %x, %d, %d)", p, type, id, clen));
523564
534    if ((p = stfufs_buffer_reserve(p, palen)) == null)575    if ((p = stfufs_buffer_reserve(p, palen)) == null)
535        return null;576        return null;
536577
578    if (memcmp(writesec.path, p, palen) == 0) {
579        fd = writesec.fd;
580        cacheoffset = writesec.offset;
581    }
582    else {
537    if ((fd = open(_mypath(p), O_WRONLY, 0500)) < 0) {583        if ((fd = open(_mypath(p), O_WRONLY, 0500)) < 0) {
538        _write_status(type, id, errno);584            _write_status(type, id, errno);
539        return stfufs_buffer_discard(r, clen);585            return stfufs_buffer_discard(r, clen);
586        }
587        cacheoffset = -1;
540    }588    }
589    if (cacheoffset == offset)
590        d1(("Optimal cache hit at offset %lld", offset));
591    else {
541    if (lseek(fd, offset, SEEK_SET) < 0) {592        if (lseek(fd, offset, SEEK_SET) < 0) {
542        _write_status(type, id, errno);593            _write_status(type, id, errno);
594            if (cacheoffset < 0)
543        close(fd);595                close(fd);
544        return stfufs_buffer_discard(r, clen);596            return stfufs_buffer_discard(r, clen);
545    }597        }}
598    filename = p;
546599
547    p += palen;600    p += palen;
548    len = stfufs_buffer_rest(p);601    len = stfufs_buffer_rest(p);
549602
550    if ((int32_t)(len = write(fd, p, len < size? len: size)) < 0) {603    if ((int32_t)(len = write(fd, p, len < size? len: size)) < 0) {
551        _write_status(type, id, errno);604        _write_status(type, id, errno);
605        if (cacheoffset < 0)
552        close(fd);606            close(fd);
553        return stfufs_buffer_discard(r, clen);607        return stfufs_buffer_discard(r, clen);
554    }608    }
555    /* XXX partial write above is a problem ! need a wrapper or something */609    /* XXX partial write above is a problem ! need a wrapper or something */
565        r = p + needreserve;619        r = p + needreserve;
566        if ((len2 = write(fd, p, missing)) < 0) {620        if ((len2 = write(fd, p, missing)) < 0) {
567            _write_status(type, id, errno);621            _write_status(type, id, errno);
622            if (cacheoffset < 0)
568            close(fd);623                close(fd);
569            return r;624            return r;
570        }625        }
571        len += len2;626        len += len2;
572    }627    }
628 
629    if (cacheoffset < 0) {
630        if (palen > sizeof writesec.path)
573    close(fd);631            close(fd);
632        else {
633            if (writesec.fd >= 0)
634                close(writesec.fd);
635            memcpy(writesec.path, filename, palen);
636            writesec.fd = fd;
637            d1(("--- write path '%s'", p));
638        }}
639    writesec.offset = offset + len;
574640
575    p = buf;641    p = buf;
576    p = xencode_uint32(p, type);642    p = xencode_uint32(p, type);
633}699}
634700
635701
702static uint8_t * stfufs_server_release(uint8_t * p,
703                                       uint32_t type, uint32_t id, int clen)
704{
705    uint8_t * r;
706 
707    d1(("--- stfufs_server_release(%p, %x, %d, %d)", p, type, id, clen));
708 
709    if ((p = stfufs_buffer_reserve(p, clen)) == null)
710        return null;
711 
712    if (memcmp(p, readsec.path, clen) == 0) {
713        d1(("read release: '%s'", p));
714        readsec.path[0] = 0;
715        close(readsec.fd);
716        readsec.fd = -1;
717    }
718    if (memcmp(p, writesec.path, clen) == 0) {
719        d1(("write release: '%s'", p));
720        writesec.path[0] = 0;
721        close(writesec.fd);
722        writesec.fd = -1;
723    }
724 
725    r = p + clen;
726 
727    /* do release on _mypath(p) */
728    errno = 0;
729 
730    _write_status(type, id, errno);
731    return r;
732}
733 
636static uint8_t * stfufs_server_readdir(uint8_t * p,734static uint8_t * stfufs_server_readdir(uint8_t * p,
637                                      uint32_t type, uint32_t id, int clen)735                                      uint32_t type, uint32_t id, int clen)
638{736{
722    stfufs_server_write,820    stfufs_server_write,
723    stfufs_server_statfs, /* 17 */821    stfufs_server_statfs, /* 17 */
724    unsupported,822    unsupported,
725    unsupported,823    stfufs_server_release,
726    unsupported,824    unsupported,
727    unsupported,825    unsupported,
728    unsupported,826    unsupported,
743void stfufs_server()841void stfufs_server()
744{842{
745    uint8_t * p = stfufs_buffer_init(0);843    uint8_t * p = stfufs_buffer_init(0);
844 
845    readsec.path[0] = writesec.path[0] = 0;
846    readsec.fd = writesec.fd = -1;
746847
747    while (1)848    while (1)
748    {849    {

Only in stfufs-1.1: version.h