[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: 1.9.4 file move on complete patch (revision 3)



On Friday 08 November 2002 09:45 pm, Peter Zelezny wrote:
> On Fri, 8 Nov 2002 10:39:48 -0500
>
> <chrismorgan@rcn.com> wrote:
> > Peter, I still haven't heard anything back about this patch and what I
> > can do to get it into shape for 1.9.5.  I do know of a few people other
> > than myself that are using it successfully and there appears to be a
> > demand for it.
>
> * Using that same coding style as most of xchat. Like:
>
> void
> download_move_to_completed_dir (char *dcc_dir, char *dcc_completed_dir,
> char *output_name) {
>
Fixed this case, not really sure if you are referring to other things, the 
tabbing and braces styles look the same to me, if there is anything else you 
want fixed just say so.

> * I think we should keep the current behaviour as default.
>   (Perhaps leave prefs.dcc_Completed_dir blank, and no moving).
>
Default is now the same directory as the dcc so the moving is off by default.  

> * Use "| OFLAGS" on all unix level open()'s. No need for the #ifdef WIN32.
>
Fixed.

> * Xchat has a dcc permissions setting. Will this work after the file
>   has been moved?
Fixed, we now use prefs.dccpermissions as the permissions on the destination 
file in the case where rename() fails.

Anything else that needs to be addressed?  Attached is a patch against 1.9.4, 
I'd like to get this patch into 1.9.5 if at all possible.

Thanks,
Chris
--- ../x194o/src/common/util.c	2002-10-08 11:51:15.000000000 -0500
+++ src/common/util.c	2002-11-11 23:56:12.000000000 -0500
@@ -21,6 +21,8 @@
 #include <string.h>
 #include <stdlib.h>
 #include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
 #ifdef WIN32
 #include <sys/timeb.h>
 #include <winsock.h>
@@ -1216,3 +1218,153 @@
 	0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9,
 	0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
 };*/
+
+/* Code borrowed from gtk-gnutella */
+/* Takes care of moving a file from a temporary download location to a completed location */
+void
+download_move_to_completed_dir(char* dcc_dir, char* dcc_completed_dir, 
+	char* output_name, int dccpermissions)
+{
+	/* Move a complete file to move_file_path */
+
+	char dl_src[4096];
+	char dl_dest[4096];
+	char dl_tmp[4096];
+	int return_tmp, return_tmp2;
+	struct stat buf;
+
+	/* if dcc_dir and dcc_completed_dir are the same then we are done */
+	if (0 == strcmp(dcc_dir, dcc_completed_dir))
+		return;			/* Already in "completed dir" */
+
+	snprintf(dl_src, sizeof(dl_src), "%s/%s", dcc_dir, output_name);
+	snprintf(dl_dest, sizeof(dl_dest), "%s/%s", dcc_completed_dir,
+			   output_name);
+
+	dl_src[sizeof(dl_src)-1] = '\0';
+	dl_dest[sizeof(dl_dest)-1] = '\0';
+
+	/*
+	 * If, by extraordinary, there is already a file in the "completed dir"
+	 * with the same name, don't overwrite the existing file.
+	 *
+	 * NB: we assume either there is only one gnutella servent running, or if
+	 * several ones are running, that they are configured to use different
+	 * download and completed dirs.
+	 *
+	 *		--RAM, 03/11/2001
+	 */
+
+	if (-1 != stat(dl_dest, &buf))
+	{
+		int destlen = strlen(dl_dest);
+		int i;
+
+		/*
+		 * There must be enough room for us to append the ".xx" extensions.
+		 * That's 3 chars, plus the trailing NUL.
+		 */
+
+		if (destlen >= sizeof(dl_dest) - 4)
+                {
+			fprintf(stderr, "Found '%s' in completed dir, and path already too long",
+				output_name);
+			return;
+		}
+
+		strncpy(dl_tmp, dl_dest, destlen);
+
+		for (i = 1; i < 100; i++)
+		{
+			char ext[4];
+
+			snprintf(ext, 4, ".%02d", i);
+			dl_tmp[destlen] = '\0';				/* Ignore prior attempt */
+			strncat(dl_tmp+destlen, ext, 3);	/* Append .01, .02, ...*/
+			if (-1 == stat(dl_tmp, &buf))
+				break;
+		}
+
+		if (i == 100)
+		{
+			fprintf(stderr, "Found '%s' in completed dir, "
+				"and was unable to find another unique name",
+				output_name);
+			return;
+		}
+
+		strncat(dl_dest+destlen, dl_tmp+destlen, 3);
+	}
+
+	/* First try and link it to the new locatation */
+
+	return_tmp = rename(dl_src, dl_dest);
+
+	if (return_tmp == -1 && (errno == EXDEV || errno == EPERM))
+	{
+		/* link failed becase either the two paths aren't on the */
+		/* same filesystem or the filesystem doesn't support hard */
+		/* links, so we have to do a copy. */
+
+		int tmp_src, tmp_dest;
+		gboolean ok = FALSE;
+
+		if ((tmp_src = open(dl_src, O_RDONLY)) < 0)
+		{
+			fprintf(stderr, "Unable to open() file '%s' (%s) !", dl_src,
+					  g_strerror(errno));
+			return;
+		}
+
+		if ((tmp_dest =
+			 open(dl_dest, O_WRONLY | O_CREAT | O_TRUNC | OFLAGS, dccpermissions)) < 0)
+		{
+			close(tmp_src);
+			fprintf(stderr, "Unable to create file '%s' (%s) !", dl_src,
+					  strerror(errno));
+			return;
+		}
+
+		for (;;)
+		{
+			return_tmp = read(tmp_src, dl_tmp, sizeof(dl_tmp));
+
+			if (!return_tmp)
+			{
+				ok = TRUE;
+				break;
+			}
+
+			if (return_tmp < 0)
+			{
+				fprintf(stderr, "download_move_to_completed_dir(): "
+					"error reading while moving file to save directory (%s)",
+					 strerror(errno));
+				break;
+			}
+
+			return_tmp2 = write(tmp_dest, dl_tmp, return_tmp);
+
+			if (return_tmp2 < 0)
+			{
+				fprintf(stderr, "download_move_to_completed_dir(): "
+					"error writing while moving file to save directory (%s)",
+					 strerror(errno));
+				break;
+			}
+
+			if (return_tmp < sizeof(dl_tmp))
+			{
+				ok = TRUE;
+				break;
+			}
+		}
+
+		close(tmp_dest);
+		close(tmp_src);
+		if (ok)
+			unlink(dl_src);
+	}
+
+	return;
+}
--- ../x194o/src/common/util.h	2002-10-08 11:51:24.000000000 -0500
+++ src/common/util.h	2002-11-11 23:52:51.000000000 -0500
@@ -33,3 +33,5 @@
 char *errorstring (int err);
 int waitline (int sok, char *buf, int bufsize);
 unsigned long make_ping_time (void);
+void download_move_to_completed_dir(char* dcc_dir, char* dcc_completed_dir, char* output_name, int dccpermissions);
+
--- ../x194o/src/common/cfgfiles.c	2002-11-03 01:27:33.000000000 -0500
+++ src/common/cfgfiles.c	2002-11-11 23:35:32.000000000 -0500
@@ -305,6 +305,7 @@
 	{"dcc_auto_send", P_OFFINT (autodccsend), TYPE_BOOL},
 	{"dcc_blocksize", P_OFFINT (dcc_blocksize), TYPE_INT},
 	{"dcc_dir", P_OFFSET (dccdir), TYPE_STR},
+	{"dcc_completed_dir", P_OFFSET (dcc_completed_dir), TYPE_STR},
 	{"dcc_fast_send", P_OFFINT (fastdccsend), TYPE_BOOL},
 	{"dcc_ip", P_OFFSET (dcc_ip_str), TYPE_STR},
 	{"dcc_ip_from_server", P_OFFINT (ip_from_server), TYPE_BOOL},
@@ -536,9 +537,11 @@
 #ifdef WIN32
 	strcpy (prefs.sounddir, "./sound");
 	strcpy (prefs.dccdir, "./dcc");
+	strcpy (prefs.dcc_completed_dir, "./dcc");
 #else
 	sprintf (prefs.sounddir, "%s/sound", g_get_home_dir ());
 	sprintf (prefs.dccdir, "%s/dcc", g_get_home_dir ());
+	sprintf (prefs.dcc_completed_dir, "%s/dcc", g_get_home_dir ());
 #endif
 	strcpy (prefs.doubleclickuser, "QUOTE WHOIS %s");
 	strcpy (prefs.awayreason, _("I'm busy"));
@@ -599,8 +602,10 @@
 
 #ifdef WIN32
 		mkdir (prefs.dccdir);
+		mkdir (prefs.dcc_completed_dir);
 #else
 		mkdir (prefs.dccdir, S_IRUSR | S_IWUSR | S_IXUSR);
+		mkdir (prefs.dcc_completed_dir, S_IRUSR | S_IWUSR | S_IXUSR);
 #endif
 
 	}
