autogen added
This commit is contained in:
parent
2e8db79ab1
commit
8390634da0
34
BETA.README
34
BETA.README
|
|
@ -2,16 +2,28 @@ This is a BETA release, as such it's not guaranteed to work perfectly any
|
|||
problems let me know, they'll be sorted out in the next Beta release. At the
|
||||
point at which people stop complaining the non-beta release will be let out.
|
||||
|
||||
You can get beta version from CVS on sf.net there are tagged fsp-281-bXX.
|
||||
You can get beta versions from CVS on sf.net there are tagged fsp-281-bXX.
|
||||
checkouting HEAD it always best.
|
||||
|
||||
FSP Development Battle plan:
|
||||
============================
|
||||
* for next 2.8 Stable version (will be called 2.8.2)
|
||||
|
||||
2.8.2 - Next Stable version after 10 years or so
|
||||
- get out this version as soon as possible. 2.8.1b3 and lower are buggy.
|
||||
- add FSP Rename command
|
||||
- add FSP Info command
|
||||
- go out this version as soon as possible. 2.8.1b3 and lower are buggy.
|
||||
- resolve symlink support problem. This maybe breaks compatibility
|
||||
with older software versions.
|
||||
- security: symlink to FILE can escape from FSP root directory.
|
||||
- fix Sven's Slowaris 8 compile problem
|
||||
- local bind address FSP_LOCALIP for clients
|
||||
- bind-ip-address for server
|
||||
- normalize return error codes of all clients
|
||||
- server can be run multiple times on the same port, how to check?
|
||||
on freebsd this works okay. needs re-testing on linux.
|
||||
- fspd: add special defence against rapid/double fire clients (burst command in fspclient)
|
||||
|
||||
* for next point Stable version 2.8.3
|
||||
- add native symbolic link support
|
||||
- add FSP change password command
|
||||
- add FSP command for changing owners
|
||||
- add FSP command for listing directory owners
|
||||
|
|
@ -33,17 +45,9 @@ release and ultimately into the final release.
|
|||
|
||||
-----------------------------------------------------------------------------
|
||||
|
||||
This version is fully backwards compatible with 2.7.1 and 2.8.1 both from the
|
||||
client and the server viewpoints. Bar one thing, the reversed IP problem with
|
||||
restricted host lists has now been fixed, so if you've deliberately reversed
|
||||
the IP numbers in that list to get around the bug you should now put them back
|
||||
in the correct order again.
|
||||
|
||||
Another point worth noting is that the next release will go to ANSI-C. If you
|
||||
have a problem with this then now is the time to let me know. I don't forsee
|
||||
any portability problems since I would expect that ANSI-C compliant compilers
|
||||
are available for all platforms by now. This move will aid both maintenance and
|
||||
any future use of C++ for Application Programming Interfaces.
|
||||
This version is not quite fully backwards compatible with 2.7.1 and 2.8.1 from
|
||||
the client and the server viewpoints. See file PROTOCOL for minor changes
|
||||
in wire-protocol.
|
||||
|
||||
If you successfully build this distribution on a machine/OS/compiler
|
||||
combination which isn't listed in the MACHINES file then please drop me a line
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
Authors:
|
||||
Radim Kolar <hsn@cybermail.net> (Current FSP maintainer)
|
||||
Radim Kolar <hsn@netmag.cz> (Current FSP maintainer)
|
||||
Andrew Doherty <A.J.Doherty@reading.ac.uk>
|
||||
Michael Fischbein
|
||||
Cimarron D. Taylor
|
||||
|
|
|
|||
450
ChangeLog
450
ChangeLog
|
|
@ -1,49 +1,91 @@
|
|||
Version - not yet released
|
||||
Added pidfile.[c|h] from FreeBSD and modified it to fit in (hoaxter)
|
||||
Added pidfile support, config option is 'pidlogname', the option
|
||||
is required to start fspd, hope that's ok for most people (hoaxter)
|
||||
Replaced . file information from INSTALL with a hint to man 1 fspd (hoaxter)
|
||||
|
||||
Added pidfile support, config option is 'pidlogname' (hoaxter)
|
||||
Replaced .file information from INSTALL with a hint to man 1 fspd (hoaxter)
|
||||
PROTOCOL: Added security section, fixed method of computing of checksums fspd: unlink filecache.c from build
|
||||
conf: commented dangerours settings for win32 platform which can
|
||||
cause data loss when fspd.conf is reused on win32 without editing.
|
||||
Defaults are detected at build time.
|
||||
fspd: allow to run without pidfile set.
|
||||
added autogen.sh for regenerating of autoconf on FreeBSD which needs
|
||||
to set some env. variables unless --enable-maintainer-mode do
|
||||
not works.
|
||||
do not free pidfile name on failure
|
||||
changelog reformated: each entry begins with tab/not spaces.
|
||||
continuation line has 2 chars leading space
|
||||
removed trailing spaces from all sources and headers
|
||||
tests: run random test 2000 times by default
|
||||
random generator switched to simple2. Better results on both
|
||||
freebsd and linux systems.
|
||||
added maximum supported packet size to output of CC_VER command
|
||||
fspd: -b command line switch for bandwidth limiting
|
||||
PROTOCOL: Added compatibility section to some commands
|
||||
Default timeout increased from 180 to 360 seconds.
|
||||
clients: apply delay timeout also when starting transfer
|
||||
clients: added env. variable FSP_MAXDELAY for fine-tuning resends
|
||||
DEFAULT_MAXDELAY added to source code
|
||||
FSP_TIMEOUT is total number of seconds, not retry count.
|
||||
clients: try to resend packet on less fatal error (network down or so)
|
||||
remove clients lock files after sending BYE. code merged from fspclient.
|
||||
threre is an race condition: After client unlinks lock file and other
|
||||
clients still runs new client will create new lock file which will
|
||||
not share secret key with other clients. New client can't communicate
|
||||
with server until other clients terminates.
|
||||
man: we did not install fsp_env.7 manpage
|
||||
allow home directory not starting with /
|
||||
allow uploads only on file border
|
||||
up/down speed is in B/s, not b/s.
|
||||
client tracing improved:
|
||||
H - not enough bytes for header
|
||||
C - wrong checksum
|
||||
S - wrong seq. number
|
||||
T - truncated
|
||||
R - First resend
|
||||
I - Idle resend
|
||||
client: use random starting seq. number - better for avoiding
|
||||
seq. number clash with another client
|
||||
fixed compiler warning on BB_READ4(const char *);
|
||||
|
||||
Version 2.8.1b19 - 11 Jan 2004
|
||||
sven has added fspget URL command to setup.sh.
|
||||
fixed case for mklargefile.py in tests/Makefile.am
|
||||
added --enable-debug switch to configure for enabling extra
|
||||
debuging code in client library
|
||||
debuging code in client library
|
||||
fsp/fifocache.c changed malloc.h to stdlib.h -> allow compile on
|
||||
freebsd
|
||||
freebsd
|
||||
do not use ${RM} in clients/Makefile.am -> allow compile with bsd make
|
||||
|
||||
Version 2.8.1b18 - 25 Nov 24 2003
|
||||
This is MINIMUM REQUIRED VERSION for applications which are using
|
||||
javafsp library, only download machine atm. Javafsp library will
|
||||
be released shortly as separate package.
|
||||
PROTOCOL updated. Made rules about breaking directory header on
|
||||
packet boundary more clear. Previous text was from fspd code comment
|
||||
and was bad.
|
||||
This is MINIMUM REQUIRED VERSION for applications which are using
|
||||
javafsp library, only download machine atm. Javafsp library will
|
||||
be released shortly as separate package.
|
||||
PROTOCOL updated. Made rules about breaking directory header on
|
||||
packet boundary more clear. Previous text was from fspd code comment
|
||||
and was bad.
|
||||
fixed tests/mklargefile.py
|
||||
log uploads to wuftpd logfile also
|
||||
PROTOCOL file updated. Added required commands section.
|
||||
PROTOCOL file updated. Added recommended delay management section.
|
||||
default delay in clients adjusted from 1.5 to 1.34 sec as recommended
|
||||
in PROTOCOL
|
||||
in PROTOCOL
|
||||
support for MIN_DELAY, MAX_DELAY and DEFAULT_DELAY in source
|
||||
path parsing moved to separate file server/path.c
|
||||
new test tool parsecheck for testing server path parser
|
||||
reworked parse path: separate error messages for high bit chars,
|
||||
control chars
|
||||
control chars
|
||||
MAJOR BUGFIX: path with trailing / or starting / is now parsed correctly
|
||||
pathes with dot after slash are now detected at parse level (side
|
||||
effect of prev. fix, fixed security prob)
|
||||
effect of prev. fix, fixed security prob)
|
||||
tests moved from server/ into tests/ directory
|
||||
removed special test case for root directory in path.c -> use more
|
||||
general alg. instead. This fixed "/" dir.
|
||||
general alg. instead. This fixed "/" dir.
|
||||
parsecheck turned into test suite with hard coded test results
|
||||
parsecheck added to 'make check'
|
||||
support for multiple \n in filename - in future there will be
|
||||
used for symlinks.
|
||||
used for symlinks.
|
||||
random generator changed to one recommended by Jiann-Ming Su.
|
||||
new test program tests/randomcheck.c - tests random number generators.
|
||||
|
||||
|
||||
Version 2.8.1b17 -- 17 Nov 2003
|
||||
Allow filenames with spaces inside
|
||||
check for fork() and setsid() in configure.ac
|
||||
|
|
@ -63,31 +105,31 @@ Version 2.8.1b16 -- 8 Nov 2003
|
|||
fixed memory leak in client/util.c:get_dir_blk
|
||||
fixed memory leak in client/util.c:open_dir
|
||||
fixed error from 2.8.1b15 in util_stat which brokes recursive
|
||||
directory listings
|
||||
directory listings
|
||||
do not delete partial file on FSP timeout in fgetcmd
|
||||
|
||||
Version 2.8.1b15 -- 15 Oct 2003
|
||||
Sven writes manpage for fspscan.1
|
||||
Sven writes manpage for fspscan.1
|
||||
junked concept of private directory, now directory has flag
|
||||
+g - public can get files
|
||||
+g - public can get files
|
||||
dir_priv -> dir_get
|
||||
fprocmd flags changed +p -> -g (incompatible change in protocol)
|
||||
fgetprocmd works in private directories. There are no more
|
||||
private.
|
||||
private.
|
||||
.FSP_PRIVATE -> .FSP_NO_GET for avoiding user confusion because
|
||||
i have axed marking directories as private in beta6
|
||||
i have axed marking directories as private in beta6
|
||||
fixed off-by-one error in getpro cmd
|
||||
fsetpro cmd shows command syntax on error
|
||||
fspd: do not save readme files to disk (avoids truncation them
|
||||
to 1k)
|
||||
to 1k)
|
||||
fspd: fixed reply for makedir command (size of reply block was
|
||||
not included)
|
||||
fspd: getdirlisting checks for seek offsets (do not allow send partial
|
||||
packets of dir listings)
|
||||
Done item from my 1997 fsp wishlist: check 4 rights before
|
||||
not included)
|
||||
fspd: getdirlisting checks for seek offsets (do not allow send partial
|
||||
packets of dir listings)
|
||||
Done item from my 1997 fsp wishlist: check 4 rights before
|
||||
uploading!
|
||||
fver command can be disabled on server -- protection against FSP
|
||||
detectors.
|
||||
detectors.
|
||||
fspscan: end port -e switch
|
||||
configure.ac add check for compiler warning options
|
||||
removed multiple definition of process from bsd_src/find.c and
|
||||
|
|
@ -104,7 +146,7 @@ Version 2.8.1b15 -- 15 Oct 2003
|
|||
fsp_prof: made `fsp` in `fsp port` optional
|
||||
fsp_prof: made `fsp` in `fsp directory' optional
|
||||
fhostcmd has now parser written in flex, should be less brain
|
||||
damaged and more stable
|
||||
damaged and more stable
|
||||
fhostcmd: searching can now match full hostname or alias, not
|
||||
a subpart of hostname or alias.
|
||||
fhostcmd: added -? switch
|
||||
|
|
@ -116,33 +158,33 @@ Version 2.8.1b15 -- 15 Oct 2003
|
|||
do not use echo -e when building fspmerge client
|
||||
updated manpages for fhostcmd.1 and fsp_prof.5
|
||||
fspd: really reuse cached directory listings. Forgot to update
|
||||
mtime after loading and they were loaded for every dirlisting
|
||||
packet.
|
||||
client library: do not use CC_STAT when building a directory listing.
|
||||
fix in beta14 do not fixed the problem when working in non root
|
||||
directory.
|
||||
mtime after loading and they were loaded for every dirlisting
|
||||
packet.
|
||||
client library: do not use CC_STAT when building a directory listing.
|
||||
fix in beta14 do not fixed the problem when working in non root
|
||||
directory.
|
||||
|
||||
Version 2.8.1b14 -- 22 Sep 2003
|
||||
Sven fixed bash shell script
|
||||
Sven fixed bash shell script
|
||||
fspd: list files over 4GB as 4GB in directory listings
|
||||
fspd: do not allow seeking over 2GB when OS is not LFS friendly
|
||||
fspd: print command names instead of numbers in debug mode
|
||||
added new program fspscan.c to package. Well known fsp port scanner
|
||||
made in 1992. Paranoid people calls this program fsp exploit.
|
||||
made in 1992. Paranoid people calls this program fsp exploit.
|
||||
added new SGML FSP FAQ made by Sven
|
||||
fspd: debug messages are printed to stderr
|
||||
PROTOCOL: added talking about timeouts
|
||||
fcatcmd: removed debug messages
|
||||
!!dirlist cache hit ratio is bad - something overwrites that!!
|
||||
!!only happens when compiled without EFENCE??
|
||||
fixed by fifocache malloc -> calloc
|
||||
!!dirlist cache hit ratio is bad - something overwrites that!!
|
||||
!!only happens when compiled without EFENCE??
|
||||
fixed by fifocache malloc -> calloc
|
||||
fspd: return 'is a directory' when trying to download directory
|
||||
client library: do not use CC_STAT when building a directory listing
|
||||
PLEASE!!! It is S l o w. Fixed: Performance of flscmd -l is now
|
||||
back to the normal speed. EnJoy!
|
||||
client library: do not use CC_STAT when building a directory listing
|
||||
PLEASE!!! It is S l o w. Fixed: Performance of flscmd -l is now
|
||||
back to the normal speed. EnJoy!
|
||||
fstatcmd: print dates in ISO format, avoid tabs in output
|
||||
fspd: support for long local directory names > 1024 but < 2048
|
||||
fixed SECURITY prob: stat can stat any file (even out of FSP root!)
|
||||
fixed SECURITY prob: stat can stat any file (even out of FSP root!)
|
||||
added support for fstat to both shell scripts
|
||||
fifocache.c support for memory profiler functions
|
||||
fifocache.c supports nice memory stats
|
||||
|
|
@ -150,19 +192,19 @@ Version 2.8.1b14 -- 22 Sep 2003
|
|||
cache stats are dumped to dumpfile also on SIGUSR1
|
||||
|
||||
Version 2.8.1b13 -- 10 Sep 2003
|
||||
fver: reports if timestamping is supported
|
||||
fver: reports if timestamping is supported
|
||||
CC_VER: now reports fspd + version + \n
|
||||
Hanno Hecker help us port shell script from CSH to BASH
|
||||
large file support activated in configure
|
||||
example.conf -> fspd.conf
|
||||
added contrib/mklargefile.c program for creating a large file with
|
||||
hole
|
||||
hole
|
||||
fver -l reports max file size supported and LFS mode
|
||||
server detects i/o errors when uploading (out of diskspace)
|
||||
4GB-1 files should work from server p. of view if LFS is on
|
||||
fspd -F runs in foreground, for broken startup scripts
|
||||
random port for fspd (-p 65535) important for keeping lamers out of
|
||||
your warez site.
|
||||
your warez site.
|
||||
changed exit codes for server, for easy debuging
|
||||
manual page for fspd updated - exit codes added
|
||||
PROTOCOL: added support for timestamping on uploads
|
||||
|
|
@ -170,8 +212,8 @@ Version 2.8.1b13 -- 10 Sep 2003
|
|||
fspd: -T switch for setting temporary directory for uploads
|
||||
fput.c: added support for timestamping uploads
|
||||
fcdcmd supports new permisions also
|
||||
fput - made timestamping optional -p option
|
||||
correct stats dumping - now dumpfile is used (really)
|
||||
fput - made timestamping optional -p option
|
||||
correct stats dumping - now dumpfile is used (really)
|
||||
inetd mode now works!
|
||||
updated INFO document
|
||||
moved faq, history and protocol to a new doc subdirectory
|
||||
|
|
@ -181,17 +223,17 @@ Version 2.8.1b12 -- 3 Sep 2003
|
|||
port setting in config file works
|
||||
manual page for fprocmd updated
|
||||
fstatcmd now uses remote wildcard expansion like rest of fsp
|
||||
merged fgetcmd and fgrabcmd commands
|
||||
merged fgetcmd and fgrabcmd commands
|
||||
merged patch Geoffrey T. Dairiki. Server records new keyid from client
|
||||
when serving session timeout.
|
||||
when serving session timeout.
|
||||
updated Bash version of CSH setup script, but still do not works
|
||||
NEW FEATURE: fget/fgrab can now set file timestamps to remote date
|
||||
When I have first used FSP in 1996 - I wanted this option.
|
||||
When I have first used FSP in 1996 - I wanted this option.
|
||||
Cygwin has now different builtin defaults
|
||||
modified man page for fgetcmd - after 10 years! same goes for
|
||||
fgrabcmd
|
||||
default mode of fget/grab changed to unique fnames. Should I
|
||||
change it to noclober
|
||||
fgrabcmd
|
||||
default mode of fget/grab changed to unique fnames. Should I
|
||||
change it to noclober?
|
||||
fget/grab has now -h help
|
||||
|
||||
Version 2.8.1b11 -- 27 Aug 2003
|
||||
|
|
@ -200,7 +242,7 @@ Version 2.8.1b11 -- 27 Aug 2003
|
|||
stat type log switch
|
||||
new command FSP_STAT (not tested)
|
||||
some code cleanup in client/ and common/ directories, warnings
|
||||
removed.
|
||||
removed.
|
||||
PROTOCOL definition updated (stat and rename commands added)
|
||||
auto_del.csh script added to server directory (untested)
|
||||
return only file or directory objects in dir listing and stat command.
|
||||
|
|
@ -208,8 +250,8 @@ Version 2.8.1b11 -- 27 Aug 2003
|
|||
server has -? and -h options
|
||||
new command fstatcmd (no manpage yet)
|
||||
fixed main arg count in merged fsp client
|
||||
client library now uses a new command FSP_STAT if server supports it
|
||||
fprocmd without args displays directory name instead of .
|
||||
client library now uses a new command FSP_STAT if server supports it
|
||||
fprocmd without args displays directory name instead of .
|
||||
fprocmd now supports 2.8.1bXX extented access rights
|
||||
|
||||
Version 2.8.1b10 -- 21 Jul 2003
|
||||
|
|
@ -217,155 +259,155 @@ Version 2.8.1b10 -- 21 Jul 2003
|
|||
removed -Wconversion from debug gcc switches
|
||||
MAJOR BUGFIX: can CD to more than 1 level deep
|
||||
changes init order in server/main.c so we can see error messages
|
||||
during server startup
|
||||
|
||||
during server startup
|
||||
|
||||
Version 2.8.1b9 -- 19 Jul 2003
|
||||
missing tmpdir switches fspd to read-only mode (really!)
|
||||
daemonize is on by default
|
||||
added port to default cnf file for fspd
|
||||
check for -lefence in configure script
|
||||
check for sys/syslimits.h - needed for cygwin
|
||||
default port is 21 in conf.c
|
||||
FIXED BUG when server root != file system root
|
||||
Now compiles and runs on cygwin
|
||||
do not use -1 exit code in server/main.c
|
||||
server now tries to create tmpdirectory on startup
|
||||
fspd: allow command line overide even when -f is used
|
||||
|
||||
missing tmpdir switches fspd to read-only mode (really!)
|
||||
daemonize is on by default
|
||||
added port to default cnf file for fspd
|
||||
check for -lefence in configure script
|
||||
check for sys/syslimits.h - needed for cygwin
|
||||
default port is 21 in conf.c
|
||||
FIXED BUG when server root != file system root
|
||||
Now compiles and runs on cygwin
|
||||
do not use -1 exit code in server/main.c
|
||||
server now tries to create tmpdirectory on startup
|
||||
fspd: allow command line overide even when -f is used
|
||||
|
||||
Version 2.8.1b8 -- 17 Jul 2003
|
||||
new cfg switch: setgid
|
||||
use /dev/random for seeding a random number generator
|
||||
new cfg switches: umask and serverumask (octal value). Umask
|
||||
for creating server files
|
||||
fixed compilation on GCC < 3.0
|
||||
fixed check for maintainer_mode in server/Makefile.am and
|
||||
clients/Makefile.am
|
||||
fhostcmd: check for $SHELL if we have csh-like shell
|
||||
fhostcmd: options -c or -b to force C or Bourne shell syntax
|
||||
server tables dump signal changed from alarm -> sigusr1
|
||||
new cfg switch: dumpname for dumping runtime stats
|
||||
clean server shutdown on sigint, sigterm
|
||||
new cfg switch: grabcommand on/off
|
||||
env. vars removed from individual manual pages and moved to a New
|
||||
manpage fsp_env 7.
|
||||
updated PROTOCOL definition of FSP. Fixed some bugs, added method
|
||||
of packet checksum.
|
||||
updated example configuration file for server
|
||||
removed all prints when debug is not on
|
||||
updated FILES section in fspd manpage
|
||||
new cfg switch: setgid
|
||||
use /dev/random for seeding a random number generator
|
||||
new cfg switches: umask and serverumask (octal value). Umask
|
||||
for creating server files
|
||||
fixed compilation on GCC < 3.0
|
||||
fixed check for maintainer_mode in server/Makefile.am and
|
||||
clients/Makefile.am
|
||||
fhostcmd: check for $SHELL if we have csh-like shell
|
||||
fhostcmd: options -c or -b to force C or Bourne shell syntax
|
||||
server tables dump signal changed from alarm -> sigusr1
|
||||
new cfg switch: dumpname for dumping runtime stats
|
||||
clean server shutdown on sigint, sigterm
|
||||
new cfg switch: grabcommand on/off
|
||||
env. vars removed from individual manual pages and moved to a New
|
||||
manpage fsp_env 7.
|
||||
updated PROTOCOL definition of FSP. Fixed some bugs, added method
|
||||
of packet checksum.
|
||||
updated example configuration file for server
|
||||
removed all prints when debug is not on
|
||||
updated FILES section in fspd manpage
|
||||
|
||||
Version 2.8.1b7 -- 13 Jul 2003
|
||||
do not sent zero length blocks if client asks for them
|
||||
filecache.c nuked
|
||||
new cfg statement tmpdir for placing files during upload
|
||||
all server code (except host.c) rewriting complete.
|
||||
do not sent zero length blocks if client asks for them
|
||||
filecache.c nuked
|
||||
new cfg statement tmpdir for placing files during upload
|
||||
all server code (except host.c) rewriting complete.
|
||||
|
||||
Version 2.8.1b6 -- 2 Jul 2003
|
||||
configuration file was not closed after reading (found by valgrind)
|
||||
link against Eletric Fence only in maintainer mode
|
||||
compile server/cachecheck only in maintainer mode
|
||||
removed long files check and support for code. FSP has maximum path
|
||||
about 1024; it is no need to check if file can be longer than 14 chars
|
||||
use config.guess for guessing OS type.
|
||||
simplified configure.ac
|
||||
up to date BETA.README
|
||||
MACHINES file lives again
|
||||
allow files starting with \ in directory listing
|
||||
directory content is builded correctly on systems with pragma pack > 1
|
||||
fixed another bug in generating of directory listing which violates FSP
|
||||
protocol definiton (but worked in current code anyway)
|
||||
use extern only in header files
|
||||
key was not initialised when using shmem locking method
|
||||
default timeout for clients changed from 4 to 180 sec.
|
||||
removed option -r from fcatcmd
|
||||
init socket data in udp io and avoid using sin there (gcc builtin)
|
||||
server debug option changed from -d to -X
|
||||
server argument -d directory -> sets root directory
|
||||
server now runs also without configuration file!
|
||||
keys generated by server are now 16bit random, not 8bit random
|
||||
directory_cache nuked - it was uneffective and it has a file
|
||||
descriptor leak!
|
||||
new cfg. use_prebuild_dirlists (load/save) content file
|
||||
new directory memory based cache engine works!
|
||||
new directory .FSP_CONTENT load/save engine works
|
||||
clear buffer before generating a directory listing (no information
|
||||
leak)
|
||||
fixed buffer overflow (exploitable if file uploads was allowed).
|
||||
new cfg keyword statcache - size of dirstatcache
|
||||
new cfg keyword statcache_timeout - (sec)
|
||||
new cfg keyword use_access_files - boolean
|
||||
fixed bug when home directory was symlinked to somewhere
|
||||
removed remote FSP support from PPATH. It was never used in code.
|
||||
new cfg use_directory_mtime - boolean. For windows set it to NO.
|
||||
!!! NEW DIRECTORY STATE ENGINE CACHE !!!
|
||||
new .FSP_PASSWORD access file
|
||||
new .FSP_OWNER owner file (not yet implemented)
|
||||
resend of BYE command is also accepted, why not?
|
||||
no memory leaks in new code. Last leaks are in code which is going
|
||||
to be rewrited
|
||||
!!! MAJOR PERFORMANCE SPEEDUP. Need only 1 syscal to serve a
|
||||
packet (if everything is cached).
|
||||
do not list special files as directories
|
||||
added file COPYRIGHT
|
||||
speedup when loading access files
|
||||
min delay for clients was increased from 0.5s to 1.5s (packets
|
||||
was are just thrown out by server for <3sec reply). Performance
|
||||
tested on our WireLess network. Today only 65% packets loss!
|
||||
new configuration option homedir_restricted for following symlinks
|
||||
out of home_directory
|
||||
if $test in configure changed to x$test
|
||||
ip range and IP parsing function moved out of host.c to iprange.c
|
||||
host type must be specified (in config or in owner file)
|
||||
renamed cfg. bufsize -> packetsize
|
||||
use packetsize when generatin a directory listing. -> max packet size
|
||||
management moved from user cfg. to server cfg.
|
||||
added support for readme files to new dirstat engine
|
||||
public directory list flag changed from negative to positive
|
||||
new cfg option permit_passwordless_owners
|
||||
NEW SECURITY ENGINE implemented
|
||||
fixed infinite loop in client library if server sends directory
|
||||
in smaller blocks than expected.
|
||||
removed buffer overflow in log code (remote exploitable of course)
|
||||
added new log switch 'readonly'
|
||||
fixed security hole in grab command
|
||||
rewrite log in packet processing (more readable)
|
||||
corrected handling of public rights in private directories
|
||||
detect if cached directory listings are out of date
|
||||
configuration file was not closed after reading (found by valgrind)
|
||||
link against Eletric Fence only in maintainer mode
|
||||
compile server/cachecheck only in maintainer mode
|
||||
removed long files check and support for code. FSP has maximum path
|
||||
about 1024; it is no need to check if file can be longer than 14 chars
|
||||
use config.guess for guessing OS type.
|
||||
simplified configure.ac
|
||||
up to date BETA.README
|
||||
MACHINES file lives again
|
||||
allow files starting with \ in directory listing
|
||||
directory content is builded correctly on systems with pragma pack > 1
|
||||
fixed another bug in generating of directory listing which violates FSP
|
||||
protocol definiton (but worked in current code anyway)
|
||||
use extern only in header files
|
||||
key was not initialised when using shmem locking method
|
||||
default timeout for clients changed from 4 to 180 sec.
|
||||
removed option -r from fcatcmd
|
||||
init socket data in udp io and avoid using sin there (gcc builtin)
|
||||
server debug option changed from -d to -X
|
||||
server argument -d directory -> sets root directory
|
||||
server now runs also without configuration file!
|
||||
keys generated by server are now 16bit random, not 8bit random
|
||||
directory_cache nuked - it was uneffective and it has a file
|
||||
descriptor leak!
|
||||
new cfg. use_prebuild_dirlists (load/save) content file
|
||||
new directory memory based cache engine works!
|
||||
new directory .FSP_CONTENT load/save engine works
|
||||
clear buffer before generating a directory listing (no information
|
||||
leak)
|
||||
fixed buffer overflow (exploitable if file uploads was allowed).
|
||||
new cfg keyword statcache - size of dirstatcache
|
||||
new cfg keyword statcache_timeout - (sec)
|
||||
new cfg keyword use_access_files - boolean
|
||||
fixed bug when home directory was symlinked to somewhere
|
||||
removed remote FSP support from PPATH. It was never used in code.
|
||||
new cfg use_directory_mtime - boolean. For windows set it to NO.
|
||||
!!! NEW DIRECTORY STATE ENGINE CACHE !!!
|
||||
new .FSP_PASSWORD access file
|
||||
new .FSP_OWNER owner file (not yet implemented)
|
||||
resend of BYE command is also accepted, why not?
|
||||
no memory leaks in new code. Last leaks are in code which is going
|
||||
to be rewrited
|
||||
!!! MAJOR PERFORMANCE SPEEDUP. Need only 1 syscal to serve a
|
||||
packet (if everything is cached).
|
||||
do not list special files as directories
|
||||
added file COPYRIGHT
|
||||
speedup when loading access files
|
||||
min delay for clients was increased from 0.5s to 1.5s (packets
|
||||
was are just thrown out by server for <3sec reply). Performance
|
||||
tested on our WireLess network. Today only 65% packets loss!
|
||||
new configuration option homedir_restricted for following symlinks
|
||||
out of home_directory
|
||||
if $test in configure changed to x$test
|
||||
ip range and IP parsing function moved out of host.c to iprange.c
|
||||
host type must be specified (in config or in owner file)
|
||||
renamed cfg. bufsize -> packetsize
|
||||
use packetsize when generatin a directory listing. -> max packet size
|
||||
management moved from user cfg. to server cfg.
|
||||
added support for readme files to new dirstat engine
|
||||
public directory list flag changed from negative to positive
|
||||
new cfg option permit_passwordless_owners
|
||||
NEW SECURITY ENGINE implemented
|
||||
fixed infinite loop in client library if server sends directory
|
||||
in smaller blocks than expected.
|
||||
removed buffer overflow in log code (remote exploitable of course)
|
||||
added new log switch 'readonly'
|
||||
fixed security hole in grab command
|
||||
rewrite log in packet processing (more readable)
|
||||
corrected handling of public rights in private directories
|
||||
detect if cached directory listings are out of date
|
||||
|
||||
Version 2.8.1b5 -- 25 June 2003
|
||||
configure.ac upgaded to autoconf 2.57 and cleaned
|
||||
added missing include headers to source code
|
||||
vms code nuked from rest of headers
|
||||
prefix is now used when finding configuration file
|
||||
check for max. number of open files and adjust open handle cache
|
||||
removed long file limit hack for FAT/VMS filesystems. Nonstandard and
|
||||
unsecure.
|
||||
removed include/version.h - use autoconf instead
|
||||
added -V server option (display version)
|
||||
do not use dircache as upload cache. Uploads now works even without
|
||||
dircache
|
||||
turn off cachedir when it do not exists
|
||||
better init of random number generator. It should be really random.
|
||||
fixed use of prebuild directory content and dircache
|
||||
turn of logging if no log file is set
|
||||
clean cache directory on startup
|
||||
merged security patch from Debian package fsp_2.81.b3-4, i have
|
||||
fixed this problem in 2.8.1b4; but Debian code looks better.
|
||||
removed non standard NEED_ from configure.ac, use HAVE_
|
||||
fver displays locking method and used config. files.
|
||||
give lockf locking method priority over flock method
|
||||
fgetcmd and fgrabcmd now understands -c continue download
|
||||
fixed check for in.fspd
|
||||
we have called check_required_vars twice
|
||||
display copyright in fspd -V
|
||||
INFO document updated, fixed spelling errors, added section
|
||||
FSP today
|
||||
added -t option for fspd; specifes timeout for inetd mode (or
|
||||
when debug is on for normal more also)
|
||||
configure.ac upgaded to autoconf 2.57 and cleaned
|
||||
added missing include headers to source code
|
||||
vms code nuked from rest of headers
|
||||
prefix is now used when finding configuration file
|
||||
check for max. number of open files and adjust open handle cache
|
||||
removed long file limit hack for FAT/VMS filesystems. Nonstandard and
|
||||
unsecure.
|
||||
removed include/version.h - use autoconf instead
|
||||
added -V server option (display version)
|
||||
do not use dircache as upload cache. Uploads now works even without
|
||||
dircache
|
||||
turn off cachedir when it do not exists
|
||||
better init of random number generator. It should be really random.
|
||||
fixed use of prebuild directory content and dircache
|
||||
turn off logging if no log file is set
|
||||
clean cache directory on startup
|
||||
merged security patch from Debian package fsp_2.81.b3-4, i have
|
||||
fixed this problem in 2.8.1b4; but Debian code looks better.
|
||||
removed non standard NEED_ from configure.ac, use HAVE_
|
||||
fver displays locking method and used config. files.
|
||||
give lockf locking method priority over flock method
|
||||
fgetcmd and fgrabcmd now understands -c continue download
|
||||
fixed check for in.fspd
|
||||
we have called check_required_vars twice
|
||||
display copyright in fspd -V
|
||||
INFO document updated, fixed spelling errors, added section
|
||||
FSP today
|
||||
added -t option for fspd; specifes timeout for inetd mode (or
|
||||
when debug is on for normal more also)
|
||||
|
||||
Version 2.8.1b4 -- 30 March, 2001
|
||||
-------------------------------------------------------------------------
|
||||
New maintainer: Radim Kolar hsn/at/cybermail.net now maintains FSP codebase.
|
||||
New maintainer: Radim Kolar hsn/at/netmag.cz now maintains FSP codebase.
|
||||
-------------------------------------------------------------------------
|
||||
1) Eliminated a lot of warnings when compiling with -Wall.
|
||||
2) Moved to autoconf 2.12. Replaced old m4 macros with Autoconf's.
|
||||
|
|
@ -381,11 +423,11 @@ New maintainer: Radim Kolar hsn/at/cybermail.net now maintains FSP codebase.
|
|||
8) Server has now configurable timeouts, maximal packetsize,
|
||||
directory and file handles caches.
|
||||
9) REMOVED VMS part vms/ and vms_src/. Is was out of date.
|
||||
10) Removed file MACHINES. It was out of date. After my changes in
|
||||
autoconf, it may not compile on non-Linux systems.
|
||||
11) Implemented a check for reliable signals in the configure script.
|
||||
12) Return type of signal handler is detected in configure script.
|
||||
13) ANSI prototypes are now used, if host compiler supports them.
|
||||
14) When server is running in read-only mode, server send this
|
||||
information to clients, instead generic "Permission denied".
|
||||
15) Access checking and uploading was fixed. Now works.
|
||||
10) Removed file MACHINES. It was out of date. After my changes in
|
||||
autoconf, it may not compile on non-Linux systems.
|
||||
11) Implemented a check for reliable signals in the configure script.
|
||||
12) Return type of signal handler is detected in configure script.
|
||||
13) ANSI prototypes are now used, if host compiler supports them.
|
||||
14) When server is running in read-only mode, server send this
|
||||
information to clients, instead generic "Permission denied".
|
||||
15) Access checking and uploading was fixed. Now works.
|
||||
|
|
|
|||
78
INFO
78
INFO
|
|
@ -9,40 +9,74 @@
|
|||
and FSP software was not maintained...
|
||||
|
||||
FSP today
|
||||
|
||||
Written by Radim Kolar
|
||||
|
||||
FSP uses UDP datagrams and it is reliable even when there is high
|
||||
number of packet loss. It is usable on WiFi network with 60% packet
|
||||
loss.
|
||||
Protocol related
|
||||
|
||||
FSP uses UDP datagrams and it is reliable even when there is
|
||||
high number of packet loss. It is usable on WiFi network with
|
||||
60% packet loss.
|
||||
|
||||
Unlike TCP, FSP has a fast restart when line comes up.
|
||||
FSP can very quickly addapt to changing line condition. This
|
||||
is excelent for wireless packet networks. FSP needs about 6
|
||||
RTT to retune itself after receiving condition goes worse.
|
||||
And unlike TCP based protocols, FSP has a fast restart when
|
||||
line improves - It do not needs any RTT; FSP goes immediatly
|
||||
to maximum possible speed.
|
||||
|
||||
Maximum FSP speed is by design lower than maximum speed of TCP
|
||||
based protocols because it has only 1 packet in the network.
|
||||
TCP protocol has about 3 packets. Design of FSP protocol
|
||||
makes impossible to send more than 1 packet into network.
|
||||
This is nice method for bandwidth protection.
|
||||
|
||||
FSP server do not sends any data out unless is asked for. This
|
||||
solves problem with transfering duplicate data when using
|
||||
TCP protocol on overloaded lines. About 30% are dupes, thrown
|
||||
out by client.
|
||||
FSP server do not sends any data out unless is asked for. This
|
||||
solves problem with transfering duplicate data when using TCP
|
||||
protocol on overloaded lines. About 30% are dupes, thrown out
|
||||
by client. Note: TCP stacks from BSD family has this dupe
|
||||
ratio much lower.
|
||||
|
||||
UDP ports are not often port scanned today. Nobody notice that
|
||||
you are running a server.
|
||||
Embedded devices
|
||||
|
||||
FSP uses UDP which is unnoticed by many firewalls. FSP server
|
||||
runs on 21 port by default, if you move it to port 53 (dns)
|
||||
even strictly configured firewall can be worked around.
|
||||
FSP protocol is very easy to implement; client core has about
|
||||
one page of C code. It is ideal for embedded devices for
|
||||
file-transfer tasks, like firmware downloading. Because of its
|
||||
simplicity, there is a little chance to writing buggy
|
||||
implementation.
|
||||
|
||||
You want to run anonymous archive and want to keep lamers out.
|
||||
FSP is also good for remote booting. It is simplier than TFTP
|
||||
and supports directory listings.
|
||||
|
||||
You want to share something without ruining your valueable bandwidth.
|
||||
FSP protocol can be used as wire-protocol even without using
|
||||
any layer 2 stuff. It operates in degraded mode with extra
|
||||
features disabled.
|
||||
|
||||
You have overloaded archive site.
|
||||
|
||||
You do want to share large data files (movies, ISO images) on
|
||||
slow (or you do not want to waste valuable bandwidth) lines.
|
||||
Ideal for sharing files on modem lines.
|
||||
Internet operation
|
||||
|
||||
UDP ports are not often port scanned today, only one exception
|
||||
is scanning for Windows/Samba file sharing service. Nobody
|
||||
will notice that you are running a fsp server.
|
||||
|
||||
FSP uses UDP which is unnoticed by many firewalls. FSP server
|
||||
runs on 21 port by default, if you move it to port 53 (dns)
|
||||
even strictly configured firewall can be worked around.
|
||||
|
||||
You want to run anonymous archive and want to keep lamers out.
|
||||
|
||||
You want to share something without ruining your valueable
|
||||
bandwidth.
|
||||
|
||||
You have overloaded archive site.
|
||||
|
||||
You do want to share large data files (movies, ISO images) on
|
||||
slow (or you do not want to waste valuable bandwidth) lines.
|
||||
Ideal for sharing files on modem lines.
|
||||
|
||||
FSP daemon is a very light server.
|
||||
|
||||
|
||||
What is the purpose of FSP (V2.8.1):
|
||||
|
||||
|
||||
Written by A.J.Doherty@reading.ac.uk
|
||||
|
||||
FSP is a set of programs that implements a public-access archive
|
||||
|
|
|
|||
5
MACHINES
5
MACHINES
|
|
@ -3,7 +3,7 @@ successfully compiled out of the box using configure script. If you get it to
|
|||
compile on an architecture/compiler combination other than one listed here,
|
||||
PLEASE SEND ME DETAILS of the fsp version, the type of machine, the OS, the
|
||||
compiler used and C library used; As well as what changes (if any) were needed
|
||||
to for a clean compile. My email address is hsn/at/cybermail.net. Thanks
|
||||
to for a clean compile. My email address is hsn/at/sendmail.cz. Thanks
|
||||
for your cooperation.
|
||||
|
||||
FSP Version CPU OS Compiler C library
|
||||
|
|
@ -14,4 +14,5 @@ FSP Version CPU OS Compiler C library
|
|||
2.8.1 Beta 14 i386 Debian/testing-unstable
|
||||
2.8.1 Beta 14 i386 RedHat 7.3
|
||||
2.8.1 Beta 14 i386 Conectiva Linux 9
|
||||
2.8.1 Beta 19 i386 FreeBSD 5.x gcc-3.3
|
||||
2.8.1 Beta 19 i386 FreeBSD 5.2 gcc-3.3
|
||||
2.8.1 Beta 19 i386 FreeBSD 5.3 gcc-3.4
|
||||
|
|
|
|||
26
TODO
26
TODO
|
|
@ -6,31 +6,36 @@ show loosers online (finfo command) and server statz
|
|||
rename command
|
||||
password change command
|
||||
|
||||
TESTING NEEDED:
|
||||
TESTSUITE NEEDED:
|
||||
Write a simple FSP protocol testing tool
|
||||
Write a test suite using testing tool
|
||||
test for remote buffer overflows
|
||||
Test new command rename /when implemented/
|
||||
Test if >2GB files but <4GB works correctly with and without --disable-largefile
|
||||
Test new command rename /when implemented/
|
||||
|
||||
SECURITY BUGS:
|
||||
symlink to FILE can escape from FSP root directory. OLD known problem.
|
||||
|
||||
PROTOCOL-RELATED BUGS:
|
||||
none known
|
||||
|
||||
PORTING
|
||||
Sven's Slowaris 8 compile problem
|
||||
not builds on freebsd 4 and non intel platforms?
|
||||
|
||||
NEEDS IMPROVMENT:
|
||||
|
||||
Client LIBRARY
|
||||
:high:
|
||||
local bind address FSP_LOCALIP
|
||||
remove stale lock files if not needed, port code from fspclient.
|
||||
FSP_TIMEOUT should be total number of seconds, not delay between retrys.
|
||||
we should retune retry algoritm for better support lines with higher
|
||||
packed loss.
|
||||
add more detailed stats from retry alg.
|
||||
:low:
|
||||
fver and others add support new syntax fsp://host:port/file
|
||||
add sem locking method, possible?
|
||||
flscmd does stat before directory listing, why?
|
||||
:long-term goals:
|
||||
:better to write a new code instead fixing old crap
|
||||
=convert to multi threaded=
|
||||
make setup from env a separate function
|
||||
|
|
@ -42,17 +47,21 @@ write new clients for new commands - fsprencmd fpasswd finfo
|
|||
:low:
|
||||
add support for more sane fsplist file format (as used by warez
|
||||
ppl) to fhostcmd
|
||||
it looks like
|
||||
#FSP Sites list
|
||||
genie.lut.ac.uk 21 genie / # small UK site
|
||||
|
||||
clients do not freeing memory allocated from glob()
|
||||
|
||||
FUTURE FEATURES FOR SERVER:
|
||||
:high:
|
||||
can be run multiple times on the same port, how to check?
|
||||
:high: required for 2.8.2 final
|
||||
can be run multiple times on the same port, how to check?
|
||||
Currently looks fine on bsd.
|
||||
write RENAME FSP command
|
||||
bind-ip-address for server (and client via FSP_LOCAL_IP)
|
||||
report number of clients connected, size of hostable in new command
|
||||
CC_INFO command
|
||||
special defence against rapid/double fire clients (burst command in fspclient)
|
||||
common log format - replace custom fspd log
|
||||
|
||||
:midle:may not be in 2.8.2
|
||||
Native Supports for symbolic links (needed for mirroring Debian)
|
||||
|
|
@ -73,7 +82,7 @@ PERFORMANCE:
|
|||
host hashtable shrinking sometimes
|
||||
stat cache pro FSP_STAT a ostatni
|
||||
background time() alarm() caller
|
||||
Current performance 1925648b/s
|
||||
Current performance 1925648B/s
|
||||
|
||||
MAN:
|
||||
update FAQ - urgent!!
|
||||
|
|
@ -96,3 +105,4 @@ LARGEFILES64 how to turn them on:
|
|||
Cygwin: #define __LARGE64_FILES fopen64,ftello64,fseeko64 _off64_t
|
||||
glibc 2.3: #define _LARGEFILE64_SOURCE off64_t
|
||||
native: _FILE_OFFSETS_BITS = 32 / 64 then use off_t
|
||||
FreeBSD: in 5.X always enabled, in 4.X not supported.
|
||||
|
|
|
|||
32
autogen.sh
Executable file
32
autogen.sh
Executable file
|
|
@ -0,0 +1,32 @@
|
|||
#! /bin/sh -e
|
||||
# This scripts rebuilds configure files using autoconf tools.
|
||||
# Supports both FreeBSD and Linux installations. No copyrights
|
||||
# script is public domain.
|
||||
#
|
||||
# I am not big fan of autotools stuff, but other solutions
|
||||
# like scons are worse (harder to maintain).
|
||||
#
|
||||
# Radim Kolar
|
||||
#
|
||||
# TODO: add linux support (sven?)
|
||||
# add detection of automake19 and use it instead of
|
||||
# automake18
|
||||
#
|
||||
rm -f configure configure.lineno config.log config.status
|
||||
rm -f aclocal.m4
|
||||
#rm -fr autom4te.cache
|
||||
rm -f Makefile "Makefile.in"
|
||||
echo "Generating configure and friends..."
|
||||
if [ `uname -s` = 'FreeBSD' ]; then
|
||||
echo "* FreeBSD detected"
|
||||
echo "* Using autoconf 2.59 + automake 1.8"
|
||||
#Use autoconf 2.59 + automake 1.8 pair
|
||||
ACLOCAL=aclocal18; export ACLOCAL
|
||||
AUTOMAKE=automake18; export AUTOMAKE
|
||||
AUTOHEADER=autoheader259; export AUTOHEADER
|
||||
AUTOCONF=autoconf259; export AUTOCONF
|
||||
autoreconf259 -v
|
||||
fi
|
||||
echo "Now running configure $@"
|
||||
./configure $@
|
||||
echo "done."
|
||||
|
|
@ -68,7 +68,7 @@ void find_formplan PROTO1(char **, argv)
|
|||
tail = new;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!isoutput) {
|
||||
new = c_print();
|
||||
if (plan == NULL) tail = plan = new;
|
||||
|
|
|
|||
|
|
@ -71,8 +71,8 @@
|
|||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
|
||||
#ifdef HAVE_SYS_WAIT_H
|
||||
#include <sys/wait.h>
|
||||
#endif
|
||||
#ifndef WEXITSTATUS
|
||||
|
|
@ -111,7 +111,7 @@ static PLAN *palloc (t, f)
|
|||
PLAN *new;
|
||||
|
||||
new = (PLAN *) malloc(sizeof(PLAN));
|
||||
|
||||
|
||||
if ( new ) {
|
||||
new->type = t;
|
||||
new->eval = f;
|
||||
|
|
@ -135,7 +135,7 @@ static long find_parsenum PROTO4(PLAN *, plan, const char *, option, char *, str
|
|||
{
|
||||
long value;
|
||||
char *endchar; /* pointer to character ending conversion */
|
||||
|
||||
|
||||
/* determine comparison from leading + or - */
|
||||
switch(*str) {
|
||||
case '+':
|
||||
|
|
@ -150,7 +150,7 @@ static long find_parsenum PROTO4(PLAN *, plan, const char *, option, char *, str
|
|||
plan->flags = FIND_EQUAL;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* convert the string with strtol(). Note, if strtol() returns zero
|
||||
* and endchar points to the beginning of the string we know we have
|
||||
|
|
@ -183,7 +183,7 @@ static int find_time PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
COMPARE((now - sbuf->st_atime + SECSPERDAY - 1) / SECSPERDAY, plan->t_data);
|
||||
}
|
||||
|
||||
|
||||
|
||||
PLAN * c_time PROTO1(char *, arg)
|
||||
{
|
||||
PLAN *new;
|
||||
|
|
@ -234,9 +234,9 @@ static int queryuser PROTO1(char **, argv)
|
|||
fflush(stderr);
|
||||
|
||||
first = ch = getchar();
|
||||
for (nl = 0;;)
|
||||
for (nl = 0;;)
|
||||
{
|
||||
if (ch == '\n')
|
||||
if (ch == '\n')
|
||||
{
|
||||
nl = 1;
|
||||
break;
|
||||
|
|
@ -304,7 +304,7 @@ static char *emalloc_ffind PROTO1(unsigned int, len)
|
|||
perror("malloc");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* c_exec --
|
||||
* build three parallel arrays, one with pointers to the strings passed
|
||||
|
|
@ -319,7 +319,7 @@ PLAN *c_exec PROTO2(char ***, argvp, int, isok)
|
|||
register char **argv, **ap, *p;
|
||||
|
||||
isoutput = 1;
|
||||
|
||||
|
||||
new = palloc(N_EXEC, find_exec);
|
||||
new->flags = isok;
|
||||
|
||||
|
|
@ -389,7 +389,7 @@ static void printlong_ffind PROTO2(char *, name, struct stat *, sb)
|
|||
printf("%s", name);
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* -ls functions --
|
||||
*
|
||||
|
|
@ -400,7 +400,7 @@ static int find_ls PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
printlong_ffind(path, sbuf);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_ls PROTO0((void))
|
||||
{
|
||||
isoutput = 1;
|
||||
|
|
@ -422,7 +422,7 @@ static int find_name PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
if (*name == '/') name++;
|
||||
return(fnmatch(plan->c_data, name));
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_name PROTO1(char *, pattern)
|
||||
{
|
||||
PLAN *new;
|
||||
|
|
@ -431,7 +431,7 @@ PLAN *c_name PROTO1(char *, pattern)
|
|||
new->c_data = pattern;
|
||||
return(new);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* -newer file functions --
|
||||
*
|
||||
|
|
@ -443,12 +443,12 @@ static int find_newer PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
{
|
||||
return(sbuf->st_mtime > plan->t_data);
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_newer PROTO1(char *, filename)
|
||||
{
|
||||
PLAN *new;
|
||||
struct stat sb;
|
||||
|
||||
|
||||
if (stat(filename, &sb)) {
|
||||
perror("stat");
|
||||
exit(1);
|
||||
|
|
@ -457,7 +457,7 @@ PLAN *c_newer PROTO1(char *, filename)
|
|||
new->t_data = sb.st_mtime;
|
||||
return(new);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* -print functions --
|
||||
*
|
||||
|
|
@ -469,14 +469,14 @@ static int find_print PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
(void)printf("%s\n", path);
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_print PROTO0((void))
|
||||
{
|
||||
isoutput = 1;
|
||||
|
||||
return(palloc(N_PRINT, find_print));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* -prune functions --
|
||||
*
|
||||
|
|
@ -487,12 +487,12 @@ static int find_prune PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
process = -1;
|
||||
return(1);
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_prune PROTO0((void))
|
||||
{
|
||||
return(palloc(N_PRUNE, find_prune));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* -size n[c] functions --
|
||||
*
|
||||
|
|
@ -510,18 +510,18 @@ static int find_size PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
size = divsize ? ((sbuf->st_size + FIND_SIZE - 1)/FIND_SIZE) : sbuf->st_size;
|
||||
COMPARE(size, plan->o_data);
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_size PROTO1(char *, arg)
|
||||
{
|
||||
PLAN *new;
|
||||
char endch='c';
|
||||
|
||||
|
||||
new = palloc(N_SIZE, find_size);
|
||||
new->o_data = find_parsenum(new, "-size", arg, &endch);
|
||||
if (endch == 'c') divsize = 0;
|
||||
return(new);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* -type c functions --
|
||||
*
|
||||
|
|
@ -532,12 +532,12 @@ static int find_type PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
{
|
||||
return((sbuf->st_mode & S_IFMT) == plan->m_data);
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_type PROTO1(char *, typestring)
|
||||
{
|
||||
PLAN *new;
|
||||
mode_t mask;
|
||||
|
||||
|
||||
switch (typestring[0]) {
|
||||
case 'd':
|
||||
mask = S_IFDIR;
|
||||
|
|
@ -549,12 +549,12 @@ PLAN *c_type PROTO1(char *, typestring)
|
|||
fprintf(stderr,"-type: unknown type");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
new = palloc(N_TYPE, find_type);
|
||||
new->m_data = mask;
|
||||
return(new);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* ( expression ) functions --
|
||||
*
|
||||
|
|
@ -568,7 +568,7 @@ int find_expr PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
for(p=plan->p_data[0]; p && (state=(p->eval)(p, sbuf, path)); p=p->next);
|
||||
return(state);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* N_OPENPAREN and N_CLOSEPAREN nodes are temporary place markers. They are
|
||||
* eliminated during phase 2 of find_formplan() --- the '(' node is converted
|
||||
|
|
@ -578,12 +578,12 @@ PLAN *c_openparen PROTO0((void))
|
|||
{
|
||||
return(palloc(N_OPENPAREN, (int (*)())-1));
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_closeparen PROTO0((void))
|
||||
{
|
||||
return(palloc(N_CLOSEPAREN, (int (*)())-1));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* ! expression functions --
|
||||
|
|
@ -598,12 +598,12 @@ static int find_not PROTO3(PLAN *, plan, struct stat *, sbuf, char *, path)
|
|||
for(p=plan->p_data[0]; p && (state=(p->eval)(p, sbuf, path)); p=p->next);
|
||||
return(!state);
|
||||
}
|
||||
|
||||
|
||||
PLAN *c_not PROTO0((void))
|
||||
{
|
||||
return(palloc(N_NOT, find_not));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* expression -o expression functions --
|
||||
*
|
||||
|
|
|
|||
|
|
@ -425,7 +425,7 @@ static void rscan(t, f)
|
|||
#ifdef PROTOTYPES
|
||||
if (f == (charfunc) tglob)
|
||||
#else
|
||||
if (f == tglob)
|
||||
if (f == tglob)
|
||||
#endif
|
||||
{
|
||||
if (*p == '~') gflag |= 2;
|
||||
|
|
|
|||
22
bsd_src/ls.c
22
bsd_src/ls.c
|
|
@ -82,7 +82,7 @@ static int tabdir PROTO2(LS *, lp, LS **, s_stats)
|
|||
struct rdirent *dp;
|
||||
unsigned long blocks;
|
||||
LS *stats;
|
||||
|
||||
|
||||
if (!(dirp = util_opendir("."))) {
|
||||
perror(lp->name);
|
||||
return(0);
|
||||
|
|
@ -118,25 +118,25 @@ static int tabdir PROTO2(LS *, lp, LS **, s_stats)
|
|||
continue;
|
||||
}
|
||||
stats[cnt].name = dp->d_name;
|
||||
|
||||
|
||||
/*
|
||||
* get the inode from the directory, so the -f flag
|
||||
* works right.
|
||||
*/
|
||||
stats[cnt].lstat.st_ino = dp->d_fileno;
|
||||
|
||||
|
||||
/* save name length for -C format */
|
||||
stats[cnt].len = dp->d_namlen;
|
||||
|
||||
|
||||
/* calculate number of blocks if -l/-s formats */
|
||||
if (f_longform || f_size) blocks += (stats[cnt].lstat.st_size+1023)/1024;
|
||||
|
||||
|
||||
/* save max length if -C format */
|
||||
if (f_column && maxlen < (int)dp->d_namlen) maxlen = dp->d_namlen;
|
||||
++cnt;
|
||||
}
|
||||
(void)util_closedir(dirp);
|
||||
|
||||
|
||||
if (cnt) {
|
||||
stats[0].lstat.st_btotal = blocks;
|
||||
stats[0].lstat.st_maxlen = maxlen;
|
||||
|
|
@ -187,12 +187,12 @@ static void displaydir PROTO2(LS *, stats, register int, num)
|
|||
|
||||
printfcn(stats, num);
|
||||
|
||||
if (f_recursive)
|
||||
if (f_recursive)
|
||||
{
|
||||
savedpath = endofpath;
|
||||
for (lp = stats; num--; ++lp)
|
||||
for (lp = stats; num--; ++lp)
|
||||
{
|
||||
if (!(S_ISDIR(lp->lstat.st_mode)))
|
||||
if (!(S_ISDIR(lp->lstat.st_mode)))
|
||||
continue;
|
||||
p = lp->name;
|
||||
if (p[0] == '.' && (!p[1] || (p[1] == '.' && !p[2]))) continue;
|
||||
|
|
@ -227,7 +227,7 @@ static void doargs PROTO2(int, argc, char **, argv)
|
|||
av2[0] = *argv;
|
||||
av2[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
for( ; *av; av++) {
|
||||
if (util_stat(*av, &sb)) {
|
||||
perror(*av);
|
||||
|
|
@ -421,7 +421,7 @@ void fls_main PROTO2(int, argc, char **, argv)
|
|||
if (!f_timesort) sortfcn = revnamecmp;
|
||||
else if (f_accesstime) sortfcn = revacccmp;
|
||||
else if (f_statustime) sortfcn = revstatcmp;
|
||||
else sortfcn = revmodcmp; /* use modification time */
|
||||
else sortfcn = revmodcmp; /* use modification time */
|
||||
} else {
|
||||
if (!f_timesort) sortfcn = namecmp;
|
||||
else if (f_accesstime) sortfcn = acccmp;
|
||||
|
|
|
|||
|
|
@ -47,10 +47,10 @@
|
|||
* yanknode --
|
||||
* destructively removes the top from the plan
|
||||
*/
|
||||
static PLAN *yanknode PROTO1(PLAN **, planp)
|
||||
static PLAN *yanknode PROTO1(PLAN **, planp)
|
||||
{
|
||||
PLAN *node; /* top node removed from the plan */
|
||||
|
||||
|
||||
if ((node = (*planp)) == NULL) return(NULL);
|
||||
(*planp) = (*planp)->next;
|
||||
node->next = NULL;
|
||||
|
|
@ -63,16 +63,16 @@ static PLAN *yanknode PROTO1(PLAN **, planp)
|
|||
* paren_squish. In comments below, an expression is either a
|
||||
* simple node or a N_EXPR node containing a list of simple nodes.
|
||||
*/
|
||||
static PLAN *yankexpr PROTO1(PLAN **, planp)
|
||||
static PLAN *yankexpr PROTO1(PLAN **, planp)
|
||||
{
|
||||
register PLAN *next; /* temp node holding subexpression results */
|
||||
PLAN *node; /* pointer to returned node or expression */
|
||||
PLAN *tail; /* pointer to tail of subplan */
|
||||
PLAN *subplan; /* pointer to head of ( ) expression */
|
||||
|
||||
|
||||
/* first pull the top node from the plan */
|
||||
if ((node = yanknode(planp)) == NULL) return(NULL);
|
||||
|
||||
|
||||
/*
|
||||
* If the node is an '(' then we recursively slurp up expressions
|
||||
* until we find its associated ')'. If it's a closing paren we
|
||||
|
|
@ -120,9 +120,9 @@ PLAN *paren_squish PROTO1(PLAN *, plan)
|
|||
register PLAN *expr; /* pointer to next expression */
|
||||
register PLAN *tail; /* pointer to tail of result plan */
|
||||
PLAN *result; /* pointer to head of result plan */
|
||||
|
||||
|
||||
result = tail = NULL;
|
||||
|
||||
|
||||
/*
|
||||
* the basic idea is to have yankexpr do all our work and just
|
||||
* collect it's results together.
|
||||
|
|
@ -136,7 +136,7 @@ PLAN *paren_squish PROTO1(PLAN *, plan)
|
|||
fprintf(stderr,"): no beginning '('");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
/* add the expression to our result plan */
|
||||
if (result == NULL) tail = result = expr;
|
||||
else {
|
||||
|
|
@ -158,16 +158,16 @@ PLAN *not_squish PROTO1(PLAN *, plan)
|
|||
register PLAN *node; /* temporary node used in N_NOT processing */
|
||||
register PLAN *tail; /* pointer to tail of result plan */
|
||||
PLAN *result; /* pointer to head of result plan */
|
||||
|
||||
|
||||
tail = result = next = NULL;
|
||||
|
||||
|
||||
while ((next = yanknode(&plan)) != NULL) {
|
||||
/*
|
||||
* if we encounter a ( expression ) then look for nots in
|
||||
* the expr subplan.
|
||||
*/
|
||||
if (next->type == N_EXPR) next->p_data[0] = not_squish(next->p_data[0]);
|
||||
|
||||
|
||||
/*
|
||||
* if we encounter a not, then snag the next node and place
|
||||
* it in the not's subplan. As an optimization we compress
|
||||
|
|
@ -175,7 +175,7 @@ PLAN *not_squish PROTO1(PLAN *, plan)
|
|||
*/
|
||||
if (next->type == N_NOT) {
|
||||
int notlevel = 1;
|
||||
|
||||
|
||||
node = yanknode(&plan);
|
||||
while (node->type == N_NOT) {
|
||||
++notlevel;
|
||||
|
|
@ -192,7 +192,7 @@ PLAN *not_squish PROTO1(PLAN *, plan)
|
|||
if (notlevel % 2 != 1) next = node;
|
||||
else next->p_data[0] = node;
|
||||
}
|
||||
|
||||
|
||||
/* add the node to our result plan */
|
||||
if (result == NULL) tail = result = next;
|
||||
else {
|
||||
|
|
@ -213,19 +213,19 @@ PLAN *or_squish PROTO1(PLAN *, plan)
|
|||
register PLAN *next; /* next node being processed */
|
||||
register PLAN *tail; /* pointer to tail of result plan */
|
||||
PLAN *result; /* pointer to head of result plan */
|
||||
|
||||
|
||||
tail = result = next = NULL;
|
||||
|
||||
|
||||
while ((next = yanknode(&plan)) != NULL) {
|
||||
/*
|
||||
* if we encounter a ( expression ) then look for or's in
|
||||
* the expr subplan.
|
||||
*/
|
||||
if (next->type == N_EXPR) next->p_data[0] = or_squish(next->p_data[0]);
|
||||
|
||||
|
||||
/* if we encounter a not then look for not's in the subplan */
|
||||
if (next->type == N_NOT) next->p_data[0] = or_squish(next->p_data[0]);
|
||||
|
||||
|
||||
/*
|
||||
* if we encounter an or, then place our collected plan in the
|
||||
* or's first subplan and then recursively collect the
|
||||
|
|
@ -244,7 +244,7 @@ PLAN *or_squish PROTO1(PLAN *, plan)
|
|||
}
|
||||
return(next);
|
||||
}
|
||||
|
||||
|
||||
/* add the node to our result plan */
|
||||
if (result == NULL) tail = result = next;
|
||||
else {
|
||||
|
|
|
|||
|
|
@ -80,9 +80,9 @@ PLAN *find_create PROTO1(char ***, argvp)
|
|||
register OPTION *p;
|
||||
PLAN *new;
|
||||
char **argv;
|
||||
|
||||
|
||||
argv = *argvp;
|
||||
|
||||
|
||||
if ((p = option(*argv)) == NULL) {
|
||||
(void)fprintf(stderr, "find: unknown option %s.\n", *argv);
|
||||
exit(1);
|
||||
|
|
@ -93,7 +93,7 @@ PLAN *find_create PROTO1(char ***, argvp)
|
|||
*--argv);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
switch(p->flags) {
|
||||
case O_NONE:
|
||||
new = NULL;
|
||||
|
|
@ -120,7 +120,7 @@ static int typecompare PROTO2(const void *, a, const void *, b)
|
|||
OPTION *option PROTO1(char *, name)
|
||||
{
|
||||
OPTION tmp;
|
||||
|
||||
|
||||
tmp.name = name;
|
||||
return((OPTION *)bsearch(&tmp, options, sizeof(options)/sizeof(OPTION),
|
||||
sizeof(OPTION), typecompare));
|
||||
|
|
|
|||
|
|
@ -21,9 +21,9 @@
|
|||
*/
|
||||
|
||||
#include "tweak.h"
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#ifdef HAVE_UNISTD_H
|
||||
|
|
@ -43,11 +43,11 @@
|
|||
# include <time.h>
|
||||
# endif
|
||||
#endif
|
||||
#include "my-string.h"
|
||||
#include "my-string.h"
|
||||
#include "ls.h"
|
||||
|
||||
|
||||
#define BLK(A) (((A)+1023)/1024)
|
||||
|
||||
|
||||
static int printtype PROTO1(mode_t, mode)
|
||||
{
|
||||
switch(mode & S_IFMT) {
|
||||
|
|
@ -65,23 +65,23 @@ static int printtype PROTO1(mode_t, mode)
|
|||
static int printaname PROTO1(LS *, lp)
|
||||
{
|
||||
int chcnt;
|
||||
|
||||
|
||||
chcnt = 0;
|
||||
|
||||
|
||||
if (f_inode) {
|
||||
printf("%5lu ", (unsigned long)lp->lstat.st_ino);
|
||||
chcnt += 6;
|
||||
}
|
||||
|
||||
|
||||
if (f_size) {
|
||||
printf("%4ld ", (long)BLK(lp->lstat.st_size));
|
||||
chcnt += 5;
|
||||
}
|
||||
|
||||
|
||||
printf("%s", lp->name); chcnt += strlen(lp->name);
|
||||
|
||||
|
||||
if (f_type) chcnt += printtype(lp->lstat.st_mode);
|
||||
|
||||
|
||||
return(chcnt);
|
||||
}
|
||||
|
||||
|
|
@ -97,10 +97,10 @@ static void printtime PROTO1(time_t, ftime)
|
|||
{
|
||||
int i;
|
||||
char *longstring;
|
||||
|
||||
|
||||
longstring = (char *)ctime((long *)&ftime);
|
||||
for (i = 4; i < 11; ++i) (void)putchar(longstring[i]);
|
||||
|
||||
|
||||
#define SIXMONTHS ((365 / 2) * 24 * 60 * 60)
|
||||
|
||||
if (ftime + SIXMONTHS > time((time_t *)NULL))
|
||||
|
|
@ -115,13 +115,13 @@ static void printtime PROTO1(time_t, ftime)
|
|||
void printlong PROTO2(LS *, stats, int, num)
|
||||
{
|
||||
const char *modep;
|
||||
|
||||
|
||||
if (f_total) (void)printf("total %lu\n",(unsigned long) stats[0].lstat.st_btotal);
|
||||
for (; num--; ++stats) {
|
||||
if (f_inode) printf("%6lu ", (unsigned long)stats->lstat.st_ino);
|
||||
if (f_size ) printf("%4lu ", (unsigned long)BLK(stats->lstat.st_size));
|
||||
modep = ((S_IFDIR & stats->lstat.st_mode)) ? "drwxrwxrwx" : "-rw-rw-rw-" ;
|
||||
|
||||
|
||||
(void)printf("%s %3u %-*s ", modep, stats->lstat.st_nlink, 8, "nobody");
|
||||
if (f_group) printf("%-*s ", 8, "nobody");
|
||||
else printf("%8lu ", (unsigned long)stats->lstat.st_size);
|
||||
|
|
@ -137,27 +137,27 @@ void printlong PROTO2(LS *, stats, int, num)
|
|||
#define TAB 8
|
||||
|
||||
extern int termwidth;
|
||||
|
||||
|
||||
void printcol PROTO2(LS *, stats, int, num)
|
||||
{
|
||||
register int base, chcnt, cnt, col, colwidth;
|
||||
int endcol, numcols, numrows, row;
|
||||
|
||||
|
||||
colwidth = stats[0].lstat.st_maxlen;
|
||||
if (f_inode) colwidth += 6;
|
||||
if (f_size) colwidth += 5;
|
||||
if (f_type) colwidth += 1;
|
||||
|
||||
|
||||
colwidth = (colwidth + TAB) & ~(TAB - 1);
|
||||
if (termwidth < 2 * colwidth) {
|
||||
printscol(stats, num);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
numcols = termwidth / colwidth;
|
||||
numrows = num / numcols;
|
||||
if (num % numcols) ++numrows;
|
||||
|
||||
|
||||
if (f_size && f_total) printf("total %lu\n", (unsigned long)stats[0].lstat.st_btotal);
|
||||
for (row = 0; row < numrows; ++row) {
|
||||
endcol = colwidth;
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
void prcopy PROTO3(char *, src, char *, dest, int, len)
|
||||
{
|
||||
register int ch;
|
||||
|
||||
|
||||
while(len--) {
|
||||
ch = *src++;
|
||||
*dest++ = isprint(ch) ? ch : '?';
|
||||
|
|
@ -50,7 +50,7 @@ void nomem PROTO0((void))
|
|||
char *emalloc PROTO1(int, size)
|
||||
{
|
||||
char *retval;
|
||||
|
||||
|
||||
if (!(retval = malloc(size))) nomem();
|
||||
return(retval);
|
||||
}
|
||||
|
|
|
|||
114
client/lib.c
114
client/lib.c
|
|
@ -1,4 +1,5 @@
|
|||
/*********************************************************************\
|
||||
* Copyright (c) 2004 by Radim Kolar *
|
||||
* Copyright (c) 1991 by Wen-King Su (wen-king@vlsi.cs.caltech.edu) *
|
||||
* *
|
||||
* You may copy or modify this file in any manner you wish, provided *
|
||||
|
|
@ -26,7 +27,9 @@ static unsigned short key;
|
|||
|
||||
int client_trace = 0;
|
||||
int client_intr_state = 0;
|
||||
unsigned long target_delay = DEFAULT_DELAY; /* expected max delay */
|
||||
unsigned long target_delay = DEFAULT_DELAY; /* expected max delay from server on good connection */
|
||||
|
||||
unsigned long target_maxdelay = DEFAULT_MAXDELAY; /* max resend timer */
|
||||
unsigned long busy_delay = DEFAULT_DELAY; /* busy retransmit timer */
|
||||
unsigned long idle_delay = DEFAULT_DELAY; /* idle retransmit timer */
|
||||
unsigned long udp_sent_time;
|
||||
|
|
@ -41,8 +44,10 @@ UBUF *client_interact PROTO6(unsigned char, cmd, unsigned long, pos,
|
|||
unsigned char *s, *t, *d, seq0, seq1;
|
||||
unsigned u, n, sum, mlen, rlen;
|
||||
fd_set mask;
|
||||
int retval, bytes, retry_send, retry_recv;
|
||||
int retval, retry_send, retry_recv;
|
||||
socklen_t bytes;
|
||||
unsigned long w_delay;
|
||||
unsigned long total_delay;
|
||||
|
||||
FD_ZERO(&mask);
|
||||
sbuf.cmd = cmd;
|
||||
|
|
@ -53,24 +58,27 @@ UBUF *client_interact PROTO6(unsigned char, cmd, unsigned long, pos,
|
|||
|
||||
BB_WRITE2(sbuf.bb_len,l1);
|
||||
BB_WRITE4(sbuf.bb_pos,pos);
|
||||
|
||||
|
||||
client_intr_state = 1;
|
||||
|
||||
total_delay = 0;
|
||||
w_delay = 0;
|
||||
|
||||
for(u = l1, d = (unsigned char *) sbuf.buf; u--; *d++ = *p1++);
|
||||
for(u = l2; u--; *d++ = *p2++);
|
||||
mlen = d - (unsigned char *) &sbuf;
|
||||
|
||||
|
||||
key = client_get_key();
|
||||
|
||||
|
||||
for(retry_send = 0; ; retry_send++) {
|
||||
total_delay += w_delay;
|
||||
BB_WRITE2(sbuf.bb_key,key);
|
||||
sbuf.bb_seq[0] = seq0 = (myseq >> 8) & 0xff;
|
||||
sbuf.bb_seq[1] = seq1 = (myseq & 0xfc) | (retry_send & 0x0003);
|
||||
sbuf.sum = 0;
|
||||
|
||||
|
||||
for(t = (unsigned char *) &sbuf, sum = n = mlen; n--; sum += *t++);
|
||||
sbuf.sum = sum + (sum >> 8);
|
||||
|
||||
|
||||
switch(retry_send) { /* adaptive retry delay adjustments */
|
||||
case 0:
|
||||
busy_delay = (target_delay+(busy_delay<<3)-busy_delay)>>3;
|
||||
|
|
@ -79,58 +87,89 @@ UBUF *client_interact PROTO6(unsigned char, cmd, unsigned long, pos,
|
|||
case 1:
|
||||
busy_delay = busy_delay * 3 / 2;
|
||||
w_delay = busy_delay;
|
||||
if(client_trace) write(2,"R",1);
|
||||
if(client_trace) write(2,"R",1);
|
||||
break;
|
||||
|
||||
|
||||
default:
|
||||
#ifdef CLIENT_TIMEOUT
|
||||
if (!pos && retry_send >= env_timeout ) {
|
||||
if (total_delay/1000 >= env_timeout ) {
|
||||
fprintf(stderr, "\rRemote server not responding.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
if(idle_delay < 3*60*1000) idle_delay = idle_delay * 3 / 2;
|
||||
idle_delay = idle_delay * 3 / 2;
|
||||
if (idle_delay > target_maxdelay) idle_delay = target_maxdelay;
|
||||
w_delay = idle_delay;
|
||||
if(client_trace) write(2,"I",1);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
if(sendto(myfd,(const char*)&sbuf,mlen,0,(struct sockaddr *)&server_addr,
|
||||
sizeof(server_addr)) == -1) {
|
||||
perror("sendto");
|
||||
exit(1);
|
||||
switch(errno) {
|
||||
case ENOBUFS:
|
||||
case EHOSTUNREACH:
|
||||
case ECONNREFUSED:
|
||||
case EHOSTDOWN:
|
||||
case ENETDOWN:
|
||||
case EPIPE:
|
||||
/* try to resend packet */
|
||||
continue;
|
||||
default:
|
||||
perror("sendto");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
udp_sent_time = time((time_t *) 0);
|
||||
FD_SET(myfd,&mask);
|
||||
|
||||
|
||||
for(retry_recv = 0; ; retry_recv++) {
|
||||
if(retry_recv && client_trace) write(2,"E",1);
|
||||
retval = _x_select(&mask, w_delay);
|
||||
if((retval == -1) && (errno == EINTR)) continue;
|
||||
if(retval == 1) { /* an incoming message is waiting */
|
||||
bytes = sizeof(from);
|
||||
if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0,
|
||||
(struct sockaddr *)&from, &bytes)) < UBUF_HSIZE)
|
||||
{
|
||||
/* too enough bytes for header */
|
||||
if (client_trace) write(2,"H",1);
|
||||
continue;
|
||||
|
||||
}
|
||||
|
||||
rlen = BB_READ2(rbuf.bb_len);
|
||||
|
||||
if( (rlen+UBUF_HSIZE) > bytes)
|
||||
{
|
||||
/* truncated. */
|
||||
if (client_trace) write(2,"T",1);
|
||||
continue;
|
||||
}
|
||||
|
||||
s = (unsigned char *) &rbuf;
|
||||
d = s + bytes;
|
||||
u = rbuf.sum; rbuf.sum = 0;
|
||||
for(t = s, sum = 0; t < d; sum += *t++);
|
||||
sum = (sum + (sum >> 8)) & 0xff;
|
||||
if(sum != u) continue; /* wrong check sum */
|
||||
|
||||
rlen = BB_READ2(rbuf.bb_len);
|
||||
|
||||
if(sum != u)
|
||||
{
|
||||
/* wrong check sum */
|
||||
if (client_trace) write(2,"C",1);
|
||||
continue;
|
||||
}
|
||||
|
||||
if( (rbuf.bb_seq[0] ^ seq0) ||
|
||||
((rbuf.bb_seq[1] ^ seq1)&0xfc)) continue; /* wrong seq # */
|
||||
if((int) (rlen+UBUF_HSIZE) > bytes) continue; /* truncated. */
|
||||
|
||||
((rbuf.bb_seq[1] ^ seq1)&0xfc))
|
||||
{
|
||||
/* wrong seq # */
|
||||
if (client_trace) write(2,"S",1);
|
||||
continue;
|
||||
}
|
||||
myseq = (myseq + 0x0004) & 0xfffc; /* seq for next request */
|
||||
key = BB_READ2(rbuf.bb_key); /* key for next request */
|
||||
|
||||
client_set_key(key);
|
||||
|
||||
|
||||
if(rbuf.cmd != CC_BYE)
|
||||
client_set_key(key);
|
||||
|
||||
if(client_intr_state == 2) {
|
||||
if(!key_persists) client_done();
|
||||
exit(1);
|
||||
|
|
@ -139,9 +178,9 @@ UBUF *client_interact PROTO6(unsigned char, cmd, unsigned long, pos,
|
|||
#ifdef DEBUG
|
||||
printf("rbuf.cmd = %u\n",rbuf.cmd);
|
||||
#endif
|
||||
|
||||
|
||||
return(&rbuf);
|
||||
|
||||
|
||||
} else break; /* go back to re-transmit buffer again */
|
||||
}
|
||||
}
|
||||
|
|
@ -154,25 +193,26 @@ static RETSIGTYPE client_intr PROTO1(int, signum)
|
|||
case 1: client_intr_state = 2; break;
|
||||
case 2: exit(3);
|
||||
}
|
||||
#ifndef RELIABLE_SIGNALS
|
||||
#ifndef RELIABLE_SIGNALS
|
||||
signal(SIGINT,client_intr);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
void init_client PROTO3(const char *, host, unsigned short, port, unsigned short, myport)
|
||||
{
|
||||
busy_delay = idle_delay = target_delay;
|
||||
|
||||
myseq = random();
|
||||
|
||||
if((myfd = _x_udp(&myport)) == -1) {
|
||||
perror("socket open");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
if(_x_adr(host,port,&server_addr) == -1) {
|
||||
perror("server addr");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
client_init_key(server_addr.sin_addr.s_addr,port,getpid());
|
||||
signal(SIGINT,client_intr);
|
||||
}
|
||||
|
|
@ -181,6 +221,6 @@ int client_done PROTO0((void))
|
|||
{
|
||||
(void) client_interact(CC_BYE, 0L, 0, (unsigned char *)NULLP, 0,
|
||||
(unsigned char *)NULLP);
|
||||
client_destroy_key();
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,21 +17,21 @@
|
|||
|
||||
#ifndef NOLOCKING
|
||||
static char key_string[sizeof(KEY_PREFIX)+32];
|
||||
|
||||
|
||||
static char code_str[] =
|
||||
"0123456789:_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
"0123456789:_ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
|
||||
static void make_key_string PROTO2(unsigned long, server_addr,
|
||||
unsigned long, server_port)
|
||||
{
|
||||
unsigned long v1, v2;
|
||||
char *p;
|
||||
|
||||
|
||||
strcpy(key_string,KEY_PREFIX);
|
||||
for(p = key_string; *p; p++);
|
||||
v1 = server_addr;
|
||||
v2 = server_port;
|
||||
|
||||
|
||||
*p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
||||
*p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
||||
*p++ = code_str[v1 & 0x3f]; v1 >>= 6;
|
||||
|
|
@ -94,14 +94,19 @@ void client_init_key PROTO3(unsigned long, server_addr,
|
|||
{
|
||||
unsigned long omask;
|
||||
okey = key;
|
||||
|
||||
|
||||
make_key_string(server_addr,server_port);
|
||||
|
||||
|
||||
omask = umask(0);
|
||||
lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
|
||||
umask(omask);
|
||||
}
|
||||
|
||||
void client_destroy_key(void)
|
||||
{
|
||||
(void)close(lock_fd);
|
||||
unlink(key_string);
|
||||
}
|
||||
#endif
|
||||
/********************************************************************/
|
||||
/******* For those systems that has lockf function call *************/
|
||||
|
|
@ -155,14 +160,19 @@ void client_init_key PROTO3(unsigned long, server_addr,
|
|||
{
|
||||
unsigned long omask;
|
||||
okey = key;
|
||||
|
||||
|
||||
make_key_string(server_addr,server_port);
|
||||
|
||||
|
||||
omask = umask(0);
|
||||
lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
|
||||
umask(omask);
|
||||
}
|
||||
|
||||
void client_destroy_key(void)
|
||||
{
|
||||
(void)close(lock_fd);
|
||||
unlink(key_string);
|
||||
}
|
||||
#endif
|
||||
/********************************************************************/
|
||||
/******* For those systems that has SysV shared memory + lockf ******/
|
||||
|
|
@ -178,6 +188,7 @@ void client_init_key PROTO3(unsigned long, server_addr,
|
|||
int key_persists = 0;
|
||||
static unsigned short *share_key;
|
||||
static unsigned int lock_fd;
|
||||
static int lock_shm;
|
||||
|
||||
unsigned short client_get_key PROTO0((void))
|
||||
{
|
||||
|
|
@ -203,14 +214,13 @@ void client_init_key PROTO3(unsigned long, server_addr,
|
|||
{
|
||||
unsigned long omask;
|
||||
key_t lock_key;
|
||||
int lock_shm;
|
||||
|
||||
|
||||
make_key_string(server_addr,server_port);
|
||||
|
||||
|
||||
omask = umask(0);
|
||||
lock_fd = open(key_string,O_RDWR|O_CREAT,0666);
|
||||
umask(omask);
|
||||
|
||||
|
||||
if((lock_key = ftok(key_string,238)) == -1) {
|
||||
perror("ftok");
|
||||
exit(1);
|
||||
|
|
@ -226,6 +236,21 @@ void client_init_key PROTO3(unsigned long, server_addr,
|
|||
*share_key = key;
|
||||
}
|
||||
|
||||
void client_destroy_key(void)
|
||||
{
|
||||
(void)close(lock_fd);
|
||||
if (shmdt((char *)share_key) < 0)
|
||||
{
|
||||
perror("shmdt");
|
||||
exit(1);
|
||||
}
|
||||
if (shmctl(lock_shm,IPC_RMID,NULL) < 0)
|
||||
{
|
||||
perror("shmctl");
|
||||
exit(1);
|
||||
}
|
||||
unlink(key_string);
|
||||
}
|
||||
#endif
|
||||
/********************************************************************/
|
||||
/******* For those who does not want to use locking *****************/
|
||||
|
|
@ -252,4 +277,11 @@ void client_init_key PROTO3(unsigned long, server_addr,
|
|||
okey = key;
|
||||
}
|
||||
|
||||
void client_destroy_key(void)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
/********************************************************************/
|
||||
|
|
|
|||
222
client/util.c
222
client/util.c
|
|
@ -22,7 +22,7 @@ const char *env_myport;
|
|||
const char *env_host;
|
||||
const char *env_port;
|
||||
const char *env_local_dir;
|
||||
int env_timeout;
|
||||
unsigned int env_timeout;
|
||||
unsigned short client_buf_len;
|
||||
unsigned short client_net_len;
|
||||
|
||||
|
|
@ -33,10 +33,10 @@ unsigned short client_net_len;
|
|||
char *util_abs_path PROTO1(const char *, s2)
|
||||
{
|
||||
char *path, *s, *d, *t;
|
||||
|
||||
|
||||
if(!env_dir) env_dir = "";
|
||||
if(!s2) s2 = "";
|
||||
|
||||
|
||||
if(*s2 == '/') {
|
||||
path = malloc(strlen(s2)+2+strlen(env_passwd)+1);
|
||||
sprintf(path,"/%s",s2);
|
||||
|
|
@ -44,7 +44,7 @@ char *util_abs_path PROTO1(const char *, s2)
|
|||
path = malloc(strlen(env_dir)+strlen(s2)+3+strlen(env_passwd)+1);
|
||||
sprintf(path,"/%s/%s",env_dir,s2);
|
||||
}
|
||||
|
||||
|
||||
for(t = path; *t; ) {
|
||||
if(t[0] == '/') {
|
||||
while(t[1] == '/') for(d = t, (s = t+1); (*d++ = *s++); );
|
||||
|
|
@ -82,7 +82,7 @@ char *util_abs_path PROTO1(const char *, s2)
|
|||
}
|
||||
if(t[-1] == '/' && (t[1] == '/' || t[1] == 0)) {
|
||||
s = t + 1; /* point to either slash or nul */
|
||||
for(d = t-1; (*d++ = *s++); );
|
||||
for(d = t-1; (*d++ = *s++); );
|
||||
t--;
|
||||
continue;
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ static int util_split_path PROTO4(char *, path, char **, p1, char **, p2,
|
|||
{
|
||||
char *s;
|
||||
static char junk;
|
||||
|
||||
|
||||
*p1 = "/";
|
||||
if(*path == '/') {
|
||||
*p2 = path;
|
||||
|
|
@ -106,7 +106,7 @@ static int util_split_path PROTO4(char *, path, char **, p1, char **, p2,
|
|||
*p2 = &junk;
|
||||
*p3 = path;
|
||||
}
|
||||
|
||||
|
||||
for(s = *p3; *s; s++) {
|
||||
if(*s == '/') {
|
||||
*p1 = path;
|
||||
|
|
@ -114,7 +114,7 @@ static int util_split_path PROTO4(char *, path, char **, p1, char **, p2,
|
|||
*p3 = s+1;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (**p3 == '\0') *p3 = ".";
|
||||
return(1);
|
||||
}
|
||||
|
|
@ -133,17 +133,17 @@ static RDIRENT **get_dir_blk PROTO1(char *, path)
|
|||
unsigned long pos;
|
||||
int cnt, k, len, rem, acc, at_eof, rlen;
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
fpath = util_abs_path(path);
|
||||
|
||||
for(pos = 0, at_eof = acc = cnt = 0; ; )
|
||||
|
||||
for(pos = 0, at_eof = acc = cnt = 0; ; )
|
||||
{
|
||||
while((acc < UBUF_SPACE) && !at_eof)
|
||||
while((acc < UBUF_SPACE) && !at_eof)
|
||||
{
|
||||
ub = client_interact(CC_GET_DIR,pos, strlen(fpath),
|
||||
(unsigned char *)fpath+1, 2,
|
||||
(unsigned char *)&client_net_len);
|
||||
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr,"%s: %s\n",path, ub->buf);
|
||||
free(fpath);
|
||||
|
|
@ -157,10 +157,10 @@ static RDIRENT **get_dir_blk PROTO1(char *, path)
|
|||
acc += rlen;
|
||||
pos += rlen;
|
||||
}
|
||||
|
||||
|
||||
if(acc >= UBUF_SPACE) len = UBUF_SPACE;
|
||||
else len = acc;
|
||||
|
||||
|
||||
for(p2 = buf, rem = len, k = 0; ; k++) {
|
||||
if(rem < RDHSIZE) break;
|
||||
if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
|
||||
|
|
@ -172,17 +172,17 @@ static RDIRENT **get_dir_blk PROTO1(char *, path)
|
|||
rem--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
p1 = malloc(p2-buf);
|
||||
if(cnt) dp = (RDIRENT **) realloc(dp,(cnt+k+1)*sizeof(RDIRENT *));
|
||||
else dp = (RDIRENT **) malloc((cnt+k+1)*sizeof(RDIRENT *));
|
||||
|
||||
|
||||
if(!p1 || !dp) {
|
||||
fputs("directory reading out of memory\n",stderr);
|
||||
free(fpath);
|
||||
return((RDIRENT **) 0);
|
||||
}
|
||||
|
||||
|
||||
for(p2 = buf, rem = len; ; cnt++) {
|
||||
if(rem < RDHSIZE) break;
|
||||
if(((RDIRENT *) p2)->type == RDTYPE_SKIP) break;
|
||||
|
|
@ -192,7 +192,7 @@ static RDIRENT **get_dir_blk PROTO1(char *, path)
|
|||
return(dp);
|
||||
}
|
||||
dp[cnt] = (RDIRENT *) p1;
|
||||
|
||||
|
||||
for(k = RDHSIZE, rem -= (RDHSIZE+1); k--; *p1++ = *p2++);
|
||||
while( (*p1++ = *p2++) ) rem--;
|
||||
while((p2 - buf) & 3) {
|
||||
|
|
@ -201,7 +201,7 @@ static RDIRENT **get_dir_blk PROTO1(char *, path)
|
|||
rem--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(acc < UBUF_SPACE) {
|
||||
dp[cnt] = 0;
|
||||
free(fpath);
|
||||
|
|
@ -215,28 +215,28 @@ static RDIRENT **get_dir_blk PROTO1(char *, path)
|
|||
|
||||
static int util_download_main PROTO5(char *, path, char *, fpath, FILE *, fp,
|
||||
unsigned long, start_from, int, cmd)
|
||||
{
|
||||
{
|
||||
unsigned long pos, started_from = start_from, downloaded;
|
||||
unsigned tmax, wrote, sent_time, rlen;
|
||||
UBUF *ub;
|
||||
time_t t = time(NULL);
|
||||
|
||||
for(tmax = 1, pos = start_from, sent_time = 0; ;) {
|
||||
|
||||
for(tmax = 1, pos = start_from, sent_time = 0; ;) {
|
||||
ub = client_interact(cmd,pos,strlen(fpath),(unsigned char *)fpath+1, 2,
|
||||
(unsigned char *)&client_net_len);
|
||||
|
||||
|
||||
if(client_trace && (udp_sent_time != sent_time)) {
|
||||
sent_time = udp_sent_time;
|
||||
if(client_buf_len == UBUF_SPACE) fprintf(stderr,"\r%luk ",1+(pos>>10));
|
||||
else fprintf(stderr,"\r%lu ", pos);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr,"downloading %s: %s\n",path,ub->buf);
|
||||
return(-1);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
rlen = BB_READ2(ub->bb_len);
|
||||
wrote = fwrite(ub->buf,1,rlen,fp);
|
||||
/* check for long integer pos overflow */
|
||||
|
|
@ -244,34 +244,34 @@ static int util_download_main PROTO5(char *, path, char *, fpath, FILE *, fp,
|
|||
if(pos+bytes>FOURGIGS)
|
||||
break;
|
||||
#else
|
||||
if(pos+wrote<pos)
|
||||
if(pos+wrote<pos)
|
||||
break;
|
||||
#endif
|
||||
pos += wrote;
|
||||
|
||||
if(rlen == 0)
|
||||
|
||||
if(rlen == 0)
|
||||
break; /* end of file */
|
||||
if(rlen != wrote)
|
||||
if(rlen != wrote)
|
||||
return -1; /* write to local file failed */
|
||||
}
|
||||
|
||||
|
||||
t = time(NULL) - t;
|
||||
if (t == 0) t = 1;
|
||||
downloaded = pos - started_from;
|
||||
if(client_trace)
|
||||
if(client_trace)
|
||||
{
|
||||
fprintf(stderr,"\r%luk : %s [%ldb/s] \n", 1+(pos>>10), path, downloaded/t);
|
||||
fprintf(stderr,"\r%luk : %s [%ldB/s] \n", 1+(pos>>10), path, downloaded/t);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int util_download PROTO3(char *, path, FILE *, fp, unsigned long, start_from)
|
||||
{
|
||||
{
|
||||
int code, len;
|
||||
char *fpath;
|
||||
|
||||
|
||||
fpath = util_abs_path(path);
|
||||
if(*env_passwd) {
|
||||
strcat(fpath, "\n");
|
||||
|
|
@ -284,11 +284,11 @@ int util_download PROTO3(char *, path, FILE *, fp, unsigned long, start_from)
|
|||
}
|
||||
|
||||
int util_grab_file PROTO3(char *, path, FILE *, fp, unsigned long, start_from)
|
||||
{
|
||||
{
|
||||
int code, len;
|
||||
char *fpath;
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
fpath = util_abs_path(path);
|
||||
if(*env_passwd) {
|
||||
strcat(fpath, "\n");
|
||||
|
|
@ -300,20 +300,20 @@ int util_grab_file PROTO3(char *, path, FILE *, fp, unsigned long, start_from)
|
|||
free(fpath);
|
||||
return(code);
|
||||
}
|
||||
|
||||
|
||||
ub = client_interact(CC_GRAB_DONE, 0L, len, (unsigned char *)fpath+1, 0,
|
||||
(unsigned char *)NULLP);
|
||||
|
||||
(unsigned char *)NULLP);
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr,"Warning, unexpected grab error: %s\n",ub->buf);
|
||||
}
|
||||
|
||||
|
||||
free(fpath);
|
||||
return(code);
|
||||
}
|
||||
|
||||
int util_upload PROTO3(char *, path, FILE *, fp, time_t , stamp)
|
||||
{
|
||||
{
|
||||
unsigned long pos;
|
||||
unsigned bytes, first, tmax, sent_time;
|
||||
char *fpath, buf[UBUF_SPACE];
|
||||
|
|
@ -322,21 +322,21 @@ int util_upload PROTO3(char *, path, FILE *, fp, time_t , stamp)
|
|||
char *dpath,*p1,*p2;
|
||||
unsigned char flags;
|
||||
struct stat sb;
|
||||
|
||||
|
||||
fpath = util_abs_path(path);
|
||||
util_split_path(fpath,&dpath,&p1,&p2);
|
||||
*p1='\0';
|
||||
|
||||
|
||||
/* check if we have enough rights to create file */
|
||||
ub = client_interact(CC_GET_PRO,0, strlen(dpath), (unsigned char *)dpath+1, 0,
|
||||
(unsigned char *)NULLP);
|
||||
free(fpath);
|
||||
fpath = util_abs_path(path);
|
||||
if(ub->cmd == CC_ERR)
|
||||
{
|
||||
if(ub->cmd == CC_ERR)
|
||||
{
|
||||
fprintf(stderr,"uploading %s: %s\n",path,ub->buf);
|
||||
free(fpath);
|
||||
return(1);
|
||||
return(1);
|
||||
}
|
||||
/* extract flags from server reply */
|
||||
bytes = BB_READ2(ub->bb_len);
|
||||
|
|
@ -346,13 +346,13 @@ int util_upload PROTO3(char *, path, FILE *, fp, time_t , stamp)
|
|||
/* flags are in the reply */
|
||||
flags = *(ub->buf+bytes);
|
||||
/* check for required flags */
|
||||
if(! (flags & DIR_OWNER))
|
||||
if(! (flags & DIR_OWNER))
|
||||
{
|
||||
if( ! (flags & DIR_ADD))
|
||||
{
|
||||
fprintf(stderr,"No permission for adding files.\n");
|
||||
free(fpath);
|
||||
return(1);
|
||||
return(1);
|
||||
}
|
||||
} else
|
||||
{
|
||||
|
|
@ -366,18 +366,18 @@ int util_upload PROTO3(char *, path, FILE *, fp, time_t , stamp)
|
|||
{
|
||||
fprintf(stderr,"No permission for overwriting: %s\n",fpath);
|
||||
free(fpath);
|
||||
return(1);
|
||||
return(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for(tmax = 1, sent_time = 0, pos = 0, first = 1; ; first = 0)
|
||||
{
|
||||
if((bytes = fread(buf,1,client_buf_len,fp)) || first)
|
||||
|
||||
for(tmax = 1, sent_time = 0, pos = 0, first = 1; ; first = 0)
|
||||
{
|
||||
if((bytes = fread(buf,1,client_buf_len,fp)) || first)
|
||||
{
|
||||
ub = client_interact(CC_UP_LOAD,pos, bytes, (unsigned char *)buf, 0,
|
||||
(unsigned char *)NULLP);
|
||||
if(client_trace && (udp_sent_time != sent_time))
|
||||
if(client_trace && (udp_sent_time != sent_time))
|
||||
{
|
||||
sent_time = udp_sent_time;
|
||||
if(client_buf_len == UBUF_SPACE)
|
||||
|
|
@ -389,16 +389,16 @@ int util_upload PROTO3(char *, path, FILE *, fp, time_t , stamp)
|
|||
else
|
||||
{
|
||||
BB_WRITE4(buf,stamp);
|
||||
ub = client_interact(CC_INSTALL,pos,strlen(fpath),
|
||||
ub = client_interact(CC_INSTALL,pos,strlen(fpath),
|
||||
(unsigned char *)fpath+1, stamp==0?0:4,
|
||||
(unsigned char *)buf);
|
||||
}
|
||||
if(ub->cmd == CC_ERR) {
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr,"uploading %s: %s\n",path,ub->buf);
|
||||
free(fpath);
|
||||
return(1);
|
||||
}
|
||||
|
||||
return(1);
|
||||
}
|
||||
|
||||
if(!bytes && !first) break;
|
||||
#if SIZEOF_LONG > 4
|
||||
if(pos+bytes>FOURGIGS)
|
||||
|
|
@ -409,12 +409,12 @@ int util_upload PROTO3(char *, path, FILE *, fp, time_t , stamp)
|
|||
#endif
|
||||
pos += bytes;
|
||||
}
|
||||
|
||||
|
||||
t = time(NULL) - t;
|
||||
if(t == 0) t = 1;
|
||||
if(client_trace)
|
||||
if(client_trace)
|
||||
{
|
||||
fprintf(stderr,"\r%luk : %s [%ldb/s] \n", 1+(pos>>10), path, pos/t);
|
||||
fprintf(stderr,"\r%luk : %s [%ldB/s] \n", 1+(pos>>10), path, pos/t);
|
||||
fflush(stderr);
|
||||
}
|
||||
free(fpath);
|
||||
|
|
@ -424,7 +424,7 @@ int util_upload PROTO3(char *, path, FILE *, fp, time_t , stamp)
|
|||
static void util_get_env PROTO0((void))
|
||||
{
|
||||
char *p;
|
||||
|
||||
|
||||
if(!(env_host = getenv("FSP_HOST"))) {
|
||||
fputs("No FSP_HOST specified.\n",stderr);
|
||||
exit(1);
|
||||
|
|
@ -442,17 +442,21 @@ static void util_get_env PROTO0((void))
|
|||
client_trace = !!getenv("FSP_TRACE");
|
||||
if( (p = getenv("FSP_BUF_SIZE")) ) client_buf_len = atoi(p);
|
||||
else client_buf_len = UBUF_SPACE;
|
||||
|
||||
if(client_buf_len > UBUF_SPACE) client_buf_len = UBUF_SPACE;
|
||||
|
||||
if(client_buf_len > UBUF_SPACE) client_buf_len = UBUF_SPACE;
|
||||
client_net_len = htons(client_buf_len);
|
||||
|
||||
|
||||
if( (p = getenv("FSP_DELAY")) ) target_delay = atol(p);
|
||||
if(target_delay < MIN_DELAY) target_delay = MIN_DELAY;
|
||||
if(target_delay > MAX_DELAY) target_delay = MAX_DELAY;
|
||||
|
||||
if( (p = getenv("FSP_MAXDELAY")) ) target_maxdelay = atol(p);
|
||||
if(target_maxdelay < target_delay) target_maxdelay = target_delay;
|
||||
if(target_maxdelay > MAX_DELAY) target_maxdelay = MAX_DELAY;
|
||||
|
||||
if(!(env_local_dir = getenv("FSP_LOCAL_DIR"))) env_local_dir=".";
|
||||
|
||||
if(!(p = getenv("FSP_TIMEOUT"))) env_timeout = 180;
|
||||
|
||||
if(!(p = getenv("FSP_TIMEOUT"))) env_timeout = DEFAULT_TIMEOUT;
|
||||
else env_timeout = atol(p);
|
||||
}
|
||||
|
||||
|
|
@ -471,12 +475,12 @@ RDIR *util_opendir PROTO1(char *, path)
|
|||
RDIRENT **dep;
|
||||
DDLIST *ddp;
|
||||
RDIR *rdirp;
|
||||
|
||||
|
||||
fpath = util_abs_path(path);
|
||||
|
||||
|
||||
for(ddp = ddroot; ddp; ddp = ddp->next)
|
||||
if(!strcmp(ddp->path,fpath)) break;
|
||||
|
||||
|
||||
if(!ddp) {
|
||||
if(!(dep = get_dir_blk(fpath)))
|
||||
{
|
||||
|
|
@ -490,9 +494,9 @@ RDIR *util_opendir PROTO1(char *, path)
|
|||
ddp->next = ddroot;
|
||||
ddroot = ddp;
|
||||
} else free(fpath);
|
||||
|
||||
|
||||
ddp->ref_cnt++;
|
||||
|
||||
|
||||
rdirp = (RDIR *) malloc(sizeof(RDIR));
|
||||
rdirp->ddp = ddp;
|
||||
rdirp->dep = ddp->dep_root;
|
||||
|
|
@ -509,17 +513,17 @@ rdirent *util_readdir PROTO1(RDIR *, rdirp)
|
|||
{
|
||||
static rdirent rde;
|
||||
RDIRENT **dep;
|
||||
|
||||
|
||||
dep = rdirp->dep;
|
||||
|
||||
|
||||
if(!*dep) return((rdirent *) 0);
|
||||
|
||||
|
||||
rde.d_fileno = 10;
|
||||
rde.d_rcdlen = 10;
|
||||
rde.d_namlen = strlen((*dep)->name);
|
||||
rde.d_name = (*dep)->name;
|
||||
rdirp->dep = dep+1;
|
||||
|
||||
|
||||
return(&rde);
|
||||
}
|
||||
|
||||
|
|
@ -533,10 +537,10 @@ int util_stat PROTO2(char *, path, struct stat *, sbuf)
|
|||
UBUF *ub;
|
||||
char *fpath,*fpath2, *ppath, *p1, *pfile;
|
||||
int cached=0;
|
||||
|
||||
|
||||
fpath = util_abs_path(path);
|
||||
fpath2 = strdup(fpath);
|
||||
|
||||
|
||||
if(!strcmp(fpath,env_dir)) {
|
||||
ppath = fpath;
|
||||
pfile = ".";
|
||||
|
|
@ -564,19 +568,19 @@ int util_stat PROTO2(char *, path, struct stat *, sbuf)
|
|||
/* send a new FSP_STAT command to server */
|
||||
ub = client_interact(CC_STAT,0L, strlen(fpath2),
|
||||
(unsigned char *) fpath2+1, 0, 0);
|
||||
if(ub->cmd == CC_STAT)
|
||||
if(ub->cmd == CC_STAT)
|
||||
{
|
||||
sbuf->st_uid = 0;
|
||||
sbuf->st_gid = 0;
|
||||
sbuf->st_atime = sbuf->st_mtime =
|
||||
sbuf->st_atime = sbuf->st_mtime =
|
||||
sbuf->st_ctime = BB_READ4((ub->buf));
|
||||
sbuf->st_size = BB_READ4((ub->buf+4));
|
||||
if((ub->buf[8]) == RDTYPE_DIR)
|
||||
if((ub->buf[8]) == RDTYPE_DIR)
|
||||
{
|
||||
sbuf->st_mode = 0777 | S_IFDIR;
|
||||
sbuf->st_nlink = 2;
|
||||
}
|
||||
else
|
||||
else
|
||||
{
|
||||
sbuf->st_mode = 0666 | S_IFREG;
|
||||
sbuf->st_nlink = 1;
|
||||
|
|
@ -584,11 +588,11 @@ int util_stat PROTO2(char *, path, struct stat *, sbuf)
|
|||
|
||||
free(fpath);
|
||||
free(fpath2);
|
||||
|
||||
if(ub->buf[8]==0)
|
||||
|
||||
if(ub->buf[8]==0)
|
||||
{
|
||||
errno = ENOENT;
|
||||
return -1;
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -597,27 +601,27 @@ int util_stat PROTO2(char *, path, struct stat *, sbuf)
|
|||
statworks=0;
|
||||
}
|
||||
} /* CC_STAT */
|
||||
|
||||
if( (drp = util_opendir(ppath)) )
|
||||
|
||||
if( (drp = util_opendir(ppath)) )
|
||||
{
|
||||
for(dep = drp->dep; *dep; dep++)
|
||||
for(dep = drp->dep; *dep; dep++)
|
||||
{
|
||||
if(!strcmp((*dep)->name,pfile))
|
||||
if(!strcmp((*dep)->name,pfile))
|
||||
{
|
||||
if((*dep)->type == RDTYPE_DIR)
|
||||
if((*dep)->type == RDTYPE_DIR)
|
||||
sbuf->st_mode = 0777 | S_IFDIR;
|
||||
else
|
||||
else
|
||||
sbuf->st_mode = 0666 | S_IFREG;
|
||||
|
||||
if((*dep)->type == RDTYPE_DIR)
|
||||
|
||||
if((*dep)->type == RDTYPE_DIR)
|
||||
sbuf->st_nlink = 2;
|
||||
else
|
||||
else
|
||||
sbuf->st_nlink = 1;
|
||||
|
||||
sbuf->st_uid = 0;
|
||||
sbuf->st_gid = 0;
|
||||
sbuf->st_size = BB_READ4((*dep)->bb_size);
|
||||
sbuf->st_atime = sbuf->st_mtime =
|
||||
sbuf->st_atime = sbuf->st_mtime =
|
||||
sbuf->st_ctime = BB_READ4((*dep)->bb_time);
|
||||
util_closedir(drp);
|
||||
free(fpath);
|
||||
|
|
@ -627,7 +631,7 @@ int util_stat PROTO2(char *, path, struct stat *, sbuf)
|
|||
}
|
||||
util_closedir(drp);
|
||||
}
|
||||
|
||||
|
||||
free(fpath);
|
||||
free(fpath2);
|
||||
errno = ENOENT;
|
||||
|
|
@ -639,11 +643,11 @@ int util_cd PROTO1(char *, p)
|
|||
char *fpath;
|
||||
UBUF *ub;
|
||||
DDLIST *ddp;
|
||||
|
||||
|
||||
fpath = util_abs_path(p);
|
||||
for(ddp = ddroot; ddp; ddp = ddp->next)
|
||||
if(!strcmp(ddp->path,fpath)) break;
|
||||
|
||||
|
||||
if(!ddp && strcmp(p,".") && strcmp(p,"..")) {
|
||||
ub = client_interact(CC_GET_DIR,0L, strlen(fpath),
|
||||
(unsigned char *) fpath+1, 2,
|
||||
|
|
@ -655,7 +659,7 @@ int util_cd PROTO1(char *, p)
|
|||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(env_dir_malloced) free(env_dir);
|
||||
env_dir_malloced = 1;
|
||||
env_dir = fpath;
|
||||
|
|
@ -668,9 +672,9 @@ int util_cd PROTO1(char *, p)
|
|||
int util_cd2 PROTO1(char *, p)
|
||||
{
|
||||
char *fpath;
|
||||
|
||||
|
||||
fpath = util_abs_path(p);
|
||||
|
||||
|
||||
if(env_dir_malloced) free(env_dir);
|
||||
env_dir_malloced = 1;
|
||||
env_dir = fpath;
|
||||
|
|
@ -678,9 +682,9 @@ int util_cd2 PROTO1(char *, p)
|
|||
}
|
||||
|
||||
#ifdef PROTOTYPES
|
||||
void util_process_file(char *path, int mode,
|
||||
void util_process_file(char *path, int mode,
|
||||
void (*process_file)(char *,struct stat *, int, int),
|
||||
int (*process_start_dir)(char *,struct stat *,u_long *),
|
||||
int (*process_start_dir)(char *,struct stat *,u_long *),
|
||||
void (*process_end_dir)(char *,int,u_long,int),
|
||||
int level)
|
||||
#else
|
||||
|
|
@ -703,7 +707,7 @@ void util_process_file(path, mode, process_file, process_start_dir,
|
|||
perror(path);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if (S_ISREG(sbuf.st_mode)) {
|
||||
if(process_file) (*process_file)(path, &sbuf, mode, level);
|
||||
} else if (S_ISDIR(sbuf.st_mode)) {
|
||||
|
|
|
|||
|
|
@ -23,15 +23,15 @@ static RETSIGTYPE dont_die PROTO1(int, signum)
|
|||
{
|
||||
#ifndef RELIABLE_SIGNALS
|
||||
signal(SIGPIPE,dont_die);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
int main PROTO2(int, argc, char **, argv)
|
||||
{
|
||||
char **av;
|
||||
|
||||
env_client();
|
||||
|
||||
|
||||
signal(SIGPIPE,dont_die);
|
||||
if(isatty(1)) client_trace = 0;
|
||||
|
||||
|
|
@ -44,8 +44,8 @@ int main PROTO2(int, argc, char **, argv)
|
|||
*av++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,10 +23,10 @@
|
|||
static int f_cd PROTO1(const char *, p)
|
||||
{
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
ub = client_interact(CC_GET_PRO,0L, strlen(p), (unsigned const char *)p+1, 0,
|
||||
(unsigned char *)NULLP);
|
||||
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr, "ERR: %s\n",ub->buf);
|
||||
return(0);
|
||||
|
|
@ -41,7 +41,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
{
|
||||
char *np;
|
||||
char **av, *av2[2];
|
||||
|
||||
|
||||
env_client();
|
||||
if(argc == 1) {
|
||||
f_cd("/");
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ static void add_file_size PROTO4(char *, name, struct stat *, sbufp,
|
|||
int, mode, int, level)
|
||||
{
|
||||
register u_long file_size;
|
||||
|
||||
|
||||
file_size = (sbufp->st_size + 1023) / 1024;
|
||||
total_file_size += file_size;
|
||||
if(((mode & EACH) && (mode & RECURSIVE)) ||
|
||||
|
|
@ -70,9 +70,9 @@ int main PROTO2(int, argc, char **, argv)
|
|||
static const char *wild[2] = { ".", 0 };
|
||||
char **files, *singlefile[2];
|
||||
int optletter;
|
||||
|
||||
|
||||
env_client();
|
||||
|
||||
|
||||
while ((optletter=getopt(argc, argv,"ras")) != EOF)
|
||||
switch (optletter) {
|
||||
case 'r':
|
||||
|
|
@ -88,31 +88,31 @@ int main PROTO2(int, argc, char **, argv)
|
|||
fprintf(stderr,"Usage: du [-r|a|s] directory name.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
/* special case `du' without file arguments -- becomes `du .' */
|
||||
if (argc == optind) {
|
||||
argv=wild;
|
||||
optind=0;
|
||||
}
|
||||
|
||||
|
||||
for ( ; argv[optind]; optind++) {
|
||||
if (!(files = glob(argv[optind]))) {
|
||||
files = singlefile;
|
||||
singlefile[0] = argv[optind];
|
||||
singlefile[1] = 0;
|
||||
}
|
||||
|
||||
|
||||
for ( ; *files; files++) {
|
||||
util_process_file(*files, mode, add_file_size, start_dir, end_dir, 0);
|
||||
filcnt++;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (filcnt > 1) {
|
||||
fprintf(stdout, "--------:------\n");
|
||||
fprintf(stdout, "%-7ld TOTAL\n", total_file_size);
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -69,14 +69,14 @@ static void eval_file PROTO4(char *, name, struct stat *, sbufp,
|
|||
int, mode, int, level)
|
||||
{
|
||||
register PLAN *p;
|
||||
|
||||
|
||||
for (p = plan; p && (p->eval)(p, sbufp, name); p = p->next);
|
||||
}
|
||||
|
||||
static int eval_dir PROTO3(char *, name, struct stat *, sbufp, u_long *, sum)
|
||||
{
|
||||
register PLAN *p;
|
||||
|
||||
|
||||
process = 0;
|
||||
for (p = plan; p && (p->eval)(p, sbufp, name); p = p->next);
|
||||
return (process);
|
||||
|
|
@ -86,18 +86,18 @@ int main PROTO2(int, argc, char **, argv)
|
|||
{
|
||||
register char **p;
|
||||
char *singlefile[2], **files;
|
||||
|
||||
|
||||
env_client();
|
||||
(void)time(&now); /* initialize the time-of-day */
|
||||
|
||||
|
||||
p = ++argv;
|
||||
|
||||
|
||||
/* First option delimits the file list. */
|
||||
while (*p && !option(*p)) p++;
|
||||
if (p == argv) usage_ffind();
|
||||
|
||||
|
||||
find_formplan(p);
|
||||
|
||||
|
||||
/* Execute plan for all file lists */
|
||||
while (*argv) {
|
||||
if (argv >= p) break;
|
||||
|
|
@ -108,10 +108,10 @@ int main PROTO2(int, argc, char **, argv)
|
|||
}
|
||||
for ( ; *files; files++)
|
||||
util_process_file(*files, 0, eval_file, eval_dir, 0L, 0);
|
||||
|
||||
|
||||
argv++;
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
return(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,11 +27,11 @@
|
|||
|
||||
#if !defined(COMMAND_GRAB) && !defined(COMMAND_GET)
|
||||
#error "#define COMMAND_XXX to GET or GRAB when compiling this file"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(COMMAND_GRAB) && defined(COMMAND_GET)
|
||||
#error "You must define COMMAND_GRAB -OR- COMMAND_GET"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int clobbertype=C_UNIQUE;
|
||||
static int preserve=0;
|
||||
|
|
@ -50,9 +50,9 @@ static RETSIGTYPE fsp_cleanup PROTO1(int, signum)
|
|||
exit(1);
|
||||
}
|
||||
|
||||
static void
|
||||
static void
|
||||
#ifdef COMMAND_GET
|
||||
get_file
|
||||
get_file
|
||||
#else
|
||||
grab_file
|
||||
#endif
|
||||
|
|
@ -64,15 +64,15 @@ PROTO4(char *, path, struct stat *, sbufp, int, mode, int, level)
|
|||
#ifdef HAVE_UTIME_H
|
||||
struct utimbuf tb;
|
||||
#endif
|
||||
|
||||
start_from = 0;
|
||||
/* printf("Get function called!\n");
|
||||
|
||||
start_from = 0;
|
||||
/* printf("Get function called!\n");
|
||||
if(sbufp)
|
||||
{
|
||||
printf("We have stat *!\n");
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
if (clobbertype==C_NOCLOBBER) {
|
||||
if ( (fp=fopen(name,"r"))) {
|
||||
fclose(fp);
|
||||
|
|
@ -80,7 +80,7 @@ PROTO4(char *, path, struct stat *, sbufp, int, mode, int, level)
|
|||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (clobbertype==C_UNIQUE) {
|
||||
fname=name;
|
||||
name=(char *)malloc(strlen(fname)+5);
|
||||
|
|
@ -90,13 +90,13 @@ PROTO4(char *, path, struct stat *, sbufp, int, mode, int, level)
|
|||
sprintf(name,"%s-%d",fname,suffix);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (clobbertype==C_TEMPNAME) {
|
||||
fname=name;
|
||||
name=(char*)malloc(20);
|
||||
sprintf(name,".fsp.%d",getpid());
|
||||
}
|
||||
|
||||
|
||||
if(clobbertype == C_APPEND) {
|
||||
if(stat(name, &statbuf) == 0) {
|
||||
start_from = statbuf.st_size;
|
||||
|
|
@ -105,14 +105,14 @@ PROTO4(char *, path, struct stat *, sbufp, int, mode, int, level)
|
|||
start_from = 0;}
|
||||
} else start_from = 0;
|
||||
} else start_from = 0;
|
||||
|
||||
|
||||
if(start_from == 0) {
|
||||
fp = fopen(name, "w");
|
||||
if (fp == NULL )
|
||||
fprintf(stderr,"Cannot create %s\n",name);
|
||||
}
|
||||
|
||||
if(fp)
|
||||
|
||||
if(fp)
|
||||
{
|
||||
if(
|
||||
#ifdef COMMAND_GET
|
||||
|
|
@ -120,7 +120,7 @@ PROTO4(char *, path, struct stat *, sbufp, int, mode, int, level)
|
|||
#else
|
||||
util_grab_file
|
||||
#endif
|
||||
(path,fp, start_from) == -1)
|
||||
(path,fp, start_from) == -1)
|
||||
{
|
||||
fclose(fp);
|
||||
if(clobbertype==C_TEMPNAME)
|
||||
|
|
@ -128,7 +128,7 @@ PROTO4(char *, path, struct stat *, sbufp, int, mode, int, level)
|
|||
} else
|
||||
fclose(fp);
|
||||
} else fprintf(stderr,"Cannot write %s\n",name);
|
||||
|
||||
|
||||
#ifdef HAVE_UTIME_H
|
||||
/* update last modified time stamp */
|
||||
if(preserve && sbufp)
|
||||
|
|
@ -142,7 +142,7 @@ PROTO4(char *, path, struct stat *, sbufp, int, mode, int, level)
|
|||
rename(name,fname);
|
||||
free(name);
|
||||
}
|
||||
|
||||
|
||||
if (clobbertype==C_UNIQUE) {
|
||||
free(name);
|
||||
}
|
||||
|
|
@ -179,7 +179,7 @@ static int make_dir PROTO3(char *, name, struct stat *, sbufp, u_long *, mode)
|
|||
|
||||
static void usage PROTO0((void))
|
||||
{
|
||||
|
||||
|
||||
#ifdef COMMAND_GET
|
||||
printf("fgetcmd");
|
||||
#else
|
||||
|
|
@ -187,7 +187,7 @@ static void usage PROTO0((void))
|
|||
#endif
|
||||
printf(" -[<f|o>|u|t|n|<a|c>] -r -p -h -?\n");
|
||||
}
|
||||
|
||||
|
||||
/* Parse options
|
||||
* -f forces overwrite (clobber)
|
||||
* -u forces unique names (unique)
|
||||
|
|
@ -196,14 +196,14 @@ static void usage PROTO0((void))
|
|||
* -a append to files if they exist (append)
|
||||
* -c same as -a
|
||||
* -o same as -f
|
||||
* -r recursively get directories
|
||||
* -r recursively get directories
|
||||
* -p preserve date/times of original file on downloaded copy
|
||||
*/
|
||||
int main PROTO2(int, argc, char **, argv)
|
||||
{
|
||||
char **av, *av2[2], n[1024];
|
||||
int prompt, mode = 0;
|
||||
|
||||
|
||||
signal(SIGHUP,fsp_cleanup);
|
||||
signal(SIGINT,fsp_cleanup);
|
||||
signal(SIGQUIT,fsp_cleanup);
|
||||
|
|
@ -224,7 +224,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
perror("chdir");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
while ((optletter=getopt(argc, argv,"ofutnacrph?")) != EOF)
|
||||
switch (optletter) {
|
||||
case 'o':
|
||||
|
|
@ -255,7 +255,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
usage();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
if(argc > optind) {
|
||||
for( ; argc>optind ; optind++) {
|
||||
if(!(av = glob(argv[optind]))) {
|
||||
|
|
@ -267,9 +267,9 @@ int main PROTO2(int, argc, char **, argv)
|
|||
{
|
||||
for(len = strlen(*av); len >= 0 && (*av)[len] != '/'; len--);
|
||||
len++;
|
||||
util_process_file(*av, mode,
|
||||
util_process_file(*av, mode,
|
||||
#ifdef COMMAND_GET
|
||||
get_file,
|
||||
get_file,
|
||||
#else
|
||||
grab_file,
|
||||
#endif
|
||||
|
|
@ -303,7 +303,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
len++;
|
||||
util_process_file(*av, mode,
|
||||
#ifdef COMMAND_GET
|
||||
get_file,
|
||||
get_file,
|
||||
#else
|
||||
grab_file,
|
||||
#endif
|
||||
|
|
@ -312,8 +312,8 @@ int main PROTO2(int, argc, char **, argv)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -96,7 +96,7 @@ void add_host(struct fsp_host *h)
|
|||
static struct fsp_host *find_host(const char *name)
|
||||
{
|
||||
int i,j;
|
||||
|
||||
|
||||
if(name==NULL || hostsize==0 ) return NULL;
|
||||
for(i=0;i<hostsize;i++)
|
||||
{
|
||||
|
|
@ -126,22 +126,22 @@ static void host_usage PROTO0((void)) /* print usage message */
|
|||
/* get data out of resource file */
|
||||
static void parse_prof_file_new PROTO1(const char *, filename)
|
||||
{
|
||||
|
||||
|
||||
FILE *input=NULL;
|
||||
int rc;
|
||||
|
||||
|
||||
if(filename)
|
||||
{
|
||||
input=fopen(filename,"r");
|
||||
}
|
||||
|
||||
|
||||
if(input)
|
||||
{
|
||||
yyin=input;
|
||||
rc=0;
|
||||
} else
|
||||
rc=yywrap();
|
||||
|
||||
|
||||
if(rc==0)
|
||||
yylex();
|
||||
|
||||
|
|
@ -156,7 +156,7 @@ static void list_prof_file PROTO0((void)) /* list resource file */
|
|||
{
|
||||
printf("host: %s port: %d\n",(host[i].hostname?host[i].hostname : host[i].hostaddr),(host[i].port<=0? 21 : host[i].port));
|
||||
}
|
||||
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
home = pw->pw_dir; /* for default search for file .fsp_prof*/
|
||||
} else
|
||||
home=getenv("HOME");
|
||||
|
||||
|
||||
/*
|
||||
* Figure out what shell we're using. A hack, we look for a shell
|
||||
* ending in "csh".
|
||||
|
|
@ -189,7 +189,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
{
|
||||
csh = !strcmp(log + strlen(log) - 3, "csh");
|
||||
}
|
||||
|
||||
|
||||
setup=init_host();
|
||||
while ((optletter=getopt(argc, argv,"d:p:l:t:o:f:h:w:bc?")) != EOF)
|
||||
switch (optletter) {
|
||||
|
|
@ -347,7 +347,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
}
|
||||
|
||||
/*
|
||||
* search order: curdir, homedir, sysdir
|
||||
* search order: curdir, homedir, sysdir
|
||||
*
|
||||
* Returns: 1 for terminating scanner or 0 for switching
|
||||
*/
|
||||
|
|
@ -356,7 +356,7 @@ int yywrap(void)
|
|||
{
|
||||
char *f2=NULL;
|
||||
int rc;
|
||||
|
||||
|
||||
if(yyin!=NULL)
|
||||
{
|
||||
fclose(yyin);
|
||||
|
|
@ -393,6 +393,6 @@ int yywrap(void)
|
|||
rc=yywrap();
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -28,10 +28,10 @@ int ls_bad PROTO1(int, n)
|
|||
int main PROTO2(int, argc, char **, argv)
|
||||
{
|
||||
env_client();
|
||||
|
||||
|
||||
fls_main(argc,argv);
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,20 +22,20 @@ static int make_dir PROTO1(char *, p)
|
|||
{
|
||||
char *op;
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
op = util_abs_path(p);
|
||||
|
||||
|
||||
ub = client_interact(CC_MAKE_DIR,0L, strlen(op), (unsigned char *)op+1, 0,
|
||||
(unsigned char *)NULLP);
|
||||
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr,"Can't create %s: %s\n",p,ub->buf);
|
||||
free(op);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
|
||||
printf("%s\t: %s\n",p,ub->buf);
|
||||
|
||||
|
||||
free(op);
|
||||
return(0);
|
||||
}
|
||||
|
|
@ -45,6 +45,6 @@ int main PROTO2(int, argc, char **, argv)
|
|||
env_client();
|
||||
while(*++argv) make_dir(*argv);
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,9 +24,9 @@ static int get_pro PROTO1(const char *, p)
|
|||
{
|
||||
char *op;
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
op = util_abs_path(p);
|
||||
|
||||
|
||||
ub = client_interact(CC_GET_PRO,0L, strlen(op), (unsigned char *)op+1, 0,
|
||||
(unsigned char *)NULLP);
|
||||
if(ub->cmd == CC_ERR) {
|
||||
|
|
@ -35,7 +35,7 @@ static int get_pro PROTO1(const char *, p)
|
|||
}
|
||||
printf("%s\n",p);
|
||||
print_pro(ub,stdout);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
@ -43,9 +43,9 @@ static int set_pro PROTO2(char *, p, char *, key)
|
|||
{
|
||||
char *op;
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
op = util_abs_path(p);
|
||||
|
||||
|
||||
ub = client_interact(CC_SET_PRO,0L, strlen(op), (unsigned char *)op+1,
|
||||
strlen(key)+1, (unsigned char *)key);
|
||||
if(ub->cmd == CC_ERR) {
|
||||
|
|
@ -54,16 +54,16 @@ static int set_pro PROTO2(char *, p, char *, key)
|
|||
}
|
||||
printf("%s\n",p);
|
||||
print_pro(ub,stdout);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int main PROTO2(int, argc, char **, argv)
|
||||
{
|
||||
char **av, *av2[2], *key;
|
||||
|
||||
|
||||
env_client();
|
||||
|
||||
|
||||
if(argv[1] && (argv[1][0] == '+' || argv[1][0] == '-') && !argv[1][2]) {
|
||||
key = *++argv;
|
||||
while(*++argv) {
|
||||
|
|
@ -84,8 +84,8 @@ int main PROTO2(int, argc, char **, argv)
|
|||
while(*av) get_pro(*av++);
|
||||
} else get_pro(env_dir);
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ static int put_file PROTO1(char *, path)
|
|||
struct stat sb;
|
||||
char *name, *t2;
|
||||
FILE *fp;
|
||||
|
||||
|
||||
if(stat(path,&sb) != 0) {
|
||||
perror(path);
|
||||
return(0);
|
||||
|
|
@ -42,10 +42,10 @@ static int put_file PROTO1(char *, path)
|
|||
fprintf(stderr,"%s: not a file\n",path);
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
||||
for(name = t2 = path; *t2; t2++)
|
||||
if(*t2 == '/') name = t2 + 1;
|
||||
|
||||
|
||||
if( (fp = fopen(path,"rb"))) {
|
||||
util_upload(name,fp,timestamps==1?sb.st_mtime:0);
|
||||
fclose(fp);
|
||||
|
|
@ -58,13 +58,13 @@ int main PROTO2(int, argc, char **, argv)
|
|||
{
|
||||
char n[1024];
|
||||
int prompt;
|
||||
|
||||
|
||||
env_client();
|
||||
if (strcmp(env_local_dir,".") && chdir(env_local_dir)) {
|
||||
perror("chdir");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
while ((optletter=getopt(argc, argv,"ph?")) != EOF)
|
||||
switch (optletter) {
|
||||
case 'h':
|
||||
|
|
@ -88,8 +88,8 @@ int main PROTO2(int, argc, char **, argv)
|
|||
put_file(n);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ static int remove_it PROTO1(char *, p)
|
|||
{
|
||||
char *op;
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
op = util_abs_path(p);
|
||||
|
||||
|
||||
ub = client_interact(CC_DEL_FILE,0L, strlen(op), (unsigned char *)op+1, 0,
|
||||
(unsigned char *)NULLP);
|
||||
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr,"Can't remove %s: %s\n",p,ub->buf);
|
||||
free(op); return(-1);
|
||||
|
|
@ -39,9 +39,9 @@ static int remove_it PROTO1(char *, p)
|
|||
int main PROTO2(int, argc, char **, argv)
|
||||
{
|
||||
char **av, *av2[2];
|
||||
|
||||
|
||||
env_client();
|
||||
|
||||
|
||||
while(*++argv) {
|
||||
if(!(av = glob(*argv))) {
|
||||
av = av2;
|
||||
|
|
@ -50,8 +50,8 @@ int main PROTO2(int, argc, char **, argv)
|
|||
}
|
||||
while(*av) remove_it(*av++);
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,12 +23,12 @@ static int remove_it PROTO1(char *, p)
|
|||
{
|
||||
char *op;
|
||||
UBUF *ub;
|
||||
|
||||
|
||||
op = util_abs_path(p);
|
||||
|
||||
|
||||
ub = client_interact(CC_DEL_DIR,0L, strlen(op), (unsigned char *)op+1, 0,
|
||||
(unsigned char *)NULLP);
|
||||
|
||||
|
||||
if(ub->cmd == CC_ERR) {
|
||||
fprintf(stderr,"Can't remove %s: %s\n",p,ub->buf);
|
||||
free(op);
|
||||
|
|
@ -40,9 +40,9 @@ static int remove_it PROTO1(char *, p)
|
|||
int main PROTO2(int, argc, char **, argv)
|
||||
{
|
||||
char **av, *av2[2];
|
||||
|
||||
|
||||
env_client();
|
||||
|
||||
|
||||
while(*++argv) {
|
||||
if(!(av = glob(*argv))) {
|
||||
av = av2;
|
||||
|
|
@ -51,8 +51,8 @@ int main PROTO2(int, argc, char **, argv)
|
|||
}
|
||||
while(*av) remove_it(*av++);
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -59,13 +59,13 @@ HOSTNAME [[:alpha:]][\-._[:alnum:]]+
|
|||
}
|
||||
<shostname>.|\n fprintf(stderr,"invalid hostname `%s`\n",yytext);BEGIN(INITIAL);
|
||||
<shost>(fsp{WHITESPACE})?port BEGIN(sport);
|
||||
<sport>{WHITESPACE}
|
||||
<sport>{WHITESPACE}
|
||||
<sport>{NUMBER} host->port=atoi(yytext);BEGIN(shost);
|
||||
<sport>.|\n fprintf(stderr,"invalid port `%s`\n",yytext);BEGIN(shost);
|
||||
<shost>alias{WHITESPACE} BEGIN(salias);
|
||||
<salias>{HOSTNAME} add_host_alias(host,yytext);BEGIN(shost);
|
||||
<shost>local{WHITESPACE}port BEGIN(slport);
|
||||
<slport>{WHITESPACE}
|
||||
<slport>{WHITESPACE}
|
||||
<slport>{NUMBER} host->local_port=atoi(yytext);BEGIN(shost);
|
||||
<shost>(fsp{WHITESPACE})?directory{WHITESPACE} BEGIN(sdir);
|
||||
<sdir>\/[[:graph:]]* host->dir=strdup(yytext);BEGIN(shost);
|
||||
|
|
@ -74,11 +74,11 @@ HOSTNAME [[:alpha:]][\-._[:alnum:]]+
|
|||
<sldir>[[:graph:]]* host->local_dir=strdup(yytext);BEGIN(shost);
|
||||
<sldir>.|\n fprintf(stderr,"invalid local directory `%s`\n",yytext);BEGIN(shost);
|
||||
<shost>delay BEGIN(sdelay);
|
||||
<sdelay>{WHITESPACE}
|
||||
<sdelay>{WHITESPACE}
|
||||
<sdelay>{NUMBER} host->delay=atoi(yytext);BEGIN(shost);
|
||||
<sdelay>.|\n fprintf(stderr,"invalid delay `%s`\n",yytext);BEGIN(shost);
|
||||
<shost>timeout BEGIN(stimeout);
|
||||
<stimeout>{WHITESPACE}
|
||||
<stimeout>{WHITESPACE}
|
||||
<stimeout>{NUMBER} host->timeout=atoi(yytext);BEGIN(shost);
|
||||
<stimeout>.|\n fprintf(stderr,"invalid timeout `%s`\n",yytext);BEGIN(shost);
|
||||
<shost>trace{WHITESPACE}on host->trace=1;
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@ static void stat_file PROTO1(const char *,fname)
|
|||
struct stat sb;
|
||||
struct tm *ftime;
|
||||
char buf[35];
|
||||
|
||||
|
||||
if(util_stat(fname,&sb))
|
||||
{
|
||||
printf("%s: stat error\n",fname);
|
||||
|
|
@ -37,7 +37,7 @@ static void stat_file PROTO1(const char *,fname)
|
|||
else
|
||||
if(S_ISDIR(sb.st_mode))
|
||||
printf("Directory");
|
||||
|
||||
|
||||
ftime=localtime(&sb.st_mtime);
|
||||
strftime(buf,35,"%Y-%m-%d %H:%M:%S",ftime);
|
||||
#ifdef NATIVE_LARGEFILES
|
||||
|
|
@ -47,8 +47,8 @@ static void stat_file PROTO1(const char *,fname)
|
|||
#endif
|
||||
printf(": %s Size: "SFORM" Time: %s\n",fname,sb.st_size,buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
int main PROTO2(int, argc, char **, argv)
|
||||
|
|
@ -56,20 +56,20 @@ int main PROTO2(int, argc, char **, argv)
|
|||
char n[1024];
|
||||
int prompt;
|
||||
char **av, *av2[2];
|
||||
|
||||
|
||||
env_client();
|
||||
|
||||
|
||||
if(argc>1)
|
||||
{
|
||||
for( optind=1; argc>optind ; optind++)
|
||||
for( optind=1; argc>optind ; optind++)
|
||||
{
|
||||
if(!(av = glob(argv[optind])))
|
||||
if(!(av = glob(argv[optind])))
|
||||
{
|
||||
av = av2;
|
||||
av2[0] = argv[optind];
|
||||
av2[1] = 0;
|
||||
}
|
||||
while(*av)
|
||||
while(*av)
|
||||
stat_file(*av++);
|
||||
}
|
||||
} else {
|
||||
|
|
@ -86,12 +86,12 @@ int main PROTO2(int, argc, char **, argv)
|
|||
av2[0] = n;
|
||||
av2[1] = 0;
|
||||
}
|
||||
while(*av)
|
||||
while(*av)
|
||||
stat_file(*av++);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
client_done();
|
||||
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
UBUF *ub;
|
||||
unsigned int len, tput = 0, len2;
|
||||
char *v1, *v2;
|
||||
|
||||
|
||||
if(argc == 1) { /* no arg supplied, get version string of server */
|
||||
env_client();
|
||||
ub = client_interact(CC_VERSION,0L, 0, (unsigned char *)NULLP, 0,
|
||||
|
|
@ -64,6 +64,13 @@ int main PROTO2(int, argc, char **, argv)
|
|||
printf(" (max %d bytes/sec)\n", tput);
|
||||
} else
|
||||
printf("\tRemote server throughput control is DISABLED.\n");
|
||||
/* check for optional max. packet size block */
|
||||
if(++v2 < ub->buf+len+len2)
|
||||
{
|
||||
tput=0;
|
||||
tput = BB_READ2(v2);
|
||||
printf("\tMax. packet size supported by server is %d bytes.\n",tput);
|
||||
}
|
||||
}
|
||||
else
|
||||
printf("\tRemote server do not send extended info.\n");
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
char *p, *q;
|
||||
|
||||
for(p = q = argv[0]; *p; p++) if(*p == '/') q = p+1;
|
||||
|
||||
|
||||
if(!strcmp(q,"fcatcmd")) fcatcmd_main(argc,argv);
|
||||
else if(!strcmp(q,"fcdcmd")) fcdcmd_main(argc,argv);
|
||||
else if(!strcmp(q,"fgetcmd")) fgetcmd_main(argc,argv);
|
||||
|
|
|
|||
|
|
@ -28,12 +28,12 @@ int print_pro PROTO2(UBUF *, ub, FILE *, where)
|
|||
char flags;
|
||||
unsigned len, len1;
|
||||
char *pro1, *pro2;
|
||||
|
||||
|
||||
len = BB_READ2(ub->bb_len);
|
||||
len1 = BB_READ4(ub->bb_pos);
|
||||
pro1 = ub->buf;
|
||||
pro2 = ub->buf+len;
|
||||
|
||||
|
||||
if(len1) {
|
||||
flags = *pro2;
|
||||
fprintf(where,"owner: %s, del: %s, create: %s, mkdir: %s, get: %s, list: %s, rename: %s.\n",
|
||||
|
|
@ -43,6 +43,6 @@ int print_pro PROTO2(UBUF *, ub, FILE *, where)
|
|||
}
|
||||
fprintf(where,"%s", pro1);
|
||||
fprintf(where,"\n");
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ static char sccsid[] = "@(#)random.c 5.7 (Berkeley) 6/1/90";
|
|||
* zeroeth element of the array is the type of R.N.G. being used (small
|
||||
* integer); the remainder of the array is the state information for the
|
||||
* R.N.G. Thus, 32 bytes of state information will give 7 longs worth of
|
||||
* state information, which will allow a degree seven polynomial. (Note: the
|
||||
* state information, which will allow a degree seven polynomial. (Note: the
|
||||
* zeroeth word of state information also has some other information stored
|
||||
* in it -- see setstate() for details).
|
||||
* The random number generation technique is a linear feedback shift register
|
||||
|
|
@ -74,7 +74,7 @@ static char sccsid[] = "@(#)random.c 5.7 (Berkeley) 6/1/90";
|
|||
#define BREAK_0 8
|
||||
#define DEG_0 0
|
||||
#define SEP_0 0
|
||||
|
||||
|
||||
#define TYPE_1 1 /* x**7 + x**3 + 1 */
|
||||
#define BREAK_1 32
|
||||
#define DEG_1 7
|
||||
|
|
@ -104,7 +104,7 @@ static char sccsid[] = "@(#)random.c 5.7 (Berkeley) 6/1/90";
|
|||
|
||||
static int degrees[MAX_TYPES] = {DEG_0, DEG_1, DEG_2, DEG_3, DEG_4};
|
||||
static int seps[MAX_TYPES] = {SEP_0, SEP_1, SEP_2, SEP_3, SEP_4};
|
||||
|
||||
|
||||
/*
|
||||
* Initially, everything is set up as if from :
|
||||
* initstate( 1, &randtbl, 128 );
|
||||
|
|
@ -115,20 +115,20 @@ static int seps[MAX_TYPES] = {SEP_0, SEP_1, SEP_2, SEP_3, SEP_4};
|
|||
* position of the rear pointer is just
|
||||
* MAX_TYPES*(rptr - state) + TYPE_3 == TYPE_3.
|
||||
*/
|
||||
|
||||
|
||||
static long randtbl[DEG_3+1] = {TYPE_3,
|
||||
0x9a319039, 0x32d9c024, 0x9b663182,
|
||||
0x9a319039, 0x32d9c024, 0x9b663182,
|
||||
0x5da1f342, 0xde3b81e0, 0xdf0a6fb5,
|
||||
0xf103bc02, 0x48f340fb, 0x7449e56b,
|
||||
0xbeb1dbb0, 0xab5c5918, 0x946554fd,
|
||||
0x8c2e680f, 0xeb3d799f, 0xb11ee0b7,
|
||||
0x2d436b86, 0xda672e2a, 0x1588ca88,
|
||||
0xe369735d, 0x904f35f7, 0xd7158fd6,
|
||||
0x6fa6f051, 0x616e6b96, 0xac94efdc,
|
||||
0x6fa6f051, 0x616e6b96, 0xac94efdc,
|
||||
0x36413f93, 0xc622c298, 0xf5a42ab8,
|
||||
0x8a88d77b, 0xf5ad9d0e, 0x8999220b,
|
||||
0x27fb47b9 };
|
||||
|
||||
|
||||
/*
|
||||
* fptr and rptr are two pointers into the state info, a front and a rear
|
||||
* pointer. These two pointers are always rand_sep places aparts, as they
|
||||
|
|
@ -140,7 +140,7 @@ static long randtbl[DEG_3+1] = {TYPE_3,
|
|||
* randtbl) because the state table pointer is set to point to randtbl[1]
|
||||
* (as explained below).
|
||||
*/
|
||||
|
||||
|
||||
static long *fptr = &randtbl[SEP_3+1];
|
||||
static long *rptr = &randtbl[1];
|
||||
|
||||
|
|
@ -179,7 +179,7 @@ void srandom PROTO1(unsigned int, x)
|
|||
{
|
||||
register int i, j;
|
||||
long random();
|
||||
|
||||
|
||||
if(rand_type == TYPE_0) state[0] = x;
|
||||
else {
|
||||
j = 1;
|
||||
|
|
@ -212,7 +212,7 @@ void srandom PROTO1(unsigned int, x)
|
|||
char * initstate PROTO3(unsigned int, seed, char *, arg_state, int, n )
|
||||
{
|
||||
register char *ostate = (char *)(&state[-1]);
|
||||
|
||||
|
||||
if(rand_type == TYPE_0) state[-1] = rand_type;
|
||||
else state[-1] = MAX_TYPES*(rptr - state) + rand_type;
|
||||
if(n < BREAK_1) {
|
||||
|
|
@ -272,7 +272,7 @@ char *setstate PROTO1(char *, arg_state)
|
|||
register int type = new_state[0]%MAX_TYPES;
|
||||
register int rear = new_state[0]/MAX_TYPES;
|
||||
char *ostate = (char *)(&state[-1]);
|
||||
|
||||
|
||||
if(rand_type == TYPE_0) state[-1] = rand_type;
|
||||
else state[-1] = MAX_TYPES*(rptr - state) + rand_type;
|
||||
switch(type) {
|
||||
|
|
@ -315,7 +315,7 @@ char *setstate PROTO1(char *, arg_state)
|
|||
long random PROTO0((void))
|
||||
{
|
||||
long i;
|
||||
|
||||
|
||||
if(rand_type == TYPE_0) {
|
||||
i = state[0] = (state[0]*1103515245 + 12345)&0x7fffffff;
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -33,14 +33,14 @@ int _x_udp PROTO1(unsigned short *, port)
|
|||
struct sockaddr_in me ;
|
||||
struct sockaddr_in myadr;
|
||||
int zz=1;
|
||||
|
||||
|
||||
memset(&me,0,sizeof(me));
|
||||
|
||||
|
||||
me.sin_port = htons(*port);
|
||||
me.sin_family = AF_INET;
|
||||
|
||||
len=sizeof(me);
|
||||
|
||||
|
||||
if((f=socket(AF_INET,SOCK_DGRAM,0)) == -1) return(-1);
|
||||
|
||||
if(setsockopt(f,SOL_SOCKET,SO_REUSEADDR,(char *)&zz,sizeof(zz)) < 0 ||
|
||||
|
|
@ -51,7 +51,7 @@ int _x_udp PROTO1(unsigned short *, port)
|
|||
}
|
||||
if(!*port) *port = ntohs((unsigned short) myadr.sin_port);
|
||||
return(f);
|
||||
}
|
||||
}
|
||||
|
||||
int _x_adr PROTO3(const char *, host, int, port, struct sockaddr_in *, his)
|
||||
{
|
||||
|
|
@ -59,7 +59,7 @@ int _x_adr PROTO3(const char *, host, int, port, struct sockaddr_in *, his)
|
|||
struct hostent *H;
|
||||
int i;
|
||||
char *s, *d;
|
||||
|
||||
|
||||
memset(his,0,sizeof(his));
|
||||
if(!host) {
|
||||
gethostname(myhost,sizeof(myhost));
|
||||
|
|
@ -76,21 +76,21 @@ int _x_adr PROTO3(const char *, host, int, port, struct sockaddr_in *, his)
|
|||
his->sin_family = H->h_addrtype;
|
||||
} else return(-1);
|
||||
his->sin_port = htons((unsigned short) port);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int _x_select PROTO2(fd_set *, rf, long, tt) /* tt is in unit of ms */
|
||||
{
|
||||
struct timeval timeout;
|
||||
|
||||
|
||||
if(tt != -1) {
|
||||
if(tt < MIN_DELAY) tt = MIN_DELAY;
|
||||
timeout.tv_sec = tt / 1000;
|
||||
timeout.tv_usec = (tt % 1000)*1000;
|
||||
return(select(DSIZE, rf, NULL, NULL, &timeout));
|
||||
}
|
||||
|
||||
|
||||
return(select(DSIZE, rf, NULL, NULL , (struct timeval *) 0));
|
||||
}
|
||||
#endif /* not EXOS_IPC */
|
||||
|
|
@ -102,7 +102,7 @@ extern long rhost();
|
|||
int _x_udp PROTO1(int *, port)
|
||||
{
|
||||
struct sockaddr_in sin; int f;
|
||||
|
||||
|
||||
sin = INET_ZERO;
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_port = htons((unsigned short) *port);
|
||||
|
|
@ -122,15 +122,15 @@ int _x_adr PROTO3(char *, host, int, port, struct sockaddr_in *, his)
|
|||
{
|
||||
char myhost[128];
|
||||
int f;
|
||||
|
||||
|
||||
*his = INET_ZERO;
|
||||
if(!host) (void) gethostname(host = myhost,sizeof(myhost));
|
||||
|
||||
|
||||
his->sin_family = AF_INET;
|
||||
his->sin_port = htons((unsigned short) port);
|
||||
|
||||
|
||||
if((his->sin_addr.s_addr = rhost(&host)) == -1) return(-1);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
|
|
@ -138,13 +138,13 @@ int _x_select PROTO2(unsigned int *, readfds, long, tt)
|
|||
{
|
||||
int code;
|
||||
long mask = *readfds;
|
||||
|
||||
|
||||
if(tt & 0xc0000000) tt = 0x3fffffff;/* It does not like 0x7fffffff. */
|
||||
|
||||
|
||||
code = select(DSIZE, &mask, (long *) 0, tt);
|
||||
|
||||
|
||||
*readfds = mask;
|
||||
|
||||
|
||||
return(code);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
dnl Process this file with autoconf to produce a working configure script.
|
||||
dnl tested with autoconf 2.57
|
||||
AC_INIT(fsp,2.8.1b19,hsn@netmag.cz)
|
||||
AC_INIT(fsp,2.8.1b20,hsn@netmag.cz)
|
||||
AC_CONFIG_SRCDIR(server/main.c)
|
||||
AM_INIT_AUTOMAKE([dist-bzip2])
|
||||
AM_MAINTAINER_MODE
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ suite. Don't blame me for the code, i have not touched it.
|
|||
char *host = NULL;
|
||||
char *outputfile = NULL;
|
||||
/* Default values */
|
||||
int localport = 9191;
|
||||
int localport = 9191;
|
||||
int remoteport = 21;
|
||||
int endport = 65535;
|
||||
int retries = 3;
|
||||
|
|
@ -123,7 +123,7 @@ int main(int argc,char **argv)
|
|||
fprintf(stderr,"This error should not happen\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (host == NULL) {
|
||||
fprintf(stderr, "host/ip not specified, unable to continue\n");
|
||||
printhelp(argc, argv);
|
||||
|
|
@ -148,7 +148,7 @@ int main(int argc,char **argv)
|
|||
fprintf(logfile,"Found FSP ver: %s on port %0d\n",
|
||||
ub->buf,remoteport);
|
||||
else
|
||||
fprintf(logfile,"%0d...nada\n",remoteport);
|
||||
fprintf(logfile,"%0d...nada\n",remoteport);
|
||||
fflush(logfile);
|
||||
fdclose();
|
||||
}
|
||||
|
|
@ -187,7 +187,7 @@ UBUF *client_interact(cmd,pos,l1,p1,l2,p2)
|
|||
|
||||
for(t = (unsigned char *) &sbuf, sum = n = mlen; n--; sum += *t++);
|
||||
sbuf.sum = sum + (sum >> 8);
|
||||
if(client_trace && retry)
|
||||
if(client_trace && retry)
|
||||
write(2,"R",1);
|
||||
|
||||
if(sendto(myfd,&sbuf,mlen,0,(struct sockaddr*)&server_addr,sizeof(server_addr)) == -1)
|
||||
|
|
@ -237,7 +237,7 @@ void init_client(char *myhost,int port,int myport)
|
|||
{ perror("socket open"); exit(1); }
|
||||
|
||||
if(_x_adr(myhost,port,&server_addr) == -1)
|
||||
{ perror("server addr"); exit(1); }
|
||||
{ perror("server addr"); exit(1); }
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -261,15 +261,15 @@ int _x_udp(int *port)
|
|||
|
||||
me.sin_port = htons((unsigned short) *port);
|
||||
me.sin_family = AF_INET;
|
||||
|
||||
|
||||
if((f=socket(AF_INET,SOCK_DGRAM,0)) == -1) return(-1);
|
||||
|
||||
|
||||
if( setsockopt(f,SOL_SOCKET,SO_REUSEADDR,&zz,sizeof(zz)) < 0 ||
|
||||
bind(f,(struct sockaddr *) &me,(len = sizeof(me))) < 0 ||
|
||||
getsockname(f,(struct sockaddr*)&sin,&len) < 0)
|
||||
{ SAVE(((void) close(f))); return(-1); }
|
||||
if(!*port) *port = ntohs((unsigned short) sin.sin_port); return(f);
|
||||
}
|
||||
}
|
||||
|
||||
int _x_adr(char *host,int port,struct sockaddr_in *his)
|
||||
{
|
||||
|
|
@ -277,34 +277,34 @@ int _x_adr(char *host,int port,struct sockaddr_in *his)
|
|||
struct hostent *H;
|
||||
int i;
|
||||
char *s, *d;
|
||||
|
||||
|
||||
*his = INET_ZERO;
|
||||
if(!host) (void) gethostname(host = myhost,sizeof(myhost));
|
||||
|
||||
if((his->sin_addr.s_addr = inet_addr(host)) != INADDR_NONE) {
|
||||
|
||||
if((his->sin_addr.s_addr = inet_addr(host)) != INADDR_NONE) {
|
||||
his->sin_family = AF_INET;
|
||||
} else
|
||||
if(H = gethostbyname(host)) {
|
||||
for(s = (char *)H->h_addr,
|
||||
d = (char *)&his->sin_addr,
|
||||
if(H = gethostbyname(host)) {
|
||||
for(s = (char *)H->h_addr,
|
||||
d = (char *)&his->sin_addr,
|
||||
i = H->h_length; i--; *d++ = *s++);
|
||||
his->sin_family = H->h_addrtype;
|
||||
} else return(-1);
|
||||
his->sin_port = htons((unsigned short) port);
|
||||
|
||||
|
||||
return(0);
|
||||
}
|
||||
|
||||
int _x_select(fd_set *rf, long tt) /* tt is in unit of ms */
|
||||
{
|
||||
struct timeval timeout;
|
||||
|
||||
|
||||
if(tt != -1)
|
||||
{
|
||||
timeout.tv_sec = tt / 1000;
|
||||
timeout.tv_usec = (tt % 1000)*1000;
|
||||
return(select(DSIZE, rf, NULL, NULL, &timeout));
|
||||
}
|
||||
|
||||
|
||||
return(select(DSIZE, rf, NULL, NULL, (struct timeval *) 0));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#include <signal.h>
|
||||
|
||||
/****************************************************************************
|
||||
* UBUF is the structure of message exchanged between server and clients.
|
||||
* UBUF is the structure of message exchanged between server and clients.
|
||||
*
|
||||
* The 'buf' part of the buffer is variable lenght up to max of 1024.
|
||||
* The 'key' field is used by the server for sequence identification.
|
||||
|
|
@ -21,7 +21,7 @@
|
|||
* Client's message to server contain a key value that is the same as the
|
||||
* key value of the previous message received from the server. Similarly,
|
||||
* the server's message to client contains a seq value that is the same
|
||||
* as the seq value of the previous message from the client.
|
||||
* as the seq value of the previous message from the client.
|
||||
*
|
||||
* The buf field is logically partitioned into two parts by the len field.
|
||||
* The len field indicate the size of the first part of the buffer starting
|
||||
|
|
|
|||
159
doc/PROTOCOL
159
doc/PROTOCOL
|
|
@ -1,18 +1,17 @@
|
|||
File Service Protocol version 2
|
||||
specification
|
||||
FILE SERVICE PROTOCOL VERSION 2
|
||||
|
||||
Document version 0.9
|
||||
Last updated 18 Nov 2003
|
||||
Document version 0.10
|
||||
Last updated 18 Oct 2004
|
||||
|
||||
Also known as
|
||||
File Slurping Protocol,
|
||||
Flaky Stream Protocol,
|
||||
Also known as
|
||||
File Slurping Protocol,
|
||||
Flaky Stream Protocol,
|
||||
FTP's Sexier Partner,
|
||||
File Sharing Protocol or
|
||||
Fucking Slow Protocol.
|
||||
|
||||
`FSP is what anonymous FTP *should* be'
|
||||
|
||||
|
||||
This document was created by Radim Kolar, because there is no RFC for
|
||||
FSP. It was planed, but never comes out. Based on sources of FSP 2.8.1 Beta 13.
|
||||
This document is not copyrighted and is placed into public domain.
|
||||
|
|
@ -20,7 +19,7 @@ This document is not copyrighted and is placed into public domain.
|
|||
Data formats used in this document
|
||||
byte - unsigned 1 byte integer 0-255
|
||||
word - unsigned 2 byte integer 0-65535
|
||||
long - unsigned 4 byte integer 0-4294967295
|
||||
long - unsigned 4 byte integer 0-4294967295
|
||||
bits - counted from right to left. bit 0 is the lowest.
|
||||
NULL - byte 00
|
||||
ASCIIZ - ASCII string terminated with one NULL (the same as used in C
|
||||
|
|
@ -34,10 +33,31 @@ Data formats used in this document
|
|||
Numbers starting with 0x are in hexadecimal (base 16) notation.
|
||||
|
||||
Transport
|
||||
|
||||
FSP uses UDP datagrams as transport medium. Minimum UDP packet size (not
|
||||
including size of UDP, IP and link layer headers) is 12 bytes, maximum UDP
|
||||
packet size is 1024+12 bytes.
|
||||
|
||||
Security
|
||||
|
||||
Design
|
||||
|
||||
FSP protocol was not designed to transfer secret data. It was designed as
|
||||
alternative protocol for providing lightweight access to collection of public
|
||||
files. FSP has the same user level of security as the anonymous FTP file
|
||||
server. FSP has better network level security, because it was designed
|
||||
to ressist various denial-of-service attacks. FSP protocol v3 will be
|
||||
designed to be fully secure. FSP3 will not be backward compatible with
|
||||
FSP2.
|
||||
|
||||
Passwords
|
||||
|
||||
Recently, password support was added to protocol, because just
|
||||
too many people wants it and there were hacked version of FSP with
|
||||
password support floating around. Passwords are transmited in clear
|
||||
text over network which makes them a weak protection for determined
|
||||
intruder.
|
||||
|
||||
FSP Packet format:
|
||||
HEADER - size = Fixed size 12 bytes. Always present.
|
||||
DATA - size = defined in header (DATA_LENGTH)
|
||||
|
|
@ -57,9 +77,15 @@ HEADER FORMAT (12 bytes)
|
|||
|
||||
MESSAGE_CHECKSUM
|
||||
Entire packet (HEADER + DATA + XTRA DATA) is checksumed. When computing a
|
||||
checksum use zero in place of MESSAGE_CHECKSUM header field. Checksums are
|
||||
computed as follows:
|
||||
|
||||
checksum use zero in place of MESSAGE_CHECKSUM header field.
|
||||
|
||||
Due to some unknown reason, method of computing checksums is different in each
|
||||
direction. For packets travelling from server to client initial checksum
|
||||
value is zero, otherwise it is HEADER + DATA + XTRA DATA size.
|
||||
|
||||
Checksums in server->client direction are computed as follows:
|
||||
|
||||
/* assume that we have already zeroed checksum in packet */
|
||||
unsigned int sum,checksum;
|
||||
for(t = packet_start, sum = 0; t < packet_end; sum += *t++);
|
||||
checksum= sum + (sum >> 8);
|
||||
|
|
@ -72,7 +98,7 @@ by server.
|
|||
TIMEOUTS
|
||||
Resends:
|
||||
Server will accept resent message from client with old KEY after 3 seconds.
|
||||
Client MUST wait at least 1 second before resending a message.
|
||||
Client MUST wait at least 1 second before resending a message.
|
||||
It is recommended to use initial delay of 1.34 second and after each
|
||||
unsuccessfull resend multiply delay time by 1.5. Maximum recommended delay
|
||||
time is 300 seconds.
|
||||
|
|
@ -110,12 +136,12 @@ FSP File servers MUST supports following commands:
|
|||
|
||||
|
||||
CC_VERSION 0x10 - Get server version string and setup
|
||||
|
||||
|
||||
request
|
||||
file position: ignored
|
||||
data: not used
|
||||
xtra data: not used
|
||||
|
||||
|
||||
reply
|
||||
file position: size of optional extra version data
|
||||
data: ASCIIZ Server version string
|
||||
|
|
@ -126,15 +152,21 @@ FSP File servers MUST supports following commands:
|
|||
bit 2 set - reverse lookup required
|
||||
bit 3 set - server is in private mode
|
||||
bit 4 set - thruput control
|
||||
if bit 4 is set thruput info follows
|
||||
long - max_thruput allowed (in bytes/sec)
|
||||
word - max. packet size supported by server
|
||||
|
||||
Compatibility
|
||||
|
||||
Max. packet size supported is reported only by fspd 2.8.1 b20
|
||||
or newer.
|
||||
|
||||
|
||||
CC_ERR 0x40 - error response from server
|
||||
|
||||
If you want to get a error from server, send
|
||||
any unknown client command (for example CC_ERR).
|
||||
CC_ERRs are normally sent only by server on
|
||||
errors.
|
||||
errors conditions.
|
||||
|
||||
request (not used)
|
||||
file position: not used
|
||||
|
|
@ -163,7 +195,7 @@ RDIRENT is the structure of a directory entry contained in a directory listing.
|
|||
Each entry contains a HEADER, which has 4 bytes quantity 'time' in Unix
|
||||
standard format, a 4 bytes quantity 'size', and 1 byte of 'type'. Header is
|
||||
followed by ASCIIZ encoded 'name'. RDIRENT is followed by enough number of
|
||||
padding to fill to an 4-byte boundary.
|
||||
padding to fill to an 4-byte boundary.
|
||||
|
||||
At this point, if the next RDIRENT entry to follow will spread across 1k
|
||||
boundary, then two possible things will happen:
|
||||
|
|
@ -171,14 +203,14 @@ boundary, then two possible things will happen:
|
|||
1) if the HEADER fits between this entry and the 1k boundary,
|
||||
a complete header will be filled in with a 'type' set to RDTYPE_SKIP.
|
||||
Repeat this step as neceseary until no HEADER fits.
|
||||
2) if the HEADER does not fit, then simply pad to the 1k boundary.
|
||||
|
||||
2) if the HEADER does not fit, then simply pad to the 1k boundary.
|
||||
|
||||
This will make sure that messages carrying directory information carry only
|
||||
complete directory entries and no fragmented entries.
|
||||
|
||||
|
||||
The last entry is type RDTYPE_END.
|
||||
|
||||
struct RDIRENT {
|
||||
struct RDIRENT {
|
||||
struct HEADER {
|
||||
long time;
|
||||
long size;
|
||||
|
|
@ -205,7 +237,7 @@ RDIRENT.HEADER types:
|
|||
file position: same as in request
|
||||
data: binary file data
|
||||
xtra data: not used
|
||||
|
||||
|
||||
CC_UP_LOAD 0x43 - open a file for writing
|
||||
|
||||
request
|
||||
|
|
@ -217,7 +249,7 @@ RDIRENT.HEADER types:
|
|||
file position: same as in request
|
||||
data: not used
|
||||
xtra data: not used
|
||||
|
||||
|
||||
CC_INSTALL 0x44 - close and install file opened for writing
|
||||
|
||||
request
|
||||
|
|
@ -230,9 +262,9 @@ RDIRENT.HEADER types:
|
|||
file position: not used
|
||||
data: not used
|
||||
xtra data: not used
|
||||
|
||||
|
||||
CC_DEL_FILE 0x45 - delete a file
|
||||
|
||||
|
||||
request
|
||||
file position: not used
|
||||
data: ASCIIZ filename
|
||||
|
|
@ -242,7 +274,7 @@ RDIRENT.HEADER types:
|
|||
file position: not used
|
||||
data: not used
|
||||
xtra data: not used
|
||||
|
||||
|
||||
CC_DEL_DIR 0x46 - delete a directory
|
||||
|
||||
request
|
||||
|
|
@ -262,21 +294,27 @@ RDIRENT.HEADER types:
|
|||
data: ASCIIZ directory
|
||||
xtra data: (not required)
|
||||
word - size of reply's optional data block
|
||||
|
||||
|
||||
reply
|
||||
file position: number of extra protection bytes (now 1)
|
||||
data: ASCIIZ directory readme
|
||||
xtra data: extra protection data (format follows)
|
||||
|
||||
Protection bits:
|
||||
0 - caller owns the directory
|
||||
1 - files can be deleted from this dir
|
||||
2 - files can be added to this dir
|
||||
3 - new subdirectories can be created
|
||||
4 - files are NOT readable by non-owners
|
||||
5 - directory contain an readme file
|
||||
6 - directory can be listed
|
||||
7 - files can be renamed in this directory
|
||||
Protection bits:
|
||||
0 - caller owns the directory
|
||||
1 - files can be deleted from this dir
|
||||
2 - files can be added to this dir
|
||||
3 - new subdirectories can be created
|
||||
4 - files are NOT readable by non-owners
|
||||
5 - directory contain an readme file
|
||||
6 - directory can be listed
|
||||
7 - files can be renamed in this directory
|
||||
|
||||
Compatibility
|
||||
|
||||
Versions older than 2.8.1b6 do not uses bits 6 and 7. This
|
||||
causes that directory can be listable even it do not have
|
||||
6th bit set.
|
||||
|
||||
CC_SET_PRO 0x48 - set directory protection
|
||||
|
||||
|
|
@ -297,9 +335,13 @@ Protection bits:
|
|||
|
||||
reply
|
||||
same as CC_GET_PRO
|
||||
|
||||
Compatibility
|
||||
FSP versions older than 2.8.1 beta15 used p flag instead
|
||||
g flag. +p = -g
|
||||
|
||||
CC_MAKE_DIR 0x49 - create a directory
|
||||
|
||||
|
||||
request
|
||||
file position: not used
|
||||
data: ASCIIZ directory name
|
||||
|
|
@ -319,16 +361,20 @@ Protection bits:
|
|||
optional data: not used
|
||||
xtra data: not used
|
||||
|
||||
You should send this packet when you are done with
|
||||
talking to server. This causes that server will
|
||||
accept next packet from your IP with any key.
|
||||
|
||||
Commands starting from FSP version 2.4 ( released March 27, 1992 )
|
||||
|
||||
|
||||
CC_GRAB_FILE 0x4B - atomic get+delete a file
|
||||
|
||||
|
||||
same format as CC_GET_FILE, but file is deleted after
|
||||
sucessfull transfer is done. If there are multiple
|
||||
grabs for the same file, only one will succeed.
|
||||
|
||||
|
||||
CC_GRAB_DONE 0x4C - atomic get+delete a file done
|
||||
|
||||
|
||||
same format as CC_INSTALL. File is not
|
||||
installed, but deleted.
|
||||
|
||||
|
|
@ -349,21 +395,27 @@ Commands starting from FSP 2.8.1 Beta 11
|
|||
data format is the same as in directory listing with exception
|
||||
that there is no file name appended. If file do not exists or
|
||||
there is other problem (no access rights) return type of file is
|
||||
0. CC_ERR message is NOT returned in this case.
|
||||
|
||||
struct STAT {
|
||||
long time;
|
||||
long size;
|
||||
byte type;
|
||||
}
|
||||
|
||||
0.
|
||||
|
||||
struct STAT {
|
||||
long time;
|
||||
long size;
|
||||
byte type;
|
||||
}
|
||||
|
||||
Compatibility
|
||||
CC_ERR message is NEVER returned as reply to CC_STAT command
|
||||
by server supporting CC_STAT command. If you have got CC_ERR reply,
|
||||
you are talking to old server, which do not supports this
|
||||
command.
|
||||
|
||||
CC_RENAME 0x4E - rename file or directory
|
||||
request
|
||||
file position: not used
|
||||
data: ASCIIZ source file or directory
|
||||
ASCIIZ destination file or directory
|
||||
xtra data: not used
|
||||
|
||||
|
||||
Note: It is possible to do cross-directory rename. In this
|
||||
case you must have rights to DELETE in source directory and
|
||||
to CREATE in target directory.
|
||||
|
|
@ -380,6 +432,7 @@ Reserved commands:
|
|||
|
||||
CC_LIMIT 0x80 - commands > 0x7F will have extended
|
||||
header. No such extensions or commands
|
||||
which uses that are known today.
|
||||
|
||||
which uses that are known today. This
|
||||
header will be used in protocol version 3.
|
||||
|
||||
CC_TEST 0x81 - reserved for testing of new header
|
||||
|
|
|
|||
22
fspd.conf
22
fspd.conf
|
|
@ -42,12 +42,13 @@ use_access_files yes
|
|||
permit_passwordless_owners off
|
||||
|
||||
# The 'tmpdir' command controls where the server stores temporary files
|
||||
# during upload or grab.
|
||||
# during upload or grab. You must have it or server will support
|
||||
# read operations only. This can be absolute or relative path to home
|
||||
# dir. Server will try to create it.
|
||||
#
|
||||
tmpdir /tmp/fsp
|
||||
|
||||
# The 'pidlogname command controls where we write the fspd pid
|
||||
# This command is required!
|
||||
# The 'pidlogname command controls where we write the fspd pid.
|
||||
pidlogname /var/run/fspd.pid
|
||||
|
||||
# The 'grabcommand' can turn grab command on or off.
|
||||
|
|
@ -64,12 +65,12 @@ vercommand on
|
|||
# readme .README
|
||||
|
||||
# The 'dircache' command controls how much directories listings gets cached.
|
||||
dircache 50
|
||||
dircache 100
|
||||
|
||||
# 'use_prebuild_dirlists' allows to load/save prebuilded directories
|
||||
# listing from filesystem. It is a good idea to allow that.
|
||||
# Win32: Set to NO
|
||||
use_prebuild_dirlists yes
|
||||
# Do not use on Win32 system.
|
||||
#use_prebuild_dirlists yes
|
||||
|
||||
# The 'statcache' command controls how many directories are placed into
|
||||
# stat cache. Cache contains last modified time and access rights.
|
||||
|
|
@ -82,8 +83,8 @@ statcache_timeout 15
|
|||
# 'use_directory_mtime'. If your filesystem changes mtime when directory
|
||||
# is updated, set it to YES. If set to NO, directory will be rechecked
|
||||
# after statcache_timeout and dircache entry invalidated.
|
||||
# Win32: Set to NO
|
||||
use_directory_mtime yes
|
||||
# Do not use on Win32 system.
|
||||
#use_directory_mtime yes
|
||||
|
||||
# The 'filecache' command controls maximal number of open files by server.
|
||||
# After this limit will be reached, server will close last recently used files.
|
||||
|
|
@ -229,11 +230,12 @@ xferlog ../logs/xferlog
|
|||
# pass after new packet with the old KEY from client will be accepted
|
||||
# FSP protocol definition says that must be at least 3 secs, but you
|
||||
# can set this to shorter time and allow faster error recovery. It is
|
||||
# higly recommended to keep 3 seconds.
|
||||
# higly recommended to keep it at least 3 seconds.
|
||||
# retry 3
|
||||
|
||||
# The "timeout" command specifies how much time must pass after new
|
||||
# packet with wrong KEY number is accepted. FSP definition sets this
|
||||
# to 60 seconds.
|
||||
# to 60 seconds. You can set it to lower value for faster clients
|
||||
# recovery (about 20 sec is fine).
|
||||
|
||||
# timeout 60
|
||||
|
|
|
|||
|
|
@ -3,9 +3,9 @@
|
|||
|
||||
/* lib.c */
|
||||
extern int client_trace;
|
||||
extern unsigned long udp_sent_time,target_delay;
|
||||
extern unsigned long udp_sent_time,target_delay,target_maxdelay;
|
||||
UBUF *client_interact PROTO0((unsigned char, unsigned long, unsigned int,
|
||||
unsigned const char *, unsigned int,
|
||||
unsigned const char *, unsigned int,
|
||||
unsigned const char *));
|
||||
void init_client PROTO0((const char *, unsigned short, unsigned short));
|
||||
int client_done PROTO0((void));
|
||||
|
|
@ -14,12 +14,13 @@ int client_done PROTO0((void));
|
|||
extern int key_persists;
|
||||
unsigned short client_get_key PROTO0((void));
|
||||
void client_set_key PROTO0((unsigned short));
|
||||
void client_destroy_key PROTO0((void));
|
||||
void client_init_key PROTO0((unsigned long, unsigned long,
|
||||
unsigned short));
|
||||
|
||||
/* util.c */
|
||||
extern const char *env_dir,*env_passwd,*env_local_dir,*env_port,*env_myport,*env_host;
|
||||
extern int env_timeout;
|
||||
extern unsigned int env_timeout;
|
||||
extern unsigned short client_buf_len,client_net_len;
|
||||
char *util_abs_path PROTO0((const char *));
|
||||
char *util_getwd PROTO0((char *));
|
||||
|
|
@ -33,10 +34,10 @@ rdirent *util_readdir PROTO0((RDIR *));
|
|||
int util_stat PROTO0((char *, struct stat *));
|
||||
int util_cd PROTO0((char *));
|
||||
int util_cd2 PROTO0((char *));
|
||||
void util_process_file PROTO0((char *, int,
|
||||
void (*)PROTO0((char *,struct stat *,int,int)),
|
||||
void util_process_file PROTO0((char *, int,
|
||||
void (*)PROTO0((char *,struct stat *,int,int)),
|
||||
int (*)PROTO0((char *,struct stat *,u_long *)),
|
||||
void (*)PROTO0((char *,int,u_long,int)),
|
||||
void (*)PROTO0((char *,int,u_long,int)),
|
||||
int));
|
||||
|
||||
#endif /* _FSP_C_EXTERN_H_ */
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@
|
|||
remote file is not found */
|
||||
#define C_UNIQUE 3 /* Create unique name to avoid overwrite */
|
||||
#define C_TEMPNAME 4 /* Download to temp name */
|
||||
#define C_APPEND 5 /* Downloads will attempt to append to
|
||||
#define C_APPEND 5 /* Downloads will attempt to append to
|
||||
end of file if it already exists */
|
||||
|
||||
/****************************************************************************
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@
|
|||
#endif
|
||||
|
||||
/****************************************************************************
|
||||
* UBUF is the structure of message exchanged between server and clients.
|
||||
* UBUF is the structure of message exchanged between server and clients.
|
||||
*
|
||||
* The 'buf' part of the buffer is variable length up to max of 1024.
|
||||
* The 'key' field is used by the server for sequence identification.
|
||||
|
|
@ -71,7 +71,7 @@
|
|||
* Client's message to server contain a key value that is the same as the
|
||||
* key value of the previous message received from the server. Similarly,
|
||||
* the server's message to client contains a seq value that is the same
|
||||
* as the seq value of the previous message from the client.
|
||||
* as the seq value of the previous message from the client.
|
||||
*
|
||||
* The buf field is logically partitioned into two parts by the len field.
|
||||
* The len field indicate the size of the first part of the buffer starting
|
||||
|
|
@ -169,6 +169,8 @@ typedef struct RDIRENT { unsigned char bb_time[4];
|
|||
|
||||
#define MIN_DELAY 1000L
|
||||
#define DEFAULT_DELAY 1340L
|
||||
#define MAX_DELAY 300000L
|
||||
#define DEFAULT_MAXDELAY 60000L
|
||||
#define MAX_DELAY 300000L
|
||||
#define DEFAULT_TIMEOUT 360
|
||||
|
||||
#endif /* _FSP_COMMON_DEF_H_ */
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
|
||||
/* #ifdef UNDERSTANDS_PROTOTYPES */
|
||||
#ifdef PROTOTYPES
|
||||
#ifdef PROTOTYPES
|
||||
#define PROTO0(a) a
|
||||
#define PROTO1(a, b) (a b)
|
||||
#define PROTO2(a, b, c, d) (a b, c d)
|
||||
|
|
|
|||
|
|
@ -24,16 +24,16 @@
|
|||
* Following setting is a minimum recommended size. *
|
||||
****************************************************************************/
|
||||
|
||||
#define DEFAULT_DIRLISTCACHE_SIZE 32
|
||||
#define DEFAULT_DIRLISTCACHE_SIZE 50
|
||||
|
||||
/****************************************************************************
|
||||
* DEFAULT_DIRSTATCACHE_SIZE should be set to contain the number of dirs *
|
||||
* you want to held in dirstat memory cache. This cache avoids calling stat *
|
||||
* on directory and loading access perms. This operation is far less
|
||||
* on directory and loading access perms. This operation is far less
|
||||
* expensive than listing a directory, so if can be a lower number.
|
||||
*/
|
||||
|
||||
#define DEFAULT_DIRSTATCACHE_SIZE 20
|
||||
#define DEFAULT_DIRSTATCACHE_SIZE 30
|
||||
|
||||
/* THCCOUNT is the number of seconds used to compute average throughput.
|
||||
* 10 seconds seems to be a good value
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ typedef struct {
|
|||
* path string. See server_file.c for more info.
|
||||
*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
typedef struct {
|
||||
const char *fullp; /* ptr to string containing full pathname */
|
||||
const char *f_ptr; /* ptr to begining of last path component */
|
||||
unsigned int f_len; /* length of last component in path */
|
||||
|
|
@ -101,7 +101,7 @@ typedef struct {
|
|||
#define L_MAKEDIR 0x0200
|
||||
#define L_GRABFILE 0x0400
|
||||
#define L_GETPRO 0x0800
|
||||
#define L_RDONLY 0x1000
|
||||
#define L_RDONLY 0x1000
|
||||
#define L_STAT 0x2000
|
||||
#define L_RENAME 0x4000
|
||||
#define L_ALL 0xffff
|
||||
|
|
@ -118,5 +118,5 @@ typedef struct {
|
|||
#define FSP_OWNER ".FSP_OWNER"
|
||||
#define FSP_PASSWORD ".FSP_OK_PASSWORD"
|
||||
#define FSP_OWNERPASSWORD ".FSP_OWNER_PASSWORD"
|
||||
|
||||
|
||||
#endif /* _FSP_SERVER_DEF_H_ */
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
|
||||
#ifdef WORD_TYPE_4
|
||||
/* there is an integer type of size 4 */
|
||||
#define BB_READ4(V) ntohl(*(WORD_TYPE_4 *)(V))
|
||||
#define BB_READ4(V) ntohl(*(const WORD_TYPE_4 *)(V))
|
||||
#define BB_WRITE4(V,A) *(WORD_TYPE_4 *)(V) = htonl(A)
|
||||
#else
|
||||
/* there is no integer type of size 4 */
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
man_MANS= fcat.1 fcatcmd.1 fcd.1 fcdcmd.1 fdu.1 fducmd.1 ffind.1 ffindcmd.1 \
|
||||
fget.1 fgetcmd.1 fgrab.1 fgrabcmd.1 fhost.1 fhostcmd.1 fls.1 \
|
||||
flscmd.1 fmkdir.1 fpro.1 fprocmd.1 fput.1 frm.1 frmcmd.1 frmdir.1 \
|
||||
frmdircmd.1 fsp_prof.5 fspd.1 fver.1 fstatcmd.1 fspscan.1
|
||||
frmdircmd.1 fsp_prof.5 fspd.1 fver.1 fstatcmd.1 fspscan.1 \
|
||||
fsp_env.7
|
||||
|
||||
EXTRA_DIST=$(man_MANS)
|
||||
EXTRA_DIST=$(man_MANS)
|
||||
|
|
|
|||
|
|
@ -42,11 +42,15 @@ so that network speed has an indicator. This variable has no effect when the
|
|||
standard output is a terminal.
|
||||
.TP
|
||||
.B FSP_TIMEOUT
|
||||
If this variable is set, it contains the timeout value. The default value is 180.
|
||||
If this variable is set, it contains the timeout value in seconds.
|
||||
The default value is 360.
|
||||
No function if program was compiled without timeout code.
|
||||
.TP
|
||||
.B FSP_DELAY
|
||||
Minimum wait time before resending packet in milliseconds.
|
||||
.TP
|
||||
.B FSP_MAXDELAY
|
||||
Maximum wait time before resending packet in milliseconds.
|
||||
.TP
|
||||
.B FSP_LOCAL_DIR
|
||||
Where to look for local files. Default is current directory.
|
||||
|
|
|
|||
20
man/fspd.1
20
man/fspd.1
|
|
@ -1,8 +1,8 @@
|
|||
.TH FSPD 1 "29 Sep 2003" FSP
|
||||
.TH FSPD 1 "18 Oct 2004" FSP
|
||||
.SH NAME
|
||||
fspd, in.fspd \- File Service Protocol (FSP) server
|
||||
.SH SYNOPSIS
|
||||
.B fspd [-f configfile] [-p port] [-i] [-v|-V] [-t timeout] [-X] [-d directory] [-F ] [-T temporary directory] [-l logfile] [-P pidlogname]
|
||||
.B fspd [-f configfile] [-p port] [-i] [-v|-V] [-t timeout] [-X] [-d directory] [-F ] [-T temporary directory] [-l logfile] [-P pidlogname] [-b bandwidth]
|
||||
.SH DESCRIPTION
|
||||
.B fspd
|
||||
is the server for an anonymous-ftp style archive called FSP. The main
|
||||
|
|
@ -69,8 +69,14 @@ Write log output to file.
|
|||
.PD 0
|
||||
.TP 20
|
||||
.B -P pidlogname
|
||||
Write pid to the given file name. This Option is required, if it's
|
||||
not given in your fspd.conf or on command line fspd will fail to start.
|
||||
Write pid to the given file name.
|
||||
|
||||
.PD 0
|
||||
.TP 20
|
||||
.B -b bandwidth
|
||||
Enable bandwidth limiting. Limit output to
|
||||
.I bandwidth
|
||||
bytes per second.
|
||||
|
||||
.LP
|
||||
.SH FILES
|
||||
|
|
@ -163,6 +169,12 @@ Server dumps stats to file specified as dumpfile in configuration.
|
|||
This file must be writeable by server or server must have rights
|
||||
to create it.
|
||||
|
||||
.TP
|
||||
.B SIGINT | SIGTERM
|
||||
Server performs cleaup and exits. All connected clients will be
|
||||
disconnected. Because FSP is stateless protocol, if you start
|
||||
server later, than can continue without breakage.
|
||||
|
||||
.SH EXIT CODES
|
||||
.B 1
|
||||
configuration or command line invocation error.
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
.TH FVER 1 "8 December 1991" FSP
|
||||
.TH FVER 1 "Oct 2004" FSP
|
||||
.SH NAME
|
||||
fver \- displays the version number string of the FSP database
|
||||
.SH SYNOPSIS
|
||||
|
|
@ -8,7 +8,7 @@ fver \- displays the version number string of the FSP database
|
|||
.LP
|
||||
Without arguments,
|
||||
.B fver
|
||||
displays the version string of the FSP database.
|
||||
displays the version string of the FSP server.
|
||||
Otherwise, the version string of the client utilities is displayed.
|
||||
.SH ENVIRONMENT
|
||||
.LP
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
bin_PROGRAMS=fspd
|
||||
|
||||
fspd_SOURCES=file.c host.c main.c conf.c filecache.c server.c fifocache.c \
|
||||
fspd_SOURCES=file.c host.c main.c conf.c server.c fifocache.c \
|
||||
log.c iprange.c acl.c path.c random.c pidfile.c
|
||||
fspd_CFLAGS=-DSYSCONFDIR="\"@sysconfdir@\"" $(AM_CFLAGS)
|
||||
fspd_LDADD=-L../common -lcommon
|
||||
|
|
|
|||
22
server/acl.c
22
server/acl.c
|
|
@ -60,7 +60,7 @@ void save_access_rights PROTO1(DIRINFO *,di)
|
|||
unlink(FSP_OWNER);
|
||||
unlink(FSP_OWNERPASSWORD);
|
||||
unlink(FSP_DIRLISTING);
|
||||
|
||||
|
||||
if(!use_access_files) return;
|
||||
|
||||
/* step2 save flagfiles */
|
||||
|
|
@ -110,8 +110,8 @@ void load_access_rights PROTO1(DIRINFO *,di)
|
|||
{
|
||||
unsigned int s;
|
||||
/* max readme file size is
|
||||
* packetsize - pro_bytes (now 1) - 1 (for /0)
|
||||
*/
|
||||
* packetsize - pro_bytes (now 1) - 1 (for /0)
|
||||
*/
|
||||
s=min(packetsize-PRO_BYTES-1,sf.st_size);
|
||||
di->readme=malloc(s+1);
|
||||
if(di->readme)
|
||||
|
|
@ -124,7 +124,7 @@ void load_access_rights PROTO1(DIRINFO *,di)
|
|||
}
|
||||
|
||||
if(!use_access_files) return;
|
||||
|
||||
|
||||
/* LOAD ACCESS RIGHTS FROM FILES IN CURRENT DIRECTORY */
|
||||
if(fexist(FSP_NOGET)) di->protection^=DIR_GET;
|
||||
if(fexist(FSP_DEL)) di->protection|=DIR_DEL;
|
||||
|
|
@ -135,13 +135,13 @@ void load_access_rights PROTO1(DIRINFO *,di)
|
|||
if(!FSP_STAT(FSP_PASSWORD,&sf))
|
||||
if(sf.st_size>0)
|
||||
di->public_password=load_password(FSP_PASSWORD);
|
||||
|
||||
|
||||
/* load owner info */
|
||||
f=fopen(FSP_OWNER,"r");
|
||||
if(!f)
|
||||
return;
|
||||
|
||||
while(fscanf(f, "%255[^\n\r]", owner_line) == 1)
|
||||
while(fscanf(f, "%255[^\n\r]", owner_line) == 1)
|
||||
{
|
||||
add_ipline(owner_line,&di->owner);
|
||||
}
|
||||
|
|
@ -162,17 +162,17 @@ void load_access_rights PROTO1(DIRINFO *,di)
|
|||
const char * require_access_rights PROTO4(const DIRINFO *,di,unsigned char,rights,unsigned long, ip_addr, const char *, passwd)
|
||||
{
|
||||
const char *acc=NULL;
|
||||
|
||||
|
||||
/* check if we has record in an owner tabl. */
|
||||
if(di->owner)
|
||||
{
|
||||
/* check ip access */
|
||||
acc=check_ip_table(ip_addr,di->owner);
|
||||
}
|
||||
|
||||
|
||||
if(acc!=NULL)
|
||||
{
|
||||
if(acc[0]=='I' || acc[0]=='D')
|
||||
if(acc[0]=='I' || acc[0]=='D')
|
||||
/* bazmeg IP! */
|
||||
return acc;
|
||||
if(acc[0]=='O') /* possible owner */
|
||||
|
|
@ -209,8 +209,8 @@ const char * require_access_rights PROTO4(const DIRINFO *,di,unsigned char,right
|
|||
}
|
||||
|
||||
/* now check public access rights */
|
||||
if( (rights & di->protection) ||
|
||||
(rights==0)
|
||||
if( (rights & di->protection) ||
|
||||
(rights==0)
|
||||
)
|
||||
return "NWelcome on board captain!";
|
||||
else
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
static int conf_read = 0;
|
||||
|
||||
int daemonize = 1;
|
||||
int use_prebuild_dirlists =
|
||||
int use_prebuild_dirlists =
|
||||
#ifdef OS_CYGWIN
|
||||
0;
|
||||
#else
|
||||
|
|
@ -40,7 +40,7 @@ int no_unnamed = 0;
|
|||
int logging = 0;
|
||||
int use_access_files = 1;
|
||||
int use_directory_mtime =
|
||||
#ifdef OS_CYGWIN
|
||||
#ifdef OS_CYGWIN
|
||||
0;
|
||||
#else
|
||||
1;
|
||||
|
|
@ -94,7 +94,7 @@ static int get_boolean PROTO1(const char, *q)
|
|||
else
|
||||
if(strcmp(q, "1") == 0) return 1;
|
||||
else
|
||||
|
||||
|
||||
fprintf(stderr,"Bogus boolean value '%s'. Exiting.\n",q);
|
||||
exit(1);
|
||||
return -1;
|
||||
|
|
@ -157,7 +157,7 @@ static void read_configuration PROTO1(const char *, name)
|
|||
int neg;
|
||||
do {
|
||||
/* skip to next token */
|
||||
r = q; while(*r && !isspace(*r)) r++;
|
||||
r = q; while(*r && !isspace(*r)) r++;
|
||||
if (*r) { *r++ = 0 ; while(*r && isspace(*r)) r++; }
|
||||
if(strcasecmp(q, "none") == 0) {
|
||||
logging = L_NONE;
|
||||
|
|
@ -210,11 +210,11 @@ static void read_configuration PROTO1(const char *, name)
|
|||
retry_timeout = atoi(q);
|
||||
if(retry_timeout < 1 ) retry_timeout = 3;
|
||||
}
|
||||
else if(strcasecmp(p, "timeout") == 0) {
|
||||
else if(strcasecmp(p, "timeout") == 0) {
|
||||
session_timeout = atoi(q);
|
||||
if(session_timeout <= 5 ) session_timeout = 60;
|
||||
}
|
||||
else if(strcasecmp(p, "statcache_timeout") == 0) {
|
||||
else if(strcasecmp(p, "statcache_timeout") == 0) {
|
||||
session_timeout = atoi(q);
|
||||
if(stat_cache_timeout <= 0 ) stat_cache_timeout = 20;
|
||||
}
|
||||
|
|
@ -289,5 +289,6 @@ void destroy_configuration PROTO0((void))
|
|||
if(iptab) free_ip_table(iptab);
|
||||
|
||||
readme_file = home_dir = logname = tmp_dir = dumpname = NULL;
|
||||
iptab = pidlogname = NULL;
|
||||
iptab = NULL;
|
||||
pidlogname = NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Simple FIFO generic cache. (c) Radim Kolar 2003.
|
||||
/*
|
||||
* Simple FIFO generic cache. (c) Radim Kolar 2003.
|
||||
* This file is copyrighted as LGPL.
|
||||
*
|
||||
* When this file is used as part of FSP, it uses 2-term BSD license
|
||||
|
|
@ -30,7 +30,7 @@ struct FifoCache * f_cache_new(unsigned int cachesize,unsigned int entrysize,
|
|||
cache->e_head=calloc(1,1);
|
||||
else
|
||||
cache->e_head=calloc(cachesize,entrysize);
|
||||
|
||||
|
||||
if(keysize==0)
|
||||
cache->k_head=calloc(1,1);
|
||||
else
|
||||
|
|
@ -42,18 +42,18 @@ struct FifoCache * f_cache_new(unsigned int cachesize,unsigned int entrysize,
|
|||
return NULL;
|
||||
}
|
||||
cache->k_next=cache->k_head;
|
||||
|
||||
|
||||
if(keysize==0)
|
||||
cache->k_stop=NULL;
|
||||
else
|
||||
cache->k_stop=cache->k_head+cache->keysize*cache->cachesize;
|
||||
|
||||
|
||||
cache->e_next=cache->e_head;
|
||||
if(entrysize==0)
|
||||
cache->e_stop=NULL;
|
||||
else
|
||||
cache->e_stop=cache->e_head+cache->entrysize*cache->cachesize;
|
||||
|
||||
|
||||
cache->k_destroy_func=kdf;
|
||||
cache->e_destroy_func=edf;
|
||||
cache->k_compare_func=kcf;
|
||||
|
|
@ -120,7 +120,7 @@ unsigned int f_cache_void_profiler(void *anything)
|
|||
void f_cache_destroy(struct FifoCache *cache)
|
||||
{
|
||||
if(cache==NULL) return;
|
||||
if(cache->e_head)
|
||||
if(cache->e_head)
|
||||
{
|
||||
memset(cache->e_head,0,cache->entrysize*cache->cachesize);
|
||||
free(cache->e_head);
|
||||
|
|
@ -151,7 +151,7 @@ void * f_cache_put(struct FifoCache *cache,const void *key,const void *data)
|
|||
/* update next pos. */
|
||||
cache->e_next+=cache->entrysize;
|
||||
cache->k_next+=cache->keysize;
|
||||
|
||||
|
||||
/* roll over? */
|
||||
if(cache->e_next==cache->e_stop || cache->k_next==cache->k_stop)
|
||||
{
|
||||
|
|
@ -166,10 +166,10 @@ void * f_cache_put(struct FifoCache *cache,const void *key,const void *data)
|
|||
void *f_cache_find(struct FifoCache *cache,const void *key)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
|
||||
if(!cache->k_compare_func) return NULL;
|
||||
if(cache->keysize==0) return NULL;
|
||||
|
||||
|
||||
for(i=0;i<cache->cachesize;i++)
|
||||
if(!cache->k_compare_func(key,cache->k_head+i*cache->keysize))
|
||||
{
|
||||
|
|
@ -188,16 +188,16 @@ void f_cache_clear(struct FifoCache *cache)
|
|||
/* free entries */
|
||||
for(i=0;i<cache->cachesize;i++)
|
||||
{
|
||||
if(cache->k_destroy_func)
|
||||
if(cache->k_destroy_func)
|
||||
cache->k_destroy_func(cache->k_head+i*cache->keysize);
|
||||
if(cache->e_destroy_func)
|
||||
if(cache->e_destroy_func)
|
||||
cache->e_destroy_func(cache->e_head+i*cache->entrysize);
|
||||
}
|
||||
|
||||
/* clear entries */
|
||||
memset(cache->k_head,0,cache->cachesize*cache->keysize);
|
||||
memset(cache->e_head,0,cache->cachesize*cache->entrysize);
|
||||
|
||||
|
||||
cache->k_next=cache->k_head;
|
||||
cache->e_next=cache->e_head;
|
||||
|
||||
|
|
@ -227,14 +227,14 @@ int f_cache_delete_entry(struct FifoCache *cache, void *entry)
|
|||
if(entry<(const void *)cache->e_head || entry>=(const void *)cache->e_stop) return 0;
|
||||
/* find cache index */
|
||||
i=((BYTE *)(entry)-cache->e_head)/cache->entrysize;
|
||||
|
||||
|
||||
/* deallocate */
|
||||
if(cache->k_destroy_func) cache->k_destroy_func(cache->k_head+cache->keysize*i);
|
||||
if(cache->e_destroy_func) cache->e_destroy_func(entry);
|
||||
/* zero them */
|
||||
memset(entry,0,cache->entrysize);
|
||||
memset(cache->k_head+cache->keysize*i,0,cache->keysize);
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
|
|||
217
server/file.c
217
server/file.c
|
|
@ -37,15 +37,15 @@ static struct FifoCache *fpcache;
|
|||
#define TWOGIGS 0x7fffffffUL
|
||||
|
||||
static FPCACHE *search_fpcache PROTO3(unsigned long, inet_num,
|
||||
unsigned short, port_num,
|
||||
unsigned short, port_num,
|
||||
const char *, fname)
|
||||
{
|
||||
unsigned int i;
|
||||
FPCACHE *entry;
|
||||
const char **key;
|
||||
|
||||
for (i=0;i<fp_cache_limit;i++)
|
||||
{
|
||||
|
||||
for (i=0;i<fp_cache_limit;i++)
|
||||
{
|
||||
/* search for file in cache */
|
||||
entry=(FPCACHE *)(fpcache->e_head+i*sizeof(FPCACHE));
|
||||
if (port_num==entry->port_num && inet_num==entry->inet_num)
|
||||
|
|
@ -85,7 +85,7 @@ static unsigned int fpcache_entry_profiler PROTO1(void *,entry)
|
|||
static void dirlistcache_free_entry PROTO1(void *, entry)
|
||||
{
|
||||
DIRLISTING *d=entry;
|
||||
|
||||
|
||||
if(d->listing)
|
||||
free(d->listing);
|
||||
}
|
||||
|
|
@ -100,7 +100,7 @@ static unsigned int dirlistcache_entry_profiler PROTO1(void *,entry)
|
|||
static void dirstatcache_free_entry PROTO1(void *, entry)
|
||||
{
|
||||
DIRINFO *d=entry;
|
||||
|
||||
|
||||
if(d->realname)
|
||||
free(d->realname);
|
||||
if(d->owner_password)
|
||||
|
|
@ -155,7 +155,7 @@ static void string_free PROTO1(void *, entry)
|
|||
static unsigned int string_profiler PROTO1(void *,entry)
|
||||
{
|
||||
char **s=entry;
|
||||
|
||||
|
||||
if(*s!=NULL)
|
||||
return(strlen(*s));
|
||||
else
|
||||
|
|
@ -231,14 +231,14 @@ void shutdown_caches PROTO0((void))
|
|||
|
||||
/*****************************************************************************
|
||||
* Validate path - check that path does not fall outside the bounds of the
|
||||
* FSP root directory, weed out references to / and ../.. type links.
|
||||
* FSP root directory, weed out references to / and ../.. type links.
|
||||
* Input: fullp - pointer to full filename
|
||||
* lenfullp - length of full filename (including \0)
|
||||
* *di - where to return DIRINFO information about directory
|
||||
* want_directory - want to operate on directory, not a file
|
||||
* want_directory - want to operate on directory, not a file
|
||||
*****************************************************************************/
|
||||
const char *validate_path PROTO5(char *, fullp, unsigned, lenfullp, PPATH *, pp,DIRINFO **,di, int, want_directory)
|
||||
{
|
||||
{
|
||||
char work [NBSIZE];
|
||||
const char *err;
|
||||
char *s;
|
||||
|
|
@ -350,7 +350,7 @@ static const char *copy_file PROTO2(const char *, n1, const char *, n2)
|
|||
if(!(ft = fopen(n1,"rb"))) {
|
||||
return("Can't open temporary file");
|
||||
}
|
||||
|
||||
|
||||
if(!(fp = fopen(n2,"wb"))) {
|
||||
fclose(ft);
|
||||
return("Can't open file for output");
|
||||
|
|
@ -359,7 +359,7 @@ static const char *copy_file PROTO2(const char *, n1, const char *, n2)
|
|||
/* copy temporary file to actual fput file */
|
||||
while( (bytes = fread(buf,1,sizeof(buf),ft)))
|
||||
fwrite(buf,1,bytes,fp);
|
||||
|
||||
|
||||
fclose(ft);
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
|
|
@ -369,7 +369,7 @@ static const char *copy_file PROTO2(const char *, n1, const char *, n2)
|
|||
static int append_dir_listing PROTO3(DIRLISTING *, dl,const char *, buf,unsigned int, size)
|
||||
{
|
||||
BYTE *newbuf;
|
||||
|
||||
|
||||
/* append this buffer */
|
||||
newbuf=realloc(dl->listing,dl->listing_size+size);
|
||||
if(newbuf==NULL)
|
||||
|
|
@ -381,12 +381,12 @@ static int append_dir_listing PROTO3(DIRLISTING *, dl,const char *, buf,unsigned
|
|||
memcpy(newbuf+dl->listing_size,buf,size);
|
||||
dl->listing_size+=size;
|
||||
dl->listing=newbuf;
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* builds directory listing into DIRLISTING structure, in case of any
|
||||
* error. nulls dl->listing
|
||||
* error. nulls dl->listing
|
||||
*/
|
||||
static void build_dir_listing PROTO2(DIRLISTING *, dl,const char *,directory)
|
||||
{
|
||||
|
|
@ -401,7 +401,7 @@ static void build_dir_listing PROTO2(DIRLISTING *, dl,const char *,directory)
|
|||
char name[NBSIZE]; /* buffer for stat name */
|
||||
int namelen; /* directory name length */
|
||||
unsigned int bufpos; /* current write pos. in buffer */
|
||||
|
||||
|
||||
/* init pointers */
|
||||
dl->listing=NULL;
|
||||
dl->listing_size=0;
|
||||
|
|
@ -411,16 +411,16 @@ static void build_dir_listing PROTO2(DIRLISTING *, dl,const char *,directory)
|
|||
fprintf(stderr,"Can't open dir during listing initialization\n");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
memset(buffer,0,packetsize); /* clear memory on the stack */
|
||||
strcpy(name,directory);
|
||||
strcpy(name,directory);
|
||||
namelen=strlen(directory);
|
||||
name[namelen++]='/'; /* add directory separator to name */
|
||||
|
||||
|
||||
for(rem = packetsize; (dp = readdir(dir_f)); ) {
|
||||
if (dp->d_ino == 0) continue;
|
||||
s = dp->d_name;
|
||||
|
||||
|
||||
/* hide dot files, but allow . or .. */
|
||||
if((s[0]=='.') && ((s[1]!=0) && (s[1] != '.' || s[2] != 0))) continue;
|
||||
|
||||
|
|
@ -428,7 +428,7 @@ static void build_dir_listing PROTO2(DIRLISTING *, dl,const char *,directory)
|
|||
if(FSP_STAT(name,&sb)) continue;
|
||||
if(!S_ISDIR(sb.st_mode) && !S_ISREG(sb.st_mode)) continue;
|
||||
if(sb.st_size>FOURGIGS) sb.st_size=FOURGIGS;
|
||||
|
||||
|
||||
nlen = strlen(s)+1;
|
||||
|
||||
/* do we have space in buffer for entire entry? */
|
||||
|
|
@ -444,7 +444,7 @@ static void build_dir_listing PROTO2(DIRLISTING *, dl,const char *,directory)
|
|||
rem = packetsize;
|
||||
bufpos = 0;
|
||||
}
|
||||
|
||||
|
||||
BB_WRITE4(buffer+bufpos,sb.st_mtime);
|
||||
bufpos+=4;
|
||||
BB_WRITE4(buffer+bufpos,sb.st_size );
|
||||
|
|
@ -462,7 +462,7 @@ static void build_dir_listing PROTO2(DIRLISTING *, dl,const char *,directory)
|
|||
}
|
||||
}
|
||||
closedir(dir_f);
|
||||
|
||||
|
||||
/* do we have space for final END entry? */
|
||||
if(rem <RDHSIZE )
|
||||
{
|
||||
|
|
@ -487,7 +487,7 @@ const char *server_get_dir PROTO2(DIRLISTING **, dl, const DIRINFO *, di)
|
|||
{
|
||||
struct stat sf;
|
||||
char list_p[NBSIZE];
|
||||
|
||||
|
||||
/* get directory from memory cache */
|
||||
if(dbug) fprintf(stderr,"finding %s in dirlistcache\n",di->realname);
|
||||
*dl=f_cache_find(dirlistcache,&(di->realname));
|
||||
|
|
@ -504,7 +504,7 @@ const char *server_get_dir PROTO2(DIRLISTING **, dl, const DIRINFO *, di)
|
|||
DIRLISTING dlnew;
|
||||
char *key;
|
||||
unsigned int ok;
|
||||
|
||||
|
||||
if(dbug) fprintf(stderr," miss.\n");
|
||||
ok=0;
|
||||
if(use_prebuild_dirlists)
|
||||
|
|
@ -515,14 +515,14 @@ const char *server_get_dir PROTO2(DIRLISTING **, dl, const DIRINFO *, di)
|
|||
if(sf.st_mtime>=di->mtime) {
|
||||
/* try to load it */
|
||||
FILE *f;
|
||||
|
||||
|
||||
dlnew.listing_size=sf.st_size;
|
||||
dlnew.listing=malloc(dlnew.listing_size);
|
||||
if(dlnew.listing)
|
||||
{
|
||||
if( (f=fopen(list_p,"rb")) )
|
||||
if( (f=fopen(list_p,"rb")) )
|
||||
{
|
||||
if(dlnew.listing_size==fread(dlnew.listing,1,dlnew.listing_size,f))
|
||||
if(dlnew.listing_size==fread(dlnew.listing,1,dlnew.listing_size,f))
|
||||
ok=1;
|
||||
fclose(f);
|
||||
}
|
||||
|
|
@ -578,19 +578,19 @@ const char *server_get_dir PROTO2(DIRLISTING **, dl, const DIRINFO *, di)
|
|||
const char *server_del_file PROTO2(PPATH *, pp, DIRINFO *, di)
|
||||
{
|
||||
struct stat sb;
|
||||
|
||||
|
||||
if(FSP_STAT(pp->fullp,&sb)) return("unlink: file not accessible");
|
||||
if(!(S_ISREG(sb.st_mode))) return("unlink: not an ordinary file");
|
||||
|
||||
|
||||
if(unlink(pp->fullp) == -1) return("unlink: cannot unlink");
|
||||
di->mtime=cur_time;
|
||||
di->lastcheck=cur_time;
|
||||
|
||||
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
const char *server_del_dir PROTO2(PPATH *, pp, DIRINFO *,di)
|
||||
{
|
||||
struct stat sb;
|
||||
|
|
@ -598,11 +598,11 @@ const char *server_del_dir PROTO2(PPATH *, pp, DIRINFO *,di)
|
|||
|
||||
if(FSP_STAT(pp->fullp,&sb)) return("rmdir: directory not accessible");
|
||||
if(!(S_ISDIR(sb.st_mode))) return("rmdir: not an ordinary directory");
|
||||
|
||||
|
||||
memset(&null,0,sizeof(DIRINFO));
|
||||
|
||||
|
||||
chdir(pp->fullp);
|
||||
save_access_rights(&null);
|
||||
save_access_rights(&null);
|
||||
chdir(home_dir);
|
||||
if(rmdir(pp->fullp) != 0) {
|
||||
chdir(pp->fullp);
|
||||
|
|
@ -614,12 +614,12 @@ const char *server_del_dir PROTO2(PPATH *, pp, DIRINFO *,di)
|
|||
{
|
||||
di->lastcheck=0;
|
||||
}
|
||||
|
||||
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
|
||||
const char *server_make_dir PROTO3(PPATH *, pp, unsigned long, inet_num,DIRINFO, **di)
|
||||
{
|
||||
DIRINFO newdir;
|
||||
|
|
@ -652,10 +652,10 @@ const char *server_make_dir PROTO3(PPATH *, pp, unsigned long, inet_num,DIRINFO,
|
|||
*di=f_cache_put(dirstatcache,&name,&newdir);
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
const char *server_get_file PROTO5(PPATH *, pp,
|
||||
|
||||
const char *server_get_file PROTO5(PPATH *, pp,
|
||||
FILE **, fp,
|
||||
unsigned long, inet_num,
|
||||
unsigned short, port_num,
|
||||
|
|
@ -665,17 +665,17 @@ const char *server_get_file PROTO5(PPATH *, pp,
|
|||
struct stat sb;
|
||||
char realfn[NBSIZE];
|
||||
FPCACHE *cache_f;
|
||||
|
||||
|
||||
sprintf(realfn,"%s/%s",di->realname,pp->f_ptr);
|
||||
cache_f=search_fpcache(inet_num,port_num,realfn);
|
||||
|
||||
|
||||
if(!cache_f) {
|
||||
FPCACHE newfile;
|
||||
char *key;
|
||||
/* file not found in cache? */
|
||||
|
||||
if (FSP_STAT(realfn,&sb)) return("No such file");
|
||||
if(!(S_ISREG(sb.st_mode)))
|
||||
if(!(S_ISREG(sb.st_mode)))
|
||||
{
|
||||
if(S_ISDIR(sb.st_mode))
|
||||
return ("Is a directory");
|
||||
|
|
@ -693,17 +693,17 @@ const char *server_get_file PROTO5(PPATH *, pp,
|
|||
f_cache_put(fpcache,&key,&newfile);
|
||||
}
|
||||
/* get filepoint from cache */
|
||||
else *fp = cache_f->fp;
|
||||
|
||||
else *fp = cache_f->fp;
|
||||
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* result and pp->fullp may overlap */
|
||||
const char *server_get_pro PROTO3(DIRINFO *, di, char *, result, const char *, acc)
|
||||
{
|
||||
result[0]='\0'; /* truncate output buffer */
|
||||
|
||||
|
||||
if(di->readme) strcat(result,di->readme);
|
||||
result[strlen(result)+1] = di->protection^DIR_GET;
|
||||
if(acc[0]=='O')
|
||||
|
|
@ -711,7 +711,7 @@ const char *server_get_pro PROTO3(DIRINFO *, di, char *, result, const char *, a
|
|||
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
const char *server_set_pro PROTO2(DIRINFO *,di, const char *, key)
|
||||
|
|
@ -739,7 +739,7 @@ const char *server_set_pro PROTO2(DIRINFO *,di, const char *, key)
|
|||
default:
|
||||
return("Invalid syntax. <+|-> <c|d|g|m|l|r>");
|
||||
}
|
||||
|
||||
|
||||
switch(key[0]) {
|
||||
case '+':
|
||||
di->protection|=act;
|
||||
|
|
@ -750,21 +750,21 @@ const char *server_set_pro PROTO2(DIRINFO *,di, const char *, key)
|
|||
default:
|
||||
return("Invalid syntax. <+|-> <c|d|g|m|l|r>");
|
||||
}
|
||||
|
||||
|
||||
di->mtime=cur_time;
|
||||
di->lastcheck=cur_time;
|
||||
|
||||
chdir(di->realname);
|
||||
save_access_rights (di);
|
||||
chdir(home_dir);
|
||||
|
||||
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* These two are used for file uploading.
|
||||
**********************************************************************/
|
||||
|
||||
|
||||
const char *server_up_load PROTO5(char *, data, unsigned int, len, unsigned long, pos,
|
||||
unsigned long, inet_num, unsigned short, port_num)
|
||||
{
|
||||
|
|
@ -775,26 +775,45 @@ const char *server_up_load PROTO5(char *, data, unsigned int, len, unsigned long
|
|||
struct stat sf;
|
||||
|
||||
sprintf(tname, "%s/.T%08lX%04X", tmp_dir,inet_num, port_num);
|
||||
|
||||
|
||||
tmp=tname;
|
||||
cache_f=f_cache_find(fpcache,&tmp);
|
||||
if(! cache_f ) {
|
||||
/* file not found in cache */
|
||||
FPCACHE newfile;
|
||||
/* file not found in cache? */
|
||||
if (pos) {
|
||||
fp = fopen(tname, "r+b");
|
||||
} else {
|
||||
unlink(tname);
|
||||
fp = fopen(tname,"wb");
|
||||
}
|
||||
|
||||
|
||||
if(!fp) return("Cannot open temporary file");
|
||||
|
||||
if(lstat(tname,&sf) || !S_ISREG(sf.st_mode))
|
||||
|
||||
/* check for symlinks or other junk */
|
||||
if(lstat(tname,&sf) || !S_ISREG(sf.st_mode))
|
||||
{
|
||||
fclose(fp);
|
||||
remove(tname);
|
||||
return("Temporary file is NOT a regular file");
|
||||
}
|
||||
/* test if we do not create hole in file which is caused that
|
||||
client continues upload across server crash, which causes
|
||||
some data loss due to libc stdio write caching */
|
||||
/* server do not cleans temporary directory on startup - so
|
||||
uploads across restart should work */
|
||||
if(pos > sf.st_size || pos < sf.st_size - UBUF_SPACE)
|
||||
{
|
||||
fclose(fp);
|
||||
unlink(tname);
|
||||
return("Temporary file is NOT a regular file");
|
||||
return("Non continuous upload detected. Restart upload please.");
|
||||
}
|
||||
/* seek to starting position */
|
||||
if(fseeko(fp, pos, SEEK_SET))
|
||||
{
|
||||
fclose(fp);
|
||||
unlink(tname);
|
||||
return("Seeking in file failed");
|
||||
}
|
||||
/* protect temporary file */
|
||||
chmod(tname,S_IRUSR|S_IWUSR);
|
||||
|
|
@ -804,16 +823,36 @@ const char *server_up_load PROTO5(char *, data, unsigned int, len, unsigned long
|
|||
newfile.fp=fp;
|
||||
tmp=strdup(tname);
|
||||
f_cache_put(fpcache,&tmp,&newfile);
|
||||
} else
|
||||
} else {
|
||||
/* get file pointer from cache */
|
||||
fp=cache_f->fp;
|
||||
|
||||
}
|
||||
|
||||
/* check for uploading on non-tail of file */
|
||||
sf.st_size= ftello(fp);
|
||||
if(pos > sf.st_size || pos < sf.st_size - UBUF_SPACE)
|
||||
{
|
||||
f_cache_delete_entry(fpcache,cache_f);
|
||||
unlink(tname);
|
||||
if( pos == 0)
|
||||
{
|
||||
/* we can retry */
|
||||
return server_up_load (data,len,pos,inet_num,port_num);
|
||||
}
|
||||
return("Non continuous upload detected. Restart upload please.");
|
||||
}
|
||||
/*
|
||||
if(fseeko(fp, pos, SEEK_SET))
|
||||
return("Seeking in file failed");
|
||||
*/
|
||||
if(len!=fwrite(data, 1, len, fp))
|
||||
{
|
||||
f_cache_delete_entry(fpcache,cache_f);
|
||||
return("Writing to file failed");
|
||||
}
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
const char *server_install PROTO7(PPATH *, pp, unsigned long, inet_num,
|
||||
unsigned short, port_num, const char *, acc, DIRINFO *,di, unsigned int, l2, const char *,s2)
|
||||
{
|
||||
|
|
@ -823,26 +862,26 @@ const char *server_install PROTO7(PPATH *, pp, unsigned long, inet_num,
|
|||
#ifdef HAVE_UTIME_H
|
||||
struct utimbuf ut;
|
||||
#endif
|
||||
|
||||
|
||||
sprintf(tname, "%s/.T%08lX%04X", tmp_dir,inet_num, port_num);
|
||||
/* if file still in cache, then close it & remove it from cache */
|
||||
tmp=tname;
|
||||
cache_f=f_cache_find(fpcache,&tmp);
|
||||
f_cache_delete_entry(fpcache,cache_f);
|
||||
|
||||
|
||||
if (dbug)
|
||||
fprintf(stderr,"server_install: tname: %s, pp->fullp: %s\n",tname, pp->fullp);
|
||||
|
||||
if(fexist(pp->fullp) &&
|
||||
if(fexist(pp->fullp) &&
|
||||
( (di->protection & DIR_DEL) || acc[0]=='O' )
|
||||
)
|
||||
)
|
||||
{
|
||||
unlink(tname);
|
||||
if(dbug)
|
||||
if(dbug)
|
||||
fprintf(stderr,"File %s already exists, but there is no user is not directory owner and public can't delete files.\n",pp->fullp);
|
||||
return("no permission for replacing that file. Not an owner.");
|
||||
}
|
||||
|
||||
|
||||
di->lastcheck=cur_time;
|
||||
di->mtime=cur_time;
|
||||
|
||||
|
|
@ -855,7 +894,7 @@ const char *server_install PROTO7(PPATH *, pp, unsigned long, inet_num,
|
|||
unlink(tname);
|
||||
umask(system_umask);
|
||||
#ifdef HAVE_UTIME_H
|
||||
if(l2>=4)
|
||||
if(l2>=4)
|
||||
{
|
||||
ut.modtime=BB_READ4(s2);
|
||||
ut.actime=cur_time;
|
||||
|
|
@ -865,7 +904,7 @@ const char *server_install PROTO7(PPATH *, pp, unsigned long, inet_num,
|
|||
|
||||
return(tmp);
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
/* assume path is validated */
|
||||
/* start GRAB OPERATION! */
|
||||
|
|
@ -875,12 +914,12 @@ const char *server_secure_file PROTO4(PPATH *, pp, unsigned long, inet_num,
|
|||
struct stat sb;
|
||||
char temp_p[NBSIZE];
|
||||
const char *tmp;
|
||||
|
||||
|
||||
if(FSP_STAT(pp->fullp,&sb)) return("grab: file not accessible");
|
||||
if(!(S_ISREG(sb.st_mode))) return("grab: not an ordinary file");
|
||||
|
||||
|
||||
sprintf(temp_p,"%s/.G%08lX%04X", tmp_dir, inet_num,port_num);
|
||||
|
||||
|
||||
unlink(temp_p);
|
||||
/* link emulated as a filecopy */
|
||||
tmp=copy_file(pp->fullp,temp_p);
|
||||
|
|
@ -890,13 +929,13 @@ const char *server_secure_file PROTO4(PPATH *, pp, unsigned long, inet_num,
|
|||
unlink(temp_p);
|
||||
return("grab: cannot unlink original file");
|
||||
}
|
||||
|
||||
|
||||
di->lastcheck=cur_time;
|
||||
di->mtime=cur_time;
|
||||
|
||||
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
const char *server_grab_file PROTO3(FILE **, fp,
|
||||
unsigned long, inet_num,
|
||||
unsigned short, port_num)
|
||||
|
|
@ -905,7 +944,7 @@ const char *server_grab_file PROTO3(FILE **, fp,
|
|||
char temp_p[NBSIZE];
|
||||
FPCACHE *cache_f;
|
||||
char *key;
|
||||
|
||||
|
||||
sprintf(temp_p,"%s/.G%08lX%04X",tmp_dir,inet_num,port_num);
|
||||
key=temp_p;
|
||||
cache_f=f_cache_find(fpcache,&key);
|
||||
|
|
@ -926,7 +965,7 @@ const char *server_grab_file PROTO3(FILE **, fp,
|
|||
|
||||
return(NULLP);
|
||||
}
|
||||
|
||||
|
||||
const char *server_grab_done PROTO2(unsigned long, inet_num,
|
||||
unsigned short, port_num)
|
||||
{
|
||||
|
|
@ -934,7 +973,7 @@ const char *server_grab_done PROTO2(unsigned long, inet_num,
|
|||
char temp_p[NBSIZE];
|
||||
FPCACHE *cache_f;
|
||||
char *key;
|
||||
|
||||
|
||||
sprintf(temp_p,"%s/.G%08lX%04X",tmp_dir,inet_num,port_num);
|
||||
if(FSP_STAT(temp_p,&sb)) return("grabdone: can't find temporary file");
|
||||
key=temp_p;
|
||||
|
|
@ -981,11 +1020,11 @@ const char *server_stat PROTO1(UBUF *, ubuf )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BB_WRITE4(ubuf->buf,sb.st_mtime);
|
||||
BB_WRITE4(ubuf->buf+4,sb.st_size );
|
||||
|
||||
if(rc)
|
||||
|
||||
if(rc)
|
||||
rc=0;
|
||||
else
|
||||
if S_ISDIR(sb.st_mode) rc=RDTYPE_DIR;
|
||||
|
|
@ -993,7 +1032,7 @@ const char *server_stat PROTO1(UBUF *, ubuf )
|
|||
if S_ISREG(sb.st_mode) rc=RDTYPE_FILE;
|
||||
else
|
||||
rc=0; /* not a file or directory */
|
||||
|
||||
|
||||
(ubuf->buf)[8]=rc;
|
||||
return(NULLP);
|
||||
}
|
||||
|
|
@ -1007,10 +1046,10 @@ const char *server_rename PROTO3(char *, ub, unsigned int, l1, unsigned int, l2)
|
|||
int srcdir; /* is source object a directory ? */
|
||||
PPATH dest;
|
||||
const char *pe;
|
||||
|
||||
|
||||
if(FSP_STAT(pp->fullp,&sb)) return("can't find source file or directory");
|
||||
if(S_ISDIR(sb.st_mode))
|
||||
srcdir=1;
|
||||
srcdir=1;
|
||||
else
|
||||
if(S_ISREG(sb.st_mode))
|
||||
srcdir=0;
|
||||
|
|
@ -1024,11 +1063,11 @@ const char *server_rename PROTO3(char *, ub, unsigned int, l1, unsigned int, l2)
|
|||
/*********************************************************************
|
||||
test and resolve home directory
|
||||
*********************************************************************/
|
||||
|
||||
|
||||
void init_home_dir PROTO0((void))
|
||||
{
|
||||
void *newhd;
|
||||
|
||||
|
||||
/* test and goto home dir */
|
||||
if(chdir(home_dir) == -1) {
|
||||
perror(home_dir);
|
||||
|
|
|
|||
|
|
@ -2,6 +2,6 @@
|
|||
*
|
||||
* 05-MAR-93 First Version <S.A.Pechler@bdk.tue.nl>
|
||||
* 10-MAR-93 Merged into standard distribution by jtraub@cs.cmu.edu
|
||||
* 03-JUL-2003 Last Version (c) Radim Kolar. I have thrown out all previous
|
||||
* 03-JUL-2003 Last Version (c) Radim Kolar. I have thrown out all previous
|
||||
* code and write a new one. New code has been moved into file.c
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -36,13 +36,13 @@ static char *find_hostname PROTO1(unsigned long, inet_num)
|
|||
{
|
||||
struct hostent *he;
|
||||
char *hostname;
|
||||
|
||||
|
||||
if ((he = gethostbyaddr((char*)&inet_num, sizeof(inet_num), AF_INET))) {
|
||||
hostname = malloc(strlen(he->h_name)+1);
|
||||
strcpy(hostname, he->h_name);
|
||||
} else
|
||||
hostname = 0;
|
||||
|
||||
|
||||
return hostname;
|
||||
}
|
||||
|
||||
|
|
@ -58,7 +58,7 @@ HTAB *find_host PROTO1(unsigned long, inet_num)
|
|||
unsigned l, h, m, i;
|
||||
unsigned long inum;
|
||||
HTAB *hs, *hd;
|
||||
|
||||
|
||||
for(l = 0, h = hcnt-1; (m = (l + h) >> 1) != l; ) { /* binary search */
|
||||
inum = htab[m].inet_num;
|
||||
if(inum > inet_num) h = m;
|
||||
|
|
@ -72,20 +72,20 @@ HTAB *find_host PROTO1(unsigned long, inet_num)
|
|||
return(htab+m);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(htab[m].inet_num < inet_num) m++; /* locate first entry that is > */
|
||||
|
||||
|
||||
if((hcnt+1) > htot) { /* need more space */
|
||||
htot += HALLOC_SIZE; /* add HALLOC_SIZE entries at a time */
|
||||
|
||||
|
||||
if(!(htab = (HTAB *) realloc(htab,sizeof(HTAB)*htot))) {
|
||||
perror("grow_htab realloc");
|
||||
exit(5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for(i = hcnt-m, hs = htab+hcnt, hd=htab+hcnt+1; i--; *--hd = *--hs);
|
||||
|
||||
|
||||
htab[m]=hzero;
|
||||
htab[m].inet_num = inet_num;
|
||||
htab[m].hostname = find_hostname(inet_num);
|
||||
|
|
@ -119,17 +119,17 @@ int dump_htab PROTO1(FILE *,fp)
|
|||
{
|
||||
int i;
|
||||
HTAB *hp;
|
||||
|
||||
|
||||
if( fp == NULL)
|
||||
{
|
||||
if(dbug)
|
||||
if(dbug)
|
||||
fp=stdout;
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
|
||||
fprintf(fp,"#FSP Server "PACKAGE_VERSION", dumping at %s\nHost table content:\n",ctime(&cur_time));
|
||||
|
||||
|
||||
fprintf(fp,"#IP address\tcount last access date\n");
|
||||
for(i = hcnt-2, hp = htab+1; i--; hp++) {
|
||||
fprintf(fp,"%d.%d.%d.%d\t%5d %s", ((unsigned char *)(&hp->inet_num))[0],
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ static char *check_ip PROTO2(unsigned long, inet_num, const IPrange *, iprange)
|
|||
unsigned char val[4];
|
||||
|
||||
inet_num = ntohl(inet_num);
|
||||
|
||||
|
||||
val[0] = (inet_num & 0x000000ff) ;
|
||||
val[1] = (inet_num & 0x0000ff00) >> 8;
|
||||
val[2] = (inet_num & 0x00ff0000) >> 16;
|
||||
|
|
@ -38,7 +38,7 @@ static char *check_ip PROTO2(unsigned long, inet_num, const IPrange *, iprange)
|
|||
|
||||
for (j = 0; j < 4; j++)
|
||||
if (iprange->lo[j] > val[j] || val[j] > iprange->hi[j]) return NULL;
|
||||
|
||||
|
||||
return iprange->text;
|
||||
}
|
||||
|
||||
|
|
@ -46,7 +46,7 @@ static char *check_ip PROTO2(unsigned long, inet_num, const IPrange *, iprange)
|
|||
const char *check_ip_table PROTO2(unsigned long, inet_num,IPrange *,table)
|
||||
{
|
||||
char *res;
|
||||
|
||||
|
||||
while(table)
|
||||
{
|
||||
if(!table->text) return NULL; /* EOT! */
|
||||
|
|
@ -77,7 +77,7 @@ void free_ip_table PROTO1(IPrange *,table)
|
|||
static unsigned char parse_ipcomponentnum PROTO1(const char * *, textp)
|
||||
{
|
||||
unsigned long val = 0;
|
||||
|
||||
|
||||
if (!isdigit(**textp)) {
|
||||
*textp = 0;
|
||||
} else
|
||||
|
|
@ -85,12 +85,12 @@ static unsigned char parse_ipcomponentnum PROTO1(const char * *, textp)
|
|||
val = 10 * val + (**textp - '0');
|
||||
(*textp)++;
|
||||
} while (isdigit(**textp));
|
||||
|
||||
|
||||
if (val > 0xff) {
|
||||
val = 0;
|
||||
*textp = 0;
|
||||
}
|
||||
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
|
|
@ -107,15 +107,15 @@ static const char *parse_ipcomponent PROTO3(const char *, text, unsigned char *,
|
|||
*hi = 0xff;
|
||||
return (text + 1);
|
||||
}
|
||||
|
||||
|
||||
*lo = parse_ipcomponentnum(&text);
|
||||
if (!text) return 0;
|
||||
|
||||
|
||||
if (*text == '-') {
|
||||
text++;
|
||||
*hi = parse_ipcomponentnum(&text);
|
||||
} else *hi = *lo;
|
||||
|
||||
|
||||
return text;
|
||||
}
|
||||
|
||||
|
|
@ -123,9 +123,9 @@ static IPrange *parse_ipnumber PROTO1(const char *, text)
|
|||
{
|
||||
IPrange *reply;
|
||||
int i;
|
||||
|
||||
|
||||
reply = (IPrange *)malloc(sizeof(IPrange));
|
||||
|
||||
|
||||
for (i = 3; i >= 0 && !isspace(*text); i--) {
|
||||
if (i < 3) {
|
||||
if (*text != '.') return 0;
|
||||
|
|
@ -137,14 +137,14 @@ static IPrange *parse_ipnumber PROTO1(const char *, text)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* fill in the gaps in the case that the loop terminated due to
|
||||
the occurrence of white-space */
|
||||
for (; i >= 0; i--) {
|
||||
reply->lo[i] = 0x00;
|
||||
reply->hi[i] = 0xff;
|
||||
}
|
||||
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
|
@ -154,23 +154,23 @@ static IPrange *parse_hostname PROTO2(const char *, text, unsigned int, len)
|
|||
struct hostent *hostaddr;
|
||||
unsigned long inet_num;
|
||||
char *hostname;
|
||||
|
||||
|
||||
hostname = malloc(len + 1);
|
||||
strncpy(hostname, text, len);
|
||||
hostname[len] = 0;
|
||||
|
||||
|
||||
hostaddr = gethostbyname(hostname);
|
||||
free(hostname);
|
||||
|
||||
|
||||
if (!hostaddr) return 0;
|
||||
|
||||
|
||||
reply = (IPrange *)malloc(sizeof(IPrange));
|
||||
inet_num = ((struct in_addr *)(hostaddr->h_addr))->s_addr;
|
||||
reply->lo[0] = reply->hi[0] = (inet_num & 0x000000ff) ;
|
||||
reply->lo[1] = reply->hi[1] = (inet_num & 0x0000ff00) >> 8;
|
||||
reply->lo[2] = reply->hi[2] = (inet_num & 0x00ff0000) >> 16;
|
||||
reply->lo[3] = reply->hi[3] = (inet_num & 0xff000000) >> 24;
|
||||
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
|
@ -192,12 +192,12 @@ static IPrange *parse_ipline PROTO1(const char *, text)
|
|||
char type = 0;
|
||||
const char *message = 0;
|
||||
size_t messlen = 0, addresslen;
|
||||
|
||||
|
||||
/* skip the leading white-space */
|
||||
skip_whitespace(text);
|
||||
skip_whitespace(text);
|
||||
/* if the line is commented or empty, ignore it */
|
||||
if (!*text || *text == '#') return 0;
|
||||
|
||||
|
||||
/* load hostname range (can not have spaces inside) */
|
||||
message = text;
|
||||
while (*message && !isspace(*message)) message++;
|
||||
|
|
@ -206,7 +206,7 @@ static IPrange *parse_ipline PROTO1(const char *, text)
|
|||
/* find the first non-space character after the address - this
|
||||
identifies the type of host this is */
|
||||
skip_whitespace(message);
|
||||
|
||||
|
||||
if (!*message || *message == '#') {
|
||||
fprintf(stderr, "No host type specified in config file:\n\t%s\n", text);
|
||||
/* if a host name is mentioned by itself, then treat it as ignored
|
||||
|
|
@ -216,28 +216,28 @@ static IPrange *parse_ipline PROTO1(const char *, text)
|
|||
|
||||
/* the first character after the host name is the type of host */
|
||||
type = *message;
|
||||
|
||||
|
||||
/* skip over the white space trailing the type - the start of the
|
||||
associated message */
|
||||
message++; /* remember skip_whitespace() is a macro... */
|
||||
skip_whitespace(message);
|
||||
|
||||
|
||||
/* `remove' the trailing white-space from the message */
|
||||
messlen = strlen(message);
|
||||
while (messlen > 0 && isspace(message[messlen-1])) messlen--;
|
||||
|
||||
|
||||
/* if the first character of the address is numerical or '*' then parse
|
||||
as a numerical address, otherwise we do a host lookup on the name. */
|
||||
if (*text == '*' || isdigit(*text))
|
||||
reply = parse_ipnumber(text);
|
||||
else
|
||||
reply = parse_hostname(text, addresslen);
|
||||
|
||||
|
||||
if (!reply) {
|
||||
fprintf(stderr, "Badly formed address in config file:\n\t%s\n", text);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* allocate a string to hold the message */
|
||||
reply->text = malloc(1 + messlen + 1); /* type + text + '\0' */
|
||||
if(!reply->text)
|
||||
|
|
@ -248,7 +248,7 @@ static IPrange *parse_ipline PROTO1(const char *, text)
|
|||
reply->text[0] = type;
|
||||
strncpy(&reply->text[1], message, messlen);
|
||||
reply->text[1 + messlen] = '\0';
|
||||
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
|
|
@ -258,7 +258,7 @@ void add_ipline PROTO2(const char *, text, IPrange **, table)
|
|||
IPrange *nl;
|
||||
IPrange *newtab;
|
||||
int i;
|
||||
|
||||
|
||||
nl = parse_ipline(text);
|
||||
if(!nl) return;
|
||||
/* add a new record to table */
|
||||
|
|
@ -287,7 +287,7 @@ void add_ipline PROTO2(const char *, text, IPrange **, table)
|
|||
|
||||
void dump_iptab PROTO2(IPrange *,table,FILE *, fp)
|
||||
{
|
||||
|
||||
|
||||
if(fp==NULL)
|
||||
{
|
||||
if(dbug)
|
||||
|
|
@ -295,7 +295,7 @@ void dump_iptab PROTO2(IPrange *,table,FILE *, fp)
|
|||
else
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
while(table) {
|
||||
if(!table->text) break;
|
||||
fprintf(fp, "%d-%d.%d-%d.%d-%d.%d-%d %c %s\n",
|
||||
|
|
|
|||
|
|
@ -72,7 +72,7 @@ void xferlog(char direction, const char *filename,unsigned long filesize,const c
|
|||
{
|
||||
size_t pos=0,timelen;
|
||||
char *timestr;
|
||||
|
||||
|
||||
if(!tlogname) return; /* xfer logging is not enabled */
|
||||
|
||||
/* current-time */
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ static void display_version PROTO0((void))
|
|||
{
|
||||
printf(
|
||||
"File Service Protocol Daemon - FSP "PACKAGE_VERSION"\n"
|
||||
"Copyright (c) 1991-1996 by A. J. Doherty, 2001-2003 by Radim Kolar.\n"
|
||||
"Copyright (c) 1991-1996 by A. J. Doherty, 2001-2004 by Radim Kolar.\n"
|
||||
"All of the FSP code is free software with revised BSD license.\n"
|
||||
"Portions copyright by BSD, Wen-King Su, Philip G. Richards, Michael Meskes.\n"
|
||||
#ifdef __GNUC__
|
||||
|
|
@ -37,15 +37,15 @@ static void display_version PROTO0((void))
|
|||
|
||||
static void arg_err PROTO0((void))
|
||||
{
|
||||
fputs("Usage: fspd [-f configfile] [-d directory] [-v|-V] [-i] [-F] [-p port] [-X] [-t timeout] [-T temporary directory] [-l logfile] [-P pidlogname]\n", stderr);
|
||||
fputs("Usage: fspd [-f configfile] [-d directory] [-v|-V] [-i] [-F] [-p port] [-X] [-t timeout] [-T temporary directory] [-l logfile] [-P pidlogname] [-b bytes/sec]\n", stderr);
|
||||
}
|
||||
|
||||
static void check_required_vars PROTO0((void))
|
||||
{
|
||||
double rnd;
|
||||
|
||||
|
||||
if(!inetd_mode && udp_port==0) {
|
||||
fprintf(stderr, "No port set. Exiting. (Use 65535 for random port)\n");
|
||||
fprintf(stderr, "Error: No port set. (Use 65535 for random port)\n");
|
||||
exit(1);
|
||||
}
|
||||
if(udp_port == 65535)
|
||||
|
|
@ -55,17 +55,21 @@ static void check_required_vars PROTO0((void))
|
|||
udp_port=rnd*(65535-1024)+1024;
|
||||
}
|
||||
if(!home_dir) {
|
||||
fprintf(stderr, "No home directory set.\n");
|
||||
fprintf(stderr, "Error: No home directory set.\n");
|
||||
exit(1);
|
||||
}
|
||||
if(*home_dir != '/') {
|
||||
fprintf(stderr,"home directory [%s] does not start with a /.\n", home_dir);
|
||||
exit(1);
|
||||
#if 0
|
||||
if(*home_dir != '/') {
|
||||
fprintf(stderr,"Error: home directory [%s] does not start with a /.\n", home_dir);
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
#if 0
|
||||
if(!pidlogname) {
|
||||
fprintf(stderr, "No pidlogname set in your fspd.conf.\n");
|
||||
exit(1);
|
||||
}
|
||||
#endif
|
||||
if(!readme_file) {
|
||||
readme_file = strdup(".README");
|
||||
}
|
||||
|
|
@ -78,7 +82,7 @@ static void check_required_vars PROTO0((void))
|
|||
dbug = 0;
|
||||
if(!tmp_dir && !read_only)
|
||||
{
|
||||
if(!inetd_mode)
|
||||
if(!inetd_mode)
|
||||
fprintf(stderr,"Warning: no tmpdir set, switching to readonly mode.\n");
|
||||
read_only = 1;
|
||||
}
|
||||
|
|
@ -104,11 +108,11 @@ int main PROTO2(int, argc, char **, argv)
|
|||
{
|
||||
int opt;
|
||||
long inetd_timeout=0;
|
||||
|
||||
|
||||
if(strlen(argv[0])>=7)
|
||||
inetd_mode = !strcasecmp(&argv[0][strlen(argv[0])-7],"in.fspd");
|
||||
|
||||
while( (opt=getopt(argc,argv,"h?Xd:f:vVip:t:FT:l:P:"))!=EOF)
|
||||
while( (opt=getopt(argc,argv,"h?Xd:f:vVip:t:FT:l:P:b:"))!=EOF)
|
||||
{
|
||||
switch(opt)
|
||||
{
|
||||
|
|
@ -143,6 +147,9 @@ int main PROTO2(int, argc, char **, argv)
|
|||
case 'p':
|
||||
udp_port = atoi (optarg);
|
||||
break;
|
||||
case 'b':
|
||||
maxthcallowed = atoi (optarg);
|
||||
break;
|
||||
case 't':
|
||||
inetd_timeout = 1000L * atoi (optarg);
|
||||
break;
|
||||
|
|
@ -171,7 +178,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
{
|
||||
opt=_x_udp(&udp_port);
|
||||
if(opt == -1) {
|
||||
perror("socket open");
|
||||
perror("Error: socket open");
|
||||
exit(2);
|
||||
}
|
||||
if(dbug) {
|
||||
|
|
@ -190,14 +197,14 @@ int main PROTO2(int, argc, char **, argv)
|
|||
fprintf(stderr,"Can not change my uid to %d.\n",run_uid);
|
||||
exit(3);
|
||||
}
|
||||
|
||||
|
||||
if(run_gid) if(setgid(run_gid) != 0) {
|
||||
fprintf(stderr,"Can not change my gid to %d.\n",run_uid);
|
||||
exit(4);
|
||||
}
|
||||
|
||||
init_home_dir();
|
||||
|
||||
|
||||
if(init_caches())
|
||||
{
|
||||
perror("init_caches");
|
||||
|
|
@ -205,13 +212,13 @@ int main PROTO2(int, argc, char **, argv)
|
|||
}
|
||||
|
||||
umask(system_umask);
|
||||
|
||||
|
||||
if (logging) {
|
||||
if (dbug)
|
||||
if (dbug)
|
||||
fprintf(stderr,"logging to %s\n",logname);
|
||||
/* test to see if logfile can be written */
|
||||
/* open it append mode so that it doesn't wipe the file when
|
||||
* you are running under inetd.
|
||||
* you are running under inetd.
|
||||
*/
|
||||
if((logfd=open(logname, O_WRONLY | O_APPEND | O_CREAT, 0640)) < 0) {
|
||||
if(! inetd_mode )
|
||||
|
|
@ -223,11 +230,11 @@ int main PROTO2(int, argc, char **, argv)
|
|||
|
||||
if(tlogname)
|
||||
{
|
||||
if (dbug)
|
||||
if (dbug)
|
||||
fprintf(stderr,"logging transfers to %s\n",tlogname);
|
||||
|
||||
/* test to see if logfile can be written */
|
||||
if((tlogfd=open(tlogname, O_WRONLY | O_APPEND | O_CREAT, 0640)) < 0)
|
||||
if((tlogfd=open(tlogname, O_WRONLY | O_APPEND | O_CREAT, 0640)) < 0)
|
||||
{
|
||||
if(! inetd_mode )
|
||||
fprintf(stderr, "Error opening transferfile: %s, transfer logging disabled.\n",tlogname);
|
||||
|
|
@ -236,6 +243,17 @@ int main PROTO2(int, argc, char **, argv)
|
|||
}
|
||||
}
|
||||
|
||||
/* With pidfile we have currently 2 problems:
|
||||
1) creating pidfile after we have droped root rights. We can not
|
||||
write to root only directories like /var/run
|
||||
2) If we create pidfile early before setuid() we can't write
|
||||
new pid to it after we setuid()+fork()
|
||||
*/
|
||||
if (pidfile(pidlogname)) {
|
||||
fprintf(stderr,"Error: can not write pidfile - exiting.\n");
|
||||
exit(1);/* cannot write pid file - exit */
|
||||
}
|
||||
|
||||
init_htab();
|
||||
/* we can enable table dumping from there */
|
||||
signal(SIGINT,server_interrupt);
|
||||
|
|
@ -264,7 +282,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
freopen(NULL_DEV,"w",stderr);
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(!inetd_mode) {
|
||||
/* Fork and die to drop daemon into background */
|
||||
/* Added Alban E J Fellows 12 Jan 93 */
|
||||
|
|
@ -274,8 +292,10 @@ int main PROTO2(int, argc, char **, argv)
|
|||
pid_t forkpid;
|
||||
forkpid = fork();
|
||||
if (forkpid == 0) { /* child prozess */
|
||||
if (pidfile(pidlogname))
|
||||
if (pidfile(pidlogname)) {
|
||||
pidfile_cleanup(pidlogname); /* try cleanup */
|
||||
exit(1);/* cannot write pid file - exit */
|
||||
}
|
||||
} else if (forkpid > 0) { /* father prozess */
|
||||
_exit(0);
|
||||
}
|
||||
|
|
@ -288,7 +308,7 @@ int main PROTO2(int, argc, char **, argv)
|
|||
|
||||
while(1)
|
||||
{
|
||||
server_loop(opt,inetd_timeout);
|
||||
server_loop(opt,inetd_timeout);
|
||||
if(inetd_mode||dbug||shutdowning) break;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
*
|
||||
* The PPATH structure is filled in by the function check_path when given a
|
||||
* path string. The elements are filled in as such:
|
||||
*
|
||||
*
|
||||
* fullp pointer to a string containing the full path name
|
||||
* f_ptr pointer to begining of the last component of the path
|
||||
* f_len length of the last component of the path
|
||||
|
|
@ -43,32 +43,32 @@ const char *parse_path PROTO3(char *, fullp, unsigned int, len, PPATH *, pp)
|
|||
|
||||
if(len < 1) return("Path must have non-zero length");
|
||||
if(fullp[len-1]) return("Path must be null terminated");
|
||||
|
||||
|
||||
pp->passwd = NULL; /* default, no password */
|
||||
pp->d_len = 0;
|
||||
|
||||
|
||||
for(
|
||||
s = pp->fullp = pp->f_ptr = pp->d_ptr = fullp, state = 0;
|
||||
*s;
|
||||
*s;
|
||||
s++
|
||||
)
|
||||
)
|
||||
{
|
||||
if(*s == '\n')
|
||||
if(*s == '\n')
|
||||
{
|
||||
p=strrchr(pp->fullp,'\n');
|
||||
pp->passwd = p+1;
|
||||
pp->passwd = p+1;
|
||||
*p = '\0';
|
||||
*s = '\0';
|
||||
if(dbug) fprintf(stderr,"parse_path: found password field %s\n", p+1);
|
||||
break;
|
||||
}
|
||||
else
|
||||
else
|
||||
if(*s < ' ') return("Path contains control chars");
|
||||
else
|
||||
if(*s >= '~') return("Path contains high chars");
|
||||
|
||||
switch(*s)
|
||||
|
||||
switch(*s)
|
||||
{
|
||||
case '\\':
|
||||
case '.':
|
||||
|
|
@ -99,14 +99,14 @@ const char *parse_path PROTO3(char *, fullp, unsigned int, len, PPATH *, pp)
|
|||
}
|
||||
|
||||
/* pp->d_len = pp->f_ptr - pp->fullp; */
|
||||
|
||||
|
||||
/* turn empty directory into "." */
|
||||
if(pp->d_len == 0)
|
||||
{
|
||||
pp->d_ptr = ".";
|
||||
pp->d_len = 1;
|
||||
}
|
||||
|
||||
|
||||
pp->f_len = s - pp->f_ptr;
|
||||
|
||||
/* turn empty file into "." */
|
||||
|
|
@ -115,13 +115,13 @@ const char *parse_path PROTO3(char *, fullp, unsigned int, len, PPATH *, pp)
|
|||
pp->f_ptr = ".";
|
||||
pp->f_len = 1;
|
||||
}
|
||||
|
||||
|
||||
/* turn empty fullp into "." */
|
||||
if(pp->fullp[0] == 0)
|
||||
{
|
||||
{
|
||||
/* null path --> root */
|
||||
pp->fullp = ".";
|
||||
}
|
||||
|
||||
|
||||
return(NULLP);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
* This code is derived from software contributed to The NetBSD Foundation
|
||||
* by Jason R. Thorpe.
|
||||
*
|
||||
* Modified by Sven Hoaxter and Radim Kolar for FSP project.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
|
|
@ -45,19 +47,18 @@
|
|||
|
||||
static pid_t pidfile_pid;
|
||||
|
||||
int pidfile(char *pidfile_path)
|
||||
int pidfile(const char *pidfile_path)
|
||||
{
|
||||
FILE *f;
|
||||
int save_errno;
|
||||
pid_t pid;
|
||||
|
||||
if (pidfile_path == NULL)
|
||||
return (-1);
|
||||
return (0);
|
||||
|
||||
if ((f = fopen(pidfile_path, "w")) == NULL) {
|
||||
save_errno = errno;
|
||||
free(pidfile_path);
|
||||
pidfile_path = NULL;
|
||||
(void) unlink(pidfile_path);
|
||||
errno = save_errno;
|
||||
return (-1);
|
||||
}
|
||||
|
|
@ -66,8 +67,6 @@ int pidfile(char *pidfile_path)
|
|||
if (fprintf(f, "%ld\n", (long)pid) <= 0 || fclose(f) != 0) {
|
||||
save_errno = errno;
|
||||
(void) unlink(pidfile_path);
|
||||
free(pidfile_path);
|
||||
pidfile_path = NULL;
|
||||
errno = save_errno;
|
||||
return (-1);
|
||||
}
|
||||
|
|
@ -77,7 +76,9 @@ int pidfile(char *pidfile_path)
|
|||
}
|
||||
|
||||
|
||||
void pidfile_cleanup(char *pidfile_path)
|
||||
void pidfile_cleanup(const char *pidfile_path)
|
||||
{
|
||||
if (pidfile_path) {
|
||||
(void) unlink(pidfile_path);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
int pidfile(char *);
|
||||
void pidfile_cleanup(char *);
|
||||
int pidfile(const char *);
|
||||
void pidfile_cleanup(const char *);
|
||||
|
|
|
|||
|
|
@ -7,6 +7,13 @@
|
|||
****************************************************************************/
|
||||
|
||||
|
||||
/* get high bits from random result - better */
|
||||
unsigned short gen_next_key PROTO0((void))
|
||||
{
|
||||
return (random() >> 15);
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* The following algorithm is recommended by Numerical Recipies. */
|
||||
/* Best, but needs floating point division. */
|
||||
unsigned short gen_next_key PROTO0 ((void))
|
||||
|
|
@ -14,15 +21,16 @@ unsigned short gen_next_key PROTO0 ((void))
|
|||
unsigned short ulRandom = ((float)(0xffff)*rand()/(RAND_MAX+1.0f));
|
||||
return(ulRandom);
|
||||
}
|
||||
|
||||
#if 0
|
||||
#endif
|
||||
#if 0
|
||||
/* FSP original */
|
||||
unsigned short gen_next_key PROTO0((void))
|
||||
{
|
||||
unsigned long k;
|
||||
|
||||
|
||||
k = random();
|
||||
k = k ^ (k >> 8) ^ (k >> 16) ^ (k << 8);
|
||||
|
||||
|
||||
return k;
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -142,11 +142,11 @@ static const char * print_command(unsigned char cmd)
|
|||
static void send_error PROTO3(struct sockaddr_in *, from, UBUF *, ub, const char *, msg)
|
||||
{
|
||||
size_t sz;
|
||||
|
||||
|
||||
sz=strlen(msg)+1;
|
||||
memcpy(ub->buf,msg,sz);
|
||||
ub->cmd = CC_ERR;
|
||||
|
||||
|
||||
server_reply(from,ub,sz,0);
|
||||
}
|
||||
|
||||
|
|
@ -168,7 +168,7 @@ int server_loop PROTO2(int, fd, time_t, timeout)
|
|||
socklen_t bytes;
|
||||
unsigned char *s, *d, *t;
|
||||
fd_set mask;
|
||||
|
||||
|
||||
FD_ZERO(&mask);
|
||||
myfd=fd;
|
||||
|
||||
|
|
@ -190,7 +190,7 @@ int server_loop PROTO2(int, fd, time_t, timeout)
|
|||
dump_htab(fp);
|
||||
dump_iptab(iptab,fp);
|
||||
stat_caches(fp);
|
||||
if(fp)
|
||||
if(fp)
|
||||
{
|
||||
fclose(fp);
|
||||
}
|
||||
|
|
@ -199,13 +199,13 @@ int server_loop PROTO2(int, fd, time_t, timeout)
|
|||
if(shutdowning) return 1;
|
||||
|
||||
retval = _x_select(&mask, timeout);
|
||||
|
||||
|
||||
if(retval == -1) {
|
||||
if(errno == EINTR) continue;
|
||||
perror("select");
|
||||
exit(7);
|
||||
}
|
||||
|
||||
|
||||
if(retval == 1) { /* an incoming message is waiting */
|
||||
bytes = sizeof(from);
|
||||
if((bytes = recvfrom(myfd,(char*)&rbuf,sizeof(rbuf),0,
|
||||
|
|
@ -214,19 +214,19 @@ int server_loop PROTO2(int, fd, time_t, timeout)
|
|||
if(dbug) fprintf(stderr,"Header truncated.\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
rlen = BB_READ2(rbuf.bb_len);
|
||||
if((rlen+UBUF_HSIZE) > bytes)
|
||||
if((rlen+UBUF_HSIZE) > bytes)
|
||||
{
|
||||
if(dbug) fprintf(stderr,"Message truncated.\n");
|
||||
continue; /* truncated. */
|
||||
}
|
||||
|
||||
|
||||
if(!(ir = check_ip_table(from.sin_addr.s_addr,iptab)))
|
||||
{ /* host not found in table */
|
||||
ir = priv_mode ? "DFSP service not available": "N";
|
||||
}
|
||||
|
||||
|
||||
switch (*ir) {
|
||||
case 'D': /* disabled host - return error message */
|
||||
if (rbuf.cmd == CC_BYE)
|
||||
|
|
@ -241,17 +241,17 @@ int server_loop PROTO2(int, fd, time_t, timeout)
|
|||
fputs("check_ip() returned illegal host type\n",stderr);
|
||||
exit(99);
|
||||
}
|
||||
|
||||
|
||||
hp = find_host(from.sin_addr.s_addr);
|
||||
|
||||
if(hp->hostname == 0 && no_unnamed) {
|
||||
send_error(&from,&rbuf, REVERSE_ERR_MSG);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
old = 0;
|
||||
cur_time = time((time_t *) 0);
|
||||
|
||||
|
||||
rkey = BB_READ2(rbuf.bb_key);
|
||||
if(hp->next_key != rkey) {
|
||||
if(!hp->active)
|
||||
|
|
@ -259,16 +259,16 @@ int server_loop PROTO2(int, fd, time_t, timeout)
|
|||
else {
|
||||
if(hp->last_key == rkey) {
|
||||
if(cur_time < hp->last_acc + retry_timeout) {
|
||||
if(dbug) fprintf(stderr,"Ignoring too early retry request (rtime=%ld,timeout=%d).\n",cur_time-hp->last_acc,(int)retry_timeout);
|
||||
if(dbug) fprintf(stderr,"Ignoring too early retry request (rtime=%ld,timeout=%d).\n",(long)cur_time-hp->last_acc,(int)retry_timeout);
|
||||
continue;
|
||||
}
|
||||
old = 1;
|
||||
} else {
|
||||
if(cur_time < hp->last_acc + session_timeout ) {
|
||||
if(dbug) fprintf(stderr,"Request with bad key (rtime=%ld,timeout=%d).\n",cur_time-hp->last_acc, (int)session_timeout);
|
||||
if(dbug) fprintf(stderr,"Request with bad key (rtime=%ld,timeout=%d).\n",(long)cur_time-hp->last_acc, (int)session_timeout);
|
||||
continue;
|
||||
}
|
||||
hp->active = 0;
|
||||
hp->active = 0;
|
||||
hp->next_key = rkey;
|
||||
}
|
||||
}
|
||||
|
|
@ -284,12 +284,12 @@ int server_loop PROTO2(int, fd, time_t, timeout)
|
|||
u = rbuf.sum; rbuf.sum = 0;
|
||||
for(t = s, sum = bytes; t < d; sum += *t++);
|
||||
sum = (sum + (sum >> 8)) & 0xff;
|
||||
if(sum != u)
|
||||
if(sum != u)
|
||||
{
|
||||
if(dbug) fprintf(stderr,"Wrong checksum got %x, expected %x\n",u,sum);
|
||||
continue; /* wrong check sum */
|
||||
}
|
||||
|
||||
|
||||
server_process_packet(bytes,&rbuf,old,hp,&from);
|
||||
} else return(0); /* got a timeout */
|
||||
}
|
||||
|
|
@ -309,23 +309,23 @@ int server_reply PROTO4(struct sockaddr_in *, from, UBUF *, ub,
|
|||
unsigned sum;
|
||||
int i;
|
||||
unsigned int thcsum;
|
||||
|
||||
if(dbug)
|
||||
|
||||
if(dbug)
|
||||
fprintf(stderr,"snd (%s,key=0x%0X,seq=0x%0X,len=%d,len2=%d,pos=%u) ---> %d.%d.%d.%d\n",
|
||||
print_command(ub->cmd), BB_READ2(ub->bb_key), BB_READ2(ub->bb_seq),len1, len2, BB_READ4(ub->bb_pos),
|
||||
((unsigned char *)(&(from->sin_addr.s_addr)))[0],
|
||||
((unsigned char *)(&(from->sin_addr.s_addr)))[1],
|
||||
((unsigned char *)(&(from->sin_addr.s_addr)))[2],
|
||||
((unsigned char *)(&(from->sin_addr.s_addr)))[3]);
|
||||
|
||||
|
||||
BB_WRITE2(ub->bb_len,len1);
|
||||
|
||||
|
||||
ub->sum = 0;
|
||||
s = (unsigned char *) ub;
|
||||
d = s + (len1 + len2 + UBUF_HSIZE);
|
||||
for(t = s, sum = 0; t < d; sum += *t++);
|
||||
ub->sum = sum + (sum >> 8);
|
||||
|
||||
|
||||
/*
|
||||
* Check that we do not exceed maximum throughput allowed before sending
|
||||
*/
|
||||
|
|
@ -358,7 +358,7 @@ fprintf(stderr,"\n") ;
|
|||
if(dbug) fprintf(stderr, "Throughput too high, waiting.\n");
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
|
||||
if(sendto(myfd,(char *)ub,(len1 + len2 + UBUF_HSIZE),0,
|
||||
(struct sockaddr *)from,sizeof(struct sockaddr_in)) == -1) {
|
||||
perror("sendto");
|
||||
|
|
@ -380,7 +380,7 @@ void send_file PROTO5(struct sockaddr_in *, from, UBUF *, ub, FILE *, fp,
|
|||
size_t bytes;
|
||||
unsigned len;
|
||||
unsigned long pos;
|
||||
|
||||
|
||||
if(has_len == 2) { /* recover length field if it exists */
|
||||
len=lp[0] << 8;
|
||||
len = len + lp[1];
|
||||
|
|
@ -388,23 +388,23 @@ void send_file PROTO5(struct sockaddr_in *, from, UBUF *, ub, FILE *, fp,
|
|||
} else len = packetsize; /* use default if it doesn't exist */
|
||||
|
||||
pos = BB_READ4(ub->bb_pos);
|
||||
|
||||
|
||||
#ifndef NATIVE_LARGEFILES
|
||||
#if SIZEOF_OFF_T == 4
|
||||
if(pos>TWOGIGS)
|
||||
len=0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
if(fseeko(fp,pos,SEEK_SET))
|
||||
{
|
||||
/* seek failed, do not send any more data */
|
||||
/* TODO: or can we return error instead? */
|
||||
len=0;
|
||||
}
|
||||
|
||||
|
||||
bytes = fread(ub->buf, 1, len, fp);
|
||||
|
||||
|
||||
server_reply(from,ub,bytes,0);
|
||||
}
|
||||
|
||||
|
|
@ -416,6 +416,7 @@ void send_file PROTO5(struct sockaddr_in *, from, UBUF *, ub, FILE *, fp,
|
|||
static void server_show_version PROTO2(struct sockaddr_in *, from, UBUF *, ub)
|
||||
{
|
||||
char buf[UBUF_SPACE], verflags = 0;
|
||||
unsigned int xtra = VER_BYTES;
|
||||
|
||||
strcpy(buf, "fspd " PACKAGE_VERSION);
|
||||
strcat(buf, "\n");
|
||||
|
|
@ -427,24 +428,22 @@ static void server_show_version PROTO2(struct sockaddr_in *, from, UBUF *, ub)
|
|||
if (maxthcallowed) verflags |= VER_THRUPUT;
|
||||
|
||||
strcpy(ub->buf, buf);
|
||||
BB_WRITE4(ub->bb_pos,VER_BYTES);
|
||||
ub->buf[strlen(ub->buf)] = '\0';
|
||||
ub->buf[strlen(ub->buf)+1] = verflags;
|
||||
/* add optional thruput data */
|
||||
if(maxthcallowed) {
|
||||
BB_WRITE4(ub->bb_pos,VER_BYTES+4);
|
||||
ub->buf[strlen(ub->buf)+2] = (char)((maxthcallowed & 0xff000000)>>24);
|
||||
ub->buf[strlen(ub->buf)+3] = (char)((maxthcallowed & 0x00ff0000)>>16);
|
||||
ub->buf[strlen(ub->buf)+4] = (char)((maxthcallowed & 0x0000ff00)>>8);
|
||||
ub->buf[strlen(ub->buf)+5] = (char)(maxthcallowed & 0x000000ff);
|
||||
|
||||
server_reply(from, ub, strlen(ub->buf)+1, VER_BYTES+4);
|
||||
} else {
|
||||
server_reply(from, ub, strlen(ub->buf)+1, VER_BYTES);
|
||||
BB_WRITE4(ub->buf+strlen(ub->buf)+2,maxthcallowed);
|
||||
xtra+=4;
|
||||
}
|
||||
/* Add packetsize - 2.8.1 b20 extension */
|
||||
BB_WRITE2(ub->buf+strlen(ub->buf)+xtra+1,packetsize);
|
||||
xtra+=2;
|
||||
BB_WRITE4(ub->bb_pos,xtra);
|
||||
server_reply(from, ub, strlen(ub->buf)+1, xtra);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* This is the dispatch loop for message that has been accepted.
|
||||
* This is the dispatch loop for message that has been accepted.
|
||||
* Serves command in message and sends out a reply.
|
||||
* bytes: size of the message received.
|
||||
* ub: pointer to the message buffer.
|
||||
|
|
@ -807,7 +806,7 @@ static void server_process_packet PROTO5(unsigned, bytes, UBUF *, ub, int, old,
|
|||
ACTIONLOG1(L_GRABFILE,"GRABFILE");
|
||||
}
|
||||
pe = validate_path(s1,l1,&pp,&di,0);
|
||||
if(pe)
|
||||
if(pe)
|
||||
{
|
||||
ACTIONLOG1(L_ERR|L_GRABFILE,"GRABFILE");
|
||||
ACTIONFAILED(L_ERR|L_GRABFILE,pe);
|
||||
|
|
@ -827,7 +826,7 @@ static void server_process_packet PROTO5(unsigned, bytes, UBUF *, ub, int, old,
|
|||
}
|
||||
}
|
||||
pe = server_grab_file(&fp, inet_num, port_num);
|
||||
if(pe)
|
||||
if(pe)
|
||||
{
|
||||
ACTIONLOG1(L_ERR|L_GRABFILE,"GRABFILE");
|
||||
ACTIONFAILED(L_ERR|L_GRABFILE,pe);
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ int main(int argv,char **argc)
|
|||
|
||||
cache=f_cache_new(4,0,0,sizeof(char *),string_free,string_compare);
|
||||
assert(cache!=NULL);
|
||||
|
||||
|
||||
s="lamer1";
|
||||
f_cache_put(cache,&s,NULL);
|
||||
s="lamer2";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
/* this file is public domain */
|
||||
/* return values:
|
||||
/* return values:
|
||||
* 3 - invocation error
|
||||
* 2 - no LFS support
|
||||
* 1 - file creation failed
|
||||
|
|
@ -20,7 +20,7 @@ int main(int argc,char *argv[])
|
|||
FILE *fd;
|
||||
off_t pos;
|
||||
float size;
|
||||
|
||||
|
||||
if(argc<3)
|
||||
{
|
||||
printf("Makes a large file with hole using fseeko\n");
|
||||
|
|
@ -35,7 +35,7 @@ int main(int argc,char *argv[])
|
|||
return 1;
|
||||
}
|
||||
size=atof(argv[2]);
|
||||
#if SIZEOF_OFF_T <= 4
|
||||
#if SIZEOF_OFF_T <= 4
|
||||
if(size>2)
|
||||
{
|
||||
printf("You do not have LFS your system.\nMaximum supported filesize is 2 GB.\n");
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
|
||||
int dbug=1;
|
||||
|
||||
const char *testcases[]={
|
||||
const char *testcases[]={
|
||||
"", ".","/",
|
||||
"filename","/filename","//filename",
|
||||
"dirname/filename","//dirname/filename","//dirname//filename",
|
||||
|
|
@ -26,7 +26,7 @@ PPATH testresults[]={
|
|||
{"dir1name/dir2name/",".",1,"dir1name/dir2name",17}, {"dir1name//dir2name//",".",1,"dir1name//dir2name",18},
|
||||
{"filename","filename",8,".",1,"passwd"}, {"filename","filename",8,".",1,"passwd"},
|
||||
{NULL},{NULL},{NULL},
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
|
@ -45,7 +45,7 @@ static void print_path(PPATH *pp)
|
|||
}
|
||||
|
||||
/* returns: 0 okay, 1 different */
|
||||
|
||||
|
||||
static int compareresults(PPATH *p1,PPATH *p2)
|
||||
{
|
||||
if(p1->fullp==NULL && p2->fullp==NULL) return 0;
|
||||
|
|
@ -76,7 +76,7 @@ static int runtestcase(void)
|
|||
pp.fullp=NULL;
|
||||
err=parse_path(test,strlen(test)+1,&pp);
|
||||
printf("parsing: '%s'",test);
|
||||
if(err)
|
||||
if(err)
|
||||
{
|
||||
printf(" parse err: '%s'. ",err);
|
||||
pp.fullp=NULL;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@
|
|||
static int bitcount[16];
|
||||
static int rounds;
|
||||
static int result;
|
||||
#define MAX_WORST_ALLOWED 0.2f
|
||||
#define MAX_WORST_ALLOWED 0.1f
|
||||
|
||||
/* FSP classic algo */
|
||||
static unsigned short classic PROTO0((void))
|
||||
|
|
@ -44,7 +44,7 @@ static void run_randomtest( unsigned short (*keygen)(void) )
|
|||
{
|
||||
int i,j;
|
||||
unsigned short rnd;
|
||||
|
||||
|
||||
/* zero bitcount first */
|
||||
memset(bitcount,0,16*sizeof(int));
|
||||
|
||||
|
|
@ -66,7 +66,7 @@ static void print_bitcount(void)
|
|||
int i;
|
||||
float worst;
|
||||
float ratio;
|
||||
|
||||
|
||||
printf("Set ratio: ");
|
||||
worst=0;
|
||||
|
||||
|
|
@ -84,20 +84,20 @@ static void print_bitcount(void)
|
|||
|
||||
int main(int argc,const char *argv[])
|
||||
{
|
||||
rounds=200;
|
||||
rounds=2000;
|
||||
if(argc>1)
|
||||
{
|
||||
rounds=atoi(argv[1]);
|
||||
}
|
||||
|
||||
printf("Running %d rounds.\n\n",rounds);
|
||||
|
||||
|
||||
result=0;
|
||||
|
||||
printf("Generator: classic\n");
|
||||
run_randomtest(classic);
|
||||
print_bitcount();
|
||||
|
||||
|
||||
printf("Generator: simple\n");
|
||||
run_randomtest(simple);
|
||||
print_bitcount();
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user