├── .gitignore ├── BUGS ├── Changelog ├── FAQ ├── INSTALL ├── LICENSE ├── Makefile.am ├── README ├── README.CVS ├── README.MCAST ├── README.PCRE ├── TODO ├── argz.c ├── argz.h ├── atftp.1 ├── atftpd.8 ├── autogen.sh ├── configure.ac ├── debian ├── atftp.docs ├── atftp.files ├── atftpd.README.Debian ├── atftpd.conffiles ├── atftpd.config ├── atftpd.docs ├── atftpd.files ├── atftpd.init.d ├── atftpd.postinst ├── atftpd.postrm ├── atftpd.prerm ├── atftpd.templates ├── changelog ├── control ├── copyright ├── po │ ├── POTFILES.in │ ├── ca.po │ ├── cs.po │ ├── da.po │ ├── de.po │ ├── es.po │ ├── fi.po │ ├── fr.po │ ├── gl.po │ ├── it.po │ ├── ja.po │ ├── nl.po │ ├── pl.po │ ├── pt.po │ ├── pt_BR.po │ ├── ru.po │ ├── sk.po │ ├── sv.po │ ├── templates.pot │ └── vi.po ├── rules └── watch.old ├── docs └── pxespec.txt ├── logger.c ├── logger.h ├── options.c ├── options.h ├── redhat ├── README └── atftp.spec.in ├── stats.c ├── stats.h ├── test ├── Makefile.am ├── load.sh ├── mtftp.conf ├── pcre_pattern.txt ├── test.sh └── test_suite.txt ├── tftp.c ├── tftp.h ├── tftp_def.c ├── tftp_def.h ├── tftp_file.c ├── tftp_io.c ├── tftp_io.h ├── tftp_mtftp.c ├── tftpd.c ├── tftpd.h ├── tftpd_file.c ├── tftpd_list.c ├── tftpd_mcast.c ├── tftpd_mtftp.c ├── tftpd_mtftp.h ├── tftpd_pcre.c └── tftpd_pcre.h /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.tar.gz 3 | *~ 4 | .deps 5 | Makefile 6 | Makefile.in 7 | PLATFORM 8 | aclocal.m4 9 | atftp 10 | atftpd 11 | autom4te.cache 12 | compile 13 | config.guess 14 | config.h 15 | config.h.in 16 | config.log 17 | config.status 18 | config.sub 19 | configure 20 | depcomp 21 | install-sh 22 | missing 23 | redhat/atftp.spec 24 | stamp-h1 25 | test-driver 26 | test/??-out 27 | test/Makefile 28 | test/Makefile.in 29 | test/atftpd.log 30 | test/out.bin 31 | -------------------------------------------------------------------------------- /BUGS: -------------------------------------------------------------------------------- 1 | If you find some bugs, please send us a detailed description of the 2 | problem observed. Please include the logfile and a full description of 3 | your setup. 4 | 5 | To get a detailed log, use --verbose=7 and --logfile /var/log/tftpd to 6 | generate a separate logfile. Please include the number of machines 7 | that were booting of the server, the type of server (single or dual 8 | processor, processor speed, etc.) and the type of network you have 9 | (10Mbit, 100Mbit or 1Gbit). 10 | 11 | Jean-Pierre Lefebvre 12 | Remi Lefebvre 13 | -------------------------------------------------------------------------------- /FAQ: -------------------------------------------------------------------------------- 1 | 1) What are the best values for --tftpd-timeout, --retry-timeout and 2 | --max-thread ? 3 | 4 | There is no absolute answer to that question. It is highly dependent 5 | of your personal setup. Here's an explanation of what they mean and 6 | how to tune them. 7 | 8 | --tftpd-timeout controls how much time the server will wait for an 9 | incoming connection before killing the main thread. If you use small 10 | number, the server will be respawned by inetd when a new query 11 | arrives. If number is high, atftpd will behave more like a standalone 12 | server in that it will always receive queries directly. When booting a 13 | whole cluster, the first tftp request will start the daemon and have 14 | higher latency. All other clients will be handled directly by the tftp 15 | server. It is a good idea to set the timeout high enough so that the 16 | main thread won't hog your system killing itself and respawning all 17 | the time. 18 | 19 | --retry-timeout controls how much time the server waits before 20 | retransmitting a packet. If you expect some lag on the network (when 21 | the network is under high load), it is a good idea to increase that 22 | value. Note that the client's delay must be taken into 23 | consideration. The client can set the server delay too, and it 24 | overides the --retry-timeout value. 25 | 26 | --max-thread controls how many simultaneous clients may be served. This 27 | limit depends on your server's performance. It also depends on the 28 | maximum load you are willing to put on the server. For example, this 29 | server may have other things to do, and you want to limit the number 30 | of clients booting at the same time to 10. The maximum number of 31 | threads is also throttled by the available bandwidth of the network 32 | and server, because packets cannot be processed fast enough and there is 33 | a maximum rate at which servers may be started. But this is not a desirable 34 | condition and --maxthread should be set to avoid that. 35 | 36 | 2) Why do I get "recvfrom: Connection refused" in my log file? 37 | 38 | That indicates that either your server or network can't handle all the 39 | packets fast enough. What happens is the following: 40 | - client sends a RRQ (read request) 41 | - server starts a thread (A) that sends a DATA packet 42 | - the client times out and sends a second RRQ 43 | - server A sends the whole file 44 | - client and server thread A both exit normally 45 | - server finally starts a second thread (B) for the second RRQ 46 | - the server thread sends a DATA packet to the client 47 | - the client isn't listening anymore, we got a connection refused. 48 | 49 | Solution: 50 | a) increase timeout on client and server side 51 | b) reduce the number of concurrent threads allowed 52 | c) do nothing, it's not harmful at all. 53 | 54 | 3) How can I boot a simple image from the network? 55 | 56 | A boot from LAN setup requires the following on the server side: a dhcp 57 | server, a tftp server (atftpd), a working pxelinux config, a kernel image 58 | and a root file system image. 59 | 60 | You can get documentation on how to configure the dhcp server to work with 61 | pxelinux from the pxelinux and dhcp documentation. 62 | 63 | For atftp to work out of the box, be sure to have the following line in your 64 | inetd.conf and to restart the inetd daemon: 65 | tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftpboot 66 | 67 | You also need to have /tftpboot world readable. 68 | 69 | The pxelinux configuration is the same as syslinux. Documentation for it can 70 | be found in the syslinux package. 71 | 72 | The configuration file for pxelinux will tell it the name of the kernel and 73 | file system images to download. It is very important that you tell the kernel 74 | image where to get its root file system with rdev like this for example: 75 | 76 | rdev image /dev/ramdisk 77 | 78 | You can find detailed information on how to create a filesystem image in the 79 | Bootdisk HOWTO (www.linuxdoc.org). 80 | 81 | On the client side, you need to have a boot ROM. Have a look at Etherboot 82 | (www.etherboot.org), NetTools and Nilo (www.nilo.org) to find out more 83 | information about this if you need to burn one. 84 | 85 | After you got all of these setup, you should see the client attempt to get 86 | an IP address on boot, download pxelinux.bin, then download the kernel and 87 | filesystem images and boot from it. 88 | 89 | 90 | 4) I followed the above steps and it still fails to boot! 91 | 92 | Try putting log verbosity at high in the concerned programs on the server side 93 | and see if something fails or if you get the requests at all. You should see 94 | dhcpd give a lease to the client, if it doesn't, your dhcp configuration is 95 | faulty. You can also monitor the activity on the network to track down the 96 | problem using tools like tcpdump or ethereal/wireshark. 97 | 98 | 5) How do I setup multicast stuff? 99 | 100 | - Make sure your client and server support multicast. 101 | - Make sure you server routing table knows what to do with multicast addresses. 102 | You need to do something like this: 103 | route add -net 224.0.0.0 netmask 240.0.0.0 dev eth0 104 | - Make sure your network is working by testing with atftp client against 105 | atftpd server 106 | 107 | That's currently all that I've made working folks. I've never tried a multicast 108 | boot ROM or boot loader yet. 109 | 110 | 6) What inetd or xinetd configuration should I use? 111 | 112 | Something like that for inetd in /etc/inetd.conf: 113 | tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd 114 | 115 | For xinetd, in /etc/xinetd.conf: 116 | service tftp 117 | { 118 | socket_type = dgram 119 | protocol = udp 120 | wait = no 121 | user = nobody 122 | server = /usr/sbin/in.tftpd 123 | server_args = 124 | } 125 | 126 | This is the basic stuff. Read inetd or xinetd man page for more specialised 127 | configuration. 128 | -------------------------------------------------------------------------------- /INSTALL: -------------------------------------------------------------------------------- 1 | The simplest way to install atftp is using either the Debian package 2 | or one provided by your distribution if any. If you need to install 3 | atftp from source, here's the procedure. 4 | 5 | 6 | 1) Needed libraries 7 | ---------------- 8 | 9 | libpthread Needed for the atftpd server. 10 | libwrap Optional if you need host access control. 11 | libpcre2 Optional if you want to perform file name 12 | substitution. See README.PCRE. 13 | libreadline Optional. Used by the atftp client for better command 14 | line input and history. 15 | 16 | 17 | 2) Needed tools 18 | ------------ 19 | 20 | At least, you need these programs: 21 | make 22 | gcc 23 | You may also need these: 24 | git 25 | automake (tested using version 1.7 and 1.8) 26 | autoconf (tested with version 2.50) 27 | 28 | 29 | 3) How to compile 30 | -------------- 31 | 32 | 3.1) From tarball 33 | 34 | ./configure [options] (this generates makefiles) 35 | make (actually build the programs) 36 | su -c 'make install' (install files (default location is /usr) 37 | 38 | 3.2) From git checkout 39 | 40 | git clone git://atftp.git.sourceforge.net/gitroot/atftp/atftp 41 | - or - 42 | git clone https://github.com/madmartin/atftp.git 43 | (this creates a clone of the git repository) 44 | cd atftp (change into the newly created subdir) 45 | ./autogen.sh (this generates the configure script) 46 | ./configure [options] (this generate makefiles) 47 | make (actually build the programs) 48 | su -c 'make install' (install files (default location is /usr) 49 | 50 | 51 | 4) How to start atftpd server 52 | -------------------------- 53 | 54 | 4.1) Using the inetd super server 55 | 56 | Add this line to the /etc/inetd.conf file: 57 | 58 | tftp dgram udp wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd /tftpboot 59 | 60 | You can add necessary options to atftpd at the end of the line. 61 | 62 | 4.2) Using xinetd 63 | 64 | Add this to the /etc/xinetd.conf file, or create /etc/xinetd.d/tftp-udp file 65 | with the following content: 66 | 67 | # tftp-udp 68 | service tftp 69 | { 70 | id = tftp-udp 71 | disable = no 72 | socket_type = dgram 73 | protocol = udp 74 | wait = no 75 | user = nobody 76 | nice = 5 77 | server = /usr/local/sbin/atftpd 78 | server_args = /tftpboot # add other server argument as necessary 79 | } 80 | # eof 81 | 82 | 4.3) As a stand alone server from init.d scripts 83 | 84 | You need to add the proper init script in your boot sequence. The 85 | Debian package automatically does that. I'm not aware if any rpm based 86 | distribution includes init scripts. If you absolutely need this on rpm 87 | based distribution or on other systems, start with the Debian 88 | scripts and adapt it to your particular system. 89 | 90 | 91 | 5) Information for future developers of atftp 92 | ------------------------------------------ 93 | 94 | 5.1) Cleanup the source directory 95 | 96 | After some work and compiling in the package sources, you can delete the 97 | files produced from the compilers by running 98 | 99 | make clean 100 | 101 | Note: The "Makefile" necessary for this operation is only available 102 | if the "./configure" command has been run at least once. 103 | 104 | More cleanup is done with the command 105 | 106 | make distclean 107 | 108 | This removes all files produced by "./configure" - which includes the 109 | Makefile. If you want to use "make " again, you need to run 110 | "./configure" before. 111 | 112 | 5.2) Create a release tarball 113 | 114 | If a new release should be created, first edit configure.ac and change the 115 | AC_INIT parameter to the new release version number. 116 | Then execute "./autogen.sh" and "./configure". After that, 117 | 118 | make distcheck 119 | 120 | creates a tar archive with the requested version number, unpacks it immedia- 121 | tely in a temporary subdirectory, compiles the package and executes the 122 | test.sh suite and cleans all that up. If you get the final message 123 | ============================================= 124 | atftp- archives ready for distribution: 125 | atftp-.tar.gz 126 | ============================================= 127 | then you can upload atftp-.tar.gz to 128 | http://sourceforge.net/projects/atftp/files/ 129 | 130 | -------------------------------------------------------------------------------- /Makefile.am: -------------------------------------------------------------------------------- 1 | # Makefile.am 2 | # Automake makefile for atftp 3 | # 4 | # $Id: Makefile.am,v 1.15 2004/03/16 01:37:24 jp Exp $ 5 | # 6 | # Copyright (c) 2001 Jean-Pierre Lefebvre 7 | # and Remi Lefebvre 8 | # 9 | # atftp is free software; you can redistribute them and/or modify them 10 | # under the terms of the GNU General Public License as published by the 11 | # Free Software Foundation; either version 2 of the License, or (at your 12 | # option) any later 13 | 14 | AUTOMAKE_OPTIONS = foreign 15 | SUBDIRS = . test 16 | DIST_SUBDIRS = $(SUBDIRS) 17 | CLEANFILES = *~ 18 | DISTCLEANFILES = libtool PLATFORM 19 | AM_CPPFLAGS = -D_GNU_SOURCE 20 | 21 | man_MANS = atftp.1 atftpd.8 22 | dist_scripts = autogen.sh 23 | dist_docs = BUGS Changelog FAQ LICENSE README.CVS README.MCAST README.PCRE 24 | dist_dirs = test redhat docs debian 25 | EXTRA_DIST = $(dist_docs) $(dist_dirs) $(man_MANS) $(dist_scripts) 26 | 27 | noinst_HEADERS = argz.h logger.h options.h stats.h tftp.h tftp_def.h tftp_io.h \ 28 | tftpd.h tftpd_pcre.h tftpd_mtftp.h 29 | 30 | bin_PROGRAMS = atftp 31 | atftp_LDADD = $(LIBTERMCAP) $(LIBREADLINE) $(LIBPTHREAD) 32 | atftp_SOURCES = tftp.c tftp_io.c logger.c options.c tftp_def.c tftp_file.c \ 33 | argz.c tftp_mtftp.c 34 | 35 | sbin_PROGRAMS = atftpd 36 | atftpd_LDADD = $(LIBWRAP) $(LIBPTHREAD) $(LIBPCRE) 37 | atftpd_SOURCES = tftpd.c logger.c options.c stats.c tftp_io.c tftp_def.c \ 38 | tftpd_file.c tftpd_list.c tftpd_mcast.c argz.c tftpd_pcre.c \ 39 | tftpd_mtftp.c 40 | 41 | install-exec-hook: 42 | (cd $(DESTDIR)$(sbindir) && ln -sf atftpd in.tftpd) 43 | 44 | install-data-hook: 45 | (cd $(DESTDIR)$(mandir)/man8 && ln -sf atftpd.8 in.tftpd.8) 46 | 47 | uninstall-local: 48 | rm -f $(DESTDIR)$(sbindir)/in.tftpd $(DESTDIR)$(mandir)/man8/in.tftpd.8 49 | 50 | dist-hook: 51 | cd $(distdir) && rm -rf `find . -type d -name CVS` 52 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 |  Jean-Pierre Lefebvre 2 | August 20th, 2000 3 | ----------------- 4 | 5 | atftp stands for Advanced Trivial File Transfer Protocol. It is called 6 | "advanced", by contrast to others TFTP servers, for two reasons. 7 | Firstly, it is intended to be fully compliant with all related 8 | RFCs. This include RFC1350, RFC2090, RFC2347, RFC2348 and RFC2349. To 9 | my knowledge, there is no TFTP server currently available in the 10 | public domain that fulfills this requirement. Secondly, atftp is 11 | intended for serving boot files to large clusters. It is 12 | multi-threaded and support multicast (RFC2090 and PXE), allowing 13 | faster boot of hundreds of machine simultaneously. 14 | 15 | I started writing the atftp server after trying to boot Debian from 16 | the LAN using pxelinux (distributed with syslinux). Since pxelinux 17 | needs support for the "tsize" option defined in RFC2349, I looked for 18 | different TFTP servers but found none that fulfilled my needs. 19 | 20 | With atftp, I have successfully used pxelinux and dhcpd to boot from 21 | the LAN. Unfortunately, new development will slow down since I do it 22 | on my spare time and atftp now does what I need. However, atftp is 23 | actively maintained. Comments, bug reports and patches are welcome. 24 | 25 | Great thanks to my brother Remi who works on the client and server 26 | implementation and the debian packaging. 27 | 28 | 29 | Authors 30 | ------- 31 | 32 | Jean-Pierre Lefebvre 33 | Remi Lefebvre 34 | 35 | 36 | Contributors 37 | ------------ 38 | 39 | Jeff Miller 40 | Leif Lindholm 41 | Jens Schmidt 42 | Svend Odgaard 43 | Joshua Aune 44 | Mario Lorenz 45 | Allen Reese 46 | Thayne Harbaugh 47 | Thomas Anders 48 | Michał Rzechonek 49 | Florian Fainelli 50 | Denis Andzakovic 51 | Rosen Penev 52 | Peter Kaestle 53 | Grant Edwards 54 | Ryan Barnett 55 | Peter Seiderer 56 | Simon Rettberg 57 | Andreas B. Mundt 58 | 59 | -------------------------------------------------------------------------------- /README.CVS: -------------------------------------------------------------------------------- 1 | atftp-0.7.1 and later 2 | ===================== 3 | 4 | Development of atftp has switched over to a sourceforge project, with a mirror 5 | on github.com 6 | A git repository is used for the source code. 7 | 8 | A copy of the repository can be fetched with the command 9 | 10 | git clone git://atftp.git.sourceforge.net/gitroot/atftp/atftp 11 | - or - 12 | git clone https://github.com/madmartin/atftp.git 13 | 14 | Please read the file INSTALL for further instructions. 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | atftp-0.7 23 | ========= 24 | 25 | 26 | The development for atftp is done using CVS. It is possible to access the 27 | repository read-only by using the following CVSROOT with a null password: 28 | 29 | :pserver:anonymous@heimlich.syspark.com:/var/cvs/atftp 30 | 31 | It is also possible to grant write access to the CVS repository for people 32 | wishing to participate in the development. Please address such requests to 33 | either of us. 34 | 35 | Thanks 36 | 37 | -- 38 | Remi Lefebvre 39 | Jean-Pierre Lefebvre 40 | -------------------------------------------------------------------------------- /README.MCAST: -------------------------------------------------------------------------------- 1 | Atftp supports multicast transfer. This feature allows the server to 2 | send a file to many clients at once. There are two ways of doing 3 | multicast TFTP. One is documented in RFC2090 and the other is known 4 | as MTFTP and documented in Intel's PXE specification. Atftp supports 5 | both protocols. 6 | 7 | RFC2090 8 | ------- 9 | 10 | Multicast using RFC2090 is very similar to any other TFTP transfer. The 11 | read request sent by the client contains an option to inform the server to 12 | use multicast. The server will send configuration information (IP and 13 | port) through the option acknowledge mechanism. The initial read 14 | request is done at the same port as without multicast (port 69 in most 15 | configuration). Data transfer is done at IP and port chosen by the 16 | server. 17 | 18 | When more clients connect to the server, atftpd tries to find a thread 19 | currently sending the same file. If it exists, this thread will take 20 | care of the new client. If not, a new thread is started for that new 21 | client. It is possible to send many different files to many clients 22 | when using multicast. Each file transfer uses a unique IP and port. 23 | 24 | MTFTP 25 | ----- 26 | 27 | The PXE specification uses a completely different (and incompatible 28 | with RFC2090) way of doing things. Basically, the TFTP 29 | request is sent at a different port than a normal TFTP request. Various 30 | options like IP address, port and timeout value are fetched by the client 31 | from a DHCP server. Server configuration is done with command line 32 | arguments and a configuration file. It is much less flexible than 33 | RFC2090 since configuration of the DHCP server must match the configuration 34 | of atftpd. See the file mtftp.conf as an example. Most boot ROMs use this 35 | method for multicast transfer since it is part of the PXE specification 36 | (ftp://download.intel.com/labs/manage/wfm/download/pxespec.pdf). 37 | 38 | Note: mtftp support starting in atftp 0.7 is experimental. 39 | -------------------------------------------------------------------------------- /README.PCRE: -------------------------------------------------------------------------------- 1 | File name mangling with PCRE in atftpd 2 | ====================================== 3 | 4 | Here is an attempt at using PCRE (Perl Compatible Regular Expressions) 5 | with a TFTP server. The first question on your mind is most likely "Why in 6 | blazes would anyone want to use a regular expression with a TFTP server?" 7 | Imagine you have a network of machines that all download an identical 8 | config file, but each machine requests its file as .conf where 9 | is the serial number of the machine. This setup is useful when 10 | you wish each machine to have individual configs. When you wish to have 11 | identical configurations on each box this is annoying. The solution is to 12 | map all requested files ending in .conf to one master.conf file via a 13 | regex. The exact expression I use is 14 | 15 | ^\w*\.conf$ master.conf 16 | 17 | The left hand side is the expression to match, the right hand side is the 18 | substitution. This is equivalent to perl's s/// statement. One or more of these 19 | expressions can be stored in a file (one per line) and feed to atftpd via a 20 | --pcre switch on the command line. For example, 21 | 22 | ./atftpd --daemon --pcre ./test/pcre_pattern.txt /tftpboot/ 23 | 24 | Also included is a test program using the --pcre-test option. You 25 | can interactively (or via redirection) feed file name to atftpd and look at 26 | the substitution to verify your rules. for example, 27 | 28 | ./atftpd --pcre-test ./test/pcre_pattern.txt 29 | 30 | Jeff. 31 | (jeffm@ghostgun.com) 32 | -------------------------------------------------------------------------------- /TODO: -------------------------------------------------------------------------------- 1 | Client 2 | ------ 3 | 4 | Server 5 | ------ 6 | 7 | * Use mmap instead of read/write. This way, we'll benefit from zero copy 8 | networking in 2.4.x 9 | * number_of_timeout should be per client 10 | * Get ICMP error message 11 | * add maximum number of client for a multicast server thread. Use new thread 12 | to server the file if needed? 13 | * It may be necessary to free client structure when client is done to make 14 | sure a long lasting multicast server never build up a huge list of done 15 | client 16 | * Rate control not working yet. 17 | 18 | Both 19 | ---- 20 | * revise man pages 21 | * add statistics mor mtftp 22 | * Verify the whole logging thing 23 | * Support IPv6 24 | * Decide what to do when we got memory allocation failure (other than exit) 25 | * There is a problem when using block size around 56000 up to 65464. (56944 for 26 | Glenn McGrath, 64546 for me on linux 2.4 with Debian unstable). Server send 27 | packets (they are fragmented), client machine receive packet but not the 28 | application. On an other setup, (linux 2.2.19, Debian 2.2) it work fine up 29 | to the maximum of 65464. 30 | * When receiving error packet, buffer not beeing initilised with 0 seems to 31 | create error. String sended by peer to not have proper 0 termination??? Not 32 | confirmed. 33 | 34 | Generic 35 | ------- 36 | - Redhat/atftp.spec and test/Makefile are included in make dist and should 37 | not. 38 | 39 | -------------------------------------------------------------------------------- /argz.c: -------------------------------------------------------------------------------- 1 | /* 2 | * argz.h 3 | * The functions below are "borrowed" from glibc-2.2.3 (argz-next.c). 4 | * This has been done to make atftp compile with uclibc, BSD, Solaris 5 | * and other platform without glic 6 | * 7 | * 8 | * $Id: argz.c,v 1.1 2003/01/21 01:38:35 jp Exp $ 9 | * 10 | * Copyright (c) 2000 Jean-Pierre Lefebvre 11 | * and Remi Lefebvre 12 | * 13 | * atftp is free software; you can redistribute them and/or modify them 14 | * under the terms of the GNU General Public License as published by the 15 | * Free Software Foundation; either version 2 of the License, or (at your 16 | * option) any later version. 17 | * 18 | */ 19 | 20 | #include "config.h" 21 | 22 | #ifndef HAVE_ARGZ_H 23 | 24 | /* Routines for dealing with '\0' separated arg vectors. 25 | Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. 26 | This file is part of the GNU C Library. 27 | 28 | The GNU C Library is free software; you can redistribute it and/or 29 | modify it under the terms of the GNU Lesser General Public 30 | License as published by the Free Software Foundation; either 31 | version 2.1 of the License, or (at your option) any later version. 32 | 33 | The GNU C Library is distributed in the hope that it will be useful, 34 | but WITHOUT ANY WARRANTY; without even the implied warranty of 35 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 36 | Lesser General Public License for more details. 37 | 38 | You should have received a copy of the GNU Lesser General Public 39 | License along with the GNU C Library; if not, write to the Free 40 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 41 | 02111-1307 USA. */ 42 | 43 | #include 44 | #include "argz.h" 45 | 46 | char * argz_next (const char *argz, size_t argz_len, const char *entry) 47 | { 48 | if (entry) 49 | { 50 | if (entry < argz + argz_len) 51 | entry = strchr (entry, '\0') + 1; 52 | 53 | return entry >= argz + argz_len ? NULL : (char *) entry; 54 | } 55 | else 56 | if (argz_len > 0) 57 | return (char *) argz; 58 | else 59 | return NULL; 60 | } 61 | 62 | error_t argz_create_sep (const char *string, int delim, char **argz, size_t *len) 63 | { 64 | size_t nlen = strlen (string) + 1; 65 | 66 | if (nlen > 1) 67 | { 68 | const char *rp; 69 | char *wp; 70 | 71 | *argz = (char *) malloc (nlen); 72 | if (*argz == NULL) 73 | return ENOMEM; 74 | 75 | rp = string; 76 | wp = *argz; 77 | do 78 | if (*rp == delim) 79 | { 80 | if (wp > *argz && wp[-1] != '\0') 81 | *wp++ = '\0'; 82 | else 83 | --nlen; 84 | } 85 | else 86 | *wp++ = *rp; 87 | while (*rp++ != '\0'); 88 | 89 | if (nlen == 0) 90 | { 91 | free (*argz); 92 | *argz = NULL; 93 | *len = 0; 94 | } 95 | 96 | *len = nlen; 97 | } 98 | else 99 | { 100 | *argz = NULL; 101 | *len = 0; 102 | } 103 | 104 | return 0; 105 | } 106 | 107 | size_t argz_count (const char *argz, size_t len) 108 | { 109 | size_t count = 0; 110 | while (len > 0) 111 | { 112 | size_t part_len = strlen(argz); 113 | argz += part_len + 1; 114 | len -= part_len + 1; 115 | count++; 116 | } 117 | return count; 118 | } 119 | 120 | /* Puts pointers to each string in ARGZ, plus a terminating 0 element, into 121 | ARGV, which must be large enough to hold them all. */ 122 | void argz_extract (const char *argz, size_t len, char **argv) 123 | { 124 | while (len > 0) 125 | { 126 | size_t part_len = strlen (argz); 127 | *argv++ = (char *) argz; 128 | argz += part_len + 1; 129 | len -= part_len + 1; 130 | } 131 | *argv = 0; 132 | } 133 | 134 | #endif 135 | -------------------------------------------------------------------------------- /argz.h: -------------------------------------------------------------------------------- 1 | /* 2 | * argz.h 3 | * Source file borrowed from glibc-2.2.3. This has been done to make 4 | * atftp compile with uclibc, BSD, Solaris and other platform without 5 | * glic 6 | * 7 | * $Id: argz.h,v 1.1 2003/01/21 01:38:35 jp Exp $ 8 | * 9 | * Copyright (c) 2000 Jean-Pierre Lefebvre 10 | * and Remi Lefebvre 11 | * 12 | * atftp is free software; you can redistribute them and/or modify them 13 | * under the terms of the GNU General Public License as published by the 14 | * Free Software Foundation; either version 2 of the License, or (at your 15 | * option) any later version. 16 | * 17 | */ 18 | 19 | /* Routines for dealing with '\0' separated arg vectors. 20 | Copyright (C) 1995, 96, 97, 98, 99, 2000 Free Software Foundation, Inc. 21 | This file is part of the GNU C Library. 22 | 23 | The GNU C Library is free software; you can redistribute it and/or 24 | modify it under the terms of the GNU Lesser General Public 25 | License as published by the Free Software Foundation; either 26 | version 2.1 of the License, or (at your option) any later version. 27 | 28 | The GNU C Library is distributed in the hope that it will be useful, 29 | but WITHOUT ANY WARRANTY; without even the implied warranty of 30 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 31 | Lesser General Public License for more details. 32 | 33 | You should have received a copy of the GNU Lesser General Public 34 | License along with the GNU C Library; if not, write to the Free 35 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 36 | 02111-1307 USA. */ 37 | 38 | #ifndef _ARGZ_H 39 | #define _ARGZ_H 1 40 | 41 | #define __need_error_t 42 | #include 43 | #include /* Need size_t, and strchr is called below. */ 44 | 45 | #ifndef __const 46 | # define __const const 47 | #endif 48 | 49 | #ifndef __THROW 50 | # define __THROW 51 | #endif 52 | 53 | #ifndef __BEGIN_DECLS 54 | # define __BEGIN_DECLS 55 | #endif 56 | 57 | #ifndef __END_DECLS 58 | # define __END_DECLS 59 | #endif 60 | 61 | #ifndef __attribute_pure__ 62 | # define __attribute_pure__ 63 | #endif 64 | 65 | #ifndef __error_t_defined 66 | typedef int error_t; 67 | #endif 68 | 69 | /* Make a '\0' separated arg vector from a unix argv vector, returning it in 70 | ARGZ, and the total length in LEN. If a memory allocation error occurs, 71 | ENOMEM is returned, otherwise 0. The result can be destroyed using free. */ 72 | extern error_t __argz_create (char *__const __argv[], char **__restrict __argz, 73 | size_t *__restrict __len); 74 | extern error_t argz_create (char *__const __argv[], char **__restrict __argz, 75 | size_t *__restrict __len); 76 | 77 | /* Make a '\0' separated arg vector from a SEP separated list in 78 | STRING, returning it in ARGZ, and the total length in LEN. If a 79 | memory allocation error occurs, ENOMEM is returned, otherwise 0. 80 | The result can be destroyed using free. */ 81 | extern error_t __argz_create_sep (__const char *__restrict __string, 82 | int __sep, char **__restrict __argz, 83 | size_t *__restrict __len); 84 | extern error_t argz_create_sep (__const char *__restrict __string, 85 | int __sep, char **__restrict __argz, 86 | size_t *__restrict __len); 87 | 88 | /* Returns the number of strings in ARGZ. */ 89 | extern size_t __argz_count (__const char *__argz, size_t __len) 90 | __attribute_pure__; 91 | extern size_t argz_count (__const char *__argz, size_t __len) 92 | __attribute_pure__; 93 | 94 | /* Puts pointers to each string in ARGZ into ARGV, which must be large enough 95 | to hold them all. */ 96 | extern void __argz_extract (__const char *__restrict __argz, size_t __len, 97 | char **__restrict __argv); 98 | extern void argz_extract (__const char *__restrict __argz, size_t __len, 99 | char **__restrict __argv); 100 | 101 | /* Make '\0' separated arg vector ARGZ printable by converting all the '\0's 102 | except the last into the character SEP. */ 103 | extern void __argz_stringify (char *__argz, size_t __len, int __sep); 104 | extern void argz_stringify (char *__argz, size_t __len, int __sep); 105 | 106 | /* Append BUF, of length BUF_LEN to the argz vector in ARGZ & ARGZ_LEN. */ 107 | extern error_t __argz_append (char **__restrict __argz, 108 | size_t *__restrict __argz_len, 109 | __const char *__restrict __buf, size_t _buf_len); 110 | extern error_t argz_append (char **__restrict __argz, 111 | size_t *__restrict __argz_len, 112 | __const char *__restrict __buf, size_t __buf_len); 113 | 114 | /* Append STR to the argz vector in ARGZ & ARGZ_LEN. */ 115 | extern error_t __argz_add (char **__restrict __argz, 116 | size_t *__restrict __argz_len, 117 | __const char *__restrict __str); 118 | extern error_t argz_add (char **__restrict __argz, 119 | size_t *__restrict __argz_len, 120 | __const char *__restrict __str); 121 | 122 | /* Append SEP separated list in STRING to the argz vector in ARGZ & 123 | ARGZ_LEN. */ 124 | extern error_t __argz_add_sep (char **__restrict __argz, 125 | size_t *__restrict __argz_len, 126 | __const char *__restrict __string, int __delim); 127 | extern error_t argz_add_sep (char **__restrict __argz, 128 | size_t *__restrict __argz_len, 129 | __const char *__restrict __string, int __delim); 130 | 131 | /* Delete ENTRY from ARGZ & ARGZ_LEN, if it appears there. */ 132 | extern void __argz_delete (char **__restrict __argz, 133 | size_t *__restrict __argz_len, 134 | char *__restrict __entry); 135 | extern void argz_delete (char **__restrict __argz, 136 | size_t *__restrict __argz_len, 137 | char *__restrict __entry); 138 | 139 | /* Insert ENTRY into ARGZ & ARGZ_LEN before BEFORE, which should be an 140 | existing entry in ARGZ; if BEFORE is NULL, ENTRY is appended to the end. 141 | Since ARGZ's first entry is the same as ARGZ, argz_insert (ARGZ, ARGZ_LEN, 142 | ARGZ, ENTRY) will insert ENTRY at the beginning of ARGZ. If BEFORE is not 143 | in ARGZ, EINVAL is returned, else if memory can't be allocated for the new 144 | ARGZ, ENOMEM is returned, else 0. */ 145 | extern error_t __argz_insert (char **__restrict __argz, 146 | size_t *__restrict __argz_len, 147 | char *__restrict __before, 148 | __const char *__restrict __entry); 149 | extern error_t argz_insert (char **__restrict __argz, 150 | size_t *__restrict __argz_len, 151 | char *__restrict __before, 152 | __const char *__restrict __entry); 153 | 154 | /* Replace any occurrences of the string STR in ARGZ with WITH, reallocating 155 | ARGZ as necessary. If REPLACE_COUNT is non-zero, *REPLACE_COUNT will be 156 | incremented by number of replacements performed. */ 157 | extern error_t __argz_replace (char **__restrict __argz, 158 | size_t *__restrict __argz_len, 159 | __const char *__restrict __str, 160 | __const char *__restrict __with, 161 | unsigned int *__restrict __replace_count); 162 | extern error_t argz_replace (char **__restrict __argz, 163 | size_t *__restrict __argz_len, 164 | __const char *__restrict __str, 165 | __const char *__restrict __with, 166 | unsigned int *__restrict __replace_count); 167 | 168 | /* Returns the next entry in ARGZ & ARGZ_LEN after ENTRY, or NULL if there 169 | are no more. If entry is NULL, then the first entry is returned. This 170 | behavior allows two convenient iteration styles: 171 | 172 | char *entry = 0; 173 | while ((entry = argz_next (argz, argz_len, entry))) 174 | ...; 175 | 176 | or 177 | 178 | char *entry; 179 | for (entry = argz; entry; entry = argz_next (argz, argz_len, entry)) 180 | ...; 181 | */ 182 | extern char *__argz_next (__const char *__restrict __argz, size_t __argz_len, 183 | __const char *__restrict __entry); 184 | extern char *argz_next (__const char *__restrict __argz, size_t __argz_len, 185 | __const char *__restrict __entry); 186 | 187 | #endif /* argz.h */ 188 | -------------------------------------------------------------------------------- /atftp.1: -------------------------------------------------------------------------------- 1 | .\" Hey, EMACS: -*- nroff -*- 2 | .TH ATFTP 1 "December 27, 2000" 3 | .\" Some roff macros, for reference: 4 | .\" .nh disable hyphenation 5 | .\" .hy enable hyphenation 6 | .\" .ad l left justify 7 | .\" .ad b justify to both left and right margins 8 | .\" .nf disable filling 9 | .\" .fi enable filling 10 | .\" .br insert line break 11 | .\" .sp insert n+1 empty lines 12 | .\" for manpage-specific macros, see man(7) 13 | .SH NAME 14 | atftp \- TFTP client (RFC1350). 15 | .SH SYNOPSIS 16 | .B atftp [options] [host [port]] 17 | 18 | .SH DESCRIPTION 19 | .B atftp 20 | can be used interactively or in batch mode to retrieve files from TFTP 21 | servers. When used interactively, a summary of the commands can be 22 | printed by typing 'help'. This TFTP client support all basic features 23 | from RFC1350, RFC2347, RFC2348 and RFC2349. It also support multicast 24 | implementation of RFC2090 and mtftp as defined in the PXE 25 | specification. 26 | 27 | .SH OPTIONS 28 | This program supports both the usual GNU command line syntax, with 29 | long options starting with two dashes ('--') as well as short 30 | options. Some options are usable in batch mode only, they have no meaning 31 | when atftp is use interactively. A description of the options is 32 | shown below. 33 | 34 | .TP 35 | .B \-g, \-\-get 36 | Non interactive invocation only. Instruct atftp to fetch a file from a tftp server. 37 | 38 | .TP 39 | .B \-\-mget 40 | Non interactive invocation only. Used to fetch a file from a mtftp capable 41 | server. 42 | 43 | .TP 44 | .B \-p, \-\-put 45 | Non interactive invocation only. Instruct atftp to send a file to a tftp server. 46 | 47 | .TP 48 | .B \-P, \-\-password 49 | Give password to tftp server. This is a non-standard extension to the 50 | atftp client necessary for Linksys routers and shouldn't be used elsewhere. 51 | 52 | .TP 53 | .B \-l, \-\-local-file 54 | Non interactive invocation only. The client side (locat) file name to read or 55 | write. Must be used in conjunction with \-\-get or \-\-put. 56 | 57 | .TP 58 | .B \-r, \-\-remote-file 59 | Non interactive invocation only. The server side (remote) file name to get or 60 | put. Must be used in conjunction with \-\-get or \-\-put. 61 | 62 | .TP 63 | .B \-\-tftp-timeout 64 | Number of seconds for timeout of the client. Default is 5 seconds. 65 | 66 | .TP 67 | .B \-\-option <"name value"> 68 | Set option "name" to "value". This command supports exactly the same 69 | arguments as the interactive one. For example, use: --option "blksize 1428" 70 | to configure block size. 71 | .br 72 | Possible settings are: 73 | .br 74 | --option "blksize disable" 75 | --option "blksize 8" 76 | --option "blksize 65464" 77 | --option "timeout 1" 78 | --option "tsize enable" 79 | --option "tsize disable" 80 | --option "windowsize disable" 81 | --option "windowsize 4" 82 | --option "multicast" 83 | 84 | .TP 85 | .B \-\-mtftp <"name value"> 86 | Set mtftp possible options. Accepts the same options as the interactive 87 | mtftp command. For example, use: 88 | --mtftp "client-port 76" 89 | to configure client side port to use. 90 | 91 | .TP 92 | .B \-\-no\-source\-port\-checking 93 | See atftpd's man page. 94 | 95 | .TP 96 | .B \-\-prevent\-sas 97 | Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350. 98 | This RFC requires repeated responses to a single packet to be 99 | rejected. Thus a block will only get retransmitted on a timeout. 100 | For backward compatibility, the default stays to ignore this RFC. 101 | So blocks get transmitted on every request. 102 | 103 | .TP 104 | .B \-\-verbose 105 | Instruct atftp to be verbose. It will print more information about 106 | what's going on. 107 | 108 | .TP 109 | .B \-\-trace 110 | This is useful for debugging purpose to display all packet going to 111 | and from the network. 112 | 113 | .TP 114 | .B \-V, \-\-version 115 | Print version. 116 | 117 | .TP 118 | .B \-h, \-\-help 119 | Print a summary of command line arguments. 120 | 121 | 122 | .SH AUTHOR 123 | This manual page was written by Remi Lefebvre and 124 | Jean-Pierre Lefebvre . 125 | -------------------------------------------------------------------------------- /atftpd.8: -------------------------------------------------------------------------------- 1 | .\" Hey, EMACS: -*- nroff -*- 2 | .TH ATFTPD 8 "December 27, 2000" 3 | .\" Some roff macros, for reference: 4 | .\" .nh disable hyphenation 5 | .\" .hy enable hyphenation 6 | .\" .ad l left justify 7 | .\" .ad b justify to both left and right margins 8 | .\" .nf disable filling 9 | .\" .fi enable filling 10 | .\" .br insert line break 11 | .\" .sp insert n+1 empty lines 12 | .\" for manpage-specific macros, see man(7) 13 | 14 | .SH NAME 15 | atftpd \- Trivial File Transfer Protocol Server. 16 | .SH SYNOPSIS 17 | .B atftpd 18 | .RI [ options ] " directory" 19 | 20 | .SH DESCRIPTION 21 | .B atftpd 22 | is a TFTP (RFC1350) server. By default it is started by inetd on most 23 | systems, but may run as a stand alone daemon. This server is 24 | multi-threaded and supports all options described in RFC2347 (option 25 | extension), RFC2348 (blksize), RFC2349 (tsize and timeout) and RFC2090 26 | (multicast option). It also supports mtftp as defined in the PXE 27 | specification. 28 | 29 | .SH OPTIONS 30 | This program supports both the usual GNU command line syntax, with 31 | long options starting with two dashes ('-') as well as short 32 | options. A description of the options is included below. 33 | 34 | .TP 35 | .B \-t, \-\-tftpd\-timeout 36 | Number of seconds of inactivity before the server exits. This value 37 | has meaning only when the server is started by inetd. In daemon mode, 38 | the server never exits. Default is 300 seconds. 39 | 40 | .TP 41 | .B \-r, \-\-retry\-timeout 42 | How many seconds to wait for a reply before retransmitting a 43 | packet. Default is 5 seconds. This can be overridden by the TFTP 44 | client with the 'timeout' option. 45 | 46 | .TP 47 | .B \-m, \-\-maxthread 48 | Maximum number of concurrent threads allowed. Default is 100. 49 | 50 | .TP 51 | .B \-v, \-\-verbose[=value] 52 | Increase or set the logging level. No arguments will increase by one 53 | the current value. Default is LOG_NOTICE, see syslog(3) for log 54 | level. Valid value range from 0 (LOG_EMERG) to 7 (LOG_DEBUG). 55 | 56 | .TP 57 | .B \-\-trace 58 | When verbose level is set to 7, this will output debug information for 59 | each packet sent or received from the network. 60 | 61 | .TP 62 | .B \-\-no\-timeout 63 | disable 'timeout' from RFC2349. This will prevent the server from 64 | acknowledging the 'timeout' option requested by the client. 65 | 66 | .TP 67 | .B \-\-no\-tsize 68 | disable 'tsize' from RFC2349. This will prevent the server from 69 | acknowledging the 'tsize' option requested by the client. 70 | 71 | .TP 72 | .B \-\-no\-blksize 73 | disable 'blksize' from RFC2348. This will prevent the server from 74 | acknowledging the 'blksize' request by the client. 75 | 76 | .TP 77 | .B \-\-no\-windowsize 78 | disable 'windowsize' from RFC7440. This will prevent the server from 79 | acknowledging the 'windowsize' request by the client. 80 | 81 | .TP 82 | .B \-\-no\-multicast 83 | disable 'multicast' from RFC2090. This will prevent the server from 84 | acknowledging the 'multicast' request by the client. 85 | 86 | .TP 87 | .B \-\-logfile 88 | Log to a specific file instead of only syslog. 'nobody' (or any user 89 | used to run the server) must have permissions on the given 90 | file. Assuming the file is /var/log/atftpd.log, simply run: "touch 91 | /var/log/atftpd.log" and then "chown nobody.nogroup 92 | /var/log/atftpd.log". When the server is run in daemon mode, 93 | /dev/stdout or /dev/stderr can be used. Specifying a single dash as 94 | the filename will send logs to stdout (file descriptor 1). 95 | 96 | .TP 97 | .B \-\-pidfile 98 | Write the PID of the server to the specified file. This may be useful 99 | when automatically starting and stopping one or more instance of the 100 | server. 101 | 102 | .TP 103 | .B \-\-daemon 104 | Run as a daemon. Do not use this option if atftpd is started by inetd. 105 | 106 | .TP 107 | .B \-\-no-fork 108 | When \-\-daemon is specified, this option will prevent the server from 109 | forking to background. It is useful for debugging purpose or 110 | specialized usage. 111 | 112 | .TP 113 | .B \-\-user 114 | By default, the server change identity to the user nobody and group 115 | nogroup. Specify an alternate user.group with this option. 116 | 117 | .TP 118 | .B \-\-group 119 | Alternate way of specifying the group. If group is specified with 120 | \-\-user and \-\-group, the last option will be used. 121 | 122 | .TP 123 | .B \-\-port 124 | Specify the port on which atftpd listens. Useful when \-\-daemon is 125 | specified. Default is standard tftp port as determined 126 | by \fIgetservbyname\fR\|(3). 127 | 128 | .TP 129 | .B \-\-bind\-address 130 | Specify the IP address which atftpd binds to. Useful when \-\-daemon is 131 | specified. Default is to bind to all interfaces. Only one address can 132 | be specified, the server can only listen to one or all interfaces. 133 | 134 | .TP 135 | .B \-\-mcast\-ttl 136 | Specify the TTL to be used for multicast datagram. By default a value 137 | of 1 is used. Note that TTL has a special meaning in multicast as it 138 | is used to determine the scope of the packets. The value of 1 means 139 | the packets don't leave the local network, see ip(4). Scope may also 140 | be determine by the address as described RFC2365. 141 | 142 | .TP 143 | .B \-\-mcast\-addr 144 | Specify the IP address range to be used for multicast transfer. Format 145 | string may comprise range and list of values: 146 | "239.255.0.0-31,128-132,200". 147 | Default value is "239.255.0.0-255". This address range is proposed in 148 | RFC2365 for local scope. 149 | 150 | .TP 151 | .B \-\-mcast\-port 152 | Specify the UDP port to use for multicast transfer. Format string may 153 | contain range and list of port number: "1758-2000,8000-9000". default 154 | value is "1758". 155 | 156 | .TP 157 | .B \-\-pcre 158 | Specify a pattern/replacement file to use. This allows one to replace 159 | requested file name based on Perl Compatible Regular Expression. See 160 | README.PCRE. 161 | 162 | .TP 163 | .B \-\-pcre\-test 164 | Test a pattern/replacement file. When using this option, the server 165 | will not start as usual but just read file name from stdin and 166 | printout the substitution. 167 | 168 | .TP 169 | .B \-\-mtftp 170 | This will start a mtftp server thread for each valid entry in the 171 | supplied file. See PXE specification for detail about mtftp. An 172 | example file is provided in the source distribution. 173 | 174 | .TP 175 | .B \-\-mtftp\-port 176 | Port the mtftp server shall listen to for incoming request. 177 | 178 | .TP 179 | .B \-\-no\-source\-port\-checking 180 | In some specific cases of networks using load balancer or other 181 | equipment performing NAT (network address translation), some needs to 182 | disable source port checking because port number as been translated. If 183 | you want to use this feature, you must know why you need it and the 184 | implication. Be aware that this option violate the RFC1350. This 185 | option has effect only for non-multicast transfer. 186 | 187 | .TP 188 | .B \-\-prevent\-sas 189 | Address the Sorcerer's Apprentice Syndrome situation as requested by RFC 1350. 190 | This RFC requires repeated responses to a single packet to be 191 | rejected. Thus a block will only get retransmitted on a timeout. 192 | For backward compatibility, the default stays to ignore this RFC. 193 | So blocks get transmitted on every request. 194 | 195 | .TP 196 | .B \-\-mcast\-switch\-client 197 | This option allows the server to proceed with the next multicast client 198 | as soon as the current client timeout. When the current master client 199 | fails to send an acknowledge (ACK) to the server, the server will send 200 | an option acknowledge (OACK) to the master client with the field MC 201 | (master client) set to false and send an OACK to the next multicast 202 | client with MC set to true. Without this option, the server will retry 203 | the current master client up to 5 times and then mark it done, 204 | proceeding with the next one. 205 | 206 | .TP 207 | .B \-V, \-\-version 208 | Show version of program. 209 | 210 | .TP 211 | .B \-h, \-\-help 212 | Show summary of options. 213 | 214 | .TP 215 | .B path 216 | This is the root directory used by the TFTP server. All requested 217 | files from a TFTP client must reside in this directory. If not 218 | specified, the directory defaults to /tftpboot. Since 219 | atftpd run as the nobody user, the permission of the directory 220 | must be set properly to allow file reading and writing. 221 | 222 | .SH STATS 223 | Starting with release 0.2, the server collects some statistics. 224 | Currently the server compute system load, time between connections and 225 | some thread statistics like number of file sent, received, number of 226 | abort... To see those stats in the logs, you need to set --verbose=6 227 | (LOG_NOTICE) or higher. 228 | 229 | .SH SECURITY 230 | TFTP by itself has no provision for security. There is no user 231 | authentication and TFTP clients get access to all files within the 232 | specified root directory for which the server has permission. 233 | 234 | Some level of security can be gained using atftp libwrap 235 | support. Adding proper entry to /etc/hosts.allow and /etc/hosts.deny 236 | will restrict access to trusted hosts. Daemon name to use in these 237 | files is in.tftpd. 238 | 239 | .SH PCRE 240 | The atftpd server provides a way to dynamically replace requested file 241 | name by a new one based on Perl compatible regular expression. Pairs 242 | of pattern/replacement are read from the specified files. Upon 243 | reception of a read request, the server will first try to open the 244 | file name requested. If it fails, then it will search for a 245 | replacement based on the content of the pattern file. If this still 246 | fails, then an error will be sent to the client. This feature is 247 | available only for read request. It makes no sense doing this 248 | substitution for client writing files to the server. 249 | 250 | .SH MTFTP 251 | The mtftp name refer to multicasrt tftp as define by the PXE 252 | specification. See pxespec.txt for the source of the 253 | specification. Note that this is not the same as RFC2090. PXE 254 | compliant boot implements mtftp, not RFC2090. 255 | 256 | .SH SEE ALSO 257 | .BR inetd (8), hosts_access (5), libpcre (7), 258 | RFC1350, RFC2090, RFC2347, RFC2348, RFC2349 and pxespec.pdf. 259 | .SH AUTHOR 260 | This manual page was written by Remi Lefebvre and Jean-Pierre 261 | Lefebvre . 262 | -------------------------------------------------------------------------------- /autogen.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | AUTOCONF_REQUIRED_VERSION=2.5 4 | AUTOMAKE_REQUIRED_VERSION=1.7 5 | 6 | check_version ( ) { 7 | if [ "x$1" = "x" ] ; then 8 | echo "INTERNAL ERROR: check_version was not provided a minimum version" 9 | exit 1 10 | fi 11 | _min="$1" 12 | if [ "x$2" = "x" ] ; then 13 | echo "INTERNAL ERROR: version check was not provided a comparison version" 14 | exit 1 15 | fi 16 | _cur="$2" 17 | 18 | # needed to handle versions like 1.10 and 1.4-p6 19 | _min="`echo ${_min}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`" 20 | _cur="`echo ${_cur}. | sed 's/[^0-9]/./g' | sed 's/\.\././g'`" 21 | 22 | _min_major="`echo $_min | cut -d. -f1`" 23 | _min_minor="`echo $_min | cut -d. -f2`" 24 | _min_patch="`echo $_min | cut -d. -f3`" 25 | 26 | _cur_major="`echo $_cur | cut -d. -f1`" 27 | _cur_minor="`echo $_cur | cut -d. -f2`" 28 | _cur_patch="`echo $_cur | cut -d. -f3`" 29 | 30 | if [ "x$_min_major" = "x" ] ; then 31 | _min_major=0 32 | fi 33 | if [ "x$_min_minor" = "x" ] ; then 34 | _min_minor=0 35 | fi 36 | if [ "x$_min_patch" = "x" ] ; then 37 | _min_patch=0 38 | fi 39 | if [ "x$_cur_minor" = "x" ] ; then 40 | _cur_major=0 41 | fi 42 | if [ "x$_cur_minor" = "x" ] ; then 43 | _cur_minor=0 44 | fi 45 | if [ "x$_cur_patch" = "x" ] ; then 46 | _cur_patch=0 47 | fi 48 | 49 | # $VERBOSE_ECHO "Checking if ${_cur_major}.${_cur_minor}.${_cur_patch} is greater than ${_min_major}.${_min_minor}.${_min_patch}" 50 | 51 | RESULT=1 52 | if [ $_min_major -lt $_cur_major ] ; then 53 | RESULT=0 54 | elif [ $_min_major -eq $_cur_major ] ; then 55 | if [ $_min_minor -lt $_cur_minor ] ; then 56 | RESULT=0 57 | elif [ $_min_minor -eq $_cur_minor ] ; then 58 | if [ $_min_patch -lt $_cur_patch ] ; then 59 | RESULT=0 60 | elif [ $_min_patch -eq $_cur_patch ] ; then 61 | RESULT=0 62 | fi 63 | fi 64 | fi 65 | 66 | if [ $RESULT -eq 1 ] ; then 67 | echo "yes (version $1)" 68 | else 69 | echo "no (version $1)" 70 | fi 71 | 72 | return $RESULT 73 | } 74 | 75 | echo -n "checking for autoconf >= $AUTOCONF_REQUIRED_VERSION ... " 76 | if autoconf --version >/dev/null; then 77 | VER=$(autoconf --version | grep -iw autoconf | sed "s/.* \([0-9.]*\)[-a-z0-9]*$/\1/") 78 | check_version $VER $AUTOCONF_REQUIRED_VERSION 79 | else 80 | echo "not found" 81 | exit 1 82 | fi 83 | 84 | echo -n "checking for automake >= $AUTOMAKE_REQUIRED_VERSION ... " 85 | if automake --version >/dev/null; then 86 | VER=$(automake --version | grep -iw automake | sed "s/.* \([0-9.]*\)[-a-z0-9]*$/\1/") 87 | check_version $VER $AUTOMAKE_REQUIRED_VERSION 88 | else 89 | echo "not found" 90 | exit 1 91 | fi 92 | 93 | aclocal 94 | autoheader 95 | automake --add-missing --copy --foreign --force-missing 96 | autoconf 97 | -------------------------------------------------------------------------------- /configure.ac: -------------------------------------------------------------------------------- 1 | dnl configure.in 2 | dnl 3 | dnl $Id: configure.ac,v 1.3 2004/03/16 01:51:40 jp Exp $ 4 | dnl 5 | dnl Copyright (c) 2001 Jean-Pierre Lefebvre 6 | dnl and Remi Lefebvre 7 | dnl 8 | dnl atftp is free software; you can redistribute them and/or modify them 9 | dnl under the terms of the GNU General Public License as published by the 10 | dnl Free Software Foundation; either version 2 of the License, or (at your 11 | dnl option) any later version. 12 | 13 | AC_INIT([atftp],[0.8.0]) 14 | AC_CONFIG_SRCDIR([tftp.c]) 15 | AM_INIT_AUTOMAKE 16 | 17 | AC_SUBST(VERSION) 18 | AC_CONFIG_HEADERS(config.h) 19 | 20 | ISODATE=`date +%Y-%m-%d` 21 | AC_SUBST(ISODATE) 22 | 23 | dnl canonicalize the host 24 | AC_CANONICAL_HOST 25 | dnl AC_CANONICAL_TARGET 26 | PLATFORM="${host_vendor}-${host_cpu}-${host_os}" 27 | AC_SUBST(PLATFORM) 28 | 29 | dnl Additional argument 30 | AC_ARG_ENABLE(libreadline, 31 | [ --enable-libreadline enable readline support in client], 32 | [ case "${enableval}" in 33 | yes) libreadline=true ;; 34 | no) libreadline=false ;; 35 | esac], [libreadline=true]) 36 | 37 | AC_ARG_ENABLE(libwrap, 38 | [ --enable-libwrap enable libwrap support in server], 39 | [ case "${enableval}" in 40 | yes) libwrap=true ;; 41 | no) libwrap=false ;; 42 | esac], [libwrap=true]) 43 | 44 | AC_ARG_ENABLE(libpcre, 45 | [ --enable-libpcre enable libpcre2 support in server], 46 | [ case "${enableval}" in 47 | yes) libpcre=true ;; 48 | no) libpcre=false ;; 49 | esac], [libpcre=true]) 50 | 51 | AC_ARG_ENABLE(mtftp, 52 | [ --enable-mtftp enable mtftp support in server], 53 | [ case "${enableval}" in 54 | yes) mtftp=true ;; 55 | no) mtftp=false ;; 56 | esac], [mtftp=true]) 57 | 58 | AC_ARG_ENABLE(debug, 59 | [ --enable-debug enable debug code in server/client], 60 | [ case "${enableval}" in 61 | yes) debug=true ;; 62 | no) debug=false ;; 63 | esac], [debug=false]) 64 | 65 | dnl Check for programs 66 | AC_PROG_CC 67 | AC_GNU_SOURCE 68 | 69 | dnl Check for AIX 70 | AC_AIX 71 | 72 | CFLAGS="$CFLAGS -g -Wall -D_REENTRANT" 73 | 74 | if test x$debug = xtrue; then 75 | CFLAGS="$CFLAGS -O0 -DDEBUG" 76 | else 77 | if test -n "$auto_cflags"; then 78 | if test -n "$GCC"; then 79 | CFLAGS="$CFLAGS -g -O2 -Wall -Wno-implicit" 80 | else 81 | case "$host_os" in 82 | *hpux*) CFLAGS="$CFLAGS +O3" 83 | ;; 84 | *ultrix* | *osf*) CFLAGS="$CFLAGS -O -Olimit 2000" 85 | ;; 86 | *) CFLAGS="$CFLAGS -O2" 87 | ;; 88 | esac 89 | fi 90 | else 91 | CFLAGS="$CFLAGS -O2" 92 | fi 93 | fi 94 | 95 | case "$CC" in 96 | gcc*|clang*) CFLAGS="$CFLAGS -std=gnu89" 97 | ;; 98 | esac 99 | 100 | AC_PROG_MAKE_SET 101 | AC_PROG_INSTALL 102 | 103 | dnl enable mtftp support 104 | if test x$mtftp = xtrue; then 105 | AC_DEFINE([HAVE_MTFTP], 1, "Support MTFTP protocol") 106 | fi 107 | 108 | dnl Checks for libraries 109 | dnl Thread support is needed in the server 110 | AC_CHECK_LIB(pthread, pthread_create, [LIBPTHREAD=-lpthread], 111 | [AC_MSG_ERROR(not found)]) 112 | AC_SUBST(LIBPTHREAD) 113 | 114 | dnl If we want libreadline support 115 | if test x$libreadline = xtrue; then 116 | dnl Debian's readline is already linked to ncurses. It is not the case for 117 | dnl all other systems. 118 | AC_CHECK_LIB(readline, tgetent, LIBTERMCAP="", 119 | AC_CHECK_LIB(ncurses, tgetent, LIBTERMCAP=-lncurses, 120 | AC_CHECK_LIB(curses, tgetent, LIBTERMCAP=-lcurses, 121 | AC_CHECK_LIB(termcap, tgetent, LIBTERMCAP=-ltermcap, 122 | AC_MSG_RESULT(no))))) 123 | AC_SUBST(LIBTERMCAP) 124 | 125 | dnl Check for readline 126 | AC_CHECK_LIB(readline, readline, 127 | [LIBREADLINE=-lreadline] 128 | [AC_DEFINE([HAVE_READLINE], 1, 129 | "Support for readline in tftp client")], 130 | AC_MSG_RESULT(no), $LIBTERMCAP) 131 | AC_SUBST(LIBREADLINE) 132 | 133 | dnl Verify readline has completion support (this function changes from 134 | dnl release to release :( 135 | AC_CHECK_LIB(readline, rl_completion_matches, 136 | AC_DEFINE([HAVE_RL_COMPLETION_MATCHES], 1, "Use completion"), 137 | AC_CHECK_LIB(readline, completion_matches, 138 | AC_DEFINE([HAVE_COMPLETION_MATCHES], 1, 139 | "Use completion"), 140 | AC_MSG_RESULT(no), $LIBTERMCAP), 141 | $LIBTERMCAP) 142 | fi 143 | 144 | dnl If we want to compile libwrap stuff, check for libraries 145 | if test x$libwrap = xtrue; then 146 | dnl Checking to libwrap. Some systems don't define default values for 147 | dnl allow_severity and deny_severity so we need a somewhat more complicated 148 | dnl test here. We automatically link against nsl since libwrap is not 149 | dnl already linked with it on all systems. 150 | orig_LIBS="$LIBS" 151 | LIBS="-lnsl -lwrap" 152 | AC_MSG_CHECKING([for hosts_ctl in -lwrap]) 153 | AC_TRY_LINK([ 154 | #include 155 | int allow_severity; 156 | int deny_severity; 157 | ], 158 | hosts_ctl("", STRING_UNKNOWN, STRING_UNKNOWN, STRING_UNKNOWN); 159 | , 160 | LIBWRAP="-lnsl -lwrap" 161 | LIBS="$orig_LIBS" 162 | AC_MSG_RESULT(yes) 163 | AC_DEFINE([HAVE_WRAP], 1, "Support for libwrap") 164 | , 165 | LIBWRAP="" 166 | LIBS="$orig_LIBS" 167 | AC_MSG_RESULT(no) 168 | ) 169 | AC_SUBST(LIBWRAP) 170 | fi 171 | 172 | dnl If we want to compile pcre2 stuff, check for libraries 173 | if test x$libpcre = xtrue; then 174 | dnl Checking to pcre2. 175 | AC_CHECK_LIB(pcre2-8, pcre2_config_8, 176 | [LIBPCRE=-lpcre2-8] 177 | [AC_DEFINE([HAVE_PCRE], 1, 178 | "Support for libpcre2 pattern substitution")]) 179 | AC_SUBST(LIBPCRE) 180 | fi 181 | 182 | dnl Checks for header files. 183 | AC_HEADER_STDC 184 | AC_CHECK_HEADERS(sys/time.h sys/types.h sys/socket.h) 185 | AC_CHECK_HEADERS(arpa/inet.h arpa/tftp.h) 186 | AC_CHECK_HEADERS(getopt.h unistd.h signal.h pthread.h argz.h) 187 | AC_CHECK_HEADERS(netdb.h) 188 | AC_CHECK_HEADERS(readline/readline.h) 189 | AC_CHECK_HEADERS(readline/history.h) 190 | if test x$libwrap = xtrue; then 191 | AC_CHECK_HEADERS(tcpd.h) 192 | fi 193 | if test x$libpcre = xtrue; then 194 | AC_CHECK_HEADERS([pcre2.h],[],[],[#define PCRE2_CODE_UNIT_WIDTH 8]) 195 | fi 196 | 197 | dnl Checks for typedefs, structures, and compiler characteristics. 198 | AC_C_CONST 199 | AC_TYPE_SIZE_T 200 | AC_HEADER_TIME 201 | AC_TYPE_SIGNAL 202 | 203 | dnl Checks for library functions. 204 | AC_CHECK_FUNCS(strchr memcpy strstr strcmp strncmp strncpy strlen) 205 | AC_CHECK_FUNCS(strncasecmp strcasecmp strncmp) 206 | AC_CHECK_FUNCS(socket gethostbyname gethostbyname_r gethostbyaddr) 207 | 208 | dnl Write platform to file for support reporting 209 | AC_OUTPUT_COMMANDS([ 210 | outfile=PLATFORM 211 | tmpfile=${outfile} 212 | cat > $tmpfile << _EOF_ 213 | $PLATFORM 214 | _EOF_ 215 | ], [PLATFORM=$PLATFORM]) 216 | 217 | AC_OUTPUT(Makefile test/Makefile redhat/atftp.spec) 218 | -------------------------------------------------------------------------------- /debian/atftp.docs: -------------------------------------------------------------------------------- 1 | TODO 2 | README 3 | README.CVS 4 | README.MCAST 5 | -------------------------------------------------------------------------------- /debian/atftp.files: -------------------------------------------------------------------------------- 1 | usr/bin/atftp 2 | usr/share/man/man1/atftp.1 3 | -------------------------------------------------------------------------------- /debian/atftpd.README.Debian: -------------------------------------------------------------------------------- 1 | atftpd for Debian 2 | ----------------- 3 | 4 | atftpd uses /srv/tftp by default as base directory. You can change 5 | that by editing /etc/inetd.conf or with 'dpkg-reconfigure atftpd'. 6 | 7 | Please note that inetd.conf will not be modified by a dpkg-reconfigure, if 8 | there's already an entry. 9 | Also, /etc/default/atftpd will be created if it does not exist. So if 10 | you want 'dpkg-reconfigure atftpd' to create /etc/default/atftpd or 11 | /etc/inetd.conf you should remove the file or delete the tftp line. 12 | 13 | Remember that you must give the directory appropriate permissions in order 14 | to be able to read/write files according to your needs (owner=nobody). 15 | 16 | The /srv/tftp directory is not created by the package. You need to 17 | create it and give appropriate permissions by hand. 18 | 19 | -------------------------------------------------------------------------------- /debian/atftpd.conffiles: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madmartin/atftp/d5c27eb7a9695d83569767e27ef69674173db39a/debian/atftpd.conffiles -------------------------------------------------------------------------------- /debian/atftpd.config: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | . /usr/share/debconf/confmodule 4 | db_version 2.0 5 | 6 | # Do not ask if you need to configure atftp (Bug#266329) 7 | 8 | #db_beginblock 9 | #db_input high atftpd/configure || true 10 | #db_endblock 11 | #db_go 12 | 13 | #db_get atftpd/configure 14 | #if [ "$RET" = "true" ]; then 15 | 16 | db_beginblock 17 | db_input medium atftpd/use_inetd || true 18 | db_endblock 19 | db_go 20 | 21 | db_get atftpd/use_inetd 22 | 23 | if [ "$RET" = "true" ]; then 24 | db_beginblock 25 | db_input low atftpd/tftpd-timeout || true 26 | db_endblock 27 | db_go 28 | fi 29 | 30 | db_beginblock 31 | db_input low atftpd/port || true 32 | db_input low atftpd/retry-timeout || true 33 | db_input low atftpd/maxthread || true 34 | db_input low atftpd/timeout || true 35 | db_input low atftpd/tsize || true 36 | db_input low atftpd/blksize || true 37 | db_input low atftpd/multicast || true 38 | db_endblock 39 | db_go 40 | 41 | db_get atftpd/multicast 42 | if [ "$RET" = "true" ]; then 43 | db_beginblock 44 | db_input low atftpd/mcast_port || true 45 | db_input medium atftpd/mcast_addr || true 46 | db_input medium atftpd/ttl || true 47 | db_endblock 48 | db_go 49 | fi 50 | 51 | db_beginblock 52 | db_input low atftpd/verbosity || true 53 | db_input medium atftpd/basedir || true 54 | db_input low atftpd/logtofile || true 55 | db_endblock 56 | db_go 57 | 58 | db_get atftpd/logtofile 59 | if [ "$RET" = "true" ]; then 60 | db_beginblock 61 | db_input low atftpd/logfile || true 62 | db_endblock 63 | db_go 64 | fi 65 | #fi 66 | -------------------------------------------------------------------------------- /debian/atftpd.docs: -------------------------------------------------------------------------------- 1 | TODO 2 | README 3 | README.CVS 4 | README.MCAST 5 | README.PCRE 6 | FAQ 7 | BUGS 8 | test/mtftp.conf 9 | test/pcre_pattern.txt 10 | -------------------------------------------------------------------------------- /debian/atftpd.files: -------------------------------------------------------------------------------- 1 | usr/sbin/atftpd 2 | usr/sbin/in.tftpd 3 | usr/share/man/man8/atftpd.8 4 | usr/share/man/man8/in.tftpd.8 5 | -------------------------------------------------------------------------------- /debian/atftpd.init.d: -------------------------------------------------------------------------------- 1 | #! /bin/sh 2 | # 3 | # atftpd - Script to launch atftpd server. 4 | # 5 | ### BEGIN INIT INFO 6 | # Provides: atftpd 7 | # Required-Start: $syslog $network $remote_fs 8 | # Required-Stop: $syslog $network $remote_fs 9 | # Should-Start: $local_fs 10 | # Should-Stop: $local_fs 11 | # Default-Start: 2 3 4 5 12 | # Default-Stop: 0 1 6 13 | # Short-Description: Launch atftpd server 14 | # Description: Launch atftpd server, a TFTP server useful 15 | # for network boot (PXE). 16 | ### END INIT INFO 17 | 18 | PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin 19 | DAEMON=/usr/sbin/atftpd 20 | NAME=atftpd 21 | DESC="Advanced TFTP server" 22 | USE_INETD=true 23 | OPTIONS="" 24 | 25 | test -f $DAEMON || exit 0 26 | 27 | set -e 28 | 29 | if [ -f /etc/default/atftpd ]; then 30 | . /etc/default/atftpd 31 | fi 32 | 33 | if [ "$USE_INETD" = "true" ]; then 34 | exit 0; 35 | fi 36 | 37 | # Make sure we have --daemon when not using inetd 38 | echo "$OPTIONS"|grep -q -- --daemon || OPTIONS="--daemon $OPTIONS" 39 | 40 | case "$1" in 41 | start) 42 | echo -n "Starting $DESC: " 43 | start-stop-daemon --start --oknodo --quiet --exec $DAEMON -- $OPTIONS 44 | echo "$NAME." 45 | ;; 46 | stop) 47 | echo -n "Stopping $DESC: " 48 | start-stop-daemon --stop --oknodo --quiet --exec $DAEMON 49 | echo "$NAME." 50 | ;; 51 | restart|reload|force-reload) 52 | echo -n "Restarting $DESC: " 53 | start-stop-daemon --stop --oknodo --quiet --exec $DAEMON 54 | sleep 1 55 | start-stop-daemon --start --oknodo --quiet --exec $DAEMON -- $OPTIONS 56 | echo "$NAME." 57 | ;; 58 | *) 59 | N=/etc/init.d/$NAME 60 | echo "Usage: $N {start|stop|restart|reload|force-reload}" >&2 61 | exit 1 62 | ;; 63 | esac 64 | 65 | exit 0 66 | -------------------------------------------------------------------------------- /debian/atftpd.postinst: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | # 3 | # TODO: 4 | # - error checking on values provided by debconf frontend 5 | 6 | BASEDIR=/srv/tftp 7 | DAEMON="--daemon" 8 | 9 | . /usr/share/debconf/confmodule 10 | db_version 2.0 11 | 12 | # Do not ask if we want to configure it 13 | #db_get atftpd/configure 14 | #if [ "$RET" = "true" ]; then 15 | 16 | db_get atftpd/use_inetd 17 | if [ "$RET" ]; then 18 | if [ "$RET" = "true" ]; then 19 | USE_INETD=true 20 | else 21 | USE_INETD=false 22 | fi 23 | else 24 | USE_INETD=true 25 | fi 26 | 27 | db_get atftpd/port 28 | if [ "$RET" ]; then 29 | TFTPD_PORT="--port $RET" 30 | fi 31 | 32 | db_get atftpd/tftpd-timeout 33 | if [ "$RET" ]; then 34 | TFTPD_TIMEOUT="--tftpd-timeout $RET" 35 | fi 36 | 37 | db_get atftpd/retry-timeout 38 | if [ "$RET" ]; then 39 | RETRY_TIMEOUT="--retry-timeout $RET" 40 | fi 41 | 42 | db_get atftpd/maxthread 43 | if [ "$RET" ]; then 44 | MAXTHREAD="--maxthread $RET" 45 | fi 46 | 47 | db_get atftpd/timeout 48 | if [ "$RET" != "true" ]; then 49 | NOTIMEOUT="--no-timeout" 50 | fi 51 | 52 | db_get atftpd/tsize 53 | if [ "$RET" != "true" ]; then 54 | NOTSIZE="--no-tsize" 55 | fi 56 | 57 | db_get atftpd/blksize 58 | if [ "$RET" != "true" ]; then 59 | NOBLKSIZE="--no-blksize" 60 | fi 61 | 62 | db_get atftpd/multicast 63 | if [ "$RET" != "true" ]; then 64 | NOMCAST="--no-multicast" 65 | else 66 | db_get atftpd/mcast_port 67 | if [ "$RET" ]; then 68 | MCASTPORT="--mcast-port $RET" 69 | fi 70 | db_get atftpd/mcast_addr 71 | if [ "$RET" ]; then 72 | MCASTADDR="--mcast-addr $RET" 73 | fi 74 | db_get atftpd/ttl 75 | if [ "$RET" ]; then 76 | MCASTTTL="--mcast-ttl $RET" 77 | fi 78 | fi 79 | 80 | db_get atftpd/verbosity 81 | if [ "$RET" ]; then 82 | RET=`echo $RET | cut -f1 -d ' '` 83 | VERBOSITY="--verbose=$RET" 84 | fi 85 | 86 | db_get atftpd/logtofile 87 | if [ "$RET" = "true" ]; then 88 | db_get atftpd/logfile 89 | if [ "$RET" ]; then 90 | LOGFILE="--logfile $RET" 91 | # if the file doesn't exist, create it 92 | if [ ! -f $RET ]; then 93 | touch $RET 94 | chown nobody:nogroup $RET 95 | chmod 640 $RET 96 | fi 97 | # modify the logrotate file 98 | cat >/etc/logrotate.d/atftpd < /etc/default/atftpd 133 | echo "OPTIONS=\"$DAEMON $TFTPD_PORT $RETRY_TIMEOUT $NOTIMEOUT $NOTSIZE $NOBLKSIZE $NOMCAST \ 134 | $MCASTPORT $MCASTADDR $MCASTTTL $MAXTHREAD $VERBOSITY $LOGFILE $BASEDIR\""|tr -s " " >> /etc/default/atftpd 135 | fi 136 | update-inetd --disable tftp 137 | else 138 | INETOPTS=`echo "$TFTPD_TIMEOUT $RETRY_TIMEOUT $NOTIMEOUT $NOTSIZE $NOBLKSIZE $NOMCAST $MCASTPORT $MCASTADDR $MCASTTTL $MAXTHREAD $VERBOSITY $LOGFILE $BASEDIR"|tr -s " "` 139 | update-inetd --group BOOT --add "tftp dgram udp4 wait nobody /usr/sbin/tcpd /usr/sbin/in.tftpd $INETOPTS" 140 | if [ ! -f /etc/default/atftpd ]; then 141 | echo "USE_INETD=true" > /etc/default/atftpd 142 | echo "OPTIONS=\"$INETOPTS\""|tr -s " " >> /etc/default/atftpd 143 | fi 144 | fi 145 | 146 | #DEBHELPER# 147 | 148 | # tell debconf we are done. otherwise, it hangs waiting for the daemon. 149 | db_stop; 150 | 151 | exit 0; 152 | -------------------------------------------------------------------------------- /debian/atftpd.postrm: -------------------------------------------------------------------------------- 1 | #!/bin/sh -e 2 | 3 | 4 | if [ "$1" = "purge" ]; then 5 | # If netbase is not installed, then we don't need to do the remove. 6 | if command -v update-inetd >/dev/null 2>&1; 7 | then 8 | update-inetd --group BOOT --remove "tftp.*/usr/sbin/in.tftpd.*" 9 | fi 10 | 11 | BASEDIR="/var/lib/tftpd" 12 | if [ -f /usr/share/debconf/confmodule ]; then 13 | . /usr/share/debconf/confmodule 14 | db_get atftpd/basedir 15 | if [ "$RET" ]; then 16 | BASEDIR="$RET" 17 | fi 18 | fi 19 | 20 | if [ -d $BASEDIR ]; then 21 | rmdir --ignore-fail-on-non-empty $BASEDIR 22 | fi 23 | 24 | # logrotate 25 | rm -f /etc/logorotate.d/atftpd 26 | 27 | # init.d config file 28 | if [ -r /etc/default/atftpd ]; then 29 | rm -f /etc/default/atftpd 30 | fi 31 | fi 32 | 33 | #DEBHELPER# 34 | -------------------------------------------------------------------------------- /debian/atftpd.prerm: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | # Stops daemon if it is running under our control 6 | if [ -x /etc/init.d/atftpd ]; then 7 | if [ -x /usr/sbin/invoke-rc.d ]; then 8 | invoke-rc.d --quiet atftpd stop 9 | else 10 | /etc/init.d/atftpd stop 11 | fi 12 | fi 13 | 14 | #DEBHELPER# 15 | 16 | exit 0 17 | -------------------------------------------------------------------------------- /debian/atftpd.templates: -------------------------------------------------------------------------------- 1 | Template: atftpd/use_inetd 2 | Type: boolean 3 | Default: true 4 | _Description: Should the server be started by inetd? 5 | atftpd can be started by the inetd superserver or as a daemon and handle 6 | incoming connections by itself. The latter is only recommend for very high 7 | usage server. 8 | 9 | Template: atftpd/tftpd-timeout 10 | Type: string 11 | Default: 300 12 | _Description: Server timeout: 13 | How many seconds the main thread waits before exiting. 14 | 15 | Template: atftpd/retry-timeout 16 | Type: string 17 | Default: 5 18 | _Description: Retry timeout: 19 | How many seconds to wait for a reply before retransmitting a packet. 20 | 21 | Template: atftpd/maxthread 22 | Type: string 23 | Default: 100 24 | _Description: Maximum number of threads: 25 | Maximum number of concurrent threads that can be running. 26 | 27 | Template: atftpd/verbosity 28 | Type: select 29 | Choices: 7 (LOG_DEBUG), 6 (LOG_INFO), 5 (LOG_NOTICE), 4 (LOG_WARNING), 1 (LOG_ALERT) 30 | Default: 5 (LOG_NOTICE) 31 | _Description: Verbosity level: 32 | Level of logging. 7 logs everything including debug logs. 1 will log only 33 | the system critical logs. 5 (LOG_NOTICE) is the default value. 34 | 35 | Template: atftpd/timeout 36 | Type: boolean 37 | Default: true 38 | _Description: Enable 'timeout' support? 39 | 40 | Template: atftpd/tsize 41 | Type: boolean 42 | Default: true 43 | _Description: Enable 'tsize' support? 44 | 45 | Template: atftpd/blksize 46 | Type: boolean 47 | Default: true 48 | _Description: Enable 'block size' support? 49 | 50 | Template: atftpd/multicast 51 | Type: boolean 52 | Default: true 53 | _Description: Enable multicast support? 54 | 55 | Template: atftpd/ttl 56 | Type: string 57 | Default: 1 58 | _Description: TTL for multicast packets: 59 | 60 | Template: atftpd/port 61 | Type: string 62 | Default: 69 63 | _Description: Port to listen for tftp request: 64 | 65 | Template: atftpd/mcast_port 66 | Type: string 67 | Default: 1758 68 | _Description: Port range for multicast file transfer: 69 | Multicast transfer will use any available port in a given set. For 70 | example, "2000-2003, 3000" allow atftpd to use port 2000 to 2003 and 3000. 71 | 72 | Template: atftpd/mcast_addr 73 | Type: string 74 | Default: 239.239.239.0-255 75 | _Description: Address range for multicast transfer: 76 | Multicast transfer will use any available addresses from a given set of 77 | addresses. Syntax is "a.b.c.d-d,a.b.c.d,..." 78 | 79 | Template: atftpd/logtofile 80 | Type: boolean 81 | Default: false 82 | _Description: Log to file instead of syslog? 83 | If your server does intensive tftp file serving, it is a good idea to 84 | accept here. That will avoid cluttering your syslog with tftpd logs. 85 | 86 | Template: atftpd/logfile 87 | Type: string 88 | Default: /var/log/atftpd.log 89 | _Description: Log file: 90 | A file where atftpd will write its logs. This file will be made writable for 91 | the user 'nobody' and group 'nogroup'. 92 | 93 | Template: atftpd/basedir 94 | Type: string 95 | Default: /srv/tftp 96 | _Description: Base directory: 97 | The directory tree from where atftpd can serve files. That directory must 98 | be world readable. 99 | -------------------------------------------------------------------------------- /debian/changelog: -------------------------------------------------------------------------------- 1 | atftp (0.7.dfsg-9.3) unstable; urgency=low 2 | 3 | * Non-maintainer upload. 4 | * Apply patch listen on requested port when in daemon mode. 5 | Thanks to Len Sorensen. (Closes: #609813) 6 | 7 | -- tony mancill Wed, 12 Jan 2011 20:58:05 -0800 8 | 9 | atftp (0.7.dfsg-9.2) unstable; urgency=low 10 | 11 | * Non-maintainer upload. 12 | * Fixed use of sendto() over a connected datagram socket on FreeBSD 13 | (closes: #598474). 14 | 15 | -- Giovanni Mascellani Mon, 04 Oct 2010 16:46:32 +0200 16 | 17 | atftp (0.7.dfsg-9.1) unstable; urgency=low 18 | 19 | * Non-maintainer upload. 20 | * Apply IPv6 support patch by Ben Hutchings. Closes: #580473 21 | * Add AC_GNU_SOURCE to configure.ac to address FTBFS. 22 | - Patches applied directly to sources to minimize changes for NMU, 23 | as the current Debian packaging does not include a patch system. 24 | 25 | -- tony mancill Wed, 15 Sep 2010 21:24:52 -0700 26 | 27 | atftp (0.7.dfsg-9) unstable; urgency=medium 28 | 29 | * urgency=medium RC bug. 30 | * use rmdir instead of rm in postrm. Closes: #573992, #574211 31 | * added $remote_fs in Required-Start 32 | 33 | -- Ludovic Drolez Mon, 29 Mar 2010 18:55:55 +0200 34 | 35 | atftp (0.7.dfsg-8) unstable; urgency=low 36 | 37 | * depends on libreadline-dev. Closes: #553729 38 | * Purge empty dir. Closes: #531282 39 | * /srv/tftp is now the default tftp root data directory. Closes: #537642 40 | * Updated cs.po. Closes: #534959 41 | * Updated config.sub .guess. Closes: #536295 42 | * Fixed a typo in the help screen. Closes: #537405 43 | * Make sure we have the --daemon option before starting atftpd. 44 | Closes: #535604 45 | 46 | -- Ludovic Drolez Tue, 21 Aug 2009 17:03:24 +0200 47 | 48 | atftp (0.7.dfsg-7) unstable; urgency=low 49 | 50 | * Crash fix. Closes: #514521 51 | * Updated sv.po. Closes: #503348 52 | * Added support for logging to stdout. Closes: #484739 53 | * Added the --listen-local patch. Closes: #366632 54 | * Recommends inet-superserver. Closes: #516407 55 | 56 | -- Ludovic Drolez Wed, 01 Apr 2009 17:03:07 +0200 57 | 58 | atftp (0.7.dfsg-6) unstable; urgency=medium 59 | 60 | * Urgency = medium because of a grave bug 61 | * Now generate a cleaner /etc/default/atftpd file. Closes: #489757 62 | * Do not overwrite /etc/default/atftpd and inetd.conf. Closes: #490152 63 | * The basedir is now created with proper permissions. Upload 64 | feature tested. Closes: #489757 65 | * Updated sv.po. Closes: #491757 66 | 67 | -- Ludovic Drolez Tue, 22 Jul 2008 19:07:56 +0200 68 | 69 | atftp (0.7.dfsg-5) unstable; urgency=medium 70 | 71 | * inetd.conf: change udp to udp4. Closes: #484932 72 | * fixed pcre substitutions. Closes: #473777 73 | 74 | -- Ludovic Drolez Fri, 13 Jun 2008 16:00:57 +0200 75 | 76 | atftp (0.7.dfsg-4) unstable; urgency=medium 77 | 78 | * Urgency=medium because of RC bug fixed 79 | * Choosed /var/lib/tftpboot as default tftp directory, and removed 80 | the provides field. Closes: #455263, #411322 81 | * Moved the watch file. Closes: #449674 82 | * Fixed incorrect options handling thanks to Hollis Blanchard. 83 | Closes: #332621 84 | * Updated pt.po. Closes: #443653 85 | 86 | -- Ludovic Drolez Tue, 18 Dec 2007 18:49:33 +0100 87 | 88 | atftp (0.7.dfsg-3) unstable; urgency=high 89 | 90 | * Removed the inetd dependency. 91 | * Added Leo Weppelman select patch. Closes: #411456 92 | * Fixed the FTBFS. Closes: #436310 93 | 94 | -- Ludovic Drolez Mon, 6 Aug 2007 20:52:06 +0200 95 | 96 | atftp (0.7.dfsg-2) unstable; urgency=medium 97 | 98 | * Use CLOCKS_PER_SEC instead of CLK_TCK. Fixed a FTBFS. Closes: #420900 99 | * Re-added a kFreeBSD patch lost by a NMU !!! Closes: #404063, #402700 100 | * New debconf translations. Closes: #410212, #414112, #422416 101 | 102 | -- Ludovic Drolez Fri, 18 May 2007 17:59:01 +0200 103 | 104 | atftp (0.7.dfsg-1.2) unstable; urgency=low 105 | 106 | * Non-maintainer upload to fix a pending l10n issues that affects the 107 | experimental Debian i18n server. 108 | * Debconf translations: 109 | - Japanese fixed. Closes: #410525 110 | 111 | -- Christian Perrier Sun, 11 Feb 2007 15:08:39 +0100 112 | 113 | atftp (0.7.dfsg-1.1) unstable; urgency=low 114 | 115 | * Non-maintainer upload to fix longstanding l10n issues 116 | * Debconf templates translations: 117 | - German updated. Closes: #399964 118 | - Japanense updated. Closes: #402616 119 | - Dutch updated. Closes: #392215 120 | - French updated. Closes: #393740 121 | - Russian updated. Closes: #404426 122 | - Spanish updated. Closes: #402098 123 | 124 | -- Christian Perrier Sat, 20 Jan 2007 12:48:31 +0100 125 | 126 | atftp (0.7.dfsg-1) unstable; urgency=medium 127 | 128 | * Integrated the NMUs. Closes: #382683, #365188, #389830 129 | * If netbase is not installed, then we don't need to use update-inetd. 130 | Closes: #388295 131 | * Bump Standards-Version to 3.7.2. 132 | * Add debconf-updatepo to the rules. 133 | * Russian translation of debconf messages thanks to Yuri Kozlov. 134 | Closes: #368498 135 | 136 | -- Ludovic Drolez Mon, 2 Oct 2006 00:31:23 +0200 137 | 138 | atftp (0.7.dfsg-0.2) unstable; urgency=low 139 | 140 | * Non-maintainer upload. 141 | * debian/control: Remove netkit-inetd recommends, and make the netbase 142 | dependency versioned. netbase provides the appropriate inetd 143 | dependency. Closes: #382683. 144 | 145 | -- Roger Leigh Sun, 20 Aug 2006 17:11:26 +0100 146 | 147 | atftp (0.7.dfsg-0.1) unstable; urgency=low 148 | 149 | * Non-maintainer upload. 150 | * Repackage upstream without RFC (Closes: #365188) 151 | 152 | -- Julien Danjou Thu, 1 Jun 2006 15:53:11 +0200 153 | 154 | atftp (0.7-11) unstable; urgency=low 155 | 156 | * added a patch for freebsd. Closes: #342391 157 | * added debconf Portuguese translation. Closes: #342284 158 | 159 | -- Ludovic Drolez Tue, 13 Dec 2005 16:29:05 +0100 160 | 161 | atftp (0.7-10) unstable; urgency=low 162 | 163 | * DH_COMPAT=4 and added ${misc:Depends}. Closes: #331747 164 | * Debconf Swedish translation update. Closes: #330263 165 | 166 | -- Ludovic Drolez Fri, 7 Oct 2005 15:00:35 +0200 167 | 168 | atftp (0.7-9) unstable; urgency=medium 169 | 170 | * Random segfaults fixed. Closes: #271816 171 | * Now only recommend netkid-inetd. Closes: #313208 172 | * Updated the Vietnamese debconf translation. Closes: #313122 173 | 174 | -- Ludovic Drolez Tue, 21 Jun 2005 21:51:23 +0200 175 | 176 | atftp (0.7-8) unstable; urgency=low 177 | 178 | * Typos removed from atftpd.templates. Closes: #309468 179 | * Added the Vietnamese translation for debconf. Closes: #309461 180 | * Thanks to Clytie Siddall for submitting the two bugs above. 181 | 182 | -- Ludovic Drolez Tue, 7 Jun 2005 21:31:25 +0200 183 | 184 | atftp (0.7-7) unstable; urgency=low 185 | 186 | * Fixed a FTBFS on amd64. Closes: #297549 187 | * Added Japanese and Brazilian debconf translations. Closes: #304280,#297038 188 | 189 | -- Ludovic Drolez Tue, 12 Apr 2005 12:55:47 +0200 190 | 191 | atftp (0.7-6) unstable; urgency=low 192 | 193 | * Segfault fixed on AMD64. Closes: Bug#291829 194 | * debian 'watch' file added. 195 | 196 | -- Ludovic Drolez Wed, 26 Jan 2005 19:12:44 +0100 197 | 198 | atftp (0.7-5) unstable; urgency=high 199 | 200 | * Ugency=high because of a RC bug fixed. 201 | * Removed a bashism in the postinst. Closes: #289633 202 | * Czech po-debconf translation added by Miroslav Kure. Closes: #288014 203 | * Danish po-debconf translation added by Morten Brix Pedersen. 204 | Closes: #288133 205 | * Copyright fixed. Closes: #290062 206 | 207 | -- Ludovic Drolez Tue, 11 Jan 2005 12:19:27 +0100 208 | 209 | atftp (0.7-4) unstable; urgency=low 210 | 211 | * updated all po-debconf translations. Closes: #281561 212 | * polish debconf translation added. Thanks to Bartosz Fenski. 213 | * added debconf support for setting the multicast TTL value 214 | * default mcast subnet changed to 239.239.239.0/24 since some routers 215 | do not seem to like 239.255.0.0/24 216 | 217 | -- Ludovic Drolez Mon, 28 Dec 2004 19:11:57 +0100 218 | 219 | atftp (0.7-3) unstable; urgency=low 220 | 221 | * /etc/default/atftpd removed on purge. Closes: #279707 222 | * purging stops atftpd. Closes: #275258 223 | * punctuation modified. Closes: #275692 224 | * updated the German debconf translation. Closes: #275691 225 | 226 | -- Ludovic Drolez Fri, 5 Nov 2004 14:32:57 +0100 227 | 228 | atftp (0.7-2) unstable; urgency=medium 229 | 230 | * Patched tftp.c, to have an exit status !=0 when an error occurs 231 | * Data corruption bug in multicast mode fixed. Closes: #275052 232 | Urgency set to medium because of this bug. 233 | * Typos in description corrected. Closes: #272565 234 | * Dutch debconf translation added. Closes: #245913 235 | * Debconf: removed the initial question and changed priority 236 | levels. Closes: #266329 237 | 238 | -- Ludovic Drolez Sun, 26 Sep 2004 14:25:40 +0200 239 | 240 | atftp (0.7-1) unstable; urgency=low 241 | 242 | * New maintainer. Closes: Bug#227258. 243 | * New release. Closes: Bug#263221, Bug#155300, Bug#180461, Bug#238196. 244 | 245 | -- Ludovic Drolez Tue, 14 Sep 2004 18:50:20 +0200 246 | 247 | atftp (0.6.2) unstable; urgency=low 248 | 249 | * Fixed local and remote buffer overflow (Closes: #196304) 250 | 251 | -- Remi Lefebvre Sun, 15 Jun 2003 16:26:13 -0400 252 | 253 | atftp (0.6.1.1) unstable; urgency=low 254 | 255 | * NMU 256 | * New config.guess, config.sub. Add libwrap-dev to build-depends. 257 | Closes: #142949 258 | 259 | -- LaMont Jones Wed, 24 Apr 2002 00:23:52 -0600 260 | 261 | atftp (0.6.1) unstable; urgency=low 262 | 263 | * Fixed French translations for real this time (Closes: #136339). 264 | 265 | -- Remi Lefebvre Sun, 13 Apr 2002 14:09:23 -0500 266 | 267 | atftp (0.6) unstable; urgency=low 268 | 269 | * Update of German translations (Thanks to Christian Neumair) 270 | (Closes: #139080) 271 | * Update of French translations (Thanks to Denis Barbier) (Closes: #136339). 272 | * Fix autoconf issue related to RedHat 273 | * Fix bug associated with very small value of blksize 274 | * Fix server to allow logging to stdout and stderr in daemon mode 275 | * Add --no-fork option for use in conjonction with --daemon 276 | * Add command line option to overide the default nobody.nogroup user 277 | * Fix bug where server segfault if nobody.nogroup doesn't exist 278 | * Fix grave bug with libwrap support causing server to segfault 279 | 280 | -- Remi Lefebvre Sun, 31 Mar 2002 13:55:54 -0500 281 | 282 | atftp (0.5) unstable; urgency=low 283 | 284 | * Filename length limit increased (Closes: #124052). 285 | * General bug fixes. 286 | * Autoconf enhancement. 287 | * Libwrap support (for spawned thread). 288 | * Multicast support (not tested thoroughly). 289 | * Be less picky about removing existing tftp entries in inetd.conf 290 | (Closes: #107053). 291 | * General spelling fixes in the english templates (Closes: #109475). 292 | * Swedish templates (Thanks to Martin Sjogren) (Closes: #109523). 293 | * Portuguese templates (Thanks to Andre Luis Lopes) (Closes: #107042). 294 | 295 | -- Remi Lefebvre Sat, 18 Aug 2001 23:13:25 -0400 296 | 297 | atftp (0.4) unstable; urgency=low 298 | 299 | * Now handle SIGINT and SIGTERM in the client and server. 300 | * Improved readline support. 301 | * Added status info in the client. 302 | * Added daemon mode. 303 | * Added spanish templates (Thanks to Carlos Valdivia Yague) (Closes: #103043). 304 | * Added "Provides: tftpd" (Closes: #100676). 305 | * Added french templates. 306 | * Added german templates (Thanks to Sebastian Feltel) (Closes: #100066). 307 | * Fixed config script (Closes: #93398). 308 | * Moved over to autoconf (Thanks to Jeffrey Fulmer). 309 | 310 | -- Remi Lefebvre Sat, 16 Jun 2001 01:27:27 -0500 311 | 312 | atftp (0.3) unstable; urgency=low 313 | 314 | * Fixed format string bug. 315 | * Fixed an uninitialised variable bug. 316 | * Fixed name resolution. 317 | 318 | -- Remi Lefebvre Sun, 11 Feb 2001 13:08:34 -0500 319 | 320 | atftp (0.2) unstable; urgency=low 321 | 322 | * Add statistics collecting functions to the server. 323 | * Added support for debconf. 324 | * Bugfixes. 325 | 326 | -- Remi Lefebvre Wed, 27 Dec 2000 11:44:02 -0500 327 | 328 | atftp (0.1) unstable; urgency=low 329 | 330 | * Initial Release (Closes: #69486). 331 | 332 | -- Remi Lefebvre Fri, 30 Jun 2000 14:32:15 -0400 333 | 334 | Local variables: 335 | mode: debian-changelog 336 | End: 337 | -------------------------------------------------------------------------------- /debian/control: -------------------------------------------------------------------------------- 1 | Source: atftp 2 | Section: net 3 | Priority: extra 4 | Maintainer: Ludovic Drolez 5 | Build-Depends: libreadline-dev, debhelper (>= 5), po-debconf, libwrap0-dev, libpcre3-dev 6 | Standards-Version: 3.8.4 7 | 8 | Package: atftp 9 | Architecture: any 10 | Depends: ${shlibs:Depends}, ${misc:Depends} 11 | Description: advanced TFTP client 12 | Interactive client for the Trivial File Transfer Protocol (TFTP). Its 13 | usage is mainly for testing and debugging the Atftp server. TFTP client 14 | is usually implemented in BIOS and bootstraps programs like pxelinux when 15 | booting from LAN. Atftp also supports non-interactive invocation for 16 | easy use in scripts. 17 | 18 | Package: atftpd 19 | Architecture: any 20 | Depends: ${shlibs:Depends}, ${misc:Depends}, update-inetd 21 | Recommends: inet-superserver 22 | Conflicts: tftpd 23 | Suggests: logrotate 24 | Description: advanced TFTP server 25 | Multi-threaded TFTP server implementing all options (option extension and 26 | multicast) as specified in RFC1350, RFC2090, RFC2347, RFC2348 and RFC2349. 27 | Atftpd also supports multicast protocol known as mtftp, defined in the PXE 28 | specification. The server supports being started from inetd(8) as well as 29 | in daemon mode using init scripts. 30 | -------------------------------------------------------------------------------- /debian/copyright: -------------------------------------------------------------------------------- 1 | This package was debianized by Remi Lefebvre on 2 | Fri, 30 Jun 2000 14:32:15 -0400. 3 | 4 | It was downloaded from ftp://ftp.mamalinux.com/pub/atftp/ 5 | 6 | Upstream Authors: Jean-Pierre Lefebvre 7 | Remi Lefebvre 8 | 9 | Copyright: 10 | 11 | Copyright (c) 2000 Jean-Pierre Lefebvre 12 | and Remi Lefebvre 13 | 14 | License: 15 | 16 | atftp is free software; you can redistribute them and/or modify them under 17 | the terms of the GNU General Public License as published by the Free Software 18 | Foundation; either version 2 of the License, or (at your option) any later 19 | version. 20 | 21 | You can find a copy of the GPL at /usr/share/common-licenses/GPL 22 | -------------------------------------------------------------------------------- /debian/po/POTFILES.in: -------------------------------------------------------------------------------- 1 | [type: gettext/rfc822deb] atftpd.templates 2 | [type: gettext/rfc822deb] atftpd.templates 3 | -------------------------------------------------------------------------------- /debian/po/fi.po: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # Esko Arajärvi , 2011. 5 | msgid "" 6 | msgstr "" 7 | "Project-Id-Version: PACKAGE VERSION\n" 8 | "Report-Msgid-Bugs-To: ldrolez@debian.org\n" 9 | "POT-Creation-Date: 2006-10-02 00:46+0200\n" 10 | "PO-Revision-Date: 2011-04-05 22:11+0300\n" 11 | "Last-Translator: Esko Arajärvi \n" 12 | "Language-Team: debian-10n-finnish@lists.debian.org\n" 13 | "Language: fi\n" 14 | "MIME-Version: 1.0\n" 15 | "Content-Type: text/plain; charset=UTF-8\n" 16 | "Content-Transfer-Encoding: 8bit\n" 17 | "Plural-Forms: nplurals=2; plural=(n != 1);\n" 18 | "X-Generator: Virtaal 0.6.1\n" 19 | 20 | #. Type: boolean 21 | #. Description 22 | #: ../atftpd.templates:1001 23 | msgid "Should the server be started by inetd?" 24 | msgstr "Käynnistetäänkö palvelin inetdin avulla?" 25 | 26 | #. Type: boolean 27 | #. Description 28 | #: ../atftpd.templates:1001 29 | msgid "" 30 | "atftpd can be started by the inetd superserver or as a daemon and handle " 31 | "incoming connections by itself. The latter is only recommend for very high " 32 | "usage server." 33 | msgstr "" 34 | "atftp voidaan käynnistää inetd-superpalvelimen avulla tai ajaa itsenäisenä " 35 | "taustaohjelmana, joka käsittelee yhteydenotot itse. Jälkimmäistä " 36 | "suositellaan vain hyvin raskaassa käytössä." 37 | 38 | #. Type: string 39 | #. Description 40 | #: ../atftpd.templates:2001 41 | msgid "Server timeout:" 42 | msgstr "Palvelimen aikakatkaisu:" 43 | 44 | #. Type: string 45 | #. Description 46 | #: ../atftpd.templates:2001 47 | msgid "How many seconds the main thread waits before exiting." 48 | msgstr "" 49 | "Valitse kuinka monta sekuntia ohjelma odottaa ennen kuin se sulkee itsensä." 50 | 51 | #. Type: string 52 | #. Description 53 | #: ../atftpd.templates:3001 54 | msgid "Retry timeout:" 55 | msgstr "Uudelleenyrityksen aikakatkaisu:" 56 | 57 | #. Type: string 58 | #. Description 59 | #: ../atftpd.templates:3001 60 | msgid "How many seconds to wait for a reply before retransmitting a packet." 61 | msgstr "" 62 | "Valitse montako sekuntia vastausta odotetaan ennen paketin " 63 | "uudelleenlähetystä." 64 | 65 | #. Type: string 66 | #. Description 67 | #: ../atftpd.templates:4001 68 | msgid "Maximum number of threads:" 69 | msgstr "Säikeiden enimmäismäärä:" 70 | 71 | #. Type: string 72 | #. Description 73 | #: ../atftpd.templates:4001 74 | msgid "Maximum number of concurrent threads that can be running." 75 | msgstr "Valitse montako säiettä voi yhtä aikaa olla ajossa." 76 | 77 | #. Type: select 78 | #. Description 79 | #: ../atftpd.templates:5001 80 | msgid "Verbosity level:" 81 | msgstr "Yksityiskohtien määrä lokissa:" 82 | 83 | #. Type: select 84 | #. Description 85 | #: ../atftpd.templates:5001 86 | msgid "" 87 | "Level of logging. 7 logs everything including debug logs. 1 will log only " 88 | "the system critical logs. 5 (LOG_NOTICE) is the default value." 89 | msgstr "" 90 | "Valitse lokituksen taso. 7 kirjoittaa lokiin kaiken, mukaan lukien " 91 | "virheidenjäljitysviestit. 1 kirjoittaa lokiin vain järjestelmän kannalta " 92 | "kriittiset viestit. Oletusarvo on 5 (LOG_NOTICE)." 93 | 94 | #. Type: boolean 95 | #. Description 96 | #: ../atftpd.templates:6001 97 | msgid "Enable 'timeout' support?" 98 | msgstr "Otetaanko aikakatkaisun (timeout) tuki käyttöön?" 99 | 100 | #. Type: boolean 101 | #. Description 102 | #: ../atftpd.templates:7001 103 | msgid "Enable 'tsize' support?" 104 | msgstr "Otetaanko tiedoston koon kyselyn (tsize) tuki käyttöön?" 105 | 106 | #. Type: boolean 107 | #. Description 108 | #: ../atftpd.templates:8001 109 | msgid "Enable 'block size' support?" 110 | msgstr "Otetaanko lohkokoon (block size) määrittelyn tuki käyttöön?" 111 | 112 | #. Type: boolean 113 | #. Description 114 | #: ../atftpd.templates:9001 115 | msgid "Enable multicast support?" 116 | msgstr "Otetaanko multicast-lähetysten tuki käyttöön?" 117 | 118 | #. Type: string 119 | #. Description 120 | #: ../atftpd.templates:10001 121 | msgid "TTL for multicast packets:" 122 | msgstr "Multicast-pakettien TTL:" 123 | 124 | #. Type: string 125 | #. Description 126 | #: ../atftpd.templates:11001 127 | msgid "Port to listen for tftp request:" 128 | msgstr "Portti, jossa ohjelma kuuntelee tftp-pyyntöjä:" 129 | 130 | #. Type: string 131 | #. Description 132 | #: ../atftpd.templates:12001 133 | msgid "Port range for multicast file transfer:" 134 | msgstr "Multicast-tiedostosiirron porttiavaruus:" 135 | 136 | #. Type: string 137 | #. Description 138 | #: ../atftpd.templates:12001 139 | msgid "" 140 | "Multicast transfer will use any available port in a given set. For example, " 141 | "\"2000-2003, 3000\" allow atftpd to use port 2000 to 2003 and 3000." 142 | msgstr "" 143 | "Multicast-siirto käyttää mitä tahansa vapaata porttia annetusta joukosta. " 144 | "Esimerkiksi määrittely ”2000-2003, 3000” sallii atftpd:n käyttää portteja " 145 | "välillä 2000-2003 ja porttia 3000." 146 | 147 | #. Type: string 148 | #. Description 149 | #: ../atftpd.templates:13001 150 | msgid "Address range for multicast transfer:" 151 | msgstr "Multicast-siirtojen osoiteavaruus:" 152 | 153 | #. Type: string 154 | #. Description 155 | #: ../atftpd.templates:13001 156 | msgid "" 157 | "Multicast transfer will use any available addresses from a given set of " 158 | "addresses. Syntax is \"a.b.c.d-d,a.b.c.d,...\"" 159 | msgstr "" 160 | "Multicast-lähetys käyttää mitä tahansa vapaata osoitetta annetusta joukosta. " 161 | "Syntaksi on ”a.b.c.d-d,a.b.c.d,...”" 162 | 163 | #. Type: boolean 164 | #. Description 165 | #: ../atftpd.templates:14001 166 | msgid "Log to file instead of syslog?" 167 | msgstr "Kirjoitetaanko loki tiedostoon syslogin sijaan?" 168 | 169 | #. Type: boolean 170 | #. Description 171 | #: ../atftpd.templates:14001 172 | msgid "" 173 | "If your server does intensive tftp file serving, it is a good idea to " 174 | "accept here. That will avoid cluttering your syslog with tftpd logs." 175 | msgstr "" 176 | "Jos palvelimelle tulee paljon tftp-tiedostopyyntöjä, on tämän valitseminen " 177 | "hyvä idea. Tällä vältetään syslogin täyttäminen tftpd:n riveillä." 178 | 179 | #. Type: string 180 | #. Description 181 | #: ../atftpd.templates:15001 182 | msgid "Log file:" 183 | msgstr "Lokitiedosto:" 184 | 185 | #. Type: string 186 | #. Description 187 | #: ../atftpd.templates:15001 188 | msgid "" 189 | "A file where atftpd will write its logs. This file will be made writable for " 190 | "the user 'nobody' and group 'nogroup'." 191 | msgstr "" 192 | "Tiedosto, johon atftpd kirjoittaa lokinsa. Käyttäjälle ”nobody” ja ryhmälle " 193 | "”nogroup” annetaan kirjoitusoikeudet tähän tiedostoon." 194 | 195 | #. Type: string 196 | #. Description 197 | #: ../atftpd.templates:16001 198 | msgid "Base directory:" 199 | msgstr "Juurihakemisto:" 200 | 201 | #. Type: string 202 | #. Description 203 | #: ../atftpd.templates:16001 204 | msgid "" 205 | "The directory tree from where atftpd can serve files. That directory must be " 206 | "world readable." 207 | msgstr "" 208 | "Hakemistopuu, josta atftpd voi jakaa tiedostoja. Hakemiston tulee olla " 209 | "kaikkien luettavissa." 210 | -------------------------------------------------------------------------------- /debian/po/fr.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madmartin/atftp/d5c27eb7a9695d83569767e27ef69674173db39a/debian/po/fr.po -------------------------------------------------------------------------------- /debian/po/ja.po: -------------------------------------------------------------------------------- 1 | # 2 | # Translators, if you are not familiar with the PO format, gettext 3 | # documentation is worth reading, especially sections dedicated to 4 | # this format, e.g. by running: 5 | # info -n '(gettext)PO Files' 6 | # info -n '(gettext)Header Entry' 7 | # 8 | # Some information specific to po-debconf are available at 9 | # /usr/share/doc/po-debconf/README-trans 10 | # or http://www.debian.org/intl/l10n/po-debconf/README-trans 11 | # 12 | # Developers do not need to manually edit POT or PO files. 13 | # 14 | # 15 | msgid "" 16 | msgstr "" 17 | "Project-Id-Version: atftp 0.7.dfsg-1\n" 18 | "Report-Msgid-Bugs-To: ldrolez@debian.org\n" 19 | "POT-Creation-Date: 2006-10-02 00:46+0200\n" 20 | "PO-Revision-Date: 2006-12-12 01:47+0900\n" 21 | "Last-Translator: Atsushi Shimono \n" 22 | "Language-Team: Japanese \n" 23 | "Language: ja\n" 24 | "MIME-Version: 1.0\n" 25 | "Content-Type: text/plain; charset=UTF-8\n" 26 | "Content-Transfer-Encoding: 8bit\n" 27 | 28 | #. Type: boolean 29 | #. Description 30 | #: ../atftpd.templates:1001 31 | msgid "Should the server be started by inetd?" 32 | msgstr "inetd をサーバの起動に利用しますか?" 33 | 34 | #. Type: boolean 35 | #. Description 36 | #: ../atftpd.templates:1001 37 | msgid "" 38 | "atftpd can be started by the inetd superserver or as a daemon and handle " 39 | "incoming connections by itself. The latter is only recommend for very high " 40 | "usage server." 41 | msgstr "" 42 | "atftpd は、inetd から起動するか、もしくはデーモンとして動作し接続を自分で処理" 43 | "することもできます。後者は、高負荷のサーバで推奨されます。" 44 | 45 | #. Type: string 46 | #. Description 47 | #: ../atftpd.templates:2001 48 | msgid "Server timeout:" 49 | msgstr "サーバのタイムアウト値 :" 50 | 51 | #. Type: string 52 | #. Description 53 | #: ../atftpd.templates:2001 54 | msgid "How many seconds the main thread waits before exiting." 55 | msgstr "メインのスレッドを終了するまで何秒待機させるか。" 56 | 57 | #. Type: string 58 | #. Description 59 | #: ../atftpd.templates:3001 60 | msgid "Retry timeout:" 61 | msgstr "リトライ時のタイムアウト値 :" 62 | 63 | #. Type: string 64 | #. Description 65 | #: ../atftpd.templates:3001 66 | msgid "How many seconds to wait for a reply before retransmitting a packet." 67 | msgstr "パケットの再送まで何秒待つか。" 68 | 69 | #. Type: string 70 | #. Description 71 | #: ../atftpd.templates:4001 72 | msgid "Maximum number of threads:" 73 | msgstr "最大スレッド数 :" 74 | 75 | #. Type: string 76 | #. Description 77 | #: ../atftpd.templates:4001 78 | msgid "Maximum number of concurrent threads that can be running." 79 | msgstr "同時に動作させる最大のスレッド数。" 80 | 81 | #. Type: select 82 | #. Description 83 | #: ../atftpd.templates:5001 84 | msgid "Verbosity level:" 85 | msgstr "冗長レベル :" 86 | 87 | #. Type: select 88 | #. Description 89 | #: ../atftpd.templates:5001 90 | msgid "" 91 | "Level of logging. 7 logs everything including debug logs. 1 will log only " 92 | "the system critical logs. 5 (LOG_NOTICE) is the default value." 93 | msgstr "" 94 | "ログ出力のレベル。7 ではデバッグログを含むすべてのログを出力。1 では、システ" 95 | "ムの重大なログのみを出力。 5 (LOG_NOTICE) がデフォルト値。" 96 | 97 | #. Type: boolean 98 | #. Description 99 | #: ../atftpd.templates:6001 100 | msgid "Enable 'timeout' support?" 101 | msgstr "'タイムアウト'を有効にしますか?" 102 | 103 | #. Type: boolean 104 | #. Description 105 | #: ../atftpd.templates:7001 106 | msgid "Enable 'tsize' support?" 107 | msgstr "'tsize'を有効にしますか?" 108 | 109 | #. Type: boolean 110 | #. Description 111 | #: ../atftpd.templates:8001 112 | msgid "Enable 'block size' support?" 113 | msgstr "'ブロックサイズ'を有効にしますか?" 114 | 115 | #. Type: boolean 116 | #. Description 117 | #: ../atftpd.templates:9001 118 | msgid "Enable multicast support?" 119 | msgstr "マルチキャストを有効にしますか?" 120 | 121 | #. Type: string 122 | #. Description 123 | #: ../atftpd.templates:10001 124 | msgid "TTL for multicast packets:" 125 | msgstr "マルチキャストパケットの TTL 値" 126 | 127 | #. Type: string 128 | #. Description 129 | #: ../atftpd.templates:11001 130 | msgid "Port to listen for tftp request:" 131 | msgstr "tftp のリクエストを待ち受けるポート番号 :" 132 | 133 | #. Type: string 134 | #. Description 135 | #: ../atftpd.templates:12001 136 | msgid "Port range for multicast file transfer:" 137 | msgstr "マルチキャスト転送に利用するポート番号の範囲 :" 138 | 139 | #. Type: string 140 | #. Description 141 | #: ../atftpd.templates:12001 142 | msgid "" 143 | "Multicast transfer will use any available port in a given set. For example, " 144 | "\"2000-2003, 3000\" allow atftpd to use port 2000 to 2003 and 3000." 145 | msgstr "" 146 | "マルチキャスト転送は設定された番号のうち利用できるポートを利用します。例えば" 147 | "\"2000-2003, 3000\"を設定すると、atftpd は、2000 から 2003 と 3000 番を利用し" 148 | "ます。" 149 | 150 | #. Type: string 151 | #. Description 152 | #: ../atftpd.templates:13001 153 | msgid "Address range for multicast transfer:" 154 | msgstr "マルチキャスト転送先のアドレス範囲:" 155 | 156 | #. Type: string 157 | #. Description 158 | #: ../atftpd.templates:13001 159 | msgid "" 160 | "Multicast transfer will use any available addresses from a given set of " 161 | "addresses. Syntax is \"a.b.c.d-d,a.b.c.d,...\"" 162 | msgstr "" 163 | "マルチキャスト転送は送信先のアドレスに設定されたアドレスを利用します。設定可" 164 | "能なシンタックスは、\"a.b.c.d-d,a.b.c.d,...\"です。" 165 | 166 | #. Type: boolean 167 | #. Description 168 | #: ../atftpd.templates:14001 169 | msgid "Log to file instead of syslog?" 170 | msgstr "ログを syslog でなくファイルに書き出しますか?" 171 | 172 | #. Type: boolean 173 | #. Description 174 | #: ../atftpd.templates:14001 175 | msgid "" 176 | "If your server does intensive tftp file serving, it is a good idea to " 177 | "accept here. That will avoid cluttering your syslog with tftpd logs." 178 | msgstr "" 179 | "サーバが大量の tftp 転送を行う場合、これを有効にするのはよいアイデアです。" 180 | "tftpd のログによって syslog が乱雑になることがなくなります。" 181 | 182 | #. Type: string 183 | #. Description 184 | #: ../atftpd.templates:15001 185 | msgid "Log file:" 186 | msgstr "ログファイル名 :" 187 | 188 | #. Type: string 189 | #. Description 190 | #: ../atftpd.templates:15001 191 | msgid "" 192 | "A file where atftpd will write its logs. This file will be made writable for " 193 | "the user 'nobody' and group 'nogroup'." 194 | msgstr "" 195 | "aftpd がログを書き出すファイルです。このファイルは、'nobody' ユーザと " 196 | "'nobody' グループに対して書き込み可能な状態で作成されます。" 197 | 198 | #. Type: string 199 | #. Description 200 | #: ../atftpd.templates:16001 201 | msgid "Base directory:" 202 | msgstr "ベースディレクトリ:" 203 | 204 | #. Type: string 205 | #. Description 206 | #: ../atftpd.templates:16001 207 | msgid "" 208 | "The directory tree from where atftpd can serve files. That directory must be " 209 | "world readable." 210 | msgstr "" 211 | "aftpd がファイルを提供するディレクトリです。このディレクトリは誰からでも読め" 212 | "るようにする必要があります。" 213 | # 214 | # Translators, if you are not familiar with the PO format, gettext 215 | # documentation is worth reading, especially sections dedicated to 216 | # this format, e.g. by running: 217 | # info -n '(gettext)PO Files' 218 | # info -n '(gettext)Header Entry' 219 | # 220 | # Some information specific to po-debconf are available at 221 | # /usr/share/doc/po-debconf/README-trans 222 | # or http://www.debian.org/intl/l10n/po-debconf/README-trans 223 | # 224 | # Developers do not need to manually edit POT or PO files. 225 | # 226 | # 227 | msgid "" 228 | msgstr "" 229 | "Project-Id-Version: atftp 0.7.dfsg-1\n" 230 | "Report-Msgid-Bugs-To: ldrolez@debian.org\n" 231 | "POT-Creation-Date: 2006-10-02 00:46+0200\n" 232 | "PO-Revision-Date: 2006-12-12 01:47+0900\n" 233 | "Last-Translator: Atsushi Shimono \n" 234 | "Language-Team: Japanese \n" 235 | "Language: ja\n" 236 | "MIME-Version: 1.0\n" 237 | "Content-Type: text/plain; charset=UTF-8\n" 238 | "Content-Transfer-Encoding: 8bit\n" 239 | 240 | #. Type: boolean 241 | #. Description 242 | #: ../atftpd.templates:1001 243 | msgid "Should the server be started by inetd?" 244 | msgstr "inetd をサーバの起動に利用しますか?" 245 | 246 | #. Type: boolean 247 | #. Description 248 | #: ../atftpd.templates:1001 249 | msgid "" 250 | "atftpd can be started by the inetd superserver or as a daemon and handle " 251 | "incoming connections by itself. The latter is only recommend for very high " 252 | "usage server." 253 | msgstr "" 254 | "atftpd は、inetd から起動するか、もしくはデーモンとして動作し接続を自分で処理" 255 | "することもできます。後者は、高負荷のサーバで推奨されます。" 256 | 257 | #. Type: string 258 | #. Description 259 | #: ../atftpd.templates:2001 260 | msgid "Server timeout:" 261 | msgstr "サーバのタイムアウト値 :" 262 | 263 | #. Type: string 264 | #. Description 265 | #: ../atftpd.templates:2001 266 | msgid "How many seconds the main thread waits before exiting." 267 | msgstr "メインのスレッドを終了するまで何秒待機させるか。" 268 | 269 | #. Type: string 270 | #. Description 271 | #: ../atftpd.templates:3001 272 | msgid "Retry timeout:" 273 | msgstr "リトライ時のタイムアウト値 :" 274 | 275 | #. Type: string 276 | #. Description 277 | #: ../atftpd.templates:3001 278 | msgid "How many seconds to wait for a reply before retransmitting a packet." 279 | msgstr "パケットの再送まで何秒待つか。" 280 | 281 | #. Type: string 282 | #. Description 283 | #: ../atftpd.templates:4001 284 | msgid "Maximum number of threads:" 285 | msgstr "最大スレッド数 :" 286 | 287 | #. Type: string 288 | #. Description 289 | #: ../atftpd.templates:4001 290 | msgid "Maximum number of concurrent threads that can be running." 291 | msgstr "同時に動作させる最大のスレッド数。" 292 | 293 | #. Type: select 294 | #. Description 295 | #: ../atftpd.templates:5001 296 | msgid "Verbosity level:" 297 | msgstr "冗長レベル :" 298 | 299 | #. Type: select 300 | #. Description 301 | #: ../atftpd.templates:5001 302 | msgid "" 303 | "Level of logging. 7 logs everything including debug logs. 1 will log only " 304 | "the system critical logs. 5 (LOG_NOTICE) is the default value." 305 | msgstr "" 306 | "ログ出力のレベル。7 ではデバッグログを含むすべてのログを出力。1 では、システ" 307 | "ムの重大なログのみを出力。 5 (LOG_NOTICE) がデフォルト値。" 308 | 309 | #. Type: boolean 310 | #. Description 311 | #: ../atftpd.templates:6001 312 | msgid "Enable 'timeout' support?" 313 | msgstr "'タイムアウト'を有効にしますか?" 314 | 315 | #. Type: boolean 316 | #. Description 317 | #: ../atftpd.templates:7001 318 | msgid "Enable 'tsize' support?" 319 | msgstr "'tsize'を有効にしますか?" 320 | 321 | #. Type: boolean 322 | #. Description 323 | #: ../atftpd.templates:8001 324 | msgid "Enable 'block size' support?" 325 | msgstr "'ブロックサイズ'を有効にしますか?" 326 | 327 | #. Type: boolean 328 | #. Description 329 | #: ../atftpd.templates:9001 330 | msgid "Enable multicast support?" 331 | msgstr "マルチキャストを有効にしますか?" 332 | 333 | #. Type: string 334 | #. Description 335 | #: ../atftpd.templates:10001 336 | msgid "TTL for multicast packets:" 337 | msgstr "マルチキャストパケットの TTL 値" 338 | 339 | #. Type: string 340 | #. Description 341 | #: ../atftpd.templates:11001 342 | msgid "Port to listen for tftp request:" 343 | msgstr "tftp のリクエストを待ち受けるポート番号 :" 344 | 345 | #. Type: string 346 | #. Description 347 | #: ../atftpd.templates:12001 348 | msgid "Port range for multicast file transfer:" 349 | msgstr "マルチキャスト転送に利用するポート番号の範囲 :" 350 | 351 | #. Type: string 352 | #. Description 353 | #: ../atftpd.templates:12001 354 | msgid "" 355 | "Multicast transfer will use any available port in a given set. For example, " 356 | "\"2000-2003, 3000\" allow atftpd to use port 2000 to 2003 and 3000." 357 | msgstr "" 358 | "マルチキャスト転送は設定された番号のうち利用できるポートを利用します。例えば" 359 | "\"2000-2003, 3000\"を設定すると、atftpd は、2000 から 2003 と 3000 番を利用し" 360 | "ます。" 361 | 362 | #. Type: string 363 | #. Description 364 | #: ../atftpd.templates:13001 365 | msgid "Address range for multicast transfer:" 366 | msgstr "マルチキャスト転送先のアドレス範囲:" 367 | 368 | #. Type: string 369 | #. Description 370 | #: ../atftpd.templates:13001 371 | msgid "" 372 | "Multicast transfer will use any available addresses from a given set of " 373 | "addresses. Syntax is \"a.b.c.d-d,a.b.c.d,...\"" 374 | msgstr "" 375 | "マルチキャスト転送は送信先のアドレスに設定されたアドレスを利用します。設定可" 376 | "能なシンタックスは、\"a.b.c.d-d,a.b.c.d,...\"です。" 377 | 378 | #. Type: boolean 379 | #. Description 380 | #: ../atftpd.templates:14001 381 | msgid "Log to file instead of syslog?" 382 | msgstr "ログを syslog でなくファイルに書き出しますか?" 383 | 384 | #. Type: boolean 385 | #. Description 386 | #: ../atftpd.templates:14001 387 | msgid "" 388 | "If your server does intensive tftp file serving, it is a good idea to " 389 | "accept here. That will avoid cluttering your syslog with tftpd logs." 390 | msgstr "" 391 | "サーバが大量の tftp 転送を行う場合、これを有効にするのはよいアイデアです。" 392 | "tftpd のログによって syslog が乱雑になることがなくなります。" 393 | 394 | #. Type: string 395 | #. Description 396 | #: ../atftpd.templates:15001 397 | msgid "Log file:" 398 | msgstr "ログファイル名 :" 399 | 400 | #. Type: string 401 | #. Description 402 | #: ../atftpd.templates:15001 403 | msgid "" 404 | "A file where atftpd will write its logs. This file will be made writable for " 405 | "the user 'nobody' and group 'nogroup'." 406 | msgstr "" 407 | "aftpd がログを書き出すファイルです。このファイルは、'nobody' ユーザと " 408 | "'nobody' グループに対して書き込み可能な状態で作成されます。" 409 | 410 | #. Type: string 411 | #. Description 412 | #: ../atftpd.templates:16001 413 | msgid "Base directory:" 414 | msgstr "ベースディレクトリ:" 415 | 416 | #. Type: string 417 | #. Description 418 | #: ../atftpd.templates:16001 419 | msgid "" 420 | "The directory tree from where atftpd can serve files. That directory must be " 421 | "world readable." 422 | msgstr "" 423 | "aftpd がファイルを提供するディレクトリです。このディレクトリは誰からでも読め" 424 | "るようにする必要があります。" 425 | -------------------------------------------------------------------------------- /debian/po/pl.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madmartin/atftp/d5c27eb7a9695d83569767e27ef69674173db39a/debian/po/pl.po -------------------------------------------------------------------------------- /debian/po/pt_BR.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madmartin/atftp/d5c27eb7a9695d83569767e27ef69674173db39a/debian/po/pt_BR.po -------------------------------------------------------------------------------- /debian/po/sk.po: -------------------------------------------------------------------------------- 1 | # Slovak translations for atftp package 2 | # Slovenské preklady pre balík atftp. 3 | # Copyright (C) 2011 THE atftp'S COPYRIGHT HOLDER 4 | # This file is distributed under the same license as the atftp package. 5 | # Automatically generated, 2011. 6 | # Slavko , 2011. 7 | # 8 | msgid "" 9 | msgstr "" 10 | "Project-Id-Version: atftp 0.7.dfsg-10\n" 11 | "Report-Msgid-Bugs-To: ldrolez@debian.org\n" 12 | "POT-Creation-Date: 2006-10-02 00:46+0200\n" 13 | "PO-Revision-Date: 2011-03-30 19:22+0200\n" 14 | "Last-Translator: Slavko \n" 15 | "Language-Team: Slovak \n" 16 | "Language: sk\n" 17 | "MIME-Version: 1.0\n" 18 | "Content-Type: text/plain; charset=UTF-8\n" 19 | "Content-Transfer-Encoding: 8bit\n" 20 | "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" 21 | 22 | #. Type: boolean 23 | #. Description 24 | #: ../atftpd.templates:1001 25 | msgid "Should the server be started by inetd?" 26 | msgstr "Má byť server spúšťaný prostredníctvom inetd?" 27 | 28 | #. Type: boolean 29 | #. Description 30 | #: ../atftpd.templates:1001 31 | msgid "" 32 | "atftpd can be started by the inetd superserver or as a daemon and handle " 33 | "incoming connections by itself. The latter is only recommend for very high " 34 | "usage server." 35 | msgstr "" 36 | "atftpd môže byť spúšťaný pomocou superservera inetd alebo môže bežať ako " 37 | "démon a spracovávať prichádzajúce požiadavky sám. Druhá možnosť je " 38 | "odporúčaná len pre veľmi vyťažený server." 39 | 40 | #. Type: string 41 | #. Description 42 | #: ../atftpd.templates:2001 43 | msgid "Server timeout:" 44 | msgstr "Časový limit servera:" 45 | 46 | #. Type: string 47 | #. Description 48 | #: ../atftpd.templates:2001 49 | msgid "How many seconds the main thread waits before exiting." 50 | msgstr "Koľko sekúnd má hlavné vlákno čakať, kým skončí." 51 | 52 | #. Type: string 53 | #. Description 54 | #: ../atftpd.templates:3001 55 | msgid "Retry timeout:" 56 | msgstr "Časový limit opakovania:" 57 | 58 | #. Type: string 59 | #. Description 60 | #: ../atftpd.templates:3001 61 | msgid "How many seconds to wait for a reply before retransmitting a packet." 62 | msgstr "Koľko sekúnd má server čakať na odpoveď, kým znova prenesie paket." 63 | 64 | #. Type: string 65 | #. Description 66 | #: ../atftpd.templates:4001 67 | msgid "Maximum number of threads:" 68 | msgstr "Maximálny počet vlákien:" 69 | 70 | #. Type: string 71 | #. Description 72 | #: ../atftpd.templates:4001 73 | msgid "Maximum number of concurrent threads that can be running." 74 | msgstr "Maximálny počet súčasne bežiacich vlákien." 75 | 76 | #. Type: select 77 | #. Description 78 | #: ../atftpd.templates:5001 79 | msgid "Verbosity level:" 80 | msgstr "Úroveň výrečnosti:" 81 | 82 | #. Type: select 83 | #. Description 84 | #: ../atftpd.templates:5001 85 | msgid "" 86 | "Level of logging. 7 logs everything including debug logs. 1 will log only " 87 | "the system critical logs. 5 (LOG_NOTICE) is the default value." 88 | msgstr "" 89 | "Úroveň zaznamenávania. Úroveň 7 zaznamenáva všetko, vrátane ladiacich " 90 | "informácií. Úroveň 1 zaznamenáva len kritické systémové udalosti. " 91 | "Východisková hodnota je 5 (LOG_NOTICE)." 92 | 93 | #. Type: boolean 94 | #. Description 95 | #: ../atftpd.templates:6001 96 | msgid "Enable 'timeout' support?" 97 | msgstr "Zapnúť podporu „timeout”?" 98 | 99 | #. Type: boolean 100 | #. Description 101 | #: ../atftpd.templates:7001 102 | msgid "Enable 'tsize' support?" 103 | msgstr "Zapnúť podporu „tsize”?" 104 | 105 | #. Type: boolean 106 | #. Description 107 | #: ../atftpd.templates:8001 108 | msgid "Enable 'block size' support?" 109 | msgstr "Zapnúť podporu „block size”?" 110 | 111 | #. Type: boolean 112 | #. Description 113 | #: ../atftpd.templates:9001 114 | msgid "Enable multicast support?" 115 | msgstr "Zapnúť podporu multicast?" 116 | 117 | #. Type: string 118 | #. Description 119 | #: ../atftpd.templates:10001 120 | msgid "TTL for multicast packets:" 121 | msgstr "TTL multicastových paketov:" 122 | 123 | #. Type: string 124 | #. Description 125 | #: ../atftpd.templates:11001 126 | msgid "Port to listen for tftp request:" 127 | msgstr "Port, na ktorom má tftp prijímať požiadavky:" 128 | 129 | #. Type: string 130 | #. Description 131 | #: ../atftpd.templates:12001 132 | msgid "Port range for multicast file transfer:" 133 | msgstr "Rozsah portov multicastového prenosu súborov:" 134 | 135 | #. Type: string 136 | #. Description 137 | #: ../atftpd.templates:12001 138 | msgid "" 139 | "Multicast transfer will use any available port in a given set. For example, " 140 | "\"2000-2003, 3000\" allow atftpd to use port 2000 to 2003 and 3000." 141 | msgstr "" 142 | "Multicastový prenos bude používať všetky dostupné porty zo zadanej množiny. " 143 | "Napríklad \"2000-2003, 3000\" dovolí atftpd používať porty od 2000 do 2003 a " 144 | "3000." 145 | 146 | #. Type: string 147 | #. Description 148 | #: ../atftpd.templates:13001 149 | msgid "Address range for multicast transfer:" 150 | msgstr "Rozsah adries multicastového prenosu:" 151 | 152 | #. Type: string 153 | #. Description 154 | #: ../atftpd.templates:13001 155 | msgid "" 156 | "Multicast transfer will use any available addresses from a given set of " 157 | "addresses. Syntax is \"a.b.c.d-d,a.b.c.d,...\"" 158 | msgstr "" 159 | "Multicastový prenos bude používať všetky dostupné adresy zo zadanej množiny " 160 | "adries. Formát je \"a.b.c.d-d,a.b.c.d,...\"" 161 | 162 | #. Type: boolean 163 | #. Description 164 | #: ../atftpd.templates:14001 165 | msgid "Log to file instead of syslog?" 166 | msgstr "Zaznamenávať do súboru, namiesto do syslog?" 167 | 168 | #. Type: boolean 169 | #. Description 170 | #: ../atftpd.templates:14001 171 | msgid "" 172 | "If your server does intensive tftp file serving, it is a good idea to " 173 | "accept here. That will avoid cluttering your syslog with tftpd logs." 174 | msgstr "" 175 | "Ak TFTP server intenzívne poskytuje súbory, je dobrým nápadom povoliť túto " 176 | "možnosť. Takto sa vyhnete zaplňovaniu svojho syslog záznamami tftpd." 177 | 178 | #. Type: string 179 | #. Description 180 | #: ../atftpd.templates:15001 181 | msgid "Log file:" 182 | msgstr "Súbor záznamov:" 183 | 184 | #. Type: string 185 | #. Description 186 | #: ../atftpd.templates:15001 187 | msgid "" 188 | "A file where atftpd will write its logs. This file will be made writable for " 189 | "the user 'nobody' and group 'nogroup'." 190 | msgstr "" 191 | "Súbor, do ktorého bude atftpd zapisovať svoje záznamy. Tento súbor musí byť " 192 | "zapisovateľný pre používateľa „nobody” a skupinu „nogroup”" 193 | 194 | #. Type: string 195 | #. Description 196 | #: ../atftpd.templates:16001 197 | msgid "Base directory:" 198 | msgstr "Základný adresár:" 199 | 200 | #. Type: string 201 | #. Description 202 | #: ../atftpd.templates:16001 203 | msgid "" 204 | "The directory tree from where atftpd can serve files. That directory must be " 205 | "world readable." 206 | msgstr "" 207 | "Adresárový strom, z ktorého bude atftpd poskytovať súbory. Tento adresár " 208 | "musí byť zapisovateľný pre všetkých." 209 | -------------------------------------------------------------------------------- /debian/po/sv.po: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/madmartin/atftp/d5c27eb7a9695d83569767e27ef69674173db39a/debian/po/sv.po -------------------------------------------------------------------------------- /debian/po/templates.pot: -------------------------------------------------------------------------------- 1 | # SOME DESCRIPTIVE TITLE. 2 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 3 | # This file is distributed under the same license as the PACKAGE package. 4 | # FIRST AUTHOR , YEAR. 5 | # 6 | #, fuzzy 7 | msgid "" 8 | msgstr "" 9 | "Project-Id-Version: PACKAGE VERSION\n" 10 | "Report-Msgid-Bugs-To: ldrolez@debian.org\n" 11 | "POT-Creation-Date: 2006-10-02 00:46+0200\n" 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 13 | "Last-Translator: FULL NAME \n" 14 | "Language-Team: LANGUAGE \n" 15 | "MIME-Version: 1.0\n" 16 | "Content-Type: text/plain; charset=CHARSET\n" 17 | "Content-Transfer-Encoding: 8bit\n" 18 | 19 | #. Type: boolean 20 | #. Description 21 | #: ../atftpd.templates:1001 22 | msgid "Should the server be started by inetd?" 23 | msgstr "" 24 | 25 | #. Type: boolean 26 | #. Description 27 | #: ../atftpd.templates:1001 28 | msgid "" 29 | "atftpd can be started by the inetd superserver or as a daemon and handle " 30 | "incoming connections by itself. The latter is only recommend for very high " 31 | "usage server." 32 | msgstr "" 33 | 34 | #. Type: string 35 | #. Description 36 | #: ../atftpd.templates:2001 37 | msgid "Server timeout:" 38 | msgstr "" 39 | 40 | #. Type: string 41 | #. Description 42 | #: ../atftpd.templates:2001 43 | msgid "How many seconds the main thread waits before exiting." 44 | msgstr "" 45 | 46 | #. Type: string 47 | #. Description 48 | #: ../atftpd.templates:3001 49 | msgid "Retry timeout:" 50 | msgstr "" 51 | 52 | #. Type: string 53 | #. Description 54 | #: ../atftpd.templates:3001 55 | msgid "How many seconds to wait for a reply before retransmitting a packet." 56 | msgstr "" 57 | 58 | #. Type: string 59 | #. Description 60 | #: ../atftpd.templates:4001 61 | msgid "Maximum number of threads:" 62 | msgstr "" 63 | 64 | #. Type: string 65 | #. Description 66 | #: ../atftpd.templates:4001 67 | msgid "Maximum number of concurrent threads that can be running." 68 | msgstr "" 69 | 70 | #. Type: select 71 | #. Description 72 | #: ../atftpd.templates:5001 73 | msgid "Verbosity level:" 74 | msgstr "" 75 | 76 | #. Type: select 77 | #. Description 78 | #: ../atftpd.templates:5001 79 | msgid "" 80 | "Level of logging. 7 logs everything including debug logs. 1 will log only " 81 | "the system critical logs. 5 (LOG_NOTICE) is the default value." 82 | msgstr "" 83 | 84 | #. Type: boolean 85 | #. Description 86 | #: ../atftpd.templates:6001 87 | msgid "Enable 'timeout' support?" 88 | msgstr "" 89 | 90 | #. Type: boolean 91 | #. Description 92 | #: ../atftpd.templates:7001 93 | msgid "Enable 'tsize' support?" 94 | msgstr "" 95 | 96 | #. Type: boolean 97 | #. Description 98 | #: ../atftpd.templates:8001 99 | msgid "Enable 'block size' support?" 100 | msgstr "" 101 | 102 | #. Type: boolean 103 | #. Description 104 | #: ../atftpd.templates:9001 105 | msgid "Enable multicast support?" 106 | msgstr "" 107 | 108 | #. Type: string 109 | #. Description 110 | #: ../atftpd.templates:10001 111 | msgid "TTL for multicast packets:" 112 | msgstr "" 113 | 114 | #. Type: string 115 | #. Description 116 | #: ../atftpd.templates:11001 117 | msgid "Port to listen for tftp request:" 118 | msgstr "" 119 | 120 | #. Type: string 121 | #. Description 122 | #: ../atftpd.templates:12001 123 | msgid "Port range for multicast file transfer:" 124 | msgstr "" 125 | 126 | #. Type: string 127 | #. Description 128 | #: ../atftpd.templates:12001 129 | msgid "" 130 | "Multicast transfer will use any available port in a given set. For example, " 131 | "\"2000-2003, 3000\" allow atftpd to use port 2000 to 2003 and 3000." 132 | msgstr "" 133 | 134 | #. Type: string 135 | #. Description 136 | #: ../atftpd.templates:13001 137 | msgid "Address range for multicast transfer:" 138 | msgstr "" 139 | 140 | #. Type: string 141 | #. Description 142 | #: ../atftpd.templates:13001 143 | msgid "" 144 | "Multicast transfer will use any available addresses from a given set of " 145 | "addresses. Syntax is \"a.b.c.d-d,a.b.c.d,...\"" 146 | msgstr "" 147 | 148 | #. Type: boolean 149 | #. Description 150 | #: ../atftpd.templates:14001 151 | msgid "Log to file instead of syslog?" 152 | msgstr "" 153 | 154 | #. Type: boolean 155 | #. Description 156 | #: ../atftpd.templates:14001 157 | msgid "" 158 | "If your server does intensive tftp file serving, it is a good idea to " 159 | "accept here. That will avoid cluttering your syslog with tftpd logs." 160 | msgstr "" 161 | 162 | #. Type: string 163 | #. Description 164 | #: ../atftpd.templates:15001 165 | msgid "Log file:" 166 | msgstr "" 167 | 168 | #. Type: string 169 | #. Description 170 | #: ../atftpd.templates:15001 171 | msgid "" 172 | "A file where atftpd will write its logs. This file will be made writable for " 173 | "the user 'nobody' and group 'nogroup'." 174 | msgstr "" 175 | 176 | #. Type: string 177 | #. Description 178 | #: ../atftpd.templates:16001 179 | msgid "Base directory:" 180 | msgstr "" 181 | 182 | #. Type: string 183 | #. Description 184 | #: ../atftpd.templates:16001 185 | msgid "" 186 | "The directory tree from where atftpd can serve files. That directory must be " 187 | "world readable." 188 | msgstr "" 189 | # SOME DESCRIPTIVE TITLE. 190 | # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER 191 | # This file is distributed under the same license as the PACKAGE package. 192 | # FIRST AUTHOR , YEAR. 193 | # 194 | #, fuzzy 195 | msgid "" 196 | msgstr "" 197 | "Project-Id-Version: PACKAGE VERSION\n" 198 | "Report-Msgid-Bugs-To: ldrolez@debian.org\n" 199 | "POT-Creation-Date: 2006-10-02 00:46+0200\n" 200 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" 201 | "Last-Translator: FULL NAME \n" 202 | "Language-Team: LANGUAGE \n" 203 | "MIME-Version: 1.0\n" 204 | "Content-Type: text/plain; charset=CHARSET\n" 205 | "Content-Transfer-Encoding: 8bit\n" 206 | 207 | #. Type: boolean 208 | #. Description 209 | #: ../atftpd.templates:1001 210 | msgid "Should the server be started by inetd?" 211 | msgstr "" 212 | 213 | #. Type: boolean 214 | #. Description 215 | #: ../atftpd.templates:1001 216 | msgid "" 217 | "atftpd can be started by the inetd superserver or as a daemon and handle " 218 | "incoming connections by itself. The latter is only recommend for very high " 219 | "usage server." 220 | msgstr "" 221 | 222 | #. Type: string 223 | #. Description 224 | #: ../atftpd.templates:2001 225 | msgid "Server timeout:" 226 | msgstr "" 227 | 228 | #. Type: string 229 | #. Description 230 | #: ../atftpd.templates:2001 231 | msgid "How many seconds the main thread waits before exiting." 232 | msgstr "" 233 | 234 | #. Type: string 235 | #. Description 236 | #: ../atftpd.templates:3001 237 | msgid "Retry timeout:" 238 | msgstr "" 239 | 240 | #. Type: string 241 | #. Description 242 | #: ../atftpd.templates:3001 243 | msgid "How many seconds to wait for a reply before retransmitting a packet." 244 | msgstr "" 245 | 246 | #. Type: string 247 | #. Description 248 | #: ../atftpd.templates:4001 249 | msgid "Maximum number of threads:" 250 | msgstr "" 251 | 252 | #. Type: string 253 | #. Description 254 | #: ../atftpd.templates:4001 255 | msgid "Maximum number of concurrent threads that can be running." 256 | msgstr "" 257 | 258 | #. Type: select 259 | #. Description 260 | #: ../atftpd.templates:5001 261 | msgid "Verbosity level:" 262 | msgstr "" 263 | 264 | #. Type: select 265 | #. Description 266 | #: ../atftpd.templates:5001 267 | msgid "" 268 | "Level of logging. 7 logs everything including debug logs. 1 will log only " 269 | "the system critical logs. 5 (LOG_NOTICE) is the default value." 270 | msgstr "" 271 | 272 | #. Type: boolean 273 | #. Description 274 | #: ../atftpd.templates:6001 275 | msgid "Enable 'timeout' support?" 276 | msgstr "" 277 | 278 | #. Type: boolean 279 | #. Description 280 | #: ../atftpd.templates:7001 281 | msgid "Enable 'tsize' support?" 282 | msgstr "" 283 | 284 | #. Type: boolean 285 | #. Description 286 | #: ../atftpd.templates:8001 287 | msgid "Enable 'block size' support?" 288 | msgstr "" 289 | 290 | #. Type: boolean 291 | #. Description 292 | #: ../atftpd.templates:9001 293 | msgid "Enable multicast support?" 294 | msgstr "" 295 | 296 | #. Type: string 297 | #. Description 298 | #: ../atftpd.templates:10001 299 | msgid "TTL for multicast packets:" 300 | msgstr "" 301 | 302 | #. Type: string 303 | #. Description 304 | #: ../atftpd.templates:11001 305 | msgid "Port to listen for tftp request:" 306 | msgstr "" 307 | 308 | #. Type: string 309 | #. Description 310 | #: ../atftpd.templates:12001 311 | msgid "Port range for multicast file transfer:" 312 | msgstr "" 313 | 314 | #. Type: string 315 | #. Description 316 | #: ../atftpd.templates:12001 317 | msgid "" 318 | "Multicast transfer will use any available port in a given set. For example, " 319 | "\"2000-2003, 3000\" allow atftpd to use port 2000 to 2003 and 3000." 320 | msgstr "" 321 | 322 | #. Type: string 323 | #. Description 324 | #: ../atftpd.templates:13001 325 | msgid "Address range for multicast transfer:" 326 | msgstr "" 327 | 328 | #. Type: string 329 | #. Description 330 | #: ../atftpd.templates:13001 331 | msgid "" 332 | "Multicast transfer will use any available addresses from a given set of " 333 | "addresses. Syntax is \"a.b.c.d-d,a.b.c.d,...\"" 334 | msgstr "" 335 | 336 | #. Type: boolean 337 | #. Description 338 | #: ../atftpd.templates:14001 339 | msgid "Log to file instead of syslog?" 340 | msgstr "" 341 | 342 | #. Type: boolean 343 | #. Description 344 | #: ../atftpd.templates:14001 345 | msgid "" 346 | "If your server does intensive tftp file serving, it is a good idea to " 347 | "accept here. That will avoid cluttering your syslog with tftpd logs." 348 | msgstr "" 349 | 350 | #. Type: string 351 | #. Description 352 | #: ../atftpd.templates:15001 353 | msgid "Log file:" 354 | msgstr "" 355 | 356 | #. Type: string 357 | #. Description 358 | #: ../atftpd.templates:15001 359 | msgid "" 360 | "A file where atftpd will write its logs. This file will be made writable for " 361 | "the user 'nobody' and group 'nogroup'." 362 | msgstr "" 363 | 364 | #. Type: string 365 | #. Description 366 | #: ../atftpd.templates:16001 367 | msgid "Base directory:" 368 | msgstr "" 369 | 370 | #. Type: string 371 | #. Description 372 | #: ../atftpd.templates:16001 373 | msgid "" 374 | "The directory tree from where atftpd can serve files. That directory must be " 375 | "world readable." 376 | msgstr "" 377 | -------------------------------------------------------------------------------- /debian/rules: -------------------------------------------------------------------------------- 1 | #!/usr/bin/make -f 2 | # Sample debian/rules that uses debhelper. 3 | # GNU copyright 1997 by Joey Hess. 4 | # 5 | # This version is for a hypothetical package that builds an 6 | # architecture-dependant package, as well as an architecture-independent 7 | # package. 8 | 9 | # Uncomment this to turn on verbose mode. 10 | export DH_VERBOSE=1 11 | 12 | # This has to be exported to make some magic below work. 13 | export DH_OPTIONS 14 | 15 | configure: configure-stamp 16 | 17 | configure-stamp: 18 | dh_testdir 19 | # Add here commands to configure the package. 20 | ./configure --prefix=/usr --mandir=/usr/share/man 21 | 22 | touch configure-stamp 23 | 24 | build: configure-stamp build-stamp 25 | build-stamp: 26 | dh_testdir 27 | 28 | # Add here commands to compile the package. 29 | $(MAKE) 30 | # For the woody backport 31 | #$(MAKE) LDFLAGS="--static" LIBREADLINE="-lreadline -lncurses -lpthread" LIBWRAP="-lwrap -lnsl" 32 | touch build-stamp 33 | 34 | clean: clean-patched 35 | 36 | clean-patched: 37 | dh_testdir 38 | dh_testroot 39 | debconf-updatepo 40 | rm -f build-stamp configure-stamp 41 | # Add here commands to clean up after the build process. 42 | [ ! -f Makefile ] || $(MAKE) clean 43 | [ ! -f Makefile ] || $(MAKE) distclean 44 | 45 | 46 | dh_clean 47 | 48 | install: DH_OPTIONS= 49 | install: build 50 | dh_testdir 51 | dh_testroot 52 | dh_clean -k 53 | dh_installdirs 54 | 55 | # Add here commands to install the package into debian/tmp. 56 | $(MAKE) install prefix=`pwd`/debian/tmp/usr \ 57 | mandir=`pwd`/debian/tmp/usr/share/man 58 | 59 | dh_movefiles 60 | dh_installdocs -patftp 61 | dh_installdocs -patftpd 62 | 63 | # Build architecture-independent files here. 64 | # Pass -i to all debhelper commands in this target to reduce clutter. 65 | binary-indep: build install 66 | 67 | # Build architecture-dependent files here. 68 | # Pass -a to all debhelper commands in this target to reduce clutter. 69 | binary-arch: DH_OPTIONS=-a 70 | binary-arch: build install 71 | dh_testdir 72 | dh_testroot 73 | dh_installdebconf 74 | dh_installinit 75 | # dh_installexamples 76 | # dh_installcron 77 | # dh_installmanpages 78 | # dh_installinfo 79 | dh_installchangelogs Changelog 80 | dh_strip 81 | dh_link 82 | dh_compress 83 | dh_fixperms 84 | # You may want to make some executables suid here. 85 | #dh_suidregister 86 | dh_installdeb 87 | dh_shlibdeps 88 | dh_gencontrol 89 | dh_md5sums 90 | dh_builddeb 91 | 92 | binary: binary-indep binary-arch 93 | 94 | #patch: patch-stamp 95 | #patch-stamp: 96 | # dpatch apply-all 97 | # dpatch call-all -a=pkg-info >patch-stamp 98 | # 99 | #unpatch: 100 | # dpatch deapply-all 101 | # rm -rf patch-stamp debian/patched 102 | 103 | .PHONY: build clean binary-indep binary-arch binary install 104 | -------------------------------------------------------------------------------- /debian/watch.old: -------------------------------------------------------------------------------- 1 | version=2 2 | ftp://ftp.mamalinux.com/pub/atftp/ atftp-([0-9\.]*)\.tar\.gz debian uupdate 3 | -------------------------------------------------------------------------------- /docs/pxespec.txt: -------------------------------------------------------------------------------- 1 | The PXE specification defined multicast TFTP knowed as MTFTP. This 2 | is not the same as RFC2090 and is defined in this document: 3 | 4 | ftp://download.intel.com/labs/manage/wfm/download/pxespec.pdf 5 | -------------------------------------------------------------------------------- /logger.c: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * logger.c 4 | * functions for logging messages. 5 | * 6 | * $Id: logger.c,v 1.12 2004/02/27 02:05:26 jp Exp $ 7 | * 8 | * Copyright (c) 2000 Jean-Pierre Lefebvre 9 | * and Remi Lefebvre 10 | * 11 | * atftp is free software; you can redistribute them and/or modify them 12 | * under the terms of the GNU General Public License as published by the 13 | * Free Software Foundation; either version 2 of the License, or (at your 14 | * option) any later version. 15 | * 16 | */ 17 | 18 | #include "config.h" 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include "logger.h" 32 | 33 | #define MAXLEN 128 34 | 35 | static int log_syslog_is_open = 0; 36 | static int log_priority = 0; 37 | static char *log_filename = NULL; 38 | static int log_fd; 39 | static FILE *log_fp = NULL; 40 | static char *log_ident; 41 | 42 | /* 43 | * Open a file for logging. If filename is NULL, then use 44 | * stderr for the client or the syslog for the server. Log 45 | * only message less or equal to priority. 46 | */ 47 | void open_logger(char *ident, char *filename, int priority) 48 | { 49 | close_logger(); /* make sure we initialise variables and close 50 | previously opened log. */ 51 | 52 | log_priority = priority; 53 | 54 | if (ident) 55 | log_ident = strdup(ident); 56 | else 57 | log_ident = "unset"; 58 | 59 | if (filename) 60 | { 61 | log_filename = strdup(filename); 62 | if (!strcmp(filename, "-")) 63 | { 64 | log_fd = STDOUT_FILENO; 65 | log_fp = fdopen(log_fd, "a"); 66 | return; 67 | } 68 | } 69 | else 70 | { 71 | openlog(log_ident, LOG_PID, LOG_DAEMON); 72 | log_syslog_is_open = 1; 73 | } 74 | 75 | if (log_filename) 76 | { 77 | if ((log_fd = open(log_filename, O_WRONLY | O_APPEND)) < 0) 78 | { 79 | openlog(log_ident, LOG_PID, LOG_DAEMON); 80 | log_syslog_is_open = 1; 81 | logger(LOG_CRIT, "Unable to open %s for logging, " 82 | "reverting to syslog", log_filename); 83 | } 84 | else 85 | log_fp = fdopen(log_fd, "a"); 86 | } 87 | } 88 | 89 | /* 90 | * Same as syslog but allows one to format a string, like printf, when logging to 91 | * file. This fonction will either call syslog or fprintf depending of the 92 | * previous call to open_logger(). 93 | */ 94 | void logger(int severity, const char *fmt, ...) 95 | { 96 | char message[MAXLEN]; 97 | char time_buf[MAXLEN]; 98 | char hostname[MAXLEN]; 99 | time_t t; 100 | struct tm *tm; 101 | 102 | 103 | va_list args; 104 | va_start(args, fmt); 105 | 106 | time(&t); 107 | tm = localtime(&t); 108 | strftime(time_buf, MAXLEN, "%b %d %H:%M:%S", tm); 109 | gethostname(hostname, MAXLEN); 110 | 111 | if (severity <= log_priority) 112 | { 113 | vsnprintf(message, sizeof(message), fmt, args); 114 | 115 | if (log_fp) 116 | { 117 | fprintf(log_fp, "%s %s %s[%d.%li]: %s\n", time_buf, hostname, 118 | log_ident, getpid(), pthread_self(), message); 119 | fflush(log_fp); 120 | } 121 | else if (log_syslog_is_open) 122 | syslog(severity, "%s", message); 123 | else 124 | fprintf(stderr, "%s %s %s[%d.%li]: %s\n", time_buf, hostname, 125 | log_ident, getpid(), pthread_self(), message); 126 | } 127 | va_end(args); 128 | } 129 | 130 | /* 131 | * Close the file or syslog. Initialise variables. 132 | */ 133 | void close_logger(void) 134 | { 135 | log_priority = 0; 136 | if (log_syslog_is_open) 137 | closelog(); 138 | log_syslog_is_open = 0; 139 | if (log_fp) 140 | fclose(log_fp); 141 | log_fp = NULL; 142 | if (log_filename) 143 | free(log_filename); 144 | log_filename = NULL; 145 | if (log_ident) 146 | free(log_ident); 147 | } 148 | -------------------------------------------------------------------------------- /logger.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * logger.h 4 | * 5 | * $Id: logger.h,v 1.6 2000/12/27 00:57:16 remi Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef logger_h 18 | #define logger_h 19 | 20 | #include 21 | 22 | void open_logger(char *ident, char *filename, int priority); 23 | void logger(int severity, const char *fmt, ...); 24 | void close_logger(void); 25 | 26 | #endif 27 | -------------------------------------------------------------------------------- /options.c: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * options.c 4 | * Set of functions to deal with the options structure and for parsing 5 | * options in TFTP data buffer. 6 | * 7 | * $Id: options.c,v 1.16 2003/04/25 00:16:18 jp Exp $ 8 | * 9 | * Copyright (c) 2000 Jean-Pierre Lefebvre 10 | * and Remi Lefebvre 11 | * 12 | * atftp is free software; you can redistribute them and/or modify them 13 | * under the terms of the GNU General Public License as published by the 14 | * Free Software Foundation; either version 2 of the License, or (at your 15 | * option) any later version. 16 | * 17 | */ 18 | 19 | #include "config.h" 20 | 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #if HAVE_ARGZ_H 27 | #include 28 | #else 29 | #include "argz.h" 30 | #endif 31 | 32 | #include 33 | #include 34 | #include "options.h" 35 | 36 | /* 37 | * Fill a structure with the request packet of the client. 38 | */ 39 | int opt_parse_request(char *data, int data_size, struct tftp_opt *options) 40 | { 41 | char *entry = NULL; 42 | char *tmp; 43 | struct tftphdr *tftp_data = (struct tftphdr *)data; 44 | size_t size = data_size - sizeof(tftp_data->th_opcode); 45 | 46 | /* sanity check - requests always end in a null byte, 47 | * check to prevent argz_next from reading past the end of 48 | * data, as it doesn't do bounds checks */ 49 | if (data_size == 0 || data[data_size-1] != '\0') 50 | return ERR; 51 | 52 | /* read filename */ 53 | entry = argz_next(tftp_data->th_stuff, size, entry); 54 | if (!entry) 55 | return ERR; 56 | else 57 | opt_set_options(options, "filename", entry); 58 | /* read mode */ 59 | entry = argz_next(tftp_data->th_stuff, size, entry); 60 | if (!entry) 61 | return ERR; 62 | else 63 | opt_set_options(options, "mode", entry); 64 | /* scan for options */ 65 | // FIXME: we should use opt_parse_options() here 66 | while ((entry = argz_next(tftp_data->th_stuff, size, entry))) 67 | { 68 | tmp = entry; 69 | entry = argz_next(tftp_data->th_stuff, size, entry); 70 | if (!entry) 71 | return ERR; 72 | else 73 | opt_set_options(options, tmp, entry); 74 | } 75 | return OK; 76 | } 77 | 78 | /* 79 | * Fill a structure looking only at TFTP options. 80 | */ 81 | int opt_parse_options(char *data, int data_size, struct tftp_opt *options) 82 | { 83 | char *entry = NULL; 84 | char *tmp; 85 | struct tftphdr *tftp_data = (struct tftphdr *)data; 86 | size_t size = data_size - sizeof(tftp_data->th_opcode); 87 | 88 | /* sanity check - options always end in a null byte, 89 | * check to prevent argz_next from reading past the end of 90 | * data, as it doesn't do bounds checks */ 91 | if (data_size == 0 || data[data_size-1] != '\0') 92 | return ERR; 93 | 94 | while ((entry = argz_next(tftp_data->th_stuff, size, entry))) 95 | { 96 | tmp = entry; 97 | entry = argz_next(tftp_data->th_stuff, size, entry); 98 | if (!entry) 99 | return ERR; 100 | else 101 | opt_set_options(options, tmp, entry); 102 | } 103 | return OK; 104 | } 105 | 106 | /* 107 | * Set an option by name in the structure. 108 | * name is the name of the option as in tftp_def.c. 109 | * value is it's new value, that must comply with the rfc's. 110 | * When setting an option, it is marked as specified. 111 | * 112 | */ 113 | int opt_set_options(struct tftp_opt *options, char *name, char *value) 114 | { 115 | int i; 116 | 117 | for (i = 0; i < OPT_NUMBER; i++) 118 | { 119 | if (strncasecmp(name, options[i].option, OPT_SIZE) == 0) 120 | { 121 | options[i].specified = 1; 122 | if (value) 123 | Strncpy(options[i].value, value, VAL_SIZE); 124 | else 125 | Strncpy(options[i].value, tftp_default_options[i].value, 126 | VAL_SIZE); 127 | return OK; 128 | } 129 | } 130 | return ERR; 131 | } 132 | 133 | /* 134 | * Return "value" for a given option name in the given option 135 | * structure. 136 | */ 137 | int opt_get_options(struct tftp_opt *options, char *name, char *value) 138 | { 139 | int i; 140 | 141 | for (i = 0; i < OPT_NUMBER; i++) 142 | { 143 | if (strncasecmp(name, options[i].option, OPT_SIZE) == 0) 144 | { 145 | if (options[i].enabled) 146 | Strncpy(value, options[i].value, VAL_SIZE); 147 | else 148 | return ERR; 149 | return OK; 150 | } 151 | } 152 | return ERR; 153 | } 154 | 155 | /* 156 | * Disable an option by name. 157 | */ 158 | int opt_disable_options(struct tftp_opt *options, char *name) 159 | { 160 | int i; 161 | 162 | for (i = 2; i < OPT_NUMBER; i++) 163 | { 164 | if (name == NULL) 165 | options[i].specified = 0; 166 | else 167 | { 168 | if (strncasecmp(name, options[i].option, OPT_SIZE) == 0) 169 | { 170 | options[i].specified = 0; 171 | return OK; 172 | } 173 | } 174 | } 175 | if (name == NULL) 176 | return OK; 177 | return ERR; 178 | } 179 | 180 | 181 | /* 182 | * Return 1 if one or more options are specified in the options structure. 183 | */ 184 | int opt_support_options(struct tftp_opt *options) 185 | { 186 | int i; 187 | int support = 0; 188 | 189 | for (i = 2; i < OPT_NUMBER; i++) 190 | { 191 | if (options[i].specified) 192 | support = 1; 193 | } 194 | return support; 195 | } 196 | 197 | /* 198 | * The next few functions deal with TFTP options. Function's name are self 199 | * explicative. 200 | */ 201 | 202 | int opt_get_tsize(struct tftp_opt *options) 203 | { 204 | int tsize; 205 | if (options[OPT_TSIZE].enabled && options[OPT_TSIZE].specified) 206 | { 207 | tsize = atoi(options[OPT_TSIZE].value); 208 | return tsize; 209 | } 210 | return ERR; 211 | } 212 | 213 | int opt_get_timeout(struct tftp_opt *options) 214 | { 215 | int timeout; 216 | if (options[OPT_TIMEOUT].enabled && options[OPT_TIMEOUT].specified) 217 | { 218 | timeout = atoi(options[OPT_TIMEOUT].value); 219 | return timeout; 220 | } 221 | return ERR; 222 | } 223 | 224 | int opt_get_blksize(struct tftp_opt *options) 225 | { 226 | int blksize; 227 | if (options[OPT_BLKSIZE].enabled && options[OPT_BLKSIZE].specified) 228 | { 229 | blksize = atoi(options[OPT_BLKSIZE].value); 230 | return blksize; 231 | } 232 | return ERR; 233 | } 234 | 235 | int opt_get_windowsize(struct tftp_opt *options) 236 | { 237 | int windowsize; 238 | if (options[OPT_WINDOWSIZE].enabled && options[OPT_WINDOWSIZE].specified) 239 | { 240 | windowsize = atoi(options[OPT_WINDOWSIZE].value); 241 | return windowsize; 242 | } 243 | return ERR; 244 | } 245 | 246 | int opt_get_multicast(struct tftp_opt *options, char *addr, int *port, int *mc) 247 | { 248 | char *token = NULL; 249 | char *string = NULL; 250 | char *temp = NULL; 251 | 252 | if (options[OPT_MULTICAST].enabled && options[OPT_MULTICAST].specified) 253 | { 254 | string = strdup(options[OPT_MULTICAST].value); 255 | /* get first argument */ 256 | if ((token = strtok_r(string, ",", &temp)) == NULL) 257 | { 258 | free(string); 259 | return ERR; 260 | } 261 | else 262 | Strncpy(addr, token, IPADDRLEN); 263 | /* get second argument */ 264 | if ((token = strtok_r(NULL, ",", &temp)) == NULL) 265 | { 266 | free(string); 267 | return ERR; 268 | } 269 | else 270 | { 271 | *port = atoi(token); 272 | if ((*port < 0) || (*port > 65536)) 273 | { 274 | free(string); 275 | return ERR; 276 | } 277 | } 278 | /* get third (last) argument */ 279 | if ((token = strtok_r(NULL, ",", &temp)) == NULL) 280 | { 281 | free(string); 282 | return ERR; 283 | } 284 | else 285 | { 286 | *mc = atoi(token); 287 | if ((*mc != 0) && (*mc != 1)) 288 | { 289 | free(string); 290 | return ERR; 291 | } 292 | } 293 | free(string); 294 | return *mc; 295 | } 296 | return ERR; 297 | } 298 | 299 | void opt_set_tsize(int tsize, struct tftp_opt *options) 300 | { 301 | snprintf(options[OPT_TSIZE].value, VAL_SIZE, "%d", tsize); 302 | } 303 | 304 | void opt_set_timeout(int timeout, struct tftp_opt *options) 305 | { 306 | snprintf(options[OPT_TIMEOUT].value, VAL_SIZE, "%d", timeout); 307 | } 308 | 309 | void opt_set_blksize(int blksize, struct tftp_opt *options) 310 | { 311 | snprintf(options[OPT_BLKSIZE].value, VAL_SIZE, "%d", blksize); 312 | } 313 | 314 | void opt_set_windowsize(int windowsize, struct tftp_opt *options) 315 | { 316 | snprintf(options[OPT_WINDOWSIZE].value, VAL_SIZE, "%d", windowsize); 317 | } 318 | 319 | void opt_set_multicast(struct tftp_opt *options, char *addr, int port, int mc) 320 | { 321 | snprintf(options[OPT_MULTICAST].value, VAL_SIZE, "%s,%d,%d", addr, port, 322 | mc); 323 | } 324 | 325 | /* 326 | * Format the content of the options structure (this is the content of a 327 | * read or write request) to a string. 328 | */ 329 | void opt_request_to_string(struct tftp_opt *options, char *string, int len) 330 | { 331 | int i, index = 0; 332 | 333 | for (i = 0; i < 2; i++) 334 | { 335 | if ((index + (int)strlen(options[i].option) + 2) < len) 336 | { 337 | Strncpy(string + index, options[i].option, len - index); 338 | index += strlen(options[i].option); 339 | Strncpy(string + index, ": ", len - index); 340 | index += 2; 341 | } 342 | if ((index + (int)strlen(options[i].value) + 2) < len) 343 | { 344 | Strncpy(string + index, options[i].value, len - index); 345 | index += strlen(options[i].value); 346 | Strncpy(string + index, ", ", len - index); 347 | index += 2; 348 | } 349 | } 350 | opt_options_to_string(options, string + index, len - index); 351 | } 352 | 353 | /* 354 | * Convert the options structure to a string. 355 | */ 356 | void opt_options_to_string(struct tftp_opt *options, char *string, int len) 357 | { 358 | int i, index = 0; 359 | 360 | for (i = 2; i < OPT_NUMBER; i++) 361 | { 362 | if (options[i].specified && options[i].enabled) 363 | { 364 | if ((index + (int)strlen(options[i].option) + 2) < len) 365 | { 366 | Strncpy(string + index, options[i].option, len - index); 367 | index += strlen(options[i].option); 368 | Strncpy(string + index, ": ", len - index); 369 | index += 2; 370 | } 371 | if ((index + (int)strlen(options[i].value) + 2) < len) 372 | { 373 | Strncpy(string + index, options[i].value, len - index); 374 | index += strlen(options[i].value); 375 | Strncpy(string + index, ", ", len - index); 376 | index += 2; 377 | } 378 | } 379 | } 380 | if (index > 0) 381 | string[index - 2] = 0; 382 | else 383 | string[0] = 0; 384 | } 385 | -------------------------------------------------------------------------------- /options.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * options.h 4 | * 5 | * $Id: options.h,v 1.7 2001/07/06 23:35:18 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef options_h 18 | #define options_h 19 | 20 | #include "tftp_def.h" 21 | 22 | /* Structure definition for tftp options. */ 23 | struct tftp_opt { 24 | char option[OPT_SIZE]; 25 | char value[VAL_SIZE]; 26 | int specified; /* specified by the client (for tftp server) */ 27 | int enabled; /* enabled for use by server or client */ 28 | }; 29 | 30 | extern struct tftp_opt tftp_default_options[OPT_NUMBER + 1]; 31 | 32 | int opt_parse_request(char *data, int data_size, struct tftp_opt *options); 33 | int opt_parse_options(char *data, int data_size, struct tftp_opt *options); 34 | int opt_set_options(struct tftp_opt *options, char *name, char *value); 35 | int opt_get_options(struct tftp_opt *options, char *name, char *value); 36 | int opt_disable_options(struct tftp_opt *options, char *name); 37 | int opt_support_options(struct tftp_opt *options); 38 | 39 | int opt_get_tsize(struct tftp_opt *options); 40 | int opt_get_timeout(struct tftp_opt *options); 41 | int opt_get_blksize(struct tftp_opt *options); 42 | int opt_get_windowsize(struct tftp_opt *options); 43 | int opt_get_multicast(struct tftp_opt *options, char *addr, int *port, int *mc); 44 | 45 | void opt_set_tsize(int tsize, struct tftp_opt *options); 46 | void opt_set_timeout(int timeout, struct tftp_opt *options); 47 | void opt_set_blksize(int blksize, struct tftp_opt *options); 48 | void opt_set_windowsize(int windowsize, struct tftp_opt *options); 49 | void opt_set_multicast(struct tftp_opt *options, char *addr, int port, int mc); 50 | 51 | void opt_request_to_string(struct tftp_opt *options, char *string, int len); 52 | void opt_options_to_string(struct tftp_opt *options, char *string, int len); 53 | 54 | #endif 55 | 56 | -------------------------------------------------------------------------------- /redhat/README: -------------------------------------------------------------------------------- 1 | The spec file provided in this directory was provided by Allen Reese 2 | . For support/requests regarding the rpm packages, 3 | please contact him. The rpm packages aren't officially supported by the 4 | project and we do not test them. The spec file is provided as a conveniance 5 | to redhat users. 6 | 7 | -- 8 | Remi Lefebvre Sat Jul 14 20:34:41 EST 2001 9 | -------------------------------------------------------------------------------- /redhat/atftp.spec.in: -------------------------------------------------------------------------------- 1 | Name: atftp 2 | Summary: Advanced Trivial File Transfer Protocol (ATFTP) - TFTP server 3 | Group: System Environment/Daemons 4 | Version: @VERSION@ 5 | Release: 1 6 | Copyright: GPL 7 | Vendor: Linux Networx Inc. 8 | Source: /usr/src/redhat/SOURCES/atftp-%{version}.tar.gz 9 | Buildroot: /var/tmp/atftp-buildroot 10 | Packager: Allen Reese 11 | 12 | 13 | %description 14 | Multithreaded TFTP server implementing all options (option extension and 15 | multicast) as specified in RFC1350, RFC2090, RFC2347, RFC2348 and RFC2349. 16 | Atftpd also support multicast protocol knowed as mtftp, defined in the PXE 17 | specification. The server supports being started from inetd(8) as well as 18 | a deamon using init scripts. 19 | 20 | 21 | %package client 22 | Summary: Advanced Trivial File Transfer Protocol (ATFTP) - TFTP client 23 | Group: Applications/Internet 24 | 25 | 26 | %description client 27 | Advanced Trivial File Transfer Protocol client program for requesting 28 | files using the TFTP protocol. 29 | 30 | 31 | %prep 32 | %setup 33 | 34 | 35 | %build 36 | %configure 37 | make 38 | 39 | 40 | %install 41 | [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != '/' ] && rm -rf $RPM_BUILD_ROOT 42 | %makeinstall 43 | 44 | 45 | %files 46 | %{_mandir}/man8/atftpd.8.gz 47 | %{_sbindir}/atftpd 48 | %{_mandir}/man8/in.tftpd.8.gz 49 | %{_sbindir}/in.tftpd 50 | 51 | 52 | %files client 53 | %{_mandir}/man1/atftp.1.gz 54 | %{_bindir}/atftp 55 | 56 | 57 | %preun 58 | 59 | 60 | %post 61 | 62 | 63 | %clean 64 | [ -n "$RPM_BUILD_ROOT" -a "$RPM_BUILD_ROOT" != '/' ] && rm -rf $RPM_BUILD_ROOT 65 | 66 | 67 | %changelog 68 | 69 | * Tue Jan 07 2003 Thayne Harbaugh 70 | - put client in sub-rpm 71 | -------------------------------------------------------------------------------- /stats.c: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * stats.c 4 | * some functions to collect statistics 5 | * 6 | * $Id: stats.c,v 1.6 2002/03/27 03:02:12 jp Exp $ 7 | * 8 | * Copyright (c) 2000 Jean-Pierre Lefebvre 9 | * and Remi Lefebvre 10 | * 11 | * atftp is free software; you can redistribute them and/or modify them 12 | * under the terms of the GNU General Public License as published by the 13 | * Free Software Foundation; either version 2 of the License, or (at your 14 | * option) any later version. 15 | */ 16 | 17 | #include "config.h" 18 | 19 | #include 20 | #include 21 | #include "tftp_def.h" 22 | #include "stats.h" 23 | #include "logger.h" 24 | 25 | /* 26 | * That structure allows global statistic to be collected. See stats.h. 27 | */ 28 | struct server_stats s_stats; 29 | 30 | /* 31 | * Must be called to initilise stats structure and record the 32 | * start time. 33 | */ 34 | void stats_start(void) 35 | { 36 | /* stats struct initialisation */ 37 | memset(&s_stats, 0, sizeof(s_stats)); 38 | s_stats.min_time.tv_sec = LONG_MAX; 39 | pthread_mutex_init(&s_stats.mutex, NULL); 40 | 41 | gettimeofday(&s_stats.start_time, NULL); 42 | } 43 | 44 | /* 45 | * Called when execution is finnished, before calling stats_print. 46 | */ 47 | void stats_end(void) 48 | { 49 | gettimeofday(&s_stats.end_time, NULL); 50 | } 51 | 52 | /* 53 | * Called by server threads each time a file is sent succesfully. 54 | * Be aware that a mutex is locked in there. 55 | */ 56 | void stats_send_locked(void) 57 | { 58 | pthread_mutex_lock(&s_stats.mutex); 59 | s_stats.number_of_server++; 60 | s_stats.num_file_send++; 61 | pthread_mutex_unlock(&s_stats.mutex); 62 | } 63 | 64 | /* 65 | * Called by verver threads each time a file is received. 66 | */ 67 | void stats_recv_locked(void) 68 | { 69 | pthread_mutex_lock(&s_stats.mutex); 70 | s_stats.number_of_server++; 71 | s_stats.num_file_recv++; 72 | pthread_mutex_unlock(&s_stats.mutex); 73 | } 74 | 75 | /* 76 | * Called by server threads each time tftpd_send_file or tftpd_recv_file 77 | * return with error. 78 | */ 79 | void stats_err_locked(void) 80 | { 81 | pthread_mutex_lock(&s_stats.mutex); 82 | s_stats.number_of_err++; 83 | pthread_mutex_unlock(&s_stats.mutex); 84 | } 85 | 86 | /* 87 | * Called by server threads when the maximum number of threads is reached. 88 | */ 89 | void stats_abort_locked(void) 90 | { 91 | pthread_mutex_lock(&s_stats.mutex); 92 | s_stats.number_of_abort++; 93 | pthread_mutex_unlock(&s_stats.mutex); 94 | } 95 | 96 | /* 97 | * Called by main thread only (in fact in tftpd_receive_request(), but 98 | * before stdin_mutex is released) every time a new thread is created. 99 | * We record the number of thread, the number of simultaeous thread, the 100 | * between threads. 101 | */ 102 | void stats_new_thread(int number_of_thread) 103 | { 104 | struct timeval tmp; 105 | 106 | if (number_of_thread > s_stats.max_simul_threads) 107 | s_stats.max_simul_threads = number_of_thread; 108 | 109 | /* calculate the arrival time of this thread */ 110 | if (s_stats.prev_time.tv_sec != 0) 111 | { 112 | gettimeofday(&s_stats.curr_time, NULL); 113 | timeval_diff(&s_stats.diff_time, &s_stats.curr_time, 114 | &s_stats.prev_time); 115 | if (timeval_diff(&tmp, &s_stats.diff_time, 116 | &s_stats.min_time) < 0) 117 | memcpy(&s_stats.min_time, &s_stats.diff_time, 118 | sizeof(struct timeval)); 119 | if (timeval_diff(&tmp, &s_stats.diff_time, 120 | &s_stats.max_time) > 0) 121 | memcpy(&s_stats.max_time, &s_stats.diff_time, 122 | sizeof(struct timeval)); 123 | memcpy(&s_stats.prev_time, &s_stats.curr_time, 124 | sizeof(struct timeval)); 125 | } 126 | else 127 | gettimeofday(&s_stats.prev_time, NULL); 128 | } 129 | 130 | /* 131 | * Called by server threads when the finnished to add CPU ressources 132 | * information. 133 | */ 134 | void stats_thread_usage_locked(void) 135 | { 136 | struct tms tms_tmp; 137 | 138 | times(&tms_tmp); 139 | pthread_mutex_lock(&s_stats.mutex); 140 | s_stats.tms_thread.tms_utime += tms_tmp.tms_utime; 141 | s_stats.tms_thread.tms_stime += tms_tmp.tms_stime; 142 | pthread_mutex_unlock(&s_stats.mutex); 143 | } 144 | 145 | /* 146 | * Called at the end of the main thread, when no other threads are 147 | * running, to print the final statistics. 148 | */ 149 | void stats_print(void) 150 | { 151 | struct timeval tmp; 152 | 153 | timeval_diff(&tmp, &s_stats.end_time, &s_stats.start_time); 154 | times(&s_stats.tms); 155 | s_stats.tms.tms_utime += s_stats.tms_thread.tms_utime; 156 | s_stats.tms.tms_stime += s_stats.tms_thread.tms_stime; 157 | 158 | logger(LOG_INFO, " Load measurements:"); 159 | logger(LOG_INFO, " User: %8.3fs Sys:%8.3fs", 160 | (double)(s_stats.tms.tms_utime) / CLOCKS_PER_SEC, 161 | (double)(s_stats.tms.tms_stime) / CLOCKS_PER_SEC); 162 | logger(LOG_INFO, " Total:%8.3fs CPU:%8.3f%%", 163 | (double)(tmp.tv_sec + tmp.tv_usec * 1e-6), 164 | (double)(s_stats.tms.tms_utime + s_stats.tms.tms_stime) / 165 | (double)(tmp.tv_sec + tmp.tv_usec * 1e-6)); 166 | logger(LOG_INFO, " Time between connections:"); 167 | if (s_stats.min_time.tv_sec == LONG_MAX) 168 | logger(LOG_INFO, " Min: ----- Max: -----"); 169 | else 170 | logger(LOG_INFO, " Min: %.3fs Max: %.3fs", 171 | (double)(s_stats.min_time.tv_sec + s_stats.min_time.tv_usec * 1e-6), 172 | (double)(s_stats.max_time.tv_sec + s_stats.max_time.tv_usec * 1e-6)); 173 | logger(LOG_INFO, " Thread stats:"); 174 | logger(LOG_INFO, " simultaneous threads: %d", s_stats.max_simul_threads); 175 | logger(LOG_INFO, " number of servers: %d", s_stats.number_of_server); 176 | logger(LOG_INFO, " number of aborts: %d", s_stats.number_of_abort); 177 | logger(LOG_INFO, " number of errors: %d", s_stats.number_of_err); 178 | logger(LOG_INFO, " number of files sent: %d", s_stats.num_file_send); 179 | logger(LOG_INFO, " number of files received: %d", s_stats.num_file_recv); 180 | } 181 | -------------------------------------------------------------------------------- /stats.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * stats.h 4 | * 5 | * $Id: stats.h,v 1.3 2000/12/27 17:02:23 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef stats_h 18 | #define stats_h 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /* structure to collect some stats */ 25 | struct server_stats { 26 | /* updated by main thread */ 27 | struct timeval start_time; 28 | struct timeval end_time; 29 | struct tms tms; 30 | 31 | /* connection statistics, updated by main thread */ 32 | int max_simul_threads; /* maximum number of simultaneous server */ 33 | struct timeval min_time; /* time between connection stats */ 34 | struct timeval max_time; 35 | struct timeval curr_time; /* temporary usage for calculation */ 36 | struct timeval prev_time; 37 | struct timeval diff_time; 38 | 39 | /* updated by server thread */ 40 | pthread_mutex_t mutex; 41 | struct tms tms_thread; 42 | int number_of_server; /* number of server that return successfully */ 43 | int number_of_abort; /* when number max of client is reached */ 44 | int number_of_err; /* send or receive that return with error */ 45 | int num_file_send; 46 | int num_file_recv; 47 | int byte_send; /* total byte transferred to client (file) */ 48 | int byte_recv; /* total byte read from client (file) */ 49 | }; 50 | 51 | /* Functions defined in stats.c */ 52 | void stats_start(void); 53 | void stats_end(void); 54 | void stats_send_locked(void); 55 | void stats_recv_locked(void); 56 | void stats_err_locked(void); 57 | void stats_abort_locked(void); 58 | void stats_new_thread(int number_of_thread); 59 | void stats_thread_usage_locked(void); 60 | void stats_print(void); 61 | 62 | #endif 63 | -------------------------------------------------------------------------------- /test/Makefile.am: -------------------------------------------------------------------------------- 1 | TESTS = test.sh 2 | CLEANFILES = *~ 3 | -------------------------------------------------------------------------------- /test/load.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -lt 1 ]; then 4 | echo "Usage: load.sh [host] [port]" 5 | exit 1 6 | fi 7 | 8 | TFTP=../atftp 9 | HOST=$1 10 | PORT=$2 11 | FILE=linux 12 | CONCURENT=40 13 | TIMEOUT=80 14 | LOOP=1 15 | i=$LOOP 16 | while [ $i -gt 0 ]; do 17 | echo -n "Loop $i " 18 | j=$CONCURENT 19 | while [ $j -gt 0 ]; do 20 | $TFTP --tftp-timeout 5 --timeout 10 --get -r $FILE -l /dev/null $HOST $PORT 2>$j.out& 21 | echo -n "." 22 | j=$[ $j - 1 ] 23 | done 24 | echo " done" 25 | i=$[ $i - 1 ] 26 | if [ $i -gt 0 ]; then 27 | sleep $TIMEOUT 28 | fi 29 | done 30 | -------------------------------------------------------------------------------- /test/mtftp.conf: -------------------------------------------------------------------------------- 1 | # format is: 2 | # file_name IP Port 3 | 4 | linux 239.255.1.1 3001 5 | pxelinux.0 239.255.1.2 3001 6 | -------------------------------------------------------------------------------- /test/pcre_pattern.txt: -------------------------------------------------------------------------------- 1 | ^[p]?pxelinux.cfg/[0-9A-F]{1,6}$ pxelinux.cfg/default 2 | ^[p]?pxelinux.0$ pxelinux.0 3 | linux linux 4 | ^str$ replaced1 5 | ^str replaced2 6 | str$ replaced3 7 | repl(ace) m$1 8 | ^\w*\.conf$ master.conf 9 | -------------------------------------------------------------------------------- /test/test_suite.txt: -------------------------------------------------------------------------------- 1 | 1) test get, put 2 | 2) test blksize 3 | 3) test tsize 4 | 4) test timeout 5 | 5) -------------------------------------------------------------------------------- /tftp.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftp.h 4 | * 5 | * $Id: tftp.h,v 1.15 2003/03/19 04:02:49 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef tftp_h 18 | #define tftp_h 19 | 20 | #include 21 | #include 22 | #include 23 | #include "tftp_def.h" 24 | #include "config.h" 25 | 26 | struct client_data { 27 | char *data_buffer; /* used for sending and receiving of data */ 28 | int data_buffer_size; /* size of the buffer, may be reallocated */ 29 | 30 | char local_file[VAL_SIZE]; /* the file we are reading or writing is not 31 | necessary the same on the server */ 32 | struct tftp_opt *tftp_options; /* hold requested options */ 33 | struct tftp_opt *tftp_options_reply; /* hold server reply */ 34 | 35 | int timeout; /* client side timeout for select() */ 36 | int checkport; /* Disable TID check. Violate RFC */ 37 | int trace; /* debugging information */ 38 | int verbose; /* to print message at each step */ 39 | 40 | char hostname[MAXLEN]; /* peer's hostname */ 41 | short port; /* tftp port for the server, 69 by default */ 42 | 43 | struct sockaddr_storage sa_peer; /* peer address and port */ 44 | struct sockaddr_storage sa_local; /* local address and port */ 45 | int sockfd; 46 | 47 | int connected; /* we are 'connected' */ 48 | 49 | #ifdef HAVE_MTFTP 50 | /* for MTFTP */ 51 | int mtftp_client_port; 52 | char mtftp_mcast_ip[MAXLEN]; 53 | int mtftp_listen_delay; 54 | int mtftp_timeout_delay; 55 | #endif 56 | 57 | /* statistics */ 58 | struct timeval start_time; 59 | struct timeval end_time; 60 | int file_size; 61 | 62 | #if DEBUG 63 | int delay; 64 | #endif 65 | 66 | }; 67 | 68 | /* Defined in tftp_file.c */ 69 | int tftp_find_bitmap_hole(int prev_hole, unsigned int *bitmap); 70 | int tftp_receive_file(struct client_data *data); 71 | int tftp_send_file(struct client_data *data); 72 | /* Defined in tftp_mtftp.c */ 73 | #ifdef HAVE_MTFTP 74 | int tftp_mtftp_receive_file(struct client_data *data); 75 | #endif 76 | 77 | #endif 78 | -------------------------------------------------------------------------------- /tftp_def.c: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftp_def.c 4 | * 5 | * $Id: tftp_def.c,v 1.15 2004/02/13 03:16:09 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #include "config.h" 18 | 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include "tftp_def.h" 26 | #include "options.h" 27 | #include "logger.h" 28 | 29 | /* 30 | * This is the default option structure, that must be used 31 | * for initialisation. 32 | */ 33 | 34 | // FIXME: is there a way to use TIMEOUT and SEGSIZE here? 35 | struct tftp_opt tftp_default_options[OPT_NUMBER + 1] = { 36 | { "filename", "", 0, 1}, /* file to transfer */ 37 | { "mode", "octet", 0, 1}, /* mode for transfer */ 38 | { "tsize", "0", 0, 1 }, /* RFC1350 options. See RFC2347, */ 39 | { "timeout", "5", 0, 1 }, /* 2348, 2349, 2090. */ 40 | { "blksize", "512", 0, 1 }, /* This is the default option */ 41 | { "multicast", "", 0, 1 }, /* structure */ 42 | { "password", "", 0, 1}, /* password */ 43 | { "windowsize", "1", 0, 1 }, /* Default without RFC7440 */ 44 | { "", "", 0, 0} 45 | }; 46 | 47 | /* Error message defined in RFC1350. */ 48 | char *tftp_errmsg[9] = { 49 | "Undefined error code", 50 | "File not found", 51 | "Access violation", 52 | "Disk full or allocation exceeded", 53 | "Illegal TFTP operation", 54 | "Unknown transfer ID", 55 | "File already exists", 56 | "No such user", 57 | "Failure to negotiate RFC2347 options", 58 | }; 59 | 60 | 61 | /* 62 | * Compute the difference of two timeval structs handling wrap around. 63 | * The result is returned in *res. 64 | * Return value are: 65 | * 1 if t1 > t0 66 | * 0 if t1 = t0 67 | * -1 if t1 < t0 68 | */ 69 | int timeval_diff(struct timeval *res, struct timeval *t1, struct timeval *t0) 70 | { 71 | int neg = 1; 72 | res->tv_sec = t1->tv_sec - t0->tv_sec; 73 | res->tv_usec = t1->tv_usec - t0->tv_usec; 74 | 75 | while (res->tv_sec < 0 || res->tv_usec < 0) 76 | { 77 | if (res->tv_sec < 0 || (res->tv_sec == 0 && res->tv_usec < 0)) 78 | { 79 | neg = -neg; 80 | res->tv_sec = -res->tv_sec; 81 | res->tv_usec = -res->tv_usec; 82 | } 83 | if (res->tv_usec < 0) 84 | { 85 | long s = (res->tv_usec - 999999) / 1000000; 86 | res->tv_sec += s; 87 | res->tv_usec -= s * 1000000; 88 | } 89 | } 90 | if (res->tv_usec >= 1000000) 91 | { 92 | long s = res->tv_usec / 1000000; 93 | res->tv_sec += s; 94 | res->tv_usec -= s * 1000000; 95 | } 96 | if (res->tv_sec == 0 && res->tv_usec == 0) 97 | { 98 | return 0; 99 | } 100 | return neg; 101 | } 102 | 103 | /* 104 | * Print a string in engineering notation. 105 | * 106 | * IN: 107 | * value: value to print 108 | * string: if NULL, the function print to stdout, else if print 109 | * to the string. 110 | * format: format string for printf. 111 | */ 112 | int print_eng(double value, char *string, int size, char *format) 113 | { 114 | char suffix[] = {'f', 'p', 'n', 'u', 'm', 0, 'k', 'M', 'G', 'T', 'P'}; 115 | double tmp; 116 | double div = 1e-15; 117 | int i; 118 | 119 | 120 | for (i = 0; i < 11; i++) 121 | { 122 | tmp = value / div; 123 | if ((tmp > 1.0) && (tmp < 1000.0)) 124 | break; 125 | div *= 1000.0; 126 | } 127 | if (string) 128 | snprintf(string, size, format, tmp, suffix[i]); 129 | else 130 | printf(format, tmp, suffix[i]); 131 | return OK; 132 | } 133 | 134 | /* 135 | * This is a strncpy function that take care of string NULL termination 136 | */ 137 | inline char *Strncpy(char *to, const char *from, size_t size) 138 | { 139 | strncpy(to, from, size); 140 | if (size>0) 141 | to[size-1] = '\000'; 142 | return to; 143 | } 144 | 145 | 146 | /* 147 | * gethostbyname replacement that is reentrant. This function is copyied 148 | * from the libc manual. 149 | */ 150 | int Gethostbyname(char *addr, struct hostent *host) 151 | { 152 | struct hostent *hp; 153 | char *tmpbuf; 154 | size_t tmpbuflen; 155 | int res; 156 | int herr; 157 | 158 | tmpbuflen = 1024; 159 | 160 | if ((tmpbuf = (char *)malloc(tmpbuflen)) == NULL) 161 | return ERR; 162 | 163 | res = gethostbyname_r(addr, host, tmpbuf, tmpbuflen, &hp, &herr); 164 | 165 | free(tmpbuf); 166 | 167 | /* Check for errors. */ 168 | if (res != 0) 169 | { 170 | logger(LOG_ERR, "%s: %d: gethostbyname_r: %s", 171 | __FILE__, __LINE__, strerror(herr)); 172 | return ERR; 173 | } 174 | if (hp != host) 175 | { 176 | logger(LOG_ERR, "%s: %d: abnormal return value", 177 | __FILE__, __LINE__); 178 | return ERR; 179 | } 180 | 181 | return OK; 182 | } 183 | 184 | int 185 | sockaddr_family_supported(const struct sockaddr_storage *ss) 186 | { 187 | if (ss->ss_family == AF_INET || ss->ss_family == AF_INET6) 188 | return 1; 189 | else 190 | return 0; 191 | } 192 | 193 | char * 194 | sockaddr_print_addr(const struct sockaddr_storage *ss, char *buf, size_t len) 195 | { 196 | const void *addr; 197 | if (ss->ss_family == AF_INET) 198 | addr = &((const struct sockaddr_in *)ss)->sin_addr; 199 | else if (ss->ss_family == AF_INET6) 200 | addr = &((const struct sockaddr_in6 *)ss)->sin6_addr; 201 | else 202 | return "sockaddr_print: unsupported address family"; 203 | return (char *)inet_ntop(ss->ss_family, addr, buf, len); 204 | } 205 | 206 | uint16_t sockaddr_get_port(const struct sockaddr_storage *ss) 207 | { 208 | if (ss->ss_family == AF_INET) 209 | return ntohs(((const struct sockaddr_in *)ss)->sin_port); 210 | if (ss->ss_family == AF_INET6) 211 | return ntohs(((const struct sockaddr_in6 *)ss)->sin6_port); 212 | return 0; 213 | } 214 | 215 | void sockaddr_set_port(struct sockaddr_storage *ss, uint16_t port) 216 | { 217 | if (ss->ss_family == AF_INET) 218 | ((struct sockaddr_in *)ss)->sin_port = htons(port); 219 | else if (ss->ss_family == AF_INET6) 220 | ((struct sockaddr_in6 *)ss)->sin6_port = htons(port); 221 | else 222 | assert(!"sockaddr_set_port: unsupported address family"); 223 | } 224 | 225 | int sockaddr_equal(const struct sockaddr_storage *left, 226 | const struct sockaddr_storage *right) 227 | { 228 | if (left->ss_family != right->ss_family) 229 | return 0; 230 | if (left->ss_family == AF_INET) 231 | { 232 | const struct sockaddr_in 233 | *sa_left = (const struct sockaddr_in *)left, 234 | *sa_right = (const struct sockaddr_in *)right; 235 | return (sa_left->sin_port == sa_right->sin_port && 236 | sa_left->sin_addr.s_addr == sa_right->sin_addr.s_addr); 237 | } 238 | if (left->ss_family == AF_INET6) 239 | { 240 | const struct sockaddr_in6 241 | *sa_left = (const struct sockaddr_in6 *)left, 242 | *sa_right = (const struct sockaddr_in6 *)right; 243 | return (sa_left->sin6_port == sa_right->sin6_port && 244 | memcmp(&sa_left->sin6_addr, &sa_right->sin6_addr, 245 | sizeof(sa_left->sin6_addr)) == 0 && 246 | sa_left->sin6_scope_id == sa_right->sin6_scope_id); 247 | } 248 | assert(!"sockaddr_equal: unsupported address family"); 249 | } 250 | 251 | int sockaddr_equal_addr(const struct sockaddr_storage *left, 252 | const struct sockaddr_storage *right) 253 | { 254 | if (left->ss_family != right->ss_family) 255 | return 0; 256 | if (left->ss_family == AF_INET) 257 | { 258 | const struct sockaddr_in 259 | *sa_left = (const struct sockaddr_in *)left, 260 | *sa_right = (const struct sockaddr_in *)right; 261 | return sa_left->sin_addr.s_addr == sa_right->sin_addr.s_addr; 262 | } 263 | if (left->ss_family == AF_INET6) 264 | { 265 | const struct sockaddr_in6 266 | *sa_left = (const struct sockaddr_in6 *)left, 267 | *sa_right = (const struct sockaddr_in6 *)right; 268 | return (memcmp(&sa_left->sin6_addr, &sa_right->sin6_addr, 269 | sizeof(sa_left->sin6_addr)) == 0 && 270 | sa_left->sin6_scope_id == sa_right->sin6_scope_id); 271 | } 272 | assert(!"sockaddr_equal_addr: unsupported address family"); 273 | } 274 | 275 | int sockaddr_is_multicast(const struct sockaddr_storage *ss) 276 | { 277 | if (ss->ss_family == AF_INET) 278 | return IN_MULTICAST(ntohl(((const struct sockaddr_in *)ss) 279 | ->sin_addr.s_addr)); 280 | if (ss->ss_family == AF_INET6) 281 | return IN6_IS_ADDR_MULTICAST(&((const struct sockaddr_in6 *)ss) 282 | ->sin6_addr); 283 | return 0; 284 | } 285 | 286 | void sockaddr_get_mreq(const struct sockaddr_storage *ss, 287 | union ip_mreq_storage *mreq) 288 | { 289 | if (ss->ss_family == AF_INET) 290 | { 291 | const struct sockaddr_in *sa = (const struct sockaddr_in *)ss; 292 | mreq->v4.imr_multiaddr = sa->sin_addr; 293 | mreq->v4.imr_interface.s_addr = htonl(INADDR_ANY); 294 | } 295 | else if (ss->ss_family == AF_INET6) 296 | { 297 | const struct sockaddr_in6 *sa = (const struct sockaddr_in6 *)ss; 298 | mreq->v6.ipv6mr_multiaddr = sa->sin6_addr; 299 | mreq->v6.ipv6mr_interface = 0; /* ??? */ 300 | } 301 | else 302 | { 303 | assert(!"sockaddr_get_mreq: unsupported address family"); 304 | } 305 | } 306 | 307 | int 308 | sockaddr_set_addrinfo(struct sockaddr_storage *ss, const struct addrinfo *ai) 309 | { 310 | while (ai->ai_family != AF_INET && ai->ai_family != AF_INET6) 311 | { 312 | ai = ai->ai_next; 313 | if (!ai) 314 | { 315 | errno = EAFNOSUPPORT; 316 | return -1; 317 | } 318 | } 319 | 320 | assert(sizeof(*ss) >= ai->ai_addrlen); 321 | memcpy(ss, ai->ai_addr, ai->ai_addrlen); 322 | return 0; 323 | } 324 | -------------------------------------------------------------------------------- /tftp_def.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftp_def.h 4 | * 5 | * $Id: tftp_def.h,v 1.17 2004/02/13 03:16:09 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef tftp_def_h 18 | #define tftp_def_h 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | /* standard return value */ 25 | #define OK 0 26 | #define ERR -1 27 | #define ABORT -2 28 | #define QUIT -10 29 | 30 | #define MAXLEN 256 /* For file names and such */ 31 | #define IPADDRLEN 24 /* For IPv4 and IPv6 address string */ 32 | #define TIMEOUT 5 /* Client timeout */ 33 | #define S_TIMEOUT 5 /* Server timout. */ 34 | #define NB_OF_RETRY 5 35 | #define MAXBLOCKS ((1 << (32 - 9)) - 1) /* Maximum blocks we will xfer */ 36 | 37 | /* definition to use tftp_options structure */ 38 | #define OPT_FILENAME 0 39 | #define OPT_MODE 1 40 | #define OPT_TSIZE 2 41 | #define OPT_TIMEOUT 3 42 | #define OPT_BLKSIZE 4 43 | #define OPT_MULTICAST 5 44 | #define OPT_PASSWORD 6 45 | #define OPT_WINDOWSIZE 7 46 | #define OPT_NUMBER 8 /* number of OPT_xx options */ 47 | 48 | #define OPT_SIZE 12 49 | #define VAL_SIZE MAXLEN 50 | 51 | extern char *tftp_errmsg[9]; 52 | 53 | int timeval_diff(struct timeval *res, struct timeval *t1, struct timeval *t0); 54 | int print_eng(double value, char *string, int size, char *format); 55 | char *Strncpy(char *to, const char *from, size_t size); 56 | int Gethostbyname(char *addr, struct hostent *host); 57 | 58 | int sockaddr_family_supported(const struct sockaddr_storage *ss); 59 | char *sockaddr_print_addr(const struct sockaddr_storage *, char *, size_t); 60 | #define SOCKADDR_PRINT_ADDR_LEN INET6_ADDRSTRLEN 61 | uint16_t sockaddr_get_port(const struct sockaddr_storage *); 62 | void sockaddr_set_port(struct sockaddr_storage *, uint16_t); 63 | int sockaddr_equal(const struct sockaddr_storage *, 64 | const struct sockaddr_storage *); 65 | int sockaddr_equal_addr(const struct sockaddr_storage *, 66 | const struct sockaddr_storage *); 67 | int sockaddr_is_multicast(const struct sockaddr_storage *); 68 | 69 | union ip_mreq_storage 70 | { 71 | struct ip_mreq v4; 72 | struct ipv6_mreq v6; 73 | }; 74 | void 75 | sockaddr_get_mreq(const struct sockaddr_storage *, union ip_mreq_storage *); 76 | 77 | int 78 | sockaddr_set_addrinfo(struct sockaddr_storage *ss, const struct addrinfo *ai); 79 | 80 | #endif 81 | -------------------------------------------------------------------------------- /tftp_io.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftp_io.h 4 | * 5 | * $Id: tftp_io.h,v 1.18 2004/02/13 03:16:09 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef tftp_io_h 18 | #define tftp_io_h 19 | 20 | #include 21 | #include 22 | #include "tftp_def.h" 23 | #include "options.h" 24 | 25 | /* missing from */ 26 | /* new opcode */ 27 | #define OACK 06 28 | /* new error code */ 29 | #define EOPTNEG 8 /* error in option negotiation */ 30 | 31 | /* return value of tftp_get_packet */ 32 | #define GET_DISCARD 0 33 | #define GET_TIMEOUT 1 34 | #define GET_RRQ 2 35 | #define GET_WRQ 3 36 | #define GET_ACK 4 37 | #define GET_OACK 5 38 | #define GET_ERROR 6 39 | #define GET_DATA 7 40 | 41 | /* function prototypes */ 42 | int tftp_send_request(int socket, struct sockaddr_storage *s_inn, short type, 43 | char *data_buffer, int data_buffer_size, 44 | struct tftp_opt *tftp_options); 45 | int tftp_send_ack(int socket, struct sockaddr_storage *s_inn, long block_number); 46 | int tftp_send_oack(int socket, struct sockaddr_storage *s_inn, struct tftp_opt *tftp_options, 47 | char *buffer, int buffer_size); 48 | int tftp_send_error(int socket, struct sockaddr_storage *s_inn, short err_code, 49 | char *buffer, int buffer_size); 50 | int tftp_send_data(int socket, struct sockaddr_storage *s_inn, long block_number, 51 | int size, char *data); 52 | int tftp_get_packet(int sock1, int sock2, int *sock, struct sockaddr_storage *sa, 53 | struct sockaddr_storage *from, struct sockaddr_storage *to, 54 | int timeout, int timeout_usec, int *size, char *data); 55 | int tftp_file_read(FILE *fp, char *buffer, int buffer_size, long block_number, int convert, 56 | long *prev_block_number, long *prev_file_pos, int *temp); 57 | int tftp_file_write(FILE *fp, char *data_buffer, int data_buffer_size, long block_number, 58 | int data_size, int convert, long *prev_block_number, int *temp); 59 | long tftp_rollover_blocknumber(short block_number, long prev_block_number, unsigned short wrap_to); 60 | #endif 61 | -------------------------------------------------------------------------------- /tftpd.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftpd.h 4 | * 5 | * $Id: tftpd.h,v 1.22 2004/02/27 02:05:26 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef tftpd_h 18 | #define tftpd_h 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "tftp_io.h" 25 | 26 | /* 27 | * Per thread data. There is a thread for each client or group 28 | * (multicast) of client. 29 | */ 30 | struct thread_data { 31 | pthread_t tid; 32 | 33 | /* private to thread */ 34 | char *data_buffer; 35 | int data_buffer_size; 36 | 37 | int timeout; 38 | int checkport; /* Disable TID check. Violate RFC */ 39 | int mcast_switch_client; /* When set, server will switch to next client 40 | on first timeout from the current client. */ 41 | int trace; 42 | 43 | int sockfd; 44 | 45 | /* multicast stuff */ 46 | short mc_port; /* multicast port */ 47 | char *mc_addr; /* multicast address */ 48 | struct sockaddr_storage sa_mcast; 49 | union ip_mreq_storage mcastaddr; 50 | u_char mcast_ttl; 51 | 52 | /* 53 | * Self can read/write until client_ready is set. Then only allowed to read. 54 | * Other thread can read it only when client_ready is set. Remember that access 55 | * to client_ready below is protected by a mutex. 56 | */ 57 | struct tftp_opt *tftp_options; 58 | 59 | /* 60 | * Must lock to insert in the list or search, but not to read or write 61 | * in the client_info structure, since only the propriotary thread do it. 62 | */ 63 | pthread_mutex_t client_mutex; 64 | struct client_info *client_info; 65 | int client_ready; /* one if other thread may add client */ 66 | 67 | /* must be lock (list lock) to update */ 68 | struct thread_data *prev; 69 | struct thread_data *next; 70 | }; 71 | 72 | struct client_info { 73 | struct sockaddr_storage client; 74 | int done; /* that client as receive it's file */ 75 | struct client_info *next; 76 | }; 77 | 78 | /* 79 | * Functions defined in tftpd_file.c 80 | */ 81 | int tftpd_rules_check(char *filename); 82 | int tftpd_receive_file(struct thread_data *data); 83 | int tftpd_send_file(struct thread_data *data); 84 | 85 | /* 86 | * Defined in tftpd_list.c, operation on thread_data list. 87 | */ 88 | int tftpd_list_add(struct thread_data *new); 89 | int tftpd_list_remove(struct thread_data *old); 90 | int tftpd_list_num_of_thread(void); 91 | int tftpd_list_find_multicast_server_and_add(struct thread_data **thread, 92 | struct thread_data *data, 93 | struct client_info *client); 94 | /* 95 | * Defined in tftpd_list.c, operation on client structure list. 96 | */ 97 | void tftpd_clientlist_ready(struct thread_data *thread); 98 | void tftpd_clientlist_remove(struct thread_data *thread, 99 | struct client_info *client); 100 | void tftpd_clientlist_free(struct thread_data *thread); 101 | int tftpd_clientlist_done(struct thread_data *thread, 102 | struct client_info *client, 103 | struct sockaddr_storage *sock); 104 | int tftpd_clientlist_next(struct thread_data *thread, 105 | struct client_info **client); 106 | void tftpd_list_kill_threads(void); 107 | 108 | /* 109 | * Defines in tftpd_mcast.c 110 | */ 111 | int tftpd_mcast_get_tid(char **addr, short *port); 112 | int tftpd_mcast_free_tid(char *addr, short port); 113 | int tftpd_mcast_parse_opt(char *addr, char *ports); 114 | 115 | #endif 116 | -------------------------------------------------------------------------------- /tftpd_list.c: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftpd_list.c 4 | * thread_data and client list related functions 5 | * 6 | * $Id: tftpd_list.c,v 1.9 2004/02/27 02:05:26 jp Exp $ 7 | * 8 | * Copyright (c) 2000 Jean-Pierre Lefebvre 9 | * and Remi Lefebvre 10 | * 11 | * atftp is free software; you can redistribute them and/or modify them 12 | * under the terms of the GNU General Public License as published by the 13 | * Free Software Foundation; either version 2 of the License, or (at your 14 | * option) any later version. 15 | * 16 | */ 17 | 18 | #include "config.h" 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include "tftpd.h" 25 | #include "logger.h" 26 | 27 | /* 28 | * thread_data is a double link list of server threads. Server threads 29 | * are started by the main thread when a new request arrives. The number 30 | * of threads running is held in number_of_thread. Any access to the 31 | * thread_data list: insertion and extraction of elements must be protected 32 | * by the mutex. This is done in this file by all functions playing with the thread list. 33 | * Note that individual threads do not need to lock the list when playing in their data. 34 | * See tftpd.h. 35 | * 36 | * In addition, it is needed to use mutex when working on the client list of 37 | * individual thread. In some case, the thread data mutex is needed also. 38 | * Again, the functions in this file take care of this. 39 | */ 40 | 41 | struct thread_data *thread_data = NULL; /* head of thread list */ 42 | static int number_of_thread = 0; 43 | 44 | pthread_mutex_t thread_list_mutex = PTHREAD_MUTEX_INITIALIZER; 45 | 46 | /* 47 | * Add a new thread_data structure to the list. Thread list mutex is locked 48 | * before walking the list and doing the insertion. 49 | */ 50 | int tftpd_list_add(struct thread_data *new) 51 | { 52 | pthread_mutex_lock(&thread_list_mutex); 53 | 54 | struct thread_data *current = thread_data; 55 | int ret; 56 | 57 | number_of_thread++; 58 | 59 | ret = number_of_thread; 60 | 61 | if (thread_data == NULL) 62 | { 63 | thread_data = new; 64 | new->prev = NULL; 65 | new->next = NULL; 66 | } 67 | else 68 | { 69 | while (current->next != NULL) 70 | current = current->next; 71 | current->next = new; 72 | new->prev = current; 73 | new->next = NULL; 74 | } 75 | pthread_mutex_unlock(&thread_list_mutex); 76 | return ret; 77 | } 78 | 79 | /* 80 | * Remove a thread_data structure from the list. 81 | */ 82 | int tftpd_list_remove(struct thread_data *old) 83 | { 84 | pthread_mutex_lock(&thread_list_mutex); 85 | 86 | struct thread_data *current = thread_data; 87 | int ret; 88 | 89 | number_of_thread--; 90 | ret = number_of_thread; 91 | 92 | if (thread_data == old) 93 | { 94 | if (thread_data->next != NULL) 95 | { 96 | thread_data = thread_data->next; 97 | thread_data->prev = NULL; 98 | } 99 | else 100 | thread_data = NULL; 101 | } 102 | else 103 | { 104 | while (current != old) 105 | current = current->next; 106 | if (current->next && current->prev) 107 | { 108 | current->prev->next = current->next; 109 | current->next->prev = current->prev; 110 | } 111 | else 112 | current->prev->next = NULL; 113 | } 114 | pthread_mutex_unlock(&thread_list_mutex); 115 | return ret; 116 | } 117 | 118 | /* 119 | * Return the number of threads actually started. 120 | */ 121 | int tftpd_list_num_of_thread(void) 122 | { 123 | int ret; 124 | 125 | pthread_mutex_lock(&thread_list_mutex); 126 | ret = number_of_thread; 127 | pthread_mutex_unlock(&thread_list_mutex); 128 | return ret; 129 | } 130 | 131 | /* 132 | * This function looks for a thread serving exactly the same 133 | * file and with the same options as another client. This implies a 134 | * multicast enabled client. 135 | */ 136 | int tftpd_list_find_multicast_server_and_add(struct thread_data **thread, 137 | struct thread_data *data, 138 | struct client_info *client) 139 | { 140 | /* lock the whole list before walking it */ 141 | pthread_mutex_lock(&thread_list_mutex); 142 | 143 | struct thread_data *current = thread_data; /* head of the list */ 144 | struct tftp_opt *tftp_options = data->tftp_options; 145 | struct client_info *tmp; 146 | char options[MAXLEN]; 147 | char string[MAXLEN]; 148 | char *index; 149 | int len; 150 | 151 | *thread = NULL; 152 | 153 | opt_request_to_string(tftp_options, options, MAXLEN); 154 | index = strstr(options, "multicast"); 155 | len = (int)((unsigned long)index - (unsigned long)options); 156 | 157 | while (current) 158 | { 159 | if (current != data) 160 | { 161 | /* Lock the client list before reading client ready state */ 162 | pthread_mutex_lock(¤t->client_mutex); 163 | if (current->client_ready == 1) 164 | { 165 | opt_request_to_string(current->tftp_options, string, MAXLEN); 166 | /* must have exact same option string */ 167 | if (strncmp(string, options, len) == 0) 168 | { 169 | *thread = current; 170 | /* insert the new client at the end. If the client is already 171 | in the list, don't add it again. */ 172 | tmp = current->client_info; 173 | 174 | while (1) 175 | { 176 | if (sockaddr_equal(&tmp->client, &client->client) && 177 | (tmp->done == 0)) 178 | { 179 | /* unlock mutex and exit */ 180 | pthread_mutex_unlock(¤t->client_mutex); 181 | pthread_mutex_unlock(&thread_list_mutex); 182 | return 2; 183 | } 184 | if (tmp->next == NULL) 185 | break; 186 | tmp = tmp->next; 187 | } 188 | tmp->next = client; 189 | /* unlock mutex and exit */ 190 | pthread_mutex_unlock(¤t->client_mutex); 191 | pthread_mutex_unlock(&thread_list_mutex); 192 | return 1; 193 | } 194 | } 195 | pthread_mutex_unlock(¤t->client_mutex); 196 | } 197 | current = current->next; 198 | } 199 | pthread_mutex_unlock(&thread_list_mutex); 200 | 201 | return 0; 202 | } 203 | 204 | inline void tftpd_clientlist_ready(struct thread_data *thread) 205 | { 206 | pthread_mutex_lock(&thread->client_mutex); 207 | thread->client_ready = 1; 208 | pthread_mutex_unlock(&thread->client_mutex); 209 | } 210 | 211 | /* 212 | * As of the the above comment, we never remove the head element. 213 | */ 214 | void tftpd_clientlist_remove(struct thread_data *thread, 215 | struct client_info *client) 216 | { 217 | pthread_mutex_lock(&thread->client_mutex); 218 | struct client_info *tmp = thread->client_info; 219 | 220 | while ((tmp->next != client) && (tmp->next != NULL)) 221 | tmp = tmp->next; 222 | if (tmp->next == NULL) 223 | return; 224 | tmp->next = tmp->next->next; 225 | pthread_mutex_unlock(&thread->client_mutex); 226 | } 227 | 228 | /* 229 | * Free all allocated client structure. 230 | */ 231 | void tftpd_clientlist_free(struct thread_data *thread) 232 | { 233 | pthread_mutex_lock(&thread->client_mutex); 234 | 235 | struct client_info *tmp; 236 | struct client_info *head = thread->client_info; 237 | 238 | while (head) 239 | { 240 | tmp = head; 241 | head = head->next; 242 | free(tmp); 243 | } 244 | pthread_mutex_unlock(&thread->client_mutex); 245 | } 246 | 247 | /* 248 | * Mark a client as done 249 | */ 250 | int tftpd_clientlist_done(struct thread_data *thread, 251 | struct client_info *client, 252 | struct sockaddr_storage *sock) 253 | { 254 | pthread_mutex_lock(&thread->client_mutex); 255 | 256 | struct client_info *head = thread->client_info; 257 | 258 | if (client) 259 | { 260 | client->done = 1; 261 | pthread_mutex_unlock(&thread->client_mutex); 262 | return 1; 263 | } 264 | if (sock) 265 | { 266 | /* walk the list to find this client */ 267 | while (head) 268 | { 269 | if (sockaddr_equal(sock, &head->client)) 270 | { 271 | head->done = 1; 272 | pthread_mutex_unlock(&thread->client_mutex); 273 | return 1; 274 | } 275 | else 276 | head = head->next; 277 | } 278 | } 279 | pthread_mutex_unlock(&thread->client_mutex); 280 | return 0; 281 | } 282 | 283 | /* 284 | * Return the next client in the list. 285 | * If a client is found, *client got the address and return 1. 286 | * If no more client are available, 0 is returned and client_ready is unset 287 | * If the new client is the same, -1 is returned. 288 | * 289 | * List is search from the current client address and wrap around. 290 | */ 291 | int tftpd_clientlist_next(struct thread_data *thread, 292 | struct client_info **client) 293 | { 294 | struct client_info *tmp; 295 | 296 | pthread_mutex_lock(&thread->client_mutex); 297 | 298 | /* If there's a next, start with it. Else search from the 299 | beginning */ 300 | if ((*client)->next) 301 | tmp = (*client)->next; 302 | else 303 | tmp = thread->client_info; 304 | 305 | /* search from the current client */ 306 | while (tmp) 307 | { 308 | if (!tmp->done) 309 | { 310 | /* If this is the same as *client */ 311 | if (tmp == *client) 312 | { 313 | pthread_mutex_unlock(&thread->client_mutex); 314 | return -1; 315 | } 316 | *client = tmp; 317 | pthread_mutex_unlock(&thread->client_mutex); 318 | return 1; 319 | } 320 | tmp = tmp->next; 321 | /* if no more entry, start at begining */ 322 | if (tmp == NULL) 323 | tmp = thread->client_info; 324 | /* if we fall back on the current client, there is no more 325 | client to serve */ 326 | if (tmp == *client) 327 | tmp = NULL; 328 | } 329 | /* There is no more client to server */ 330 | thread->client_ready = 0; 331 | *client = NULL; 332 | pthread_mutex_unlock(&thread->client_mutex); 333 | return 0; 334 | } 335 | 336 | void tftpd_list_kill_threads(void) 337 | { 338 | pthread_mutex_lock(&thread_list_mutex); 339 | 340 | struct thread_data *current = thread_data; /* head of list */ 341 | 342 | while (current != NULL) 343 | { 344 | pthread_kill(current->tid, SIGTERM); 345 | current = current->next; 346 | } 347 | 348 | pthread_mutex_unlock(&thread_list_mutex); 349 | } 350 | -------------------------------------------------------------------------------- /tftpd_mcast.c: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftpd_mcast.c 4 | * support routine for multicast server 5 | * 6 | * $Id: tftpd_mcast.c,v 1.6 2003/04/25 00:16:19 jp Exp $ 7 | * 8 | * Copyright (c) 2000 Jean-Pierre Lefebvre 9 | * and Remi Lefebvre 10 | * 11 | * atftp is free software; you can redistribute them and/or modify them 12 | * under the terms of the GNU General Public License as published by the 13 | * Free Software Foundation; either version 2 of the License, or (at your 14 | * option) any later version. 15 | * 16 | */ 17 | 18 | #include "config.h" 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include "tftpd.h" 27 | #include "tftp_def.h" 28 | #include "logger.h" 29 | 30 | #define START 0 31 | #define GET_ENUM 1 32 | #define GET_GRP 2 33 | #define EXPAND 3 34 | 35 | pthread_mutex_t mcast_tid_list = PTHREAD_MUTEX_INITIALIZER; 36 | 37 | int parse_ip(char *string, char **res_ip); 38 | int parse_port(char *string, char **res_port); 39 | 40 | struct tid { 41 | char *addr; 42 | short port; 43 | int used; 44 | struct tid *next; 45 | }; 46 | 47 | struct tid *tid_list = NULL; 48 | 49 | /* 50 | * Return a free IP/Port for the multicast transfer 51 | */ 52 | int tftpd_mcast_get_tid(char **addr, short *port) 53 | { 54 | struct tid *current = tid_list; 55 | 56 | pthread_mutex_lock(&mcast_tid_list); 57 | /* walk the list for a free tid */ 58 | while (current != NULL) 59 | { 60 | if (current->used == 0) 61 | { 62 | *addr = current->addr; 63 | *port = current->port; 64 | current->used = 1; 65 | pthread_mutex_unlock(&mcast_tid_list); 66 | return OK; 67 | } 68 | else 69 | current = current->next; 70 | } 71 | pthread_mutex_unlock(&mcast_tid_list); 72 | return ERR; 73 | } 74 | 75 | int tftpd_mcast_free_tid(char *addr, short port) 76 | { 77 | struct tid *current = tid_list; 78 | 79 | pthread_mutex_lock(&mcast_tid_list); 80 | while (current != NULL) 81 | { 82 | if ((current->used == 1) && (current->port == port) && 83 | (strcmp(current->addr, addr) == 0)) 84 | { 85 | current->used = 0; 86 | pthread_mutex_unlock(&mcast_tid_list); 87 | return OK; 88 | } 89 | else 90 | current = current->next; 91 | } 92 | pthread_mutex_unlock(&mcast_tid_list); 93 | return ERR; 94 | } 95 | 96 | /* valid address specification: 97 | 239.255.0.0-239.255.0.20 98 | 239.255.0.0-20 99 | 239.255.0.0,1,2,3,8,10 100 | */ 101 | /* valid port specification 102 | 1758 103 | 1758-1780 104 | 1758,1760,4000 105 | */ 106 | int tftpd_mcast_parse_opt(char *addr, char *ports) 107 | { 108 | char *ip; 109 | char *port; 110 | struct tid *current = NULL; 111 | struct tid *tmp = NULL; 112 | 113 | while (1) 114 | { 115 | if (parse_ip(addr, &ip) != OK) 116 | { 117 | printf("unable to parse IP address\n"); 118 | return ERR; 119 | } 120 | if (ip == NULL) 121 | return OK; 122 | while (1) 123 | { 124 | if (parse_port(ports, &port) != OK) 125 | { 126 | printf("unable to parse port\n"); 127 | return ERR; 128 | } 129 | if (port == NULL) 130 | break; 131 | /* add this ip/port to the tid list */ 132 | tmp = malloc(sizeof(struct tid)); 133 | tmp->addr = strdup(ip); 134 | tmp->port = (short)atoi(port); 135 | tmp->used = 0; 136 | tmp->next = NULL; 137 | if (tid_list == NULL) 138 | { 139 | tid_list = tmp; 140 | current = tid_list; 141 | } 142 | else 143 | { 144 | current->next = tmp; 145 | current = tmp; 146 | } 147 | } 148 | } 149 | } 150 | 151 | void tftpd_mcast_clean(void) 152 | { 153 | 154 | 155 | } 156 | 157 | int parse_ip(char *string, char **res_ip) 158 | { 159 | static int state = START; 160 | 161 | static char s[MAXLEN]; 162 | static char *saveptr; 163 | static char s2[MAXLEN]; 164 | static char *saveptr2; 165 | 166 | static int ip[4]; 167 | static int tmp_ip[4]; 168 | 169 | static int i; 170 | 171 | int res; 172 | char *tmp = NULL, *tmp2 = NULL; 173 | static char out[MAXLEN]; 174 | 175 | *res_ip = NULL; 176 | 177 | while (1) 178 | { 179 | switch (state) 180 | { 181 | case START: 182 | Strncpy(s, string, MAXLEN); 183 | tmp = strtok_r(s, ",", &saveptr); 184 | if (tmp == NULL) 185 | { 186 | state = START; 187 | return ERR; 188 | } 189 | else 190 | state = GET_GRP; 191 | break; 192 | case GET_ENUM: 193 | tmp = strtok_r(NULL, ",", &saveptr); 194 | if (tmp == NULL) 195 | { 196 | state = START; 197 | return OK; 198 | } 199 | else 200 | state = GET_GRP; 201 | break; 202 | case GET_GRP: 203 | Strncpy(s2, tmp, MAXLEN); 204 | tmp = strtok_r(s2, "-", &saveptr2); 205 | if (tmp == NULL) 206 | { 207 | state = START; 208 | return ERR; 209 | } 210 | res = sscanf(tmp, "%d.%d.%d.%d", &tmp_ip[0], &tmp_ip[1], 211 | &tmp_ip[2], &tmp_ip[3]); 212 | if (res == 4) 213 | { 214 | for (i=0; i < 4; i++) 215 | ip[i] = tmp_ip[i]; 216 | } 217 | else 218 | { 219 | if (res == 1) 220 | { 221 | ip[3] = tmp_ip[0]; 222 | } 223 | else 224 | { 225 | state = START; 226 | return ERR; 227 | } 228 | } 229 | tmp2 = strtok_r(NULL, "-", &saveptr2); 230 | if (tmp2 == NULL) 231 | { 232 | state = GET_ENUM; 233 | snprintf(out, sizeof(out), "%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]); 234 | *res_ip = out; 235 | return OK; 236 | } 237 | else 238 | { 239 | sscanf(tmp2, "%d", &tmp_ip[0]); 240 | i = ip[3]; 241 | if (i >= tmp_ip[0]) 242 | { 243 | logger(LOG_ERR, "Bad address range: %d.%d.%d.%d-%d", 244 | ip[0], ip[1], ip[2], ip[3], tmp_ip[0]); 245 | return ERR; 246 | } 247 | state = EXPAND; 248 | } 249 | break; 250 | case EXPAND: 251 | if (i > tmp_ip[0]) 252 | { 253 | state = GET_ENUM; 254 | break; 255 | } 256 | snprintf(out, sizeof(out), "%d.%d.%d.%d", ip[0], ip[1], ip[2], i); 257 | i++; 258 | *res_ip = out; 259 | return OK; 260 | break; 261 | } 262 | } 263 | } 264 | 265 | int parse_port(char *string, char **res_port) 266 | { 267 | static int state = START; 268 | 269 | static char s[MAXLEN]; 270 | static char *saveptr; 271 | static char s2[MAXLEN]; 272 | static char *saveptr2; 273 | 274 | static int port; 275 | static int tmp_port; 276 | 277 | static int i; 278 | 279 | int res; 280 | char *tmp = NULL, *tmp2 = NULL; 281 | static char out[MAXLEN]; 282 | 283 | *res_port = NULL; 284 | 285 | while (1) 286 | { 287 | switch (state) 288 | { 289 | case START: 290 | Strncpy(s, string, MAXLEN); 291 | tmp = strtok_r(s, ",", &saveptr); 292 | if (tmp == NULL) 293 | { 294 | state = START; 295 | return ERR; 296 | } 297 | else 298 | state = GET_GRP; 299 | break; 300 | case GET_ENUM: 301 | tmp = strtok_r(NULL, ",", &saveptr); 302 | if (tmp == NULL) 303 | { 304 | state = START; 305 | return OK; 306 | } 307 | else 308 | state = GET_GRP; 309 | break; 310 | case GET_GRP: 311 | Strncpy(s2, tmp, MAXLEN); 312 | tmp = strtok_r(s2, "-", &saveptr2); 313 | if (tmp == NULL) 314 | { 315 | state = START; 316 | return ERR; 317 | } 318 | res = sscanf(tmp, "%d", &port); 319 | if (res != 1) 320 | { 321 | state = START; 322 | return ERR; 323 | } 324 | tmp2 = strtok_r(NULL, "-", &saveptr2); 325 | if (tmp2 == NULL) 326 | { 327 | state = GET_ENUM; 328 | snprintf(out, sizeof(out), "%d", port); 329 | *res_port = out; 330 | return OK; 331 | } 332 | else 333 | { 334 | sscanf(tmp2, "%d", &tmp_port); 335 | i = port; 336 | if (i >= tmp_port) 337 | { 338 | logger(LOG_ERR, "Bad port range: %d-%d", i, tmp_port); 339 | return ERR; 340 | } 341 | state = EXPAND; 342 | } 343 | break; 344 | case EXPAND: 345 | if (i > tmp_port) 346 | { 347 | state = GET_ENUM; 348 | break; 349 | } 350 | snprintf(out, sizeof(out), "%d", i); 351 | i++; 352 | *res_port = out; 353 | return OK; 354 | break; 355 | } 356 | } 357 | } 358 | -------------------------------------------------------------------------------- /tftpd_mtftp.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftpd_mtftp.h 4 | * 5 | * $Id: tftpd_mtftp.h,v 1.5 2004/02/27 02:05:26 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * atftp is free software; you can redistribute them and/or modify them 11 | * under the terms of the GNU General Public License as published by the 12 | * Free Software Foundation; either version 2 of the License, or (at your 13 | * option) any later version. 14 | * 15 | */ 16 | 17 | #ifndef tftpd_mtftp_h 18 | #define tftpd_mtftp_h 19 | 20 | #include 21 | #include 22 | #include 23 | #include "tftp_io.h" 24 | #include "options.h" 25 | 26 | /* 27 | * This structure holds information on mtftp configuration 28 | * 29 | */ 30 | struct mtftp_data { 31 | struct mtftp_thread *thread_data; 32 | int number_of_thread; 33 | 34 | /* for receiving of initial request */ 35 | char *data_buffer; 36 | int data_buffer_size; 37 | struct tftp_opt *tftp_options; 38 | 39 | /* options scanned from command line */ 40 | int server_port; 41 | int mcast_ttl; 42 | int timeout; 43 | int checkport; 44 | int trace; 45 | }; 46 | 47 | struct mtftp_thread { 48 | pthread_t tid; 49 | 50 | /* Configuration data */ 51 | int running; 52 | char file_name[MAXLEN]; 53 | char mcast_ip[MAXLEN]; /* FIXME: could be less memory */ 54 | char client_port[MAXLEN]; 55 | 56 | /* Server thread variables */ 57 | FILE *fp; 58 | 59 | int sockfd; 60 | struct sockaddr_storage sa_in; 61 | struct sockaddr_storage sa_client; 62 | 63 | int mcast_sockfd; 64 | int mcast_port; 65 | struct sockaddr_storage sa_mcast; 66 | union ip_mreq_storage mcastaddr; 67 | 68 | char *data_buffer; 69 | int data_buffer_size; 70 | 71 | /* For options access */ 72 | struct mtftp_data *mtftp_data; 73 | 74 | struct mtftp_thread *next; 75 | }; 76 | 77 | /* 78 | * Functions defined in tftpd_file.c 79 | */ 80 | struct mtftp_data *tftpd_mtftp_init(char *filename); 81 | int tftpd_mtftp_clean(struct mtftp_data *data); 82 | void *tftpd_mtftp_server(void *arg); 83 | void tftpd_mtftp_kill_threads(struct mtftp_data *data); 84 | 85 | #endif 86 | -------------------------------------------------------------------------------- /tftpd_pcre.c: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftpd_pcre.c 4 | * functions to remmap file name requested by tftp clients according 5 | * to regular expression rules 6 | * 7 | * $Id: tftpd_pcre.c,v 1.2 2003/04/25 00:16:19 jp Exp $ 8 | * 9 | * Copyright (c) 2003 Jean-Pierre Lefebvre 10 | * and Remi Lefebvre 11 | * 12 | * The PCRE code is provided by Jeff Miller 13 | * 14 | * Copyright (c) 2003 Jeff Miller 15 | * 16 | * atftp is free software; you can redistribute them and/or modify them 17 | * under the terms of the GNU General Public License as published by the 18 | * Free Software Foundation; either version 2 of the License, or (at your 19 | * option) any later version. 20 | * 21 | */ 22 | 23 | #include "config.h" 24 | 25 | #if HAVE_PCRE 26 | 27 | #include 28 | #include 29 | #include 30 | 31 | #include "tftp_def.h" 32 | #include "config.h" 33 | #include "logger.h" 34 | 35 | #include "tftpd_pcre.h" 36 | 37 | /* create a pattern list from a file */ 38 | /* return 0 on success, -1 otherwise */ 39 | tftpd_pcre_self_t *tftpd_pcre_open(char *filename) 40 | { 41 | int linecount; 42 | PCRE2_SIZE erroffset; 43 | PCRE2_SIZE *len; 44 | int errnumber; 45 | int matches; 46 | char line[MAXLEN]; 47 | FILE *fh; 48 | int subnum; 49 | PCRE2_UCHAR **substrlist; 50 | pcre2_code *file_re; 51 | pcre2_match_data *match_data; 52 | tftpd_pcre_self_t *self; 53 | tftpd_pcre_pattern_t *pat, **curpatp; 54 | 55 | /* open file */ 56 | if ((fh = fopen(filename, "r")) == NULL) 57 | { 58 | logger(LOG_ERR, "Cannot open %s for reading: %s", 59 | filename, strerror(errno)); 60 | return NULL; 61 | } 62 | 63 | /* compile pattern for lines */ 64 | logger(LOG_DEBUG, "Using file pattern %s", TFTPD_PCRE_FILE_PATTERN); 65 | if ((file_re = pcre2_compile((PCRE2_SPTR)TFTPD_PCRE_FILE_PATTERN, PCRE2_ZERO_TERMINATED, 0, 66 | &errnumber, &erroffset, NULL)) == NULL) 67 | { 68 | logger(LOG_ERR, "PCRE file pattern failed to compile"); 69 | return NULL; 70 | } 71 | 72 | /* allocate header and copy info */ 73 | if ((self = calloc(1, sizeof(tftpd_pcre_self_t))) == NULL) 74 | { 75 | logger(LOG_ERR, "calloc failed"); 76 | return NULL; 77 | } 78 | self->lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER; 79 | Strncpy(self->filename, filename, MAXLEN); 80 | 81 | /* read patterns */ 82 | for (linecount = 1, curpatp = &self->list; 83 | fgets(line, MAXLEN, fh) != NULL; 84 | linecount++, curpatp = &pat->next) 85 | { 86 | logger(LOG_DEBUG,"file: %s line: %d value: %s", 87 | filename, linecount, line); 88 | 89 | /* allocate space for pattern info */ 90 | if ((pat = (tftpd_pcre_pattern_t *)calloc(1,sizeof(tftpd_pcre_pattern_t))) == NULL) 91 | { 92 | tftpd_pcre_close(self); 93 | return NULL; 94 | } 95 | *curpatp = pat; 96 | 97 | /* for each pattern read, compile and store the pattern */ 98 | match_data = pcre2_match_data_create_from_pattern(file_re, NULL); 99 | matches = pcre2_match(file_re, (PCRE2_SPTR)line, (int)(strlen(line)), 100 | 0, 0, match_data, NULL); 101 | 102 | /* log substring to help with debugging */ 103 | pcre2_substring_list_get(match_data, &substrlist, NULL); 104 | for(subnum = 0; subnum < matches; subnum++) 105 | { 106 | logger(LOG_DEBUG,"file: %s line: %d substring: %d value: %s", 107 | filename, linecount, subnum, substrlist[subnum]); 108 | } 109 | pcre2_substring_list_free((const PCRE2_UCHAR **)substrlist); 110 | 111 | if (matches != 3) 112 | { 113 | logger(LOG_ERR, "error with pattern in file \"%s\" line %d", 114 | filename, linecount); 115 | tftpd_pcre_close(self); 116 | pcre2_match_data_free(match_data); 117 | pcre2_code_free(file_re); 118 | return NULL; 119 | } 120 | /* remember line number */ 121 | pat->linenum = linecount; 122 | /* extract left side */ 123 | pcre2_substring_get_bynumber(match_data, 1, 124 | (PCRE2_UCHAR **)&pat->pattern, (PCRE2_SIZE *)&len); 125 | /* extract right side */ 126 | pcre2_substring_get_bynumber(match_data, 2, 127 | (PCRE2_UCHAR **)&pat->right_str, (PCRE2_SIZE *)&len); 128 | 129 | logger(LOG_DEBUG,"pattern: %s right_str: %s", pat->pattern, pat->right_str); 130 | 131 | if ((pat->left_re = pcre2_compile((PCRE2_SPTR)pat->pattern, PCRE2_ZERO_TERMINATED, 0, 132 | &errnumber, &erroffset, NULL)) == NULL) 133 | { 134 | /* compilation failed*/ 135 | PCRE2_UCHAR buffer[256]; 136 | pcre2_get_error_message(errnumber, buffer, sizeof(buffer)); 137 | logger(LOG_ERR, 138 | "PCRE compilation failed in file \"%s\" line %d at %d: %s", 139 | filename, linecount, 140 | erroffset, buffer); 141 | /* close file */ 142 | fclose(fh); 143 | /* clean up */ 144 | pcre2_code_free(file_re); 145 | pcre2_match_data_free(match_data); 146 | tftpd_pcre_close(self); 147 | return NULL; 148 | } 149 | } 150 | /* clean up */ 151 | pcre2_code_free(file_re); 152 | pcre2_match_data_free(match_data); 153 | /* close file */ 154 | fclose(fh); 155 | return self; 156 | } 157 | 158 | /* return filename being used */ 159 | /* returning a char point directly is a little risking when 160 | * using thread, but as we're using this before threads 161 | * are created we should be able to get away with it 162 | */ 163 | char *tftpd_pcre_getfilename(tftpd_pcre_self_t *self) 164 | { 165 | return self->filename; 166 | } 167 | 168 | /* search for a replacement and return a string after substitution */ 169 | /* if no match is found return -1 */ 170 | int tftpd_pcre_sub(tftpd_pcre_self_t *self, char *outstr, int outlen, char *str) 171 | { 172 | int matches; 173 | pcre2_match_data *match_data; 174 | tftpd_pcre_pattern_t *pat; 175 | 176 | /* lock for duration */ 177 | pthread_mutex_lock(&self->lock); 178 | 179 | logger(LOG_DEBUG, "Looking to match \"%s\"", str); 180 | /* interate over pattern list */ 181 | for(pat = self->list; pat != NULL; pat = pat->next) 182 | { 183 | logger(LOG_DEBUG,"Attempting to match \"%s\"", pat->pattern); 184 | 185 | /* attempt match */ 186 | match_data = pcre2_match_data_create_from_pattern(pat->left_re, NULL); 187 | matches = pcre2_match(pat->left_re, (PCRE2_SPTR)str, (int)(strlen(str)), 188 | 0, 0, match_data, NULL); 189 | /* no match so we try again */ 190 | if (matches == PCRE2_ERROR_NOMATCH) 191 | continue; 192 | /* error in making a match - log and attempt to continue */ 193 | if (matches < 0) 194 | { 195 | logger(LOG_WARNING, 196 | "PCRE Matching error %d", matches); 197 | continue; 198 | } 199 | /* we have a match - carry out substitution */ 200 | logger(LOG_DEBUG,"Pattern \"%s\" matches", pat->pattern); 201 | pcre2_substitute(pat->left_re, (PCRE2_SPTR)str, (PCRE2_SIZE)(strlen(str)), 202 | 0, 0, match_data, NULL, (PCRE2_SPTR)pat->right_str, 203 | (PCRE2_SIZE)(strlen((const char *)pat->right_str)), 204 | (PCRE2_UCHAR *)outstr, (PCRE2_SIZE *)&outlen); 205 | logger(LOG_DEBUG,"outstr: \"%s\"", outstr); 206 | pcre2_match_data_free(match_data); 207 | pthread_mutex_unlock(&self->lock); 208 | return 0; 209 | } 210 | logger(LOG_DEBUG, "Failed to match \"%s\"", str); 211 | pcre2_match_data_free(match_data); 212 | pthread_mutex_unlock(&self->lock); 213 | return -1; 214 | } 215 | 216 | /* clean up and displose of anything we set up*/ 217 | void tftpd_pcre_close(tftpd_pcre_self_t *self) 218 | { 219 | tftpd_pcre_pattern_t *next, *cur; 220 | 221 | /* free up list */ 222 | pthread_mutex_lock(&self->lock); 223 | 224 | cur = self->list; 225 | while (cur != NULL) 226 | { 227 | next = cur->next; 228 | pcre2_substring_free(cur->pattern); 229 | pcre2_substring_free(cur->right_str); 230 | pcre2_code_free(cur->left_re); 231 | free(cur); 232 | cur = next; 233 | } 234 | pthread_mutex_unlock(&self->lock); 235 | free(self); 236 | } 237 | 238 | #endif 239 | -------------------------------------------------------------------------------- /tftpd_pcre.h: -------------------------------------------------------------------------------- 1 | /* hey emacs! -*- Mode: C; c-file-style: "k&r"; indent-tabs-mode: nil -*- */ 2 | /* 3 | * tftpd_pcre.h 4 | * 5 | * $Id: tftpd_pcre.h,v 1.1 2003/02/21 05:06:06 jp Exp $ 6 | * 7 | * Copyright (c) 2000 Jean-Pierre Lefebvre 8 | * and Remi Lefebvre 9 | * 10 | * The PCRE code is provided by Jeff Miller 11 | * 12 | * Copyright (c) 2003 Jeff Miller 13 | * 14 | * atftp is free software; you can redistribute them and/or modify them 15 | * under the terms of the GNU General Public License as published by the 16 | * Free Software Foundation; either version 2 of the License, or (at your 17 | * option) any later version. 18 | * 19 | */ 20 | #ifndef TFTPD_PCRE_H 21 | #define TFTPD_PCRE_H 22 | #include 23 | #define PCRE2_CODE_UNIT_WIDTH 8 24 | #include 25 | 26 | #include "tftpd.h" 27 | 28 | /* Carry out filename substitution 29 | * example, pattern 30 | * (name) sur($1) 31 | * 32 | * for the requested file "filename" would give "surname" 33 | * 34 | */ 35 | 36 | /* 37 | * for when we read files, what is the format of a line 38 | * pattern [whitespace] replacement_string 39 | */ 40 | 41 | #define TFTPD_PCRE_FILE_PATTERN "^(\\S+)\\s+(\\S+)$" 42 | 43 | /* 44 | * Definition of struct to hold patterns 45 | */ 46 | 47 | struct tftpd_pcre_pattern 48 | { 49 | unsigned int linenum; 50 | PCRE2_UCHAR *pattern; 51 | PCRE2_UCHAR *right_str; 52 | pcre2_code *left_re; 53 | struct tftpd_pcre_pattern *next; 54 | }; 55 | 56 | typedef struct tftpd_pcre_pattern tftpd_pcre_pattern_t; 57 | 58 | struct tftpd_pcre_self 59 | { 60 | pthread_mutex_t lock; 61 | char filename[MAXLEN]; 62 | struct tftpd_pcre_pattern *list; 63 | }; 64 | 65 | typedef struct tftpd_pcre_self tftpd_pcre_self_t; 66 | 67 | /* function prototypes */ 68 | tftpd_pcre_self_t *tftpd_pcre_open(char *filename); 69 | char *tftpd_pcre_getfilename(tftpd_pcre_self_t *self); 70 | int tftpd_pcre_sub(tftpd_pcre_self_t *self, char *outstr, int outlen, char *str); 71 | void tftpd_pcre_close(tftpd_pcre_self_t *self); 72 | 73 | #endif 74 | --------------------------------------------------------------------------------