stfufs-1.1/ChangeLog stfufs-1.2/ChangeLog
12008-02-01  Tomi Ollila
2 
3        * Release 1.2 (beta quality persists, no known bugs, though)
4 
5        * make install now requires PREFIX directory to exist
6 
7        * A few debugging tunes and improvements
8 
92008-01-31  Tomi Ollila
10 
11        * Final release tunes in stfufs components
12 
132008-01-30  Tomi Ollila
14 
15        * Some error messages and error behaviour tunes
16 
17        * Bug fixes in server launcher program
18 
192008-01-29  Tomi Ollila
20 
21        * Bug fixes in new protocol implementation
22 
232008-01-28  Tomi Ollila
24 
25        * Dropped single element read/write caches in server end, replaced
26          with 1024-item offset table. This makes multible reads/writes
27          "cached" -- also this limits concurrent reads/writes to max 1024
28 
292008-01-22  Tomi Ollila
30 
31        * Created separate server launcher program so that server end
32          can support multible protocol versions
33 
12008-01-20  Tomi Ollila342008-01-20  Tomi Ollila
235
3        * Release 1.1 (beta quality, more tests needed to ensure stability)36        * Release 1.1 (beta quality, more tests needed to ensure stability)

stfufs-1.1/Makefile stfufs-1.2/Makefile
17#+#  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).
18#+#18#+#
1919
20# No implicit rules (at least these)
21.SUFFIXES:
22% : %.o
23% : %.c
24%.o : %.c
25 
20debug:26debug:
21         $(MAKE) -f Makefile.build __debug OD=_obj_dbg DEBUG=1 DEP=_depend_dbg27         $(MAKE) -f Makefile.build __debug OD=_obj_dbg DEBUG=1 DEP=_depend_dbg
2228
29snap=-xxx
2330
24snapshot: ver=$$ver-`date +%Y%m%d`31snapshot: snap=-`date +%Y%m%d`
25snapshot: _dist32snapshot: _dist
2633
27release: ver=$$ver34release: snap=
28release: _dist35release: _dist
2936
30_dist:37_dist:
31        case '$(ver)' in '') echo "xxx"; false ;; esac38        eval `sh version.h`; \
32        ver=`sed -n '/VERSION /{s/.*VERSION *"//;s/".*//;p;}' version.h`; \
33        ver=stfufs-$(ver); { echo 755 root root . $$ver /; \39        version=stfufs-$$version$(snap); { echo 755 root root . $$version /; \
34        grep '^#,#' Makefile | while read _ f x; do p=755; d=$$f; \40        grep '^#,#' Makefile | while read _ f x; do p=755; d=$$f; \
35                test -d $$f && d=/ || case $$x in '') p=644;; esac; \41                test -d $$f && d=/ || case $$x in '') p=644;; esac; \
36                echo $$p root root . $$ver/$$f $$d; done; } \42                echo $$p root root . $$version/$$f $$d; done; } \
37        | tarlisted -Vz -o $$ver.tar.gz43        | tarlisted -Vz -o $$version.tar.gz
3844
39#,#  ChangeLog45#,#  ChangeLog
40#,#  README.brief46#,#  README.brief
58#,#  stfufs.h64#,#  stfufs.h
59#,#  stfufs-server.c65#,#  stfufs-server.c
60#,#  stfufs-server-fs.c66#,#  stfufs-server-fs.c
67#,#  stfufs-server-launcher.c
61#,#  util.c68#,#  util.c
62#,#  util.h69#,#  util.h
63#,#  version.h70#,#  version.h

stfufs-1.1/Makefile.build stfufs-1.2/Makefile.build
17DEBUG ?= 017DEBUG ?= 0
18DEP   ?= _depend18DEP   ?= _depend
1919
20TRGS=stfufs-server stfufs20TRGS=stfufs-server stfufs-server-launcher stfufs
2121
22all:  $(TRGS)22all:  $(TRGS)
2323
24DF= -O224CF= -O2
25LF= -s
2526
26__debug: DF= -ggdb -fstack-protector -Wstack-protector27__debug: CF= -ggdb -fstack-protector -Wstack-protector
28__debug: LF=
27__debug: $(TRGS)29__debug: $(TRGS)
2830
29OPT= $(O64) $(DF) -DDEBUG=$(DEBUG)31OPT= $(O64) $(CF) -DDEBUG=$(DEBUG)
3032
31client: stfufs33client: stfufs
32server: stfufs-server34server: stfufs-server stfufs-server-launcher
3335
34COBJS=pretocol.o random.o util.o simplexdr.o36COBJS=pretocol.o random.o util.o simplexdr.o
3537
47ALLOBJS=$(SRVONLY) $(CLIONLY) $(COBJS)49ALLOBJS=$(SRVONLY) $(CLIONLY) $(COBJS)
4850
49stfufs-server: $(SRVOBJS)51stfufs-server: $(SRVOBJS)
50        $(CC) -o $@ $(SRVOBJS)52        $(CC) $(LF) -o $@ $(SRVOBJS)
53 
54stfufs-server-launcher: stfufs-server-launcher.c
55        $(CC) $(LF) -o $@ $(OPT) $(WOPTS) $<
56 
5157
52stfufs: $(CLIOBJS)58stfufs: $(CLIOBJS)
53        $(CC) -o $@ $(CLIOBJS) `pkg-config --libs fuse`59        $(CC) $(LF) -o $@ $(CLIOBJS) `pkg-config --libs fuse`
5460
55ODS = $(OD)/stamp61ODS = $(OD)/stamp
5662
87include $(DEP)93include $(DEP)
8894
89install: $(TRGS) chkprefix95install: $(TRGS) chkprefix
90        cp $(TRGS) $(PREFIX)/bin96        sed -n '/^install.sh:/,/^ *$$/ p' Makefile.build \
97                | tail -n +4 | sh -ves
9198
92chkprefix: ALWAYS99chkprefix: ALWAYS
93        @[ x"$(PREFIX)" != x ] \100        @[ x"$(PREFIX)" != x ] \
94                || { sed -n 's/^#prfx: \?/   /p;' Makefile.build; false; }101                || { sed -n 's/^#prfx: \?/ /p;' Makefile.build; false; }
95        @[ -d "$(PREFIX)/bin" ] || { set -x; mkdir -m 755 -p "$(PREFIX)/bin"; }
96102
97#prfx:103#prfx:
98#prfx: Can not install: PREFIX missing.104#prfx: Can not install: PREFIX missing.
99#prfx:105#prfx:
106#prfx: files to be installed:
107#prfx:
108#prfx:    PREFIX/bin/stfufs
109#prfx:    PREFIX/bin/stfufs-server
110#prfx:    PREFIX/lib/stfufs/stfufs-server-<protocol version>
111#prfx:
100#prfx: Try for example: 'make install PREFIX=/usr' or 'make install PREFIX=/usr/112#prfx: Try for example: 'make install PREFIX=/usr' or 'make install PREFIX=/usr/
local'local'
101#prfx:113#prfx:
102114
115install.sh:
116        exit 1 # this target is not to be run
117        :
118        die () { echo "$@" >&2; exit 1; }
119        [ -d "$PREFIX" ] || die Directory "'"$PREFIX"'" does not exist
120        [ -d "$PREFIX/bin" ] || { set -x; mkdir -m 755 -p "$PREFIX/bin"; }
121        [ -d "$PREFIX/lib/stfufs" ] \
122                || { set -x; mkdir -m 755 -p "$PREFIX/lib/stfufs"; }
123        :
124        grep ' TCP FUSE .* protocol version 2' $PREFIX/bin/stfufs-server \
125                && cp $PREFIX/bin/stfufs-server $PREFIX/lib/stfufs/stfufs-server
 -2 || true