--- ../x194o/src/common/xchat.h	2002-11-03 01:27:47.000000000 -0500
+++ src/common/xchat.h	2002-11-11 23:30:57.000000000 -0500
@@ -119,6 +119,7 @@
 	char background[PATHLEN + 1];
 	char background_dialog[PATHLEN + 1];
 	char dccdir[PATHLEN + 1];
+	char dcc_completed_dir[PATHLEN + 1];
 	char bluestring[300];
 	char dnsprogram[72];
 	char hostname[127];
--- ../x194o/src/common/dcc.c	2002-11-04 09:20:11.000000000 -0500
+++ src/common/dcc.c	2002-11-11 23:52:27.000000000 -0500
@@ -211,6 +211,18 @@
 	{
 		close (dcc->fp);
 		dcc->fp = -1;
+
+		if(dccstat == STAT_DONE)
+		{
+			/* if we just completed a dcc recieve, move the */
+			/* completed file to the completed directory */
+			if(dcc->type == TYPE_RECV)
+			{			
+				download_move_to_completed_dir(prefs.dccdir, prefs.dcc_completed_dir, 
+					dcc->file, prefs.dccpermissions);
+			}
+
+		}
 	}
 
 	dcc->dccstat = dccstat;
--- ../x194o/src/fe-gtk/setup.c	2002-11-03 01:28:54.000000000 -0500
+++ src/fe-gtk/setup.c	2002-11-11 23:30:57.000000000 -0500
@@ -144,6 +144,7 @@
 static const setting filexfer_settings[] =
 {
 	{ST_ENTRY,	N_("Download files to:"), P_OFFSET(dccdir), 0, 0, sizeof prefs.dccdir},
+	{ST_ENTRY,	N_("Move completed files to:"), P_OFFSET(dcc_completed_dir), 0, 0, sizeof prefs.dcc_completed_dir},
 	{ST_ENTRY,	N_("DCC IP address:"), P_OFFSET(dcc_ip_str), 0, 0, sizeof prefs.dcc_ip_str},
 	{ST_NUMBER,	N_("First DCC send port:"), P_OFFINT(first_dcc_send_port), 0, 0, 65535},
 	{ST_NUMBER,	N_("Last DCC send port:"), P_OFFINT(last_dcc_send_port), 0, 0, 65535},