This patch adds a ``-x'' flag to ftpd, which instructs ftpd to obtain an
exclusive lock on files it commits to disk as a result of a store operation.
This way it becomes easy to tell whether a download has finished, in case the
file needs to be copied someplace else (as in my case). I used open()/fdopen()
instead of fopen()/flock() to avoid the obvious race.

I didn't see any easier ways to accomplish this, but if someone else does,
please let me know. And if this is deemed worthy of a PR, I will send one in.
Thanks.

For testing, I used the following script which shows newly downloaded files:

#!/bin/sh

while :
do
  ls | while read file
  do
    lockf -k -s -t 0 $file ls -l $file
  done
  sleep 10
done

The patch:

--- ftpd.c.orig Mon Sep 20 19:45:09 1999
+++ ftpd.c      Thu Nov  4 22:49:49 1999
@@ -132,6 +132,7 @@
 int    restricted_data_ports = 1;
 int    paranoid = 1;     /* be extra careful about security */
 int    anon_only = 0;    /* Only anonymous ftp allowed */
+int    use_locking = 0;  /* Attempt to lock exclusively while storing */
 int    guest;
 int    dochroot;
 int    stats;
@@ -281,7 +282,7 @@
 
 
        bind_address.s_addr = htonl(INADDR_ANY);
-       while ((ch = getopt(argc, argv, "AdlDSURt:T:u:va:p:")) != -1) {
+       while ((ch = getopt(argc, argv, "AdlDSURt:T:u:xva:p:")) != -1) {
                switch (ch) {
                case 'D':
                        daemon_mode++;
@@ -343,6 +344,10 @@
                        anon_only = 1;
                        break;
 
+               case 'x':
+                       use_locking = 1;
+                       break;
+
                case 'v':
                        debug = 1;
                        break;
@@ -1338,7 +1343,34 @@
 
        if (restart_point)
                mode = "r+";
-       fout = fopen(name, mode);
+       if (use_locking) {
+               int fdout;
+               int flags;
+               mode_t create_mode = S_IRUSR | S_IWUSR
+                                  | S_IRGRP | S_IWGRP
+                                  | S_IROTH | S_IWOTH;
+
+               switch (*mode) {
+                       case 'a':
+                               flags = O_CREAT | O_WRONLY | O_APPEND;
+                       case 'w':
+                               flags = O_CREAT | O_WRONLY | O_TRUNC;
+                       default: /* "r+" */
+                               flags = O_RDWR;
+               }
+               
+               flags |= O_EXLOCK;
+               if (flags & O_CREAT)
+                       fdout = open(name, flags, create_mode);
+               else
+                       fdout = open(name, flags);
+               if (fdout < 0)
+                       fout = NULL;
+               else    
+                       fout = fdopen(fdout, mode);
+       } else {
+               fout = fopen(name, mode);
+       }
        closefunc = fclose;
        if (fout == NULL) {
                perror_reply(553, name);

-- 
Jos Backus                 _/  _/_/_/        "Modularity is not a hack."
                          _/  _/   _/                -- D. J. Bernstein
                         _/  _/_/_/             
                    _/  _/  _/    _/
[EMAIL PROTECTED]     _/_/   _/_/_/            use Std::Disclaimer;


To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to