126        test -x stfufs && cp stfufs $PREFIX/bin || true
127        cp stfufs-server-launcher $PREFIX/bin/stfufs-server
128        eval `sh version.h`
129        cp stfufs-server $PREFIX/lib/stfufs/stfufs-server-$protver
103130
104.PHONY: ALWAYS131.PHONY: ALWAYS
105132

stfufs-1.1/README.brief stfufs-1.2/README.brief
3===========================3===========================
44
5---5---
61.161.2
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.**11**Note: Communication protocol in 1.2 is incompatible with older verions.**
12Connection attempt will fail if using mixed versions.12Connection attempt will fail if using mixed versions.
13 
14Server end may have versions 1.1 and 1.2 installed at the same time if 1.1
15is installed when 1.2 is being installed. If this is the case, both 1.1 client
16and 1.2 client can connect to stfufs server.
17 
1318
14Brief Intro19Brief Intro
15===========20===========
272) The machines has important high-load application(s) running.322) The machines has important high-load application(s) running.
283) One wants to see real statvfs values ;)333) One wants to see real statvfs values ;)
2934
30This is first version. There is lot to improve. New versions may come.35This is one of the first versions. There is lot to improve.
36New versions may come.
3137
3238
33License39License
5258
53After client compilation on "local" machine (where directory is to be mounted)59After client compilation on "local" machine (where directory is to be mounted)
54and server compilation on "remote" machine (from where directory is mounted),60and server compilation on "remote" machine (from where directory is mounted),
55move server component to a location that is on your PATH. In many cases61install client and server by using command ``make install PREFIX=<prefix>``.
56entering command ``cp stfufs-server $HOME/bin/stfufs-server`` does the job.62Components will be installed in directories ``PREFIX/bin`` and
57During initial testing, client does not need to be copied anywhere, but for63``PREFIX/lib/stfufs``. Make sure ``PREFIX/bin`` is in your PATH.
58permanent use it is good to be get somewhere in your PATH.
59 
6064
61Use65Use
62===66===
63 
64These examples expect stfufs (client) is found in your PATH. During
65initial testing on stfufs source directory, use ``./stfufs ...``
6667
67In it's basic form, the usage is pretty same as with sshfs_:68In it's basic form, the usage is pretty same as with sshfs_:
6869
145  more docs in general146  more docs in general
146  protocol updates for smarter stuff147  protocol updates for smarter stuff
147  pretocol using stfufs-buffer code (maybe)148  pretocol using stfufs-buffer code (maybe)
149  split client code out of stfufs binary, to make "reverse" mount possible.
148  more150  more
149151
150Thanks152Thanks

