[eggheads-patches] PATCH1.4: transfer_1.4.patch

Fabian Knittel fknittel at gmx.de
Tue Oct 12 13:25:19 CST 1999


[ transfer_1.4.patch ]

This patch makes the transfer module accept unlimited file
name sizes, only restricted to the system specific maximum
file name length when saving it.

In addition, all files written to the temp dir during the
transfer, get a random string added to the filename to avoid
conflicts between several running bots and to prevent bad
guys from doing bad stuff :P

The patch has no effect on the filesys module (yet..), which
truncates filenames with more than 60 characters as before.

Fabian
-------------- next part --------------
diff -urN eggdrop1.4+filerace~/doc/UPDATES1.4 eggdrop1.4+filerace/doc/UPDATES1.4
--- eggdrop1.4+filerace~/doc/UPDATES1.4	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/doc/UPDATES1.4	Mon Oct 11 18:01:01 1999
@@ -5,6 +5,10 @@
 
 1.4.0
 Foundby   Fixedby   What....
+	  Fabian    The transfer module now supports almost unlimited file
+		    lengths, limited only by the system's max file name length.
+		    In addition, temporary files are created in a more race
+		    safe way.
 	  rtc       reintroduced the text/-dir, renamed telnet-banner to
 		    banner, set default config filename to eggdrop.conf,
 		    put logfiles to logs/-dir by default
diff -urN eggdrop1.4+filerace~/src/eggdrop.h eggdrop1.4+filerace/src/eggdrop.h
--- eggdrop1.4+filerace~/src/eggdrop.h	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/src/eggdrop.h	Mon Oct 11 16:57:36 1999
@@ -79,6 +79,16 @@
 #include "HANDLEN MUST BE <= NICKMAX"
 #endif
 
+/* NAME_MAX is what POSIX defines, but BSD calls it MAXNAMLEN.
+   Use 255 if we can't find anything else. */
+#ifndef NAME_MAX
+#  ifdef MAXNAMLEN
+#    define NAME_MAX	MAXNAMLEN
+#  else
+#    define NAME_MAX	255
+#  endif
+#endif
+
 /* almost every module needs some sort of time thingy, so... */
 #if TIME_WITH_SYS_TIME
 #include <sys/time.h>
@@ -246,7 +256,8 @@
 };
 
 struct xfer_info {
-  char filename[121];
+  char *filename;
+  char *origname;
   char dir[121];		/* used when uploads go to the current dir */
   unsigned long length;
   unsigned long acked;
diff -urN eggdrop1.4+filerace~/src/mod/filesys.mod/filesys.c eggdrop1.4+filerace/src/mod/filesys.mod/filesys.c
--- eggdrop1.4+filerace~/src/mod/filesys.mod/filesys.c	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/src/mod/filesys.mod/filesys.c	Mon Oct 11 17:43:37 1999
@@ -68,6 +68,7 @@
 static int expmem_dcc_files(void *x);
 static void kill_dcc_files(int idx, void *x);
 static void out_dcc_files(int idx, char *buf, void *x);
+static char *mktempfile(char *filename);
 
 static struct dcc_table DCC_FILES =
 {
@@ -364,9 +365,9 @@
 	   dcc[idx].nick);
     return 0;
   }
-  nfn = strrchr(filename, '/');
+  nfn = strrchr(dir, '/');
   if (nfn == NULL)
-    nfn = filename;
+    nfn = dir;
   else
     nfn++;
   if (strcasecmp(nick, dcc[idx].nick))
@@ -378,7 +379,7 @@
 
 static int do_dcc_send(int idx, char *dir, char *nick)
 {
-  char s[161], s1[161], *fn;
+  char *s = NULL, *s1 = NULL, *fn;
   FILE *f;
   int x;
 
@@ -397,14 +398,18 @@
     putlog(LOG_FILES, "*", "Refused dcc get %s from [%s]", fn, dcc[idx].nick);
     return 0;
   }
-  if (dir[0])
+  if (dir[0]) {
+    s = nmalloc(strlen(dccdir) + strlen(dir) + strlen(fn) + 2);
     sprintf(s, "%s%s/%s", dccdir, dir, fn);
-  else
+  } else {
+    s = nmalloc(strlen(dccdir) + strlen(fn) + 1);
     sprintf(s, "%s%s", dccdir, fn);
+  }
   f = fopen(s, "r");
   if (f == NULL) {
     dprintf(idx, "No such file.\n");
     putlog(LOG_FILES, "*", "Refused dcc get %s from [%s]", fn, dcc[idx].nick);
+    nfree(s);
     return 0;
   }
   fclose(f);
@@ -417,25 +422,38 @@
     sprintf(xxx, "%d*%s%s", strlen(dccdir), dccdir, dir);
     queue_file(xxx, fn, dcc[idx].nick, nick);
     dprintf(idx, "Queued: %s to %s\n", fn, nick);
