[cvslog] (2002-10-07 22:36:47 UTC) Module eggdrop1.7: Change committed

cvslog cvs at tsss.org
Mon Oct 7 17:37:01 CST 2002


CVSROOT    : /usr/local/cvsroot
Module     : eggdrop1.7
Commit time: 2002-10-07 22:36:47 UTC
Commited by: stdarg <stdarg at techmonkeys.org>

Modified files:
     lib/egglib/Makefile.am lib/egglib/egglib.h modules/server/binds.c
     modules/server/binds.h modules/server/dcc.c modules/server/dcc.h
     modules/server/scriptcmds.c src/Makefile.am src/cmds.c
     src/core_binds.c src/dcc.c src/logfile.c src/main.c src/modules.c
     src/scriptnet.c src/tcl.c src/tcluser.c src/users.c

Log message:

* Added some dcc support functions like sending/accepting files, with resume, and chats.
* Starting to migrate to new user system.

---------------------- diff included ----------------------
Index: eggdrop1.7/lib/egglib/Makefile.am
diff -u eggdrop1.7/lib/egglib/Makefile.am:1.2 eggdrop1.7/lib/egglib/Makefile.am:1.3
--- eggdrop1.7/lib/egglib/Makefile.am:1.2	Thu Jan  3 20:56:22 2002
+++ eggdrop1.7/lib/egglib/Makefile.am	Mon Oct  7 17:36:36 2002
@@ -1,4 +1,4 @@
-# $Id: Makefile.am,v 1.2 2002/01/04 02:56:22 ite Exp $
+# $Id: Makefile.am,v 1.3 2002/10/07 22:36:36 stdarg Exp $
 
 ## libcompat is built as convenience library
 
@@ -12,8 +12,6 @@
 			base64.c \
 			base64.h \
 			egglib.h \
-			hash_table.c \
-			hash_table.h \
 			linked_list.c \
 			linked_list.h \
 			mempool.c \
Index: eggdrop1.7/lib/egglib/egglib.h
diff -u eggdrop1.7/lib/egglib/egglib.h:1.4 eggdrop1.7/lib/egglib/egglib.h:1.5
--- eggdrop1.7/lib/egglib/egglib.h:1.4	Sun May  5 11:40:33 2002
+++ eggdrop1.7/lib/egglib/egglib.h	Mon Oct  7 17:36:36 2002
@@ -21,7 +21,7 @@
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  */
 /*
- * $Id: egglib.h,v 1.4 2002/05/05 16:40:33 tothwolf Exp $
+ * $Id: egglib.h,v 1.5 2002/10/07 22:36:36 stdarg Exp $
  */
 
 #ifndef _EGGLIB_H
@@ -34,6 +34,5 @@
 #include "../compat/compat.h"
 #include "mstack.h"
 #include "msprintf.h"
-#include "hash_table.h"
 
 #endif				/* !_EGGLIB_H */
Index: eggdrop1.7/modules/server/binds.c
diff -u eggdrop1.7/modules/server/binds.c:1.2 eggdrop1.7/modules/server/binds.c:1.3
--- eggdrop1.7/modules/server/binds.c:1.2	Sun Sep 22 03:50:46 2002
+++ eggdrop1.7/modules/server/binds.c	Mon Oct  7 17:36:36 2002
@@ -5,6 +5,7 @@
 #define MODULE_NAME "server"
 #define MAKING_SERVER
 #include "lib/eggdrop/module.h"
+#include "dcc.h"
 
 bind_table_t *BT_wall = NULL,
 	*BT_raw = NULL,
@@ -16,7 +17,8 @@
 	*BT_pubm = NULL,
 	*BT_ctcp = NULL,
 	*BT_ctcr = NULL,
-	*BT_dcc_chat = NULL;
+	*BT_dcc_chat = NULL,
+	*BT_dcc_recv = NULL;
 
 void server_binds_destroy()
 {
@@ -46,7 +48,10 @@
 	BT_pubm = bind_table_add("pubm", 5, "ssUss", MATCH_MASK, BIND_STACKABLE | BIND_USE_ATTR);
 	BT_ctcr = bind_table_add("ctcr", 6, "ssUsss", MATCH_MASK, BIND_USE_ATTR | BIND_STACKABLE);
 	BT_ctcp = bind_table_add("ctcp", 6, "ssUsss", MATCH_MASK, BIND_USE_ATTR | BIND_STACKABLE);
-	BT_dcc_chat = bind_table_add("dcc_chat", 4, "ssss", MATCH_MASK, BIND_USE_ATTR | BIND_STACKABLE);
+	BT_dcc_chat = bind_table_add("dcc_chat", 6, "ssUssi", MATCH_MASK, BIND_USE_ATTR | BIND_STACKABLE);
+	BT_dcc_recv = bind_table_add("dcc_recv", 7, "ssUssii", MATCH_MASK, BIND_USE_ATTR | BIND_STACKABLE);
+
+	add_builtins("ctcp", ctcp_dcc_binds);
 }
 
 void check_tcl_notc(char *nick, char *uhost, struct userrec *u, char *dest, char *arg)
Index: eggdrop1.7/modules/server/binds.h
diff -u eggdrop1.7/modules/server/binds.h:1.2 eggdrop1.7/modules/server/binds.h:1.3
--- eggdrop1.7/modules/server/binds.h:1.2	Sun Sep 22 03:50:46 2002
+++ eggdrop1.7/modules/server/binds.h	Mon Oct  7 17:36:36 2002
@@ -11,7 +11,8 @@
 	*BT_pubm,
 	*BT_ctcp,
 	*BT_ctcr,
-	*BT_dcc_chat;
+	*BT_dcc_chat,
+	*BT_dcc_recv;
 
 extern void server_binds_destroy();
 extern void server_binds_init();
Index: eggdrop1.7/modules/server/dcc.c
diff -u eggdrop1.7/modules/server/dcc.c:1.1 eggdrop1.7/modules/server/dcc.c:1.2
--- eggdrop1.7/modules/server/dcc.c:1.1	Sun Sep 22 03:50:46 2002
+++ eggdrop1.7/modules/server/dcc.c	Mon Oct  7 17:36:36 2002
@@ -8,56 +8,105 @@
 #include "parse.h"
 #include "binds.h"
 #include <netinet/in.h>
+#include <fcntl.h>
+#include <stdio.h>
 
-typedef struct dcc_chat {
-	int serv, idx;
+#include "dcc.h"
+
+typedef struct dcc_listen {
+	int serv, client;
 	int timer_id, timeout;
-} dcc_chat_t;
+	int port;
+} dcc_listen_t;
 