stfufs-1.1/devel/stfufs-server-dbgwrapper.sh stfufs-1.2/devel/stfufs-server-dbgwrapper.sh
7#           All rights reserved7#           All rights reserved
8#8#
9# Created: Sun Dec 30 17:35:55 EET 2007 too9# Created: Sun Dec 30 17:35:55 EET 2007 too
10# Last modified: Sat Jan 05 22:44:57 EET 2008 too10# Last modified: Fri Feb 01 17:34:09 EET 2008 too
1111
12# symlink this to stfufs-server at somewher in your path...12# symlink this to stfufs-server at somewher in your path...
13# example: ln -s `pwd`/stfufs-server-dbgwrapper.sh $HOME/bin/stfufs-server13# example: ln -s `pwd`/stfufs-server-dbgwrapper.sh $HOME/bin/stfufs-server
1414
15LC_ALL=C LANG=C; export LC_ALL LANG15LC_ALL=C LANG=C; export LC_ALL LANG
16 
17case $1 in link)
18        case $2 in '') echo link needs target dir; exit 1 ;; esac
19        test -d $2 || { echo $2: not a directory; exit 1; }
20        case $0 in      /*) s=$0 ;;
21                        *)  s=`cd \`dirname $0\`; pwd`/`basename $0` ;; esac
22        ln -s $s $2/stfufs-server
23        exit 0
24esac
1625
17lf=`/bin/ls -l $0 | awk '{print $11}'`26lf=`/bin/ls -l $0 | awk '{print $11}'`
18ld=`dirname "$lf"`27ld=`dirname "$lf"`
21date +' -- start %c --' >&230date +' -- start %c --' >&2
2231
23set -x32set -x
24"$ld"/../stfufs-server33"$ld"/../stfufs-server "$@"

stfufs-1.1/devel/testreadwrite.sh stfufs-1.2/devel/testreadwrite.sh
5#           All rights reserved5#           All rights reserved
6#6#
7# Created: Sat Jan 12 20:48:54 EET 2008 too7# Created: Sat Jan 12 20:48:54 EET 2008 too
8# Last modified: Sat Jan 12 21:32:45 EET 2008 too8# Last modified: Fri Feb 01 17:23:20 EET 2008 too
99
10# Separate script for some (initial) read/write testing.10# Separate script for some (initial) read/write testing.
11# More thorough tests are done with ...11# More thorough tests are done with ...
64        head -c $i $thisdir/travis2stfufs.c | md5sum64        head -c $i $thisdir/travis2stfufs.c | md5sum
65done65done
6666
67# test many files at the same time...
68 
69exec 3> $tdir/file1
70exec 4> $tdir/file2
71exec 5> $tdir/file3
72exec 6> $tdir/file4
73exec 7> $tdir/file5
74 
75echo file1 > $tdir/file1
76echo file2 > $tdir/file2
77echo file3 > $tdir/file3
78echo file4 > $tdir/file4
79echo file5 > $tdir/file5
80 
81# these are one at at time
82cat $tdir/file1 $tdir/file2 $tdir/file3 $tdir/file4 $tdir/file5
83 
84exec 3<&-
85exec 4<&-
86exec 5<&-
87exec 6<&-
88exec 7<&-
89 
67xxx90xxx

stfufs-1.1/pretocol.c stfufs-1.2/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: Sun Jan 20 22:10:59 EET 2008 too10 * Last modified: Fri Feb 01 16:40:20 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
3535
36    switch (poll(&pfd, 1, timeout)) {36    switch (poll(&pfd, 1, timeout)) {
37    case -1:37    case -1:
38        die("poll failed:");38        die("%C: poll failed:");
39    case 0:39    case 0:
40        die("timeout");40        die("%C: timeout");
41    }41    }
42    i = read(fd, buf, len);42    i = read(fd, buf, len);
43    if (i <= 0)43    if (i <= 0)
44        die("eof or read error");44        die("%C: eof or read error");
4545
46#if 0 /* d1(()) */46#if 0 /* d1(()) */
47    {int j; for (j = 0; j < i; j++) printf("%02x ", buf[j]); puts("");}47    {int j; for (j = 0; j < i; j++) printf("%02x ", buf[j]); puts("");}
51}51}
5252
53/*                    123456789012345678901234567 */53/*                    123456789012345678901234567 */
54const char ident[] = "Simple TCP FUSE filesystem " VERSION " protocol version 2\54const char ident[] = "Simple TCP FUSE filesystem " VERSION
n"; 
55    " protocol version " PROTVER "\n";
5556
56void sendident(int fd)57void sendident(int fd)
57{58{
75out:76out:
76    d0(("%d %s -%c %c-", l, buf, p[-3], p[-2]));77    d0(("%d %s -%c %c-", l, buf, p[-3], p[-2]));
7778
78    if (l == 0 || memcmp(buf, ident, 27) != 079    if (l == 0 || memcmp(buf, ident, 27) != 0)
79        || p[-3] != ' ' || p[-2] != '2')80        die("%C: ident mismatch");
80        die("Received ident mismatch"); /* XXX show ident. */81    if (p[-3] != ' ' || p[-2] != PROTVER[0])
82        die("%C: protocol mismatch. Got %c%c, expected %s",
83            p[-3], p[-2], PROTVER);
8184
82    if (i > 0) /* ack already in buffer */85    if (i > 0) /* ack already in buffer */
83        return p[0];86        return p[0];
92    unsigned char * p;95    unsigned char * p;
9396
94    if (read(fd, &c, 1) <= 0)97    if (read(fd, &c, 1) <= 0)
95        die("Disconnect:");98        die("%C: Disconnect:");
96    if (c == 0)99    if (c == 0)
97        die("0-sized message");100        die("%C: 0-sized message");
98101
99    for (p = buf, i = c; i; p += l, i -= l)102    for (p = buf, i = c; i; p += l, i -= l)
100        l = readwt(fd, p, i, 10 * 1000);103        l = readwt(fd, p, i, 10 * 1000);
121    int sd = socket(AF_INET, SOCK_STREAM, 0);124    int sd = socket(AF_INET, SOCK_STREAM, 0);
122125
123    if (sd < 0)126    if (sd < 0)
124        die("socket failed:");127        die("%C: socket failed:");
125128
126    setsockopt(sd, SOL_SOCKET,129    setsockopt(sd, SOL_SOCKET,
127               dobind? SO_REUSEADDR: SO_KEEPALIVE, &one, sizeof one);130               dobind? SO_REUSEADDR: SO_KEEPALIVE, &one, sizeof one);
147        l = readwt(sd, p, i, 10 * 1000);150        l = readwt(sd, p, i, 10 * 1000);
148151
149    if (memcmp(buf, secrets, 4) != 0)152    if (memcmp(buf, secrets, 4) != 0)
150        die("Secret mismatch");153        die("%C: Secret mismatch");
151154
152    write(sd, "", 1);155    write(sd, "", 1);
153    readwt(sd, buf, 1, 10 * 1000);156    readwt(sd, buf, 1, 10 * 1000);
154    if (buf[0] != 0)157    if (buf[0] != 0)
155        die("Peer did not accept our secret -- actually junk in stream");158        die("%C: Peer did not accept our secret -- actually junk in stream");
156159
157    return sd;160    return sd;
158}161}
167170
168    remote = gethostbyname(host);171    remote = gethostbyname(host);
169    if (remote == null)172    if (remote == null)
170        die("gethostbyname on '%s' returned no value", host);173        die("%C: gethostbyname on '%s' returned no value", host);
171174
172    memcpy(&addr.sin_addr, remote->h_addr, sizeof addr.sin_addr);175    memcpy(&addr.sin_addr, remote->h_addr, sizeof addr.sin_addr);
173176
174    if (connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0)177    if (connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0)
175        die("connect failed:");178        die("%C: connect failed:");
176179
177    return doweaksecretexchange(sd, secrets);180    return doweaksecretexchange(sd, secrets);
178}181}
184187
185    if (bind(ssd, (struct sockaddr *)&addr, sizeof addr) < 0) {188    if (bind(ssd, (struct sockaddr *)&addr, sizeof addr) < 0) {
186        if (fatal)189        if (fatal)
187            die("bind failed:");190            die("%C: bind failed:");
188        else191        else
189            return -1;192            return -1;
190    }193    }
202    memset(&addr, 0, sizeof addr);205    memset(&addr, 0, sizeof addr);
203    sd = accept(ssd, (struct sockaddr *)&addr, &addrlen);206    sd = accept(ssd, (struct sockaddr *)&addr, &addrlen);
204    if (sd < 0)207    if (sd < 0)
205        die("accept failed:");208        die("%C: accept failed:");
206209
207    close(ssd);210    close(ssd);
208    return doweaksecretexchange(sd, secrets);211    return doweaksecretexchange(sd, secrets);

