diff -Nur src.orig/ftpd.c src/ftpd.c
--- src.orig/ftpd.c	2006-06-12 18:44:25.000000000 +0800
+++ src/ftpd.c	2006-09-11 14:33:30.885922891 +0800
@@ -405,6 +405,48 @@
     (void) title;
 }
 
+// add by twu2 20060612 begin
+// check local net in /etc/localnet
+static void check_local_net(const struct sockaddr_storage * const addr)
+{
+    FILE *fp;
+    unsigned long a1 = 0U;
+    unsigned long a2 = 0U;
+    unsigned long mask = 0U;
+    unsigned int b1, b2, b3, b4;
+    unsigned int m1, m2, m3, m4;
+    char buf[1024];
+
+    if (addr == NULL) return;
+    // only for IPV4 now
+    if (STORAGE_FAMILY(*addr) != AF_INET) return;
+    a1 = ntohl(STORAGE_SIN_ADDR(*addr));
+    fp = fopen("/etc/localnet", "rt");
+    // no localnet file
+    if (fp == NULL) return;
+    while (1) {
+        if (fgets(buf, 1024, fp) == NULL) break;
+        b1 = b2 = b3 = b4 = m1 = m2 = m3 = m4 = 0;
+        if ((sscanf(buf, "%u.%u.%u.%u/%u.%u.%u.%u", &b1, &b2, &b3, &b4, &m1, &m2, &m3, &m4) != 8) ||
+            b1 > 255U || b2 > 255U || b3 > 255U || b4 > 255U ||
+            (b1 | b2 | b3 | b4) == 0U ||
+            m1 > 255U || m2 > 255U || m3 > 255U || m4 > 255U ||
+            (m1 | m2 | m3 | m4) == 0U)
+            continue;
+        a2 = b1 << 24 | b2 << 16 | b3 << 8 | b4;
+        mask = m1 << 24 | m2 << 16 | m3 << 8 | m4;
+        // correct format
+        if ((a1 & mask) == (a2 & mask)) {
+            // same subnet
+            is_local = 1;
+            break;
+        }
+    }
+    fclose(fp);
+    return;
+}
+// add by twu2 20060612 end
+
 /* Check whether an address is valid, return 1 if ok, 0 otherwise.
  * Unfortunately, multicasting with the FTP protocol is impossible,
  * you have to use things like MTP instead. So prohibit multicast.
@@ -1531,6 +1573,31 @@
     return chdir(home);
 }
 
+// add by twu2 20080907 begin
+int is_no_bandwidth_user(char *username)
+{
+    FILE *fp;
+    char buf[1024];
+    char *p;
+    int match = 0;
+
+    if (username == NULL || *username == '\0') return 0;
+    fp = fopen("/etc/pure-ftpd/nobandwidth.user", "rt");
+    if (fp == NULL) return 0;
+    while (1) {
+        if (fgets(buf, 1024, fp) == NULL) break;
+        p = strtok(buf, " \t\r\n");
+        if (p == NULL) continue;
+        if (strcmp(p, username) == 0) {
+            match = 1;
+            break;
+        }
+    }
+    fclose(fp);
+    return match;
+}
+// add by twu2 20080907 end
+// add by twu2 20060612 begin
+int is_no_chroot_user(char *username)
+{
+    FILE *fp;
+    char buf[1024];
+    char *p;
+    int match = 0;
+
+    if (username == NULL || *username == '\0') return 0;
+    fp = fopen("/etc/pure-ftpd/nochroot.user", "rt");
+    if (fp == NULL) return 0;
+    while (1) {
+        if (fgets(buf, 1024, fp) == NULL) break;
+        p = strtok(buf, " \t\r\n");
+        if (p == NULL) continue;
+        if (strcmp(p, username) == 0) {
+            match = 1;
+            break;
+        }
+    }
+    fclose(fp);
+    return match;
+}
+// add by twu2 20060612 end
+
 void dopass(char *password)
 {
     static unsigned int tapping;    
@@ -1545,6 +1612,9 @@
 #ifdef WITH_RFC2640
     char *nwd = NULL;
 #endif
+// add by twu2 20060911 begin
+    int skip_chroot = 0;
+    int skip_bandwidth = 0;
+// add by twu2 20060911 end
     
     if (loggedin != 0) {
         if (guest != 0) {
@@ -1594,6 +1664,10 @@
         goto randomsleep;
     }
 
+// add by twu2 20060911 begin
+    skip_chroot = is_no_chroot_user(account);
+    skip_bandwidth = is_no_bandwidth_user(account);
+    if (is_local == 0 && skip_chroot == 0 && skip_bandwidth) {
+// add by twu2 200606911 end
 #ifdef PER_USER_LIMITS
     if (per_user_max > 0U && ftpwho_read_count(account) >= per_user_max) {
         addreply(421, MSG_PERUSER_MAX, (unsigned long) per_user_max);
@@ -1601,6 +1675,9 @@
         _EXIT(1);
     }
 #endif
+// add by twu2 20060911 begin
+    }
+// add by twu2 200606911 end
     
     /* Add username to the uid/name cache */
     (void) getname(authresult.uid);