+    nfree(s);
     return 1;
   }
   if (copy_to_tmp) {
-    /* copy this file to /tmp */
+    char *tempfn = mktempfile(fn);
+
+    /* copy this file to /tmp, add a random prefix to the filename */
+    s = nrealloc(s, strlen(dccdir) + strlen(dir) + strlen(fn) + 2); 
     sprintf(s, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", fn);
-    sprintf(s1, "%s%s", tempdir, fn);
+    s1 = nrealloc(s1, strlen(tempdir) + strlen(tempfn));
+    sprintf(s1, "%s%s", tempdir, tempfn);
+    nfree(tempfn);
     if (copyfile(s, s1) != 0) {
       dprintf(idx, "Can't make temporary copy of file!\n");
       putlog(LOG_FILES | LOG_MISC, "*",
 	     "Refused dcc get %s: copy to %s FAILED!",
 	     fn, tempdir);
+      nfree(s);
+      nfree(s1);
       return 0;
     }
-  } else
+  } else {
+    s1 = nrealloc(s1, strlen(dccdir) + strlen(dir) + strlen(fn) + 2); 
     sprintf(s1, "%s%s%s%s", dccdir, dir, dir[0] ? "/" : "", fn);
+  }
+  s = nrealloc(s, strlen(dir) + strlen(fn) + 2);
   sprintf(s, "%s%s%s", dir, dir[0] ? "/" : "", fn);
   x = _dcc_send(idx, s1, nick, s);
   if (x != DCCSEND_OK)
     wipe_tmp_filename(s1, -1);
+  nfree(s);
+  nfree(s1);
   return x;
 }
 
@@ -566,10 +584,12 @@
 static void filesys_dcc_send(char *nick, char *from, struct userrec *u,
 			     char *text)
 {
-  char *param, *ip, *prt, buf[512], *msg = buf;
+  char *param, *ip, *prt, *buf = NULL, *msg;
   int atr = u ? u->flags : 0, i;
 
   context;
+  buf = nmalloc(strlen(text) + 1);
+  msg = buf;
   strcpy(buf, text);
   param = newsplit(&msg);
   if (!(atr & USER_XFER)) {
@@ -608,8 +628,10 @@
 	     nick);
     } else {
       /* This looks like a good place for a sanity check. */
-      if (!sanitycheck_dcc(nick, from, ip, prt))
+      if (!sanitycheck_dcc(nick, from, ip, prt)) {
+	nfree(buf);
 	return;
+      }
       i = new_dcc(&DCC_DNSWAIT, sizeof(struct dns_info));
 
       if (i < 0) {
@@ -621,7 +643,7 @@
       }
       dcc[i].addr = my_atoul(ip);
       dcc[i].port = atoi(prt);
-      dcc[i].sock = -1;
+      dcc[i].sock = (-1);
       dcc[i].user = u;
       strcpy(dcc[i].nick, nick);
       strcpy(dcc[i].host, from);
@@ -637,6 +659,7 @@
       dns_hostbyip(dcc[i].addr);
     }
   }
+  nfree(buf);
 }
 
 static void filesys_dcc_send_lookupfailure(int i)
@@ -646,25 +669,70 @@
     lostdcc(i);
 }
 
+/* Create a temporary filename with random elements. Shortens
+ * the filename if the total string is longer than NAME_MAX.
+ * The original buffer is not modified.   (Fabian)
+ * 
+ * Please adjust MKTEMPFILE_TOT if you change any lengths
+ *   7 - size of the random string
+ *   2 - size of additional characters in "%u-%s-%s" format string
+ *   8 - estimated size of getpid()'s output converted to %u */
+#define MKTEMPFILE_TOT (7 + 2 + 8)
+static char *mktempfile(char *filename)
+{
+  char rands[8], *tempname, *fn = filename;
+  int l;
+
+  make_rand_str(rands, 7);
+  l = strlen(filename);
+  if ((l + MKTEMPFILE_TOT) > NAME_MAX) {
+    debug2("mktempfile: shortened buffer: %d to %d", l,
+	   (NAME_MAX - MKTEMPFILE_TOT));
+    fn[NAME_MAX - MKTEMPFILE_TOT] = 0;
+    l = NAME_MAX - MKTEMPFILE_TOT;
+    fn = nmalloc(l + 1);
+    strncpy(fn, filename, l);
+    fn[l] = 0;
+  }
+  tempname = nmalloc(l + MKTEMPFILE_TOT + 1);
+  sprintf(tempname, "%u-%s-%s", getpid(), rands, fn);
+  if (fn != filename)
+    nfree(fn);
+  debug2("mktempfile: %s -> %s", filename, tempname);
+  return tempname;
+}
+
 static void filesys_dcc_send_lookupsuccess(int i)
 {
   FILE *f;
-  char s1[512], param[512];
+  char *s1, *param, prt[100], ip[100], *tempf;
   int len = dcc[i].u.dns->ibuf, j;
 
-  strncpy(param, dcc[i].u.dns->cbuf, 511);
-  sprintf(s1, "%d", dcc[i].port);
+  strncpy(dcc[i].host, dcc[i].u.dns->host, UHOSTLEN - 1);
+  dcc[i].host[UHOSTLEN - 1] = 0;
+  sprintf(prt, "%d", dcc[i].port);
+  sprintf(ip, "%lu", iptolong(my_htonl(dcc[i].addr)));
   if (!hostsanitycheck_dcc(dcc[i].nick, dcc[i].host, dcc[i].addr,
-                           dcc[i].u.dns->host, s1)) {
+                           dcc[i].u.dns->host, prt)) {
     lostdcc(i);
     return;
   }
