Send my address if no bind_address on IPCP
[l2tpns.git] / cli.c
diff --git a/cli.c b/cli.c
index 902add0..5725ea5 100644 (file)
--- a/cli.c
+++ b/cli.c
@@ -2,7 +2,7 @@
 // vim: sw=4 ts=8
 
 char const *cvs_name = "$Name:  $";
 // vim: sw=4 ts=8
 
 char const *cvs_name = "$Name:  $";
-char const *cvs_id_cli = "$Id: cli.c,v 1.6 2004-06-28 02:43:13 fred_nerk Exp $";
+char const *cvs_id_cli = "$Id: cli.c,v 1.10 2004-07-11 07:57:33 bodea Exp $";
 
 #include <stdio.h>
 #include <stdarg.h>
 
 #include <stdio.h>
 #include <stdarg.h>
@@ -39,15 +39,15 @@ extern ippoolt *ip_address_pool;
 extern struct Tstats *_statistics;
 struct cli_def *cli = NULL;
 int cli_quit = 0;
 extern struct Tstats *_statistics;
 struct cli_def *cli = NULL;
 int cli_quit = 0;
-extern int clifd, udpfd, tapfd, snoopfd, ifrfd, cluster_sockfd;
+extern int clifd, udpfd, tunfd, snoopfd, ifrfd, cluster_sockfd;
 extern int *radfds;
 extern int *radfds;
-extern sessionidt *cli_session_kill;
-extern tunnelidt *cli_tunnel_kill;
 extern struct configt *config;
 extern struct config_descriptt config_values[];
 #ifdef RINGBUFFER
 extern struct Tringbuffer *ringbuffer;
 #endif
 extern struct configt *config;
 extern struct config_descriptt config_values[];
 #ifdef RINGBUFFER
 extern struct Tringbuffer *ringbuffer;
 #endif
