diff -r -u wu-ftpd.orig/src/ftpd.c wu-ftpd/src/ftpd.c
--- wu-ftpd.orig/src/ftpd.c	2002-04-09 09:24:28.000000000 -0400
+++ wu-ftpd/src/ftpd.c	2003-02-06 17:37:08.000000000 -0500
@@ -243,6 +243,10 @@
 extern off_t restart_point;
 extern int yyerrorcalled;
 
+/*SG  For change later in the code see *SG tag
+  S. Goulart   5 fev 2003 */
+extern void load_timeouts(void);
+
 struct SOCKSTORAGE ctrl_addr;
 struct SOCKSTORAGE data_source;
 struct SOCKSTORAGE data_dest;
@@ -1172,6 +1176,11 @@
 #endif /* defined(HAVE_LIBRESOLV) */ 
 
     dolog(&his_addr);
+
+/*SG   Call the load_timeout() again to setup class based
+       timeouts.    S. Goulart    5 fev 2003 */
+    load_timeouts();
+
     /* Set up default state */
     data = -1;
     type = TYPE_A;
diff -r -u wu-ftpd.orig/src/timeout.c wu-ftpd/src/timeout.c
--- wu-ftpd.orig/src/timeout.c	2001-08-22 12:22:57.000000000 -0400
+++ wu-ftpd/src/timeout.c	2003-02-07 09:41:06.000000000 -0500
@@ -33,6 +33,11 @@
 
 #include "extensions.h"
 
+/*SG   Need these 3 next lines for SYSLOG.  S. Goulart  */
+#include <syslog.h>
+extern char *remoteident;
+extern int debug;
+
 unsigned int timeout_idle = 900;	/* Command idle: 15 minutes */
 unsigned int timeout_maxidle = 7200;	/* Command idle (MAX): 2 hours */
 unsigned int timeout_data = 1200;	/* Data idle: 20 minutes */
@@ -40,31 +45,126 @@
 unsigned int timeout_accept = 120;	/* Accepting data connection: 2 minutes */
 unsigned int timeout_connect = 120;	/* Establishing data connection: 2 minutes */
 
+
+
+/*SG  
+  Procedure load_timeout is called twice:
+  1.  (originaly)  In access_init() for class less timeouts
+  2.  (new)  In ftpc.c for class based timeouts (overrides)
+
+Basically the lines:
+
+	timeout_xxxx = value;
+
+are replaced with:
+
+        if (ARG2 == NULL) {
+            if (!is_xxx) timeout_xxxx = value;
+        } else if (strcasecmp(ARG2, class) == 0)
+            timeout_xxxx = value;
+        }
+
+the code construct below was causing SIGfaults:
+
+	if ((ARG2 == NULL) && (!is_xxx))
+	    timeout_xxxxx = value;
+
+so was changed to:
+
+	if (ARG2 == NULL) {
+	    if (!is_xxx) timeout_xxxxx = value;
+	}
+
+S. Goulart   5 fev 2003
+*/
+
 void load_timeouts(void)
 {
     struct aclmember *entry = NULL;
+
+/*SG Start other class based additions */
+/*  is_idl means 'is idle class set?'  */
+
+    char class[1024];
+    int  is_idl = 0,
+         is_rfc = 0,
+         is_max = 0,
+         is_dat = 0,
+         is_acc = 0,
+         is_con = 0;
+
+/*SG New call */
+    (void) acl_getclass(class);
+/*SG End additions */
+
+/*SG  start For SYSLOG ....  */
+    if (debug)
+        syslog(LOG_INFO, "host class is <%s> for %s",
+           class, remoteident);
+/*SG  end SYSLOG ....  */
+
     while (getaclentry("timeout", &entry)) {
 	if ((ARG0 != NULL) && (ARG1 != NULL)) {
 	    unsigned long value = strtoul(ARG1, NULL, 0);
-	    if (strcasecmp(ARG0, "rfc931") == 0)
-		timeout_rfc931 = value;
+	    if (strcasecmp(ARG0, "rfc931") == 0) {
+		if (ARG2 == NULL) {
+		    if (!is_rfc) timeout_rfc931 = value;
+		}
+		else if (strcasecmp(ARG2, class) == 0) {
+		    timeout_rfc931 = value;
+		    is_rfc = 1;
+		}
+	    }
 	    else if (value > 0) {
 		if (strcasecmp(ARG0, "idle") == 0) {
-		    timeout_idle = value;
+		    if (ARG2 == NULL) {
+			if (!is_idl) timeout_idle = value;
+		    }
+		    else if (strcasecmp(ARG2, class) == 0) {
+		        timeout_idle = value;
+			is_idl = 1;
+		    }
 		    if (timeout_maxidle < timeout_idle)
 			timeout_maxidle = timeout_idle;
 		}
 		else if (strcasecmp(ARG0, "maxidle") == 0) {
-		    timeout_maxidle = value;
+		    if (ARG2 == NULL) {
+			if (!is_max) timeout_maxidle = value;
+		    }
+		    else if (strcasecmp(ARG2, class) == 0) {
+			timeout_maxidle = value;
+			is_max = 1;
+		    }
 		    if (timeout_idle > timeout_maxidle)
 			timeout_idle = timeout_maxidle;
 		}
-		else if (strcasecmp(ARG0, "data") == 0)
-		    timeout_data = value;
-		else if (strcasecmp(ARG0, "accept") == 0)
-		    timeout_accept = value;
-		else if (strcasecmp(ARG0, "connect") == 0)
-		    timeout_connect = value;
+		else if (strcasecmp(ARG0, "data") == 0) {
+		    if (ARG2 == NULL) {
+			if (!is_dat) timeout_data = value;
+		    }
+		    else if (strcasecmp(ARG2, class) == 0) {
+			timeout_data = value;
+			is_dat = 1;
+		    }
+		}
+		else if (strcasecmp(ARG0, "accept") == 0) {
+		    if (ARG2 == NULL) {
+			if (!is_acc) timeout_accept = value;
+		    }
+		    else if (strcasecmp(ARG2, class) == 0) {
+			timeout_accept = value;
+			is_acc = 1;
+		    }
+		}
+		else if (strcasecmp(ARG0, "connect") == 0) {
+		    if (ARG2 == NULL) {
+			if (!is_con) timeout_connect = value;
+		    }
+		    else if (strcasecmp(ARG2, class) == 0) {
+			timeout_connect = value;
+			is_con = 1;
+		    }
+		}
 	    }
 	}
     }