+  param = nmalloc(strlen(dcc[i].u.dns->cbuf) + 1);
+  strcpy(param, dcc[i].u.dns->cbuf);
 
   changeover_dcc(i, &DCC_FORK_SEND, sizeof(struct xfer_info));
   if (param[0] == '.')
     param[0] = '_';
-  strncpy(dcc[i].u.xfer->filename, param, 120);
-  dcc[i].u.xfer->filename[120] = 0;
+  /* save the original filename */
+  dcc[i].u.xfer->origname = get_data_ptr(strlen(param) + 1);
+  strcpy(dcc[i].u.xfer->origname, param);
+  tempf = mktempfile(param);
+  dcc[i].u.xfer->filename = get_data_ptr(strlen(tempf) + 1);
+  strcpy(dcc[i].u.xfer->filename, tempf);
+  /* we don't need the temporary buffers anymore */
+  nfree(tempf);
+  nfree(param);
+
   if (upload_to_cd) {
     char *p = get_user(&USERENTRY_DCCDIR, dcc[i].user);
 
@@ -675,9 +743,12 @@
   } else
     strcpy(dcc[i].u.xfer->dir, dccin);
   dcc[i].u.xfer->length = len;
-  sprintf(s1, "%s%s", dcc[i].u.xfer->dir, param);
+  s1 = nmalloc(strlen(dcc[i].u.xfer->dir) +
+	       strlen(dcc[i].u.xfer->origname) + 1);
+  sprintf(s1, "%s%s", dcc[i].u.xfer->dir, dcc[i].u.xfer->origname);
   context;      
   f = fopen(s1, "r");