+extern struct cli_session_actions *cli_session_actions;
+extern struct cli_tunnel_actions *cli_tunnel_actions;
 
 char *debug_levels[] = {
     "CRIT",
 
 char *debug_levels[] = {
     "CRIT",
@@ -102,7 +102,7 @@ int cmd_remove_plugin(struct cli_def *cli, char *command, char **argv, int argc)
 int cmd_uptime(struct cli_def *cli, char *command, char **argv, int argc);
 int regular_stuff(struct cli_def *cli);
 
 int cmd_uptime(struct cli_def *cli, char *command, char **argv, int argc);
 int regular_stuff(struct cli_def *cli);
 
-void init_cli()
+void init_cli(char *hostname)
 {
     FILE *f;
     char buf[4096];
 {
     FILE *f;
     char buf[4096];
@@ -112,7 +112,10 @@ void init_cli()
     struct sockaddr_in addr;
 
     cli = cli_init();
     struct sockaddr_in addr;
 
     cli = cli_init();
-    cli_set_hostname(cli, "l2tpns");
+    if (hostname && *hostname)
+       cli_set_hostname(cli, hostname);
+    else
+       cli_set_hostname(cli, "l2tpns");
 
     c = cli_register_command(cli, NULL, "show", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
     cli_register_command(cli, c, "banana", cmd_show_banana, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a banana");
 
     c = cli_register_command(cli, NULL, "show", NULL, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, NULL);
     cli_register_command(cli, c, "banana", cmd_show_banana, PRIVILEGE_UNPRIVILEGED, MODE_EXEC, "Show a banana");
@@ -171,13 +174,13 @@ void init_cli()
     c = cli_register_command(cli, NULL, "restart", NULL, PRIVILEGE_PRIVILEGED, MODE_EXEC, NULL);
     cli_register_command(cli, c, "bgp", cmd_restart_bgp, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Restart BGP");
 
     c = cli_register_command(cli, NULL, "restart", NULL, PRIVILEGE_PRIVILEGED, MODE_EXEC, NULL);
     cli_register_command(cli, c, "bgp", cmd_restart_bgp, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Restart BGP");
 
-    c = cli_register_command(cli, NULL, "load", NULL, PRIVILEGE_PRIVILEGED, MODE_EXEC, NULL);
-    cli_register_command(cli, c, "plugin", cmd_load_plugin, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Load a plugin");
+    c = cli_register_command(cli, NULL, "load", NULL, PRIVILEGE_PRIVILEGED, MODE_CONFIG, NULL);
+    cli_register_command(cli, c, "plugin", cmd_load_plugin, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Load a plugin");
 
 
-    c = cli_register_command(cli, NULL, "remove", NULL, PRIVILEGE_PRIVILEGED, MODE_EXEC, NULL);
-    cli_register_command(cli, c, "plugin", cmd_remove_plugin, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Remove a plugin");
+    c = cli_register_command(cli, NULL, "remove", NULL, PRIVILEGE_PRIVILEGED, MODE_CONFIG, NULL);
+    cli_register_command(cli, c, "plugin", cmd_remove_plugin, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Remove a plugin");
 
 
-    cli_register_command(cli, NULL, "set", cmd_set, PRIVILEGE_PRIVILEGED, MODE_EXEC, "Set a configuration variable");
+    cli_register_command(cli, NULL, "set", cmd_set, PRIVILEGE_PRIVILEGED, MODE_CONFIG, "Set a configuration variable");
 
     // Enable regular processing
     cli_regular(cli, regular_stuff);
 
     // Enable regular processing
     cli_regular(cli, regular_stuff);
@@ -204,9 +207,9 @@ void init_cli()
            }
            else
            {
            }
            else
            {
-           cli_allow_user(cli, buf, p);
-           log(3, 0, 0, 0, "Allowing user %s to connect to the CLI\n", buf);
-       }
+               cli_allow_user(cli, buf, p);
+               log(3, 0, 0, 0, "Allowing user %s to connect to the CLI\n", buf);
+           }
        }
        fclose(f);
     }
        }
        fclose(f);
     }
@@ -262,7 +265,7 @@ void cli_do(int sockfd)
 
     // Close sockets
     if (udpfd) close(udpfd); udpfd = 0;
 
     // Close sockets
     if (udpfd) close(udpfd); udpfd = 0;
-    if (tapfd) close(tapfd); tapfd = 0;
+    if (tunfd) close(tunfd); tunfd = 0;
     if (snoopfd) close(snoopfd); snoopfd = 0;
     for (i = 0; i < config->num_radfds; i++)
        if (radfds[i]) close(radfds[i]);
     if (snoopfd) close(snoopfd); snoopfd = 0;
     for (i = 0; i < config->num_radfds; i++)
        if (radfds[i]) close(radfds[i]);
@@ -311,11 +314,7 @@ void cli_do(int sockfd)
     memset(&debug_flags, 0, sizeof(debug_flags));
     debug_flags.critical = 1;
 
     memset(&debug_flags, 0, sizeof(debug_flags));
     debug_flags.critical = 1;
 
-    {
-       char prompt[1005];
-       snprintf(prompt, 1005, "l2tpns> ");
-       cli_loop(cli, sockfd, prompt);
-    }
+    cli_loop(cli, sockfd);
 
     close(sockfd);
     log(3, 0, 0, 0, "Closed CLI connection\n");
 
     close(sockfd);
     log(3, 0, 0, 0, "Closed CLI connection\n");
@@ -331,7 +330,7 @@ void cli_do_file(FILE *fh)
 {
     log(3, 0, 0, 0, "Reading configuration file\n");
     cli_print_callback(cli, cli_print_log);
 {
     log(3, 0, 0, 0, "Reading configuration file\n");
     cli_print_callback(cli, cli_print_log);
-    cli_file(cli, fh, PRIVILEGE_PRIVILEGED);
+    cli_file(cli, fh, PRIVILEGE_PRIVILEGED, MODE_CONFIG);
     cli_print_callback(cli, NULL);
 }
 
     cli_print_callback(cli, NULL);
 }
 
@@ -374,7 +373,6 @@ int cli_arg_help(struct cli_def *cli, int cr_ok, char *entry, ...)
 int cmd_show_session(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i;
 int cmd_show_session(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i;
-    time_t time_now;
 
     if (CLI_HELP_REQUESTED)
        return cli_arg_help(cli, 1,
 
     if (CLI_HELP_REQUESTED)
        return cli_arg_help(cli, 1,
@@ -455,7 +453,7 @@ int cmd_show_session(struct cli_def *cli, char *command, char **argv, int argc)
                (unsigned long)session[i].total_cout,
                (unsigned long)session[i].total_cin,
                abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
                (unsigned long)session[i].total_cout,
                (unsigned long)session[i].total_cin,
                abs(time_now - (session[i].last_packet ? session[i].last_packet : time_now)),
-                tunnelip,
+               tunnelip,
                session[i].calling[0] ? session[i].calling : "*");
        if (userip) free(userip);
        if (tunnelip) free(tunnelip);
                session[i].calling[0] ? session[i].calling : "*");
        if (userip) free(userip);
        if (tunnelip) free(tunnelip);
@@ -466,7 +464,6 @@ int cmd_show_session(struct cli_def *cli, char *command, char **argv, int argc)
 int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i, x, show_all = 0;
 int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i, x, show_all = 0;
-    time_t time_now;
     char *states[] = {
        "Free",
        "Open",
     char *states[] = {
        "Free",
        "Open",
@@ -528,7 +525,7 @@ int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int argc)
     }
 
     // Show tunnel summary
     }
 
     // Show tunnel summary
-    cli_print(cli, "%s %s %s %s %s",
+    cli_print(cli, "%4s %20s %20s %6s %s",
            "TID",
            "Hostname",
            "IP",
            "TID",
            "Hostname",
            "IP",
@@ -540,7 +537,7 @@ int cmd_show_tunnels(struct cli_def *cli, char *command, char **argv, int argc)
        if (!show_all && (!tunnel[i].ip || tunnel[i].die || !tunnel[i].hostname[0])) continue;
 
        for (x = 0; x < MAXSESSION; x++) if (session[x].tunnel == i && session[x].opened && !session[x].die) sessions++;
        if (!show_all && (!tunnel[i].ip || tunnel[i].die || !tunnel[i].hostname[0])) continue;
 
        for (x = 0; x < MAXSESSION; x++) if (session[x].tunnel == i && session[x].opened && !session[x].die) sessions++;
-       cli_print(cli, "%d %s %s %s %d",
+       cli_print(cli, "%4d %20s %20s %6s %6d",
                i,
                *tunnel[i].hostname ? tunnel[i].hostname : "(null)",
                inet_toa(htonl(tunnel[i].ip)),
                i,
                *tunnel[i].hostname ? tunnel[i].hostname : "(null)",
                inet_toa(htonl(tunnel[i].ip)),
@@ -598,13 +595,13 @@ int cmd_show_counters(struct cli_def *cli, char *command, char **argv, int argc)
 
     cli_print(cli, "%-10s %-8s %-10s %-8s", "Ethernet", "Bytes", "Packets", "Errors");
     cli_print(cli, "%-10s %8lu %8lu %8lu", "RX",
 
     cli_print(cli, "%-10s %-8s %-10s %-8s", "Ethernet", "Bytes", "Packets", "Errors");
     cli_print(cli, "%-10s %8lu %8lu %8lu", "RX",
-           GET_STAT(tap_rx_bytes),
-           GET_STAT(tap_rx_packets),
-           GET_STAT(tap_rx_errors));
+           GET_STAT(tun_rx_bytes),
+           GET_STAT(tun_rx_packets),
+           GET_STAT(tun_rx_errors));
     cli_print(cli, "%-10s %8lu %8lu %8lu", "TX",
     cli_print(cli, "%-10s %8lu %8lu %8lu", "TX",
-           GET_STAT(tap_tx_bytes),
-           GET_STAT(tap_tx_packets),
-           GET_STAT(tap_tx_errors));
+           GET_STAT(tun_tx_bytes),
+           GET_STAT(tun_tx_packets),
+           GET_STAT(tun_tx_errors));
     cli_print(cli, "");
 
     cli_print(cli, "%-10s %-8s %-10s %-8s %-8s", "Tunnel", "Bytes", "Packets", "Errors", "Retries");
     cli_print(cli, "");
 
     cli_print(cli, "%-10s %-8s %-10s %-8s %-8s", "Tunnel", "Bytes", "Packets", "Errors", "Retries");
@@ -623,11 +620,7 @@ int cmd_show_counters(struct cli_def *cli, char *command, char **argv, int argc)
     cli_print(cli, "%-30s%-10s", "Counter", "Value");
     cli_print(cli, "-----------------------------------------");
     cli_print(cli, "%-30s%lu", "radius_retries",       GET_STAT(radius_retries));
     cli_print(cli, "%-30s%-10s", "Counter", "Value");
     cli_print(cli, "-----------------------------------------");
     cli_print(cli, "%-30s%lu", "radius_retries",       GET_STAT(radius_retries));
-    cli_print(cli, "%-30s%lu", "arp_errors",           GET_STAT(arp_errors));
-    cli_print(cli, "%-30s%lu", "arp_replies",          GET_STAT(arp_replies));
-    cli_print(cli, "%-30s%lu", "arp_discarded",                GET_STAT(arp_discarded));
     cli_print(cli, "%-30s%lu", "arp_sent",             GET_STAT(arp_sent));
     cli_print(cli, "%-30s%lu", "arp_sent",             GET_STAT(arp_sent));
-    cli_print(cli, "%-30s%lu", "arp_recv",             GET_STAT(arp_recv));
     cli_print(cli, "%-30s%lu", "packets_snooped",      GET_STAT(packets_snooped));
     cli_print(cli, "%-30s%lu", "tunnel_created",       GET_STAT(tunnel_created));
     cli_print(cli, "%-30s%lu", "session_created",      GET_STAT(session_created));
     cli_print(cli, "%-30s%lu", "packets_snooped",      GET_STAT(packets_snooped));
     cli_print(cli, "%-30s%lu", "tunnel_created",       GET_STAT(tunnel_created));
     cli_print(cli, "%-30s%lu", "session_created",      GET_STAT(session_created));
@@ -646,8 +639,7 @@ int cmd_show_counters(struct cli_def *cli, char *command, char **argv, int argc)
 #ifdef STATISTICS
     cli_print(cli, "\n%-30s%-10s", "Counter", "Value");
     cli_print(cli, "-----------------------------------------");
 #ifdef STATISTICS
     cli_print(cli, "\n%-30s%-10s", "Counter", "Value");
     cli_print(cli, "-----------------------------------------");
-    cli_print(cli, "%-30s%lu", "call_processtap",      GET_STAT(call_processtap));
-    cli_print(cli, "%-30s%lu", "call_processarp",      GET_STAT(call_processarp));
+    cli_print(cli, "%-30s%lu", "call_processtun",      GET_STAT(call_processtun));
     cli_print(cli, "%-30s%lu", "call_processipout",    GET_STAT(call_processipout));
     cli_print(cli, "%-30s%lu", "call_processudp",      GET_STAT(call_processudp));
     cli_print(cli, "%-30s%lu", "call_processpap",      GET_STAT(call_processpap));
     cli_print(cli, "%-30s%lu", "call_processipout",    GET_STAT(call_processipout));
     cli_print(cli, "%-30s%lu", "call_processudp",      GET_STAT(call_processudp));
     cli_print(cli, "%-30s%lu", "call_processpap",      GET_STAT(call_processpap));
@@ -753,7 +745,6 @@ int cmd_show_pool(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i;
     int used = 0, free = 0, show_all = 0;
 {
     int i;
     int used = 0, free = 0, show_all = 0;
-    time_t time_now;
 
     if (!config->cluster_iam_master)
     {
 
     if (!config->cluster_iam_master)
     {
@@ -873,6 +864,7 @@ int cmd_show_run(struct cli_def *cli, char *command, char **argv, int argc)
 
 int cmd_show_radius(struct cli_def *cli, char *command, char **argv, int argc)
 {
 
 int cmd_show_radius(struct cli_def *cli, char *command, char **argv, int argc)
 {
+    int i, free = 0, used = 0, show_all = 0;
     char *states[] = {
        "NULL",
        "CHAP",
     char *states[] = {
        "NULL",
        "CHAP",
@@ -882,8 +874,6 @@ int cmd_show_radius(struct cli_def *cli, char *command, char **argv, int argc)
        "STOP",
        "WAIT",
     };
        "STOP",
        "WAIT",
     };
-    int i, free = 0, used = 0, show_all = 0;
-    time_t time_now;
 
     if (CLI_HELP_REQUESTED)
     {
 
     if (CLI_HELP_REQUESTED)
     {
@@ -1009,9 +999,10 @@ int cmd_drop_user(struct cli_def *cli, char *command, char **argv, int argc)
 
     if (!config->cluster_iam_master)
     {
 
     if (!config->cluster_iam_master)
     {
-       cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
+       cli_print(cli, "Can't do this on a slave.  Do it on %s", inet_toa(config->cluster_master_address));
        return CLI_OK;
     }
        return CLI_OK;
     }
+
     if (!argc)
     {
        cli_print(cli, "Specify a user to drop");
     if (!argc)
     {
        cli_print(cli, "Specify a user to drop");
@@ -1028,17 +1019,8 @@ int cmd_drop_user(struct cli_def *cli, char *command, char **argv, int argc)
 
        if (session[s].ip && session[s].opened && !session[s].die)
        {
 
        if (session[s].ip && session[s].opened && !session[s].die)
        {
-           int x;
-
            cli_print(cli, "Dropping user %s", session[s].user);
            cli_print(cli, "Dropping user %s", session[s].user);
-           for (x = 0; x < MAXSESSION; x++)
-           {
-               if (!cli_session_kill[x])
-               {
-                   cli_session_kill[x] = s;
-                   break;
-               }
-           }
+           cli_session_actions[s].action |= CLI_SESS_KILL;
        }
     }
 
        }
     }
 
@@ -1048,7 +1030,7 @@ int cmd_drop_user(struct cli_def *cli, char *command, char **argv, int argc)
 int cmd_drop_tunnel(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i;
 int cmd_drop_tunnel(struct cli_def *cli, char *command, char **argv, int argc)
 {
     int i;
-    tunnelidt tid;
+    tunnelidt t;
 
     if (CLI_HELP_REQUESTED)
        return cli_arg_help(cli, argc > 1,
 
     if (CLI_HELP_REQUESTED)
        return cli_arg_help(cli, argc > 1,
@@ -1056,9 +1038,10 @@ int cmd_drop_tunnel(struct cli_def *cli, char *command, char **argv, int argc)
 
     if (!config->cluster_iam_master)
     {
 
     if (!config->cluster_iam_master)
     {
-       cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
+       cli_print(cli, "Can't do this on a slave.  Do it on %s", inet_toa(config->cluster_master_address));
        return CLI_OK;
     }
        return CLI_OK;
     }
+
     if (!argc)
     {
        cli_print(cli, "Specify a tunnel to drop");
     if (!argc)
     {
        cli_print(cli, "Specify a tunnel to drop");
@@ -1067,35 +1050,26 @@ int cmd_drop_tunnel(struct cli_def *cli, char *command, char **argv, int argc)
 
     for (i = 0; i < argc; i++)
     {
 
     for (i = 0; i < argc; i++)
     {
-       int x;
-
-       if ((tid = atol(argv[i])) <= 0 || (tid >= MAXTUNNEL))
+       if ((t = atol(argv[i])) <= 0 || (t >= MAXTUNNEL))
        {
            cli_print(cli, "Invalid tunnel ID (1-%d)", MAXTUNNEL-1);
            continue;
        }
 
        {
            cli_print(cli, "Invalid tunnel ID (1-%d)", MAXTUNNEL-1);
            continue;
        }
 
-       if (!tunnel[tid].ip)
+       if (!tunnel[t].ip)
        {
        {
-           cli_print(cli, "Tunnel %d is not connected", tid);
+           cli_print(cli, "Tunnel %d is not connected", t);
            continue;
        }
 
            continue;
        }
 
-       if (tunnel[tid].die)
+       if (tunnel[t].die)
        {
        {
-           cli_print(cli, "Tunnel %d is already being shut down", tid);
+           cli_print(cli, "Tunnel %d is already being shut down", t);
            continue;
        }
 
            continue;
        }
 
-       for (x = 0; x < MAXTUNNEL; x++)
-       {
-           if (!cli_tunnel_kill[x])
-           {
-               cli_tunnel_kill[x] = tid;
-               cli_print(cli, "Tunnel %d shut down (%s)", tid, tunnel[tid].hostname);
-               break;
-           }
-       }
+       cli_print(cli, "Tunnel %d shut down (%s)", t, tunnel[t].hostname);
+       cli_tunnel_actions[t].action |= CLI_TUN_KILL;
     }
 
     return CLI_OK;
     }
 
     return CLI_OK;
@@ -1112,9 +1086,10 @@ int cmd_drop_session(struct cli_def *cli, char *command, char **argv, int argc)
 
     if (!config->cluster_iam_master)
     {
 
     if (!config->cluster_iam_master)
     {
-       cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
+       cli_print(cli, "Can't do this on a slave.  Do it on %s", inet_toa(config->cluster_master_address));
        return CLI_OK;
     }
        return CLI_OK;
     }
+
     if (!argc)
     {
        cli_print(cli, "Specify a session id to drop");
     if (!argc)
     {
        cli_print(cli, "Specify a session id to drop");
@@ -1129,18 +1104,10 @@ int cmd_drop_session(struct cli_def *cli, char *command, char **argv, int argc)
            continue;
        }
 
            continue;
        }
 
-       if (session[s].opened && !session[s].die)
+       if (session[s].ip && session[s].opened && !session[s].die)
        {
        {
-           int x;
-           for (x = 0; x < MAXSESSION; x++)
-           {
-               if (!cli_session_kill[x])
-               {
-                   cli_session_kill[x] = s;
-                   break;
-               }
-           }
            cli_print(cli, "Dropping session %d", s);
            cli_print(cli, "Dropping session %d", s);
+           cli_session_actions[s].action |= CLI_SESS_KILL;
        }
        else
        {
        }
        else
        {
@@ -1214,10 +1181,11 @@ int cmd_snoop(struct cli_def *cli, char *command, char **argv, int argc)
        return CLI_OK;
     }
 
        return CLI_OK;
     }
 
-    session[s].snoop_ip = ip;
-    session[s].snoop_port = port;
-
     cli_print(cli, "Snooping user %s to %s:%d", argv[0], inet_toa(session[s].snoop_ip), session[s].snoop_port);
     cli_print(cli, "Snooping user %s to %s:%d", argv[0], inet_toa(session[s].snoop_ip), session[s].snoop_port);
+    cli_session_actions[s].snoop_ip = ip;
+    cli_session_actions[s].snoop_port = port;
+    cli_session_actions[s].action |= CLI_SESS_SNOOP;
+
     return CLI_OK;
 }
 
     return CLI_OK;
 }
 
@@ -1232,7 +1200,7 @@ int cmd_no_snoop(struct cli_def *cli, char *command, char **argv, int argc)
 
     if (!config->cluster_iam_master)
     {
 
     if (!config->cluster_iam_master)
     {
-       cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
+       cli_print(cli, "Can't do this on a slave.  Do it on %s", inet_toa(config->cluster_master_address));
        return CLI_OK;
     }
 
        return CLI_OK;
     }
 
@@ -1249,10 +1217,9 @@ int cmd_no_snoop(struct cli_def *cli, char *command, char **argv, int argc)
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
-       session[s].snoop_ip = 0;
-       session[s].snoop_port = 0;
 
        cli_print(cli, "Not snooping user %s", argv[i]);
 
        cli_print(cli, "Not snooping user %s", argv[i]);
+       cli_session_actions[s].action |= CLI_SESS_NOSNOOP;
     }
     return CLI_OK;
 }
     }
     return CLI_OK;
 }
@@ -1268,9 +1235,10 @@ int cmd_throttle(struct cli_def *cli, char *command, char **argv, int argc)
 
     if (!config->cluster_iam_master)
     {
 
     if (!config->cluster_iam_master)
     {
-       cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
+       cli_print(cli, "Can't do this on a slave.  Do it on %s", inet_toa(config->cluster_master_address));
        return CLI_OK;
     }
        return CLI_OK;
     }
+
     if (!argc)
     {
        cli_print(cli, "Specify a user");
     if (!argc)
     {
        cli_print(cli, "Specify a user");
@@ -1284,11 +1252,18 @@ int cmd_throttle(struct cli_def *cli, char *command, char **argv, int argc)
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
-       if (!throttle_session(s, config->rl_rate))
-           cli_print(cli, "Error throttling %s", argv[i]);
-       else
-           cli_print(cli, "Throttling user %s", argv[i]);
+
+       if (session[s].throttle)
+       {
+           cli_print(cli, "User %s already throttled", argv[i]);
+           continue;
+       }
+
+       cli_print(cli, "Throttling user %s", argv[i]);
+       cli_session_actions[s].throttle = config->rl_rate; // could be configurable at some stage
+       cli_session_actions[s].action |= CLI_SESS_THROTTLE;
     }
     }
+
     return CLI_OK;
 }
 
     return CLI_OK;
 }
 
@@ -1303,9 +1278,10 @@ int cmd_no_throttle(struct cli_def *cli, char *command, char **argv, int argc)
 
     if (!config->cluster_iam_master)
     {
 
     if (!config->cluster_iam_master)
     {
-       cli_print(cli, "Can't do this on a slave. Do it on %s", inet_toa(config->cluster_master_address));
+       cli_print(cli, "Can't do this on a slave.  Do it on %s", inet_toa(config->cluster_master_address));
        return CLI_OK;
     }
        return CLI_OK;
     }
+
     if (!argc)
     {
        cli_print(cli, "Specify a user");
     if (!argc)
     {
        cli_print(cli, "Specify a user");
@@ -1319,9 +1295,15 @@ int cmd_no_throttle(struct cli_def *cli, char *command, char **argv, int argc)
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
            cli_print(cli, "User %s is not connected", argv[i]);
            continue;
        }
-       throttle_session(s, 0);
+
+       if (!session[s].throttle)
+       {
+           cli_print(cli, "User %s not throttled", argv[i]);
+           continue;
+       }
 
        cli_print(cli, "Unthrottling user %s", argv[i]);
 
        cli_print(cli, "Unthrottling user %s", argv[i]);
+       cli_session_actions[s].action |= CLI_SESS_NOTHROTTLE;
     }
 
     return CLI_OK;
     }
 
     return CLI_OK;
@@ -1346,9 +1328,9 @@ int cmd_debug(struct cli_def *cli, char *command, char **argv, int argc)
     {
        char *p = (char *) &debug_flags;
        for (i = 0; i < sizeof(debug_flags); i++)
     {
        char *p = (char *) &debug_flags;
        for (i = 0; i < sizeof(debug_flags); i++)
-    {
-           if (p[i])
        {
        {
+           if (p[i])
+           {
                cli_print(cli, "Currently debugging:%s%s%s%s%s%s",
                    (debug_flags.critical) ? " critical" : "",
                    (debug_flags.error)    ? " error"    : "",
                cli_print(cli, "Currently debugging:%s%s%s%s%s%s",
                    (debug_flags.critical) ? " critical" : "",
                    (debug_flags.error)    ? " error"    : "",
@@ -1357,9 +1339,9 @@ int cmd_debug(struct cli_def *cli, char *command, char **argv, int argc)
                    (debug_flags.calls)    ? " calls"    : "",
                    (debug_flags.data)     ? " data"     : "");
 
                    (debug_flags.calls)    ? " calls"    : "",
                    (debug_flags.data)     ? " data"     : "");
 
-           return CLI_OK;
+               return CLI_OK;
+           }
        }
        }
-    }
 
        cli_print(cli, "Debugging off");
        return CLI_OK;
 
        cli_print(cli, "Debugging off");
        return CLI_OK;
@@ -1538,7 +1520,6 @@ int cmd_uptime(struct cli_def *cli, char *command, char **argv, int argc)
     FILE *fh;
     char buf[100], *p = buf, *loads[3];
     int i, num_sessions = 0;
     FILE *fh;
     char buf[100], *p = buf, *loads[3];
     int i, num_sessions = 0;
-    time_t time_now;
 
     if (CLI_HELP_REQUESTED)
        return CLI_HELP_NO_ARGS;
 
     if (CLI_HELP_REQUESTED)
        return CLI_HELP_NO_ARGS;