stfufs-1.1/pretocol.h stfufs-1.2/pretocol.h
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Sun Aug 26 22:40:13 EEST 2007 too9 * Created: Sun Aug 26 22:40:13 EEST 2007 too
10 * Last modified: Sat Sep 01 20:48:15 EEST 2007 too10 * Last modified: Wed Jan 30 21:23:35 EET 2008 too
11 */11 */
1212
13#ifndef PRETOCOL_H13#ifndef PRETOCOL_H

stfufs-1.1/stfufs-client-fuse.c stfufs-1.2/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: Sun Jan 20 22:05:37 EET 2008 too10 * Last modified: Tue Jan 29 19:17:06 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
782                                        stfufs_ok_cb, null);782                                        stfufs_ok_cb, null);
783}783}
784784
785static uint8_t * stfufs_retval_cb(void * cbdata, uint32_t rlen, uint8_t * p)
786{
787    uint32_t * rv32p = (uint32_t *)cbdata;
788    (void)rlen;
789 
790    d1(("--- %s(%p, %d, %p)", __func__, cbdata, rlen, p));
791 
792    if ((p = stfufs_buffer_reserve(p, 4)) == null)
793        return null;
794 
795    *rv32p = xdecode_uint32(&p);
796    return p;
797}
785798
786static int stfufs_open(const char * path, struct fuse_file_info * fi)799static int stfufs_open(const char * path, struct fuse_file_info * fi)
787{800{
788    uint8_t buf[32];801    uint8_t buf[32];
789    struct iovec iov[3];802    struct iovec iov[3];
790    int iovlen;803    int iovlen, error;
791    int plen = strlen(path) + 1;804    int plen = strlen(path) + 1;
792    int alen = (plen + 3) & ~3;805    int alen = (plen + 3) & ~3;
806    uint32_t fd;
793807
794    d1(("--- %s(\"%s\", %p) %d", __func__, path, fi, fi->flags));808    d1(("--- %s(\"%s\", %p) %d", __func__, path, fi, fi->flags));
795809
809823
810    alen += 4;824    alen += 4;
811825
812    return stfufs_client_request_handle(STFUFS__OPEN, iov, iovlen, alen,826    error = stfufs_client_request_handle(STFUFS__OPEN, iov, iovlen, alen,
813                                       stfufs_ok_cb, null);827                                         stfufs_retval_cb, (void *)&fd);
828    if (error < 0)
829        return error;
830    fi->fh = fd;
831    return 0;
814}832}
815833
816834
848                       off_t offset, struct fuse_file_info * fi)866                       off_t offset, struct fuse_file_info * fi)
849{867{
850    uint8_t buf[32], *p;868    uint8_t buf[32], *p;
851    struct iovec iov[3];869    struct iovec iov[1];
852    int iovlen;
853    int plen = strlen(path) + 1;
854    int alen = (plen + 3) & ~3;
855    struct iovec readdata;870    struct iovec readdata;
856    int error;871    int error;
857872
858    (void)fi;873    (void)path;
859    d1(("--- %s(\"%s\", %d, %lld)", __func__, path, size, offset));874    d1(("--- %s(\"%s\", %d, %lld)", __func__, path, size, offset));
860875
861    p = xencode_uint32(buf + REQUEST_HEADER_LEN, size);876    p = xencode_uint32(buf + REQUEST_HEADER_LEN, (uint32_t)fi->fh);
877    p = xencode_uint32(p, size);
862    (void)xencode_uint64(p, offset);878    (void)xencode_uint64(p, offset);
863879
864    iov[0].iov_base = buf; /* stfufs_client_request_handle() will fill this */880    iov[0].iov_base = buf; /* stfufs_client_request_handle() will fill this */
865    iov[0].iov_len = REQUEST_HEADER_LEN + 4 + 8;881    iov[0].iov_len = REQUEST_HEADER_LEN + 4 + 4 + 8;
866    iov[1].iov_base = str_unconst(path); /* const void * when writing... */
867    iov[1].iov_len = plen;
868 
869    if (plen != alen) {
870        iov[2].iov_base = str_unconst(G_pad000); /*const void * when writing */
871        iov[2].iov_len = alen - plen;
872        iovlen = 3;
873    }
874    else iovlen = 2;
875 
876    alen += 4 + 8;
877882
878    readdata.iov_base = data;883    readdata.iov_base = data;
879    readdata.iov_len = size;884    readdata.iov_len = size;
880885
881    error = stfufs_client_request_handle(STFUFS__READ, iov, iovlenalen,886    error = stfufs_client_request_handle(STFUFS__READ, iov, 14 + 4 + 8,
882                                         stfufs_read_cb, &readdata);887                                         stfufs_read_cb, &readdata);
883    if (error < 0)888    if (error < 0)
884        return error;889        return error;
886}891}
887892
888893
889static uint8_t * stfufs_write_cb(void * cbdata, uint32_t rlen, uint8_t * p)
890{
891    uint32_t * lenp = (uint32_t *)cbdata;
892 
893    d1(("--- %s(%p, %d, %p)", __func__, cbdata, rlen, p));
894 
895    if ((p = stfufs_buffer_reserve(p, 4)) == null)
896        return null;
897 
898    *lenp = xdecode_uint32(&p);
899    return p;
900}
901 
902static int stfufs_write(const char * path, const char * data, size_t size,894static int stfufs_write(const char * path, const char * data, size_t size,
903                        off_t offset, struct fuse_file_info * fi)895                        off_t offset, struct fuse_file_info * fi)
904{896{
905    uint8_t buf[32], *p;897    uint8_t buf[32], *p;
906    struct iovec iov[5];898    struct iovec iov[3];
907    int iovlen;
908    int plen = strlen(path) + 1;
909    int alen = (plen + 3) & ~3;
910    int rlen, error;899    int iovlen, error, alen;
900    uint32_t rlen;
911901
912    (void)fi;902    (void)path;
913    d1(("--- %s(\"%s\", %d, %lld)", __func__, path, size, offset));903    d1(("--- %s(\"%s\", %d, %lld)", __func__, path, size, offset));
914904
915    p = xencode_uint32(buf + REQUEST_HEADER_LEN, size);905    p = xencode_uint32(buf + REQUEST_HEADER_LEN, (uint32_t)fi->fh);
906    p = xencode_uint32(p, size);
916    p = xencode_uint64(p, offset);907    p = xencode_uint64(p, offset);
917    p = xencode_uint32(p, alen);
918908
919    iov[0].iov_base = buf; /* stfufs_client_request_handle() will fill this */909    iov[0].iov_base = buf; /* stfufs_client_request_handle() will fill this */
920    iov[0].iov_len = REQUEST_HEADER_LEN + 4 + 8 + 4;910    iov[0].iov_len = REQUEST_HEADER_LEN + 4 + 4 + 8;
921    iov[1].iov_base = str_unconst(path); /* const void * when writing... */911    iov[1].iov_base = str_unconst(data); /* const void * when writing... */
922    iov[1].iov_len = plen;912    iov[1].iov_len = size;
923 
924    if (plen != alen) {
925        iov[2].iov_base = str_unconst(G_pad000); /*const void * when writing */
926        iov[2].iov_len = alen - plen;
927        iovlen = 3;
928    }
929    else iovlen = 2;
930 
931    iov[iovlen].iov_base = str_unconst(data); /* const void * when writing...*/
932    iov[iovlen++].iov_len = size;
933913
934    if ((size & 3) != 0) {914    if ((size & 3) != 0) {
935        int pad = 4 - (size & 3);915        int pad = 4 - (size & 3);
936        iov[iovlen].iov_base = str_unconst(G_pad000);916        iov[2].iov_base = str_unconst(G_pad000);
937        iov[iovlen++].iov_len = pad;917        iov[2].iov_len = pad;
938        size += pad;918        size += pad;
919        iovlen = 3;
939    }920    }
921    else iovlen = 2;
940922
941    alen += 4 + 8 + 4 + size;923    alen = 4 + 8 + 4 + size;
942924
943    error = stfufs_client_request_handle(STFUFS__WRITE, iov, iovlen, alen,925    error = stfufs_client_request_handle(STFUFS__WRITE, iov, iovlen, alen,
944                                         stfufs_write_cb, (void *)&rlen);926                                         stfufs_retval_cb, (void *)&rlen);
945    if (error < 0)927    if (error < 0)
946        return error;928        return error;
947    return rlen;929    return (int)rlen; /* XXX */
948}930}
949931
950932
1002}984}
1003985
1004986
1005/* like mkdir. refactor */
1006static int stfufs_release(const char * path, struct fuse_file_info * fi)987static int stfufs_release(const char * path, struct fuse_file_info * fi)
1007{988{
1008    uint8_t buf[32];989    uint8_t buf[32], *p;
1009    struct iovec iov[3];990    struct iovec iov[1];
1010    int iovlen;
1011    int plen = strlen(path) + 1;
1012    int alen = (plen + 3) & ~3;
1013991
992    (void)path;
1014    d1(("--- %s(\"%s\", %p)", __func__, path, fi));993    d1(("--- %s(\"%s\", %lld)", __func__, path, fi->fh));
1015994
995    p = xencode_uint32(buf + REQUEST_HEADER_LEN, (uint32_t)fi->fh);
1016    iov[0].iov_base = buf; /* stfufs_client_request_handle() will fill this */996    iov[0].iov_base = buf; /* stfufs_client_request_handle() will fill this */
1017    iov[0].iov_len = REQUEST_HEADER_LEN;997    iov[0].iov_len = REQUEST_HEADER_LEN + 4;
1018    iov[1].iov_base = str_unconst(path); /* const void * when writing... */
1019    iov[1].iov_len = plen;
1020998
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, iovlenalen,999    return stfufs_client_request_handle(STFUFS__RELEASE, iov, 14,
1029                                        stfufs_ok_cb, null);1000                                        stfufs_ok_cb, null);
1030}1001}
10311002

