Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Nov 1999 23:05:30 +0100
From:      Jos Backus <jbackus@plex.nl>
To:        freebsd-hackers@freebsd.org
Subject:   ftpd feature: lock file being stored
Message-ID:  <19991104230530.B84284@jos.bugworks.com>

next in thread | raw e-mail | index | archive | help
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
                         _/  _/_/_/             
                    _/  _/  _/    _/
jbackus@plex.nl     _/_/   _/_/_/            use Std::Disclaimer;


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?19991104230530.B84284>