+  nfree(s1);
   if (f) {
     fclose(f);
     dprintf(DP_HELP, "NOTICE %s :That file already exists.\n", dcc[i].nick);
@@ -688,7 +759,7 @@
       if (j != i) {
         if ((dcc[j].type->flags & (DCT_FILETRAN | DCT_FILESEND))
 	    == (DCT_FILETRAN | DCT_FILESEND)) {
-	  if (!strcmp(param, dcc[j].u.xfer->filename)) {
+	  if (!strcmp(dcc[i].u.xfer->origname, dcc[j].u.xfer->origname)) {
 	    dprintf(DP_HELP, "NOTICE %s :That file is already being sent.\n",
 		    dcc[i].nick);
 	    lostdcc(i);
@@ -697,20 +768,18 @@
 	}
       }
     /* put uploads in /tmp first */
-    sprintf(s1, "%s%s", tempdir, param);
+    s1 = nmalloc(strlen(tempdir) + strlen(dcc[i].u.xfer->filename) + 1);
+    sprintf(s1, "%s%s", tempdir, dcc[i].u.xfer->filename);
     dcc[i].u.xfer->f = fopen(s1, "w");
+    nfree(s1);
     if (dcc[i].u.xfer->f == NULL) {
       dprintf(DP_HELP,
 	      "NOTICE %s :Can't create that file (temp dir error)\n",
 	      dcc[i].nick);
       lostdcc(i);
     } else {
-      char prt[100], ip[100];
-
       dcc[i].timeval = now;
       dcc[i].sock = getsock(SOCK_BINARY);
-      sprintf(prt, "%d", dcc[i].port);
-      sprintf(ip, "%lu", iptolong(my_htonl(dcc[i].addr)));
       if (open_telnet_dcc(dcc[i].sock, ip, prt) < 0)
 	dcc[i].type->eof(i);
     }
diff -urN eggdrop1.4+filerace~/src/mod/module.h eggdrop1.4+filerace/src/mod/module.h
--- eggdrop1.4+filerace~/src/mod/module.h	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/src/mod/module.h	Mon Oct 11 14:35:13 1999
@@ -333,6 +333,8 @@
 #define dns_ipbyhost ((void (*)(char *))(*(Function**)(global[240])))
 #define dns_hostbyip ((void (*)(IP))(*(Function**)(global[241])))
 #define changeover_dcc ((void (*)(int, struct dcc_table *, int))global[242])
+#define make_rand_str ((void (*) (char *, int))global[243])
+/* 244 - 247 */
 
 #define ASSERT(expr) { if (!(expr)) assert_failed (MODULE_NAME, __FILE__, __LINE__); }
 
diff -urN eggdrop1.4+filerace~/src/mod/share.mod/share.c eggdrop1.4+filerace/src/mod/share.mod/share.c
--- eggdrop1.4+filerace~/src/mod/share.mod/share.c	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/src/mod/share.mod/share.c	Mon Oct 11 14:07:07 1999
@@ -943,7 +943,9 @@
       dcc[i].type = &DCC_FORK_SEND;
       strcpy(dcc[i].nick, "*users");
       strcpy(dcc[i].host, dcc[idx].nick);
+      dcc[i].u.xfer->filename = nmalloc(strlen(s));
       strcpy(dcc[i].u.xfer->filename, s);
+      dcc[i].u.xfer->origname = dcc[i].u.xfer->filename;
       dcc[i].u.xfer->length = atoi(par);
       dcc[idx].status |= STAT_GETTING;
       dcc[i].u.xfer->f = f;
diff -urN eggdrop1.4+filerace~/src/mod/transfer.mod/transfer.c eggdrop1.4+filerace/src/mod/transfer.mod/transfer.c
--- eggdrop1.4+filerace~/src/mod/transfer.mod/transfer.c	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/src/mod/transfer.mod/transfer.c	Mon Oct 11 18:35:37 1999
@@ -1,3 +1,6 @@
+/*
+ * transfer.c  - main file for the transfer module
+ */
 /* 
  * This file is part of the eggdrop source code copyright (c) 1997 Robey
  * Pointer and is distributed according to the GNU general public license.
@@ -51,7 +54,7 @@
 #define MATCH (match+sofar)
 
 /* this function SHAMELESSLY :) pinched from match.c in the original
- * source, see that file for info about the authour etc */
+ * source, see that file for info about the author etc */
 
 #define QUOTE '\\'
 #define WILDS '*'
@@ -207,7 +210,7 @@
 static void send_next_file(char *to)
 {
   fileq_t *q = fileq, *this = NULL;
-  char s[256], s1[256];
+  char *s, *s1;
   int x;
 
   while (q != NULL) {
@@ -218,9 +221,10 @@
   if (this == NULL)
     return;			/* none */
   /* copy this file to /tmp */
-  if (this->dir[0] == '*')	/* absolute path */
+  if (this->dir[0] == '*') {	/* absolute path */
+    s = nmalloc(strlen(&this->dir[1]) + strlen(this->file) + 2);
     sprintf(s, "%s/%s", &this->dir[1], this->file);
-  else {
+  } else {
     char *p = strchr(this->dir, '*');
 
     if (p == NULL) {		/* if it's messed up */
@@ -228,10 +232,12 @@
       return;
     }
     p++;
+    s = nmalloc(strlen(p) + strlen(this->file) + 2);
     sprintf(s, "%s%s%s", p, p[0] ? "/" : "", this->file);
     strcpy(this->dir, &(p[atoi(this->dir)]));
   }
   if (copy_to_tmp) {
+    s1 = nmalloc(strlen(tempdir) + strlen(this->file) + 1);
     sprintf(s1, "%s%s", tempdir, this->file);
     if (copyfile(s, s1) != 0) {
       putlog(LOG_FILES | LOG_MISC, "*",
@@ -242,14 +248,21 @@
 	      this->to);
       strcpy(s, this->to);
       flush_fileq(s);
+      nfree(s1);
+      nfree(s);
       return;
     }
-  } else
+  } else {
+    s1 = nmalloc(strlen(s) + 1);
     strcpy(s1, s);
-  if (this->dir[0] == '*')
+  }
+  if (this->dir[0] == '*') {
+    s = nrealloc(s, strlen(&this->dir[1]) + strlen(this->file) + 2);
     sprintf(s, "%s/%s", &this->dir[1], this->file);
-  else
+  } else {
+    s = nrealloc(s, strlen(this->dir) + strlen(this->file) + 2);
     sprintf(s, "%s%s%s", this->dir, this->dir[0] ? "/" : "", this->file);
+  }
   x = raw_dcc_send(s1, this->to, this->nick, s);
   if (x == 1) {
     wipe_tmp_filename(s1, -1);
@@ -259,6 +272,8 @@
 	    this->to);
     strcpy(s, this->to);
     flush_fileq(s);
+    nfree(s);
+    nfree(s1);
     return;
   }
   if (x == 2) {
@@ -268,19 +283,22 @@
 	    this->to);
     strcpy(s, this->to);
     flush_fileq(s);
+    nfree(s);
+    nfree(s1);
     return;
   }
   if (strcasecmp(this->to, this->nick))
     dprintf(DP_HELP, "NOTICE %s :Here is a file from %s ...\n", this->to,
 	    this->nick);
   deq_this(this);
+  nfree(s);
+  nfree(s1);
 }
 
 static void check_tcl_sentrcvd(struct userrec *u, char *nick, char *path,
 			       p_tcl_bind_list h)
 {
-  struct flag_record fr =
-  {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
+  struct flag_record fr = {FR_GLOBAL | FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
   char *hand = u ? u->handle : "*";
 
   context;
@@ -319,7 +337,7 @@
       dprintf(DP_HELP, "NOTICE %s :%s (%s)\n", dcc[idx].nick,
 	      DCC_CONNECTFAILED1, s1);
     putlog(LOG_MISC, "*", "%s: SEND %s (%s!%s)", DCC_CONNECTFAILED2,
-	   dcc[idx].u.xfer->filename, dcc[idx].nick, dcc[idx].host);
+	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
     putlog(LOG_MISC, "*", "    (%s)", s1);
     s2 = nmalloc(strlen(tempdir) + strlen(dcc[idx].u.xfer->filename) + 1);
     sprintf(s2, "%s%s", tempdir, dcc[idx].u.xfer->filename);
@@ -333,11 +351,13 @@
 static void eof_dcc_send(int idx)
 {
   int ok, j;
-  char ofn[121], nfn[121], s[1024], *hand;
+  char *ofn, *nfn, s[1024], *hand;
   struct userrec *u;
 
   context;
   if (dcc[idx].u.xfer->length == dcc[idx].status) {
+    int l;
+
     /* success */
     ok = 0;
     fclose(dcc[idx].u.xfer->f);
@@ -354,36 +374,35 @@
       return;
     }
     putlog(LOG_FILES, "*", "Completed dcc send %s from %s!%s",
-	   dcc[idx].u.xfer->filename, dcc[idx].nick, dcc[idx].host);
+	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
     simple_sprintf(s, "%s!%s", dcc[idx].nick, dcc[idx].host);
     u = get_user_by_host(s);
     hand = u ? u->handle : "*";
-    /* move the file from /tmp */
-    /* slwstub - filenames to long segfault and kill the eggdrop
-     * NOTE: This is NOT A PTF. Its a circumvention, a workaround
-     * I'm not moving the file from the receiving area. You may
-     * want to inspect it, shorten the name, give credit or NOT! */
-    if (strlen(dcc[idx].u.xfer->filename) > MAX_FILENAME_LENGTH) {
+
+    context;
+    l = strlen(dcc[idx].u.xfer->filename);
+    if (l > NAME_MAX) {
       /* the filename is to long... blow it off */
-      putlog(LOG_FILES, "*", "Filename %d length. Way To LONG.",
-	     strlen(dcc[idx].u.xfer->filename));
+      putlog(LOG_FILES, "*", "Filename %d length. Way To LONG.", l);
       dprintf(DP_HELP, "NOTICE %s :Filename %d length Way To LONG!\n",
-	      dcc[idx].nick, strlen(dcc[idx].u.xfer->filename));
+              dcc[idx].nick, l);
       putlog(LOG_FILES, "*", "To Bad So Sad Your Dad!");
       dprintf(DP_HELP, "NOTICE %s :To Bad So Sad Your Dad!\n",
-	      dcc[idx].nick);
+              dcc[idx].nick);
       killsock(dcc[idx].sock);
       lostdcc(idx);
       return;
     }
-    /* slwstub - filenames to long segfault and kill the eggdrop */
+    context;
+    /* move the file from /tmp */
+    ofn = nmalloc(strlen(tempdir) + strlen(dcc[idx].u.xfer->filename) + 1);
+    nfn = nmalloc(strlen(dcc[idx].u.xfer->dir) + strlen(dcc[idx].u.xfer->origname) + 1);
     simple_sprintf(ofn, "%s%s", tempdir, dcc[idx].u.xfer->filename);
     simple_sprintf(nfn, "%s%s", dcc[idx].u.xfer->dir,
-		   dcc[idx].u.xfer->filename);
+		   dcc[idx].u.xfer->origname);
     if (movefile(ofn, nfn))
       putlog(LOG_MISC | LOG_FILES, "*",
-	     "FAILED move %s from %s ! File lost!",
-	     dcc[idx].u.xfer->filename, tempdir);
+	     "FAILED move `%s' from `%s'! File lost!", nfn, ofn);
     else {
       /* add to file database */
       module_entry *fs = module_find("filesys", 0, 0);
@@ -391,11 +410,13 @@
       if (fs != NULL) {
 	Function f = fs->funcs[FILESYS_ADDFILE];
 
-	f(dcc[idx].u.xfer->dir, dcc[idx].u.xfer->filename, hand);
+	f(dcc[idx].u.xfer->dir, dcc[idx].u.xfer->origname, hand);
       }
       stats_add_upload(u, dcc[idx].u.xfer->length);
       check_tcl_sentrcvd(u, dcc[idx].nick, nfn, H_rcvd);
     }
+    nfree(ofn);
+    nfree(nfn);
     for (j = 0; j < dcc_total; j++)
       if (!ok && (dcc[j].type->flags & (DCT_GETNOTES | DCT_FILES)) &&
 	  !strcasecmp(dcc[j].nick, hand)) {
@@ -440,10 +461,11 @@
     }
   } else {
     putlog(LOG_FILES, "*", "Lost dcc send %s from %s!%s (%lu/%lu)",
-	   dcc[idx].u.xfer->filename, dcc[idx].nick, dcc[idx].host,
+	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host,
 	   dcc[idx].status, dcc[idx].u.xfer->length);
-    sprintf(s, "%s%s", tempdir, dcc[idx].u.xfer->filename);
-    unlink(s);
+    ofn = nmalloc(strlen(tempdir) + strlen(dcc[idx].u.xfer->filename) + 1);
+    sprintf(ofn, "%s%s", tempdir, dcc[idx].u.xfer->filename);
+    unlink(ofn);
     killsock(dcc[idx].sock);
     lostdcc(idx);
   }
@@ -487,7 +509,7 @@
       fseek(dcc[idx].u.xfer->f, cmp, SEEK_SET);
       dcc[idx].status = cmp;
       putlog(LOG_FILES, "*", "Resuming file transfer at %dk for %s to %s",
-	     (int) (cmp / 1024), dcc[idx].u.xfer->filename,
+	     (int) (cmp / 1024), dcc[idx].u.xfer->origname,
 	     dcc[idx].nick);
     }
   }
