The following reply was made to PR bin/106049; it has been noted by GNATS.

From: dfil...@freebsd.org (dfilter service)
To: bug-follo...@freebsd.org
Cc:  
Subject: Re: bin/106049: commit references a PR
Date: Wed, 22 Sep 2010 20:28:06 +0000 (UTC)

 Author: marius
 Date: Wed Sep 22 20:27:59 2010
 New Revision: 213027
 URL: http://svn.freebsd.org/changeset/base/213027
 
 Log:
   MFC: r173852
   
   Add the -W options, which acts the same as -w but will generate
   unique names based on the submitted filename, a strftime(3) format
   string and a two digit sequence number.
   
   By default the strftime(3) format string is %Y%m%d (YYYYMMDD), but
   this can be changed by the -F option.
   
   PR:          bin/106049 (based on patch in that PR)
   Approved by: grog@ (mentor)
 
 Modified:
   stable/7/libexec/tftpd/Makefile
   stable/7/libexec/tftpd/tftpd.8
   stable/7/libexec/tftpd/tftpd.c
 Directory Properties:
   stable/7/libexec/tftpd/   (props changed)
 
 Modified: stable/7/libexec/tftpd/Makefile
 ==============================================================================
 --- stable/7/libexec/tftpd/Makefile    Wed Sep 22 20:17:34 2010        
(r213026)
 +++ stable/7/libexec/tftpd/Makefile    Wed Sep 22 20:27:59 2010        
(r213027)
 @@ -5,6 +5,7 @@ PROG=  tftpd
  SRCS= tftpd.c tftpsubs.c
  DPADD=        ${LIBUTIL}
  LDADD=        -lutil
 +WFORMAT=0
  MAN=  tftpd.8
  CFLAGS+=-I${.CURDIR}/../../usr.bin/tftp
  .PATH:        ${.CURDIR}/../../usr.bin/tftp
 
 Modified: stable/7/libexec/tftpd/tftpd.8
 ==============================================================================
 --- stable/7/libexec/tftpd/tftpd.8     Wed Sep 22 20:17:34 2010        
(r213026)
 +++ stable/7/libexec/tftpd/tftpd.8     Wed Sep 22 20:27:59 2010        
(r213027)
 @@ -40,7 +40,8 @@
  .Nd Internet Trivial File Transfer Protocol server
  .Sh SYNOPSIS
  .Nm tftpd
 -.Op Fl cClnw
 +.Op Fl cClnwW
 +.Op Fl F Ar strftime-format
  .Op Fl s Ar directory
  .Op Fl u Ar user
  .Op Fl U Ar umask
 @@ -142,6 +143,13 @@ except it falls back to
  specified via
  .Fl s
  if a directory does not exist for the client's IP.
 +.It Fl F
 +Use this
 +.Xr strftime 3
 +compatible format string for the creation of the suffix if
 +.Fl W
 +is specified.
 +By default the string "%Y%m%d" is used.
  .It Fl l
  Log all requests using
  .Xr syslog 3
 @@ -184,6 +192,17 @@ Allow write requests to create new files
  By default
  .Nm
  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 YYYYMMDD.nn sequence number to the end of the filename.
 +Note that the string YYYYMMDD can be changed the
 +.Fl F
 +option.
  .El
  .Sh SEE ALSO
  .Xr tftp 1 ,
 @@ -212,10 +231,17 @@ the
  .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 F
 +and
 +.Fl W
 +options were introduced in
 +.Fx 7 .
 +.Pp
  .Sh BUGS
  Files larger than 33488896 octets (65535 blocks) cannot be transferred
  without client and server supporting blocksize negotiation (RFC1783).
 
 Modified: stable/7/libexec/tftpd/tftpd.c
 ==============================================================================
 --- stable/7/libexec/tftpd/tftpd.c     Wed Sep 22 20:17:34 2010        
(r213026)
 +++ stable/7/libexec/tftpd/tftpd.c     Wed Sep 22 20:27:59 2010        
