| stfufs-1.0/Makefile.build | | stfufs-1.1/Makefile.build |
| 13 | | 13 | |
| 14 | O64= -DLARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 | 14 | O64= -DLARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 |
| 15 | | 15 | |
| 16 | DF= -O2 -DDEBUG=0 | 16 | OD ?= /dev/null |
| 17 | | 17 | DEBUG ?= 0 |
| 18 | OPT= $(O64) $(DF) | 18 | DEP ?= _depend |
| 19 | | 19 | |
| 20 | TRGS=stfufs-server stfufs | 20 | TRGS=stfufs-server stfufs |
| 21 | | 21 | |
| 22 | all: $(TRGS) | 22 | all: $(TRGS) |
| 23 | | 23 | |
| | 24 | DF= -O2 |
| | 25 | |
| 24 | debug: DF= -ggdb -DDEBUG=1 -fstack-protector -Wstack-protector | 26 | __debug: DF= -ggdb -fstack-protector -Wstack-protector |
| 25 | debug: $(TRGS) | 27 | __debug: $(TRGS) |
| | 28 | |
| | 29 | OPT= $(O64) $(DF) -DDEBUG=$(DEBUG) |
| 26 | | 30 | |
| 27 | client: stfufs | 31 | client: stfufs |
| 28 | server: stfufs-server | 32 | server: stfufs-server |
| 35 | CLIONLY=stfufs-client.o stfufs-client-fuse.o \ | 39 | CLIONLY=stfufs-client.o stfufs-client-fuse.o \ |
| 36 | stfufs-client-buffer.o stfufs-client-errmap.o | 40 | stfufs-client-buffer.o stfufs-client-errmap.o |
| 37 | | 41 | |
| 38 | SRVOBJS=$(SRVONLY) $(COBJS) | 42 | SRVOBJS0=$(SRVONLY) $(COBJS) |
| | 43 | SRVOBJS=$(SRVOBJS0:%=$(OD)/%) |
| 39 | CLIOBJS=$(CLIONLY) $(COBJS) | 44 | CLIOBJS0=$(CLIONLY) $(COBJS) |
| | 45 | CLIOBJS=$(CLIOBJS0:%=$(OD)/%) |
| 40 | | 46 | |
| 41 | ALLOBJS=$(SRVONLY) $(CLIONLY) $(COBJS) | 47 | ALLOBJS=$(SRVONLY) $(CLIONLY) $(COBJS) |
| 42 | | 48 | |
| 43 | stfufs-server: $(SRVOBJS) depend | 49 | stfufs-server: $(SRVOBJS) |
| 44 | $(CC) -o $@ $(SRVOBJS) | 50 | $(CC) -o $@ $(SRVOBJS) |
| 45 | | 51 | |
| 46 | stfufs: $(CLIOBJS) depend | 52 | stfufs: $(CLIOBJS) |
| 47 | $(CC) -o $@ $(CLIOBJS) `pkg-config --libs fuse` | 53 | $(CC) -o $@ $(CLIOBJS) `pkg-config --libs fuse` |
| | 54 | |
| | 55 | ODS = $(OD)/stamp |
| | 56 | |
| | 57 | $(ODS): |
| | 58 | test -d $(OD) || mkdir $(OD) |
| | 59 | touch $@ |
| 48 | | 60 | |
| 49 | stfufs-client-fuse.o: stfufs-client-fuse.c | 61 | stfufs-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) |
| 51 | | 63 | |
| 52 | .c.o: depend | 64 | $(OD)/%.o: %.c $(ODS) $(DEP) |
| 53 | $(CC) -o $@ -c $< $(OPT) $(WOPTS) | 65 | $(CC) -o $@ -c $< $(OPT) $(WOPTS) |
| 54 | | 66 | |
| 55 | stfufs-client-buffer.o: stfufs-buffer.c | 67 | $(OD)/stfufs-client-buffer.o: stfufs-buffer.c $(ODS) $(DEP) |
| 56 | $(CC) -o $@ -c $< $(OPT) $(WOPTS) -DSTFUFS_CLIENT | 68 | $(CC) -o $@ -c $< $(OPT) $(WOPTS) -DSTFUFS_CLIENT |
| 57 | | 69 | |
| 58 | stfufs-server-buffer.o: stfufs-buffer.c | 70 | $(OD)/stfufs-server-buffer.o: stfufs-buffer.c $(ODS) $(DEP) |
| 59 | $(CC) -o $@ -c $< $(OPT) $(WOPTS) -DSTFUFS_SERVER | 71 | $(CC) -o $@ -c $< $(OPT) $(WOPTS) -DSTFUFS_SERVER |
| 60 | | 72 | |
| 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-errmap | 79 | rm ./gen-srv-errmap |
| 68 | | 80 | |
| 69 | depend: Makefile.build | 81 | $(DEP): Makefile.build |
| 70 | echo; devel/mkdep.perl $(CC) "$(OPT) -E" $(ALLOBJS) | tee depend; echo | 82 | 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) |
| 71 | | 86 | |
| 72 | include depend | 87 | include $(DEP) |
| | 88 | |
| | 89 | install: $(TRGS) chkprefix |
| | 90 | cp $(TRGS) $(PREFIX)/bin |
| | 91 | |
| | 92 | chkprefix: 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 |
| 73 | | 105 | |
| 74 | | 106 | |
| 75 | tags: | 107 | tags: |
| 76 | etags *.c *.h | 108 | etags *.c *.h |
| 77 | | 109 | |
| 78 | clean: | 110 | clean: |
| 79 | rm -f $(ALLOBJS) stfufs-server-errmap.c depend TAGS *~ | 111 | rm -rf stfufs-server-errmap.c TAGS _depend* _obj* *~ |
| 80 | | | |
| 81 | | 112 | |
| 82 | distclean: clean | 113 | distclean: clean |
| 83 | rm -f $(TRGS) | 114 | rm -f $(TRGS) |
| stfufs-1.0/pretocol.c | | stfufs-1.1/pretocol.c |
| 7 | * All rights reserved | 7 | * All rights reserved |
| 8 | * | 8 | * |
| 9 | * Created: Sun Aug 26 19:08:59 EEST 2007 too | 9 | * Created: Sun Aug 26 19:08:59 EEST 2007 too |
| 10 | * Last modified: Sat Jan 19 14:20:55 EET 2008 too | 10 | * Last modified: Sun Jan 20 22:10:59 EET 2008 too |
| 11 | */ | 11 | */ |
| 12 | | 12 | |
| 13 | #include <unistd.h> | 13 | #include <unistd.h> |
| 23 | #include <string.h> | 23 | #include <string.h> |
| 24 | | 24 | |
| 25 | #include "util.h" | 25 | #include "util.h" |
| | 26 | |
| | 27 | #include "version.h" |
| 26 | | 28 | |
| 27 | int readwt(int fd, unsigned char * buf, int len, int timeout) | 29 | int readwt(int fd, unsigned char * buf, int len, int timeout) |
| 28 | { | 30 | { |
| 49 | } | 51 | } |
| 50 | | 52 | |
| 51 | /* 123456789012345678901234567 */ | 53 | /* 123456789012345678901234567 */ |
| 52 | const char ident[] = "Simple TCP FUSE filesystem 1.0 protocol version 1\n"; | 54 | const char ident[] = "Simple TCP FUSE filesystem " VERSION " protocol version 2\ |
| | | n"; |
| 53 | | 55 | |
| 54 | void sendident(int fd) | 56 | void 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])); |
| 75 | | 77 | |
| 76 | if (l == 0 || memcmp(buf, ident, 27) != 0 | 78 | 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. */ |
| 79 | | 81 | |
| 80 | if (i > 0) /* ack already in buffer */ | 82 | if (i > 0) /* ack already in buffer */ |
| 165 | | 167 | |
| 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); |
| 169 | | 171 | |
| 170 | memcpy(&addr.sin_addr, remote->h_addr, sizeof addr.sin_addr); | 172 | memcpy(&addr.sin_addr, remote->h_addr, sizeof addr.sin_addr); |
| 171 | | 173 | |
| stfufs-1.0/stfufs-client-fuse.c | | stfufs-1.1/stfufs-client-fuse.c |
| 7 | * All rights reserved | 7 | * All rights reserved |
| 8 | * | 8 | * |
| 9 | * Created: Tue Aug 28 21:47:30 EEST 2007 too | 9 | * Created: Tue Aug 28 21:47:30 EEST 2007 too |
| 10 | * Last modified: Sat Jan 19 09:56:24 EET 2008 too | 10 | * Last modified: Sun Jan 20 22:05:37 EET 2008 too |
| 11 | */ | 11 | */ |
| 12 | | 12 | |
| 13 | #include <unistd.h> | 13 | #include <unistd.h> |
| 34 | | 34 | |
| 35 | #define AMIGA_LIST_INLINE | 35 | #define AMIGA_LIST_INLINE |
| 36 | #include "amiga_list.h" | 36 | #include "amiga_list.h" |
| | 37 | |
| | 38 | #include "version.h" |
| 37 | | 39 | |
| 38 | #ifndef null | 40 | #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 null | 62 | #define stfufs_flush null |
| 61 | #define stfufs_release null | 63 | /* #define stfufs_release null */ |
| 62 | #define stfufs_fsync null | 64 | #define stfufs_fsync null |
| 63 | #define stfufs_setxattr null | 65 | #define stfufs_setxattr null |
| 64 | #define stfufs_getxattr null | 66 | #define stfufs_getxattr null |
| 997 | | 999 | |
| 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 */ |
| | 1006 | static 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 | } |
| 1001 | | 1031 | |
| 1002 | | 1032 | |
| 1133 | | 1163 | |
| 1134 | void usage(char * progname) | 1164 | void 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); |
| 1138 | | 1168 | |
| 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 the | 1171 | "\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); |
| 1148 | | 1179 | |
| 1149 | } | 1180 | } |
| 1150 | | 1181 | |
| 1151 | | 1182 | |
| 1152 | enum { KEY_CONN = 1, KEY_BIND, KEY_PROXY, KEY_HELP }; | 1183 | enum { KEY_CONN = 1, KEY_BIND, KEY_PROXY, KEY_HELP, KEY_VERSION }; |
| 1153 | | 1184 | |
| 1154 | static int stfufs_handle_args(void * data, const char * arg, int key, | 1185 | static 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-server-fs.c | | stfufs-1.1/stfufs-server-fs.c |
| 7 | * All rights reserved | 7 | * All rights reserved |
| 8 | * | 8 | * |
| 9 | * Created: Tue Aug 28 21:47:42 EEST 2007 too | 9 | * Created: Tue Aug 28 21:47:42 EEST 2007 too |
| 10 | * Last modified: Thu Jan 17 19:31:44 EET 2008 too | 10 | * Last modified: Sun Jan 20 19:59:47 EET 2008 too |
| 11 | */ | 11 | */ |
| 12 | | 12 | |
| 13 | #include <unistd.h> | 13 | #include <unistd.h> |
| 459 | return ll; | 459 | return ll; |
| 460 | } | 460 | } |
| 461 | | 461 | |
| | 462 | struct SEC4RW /* single element cache for read/write */ |
| | 463 | { |
| | 464 | uint32_t path[4100]; |
| | 465 | int fd; |
| | 466 | off_t offset; |
| | 467 | }; |
| | 468 | |
| | 469 | struct SEC4RW readsec; |
| | 470 | |
| 462 | static uint8_t * stfufs_server_read(uint8_t * p, | 471 | static 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; |
| 470 | | 481 | |
| 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)); |
| 472 | | 483 | |
| 478 | size = xdecode_uint32(&p); | 489 | size = xdecode_uint32(&p); |
| 479 | offset = xdecode_uint64(&p); | 490 | offset = xdecode_uint64(&p); |
| 480 | | 491 | |
| | 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; |
| 492 | | 516 | |
| 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)); |
| 495 | | 519 | |
| 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; |
| 501 | | 538 | |
| 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 | } |
| 512 | | 549 | |
| | 550 | struct SEC4RW writesec; |
| | 551 | |
| 513 | static uint8_t * stfufs_server_write(uint8_t * p, | 552 | static 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; |
| 521 | | 562 | |
| 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)); |
| 523 | | 564 | |
| 534 | if ((p = stfufs_buffer_reserve(p, palen)) == null) | 575 | if ((p = stfufs_buffer_reserve(p, palen)) == null) |
| 535 | return null; | 576 | return null; |
| 536 | | 577 | |
| | 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; |
| 546 | | 599 | |
| 547 | p += palen; | 600 | p += palen; |
| 548 | len = stfufs_buffer_rest(p); | 601 | len = stfufs_buffer_rest(p); |
| 549 | | 602 | |
| 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; |
| 574 | | 640 | |
| 575 | p = buf; | 641 | p = buf; |
| 576 | p = xencode_uint32(p, type); | 642 | p = xencode_uint32(p, type); |
| 633 | } | 699 | } |
| 634 | | 700 | |
| 635 | | 701 | |
| | 702 | static 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 | |
| 636 | static uint8_t * stfufs_server_readdir(uint8_t * p, | 734 | static 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, |
| 743 | void stfufs_server() | 841 | void 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; |
| 746 | | 847 | |
| 747 | while (1) | 848 | while (1) |
| 748 | { | 849 | { |