pax_global_header00006660000000000000000000000064151103646430014515gustar00rootroot0000000000000052 comment=3e3dbbef681c1e01cdb45dfbac54f7398e91bb26 tftp-hpa-5.3+20251209/000077500000000000000000000000001511036464300140075ustar00rootroot00000000000000tftp-hpa-5.3+20251209/.editorconfig000066400000000000000000000002361511036464300164650ustar00rootroot00000000000000root = true [*] end_of_line = lf trim_trailing_whitespace = true insert_final_newline = true [{*.c,*.h}] indent_style = space indent_size = 4 tab_width = 8 tftp-hpa-5.3+20251209/.gitignore000066400000000000000000000003501511036464300157750ustar00rootroot00000000000000/config/MCONFIG /config/config.h /config/config.h.in /autoconf/aclocal.m4 /autoconf/clean.sh /autoconf/helpers/ /autom4te.cache /config.log /config.status /configure /version.h /tftp/tftp /tftpd/tftpd *.1 *.8 *.a *.o *.i *.s *~ \#* tftp-hpa-5.3+20251209/CHANGES000066400000000000000000000243231511036464300150060ustar00rootroot00000000000000Changes in 5.2: Fix breakage on newer Linux when a single interface has multiple IP addresses. Changes in 5.1: Add -P option to write a PID file. Patch by Ferenc Wagner. Bounce the tftpd_log socket in standalone mode, in case the tftpd_log daemon has been restarted. Patch by Ferenc Wagner. Build fixes. Fix handling of block number wraparound after a successful options negotiation. Fix a buffer overflow in option parsing. Changes in 5.0: Try to on platforms with getaddrinfo() without AI_ADDRCONFIG or AI_CANONNAME. Implement the "rollover" option, for clients which want block number to rollover to anything other than zero. Correctly disable PMTU in standalone mode. Patch by Florian Lohoff. Changes in 0.49: Add IPv6 support. Patch by Karsten Keil. Support systems with editline instead of readline. Support long options in the server. Changes in 0.48: Unbreak -l -s in the server, which was broken in 0.47. Changes in 0.47: Add -L option to the server to run standalone without detaching from the shell. Parallel make fix. Changes in 0.46: Minor portability improvements. Changes in 0.45: Add -l (literal) option to the client, to override the special treatment of the colon (:) character as a hostname separator. Changes in 0.44: Allow the client to specify a range of local port numbers, just like the server can. Fix sending SIGHUP to update the regular expression table. Changes in 0.43: Fix double-free error on ^c in client. Try to deal with clients that send TFTP requests to broadcasts (apparently some recent Sun boxes do this instead of using the address told by DHCP. Bad Sun! Bad Sun!) Portability fixes. Changes in 0.42: Try to disable path MTU discovery for TFTP connections (it's useless anyway.) Add a hack to allow the admin to specify a range of local port numbers to use. Fix local IP number handling on systems which present IP_RECVDSTADDR in recvmsg(). Changes in 0.41: Fix bug by which patterns of the form \U\1 weren't converted correctly. Changes in 0.40.1: Solaris build fix. Changes in 0.40: Fix bug which would cause "r" remapping rules to be incorrectly rejected. Changes in 0.39: Support Perl-style \U...\E and \L...\E, as well as allow matching rules to be inverted (execute if rule *doesn't* match.) Fix a timeout bug. Add an RPM spec file. Changes in 0.38: Portability fixes. Changes in 0.37: Fix a pathology where a client sending ACKs for the wrong packet can prevent proper retransmission. Changes in 0.36: Portability fixes. Changes in 0.35: Add an option to control the maximum value of blksize negotiated. Removed workaround for obsolete Cygwin problem. Don't use getopt() -- the -c option doesn't work correctly since it depends on the ordering of arguments and options. It is now possible to do: tftp -m binary hostname -c get filename This was previous possible by doing: tftp -m binary -c get hostname:filename ... but it seemed that was counterintuitive to people. Somewhat improved configure scripts. Changes in 0.34: Additional Solaris gcc compiler bug workarounds; these actually make the code somewhat cleaner. Changes in 0.33: Even better error messages. Work around a suspect Solaris gcc bug. Configuration fix: readline needs termcap. Support running the tftp client from the command line. For example: tftp -m binary -c get hostname:file Changes in 0.32: Better error messages; including the capability to send a custom error message to the client when hitting an "a" rule in a remapping table. Changes in 0.31: Put in a check to make sure xinetd (in particular) doesn't pass us an IPv6 socket. Fix some problems related to timeout negotiation. Allow the user to set the default timeout speed. Changes in 0.30: (Hopefully) better timeout algorithm. Add a "utimeout" option; like "timeout" but in microseconds. Change the log level of client-side errors to LOG_WARNING. autoconf portability improvements. Minor bugfixes. Changes in 0.29: Posixly correctness. Now compiles and runs on Win32 systems using Cygwin (http://www.cygwin.com/). (). Fixed a bug which could cause a standalone server to exit with a "recvfrom: Interrupted system call" log message if signals arrive at a particularly inopportune moment. Fix a macro substitution bug (thanks to Richard Nyberg.) Changes in 0.28: Fix stupid one-liner bug which broke standalone mode (-l). Changes in 0.27: Make the Digital Unix 4.0F platform work again. Thanks to Alan Sundell for helping out with this platform! Make the AIX 4.3 platform work again. Thanks to Josef Siemes for helping out with this platform! Allow replacement patterns to include the IP address of the requesting host (\i). Allow relying on Unix permissions rather than o+r magic if the -p option is specified. As part of this, set all groups if initgroups() is specified on the platform. Clean up race conditions inherited from the BSD source base. Changes in 0.26: Fix the configuration process so tftpd doesn't end up depending on readline, which apparently could happen on some platforms before. Make parallel builds (make -j) work correctly. Improve parsing of the "connect" command in the tftp client. Add a -V option to both tftp and tftpd to print the version number on stdout and immediately exit. Add a -v option to tftp to start out in verbose mode. Rewrite the man pages using standard "man" troff macros. Enable the (limited) use of readline on systems which don't have readline/history.h. Support compiling under MacOS X with fink (see ). Thanks for Justin Hallett and Eric Eslinger for their help in getting this working! Changes in 0.25: Fixed Sorcerer's Apprentice bug in both the client and the server. These bugs were inherited from the original BSD code. Changes in 0.24: Fix bugs in both client and server dealing with block number wraparound, usually manifesting themselves as failure to handle files over 32 MB in size. Officially make the client a part of the tftp-hpa project. Changes in 0.23: Correct memory overwrite bug in the tftp client when compiled with readline. Changes in 0.22: Even more portability improvements: FreeBSD and Tru64/Digital Unix. Fix tsize option on systems on which off_t is "long long". Support large files on systems which need _LARGE_FILE_BITS or similar. Some source cleanups; change to autoconf 2.52. Add support for readline command-line editing in tftp. Changes in 0.21: Support running in standalone mode, without inetd. Even more portability improvements. Now known to compile and run on Linux, Solaris 5, 5.1, 6, 7 and 8, and AIX. Reports of success or failure on other modern systems always appreciated. Clean and modernize some really ugly old code. Fix a potential illegal memory access when running in "totally insecure mode" - no -s, no directories listed. Changes in 0.20: Portability improvements. Now known to compile and run on Solaris 8. Changes in 0.19: Fork before performing tcpwrappers check. Don't rely on nonstandard bsd_signal() function, instead require that the platform has sigaction(). This is 2001, after all. This may resolve some potential portability problems. Log a message if memory allocation fails, instead of dying silently. Clean up the main dispatch loop. Use for exit codes, if it exists. Add support for debugging remapping rulefiles; if logging with -vvv tftpd will log all rules actions. Correct the error code issued by an "abort" rule. Changes in 0.18: Support (almost) arbitrary filename remappings via regular expression-based rulesets. Added -v option for more verbose logging. Changes in 0.17: Add support for tcpwrapper checking (/etc/hosts.allow; /etc/hosts.deny) in tftpd. Compile correctly on glibc 2.1.2. Add -u option to specify the user id to run as (default "nobody".) Operate in "daemon mode" as long as we keep getting requests. This should speed up handling large amounts of requests at once, as can happen when a client starts up, and avoids inetd misconfiguration problems. Changes in 0.16: Correct massive lossage from 0.15: apparently 0.15 was based on an out-of-date CVS repository, somehow. Fix for ACKs in TFTP PUT; patch by Roger Venning. Changes in 0.15: If the operating system allows, try to obtain the local address used for the request packet, and reply using the same local IP address. Some embedded TFTP clients are (probably incorrectly) picky about this. Changes in 0.14: Hacks to signal handling to avoid "zombie servers." Changes in 0.13: Added the non-standard option "blksize2". The "blksize" option is limited in its usability, since TFTP is designed to be implemented in a ROM, and ROM code might find it painful to deal with packets that don't meet certain alignment restrictions. The "blksize2" option tells the server that the block size must be a power of 2 to be usable to the client. The server SHALL respond with a block size that is a power of two, up to a maximum of 32768, or reject the option. Furthermore, the server SHALL grant a block size that is no smaller than 512 bytes unless the client explicitly requested a smaller block size. If the client request both options, the server MAY accept one or the other, but not both. At some point I will probably write up an IETF draft for this option. General information on the tftp-hpa series: The core software was taken from OpenBSD (CVS source as of 1999-09-21). I believe this was the most secure source base available at the time I obtained this code, and it included support for the -s and -c options. The un-BSD-ized Makefiles and a lot of the configure macros were taken from netkit-tftp-0.10 by David Holland; I also followed this example and modernized the code style throughout. Patches by Markus Gutschke and Gero Kuhlmann were the basis for the option negotiation as well as the "blksize" and "tsize" option support, although I made a fair amount of mostly stylistic changes to their code. Adding the -r option (disable a specific option), the "timeout" option, converting to using autoconf for setup, and any additions listed in the Changes list above, has all been my own code, as are any bugs introduced in the merge. tftp-hpa-5.3+20251209/INSTALL000066400000000000000000000221241511036464300150410ustar00rootroot00000000000000Basic Installation ================== These are generic installation instructions. See the file INSTALL.tftp for specific install instructions for this package. The `configure' shell script attempts to guess correct values for various system-dependent variables used during compilation. It uses those values to create a `Makefile' in each directory of the package. It may also create one or more `.h' files containing system-dependent definitions. Finally, it creates a shell script `config.status' that you can run in the future to recreate the current configuration, and a file `config.log' containing compiler output (useful mainly for debugging `configure'). It can also use an optional file (typically called `config.cache' and enabled with `--cache-file=config.cache' or simply `-C') that saves the results of its tests to speed up reconfiguring. (Caching is disabled by default to prevent problems with accidental use of stale cache files.) If you need to do unusual things to compile the package, please try to figure out how `configure' could check whether to do them, and mail diffs or instructions to the address given in the `README' so they can be considered for the next release. If you are using the cache, and at some point `config.cache' contains results you don't want to keep, you may remove or edit it. The file `configure.ac' (or `configure.in') is used to create `configure' by a program called `autoconf'. You only need `configure.ac' if you want to change it or regenerate `configure' using a newer version of `autoconf'. The simplest way to compile this package is: 1. `cd' to the directory containing the package's source code and type `./configure' to configure the package for your system. If you're using `csh' on an old version of System V, you might need to type `sh ./configure' instead to prevent `csh' from trying to execute `configure' itself. Running `configure' takes awhile. While running, it prints some messages telling which features it is checking for. 2. Type `make' to compile the package. 3. Optionally, type `make check' to run any self-tests that come with the package. 4. Type `make install' to install the programs and any data files and documentation. 5. You can remove the program binaries and object files from the source code directory by typing `make clean'. To also remove the files that `configure' created (so you can compile the package for a different kind of computer), type `make distclean'. There is also a `make maintainer-clean' target, but that is intended mainly for the package's developers. If you use it, you may have to get all sorts of other programs in order to regenerate files that came with the distribution. Compilers and Options ===================== Some systems require unusual options for compilation or linking that the `configure' script does not know about. Run `./configure --help' for details on some of the pertinent environment variables. You can give `configure' initial values for variables by setting them in the environment. You can do that on the command line like this: ./configure CC=c89 CFLAGS=-O2 LIBS=-lposix *Note Environment Variables::, for more details. Compiling For Multiple Architectures ==================================== You can compile the package for more than one kind of computer at the same time, by placing the object files for each architecture in their own directory. To do this, you must use a version of `make' that supports the `VPATH' variable, such as GNU `make'. `cd' to the directory where you want the object files and executables to go and run the `configure' script. `configure' automatically checks for the source code in the directory that `configure' is in and in `..'. If you have to use a `make' that does not support the `VPATH' variable, you have to compile the package for one architecture at a time in the source code directory. After you have installed the package for one architecture, use `make distclean' before reconfiguring for another architecture. Installation Names ================== By default, `make install' will install the package's files in `/usr/local/bin', `/usr/local/man', etc. You can specify an installation prefix other than `/usr/local' by giving `configure' the option `--prefix=PATH'. You can specify separate installation prefixes for architecture-specific files and architecture-independent files. If you give `configure' the option `--exec-prefix=PATH', the package will use PATH as the prefix for installing programs and libraries. Documentation and other data files will still use the regular prefix. In addition, if you use an unusual directory layout you can give options like `--bindir=PATH' to specify different values for particular kinds of files. Run `configure --help' for a list of the directories you can set and what kinds of files go in them. If the package supports it, you can cause programs to be installed with an extra prefix or suffix on their names by giving `configure' the option `--program-prefix=PREFIX' or `--program-suffix=SUFFIX'. Optional Features ================= Some packages pay attention to `--enable-FEATURE' options to `configure', where FEATURE indicates an optional part of the package. They may also pay attention to `--with-PACKAGE' options, where PACKAGE is something like `gnu-as' or `x' (for the X Window System). The `README' should mention any `--enable-' and `--with-' options that the package recognizes. For packages that use the X Window System, `configure' can usually find the X include and library files automatically, but if it doesn't, you can use the `configure' options `--x-includes=DIR' and `--x-libraries=DIR' to specify their locations. Specifying the System Type ========================== There may be some features `configure' cannot figure out automatically, but needs to determine by the type of host the package will run on. Usually `configure' can figure that out, but if it prints a message saying it cannot guess the host type, give it the `--build=TYPE' option. TYPE can either be a short name for the system type, such as `sun4', or a canonical name which has the form: CPU-COMPANY-SYSTEM where SYSTEM can have one of these forms: OS KERNEL-OS See the file `config.sub' for the possible values of each field. If `config.sub' isn't included in this package, then this package doesn't need to know the host type. If you are _building_ compiler tools for cross-compiling, you should use the `--target=TYPE' option to select the type of system they will produce code for. If you want to _use_ a cross compiler, that generates code for a platform different from the build platform, you should specify the host platform (i.e., that on which the generated programs will eventually be run) with `--host=TYPE'. In this case, you should also specify the build platform with `--build=TYPE', because, in this case, it may not be possible to guess the build platform (it sometimes involves compiling and running simple test programs, and this can't be done if the compiler is a cross compiler). Sharing Defaults ================ If you want to set default values for `configure' scripts to share, you can create a site shell script called `config.site' that gives default values for variables like `CC', `cache_file', and `prefix'. `configure' looks for `PREFIX/share/config.site' if it exists, then `PREFIX/etc/config.site' if it exists. Or, you can set the `CONFIG_SITE' environment variable to the location of the site script. A warning: not all `configure' scripts look for a site script. Environment Variables ===================== Variables not defined in a site shell script can be set in the environment passed to configure. However, some packages may run configure again during the build, and the customized values of these variables may be lost. In order to avoid this problem, you should set them in the `configure' command line, using `VAR=value'. For example: ./configure CC=/usr/local2/bin/gcc will cause the specified gcc to be used as the C compiler (unless it is overridden in the site shell script). `configure' Invocation ====================== `configure' recognizes the following options to control how it operates. `--help' `-h' Print a summary of the options to `configure', and exit. `--version' `-V' Print the version of Autoconf used to generate the `configure' script, and exit. `--cache-file=FILE' Enable the cache: use and save the results of the tests in FILE, traditionally `config.cache'. FILE defaults to `/dev/null' to disable caching. `--config-cache' `-C' Alias for `--cache-file=config.cache'. `--quiet' `--silent' `-q' Do not print messages saying which checks are being made. To suppress all normal output, redirect it to `/dev/null' (any error messages will still be shown). `--srcdir=DIR' Look for the package's source code in directory DIR. Usually `configure' can determine that directory automatically. `configure' also accepts some other, not widely useful, options. Run `configure --help' for more details. tftp-hpa-5.3+20251209/INSTALL.tftp000066400000000000000000000024141511036464300160150ustar00rootroot00000000000000Specific installation instructions ================================== In addition to what is described in the INSTALL file, the following specifics apply to the tftp-hpa package: The tftp-hpa package supports the following options to ./configure: --without-tcpwrappers Disables the use of the tcp wrapper library. This is recommended, for performance reasons, on high-use sites. Kernel-based firewalling is, in general, a better alternative. --without-remap Disables the use of regular-expression-based filename remapping (the -m option to tftpd). --without-readline Disables the use of the readline command-line editing library in the tftp client. The default prefix for the tftp-hpa package is /usr, with the tftp client installing as /usr/bin/tftp and the tftpd server installing as /usr/sbin/in.tftpd on most systems. This can be overridden by setting --bindir and --sbindir. "make install" supports specifying an INSTALLROOT, which points to what will be the root of the filesystem at runtime; this is typically used when preparing packages for package-management systems. You almost certainly will need GNU make to build tftp-hpa. If you don't already have it, you can find GNU make at: ftp://ftp.gnu.org/pub/make/ or ftp://mirrors.kernel.org/gnu/make/ tftp-hpa-5.3+20251209/MRULES000066400000000000000000000004571511036464300147470ustar00rootroot00000000000000# Standard compilation rules (don't use make builtins) .SUFFIXES: .c .cc .o .s .S .i .c.o: $(CC) $(CFLAGS) -c $< .c.s: $(CC) $(CFLAGS) -S -o $@ $< .c.i: $(CC) $(CFLAGS) -E -o $@ $< .cc.o: $(CXX) $(CXXFLAGS) -c $< .cc.s: $(CXX) $(CXXFLAGS) -S -o $@ $< .cc.i: $(CXX) $(CXXFLAGS) -E -o $@ $< tftp-hpa-5.3+20251209/Makefile000066400000000000000000000032701511036464300154510ustar00rootroot00000000000000# You can do "make SUB=blah" to make only a few, or edit here, or both # You can also run make directly in the subdirs you want. SUB = lib common tftp tftpd %.build: config/MCONFIG config/config.h version.h $(MAKE) -C $(patsubst %.build, %, $@) %.install: config/MCONFIG config/config.h version.h $(MAKE) -C $(patsubst %.install, %, $@) install %.clean: $(MAKE) -C $(patsubst %.clean, %, $@) clean %.distclean: $(MAKE) -C $(patsubst %.distclean, %, $@) distclean all: config/MCONFIG $(patsubst %, %.build, $(SUB)) tftp.build: lib.build common.build tftpd.build: lib.build common.build install: config/MCONFIG $(patsubst %, %.install, $(SUB)) clean: localclean $(patsubst %, %.clean, $(SUB)) localclean: rm -f version.h distclean: localdistclean $(patsubst %, %.distclean, $(SUB)) localdistclean: localclean rm -f config/config/MCONFIG config.status config.log config/config.h *~ \#* rm -rf *.cache find . -type f \( -name \*.orig -o -name \*.rej \) | xargs rm -f spotless: distclean rm -f configure config/config.h.in tftp.spec autoconf: configure config/config.h.in config: config/MCONFIG config/config.h release: $(MAKE) autoconf $(MAKE) tftp.spec $(MAKE) distclean config/MCONFIG: configure config/MCONFIG.in config/config.h.in if test -x config.status; then \ ./config.status --recheck && ./config.status ; \ else \ ./configure ; \ fi config/config.h: config/MCONFIG : Generated by side effect configure: configure.ac sh autogen.sh config/config.h.in: configure : Generated by side effect version.h: version echo \#define VERSION \"tftp-hpa `cat version`\" > version.h tftp.spec: tftp.spec.in version sed -e "s/@@VERSION@@/`cat version`/g" < $< > $@ || rm -f $@ tftp-hpa-5.3+20251209/README000066400000000000000000000016071511036464300146730ustar00rootroot00000000000000This is tftp-hpa, a conglomerate of a number of versions of the BSD TFTP code, changed around to port to a whole collection of operating systems. The goal is to work on any reasonably modern Unix with sockets. The tftp-hpa series is maintained by H. Peter Anvin . The latest version of this collection can be found at: ftp://ftp.kernel.org/pub/software/network/tftp/ See the file CHANGES for a list of changes between versions. Please see the INSTALL and INSTALL.tftp files for compilation and installation instructions. ===> IMPORTANT: IF YOU ARE UPGRADING FROM ANOTHER TFTP SERVER, OR FROM ===> A VERSION OF TFTP-HPA OLDER THAN 0.17 SEE THE FILE ===> "README.security" FOR IMPORTANT SECURITY MODEL CHANGES! This software can be discussed on the SYSLINUX mailing list. To subscribe, go to the list subscription page at: http://www.zytor.com/mailman/listinfo/syslinux tftp-hpa-5.3+20251209/README.security000066400000000000000000000050341511036464300165370ustar00rootroot00000000000000Starting in version 0.27, tftp-hpa has the option of a "use Unix permissions" mode. In this mode, tftpd can access any file accessible by the tftpd effective user, specified via the -u option. This means that files no longer need to be set to o+r or o+w. If file creation is enabled (via the -c option), the -p option also changes the default umask from 0 (anyone can read or write) to "unchanged" (inherited from the calling process.) The -U option can be used to override the default umask; this is recommended. The sanest setup, from a security standpoint, for tftpd to run in is probably the following: 1. Create a separate "tftpd" user and group only used for tftpd; 2. Have all your boot files in a single directory tree (usually called /tftpboot). 3. Specify "-p -u tftpd -s /tftpboot" on the tftpd command line; if you want clients to be able to create files use "-p -c -U 002 -u tftpd -s /tftpboot" (replace 002 with whatever umask is appropriate for your setup.) ======================================= Starting in version 0.17, tftp-hpa operates in genuine "wait" mode, which means that an in.tftpd process hangs around for some time after the last service request has arrived. This speeds up servicing a subsequent request, which apparently has been a problem in the past, resulting in "request storms" as the client keeps retrying, resulting in multiple connections on the server which the client has already abandoned. This also means that spawning tftp via tcpd is useless (in fact, this indirection seems to be part of the reason for these "request storms.") Instead, tftp-hpa supports calling the tcpwrapper library directly. Thus, if your /etc/inetd.conf looks like this (all on one line): tftp dgram udp wait root /usr/sbin/tcpd /usr/sbin/in.tftpd -s /tftpboot -r blksize ... it's better to change to ... tftp dgram udp wait root /usr/sbin/in.tftpd in.tftpd -s /tftpboot -r blksize You should make sure that you are using "wait" option in tftpd; you also need to have tftpd spawned as root in order for chroot (-s) to work. tftpd automatically drops privilege and changes user ID to "nobody" by default; the appropriate user ID for tftpd can be specified with the -u option (e.g. "-u tftpuser"). If you are running a busy boot server, I would suggest to instead use kernel-based firewalling rules, and to compile tftpd without tcpwrapper support, in order to provide significantly better performance. To do so, specify the --without-tcpwrappers option to configure when compiling; see the INSTALL.tftp file for more information. tftp-hpa-5.3+20251209/autoconf/000077500000000000000000000000001511036464300156255ustar00rootroot00000000000000tftp-hpa-5.3+20251209/autoconf/m4/000077500000000000000000000000001511036464300161455ustar00rootroot00000000000000tftp-hpa-5.3+20251209/autoconf/m4/pa_add_cflags.m4000066400000000000000000000010301511036464300211300ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_ADD_CFLAGS(flag [,actual_flag [,success [,failure]]]]) dnl dnl Attempt to add the given option to xFLAGS, if it doesn't break dnl compilation. If the option to be tested is different than the dnl option that should actually be added, add the option to be dnl actually added as a second argument. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_ADD_CFLAGS], [PA_ADD_FLAGS(CFLAGS, [$1], [$2], [$3], [$4])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_add_flags.m4000066400000000000000000000030251511036464300207730ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_ADD_FLAGS(variable, flag [,actual_flag [,success [,failure]]]]) dnl dnl Add [flags] to the variable [flagvar] if and only if it is accepted dnl by all languages affected by [flagvar], if those languages have dnl been previously seen in the script. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_ADD_FLAGS], [ AS_VAR_PUSHDEF([old],[PA_SHSYM([_$0_$1_orig])]) AS_VAR_PUSHDEF([flags], [$1]) AS_VAR_PUSHDEF([cache],[PA_SHSYM([pa_cv_$1_$2])]) AS_VAR_COPY([old],[flags]) AC_CACHE_VAL([cache], [AS_VAR_APPEND([flags],[' $2']) AS_VAR_SET([cache],[yes]) PA_LANG_FOREACH([PA_FLAGS_LANGLIST($1)], [AS_VAR_IF([cache],[yes], [AC_MSG_CHECKING([whether $]_AC_CC[ accepts $2]) m4_case([$1], [LDFLAGS], [AC_LINK_IFELSE([AC_LANG_PROGRAM([[]],[[]])], [],[AS_VAR_SET([cache],[no])])], [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]],[[]])], [],[AS_VAR_SET([cache],[no])])]) AC_MSG_RESULT([$cache]) ])]) AS_VAR_COPY([flags],[old]) ]) AS_VAR_IF([cache],[yes], [m4_define([_pa_add_flags_newflags],[m4_default([$3],[$2])])dnl AS_VAR_APPEND([flags],[' _pa_add_flags_newflags']) m4_foreach_w([_pa_add_flags_flag],[_pa_add_flags_newflags], [AC_DEFINE(PA_SYM([$1_]_pa_add_flags_flag), 1, [Define to 1 if compiled with ]_pa_add_flags_flag[ in $1])]) $4],[$5]) AS_VAR_POPDEF([cache]) AS_VAR_POPDEF([flags]) AS_VAR_POPDEF([old]) ]) tftp-hpa-5.3+20251209/autoconf/m4/pa_add_headers.m4000066400000000000000000000007701511036464300213160ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_ADD_HEADERS(headers...) dnl dnl Call AC_CHECK_HEADERS_ONCE(), and add to ac_includes_default if found dnl -------------------------------------------------------------------------- AC_DEFUN([_PA_ADD_HEADER], [AC_CHECK_HEADERS_ONCE([$1]) AS_IF([test "x$]PA_SHSYM([ac_cv_header_$1])[" = xyes], [ac_includes_default="$ac_includes_default #include <$1>" ]) ]) AC_DEFUN([PA_ADD_HEADERS],[m4_map_args([_PA_ADD_HEADER],$@)]) tftp-hpa-5.3+20251209/autoconf/m4/pa_add_langflags.m4000066400000000000000000000006601511036464300216370ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_ADD_LANGFLAGS(flag...) dnl dnl Attempt to add the first accepted option in the given list to each dnl compiler flags (CFLAGS, CXXFLAGS, ...). dnl -------------------------------------------------------------------------- AC_DEFUN([PA_ADD_LANGFLAGS], [PA_LANG_FOREACH(PA_LANG_HAVE_FLAGVAR_LIST, [PA_FIND_FLAGS(m4_quote(PA_LANG_FLAGVAR),[$@])])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_arg_bool.m4000066400000000000000000000016161511036464300206570ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_ARG_BOOL(option,helptext,default,enabled_action,disabled_action) dnl dnl The last three arguments are optional; default can be yes or no. dnl dnl Simpler-to-use versions of AC_ARG_ENABLED, that include the dnl test for $enableval and the AS_HELP_STRING definition. This is only dnl to be used for boolean options. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_ARG_BOOL], [m4_pushdef([pa_default],m4_default(m4_normalize([$3]),[no])) m4_pushdef([pa_option],m4_case(pa_default,[yes],[disable],[enable])) AC_ARG_ENABLE([$1], [AS_HELP_STRING([--]m4_defn([pa_option])[-$1],[$2])], [pa_arg_bool_enableval="$enableval"], [pa_arg_bool_enableval="]m4_defn([pa_default])["]) m4_popdef([pa_option], [pa_default]) AS_IF([test x"$pa_arg_bool_enableval" != xno], [$4], [$5]) ]) tftp-hpa-5.3+20251209/autoconf/m4/pa_arg_disabled.m4000066400000000000000000000004451511036464300214720ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_ARG_DISABLED(option,helptext,disabled_action,enabled_action) dnl -------------------------------------------------------------------------- AC_DEFUN([PA_ARG_DISABLED],[PA_ARG_BOOL([$1],[$2],yes,[$4],[$3])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_arg_enabled.m4000066400000000000000000000004421511036464300213120ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_ARG_ENABLED(option,helptext,enabled_action,disabled_action) dnl -------------------------------------------------------------------------- AC_DEFUN([PA_ARG_ENABLED],[PA_ARG_BOOL([$1],[$2],no,[$3],[$4])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_c_typeof.m4000066400000000000000000000017721511036464300207060ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_C_TYPEOF dnl dnl Find if typeof() exists, or an equivalent (__typeof__, decltype, dnl __decltype__) dnl -------------------------------------------------------------------------- AC_DEFUN([PA_C_TYPEOF], [AC_CACHE_CHECK([if $CC supports typeof], [pa_cv_typeof], [pa_cv_typeof=no for pa_typeof_try in typeof __typeof __typeof__ decltype __decltype __decltype__ _Decltype do AS_IF([test $pa_cv_typeof = no], [AC_COMPILE_IFELSE([AC_LANG_SOURCE([ AC_INCLUDES_DEFAULT int testme(int x); int testme(int x) { $pa_typeof_try(x) y = x*x; return y; } ])], [pa_cv_typeof=$pa_typeof_try])]) done ]) AS_IF([test $pa_cv_typeof = no], [], [AC_DEFINE([HAVE_TYPEOF], 1, [Define to 1 if you have some version of the typeof operator.]) AS_IF([test $pa_cv_typeof = typeof], [], [AC_DEFINE_UNQUOTED([typeof], [$pa_cv_typeof], [Define if your typeof operator is not named `typeof'.])])])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_check_bad_stdc_inline.m4000066400000000000000000000015151511036464300233270ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_CHECK_BAD_STDC_INLINE dnl dnl Some versions of gcc seem to apply -Wmissing-prototypes to C99 dnl inline functions, which means we need to use GNU inline syntax dnl -------------------------------------------------------------------------- AC_DEFUN([PA_CHECK_BAD_STDC_INLINE], [AC_MSG_CHECKING([if $CC supports C99 external inlines]) AC_COMPILE_IFELSE([AC_LANG_SOURCE([ AC_INCLUDES_DEFAULT /* Don't mistake GNU inlines for c99 */ #if defined(__GNUC__) && !defined(__GNUC_STDC_INLINE__) # error "Using gnu inline standard" #endif inline int foo(int x) { return x+1; } ])], [AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_STDC_INLINE], 1, [Define to 1 if your compiler supports C99 extern inline])], [AC_MSG_RESULT([no]) PA_ADD_CFLAGS([-fgnu89-inline])])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_check_inttypes_h_sane.m4000066400000000000000000000013651511036464300234250ustar00rootroot00000000000000dnl ------------------------------------------------------------------------ dnl PA_CHECK_INTTYPES_H_SANE dnl dnl At least some versions of AIX 4 have macros which are dnl completely broken. Try to detect those. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_CHECK_INTTYPES_H_SANE], [AC_CHECK_HEADERS_ONCE(inttypes.h) AS_IF([test "x$ac_cv_header_inttypes_h" = xyes],[ AC_MSG_CHECKING([if inttypes.h is sane]) AC_LINK_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT], [uintmax_t max = UINTMAX_C(0); printf("%"PRIuMAX"\n", max);])], [AC_MSG_RESULT([yes]) AC_DEFINE(INTTYPES_H_IS_SANE, 1, [Define if the macros in are usable])], [AC_MSG_RESULT([no (AIX, eh?)])])])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_cross_compile.m4000066400000000000000000000023771511036464300217410ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_CROSS_COMPILE dnl dnl Get the canonical name for the build and host (runtime) systems; dnl then figure out if this is cross-compilation. Specifically, this dnl disables invoking WINE on non-Windows systems which are configured dnl to run WINE automatically. dnl dnl Use PA_CROSS_COMPILE_TOOL if the target system (output of a code- dnl generation tool) is applicable. dnl dnl This doesn't explicitly print any messages as that is automatically dnl done elsewhere. dnl -------------------------------------------------------------------------- AC_DEFUN_ONCE([PA_CROSS_COMPILE], [ AC_BEFORE([$0], [AC_LANG_COMPILER]) AC_BEFORE([$0], [AC_LANG]) AC_BEFORE([$0], [AC_PROG_CC]) AC_BEFORE([$0], [AC_PROG_CPP]) AC_BEFORE([$0], [AC_PROG_CXX]) AC_BEFORE([$0], [AC_PROG_CXXCPP]) AC_BEFORE([$0], [AC_PROG_OBJC]) AC_BEFORE([$0], [AC_PROG_OBJCPP]) AC_BEFORE([$0], [AC_PROG_OBJCXX]) AC_BEFORE([$0], [AC_PROG_OBJCXXCPP]) AC_BEFORE([$0], [AC_PROG_F77]) AC_BEFORE([$0], [AC_PROG_FC]) AC_BEFORE([$0], [AC_PROG_GO]) # Disable WINE WINELOADER=/dev/null export WINELOADER WINESERVER=/dev/null export WINESERVER WINEPREFIX=/dev/null export WINEPREFIX AC_CANONICAL_BUILD AC_CANONICAL_HOST ]) tftp-hpa-5.3+20251209/autoconf/m4/pa_csym.m4000066400000000000000000000011451511036464300200430ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_CSYM(prefix, string) dnl dnl Convert a (semi-) arbitrary string to a CPP symbol dnl Convert non-C characters to underscore, except + which is converted dnl to X (so C++ -> CXX). Unlike PA_SYM(), do not compact multiple dnl underscores. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_CSYM], [m4_bpatsubsts(m4_quote(m4_toupper(m4_normalize([$*]))), [[ ]+],[],[\+],[X],[^\(.\)\([0123456789].*\)$],[[[\1_\2]]], [[^ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]],[_], [^._\(.*\)_.$],[[[\1]]])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_find_flags.m4000066400000000000000000000011111511036464300211550ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_FIND_FLAGS(flagvar, flags_list) dnl dnl Add the first set of flags in flags_list that is accepted by dnl by all languages affected by [flagvar], if those languages have dnl been previously seen in the script. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_FIND_FLAGS], [_pa_find_flags_done=no m4_foreach([_pa_find_flags_flag],[$2], [ AS_IF([test x$_pa_find_flags_done != xyes], [PA_ADD_FLAGS([$1],_pa_find_flags_flag,,[_pa_find_flags_done=yes])])])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_flags_langlist.m4000066400000000000000000000013421511036464300220600ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_FLAGS_LANGLIST(flagvar) dnl dnl Return a list of languages affected by the variable flagvar. dnl If flagvar is unknown, assume it affects the current language. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_FLAGS_LANGLIST], [m4_case([$1], [CPPFLAGS], [[C],[C++],[Objective C],[Objective C++]], [CFLAGS], [[C]], [CXXFLAGS], [[C++]], [FFLAGS], [[Fortran 77]], [FCFLAGS], [[Fortran]], [ERLCFLAGS], [[Erlang]], [OBJCFLAGS], [[Objective C]], [OBJCXXFLAGS], [[Objective C++]], [GOFLAGS], [[Go]], [LDFLAGS], [[C],[C++],[Fortran 77],[Fortran],[Objective C],[Objective C++],[Go]], m4_quote(_AC_LANG))]) tftp-hpa-5.3+20251209/autoconf/m4/pa_have_tcpwrappers.m4000066400000000000000000000014251511036464300224460ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_HAVE_TCPWRAPPERS dnl dnl Do we have the tcpwrappers -lwrap? This can't be done using AC_CHECK_LIBS dnl due to the need to provide "allow_severity" and "deny_severity" variables dnl -------------------------------------------------------------------------- AC_DEFUN([PA_HAVE_TCPWRAPPERS], [AC_CHECK_LIB([wrap], [main]) AC_MSG_CHECKING([for tcpwrappers]) AC_LINK_IFELSE([AC_LANG_PROGRAM( [[ #include int allow_severity = 0; int deny_severity = 0; ]], [[ hosts_ctl("sample_daemon", STRING_UNKNOWN, STRING_UNKNOWN, STRING_UNKNOWN); ]])], [ AC_DEFINE(HAVE_TCPWRAPPERS, 1, [Define if we have tcpwrappers (-lwrap) and .]) AC_MSG_RESULT([yes]) ], [ AC_MSG_RESULT([no]) ])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_lang_flagvar.m4000066400000000000000000000014371511036464300215170ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_LANG_FLAGVAR([language]) dnl dnl Return the name of the compiler flag variable for the current or dnl specified language. Returns empty if the variable name is not known. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_LANG_FLAGVAR], [m4_case(m4_quote(m4_default([$1],m4_quote(_AC_LANG))), [C], [CFLAGS], [C++], [CXXFLAGS], [Fortran 77], [FFLAGS], [Fortran], [FCFLAGS], [Erlang], [ERLCFLAGS], [Objective C], [OBJCFLAGS], [Objective C++], [OBJCXXFLAGS], [Go], [GOFLAGS], [m4_fatal([PA_LANG_FLAGVAR: Unknown language: $1])])]) AC_DEFUN([PA_LANG_HAVE_FLAGVAR_LIST], [[[C], [C++], [Fortran 77], [Fortran], [Erlang], [Objective C], [Objective C++], [Go]]]) tftp-hpa-5.3+20251209/autoconf/m4/pa_lang_foreach.m4000066400000000000000000000011671511036464300215040ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_LANG_FOREACH(subset, body) dnl dnl Expand [body] for each language encountered in the configure script also dnl present in [subset], or all if [subset] is empty dnl -------------------------------------------------------------------------- AC_DEFUN([_PA_LANG_FOREACH], [m4_pushdef([pa_lang_for_each])dnl m4_foreach([pa_lang_for_each],$1,[dnl AC_LANG_PUSH(pa_lang_for_each) $2 AC_LANG_POP(pa_lang_for_each) ])dnl m4_popdef([pa_lang_for_each])]) AC_DEFUN([PA_LANG_FOREACH], [_PA_LANG_FOREACH(m4_dquote(PA_LANG_SEEN_LIST(m4_dquote($1))),[$2])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_lang_seen_list.m4000066400000000000000000000014161511036464300220570ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_LANG_SEEN_LIST(subset) dnl dnl List of the language lang has been used in the configuration dnl script so far, possibly subset by [subset]. dnl dnl This relies on overriding _AC_LANG_SET(from, to), dnl the internal implementation of _AC_LANG. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_LANG_SEEN_LIST], [m4_ifblank([$1], [m4_define([_pa_lang_seen_list_out],m4_dquote(m4_set_list(PA_LANG_SEEN_SET)))], [m4_set_delete([_pa_lang_seen_subset])dnl m4_set_add_all([_pa_lang_seen_subset],$1)dnl m4_define([_pa_lang_seen_list_out],m4_dquote(m4_cdr(m4_set_intersection([_pa_lang_seen_subset],PA_LANG_SEEN_SET))))dnl m4_dquote(_pa_lang_seen_list_out)])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_lang_seen_set.m4000066400000000000000000000013661511036464300217030ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_LANG_SEEN_SET dnl dnl Set of the languages that have been used in the configuration. dnl dnl This relies on overriding _AC_LANG_SET(from, to), dnl the internal implementation of _AC_LANG. dnl dnl The very first language transition [] -> [C] is ignored, because dnl it is done from AC_INIT regardless of any user specified language. dnl -------------------------------------------------------------------------- m4_ifndef([_PA_LANG_SET], [m4_rename([_AC_LANG_SET], [_PA_LANG_SET]) m4_set_delete([_pa_lang_seen_set]) m4_defun([_AC_LANG_SET], [m4_ifnblank([$1],[m4_set_add([_pa_lang_seen_set],[$2])])_PA_LANG_SET($@)])]) AC_DEFUN([PA_LANG_SEEN_SET],[[_pa_lang_seen_set]]) tftp-hpa-5.3+20251209/autoconf/m4/pa_option_debug.m4000066400000000000000000000011061511036464300215430ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_OPTION_DEBUG(with_debug, without_debug) dnl dnl Set debug flags and optimization flags depending on if dnl --enable-debug is set or not. Some flags are set regardless... dnl -------------------------------------------------------------------------- AC_DEFUN([PA_OPTION_DEBUG], [PA_ARG_DISABLED([gdb], [disable gdb debug extensions], [PA_ADD_LANGFLAGS([-g3])], [PA_ADD_LANGFLAGS([-ggdb3],[-g3])]) PA_ARG_ENABLED([debug], [optimize for debugging], [PA_ADD_LANGFLAGS([-Og],[-O0]) $1], [$2])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_option_profiling.m4000066400000000000000000000006301511036464300224470ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_OPTION_PROFILING(with_profiling, without_profiling) dnl dnl Try to enable profiling if --enable-profiling is set. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_OPTION_PROFILING], [PA_ARG_ENABLED([profiling], [compile with profiling (-pg option)], [PA_ADD_LANGFLAGS([-pg])])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_prog_cc.m4000066400000000000000000000013751511036464300205110ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_PROG_CC() dnl dnl Similar to AC_PROG_CC, but add a prototype for main() to dnl AC_INCLUDES_DEFAULT to avoid -Werror from breaking compilation. dnl (Very odd!) dnl dnl It can optionally take lists of CFLAGS to be added. For each argument, dnl only the *first* flag accepted is added. dnl dnl BUG: this expands AC_CHECK_HEADERS_ONCE() before the flags get dnl probed. Don't know yet how to fix that. dnl -------------------------------------------------------------------------- AC_DEFUN_ONCE([PA_PROG_CC], [AC_REQUIRE([AC_PROG_CC]) AC_USE_SYSTEM_EXTENSIONS ac_includes_default="$ac_includes_default #ifndef __cplusplus extern int main(void); #endif" PA_FIND_FLAGS(CFLAGS,[$1]) ]) tftp-hpa-5.3+20251209/autoconf/m4/pa_search_libs_and_add.m4000066400000000000000000000011241511036464300227750ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_SEARCH_LIBS_AND_ADD dnl dnl PA_SEARCH_LIBS_AND_ADD(function, libraries [,function to add]) dnl -------------------------------------------------------------------------- AC_DEFUN([PA_SEARCH_LIBS_AND_ADD], [ AH_TEMPLATE(AS_TR_CPP(HAVE_$1), [Define if $1 function was found]) AC_SEARCH_LIBS($1, $2, [ AC_DEFINE_UNQUOTED(AS_TR_CPP(HAVE_$1)) pa_add_$1=false; ], [ XTRA=true; if test $# -eq 3; then AC_LIBOBJ($3) else AC_LIBOBJ($1) fi pa_add_$1=true; ])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_shsym.m4000066400000000000000000000012271511036464300202340ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_SHSYM(...) dnl dnl Convert a (semi-) arbitrary string to a shell symbol dnl Convert non-shell characters to underscores, except + which is converted dnl to x (so C++ -> cxx). Unlike PA_SYM(), do not compact multiple dnl underscores. dnl dnl This currently differs from PA_CSYM only in not doing case conversion. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_SHSYM], [m4_bpatsubsts(m4_quote(m4_normalize([$*])), [[ ]+],[],[\+],[x],[[^abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_]],[_], [^._\(.*\)_.$],[[[\1]]])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_sigsetjmp.m4000066400000000000000000000012461511036464300210770ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_SIGSETJMP dnl dnl Do we have sigsetjmp/siglongjmp? (AC_CHECK_FUNCS doesn't seem to work dnl for these particular functions.) dnl -------------------------------------------------------------------------- AC_DEFUN([PA_SIGSETJMP], [AC_MSG_CHECKING([for sigsetjmp]) AC_LINK_IFELSE([AC_LANG_SOURCE( [ AC_INCLUDES_DEFAULT #include int main(void) { sigjmp_buf buf; if (sigsetjmp(buf,1)) return 0; siglongjmp(buf,2); return 1; } ])], [AC_MSG_RESULT([yes]) AC_DEFINE([HAVE_SIGSETJMP], 1, [Define to 1 if your system has sigsetjmp/siglongjmp])], [AC_MSG_RESULT([no])])]) tftp-hpa-5.3+20251209/autoconf/m4/pa_sym.m4000066400000000000000000000007321511036464300177010ustar00rootroot00000000000000dnl -------------------------------------------------------------------------- dnl PA_SYM(prefix, string) dnl dnl Convert a (semi-) arbitrary string to a CPP symbol dnl Compact underscores and convert non-C characters to underscore, dnl except + which is converted to X (so C++ -> CXX). dnl dnl Contract multiple underscores together. dnl -------------------------------------------------------------------------- AC_DEFUN([PA_SYM],[m4_bpatsubsts(PA_CSYM([$*]),[__+],[_])]) tftp-hpa-5.3+20251209/autogen.sh000077500000000000000000000047411511036464300160160ustar00rootroot00000000000000#!/bin/sh -x # # Run this script to regenerate autoconf files # recheck=false for arg; do case x"$arg" in x--recheck) recheck=true config=$(sh config.status --config 2>/dev/null) ;; x--clearenv) unset AUTOCONF AUTOMAKE ACLOCAL AUTOHEADER ACLOCAL_PATH ;; *) echo "$0: unknown option: $arg" 1>&2 ;; esac done # This allows for overriding the default autoconf programs AUTOCONF="${AUTOCONF:-${AUTOTOOLS_PREFIX}autoconf}" AUTOMAKE="${AUTOMAKE:-${AUTOTOOLS_PREFIX}automake}" ACLOCAL="${ACLOCAL:-${AUTOTOOLS_PREFIX}aclocal}" AUTOHEADER="${AUTOHEADER:-${AUTOTOOLS_PREFIX}autoheader}" mkdir -p autoconf autoconf/helpers config autolib="`"$AUTOMAKE" --print-libdir`" if test ! x"$autolib" = x; then for prg in install-sh compile config.guess config.sub; do # Update autoconf helpers if and only if newer ones are available if test -f "$autolib"/"$prg" && \ ( set -e ; \ test -f autoconf/helpers/"$prg" && sed -n \ -e 's/^scriptver=/scriptversion=/' \ -e 's/^timestamp=/scriptversion=/' \ -e 's/^scriptversion=['\''"]?\([^'\''"]*\).*$/\1/p' \ "$autolib"/"$prg" autoconf/helpers/"$prg" | \ sort -c 2>/dev/null ; \ test $? -ne 0 ) then cp -f "$autolib"/"$prg" autoconf/helpers fi done fi mv -f autoconf/aclocal.m4 autoconf/aclocal.m4.old mkdir -p autoconf/m4.old autoconf/m4 mv -f autoconf/m4/*.m4 autoconf/m4.old/ 2>/dev/null || true ACLOCAL_PATH="${ACLOCAL_PATH}${ACLOCAL_PATH:+:}`pwd`/autoconf/m4.old" export ACLOCAL_PATH "$ACLOCAL" --install --output=autoconf/aclocal.m4 -I autoconf/m4 if test ! -f autoconf/aclocal.m4; then # aclocal failed, revert to previous files mv -f autoconf/m4.old/*.m4 autoconf/m4/ mv -f autoconf/aclocal.m4.old autoconf/aclocal.m4 exit 1 fi rm -rf autoconf/*m4.old "$AUTOHEADER" -B autoconf "$AUTOCONF" -B autoconf ( echo '#!/bin/sh' "$AUTOCONF" -B autoconf \ -t AC_CONFIG_HEADERS:'rm -f $*' \ -t AC_CONFIG_FILES:'rm -f $*' echo 'rm -f config.log config.status' echo 'rm -rf autom4te.cache' ) > autoconf/clean.sh chmod +x autoconf/clean.sh sh autoconf/clean.sh rm -f configure~ || true # Try to regenerate unconfig.h if Perl is available and unconfig.pl # is present in the autoconf directory. if [ -n "$(which perl)" -a -f autoconf/unconfig.pl ]; then perl autoconf/unconfig.pl . config/config.h.in config/unconfig.h fi if $recheck; then # This bizarre statement has to do with how config.status quotes its output echo exec sh configure $config | sh - fi tftp-hpa-5.3+20251209/common/000077500000000000000000000000001511036464300152775ustar00rootroot00000000000000tftp-hpa-5.3+20251209/common/Makefile000066400000000000000000000005101511036464300167330ustar00rootroot00000000000000SRCROOT = .. VERSION = $(shell cat ../version) -include ../config/MCONFIG include ../MRULES OBJS = tftpsubs.$(O) signal.$(O) LIB = libcommon.a all: $(LIB) $(LIB): $(OBJS) -rm -f $(LIB) $(AR) $(LIB) $(OBJS) $(RANLIB) $(LIB) $(OBJS): tftpsubs.h install: clean: rm -f *.o *.obj *.exe $(LIB) distclean: clean rm -f *~ tftp-hpa-5.3+20251209/common/signal.c000066400000000000000000000005211511036464300167160ustar00rootroot00000000000000/* * signal.c * * User-friendly wrapper around sigaction(). */ #include "config.h" int tftp_signal(int signum, sighandler_t handler, int flags) { struct sigaction sa; memset(&sa, 0, sizeof sa); sa.sa_handler = handler; sigemptyset(&sa.sa_mask); sa.sa_flags = flags; return sigaction(signum, &sa, NULL); } tftp-hpa-5.3+20251209/common/tftpsubs.c000066400000000000000000000301321511036464300173140ustar00rootroot00000000000000/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "tftpsubs.h" /* Simple minded read-ahead/write-behind subroutines for tftp user and server. Written originally with multiple buffers in mind, but current implementation has two buffer logic wired in. Todo: add some sort of final error check so when the write-buffer is finally flushed, the caller can detect if the disk filled up (or had an i/o error) and return a nak to the other side. Jim Guyton 10/85 */ #include #define PKTSIZE MAX_SEGSIZE+4 /* should be moved to tftp.h */ int segsize = SEGSIZE; /* Default segsize */ struct bf { int counter; /* size of data in buffer, or flag */ char buf[PKTSIZE]; /* room for data packet */ } bfs[2]; /* Values for bf.counter */ #define BF_ALLOC -3 /* alloc'd but not yet filled */ #define BF_FREE -2 /* free */ /* [-1 .. segsize] = size of data in the data buffer */ static int nextone; /* index of next buffer to use */ static int current; /* index of buffer in use */ /* control flags for crlf conversions */ int newline = 0; /* fillbuf: in middle of newline expansion */ int prevchar = -1; /* putbuf: previous char (cr check) */ static struct tftphdr *rw_init(int); struct tftphdr *w_init() { return rw_init(0); } /* write-behind */ struct tftphdr *r_init() { return rw_init(1); } /* read-ahead */ /* init for either read-ahead or write-behind */ /* x == zero for write-behind, one for read-head */ static struct tftphdr *rw_init(int x) { newline = 0; /* init crlf flag */ prevchar = -1; bfs[0].counter = BF_ALLOC; /* pass out the first buffer */ current = 0; bfs[1].counter = BF_FREE; nextone = x; /* ahead or behind? */ return (struct tftphdr *)bfs[0].buf; } /* Have emptied current buffer by sending to net and getting ack. Free it and return next buffer filled with data. */ int readit(FILE * file, struct tftphdr **dpp, int convert) { struct bf *b; bfs[current].counter = BF_FREE; /* free old one */ current = !current; /* "incr" current */ b = &bfs[current]; /* look at new buffer */ if (b->counter == BF_FREE) /* if it's empty */ read_ahead(file, convert); /* fill it */ /* assert(b->counter != BF_FREE);*//* check */ *dpp = (struct tftphdr *)b->buf; /* set caller's ptr */ return b->counter; } /* * fill the input buffer, doing ascii conversions if requested * conversions are lf -> cr,lf and cr -> cr, nul */ void read_ahead(FILE * file, int convert) { int i; char *p; int c; struct bf *b; struct tftphdr *dp; b = &bfs[nextone]; /* look at "next" buffer */ if (b->counter != BF_FREE) /* nop if not free */ return; nextone = !nextone; /* "incr" next buffer ptr */ dp = (struct tftphdr *)b->buf; if (convert == 0) { b->counter = read(fileno(file), dp->th_data, segsize); return; } p = dp->th_data; for (i = 0; i < segsize; i++) { if (newline) { if (prevchar == '\n') c = '\n'; /* lf to cr,lf */ else c = '\0'; /* cr to cr,nul */ newline = 0; } else { c = getc(file); if (c == EOF) break; if (c == '\n' || c == '\r') { prevchar = c; c = '\r'; newline = 1; } } *p++ = c; } b->counter = (int)(p - dp->th_data); } /* Update count associated with the buffer, get new buffer from the queue. Calls write_behind only if next buffer not available. */ int writeit(FILE * file, struct tftphdr **dpp, int ct, int convert) { bfs[current].counter = ct; /* set size of data to write */ current = !current; /* switch to other buffer */ if (bfs[current].counter != BF_FREE) /* if not free */ (void)write_behind(file, convert); /* flush it */ bfs[current].counter = BF_ALLOC; /* mark as alloc'd */ *dpp = (struct tftphdr *)bfs[current].buf; return ct; /* this is a lie of course */ } /* * Output a buffer to a file, converting from netascii if requested. * CR,NUL -> CR and CR,LF => LF. * Note spec is undefined if we get CR as last byte of file or a * CR followed by anything else. In this case we leave it alone. */ int write_behind(FILE * file, int convert) { char *buf; int count; int ct; char *p; int c; /* current character */ struct bf *b; struct tftphdr *dp; b = &bfs[nextone]; if (b->counter < -1) /* anything to flush? */ return 0; /* just nop if nothing to do */ count = b->counter; /* remember byte count */ b->counter = BF_FREE; /* reset flag */ dp = (struct tftphdr *)b->buf; nextone = !nextone; /* incr for next time */ buf = dp->th_data; if (count <= 0) return -1; /* nak logic? */ if (convert == 0) return write(fileno(file), buf, count); p = buf; ct = count; while (ct--) { /* loop over the buffer */ c = *p++; /* pick up a character */ if (prevchar == '\r') { /* if prev char was cr */ if (c == '\n') /* if have cr,lf then just */ fseek(file, -1, 1); /* smash lf on top of the cr */ else if (c == '\0') /* if have cr,nul then */ goto skipit; /* just skip over the putc */ /* else just fall through and allow it */ } putc(c, file); skipit: prevchar = c; } return count; } /* When an error has occurred, it is possible that the two sides * are out of synch. Ie: that what I think is the other side's * response to packet N is really their response to packet N-1. * * So, to try to prevent that, we flush all the input queued up * for us on the network connection on our host. * * We return the number of packets we flushed (mostly for reporting * when trace is active). */ int synchnet(int f) { /* socket to flush */ int pktcount = 0; char rbuf[PKTSIZE]; union sock_addr from; socklen_t fromlen; fd_set socketset; struct timeval notime; while (1) { notime.tv_sec = notime.tv_usec = 0; FD_ZERO(&socketset); FD_SET(f, &socketset); if (select(f, &socketset, NULL, NULL, ¬ime) <= 0) break; /* Nothing to read */ /* Otherwise drain the packet */ pktcount++; fromlen = sizeof(from); (void)recvfrom(f, rbuf, sizeof(rbuf), 0, &from.sa, &fromlen); } return pktcount; /* Return packets drained */ } int pick_port_bind(int sockfd, union sock_addr *myaddr, unsigned int port_range_from, unsigned int port_range_to) { unsigned int port, firstport; int port_range = 0; if (port_range_from != 0 && port_range_to != 0) { port_range = 1; } firstport = port_range ? port_range_from + rand() % (port_range_to - port_range_from + 1) : 0; port = firstport; do { sa_set_port(myaddr, htons(port)); if (bind(sockfd, &myaddr->sa, SOCKLEN(myaddr)) < 0) { /* Some versions of Linux return EINVAL instead of EADDRINUSE */ if (!(port_range && (errno == EINVAL || errno == EADDRINUSE))) return -1; /* Normally, we shouldn't have to loop, but some situations involving aborted transfers make it possible. */ } else { return 0; } port++; if (port > port_range_to) port = port_range_from; } while (port != firstport); return -1; } int set_sock_addr(char *host,union sock_addr *s, char **name) { struct addrinfo *addrResult; struct addrinfo hints; int err; memset(&hints, 0, sizeof(hints)); hints.ai_family = s->sa.sa_family; hints.ai_flags = AI_CANONNAME | AI_ADDRCONFIG; hints.ai_socktype = SOCK_DGRAM; hints.ai_protocol = IPPROTO_UDP; err = getaddrinfo(strip_address(host), NULL, &hints, &addrResult); if (err) return err; if (addrResult == NULL) return EAI_NONAME; memcpy(s, addrResult->ai_addr, addrResult->ai_addrlen); if (name) { if (addrResult->ai_canonname) *name = xstrdup(addrResult->ai_canonname); else *name = xstrdup(host); } freeaddrinfo(addrResult); return 0; } #ifdef HAVE_IPV6 int is_numeric_ipv6(const char *p) { /* A numeric IPv6 address consist at least of 2 ':' and * it may have sequences of hex-digits and maybe contain * a '.' from a IPv4 mapped address and maybe is enclosed in [] * we do not check here, if it is a valid IPv6 address * only if is something like a numeric IPv6 address or something else */ int colon = 0; int dot = 0; int bracket = 0; char c; if (!p) return 0; if (*p == '[') { bracket = 1; p++; } while ((c = *p++) && c != ']') { switch (c) { case ':': colon++; break; case '.': dot++; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'a': case 'b': case 'c': case 'd': case 'e': case 'f': break; default: return 0; /* Invalid character */ } } if (colon < 2 || colon > 7) return 0; if (dot) { /* An IPv4-mapped address in dot-quad form will have 3 dots */ if (dot != 3) return 0; /* The IPv4-mapped address takes the space of one colon */ if (colon > 6) return 0; } /* If bracketed, must be closed, and vice versa */ if (bracket ^ (c == ']')) return 0; /* Otherwise, assume we're okay */ return 1; } /* strip [] from numeric IPv6 addreses */ char *strip_address(char *addr) { char *p; if (is_numeric_ipv6(addr) && (*addr == '[')) { p = addr + strlen(addr); p--; if (*p == ']') { *p = 0; addr++; } } return addr; } #endif tftp-hpa-5.3+20251209/common/tftpsubs.h000066400000000000000000000073701511036464300173310ustar00rootroot00000000000000/* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ /* * Prototypes for read-ahead/write-behind subroutines for tftp user and * server. */ #ifndef TFTPSUBS_H #define TFTPSUBS_H #include "config.h" union sock_addr { struct sockaddr sa; struct sockaddr_in si; #ifdef HAVE_IPV6 struct sockaddr_in6 s6; #endif }; #define SOCKLEN(sock) \ (((union sock_addr*)sock)->sa.sa_family == AF_INET ? \ (sizeof(struct sockaddr_in)) : \ (sizeof(union sock_addr))) #ifdef HAVE_IPV6 #define SOCKPORT(sock) \ (((union sock_addr*)sock)->sa.sa_family == AF_INET ? \ ((union sock_addr*)sock)->si.sin_port : \ ((union sock_addr*)sock)->s6.sin6_port) #else #define SOCKPORT(sock) \ (((union sock_addr*)sock)->si.sin_port) #endif #ifdef HAVE_IPV6 #define SOCKADDR_P(sock) \ (((union sock_addr*)sock)->sa.sa_family == AF_INET ? \ (void *)&((union sock_addr*)sock)->si.sin_addr : \ (void *)&((union sock_addr*)sock)->s6.sin6_addr) #else #define SOCKADDR_P(sock) \ ((void *)&((union sock_addr*)sock)->si.sin_addr) #endif #ifdef HAVE_IPV6 int is_numeric_ipv6(const char *); char *strip_address(char *); #else #define is_numeric_ipv6(a) 0 #define strip_address(a) (a) #endif static inline int sa_set_port(union sock_addr *s, u_short port) { switch (s->sa.sa_family) { case AF_INET: s->si.sin_port = port; break; #ifdef HAVE_IPV6 case AF_INET6: s->s6.sin6_port = port; break; #endif default: return -1; } return 0; } int set_sock_addr(char *, union sock_addr *, char **); struct tftphdr; struct tftphdr *r_init(void); void read_ahead(FILE *, int); int readit(FILE *, struct tftphdr **, int); int synchnet(int); struct tftphdr *w_init(void); int write_behind(FILE *, int); int writeit(FILE *, struct tftphdr **, int, int); extern int segsize; #define MAX_SEGSIZE 65464 int pick_port_bind(int sockfd, union sock_addr *myaddr, unsigned int from, unsigned int to); #endif tftp-hpa-5.3+20251209/config.h000066400000000000000000000201511511036464300154240ustar00rootroot00000000000000/* -*- c -*- ------------------------------------------------------------- * * * Copyright 2001-2025 H. Peter Anvin - All Rights Reserved * * This program is free software available under the same license * as the "OpenBSD" operating system, distributed at * http://www.openbsd.org/. * * ----------------------------------------------------------------------- */ /* * config.h * * Sets up a common baseline environment, based on "autoconf" findings... */ #ifndef CONFIG_H #define CONFIG_H 1 /* Feature enables for specific environments */ #ifdef __APPLE__ #if __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 1070 #define __APPLE_USE_RFC_3542 1 #endif #endif /* Must be included before we include any system headers! */ #include "config/config.h" /* autogenerated configuration header */ /* Standard includes */ #include #include #include #include #include #include #include #ifdef HAVE_SYS_TYPES_H #include #endif #ifdef HAVE_SYS_STAT_H #include #endif #ifdef HAVE_STRING_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef HAVE_INTTYPES_H #ifdef INTTYPES_H_IS_SANE #include #endif #else #ifdef HAVE_STDINT_H #include #endif #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SETJMP_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_GRP_H #include #endif #ifdef HAVE_FCNTL_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #else #ifdef HAVE_WINSOCK2_H #include #else #ifdef HAVE_WINSOCK_H #include #endif #endif #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_WCHAR_H #include #endif #ifdef HAVE_WCTYPE_H #include #endif #ifdef HAVE_LOCALE_H #include #endif #ifdef HAVE_GETOPT_LONG #include #else #include "lib/getopt.h" #endif /* Test for EAGAIN/EWOULDBLOCK */ #ifdef EAGAIN #if defined(EWOULDBLOCK) && (EWOULDBLOCK != EAGAIN) #define E_WOULD_BLOCK(x) ((x) == EAGAIN || (x) == EWOULDBLOCK) #else #define E_WOULD_BLOCK(x) ((x) == EAGAIN) #endif #else #define E_WOULD_BLOCK(x) ((x) == EWOULDBLOCK) #endif /* Some broken systems care about text versus binary, but real Unix systems don't... */ #if !HAVE_DECL_O_TEXT #define O_TEXT 0 #endif #if !HAVE_DECL_O_BINARY #define O_BINARY 0 #endif #ifndef HAVE_DECL_O_NONBLOCK # ifdef HAVE_DECL_O_NDELAY # define O_NONBLOCK O_NDELAY # else # define O_NONBLOCK 0 # endif #endif /* If we don't have intmax_t, try creating it */ #ifndef HAVE_INTMAX_T #ifdef HAVE_LONG_LONG typedef long long intmax_t; typedef unsigned long long uintmax_t; #define PRIdMAX "lld" #define PRIuMAX "llu" #define PRIxMAX "llx" #define INTMAX_C(x) (x##LL) #define UINTMAX_C(x) (x##ULL) #else typedef long intmax_t; typedef unsigned long uintmax_t; #define PRIdMAX "ld" #define PRIuMAX "lu" #define PRIxMAX "lx" #define INTMAX_C(x) (x##L) #define UINTMAX_C(x) (x##UL) #endif #endif /* On some version of AIX, is buggy to the point of unusability. We have to use macros here, not typedefs, to override. */ #ifdef HAVE_INTTYPES_H #ifndef INTTYPES_H_IS_SANE #undef PRIdMAX #undef PRIuMAX #undef PRIxMAX #undef INTMAX_C #undef UINTMAX_C #undef HAVE_STRTOUMAX #ifdef HAVE_LONG_LONG #define intmax_t long long #define uintmax_t unsigned long long #define PRIdMAX "Ld" #define PRIuMAX "Lu" #define PRIxMAX "Lx" #define INTMAX_C(x) (x##LL) #define UINTMAX_C(x) (x##ULL) #else #define intmax_t long #define uintmax_t unsigned long #define PRIdMAX "ld" #define PRIuMAX "lu" #define PRIxMAX "lx" #define INTMAX_C(x) (x##L) #define UINTMAX_C(x) (x##UL) #endif #endif #endif /* Even if intmax_t is defined, we may need this (Solaris 8 braindamage) */ #ifndef HAVE_STRTOUMAX #if defined(HAVE_LONG_LONG) && defined(HAVE_STRTOULL) #define strtoumax(p,e,b) ((uintmax_t)strtoull(p,e,b)) #else #define strtoumax(p,e,b) ((uintmax_t)strtoul(p,e,b)) #endif #endif /* A lot of this is old BSD code. Some newer systems don't approve. */ /* The type used by htons(), ntohs() */ #ifndef HAVE_U_SHORT #ifdef HAVE_UINT16_T typedef uint16_t u_short; #else typedef unsigned short u_short; #endif #endif /* The type used to htonl(), ntohl() */ #ifndef HAVE_U_LONG #ifdef HAVE_UINT32_T typedef uint32_t u_long; #else typedef unsigned long u_long; #endif #endif /* socklen_t */ #ifndef HAVE_SOCKLEN_T typedef int socklen_t; #endif /* sysexits.h */ #ifdef HAVE_SYSEXITS_H #include #else #define EX_USAGE 64 /* command line usage error */ #define EX_DATAERR 65 /* data format error */ #define EX_NOINPUT 66 /* cannot open input */ #define EX_NOUSER 67 /* addressee unknown */ #define EX_NOHOST 68 /* host name unknown */ #define EX_UNAVAILABLE 69 /* service unavailable */ #define EX_SOFTWARE 70 /* internal software error */ #define EX_OSERR 71 /* system error (e.g., can't fork) */ #define EX_OSFILE 72 /* critical OS file missing */ #define EX_CANTCREAT 73 /* can't create (user) output file */ #define EX_IOERR 74 /* input/output error */ #define EX_TEMPFAIL 75 /* temp failure; user is invited to retry */ #define EX_PROTOCOL 76 /* remote error in protocol */ #define EX_NOPERM 77 /* permission denied */ #define EX_CONFIG 78 /* configuration error */ #endif /* If we don't have sigsetjmp() et all, setjmp() will have to do */ #ifndef HAVE_SIGSETJMP #define sigsetjmp(x,y) setjmp(x) #define siglongjmp(x,y) longjmp(x,y) #define sigjmp_buf jmp_buf #endif /* How do we annotate unused data items? */ #ifndef UNUSED #ifdef __GNUC__ #define UNUSED __attribute__((unused)) #else #define UNUSED #endif #endif /* netinet/in.h, and possible missing pieces */ #include #if !HAVE_DECL_IPPORT_TFTP && !defined(IPPORT_TFTP) #define IPPORT_TFTP 69 #endif /* arpa/{inet,tftp}.h, and possible missing pieces */ #ifdef HAVE_ARPA_INET_H #include #endif /* If we don't have arpa/tftp.h we have problems... */ #include #ifndef OACK #define OACK 6 #endif #ifndef EOPTNEG #define EOPTNEG 8 #endif /* Prototypes for libxtra functions */ void *xmalloc(size_t); char *xstrdup(const char *); #ifndef HAVE_SIGHANDLER_T typedef void (*sighandler_t)(int); #endif int tftp_signal(int, sighandler_t, int); #ifndef HAVE_DUP2 int dup2(int, int); #endif #ifndef HAVE_DAEMON int daemon(int, int); #endif #ifndef HAVE_GETADDRINFO #ifndef HAVE_STRUCT_ADDRINFO_AI_ADDR struct addrinfo { int ai_flags; int ai_family; int ai_socktype; int ai_protocol; size_t ai_addrlen; struct sockaddr *ai_addr; char *ai_canonname; struct addrinfo *ai_next; }; #endif int getaddrinfo(const char *, const char *, const struct addrinfo *, struct addrinfo **); void freeaddrinfo(struct addrinfo *); const char *gai_strerror(int); #ifndef EAI_NONAME #define EAI_NONAME -2 /* NAME or SERVICE is unknown. */ #endif #ifndef EAI_ADDRFAMILY #define EAI_ADDRFAMILY -9 /* Address family for NAME not supported. */ #endif #ifndef EAI_MEMORY #define EAI_MEMORY -10 /* Memory allocation failure. */ #endif #ifndef EAI_SYSTEM #define EAI_SYSTEM -11 /* System error returned in `errno'. */ #endif #endif #ifndef AI_CANONNAME #define AI_CANONNAME 0 #endif #ifndef AI_ADDRCONFIG #define AI_ADDRCONFIG 0 #endif #ifndef INET6_ADDRSTRLEN #define INET6_ADDRSTRLEN 46 #endif #ifndef HAVE_INET_NTOP const char *inet_ntop(int, const void *, char *, socklen_t); #endif /* tftp-hpa version and configuration strings */ #include "version.h" #ifdef WITH_READLINE #define WITH_READLINE_STR ", with readline" #else #define WITH_READLINE_STR ", without readline" #endif #ifdef WITH_REGEX #define WITH_REGEX_STR ", with remap" #else #define WITH_REGEX_STR ", without remap" #endif #ifdef HAVE_LIBWRAP #define HAVE_LIBWRAP_STR ", with tcpwrappers" #else #define HAVE_LIBWRAP_STR ", without tcpwrappers" #endif #define TFTP_CONFIG_STR VERSION WITH_READLINE_STR #define TFTPD_CONFIG_STR VERSION WITH_REGEX_STR HAVE_LIBWRAP_STR #endif tftp-hpa-5.3+20251209/config/000077500000000000000000000000001511036464300152545ustar00rootroot00000000000000tftp-hpa-5.3+20251209/config/MCONFIG.in000066400000000000000000000026601511036464300166720ustar00rootroot00000000000000## -*- makefile -*- ------------------------------------------------------ ## ## Copyright 2001-2007 H. Peter Anvin - All Rights Reserved ## ## This program is free software available under the same license ## as the "OpenBSD" operating system, distributed at ## http://www.openbsd.org/. ## ## ----------------------------------------------------------------------- ## ## MCONFIG.in ## ## Basic Makefile definitions ## # Source and object root SRCROOT = @SRCROOT@ OBJROOT = @OBJROOT@ # Prefixes prefix = @prefix@ exec_prefix = @exec_prefix@ # Directory for user binaries BINDIR = @bindir@ # Man page tree MANDIR = @mandir@ # System binaries SBINDIR = @sbindir@ # Data root directory datarootdir = @datarootdir@ # Binary suffixes O = @OBJEXT@ X = @EXEEXT@ # Install into alternate root area, e.g. for package generation INSTALLROOT = # Link LN_S = @LN_S@ # Install program INSTALL = @INSTALL@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ INSTALL_DATA = @INSTALL_DATA@ # Compiler and compiler flags CC = @CC@ CFLAGS = @CFLAGS@ -I$(SRCROOT) # Link flags LDFLAGS = @LDFLAGS@ # Libraries (client and server) TFTP_LIBS = ../common/libcommon.a @TFTP_LIBS@ TFTPD_LIBS = ../common/libcommon.a @TFTPD_LIBS@ # Additional library we need to build LIBOBJS = @LIBOBJS@ # Additional tftpd objects we need to build TFTPDOBJS = @TFTPDOBJS@ # ar and ranlib (for making libraries) AR = ar cq RANLIB = @RANLIB@ tftp-hpa-5.3+20251209/configure.ac000066400000000000000000000173721511036464300163070ustar00rootroot00000000000000dnl Process this file with autoconf 2.71 or later to produce dnl a configure script. AC_PREREQ([2.71]) AC_INIT AC_CONFIG_SRCDIR([MRULES]) AC_PREFIX_DEFAULT([/usr]) AC_CONFIG_AUX_DIR([autoconf/helpers]) dnl This prevents us from running Wine and thinking we are not dnl cross-compiling when in fact we are; running Wine here is at dnl the best very slow and doesn't buy us a single thing at all. PA_CROSS_COMPILE dnl Enable any available C extensions PA_PROG_CC AC_USE_SYSTEM_EXTENSIONS dnl Options for debugging and profiling PA_OPTION_DEBUG PA_OPTION_PROFILING dnl LLVM doesn't error out on invalid -W options unless this option is dnl specified first. Enable this so this script can actually discover dnl which -W options are possible for this compiler. PA_ADD_CFLAGS([-Werror=unknown-warning-option]) dnl Force gcc and gcc-compatible compilers treat signed integers dnl as 2's complement PA_ADD_CFLAGS([-fwrapv]) dnl Force clang to behave in a predictable manner, in order to make bugs dnl possible to track down. gcc appears to have this behavior by default. PA_ADD_CFLAGS([-ftrivial-auto-var-init=zero]) dnl Some environments abuse __STRICT_ANSI__ to disable some dnl function declarations PA_ADD_CFLAGS([-U__STRICT_ANSI__]) dnl Don't put things in common if we can avoid it. We don't want to dnl assume all compilers support common, and this will help find those dnl problems. This also works around an OSX linker problem. PA_ADD_CFLAGS([-fno-common]) dnl Tests which may trigger warnings on some compilers AC_C_CONST AC_C_INLINE AC_C_RESTRICT dnl Checks for header files. AC_CHECK_INCLUDES_DEFAULT dnl See if we need extra libraries XTRA=false AC_SEARCH_LIBS([strerror],[cposix]) AC_CHECK_HEADERS_ONCE(inttypes.h) AC_CHECK_HEADERS_ONCE(stdint.h) AC_CHECK_HEADERS_ONCE(grp.h) AC_CHECK_HEADERS_ONCE(libgen.h) AC_CHECK_HEADERS_ONCE(setjmp.h) AC_CHECK_HEADERS_ONCE(strings.h) AC_CHECK_HEADERS_ONCE(sysexits.h) AC_CHECK_HEADERS_ONCE(unistd.h) AC_CHECK_HEADERS_ONCE(sys/filio.h) AC_CHECK_HEADERS_ONCE(sys/stat.h) AC_CHECK_HEADERS_ONCE(sys/time.h) AC_CHECK_HEADERS_ONCE(locale.h) PA_CHECK_INTTYPES_H_SANE dnl This is needed on some versions of FreeBSD... AC_CHECK_HEADERS_ONCE(machine/param.h) dnl Windows... PA_ADD_HEADERS(windows.h) PA_ADD_HEADERS(winsock2.h) AS_IF([test "x$ac_cv_header_winsock2_h" != xyes], [PA_ADD_HEADERS(winsock.h)]) PA_ADD_HEADERS(fcntl.h) PA_ADD_HEADERS(sys/types.h) PA_ADD_HEADERS(arpa/inet.h) PA_ADD_HEADERS(sys/socket.h) PA_ADD_HEADERS(sys/file.h) PA_ADD_HEADERS(netinet/in.h) PA_ADD_HEADERS(sys/uio.h) PA_ADD_HEADERS(netdb.h) AC_TYPE_OFF_T AC_TYPE_PID_T AC_TYPE_MODE_T AC_TYPE_SIZE_T AC_CHECK_TYPES(intmax_t) AC_CHECK_TYPES(long long) AC_CHECK_TYPES(uint16_t) AC_CHECK_TYPES(uint32_t) AC_CHECK_TYPES(u_short) AC_CHECK_TYPES(u_long) AC_CHECK_TYPES(socklen_t) AC_SEARCH_LIBS(socket, [socket ws2_32 wsock32], , [AC_MSG_ERROR(socket library not found)]) AC_CHECK_FUNCS(fcntl) AC_CHECK_FUNCS(flock) AC_CHECK_FUNCS(setsid) AC_CHECK_FUNCS(recvmsg) AC_CHECK_FUNCS(ftruncate) AC_CHECK_FUNCS(setresuid) AC_CHECK_FUNCS(setreuid) AC_CHECK_FUNCS(setresgid) AC_CHECK_FUNCS(setregid) AC_CHECK_FUNCS(initgroups) AC_CHECK_FUNCS(setgroups) AC_CHECK_TYPES(sighandler_t) dnl Solaris 8 has [u]intmax_t but not strtoumax(). How utterly braindamaged. AC_CHECK_FUNCS(strtoumax) AC_CHECK_FUNCS(strtoull) AC_CHECK_MEMBERS(struct msghdr.msg_control) AC_CHECK_MEMBERS(struct in_pktinfo.ipi_addr) AC_CHECK_MEMBERS(struct addrinfo.ai_addr) AC_CHECK_DECLS([O_NONBLOCK, O_NDELAY, O_BINARY, O_TEXT]) AC_CHECK_DECLS([F_SETLK]) AC_CHECK_DECLS([LOCK_SH, LOCK_EX]) PA_ADD_HEADERS(wctype.h) PA_ADD_HEADERS(wchar.h) AC_CHECK_FUNCS(mbrtowc) AC_CHECK_FUNCS(towlower) PA_SIGSETJMP dnl dnl Get common paths dnl SRCROOT=`cd $srcdir && pwd` OBJROOT=`pwd` PA_SEARCH_LIBS_AND_ADD(xmalloc, iberty) PA_SEARCH_LIBS_AND_ADD(xstrdup, iberty) PA_SEARCH_LIBS_AND_ADD(getopt_long, getopt, getopt_long) PA_SEARCH_LIBS_AND_ADD(getaddrinfo, [nsl resolv]) AS_IF([$pa_add_getaddrinfo], [AC_SEARCH_LIBS(gethostbyname, [nsl resolv], [AC_SEARCH_LIBS(herror, [nsl resolv], , [AC_MSG_ERROR(herror not found)])], [AC_MSG_ERROR(gethostbyname not found)])], [AC_SEARCH_LIBS(freeaddrinfo, [nsl resolv], , [AC_MSG_ERROR(getaddrinfo but not freeaddrinfo found)]) AC_SEARCH_LIBS(gai_strerror, [nsl resolv], , [AC_MSG_ERROR(getaddrinfo but not gai_strerror found)])]) PA_SEARCH_LIBS_AND_ADD(inet_ntop, [nsl resolv]) AS_IF([$pa_add_inet_ntop], [AC_SEARCH_LIBS(inet_ntoa, [nsl resolv], , [AC_MSG_ERROR(inet_ntoa not found)])]) AC_SEARCH_LIBS(inet_aton, [nsl resolv], ,[AC_MSG_ERROR(inet_aton not found)]) PA_SEARCH_LIBS_AND_ADD(daemon) PA_SEARCH_LIBS_AND_ADD(dup2) AS_IF([$XTRA], [XTRALIBS="$OBJROOT/lib/libxtra.a $XTRALIBS"]) dnl dnl These libraries apply to the server only dnl common_libs="$LIBS" AC_CHECK_DECLS(IPPORT_TFTP) PA_ARG_DISABLED([tcpwrappers], [disable tcpwrapper permissions checking], [], [ AC_SEARCH_LIBS(yp_get_default_domain, [nsl resolv]) PA_HAVE_TCPWRAPPERS ]) AC_CHECK_HEADERS_ONCE([regex.h]) PA_ARG_DISABLED([remap], [disable regex-based filename remapping], [], [AS_IF([test x"$ac_cv_header_regex_h" = xyes], [AC_SEARCH_LIBS(regcomp, [regex rx], [AC_DEFINE([WITH_REGEX], 1, [Define if we are compiling with regex filename remapping.]) TFTPDOBJS="remap.\$(O) $TFTPOBJS"])])]) TFTPD_LIBS="$LIBS $XTRALIBS" LIBS="$common_libs" dnl dnl These libraries apply to the client only dnl AH_TEMPLATE([WITH_READLINE], [Define if we are compiling with readline/editline command-line editing.]) PA_ARG_DISABLED([readline], [disable the use of readline command-line editing], [], [ AC_CHECK_HEADER([readline/readline.h], [ dnl readline may need libtermcap or somesuch... AC_SEARCH_LIBS(tputs, [termcap terminfo]) AC_SEARCH_LIBS(readline, [readline history], [AC_DEFINE(WITH_READLINE)]) AC_CHECK_HEADERS(readline/history.h) ], [AC_CHECK_HEADER([editline/readline.h], [ dnl editline may need libtermcap or somesuch... AC_SEARCH_LIBS(tputs, [termcap terminfo]) AC_SEARCH_LIBS(editline, [edit], [AC_DEFINE(WITH_READLINE)]) ])]) ],:) TFTP_LIBS="$LIBS $XTRALIBS" LIBS="$common_libs" dnl dnl Check for IPV6 and disable-ipv6 dnl AC_CHECK_MEMBERS(struct sockaddr_in6.sin6_addr) AC_MSG_CHECKING([for IPv6 support]) PA_ARG_DISABLED([ipv6], [disable support for IPv6], [AC_MSG_RESULT(disabled)], [AS_IF([test x"$ac_cv_member_struct_sockaddr_in6_sin6_addr$ac_cv_member_struct_addrinfo_ai_addr" = xyesyes], [AC_MSG_RESULT(yes) AC_DEFINE(HAVE_IPV6, 1, [define if IPv6 support is enabled]) AC_CHECK_MEMBERS(struct in6_pktinfo.ipi6_addr)], [AC_MSG_RESULT(no) AC_MSG_WARN([*** we do not have required IPv6 structs - IPv6 will be disabled])])]) AC_SUBST(SRCROOT) AC_SUBST(OBJROOT) AC_SUBST(TFTP_LIBS) AC_SUBST(TFTPD_LIBS) AC_SUBST(TFTPDOBJS) AC_PROG_LN_S AC_PROG_RANLIB dnl dnl Make sure the install program has an absolute path if it dnl has a path at all. autoconf doesn't do this "in order dnl to not pollute the cache." Sigh. dnl Note: the $ needs to be double-quoted for reasons unknown. dnl AC_PROG_INSTALL [if echo "$INSTALL" | grep '^[^/].*/' > /dev/null 2>&1; then INSTALL='\${SRCROOT}'/"$INSTALL" fi] PA_ADD_CFLAGS(-W) PA_ADD_CFLAGS(-Wall) PA_ADD_CFLAGS(-Wpointer-arith) PA_ADD_CFLAGS(-Wbad-function-cast) PA_ADD_CFLAGS(-Wcast-equal) PA_ADD_CFLAGS(-Wstrict-prototypes) PA_ADD_CFLAGS(-Wmissing-prototypes) PA_ADD_CFLAGS(-Wmissing-declarations) PA_ADD_CFLAGS(-Wnested-externs) PA_ADD_CFLAGS(-Winline) PA_ADD_CFLAGS(-Wwrite-strings) PA_ADD_CFLAGS(-Wundef) PA_ADD_CFLAGS(-Wshadow) PA_ADD_CFLAGS(-Wsign-compare) PA_ADD_CFLAGS(-fno-strict-aliasing) dnl dnl Test compiler features. On some compilers, this can be affected dnl by -Werror options, so run this *after* those options are added. dnl PA_CHECK_BAD_STDC_INLINE PA_C_TYPEOF AC_CONFIG_HEADERS([config/config.h]) AC_CONFIG_FILES([config/MCONFIG]) AC_OUTPUT tftp-hpa-5.3+20251209/debian/000077500000000000000000000000001511036464300152315ustar00rootroot00000000000000tftp-hpa-5.3+20251209/debian/README.source000066400000000000000000000004511511036464300174100ustar00rootroot00000000000000Create new orig tarball from git -------------------------------- git checkout master git remote add upstream git://git.kernel.org/pub/scm/network/tftp/tftp-hpa.git git pull upstream master git archive --format tar.gz HEAD --prefix tftp-hpa-5.2+20240610/ -o ../tftp-hpa_5.2+20240610.orig.tar.gz tftp-hpa-5.3+20251209/debian/changelog000066400000000000000000000657671511036464300171300ustar00rootroot00000000000000tftp-hpa (5.3+20251116-1) unstable; urgency=medium * New upstream snapshot. (Closes: #1108702) -- Chris Hofstaedtler Sat, 22 Nov 2025 17:45:30 +0100 tftp-hpa (5.3+20251110-1) unstable; urgency=medium * New upstream release. -- Chris Hofstaedtler Tue, 11 Nov 2025 05:32:19 +0100 tftp-hpa (5.2+20240610-3) unstable; urgency=medium [ Carles Pina i Estany ] * Added po-debconf Catalan translation [ Chris Hofstaedtler ] * tftpd-hpa.service: allow AF_UNIX for syslog (Closes: #1093415) * tftpd-hpa.service: restrict SystemCallArchitectures. For RestrictAddressFamilies to be effective on multiarch systems. -- Chris Hofstaedtler Tue, 21 Jan 2025 16:54:45 +0100 tftp-hpa (5.2+20240610-2) unstable; urgency=medium * Start after network-online.target so IPs exist (Closes: #1080329) -- Chris Hofstaedtler Wed, 11 Sep 2024 00:02:43 +0200 tftp-hpa (5.2+20240610-1) unstable; urgency=medium * New upstream snapshot (Closes: #1075567) * Remove patches obsoleted by upstream * Pass additional args from autogen.sh to dh_autoreconf * Remove upstart support * Add systemd service (Closes: #1029991, #1039394) * Use dh-compat level 13 * Use dh sequencer, migrate to dbgsym packages -- Chris Hofstaedtler Sun, 14 Jul 2024 23:20:03 +0200 tftp-hpa (5.2+20150808-2) unstable; urgency=medium * Adopt package (Closes: #1073086) * Setup git-buildpackage * d/control: reformat * d/control: remove Architecture restrictions * d/control: update Vcs-* fields * d/control: update Homepage -- Chris Hofstaedtler Sat, 06 Jul 2024 22:27:24 +0200 tftp-hpa (5.2+20150808-1.4) unstable; urgency=medium * Non-maintainer upload. * Versioned Breaks and Replaces on tftp (Closes: #1022722). * d/copyright: Drop the BSD advertisement clause. * Move the package to 3.0 format. -- Bastian Germann Tue, 25 Oct 2022 22:20:18 +0200 tftp-hpa (5.2+20150808-1.3) unstable; urgency=medium * Non-maintainer upload. * Replace tftp instead of conflicting to help with #1019286. -- Bastian Germann Thu, 15 Sep 2022 19:01:12 +0200 tftp-hpa (5.2+20150808-1.2) unstable; urgency=medium * Non-maintainer upload. * Fix default listen address to work for both IPv4 and IPv6 (was: IPv4 only). Closes: #952387, #935895 -- Romain Porte Wed, 16 Sep 2020 13:57:50 +0200 tftp-hpa (5.2+20150808-1.1) unstable; urgency=medium * Non-maintainer upload. * Fix build error with GCC 10 due to multiple definition of `toplevel' (Closes: #957875) -- Salvatore Bonaccorso Thu, 23 Jul 2020 06:53:24 +0200 tftp-hpa (5.2+20150808-1) unstable; urgency=medium * Canonicalize all the addresses. This avoids the situation of trying to reply to an IPv4-mapped IPv6 address using an IPv4 socket, which isn't going to fly. Closes: #793921 * This upstream snapshot now includes all the patches we were previously carrying. -- Ron Lee Sat, 08 Aug 2015 13:59:11 +0930 tftp-hpa (5.2+20140608-3) unstable; urgency=medium * Fix the Vcs- links to alioth. -- Ron Lee Thu, 31 Jul 2014 15:45:11 +0930 tftp-hpa (5.2+20140608-2) unstable; urgency=medium * Fix the upstream makefile to actually be safe for parallel builds. -- Ron Lee Thu, 31 Jul 2014 04:02:27 +0930 tftp-hpa (5.2+20140608-1) unstable; urgency=medium * Better handling of IPv4/6 mapping. * Fix the broken postrm. Don't remove users, especially not without checking what they still own. Actually remove the empty directories that we loop over, and not just by accident. Though we could probably also just kill the loop instead. Definitely don't remove users and directories using arbitrary hardcoded defaults that something other than this package might own. If we can't determine how they were configured by the local admin, then we have no business just picking things out of a hat to delete anyway. * Adopted, Closes: #756093 -- Ron Lee Wed, 30 Jul 2014 12:08:50 +0930 tftp-hpa (5.2-20) unstable; urgency=low * I don't care anymore, not worth it.. orphaning. -- Daniel Baumann Fri, 25 Jul 2014 20:57:28 +0200 tftp-hpa (5.2-19) unstable; urgency=low * Introducing initial support for upstart as wished by Steve Langasek in #746715. -- Daniel Baumann Sun, 04 May 2014 15:16:55 +0200 tftp-hpa (5.2-18) unstable; urgency=low * Updating year in copyright file. * Building with dh --parallel. -- Daniel Baumann Mon, 31 Mar 2014 21:31:43 +0200 tftp-hpa (5.2-17) experimental; urgency=low * Removing upstart hacks, they are ugly and upstart is dead now. -- Daniel Baumann Tue, 18 Feb 2014 08:04:33 +0100 tftp-hpa (5.2-16) experimental; urgency=low * Updating copyright file. -- Daniel Baumann Sat, 01 Feb 2014 05:36:00 +0100 tftp-hpa (5.2-15) experimental; urgency=low * Updating vcs fields. * Adding debug package. * Updating to standards version 3.9.5. * Updating lsb descriptions in initscript (Closes: #736742). -- Daniel Baumann Sun, 26 Jan 2014 19:07:46 +0100 tftp-hpa (5.2-14) experimental; urgency=low * Correcting typo in atftpd confilicts/replaces (Closes: #717985). -- Daniel Baumann Mon, 29 Jul 2013 11:17:21 +0200 tftp-hpa (5.2-13) experimental; urgency=low * Adding vcs fields. * Wrapping control fields. * Updating syslinux suggests. * Adding tftp-server virtual packaging handling. -- Daniel Baumann Wed, 17 Jul 2013 14:07:42 +0200 tftp-hpa (5.2-12) experimental; urgency=low * Dropping obsolete sysvinit initscript start/stop numbers. -- Daniel Baumann Tue, 11 Jun 2013 17:55:20 +0200 tftp-hpa (5.2-11) experimental; urgency=low * Building tftp-hpa on linux and kfreebsd architectures only. -- Daniel Baumann Thu, 06 Jun 2013 08:20:27 +0200 tftp-hpa (5.2-10) experimental; urgency=low * Correcting provides in lsb header of initscript. * Adding patch from Kees Cook to fix FORTIFY-detected potential memory corruption. * Building with dh-autoreconf. -- Daniel Baumann Wed, 05 Jun 2013 13:58:57 +0200 tftp-hpa (5.2-9) experimental; urgency=low * Adding upstart exit codes in initscript. * Adding slightly modified upstart script from Steve Langasek (Closes: #708851). -- Daniel Baumann Mon, 03 Jun 2013 06:50:31 +0200 tftp-hpa (5.2-8) experimental; urgency=low * Adding Slovak debconf translations from Slavko (Closes: #704163). * Updating year in copyright file. * Trimming diff headers in patches. * Prefixing patches with four digits. * Dropping dpkg-source compression levels. * Sorting targets in rules. -- Daniel Baumann Sun, 31 Mar 2013 16:54:07 +0200 tftp-hpa (5.2-7) unstable; urgency=low * Removing all references to my old email address. -- Daniel Baumann Sun, 10 Mar 2013 22:00:52 +0100 tftp-hpa (5.2-6) unstable; urgency=low * Removing Otavio from uploaders with his consent. -- Daniel Baumann Sun, 10 Mar 2013 21:52:27 +0100 tftp-hpa (5.2-5) unstable; urgency=low * Correcting spelling typo in readme, thanks to Adam D. Barratt . * Updating to standards version 3.9.4. * Adding dpkg-source local options. -- Daniel Baumann Sun, 16 Dec 2012 10:46:51 +0100 tftp-hpa (5.2-4) unstable; urgency=low * Adding note to readme about ipv6 kernel support (Closes: #544089). -- Daniel Baumann Thu, 19 Jul 2012 16:33:37 +0200 tftp-hpa (5.2-3) unstable; urgency=low * Removing example preseed file. * Trimming lintian overrides. * Switching to xz compression. -- Daniel Baumann Sat, 30 Jun 2012 14:45:15 +0200 tftp-hpa (5.2-2) unstable; urgency=low * Adding Dutch debconf translations from Jeroen Schot (Closes: #655575). * Updating to debhelper version 9. * Updating to standards version 3.9.3. * Updating copyright file machine-readable format version 1.0. -- Daniel Baumann Wed, 14 Mar 2012 07:59:35 +0100 tftp-hpa (5.2-1) unstable; urgency=low * Using compression level 9 also for binary packages. * Removing obsolete db_version call in tftpd-hpa postinst script. * Merging upstream version 5.2. -- Daniel Baumann Fri, 23 Dec 2011 15:10:17 +0100 tftp-hpa (5.1-3) unstable; urgency=low * Adding Brazilian Portuguese debconf translations from Flamarion Jorge (Closes: #640801). -- Daniel Baumann Wed, 28 Sep 2011 13:52:46 +0200 tftp-hpa (5.1-2) unstable; urgency=low * Applying patch from Chris Lamb to correct wrong variable used in tftpd-hpa postrm that lead to not removing the tftp server directory on purge (Closes: #636152). -- Daniel Baumann Sun, 07 Aug 2011 16:43:58 +0200 tftp-hpa (5.1-1) unstable; urgency=low * Updating standards version to 3.9.2. * Merging upstream version 5.1. * Removing socket.patch, included upstream. * Renumbering patches. * Updating copyright file. * Updating lintian overrides. -- Daniel Baumann Sun, 10 Jul 2011 17:18:58 +0200 tftp-hpa (5.0-22) unstable; urgency=low * Adding support for multiple server directories in packaging files (Closes: #610647). * Silencing getent call in postinst. * Adding check in tftpd-hpa.init to ensure that --secure and multiple server directories are not used at the same time. -- Daniel Baumann Sun, 20 Feb 2011 00:18:01 +0100 tftp-hpa (5.0-21) unstable; urgency=low * Updating maintainer and uploaders fields. * Removing vcs fields. * Removing references to my old email address. * Makeing packaging distribution neutral. * Removing lenny legacy stuff. * Adding autoconf to build-depends. -- Daniel Baumann Sun, 06 Feb 2011 11:05:46 +0100 tftp-hpa (5.0-20) experimental; urgency=low * Update manpage to match source code regarding mapfile parameter, thanks to Jim Paris (Closes: #606267). -- Daniel Baumann Fri, 24 Dec 2010 17:42:08 +0100 tftp-hpa (5.0-19) experimental; urgency=low * Improving user checks with getent in postinst scripts. * Switching to source format 3.0 (quilt). * Updating to debhelper version 8. * Simplyfing autotools handing in rules. -- Daniel Baumann Sun, 19 Dec 2010 21:02:26 +0100 tftp-hpa (5.0-18) unstable; urgency=medium * Making greps for tftp username in postinst more robust. -- Daniel Baumann Mon, 06 Dec 2010 23:40:45 +0100 tftp-hpa (5.0-17) experimental; urgency=low * Updating standards version to 3.9.1. * Adding Danish debconf translations from Joe Hansen (Closes: #598042). -- Daniel Baumann Sat, 25 Sep 2010 22:38:41 +0200 tftp-hpa (5.0-16) unstable; urgency=low * Adding updated debconf translations from Vincenzo Campanella (Closes: #597314). -- Daniel Baumann Sun, 19 Sep 2010 12:45:25 +0200 tftp-hpa (5.0-15) unstable; urgency=low * Adding updated Czech debconf translations from Vítězslav Kotrla (Closes: #590136). * Harmonizing headers of po files. * Adding updated Spanish debconf translations from Omar Campagne (Closes: #590664). -- Daniel Baumann Thu, 05 Aug 2010 17:13:47 +0200 tftp-hpa (5.0-14) unstable; urgency=medium * Updating standards version to 3.9.0. * Cherry-picking patch from upstream to fix logfile bug when reloading syslog (Closes: #541184). * Rediffing progname.patch. -- Daniel Baumann Sat, 10 Jul 2010 18:16:58 +0200 tftp-hpa (5.0-13) unstable; urgency=low * Not failing if removal of server directory in postinst isn't successful. * Adding updated Japanese debconf translations from Hideki Yamane (Closes: #580158). -- Daniel Baumann Thu, 13 May 2010 19:09:44 +0200 tftp-hpa (5.0-12) unstable; urgency=low * Updating to standards 3.8.4. * Updating dh call to more common order. * Updating README.source. * Improving short-description of tftpd-hpa/address and tftpd- hpa/options debconf questions. * Adding lintian overrides. * Taking over default argument -s when updating configuration from lenny to squeeze (Closes: #569633). -- Daniel Baumann Wed, 07 Apr 2010 09:59:35 +0200 tftp-hpa (5.0-11) unstable; urgency=medium * Removing explicit LDFLAGS, did apparently not fix the FTBFS on mips*. * Adding updated Russian debconf translations from Yuri Kozlov (Closes: #563079). * Applying patch from Thorsten Glaser to fix FTBFS on mips/mipsel (Closes: #564052). -- Daniel Baumann Fri, 22 Jan 2010 21:05:54 +0100 tftp-hpa (5.0-10) unstable; urgency=low * Adding explicit debian source version 1.0 until switch to 3.0. * Making an educated guess to fix FTBFS on mips (all public mips* boxes of debian are down at the moment) and setting explicit LDFLAGS. -- Daniel Baumann Wed, 16 Dec 2009 17:40:33 +0100 tftp-hpa (5.0-9) unstable; urgency=low * Adding updated Swedish debconf translations from Martin Bagge (Closes: #556581). * Adding updated Portuguese debconf translations from Americo Monteiro (Closes: #557007). -- Daniel Baumann Sun, 22 Nov 2009 17:29:06 +0100 tftp-hpa (5.0-8) unstable; urgency=low * Setting last-translator for German debconf templates to me, no intention do deal with debian-l10n-german in the future anymore (Closes: #552311). * Dealing with /etc/default/tftpd-hpa in a policy compliant way, thanks to Julien Cristau (Closes: #543199). * Setting debconf priority for tftpd-hpa/directory to high. Together with the previous commit (which has the effect, that it is always prompted for the directory on upgrades from lenny), the tftpd directory gets now more visibility (Closes: #551828). -- Daniel Baumann Tue, 10 Nov 2009 11:26:02 +0100 tftp-hpa (5.0-7) unstable; urgency=low * Removing debconf-updatepo call from clean target in rules. * Adding missing build-depends to quilt (Closes: #547738). * Simplifying autotools handling in rules. * Bumping versioned build-depends on debhelper. * Bumping versioned build-depends on quilt. * Adding updated German debconf translations form Helge Kreutzmann (Closes: #550486). * Adding updated French debconf translations from Steve Petruzzello (Closes: #552068). * Replacing some Germanisms from the German debconf translations. -- Daniel Baumann Fri, 23 Oct 2009 08:43:37 +0200 tftp-hpa (5.0-6) unstable; urgency=low * Adding patch to replace upstreams default server root with debians default server root in documentation. * Installing sample.rules for tftpd as example. * Also asking server address and port through debconf. * Allowing to specify other own options through debconf as well. * Updating to standards version 3.8.3. * Adding updated Portuguese debconf translations from Americo Monteiro (Closes: #542617). * Adding updated German debconf translations from Helge Kreutzmann (Closes: #543242). * Adding maintainer homepage field to control. * Marking maintainer homepage field to be also included in binary packages and changelog. * Adding README.source. * Moving maintainer homepage field from control to copyright. * Updating README.source. * Adding updated Swedish debconf translations from Martin Bagge (Closes: #543408). * Adding updated French debconf translations from Steve Petruzzello (Closes: #544421). * Adding updated Japanese debconf translations from Hideki Yamane (Closes: #545407). -- Daniel Baumann Mon, 21 Sep 2009 21:20:57 +0200 tftp-hpa (5.0-5) unstable; urgency=low * Adding missing build-depends to autotools-dev (Closes: #541550). -- Daniel Baumann Fri, 14 Aug 2009 21:12:27 +0200 tftp-hpa (5.0-4) unstable; urgency=low * Improving English in messages outputted in postinst script, thanks to Mark Brown (Closes: #538012). * Adding status to init script, thanks to Peter Eisentraut (Closes: #538071). * Updating maintainer field. * Updating vcs fields. * Sorting depends. * Minimizing rules file. * Fixing debconf handling of /etc/default/tftpd-hpa to not always overwrite the file (Closes: #537846). * Handling upgrades from 0.49 (lenny) to 5.0 (Closes: #539000). * Handling partial upgrades from 5.0-3 (sid). * Adding Otavio to uploaders. -- Daniel Baumann Fri, 14 Aug 2009 19:33:38 +0200 tftp-hpa (5.0-3) unstable; urgency=low * Removing obsolete entry about --secure in readme, tftpd-hpa is running with -s by default for quite some time already. * Using long options when calling tftpd-hpa in initscript. * Adding missing equal sign in defaults file (Closes: #537712). -- Daniel Baumann Tue, 21 Jul 2009 16:23:33 +0200 tftp-hpa (5.0-2) unstable; urgency=low * Adding forgotten bug numbers to previous changelog entry. * Now running always as unprivileged user (Closes: #245017). -- Daniel Baumann Mon, 20 Jul 2009 01:27:27 +0200 tftp-hpa (5.0-1) unstable; urgency=low * Merging upstream version 5.0 (Closes: #525635): - correctly turns off PMTU discovery (Closes: #501025). * Taking over package, Jaakko is mia. * Using correct rfc-2822 date formats in changelog. * Removing useless whitespaces at EOL and EOF. * Updating package to debhelper 7. * Updating package to standards 3.8.2. * Adding homepage field in control file. * Adding vcs fields in control file. * Adding misc:Depends to depends field in control. * Improving package descriptions. * Adding syslinux-common to suggests of tftpd-hpa. * Sorting fields in control file. * Rewriting copyright file in machine-interpretable format. * Prefixing debhelper files with package names. * Adding build-depends to po-debconf. * Rewriting rules file from scratch. * Using dh_install rather than dh_movefiles. * Removing unused build-depend on libreadline5-dev. * Now running always in daemon mode, it is too error prone and messy to support inetd mode (Closes: #272882, #275514, #437651, #503120, #505335, #505367, #535212, #537476). * Now using /srv/tftp as default server root (Closes: #477109). * Using debconf to ask for server root. * Aborting in initscript if server root does not exist (Closes: #497268). * Rewriting initscript, using lsb functions now. * Updating readme to reflect changes about the initscript. * Adding example preseed file. -- Daniel Baumann Sun, 19 Jul 2009 23:48:12 +0200 tftp-hpa (0.49-1.1) unstable; urgency=low * Non-maintainer upload. * Conditionally calling update-inetd in tftpd-hpa.postinst (Closes: #522780). -- Daniel Baumann Wed, 08 Jul 2009 14:50:00 +0200 tftp-hpa (0.49-1) unstable; urgency=low * New upstream release (IPv6 support and other goodies) (Closes: #513642) * Apply patch to remove stop links on rc0 and 6 (Closes: #493838) -- Jaakko Niemi Mon, 16 Feb 2009 23:01:20 +0200 tftp-hpa (0.48-2.3) unstable; urgency=low * Non-maintainer upload. * Fix pending l10n issues. Debconf translations: - Italian. Closes: #495240 - Russian. Closes: #502892 - Basque. Closes: #503073 -- Christian Perrier Mon, 27 Oct 2008 18:23:12 +0100 tftp-hpa (0.48-2.2) unstable; urgency=high * Non-maintainer upload. * Fix previous NMU for Conflict with aftpd (Closes: #476456). * Add Galician Debconf translation (Closes: 481674). Thanks to Jacobo Tarrio. * Update Standards-Version. -- Steve McIntyre <93sam@debian.org> Sun, 29 Jun 2008 17:14:31 +0100 tftp-hpa (0.48-2.1) unstable; urgency=high * Non-maintainer upload. * Add missing Conflict with aftpd (Closes: #476456). -- Pierre Habouzit Thu, 05 Jun 2008 10:37:05 +0200 tftp-hpa (0.48-2) unstable; urgency=low * Only Recommend inet-superserver (Thanks, Daniel (Closes: #462654) * Add missing dependencies (Thanks, Michael) (Closes: #452536) * Remove unnecessary Provides (Closes: #455262) -- Jaakko Niemi Sat, 15 Mar 2008 19:34:07 +0200 tftp-hpa (0.48-1) unstable; urgency=low * New upstream release * added --oknodo to initscripts (Closes: #433891, #415845) * depend on inet-superserver instead of netbase (Closes: #438163) * Debconf translations: - Dutch. (Closes: #414754, #449412) - Spanish. (Closes: #433925) -- Jaakko Niemi Tue, 20 Nov 2007 22:40:51 +0200 tftp-hpa (0.43-1.1) unstable; urgency=low * Non-maintainer upload to fix pending l10n issues. * Debconf translations: - German. Closes: #400053 - Catalan. Closes: #410217 - Brazilian Portuguese. Closes: #403560 * Provide a crude LSB header to the init script -- Christian Perrier Sat, 24 Feb 2007 07:47:29 +0100 tftp-hpa (0.43-1) unstable; urgency=low * New upstream release * Add binary-indep target to debian/rules (Closes: #395753) -- Jaakko Niemi Sat, 28 Oct 2006 14:42:52 +0300 tftp-hpa (0.42-1) unstable; urgency=low * New upstream release * Fixes pmtu issues, differently than in patches (Closes: #294882, #316616) * Fixes regexp issue, differently than in patch (Closes: #316038) * Ack NMUs: (Closes: #308688, #350649, #332116, #298748, #307006, #322296, #331595, #335952) * Check and bump debhelper compat level * Check and bump policy version -- Jaakko Niemi Sun, 19 Mar 2006 00:51:20 +0200 tftp-hpa (0.40-4.2) unstable; urgency=high * Non-maintainer upload. * Update readline build-dep to libreadline5-dev (Closes: #350649). * Added Vietnamese debconf translation (Closes: #322296). * Added Swedish debconf translation (Closes: #331595). * Added Portuguese debconf translation (Closes: #335952). * Add debconf-2.0 alternative (Closes: #332116). -- Luk Claes Wed, 15 Feb 2006 12:18:32 +0100 tftp-hpa (0.40-4.1) unstable; urgency=high * NMU * Added netbase to Depends: (closes: #308688) * Update Czech debconf translation (closes: #298748) * Added Japanese debconf translation (closes: #307006) -- Kenshi Muto Sat, 14 May 2005 11:10:59 +0900 tftp-hpa (0.40-4) unstable; urgency=low * How many times can you screw up in a row? * Fix initscript (Closes: #293040) * Updated French translation (Closes: #292847) * Added Czech debconf translations (Closes: #289285) -- Jaakko Niemi Fri, 04 Feb 2005 19:56:17 +0200 tftp-hpa (0.40-3) unstable; urgency=low * Fix and clean initscript (Closes: #279179, #279241) * Document issue with XP1000 machines, bug #285134. * Remove pidfile option from init script as in daemon mode tftpd-hpa does not create it and forks. -- Jaakko Niemi Sat, 22 Jan 2005 17:05:35 +0200 tftp-hpa (0.40-2) unstable; urgency=low * Fixed typo in debconf template. Not running debconf‐updatepo as translators propably don't have reproduced the typo. * Lowered debconf prompt priority (closes: #276832) * Made initscript to be more informative about daemon being disabled. * Fixed postinst logic to enable default to running from inetd if upgrading from older versions, and only disable from inetd if ran as daemon. (closes: #276827, #276831) -- Jaakko Niemi Sun, 17 Oct 2004 01:12:49 +0300 tftp-hpa (0.40-1) unstable; urgency=low * New upstream release * Add French translation (closes: #273990) -- Jaakko Niemi Thu, 14 Oct 2004 22:05:51 +0300 tftp-hpa (0.39-1) unstable; urgency=low * New upstream release * add initscript and /etc/defaults/tftpd-hpa (closes: #237949) -- Jaakko Niemi Sun, 19 Sep 2004 12:49:56 +0300 tftp-hpa (0.36-1) unstable; urgency=low * New upstream release, enables remap and tcpwrappers support (Closes: #205659) * Correct server postinst to use correct path with update-inetd, duh. (Closes: #229619) -- Jaakko Niemi Mon, 26 Jan 2004 20:11:31 +0200 tftp-hpa (0.34-2) unstable; urgency=low * really remove inetd line in package purge (Closes: #179867) -- Jaakko Niemi Sat, 10 Jan 2004 18:06:02 +0200 tftp-hpa (0.34-1) unstable; urgency=low * New maintainer (Closes: #136172) * New upstream release, see changelog for details. Has much improved error handling. (Closes: #213379) * Add correct line into inetd configuration (Closes: #150108) * Update standards version, no changes needed * User /var/lib/tftpboot untill FHS 2.3 gets into use -- Jaakko Niemi Sat, 10 Jan 2004 17:41:07 +0200 tftp-hpa (0.28-2.1) unstable; urgency=low * NMU * Fix prerm-doesn't-understand-args bug. Closes: #136172 -- LaMont Jones Mon, 12 Aug 2002 13:33:59 -0600 tftp-hpa (0.28-2) unstable; urgency=low * Restore binary-arch in debian/rules, which I deleted with god faith to clean up but out of ignorance (Closes: #135776) * Reaslly close previously typo-ed bug (Closes: #130801) * get rid of unneccersary bashism in tftpd-hpa.postinst (s/==/=/) -- Oliver M. Bolzer Tue, 26 Feb 2002 08:18:12 +0100 tftp-hpa (0.28-1) unstable; urgency=low * New Maintainer * new upstream version (Closes: #13081) * works in more PXE environments (like mine) * supports tcpwrapper * stays active for some time after invocation (performance improvement) * adds standalone mode (no need for inetd) for busy servers not the default for this package * file-name remapping using regexps * readline command-line editing in the client (not enabled due to BSD adv.-caluse GPL conflict) * decent manpage -- Oliver M. Bolzer Tue, 19 Feb 2002 10:44:19 +0100 tftp-hpa (0.14-2) unstable; urgency=low * Enable and disable tftp service on install and remove -- Wichert Akkerman Fri, 17 Nov 2000 14:13:36 +0000 tftp-hpa (0.14-1) unstable; urgency=low * Initial Debian release -- Wichert Akkerman Fri, 17 Nov 2000 10:41:09 +0000 tftp-hpa-5.3+20251209/debian/control000066400000000000000000000027411511036464300166400ustar00rootroot00000000000000Source: tftp-hpa Section: net Priority: optional Maintainer: Chris Hofstaedtler Build-Depends: autoconf, debhelper (>= 13), debhelper-compat (= 13), libwrap0-dev, po-debconf, Standards-Version: 3.9.6.1 Homepage: https://git.kernel.org/pub/scm/network/tftp/tftp-hpa.git/ Vcs-Git: https://salsa.debian.org/debian/tftp-hpa.git Vcs-Browser: https://salsa.debian.org/debian/tftp-hpa Package: tftp-hpa Architecture: any Depends: ${misc:Depends}, ${shlibs:Depends}, Breaks: tftp (<< 0.17-23.1), Replaces: tftp (<< 0.17-23.1), Description: HPA's tftp client Trivial File Transfer Protocol (TFTP) is a file transfer protocol, mainly to serve boot images over the network to other machines (PXE). . tftp-hpa is an enhanced version of the BSD TFTP client and server. It possesses a number of bugfixes and enhancements over the original. . This package contains the client. Package: tftpd-hpa Architecture: any Pre-Depends: ${misc:Pre-Depends}, Depends: adduser, ${misc:Depends}, ${shlibs:Depends}, Conflicts: atftpd, tftp-server, tftpd, Replaces: atftpd, tftp-server, tftpd, Provides: tftp-server, Suggests: pxelinux, Description: HPA's tftp server Trivial File Transfer Protocol (TFTP) is a file transfer protocol, mainly to serve boot images over the network to other machines (PXE). . tftp-hpa is an enhanced version of the BSD TFTP client and server. It possesses a number of bugfixes and enhancements over the original. . This package contains the server. tftp-hpa-5.3+20251209/debian/copyright000066400000000000000000000066461511036464300172000ustar00rootroot00000000000000Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Upstream-Name: tftp-hpa Upstream-Contact: syslinux@zytor.com Source: git://git.kernel.org/pub/scm/network/tftp/tftp-hpa.git Files: * Copyright: 1984-1994 The Regents of the University of California 2000-2014 H. Peter Anvin License: BSD-4 Files: */*.in Copyright: 1984-1994 The Regents of the University of California 2000-2014 H. Peter Anvin License: BSD-3 Files: debian/* Copyright: 2014 Ron Lee License: BSD-3 License: BSD-3 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. License: BSD-4 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: . 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. 4. Neither the name of the University nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. . THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. tftp-hpa-5.3+20251209/debian/gbp.conf000066400000000000000000000001171511036464300166470ustar00rootroot00000000000000[DEFAULT] pristine-tar = False debian-branch = debian upstream-branch = master tftp-hpa-5.3+20251209/debian/po/000077500000000000000000000000001511036464300156475ustar00rootroot00000000000000tftp-hpa-5.3+20251209/debian/po/POTFILES.in000066400000000000000000000000561511036464300174250ustar00rootroot00000000000000[type: gettext/rfc822deb] tftpd-hpa.templates tftp-hpa-5.3+20251209/debian/po/ca.po000066400000000000000000000076551511036464300166070ustar00rootroot00000000000000# Catalan translation of tftp-hpa's debconf messages # Copyright © 2024 Free Software Foundation, Inc. # This file is distributed under the same license as the tftp-hpa package. # poc senderi , 2024. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2024-11-01 23:55+0100\n" "Last-Translator: poc senderi \n" "Language-Team: Catalan \n" "Language: ca\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Generator: Poedit 2.4.2\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Compte de sistema dedicat per al dimoni de TFTP «tftpd-hpa»:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser " "privileges." msgstr "" "El servidor TFTP ha d'utilitzar un compte dedicat per al seu funcionament " "de manera que la seguretat del sistema no es vegi compromesa si s'executa " "amb privilegis de superusuari." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Trieu el nom d'usuari d'aquest compte." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Directori arrel TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Especifiqueu el directori que s'utilitzarà com a arrel per al servidor TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Adreça i port del servidor TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Especifiqueu una adreça i en quin port escoltar en el format [adreça][:" "port]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Per defecte, el servidor TFTP escolta pel port 69 en totes les adreces i " "totes les interfícies. Si no s'especifica cap port, per defecte és el 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Tingueu en compte que les adreces IPv6 numèriques han d'estar tancades " "entre claudàtors per evitar l'ambigüitat amb la informació opcional del " "port." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Opcions addicionals del servidor TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Es poden passar opcions addicionals al servidor TFTP amb aquest mecanisme; " "consulteu la pàgina del manual tftpd(8) per a més informació sobre les " "opcions disponibles." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only " "for special situations. If unsure, leave it at the recommended default " "value." msgstr "" "Poques vegades es necessiten opcions diferents de la recomanada «--secure» " "i només per a situacions especials. Si no se n'està segur, és millor deixar-" "hi el valor predeterminat recomanat." tftp-hpa-5.3+20251209/debian/po/cs.po000066400000000000000000000075571511036464300166320ustar00rootroot00000000000000# Czech translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Vítězslav Kotrla # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2010-07-20 05:54+0200\n" "Last-Translator: Vitezslav Kotrla \n" "Language-Team: Czech \n" "Language: cs\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Vyhrazený systémový účet, pod kterým bude běžet TFTP démon tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "Pokud by byl TFTP server spuštěn se superuživatelskými oprávněními, mohlo by " "dojít ke kompromitaci zabezpečení systému. Proto musí TFTP server pro svoji " "činnost používat vyhrazený neprivilegovaný účet." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Zvolte prosím název totoho účtu." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Kořenový adresář TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "Zadejte prosím adresář, ve kterém bude umístěn kořen TFTP serveru:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Adresa a port serveru TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Zadejte prosím adresu a port, na kterém bude TFTP server naslouchat, ve " "formě [adresa][:port]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Ve výchozím nastavení TFTP server naslouchá na portu 69 na všech adresách a " "všech síťových rozhraních. Pokud nebude zadán port, použije se " "výchozí hodnota 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Upozornění: Pro vyloučení záměny s volitelným údajem o portu je třeba " "numerické adresy IPv6 uzavřít do hranatých závorek." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Dodatečné volby pro TFTP server:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Zde mohou být TFTP serveru předány dodatečné volby, jejich přehled naleznete " "v manuálové stránce tftpd(8)." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Jiné volby než doporučované '--secure' nejsou obvykle potřeba a využijete je " "pouze ve speciálních situacích. Pokud nevíte, ponechejte doporučenou výchozí " "hodnotu." tftp-hpa-5.3+20251209/debian/po/da.po000066400000000000000000000072641511036464300166040ustar00rootroot00000000000000# Danish translation of tftpd-hpa debconf templates. # 2010 Joe Hansen # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2010-09-25 17:30+01:00\n" "Last-Translator: Joe Hansen \n" "Language-Team: Danish \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Dedikeret systemkonto til tftpd-hpa's TFTP-dæmon:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "TFTP-serveren skal bruge en dedikeret konto til sine handlinger, så " "systemets sikkerhed ikke kompromiteres ved at køre den med " "superbrugerrettigheder." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Vælg venligst den kontos brugernavn." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "TFTP-rodmappe:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "Angiv venligst mappen som vil blive brugt som rod for TFTP-serveren." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "TFTP-serveradresse og -port:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Angiv venligst en adresse og port at lytte på i form af [adresse][:port]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Som standard, lytter TFTP-serveren på port 69 for alle adresser og alle " "grænseflader. Hvis ingen port er angivet, er standarden 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Bemærk venligst at numeriske IPv6-adresser skal vedlægges i firkantede " "parenteser for at undgå tvetydighed med den frivillige portinformation." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Yderligere tilvalg for TFTP-server:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Yderligere tilvalg kan videresendes til TFTP-serveren med denne mekanisme, " "konsulter venligst manualsiden tftpd(8) for yderligere information om " "tilgængelige tilvalg." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Tilvalg udover den anbefalede '--secure' er sjældent nødvendigt og kun til " "specielle situationer. Hvis usikker, behold den anbefalede standardværdi." tftp-hpa-5.3+20251209/debian/po/de.po000066400000000000000000000077601511036464300166110ustar00rootroot00000000000000# German translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Kai Wasserbäch # Copyright (C) 2009 Helge Kreutzmann # Copyright (C) 2009-2010 Daniel Baumann # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2010-07-20 05:54+0200\n" "Last-Translator: Daniel Baumann \n" "Language-Team: none\n" "Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Eigenes Systemkonto für den tftpd-hpa TFTP-Daemon:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "Der TFTP-Server muss ein eigenes Konto für den Betrieb verwenden, um die " "Sicherheit des Systems nicht durch das Betreiben mit Superuser-Rechten zu " "kompromittieren." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Bitte wählen Sie den Benutzernamen dieses Kontos." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "TFTP-Wurzelverzeichnis:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Bitte geben Sie das Verzeichnis an, welches als Wurzelverzeichnis für den " "TFTP-Server verwendet werden soll." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "TFTP-Serveradresse und -Port:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Bitte geben Sie eine Adresse und einen Port in der Form [Adresse][:Port] an, " "an dem auf Anfragen gewartet werden soll." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Standardmässig wartet der TFTP-Server auf Port 69 auf allen Adressen und " "allen Schnittstellen. Ohne Port-Angabe wird die Vorgabe 69 " "verwendet." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Bitte beachten Sie, dass numerische IPv6-Adressen in eckige Klammern " "eingeschlossen werden müssen, um Zweideutigkeiten mit der Port-Information " "zu vermeiden." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Zusätzliche TFTP-Server Optionen:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Dem TFTP-Server kann mit diesem Mechanismus zusätzliche Optionen übergeben " "werden. Bitte lesen Sie die Handbuchseite tftpd(8) für weitere Informationen " "über verfügbare Optionen." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Andere als die empfohlene Option \"--secure\" werden selten und nur für " "besondere Situationen benötigt. Falls Sie sich unsicher sind, belassen Sie " "den Vorgabewert." tftp-hpa-5.3+20251209/debian/po/es.po000066400000000000000000000100351511036464300166150ustar00rootroot00000000000000# Spanish translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Software in the Public Interest # 2009 Fernando González de Requena # 2010 Omar Campagne # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftpd-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2010-07-18 10:38+0200\n" "Last-Translator: Omar Campagne \n" "Language-Team: Spanish \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Cuenta del sistema dedicada para el demonio de TFTP tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "El servidor de TFTP debe utilizar una cuenta dedicada para su " "funcionamiento, de tal modo que la seguridad del sistema no se vea " "comprometida por su utilización con privilegios de administración." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Elija un nombre de usuario para esa cuenta." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Directorio raíz del servidor de TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Especifique el directorio que se utilizará como directorio raíz para el " "servidor de TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Dirección y puerto del servidor de TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Especifique una dirección y puerto en el que escuchar con la forma " "[dirección][:puerto]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Por omisión, el servidor de TFTP escucha en el puerto 69 de todas las " "direcciones e interfaces. Si no se especifica un puerto, el " "valor por omisión es 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Tenga en cuenta que las direcciones IPv6 numéricas deben ir entre corchetes " "«[]» para evitar la ambigüedad con la información opcional del puerto." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Opciones adicionales del servidor de TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Mediante este mecanismo, se pueden introducir opciones adicionales al " "servidor de TFTP. Para más información acerca de las opciones disponibles " "consulte la página de manual tftpd(8)." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Rara vez, y sólo en situaciones especiales, necesitará otras opciones más " "allá de la recomendada, «--secure». Si no está seguro, deje el valor " "recomendado por omisión." tftp-hpa-5.3+20251209/debian/po/fi.po000066400000000000000000000057761511036464300166240ustar00rootroot00000000000000# Finnish translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Esko Arajärvi # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2009-04-07 22:19+0300\n" "Last-Translator: Esko Arajärvi \n" "Language-Team: Finnish \n" "Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Dedikoitu järjestelmätunnus vsfptd:n TFTP-taustaohjelman ajamiseen:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "TFTP-palvelimen tulee käyttää dedikoitua tunnusta toiminnoissaan, jotta " "järjestelmän turvallisuus ei vaarannu kuten käytettäessä " "pääkäyttäjäoikeuksia." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Valitse kyseisen tunnuksen nimi." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "TFTP-juurihakemisto:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "Anna hakemisto, jota käytetään TFTP-palvelimen juurena." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" tftp-hpa-5.3+20251209/debian/po/fr.po000066400000000000000000000075641511036464300166320ustar00rootroot00000000000000# French translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Steve Petruzzello # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2009-03-26 01:12+0100\n" "Last-Translator: Steve Petruzzello \n" "Language-Team: French \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Identifiant dédié pour le démon TFTP tftpd-hpa :" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "Afin de ne pas compromettre la sécurité du système, le serveur TFTP doit " "être exécuté avec un identifiant spécifique, différent du superutilisateur." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Veuillez choisir cet identifiant." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Répertoire racine TFTP :" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Veuillez choisir le répertoire racine qui sera utilisé par le serveur TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Adresse et port du serveur TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Veuillez indiquer une adresse et un port d'écoute sous la forme [adresse][:" "port]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Le serveur TFTP écoute par défaut sur le port 69 pour toutes les adresses et " "toutes les interfaces. Si aucun port n'est indiqué, le port par " "défaut sera le port 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Veuillez noter que pour ne pas être confondues avec des numéros de ports, " "d'éventuelles adresses IPv6 doit être entourées de crochets. " #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Options supplémentaires pour le serveur TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Des options supplémentaires peuvent être utilisées avec le serveur TFTP. " "Veuillez consulter la page de manuel tftp(8) pour davantage d'informations " "sur les options disponibles." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "À part l'option « --secure » qui est recommandée, les autres sont rarement " "nécessaires et ne sont utilisées que pour des situations très spéciales. " "Dans le doute, vous devriez laisser les valeurs par défaut." tftp-hpa-5.3+20251209/debian/po/gl.po000066400000000000000000000060511511036464300166130ustar00rootroot00000000000000# Galizian translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Marce Villarino # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2009-04-15 21:32+0200\n" "Last-Translator: marce villarino \n" "Language-Team: Galician \n" "Language: gl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n != 1;\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Conta de usuario do sistema adicada ao daemon TFTP tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "O servidor TFTP debe empregar unha conta adicada a el para que a seguridade " "do sistema non se poña en perigo ao executalo con privilexios de " "administrador." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Escolla o nome de usuario desa conta." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Directorio raíz do TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Especifique o directorio que se empregará como raíz polo servidor TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" tftp-hpa-5.3+20251209/debian/po/it.po000066400000000000000000000076421511036464300166340ustar00rootroot00000000000000# Italian translation of tftpd-hpa debconf templates. # Copyright (C) 2009-2010 Vincenzo Campanella # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-15\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2010-09-17 13:35+0100\n" "Last-Translator: Vincenzo Campanella \n" "Language-Team: Italian \n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Account di sistema dedicato per il demone TFTP di tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "Il server TFTP deve utilizzare un account dedicato per eseguire le proprie " "operazioni, in modo che la sicurezza del sistema non rischi di essere " "compromessa eseguendolo con privilegi di superutente." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Scegliere il nome utente di tale account." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Directory radice TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Specificare la directory che verrà utilizzata come radice per il server TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Indirizzo e porta del server TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Specificare un indirizzo e una porta, sotto forma di [indirizzo][:porta]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "In modo predefinito il server TFTP si pone in ascolto sulla posta 69 su " "tutti gli indirizzi e tutte le interfacce. Se non viene " "specificata alcuna porta viene utilizzata quella predefinita (la 69)." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Notare che gli indirizzi numerici IPv6 devono essere racchiusi fra parentesi " "quadre al fine di evitare ambiguità con l'informazione facoltativa della " "porta." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Opzioni addizionali per il server TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "È possibile passare al server TFTP delle opzioni addizionali utilizzando " "questo meccanismo; per maggiori informazioni sulle opzioni disponibili " "consultare le pagine del manuale di tftpd(8)." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Opzioni all'infuori di quella, raccomandata, «--secure» sono raramente " "necessarie e solo per situazioni particolari. In caso di dubbio, lasciare il " "valore predefinito." tftp-hpa-5.3+20251209/debian/po/ja.po000066400000000000000000000103041511036464300165770ustar00rootroot00000000000000# Japanese translation of tftpd-hpa debconf templates. # Copyright (C) 2009-2010 Hideki Yamane # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2010-05-04 07:21+0200\n" "Last-Translator: Hideki Yamane (Debian-JP) \n" "Language-Team: Japanese \n" "Language: ja\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "tftpd-hpa TFTP デーモン専用のシステムアカウント:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "TFTP サーバはその動作について専用のアカウントを使うようになっているため、管理" "者特権で動作していてもシステムのセキュリティは侵害されません。" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "アカウントのユーザ名を選んでください。" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "TFTP の root ディレクトリ:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "TFTP サーバの root ディレクトリとして利用するディレクトリを指定してください。" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "TFTP サーバのアドレスとポート番号" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "[address][:port] という形で listen するアドレスとポート番号を指定してくださ" "い。" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "デフォルトでは、TFTP サーバは全てのアドレス上の69番ポートと、全てのインター" "フェイス上で listen します。ポートが指定されない場合は、デフォル" "ト値は 69 です。" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "数字で表記される IPv6 アドレスは、追加のポート情報との混同を避けるため、角" "カッコ ([]) で括られなければならないことに注意してください。" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "TFTP サーバの追加オプション" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "この方法で TFTP サーバに追加オプションを渡すことができます。利用可能なオプ" "ションについての詳細は、tftpd(8) マニュアルページを確認してください。" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "推奨されている '--secure' 以外のオプションが必要なことは稀で、特定の状況にの" "み必要とされます。良く分からない場合は、推奨であるデフォルト値のままにしてお" "いてください。" tftp-hpa-5.3+20251209/debian/po/nl.po000066400000000000000000000074531511036464300166310ustar00rootroot00000000000000# Dutch translation of tftpd-hpa debconf templates. # Copyright (C) 2012 Jeroen Schot # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.2\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2012-01-12 14:42+0100\n" "Last-Translator: Jeroen Schot \n" "Language-Team: Debian l10n Dutch \n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Speciaal systeemaccount voor de tftpd-hpa-achtergronddienst:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "De TFTP-server moet een speciaal account gebruiken voor zijn werkzaamheden, " "want als hij met beheerdersrechten wordt uitgevoerd kan dit de beveiliging " "van het systeem in gevaar brengen." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Welke gebruikersnaam moet de account krijgen?" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "TFTP-hoofdmap:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "Welke map moet er worden gebruikt als hoofdmap voor de TFTP-server?" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Adres en poort voor de TFTP-server:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Op welk adres en poort moet de server luisteren? Voer dit in als [adres][:" "poort]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Standaard luistert de TFTP-server op poort 69 van alle adressen en " "interfaces. Als u geen poort opgeeft, zal de standaardwaarde 69 " "worden gebruikt." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Merk op dat numeriek IPv6-adressen tussen vierkante haken moeten worden " "geplaatst om verwarring met de optionele poortinformatie te voorkomen." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Extra opties voor TFTP-server:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Met dit mechanisme kunnen er extra opties aan de TFTP-server worden " "meegegeven. Zie de man-pagina van tftpd(8) voor meer informatie over de " "beschikbare opties." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Andere opties dan de aanbevolen '--secure' zijn zelden nodig en alleen voor " "speciale omstandigheden. Als u twijfelt, laat dit dan op de aanbevolen " "standaard waarde." tftp-hpa-5.3+20251209/debian/po/pt.po000066400000000000000000000076151511036464300166430ustar00rootroot00000000000000# Portuguese translation of tftpd-hpa debconf templates. # 2009 Américo Monteiro # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2009-11-14 01:07+0000\n" "Last-Translator: Américo Monteiro \n" "Language-Team: Portuguese \n" "Language: pt\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Conta dedicada do sistema para o daemon TFTP tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "O servidor TFTP tem que usar uma conta dedicada para as suas operações, isto " "para que a segurança do sistema não seja comprometida ao corrê-lo com " "privilégios de super-utilizador." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Por favor escolha o nome de utilizador dessa conta." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Directório raiz TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Por favor especifique o directório que será usado como a raiz do servidor " "TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Endereço e porto do servidor TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Por favor especifique um endereço e porto a escutar no formato de [endereço]" "[:porto]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Por predefinição, o servidor TFTP escuta no porto 69 em todos os endereços e " "todas as interfaces. Se nenhum porto for especificado, será " "usado o 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Por favor note que endereços IPv6 numéricos tem que estar dentro de " "parênteses rectos para evitar a ambiguidade com a informação de porto " "opcional." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Opções adicionais do servidor TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Pode ser passadas opções adicionais ao servidor TFTP com este mecanismo, por " "favor consulte a manpage tftpd(8) para mais informação sobre opções " "disponíveis." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Opções além da recomendada '--secure' são raramente necessárias e apenas " "para situações especiais. Em caso de dúvidas, deixe no valor predefinido e " "recomendado." tftp-hpa-5.3+20251209/debian/po/pt_BR.po000066400000000000000000000077271511036464300172320ustar00rootroot00000000000000# Brazilian Portuguese translation of tftpd-hpa debconf templates. # 2011 Flamarion Jorge # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-22\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2011-06-04 15:25-0300\n" "Last-Translator: Flamarion Jorge \n" "Language-Team: Brazilian Portuguese \n" "Language: pt_BR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n > 1);\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Conta de sistema dedicada para o daemon TFTP do tftp-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "O servidor TFTP deve usar uma conta dedicada para o seu funcionamento, de " "modo que a segurança do sistema não seja comprometida por executá-lo com " "privilégios de superusuário." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Por favor, escolha o nome de usuário da conta." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Diretório raiz do TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Por favor, especifique o diretório que será usado como raiz para o servidor " "TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Endereço e porta do servidor TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Por favor, especifique um endereço e uma porta para ouvir, usando o seguinte " "formato [endereço][:porta]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Por padrão, o servidor TFTP escuta na porta 69 em todos os endereços de " "todas as interfaces. Se a porta não for especificada, o padrão " "será a 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Por favor, note que os endereços IPv6 numéricos devem ser colocados entre " "colchetes para evitar ambiguidades com as informações da porta opcional." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Opções adicionais para o servidor TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Opções adicionais podem ser passadas para o servidor TFTP com este " "mecanismo, por favor, consulte a manpage tftpd(8) para mais informações " "sobre opções disponíveis." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Outras opções além da recomendada '--secure' raramente são necessárias e " "somente em situações especiais. Se não tiver certeza, é recomendado deixar o " "valor padrão." tftp-hpa-5.3+20251209/debian/po/ru.po000066400000000000000000000112201511036464300166310ustar00rootroot00000000000000# German translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Sergey Alyoshin # Copyright (C) 2009 Yuri Kozlov # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2009-12-30 19:18+0300\n" "Last-Translator: Yuri Kozlov \n" "Language-Team: Russian \n" "Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "" "Специально выделенная системная учётная запись для TFTP службы tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "Для улучшения безопасности системы TFTP сервер должен использовать " "специально выделенную учётную запись, а не запускаться с правами " "суперпользователя." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Укажите имя такой учётной записи." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Корневой каталог TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" "Укажите каталог, который будет использован в качестве корневого каталога " "TFTP сервера." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Адрес и порт сервера TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "Укажите прослушиваемый адрес и порт в виде [адрес][:порт]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "По умолчанию, сервер TFTP прослушивает порт 69 на всех адресах и интерфейсах. " "Если порт не указан, то по умолчанию используется 69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Заметим, что числовые адреса IPv6 нужно заключать в квадратные скобки, чтобы " "избежать неоднозначности с указанием номера порта." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Дополнительные параметры сервера TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Серверу TFTP можно передать дополнительные параметры; возможные параметры " "описаны в справочной странице tftpd(8)." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Кроме рекомендуемого параметра '--secure' все остальные используются редко и " "в определённых ситуациях. Если не уверены, оставьте рекомендуемое значение " "по умолчанию." tftp-hpa-5.3+20251209/debian/po/sk.po000066400000000000000000000077161511036464300166370ustar00rootroot00000000000000# Slovak translation of tftpd-hpa debconf templates. # Copyright (C) 2013 Slavko # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.2-4\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2013-03-28 19:21+0100\n" "Last-Translator: Slavko \n" "Language-Team: slovenčina \n" "Language: sk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" "X-POFile-SpellExtra: secure tftpd-hpa superpoužívateľa IPv6 69 TFTP\n" "X-POFile-SpellExtra: tftpd\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Vyhradený systémový účet pre démona TFTP tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "Server TFTP musí na svoju činnosť používať vyhradený účet, aby nebola " "ohrozená systémová bezpečnosť jeho spúšťaním s právami superpoužívateľa." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Prosím, zvoľte používateľské meno účtu." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Koreňový adresár TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "Prosím, zadajte adresár, ktorý bude použitý ako koreň servera TFTP." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Adresa a port servera TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "Prosím, zadajte adresu a port načúvania vo forme [adresa][:port]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Predvolene server TFTP načúva na porte 69 na všetkých adresách a všetkých " "rozhraniach. Ak nie je zadaný port, je predvolene použitý port " "69." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Prosím, pamätajte, že číselné adresy IPv6 musia byť uzatvorené v lomených " "zátvorkách, aby sa predišlo zámene s voliteľnou informáciou o porte." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Dodatočné voľby servera TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Pomocou tohoto mechanizmu možno serveru TFTP poslať dodatočné voľby, prosím, " "nahliadnite do manuálovej stránky tftpd(8) s ďalšími informáciami o " "dostupných voľbách." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Iné voľby ako odporúčané „--secure” sú potrebné málokedy a len v špeciálnych " "situáciách. Ak si nie ste istý, nechajte odporúčanú predvolenú hodnotu." tftp-hpa-5.3+20251209/debian/po/sv.po000066400000000000000000000073301511036464300166420ustar00rootroot00000000000000# Swedish translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Martin Bagge # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2009-11-16 23:01+0100\n" "Last-Translator: Martin Bagge \n" "Language-Team: swedish \n" "Language: sv\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "Dedikerat systemkonto för ftp-tjänsten tftpd-hpa:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "TFTP-servern måste ha ett dedikerat konto för att fungera på ett säkert " "sätt, att använda privilegier från en superanvändare är inte säkert." #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "Ange kontots användarnamn." #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "Rot-katalog för TFTP:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "Ange katalog som ska agera rot-nivå för ftp-servern." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "Adress och port till TFTP-server:" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" "Ange en adress och en port att lyssnar på, använd formen [adress][:port]." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" "Standardvärdet är att TFTP-servern lyssnar på port 69 på alla adress och " "alla gränssnitt. Om ingen port anges kommer standardporten 69 " "att användas." #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" "Observera att numeriska IPv6-adresser måste omges av hakparanteser för att " "undvika att tolkas som ett portnummer." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "Ytterligare inställningar för TFTP-server:" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" "Med detta val kan ytterligare inställningar skickas till TFTP-servern. Läs i " "manualsidan tftpd(8) om vilka inställningar som kan göras." #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" "Särskilda inställningar utöver den rekomenderade \"--secure\" används nästan " "aldrig och kräver vanligen mycket speciella omständigheter. Använd de " "rekomenderade inställningarna om du är osäker." tftp-hpa-5.3+20251209/debian/po/templates.pot000066400000000000000000000051571511036464300204010ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the tftp-hpa package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: tftp-hpa\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" tftp-hpa-5.3+20251209/debian/po/zh_CN.po000066400000000000000000000057701511036464300172210ustar00rootroot00000000000000# Simplified Chinese translation of tftpd-hpa debconf templates. # Copyright (C) 2009 Deng Xiyue # This file is distributed under the same license as the tftpd-hpa package. # msgid "" msgstr "" "Project-Id-Version: tftp-hpa 5.0-14\n" "Report-Msgid-Bugs-To: tftp-hpa@packages.debian.org\n" "POT-Creation-Date: 2020-09-16 17:46+0200\n" "PO-Revision-Date: 2009-03-26 16:48+0800\n" "Last-Translator: Deng Xiyue \n" "Language-Team: Debian Chinese GB \n" "Language: zh_CN\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Dedicated system account for the tftpd-hpa TFTP daemon:" msgstr "指定操作 tftpd-hpa TFTP 守护进程的专用系统帐户:" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "" "The TFTP server must use a dedicated account for its operation so that the " "system's security is not compromised by running it with superuser privileges." msgstr "" "TFTP 服务器必须使用一个专用的账户来进行操作,这样就不会因为使用超级用户权限运" "行而破坏系统的安全。" #. Type: string #. Description #: ../tftpd-hpa.templates:1001 msgid "Please choose that account's username." msgstr "请选择账户的用户名。" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "TFTP root directory:" msgstr "TFTP 根目录:" #. Type: string #. Description #: ../tftpd-hpa.templates:2001 msgid "" "Please specify the directory that will be used as root for the TFTP server." msgstr "请指定用作 TFTP 服务器根目录的目录。" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "TFTP server address and port:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please specify an address and port to listen to in the form of [address][:" "port]." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "By default, the TFTP server listens to port 69 on all addresses and all " "interfaces. If no port is specified, it defaults to 69." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:3001 msgid "" "Please note that numeric IPv6 addresses must be enclosed in square brackets " "to avoid ambiguity with the optional port information." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "TFTP server additional options:" msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Additional options can be passed to the TFTP server with this mechanism, " "please consult the tftpd(8) manpage for more information about available " "options." msgstr "" #. Type: string #. Description #: ../tftpd-hpa.templates:4001 msgid "" "Options other than the recommended '--secure' are rarely needed and only for " "special situations. If unsure, leave it at the recommended default value." msgstr "" tftp-hpa-5.3+20251209/debian/rules000077500000000000000000000011741511036464300163140ustar00rootroot00000000000000#!/usr/bin/make -f # Turn on all hardening flags, as we're a networked daemon. export DEB_BUILD_MAINT_OPTIONS = hardening=+all # see EXAMPLES in dpkg-buildflags(1) and read /usr/share/dpkg/* DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/default.mk %: dh $@ override_dh_autoreconf: aclocal --install --output=autoconf/aclocal.m4 -I autoconf/m4 dh_autoreconf autoreconf -- -v -f -i -B autoconf override_dh_auto_configure: dh_auto_configure -- \ --without-readline override_dh_auto_install: make install INSTALLROOT=$(CURDIR)/debian/tmp override_dh_strip: dh_strip --dbgsym-migration='tftp-hpa-dbg (<< 5.2+20150808-3~)' tftp-hpa-5.3+20251209/debian/source/000077500000000000000000000000001511036464300165315ustar00rootroot00000000000000tftp-hpa-5.3+20251209/debian/source/format000066400000000000000000000000141511036464300177370ustar00rootroot000000000000003.0 (quilt) tftp-hpa-5.3+20251209/debian/tftp-hpa.docs000066400000000000000000000000071511036464300176230ustar00rootroot00000000000000README tftp-hpa-5.3+20251209/debian/tftp-hpa.install000066400000000000000000000000511511036464300203400ustar00rootroot00000000000000/usr/bin/tftp /usr/share/man/man1/tftp.1 tftp-hpa-5.3+20251209/debian/tftpd-hpa.README.Debian000066400000000000000000000020651511036464300211630ustar00rootroot00000000000000tftpd-hpa --------- Note that you need to add '--create' to TFTP_OPTIONS in /etc/default/tftpd-hpa if you intend to upload files to the tftp server that do not already exist on the server. Instead of manually editing the file, a simple: # dpkg-reconfigure -plow tftpd-hpa let's you configure additional options more conveniently. With Compaq Professional Workstation XP1000 machines acting as clients you might need to use "-r blksize" option to inhibit OACK being sent out as they reply to regular TFTP port instead of the port where OACK originated. This is SRM firmware bug on those machines. Many thanks to Steffen Grunewald for tracking this down. If you're running a kernel configuration that has no IPv6 support (note: all Debian kernels come with IPv6 support), you need to use the "-4" option, otherwise tftpd-hpa refuses to start with: cannot open IPv6 socket, disable IPv6: Address family not supported by protocol Cannot set nonblock flag on socket: Bad file descriptor -- Daniel Baumann Sat, 15 Aug 2009 22:34:42 +0200 tftp-hpa-5.3+20251209/debian/tftpd-hpa.conffiles000066400000000000000000000000531511036464300210100ustar00rootroot00000000000000remove-on-upgrade /etc/init/tftpd-hpa.conf tftp-hpa-5.3+20251209/debian/tftpd-hpa.config000066400000000000000000000007641511036464300203160ustar00rootroot00000000000000#!/bin/sh set -e . /usr/share/debconf/confmodule CONFFILE="/etc/default/tftpd-hpa" if [ -e "${CONFFILE}" ] then . ${CONFFILE} || true db_set tftpd-hpa/username "${TFTP_USERNAME}" db_set tftpd-hpa/directory "${TFTP_DIRECTORY}" db_set tftpd-hpa/address "${TFTP_ADDRESS}" db_set tftpd-hpa/options "${TFTP_OPTIONS}" fi db_input low tftpd-hpa/username || true db_input low tftpd-hpa/directory || true db_input low tftpd-hpa/address || true db_input low tftpd-hpa/options || true db_go db_stop tftp-hpa-5.3+20251209/debian/tftpd-hpa.docs000066400000000000000000000000271511036464300177710ustar00rootroot00000000000000README README.security tftp-hpa-5.3+20251209/debian/tftpd-hpa.examples000066400000000000000000000000231511036464300206530ustar00rootroot00000000000000tftpd/sample.rules tftp-hpa-5.3+20251209/debian/tftpd-hpa.init000066400000000000000000000036141511036464300200110ustar00rootroot00000000000000#!/bin/sh ### BEGIN INIT INFO # Provides: tftpd-hpa # Required-Start: $local_fs $remote_fs $syslog $network # Required-Stop: $local_fs $remote_fs $syslog $network # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: HPA's tftp server # Description: Trivial File Transfer Protocol (TFTP) is a file transfer # protocol, mainly to serve boot images over the network # to other machines (PXE). ### END INIT INFO PATH="/sbin:/bin:/usr/sbin:/usr/bin" DAEMON="/usr/sbin/in.tftpd" test -x "$DAEMON" || exit 0 NAME="in.tftpd" DESC="HPA's tftpd" PIDFILE="/var/run/tftpd-hpa.pid" DEFAULTS="/etc/default/tftpd-hpa" set -e [ -r "$DEFAULTS" ] && . "$DEFAULTS" . /lib/lsb/init-functions do_start() { # Ensure --secure and multiple server directories are not used at the # same time if [ "$(echo $TFTP_DIRECTORY | wc -w)" -ge 2 ] && \ echo $TFTP_OPTIONS | grep -qs secure then echo echo "When --secure is specified, exactly one directory can be specified." echo "Please correct your $DEFAULTS." exit 1 fi # Ensure server directories exist for d in $TFTP_DIRECTORY do if [ ! -d "$d" ] then echo "$d missing, aborting." exit 1 fi done start-stop-daemon --start --quiet --oknodo --exec $DAEMON -- \ --listen --user $TFTP_USERNAME --address $TFTP_ADDRESS \ $TFTP_OPTIONS $TFTP_DIRECTORY } do_stop () { start-stop-daemon --stop --quiet --oknodo --name $NAME } do_reload () { start-stop-daemon --stop --quiet --oknodo --name $NAME --signal 1 } case "$1" in start) log_daemon_msg "Starting $DESC" "$NAME" do_start log_end_msg $? ;; stop) log_daemon_msg "Stopping $DESC" "$NAME" do_stop log_end_msg $? ;; restart|force-reload) log_daemon_msg "Restarting $DESC" "$NAME" do_stop sleep 1 do_start log_end_msg $? ;; status) status_of_proc $DAEMON $NAME ;; *) echo "Usage: $0 {start|stop|restart|force-reload|status}" >&2 exit 3 ;; esac tftp-hpa-5.3+20251209/debian/tftpd-hpa.install000066400000000000000000000001161511036464300205060ustar00rootroot00000000000000/usr/sbin/in.tftpd /usr/share/man/man8/in.tftpd.8 /usr/share/man/man8/tftpd.8 tftp-hpa-5.3+20251209/debian/tftpd-hpa.postinst000066400000000000000000000044621511036464300207330ustar00rootroot00000000000000#!/bin/sh set -e . /usr/share/debconf/confmodule CONFFILE="/etc/default/tftpd-hpa" case "${1}" in configure) db_get tftpd-hpa/username TFTP_USERNAME="${RET:-tftp}" db_get tftpd-hpa/directory TFTP_DIRECTORY="${RET:-/srv/tftp}" db_get tftpd-hpa/address TFTP_ADDRESS="${RET:-:69}" db_get tftpd-hpa/options TFTP_OPTIONS="${RET}" # is ok when empty db_stop if [ ! -e "${CONFFILE}" ] then cat > "${CONFFILE}" << EOF # /etc/default/tftpd-hpa TFTP_USERNAME="${TFTP_USERNAME}" TFTP_DIRECTORY="${TFTP_DIRECTORY}" TFTP_ADDRESS="${TFTP_ADDRESS}" TFTP_OPTIONS="${TFTP_OPTIONS}" EOF fi cp -a -f "${CONFFILE}" "${CONFFILE}.tmp" # If the admin deleted or commented some variables but then set # them via debconf, (re-)add them to the config file. test -z "${TFTP_USERNAME}" || \ grep -Eq '^ *TFTP_USERNAME=' "${CONFFILE}" || \ echo "TFTP_USERNAME=" >> "${CONFFILE}" test -z "${TFTP_DIRECTORY}" || \ grep -Eq '^ *TFTP_DIRECTORY=' "${CONFFILE}" || \ echo "TFTP_DIRECTORY=" >> "${CONFFILE}" test -z "${TFTP_ADDRESS}" || \ grep -Eq '^ *TFTP_ADDRESS=' "${CONFFILE}" || \ echo "TFTP_ADDRESS=" >> "${CONFFILE}" test -z "${TFTP_OPTIONS}" || \ grep -Eq '^ *TFTP_OPTIONS=' "${CONFFILE}" || \ echo "TFTP_OPTIONS=" >> "${CONFFILE}" sed -e "s|^ *TFTP_USERNAME=.*|TFTP_USERNAME=\"${TFTP_USERNAME}\"|" \ -e "s|^ *TFTP_DIRECTORY=.*|TFTP_DIRECTORY=\"${TFTP_DIRECTORY}\"|" \ -e "s|^ *TFTP_ADDRESS=.*|TFTP_ADDRESS=\"${TFTP_ADDRESS}\"|" \ -e "s|^ *TFTP_OPTIONS=.*|TFTP_OPTIONS=\"${TFTP_OPTIONS}\"|" \ < "${CONFFILE}" > "${CONFFILE}.tmp" mv -f "${CONFFILE}.tmp" "${CONFFILE}" if ! getent passwd "${TFTP_USERNAME}" > /dev/null 2>&1 then adduser --system --home $(echo ${TFTP_DIRECTORY} | awk '{ print $1 }') --no-create-home --quiet --gecos 'tftp daemon' --group ${TFTP_USERNAME} else echo "tftpd user (${TFTP_USERNAME}) already exists, doing nothing." fi for _DIRECTORY in ${TFTP_DIRECTORY} do if [ ! -d "${_DIRECTORY}" ] then mkdir -p "${_DIRECTORY}" chown root:nogroup ${_DIRECTORY} -R else echo echo "tftpd-hpa directory (${_DIRECTORY}) already exists, doing nothing." fi done ;; abort-upgrade|abort-remove|abort-deconfigure) ;; *) echo "postinst called with unknown argument \`${1}'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 tftp-hpa-5.3+20251209/debian/tftpd-hpa.postrm000066400000000000000000000007551511036464300203750ustar00rootroot00000000000000#!/bin/sh set -e case "$1" in remove) if [ -e /etc/default/tftpd-hpa ] then . /etc/default/tftpd-hpa for d in $TFTP_DIRECTORY do if [ -d "$d" ] then rmdir --ignore-fail-on-non-empty "$d" > /dev/null 2>&1 || true fi done fi ;; purge) rm -f /etc/default/tftpd-hpa ;; upgrade|failed-upgrade|abort-install|abort-upgrade|disappear) ;; *) echo "postrm called with unknown argument \`$1'" >&2 exit 1 ;; esac #DEBHELPER# exit 0 tftp-hpa-5.3+20251209/debian/tftpd-hpa.service000066400000000000000000000011231511036464300204770ustar00rootroot00000000000000[Unit] Description=tftpd-hpa TFTP Server Documentation=man:in.tftpd After=network-online.target [Service] Type=forking EnvironmentFile=/etc/default/tftpd-hpa ExecStart=/usr/sbin/in.tftpd --listen --user $TFTP_USERNAME --address $TFTP_ADDRESS $TFTP_OPTIONS $TFTP_DIRECTORY ProtectHome=yes ProtectSystem=full ProtectHostname=yes ProtectClock=yes ProtectKernelTunables=yes ProtectKernelModules=yes ProtectKernelLogs=yes ProtectControlGroups=yes PrivateDevices=yes PrivateTmp=yes RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 SystemCallArchitectures=native [Install] WantedBy=multi-user.target tftp-hpa-5.3+20251209/debian/tftpd-hpa.templates000066400000000000000000000025341511036464300210440ustar00rootroot00000000000000Template: tftpd-hpa/username Type: string Default: tftp _Description: Dedicated system account for the tftpd-hpa TFTP daemon: The TFTP server must use a dedicated account for its operation so that the system's security is not compromised by running it with superuser privileges. . Please choose that account's username. Template: tftpd-hpa/directory Type: string Default: /srv/tftp _Description: TFTP root directory: Please specify the directory that will be used as root for the TFTP server. Template: tftpd-hpa/address Type: string Default: :69 _Description: TFTP server address and port: Please specify an address and port to listen to in the form of [address][:port]. . By default, the TFTP server listens to port 69 on all addresses and all interfaces. If no port is specified, it defaults to 69. . Please note that numeric IPv6 addresses must be enclosed in square brackets to avoid ambiguity with the optional port information. Template: tftpd-hpa/options Type: string Default: --secure _Description: TFTP server additional options: Additional options can be passed to the TFTP server with this mechanism, please consult the tftpd(8) manpage for more information about available options. . Options other than the recommended '--secure' are rarely needed and only for special situations. If unsure, leave it at the recommended default value. tftp-hpa-5.3+20251209/install-sh000077500000000000000000000126711511036464300160220ustar00rootroot00000000000000#!/bin/sh # # install - install a program, script, or datafile # This comes from X11R5 (mit/util/scripts/install.sh). # # Copyright 1991 by the Massachusetts Institute of Technology # # Permission to use, copy, modify, distribute, and sell this software and its # documentation for any purpose is hereby granted without fee, provided that # the above copyright notice appear in all copies and that both that # copyright notice and this permission notice appear in supporting # documentation, and that the name of M.I.T. not be used in advertising or # publicity pertaining to distribution of the software without specific, # written prior permission. M.I.T. makes no representations about the # suitability of this software for any purpose. It is provided "as is" # without express or implied warranty. # # Calling this script install-sh is preferred over install.sh, to prevent # `make' implicit rules from creating a file called install from it # when there is no Makefile. # # This script is compatible with the BSD install script, but was written # from scratch. It can only install one file at a time, a restriction # shared with many OS's install programs. # set DOITPROG to echo to test this script # Don't use :- since 4.3BSD and earlier shells don't like it. doit="${DOITPROG-}" # put in absolute paths if you don't have them in your path; or use env. vars. mvprog="${MVPROG-mv}" cpprog="${CPPROG-cp}" chmodprog="${CHMODPROG-chmod}" chownprog="${CHOWNPROG-chown}" chgrpprog="${CHGRPPROG-chgrp}" stripprog="${STRIPPROG-strip}" rmprog="${RMPROG-rm}" mkdirprog="${MKDIRPROG-mkdir}" transformbasename="" transform_arg="" instcmd="$mvprog" chmodcmd="$chmodprog 0755" chowncmd="" chgrpcmd="" stripcmd="" rmcmd="$rmprog -f" mvcmd="$mvprog" src="" dst="" dir_arg="" while [ x"$1" != x ]; do case $1 in -c) instcmd="$cpprog" shift continue;; -d) dir_arg=true shift continue;; -m) chmodcmd="$chmodprog $2" shift shift continue;; -o) chowncmd="$chownprog $2" shift shift continue;; -g) chgrpcmd="$chgrpprog $2" shift shift continue;; -s) stripcmd="$stripprog" shift continue;; -t=*) transformarg=`echo $1 | sed 's/-t=//'` shift continue;; -b=*) transformbasename=`echo $1 | sed 's/-b=//'` shift continue;; *) if [ x"$src" = x ] then src=$1 else # this colon is to work around a 386BSD /bin/sh bug : dst=$1 fi shift continue;; esac done if [ x"$src" = x ] then echo "install: no input file specified" exit 1 else : fi if [ x"$dir_arg" != x ]; then dst=$src src="" if [ -d $dst ]; then instcmd=: chmodcmd="" else instcmd=$mkdirprog fi else # Waiting for this to be detected by the "$instcmd $src $dsttmp" command # might cause directories to be created, which would be especially bad # if $src (and thus $dsttmp) contains '*'. if [ -f $src -o -d $src ] then : else echo "install: $src does not exist" exit 1 fi if [ x"$dst" = x ] then echo "install: no destination specified" exit 1 else : fi # If destination is a directory, append the input filename; if your system # does not like double slashes in filenames, you may need to add some logic if [ -d $dst ] then dst="$dst"/`basename $src` else : fi fi ## this sed command emulates the dirname command dstdir=`echo $dst | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'` # Make sure that the destination directory exists. # this part is taken from Noah Friedman's mkinstalldirs script # Skip lots of stat calls in the usual case. if [ ! -d "$dstdir" ]; then defaultIFS=' ' IFS="${IFS-${defaultIFS}}" oIFS="${IFS}" # Some sh's can't handle IFS=/ for some reason. IFS='%' set - `echo ${dstdir} | sed -e 's@/@%@g' -e 's@^%@/@'` IFS="${oIFS}" pathcomp='' while [ $# -ne 0 ] ; do pathcomp="${pathcomp}${1}" shift if [ ! -d "${pathcomp}" ] ; then $mkdirprog "${pathcomp}" else : fi pathcomp="${pathcomp}/" done fi if [ x"$dir_arg" != x ] then $doit $instcmd $dst && if [ x"$chowncmd" != x ]; then $doit $chowncmd $dst; else : ; fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dst; else : ; fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dst; else : ; fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dst; else : ; fi else # If we're going to rename the final executable, determine the name now. if [ x"$transformarg" = x ] then dstfile=`basename $dst` else dstfile=`basename $dst $transformbasename | sed $transformarg`$transformbasename fi # don't allow the sed command to completely eliminate the filename if [ x"$dstfile" = x ] then dstfile=`basename $dst` else : fi # Make a temp file name in the proper directory. dsttmp=$dstdir/#inst.$$# # Move or copy the file name to the temp name $doit $instcmd $src $dsttmp && trap "rm -f ${dsttmp}" 0 && # and set any options; do chmod last to preserve setuid bits # If any of these fail, we abort the whole thing. If we want to # ignore errors from any of these, just make sure not to ignore # errors from the above "$doit $instcmd $src $dsttmp" command. if [ x"$chowncmd" != x ]; then $doit $chowncmd $dsttmp; else :;fi && if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd $dsttmp; else :;fi && if [ x"$stripcmd" != x ]; then $doit $stripcmd $dsttmp; else :;fi && if [ x"$chmodcmd" != x ]; then $doit $chmodcmd $dsttmp; else :;fi && # Now rename the file to the real destination. $doit $rmcmd -f $dstdir/$dstfile && $doit $mvcmd $dsttmp $dstdir/$dstfile fi && exit 0 tftp-hpa-5.3+20251209/lib/000077500000000000000000000000001511036464300145555ustar00rootroot00000000000000tftp-hpa-5.3+20251209/lib/Makefile000066400000000000000000000005201511036464300162120ustar00rootroot00000000000000# # Extra functions which may not be available everywhere # SRCROOT = .. -include ../config/MCONFIG include ../MRULES ifeq ($(LIBOBJS),) all: else all: libxtra.a endif install: clean: -rm -f *.a *.o *.obj *.exe distclean: clean -rm -f *~ libxtra.a: $(LIBOBJS) -rm -f libxtra.a $(AR) libxtra.a $(LIBOBJS) $(RANLIB) libxtra.a tftp-hpa-5.3+20251209/lib/daemon.c000066400000000000000000000011121511036464300161570ustar00rootroot00000000000000/* * daemon.c - "daemonize" a process */ #include "config.h" int daemon(int nochdir, int noclose) { int nullfd; pid_t f; if (!nochdir) { if (chdir("/")) return -1; } if (!noclose) { if ((nullfd = open("/dev/null", O_RDWR)) < 0 || dup2(nullfd, 0) < 0 || dup2(nullfd, 1) < 0 || dup2(nullfd, 2) < 0) return -1; close(nullfd); } f = fork(); if (f < 0) return -1; else if (f > 0) _exit(0); #ifdef HAVE_SETSID return setsid(); #else return 0; #endif } tftp-hpa-5.3+20251209/lib/dup2.c000066400000000000000000000004471511036464300156000ustar00rootroot00000000000000/* * dup2.c * * Ersatz dup2() for really ancient systems */ #include "config.h" int dup2(int oldfd, int newfd) { int rv, nfd; close(newfd); nfd = rv = dup(oldfd); if (rv >= 0 && rv != newfd) { rv = dup2(oldfd, newfd); close(nfd); } return rv; } tftp-hpa-5.3+20251209/lib/getaddrinfo.c000066400000000000000000000053651511036464300172200ustar00rootroot00000000000000/* * getaddrinfo.c * * Simple version of getaddrinfo() * */ #include "config.h" extern int errno; extern int h_errno; void freeaddrinfo(struct addrinfo *res) { if (!res) return; if (res->ai_next) freeaddrinfo(res->ai_next); if (res->ai_addr) free(res->ai_addr); if (res->ai_canonname) free(res->ai_canonname); free(res); } int getaddrinfo(const char *node, const char *service, const struct addrinfo *hints, struct addrinfo **res) { struct hostent *host; struct sockaddr *sa; int err, size = 0; if ((!node) || (!res)) { errno = EINVAL; return EAI_SYSTEM; } *res = NULL; /* we do not support service in this version */ if (service) { errno = EINVAL; return EAI_SYSTEM; } host = gethostbyname(node); if (!host) return EAI_NONAME; if (hints) { if (hints->ai_family != AF_UNSPEC) { if (hints->ai_family != host->h_addrtype) return EAI_ADDRFAMILY; } } *res = malloc(sizeof(struct addrinfo)); if (!*res) { return EAI_MEMORY; } memset(*res, 0, sizeof(struct addrinfo)); (*res)->ai_family = host->h_addrtype; if (host->h_length) { if (host->h_addrtype == AF_INET) size = sizeof(struct sockaddr_in); #ifdef HAVE_IPV6 else if (host->h_addrtype == AF_INET6) size = sizeof(struct sockaddr_in6); #endif else { free(*res); *res = NULL; return EAI_ADDRFAMILY; } sa = malloc(size); if (!sa) { free(*res); *res = NULL; return EAI_MEMORY; } memset(sa, 0, size); (*res)->ai_addr = sa; (*res)->ai_addrlen = size; sa->sa_family = host->h_addrtype; if (host->h_addrtype == AF_INET) memcpy(&((struct sockaddr_in *)sa)->sin_addr, host->h_addr, host->h_length); #ifdef HAVE_IPV6 else memcpy(&((struct sockaddr_in6 *)sa)->sin6_addr, host->h_addr, host->h_length); #endif } if (host->h_name) (*res)->ai_canonname = strdup(host->h_name); /* we only handle the first address entry and do not build a list now */ return 0; } const char *gai_strerror(int errcode) { const char *s = NULL; switch(errcode) { case 0: s = "no error"; break; case EAI_MEMORY: s = "no memory"; break; case EAI_SYSTEM: s = strerror(errno); break; case EAI_NONAME: s = hstrerror(h_errno); break; case EAI_ADDRFAMILY: s = "address does not match address family"; break; default: s = "unknown error code"; break; } return s; } tftp-hpa-5.3+20251209/lib/getopt.h000066400000000000000000000006011511036464300162250ustar00rootroot00000000000000#ifndef LIB_GETOPT_H #define LIB_GETOPT_H extern char *optarg; extern int optind, opterr, optopt; struct option { const char *name; int has_arg; int *flag; int val; }; enum { no_argument = 0, required_argument = 1, optional_argument = 2, }; int getopt_long(int, char *const *, const char *, const struct option *, int *); #endif /* LIB_GETOPT_H */ tftp-hpa-5.3+20251209/lib/getopt_long.c000066400000000000000000000062451511036464300172510ustar00rootroot00000000000000/* * getopt_long.c * * getopt_long(), or at least a common subset thereof: * * - Option reordering is not supported * - -W foo is not supported * - First optstring character "-" not supported. */ #include "config.h" char *optarg; int optind, opterr, optopt; static struct getopt_private_state { const char *optptr; const char *last_optstring; char *const *last_argv; } pvt; static inline const char *option_matches(const char *arg_str, const char *opt_name) { while (*arg_str != '\0' && *arg_str != '=') { if (*arg_str++ != *opt_name++) return NULL; } if (*opt_name) return NULL; return arg_str; } int getopt_long(int argc, char *const *argv, const char *optstring, const struct option *longopts, int *longindex) { const char *carg; const char *osptr; int opt; /* getopt() relies on a number of different global state variables, which can make this really confusing if there is more than one use of getopt() in the same program. This attempts to detect that situation by detecting if the "optstring" or "argv" argument have changed since last time we were called; if so, reinitialize the query state. */ if (optstring != pvt.last_optstring || argv != pvt.last_argv || optind < 1 || optind > argc) { /* optind doesn't match the current query */ pvt.last_optstring = optstring; pvt.last_argv = argv; optind = 1; pvt.optptr = NULL; } carg = argv[optind]; /* First, eliminate all non-option cases */ if (!carg || carg[0] != '-' || !carg[1]) return -1; if (carg[1] == '-') { const struct option *lo; const char *opt_end = NULL; optind++; /* Either it's a long option, or it's -- */ if (!carg[2]) { /* It's -- */ return -1; } for (lo = longopts; lo->name; lo++) { if ((opt_end = option_matches(carg+2, lo->name))) break; } if (!opt_end) return '?'; if (longindex) *longindex = lo-longopts; if (*opt_end == '=') { if (lo->has_arg) optarg = (char *)opt_end+1; else return '?'; } else if (lo->has_arg == 1) { if (!(optarg = argv[optind])) return '?'; optind++; } if (lo->flag) { *lo->flag = lo->val; return 0; } else { return lo->val; } } if ((uintptr_t) (pvt.optptr - carg) > (uintptr_t) strlen(carg)) { /* Someone frobbed optind, change to new opt. */ pvt.optptr = carg + 1; } opt = *pvt.optptr++; if (opt != ':' && (osptr = strchr(optstring, opt))) { if (osptr[1] == ':') { if (*pvt.optptr) { /* Argument-taking option with attached argument */ optarg = (char *)pvt.optptr; optind++; } else { /* Argument-taking option with non-attached argument */ if (argv[optind + 1]) { optarg = (char *)argv[optind+1]; optind += 2; } else { /* Missing argument */ optind++; return (optstring[0] == ':') ? ':' : '?'; } } return opt; } else { /* Non-argument-taking option */ /* pvt.optptr will remember the exact position to resume at */ if (!*pvt.optptr) optind++; return opt; } } else { /* Unknown option */ optopt = opt; if (!*pvt.optptr) optind++; return '?'; } } tftp-hpa-5.3+20251209/lib/inet_ntop.c000066400000000000000000000020131511036464300167140ustar00rootroot00000000000000/* * inet_ntop.c * * Simple version of inet_ntop() * */ #include "config.h" extern int errno; const char *inet_ntop(int af, const void *src, char *dst, socklen_t cnt) { char *p; switch(af) { case AF_INET: p = inet_ntoa(*((struct in_addr *)src)); if (p) { if (cnt <= strlen(p)) { errno = ENOSPC; dst = NULL; } else strcpy(dst, p); } else dst = NULL; break; #ifdef HAVE_IPV6 case AF_INET6: if (cnt < 40) { errno = ENOSPC; dst = NULL; } else { struct in6_addr *a = src; int i; p = (char *)dst; /* we do not compress :0: to :: */ for (i = 0; i < 8; i++) p += sprintf(p, "%x:", ntohs(a->s6_addr16[i])); p--; *p = 0; } break; #endif default: errno = EAFNOSUPPORT; dst = NULL; } return dst; } tftp-hpa-5.3+20251209/lib/xmalloc.c000066400000000000000000000003741511036464300163640ustar00rootroot00000000000000/* * xmalloc.c * * Simple error-checking version of malloc() * */ #include "config.h" void *xmalloc(size_t size) { void *p = malloc(size); if (!p) { fprintf(stderr, "Out of memory!\n"); exit(128); } return p; } tftp-hpa-5.3+20251209/lib/xstrdup.c000066400000000000000000000003731511036464300164350ustar00rootroot00000000000000/* * xstrdup.c * * Simple error-checking version of strdup() * */ #include "config.h" char *xstrdup(const char *s) { char *p = strdup(s); if (!p) { fprintf(stderr, "Out of memory!\n"); exit(128); } return p; } tftp-hpa-5.3+20251209/release.sh000077500000000000000000000021131511036464300157630ustar00rootroot00000000000000#!/bin/sh -xe # # Script for generating a release # PACKAGE=tftp-hpa if [ -z "$1" ]; then echo "Usage: $0 release-id" 1>&2 exit 1 fi release="$1" releasetag=$PACKAGE-$release releasedir=$PACKAGE-$release GIT_DIR=`cd "${GIT_DIR-.git}" && pwd` export GIT_DIR if [ `git diff --cached | wc -l` -ne 0 ]; then echo "$0: index not clean" 1>&2 exit 1 fi if [ x"$release" = x'test' ]; then release=`cat version` releasetag=HEAD releasedir=$PACKAGE-$release else echo $release > version if [ `git diff version | wc -l` -ne 0 ]; then git add version git commit -m "Update version for release $release" version else git checkout version fi rm -f "$GIT_DIR"/refs/tags/$releasetag git tag -a -m "$releasetag" -f "$releasetag" fi here=`pwd` tmpdir=/var/tmp/release.$$ rm -rf $tmpdir mkdir -p $tmpdir cd $tmpdir mkdir -p $releasedir git archive --format=tar $releasetag | tar -xf - -C $releasedir cd $releasedir make release rm -f release.sh cd .. tar cvvf $releasedir.tar $releasedir gzip -9 $releasedir.tar mv -f $releasedir.tar.gz $here/.. cd .. rm -rf $tmpdir tftp-hpa-5.3+20251209/tftp-xinetd000066400000000000000000000007761511036464300162120ustar00rootroot00000000000000# default: off # description: The tftp server serves files using the trivial file transfer \ # protocol. The tftp protocol is often used to boot diskless \ # workstations, download configuration files to network-aware printers, \ # and to start the installation process for some operating systems. service tftp { socket_type = dgram protocol = udp wait = yes user = root server = /usr/sbin/in.tftpd server_args = -s /tftpboot disable = yes per_source = 11 cps = 100 2 flags = IPv4 } tftp-hpa-5.3+20251209/tftp.spec.in000066400000000000000000000151201511036464300162440ustar00rootroot00000000000000Summary: The client for the Trivial File Transfer Protocol (TFTP). Name: tftp Version: @@VERSION@@ Release: 1 License: BSD Group: Applications/Internet Source0: http://www.kernel.org/pub/software/network/tftp/tftp-hpa-%{version}.tar.gz BuildRequires: tcp_wrappers-devel BuildRoot: %{_tmppath}/%{name}-root %description The Trivial File Transfer Protocol (TFTP) is normally used only for booting diskless workstations. The tftp package provides the user interface for TFTP, which allows users to transfer files to and from a remote machine. This program and TFTP provide very little security, and should not be enabled unless it is expressly needed. %package server Group: System Environment/Daemons Summary: The server for the Trivial File Transfer Protocol (TFTP). Requires: xinetd %description server The Trivial File Transfer Protocol (TFTP) is normally used only for booting diskless workstations. The tftp-server package provides the server for TFTP, which allows users to transfer files to and from a remote machine. TFTP provides very little security, and should not be enabled unless it is expressly needed. The TFTP server is run from /etc/xinetd.d/tftp, and is disabled by default on Red Hat Linux systems. %prep %setup -q -n tftp-hpa-%{version} %build %configure make %{?_smp_mflags} %install rm -rf ${RPM_BUILD_ROOT} mkdir -p ${RPM_BUILD_ROOT}%{_bindir} mkdir -p ${RPM_BUILD_ROOT}%{_mandir}/man{1,8} mkdir -p ${RPM_BUILD_ROOT}%{_sbindir} make INSTALLROOT=${RPM_BUILD_ROOT} \ SBINDIR=%{_sbindir} MANDIR=%{_mandir} \ install install -m755 -d ${RPM_BUILD_ROOT}%{_sysconfdir}/xinetd.d/ ${RPM_BUILD_ROOT}/tftpboot install -m644 tftp-xinetd ${RPM_BUILD_ROOT}%{_sysconfdir}/xinetd.d/tftp %post server /sbin/service xinetd reload > /dev/null 2>&1 || : %postun server if [ $1 = 0 ]; then /sbin/service xinetd reload > /dev/null 2>&1 || : fi %clean rm -rf ${RPM_BUILD_ROOT} %files %defattr(-,root,root) %{_bindir}/tftp %{_mandir}/man1/* %files server %defattr(-,root,root) %config(noreplace) %{_sysconfdir}/xinetd.d/tftp %dir /tftpboot %{_sbindir}/in.tftpd %{_mandir}/man8/* %changelog * Tue Sep 14 2004 H. Peter Anvin - removed completely broken "Malta" patch. - integrated into build machinery so rpm -ta works. * Fri Feb 13 2004 Elliot Lee - rebuilt * Wed Jun 04 2003 Elliot Lee - rebuilt * Fri Apr 11 2003 Elliot Lee - 0.33 - Add /tftpboot directory (#88204) * Mon Feb 24 2003 Elliot Lee - rebuilt * Sun Feb 23 2003 Tim Powers - add BuildPreReq on tcp_wrappers * Wed Jan 22 2003 Tim Powers - rebuilt * Mon Nov 11 2002 Elliot Lee 0.32-1 - Update to 0.32 * Wed Oct 23 2002 Elliot Lee 0.30-1 - Fix #55789 - Update to 0.30 * Thu Jun 27 2002 Elliot Lee - Try applying HJ's patch from #65476 * Fri Jun 21 2002 Tim Powers - automated rebuild * Mon Jun 17 2002 Elliot Lee - Update to 0.29 * Thu May 23 2002 Tim Powers - automated rebuild * Wed Jan 09 2002 Tim Powers - automated rebuild * Tue Dec 18 2001 Elliot Lee 0.17-15 - Add patch4: netkit-tftp-0.17-defaultport.patch for bug #57562 - Update to tftp-hpa-0.28 (bug #56131) - Remove include/arpa/tftp.h to fix #57259 - Add resource limits in tftp-xinetd (#56722) * Sun Jun 24 2001 Elliot Lee - Bump release + rebuild. * Tue Jun 12 2001 Helge Deller (0.17-13) - updated tftp-hpa source to tftp-hpa-0.17 - tweaked specfile with different defines for tftp-netkit and tftp-hpa version - use hpa's tftpd.8 man page instead of the netkits one * Mon May 07 2001 Helge Deller - rebuilt in 7.1.x * Wed Apr 18 2001 Helge Deller - fix tftp client's put problems (#29529) - update to tftp-hpa-0.16 * Wed Apr 4 2001 Jakub Jelinek - don't let configure to guess compiler, it can pick up egcs * Thu Feb 08 2001 Helge Deller - changed "wait" in xinetd file to "yes" (hpa-tftpd forks and exits) (#26467) - fixed hpa-tftpd to handle files greater than 32MB (#23725) - added "-l" flag to hpa-tftpd for file-logging (#26467) - added description for "-l" to the man-page * Thu Feb 08 2001 Helge Deller - updated tftp client to 0.17 stable (#19640), - drop dependency on xinetd for tftp client (#25051), * Wed Jan 17 2001 Jeff Johnson - xinetd shouldn't wait on tftp (which forks) (#23923). * Sat Jan 6 2001 Jeff Johnson - fix to permit tftp put's (#18128). - startup as root with chroot to /tftpboot with early reversion to nobody is preferable to starting as nobody w/o ability to chroot. - %%post is needed by server, not client. Add %%postun for erasure as well. * Wed Aug 23 2000 Nalin Dahyabhai - default to being disabled * Thu Aug 17 2000 Jeff Johnson - correct group. * Tue Jul 25 2000 Nalin Dahyabhai - change user from root to nobody * Sat Jul 22 2000 Jeff Johnson - update to tftp-hpa-0.14 (#14003). - add server_args (#14003). - remove -D_BSD_SOURCE (#14003). * Fri Jul 21 2000 Nalin Dahyabhai - cook up an xinetd config file for tftpd * Wed Jul 12 2000 Prospector - automatic rebuild * Sun Jun 18 2000 Jeff Johnson - FHS packaging. - update to 0.17. * Fri May 5 2000 Matt Wilson - use _BSD_SOURCE for hpa's tftpd so we get BSD signal semantics. * Fri Feb 11 2000 Bill Nottingham - fix description * Wed Feb 9 2000 Jeff Johnson - compress man pages (again). * Wed Feb 02 2000 Cristian Gafton - man pages are compressed - fix description and summary * Tue Jan 4 2000 Bill Nottingham - split client and server * Tue Dec 21 1999 Jeff Johnson - update to 0.16. * Sat Aug 28 1999 Jeff Johnson - update to 0.15. * Wed Apr 7 1999 Jeff Johnson - tftpd should truncate file when overwriting (#412) * Sun Mar 21 1999 Cristian Gafton - auto rebuild in the new build environment (release 22) * Mon Mar 15 1999 Jeff Johnson - compile for 6.0. * Fri Aug 7 1998 Jeff Johnson - build root * Mon Apr 27 1998 Prospector System - translations modified for de, fr, tr * Mon Sep 22 1997 Erik Troan - added check for getpwnam() failure * Tue Jul 15 1997 Erik Troan - initial build tftp-hpa-5.3+20251209/tftp/000077500000000000000000000000001511036464300147645ustar00rootroot00000000000000tftp-hpa-5.3+20251209/tftp/Makefile000066400000000000000000000010711511036464300164230ustar00rootroot00000000000000SRCROOT = .. VERSION = $(shell cat ../version) -include ../config/MCONFIG include ../MRULES OBJS = tftp.$(O) main.$(O) all: tftp$(X) tftp.1 tftp$(X): $(OBJS) $(CC) $(LDFLAGS) $^ $(TFTP_LIBS) -o $@ $(OBJS): ../common/tftpsubs.h tftp.1: tftp.1.in ../version sed -e 's/@@VERSION@@/$(VERSION)/g' < $< > $@ install: all mkdir -p $(INSTALLROOT)$(BINDIR) $(INSTALLROOT)$(MANDIR)/man1 $(INSTALL_PROGRAM) tftp$(X) $(INSTALLROOT)$(BINDIR) $(INSTALL_DATA) tftp.1 $(INSTALLROOT)$(MANDIR)/man1 clean: rm -f *.o *.obj *.exe tftp tftp.1 distclean: clean rm -f *~ tftp-hpa-5.3+20251209/tftp/extern.h000066400000000000000000000037501511036464300164470ustar00rootroot00000000000000/* * Copyright (c) 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #ifndef EXTERN_H #define EXTERN_H #include "config.h" void tftp_recvfile(int, const char *, const char *); void tftp_sendfile(int, const char *, const char *); extern sigjmp_buf toplevel; #endif tftp-hpa-5.3+20251209/tftp/main.c000066400000000000000000000563121511036464300160630ustar00rootroot00000000000000/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "common/tftpsubs.h" /* Many bug fixes are from Jim Guyton */ /* * TFTP User Program -- Command Interface. */ #include #include #ifdef WITH_READLINE #include #ifdef HAVE_READLINE_HISTORY_H #include #endif #endif #include "extern.h" #define TIMEOUT 5 /* secs between rexmt's */ #define LBUFLEN 200 /* size of input buffer */ struct modes { const char *m_name; const char *m_mode; int m_openflags; }; static const struct modes modes[] = { {"netascii", "netascii", O_TEXT}, {"ascii", "netascii", O_TEXT}, {"octet", "octet", O_BINARY}, {"binary", "octet", O_BINARY}, {"image", "octet", O_BINARY}, {0, 0, 0} }; #define MODE_OCTET (&modes[2]) #define MODE_NETASCII (&modes[0]) #define MODE_DEFAULT MODE_NETASCII #ifdef HAVE_IPV6 int ai_fam = AF_UNSPEC; int ai_fam_sock = AF_UNSPEC; #else int ai_fam = AF_INET; int ai_fam_sock = AF_INET; #endif union sock_addr peeraddr; int f = -1; u_short port; int trace; int verbose; int literal; int connected; const struct modes *mode; #ifdef WITH_READLINE char *line = NULL; #else char line[LBUFLEN]; #endif int margc; char *margv[20]; const char *prompt = "tftp> "; sigjmp_buf toplevel; void intr(int); struct servent *sp; int portrange = 0; unsigned int portrange_from = 0; unsigned int portrange_to = 0; void get(int, char **); void help(int, char **); void modecmd(int, char **); void put(int, char **); void quit(int, char **); void setascii(int, char **); void setbinary(int, char **); void setpeer(int, char **); void setrexmt(int, char **); void settimeout(int, char **); void settrace(int, char **); void setverbose(int, char **); void status(int, char **); void setliteral(int, char **); static void command(void); static void getusage(char *); static void makeargv(void); static void putusage(char *); static void settftpmode(const struct modes *); #define HELPINDENT (sizeof("connect")) struct cmd { const char *name; const char *help; void (*handler) (int, char **); }; struct cmd cmdtab[] = { {"connect", "connect to remote tftp", setpeer}, {"mode", "set file transfer mode", modecmd}, {"put", "send file", put}, {"get", "receive file", get}, {"quit", "exit tftp", quit}, {"verbose", "toggle verbose mode", setverbose}, {"trace", "toggle packet tracing", settrace}, {"literal", "toggle literal mode, ignore ':' in file name", setliteral}, {"status", "show current status", status}, {"binary", "set mode to octet", setbinary}, {"ascii", "set mode to netascii", setascii}, {"rexmt", "set per-packet transmission timeout", setrexmt}, {"timeout", "set total retransmission timeout", settimeout}, {"?", "print help information", help}, {"help", "print help information", help}, {0, 0, 0} }; struct cmd *getcmd(char *); char *tail(char *); char *xstrdup(const char *); const char *program; static void usage(int errcode) { fprintf(stderr, #ifdef HAVE_IPV6 "Usage: %s [-4][-6][-v][-l][-m mode] [host [port]] [-c command]\n", #else "Usage: %s [-v][-l][-m mode] [host [port]] [-c command]\n", #endif program); exit(errcode); } int main(int argc, char *argv[]) { union sock_addr sa; int arg; static int pargc, peerargc; static int iscmd = 0; char **pargv; const char *optx; char *peerargv[3]; program = argv[0]; mode = MODE_DEFAULT; peerargv[0] = argv[0]; peerargc = 1; for (arg = 1; !iscmd && arg < argc; arg++) { if (argv[arg][0] == '-') { for (optx = &argv[arg][1]; *optx; optx++) { switch (*optx) { case '4': ai_fam = AF_INET; break; #ifdef HAVE_IPV6 case '6': ai_fam = AF_INET6; break; #endif case 'v': verbose = 1; break; case 'V': /* Print version and configuration to stdout and exit */ printf("%s\n", TFTP_CONFIG_STR); exit(0); case 'l': literal = 1; break; case 'm': if (++arg >= argc) usage(EX_USAGE); { const struct modes *p; for (p = modes; p->m_name; p++) { if (!strcmp(argv[arg], p->m_name)) break; } if (p->m_name) { settftpmode(p); } else { fprintf(stderr, "%s: invalid mode: %s\n", argv[0], argv[arg]); exit(EX_USAGE); } } break; case 'c': iscmd = 1; break; case 'R': if (++arg >= argc) usage(EX_USAGE); if (sscanf (argv[arg], "%u:%u", &portrange_from, &portrange_to) != 2 || portrange_from > portrange_to || portrange_to > 65535) { fprintf(stderr, "Bad port range: %s\n", argv[arg]); exit(EX_USAGE); } portrange = 1; break; case 'h': default: usage(*optx == 'h' ? 0 : EX_USAGE); } } } else { if (peerargc >= 3) usage(EX_USAGE); peerargv[peerargc++] = argv[arg]; } } ai_fam_sock = ai_fam; pargv = argv + arg; pargc = argc - arg; sp = getservbyname("tftp", "udp"); if (sp == 0) { /* Use canned values */ if (verbose) fprintf(stderr, "tftp: tftp/udp: unknown service, faking it...\n"); sp = xmalloc(sizeof(struct servent)); sp->s_name = (char *)"tftp"; sp->s_aliases = NULL; sp->s_port = htons(IPPORT_TFTP); sp->s_proto = (char *)"udp"; } tftp_signal(SIGINT, intr, 0); if (peerargc) { /* Set peer */ if (sigsetjmp(toplevel, 1) != 0) exit(EX_NOHOST); setpeer(peerargc, peerargv); } if (ai_fam_sock == AF_UNSPEC) ai_fam_sock = AF_INET; f = socket(ai_fam_sock, SOCK_DGRAM, 0); if (f < 0) { perror("tftp: socket"); exit(EX_OSERR); } bzero(&sa, sizeof(sa)); sa.sa.sa_family = ai_fam_sock; if (pick_port_bind(f, &sa, portrange_from, portrange_to)) { perror("tftp: bind"); exit(EX_OSERR); } if (iscmd && pargc) { /* -c specified; execute command and exit */ struct cmd *c; if (sigsetjmp(toplevel, 1) != 0) exit(EX_UNAVAILABLE); c = getcmd(pargv[0]); if (c == (struct cmd *)-1 || c == (struct cmd *)0) { fprintf(stderr, "%s: invalid command: %s\n", argv[0], pargv[1]); exit(EX_USAGE); } (*c->handler) (pargc, pargv); exit(0); } #ifdef WITH_READLINE #ifdef HAVE_READLINE_HISTORY_H using_history(); #endif #endif if (sigsetjmp(toplevel, 1) != 0) (void)putchar('\n'); command(); return 0; /* Never reached */ } char *hostname; /* Called when a command is incomplete; modifies the global variable "line" */ static void getmoreargs(const char *partial, const char *mprompt) { #ifdef WITH_READLINE char *eline; int len, elen; len = strlen(partial); eline = readline(mprompt); if (!eline) exit(0); /* EOF */ elen = strlen(eline); if (line) { free(line); line = NULL; } line = xmalloc(len + elen + 1); strcpy(line, partial); strcpy(line + len, eline); free(eline); #ifdef HAVE_READLINE_HISTORY_H add_history(line); #endif #else int len = strlen(partial); strcpy(line, partial); fputs(mprompt, stdout); if (fgets(line + len, LBUFLEN - len, stdin) == 0) if (feof(stdin)) exit(0); /* EOF */ #endif } void setpeer(int argc, char *argv[]) { int err; if (argc < 2) { getmoreargs("connect ", "(to) "); makeargv(); argc = margc; argv = margv; } if ((argc < 2) || (argc > 3)) { printf("usage: %s host-name [port]\n", argv[0]); return; } peeraddr.sa.sa_family = ai_fam; err = set_sock_addr(argv[1], &peeraddr, &hostname); if (err) { printf("Error: %s\n", gai_strerror(err)); printf("%s: unknown host\n", argv[1]); connected = 0; return; } ai_fam = peeraddr.sa.sa_family; if (f == -1) { /* socket not open */ ai_fam_sock = ai_fam; } else { /* socket was already open */ if (ai_fam_sock != ai_fam) { /* need reopen socken for new family */ union sock_addr sa; close(f); ai_fam_sock = ai_fam; f = socket(ai_fam_sock, SOCK_DGRAM, 0); if (f < 0) { perror("tftp: socket"); exit(EX_OSERR); } bzero((char *)&sa, sizeof (sa)); sa.sa.sa_family = ai_fam_sock; if (pick_port_bind(f, &sa, portrange_from, portrange_to)) { perror("tftp: bind"); exit(EX_OSERR); } } } port = sp->s_port; if (argc == 3) { struct servent *usp; usp = getservbyname(argv[2], "udp"); if (usp) { port = usp->s_port; } else { unsigned long myport; char *ep; myport = strtoul(argv[2], &ep, 10); if (*ep || myport > 65535UL) { printf("%s: bad port number\n", argv[2]); connected = 0; return; } port = htons((u_short) myport); } } if (verbose) { char tmp[INET6_ADDRSTRLEN], *tp; tp = (char *)inet_ntop(peeraddr.sa.sa_family, SOCKADDR_P(&peeraddr), tmp, INET6_ADDRSTRLEN); if (!tp) tp = (char *)"???"; printf("Connected to %s (%s), port %u\n", hostname, tp, (unsigned int)ntohs(port)); } connected = 1; } void modecmd(int argc, char *argv[]) { const struct modes *p; const char *sep; if (argc < 2) { printf("Using %s mode to transfer files.\n", mode->m_mode); return; } if (argc == 2) { for (p = modes; p->m_name; p++) if (strcmp(argv[1], p->m_name) == 0) break; if (p->m_name) { settftpmode(p); return; } printf("%s: unknown mode\n", argv[1]); /* drop through and print usage message */ } printf("usage: %s [", argv[0]); sep = " "; for (p = modes; p->m_name; p++) { printf("%s%s", sep, p->m_name); if (*sep == ' ') sep = " | "; } printf(" ]\n"); return; } void setbinary(int argc, char *argv[]) { (void)argc; (void)argv; /* Quiet unused warning */ settftpmode(MODE_OCTET); } void setascii(int argc, char *argv[]) { (void)argc; (void)argv; /* Quiet unused warning */ settftpmode(MODE_NETASCII); } static void settftpmode(const struct modes *newmode) { mode = newmode; if (verbose) printf("mode set to %s\n", mode->m_mode); } /* * Send file(s). */ void put(int argc, char *argv[]) { int fd; int n, err; char *cp, *targ; if (argc < 2) { getmoreargs("send ", "(file) "); makeargv(); argc = margc; argv = margv; } if (argc < 2) { putusage(argv[0]); return; } targ = argv[argc - 1]; if (!literal && strchr(argv[argc - 1], ':')) { for (n = 1; n < argc - 1; n++) if (strchr(argv[n], ':')) { putusage(argv[0]); return; } cp = argv[argc - 1]; targ = strchr(cp, ':'); *targ++ = 0; peeraddr.sa.sa_family = ai_fam; err = set_sock_addr(cp, &peeraddr,&hostname); if (err) { printf("Error: %s\n", gai_strerror(err)); printf("%s: unknown host\n", argv[1]); connected = 0; return; } ai_fam = peeraddr.sa.sa_family; connected = 1; } if (!connected) { printf("No target machine specified.\n"); return; } if (argc < 4) { cp = argc == 2 ? tail(targ) : argv[1]; fd = open(cp, O_RDONLY | mode->m_openflags); if (fd < 0) { fprintf(stderr, "tftp: "); perror(cp); return; } if (verbose) printf("putting %s to %s:%s [%s]\n", cp, hostname, targ, mode->m_mode); sa_set_port(&peeraddr, port); tftp_sendfile(fd, targ, mode->m_mode); return; } /* this assumes the target is a directory */ /* on a remote unix system. hmmmm. */ cp = strchr(targ, '\0'); *cp++ = '/'; for (n = 1; n < argc - 1; n++) { strcpy(cp, tail(argv[n])); fd = open(argv[n], O_RDONLY | mode->m_openflags); if (fd < 0) { fprintf(stderr, "tftp: "); perror(argv[n]); continue; } if (verbose) printf("putting %s to %s:%s [%s]\n", argv[n], hostname, targ, mode->m_mode); sa_set_port(&peeraddr, port); tftp_sendfile(fd, targ, mode->m_mode); } } static void putusage(char *s) { printf("usage: %s file ... host:target, or\n", s); printf(" %s file ... target (when already connected)\n", s); } /* * Receive file(s). */ void get(int argc, char *argv[]) { int fd; int n; char *cp; char *src; if (argc < 2) { getmoreargs("get ", "(files) "); makeargv(); argc = margc; argv = margv; } if (argc < 2) { getusage(argv[0]); return; } if (!connected) { for (n = 1; n < argc; n++) if (literal || strchr(argv[n], ':') == 0) { getusage(argv[0]); return; } } for (n = 1; n < argc; n++) { src = strchr(argv[n], ':'); if (literal || src == NULL) src = argv[n]; else { int err; *src++ = 0; peeraddr.sa.sa_family = ai_fam; err = set_sock_addr(argv[n], &peeraddr, &hostname); if (err) { printf("Warning: %s\n", gai_strerror(err)); printf("%s: unknown host\n", argv[1]); continue; } ai_fam = peeraddr.sa.sa_family; connected = 1; } if (argc < 4) { cp = argc == 3 ? argv[2] : tail(src); fd = open(cp, O_WRONLY | O_CREAT | O_TRUNC | mode->m_openflags, 0666); if (fd < 0) { fprintf(stderr, "tftp: "); perror(cp); return; } if (verbose) printf("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode->m_mode); sa_set_port(&peeraddr, port); tftp_recvfile(fd, src, mode->m_mode); break; } cp = tail(src); /* new .. jdg */ fd = open(cp, O_WRONLY | O_CREAT | O_TRUNC | mode->m_openflags, 0666); if (fd < 0) { fprintf(stderr, "tftp: "); perror(cp); continue; } if (verbose) printf("getting from %s:%s to %s [%s]\n", hostname, src, cp, mode->m_mode); sa_set_port(&peeraddr, port); tftp_recvfile(fd, src, mode->m_mode); } } static void getusage(char *s) { printf("usage: %s host:file host:file ... file, or\n", s); printf(" %s file file ... file if connected\n", s); } int rexmtval = TIMEOUT; void setrexmt(int argc, char *argv[]) { int t; if (argc < 2) { getmoreargs("rexmt-timeout ", "(value) "); makeargv(); argc = margc; argv = margv; } if (argc != 2) { printf("usage: %s value\n", argv[0]); return; } t = atoi(argv[1]); if (t < 0) printf("%s: bad value\n", argv[1]); else rexmtval = t; } int maxtimeout = 5 * TIMEOUT; void settimeout(int argc, char *argv[]) { int t; if (argc < 2) { getmoreargs("maximum-timeout ", "(value) "); makeargv(); argc = margc; argv = margv; } if (argc != 2) { printf("usage: %s value\n", argv[0]); return; } t = atoi(argv[1]); if (t < 0) printf("%s: bad value\n", argv[1]); else maxtimeout = t; } void setliteral(int argc, char *argv[]) { (void)argc; (void)argv; /* Quiet unused warning */ literal = !literal; printf("Literal mode %s.\n", literal ? "on" : "off"); } void status(int argc, char *argv[]) { (void)argc; (void)argv; /* Quiet unused warning */ if (connected) printf("Connected to %s.\n", hostname); else printf("Not connected.\n"); printf("Mode: %s Verbose: %s Tracing: %s Literal: %s\n", mode->m_mode, verbose ? "on" : "off", trace ? "on" : "off", literal ? "on" : "off"); printf("Rexmt-interval: %d seconds, Max-timeout: %d seconds\n", rexmtval, maxtimeout); } void intr(int sig) { (void)sig; /* Quiet unused warning */ alarm(0); tftp_signal(SIGALRM, SIG_DFL, 0); siglongjmp(toplevel, -1); } char *tail(char *filename) { char *s; while (*filename) { s = strrchr(filename, '/'); if (s == NULL) break; if (s[1]) return (s + 1); *s = '\0'; } return (filename); } /* * Command parser. */ static void command(void) { struct cmd *c; for (;;) { #ifdef WITH_READLINE if (line) { free(line); line = NULL; } line = readline(prompt); if (!line) exit(0); /* EOF */ #else fputs(prompt, stdout); if (fgets(line, LBUFLEN, stdin) == 0) { if (feof(stdin)) { exit(0); } else { continue; } } #endif if ((line[0] == 0) || (line[0] == '\n')) continue; #ifdef WITH_READLINE #ifdef HAVE_READLINE_HISTORY_H add_history(line); #endif #endif makeargv(); if (margc == 0) continue; c = getcmd(margv[0]); if (c == (struct cmd *)-1) { printf("?Ambiguous command\n"); continue; } if (c == 0) { printf("?Invalid command\n"); continue; } (*c->handler) (margc, margv); } } struct cmd *getcmd(char *name) { const char *p; char *q; struct cmd *c, *found; int nmatches, longest; longest = 0; nmatches = 0; found = 0; for (c = cmdtab; (p = c->name) != NULL; c++) { for (q = name; *q == *p++; q++) if (*q == 0) /* exact match? */ return (c); if (!*q) { /* the name was a prefix */ if (q - name > longest) { longest = q - name; nmatches = 1; found = c; } else if (q - name == longest) nmatches++; } } if (nmatches > 1) return ((struct cmd *)-1); return (found); } /* * Slice a string up into argc/argv. */ static void makeargv(void) { char *cp; char **argp = margv; margc = 0; for (cp = line; *cp;) { while (isspace(*cp)) cp++; if (*cp == '\0') break; *argp++ = cp; margc += 1; while (*cp != '\0' && !isspace(*cp)) cp++; if (*cp == '\0') break; *cp++ = '\0'; } *argp++ = 0; } void quit(int argc, char *argv[]) { (void)argc; (void)argv; /* Quiet unused warning */ exit(0); } /* * Help command. */ void help(int argc, char *argv[]) { struct cmd *c; printf("%s\n", VERSION); if (argc == 1) { printf("Commands may be abbreviated. Commands are:\n\n"); for (c = cmdtab; c->name; c++) printf("%-*s\t%s\n", (int)HELPINDENT, c->name, c->help); return; } while (--argc > 0) { char *arg; arg = *++argv; c = getcmd(arg); if (c == (struct cmd *)-1) printf("?Ambiguous help command %s\n", arg); else if (c == (struct cmd *)0) printf("?Invalid help command %s\n", arg); else printf("%s\n", c->help); } } void settrace(int argc, char *argv[]) { (void)argc; (void)argv; /* Quiet unused warning */ trace = !trace; printf("Packet tracing %s.\n", trace ? "on" : "off"); } void setverbose(int argc, char *argv[]) { (void)argc; (void)argv; /* Quiet unused warning */ verbose = !verbose; printf("Verbose mode %s.\n", verbose ? "on" : "off"); } tftp-hpa-5.3+20251209/tftp/tftp.1.in000066400000000000000000000144541511036464300164400ustar00rootroot00000000000000.\" -*- nroff -*- --------------------------------------------------------- * .\" .\" Copyright (c) 1990, 1993, 1994 .\" The Regents of the University of California. All rights reserved. .\" .\" Copyright 2001 H. Peter Anvin - All Rights Reserved .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\"----------------------------------------------------------------------- */ .TH TFTP 1 "23 July 2008" "tftp-hpa @@VERSION@@" "User's Manual" .SH NAME .B tftp \- IPv4 Trivial File Transfer Protocol client .SH SYNOPSIS .B tftp [ \fIoptions...\fP ] [\fIhost\fP [\fIport\fP]] [\fB\-c\fP \fIcommand\fP] .br .SH DESCRIPTION .B tftp is a client for the Trivial file Transfer Protocol, which can be used to transfer files to and from remote machines, including some very minimalistic, usually embedded, systems. The remote .I host may be specified on the command line, in which case .B tftp uses .I host as the default host for future transfers (see the .B connect command below.) .SH OPTIONS .TP .B \-4 Connect with IPv4 only, even if IPv6 support was compiled in. .TP .B \-6 Connect with IPv6 only, if compiled in. .TP \fB\-c\fP \fIcommand\fP Execute \fIcommand\fP as if it had been entered on the tftp prompt. Must be specified last on the command line. .TP .B \-l Default to literal mode. Used to avoid special processing of ':' in a file name. .TP \fB\-m\fP \fImode\fP Set the default transfer mode to \fImode\fP. This is usually used with \-c. .TP \fB\-R\fP \fIport:port\fP Force the originating port number to be in the specified range of port numbers. .TP .B \-v Default to verbose mode. .TP .B \-V Print the version number and configuration to standard output, then exit gracefully. .SH COMMANDS Once .B tftp is running, it issues the prompt \f(CWtftp>\fP and recognizes the following commands: .TP \fB?\fP \fIcommand-name...\fP .TP \fBhelp\fP \fIcommand-name...\fP Print help information .TP .B ascii Shorthand for .BR "mode ascii" . .TP .B binary Shorthand for .BR "mode binary" . .TP \fBconnect\fP \fIhost [port]\fP Set the .I host (and optionally .IR port ) for transfers. Note that the TFTP protocol, unlike the FTP protocol, does not maintain connections between transfers; thus, the .B connect command does not actually create a connection, but merely remembers what host is to be used for transfers. You do not have to use the .B connect command; the remote host can be specified as part of the .B get or .B put commands. .TP \fBget\fP \fIfile\fP .sp -.6l .TP \fBget\fP \fIremotefile localfile\fP .sp -.6l .TP \fBget\fP \fIfile1 file2 file3...\fP Get a file or set of files from the specified sources. A remote filename can be in one of two forms: a plain filename on the remote host, if the host has already been specified, or a string of the form .I "host:filename" to specify both a host and filename at the same time. If the latter form is used, the last hostname specified becomes the default for future transfers. Enable .B literal mode to prevent special treatment of the ':' character (e.g. C:\\dir\\file). .TP .B literal Toggle literal mode. When set, this mode prevents special treatment of ':' in filenames. .TP \fBmode\fP \fItransfer-mode\fP Specify the mode for transfers; .I transfer-mode may be one of .B ascii (or .BR netascii ) or .B binary (or .BR octet .) The default is .BR ascii . .TP \fBput\fP \fIfile\fP .sp -.6l .TP \fBput\fP \fIlocalfile remotefile\fP .sp -.6l .TP \fBput\fP \fIfile1 file2 file3... remote-directory\fP Put a file or set of files to the specified remote file or directory. The destination can be in one of two forms: a filename on the remote host, if the host has already been specified, or a string of the form .I "host:filename" to specify both a host and filename at the same time. If the latter form is used, the hostname specified becomes the default for future transfers. If the remote-directory form is used, the remote host is assumed to be a UNIX system or another system using .B / as directory separator. Enable .B literal mode to prevent special treatment of the ':' character (e.g. C:\\dir\\file). .TP .B quit Exit .BR tftp . End-of-file will also exit. .TP \fBrexmt\fP \fIretransmission-timeout\fP Set the per-packet retransmission timeout, in seconds. .TP .B status Show current status. .TP \fBtimeout\fP \fItotal-transmission-timeout\fP Set the total transmission timeout, in seconds. .TP .B trace Toggle packet tracing (a debugging feature.) .TP .B verbose Toggle verbose mode. .SH "NOTES" The TFTP protocol provides no provisions for authentication or security. Therefore, the remote server will probably implement some kinds of access restriction or firewalling. These access restrictions are likely to be site- and server-specific. .SH "AUTHOR" This version of .B tftp is maintained by H. Peter Anvin . It was derived from, but has substantially diverged from, an OpenBSD source base, with added patches by Markus Gutschke and Gero Kulhman. .SH "SEE ALSO" .BR tftpd (8). tftp-hpa-5.3+20251209/tftp/tftp.c000066400000000000000000000311301511036464300161030ustar00rootroot00000000000000/* * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "common/tftpsubs.h" /* * TFTP User Program -- Protocol Machines */ #include "extern.h" extern union sock_addr peeraddr; /* filled in by main */ extern int f; /* the opened socket */ extern int trace; extern int verbose; extern int rexmtval; extern int maxtimeout; #define PKTSIZE SEGSIZE+4 char ackbuf[PKTSIZE]; int timeout; static sigjmp_buf timeoutbuf; static void nak(int, const char *); static int makerequest(int, const char *, struct tftphdr *, const char *); static void printstats(const char *, unsigned long); static void startclock(void); static void stopclock(void); static void timer(int); static void tpacket(const char *, struct tftphdr *, int); /* * Send the requested file. */ void tftp_sendfile(int fd, const char *name, const char *mode) { struct tftphdr *ap; /* data and ack packets */ struct tftphdr *dp; int n; volatile int is_request; volatile u_short block; volatile int size, convert; volatile off_t amount; union sock_addr from; socklen_t fromlen; FILE *file; u_short ap_opcode, ap_block; startclock(); /* start stat's clock */ dp = r_init(); /* reset fillbuf/read-ahead code */ ap = (struct tftphdr *)ackbuf; convert = !strcmp(mode, "netascii"); file = fdopen(fd, convert ? "rt" : "rb"); block = 0; is_request = 1; /* First packet is the actual WRQ */ amount = 0; tftp_signal(SIGALRM, timer, 0); do { if (is_request) { size = makerequest(WRQ, name, dp, mode) - 4; } else { /* size = read(fd, dp->th_data, SEGSIZE); */ size = readit(file, &dp, convert); if (size < 0) { nak(errno + 100, NULL); break; } dp->th_opcode = htons((u_short) DATA); dp->th_block = htons((u_short) block); } timeout = 0; (void)sigsetjmp(timeoutbuf, 1); if (trace) tpacket("sent", dp, size + 4); n = sendto(f, dp, size + 4, 0, &peeraddr.sa, SOCKLEN(&peeraddr)); if (n != size + 4) { perror("tftp: sendto"); goto abort; } read_ahead(file, convert); for (;;) { alarm(rexmtval); do { fromlen = sizeof(from); n = recvfrom(f, ackbuf, sizeof(ackbuf), 0, &from.sa, &fromlen); } while (n <= 0); alarm(0); if (n < 0) { perror("tftp: recvfrom"); goto abort; } sa_set_port(&peeraddr, SOCKPORT(&from)); /* added */ if (trace) tpacket("received", ap, n); /* should verify packet came from server */ ap_opcode = ntohs((u_short) ap->th_opcode); ap_block = ntohs((u_short) ap->th_block); if (ap_opcode == ERROR) { printf("Error code %d: %s\n", ap_block, ap->th_msg); goto abort; } if (ap_opcode == ACK) { int j; if (ap_block == block) { break; } /* On an error, try to synchronize * both sides. */ j = synchnet(f); if (j && trace) { printf("discarded %d packets\n", j); } /* * RFC1129/RFC1350: We MUST NOT re-send the DATA * packet in response to an invalid ACK. Doing so * would cause the Sorcerer's Apprentice bug. */ } } if (!is_request) amount += size; is_request = 0; block++; } while (size == SEGSIZE || block == 1); abort: fclose(file); stopclock(); if (amount > 0) printstats("Sent", amount); } /* * Receive a file. */ void tftp_recvfile(int fd, const char *name, const char *mode) { struct tftphdr *ap; struct tftphdr *dp; int n; volatile u_short block; volatile int size, firsttrip; volatile unsigned long amount; union sock_addr from; socklen_t fromlen; FILE *file; volatile int convert; /* true if converting crlf -> lf */ u_short dp_opcode, dp_block; startclock(); dp = w_init(); ap = (struct tftphdr *)ackbuf; convert = !strcmp(mode, "netascii"); file = fdopen(fd, convert ? "wt" : "wb"); block = 1; firsttrip = 1; amount = 0; tftp_signal(SIGALRM, timer, 0); do { if (firsttrip) { size = makerequest(RRQ, name, ap, mode); firsttrip = 0; } else { ap->th_opcode = htons((u_short) ACK); ap->th_block = htons((u_short) block); size = 4; block++; } timeout = 0; (void)sigsetjmp(timeoutbuf, 1); send_ack: if (trace) tpacket("sent", ap, size); if (sendto(f, ackbuf, size, 0, &peeraddr.sa, SOCKLEN(&peeraddr)) != size) { alarm(0); perror("tftp: sendto"); goto abort; } write_behind(file, convert); for (;;) { alarm(rexmtval); do { fromlen = sizeof(from); n = recvfrom(f, dp, PKTSIZE, 0, &from.sa, &fromlen); } while (n <= 0); alarm(0); if (n < 0) { perror("tftp: recvfrom"); goto abort; } sa_set_port(&peeraddr, SOCKPORT(&from)); /* added */ if (trace) tpacket("received", dp, n); /* should verify client address */ dp_opcode = ntohs((u_short) dp->th_opcode); dp_block = ntohs((u_short) dp->th_block); if (dp_opcode == ERROR) { printf("Error code %d: %s\n", dp_block, dp->th_msg); goto abort; } if (dp_opcode == DATA) { int j; if (dp_block == block) { break; /* have next packet */ } /* On an error, try to synchronize * both sides. */ j = synchnet(f); if (j && trace) { printf("discarded %d packets\n", j); } if (dp_block == (block - 1)) { goto send_ack; /* resend ack */ } } } /* size = write(fd, dp->th_data, n - 4); */ size = writeit(file, &dp, n - 4, convert); if (size < 0) { nak(errno + 100, NULL); break; } amount += size; } while (size == SEGSIZE); abort: /* ok to ack, since user */ ap->th_opcode = htons((u_short) ACK); /* has seen err msg */ ap->th_block = htons((u_short) block); (void)sendto(f, ackbuf, 4, 0, (struct sockaddr *)&peeraddr, SOCKLEN(&peeraddr)); write_behind(file, convert); /* flush last buffer */ fclose(file); stopclock(); if (amount > 0) printstats("Received", amount); } static int makerequest(int request, const char *name, struct tftphdr *tp, const char *mode) { char *cp; tp->th_opcode = htons((u_short) request); cp = (char *)&(tp->th_stuff); strcpy(cp, name); cp += strlen(name); *cp++ = '\0'; strcpy(cp, mode); cp += strlen(mode); *cp++ = '\0'; return (cp - (char *)tp); } static const char *const errmsgs[] = { "Undefined error code", /* 0 - EUNDEF */ "File not found", /* 1 - ENOTFOUND */ "Access denied", /* 2 - EACCESS */ "Disk full or allocation exceeded", /* 3 - ENOSPACE */ "Illegal TFTP operation", /* 4 - EBADOP */ "Unknown transfer ID", /* 5 - EBADID */ "File already exists", /* 6 - EEXISTS */ "No such user", /* 7 - ENOUSER */ "Failure to negotiate RFC2347 options" /* 8 - EOPTNEG */ }; #define ERR_CNT (sizeof(errmsgs)/sizeof(const char *)) /* * Send a nak packet (error message). * Error code passed in is one of the * standard TFTP codes, or a UNIX errno * offset by 100. */ static void nak(int error, const char *msg) { struct tftphdr *tp; int length; tp = (struct tftphdr *)ackbuf; tp->th_opcode = htons((u_short) ERROR); tp->th_code = htons((u_short) error); if (error >= 100) { /* This is a Unix errno+100 */ if (!msg) msg = strerror(error - 100); error = EUNDEF; } else { if ((unsigned)error >= ERR_CNT) error = EUNDEF; if (!msg) msg = errmsgs[error]; } tp->th_code = htons((u_short) error); length = strlen(msg) + 1; memcpy(tp->th_msg, msg, length); length += 4; /* Add space for header */ if (trace) tpacket("sent", tp, length); if (sendto(f, ackbuf, length, 0, &peeraddr.sa, SOCKLEN(&peeraddr)) != length) perror("nak"); } static void tpacket(const char *s, struct tftphdr *tp, int n) { static const char *opcodes[] = { "#0", "RRQ", "WRQ", "DATA", "ACK", "ERROR", "OACK" }; char *cp, *file; u_short op = ntohs((u_short) tp->th_opcode); if (op < RRQ || op > ERROR) printf("%s opcode=%x ", s, op); else printf("%s %s ", s, opcodes[op]); switch (op) { case RRQ: case WRQ: n -= 2; file = cp = (char *)&(tp->th_stuff); cp = strchr(cp, '\0'); printf("\n", file, cp + 1); break; case DATA: printf("\n", ntohs(tp->th_block), n - 4); break; case ACK: printf("\n", ntohs(tp->th_block)); break; case ERROR: printf("\n", ntohs(tp->th_code), tp->th_msg); break; } } struct timeval tstart; struct timeval tstop; static void startclock(void) { (void)gettimeofday(&tstart, NULL); } static void stopclock(void) { (void)gettimeofday(&tstop, NULL); } static void printstats(const char *direction, unsigned long amount) { double delta; delta = (tstop.tv_sec + (tstop.tv_usec / 100000.0)) - (tstart.tv_sec + (tstart.tv_usec / 100000.0)); if (verbose) { printf("%s %lu bytes in %.1f seconds", direction, amount, delta); printf(" [%.0f bit/s]", (amount * 8.) / delta); putchar('\n'); } } static void timer(int sig) { int save_errno = errno; (void)sig; /* Shut up unused warning */ timeout += rexmtval; if (timeout >= maxtimeout) { printf("Transfer timed out.\n"); errno = save_errno; siglongjmp(toplevel, -1); } errno = save_errno; siglongjmp(timeoutbuf, 1); } tftp-hpa-5.3+20251209/tftpd/000077500000000000000000000000001511036464300151305ustar00rootroot00000000000000tftp-hpa-5.3+20251209/tftpd/Makefile000066400000000000000000000013131511036464300165660ustar00rootroot00000000000000SRCROOT = .. VERSION = $(shell cat ../version) -include ../config/MCONFIG include ../MRULES OBJS = tftpd.$(O) recvfrom.$(O) misc.$(O) $(TFTPDOBJS) all: tftpd$(X) tftpd.8 tftpd$(X): $(OBJS) $(CC) $(LDFLAGS) $^ $(TFTPD_LIBS) -o $@ $(OBJS): ../common/tftpsubs.h tftpd.8: tftpd.8.in ../version sed -e 's/@@VERSION@@/$(VERSION)/g' < $< > $@ install: all mkdir -p $(INSTALLROOT)$(SBINDIR) $(INSTALLROOT)$(MANDIR)/man8 $(INSTALL_PROGRAM) tftpd$(X) $(INSTALLROOT)$(SBINDIR)/in.tftpd $(INSTALL_DATA) tftpd.8 $(INSTALLROOT)$(MANDIR)/man8/in.tftpd.8 cd $(INSTALLROOT)$(MANDIR)/man8 && $(LN_S) -f in.tftpd.8 tftpd.8 clean: rm -f *.o *.obj *.exe tftpd tftpsubs.c tftpsubs.h tftpd.8 distclean: clean rm -f *~ tftp-hpa-5.3+20251209/tftpd/misc.c000066400000000000000000000031251511036464300162300ustar00rootroot00000000000000/* ----------------------------------------------------------------------- * * * Copyright 2001-2007 H. Peter Anvin - All Rights Reserved * * This program is free software available under the same license * as the "OpenBSD" operating system, distributed at * http://www.openbsd.org/. * * ----------------------------------------------------------------------- */ /* * misc.c * * Minor help routines. */ #include "tftpd.h" /* * Set the signal handler and flags, and error out on failure. */ void set_signal(int signum, sighandler_t handler, int flags) { if (tftp_signal(signum, handler, flags)) { tftpd_log(LOG_ERR, "sigaction: %m"); exit(EX_OSERR); } } /* * malloc() that syslogs an error message and bails if it fails. * Actually uses calloc() to emphasize safety. */ void *tfmalloc(size_t size) { void *p = calloc(1, size); if (!p) { tftpd_log(LOG_ERR, "calloc: %m"); exit(EX_OSERR); } return p; } /* * realloc() equivalent, which NULL check in case of bugs */ void *tfrealloc(void *ptr, size_t size) { void *p; if (!ptr) p = malloc(size); else p = realloc(ptr, size); if (!p) { tftpd_log(LOG_ERR, "realloc: %m"); exit(EX_OSERR); } return p; } /* * strdup() equivalent */ char *tfstrdup(const char *str) { char *p = strdup(str); if (!p) { tftpd_log(LOG_ERR, "strdup: %m"); exit(EX_OSERR); } return p; } /* * free() which explicitly checks for NULL, just in case of bugs */ void tffree(void *ptr) { if (ptr) free(ptr); } tftp-hpa-5.3+20251209/tftpd/recvfrom.c000066400000000000000000000227661511036464300171340ustar00rootroot00000000000000/* ----------------------------------------------------------------------- * * * Copyright 2001-2025 H. Peter Anvin - All Rights Reserved * * This program is free software available under the same license * as the "OpenBSD" operating system, distributed at * http://www.openbsd.org/. * * ----------------------------------------------------------------------- */ /* * recvfrom.c * * Emulate recvfrom() using recvmsg(), but try to capture the local address * since some TFTP clients consider it an error to get the reply from another * IP address than the request was sent to. * */ #include "config.h" /* Must be included first! */ #include "common/tftpsubs.h" #include "recvfrom.h" #ifdef HAVE_MACHINE_PARAM_H #include /* Needed on some versions of FreeBSD */ #endif #include "tftpd.h" #if defined(HAVE_RECVMSG) && defined(HAVE_STRUCT_MSGHDR_MSG_CONTROL) #ifdef HAVE_SYS_UIO_H # include #endif #ifdef IP_PKTINFO # ifndef HAVE_STRUCT_IN_PKTINFO_IPI_ADDR # ifdef __linux__ /* Assume this version of glibc simply lacks the definition */ struct in_pktinfo { int ipi_ifindex; struct in_addr ipi_spec_dst; struct in_addr ipi_addr; }; # else # undef IP_PKTINFO /* No definition, no way to get it */ # endif # endif #endif #ifndef CMSG_LEN # define CMSG_LEN(size) (sizeof(struct cmsghdr) + (size)) #endif #ifndef CMSG_SPACE # define CMSG_SPACE(size) (sizeof(struct cmsghdr) + (size)) #endif /* * Check to see if this is a valid local address, meaning that we can * legally bind to it. */ static int address_is_local(const union sock_addr *addr) { union sock_addr sa1, sa2; int sockfd = -1; int e; int rv = 0; socklen_t addrlen; memcpy(&sa1, addr, sizeof sa1); /* Multicast or universal broadcast address? */ if (sa1.sa.sa_family == AF_INET) { if (ntohl(sa1.si.sin_addr.s_addr) >= (224UL << 24)) return 0; sa1.si.sin_port = 0; /* Any port */ } #ifdef HAVE_IPV6 else if (sa1.sa.sa_family == AF_INET6) { if (IN6_IS_ADDR_MULTICAST(&sa1.s6.sin6_addr)) return 0; sa1.s6.sin6_port = 0; /* Any port */ } #endif else return 0; sockfd = socket(sa1.sa.sa_family, SOCK_DGRAM, 0); if (sockfd < 0) goto err; if (bind(sockfd, &sa1.sa, SOCKLEN(&sa1))) goto err; addrlen = SOCKLEN(addr); if (getsockname(sockfd, (struct sockaddr *)&sa2, &addrlen)) goto err; if (sa1.sa.sa_family != sa2.sa.sa_family) goto err; if (sa2.sa.sa_family == AF_INET) rv = sa1.si.sin_addr.s_addr == sa2.si.sin_addr.s_addr; #ifdef HAVE_IPV6 else if (sa2.sa.sa_family == AF_INET6) rv = IN6_ARE_ADDR_EQUAL(&sa1.s6.sin6_addr, &sa2.s6.sin6_addr); #endif else rv = 0; err: e = errno; if (sockfd >= 0) close(sockfd); errno = e; return rv; } static void normalize_ip6_compat(union sock_addr *myaddr) { #ifdef HAVE_IPV6 static const uint8_t ip6_compat_prefix[12] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xff }; struct sockaddr_in in; if (myaddr->sa.sa_family == AF_INET6 && !memcmp(&myaddr->s6.sin6_addr, ip6_compat_prefix, sizeof ip6_compat_prefix)) { bzero(&in, sizeof in); in.sin_family = AF_INET; in.sin_port = myaddr->s6.sin6_port; memcpy(&in.sin_addr, (const char *)&myaddr->s6.sin6_addr + sizeof ip6_compat_prefix, sizeof in.sin_addr); memcpy(&myaddr->si, &in, sizeof in); } #else (void)myaddr; #endif } void set_socket_nonblock(int fd, int flag) { int flags; #if defined(HAVE_FCNTL) && (O_NONBLOCK != 0) /* Posixly correct */ flags = fcntl(fd, F_GETFL, 0); if (flags < 0) goto err; if (flag) flags |= O_NONBLOCK; else flags &= ~O_NONBLOCK; if (fcntl(fd, F_SETFL, flags) < 0) goto err; #else flags = flag ? 1 : 0; if (ioctl(fd, FIONBIO, &flags) < 0) goto err; #endif return; err: tftpd_log(LOG_ERR, "Cannot set nonblock flag on socket: %m"); exit(EX_OSERR); } /* Disable pmtu discovery */ static void pmtu_discovery_off(int fd) { #if defined(IP_MTU_DISCOVER) && defined(IP_PMTUDISC_DONT) int pmtu = IP_PMTUDISC_DONT; setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu, sizeof(pmtu)); #endif } /* Try to enable getting the receive address in recvmsg() */ static void enable_recvdstaddr(int fd) { int on = 1; (void)on; #ifdef IP_RECVDSTADDR setsockopt(fd, IPPROTO_IP, IP_RECVDSTADDR, &on, sizeof(on)); #endif #ifdef IP_PKTINFO setsockopt(fd, IPPROTO_IP, IP_PKTINFO, &on, sizeof(on)); #endif #ifdef HAVE_IPV6 #ifdef IPV6_RECVPKTINFO setsockopt(fd, IPPROTO_IPV6, IPV6_RECVPKTINFO, &on, sizeof(on)); #endif #endif } /* * Configure a socket for myrecvfrom(). It should also be suitable * for select(). * * The "peer" flag indicates that this a connected peer socket. */ void tftpd_config_socket(int fd, int peer) { /* Set socket as nonblocking */ #ifdef __CYGWIN__ /* On Cygwin, a nonblocking socket returns immediately from select()! */ set_socket_nonblock(fd, 0); #else set_socket_nonblock(fd, 1); #endif /* Disable pmtu discovery (useless for TFTP and breaks things) */ pmtu_discovery_off(fd); /* Get our own address in recvmsg()*/ if (!peer) enable_recvdstaddr(fd); } #ifdef HAVE_RECVMSG int myrecvfrom(int s, void *buf, int len, unsigned int flags, union sock_addr *from, union sock_addr *myaddr) { struct msghdr msg; struct iovec iov; int n; struct cmsghdr *cmptr; union { struct cmsghdr cm; #ifdef IP_PKTINFO char control[CMSG_SPACE(sizeof(struct in_addr)) + CMSG_SPACE(sizeof(struct in_pktinfo))]; #else char control[CMSG_SPACE(sizeof(struct in_addr))]; #endif #ifdef HAVE_IPV6 #ifdef HAVE_STRUCT_IN6_PKTINFO_IPI6_ADDR char control6[CMSG_SPACE(sizeof(struct in6_addr)) + CMSG_SPACE(sizeof(struct in6_pktinfo))]; #else char control6[CMSG_SPACE(sizeof(struct in6_addr))]; #endif #endif } control_un; #ifdef IP_PKTINFO struct in_pktinfo pktinfo; #endif #ifdef HAVE_STRUCT_IN6_PKTINFO_IPI6_ADDR struct in6_pktinfo pktinfo6; #endif #endif bzero(&msg, sizeof msg); /* Clear possible system-dependent fields */ msg.msg_control = control_un.control; msg.msg_controllen = sizeof(control_un); msg.msg_flags = 0; msg.msg_name = &from->sa; msg.msg_namelen = sizeof(*from); iov.iov_base = buf; iov.iov_len = len; msg.msg_iov = &iov; msg.msg_iovlen = 1; if ((n = recvmsg(s, &msg, flags)) < 0) return n; /* Error */ if (myaddr) { bzero(myaddr, sizeof(*myaddr)); myaddr->sa.sa_family = from->sa.sa_family; if (msg.msg_controllen < sizeof(struct cmsghdr) || (msg.msg_flags & MSG_CTRUNC)) return n; /* No information available */ for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL; cmptr = CMSG_NXTHDR(&msg, cmptr)) { if (from->sa.sa_family == AF_INET) { myaddr->sa.sa_family = AF_INET; #ifdef IP_RECVDSTADDR if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_RECVDSTADDR) { memcpy(&myaddr->si.sin_addr, CMSG_DATA(cmptr), sizeof(struct in_addr)); } #endif #ifdef IP_PKTINFO if (cmptr->cmsg_level == IPPROTO_IP && cmptr->cmsg_type == IP_PKTINFO) { memcpy(&pktinfo, CMSG_DATA(cmptr), sizeof(struct in_pktinfo)); memcpy(&myaddr->si.sin_addr, &pktinfo.ipi_addr, sizeof(struct in_addr)); } #endif } #ifdef HAVE_IPV6 else if (from->sa.sa_family == AF_INET6) { myaddr->sa.sa_family = AF_INET6; #ifdef IP6_RECVDSTADDR if (cmptr->cmsg_level == IPPROTO_IPV6 && cmptr->cmsg_type == IPV6_RECVDSTADDR) memcpy(&myaddr->s6.sin6_addr, CMSG_DATA(cmptr), sizeof(struct in6_addr)); #endif #ifdef HAVE_STRUCT_IN6_PKTINFO_IPI6_ADDR if (cmptr->cmsg_level == IPPROTO_IPV6 && ( #ifdef IPV6_RECVPKTINFO cmptr->cmsg_type == IPV6_RECVPKTINFO || #endif cmptr->cmsg_type == IPV6_PKTINFO)) { memcpy(&pktinfo6, CMSG_DATA(cmptr), sizeof(struct in6_pktinfo)); memcpy(&myaddr->s6.sin6_addr, &pktinfo6.ipi6_addr, sizeof(struct in6_addr)); } #endif } #endif } normalize_ip6_compat(myaddr); /* If the address is not a valid local address, * then bind to any address... */ if (address_is_local(myaddr) != 1) { if (myaddr->sa.sa_family == AF_INET) ((struct sockaddr_in *)myaddr)->sin_addr.s_addr = INADDR_ANY; #ifdef HAVE_IPV6 else if (myaddr->sa.sa_family == AF_INET6) memset(&myaddr->s6.sin6_addr, 0, sizeof(struct in6_addr)); #endif } } normalize_ip6_compat(from); return n; } #else /* pointless... */ int myrecvfrom(int s, void *buf, int len, unsigned int flags, union sock_addr *from, union sock_addr *myaddr) { /* There is no way we can get the local address, fudge it */ socklen_t fromlen = sizeof(*from); bzero(myaddr, sizeof(*myaddr)); myaddr->sa.sa_family = from->sa.sa_family; sa_set_port(myaddr, htons(IPPORT_TFTP)); return recvfrom(s, buf, len, flags, &from->sa, &fromlen); } #endif tftp-hpa-5.3+20251209/tftpd/recvfrom.h000066400000000000000000000016571511036464300171350ustar00rootroot00000000000000/* ----------------------------------------------------------------------- * * * Copyright 2001-2025 H. Peter Anvin - All Rights Reserved * * This program is free software available under the same license * as the "OpenBSD" operating system, distributed at * http://www.openbsd.org/. * * ----------------------------------------------------------------------- */ /* * recvfrom.h * * Header for recvfrom substitute and socket configuration functions */ #include "config.h" int myrecvfrom(int s, void *buf, int len, unsigned int flags, union sock_addr *from, union sock_addr *myaddr); void tftpd_config_socket(int fd, int peer); void set_socket_nonblock(int fd, int flag); /* On Cygwin, a nonblocking socket can cause immediate return from select?! */ #ifdef __CYGWIN__ #define cygwin_set_socket_nonblock(fd,flag) set_socket_nonblock(fd,flag) #else #define cygwin_set_socket_nonblock(fd,flag) ((void)0) #endif tftp-hpa-5.3+20251209/tftpd/remap.c000066400000000000000000000533041511036464300164050ustar00rootroot00000000000000/* ----------------------------------------------------------------------- * * * Copyright 2001-2025 H. Peter Anvin - All Rights Reserved * * This program is free software available under the same license * as the "OpenBSD" operating system, distributed at * http://www.openbsd.org/. * * ----------------------------------------------------------------------- */ /* * remap.c * * Perform regular-expression based filename remapping. */ #include "config.h" /* Must be included first! */ #include "tftpd.h" #include "remap.h" #include #include #define DEADMAN_MAX_STEPS 4096 /* Timeout after this many steps */ #define RULE_REWRITE 0x01 /* This is a rewrite rule */ #define RULE_GLOBAL 0x02 /* Global rule (repeat until no match) */ #define RULE_EXIT 0x04 /* Exit after matching this rule */ #define RULE_RESTART 0x08 /* Restart at the top after matching this rule */ #define RULE_ABORT 0x10 /* Terminate processing with an error */ #define RULE_INVERSE 0x20 /* Execute if regex *doesn't* match */ #define RULE_IPV4 0x40 /* IPv4 only */ #define RULE_IPV6 0x80 /* IPv6 only */ #define RULE_HASFILE 0x100 /* Valid if rule results in a valid filename */ #define RULE_RRQ 0x200 /* Get (read) only */ #define RULE_WRQ 0x400 /* Put (write) only */ #define RULE_SEDG 0x800 /* sed-style global */ #define RULE_JUMP 0x1000 /* Jump rule */ #define RULE_LABEL 0x2000 /* Label */ #define RULE_NOREGEX 0x4000 /* The rule has no regular expression */ #define RULE_HAS_REGEX(x) (!((x) & RULE_NOREGEX)) int deadman_max_steps = DEADMAN_MAX_STEPS; #if defined(HAVE_WCHAR_H) && defined(HAVE_WCTYPE_H) && \ defined(HAVE_MBRTOWC) && defined(HAVE_TOWLOWER) # define WITH_MB 1 #else # define WITH_MB 0 #endif struct rule { struct rule *next; unsigned int line; unsigned int rule_flags; regex_t rx; const char *pattern; /* Replacement pattern or label name */ }; #if WITH_MB typedef wint_t xform_int; #define xform_toupper towupper #define xform_tolower towlower #else typedef int xform_int; #define xform_toupper toupper #define xform_tolower tolower #endif typedef xform_int (*xform_func)(xform_int xc); struct xform_state { xform_func xform; char *out; size_t len; int err; #if WITH_MB mbstate_t ps; #endif }; static xform_int xform_null(xform_int xc) { return xc; } static void xform_init(struct xform_state *xs, char *string) { memset(xs, 0, sizeof *xs); xs->xform = xform_null; xs->out = string; } #if WITH_MB static const char *xform_out(struct xform_state *xs, const char *p, size_t len) { static char dummy_mb_buf[MB_LEN_MAX]; mbstate_t ips; char *q = xs->out; memset(&ips, 0, sizeof ips); while (len && *p && *p != '\\') { wchar_t wc; ssize_t nb = mbrtowc(&wc, p, len, &ips); if (nb > 0) { len -= nb; p += nb; wc = xs->xform(wc); nb = wcrtomb(q ? q : dummy_mb_buf, wc, &xs->ps); if (nb > 0) { xs->len += nb; if (q) q += nb; } } else { /* Conversion error */ xs->err = 1; break; } } if (q) { *q = '\0'; xs->out = q; } return p; } #else static const char *xform_out(struct xform_state *xs, const char *p, size_t len) { char *q = xs->out; while (len && *p && *p != '\\') { if (q) q++ = xs->xform((unsigned char)*p); xs->len++; p++; len--; } if (q) { *q = '\0'; xs->out = q; } return p; } #endif /* * Do \-substitution. Call with string == NULL to get length only. * "start" indicates an offset into the input buffer where the pattern * match was started; *nextp points to the first character after the * pattern expansion. * * If start is set to MATCHONLY == (size_t)-1 or the pmatch array indicates * that no match was found, then the before and after match contents of * the input string are discarded. */ #define MATCHONLY ((size_t)-1) static size_t null_macrosub(char macro, char **macrodata) { (void)macro; (void)macrodata; return (size_t)-1; } static size_t xsmemcpy(struct xform_state *xs, const char *from, size_t bytes) { if (xs->out) { memcpy(xs->out, from, bytes); xs->out += bytes; *xs->out = '\0'; /* Enforce null termination */ } xs->len += bytes; return xs->len; } static size_t do_genmatchstring(char *string, const char *pattern, const char *ibuf, const regmatch_t *pmatch, match_pattern_callback macrosub, size_t start, size_t *nextp) { size_t endbytes; struct xform_state xs; const char *input; const char *pattern_end = strchr(pattern, '\0'); if (!macrosub) macrosub = null_macrosub; xform_init(&xs, string); if (start == MATCHONLY) { input = ibuf; endbytes = 0; } else if (pmatch[0].rm_so == -1) { return xsmemcpy(&xs, ibuf, strlen(ibuf)+1); } else { input = ibuf + start; endbytes = strlen(input) - pmatch[0].rm_eo; xsmemcpy(&xs, ibuf, start + pmatch[0].rm_so); } /* Transform matched section */ while (*pattern) { if (*pattern == '\\') { char macro = pattern[1]; pattern += 2; switch (macro) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': { const regmatch_t *pm = &pmatch[macro - '0']; if (pm->rm_so != -1) { xform_out(&xs, input + pm->rm_so, pm->rm_eo - pm->rm_so); } break; } case 'L': xs.xform = xform_tolower; break; case 'U': xs.xform = xform_toupper; break; case 'E': xs.xform = xform_null; break; case '\0': pattern--; /* fall through */ case '\\': xs.len++; if (xs.out) *xs.out++ = '\\'; break; default: { char *macrodata; size_t sublen = macrosub(macro, ¯odata); if (sublen != (size_t)-1) { xform_out(&xs, macrodata, sublen); } else { /* Ignore the backslash prefix */ pattern--; } break; } } } else { pattern = xform_out(&xs, pattern, pattern_end - pattern); } } /* Pointer to post-substitution tail */ if (nextp) *nextp = xs.len; /* Copy section after match */ xsmemcpy(&xs, input + pmatch[0].rm_eo, endbytes); return xs.err ? (size_t)-1 : xs.len; } /* * Ditto, but allocate the string in a new buffer */ static size_t genmatchstring(char **string, const char *pattern, const char *ibuf, const regmatch_t *pmatch, match_pattern_callback macrosub, size_t start, size_t *nextp) { size_t len; char *buf; len = do_genmatchstring(NULL, pattern, ibuf, pmatch, macrosub, start, NULL); if (len == (size_t)-1) { *string = NULL; return len; } *string = buf = tfmalloc(len + 1); return do_genmatchstring(buf, pattern, ibuf, pmatch, macrosub, start, nextp); } /* * Extract a string terminated by non-escaped whitespace; ignoring * leading whitespace. Consider an unescaped # to be a comment marker, * functionally \n. */ static size_t readescstring(char *buf, char **str) { char *p = *str; int wasbs = 0; size_t len = 0; while (*p && isspace(*p)) p++; if (!*p) { *buf = '\0'; *str = p; return 0; } while (*p) { if (!wasbs && (isspace(*p) || *p == '#')) { *buf = '\0'; *str = p; return len; } /* Important: two backslashes leave us in the !wasbs state! */ wasbs = !wasbs && (*p == '\\'); *buf++ = *p++; len++; } *buf = '\0'; *str = p; return len; } /* * Parse a line into a set of instructions. Needs a work buffer * no shorter than the length of the line including final \0. */ static int parseline(char *line, struct rule *r, unsigned int lineno, char *buffer) { char *p; int rv; int rxflags = REG_EXTENDED; struct badcombo { unsigned int flags; char name[4]; }; static const struct badcombo badcombos[] = { { RULE_REWRITE | RULE_INVERSE, "r~" }, { RULE_REWRITE | RULE_ABORT, "ra" }, { RULE_REWRITE | RULE_JUMP, "rj" }, { RULE_ABORT | RULE_JUMP, "aj" }, { RULE_ABORT | RULE_RESTART, "as" }, { RULE_EXIT | RULE_JUMP, "ej" }, { RULE_EXIT | RULE_ABORT, "ae" }, { RULE_EXIT | RULE_RESTART, "es" }, { RULE_EXIT | RULE_HASFILE, "eE" }, { RULE_HASFILE | RULE_JUMP, "Ej" }, { RULE_HASFILE | RULE_ABORT, "aE" }, { RULE_HASFILE | RULE_RESTART, "Es" }, { 0, "" } }; const struct badcombo *bc; memset(r, 0, sizeof *r); r->line = lineno; if (!readescstring(buffer, &line)) return 0; /* No rule found */ p = buffer; if (*buffer == ':') { /* It is a label */ r->rule_flags = RULE_LABEL | RULE_NOREGEX; p++; if (*p) { r->pattern = tfstrdup(p); return 1; } } for (; *p; p++) { switch (*p) { case 'r': r->rule_flags |= RULE_REWRITE; break; case 'g': if (r->rule_flags & RULE_GLOBAL) r->rule_flags |= RULE_SEDG; else r->rule_flags |= RULE_GLOBAL; break; case 'e': r->rule_flags |= RULE_EXIT; break; case 'E': r->rule_flags |= RULE_HASFILE; break; case 's': r->rule_flags |= RULE_RESTART; break; case 'a': r->rule_flags |= RULE_ABORT; break; case 'j': r->rule_flags |= RULE_JUMP; break; case 'i': rxflags |= REG_ICASE; break; case '~': r->rule_flags |= RULE_INVERSE; rxflags |= REG_NOSUB; break; case '4': r->rule_flags |= RULE_IPV4; break; case '6': r->rule_flags |= RULE_IPV6; break; case 'G': r->rule_flags |= RULE_RRQ; break; case 'P': r->rule_flags |= RULE_WRQ; break; default: tftpd_log(LOG_ERR, "remap: line %u: invalid operation flag \"%c\"", *p, lineno); return -1; /* Error */ break; } } for (bc = badcombos; bc->flags; bc++) { if ((r->rule_flags & bc->flags) == bc->flags) { tftpd_log(LOG_ERR, "remap: line %u: rule flags %c and %c cannot be combined", lineno, bc->name[0], bc->name[1]); return -1; } } if (!(r->rule_flags & RULE_REWRITE)) { /* RULE_GLOBAL and RULE_SEDG are meaningless without RULE_REWRITE */ r->rule_flags &= ~(RULE_GLOBAL|RULE_SEDG); } if (RULE_HAS_REGEX(r->rule_flags)) { /* Read and compile the regex */ if (!readescstring(buffer, &line)) { tftpd_log(LOG_ERR, "remap: line %u: regex missing", lineno); return -1; /* Error */ } if ((rv = regcomp(&r->rx, buffer, rxflags)) != 0) { char *errbuf = tfmalloc(BUFSIZ); regerror(rv, &r->rx, errbuf, BUFSIZ); tftpd_log(LOG_ERR, "regex: line %u: bad regex: %s", lineno, errbuf); return -1; /* Error */ } } /* Read the rewrite pattern, if any */ if (readescstring(buffer, &line)) r->pattern = tfstrdup(buffer); else r->pattern = tfstrdup(""); return 1; /* Valid rule found */ } #define MIN_LINE 64 /* Minimum size of allocated buffer */ /* Read a line into an allocated buffer; drops \n \r \0 */ static size_t read_line(FILE *f, char **bufp, size_t *bufsizep) { char *buf = *bufp; size_t bufsize = *bufsizep; size_t len = 0; while (1) { int c = 0; while (len+1 < bufsize) { c = getc(f); if (c == EOF) { buf[len] = '\0'; return len ? len : (size_t)-1; } else if (c == '\n') { buf[len] = '\0'; return len; } else if (c != '\0' && c != '\r') { buf[len++] = c; } } if (bufsize < MIN_LINE) bufsize = MIN_LINE; else bufsize <<= 1; *bufsizep = bufsize; *bufp = buf = tfrealloc(buf, bufsize); } } /* Read a rule file */ struct rule *parserulefile(FILE * f) { char *line = NULL; char *parsebuf = NULL; size_t linesize = 0; size_t parsebufsize = 0; struct rule *first_rule = NULL; struct rule **last_rule = &first_rule; struct rule *this_rule = tfmalloc(sizeof(struct rule)); int rv; unsigned int lineno = 0; size_t len; int err = 0; while ((len = read_line(f, &line, &linesize)) != (size_t)-1) { lineno++; if (parsebufsize < linesize) parsebuf = tfrealloc(parsebuf, parsebufsize = linesize); rv = parseline(line, this_rule, lineno, parsebuf); if (rv < 0) err = 1; if (rv > 0) { *last_rule = this_rule; last_rule = &this_rule->next; this_rule = tfmalloc(sizeof(struct rule)); } } tffree(this_rule); /* Last one is always unused */ tffree(parsebuf); tffree(line); /* Free buffer */ if (err) { /* Bail on error, we have already logged an error message */ exit(EX_CONFIG); } return first_rule; } /* Destroy a rule file data structure */ void freerules(struct rule *r) { struct rule *next; while (r) { next = r->next; if (RULE_HAS_REGEX(r->rule_flags)) regfree(&r->rx); tffree((void *)r->pattern); tffree(r); r = next; } } static void clear_pmatch(int pmatches, regmatch_t *pmatch) { int i; for (i = 0; i < pmatches; i++) pmatch[i].rm_so = pmatch[i].rm_eo = -1; } /* Execute a rule set on a string; returns a malloc'd new string. */ char *rewrite_string(const struct formats *pf, const char *input, const struct rule *rules, int mode, int af, match_pattern_callback macrosub, const char **errmsg) { char *current = tfstrdup(input); char *newstr = current; const char *accerr; const struct rule *ruleptr = rules; regmatch_t pmatch[10]; int deadman = deadman_max_steps; unsigned int bad_flags; /* Default error */ *errmsg = "Remap table failure"; if (verbosity >= 3) { tftpd_log(LOG_INFO, "remap: input: %s", current); } bad_flags = RULE_LABEL | RULE_NOREGEX; if (mode != RRQ) bad_flags |= RULE_RRQ; if (mode != WRQ) bad_flags |= RULE_WRQ; if (af != AF_INET) bad_flags |= RULE_IPV4; if (af != AF_INET6) bad_flags |= RULE_IPV6; ruleptr = rules; while (ruleptr) { const int inverse = ruleptr->rule_flags & RULE_INVERSE; const int pmatches = inverse ? 0 : 10; const int matchsense = inverse ? REG_NOMATCH : 0; int was_match; const char *whatami; const struct rule *next = ruleptr->next; if (ruleptr->rule_flags & bad_flags) goto nextrule; if (!deadman--) goto dead; newstr = current; /* Clear the pmatch[] array for good measure */ clear_pmatch(10, pmatch); was_match = regexec(&ruleptr->rx, newstr, pmatches, pmatch, 0) == matchsense; if (!was_match) goto nextrule; /* Rule did not match */ if (verbosity >= 5) { tftpd_log(LOG_INFO, "remap: line %u: hit on %s%.*s%s, replacement: \"%s\"", ruleptr->line, inverse ? "~" : "\"", pmatch[0].rm_eo - pmatch[0].rm_so, inverse ? "" : newstr + pmatch[0].rm_so, inverse ? "" : "\"", ruleptr->pattern); } whatami = "match"; if (ruleptr->rule_flags & RULE_REWRITE) { size_t ggoffset = 0; whatami = "rewrite"; while (1) { char *newerstr; size_t len; size_t gg0 = ggoffset + pmatch[0].rm_so; len = genmatchstring(&newerstr, ruleptr->pattern, newstr, pmatch, macrosub, ggoffset, &ggoffset); if (len == (size_t)-1) { tffree(newstr); return NULL; } if (verbosity >= 4) { tftpd_log(LOG_INFO, "remap: line %u: rewrite step: \"%.*s\" -> \"%.*s\" [%d]", ruleptr->line, pmatch[0].rm_eo - pmatch[0].rm_so, newstr + gg0, (int)(ggoffset - gg0), newerstr + gg0, (int)(ggoffset - gg0)); } if (newstr != current) tffree(newstr); newstr = newerstr; if (!(ruleptr->rule_flags & RULE_GLOBAL)) break; if (!(ruleptr->rule_flags & RULE_SEDG)) ggoffset = 0; else if (ggoffset >= len) break; clear_pmatch(pmatches, pmatch); if (regexec(&ruleptr->rx, newstr + ggoffset, pmatches, pmatch, ggoffset ? REG_NOTBOL : 0) != matchsense) break; if (!deadman--) goto dead; } } if ((ruleptr->rule_flags & RULE_HASFILE) && pf->f_validate(newstr, mode, pf, &accerr)) { if (verbosity >= 3) { tftpd_log(LOG_INFO, "remap: line %u: ignoring %s (%s)", ruleptr->line, whatami, accerr); } was_match = 0; if (newstr != current) { tffree(newstr); newstr = current; } } else if (newstr != current) { tffree(current); current = newstr; if (verbosity >= 3) { tftpd_log(LOG_INFO, "remap: line %u: rewrite result: %s", ruleptr->line, current); } } if (!was_match) goto nextrule; newstr = NULL; if (ruleptr->rule_flags & (RULE_ABORT|RULE_JUMP)) { if ((ssize_t)genmatchstring(&newstr, ruleptr->pattern, current, pmatch, macrosub, MATCHONLY, NULL) <= 0) { tffree(newstr); newstr = NULL; } } if (ruleptr->rule_flags & RULE_ABORT) { if (verbosity >= 3) { tftpd_log(LOG_INFO, "remap: line %u: abort: %s", ruleptr->line, current); } *errmsg = newstr; newstr = NULL; goto quit; } if (ruleptr->rule_flags & (RULE_EXIT|RULE_HASFILE)) { if (verbosity >= 3) { tftpd_log(LOG_INFO, "remap: line %u: exit", ruleptr->line); } return current; /* Exit here, we're done */ } if (ruleptr->rule_flags & RULE_RESTART) { next = rules; } else if (ruleptr->rule_flags & RULE_JUMP) { if (!newstr) { tftpd_log(LOG_ERR, "remap: line %u: no label in j rule", ruleptr->line); goto quit; } for (next = rules; next; next++) { if ((next->rule_flags & RULE_LABEL) && !strcmp(newstr, next->pattern)) break; } if (!next) { tftpd_log(LOG_ERR, "remap: line %u: label not found: %s", ruleptr->line, newstr); goto quit; } } if (verbosity >= 3) { if (next != ruleptr->next) { if ((next->rule_flags & RULE_LABEL) && next->pattern[0]) { tftpd_log(LOG_INFO, "remap: line %u: jump to %s", ruleptr->line, next->pattern); } else { tftpd_log(LOG_INFO, "remap: line %u: jump to line %u", ruleptr->line, next->line); } } } nextrule: ruleptr = next; } if (verbosity >= 3) { tftpd_log(LOG_INFO, "remap: done: %s", current); } return current; dead: /* Deadman expired */ tftpd_log(LOG_ERR, "remap: Breaking loop after %d steps, input = %s, last = %s", deadman_max_steps, input, newstr); quit: if (newstr != current) tffree(newstr); tffree(current); return NULL; /* Did not terminate! */ } tftp-hpa-5.3+20251209/tftpd/remap.h000066400000000000000000000027441511036464300164140ustar00rootroot00000000000000/* ----------------------------------------------------------------------- * * * Copyright 2001-2025 H. Peter Anvin - All Rights Reserved * * This program is free software available under the same license * as the "OpenBSD" operating system, distributed at * http://www.openbsd.org/. * * ----------------------------------------------------------------------- */ /* * remap.h * * Prototypes for regular-expression based filename remapping. */ #ifndef TFTPD_REMAP_H #define TFTPD_REMAP_H /* Opaque type */ struct rule; #ifdef WITH_REGEX /* * This is called by the remap engine when it encounters macros such * as \i. It should put the output in a static buffer and put the * buffer address in *output, then return the length of the output * not including the terminal null. * * Return (size_t)-1 for an invalid macro, which then will be handled * by the substitution code. */ typedef size_t (*match_pattern_callback) (char, char **); /* Read a rule file */ struct rule *parserulefile(FILE *); /* Destroy a rule file data structure */ void freerules(struct rule *); /* Execute a rule set on a string; returns a malloc'd new string. */ struct formats; char *rewrite_string(const struct formats *, const char *, const struct rule *, int, int, match_pattern_callback, const char **); /* Remapping deadman counter */ extern int deadman_max_steps; #endif /* WITH_REGEX */ #endif /* TFTPD_REMAP_H */ tftp-hpa-5.3+20251209/tftpd/sample.rules000066400000000000000000000023111511036464300174620ustar00rootroot00000000000000# # Sample rule file for the -m (remapping option) # # This file has three fields: operation, regex, remapping # # The operation is a combination of the following letters: # # r - rewrite the matched string with the remapping pattern # i - case-insensitive matching # g - repeat until no match (used with "r") # e - exit (with success) if we match this pattern, do not process # subsequent rules # s - start over from the first rule if we match this pattern # a - abort (refuse the request) if we match this rule # G - this rule applies to TFTP GET requests only # P - this rule applies to TFTP PUT requests only # # The regex is a regular expression in the style of egrep(1). # # The remapping is a pattern, all characters are verbatim except \ # \0 copies the full string that matched the regex # \1..\9 copies the 9 first (..) expressions in the regex # \\ is an escaped \ # # "#" begins a comment, unless \-escaped # ri ^[a-z]: # Remove "drive letters" rg \\ / # Convert backslashes to slashes rg \# @ # Convert hash marks to @ signs rg /../ /..no../ # Convert /../ to /..no../ e ^ok/ # These are always ok r ^[^/] /tftpboot/\0 # Convert non-absolute files a \.pvt$ # Reject requests for private files tftp-hpa-5.3+20251209/tftpd/tftpd.8.in000066400000000000000000000354571511036464300167650ustar00rootroot00000000000000.\" -*- nroff -*- --------------------------------------------------------- * .\" .\" Copyright (c) 1990, 1993, 1994 .\" The Regents of the University of California. All rights reserved. .\" .\" Copyright 2001-2009 H. Peter Anvin - All Rights Reserved .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions .\" are met: .\" 1. Redistributions of source code must retain the above copyright .\" notice, this list of conditions and the following disclaimer. .\" 2. Redistributions in binary form must reproduce the above copyright .\" notice, this list of conditions and the following disclaimer in the .\" documentation and/or other materials provided with the distribution. .\" 3. Neither the name of the University nor the names of its contributors .\" may be used to endorse or promote products derived from this software .\" without specific prior written permission. .\" .\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND .\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE .\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE .\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE .\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL .\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS .\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) .\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT .\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" .\"----------------------------------------------------------------------- */ .TH TFTPD 8 "7 June 2014" "tftp-hpa @@VERSION@@" "System Manager's Manual" .SH NAME .B tftpd \- Trivial File Transfer Protocol server .SH SYNOPSIS .B in.tftpd .RI [ options... ] .I directory... .SH DESCRIPTION .B tftpd is a server for the Trivial File Transfer Protocol. The TFTP protocol is extensively used to support remote booting of diskless devices. The server is normally started by .BR inetd , but can also run standalone. .PP .SH OPTIONS .TP \fB\-\-ipv4\fP, \fB\-4\fP Connect with IPv4 only, even if IPv6 support was compiled in. .TP \fB\-\-ipv6\fP, \fB\-6\fP Connect with IPv6 only, if compiled in. .TP \fB\-l\fP, \fB\-\-listen\fP Run the server in standalone (listen) mode, rather than run from .BR inetd . In listen mode, the .B \-\-timeout option is ignored, and the .B \-\-address option can be used to specify a specific local address or port to listen to. .TP \fB\-\-foreground\fP, \fB\-L\fP Similar to .B \-\-listen but do not detach from the foreground process. Implies .BR \-\-listen . .TP \fB\-\-address\fP \fI[address][:port]\fP, \fB\-a\fP \fI[address][:port]\fP Specify a specific .I address and .I port to listen to when called with the .B \-\-listen or .B \-\-foreground option. The default is to listen to the .I tftp port specified in .I /etc/services on all local addresses. .B Please note: Numeric IPv6 adresses must be enclosed in square brackets to avoid ambiguity with the optional port information. .TP \fB\-\-create\fP, \fB\-c\fP Allow new files to be created. By default, .B tftpd will only allow upload of files that already exist. Files are created with default permissions allowing anyone to read or write them, unless the .B \-\-permissive or .B \-\-umask options are specified. .TP \fB\-\-secure\fP, \fB\-s\fP Change root directory on startup. This means the remote host does not need to pass along the directory as part of the transfer, and may add security. When .B \-\-secure is specified, exactly one .I directory should be specified on the command line. The use of this option is recommended for security as well as compatibility with some boot ROMs which cannot be easily made to include a directory name in its request. .TP \fB\-\-user\fP \fIusername\fP, \fB\-u\fP \fIusername\fP Specify the username which .B tftpd will run as; the default is "nobody". The user ID, group ID, and (if possible on the platform) the supplementary group IDs will be set to the ones specified in the system permission database for this username. .TP \fB\-\-umask\fP \fIumask\fP, \fB\-U\fP \fIumask\fP Sets the \fIumask\fP for newly created files to the specified value. The default is zero (anyone can read or write) if the .B \-\-permissive option is not specified, or inherited from the invoking process if .B \-\-permissive is specified. .TP \fB\-\-permissive\fP, \fB\-p\fP Perform no additional permissions checks above the normal system-provided access controls for the user specified via the .B \-\-user option. .TP \fB\-\-pidfile\fP \fIpidfile\fP, \fB\-P\fP \fIpidfile\fP When run in standalone mode, write the process ID of the listening server into \fIpidfile\fP. On normal termination (SIGTERM or SIGINT) the pid file is automatically removed. .TP \fB\-\-timeout\fP \fItimeout\fP, \fB\-t\fP \fItimeout\fP When run from .B inetd this specifies how long, in seconds, to wait for a second connection before terminating the server. .B inetd will then respawn the server when another request comes in. The default is 900 (15 minutes.) .TP \fB\-\-retransmit\fP \fItimeout, \fP\fB\-T\fP \fItimeout\fP Determine the default timeout, in microseconds, before the first packet is retransmitted. This can be modified by the client if the .B timeout or .B utimeout option is negotiated. The default is 1000000 (1 second.) .TP \fB\-\-map-file\fP \fIremap-file\fP, \fB\-m\fP \fIremap-file\fP Specify the use of filename remapping. The .I remap-file is a file containing the remapping rules. See the section on filename remapping below. This option may not be compiled in, see the output of .B "in.tftpd \-V" to verify whether or not it is available. .TP \fB\-\-map-steps\fP \fIsteps\fP Specify the number of remapping rules that may be executed before the filename mapping fails. The default is 4096. .TP \fB\-\-verbose\fP, \fB\-v\fP Increase the logging verbosity of .BR tftpd . This flag can be specified multiple times for even higher verbosity. .TP \fB\-\-verbosity\fP \fIvalue\fP Set the verbosity value to \fIvalue\fP. .TP \fB\-\-refuse\fP \fItftp-option\fP, \fB\-r\fP \fItftp-option\fP Indicate that a specific RFC 2347 TFTP option should never be accepted. .TP \fB\-\-blocksize\fP \fImax-block-size\fP, \fB\-B\fP \fImax-block-size\fP Specifies the maximum permitted block size. The permitted range for this parameter is from 512 to 65464. Some embedded clients request large block sizes and yet do not handle fragmented packets correctly; for these clients, it is recommended to set this value to the smallest MTU on your network minus 32 bytes (20 bytes for IP, 8 for UDP, and 4 for TFTP; less if you use IP options on your network.) For example, on a standard Ethernet (MTU 1500) a value of 1468 is reasonable. .TP \fB\-\-port-range\fP \fIport:port\fP, \fB\-R\fP \fIport:port\fP Force the server port number (the Transaction ID) to be in the specified range of port numbers. .TP \fB\-\-version\fP, \fB\-V\fP Print the version number and configuration to standard output, then exit gracefully. .SH "RFC 2347 OPTION NEGOTIATION" This version of .B tftpd supports RFC 2347 option negotation. Currently implemented options are: .TP \fBblksize\fP (RFC 2348) Set the transfer block size to anything less than or equal to the specified option. This version of .B tftpd can support any block size up to the theoretical maximum of 65464 bytes. .TP \fBblksize2\fP (nonstandard) Set the transfer block size to anything less than or equal to the specified option, but restrict the possible responses to powers of 2. The maximum is 32768 bytes (the largest power of 2 less than or equal to 65464.) .TP \fBtsize\fP (RFC 2349) Report the size of the file that is about to be transferred. This version of .B tftpd only supports the .B tsize option for binary (octet) mode transfers. .TP \fBtimeout\fP (RFC 2349) Set the time before the server retransmits a packet, in seconds. .TP \fButimeout\fP (nonstandard) Set the time before the server retransmits a packet, in microseconds. .TP \fBrollover\fP (nonstandard) Set the block number to resume at after a block number rollover. The default and recommended value is zero. .PP The .B \-\-refuse option can be used to disable specific options; this may be necessary to work around bugs in specific TFTP client implementations. For example, some TFTP clients have been found to request the .B blksize option, but crash with an error if they actually get the option accepted by the server. .SH "FILENAME REMAPPING" The .B \-\-map-file option specifies a file which contains filename remapping rules. Each non-comment line (comments begin with hash marks, .BR # ) contains either a label, preceeded by a colon: .IP \fB:\fP\fIlabel\fP .PP or an .IR operation , specified below, followed by a .I regex (an extended regular expression in the style of .MR egrep 1 ), and optionally a .IR "replacement pattern" . The operation indicated by .I operation is performed if the .I regex matches all or part of the filename. Rules are processed from the top down, and by default, all rules are processed even if there is a match. .PP Sometimes it is useful to have a rule that \fIalways\fP matches, in that case, the regular expression: .IP .B ^ .PP (a single caret symbol) can be used. .PP The .I operation can be any valid combination of the following characters: .TP .B r Replace the substring matched by .I regex by the .IR "replacement pattern" . The replacement pattern may contain escape sequences; see below. .br \fBr\fP cannot be used with \fB~\fP, \fBa\fP, or \fBj\fP. .TP .B g Repeat the replacement until it no longer matches, searching the whole string, including replacements, from the beginning each time. .br \fBg\fP is always used with \fBr\fP. .TP .B gg Repeat the replacement until it no longer matches, but only on the portion of the string that has not yet been matched, similar to how the .B s command with the .B g option works in .MR sed 1 . .br \fBgg\fP is always used with \fBr\fP. .TP .B i Match the .I regex case-insensitively. By default it is case sensitive. .TP .B e If this rule matches, end rule processing after executing the rule. .br \fBe\fP cannot be used with \fBa\fP, \fBE\fP, \fBj\fP, or \fBs\fP. .TP .B E If this rule matches, \fIand the result matches a filename that can be transferred\fP, end rule processing after executing the rule. If this is used with .BR r , then if the substitution does \fInot\fP result in a valid filename, the substitution is undone. .br \fBE\fP cannot be used with \fBa\fP, \fBe\fP, \fBj\fP, or \fBs\fP. .TP .B s If this rule matches, start rule processing over from the very first rule after executing this rule. .br \fBs\fP cannot be used with \fBa\fP, \fBe\fP, \fBE\fP, or \fBj\fP. .TP .B a If this rule matches, refuse the request and send an access denied error to the client. .br \fBa\fP cannot be used with \fBe\fP, \fBE\fP, \fBj\fP, \fBr\fP, or \fBs\fP. .TP .B j If this rule matches, jump to the label specified by \fIreplacement pattern\fP. .TP .B G This rule applies to GET (RRQ) requests only. .TP .B P This rule applies to PUT (WRQ) requests only. .TP .B 4 This rule applies to IPv4 sessions only. .TP .B 6 This rule applies to IPv6 sessions only. .TP .B ~ Inverse the sense of this rule, i.e. execute the .I operation only if the .I regex .I doesn't match. .br \fB~\fP cannot be used with \fBr\fP. .PP The following escape sequences are recognized as part of a .IR "replacement pattern" : .TP \fB\\0\fP The entire string matched by the .IR regex . .TP \fB\\1\fP to \fB\\9\fP The strings matched by each of the first nine parenthesized subexpressions, \\( ... \\), of the .I regex pattern. .TP \fB\\i\fP The IP address of the requesting host, in dotted-quad notation for IPv4 (e.g. 192.0.2.169) or conventional colon form for IPv6 (e.g. 2001:db8::1). .TP \fB\\x\fP The IP address of the requesting host, in expanded hexadecimal notation (e.g. C00002A9 for IPv4, or 20010DB8000000000000000000000001 for IPv6). .TP \fB\\\\\fP Literal backslash. .TP \fB\\\fP\fIwhitespace\fP Literal whitespace. .TP \fB\\#\fP Literal hash mark. .TP \fB\\U\fP Turns all subsequent letters to upper case. .TP \fB\\L\fP Turns all subsequent letters to lower case. .TP \fB\\E\fP Cancels the effect of \fB\\U\fP or \fB\\L\fP. .PP If the mapping file is changed, you need to send .B SIGHUP to any outstanding .B tftpd process. .SH "SECURITY" The use of TFTP services does not require an account or password on the server system. Due to the lack of authentication information, .B tftpd will allow only publicly readable files (o+r) to be accessed, unless the .B \-\-permissive option is specified. Files may be written only if they already exist and are publicly writable, unless the .B \-\-create option is specified. Note that this extends the concept of ``public'' to include all users on all hosts that can be reached through the network; this may not be appropriate on all systems, and its implications should be considered before enabling TFTP service. Typically, some kind of firewall or packet-filter solution should be employed. If appropriately compiled (see the output of .BR "in.tftpd \-\-version" ) .B tftpd will query the .BR hosts_access (5) database for access control information. This may be slow; sites requiring maximum performance may want to compile without this option and rely on firewalling or kernel-based packet filters instead. .PP The server should be set to run as the user with the lowest possible privilege; please see the .B \-\-user flag. It is probably a good idea to set up a specific user account for .BR tftpd , rather than letting it run as "nobody", to guard against privilege leaks between applications. .PP Access to files can, and should, be restricted by invoking .B tftpd with a list of directories by including pathnames as server program arguments on the command line. In this case access is restricted to files whose names are prefixed by one of the given directories. If possible, it is recommended that the .B \-\-secure flag is used to set up a chroot() environment for the server to run in once a connection has been set up. .PP Finally, the filename remapping .RB ( \-\-map-file flag) support can be used to provide a limited amount of additional access control. .SH "CONFORMING TO" RFC 1123, .IR "Requirements for Internet Hosts \- Application and Support" . .br RFC 1350, .IR "The TFTP Protocol (revision 2)" . .br RFC 2347, .IR "TFTP Option Extension" . .br RFC 2348, .IR "TFTP Blocksize Option" . .br RFC 2349, .IR "TFTP Timeout Interval and Transfer Size Options" . .SH "AUTHOR" This version of .B tftpd is maintained by H. Peter Anvin . It was derived from, but has substantially diverged from, an OpenBSD source base, with added patches by Markus Gutschke and Gero Kulhman. .SH "SEE ALSO" .MR tftp 1 , .MR egrep 1 , .MR umask 2 , .MR hosts_access 5 , .MR regex 7 , .MR inetd 8 . tftp-hpa-5.3+20251209/tftpd/tftpd.c000066400000000000000000001537411511036464300164300ustar00rootroot00000000000000/* * Copyright (c) 1983 Regents of the University of California. * Copyright (c) 1999-2009 H. Peter Anvin * Copyright (c) 2011-2014 Intel Corporation; author: H. Peter Anvin * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. */ #include "config.h" /* Must be included first */ #include "tftpd.h" /* * Trivial file transfer protocol server. * * This version includes many modifications by Jim Guyton */ #include #include #include #include #include #include #include "common/tftpsubs.h" #include "recvfrom.h" #include "remap.h" #ifdef HAVE_SYS_FILIO_H #include /* Necessary for FIONBIO on Solaris */ #endif #ifdef HAVE_TCPWRAPPERS #include int deny_severity = LOG_WARNING; int allow_severity = -1; /* Don't log at all */ static struct request_info wrap_request; #endif #ifdef HAVE_IPV6 static int ai_fam = AF_UNSPEC; #else static int ai_fam = AF_INET; #endif #define TIMEOUT 1000000 /* Default timeout (us) */ #define TRIES 6 /* Number of attempts to send each packet */ #define TIMEOUT_LIMIT ((1 << TRIES)-1) const char *tftpd_progname; static int peer; static unsigned long timeout = TIMEOUT; /* Current timeout value */ static unsigned long rexmtval = TIMEOUT; /* Basic timeout value */ static unsigned long maxtimeout = TIMEOUT_LIMIT * TIMEOUT; static int timeout_quit = 0; static sigjmp_buf timeoutbuf; static uint16_t rollover_val = 0; #define PKTSIZE MAX_SEGSIZE+4 static char buf[PKTSIZE]; static char ackbuf[PKTSIZE]; static unsigned int max_blksize = MAX_SEGSIZE; static char tmpbuf[INET6_ADDRSTRLEN], *tmp_p; static union sock_addr from; static off_t tsize; static int tsize_ok; static int ndirs; static const char **dirs; static int secure = 0; int cancreate = 0; int unixperms = 0; int portrange = 0; unsigned int portrange_from, portrange_to; int verbosity = 0; #ifdef WITH_REGEX static struct rule *rewrite_rules = NULL; static void rewrite_test(FILE *); #endif static FILE *file; int tftp(struct tftphdr *, int); static void nak(int, const char *); static void timer(int); static void do_opt(const char *, const char *, char **); static int set_blksize(uintmax_t *); static int set_blksize2(uintmax_t *); static int set_tsize(uintmax_t *); static int set_timeout(uintmax_t *); static int set_utimeout(uintmax_t *); static int set_rollover(uintmax_t *); struct options { const char *o_opt; int (*o_fnc)(uintmax_t *); } options[] = { {"blksize", set_blksize}, {"blksize2", set_blksize2}, {"tsize", set_tsize}, {"timeout", set_timeout}, {"utimeout", set_utimeout}, {"rollover", set_rollover}, {NULL, NULL} }; /* Simple handler for SIGHUP */ static volatile sig_atomic_t caught_sighup = 0; static void handle_sighup(int sig) { (void)sig; /* Suppress unused warning */ caught_sighup = 1; } /* Handle exit requests by SIGTERM and SIGINT */ static volatile sig_atomic_t exit_signal = 0; static void handle_exit(int sig) { exit_signal = sig; } /* Handle timeout signal or timeout event */ static void timer(int sig) { (void)sig; /* Suppress unused warning */ timeout <<= 1; if (timeout >= maxtimeout || timeout_quit) exit(0); siglongjmp(timeoutbuf, 1); } static const char *prio_name(int priority) { switch (priority) { case LOG_EMERG: return "emergency: "; case LOG_ALERT: return "alert: "; case LOG_CRIT: return "critical: "; case LOG_ERR: return "error: "; case LOG_WARNING: return "warning: "; case LOG_NOTICE: return "notice: "; case LOG_INFO: return "info: "; case LOG_DEBUG: return "debug: "; default: return ""; } } static void tftpd_log_stderr(int priority, const char *fmt, ...) { va_list ap; fputs(prio_name(priority), stderr); va_start(ap, fmt); vfprintf(stderr, fmt, ap); va_end(ap); putc('\n', stderr); } log_func tftpd_log = tftpd_log_stderr; static void tftpd_openlog(const char *ident, int option, int facility) { openlog(ident, option, facility); tftpd_log = syslog; } #ifdef WITH_REGEX static struct rule *read_remap_rules(const char *rulefile) { FILE *f; struct rule *rulep; f = fopen(rulefile, "rt"); if (!f) { tftpd_log(LOG_ERR, "Cannot open map file: %s: %m", rulefile); exit(EX_NOINPUT); } rulep = parserulefile(f); fclose(f); return rulep; } #endif /* * Rules for locking files; return 0 on success, -1 on failure */ static int lock_file(int fd, int lock_write) { (void)lock_write; #if defined(HAVE_FCNTL) && HAVE_DECL_F_SETLK struct flock fl; fl.l_type = lock_write ? F_WRLCK : F_RDLCK; fl.l_whence = SEEK_SET; fl.l_start = 0; fl.l_len = 0; /* Whole file */ return fcntl(fd, F_SETLK, &fl); #elif defined(HAVE_FLOCK) && HAVE_DECL_LOCK_SH && HAVE_DECL_LOCK_EX return flock(fd, lock_write ? LOCK_EX|LOCK_NB : LOCK_SH|LOCK_NB); #else return 0; /* Hope & pray... */ #endif } /* * Receive packet with synchronous timeout; timeout is adjusted * to account for time spent waiting. */ static int recv_time(int s, void *rbuf, int len, unsigned int flags, unsigned long *timeout_us_p) { fd_set fdset; struct timeval tmv, t0, t1; int rv, err; unsigned long timeout_us = *timeout_us_p; unsigned long timeout_left, dt; gettimeofday(&t0, NULL); timeout_left = timeout_us; for (;;) { FD_ZERO(&fdset); FD_SET(s, &fdset); do { tmv.tv_sec = timeout_left / 1000000; tmv.tv_usec = timeout_left % 1000000; rv = select(s + 1, &fdset, NULL, NULL, &tmv); err = errno; gettimeofday(&t1, NULL); dt = (t1.tv_sec - t0.tv_sec) * 1000000 + (t1.tv_usec - t0.tv_usec); *timeout_us_p = timeout_left = (dt >= timeout_us) ? 1 : (timeout_us - dt); } while (rv == -1 && err == EINTR); if (rv == 0) { timer(0); /* Should not return */ return -1; } #ifdef MSG_DONTWAIT rv = recv(s, rbuf, len, flags | MSG_DONTWAIT); err = errno; #else set_socket_nonblock(s, 1); rv = recv(s, rbuf, len, flags); err = errno; set_socket_nonblock(s, 0); #endif if (rv < 0) { if (E_WOULD_BLOCK(err) || err == EINTR) { continue; /* Once again, with feeling... */ } else { errno = err; return rv; } } else { return rv; } } } static int split_port(char **ap, char **pp) { char *a, *p; int ret = AF_UNSPEC; a = *ap; #ifdef HAVE_IPV6 if (is_numeric_ipv6(a)) { if (*a++ != '[') return -1; *ap = a; p = strrchr(a, ']'); if (!p) return -1; *p++ = 0; a = p; ret = AF_INET6; p = strrchr(a, ':'); if (p) *p++ = 0; } else #endif { struct in_addr in; p = strrchr(a, ':'); if (p) *p++ = 0; if (inet_aton(a, &in)) ret = AF_INET; } *pp = p; return ret; } enum long_only_options { OPT_VERBOSITY = 256, OPT_STDERR, OPT_MAP_TEST, OPT_MAP_STEPS }; static struct option long_options[] = { { "ipv4", 0, NULL, '4' }, { "ipv6", 0, NULL, '6' }, { "create", 0, NULL, 'c' }, { "secure", 0, NULL, 's' }, { "permissive", 0, NULL, 'p' }, { "verbose", 0, NULL, 'v' }, { "verbosity", 1, NULL, OPT_VERBOSITY }, { "version", 0, NULL, 'V' }, { "listen", 0, NULL, 'l' }, { "foreground", 0, NULL, 'L' }, { "address", 1, NULL, 'a' }, { "blocksize", 1, NULL, 'B' }, { "user", 1, NULL, 'u' }, { "umask", 1, NULL, 'U' }, { "refuse", 1, NULL, 'r' }, { "timeout", 1, NULL, 't' }, { "retransmit", 1, NULL, 'T' }, { "port-range", 1, NULL, 'R' }, { "map-file", 1, NULL, 'm' }, { "map-steps", 1, NULL, OPT_MAP_STEPS }, { "pidfile", 1, NULL, 'P' }, { "stderr", 0, NULL, OPT_STDERR }, { "map-test", 1, NULL, OPT_MAP_TEST }, { NULL, 0, NULL, 0 } }; static const char short_options[] = "46cspvVlLa:B:u:U:r:t:T:R:m:P:"; int main(int argc, char **argv) { struct tftphdr *tp; struct passwd *pw; struct options *opt; union sock_addr myaddr; struct sockaddr_in bindaddr4; #ifdef HAVE_IPV6 struct sockaddr_in6 bindaddr6; int force_ipv6 = 0; #endif int n; int fd = -1; int fd4 = -1; int fd6 = -1; int fdmax = 0; int standalone = 0; /* Standalone (listen) mode */ int nodaemon = 0; /* Do not detach process */ char *address = NULL; /* Address to listen to */ pid_t pid; mode_t my_umask = 0; int spec_umask = 0; int c; int setrv; int die; int waittime = 900; /* Default time to wait for a connect */ const char *user = "nobody"; /* Default user */ char *p, *ep; int use_stderr = 0; const char *map_test_file = NULL; #ifdef WITH_REGEX char *rewrite_file = NULL; #endif const char *pidfile = NULL; u_short tp_opcode; #ifdef HAVE_LOCALE_H setlocale(LC_CTYPE, ""); /* For to(w)(lower|upper)() */ #endif /* basename() is way too much of a pain from a portability standpoint */ p = strrchr(argv[0], '/'); tftpd_progname = (p && p[1]) ? p + 1 : argv[0]; srand(time(NULL) ^ getpid()); while ((c = getopt_long(argc, argv, short_options, long_options, NULL)) != -1) switch (c) { case '4': ai_fam = AF_INET; break; #ifdef HAVE_IPV6 case '6': ai_fam = AF_INET6; force_ipv6 = 1; break; #endif case 'c': cancreate = 1; break; case 's': secure = 1; break; case 'p': unixperms = 1; break; case 'l': standalone = 1; break; case 'L': standalone = 1; nodaemon = 1; break; case 'a': address = optarg; break; case 't': waittime = atoi(optarg); break; case 'B': { char *vp; max_blksize = (unsigned int)strtoul(optarg, &vp, 10); if (max_blksize < 512 || max_blksize > MAX_SEGSIZE || *vp) { tftpd_log(LOG_ERR, "Bad maximum blocksize value (range 512-%d): %s", MAX_SEGSIZE, optarg); exit(EX_USAGE); } } break; case 'T': { char *vp; unsigned long tov = strtoul(optarg, &vp, 10); if (tov < 10000UL || tov > 255000000UL || *vp) { tftpd_log(LOG_ERR, "Bad timeout value: %s", optarg); exit(EX_USAGE); } rexmtval = timeout = tov; maxtimeout = rexmtval * TIMEOUT_LIMIT; } break; case 'R': { if (sscanf(optarg, "%u:%u", &portrange_from, &portrange_to) != 2 || portrange_from > portrange_to || portrange_to >= 65535) { tftpd_log(LOG_ERR, "Bad port range: %s", optarg); exit(EX_USAGE); } portrange = 1; } break; case 'u': user = optarg; break; case 'U': my_umask = strtoul(optarg, &ep, 8); if (*ep) { tftpd_log(LOG_ERR, "Invalid umask: %s", optarg); exit(EX_USAGE); } spec_umask = 1; break; case 'r': for (opt = options; opt->o_opt; opt++) { if (!strcasecmp(optarg, opt->o_opt)) { opt->o_opt = ""; /* Don't support this option */ break; } } if (!opt->o_opt) { tftpd_log(LOG_ERR, "Unknown option: %s", optarg); exit(EX_USAGE); } break; #ifdef WITH_REGEX case 'm': if (rewrite_file) { tftpd_log(LOG_ERR, "Multiple -m options"); exit(EX_USAGE); } rewrite_file = optarg; break; case OPT_MAP_STEPS: { unsigned long steps = strtoul(optarg, &ep, 0); if (*optarg && *ep && steps > 0 && steps <= INT_MAX) { deadman_max_steps = steps; } else { tftpd_log(LOG_ERR, "Bad --map-steps option: %s", optarg); exit(EX_USAGE); } break; } case OPT_MAP_TEST: map_test_file = optarg; use_stderr = 1; break; #endif case 'v': verbosity++; break; case OPT_VERBOSITY: verbosity = atoi(optarg); break; case OPT_STDERR: use_stderr = 1; break; case 'V': /* Print configuration to stdout and exit */ printf("%s\n", TFTPD_CONFIG_STR); exit(0); break; case 'P': pidfile = optarg; break; default: tftpd_log(LOG_ERR, "Unknown option: '%c'", optopt); break; } if (!use_stderr) tftpd_openlog(tftpd_progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); #ifdef WITH_REGEX if (rewrite_file) rewrite_rules = read_remap_rules(rewrite_file); if (map_test_file) { FILE *tf = fopen(map_test_file, "r"); if (!tf) { tftpd_log(LOG_ERR, "%s: cannot open map test file: %m", map_test_file); exit(EX_NOINPUT); } rewrite_test(tf); fclose(tf); exit(0); } #endif dirs = xmalloc((argc - optind + 1) * sizeof(char *)); for (ndirs = 0; optind != argc; optind++) dirs[ndirs++] = argv[optind]; dirs[ndirs] = NULL; if (secure) { if (ndirs == 0) { tftpd_log(LOG_ERR, "no -s directory"); exit(EX_USAGE); } if (ndirs > 1) { tftpd_log(LOG_ERR, "too many -s directories"); exit(EX_USAGE); } if (chdir(dirs[0])) { tftpd_log(LOG_ERR, "%s: %m", dirs[0]); exit(EX_NOINPUT); } } pw = getpwnam(user); if (!pw) { tftpd_log(LOG_ERR, "no user %s: %m", user); exit(EX_NOUSER); } if (pidfile && !standalone) { tftpd_log(LOG_WARNING, "not in standalone mode, ignoring pid file"); pidfile = NULL; } /* If we're running standalone, set up the input port */ if (standalone) { FILE *pf; #ifdef HAVE_IPV6 if (ai_fam != AF_INET6) { #endif fd4 = socket(AF_INET, SOCK_DGRAM, 0); if (fd4 < 0) { tftpd_log(LOG_ERR, "cannot open IPv4 socket: %m"); exit(EX_OSERR); } tftpd_config_socket(fd4, 0); memset(&bindaddr4, 0, sizeof bindaddr4); bindaddr4.sin_family = AF_INET; bindaddr4.sin_addr.s_addr = INADDR_ANY; bindaddr4.sin_port = htons(IPPORT_TFTP); #ifdef HAVE_IPV6 } if (ai_fam != AF_INET) { fd6 = socket(AF_INET6, SOCK_DGRAM, 0); if (fd6 < 0) { if (fd4 < 0) { tftpd_log(LOG_ERR, "cannot open IPv6 socket: %m"); exit(EX_OSERR); } else { tftpd_log(LOG_ERR, "cannot open IPv6 socket, disable IPv6: %m"); } } tftpd_config_socket(fd6, 0); memset(&bindaddr6, 0, sizeof bindaddr6); bindaddr6.sin6_family = AF_INET6; bindaddr6.sin6_port = htons(IPPORT_TFTP); } #endif if (address) { char *portptr = NULL, *eportptr; int err; struct servent *servent; unsigned long port; address = tfstrdup(address); err = split_port(&address, &portptr); switch (err) { case AF_INET: #ifdef HAVE_IPV6 if (fd6 >= 0) { close(fd6); fd6 = -1; if (ai_fam == AF_INET6) { tftpd_log(LOG_ERR, "Address %s is not in address family AF_INET6", address); exit(EX_USAGE); } ai_fam = AF_INET; } break; case AF_INET6: if (fd4 >= 0) { close(fd4); fd4 = -1; if (ai_fam == AF_INET) { tftpd_log(LOG_ERR, "Address %s is not in address family AF_INET", address); exit(EX_USAGE); } ai_fam = AF_INET6; } break; #endif case AF_UNSPEC: break; default: tftpd_log(LOG_ERR, "Numeric IPv6 addresses need to be enclosed in []"); exit(EX_USAGE); } if (!portptr) portptr = (char *)"tftp"; if (*address) { if (fd4 >= 0) { bindaddr4.sin_family = AF_INET; err = set_sock_addr(address, (union sock_addr *)&bindaddr4, NULL); if (err) { tftpd_log(LOG_ERR, "cannot resolve local IPv4 bind address: %s, %s", address, gai_strerror(err)); exit(EX_NOINPUT); } } #ifdef HAVE_IPV6 if (fd6 >= 0) { bindaddr6.sin6_family = AF_INET6; err = set_sock_addr(address, (union sock_addr *)&bindaddr6, NULL); if (err) { if (fd4 >= 0) { tftpd_log(LOG_ERR, "cannot resolve local IPv6 bind address: %s" "(%s); using IPv4 only", address, gai_strerror(err)); close(fd6); fd6 = -1; } else { tftpd_log(LOG_ERR, "cannot resolve local IPv6 bind address: %s" "(%s)", address, gai_strerror(err)); exit(EX_NOINPUT); } } } #endif } else { /* Default to using INADDR_ANY */ } if (portptr && *portptr) { servent = getservbyname(portptr, "udp"); if (servent) { if (fd4 >= 0) bindaddr4.sin_port = servent->s_port; #ifdef HAVE_IPV6 if (fd6 >= 0) bindaddr6.sin6_port = servent->s_port; #endif } else if ((port = strtoul(portptr, &eportptr, 0)) && !*eportptr) { if (fd4 >= 0) bindaddr4.sin_port = htons(port); #ifdef HAVE_IPV6 if (fd6 >= 0) bindaddr6.sin6_port = htons(port); #endif } else if (!strcmp(portptr, "tftp")) { /* It's TFTP, we're OK */ } else { tftpd_log(LOG_ERR, "cannot resolve local bind port: %s", portptr); exit(EX_NOINPUT); } } } if (fd4 >= 0) { if (bind(fd4, (struct sockaddr *)&bindaddr4, sizeof(bindaddr4)) < 0) { tftpd_log(LOG_ERR, "cannot bind to local IPv4 socket: %m"); exit(EX_OSERR); } } #ifdef HAVE_IPV6 if (fd6 >= 0) { #if defined(IPV6_V6ONLY) int on = 1; if (fd4 >= 0 || force_ipv6) if (setsockopt(fd6, IPPROTO_IPV6, IPV6_V6ONLY, (char*)&on, sizeof(on))) tftpd_log(LOG_ERR, "cannot setsockopt IPV6_V6ONLY %m"); #endif if (bind(fd6, (struct sockaddr *)&bindaddr6, sizeof(bindaddr6)) < 0) { if (fd4 >= 0) { tftpd_log(LOG_ERR, "cannot bind to local IPv6 socket," "IPv6 disabled: %m"); close(fd6); fd6 = -1; } else { tftpd_log(LOG_ERR, "cannot bind to local IPv6 socket: %m"); exit(EX_OSERR); } } } #endif /* Daemonize this process */ /* Note: when running in secure mode (-s), we must not chdir, since we are already in the proper directory. */ if (!nodaemon && daemon(secure, 0) < 0) { tftpd_log(LOG_ERR, "cannot daemonize: %m"); exit(EX_OSERR); } set_signal(SIGTERM, handle_exit, 0); set_signal(SIGINT, handle_exit, 0); if (pidfile) { pf = fopen (pidfile, "w"); if (!pf) { tftpd_log(LOG_ERR, "cannot open pid file '%s' for writing: %m", pidfile); pidfile = NULL; } else { if (fprintf(pf, "%d\n", getpid()) < 0) tftpd_log(LOG_ERR, "error writing pid file '%s': %m", pidfile); if (fclose(pf)) tftpd_log(LOG_ERR, "error closing pid file '%s': %m", pidfile); } } if (fd6 > fd4) fdmax = fd6; else fdmax = fd4; } else { /* 0 is our socket descriptor */ close(1); close(2); fd = 0; fdmax = 0; tftpd_config_socket(fd, 0); } /* This means we don't want to wait() for children */ #ifdef SA_NOCLDWAIT set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP | SA_NOCLDWAIT); #else set_signal(SIGCHLD, SIG_IGN, SA_NOCLDSTOP); #endif /* Take SIGHUP and use it to set a variable. This is polled synchronously to make sure we don't lose packets as a result. */ set_signal(SIGHUP, handle_sighup, 0); if (spec_umask || !unixperms) umask(my_umask); while (1) { fd_set readset; struct timeval tv_waittime; int rv; if (exit_signal) { /* happens in standalone mode only */ if (pidfile && unlink(pidfile)) { tftpd_log(LOG_WARNING, "error removing pid file '%s': %m", pidfile); exit(EX_OSERR); } else { exit(0); } } if (caught_sighup) { caught_sighup = 0; if (standalone) { #ifdef WITH_REGEX if (rewrite_file) { freerules(rewrite_rules); rewrite_rules = read_remap_rules(rewrite_file); } #endif } else { /* Return to inetd for respawn */ exit(0); } } FD_ZERO(&readset); if (standalone) { if (fd4 >= 0) { FD_SET(fd4, &readset); cygwin_set_socket_nonblock(fd4, 0); } if (fd6 >= 0) { FD_SET(fd6, &readset); cygwin_set_socket_nonblock(fd6, 0); } } else { /* fd always 0 */ fd = 0; FD_SET(fd, &readset); cygwin_set_socket_nonblock(fd, 0); } tv_waittime.tv_sec = waittime; tv_waittime.tv_usec = 0; /* Never time out if we're in standalone mode */ rv = select(fdmax + 1, &readset, NULL, NULL, standalone ? NULL : &tv_waittime); if (rv == -1 && errno == EINTR) continue; /* Signal caught, reloop */ if (rv == -1) { tftpd_log(LOG_ERR, "select loop: %m"); exit(EX_IOERR); } else if (rv == 0) { exit(0); /* Timeout, return to inetd */ } if (standalone) { if ((fd4 >= 0) && FD_ISSET(fd4, &readset)) fd = fd4; else if ((fd6 >= 0) && FD_ISSET(fd6, &readset)) fd = fd6; else /* not in set ??? */ continue; } cygwin_set_socket_nonblock(fd, 1); n = myrecvfrom(fd, buf, sizeof(buf), 0, &from, &myaddr); if (n < 0) { if (E_WOULD_BLOCK(errno) || errno == EINTR) { continue; /* Again, from the top */ } else { tftpd_log(LOG_ERR, "recvfrom: %m"); exit(EX_IOERR); } } #ifdef HAVE_IPV6 if ((from.sa.sa_family != AF_INET) && (from.sa.sa_family != AF_INET6)) { tftpd_log(LOG_ERR, "received address was not AF_INET/AF_INET6," " please check your inetd config"); #else if (from.sa.sa_family != AF_INET) { tftpd_log(LOG_ERR, "received address was not AF_INET," " please check your inetd config"); #endif exit(EX_PROTOCOL); } if (standalone) { if ((from.sa.sa_family == AF_INET) && (myaddr.si.sin_addr.s_addr == INADDR_ANY)) { /* myrecvfrom() didn't capture the source address; but we might have bound to a specific address, if so we should use it */ memcpy(SOCKADDR_P(&myaddr), &bindaddr4.sin_addr, sizeof(bindaddr4.sin_addr)); #ifdef HAVE_IPV6 } else if ((from.sa.sa_family == AF_INET6) && IN6_IS_ADDR_UNSPECIFIED((struct in6_addr *) SOCKADDR_P(&myaddr))) { memcpy(SOCKADDR_P(&myaddr), &bindaddr6.sin6_addr, sizeof(bindaddr6.sin6_addr)); #endif } } /* * Now that we have read the request packet from the UDP * socket, we fork and go back to listening to the socket. */ pid = fork(); if (pid < 0) { tftpd_log(LOG_ERR, "fork: %m"); exit(EX_OSERR); /* Return to inetd, just in case */ } else if (pid == 0) break; /* Child exit, parent loop */ } /* Child process: handle the actual request here */ /* Ignore SIGHUP */ set_signal(SIGHUP, SIG_IGN, 0); /* Make sure the log socket is still connected. This has to be done before the chroot, while /dev/log is still accessible. When not running standalone, there is little chance that the tftpd_log daemon gets restarted by the time we get here. */ if (secure && standalone) { closelog(); openlog(tftpd_progname, LOG_PID | LOG_NDELAY, LOG_DAEMON); } #ifdef HAVE_TCPWRAPPERS /* Verify if this was a legal request for us. This has to be done before the chroot, while /etc is still accessible. */ request_init(&wrap_request, RQ_DAEMON, tftpd_progname, RQ_FILE, fd, RQ_CLIENT_SIN, &from, RQ_SERVER_SIN, &myaddr, 0); sock_methods(&wrap_request); tmp_p = (char *)inet_ntop(myaddr.sa.sa_family, SOCKADDR_P(&myaddr), tmpbuf, INET6_ADDRSTRLEN); if (!tmp_p) { tmp_p = tmpbuf; strcpy(tmpbuf, "???"); } if (hosts_access(&wrap_request) == 0) { if (deny_severity != -1) tftpd_log(deny_severity, "connection refused from %s", tmp_p); exit(EX_NOPERM); /* Access denied */ } else if (allow_severity != -1) { tftpd_log(allow_severity, "connect from %s", tmp_p); } #endif /* Close file descriptors we don't need */ close(fd); /* Get a socket. This has to be done before the chroot(), since some systems require access to /dev to create a socket. */ peer = socket(myaddr.sa.sa_family, SOCK_DGRAM, 0); if (peer < 0) { tftpd_log(LOG_ERR, "socket: %m"); exit(EX_IOERR); } /* Set up the supplementary group access list if possible /etc/group still need to be accessible at this point. If we get EPERM, this is already a restricted process, e.g. using user namespaces on Linux. */ die = 0; #ifdef HAVE_SETGROUPS setrv = setgroups(0, NULL); if (setrv && errno != EPERM) { tftpd_log(LOG_ERR, "cannot clear group list"); die = EX_OSERR; } #endif #ifdef HAVE_INITGROUPS setrv = initgroups(user, pw->pw_gid); if (!setrv) { die = 0; } else if (errno != EPERM) { tftpd_log(LOG_ERR, "cannot set groups for user %s", user); die = EX_OSERR; } #endif if (die) exit(die); /* Chroot and drop privileges */ if (secure) { if (chroot(".")) { tftpd_log(LOG_ERR, "chroot: %m"); exit(EX_OSERR); } #ifdef __CYGWIN__ chdir("/"); /* Cygwin chroot() bug workaround */ #endif } #ifdef HAVE_SETRESGID setrv = setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid); #elif defined(HAVE_SETREGID) setrv = setregid(pw->pw_gid, pw->pw_gid); #else setrv = setegid(pw->pw_gid) || setgid(pw->pw_gid); #endif if (setrv && errno == EPERM) { setrv = 0; /* Assume already restricted by system policy */ } #ifdef HAVE_SETRESUID setrv = setrv || setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid); #elif defined(HAVE_SETREUID) setrv = setrv || setreuid(pw->pw_uid, pw->pw_uid); #else /* Important: setuid() must come first */ setrv = setrv || setuid(pw->pw_uid) || (geteuid() != pw->pw_uid && seteuid(pw->pw_uid)); #endif if (setrv && errno == EPERM) { setrv = 0; /* Assume already restricted by system policy */ } if (setrv) { tftpd_log(LOG_ERR, "cannot drop privileges: %m"); exit(EX_OSERR); } /* Process the request... */ if (pick_port_bind(peer, &myaddr, portrange_from, portrange_to) < 0) { tftpd_log(LOG_ERR, "bind: %m"); exit(EX_IOERR); } if (connect(peer, &from.sa, SOCKLEN(&from)) < 0) { tftpd_log(LOG_ERR, "connect: %m"); exit(EX_IOERR); } tftpd_config_socket(peer, 1); tp = (struct tftphdr *)buf; tp_opcode = ntohs(tp->th_opcode); if (tp_opcode == RRQ || tp_opcode == WRQ) tftp(tp, n); exit(0); } static char *rewrite_access(const struct formats *, char *, int, int, const char **); static int validate_access(char *, int, const struct formats *, const char **); static void tftp_sendfile(const struct formats *, struct tftphdr *, int); static void tftp_recvfile(const struct formats *, struct tftphdr *, int); static const struct formats formats[] = { { "netascii", rewrite_access, validate_access, tftp_sendfile, tftp_recvfile, 1}, { "octet", rewrite_access, validate_access, tftp_sendfile, tftp_recvfile, 0}, { NULL, NULL, NULL, NULL, NULL, 0} }; /* * Handle initial connection protocol. */ int tftp(struct tftphdr *tp, int size) { char *cp, *end; int argn, ecode; const struct formats *pf = NULL; char *origfilename; char *filename, *mode = NULL; const char *errmsgptr; u_short tp_opcode = ntohs(tp->th_opcode); char *val = NULL, *opt = NULL; char *ap = ackbuf + 2; ((struct tftphdr *)ackbuf)->th_opcode = htons(OACK); origfilename = cp = (char *)&(tp->th_stuff); argn = 0; end = (char *)tp + size; while (cp < end && *cp) { do { cp++; } while (cp < end && *cp); if (*cp) { nak(EBADOP, "Request not null-terminated"); exit(0); } argn++; if (argn == 1) { mode = ++cp; } else if (argn == 2) { for (cp = mode; *cp; cp++) *cp = tolower(*cp); for (pf = formats; pf->f_mode; pf++) { if (!strcmp(pf->f_mode, mode)) break; } if (!pf->f_mode) { nak(EBADOP, "Unknown mode"); exit(0); } file = NULL; if (!(filename = (*pf->f_rewrite) (pf, origfilename, tp_opcode, from.sa.sa_family, &errmsgptr))) { nak(EACCESS, errmsgptr); /* File denied by mapping rule */ exit(0); } if (verbosity >= 1) { tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from), tmpbuf, INET6_ADDRSTRLEN); if (!tmp_p) { tmp_p = tmpbuf; strcpy(tmpbuf, "???"); } if (filename == origfilename || !strcmp(filename, origfilename)) tftpd_log(LOG_NOTICE, "%s from %s filename %s\n", tp_opcode == WRQ ? "WRQ" : "RRQ", tmp_p, filename); else tftpd_log(LOG_NOTICE, "%s from %s filename %s remapped to %s\n", tp_opcode == WRQ ? "WRQ" : "RRQ", tmp_p, origfilename, filename); } /* * If "file" is already set, then a file was already validated * and opened during remap processing. */ if (!file) { ecode = (*pf->f_validate) (filename, tp_opcode, pf, &errmsgptr); if (ecode) { nak(ecode, errmsgptr); exit(0); } } opt = ++cp; } else if (argn & 1) { val = ++cp; } else { do_opt(opt, val, &ap); opt = ++cp; } } if (!pf) { nak(EBADOP, "Missing mode"); exit(0); } if (ap != (ackbuf + 2)) { if (tp_opcode == WRQ) (*pf->f_recv) (pf, (struct tftphdr *)ackbuf, ap - ackbuf); else (*pf->f_send) (pf, (struct tftphdr *)ackbuf, ap - ackbuf); } else { if (tp_opcode == WRQ) (*pf->f_recv) (pf, NULL, 0); else (*pf->f_send) (pf, NULL, 0); } exit(0); /* Request completed */ } static int blksize_set; /* * Set a non-standard block size (c.f. RFC2348) */ static int set_blksize(uintmax_t *vp) { uintmax_t sz = *vp; if (blksize_set) return 0; if (sz < 8) return 0; else if (sz > max_blksize) sz = max_blksize; *vp = segsize = sz; blksize_set = 1; return 1; } /* * Set a power-of-two block size (nonstandard) */ static int set_blksize2(uintmax_t *vp) { uintmax_t sz = *vp; if (blksize_set) return 0; if (sz < 8) return (0); else if (sz > max_blksize) sz = max_blksize; else /* Convert to a power of two */ if (sz & (sz - 1)) { unsigned int sz1 = 1; /* Not a power of two - need to convert */ while (sz >>= 1) sz1 <<= 1; sz = sz1; } *vp = segsize = sz; blksize_set = 1; return 1; } /* * Set the block number rollover value */ static int set_rollover(uintmax_t *vp) { uintmax_t ro = *vp; if (ro > 65535) return 0; rollover_val = (uint16_t)ro; return 1; } /* * Return a file size (c.f. RFC2349) * For netascii mode, we don't know the size ahead of time; * so reject the option. */ static int set_tsize(uintmax_t *vp) { uintmax_t sz = *vp; if (!tsize_ok) return 0; if (sz == 0) sz = tsize; *vp = sz; return 1; } /* * Set the timeout (c.f. RFC2349). This is supposed * to be the (default) retransmission timeout, but being an * integer in seconds it seems a bit limited. */ static int set_timeout(uintmax_t *vp) { uintmax_t to = *vp; if (to < 1 || to > 255) return 0; rexmtval = timeout = to * 1000000UL; maxtimeout = rexmtval * TIMEOUT_LIMIT; return 1; } /* Similar, but in microseconds. We allow down to 10 ms. */ static int set_utimeout(uintmax_t *vp) { uintmax_t to = *vp; if (to < 10000UL || to > 255000000UL) return 0; rexmtval = timeout = to; maxtimeout = rexmtval * TIMEOUT_LIMIT; return 1; } /* * Conservative calculation for the size of a buffer which can hold an * arbitrary integer */ #define OPTBUFSIZE (sizeof(uintmax_t) * CHAR_BIT / 3 + 3) /* * Parse RFC2347 style options; we limit the arguments to positive * integers which matches all our current options. */ static void do_opt(const char *opt, const char *val, char **ap) { struct options *po; char retbuf[OPTBUFSIZE]; char *p = *ap; size_t optlen, retlen; char *vend; uintmax_t v; /* Global option-parsing variables initialization */ blksize_set = 0; if (!*opt || !*val) return; errno = 0; v = strtoumax(val, &vend, 10); if (*vend || errno == ERANGE) return; for (po = options; po->o_opt; po++) if (!strcasecmp(po->o_opt, opt)) { if (po->o_fnc(&v)) { optlen = strlen(opt); retlen = sprintf(retbuf, "%"PRIuMAX, v); if (p + optlen + retlen + 2 >= ackbuf + sizeof(ackbuf)) { nak(EOPTNEG, "Insufficient space for options"); exit(0); } memcpy(p, opt, optlen+1); p += optlen+1; memcpy(p, retbuf, retlen+1); p += retlen+1; } else { nak(EOPTNEG, "Unsupported option(s) requested"); exit(0); } break; } *ap = p; } #ifdef WITH_REGEX /* * This is called by the remap engine when it encounters macros such * as \i. It should put the output in a static buffer and put the * buffer address in *output, then return the length of the output * not including the terminal null. * * Return (size_t)-1 for an invalid macro, which then will be handled * by the substitution code. */ static char hexchar(unsigned char c) { return c >= 10 ? (c + 'A' - 10) : c + '0'; } static size_t rewrite_macros(char macro, char **output) { #ifdef INET6_ADDRSTRLEN static char obuf[INET_ADDRSTRLEN > 64 ? INET_ADDRSTRLEN : 64]; #else static char obuf[64]; #endif const unsigned char *cp; size_t bytes; *output = obuf; switch (from.sa.sa_family) { case AF_INET: cp = (const unsigned char *)&from.si.sin_addr; bytes = 4; break; #ifdef HAVE_IPV6 case AF_INET6: cp = (const unsigned char *)&from.s6.sin6_addr; bytes = 16; break; #endif default: return -1; /* Unknown address family... */ } switch (macro) { case 'i': { const char *p = inet_ntop(from.sa.sa_family, SOCKADDR_P(&from), obuf, sizeof obuf); return p ? strlen(p) : 0; } case 'x': { char *p = obuf; while (bytes--) { unsigned char c = *cp++; *p++ = hexchar(c >> 4); *p++ = hexchar(c & 15); } return bytes << 1; } default: return -1; /* No such macro */ } } /* * Modify the filename, if applicable. If it returns NULL, deny the access. */ static char *rewrite_access(const struct formats *pf, char *filename, int mode, int af, const char **msg) { if (rewrite_rules) { char *newname = rewrite_string(pf, filename, rewrite_rules, mode, af, rewrite_macros, msg); filename = newname; } return filename; } static int test_validate_fail(char *filename, int mode, const struct formats *pf, const char **errmsg) { (void)filename; (void)mode; (void)pf; if (errmsg) *errmsg = "Just testing..."; return EACCESS; } static void rewrite_test(FILE *tf) { static const struct formats test_dummy_format = { "dummy", NULL, test_validate_fail, NULL, NULL, 0 }; /* Dummy addresses from netblocks assigned for documentation */ static const char phony_ip6_addr[16] = { 0x20, 0x01, 0x0d, 0xb8, 0x00, 0x00, 0x00, 0x00, 0xfe, 0xed, 0xfa, 0xce, 0xde, 0xad, 0xbe, 0xef }; static const char phony_ip4_addr[4] = { 192, 0, 2, 34 }; int mode = cancreate ? WRQ : RRQ; int af = ai_fam; memset(&from, 0, sizeof from); switch (af) { #if HAVE_IPV6 case AF_INET6: memcpy(&from.s6.sin6_addr, phony_ip6_addr, 16); break; #endif default: af = AF_INET; memcpy(&from.si.sin_addr, phony_ip4_addr, 4); break; } from.sa.sa_family = af; while (fgets(buf, MAX_SEGSIZE+1, tf)) { const char *msg; char *out; char *nl = strchr(buf, '\n'); if (!nl) continue; *nl = '\0'; out = rewrite_string(&test_dummy_format, buf, rewrite_rules, mode, af, rewrite_macros, &msg); if (out) { printf("%s\n", out); if (out != buf) tffree(out); } else { printf("ERROR: %s\n", msg); } } } #else static char *rewrite_access(const struct formats *pf, char *filename, int mode, int af, const char **msg) { (void)pf; (void)mode; /* Avoid warning */ (void)msg; (void)af; return filename; } #endif /* * Validate file access. Since we * have no uid or gid, for now require * file to exist and be publicly * readable/writable, unless -p specified. * If we were invoked with arguments * from inetd then the file must also be * in one of the given directory prefixes. * Note also, full path name must be * given as we have no login directory. */ static int validate_access(char *filename, int mode, const struct formats *pf, const char **errmsg) { struct stat stbuf; int i, len; int fd, wmode, rmode; char *cp; const char **dirp; char stdio_mode[3]; tsize_ok = 0; *errmsg = NULL; if (!secure) { if (*filename != '/') { *errmsg = "Only absolute filenames allowed"; return (EACCESS); } /* * prevent tricksters from getting around the directory * restrictions */ len = strlen(filename); for (i = 1; i < len - 3; i++) { cp = filename + i; if (*cp == '.' && memcmp(cp - 1, "/../", 4) == 0) { *errmsg = "Reverse path not allowed"; return (EACCESS); } } for (dirp = dirs; *dirp; dirp++) if (strncmp(filename, *dirp, strlen(*dirp)) == 0) break; if (*dirp == 0 && dirp != dirs) { *errmsg = "Forbidden directory"; return (EACCESS); } } /* * We use different a different permissions scheme if `cancreate' is * set. */ wmode = O_WRONLY | (cancreate ? O_CREAT : 0) | (pf->f_convert ? O_TEXT : O_BINARY); rmode = O_RDONLY | (pf->f_convert ? O_TEXT : O_BINARY); #ifndef HAVE_FTRUNCATE wmode |= O_TRUNC; /* This really sucks on a dupe */ #endif fd = open(filename, mode == RRQ ? rmode : wmode, 0666); if (fd < 0) return -errno; if (fstat(fd, &stbuf) < 0) exit(EX_OSERR); /* This shouldn't happen */ /* A duplicate RRQ or (worse!) WRQ packet could really cause havoc... */ if (lock_file(fd, mode != RRQ)) exit(0); if (mode == RRQ) { if (!unixperms && (stbuf.st_mode & (S_IREAD >> 6)) == 0) { *errmsg = "File must have global read permissions"; return (EACCESS); } tsize = stbuf.st_size; /* We don't know the tsize if conversion is needed */ tsize_ok = !pf->f_convert; } else { if (!unixperms) { if ((stbuf.st_mode & (S_IWRITE >> 6)) == 0) { *errmsg = "File must have global write permissions"; return (EACCESS); } } #ifdef HAVE_FTRUNCATE /* We didn't get to truncate the file at open() time */ if (ftruncate(fd, (off_t) 0)) { *errmsg = "Cannot reset file size"; return (EACCESS); } #endif tsize = 0; tsize_ok = 1; } stdio_mode[0] = (mode == RRQ) ? 'r' : 'w'; stdio_mode[1] = (pf->f_convert) ? 't' : 'b'; stdio_mode[2] = '\0'; file = fdopen(fd, stdio_mode); if (file == NULL) exit(EX_OSERR); /* Internal error */ return (0); } /* * Send the requested file. */ static void tftp_sendfile(const struct formats *pf, struct tftphdr *oap, int oacklen) { struct tftphdr *dp; struct tftphdr *ap; /* ack packet */ static u_short block = 1; /* Static to avoid longjmp funnies */ u_short ap_opcode, ap_block; unsigned long r_timeout; int size, n; if (oap) { timeout = rexmtval; (void)sigsetjmp(timeoutbuf, 1); oack: r_timeout = timeout; if (send(peer, oap, oacklen, 0) != oacklen) { tftpd_log(LOG_WARNING, "tftpd: oack: %m\n"); goto abort; } for (;;) { n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout); if (n < 0) { tftpd_log(LOG_WARNING, "tftpd: read: %m\n"); goto abort; } ap = (struct tftphdr *)ackbuf; ap_opcode = ntohs((u_short) ap->th_opcode); ap_block = ntohs((u_short) ap->th_block); if (ap_opcode == ERROR) { tftpd_log(LOG_WARNING, "tftp: client does not accept options\n"); goto abort; } if (ap_opcode == ACK) { if (ap_block == 0) break; /* Resynchronize with the other side */ (void)synchnet(peer); goto oack; } } } dp = r_init(); do { size = readit(file, &dp, pf->f_convert); if (size < 0) { nak(-errno, NULL); goto abort; } dp->th_opcode = htons((u_short) DATA); dp->th_block = htons((u_short) block); timeout = rexmtval; (void)sigsetjmp(timeoutbuf, 1); r_timeout = timeout; if (send(peer, dp, size + 4, 0) != size + 4) { tftpd_log(LOG_WARNING, "tftpd: write: %m"); goto abort; } read_ahead(file, pf->f_convert); for (;;) { n = recv_time(peer, ackbuf, sizeof(ackbuf), 0, &r_timeout); if (n < 0) { tftpd_log(LOG_WARNING, "tftpd: read(ack): %m"); goto abort; } ap = (struct tftphdr *)ackbuf; ap_opcode = ntohs((u_short) ap->th_opcode); ap_block = ntohs((u_short) ap->th_block); if (ap_opcode == ERROR) goto abort; if (ap_opcode == ACK) { if (ap_block == block) { break; } /* Re-synchronize with the other side */ (void)synchnet(peer); /* * RFC1129/RFC1350: We MUST NOT re-send the DATA * packet in response to an invalid ACK. Doing so * would cause the Sorcerer's Apprentice bug. */ } } if (!++block) block = rollover_val; } while (size == segsize); abort: (void)fclose(file); } /* * Receive a file. */ static void tftp_recvfile(const struct formats *pf, struct tftphdr *oack, int oacklen) { struct tftphdr *dp; int n, size; /* These are "static" to avoid longjmp funnies */ static struct tftphdr *oap; static struct tftphdr *ap; /* ack buffer */ static u_short block = 0; static int acksize; u_short dp_opcode, dp_block; unsigned long r_timeout; oap = oack; dp = w_init(); do { timeout = rexmtval; if (!block && oap) { ap = (struct tftphdr *)ackbuf; acksize = oacklen; } else { ap = (struct tftphdr *)ackbuf; ap->th_opcode = htons((u_short) ACK); ap->th_block = htons((u_short) block); acksize = 4; /* If we're sending a regular ACK, that means we have successfully * sent the OACK. Clear oap so that we won't try to send another * OACK when the block number wraps back to 0. */ oap = NULL; } if (!++block) block = rollover_val; (void)sigsetjmp(timeoutbuf, 1); send_ack: r_timeout = timeout; if (send(peer, ackbuf, acksize, 0) != acksize) { tftpd_log(LOG_WARNING, "tftpd: write(ack): %m"); goto abort; } write_behind(file, pf->f_convert); for (;;) { n = recv_time(peer, dp, PKTSIZE, 0, &r_timeout); if (n < 0) { /* really? */ tftpd_log(LOG_WARNING, "tftpd: read: %m"); goto abort; } dp_opcode = ntohs((u_short) dp->th_opcode); dp_block = ntohs((u_short) dp->th_block); if (dp_opcode == ERROR) goto abort; if (dp_opcode == DATA) { if (dp_block == block) { break; /* normal */ } /* Re-synchronize with the other side */ (void)synchnet(peer); if (dp_block == (block - 1)) goto send_ack; /* rexmit */ } } /* size = write(file, dp->th_data, n - 4); */ size = writeit(file, &dp, n - 4, pf->f_convert); if (size != (n - 4)) { /* ahem */ if (size < 0) nak(-errno, NULL); else nak(ENOSPACE, NULL); goto abort; } } while (size == segsize); write_behind(file, pf->f_convert); (void)fclose(file); /* close data file */ ap->th_opcode = htons((u_short) ACK); /* send the "final" ack */ ap->th_block = htons((u_short) (block)); (void)send(peer, ackbuf, 4, 0); timeout_quit = 1; /* just quit on timeout */ n = recv_time(peer, buf, sizeof(buf), 0, &timeout); /* normally times out and quits */ timeout_quit = 0; if (n >= 4 && /* if read some data */ dp_opcode == DATA && /* and got a data block */ block == dp_block) { /* then my last ack was lost */ (void)send(peer, ackbuf, 4, 0); /* resend final ack */ } abort: return; } static const char *const errmsgs[] = { "Undefined error code", /* 0 - EUNDEF */ "File not found", /* 1 - ENOTFOUND */ "Access denied", /* 2 - EACCESS */ "Disk full or allocation exceeded", /* 3 - ENOSPACE */ "Illegal TFTP operation", /* 4 - EBADOP */ "Unknown transfer ID", /* 5 - EBADID */ "File already exists", /* 6 - EEXISTS */ "No such user", /* 7 - ENOUSER */ "Failure to negotiate RFC2347 options" /* 8 - EOPTNEG */ }; #define ERR_CNT (sizeof(errmsgs)/sizeof(const char *)) /* * Send a nak packet (error message). * Error code passed in is one of the * standard TFTP codes, or a negative * errno. */ static void nak(int error, const char *msg) { struct tftphdr *tp; int length; switch (error) { case -ENOENT: case -ENOTDIR: case -EPERM: error = ENOTFOUND; break; case -ENOSPC: error = ENOSPACE; break; case -EEXIST: error = EEXISTS; break; default: break; } if ((unsigned)error >= ERR_CNT) { error = EUNDEF; if (!msg && error < 0) msg = strerror(-error); } else if (!msg) { msg = errmsgs[error]; } if (!msg) msg = "Request failed"; tp = (struct tftphdr *)buf; tp->th_code = htons((u_short) error); length = strlen(msg) + 1; memcpy(tp->th_msg, msg, length); length += 4; /* Add space for header */ if (verbosity >= 2) { tmp_p = (char *)inet_ntop(from.sa.sa_family, SOCKADDR_P(&from), tmpbuf, INET6_ADDRSTRLEN); if (!tmp_p) { tmp_p = tmpbuf; strcpy(tmpbuf, "???"); } tftpd_log(LOG_INFO, "sending NAK (%d, %s) to %s", error, tp->th_msg, tmp_p); } if (send(peer, buf, length, 0) != length) tftpd_log(LOG_WARNING, "nak: %m"); } tftp-hpa-5.3+20251209/tftpd/tftpd.h000066400000000000000000000022301511036464300164170ustar00rootroot00000000000000/* ----------------------------------------------------------------------- * * * Copyright 2001-2025 H. Peter Anvin - All Rights Reserved * * This program is free software available under the same license * as the "OpenBSD" operating system, distributed at * http://www.openbsd.org/. * * ----------------------------------------------------------------------- */ /* * tftpd.h * * Prototypes for various functions that are part of the tftpd server. */ #ifndef TFTPD_TFTPD_H #define TFTPD_TFTPD_H #include "config.h" #include typedef void (*log_func)(int, const char *, ...); extern log_func tftpd_log; void set_signal(int, void (*)(int), int); void *tfmalloc(size_t); char *tfstrdup(const char *); void *tfrealloc(void *, size_t); void tffree(void *); extern int verbosity; struct formats { const char *f_mode; char *(*f_rewrite) (const struct formats *, char *, int, int, const char **); int (*f_validate) (char *, int, const struct formats *, const char **); void (*f_send) (const struct formats *, struct tftphdr *, int); void (*f_recv) (const struct formats *, struct tftphdr *, int); int f_convert; }; #endif tftp-hpa-5.3+20251209/version000066400000000000000000000000041511036464300154110ustar00rootroot000000000000005.3