@@ -530,7 +552,7 @@
        * (not the user who actually received it) */
       stats_add_dnload(u, dcc[idx].u.xfer->length);
       putlog(LOG_FILES, "*", "Finished dcc send %s to %s",
-	     dcc[idx].u.xfer->filename, dcc[idx].nick);
+	     dcc[idx].u.xfer->origname, dcc[idx].nick);
       wipe_tmp_filename(dcc[idx].u.xfer->filename, idx);
       strcpy((char *) xnick, dcc[idx].nick);
     }
@@ -587,7 +609,7 @@
     return;
   } else {
     putlog(LOG_FILES, "*", "Lost dcc get %s from %s!%s",
-	   dcc[idx].u.xfer->filename, dcc[idx].nick, dcc[idx].host);
+	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
     wipe_tmp_filename(dcc[idx].u.xfer->filename, idx);
     strcpy(xnick, dcc[idx].nick);
   }
@@ -601,7 +623,7 @@
 
 static void dcc_send(int idx, char *buf, int len)
 {
-  char s[512];
+  char s[512], *b;
   unsigned long sent;
 
   context;
@@ -620,10 +642,12 @@
     dprintf(DP_HELP, "NOTICE %s :Bogus file length.\n", dcc[idx].nick);
     putlog(LOG_FILES, "*",
 	   "File too long: dropping dcc send %s from %s!%s",
-	   dcc[idx].u.xfer->filename, dcc[idx].nick, dcc[idx].host);
+	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
     fclose(dcc[idx].u.xfer->f);
-    sprintf(s, "%s%s", tempdir, dcc[idx].u.xfer->filename);
-    unlink(s);
+    b = nmalloc(strlen(tempdir) + strlen(dcc[idx].u.xfer->filename) + 1);
+    sprintf(b, "%s%s", tempdir, dcc[idx].u.xfer->filename);
+    unlink(b);
+    nfree(b);
     killsock(dcc[idx].sock);
     lostdcc(idx);
   }