(r213027)
 @@ -110,6 +110,8 @@ static int suppress_naks;
  static int    logging;
  static int    ipchroot;
  static int    create_new = 0;
 +static char   *newfile_format = "%Y%m%d";
 +static int    increase_name = 0;
  static mode_t mask = S_IWGRP|S_IWOTH;
  
  static const char *errtomsg(int);
 @@ -134,7 +136,7 @@ main(int argc, char *argv[])
        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, "cCF:lns:u:U:wW")) != -1) {
                switch (ch) {
                case 'c':
                        ipchroot = 1;
 @@ -142,6 +144,9 @@ main(int argc, char *argv[])
                case 'C':
                        ipchroot = 2;
                        break;
 +              case 'F':
 +                      newfile_format = optarg;
 +                      break;
                case 'l':
                        logging = 1;
                        break;
 @@ -160,6 +165,10 @@ main(int argc, char *argv[])
                case 'w':
                        create_new = 1;
                        break;
 +              case 'W':
 +                      create_new = 1;
 +                      increase_name = 1;
 +                      break;
                default:
                        syslog(LOG_WARNING, "ignoring unknown option -%c", ch);
                }
 @@ -513,6 +522,57 @@ option_fail:
  FILE *file;
  
  /*
 + * Find the next value for YYYYMMDD.nn when the file to be written should
 + * be unique. Due to the limitations of nn, we will fail if nn reaches 100.
 + * Besides, that is four updates per hour on a file, which is kind of
 + * execessive anyway.
 + */
 +static int
 +find_next_name(char *filename, int *fd)
 +{
 +      int i;
 +      time_t tval;
 +      size_t len;
 +      struct tm lt;
 +      char yyyymmdd[MAXPATHLEN];
 +      char newname[MAXPATHLEN];
 +      struct stat sb;
 +      int ret;
 +
 +      /* Create the YYYYMMDD part of the filename */
 +      time(&tval);
 +      lt = *localtime(&tval);
 +      len = strftime(yyyymmdd, sizeof(yyyymmdd), newfile_format, &lt);
 +      if (len == 0) {
 +              syslog(LOG_WARNING,
 +                      "Filename suffix too long (%d characters maximum)",
 +                      MAXPATHLEN);
 +              return (EACCESS);
 +      }
 +
 +      /* Make sure the new filename is not too long */
 +      if (strlen(filename) > MAXPATHLEN - len - 5) {
 +              syslog(LOG_WARNING,
 +                      "Filename too long (%d characters, %d maximum)",
 +                      strlen(filename), MAXPATHLEN - len - 5);
 +              return (EACCESS);
 +      }
 +
 +      /* Find the first file which doesn't exist */
 +      for (i = 0; i < 100; i++) {
 +              sprintf(newname, "%s.%s.%02d", filename, yyyymmdd, i);
 +              *fd = open(newname,
 +                  O_WRONLY | O_CREAT | O_EXCL, 
 +                  S_IRUSR | S_IWUSR | S_IRGRP |
 +                  S_IWGRP | S_IROTH | S_IWOTH);
 +              if (*fd > 0)
 +                      return 0;
 +      }
 +
 +      return (EEXIST);
 +}
 +
 +/*
   * Validate file access.  Since we
   * have no uid or gid, for now require
   * file to exist and be publicly
 @@ -528,6 +588,7 @@ validate_access(char **filep, int mode)
  {
        struct stat stbuf;
        int     fd;
 +      int     error;
        struct dirlist *dirp;
        static char pathname[MAXPATHLEN];
        char *filename = *filep;
 @@ -610,10 +671,18 @@ validate_access(char **filep, int mode)
        if (mode == RRQ)
                fd = open(filename, O_RDONLY);
        else {
 -              if (create_new)
 -                      fd = open(filename, O_WRONLY|O_TRUNC|O_CREAT, 0666);
 -              else
 -                      fd = open(filename, O_WRONLY|O_TRUNC);
 +              if (create_new) {
 +                      if (increase_name) {
 +                              error = find_next_name(filename, &fd);
 +                              if (error > 0)
 +                                      return (error + 100);
 +                      } else
 +                              fd = open(filename,
 +                                  O_WRONLY | O_TRUNC | O_CREAT, 
 +                                  S_IRUSR | S_IWUSR | S_IRGRP | 
 +                                  S_IWGRP | S_IROTH | S_IWOTH );
 +              } else
 +                      fd = open(filename, O_WRONLY | O_TRUNC);
        }
        if (fd < 0)
                return (errno + 100);
 _______________________________________________
 svn-src-...@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"
 
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to