bin/106049: [patch] tftpd - improve -w option to support unique
filenames
Edwin Groothuis
edwin at mavetju.org
Wed Nov 29 21:40:19 PST 2006
>Number: 106049
>Category: bin
>Synopsis: [patch] tftpd - improve -w option to support unique filenames
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Nov 30 05:40:12 GMT 2006
>Closed-Date:
>Last-Modified:
>Originator: Edwin Groothuis
>Release: FreeBSD 6.1-RELEASE i386
>Organization:
-
>Environment:
System: FreeBSD k7.mavetju 6.1-RELEASE FreeBSD 6.1-RELEASE #0: Sun May 7 04:42:56 UTC 2006 root at opus.cse.buffalo.edu:/usr/obj/usr/src/sys/SMP i386
>Description:
I'm managing a large collection of network devices which, once per
month, I want to download the configuration from for safekeeping
and historical reasons.
Up to now it always was a fight with keeping track of the names of
new devices to make sure their filenames were touched in /tftpboot
and set with the proper permissions. The -w option resolved this a
little bit, but it still caused the configurations to be overwritten
without my knowledge.
So I added the -W option, which behaves the same as -w, but adds a
three digit postfix to the file to be created so it will never
overwrite old ones.
>How-To-Repeat:
>Fix:
--- tftpd.c.orig Tue Nov 28 22:54:43 2006
+++ tftpd.c Thu Nov 30 16:17:32 2006
@@ -110,6 +110,7 @@
static int logging;
static int ipchroot;
static int create_new = 0;
+static int increase_name = 0;
static mode_t mask = S_IWGRP|S_IWOTH;
static const char *errtomsg(int);
@@ -134,7 +135,7 @@
tzset(); /* syslog in localtime */
openlog("tftpd", LOG_PID | LOG_NDELAY, LOG_FTP);
- while ((ch = getopt(argc, argv, "cClns:u:U:w")) != -1) {
+ while ((ch = getopt(argc, argv, "cClns:u:U:wW")) != -1) {
switch (ch) {
case 'c':
ipchroot = 1;
@@ -160,6 +161,10 @@
case 'w':
create_new = 1;
break;
+ case 'W':
+ create_new = 1;
+ increase_name = 1;
+ break;
default:
syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
}
@@ -610,9 +615,41 @@
if (mode == RRQ)
fd = open(filename, O_RDONLY);
else {
- if (create_new)
- fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0666);
- else
+ if (create_new) {
+ if (increase_name) {
+ int i;
+
+ /* Make sure the new filename is not too long */
+ if (strlen(filename) > MAXPATHLEN-4) {
+ syslog(LOG_WARNING,
+ "Filename too long (%ld characters, %d maximum)",
+ strlen(filename), MAXPATHLEN);
+ return (EACCESS);
+ }
+
+ /* If we can't find anything, fail */
+ fd = -1;
+
+ /* Find the first file which doesn't exist */
+ for (i = 0; i < 1000; i++) {
+ char newname[MAXPATHLEN];
+ struct stat sb;
+ int ret;
+
+ sprintf(newname, "%s.%d", filename, i);
+ ret = stat(newname, &sb);
+ if (ret == -1 && errno == ENOENT) {
+ fd = open(newname,
+ O_WRONLY|O_TRUNC|
+ O_CREAT, 0666);
+ break;
+ }
+ }
+ } else {
+ fd = open(filename,
+ O_WRONLY|O_TRUNC|O_CREAT, 0666);
+ }
+ } else
fd = open(filename, O_WRONLY|O_TRUNC);
}
if (fd < 0)
--- tftpd.8.orig Tue Nov 28 22:54:51 2006
+++ tftpd.8 Thu Nov 30 16:23:34 2006
@@ -40,7 +40,7 @@
.Nd Internet Trivial File Transfer Protocol server
.Sh SYNOPSIS
.Nm /usr/libexec/tftpd
-.Op Fl cClnw
+.Op Fl cClnwW
.Op Fl s Ar directory
.Op Fl u Ar user
.Op Fl U Ar umask
@@ -171,10 +171,17 @@
The default is 022
.Pq Dv S_IWGRP | S_IWOTH .
.It Fl w
-Allow writes requests to create new files.
+Allow write requests to create new files.
By default
.Nm
-requires that the file specified in a write request exist.
+requires that the file specified in a write request exist. Note that this
+only works in directories writable by the user specified with
+.Fl u
+option.
+.It Fl W
+As
+.Fl w
+but append a three digit sequence number to the end of the filename.
.El
.Sh SEE ALSO
.Xr tftp 1 ,
@@ -200,10 +207,14 @@
.Fl u
option was introduced in
.Fx 4.2 ,
-and the
+the
.Fl c
option was introduced in
-.Fx 4.3 .
+.Fx 4.3 ,
+and the
+.Fl W
+option was introduced in
+.Fx 6.3 .
.Sh BUGS
Files larger than 33488896 octets (65535 blocks) cannot be transferred
without client and server supporting blocksize negotiation (RFC1783).
>Release-Note:
>Audit-Trail:
>Unformatted:
More information about the freebsd-bugs
mailing list