-static int dcc_chat_server_newclient(void *client_data, int idx, int newidx, const char *peer_ip, int peer_port);
-static int dcc_chat_server_delete(void *client_data, int idx);
-static int dcc_chat_client_delete(void *client_data, int idx);
-static int dcc_chat_timeout(void *client_data);
-
-static sockbuf_handler_t dcc_chat_server_handler = {
-	"DCC chat server",
-	NULL, NULL, dcc_chat_server_newclient,
+typedef struct dcc_send {
+	struct dcc_send *next;
+	/* Connection information. */
+	int serv, idx, port;
+	char *nick, *ip;
+
+	/* File information. */
+	char *fname;
+	int fd, size;
+
+	/* Timer information (for gets). */
+	int timer_id;
+
+	/* A bunch of stats. */
+	int bytes_sent, bytes_left;
+	int snapshot_bytes[5];
+	int snapshot_counter, last_snapshot;
+	int acks, bytes_acked;
+	int resumed_at;
+	int request_time, connect_time;
+} dcc_send_t;
+
+static dcc_send_t *dcc_send_head = NULL;
+static dcc_send_t *dcc_recv_head = NULL;
+
+static int dcc_listen_newclient(void *client_data, int idx, int newidx, const char *peer_ip, int peer_port);
+static int dcc_listen_delete(void *client_data, int idx);
+static int dcc_listen_timeout(void *client_data);
+static int dcc_chat_connect(void *client_data, int idx, const char *peer_ip, int peer_port);
+static int dcc_chat_eof(void *client_data, int idx, int err, const char *errmsg);
+static int dcc_chat_delete(void *client_data, int idx);
+static int dcc_send_connect(void *client_data, int idx, const char *peer_ip, int peer_port);
+static int dcc_send_read(void *client_data, int idx, char *data, int len);
+static int dcc_send_written(void *client_data, int idx, int len, int remaining);
+static int dcc_send_eof(void *client_data, int idx, int err, const char *errmsg);
+static int dcc_send_delete(void *client_data, int idx);
+static int dcc_send_done(dcc_send_t *send);
+static int dcc_recv_timeout(void *client_data);
+static int dcc_recv_connect(void *client_data, int idx, const char *peer_ip, int peer_port);
+static int dcc_recv_read(void *client_data, int idx, char *data, int len);
+static int dcc_recv_eof(void *client_data, int idx, int err, const char *errmsg);
+static int dcc_recv_delete(void *client_data, int idx);
+static void update_snapshot(dcc_send_t *send, int len);
+
+static sockbuf_handler_t dcc_listen_handler = {
+	"DCC listen",
+	NULL, NULL, dcc_listen_newclient,
 	NULL, NULL,
-	dcc_chat_server_delete
+	dcc_listen_delete
 };
 
-#define DCC_FILTER_LEVEL	(SOCKBUF_LEVEL_INTERNAL+1)
-static sockbuf_filter_t dcc_chat_client_filter = {
-	"DCC chat client", DCC_FILTER_LEVEL,
+#define DCC_FILTER_LEVEL	(SOCKBUF_LEVEL_TEXT_BUFFER+100)
+
+static sockbuf_filter_t dcc_chat_filter = {
+	"DCC chat", DCC_FILTER_LEVEL,
+	dcc_chat_connect, dcc_chat_eof, NULL,
 	NULL, NULL, NULL,
-	NULL, NULL,
-	NULL, dcc_chat_client_delete
+	NULL, dcc_chat_delete
 };
 
-/* Starts a chat with the specified nick.
- * If timeout is 0, the default timeout is used.
- * If timeout is -1, there is no timeout.
- * We don't make sure the nick is valid, so if it's not, you won't know until
- * the chat times out. */
-int dcc_start_chat(const char *nick, int timeout)
+static sockbuf_filter_t dcc_send_filter = {
+	"DCC send", DCC_FILTER_LEVEL,
+	dcc_send_connect, dcc_send_eof, NULL,
+	dcc_send_read, NULL, dcc_send_written,
+	NULL, dcc_send_delete
+};
+
+static sockbuf_filter_t dcc_recv_filter = {
+	"DCC get", DCC_FILTER_LEVEL,
+	dcc_recv_connect, dcc_recv_eof, NULL,
+	dcc_recv_read, NULL, NULL,
+	NULL, dcc_recv_delete
+};
+
+static dcc_listen_t *dcc_listen(int timeout)
 {
-	dcc_chat_t *chat;
-	int serv, idx, longip, port;
+	dcc_listen_t *listen;
+	int idx, port;
 	egg_timeval_t howlong;
 
-	/* Create a listening idx to accept the chat connection. */
-	serv = egg_listen(0, &port);
-	if (serv < 0) return(serv);
-	chat = calloc(1, sizeof(*chat));
-	sockbuf_set_handler(serv, &dcc_chat_server_handler, chat);
+	idx = egg_listen(0, &port);
+	if (idx < 0) return(NULL);
 
-	/* Create an empty sockbuf that will eventually be used for the
-	 * dcc chat (when they connect to us). */
-	idx = sockbuf_new();
-	sockbuf_attach_filter(idx, &dcc_chat_client_filter, chat);
+	listen = calloc(1, sizeof(*listen));
+	listen->serv = idx;
+	listen->port = port;
 
-	chat->serv = serv;
-	chat->idx = idx;
+	sockbuf_set_handler(idx, &dcc_listen_handler, listen);
 
 	/* See if they want the default timeout. */
 	if (!timeout) timeout = config.dcc_timeout;
@@ -65,20 +114,55 @@
 	if (timeout > 0) {
 		howlong.sec = timeout;
 		howlong.usec = 0;
-		chat->timer_id = timer_create_complex(&howlong, dcc_chat_timeout, chat, 0);
+		listen->timer_id = timer_create_complex(&howlong, dcc_listen_timeout, listen, 0);
 	}
 
+	return(listen);
+}
+
+/* Starts a chat with the specified nick.
+ * If timeout is 0, the default timeout is used.
+ * If timeout is -1, there is no timeout.
+ * We don't make sure the nick is valid, so if it's not, you won't know until
+ * the chat times out. */
+int dcc_start_chat(const char *nick, int timeout)
+{
+	dcc_listen_t *listen;
+	int idx, longip;
+
+	/* Create a listening idx to accept the chat connection. */
+	listen = dcc_listen(timeout);
+	if (!listen) return(-1);
+
+	/* Create an empty sockbuf that will eventually be used for the
+	 * dcc chat (when they connect to us). */
+	idx = sockbuf_new();
+	sockbuf_attach_filter(idx, &dcc_chat_filter, (void *)listen->serv);
+	listen->client = idx;
+
 	longip = htonl(getmyip());
-	printserv(SERVER_NORMAL, "PRIVMSG %s :%cDCC CHAT chat %u %d%c", nick, 1, longip, port, 1);
+	printserv(SERVER_NORMAL, "PRIVMSG %s :%cDCC CHAT chat %u %d%c", nick, 1, longip, listen->port, 1);
 	return(idx);
 }
 
-static int dcc_chat_server_newclient(void *client_data, int idx, int newidx, const char *peer_ip, int peer_port)
+/* If we receive a connect event, that means we belong to a dcc get resume. */
+static int dcc_listen_connect(void *client_data, int idx, const char *peer_ip, int peer_port)
 {
 	int sock;
-	dcc_chat_t *chat = client_data;
+	dcc_listen_t *recv = client_data;
+
+	sock = sockbuf_get_sock(idx);
+	sockbuf_set_sock(idx, -1, 0);
+	sockbuf_set_sock(recv->client, sock, SOCKBUF_CLIENT);
+	recv->client = -1;
+	sockbuf_delete(idx);
+	return(0);
+}
 
-	putlog(LOG_MISC, "*", "dcc_chat_server: got new client (%s:%d)", peer_ip, peer_port);
+static int dcc_listen_newclient(void *client_data, int idx, int newidx, const char *peer_ip, int peer_port)
+{
+	int sock;
+	dcc_listen_t *chat = client_data;
 
 	sock = sockbuf_get_sock(newidx);
 	sockbuf_set_sock(newidx, -1, 0);
@@ -86,94 +170,564 @@
 
 	/* Give the waiting sockbuf the new socket and mark it as a client
 	 * so that it fires the on_connect event. */
-	sockbuf_set_sock(chat->idx, sock, SOCKBUF_CLIENT);
+	sockbuf_set_sock(chat->client, sock, SOCKBUF_CLIENT);
 
 	/* Delete the listening idx since it's not needed. */
-	chat->idx = -1;
+	chat->client = -1;
 	sockbuf_delete(idx);
 	return(0);
 }
 
-static int dcc_chat_server_delete(void *client_data, int idx)
+static int dcc_listen_delete(void *client_data, int idx)
 {
-	dcc_chat_t *chat = client_data;
+	dcc_listen_t *listen = client_data;
 
 	/* If the timer is still going, kill it. */
-	if (chat->timer_id != -1) {
-		timer_destroy(chat->timer_id);
-		chat->timer_id = -1;
+	if (listen->timer_id != -1) {
+		timer_destroy(listen->timer_id);
+		listen->timer_id = -1;
 	}
 
 	/* If we're still waiting for the connection to come in, then send
 	 * an error to the associated client sock. */
-	if (chat->idx != -1) {
-		sockbuf_detach_filter(chat->idx, &dcc_chat_client_filter, NULL);
-		if (chat->timeout) {
-			sockbuf_on_eof(chat->idx, DCC_FILTER_LEVEL, -1, "DCC chat timed out");
+	if (sockbuf_isvalid(listen->client)) {
+		if (listen->timeout) {
+			sockbuf_on_eof(listen->client, SOCKBUF_LEVEL_INTERNAL, -1, "DCC timed out");
 		}
 		else {
-			sockbuf_on_eof(chat->idx, DCC_FILTER_LEVEL, -1, "DCC chat listening socket unexpectedly closed");
+			sockbuf_on_eof(listen->client, SOCKBUF_LEVEL_INTERNAL, -2, "DCC listening socket unexpectedly closed");
 		}
 	}
-	free(chat);
+	free(listen);
+	return(0);
+}
+
+static int dcc_listen_timeout(void *client_data)
+{
+	dcc_listen_t *listen = client_data;
+
+	listen->timeout = 1;
+	listen->timer_id = -1;
+	sockbuf_delete(listen->serv);
+	return(0);
+}
+
+static int dcc_chat_connect(void *client_data, int idx, const char *peer_ip, int peer_port)
+{
+	sockbuf_detach_filter(idx, &dcc_chat_filter, NULL);
+	return sockbuf_on_connect(idx, DCC_FILTER_LEVEL, peer_ip, peer_port);
+}
+
+static int dcc_chat_eof(void *client_data, int idx, int err, const char *errmsg)
+{
+	sockbuf_detach_filter(idx, &dcc_chat_filter, NULL);
+	return sockbuf_on_eof(idx, DCC_FILTER_LEVEL, err, errmsg);
+}
+
+static int dcc_chat_delete(void *client_data, int idx)
+{
+	int serv = (int) client_data;
+	sockbuf_delete(serv);
 	return(0);
 }
 
-static int dcc_chat_client_delete(void *client_data, int idx)
+int dcc_start_send(const char *nick, const char *fname, int timeout)
+{
+	dcc_listen_t *listen;
+	dcc_send_t *send;
+	int idx, longip, size, fd;
+	char *quote, *slash;
+
+	fd = open(fname, O_RDONLY);
+	if (!fd) return(-1);
+	size = lseek(fd, 0, SEEK_END);
+	lseek(fd, 0, SEEK_SET);
+
+	listen = dcc_listen(timeout);
+	if (!listen) {
+		close(fd);
+		return(-1);
+	}
+
+	/* Create an empty sockbuf that will eventually be used for the
+	 * dcc chat (when they connect to us). */
+	idx = sockbuf_new();
+	send = calloc(1, sizeof(*send));
+	sockbuf_attach_filter(idx, &dcc_send_filter, send);
+
+	listen->client = idx;
+	send->next = dcc_send_head;
+	dcc_send_head = send;
+	send->serv = listen->serv;
+	send->port = listen->port;
+	send->fd = fd;
+	send->idx = idx;
+	send->size = size;
+	send->bytes_sent = 0;
+	send->bytes_left = size;
+	send->request_time = now;
+	send->fname = strdup(fname);
+	send->nick = strdup(nick);
+
+	slash = strrchr(fname, '/');
+	if (slash) fname = slash+1;
+
+	if (strchr(fname, ' ')) quote = "\"";
+	else quote = "";
+
+	longip = htonl(getmyip());
+	printserv(SERVER_NORMAL, "PRIVMSG %s :%cDCC SEND %s%s%s %u %d %d%c", nick, 1, quote, fname, quote, longip, listen->port, size, 1);
+	return(idx);
+}
+
+static int dcc_send_bytes(dcc_send_t *send)
 {
-	dcc_chat_t *chat = client_data;
+	int n, out, total;
+	char buf[4096];
 
-	/* If the listening idx is still open, close it down. */
-	if (chat->serv != -1) {
-		chat->idx = -1;
-		sockbuf_delete(chat->serv);
+	total = 0;
+	for (;;) {
+		/* Read in a chunk from the file. If we get eof or error,
+		 * return -1. */
+		n = read(send->fd, buf, sizeof(buf));
+		if (n <= 0) return(-1);
+
+		/* Now write the chunk to the sockbuf. If we get an error
+		 * return -2, and if it starts blocking return 0. Otherwise
+		 * we loop to send another chunk. */
+		out = sockbuf_write(send->idx, buf, n);
+		if (out < 0) return(-2);
+		send->bytes_sent += out;
+		send->bytes_left -= out;
+		update_snapshot(send, out);
+		total += out;
+		if (out < n) {
+			sockbuf_on_written(send->idx, DCC_FILTER_LEVEL, total, n - out);
+			if (sockbuf_isvalid(send->idx)) return(0);
+			else return(-2);
+		}
+	}
+}
+
+static int dcc_send_connect(void *client_data, int idx, const char *peer_ip, int peer_port)
+{
+	dcc_send_t *send = client_data;
+	int n;
+
+	send->connect_time = now;
+	send->serv = -1;
+	send->ip = strdup(peer_ip);
+	sockbuf_on_connect(idx, DCC_FILTER_LEVEL, peer_ip, peer_port);
+	if (sockbuf_isvalid(idx)) {
+		n = dcc_send_bytes(send);
+		if (n == -1) dcc_send_done(send);
 	}
 	return(0);
 }
 
-static int dcc_chat_timeout(void *client_data)
+static int dcc_send_read(void *client_data, int idx, char *data, int len)
+{
+	dcc_send_t *send = client_data;
+	int ack;
+
+	memcpy(&ack, data, sizeof(int));
+	ack = ntohl(ack);
+	send->acks++;
+	send->bytes_acked = ack;
+	return(0);
+}
+
+static int dcc_send_written(void *client_data, int idx, int len, int remaining)
 {
-	dcc_chat_t *chat = client_data;
+	dcc_send_t *send = client_data;
+	int n;
+
+	/* Update stats on the send. */
+	send->bytes_sent += len;
+	send->bytes_left -= len;
+	update_snapshot(send, len);
+
+	/* Pass the event up to whoever's listening. */
+
+	sockbuf_on_written(idx, DCC_FILTER_LEVEL, len, remaining);
+	if (!sockbuf_isvalid(idx)) return(0);
+
+	/* Send as much data as we can until we block. dcc_send_bytes()
+	 * returns -1 when the file has eof(). */
+	n = dcc_send_bytes(send);
+	if (n == -1 && send->bytes_left <= 0 && send->bytes_acked >= send->bytes_sent) {
+		dcc_send_done(send);
+	}
 
-	chat->timeout = 1;
-	chat->timer_id = -1;
-	sockbuf_delete(chat->serv);
 	return(0);
 }
 
+static int dcc_send_eof(void *client_data, int idx, int err, const char *errmsg)
+{
+	sockbuf_on_eof(idx, DCC_FILTER_LEVEL, err, errmsg);
+	sockbuf_delete(idx);
+	return(0);
+}
+
+static int dcc_send_delete(void *client_data, int idx)
+{
+	dcc_send_t *send = client_data;
+	dcc_send_t *prev, *ptr;
+
+	if (sockbuf_isvalid(send->serv)) {
+		sockbuf_delete(send->serv);
+	}
+	if (send->fd != -1) close(send->fd);
+	if (send->fname) free(send->fname);
+	if (send->nick) free(send->nick);
+	if (send->ip) free(send->ip);
+	prev = NULL;
+	for (ptr = dcc_send_head; ptr; ptr = ptr->next) {
+		if (ptr == send) break;
+		prev = ptr;
+	}
+	if (prev) prev->next = send->next;
+	else dcc_send_head = send->next;
+	free(send);
+	return(0);
+}
+
+static int dcc_send_done(dcc_send_t *send)
+{
+	int idx;
+
+	idx = send->idx;
+	close(send->fd);
+	send->fd = -1;
+	sockbuf_on_eof(idx, DCC_FILTER_LEVEL, 0, "Success");
+
+	/* If their handler didn't close the idx, do it here. */
+	if (sockbuf_isvalid(idx)) sockbuf_delete(idx);
+	return(0);
+}
+
+int dcc_send_info(int idx, int field, void *valueptr)
+{
+	dcc_send_t *send;
+	int i, n;
+
+	if (!valueptr) return(-1);
+	if (sockbuf_get_filter_data(idx, &dcc_send_filter, &send) < 0) {
+		if (sockbuf_get_filter_data(idx, &dcc_recv_filter, &send) < 0) return(-1);
+	}
+
+	switch (field) {
+		case DCC_SEND_SENT:
+			*(int *)valueptr = send->bytes_sent;
+			break;
+		case DCC_SEND_LEFT:
+			*(int *)valueptr = send->bytes_left;
+			break;
+		case DCC_SEND_CPS_TOTAL:
+			if (!send->connect_time) n = 0;
+			else if (send->connect_time >= now) n = send->bytes_sent;
+			else n = (int) ((float) send->bytes_sent / ((float) now - (float) send->connect_time));
+
+			*(int *)valueptr = n;
+			break;
+		case DCC_SEND_CPS_SNAPSHOT:
+			update_snapshot(send, 0);
+			/* When we calculate the total, we do not include
+			 * the current second (snapshot_counter) because more
+			 * data might be sent this second and our report won't
+			 * be accurate. */
+			n = 0;
+			for (i = 0; i < 5; i++) {
+				if (i != send->snapshot_counter) n += send->snapshot_bytes[i];
+			}
+			if (now - send->connect_time >= 5) n = (int) ((float) n / 4.0);
+			else if (now - send->connect_time > 1) n = (int) ((float) n / (float) (now - send->connect_time - 1));
+			else n = 0;
+			*(int *)valueptr = n;
+			break;
+		default:
+			return(-1);
+	}
+	return(0);
+}
+
+int dcc_accept_send(char *nick, char *localfname, char *fname, int size, int resume, char *ip, int port, int timeout)
+{
+	dcc_send_t *send;
+	char *quote;
+	egg_timeval_t howlong;
+
+	send = calloc(1, sizeof(*send));
+	send->next = dcc_recv_head;
+	dcc_recv_head = send;
+
+	/* See if they want the default timeout. */
+	if (!timeout) timeout = config.dcc_timeout;
+	if (timeout > 0) {
+		howlong.sec = timeout;
+		howlong.usec = 0;
+		send->timer_id = timer_create_complex(&howlong, dcc_recv_timeout, send, 0);
+	}
+	else send->connect_time = -1;
+
+	send->port = port;
+	send->fname = strdup(localfname);
+	send->nick = strdup(nick);
+	send->ip = strdup(ip);
+	send->size = size;
+	send->bytes_sent = 0;
+	send->bytes_left = size;
+	send->request_time = now;
+
+	if (resume < 0) {
+		send->fd = open(localfname, O_RDWR | O_CREAT, 0640);
+		resume = lseek(send->fd, 0, SEEK_END);
+		close(send->fd);
+		if (resume < 0) resume = 0;
+	}
+
+	if (resume >= size) resume = 0;
+
+	if (resume) {
+		putlog(LOG_MISC, "*", "sending resume request");
+		send->idx = sockbuf_new();
+		send->fd = open(localfname, O_RDWR | O_CREAT, 0640);
+		if (resume < 0) resume = lseek(send->fd, 0, SEEK_END);
+		else resume = lseek(send->fd, resume, SEEK_SET);
+		if (strchr(fname, ' ')) quote = "\"";
+		else quote = "";
+		printserv(SERVER_NORMAL, "PRIVMSG %s :%cDCC RESUME %s%s%s %d %d%c", nick, 1, quote, fname, quote, port, resume, 1);
+	}
+	else {
+		send->idx = egg_connect(ip, port, -1);
+		send->fd = open(localfname, O_RDWR | O_CREAT | O_TRUNC, 0640);
+	}
+
+	sockbuf_attach_filter(send->idx, &dcc_recv_filter, send);
+
+	return(send->idx);
+}
+
+static int dcc_recv_timeout(void *client_data)
+{
+	dcc_send_t *send = client_data;
+
+	send->timer_id = -1;
+	sockbuf_on_eof(send->idx, SOCKBUF_LEVEL_INTERNAL, -1, "DCC timed out");
+	return(0);
+}
+
+static int dcc_recv_connect(void *client_data, int idx, const char *peer_ip, int peer_port)
+{
+	dcc_send_t *send = client_data;
+
+	/* send->connect_time holds our connect timer if there was one */
+	if (send->timer_id >= 0) timer_destroy(send->timer_id);
+	send->connect_time = now;
+	sockbuf_on_connect(idx, DCC_FILTER_LEVEL, peer_ip, peer_port);
+	return(0);
+}
+
+static int dcc_recv_read(void *client_data, int idx, char *data, int len)
+{
+	dcc_send_t *send = client_data;
+	int nlen; /* len in network byte order */
+
+	send->bytes_sent += len;
+	send->bytes_left -= len;
+	update_snapshot(send, len);
+	write(send->fd, data, len);
+	nlen = htonl(send->bytes_sent);
+	sockbuf_on_write(idx, DCC_FILTER_LEVEL, (char *)&nlen, 4);
+	return sockbuf_on_read(idx, DCC_FILTER_LEVEL, data, len);
+}
+
+static int dcc_recv_eof(void *client_data, int idx, int err, const char *errmsg)
+{
+	sockbuf_on_eof(idx, DCC_FILTER_LEVEL, err, errmsg);
+	sockbuf_delete(idx);
+	return(0);
+}
+
+static int dcc_recv_delete(void *client_data, int idx)
+{
+	dcc_send_t *send = client_data;
+	dcc_send_t *prev, *ptr;
+
+	if (send->timer_id != -1) timer_destroy(send->timer_id);
+
+	if (send->fd != -1) close(send->fd);
+	if (send->fname) free(send->fname);
+	if (send->nick) free(send->nick);
+	if (send->ip) free(send->ip);
+	prev = NULL;
+	for (ptr = dcc_recv_head; ptr; ptr = ptr->next) {
+		if (ptr == send) break;
+		prev = ptr;
+	}
+	if (prev) prev->next = send->next;
+	else dcc_recv_head = send->next;
+	free(send);
+	return(0);
+}
+
+static void update_snapshot(dcc_send_t *send, int len)
+{
+	int diff;
+	int i;
+
+	/* Get time diff. */
+	diff = now - send->last_snapshot;
+	send->last_snapshot = now;
+	if (diff > 5) diff = 5;
+
+	/* Reset counter for seconds that were skipped. */
+	for (i = 0; i < diff; i++) {
+		send->snapshot_counter++;
+		if (send->snapshot_counter >= 5) send->snapshot_counter = 0;
+		send->snapshot_bytes[send->snapshot_counter] = 0;
+	}
+
+	/* Add the bytes to the current second. */
+	send->snapshot_bytes[send->snapshot_counter] += len;
+}
+
 static void got_chat(char *nick, char *uhost, user_t *u, char *text)
 {
+	struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
 	char type[256], ip[256], port[32];
 	int nport;
 
 	sscanf(text, "%255s %255s %31s", type, ip, port);
+	type[255] = ip[255] = port[31] = 0;
 
 	/* Check if the ip is 'new-style' (dotted decimal or ipv6). If not,
 	 * it's the old-style long ip. */
 	if (!strchr(ip, '.') && !strchr(ip, ':')) {
-		int longip;
-		longip = atoi(ip);
-		sprintf(ip, "%d.%d.%d.%d", longip & 255, (longip >> 8) & 255, (longip >> 16) & 255, (longip >> 24) & 255);
+		unsigned int longip;
+		longip = (unsigned int) atol(ip);
+		sprintf(ip, "%d.%d.%d.%d", (longip >> 24) & 255, (longip >> 16) & 255, (longip >> 8) & 255, (longip) & 255);
 	}
 
 	nport = atoi(port);
 
-	check_bind(BT_dcc_chat, nick, NULL, nick, uhost, u, type, ip, nport);
+	get_user_flagrec(u, &fr, NULL);
+	check_bind(BT_dcc_chat, nick, &fr, nick, uhost, u, type, ip, nport);
+}
+
+static void got_resume(char *nick, char *uhost, struct userrec *u, char *text)
+{
+	int port, pos, n;
+	dcc_send_t *send;
+	char *fname, *space;
+
+	fname = text;
+	space = strrchr(text, ' ');
+	if (space && space != text) pos = atoi(space+1);
+	else return;
+	*space = 0;
+	space--;
+	space = strrchr(text, ' ');
+	if (space && space != text) port = atoi(space+1);
+	else return;
+	*space = 0;
+
+	for (send = dcc_send_head; send; send = send->next) {
+		if (send->port == port && !strcasecmp(send->nick, nick)) {
+			n = lseek(send->fd, pos, SEEK_SET);
+			send->bytes_left -= n;
+			send->resumed_at = n;
+			printserv(SERVER_NORMAL, "PRIVMSG %s :%cDCC ACCEPT %s %d %d%c", nick, 1, fname, port, n, 1);
+			break;
+		}
+	}
+}
+
+static void got_accept(char *nick, char *uhost, struct userrec *u, char *text)
+{
+	int port, pos, n;
+	dcc_send_t *send;
+	char *fname, *space;
+
+	fname = text;
+	space = strrchr(text, ' ');
+	if (space && space != text) pos = atoi(space+1);
+	else return;
+	*space = 0;
+	space--;
+	space = strrchr(text, ' ');
+	if (space && space != text) port = atoi(space+1);
+	else return;
+	*space = 0;
+
+	for (send = dcc_recv_head; send; send = send->next) {
+		if (send->port == port && !strcasecmp(send->nick, nick)) {
+			n = lseek(send->fd, pos, SEEK_SET);
+			send->bytes_left -= n;
+			send->resumed_at = n;
+			egg_reconnect(send->idx, send->ip, port, -1);
+			break;
+		}
+	}
+}
+
+static void got_send(char *nick, char *uhost, user_t *u, char *text)
+{
+	struct flag_record fr = {FR_GLOBAL, 0, 0, 0, 0, 0};
+	char *space, *fname, ip[256];
+	int port, size, n;
+
+	fname = text;
+	space = strrchr(text, ' ');
+	if (!space || space == text) return;
+	size = atoi(space+1);
+	*space-- = 0;
+	space = strrchr(text, ' ');
+	if (!space || space == text) return;
+	port = atoi(space+1);
+	*space-- = 0;
+	space = strchr(text, ' ');
+	if (!space || space == text) return;
+	strlcpy(ip, space+1, sizeof(ip));
+	*space = 0;
+
+	if (*fname == '"') {
+		fname++;
+		n = strlen(fname);
+		if (n && fname[n-1] == '"') fname[n-1] = 0;
+		else return;
+	}
+	/* Check if the ip is new-style (dotted decimal or ipv6). If not,
+	 * it's the old-style long ip. */
+	if (!strchr(ip, '.') && !strchr(ip, ':')) {
+		unsigned int longip;
+		longip = (unsigned int) atol(ip);
+		sprintf(ip, "%d.%d.%d.%d", (longip >> 24) & 255, (longip >> 16) & 255, (longip >> 8) & 255, (longip) & 255);
+	}
+
+	get_user_flagrec(u, &fr, NULL);
+	check_bind(BT_dcc_recv, nick, &fr, nick, uhost, u, fname, ip, port, size);
 }
 
 /* PRIVMSG ((target) :^ADCC CHAT ((type) ((longip) ((port)^A */
-static int got_dcc(char *nick, char *uhost, struct userrec *u, char *cmd, char *text)
+static int got_dcc(char *nick, char *uhost, struct userrec *u, char *dest, char *cmd, char *text)
 {
 	if (!strncasecmp(text, "chat ", 5)) {
 		got_chat(nick, uhost, u, text+5);
 	}
 	else if (!strncasecmp(text, "send ", 5)) {
-		//got_send(nick, uhost, u, text+5);
+		got_send(nick, uhost, u, text+5);
+	}
+	else if (!strncasecmp(text, "resume ", 7)) {
+		got_resume(nick, uhost, u, text+7);
+	}
+	else if (!strncasecmp(text, "accept ", 7)) {
+		got_accept(nick, uhost, u, text+7);
 	}
 	return(0);
 }
 
-cmd_t my_ctcp_binds[] = {
+cmd_t ctcp_dcc_binds[] = {
 	{"DCC", "", (Function) got_dcc, NULL},
 	{NULL, NULL, NULL, NULL}
 };
Index: eggdrop1.7/modules/server/dcc.h
diff -u eggdrop1.7/modules/server/dcc.h:1.1 eggdrop1.7/modules/server/dcc.h:1.2
--- eggdrop1.7/modules/server/dcc.h:1.1	Sun Sep 22 03:50:46 2002
+++ eggdrop1.7/modules/server/dcc.h	Mon Oct  7 17:36:36 2002
@@ -1,6 +1,17 @@
 #ifndef _SERVER_DCC_H_
 #define _SERVER_DCC_H_
 
+/* Statistic types for dcc_send_info(). */
+#define DCC_SEND_SENT	1
+#define DCC_SEND_LEFT	2
+#define DCC_SEND_CPS_TOTAL	3
+#define DCC_SEND_CPS_SNAPSHOT	4
+
 int dcc_start_chat(const char *nick, int timeout);
+int dcc_start_send(const char *nick, const char *fname, int timeout);
+int dcc_send_info(int idx, int field, void *valueptr);
+int dcc_accept_send(char *nick, char *localfname, char *fname, int size, int resume, char *ip, int port, int timeout);
+
+extern cmd_t ctcp_dcc_binds[];
 
 #endif
Index: eggdrop1.7/modules/server/scriptcmds.c
diff -u eggdrop1.7/modules/server/scriptcmds.c:1.12 eggdrop1.7/modules/server/scriptcmds.c:1.13
--- eggdrop1.7/modules/server/scriptcmds.c:1.12	Sun Sep 22 03:50:46 2002
+++ eggdrop1.7/modules/server/scriptcmds.c	Mon Oct  7 17:36:36 2002
@@ -22,7 +22,7 @@
 
 /* FIXME: #include mess
 #ifndef lint
-static const char rcsid[] = "$Id: scriptcmds.c,v 1.12 2002/09/22 08:50:46 stdarg Exp $";
+static const char rcsid[] = "$Id: scriptcmds.c,v 1.13 2002/10/07 22:36:36 stdarg Exp $";
 #endif
 */
 
@@ -38,6 +38,7 @@
 static int script_isbotnick (char *nick);
 static int script_putserv(char *queue, char *next, char *text);
 static int script_jump (int nargs, int num);
+static int script_dcc_send_info(int idx, char *what);
 
 /* From serverlist.c */
 extern int server_list_index;
@@ -64,6 +65,9 @@
 	{"", "nick_del", nick_del, NULL, 1, "i", "nick-num", SCRIPT_INTEGER, 0},
 	{"", "nick_clear", nick_clear, NULL, 0, "", "", SCRIPT_INTEGER, 0},
 	{"", "dcc_chat", dcc_start_chat, NULL, 1, "si", "nick ?timeout?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
+	{"", "dcc_send", dcc_start_send, NULL, 2, "ssi", "nick filename ?timeout?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
+	{"", "dcc_send_info", script_dcc_send_info, NULL, 2, "is", "idx stat", SCRIPT_INTEGER, 0},
+	{"", "dcc_accept_send", dcc_accept_send, NULL, 7, "sssiisii", "nick localfile remotefile size resume ip port ?timeout?", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
         {0}
 };
 
@@ -123,4 +127,18 @@
 	kill_server("changing servers");
 	
 	return(0);
+}
+
+static int script_dcc_send_info(int idx, char *what)
+{
+	int field, value;
+
+	if (!strcasecmp(what, "bytes_left")) field = DCC_SEND_LEFT;
+	else if (!strcasecmp(what, "bytes_sent")) field = DCC_SEND_SENT;
+	else if (!strcasecmp(what, "total_cps")) field = DCC_SEND_CPS_TOTAL;
+	else if (!strcasecmp(what, "snapshot_cps")) field = DCC_SEND_CPS_SNAPSHOT;
+	else return(-1);
+
+	if (dcc_send_info(idx, field, &value) < 0) return(-1);
+	return(value);
 }
Index: eggdrop1.7/src/Makefile.am
diff -u eggdrop1.7/src/Makefile.am:1.29 eggdrop1.7/src/Makefile.am:1.30
--- eggdrop1.7/src/Makefile.am:1.29	Sat Sep 21 02:40:16 2002
+++ eggdrop1.7/src/Makefile.am	Mon Oct  7 17:36:36 2002
@@ -1,4 +1,4 @@
-# $Id: Makefile.am,v 1.29 2002/09/21 07:40:16 stdarg Exp $
+# $Id: Makefile.am,v 1.30 2002/10/07 22:36:36 stdarg Exp $
 
 # FIXME: optionally allow a system wide install by ignoring the line below.
 bindir			= $(exec_prefix)
@@ -23,20 +23,13 @@
 eggdrop_SOURCES		= bg.c \
 			bg.h \
 			chan.h \
-			chanprog.c \
-			chanprog.h \
-			cmds.c \
-			cmds.h \
+			chanprog.c chanprog.h \
 			cmdt.h \
-			core_binds.c \
-			core_binds.h \
-			dcc.c \
-			dcc.h \
-			dccutil.c \
-			dccutil.h \
+			core_binds.c core_binds.h \
+			dcc.c dcc.h \
+			dccutil.c dccutil.h \
 			debug.h \
-			dns.c \
-			dns.h \
+			dns.c dns.h \
 			egg.h \
 			egg_timer.c \
 			flags.c \
@@ -59,6 +52,7 @@
 			net.h \
 			patch.h \
 			scriptnet.c \
+			scriptuser.c \
 			tcl.c \
 			tcl.h \
 			tcldcc.c \
Index: eggdrop1.7/src/cmds.c
diff -u eggdrop1.7/src/cmds.c:1.107 eggdrop1.7/src/cmds.c:1.108
--- eggdrop1.7/src/cmds.c:1.107	Fri Sep 20 16:41:49 2002
+++ eggdrop1.7/src/cmds.c	Mon Oct  7 17:36:36 2002
@@ -24,7 +24,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: cmds.c,v 1.107 2002/09/20 21:41:49 stdarg Exp $";
+static const char rcsid[] = "$Id: cmds.c,v 1.108 2002/10/07 22:36:36 stdarg Exp $";
 #endif
 
 #include "main.h"
@@ -43,10 +43,6 @@
 				   tell_dcc, do_boot, chanout_but,
 				   dcc_chatter, flush_lines		*/
 #include "net.h"		/* tell_netdebug, killsock		*/
-#include "userrec.h"		/* addhost_by_handle, change_handle,
-				   write_userfile, correct_handle,
-				   u_pass_match, deluser,
-				   delhost_by_handle			*/
 #include "cmds.h"		/* prototypes				*/
 
 #include <ctype.h>
@@ -54,7 +50,7 @@
 
 extern struct chanset_t	*chanset;
 extern struct dcc_t	*dcc;
-extern struct userrec	*userlist;
+extern user_t	*userlist;
 extern int		 dcc_total, remote_boots, backgrd, make_userfile,
 			 do_restart, conmask, strict_host,
 			 term_z, con_chan;
@@ -72,40 +68,7 @@
 static char	*btos(unsigned long);
 
 
-/* Add hostmask to a bot's record if possible.
- */
-static int add_bot_hostmask(int idx, char *nick)
-{
-  struct chanset_t *chan;
-
-  for (chan = chanset; chan; chan = chan->next)
-    if (channel_active(chan)) {
-      memberlist *m = ismember(chan, nick);
-
-      if (m) {
-	char s[UHOSTLEN];
-	struct userrec *u;
-
-	snprintf(s, sizeof s, "%s!%s", m->nick, m->userhost);
-	u = get_user_by_host(s);
-	if (u) {
-	  dprintf(idx, _("(Can't add hostmask for %1$s because it matches %2$s)\n"),
-		  nick, u->handle);
-	  return(0);
-	}
-	if (strchr("~^+=-", m->userhost[0]))
-	  snprintf(s, sizeof s, "*!%s%s", strict_host ? "?" : "", m->userhost+1);
-	else
-	  snprintf(s, sizeof s, "*!%s", m->userhost);
-	dprintf(idx, _("(Added hostmask for %1$s from %2$s)\n"), nick, chan->dname);
-	addhost_by_handle(nick, s);
-	return(1);
-      }
-    }
-  return 0;
-}
-
-static void tell_who(struct userrec *u, int idx, int chan)
+static void tell_who(user_t *u, int idx, int chan)
 {
   int i, k, ok = 0, atr = u ? u->flags : 0, len;
   char s[1024];			/* temp fix - 1.4 has a better one */
@@ -219,7 +182,7 @@
   }
 }
 
-static int cmd_me(struct userrec *u, int idx, char *par)
+static int cmd_me(user_t *u, int idx, char *par)
 {
   int i;
 
@@ -238,13 +201,13 @@
   return(0);
 }
 
-static int cmd_motd(struct userrec *u, int idx, char *par)
+static int cmd_motd(user_t *u, int idx, char *par)
 {
     show_motd(idx);
   return(1);
 }
 
-static int cmd_away(struct userrec *u, int idx, char *par)
+static int cmd_away(user_t *u, int idx, char *par)
 {
   if (strlen(par) > 60)
     par[60] = 0;
@@ -252,13 +215,13 @@
   return(1);
 }
 
-static int cmd_back(struct userrec *u, int idx, char *par)
+static int cmd_back(user_t *u, int idx, char *par)
 {
   not_away(idx);
   return(1);
 }
 
-static int cmd_newpass(struct userrec *u, int idx, char *par)
+static int cmd_newpass(user_t *u, int idx, char *par)
 {
   char *new;
 
@@ -279,14 +242,14 @@
   return(0);
 }
 
-static int cmd_rehelp(struct userrec *u, int idx, char *par)
+static int cmd_rehelp(user_t *u, int idx, char *par)
 {
   dprintf(idx, _("Reload help cache...\n"));
   reload_help_data();
   return(1);
 }
 
-static int cmd_help(struct userrec *u, int idx, char *par)
+static int cmd_help(user_t *u, int idx, char *par)
 {
   struct flag_record fr = {FR_GLOBAL | FR_CHAN, 0, 0, 0, 0, 0};
 
@@ -317,7 +280,7 @@
   return(1);
 }
 
-static int cmd_who(struct userrec *u, int idx, char *par)
+static int cmd_who(user_t *u, int idx, char *par)
 {
     putlog(LOG_CMDS, "*", "#%s# who", dcc[idx].nick);
     if (dcc[idx].u.chat->channel < 0)
@@ -328,7 +291,7 @@
   return(1);
 }
 
-static int cmd_whois(struct userrec *u, int idx, char *par)
+static int cmd_whois(user_t *u, int idx, char *par)
 {
   if (!par[0]) {
     dprintf(idx, "Usage: whois <handle>\n");
@@ -338,7 +301,7 @@
   return(1);
 }
 
-static int cmd_match(struct userrec *u, int idx, char *par)
+static int cmd_match(user_t *u, int idx, char *par)
 {
   int start = 1, limit = 20;
   char *s, *s1, *chname;
@@ -365,7 +328,7 @@
   return(1);
 }
 
-static int cmd_uptime(struct userrec *u, int idx, char *par)
+static int cmd_uptime(user_t *u, int idx, char *par)
 {
   char s[256];
   unsigned long uptime, tmp, hr, min; 
@@ -388,7 +351,7 @@
   return(1);
 }
 
-static int cmd_status(struct userrec *u, int idx, char *par)
+static int cmd_status(user_t *u, int idx, char *par)
 {
   int atr = u ? u->flags : 0;
 
@@ -408,17 +371,17 @@
   return(1);
 }
 
-static int cmd_dccstat(struct userrec *u, int idx, char *par)
+static int cmd_dccstat(user_t *u, int idx, char *par)
 {
   tell_dcc(idx);
   return(1);
 }
 
-static int cmd_boot(struct userrec *u, int idx, char *par)
+static int cmd_boot(user_t *u, int idx, char *par)
 {
   int i, files = 0, ok = 0;
   char *who;
-  struct userrec *u2;
+  user_t *u2;
 
   if (!par[0]) {
     dprintf(idx, "Usage: boot nick[@bot]\n");
@@ -453,7 +416,7 @@
   return(1);
 }
 
-static int cmd_console(struct userrec *u, int idx, char *par)
+static int cmd_console(user_t *u, int idx, char *par)
 {
   char *nick, s[2], s1[512];
   int dest = 0, i, ok = 0, pls, md;
@@ -568,10 +531,10 @@
   return(1);
 }
 
-static int cmd_pls_bot(struct userrec *u, int idx, char *par)
+static int cmd_pls_bot(user_t *u, int idx, char *par)
 {
   char *handle, *addr, *p, *q, *host;
-  struct userrec *u1;
+  user_t *u1;
   struct bot_addr *bi;
   int addrlen;
 
@@ -637,11 +600,11 @@
   return(1);
 }
 
-static int cmd_chhandle(struct userrec *u, int idx, char *par)
+static int cmd_chhandle(user_t *u, int idx, char *par)
 {
   char hand[HANDLEN + 1], newhand[HANDLEN + 1];
   int i, atr = u ? u->flags : 0, atr2;
-  struct userrec *u2;
+  user_t *u2;
 
   strlcpy(hand, newsplit(&par), sizeof hand);
   strlcpy(newhand, newsplit(&par), sizeof newhand);
@@ -682,7 +645,7 @@
   return(1);
 }
 
-static int cmd_handle(struct userrec *u, int idx, char *par)
+static int cmd_handle(user_t *u, int idx, char *par)
 {
   char oldhandle[HANDLEN + 1], newhandle[HANDLEN + 1];
   int i;
@@ -714,7 +677,7 @@
   return(1);
 }
 
-static int cmd_chpass(struct userrec *u, int idx, char *par)
+static int cmd_chpass(user_t *u, int idx, char *par)
 {
   char *handle, *new;
   int atr = u ? u->flags : 0, l;
@@ -754,12 +717,12 @@
   return(0);
 }
 
-static int cmd_chaddr(struct userrec *u, int idx, char *par)
+static int cmd_chaddr(user_t *u, int idx, char *par)
 {
   int telnet_port = 3333, relay_port = 3333;
   char *handle, *addr, *p, *q;
   struct bot_addr *bi;
-  struct userrec *u1;
+  user_t *u1;
   int addrlen;
 
   if (!par[0]) {
@@ -824,10 +787,10 @@
   return(1);
 }
 
-static int cmd_comment(struct userrec *u, int idx, char *par)
+static int cmd_comment(user_t *u, int idx, char *par)
 {
   char *handle;
-  struct userrec *u1;
+  user_t *u1;
 
   if (!par[0]) {
     dprintf(idx, "Usage: comment <handle> <newcomment>\n");
@@ -854,7 +817,7 @@
   return(1);
 }
 
-static int cmd_restart(struct userrec *u, int idx, char *par)
+static int cmd_restart(user_t *u, int idx, char *par)
 {
   if (!backgrd) {
     dprintf(idx, "%s\n", _("You cannot .restart a bot when running -n (due to tcl)."));
@@ -869,7 +832,7 @@
   return(1);
 }
 
-static int cmd_rehash(struct userrec *u, int idx, char *par)
+static int cmd_rehash(user_t *u, int idx, char *par)
 {
   dprintf(idx, "%s\n", _("Rehashing."));
   if (make_userfile)
@@ -880,14 +843,14 @@
   return(1);
 }
 
-static int cmd_reload(struct userrec *u, int idx, char *par)
+static int cmd_reload(user_t *u, int idx, char *par)
 {
   dprintf(idx, "%s\n", _("Reloading user file..."));
   reload();
   return(1);
 }
 
-void cmd_die(struct userrec *u, int idx, char *par)
+void cmd_die(user_t *u, int idx, char *par)
 {
   char s1[1024], s2[1024];
 
@@ -907,7 +870,7 @@
   kill_bot(s1, s2);
 }
 
-static int cmd_simul(struct userrec *u, int idx, char *par)
+static int cmd_simul(user_t *u, int idx, char *par)
 {
   char *nick;
   int i, ok = 0;
@@ -934,14 +897,14 @@
   return(1);
 }
 
-static int cmd_save(struct userrec *u, int idx, char *par)
+static int cmd_save(user_t *u, int idx, char *par)
 {
   dprintf(idx, _("Saving user file...\n"));
   write_userfile(-1);
   return(1);
 }
 
-static int cmd_backup(struct userrec *u, int idx, char *par)
+static int cmd_backup(user_t *u, int idx, char *par)
 {
   dprintf(idx, _("Backing up the channel & user files...\n"));
   call_hook(HOOK_BACKUP);
@@ -951,7 +914,7 @@
 /* After messing with someone's user flags, make sure the dcc-chat flags
  * are set correctly.
  */
-int check_dcc_attrs(struct userrec *u, int oatr)
+int check_dcc_attrs(user_t *u, int oatr)
 {
   int i, stat;
 
@@ -1045,7 +1008,7 @@
   return u->flags;
 }
 
-int check_dcc_chanattrs(struct userrec *u, char *chname, int chflags,
+int check_dcc_chanattrs(user_t *u, char *chname, int chflags,
 			int ochatr)
 {
   int i, found = 0, atr = u ? u->flags : 0;
@@ -1103,11 +1066,11 @@
   return chflags;
 }
 
-static int cmd_chattr(struct userrec *u, int idx, char *par)
+static int cmd_chattr(user_t *u, int idx, char *par)
 {
   char *hand, *arg = NULL, *tmpchg = NULL, *chg = NULL, work[1024];
   struct chanset_t *chan = NULL;
-  struct userrec *u2;
+  user_t *u2;
   struct flag_record pls = {0, 0, 0, 0, 0, 0},
   		     mns = {0, 0, 0, 0, 0, 0},
 		     user = {0, 0, 0, 0, 0, 0};
@@ -1282,11 +1245,11 @@
   return(1);
 }
 
-static int cmd_botattr(struct userrec *u, int idx, char *par)
+static int cmd_botattr(user_t *u, int idx, char *par)
 {
   char *hand, *chg = NULL, *arg = NULL, *tmpchg = NULL, work[1024];
   struct chanset_t *chan = NULL;
-  struct userrec *u2;
+  user_t *u2;
   struct flag_record pls = {0, 0, 0, 0, 0, 0},
 		     mns = {0, 0, 0, 0, 0, 0},
 		     user = {0, 0, 0, 0, 0, 0};
@@ -1422,7 +1385,7 @@
   return(1);
 }
 
-static int cmd_su(struct userrec *u, int idx, char *par)
+static int cmd_su(user_t *u, int idx, char *par)
 {
   int atr = u ? u->flags : 0;
   struct flag_record fr = {FR_ANYWH | FR_CHAN | FR_GLOBAL, 0, 0, 0, 0, 0};
@@ -1487,7 +1450,7 @@
   return(1);
 }
 
-static int cmd_fixcodes(struct userrec *u, int idx, char *par)
+static int cmd_fixcodes(user_t *u, int idx, char *par)
 {
   if (dcc[idx].status & STAT_ECHO) {
     dcc[idx].status |= STAT_TELNET;
@@ -1506,7 +1469,7 @@
   return(1);
 }
 
-static int cmd_page(struct userrec *u, int idx, char *par)
+static int cmd_page(user_t *u, int idx, char *par)
 {
   int a;
   module_entry *me;
@@ -1547,13 +1510,13 @@
   return(1);
 }
 
-static int cmd_module(struct userrec *u, int idx, char *par)
+static int cmd_module(user_t *u, int idx, char *par)
 {
   do_module_report(idx, 2, par[0] ? par : NULL);
   return(1);
 }
 
-static int cmd_loadmod(struct userrec *u, int idx, char *par)
+static int cmd_loadmod(user_t *u, int idx, char *par)
 {
   const char *p;
 
@@ -1575,7 +1538,7 @@
   return(1);
 }
 
-static int cmd_unloadmod(struct userrec *u, int idx, char *par)
+static int cmd_unloadmod(user_t *u, int idx, char *par)
 {
   char *p;
 
@@ -1596,7 +1559,7 @@
   return(1);
 }
 
-static int cmd_pls_ignore(struct userrec *u, int idx, char *par)
+static int cmd_pls_ignore(user_t *u, int idx, char *par)
 {
   char			*who;
   char			 s[UHOSTLEN];
@@ -1670,7 +1633,7 @@
   return(1);
 }
 
-static int cmd_mns_ignore(struct userrec *u, int idx, char *par)
+static int cmd_mns_ignore(user_t *u, int idx, char *par)
 {
   char buf[UHOSTLEN];
 
@@ -1686,13 +1649,13 @@
   return(1);
 }
 
-static int cmd_ignores(struct userrec *u, int idx, char *par)
+static int cmd_ignores(user_t *u, int idx, char *par)
 {
   tell_ignores(idx, par);
   return(1);
 }
 
-static int cmd_pls_user(struct userrec *u, int idx, char *par)
+static int cmd_pls_user(user_t *u, int idx, char *par)
 {
   char *handle, *host;
 
@@ -1718,11 +1681,11 @@
   return(1);
 }
 
-static int cmd_mns_user(struct userrec *u, int idx, char *par)
+static int cmd_mns_user(user_t *u, int idx, char *par)
 {
   int idx2;
   char *handle;
-  struct userrec *u2;
+  user_t *u2;
   module_entry *me;
 
   if (!par[0]) {
@@ -1773,10 +1736,10 @@
   return(1);
 }
 
-static int cmd_pls_host(struct userrec *u, int idx, char *par)
+static int cmd_pls_host(user_t *u, int idx, char *par)
 {
   char *handle, *host;
-  struct userrec *u2;
+  user_t *u2;
   struct list_type *q;
   struct flag_record fr = {FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
   module_entry *me;
@@ -1843,10 +1806,10 @@
   return(1);
 }
 
-static int cmd_mns_host(struct userrec *u, int idx, char *par)
+static int cmd_mns_host(user_t *u, int idx, char *par)
 {
   char *handle, *host;
-  struct userrec *u2;
+  user_t *u2;
   struct flag_record fr = {FR_CHAN | FR_ANYWH, 0, 0, 0, 0, 0};
   module_entry *me;
 
@@ -1906,7 +1869,7 @@
   return(1);
 }
 
-static int cmd_modules(struct userrec *u, int idx, char *par)
+static int cmd_modules(user_t *u, int idx, char *par)
 {
   module_entry *me;
 
@@ -1917,7 +1880,7 @@
   return(1);
 }
 
-static int cmd_traffic(struct userrec *u, int idx, char *par)
+static int cmd_traffic(user_t *u, int idx, char *par)
 {
   unsigned long itmp, itmp2;
 
@@ -2006,13 +1969,13 @@
   return traffictxt;
 }
 
-static int cmd_whoami(struct userrec *u, int idx, char *par)
+static int cmd_whoami(user_t *u, int idx, char *par)
 {
   dprintf(idx, _("You are %s@%s.\n"), dcc[idx].nick, botnetnick);
   return(1);
 }
 
-static int cmd_quit(struct userrec *u, int idx, char *text)
+static int cmd_quit(user_t *u, int idx, char *text)
 {
   dprintf(idx, _("*** Ja mata!\n"));
   flush_lines(idx, dcc[idx].u.chat);
Index: eggdrop1.7/src/core_binds.c
diff -u eggdrop1.7/src/core_binds.c:1.5 eggdrop1.7/src/core_binds.c:1.6
--- eggdrop1.7/src/core_binds.c:1.5	Sun May 26 03:34:13 2002
+++ eggdrop1.7/src/core_binds.c	Mon Oct  7 17:36:36 2002
@@ -20,7 +20,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: core_binds.c,v 1.5 2002/05/26 08:34:13 stdarg Exp $";
+static const char rcsid[] = "$Id: core_binds.c,v 1.6 2002/10/07 22:36:36 stdarg Exp $";
 #endif
 
 #include "main.h"
@@ -44,7 +44,6 @@
 	{0}
 };
 
-extern cmd_t C_dcc[];
 extern struct dcc_t *dcc;
 extern struct userrec *userlist;
 extern time_t now;
@@ -63,7 +62,7 @@
 	BT_disc = bind_table_add("disc", 1, "s", MATCH_MASK, BIND_STACKABLE);
 	BT_away = bind_table_add("away", 3, "sis", MATCH_MASK, BIND_STACKABLE);
 	BT_dcc = bind_table_add("dcc", 3, "Uis", MATCH_PARTIAL, BIND_USE_ATTR);
-	add_builtins("dcc", C_dcc);
+	//add_builtins("dcc", C_dcc);
 	BT_chat = bind_table_add("chat", 3, "sis", MATCH_MASK, BIND_STACKABLE | BIND_BREAKABLE);
 	BT_act = bind_table_add("act", 3, "sis", MATCH_MASK, BIND_STACKABLE);
 	BT_bcst = bind_table_add("bcst", 3, "sis", MATCH_MASK, BIND_STACKABLE);
Index: eggdrop1.7/src/dcc.c
diff -u eggdrop1.7/src/dcc.c:1.92 eggdrop1.7/src/dcc.c:1.93
--- eggdrop1.7/src/dcc.c:1.92	Fri Sep 20 16:41:49 2002
+++ eggdrop1.7/src/dcc.c	Mon Oct  7 17:36:36 2002
@@ -25,7 +25,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: dcc.c,v 1.92 2002/09/20 21:41:49 stdarg Exp $";
+static const char rcsid[] = "$Id: dcc.c,v 1.93 2002/10/07 22:36:36 stdarg Exp $";
 #endif
 
 #include "main.h"
@@ -42,8 +42,8 @@
 			   check_bind_chjn, check_bind_chon,
 			   check_bind_listen				*/
 #include "users.h"	/* match_ignore, addignore, get_user_by_host	*/
-#include "chanprog.h"	/* reaffirm_owners				*/
-#include "cmds.h"	/* check_dcc_attrs				*/
+//#include "chanprog.h"	/* reaffirm_owners				*/
+//#include "cmds.h"	/* check_dcc_attrs				*/
 #include "dccutil.h"	/* dprintf_eggdrop, lostdcc, chatout, 
 			   dcc_chatter, chanout_but, add_cr, not_away
 			   not_away, flush_lines, new_dcc,
@@ -870,11 +870,11 @@
       userlist = adduser(userlist, buf, work, "-",
 			 sanity_check(USER_PARTY | default_flags));
     }
-    reaffirm_owners();
+    //reaffirm_owners();
     dcc[idx].status = STAT_ECHO | STAT_TELNET;
     dcc[idx].type = &DCC_CHAT;	/* Just so next line will work */
     dcc[idx].user = get_user_by_handle(userlist, buf);
-    check_dcc_attrs(dcc[idx].user, USER_PARTY | default_flags);
+    //check_dcc_attrs(dcc[idx].user, USER_PARTY | default_flags);
     dcc[idx].type = &DCC_TELNET_PW;
     if (make_userfile) {
       dprintf(idx, _("\nYOU ARE THE MASTER/OWNER ON THIS BOT NOW\n"));
Index: eggdrop1.7/src/logfile.c
diff -u eggdrop1.7/src/logfile.c:1.22 eggdrop1.7/src/logfile.c:1.23
--- eggdrop1.7/src/logfile.c:1.22	Sun May 12 00:59:52 2002
+++ eggdrop1.7/src/logfile.c	Mon Oct  7 17:36:37 2002
@@ -21,11 +21,11 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: logfile.c,v 1.22 2002/05/12 05:59:52 stdarg Exp $";
+static const char rcsid[] = "$Id: logfile.c,v 1.23 2002/10/07 22:36:37 stdarg Exp $";
 #endif
 
 #include "main.h"
-#include "chanprog.h"			/* logmodes			*/
+//#include "chanprog.h"			/* logmodes			*/
 #include "modules.h" 			/* add_hook() 			*/
 #include "lib/egglib/msprintf.h"
 #include "logfile.h"			/* prototypes			*/
@@ -181,8 +181,9 @@
 {
 	int lev = 0;
 
-	lev = logmodes(level);
-	if (!lev) return(-1);
+	//lev = logmodes(level);
+	//if (!lev) return(-1);
+	lev = LOG_MISC;
 	return putlog(lev, chan, "%s", text);
 }
 
@@ -202,7 +203,8 @@
 	log->filename = strdup(fname);
 	log->chname = strdup(chan);
 	log->last_msg = strdup("");
-	log->mask = logmodes(modes);
+	log->mask = LOG_MISC;
+	//log->mask = logmodes(modes);
 	log->fp = fp;
 
 	log->next = log_list_head;
Index: eggdrop1.7/src/main.c
diff -u eggdrop1.7/src/main.c:1.123 eggdrop1.7/src/main.c:1.124
--- eggdrop1.7/src/main.c:1.123	Sat Sep 21 02:40:16 2002
+++ eggdrop1.7/src/main.c	Mon Oct  7 17:36:37 2002
@@ -30,7 +30,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: main.c,v 1.123 2002/09/21 07:40:16 stdarg Exp $";
+static const char rcsid[] = "$Id: main.c,v 1.124 2002/10/07 22:36:37 stdarg Exp $";
 #endif
 
 #include "main.h"
@@ -372,7 +372,7 @@
     check_expired_dcc();
     if (con_chan && !backgrd) {
       dprintf(DP_STDOUT, "\033[2J\033[1;1H");
-      tell_verbose_status(DP_STDOUT);
+      //tell_verbose_status(DP_STDOUT);
       do_module_report(DP_STDOUT, 0, "server");
       do_module_report(DP_STDOUT, 0, "channels");
     }
@@ -456,6 +456,7 @@
 void dns_init();
 void binds_init();
 void dcc_init();
+int user_init();
 
 void patch(const char *str)
 {
@@ -577,6 +578,8 @@
   script_init();
   script_net_init();
   binds_init();
+  user_init();
+  user_load("users.xml");
   modules_init();
   logfile_init();
   timer_init();
@@ -584,7 +587,7 @@
   egg_dns_init();
   core_binds_init();
   dcc_init();
-  user_init();
+  old_user_init();
   init_userent();
   init_net();
   traffic_init();
Index: eggdrop1.7/src/modules.c
diff -u eggdrop1.7/src/modules.c:1.119 eggdrop1.7/src/modules.c:1.120
--- eggdrop1.7/src/modules.c:1.119	Fri Sep 20 16:41:49 2002
+++ eggdrop1.7/src/modules.c	Mon Oct  7 17:36:37 2002
@@ -25,7 +25,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: modules.c,v 1.119 2002/09/20 21:41:49 stdarg Exp $";
+static const char rcsid[] = "$Id: modules.c,v 1.120 2002/10/07 22:36:37 stdarg Exp $";
 #endif
 
 #include "main.h"		/* NOTE: when removing this, include config.h */
@@ -40,7 +40,7 @@
 #include "chanprog.h"		/* clear_chanlist, reaffirm_owners, 
 				   logmodes, masktype, isowner, 
 				   clear_chanlist_member		*/
-#include "cmds.h"		/* check_dcc_attrs, check_dcc_chanattrs	*/
+//#include "cmds.h"		/* check_dcc_attrs, check_dcc_chanattrs	*/
 #include "dccutil.h"		/* chatout, chanout_but, new_dcc,
 				   lostdcc, makepass, flush_lines, 
 				   changeover_dcc			*/
@@ -90,7 +90,6 @@
 			DCC_CHAT; 
 #endif /* MAKING_MODS   */
 
-int cmd_die();
 int xtra_kill();
 int xtra_unpack();
 static int module_rename(char *name, char *newname);
@@ -332,7 +331,7 @@
   (Function) findanyidx,
   (Function) findchan,
   /* 132 - 135 */
-  (Function) cmd_die,
+  (Function) 0,
   (Function) days,
   (Function) daysago,
   (Function) daysdur,
@@ -425,9 +424,9 @@
   (Function) sub_lang,
   (Function) & online_since,	/* time_t *				*/
   (Function) 0,
-  (Function) check_dcc_attrs,
+  (Function) 0,
   /* 208 - 211 */
-  (Function) check_dcc_chanattrs,
+  (Function) 0,
   (Function) add_tcl_coups,
   (Function) rem_tcl_coups,
   (Function) &botname,
Index: eggdrop1.7/src/scriptnet.c
diff -u eggdrop1.7/src/scriptnet.c:1.2 eggdrop1.7/src/scriptnet.c:1.3
--- eggdrop1.7/src/scriptnet.c:1.2	Sun Sep 22 03:50:46 2002
+++ eggdrop1.7/src/scriptnet.c	Mon Oct  7 17:36:37 2002
@@ -41,6 +41,7 @@
 static int script_net_linemode(int idx, int onoff);
 static int script_net_handler(int idx, const char *event, script_callback_t *handler);
 static int script_net_info(script_var_t *retval, int idx, char *what);
+static int script_net_throttle_set(void *client_data, int idx, int speed);
 
 static script_command_t script_cmds[] = {
 	{"", "net_takeover", script_net_takeover, NULL, 1, "i", "idx", SCRIPT_INTEGER, 0},
@@ -50,6 +51,9 @@
 	{"", "net_handler", script_net_handler, NULL, 2, "isc", "idx event callback", SCRIPT_INTEGER, SCRIPT_VAR_ARGS},
 	{"", "net_linemode", script_net_linemode, NULL, 2, "ii", "idx on-off", SCRIPT_INTEGER, 0},
 	{"", "net_info", script_net_info, NULL, 2, "is", "idx what", 0, SCRIPT_PASS_RETVAL},
+	{"", "net_throttle", throttle_on, NULL, 1, "i", "idx", SCRIPT_INTEGER, 0},
+	{"", "net_throttle_in", script_net_throttle_set, (void *)0, 2, "ii", "idx speed", SCRIPT_INTEGER, SCRIPT_PASS_CDATA},
+	{"", "net_throttle_out", script_net_throttle_set, (void *)1, 2, "ii", "idx speed", SCRIPT_INTEGER, SCRIPT_PASS_CDATA},
 	{0}
 };
 
@@ -204,6 +208,11 @@
 	return(0);
 }
 
+static int script_net_throttle_set(void *client_data, int idx, int speed)
+{
+	return throttle_set(idx, (int) client_data, speed);
+}
+
 /* Sockbuf handler functions. */
 static int on_connect(void *client_data, int idx, const char *peer_ip, int peer_port)
 {
@@ -222,7 +231,7 @@
 	script_net_info_t *info = client_data;
 
 	if (info->on_eof) info->on_eof->callback(info->on_eof, idx, err, errmsg);
-	if (sockbuf_isvalid(idx)) sockbuf_delete(idx);
+	sockbuf_delete(idx);
 	return(0);
 }
 
Index: eggdrop1.7/src/tcl.c
diff -u eggdrop1.7/src/tcl.c:1.84 eggdrop1.7/src/tcl.c:1.85
--- eggdrop1.7/src/tcl.c:1.84	Fri Sep 20 16:41:49 2002
+++ eggdrop1.7/src/tcl.c	Mon Oct  7 17:36:37 2002
@@ -25,7 +25,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: tcl.c,v 1.84 2002/09/20 21:41:49 stdarg Exp $";
+static const char rcsid[] = "$Id: tcl.c,v 1.85 2002/10/07 22:36:37 stdarg Exp $";
 #endif
 
 #include <stdlib.h>		/* getenv()				*/
@@ -343,6 +343,7 @@
 extern tcl_cmds tcluser_cmds[], tcldcc_cmds[];
 extern script_command_t script_dcc_cmds[];
 extern script_command_t script_user_cmds[];
+extern script_command_t script_new_user_cmds[];
 extern script_command_t script_misc_cmds[];
 
 /* Not going through Tcl's crazy main() system (what on earth was he
@@ -397,6 +398,7 @@
   add_tcl_commands(tcluser_cmds);
   script_create_commands(script_dcc_cmds);
   script_create_commands(script_user_cmds);
+  script_create_commands(script_new_user_cmds);
   script_create_commands(script_misc_cmds);
 }
 
Index: eggdrop1.7/src/tcluser.c
diff -u eggdrop1.7/src/tcluser.c:1.43 eggdrop1.7/src/tcluser.c:1.44
--- eggdrop1.7/src/tcluser.c:1.43	Fri Sep 20 16:41:49 2002
+++ eggdrop1.7/src/tcluser.c	Mon Oct  7 17:36:37 2002
@@ -23,7 +23,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: tcluser.c,v 1.43 2002/09/20 21:41:49 stdarg Exp $";
+static const char rcsid[] = "$Id: tcluser.c,v 1.44 2002/10/07 22:36:37 stdarg Exp $";
 #endif
 
 #include "main.h"
@@ -50,8 +50,11 @@
 	return count_users(userlist);
 }
 
-static int script_validuser(struct userrec *u)
+static int script_validuser(char *handle)
 {
+	struct userrec *u;
+
+	u = get_user_by_handle(userlist, handle);
 	if (u) return(1);
 	return(0);
 }
@@ -415,7 +418,7 @@
 
 script_command_t script_user_cmds[] = {
 	{"", "countusers", script_countusers, NULL, 0, "", "", SCRIPT_INTEGER, 0},
-	{"", "validuser", script_validuser, NULL, 1, "U", "handle", SCRIPT_INTEGER, 0},
+	{"", "validuser", script_validuser, NULL, 1, "s", "handle", SCRIPT_INTEGER, 0},
 	{"", "finduser", (Function) script_finduser, NULL, 1, "s", "nick!user at host", SCRIPT_USER, 0},
 	{"", "passwdok", script_passwd_ok, NULL, 2, "Us", "handle password", SCRIPT_INTEGER, 0},
 	{"", "chattr", (Function) script_chattr_botattr, NULL, 1, "Uss", "handle ?changes ?channel??", SCRIPT_STRING, SCRIPT_PASS_CDATA|SCRIPT_VAR_ARGS},
Index: eggdrop1.7/src/users.c
diff -u eggdrop1.7/src/users.c:1.42 eggdrop1.7/src/users.c:1.43
--- eggdrop1.7/src/users.c:1.42	Fri Sep 20 16:41:49 2002
+++ eggdrop1.7/src/users.c	Mon Oct  7 17:36:37 2002
@@ -31,7 +31,7 @@
  */
 
 #ifndef lint
-static const char rcsid[] = "$Id: users.c,v 1.42 2002/09/20 21:41:49 stdarg Exp $";
+static const char rcsid[] = "$Id: users.c,v 1.43 2002/10/07 22:36:37 stdarg Exp $";
 #endif
 
 #include "main.h"
@@ -77,7 +77,7 @@
 	{0}
 };
 
-int user_init()
+int old_user_init()
 {
 	script_link_vars(user_script_vars);
 	return(0);
----------------------- End of diff -----------------------



More information about the Changes mailing list