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