stfufs-1.1/stfufs-client.c stfufs-1.2/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: Sun Jan 20 22:13:38 EET 2008 too10 * Last modified: Thu Jan 31 20:03:05 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
23#include "util.h"23#include "util.h"
24#include "pretocol.h"24#include "pretocol.h"
25#include "random.h"25#include "random.h"
26#include "version.h"
2627
27#define STFUFS_CLIENT 128#define STFUFS_CLIENT 1
28#include "stfufs.h"29#include "stfufs.h"
89    return p;90    return p;
90}91}
9192
93static void sshcmd_die_hook(void * data)
94{
95    d1(("sshcmd_die_hook()"));
96    close((int)data);
97    wait(null);
98}
99 
100static void exitsshcmd(void)
101{
102    d1(("waiting for ssh to exit")); /* maybe message */
103    wait(null);
104    die_hook.func = null;
105}
92106
93static int runsshcmd(const char * host, int port)107static int runsshcmd(const char * host, int port)
94{108{
109        args[i++] = p; p += strlen(p) + 1;123        args[i++] = p; p += strlen(p) + 1;
110    }124    }
111    args[i++] = pusharg(&p, "stfufs-server", -1);125    args[i++] = pusharg(&p, "stfufs-server", -1);
126    args[i++] = pusharg(&p, PROTVER, -1);
127    args[i++] = pusharg(&p, VERSION, -1);
112    args[i] = null;128    args[i] = null;
113129
114    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)130    if (socketpair(AF_UNIX, SOCK_STREAM, 0, fds) < 0)
132        break;148        break;
133    }149    }
134    close(fds[1]);150    close(fds[1]);
151    die_hook.func = sshcmd_die_hook;
152    die_hook.data = (void *)fds[0];
135    return fds[0];153    return fds[0];
136}154}
137155
281    else299    else
282        fd = doaccept(buf, ssd);300        fd = doaccept(buf, ssd);
283301
284    d1(("waiting for ssh to exit")); /* maybe message */302    exitsshcmd();
285    wait(&i);
286    d1(("ssh exited")); /* maybe message */303    d1(("ssh exited")); /* maybe message */
287    return fd;304    return fd;
288}305}
289306
307static void futsupp(const char * component)
308{
309    die("%s version " VERSION
310        " does not support requested protocol", component);
311}
290312
291int main(int argc, char ** argv)313int main(int argc, char ** argv)
292{314{
315    util_init("Client");
316 
317    if (argc > 1) {
318        if (strcmp(argv[1], "--client") == 0) futsupp("Client");
319        if (strcmp(argv[1], "--server") == 0) futsupp("Server"); }
320 
293    stfufs_client_fuse_main(argc, argv);321    stfufs_client_fuse_main(argc, argv);
294    exit(0);322    exit(0);
295}323}