@@ -1689,6 +1766,17 @@
     if (loggedin == 0) {
         candownload = 1;        /* real users can always download */
     }
+// add by twu2 20060911 begin
+    if (userchroot == 2 && skip_chroot) {
+	addreply_noformat(0, "You are not in CHROOT mode!");
+        userchroot = 0;
+	throttling = 0;
+    }
+    if (is_local) {
+	addreply_noformat(0, "You are from local network!");
+	throttling = 0;
+    }
+    if (skip_bandwidth)
+	throttling = 0;
+// add by twu2 200606911 end
 #ifdef THROTTLING
     if ((throttling == 2) || (guest != 0 && throttling == 1)) {
         addreply_noformat(0, MSG_BANDWIDTH_RESTRICTED);
@@ -2123,7 +2211,11 @@
     }
     switch (psvtype) {
     case 0:
-        if (STORAGE_FAMILY(force_passive_ip) == 0) {
+// add by twu2 20060612 begin
+        // if the connection from local subnet, don't do force passive ip convert
+        //if (STORAGE_FAMILY(force_passive_ip) == 0) {
+        if (is_local || STORAGE_FAMILY(force_passive_ip) == 0) {
+// add by twu2 20060612 end
             a = ntohl(STORAGE_SIN_ADDR(dataconn));
         } else if (STORAGE_FAMILY(force_passive_ip) == AF_INET6) {
             (void) close(datafd);
@@ -3438,14 +3530,14 @@
 # define FEAT_UTF8 ""
 #endif
     
-    char feat[] = FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV FEAT_ESTA FEAT_TLS FEAT_UTF8;
+    char feat[] = FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV FEAT_ESTA FEAT_UTF8 FEAT_TLS;
 
     if (disallow_passive != 0) {
-        feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP] = 0;
+        feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_UTF8 FEAT_TLS] = 0;
     }
 #ifndef MINIMAL
     else if (STORAGE_FAMILY(force_passive_ip) != 0) {
-        feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV] = 0;
+        feat[sizeof FEAT FEAT_DEBUG FEAT_TVFS FEAT_ESTP FEAT_PASV FEAT_UTF8 FEAT_TLS] = 0;
     }
 #endif
     addreply_noformat(0, feat);
@@ -4448,6 +4540,9 @@
         die(421, LOG_ERR, MSG_GETPEERNAME ": %s" , strerror(errno));
     }
     fourinsix(&peer);
+// add by twu2 20060612 begin
+    check_local_net(&peer);
+// add by twu2 20060612 end
     if (checkvalidaddr(&peer) == 0) {
         die(425, LOG_ERR, MSG_INVALID_IP);
     }
@@ -4486,6 +4581,9 @@
 #endif
     iptropize(&peer);
     logfile(LOG_INFO, MSG_NEW_CONNECTION, host);
+// add by twu2 20060612 begin
+    logfile(LOG_INFO, is_local == 1 ? "from local" : "from remote");
+// add by twu2 20060612 end
 
 #ifndef NO_BANNER
 # ifdef BORING_MODE
diff -Nur src.orig/globals.h src/globals.h
--- src.orig/globals.h	2006-02-15 16:55:00.000000000 +0800
+++ src/globals.h	2006-06-12 21:34:39.361685000 +0800
@@ -73,6 +73,9 @@
 GLOBAL0(signed char force_ls_a);
 GLOBAL0(struct sockaddr_storage peer);
 GLOBAL0(struct sockaddr_storage force_passive_ip);
+// add by twu2 20060612 begin
+GLOBAL(signed char is_local, 0);
+// add by twu2 20060612 end
 GLOBAL0(const char *force_passive_ip_s);
 GLOBAL0(unsigned short int peerdataport);
 GLOBAL0(double maxload);