@@ -631,12 +655,13 @@
 
 static int tcl_getfileq STDVAR
 {
-  char s[512];
+  char *s = NULL;
   fileq_t *q = fileq;
 
   BADARGS(2, 2, " handle");
   while (q != NULL) {
     if (!strcasecmp(q->nick, argv[1])) {
+      s = nrealloc(s, strlen(q->to) + strlen(q->dir) + strlen(q->file) + 4);
       if (q->dir[0] == '*')
 	sprintf(s, "%s %s/%s", q->to, &q->dir[1], q->file);
       else
@@ -645,12 +670,14 @@
     }
     q = q->next;
   }
+  if (s)
+    nfree(s);
   return TCL_OK;
 }
 
 static int tcl_dccsend STDVAR
 {
-  char s[5], sys[512], *nfn;
+  char s[5], *sys, *nfn;
   int i;
   FILE *f;
 
@@ -675,22 +702,28 @@
       nfn--;
       *nfn = 0;
       nfn++;
+      sys = nmalloc(strlen(argv[1]) + 1);
       sprintf(sys, "*%s", argv[1]);
       queue_file(sys, nfn, "(script)", argv[2]);
+      nfree(sys);
     }
     Tcl_AppendResult(irp, "4", NULL);
     return TCL_OK;
   }
   if (copy_to_tmp) {
+    sys = nmalloc(strlen(tempdir) + strlen(nfn) + 1);
     sprintf(sys, "%s%s", tempdir, nfn);		/* new filename, in /tmp */
     copyfile(argv[1], sys);
-  } else
+  } else {
+    sys = nmalloc(strlen(argv[1]) + 1);
     strcpy(sys, argv[1]);
+  }
   i = raw_dcc_send(sys, argv[2], "*", argv[1]);
   if (i > 0)
     wipe_tmp_filename(sys, -1);
   sprintf(s, "%d", i);
   Tcl_AppendResult(irp, s, NULL);