stfufs-1.1/stfufs-server-fs.c stfufs-1.2/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: Sun Jan 20 19:59:47 EET 2008 too10 * Last modified: Tue Jan 29 17:31:00 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
35#include "simplexdr.h"35#include "simplexdr.h"
3636
3737
38static struct {
39#define FDOFFSETS 1024
40    int64_t fdoffsets[FDOFFSETS];
41} S;
42 
43 
44static void init_S(void)
45{
46    int i;
47 
48    for (i = 0; i < FDOFFSETS; i++)
49        S.fdoffsets[i] = -1;
50}
51 
38static void _write_simple(uint8_t * s, uint8_t * e)52static void _write_simple(uint8_t * s, uint8_t * e)
39{53{
40    int len = write(0, s, e - s);54    int len = write(0, s, e - s);
57    p = xencode_uint32(p, 0); /* length */71    p = xencode_uint32(p, 0); /* length */
58    _write_simple(buf, p);72    _write_simple(buf, p);
59}73}
74 
75/* retvall for 64bits ;) if ever needed ? */
76static void _write_retval(uint32_t type, uint32_t id, uint32_t value)
77{
78    uint8_t buf[32];
79    uint8_t * p = buf;
80 
81    p = xencode_uint32(p, type);
82    p = xencode_uint32(p, id);
83    p = xencode_uint32(p, 0); /* no error */
84    p = xencode_uint32(p, 4); /* response length */
85    p = xencode_uint32(p, value);
86 
87    _write_simple(buf, p);
88}
89 
6090
61static uint8_t * unsupported(uint8_t * p, uint32_t type, uint32_t id, int clen)91static uint8_t * unsupported(uint8_t * p, uint32_t type, uint32_t id, int clen)
62{92{
430    flags = xdecode_uint32(&p);460    flags = xdecode_uint32(&p);
431461
432    if ((fd = open(_mypath(p), flags)) >= 0) {462    if ((fd = open(_mypath(p), flags)) >= 0) {
463        if (fd < FDOFFSETS) {
464            S.fdoffsets[fd] = 0;
465            _write_retval(type, id, (uint32_t)fd);
466            return r;
467        }
468        /* else */
433        close(fd);469        close(fd);
434        errno = 0;470        errno = ENFILE;
435    }471    }
436    _write_status(type, id, errno);472    _write_status(type, id, errno);
437    return r;473    return r;
459    return ll;495    return ll;
460}496}
461497
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;
470498
471static uint8_t * stfufs_server_read(uint8_t * p,499static uint8_t * stfufs_server_read(uint8_t * p,
472                                    uint32_t type, uint32_t id, int clen)500                                    uint32_t type, uint32_t id, int clen)
473{501{
474    uint8_t * r;502    uint8_t * r;
475    int fd, len;503    int32_t fd, len;
476    uint32_t size;504    uint32_t size;
477    off_t offset;505    off_t offset;
478    uint8_t buf[32768 + 16];506    uint8_t buf[32768 + 16];
479    uint8_t * filename;
480    off_t cacheoffset;
481507
482    d1(("--- stfufs_server_read(%p, %x, %d, %d)", p, type, id, clen));508    d1(("--- stfufs_server_read(%p, %x, %d, %d)", p, type, id, clen));
483509
486512
487    r = p + clen;513    r = p + clen;
488514
515    fd = (int32_t)xdecode_uint32(&p);
489    size = xdecode_uint32(&p);516    size = xdecode_uint32(&p);
490    offset = xdecode_uint64(&p);517    offset = xdecode_uint64(&p);
491518
492    if (memcmp(readsec.path, p, clen - 12) == 0) {519    if ((uint32_t)fd >= FDOFFSETS || S.fdoffsets[fd] < 0) {
493        fd = readsec.fd;520        _write_status(type, id, EBADF);
494        cacheoffset = readsec.offset;521        return r;
495    }522    }
496    else {523    if (S.fdoffsets[fd] == offset)
497        if ((fd = open(_mypath(p), O_RDONLY, 0)) < 0) {524        d1(("Optimal offset hit at offset %lld", offset));
525    else if (lseek(fd, offset, SEEK_SET) < 0) {
498            _write_status(type, id, errno);526        _write_status(type, id, errno);
499            return r;527        return r;
500        }
501        cacheoffset = -1;
502    }528    }
503    if (cacheoffset == offset)
504        d1(("Optimal cache hit at offset %lld", offset));
505    else {
506        if (lseek(fd, offset, SEEK_SET) < 0) {
507            _write_status(type, id, errno);
508            if (cacheoffset < 0)
509                close(fd);
510            return r;
511        }}
512    filename = p;
513529
514    if (size > 32768)530    if (size > 32768)
515        size = 32768;531        size = 32768;
519535
520    if (len < 0) {536    if (len < 0) {
521        _write_status(type, id, errno);537        _write_status(type, id, errno);
522        if (cacheoffset < 0)
523            close(fd);
524        return r;538        return r;
525    }539    }
526540
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;541    S.fdoffsets[fd] = offset + len;
538542
539    p = buf;543    p = buf;
540    p = xencode_uint32(p, type);544    p = xencode_uint32(p, type);
547    return r;551    return r;
548}552}
549553
550struct SEC4RW writesec;
551 
552static uint8_t * stfufs_server_write(uint8_t * p,554static uint8_t * stfufs_server_write(uint8_t * p,
553                                     uint32_t type, uint32_t id, int clen)555                                     uint32_t type, uint32_t id, int clen)
554{556{
555    uint8_t buf[32];
556    uint8_t * r;557    uint8_t * r;
557    int fd;558    int32_t fd;
558    uint32_t size, palen, len;559    uint32_t size, len;
559    off_t offset;560    off_t offset;
560    uint8_t * filename;
561    off_t cacheoffset;
562561
563    d1(("stfufs_server_write(%p, %x, %d, %d)", p, type, id, clen));562    d1(("stfufs_server_write(%p, %x, %d, %d)", p, type, id, clen));
564563
565    if ((p = stfufs_buffer_reserve(p, 4 + 8 + 4)) == null)564    if ((p = stfufs_buffer_reserve(p, 4 + 4 + 8)) == null)
566        return null;565        return null;
567566
567    fd = (int32_t)xdecode_uint32(&p);
568    size = xdecode_uint32(&p);568    size = xdecode_uint32(&p);
569    offset = xdecode_uint64(&p);569    offset = xdecode_uint64(&p);
570    palen = xdecode_uint32(&p);
571570
572    r = p;571    r = p;
573    clen -= (4 + 8 + 4);572    clen -= (4 + 8 + 4);
574573
575    if ((p = stfufs_buffer_reserve(p, palen)) == null)574    if ((uint32_t)fd >= FDOFFSETS || S.fdoffsets[fd] < 0) {
575        _write_status(type, id, EBADF);
576        return null;576        return r;
577 
578    if (memcmp(writesec.path, p, palen) == 0) {
579        fd = writesec.fd;
580        cacheoffset = writesec.offset;
581    }577    }
582    else {578    if (S.fdoffsets[fd] == offset)
583        if ((fd = open(_mypath(p), O_WRONLY, 0500)) < 0) {579        d1(("Optimal offset hit at offset %lld", offset));
580    else if (lseek(fd, offset, SEEK_SET) < 0) {
584            _write_status(type, id, errno);581        _write_status(type, id, errno);
585            return stfufs_buffer_discard(r, clen);582        return stfufs_buffer_discard(r, clen);
586        }
587        cacheoffset = -1;
588    }583    }
589    if (cacheoffset == offset)
590        d1(("Optimal cache hit at offset %lld", offset));
591    else {
592        if (lseek(fd, offset, SEEK_SET) < 0) {
593            _write_status(type, id, errno);
594            if (cacheoffset < 0)
595                close(fd);
596            return stfufs_buffer_discard(r, clen);
597        }}
598    filename = p;
599584
600    p += palen;
601    len = stfufs_buffer_rest(p);585    len = stfufs_buffer_rest(p);
602586
603    if ((int32_t)(len = write(fd, p, len < size? len: size)) < 0) {587    if ((int32_t)(len = write(fd, p, len < size? len: size)) < 0) {
604        _write_status(type, id, errno);588        _write_status(type, id, errno);
605        if (cacheoffset < 0)
606            close(fd);
607        return stfufs_buffer_discard(r, clen);589        return stfufs_buffer_discard(r, clen);
608    }590    }
609    /* XXX partial write above is a problem ! need a wrapper or something */591    /* XXX partial write above is a problem ! need a wrapper or something */
619        r = p + needreserve;601        r = p + needreserve;
620        if ((len2 = write(fd, p, missing)) < 0) {602        if ((len2 = write(fd, p, missing)) < 0) {
621            _write_status(type, id, errno);603            _write_status(type, id, errno);
622            if (cacheoffset < 0)
623                close(fd);
624            return r;604            return r;
625        }605        }
626        len += len2;606        len += len2;
627    }607    }
628608
629    if (cacheoffset < 0) {
630        if (palen > sizeof writesec.path)
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;609    S.fdoffsets[fd] = offset + len;
640610
641    p = buf;611    _write_retval(type, id, len);
642    p = xencode_uint32(p, type);
643    p = xencode_uint32(p, id);
644    p = xencode_uint32(p, 0); /* no error */
645    p = xencode_uint32(p, 4); /* response length */
646    p = xencode_uint32(p, len); /* written data */
647 
648    _write_simple(buf, p);
649 
650    return r;612    return r;
651}613}
652614
703                                       uint32_t type, uint32_t id, int clen)665                                       uint32_t type, uint32_t id, int clen)
704{666{
705    uint8_t * r;667    uint8_t * r;
668    int32_t fd;
706669
707    d1(("--- stfufs_server_release(%p, %x, %d, %d)", p, type, id, clen));670    d1(("--- stfufs_server_release(%p, %x, %d, %d)", p, type, id, clen));
708671
709    if ((p = stfufs_buffer_reserve(p, clen)) == null)672    if ((p = stfufs_buffer_reserve(p, clen)) == null)
710        return null;673        return null;
711674
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;675    r = p + clen;
726676
727    /* do release on _mypath(p) */677    fd = (int32_t)xdecode_uint32(&p);
678 
679    if ((uint32_t)fd >= FDOFFSETS || S.fdoffsets[fd] < 0)
680        errno = EBADF;
681    else {
682        S.fdoffsets[fd] = -1;
728    errno = 0;683        errno = 0;
729 684        close(fd);
685    }
730    _write_status(type, id, errno);686    _write_status(type, id, errno);
731    return r;687    return r;
732}688}
689 
733690
734static uint8_t * stfufs_server_readdir(uint8_t * p,691static uint8_t * stfufs_server_readdir(uint8_t * p,
735                                      uint32_t type, uint32_t id, int clen)692                                      uint32_t type, uint32_t id, int clen)
842{799{
843    uint8_t * p = stfufs_buffer_init(0);800    uint8_t * p = stfufs_buffer_init(0);
844801
845    readsec.path[0] = writesec.path[0] = 0;802    init_S();
846    readsec.fd = writesec.fd = -1;
847803
848    while (1)804    while (1)
849    {805    {

Only in stfufs-1.2: stfufs-server-launcher.c

stfufs-1.1/stfufs-server.c stfufs-1.2/stfufs-server.c
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Sun 26 Aug 2007 08:18:39 AM EEST too9 * Created: Sun 26 Aug 2007 08:18:39 AM EEST too
10 * Last modified: Thu Jan 17 19:32:43 EET 2008 too10 * Last modified: Wed Jan 30 21:43:02 EET 2008 too
11 */11 */
1212
13#include <unistd.h>13#include <unistd.h>
122122
123int main(void)123int main(void)
124{124{
125    int fd, fd2;
126 
127    util_init("Server");
125    int fd = create_connection();128    fd2 = fd = create_connection();
126    int fd2 = fd;129 
127    switch (fork())130    switch (fork())
128    {131    {
129    case -1: die("fork failed");132    case -1: die("fork failed");

stfufs-1.1/util.c stfufs-1.2/util.c
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Sun Aug 26 22:59:02 EEST 2007 too9 * Created: Sun Aug 26 22:59:02 EEST 2007 too
10 * Last modified: Tue Jan 08 22:27:07 EET 2008 too10 * Last modified: Wed Jan 30 21:41:33 EET 2008 too
11 */11 */
1212
13#include <stdio.h>13#include <stdio.h>
16#include <stdarg.h>16#include <stdarg.h>
17#include <errno.h>17#include <errno.h>
1818
19#define UTIL_C 1
19#include "util.h"20#include "util.h"
2021
21/* to be moved... */22/* to be moved... */
22const char G_pad000[3] = { 0, 0, 0 };23const char G_pad000[3] = { 0, 0, 0 };
2324
25void util_init(const char * component)
26{
27    Util.component = component;
28    setlinebuf(stderr);
29}
30 
24static void verrf(const char * format, va_list ap)31static void verrf(const char * format, va_list ap)
25{32{
26    int error = errno; /* XXX is this too late ? */33    int error = errno; /* XXX is this too late ? */
2734
35    if (memcmp(format, "%C:", 3) == 0) {
36        fputs(Util.component, stderr);
37        format += 2;
38    }
28    vfprintf(stderr, format, ap);39    vfprintf(stderr, format, ap);
29    if (format[strlen(format) - 1] == ':')40    if (format[strlen(format) - 1] == ':')
30        fprintf(stderr, " %s\n", strerror(error));41        fprintf(stderr, " %s\n", strerror(error));
31    else42    else
32        fputs("\n", stderr);43        fputs("\n", stderr);
33}44}
45 
46struct DieHookStruct die_hook = { null, null };
3447
35void die(const char * format, ...)48void die(const char * format, ...)
36{49{
40    verrf(format, ap);53    verrf(format, ap);
41    va_end(ap);54    va_end(ap);
4255
56    if (die_hook.func) die_hook.func(die_hook.data);
43    exit(1);57    exit(1);
44}58}
4559

stfufs-1.1/util.h stfufs-1.2/util.h
7 *          All rights reserved7 *          All rights reserved
8 *8 *
9 * Created: Sun Aug 26 22:59:58 EEST 2007 too9 * Created: Sun Aug 26 22:59:58 EEST 2007 too
10 * Last modified: Sun Jan 06 21:56:25 EET 2008 too10 * Last modified: Wed Jan 30 21:43:29 EET 2008 too
11 */11 */
1212
13#ifndef UTIL_H13#ifndef UTIL_H
1515
16#include "defs.h"16#include "defs.h"
1717
18/* to be moved */18/* Life is constant learning. That's why this file, and some of the
19   others use different ways to do some things (not so consistent always,
20   that is). Also, I am too lazy to consolidate all different techniques
21   to the one (probably not best, but consistent at least). Also, I've
22   thougth of merging defs.h and utils.h to one, but that probably won't
23   happen either (or putting all of these to stfufs.h (and .c) */
24 
25/* to be moved (or not...) */
19extern const char G_pad000[3];26extern const char G_pad000[3];
27 
28extern struct DieHookStruct {
29    void (*func)(void * data);
30    void * data;
31} die_hook;
32 
33#if ! UTIL_C
34extern
35#endif
36/**/ struct {
37    const char * component;
38} Util;
39 
40void util_init(const char * component);
2041
21void die(const char * format, ...) GCCATTR_NORETURN;42void die(const char * format, ...) GCCATTR_NORETURN;
2243

stfufs-1.1/version.h stfufs-1.2/version.h
1#if 0 /*
2sed -n '/[ ]VERSION / { s/.*VERSION *"/version=/; s|".*||;p; }
3        /[ ]PROTVER / { s/.*PROTVER *"/protver=/; s|".*||;p; }' $0
4exit 0
5*/
6#endif
1/*7/*
2 * Created: Sat Jan 19 16:46:57 EET 2008 too8 * Created: Sat Jan 19 16:46:57 EET 2008 too
3 * Last modified: Sun Jan 222:21:34 EET 2008 too9 * Last modified: Wed Jan 317:41:17 EET 2008 too
4 */10 */
511
6#ifndef VERSION_H12#ifndef VERSION_H
7#define VERSION_H13#define VERSION_H
814
9#define VERSION "1.1"15#define VERSION "1.2"
16#define PROTVER "3"
1017
11#endif /* VERSION_H */18#endif /* VERSION_H */
1219