+  nfree(sys);
   return TCL_OK;
 }
 
@@ -736,12 +769,12 @@
   } else {
     char *p;
 
-    strcpy(xx, dcc[i].u.xfer->filename);
-    p = strrchr(xx, '/');
+    p = strrchr(dcc[i].u.xfer->origname, '/');
     dprintf(DP_HELP, "NOTICE %s :Timeout during transfer, aborting %s.\n",
-	    dcc[i].nick, p ? p + 1 : xx);
-    putlog(LOG_FILES, "*", "DCC timeout: GET %s (%s) at %lu/%lu", p ? p + 1 : xx,
-	   dcc[i].nick, dcc[i].status, dcc[i].u.xfer->length);
+	    dcc[i].nick, p ? p + 1 : dcc[i].u.xfer->origname);
+    putlog(LOG_FILES, "*", "DCC timeout: GET %s (%s) at %lu/%lu",
+	   p ? p + 1 : dcc[i].u.xfer->origname, dcc[i].nick, dcc[i].status,
+	   dcc[i].u.xfer->length);
     wipe_tmp_filename(dcc[i].u.xfer->filename, i);
     strcpy(xx, dcc[i].nick);
   }
@@ -767,15 +800,17 @@
     unlink(dcc[idx].u.xfer->filename);
     putlog(LOG_MISC, "*", "Timeout on userfile transfer.");
   } else {
-    char xx[1024];
+    char *buf;
 
     dprintf(DP_HELP, "NOTICE %s :Timeout during transfer, aborting %s.\n",
-	    dcc[idx].nick, dcc[idx].u.xfer->filename);
+	    dcc[idx].nick, dcc[idx].u.xfer->origname);
     putlog(LOG_FILES, "*", "DCC timeout: SEND %s (%s) at %lu/%lu",
-	   dcc[idx].u.xfer->filename, dcc[idx].nick, dcc[idx].status,
+	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].status,
 	   dcc[idx].u.xfer->length);
-    sprintf(xx, "%s%s", tempdir, dcc[idx].u.xfer->filename);
-    unlink(xx);
+    buf = nmalloc(strlen(tempdir) + strlen(dcc[idx].u.xfer->filename) + 1);
+    sprintf(buf, "%s%s", tempdir, dcc[idx].u.xfer->filename);
+    unlink(buf);
+    nfree(buf);
   }
   killsock(dcc[idx].sock);
   lostdcc(idx);
@@ -785,22 +820,22 @@
 {
   if (dcc[idx].status == dcc[idx].u.xfer->length)
     sprintf(buf, "send  (%lu)/%lu\n    Filename: %s\n", dcc[idx].u.xfer->acked,
-	    dcc[idx].u.xfer->length, dcc[idx].u.xfer->filename);
+	    dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
   else
     sprintf(buf, "send  %lu/%lu\n    Filename: %s\n", dcc[idx].status,
-	    dcc[idx].u.xfer->length, dcc[idx].u.xfer->filename);
+	    dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
 }
 
 static void display_dcc_get_p(int idx, char *buf)
 {
   sprintf(buf, "send  waited %lus    Filename: %s\n", now - dcc[idx].timeval,
-	  dcc[idx].u.xfer->filename);
+	  dcc[idx].u.xfer->origname);
 }
 
 static void display_dcc_send(int idx, char *buf)
 {
   sprintf(buf, "send  %lu/%lu\n    Filename: %s\n", dcc[idx].status,
-	  dcc[idx].u.xfer->length, dcc[idx].u.xfer->filename);
+	  dcc[idx].u.xfer->length, dcc[idx].u.xfer->origname);
 }
 
 static void display_dcc_fork_send(int idx, char *buf)
@@ -810,11 +845,29 @@
 
 static int expmem_dcc_xfer(void *x)
 {
-  return sizeof(struct xfer_info);
+  register struct xfer_info *p = (struct xfer_info *) x;
+  int tot;
+  
+  tot = sizeof(struct xfer_info);
+  if (p->filename)
+    tot += strlen(p->filename) + 1;
+  /* We need to check if origname points to filename before
+   * accounting for the memory */
+  if (p->origname && (p->filename != p->origname))
+    tot += strlen(p->origname) + 1;
+  return tot;
 }
 
 static void kill_dcc_xfer(int idx, void *x)
 {
+  register struct xfer_info *p = (struct xfer_info *) x;
+
+  if (p->filename)
+    nfree(p->filename);
+  /* We need to check if origname points to filename before
+   * attempting to free the memory. */
+  if (p->origname && (p->origname != p->filename))
+    nfree(p->origname);
   nfree(x);
 }
 
@@ -863,7 +916,7 @@
   if (strcmp(dcc[idx].nick, "*users")) {
     putlog(LOG_MISC, "*", "DCC connection: SEND %s (%s)",
 	   dcc[idx].type == &DCC_SEND ?
-	   dcc[idx].u.xfer->filename : "", s1);
+	   dcc[idx].u.xfer->origname : "", s1);
   }
 }
 
@@ -940,7 +993,7 @@
     neterror(s);
     dprintf(DP_HELP, "NOTICE %s :Bad connection (%s)\n", dcc[idx].nick, s);
     putlog(LOG_FILES, "*", "DCC bad connection: GET %s (%s!%s)",
-	   dcc[idx].u.xfer->filename, dcc[idx].nick, dcc[idx].host);
+	   dcc[idx].u.xfer->origname, dcc[idx].nick, dcc[idx].host);
     lostdcc(idx);
     return;
   }
@@ -996,9 +1049,9 @@
 	dprintf(idx, "  ---------%s  --------------------\n", spaces);
 	spaces[HANDLEN - 9] = ' ';
       }
-      nfn = strrchr(dcc[i].u.xfer->filename, '/');
+      nfn = strrchr(dcc[i].u.xfer->origname, '/');
       if (nfn == NULL)
-	nfn = dcc[i].u.xfer->filename;
+	nfn = dcc[i].u.xfer->origname;
       else
 	nfn++;
       cnt++;
@@ -1023,13 +1076,14 @@
 {
   int fnd = 1, matches = 0, atot = 0, i;
   fileq_t *q;
-  char s[256];
+  char *s = NULL;
 
   while (fnd) {
     q = fileq;
     fnd = 0;
     while (q != NULL) {
       if (!strcasecmp(dcc[idx].nick, q->nick)) {
+	s = nrealloc(s, strlen(q->dir) + strlen(q->file) + 3);
 	if (q->dir[0] == '*')
 	  sprintf(s, "%s/%s", &q->dir[1], q->file);
 	else
@@ -1052,15 +1106,17 @@
       if (q != NULL)
 	q = q->next;
     }
+    if (s)
+      nfree(s);
   }
   for (i = 0; i < dcc_total; i++) {
     if (((dcc[i].type == &DCC_GET_PENDING) || (dcc[i].type == &DCC_GET)) &&
 	((!strcasecmp(dcc[i].nick, dcc[idx].nick)) ||
 	 (!strcasecmp(dcc[i].u.xfer->from, dcc[idx].nick)))) {
-      char *nfn = strrchr(dcc[i].u.xfer->filename, '/');
+      char *nfn = strrchr(dcc[i].u.xfer->origname, '/');
 
       if (nfn == NULL)
-	nfn = dcc[i].u.xfer->filename;
+	nfn = dcc[i].u.xfer->origname;
       else
 	nfn++;
       if (wild_match_file(par, nfn)) {
@@ -1101,9 +1157,9 @@
   zz = open_listen(&port);
   if (zz == (-1))
     return DCCSEND_NOSOCK;
-  nfn = strrchr(filename, '/');
+  nfn = strrchr(dir, '/');
   if (nfn == NULL)
-    nfn = filename;
+    nfn = dir;
   else
     nfn++;
   f = fopen(filename, "r");
@@ -1117,7 +1173,10 @@
   dcc[i].port = port;
   strcpy(dcc[i].nick, nick);
   strcpy(dcc[i].host, "irc");
+  dcc[i].u.xfer->filename = get_data_ptr(strlen(filename) + 1);
   strcpy(dcc[i].u.xfer->filename, filename);
+  dcc[i].u.xfer->origname = get_data_ptr(strlen(nfn) + 1);
+  strcpy(dcc[i].u.xfer->origname, nfn);
   strcpy(dcc[i].u.xfer->from, from);
   strcpy(dcc[i].u.xfer->dir, dir);
   dcc[i].u.xfer->length = ss.st_size;
diff -urN eggdrop1.4+filerace~/src/mod/transfer.mod/transfer.h eggdrop1.4+filerace/src/mod/transfer.mod/transfer.h
--- eggdrop1.4+filerace~/src/mod/transfer.mod/transfer.h	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/src/mod/transfer.mod/transfer.h	Tue Oct 12 19:49:23 1999
@@ -3,7 +3,6 @@
 #define DCCSEND_FULL   1	/* dcc table is full */
 #define DCCSEND_NOSOCK 2	/* can't open a listening socket */
 #define DCCSEND_BADFN  3	/* no such file */
-#define MAX_FILENAME_LENGTH 40	/* max file lengh */
 
 #ifndef MAKING_TRANSFER
 /* 4 - 7 */
diff -urN eggdrop1.4+filerace~/src/modules.c eggdrop1.4+filerace/src/modules.c
--- eggdrop1.4+filerace~/src/modules.c	Mon Oct 11 14:06:32 1999
+++ eggdrop1.4+filerace/src/modules.c	Mon Oct 11 14:36:09 1999
@@ -479,6 +479,8 @@
   (Function) & dns_ipbyhost,	/* Function * */
   (Function) & dns_hostbyip,	/* Function * */
   (Function) changeover_dcc,  
+  (Function) make_rand_str,
+  /* 244 - 247 */
 };
 
 void init_modules(void)


More information about the Patches mailing list