]> git.sur5r.net Git - ngadmin/commitdiff
CLI: added the possibility to interrupt hanging commands with CTRL+C.
authordarkcoven <admin@darkcoven.tk>
Sun, 25 Dec 2011 11:00:00 +0000 (12:00 +0100)
committerdarkcoven <admin@darkcoven.tk>
Sat, 29 Dec 2012 22:40:00 +0000 (23:40 +0100)
CLI: added the possiblity to enter password without displaying it.
CLI: added help command.
Lib: added check on packet extraction.

cli/admin.c
cli/com_help.c [new file with mode: 0644]
cli/com_password.c
cli/commands.c
cli/common.h
lib/src/network.c
lib/src/network.h
lib/src/protocol.c
lib/src/protocol.h

index beb40f22192c9c8768735fb36028c0890279626c..eddbf83b797179367d405b72a88757458e7d8536 100644 (file)
@@ -1,5 +1,7 @@
 
 #include <stdio.h>
+#include <signal.h>
+#include <setjmp.h>
 
 #include <getopt.h>
 #include <readline/readline.h>
@@ -121,6 +123,39 @@ char** my_completion (const char *text, int start, int end UNUSED) {
 
 
 
+static struct ngadmin *nga=NULL;
+static sigjmp_buf jmpbuf;
+struct termios orig_term, current_term;
+
+
+
+NORET static void handler (int sig) {
+ switch ( sig ) {
+  
+  case SIGTERM:
+  case SIGINT:
+   printf("interrupt\n");
+  
+   current_term.c_lflag|=ECHO;
+   tcsetattr(STDIN_FILENO, TCSANOW, &current_term);
+   
+   siglongjmp(jmpbuf, 1);
+  
+  default:
+   ngadmin_close(nga);
+   
+   tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
+   
+   exit(0);
+  
+ }
+}
+
+
 
 int main (int argc, char **argv) {
  
@@ -137,7 +172,6 @@ int main (int argc, char **argv) {
  const char *iface="eth0";
  float timeout=0.f;
  bool kb=false, force=false, global=false;
- struct ngadmin *nga=NULL;
  struct timeval tv;
  const struct TreeNode *cur, *next;
  int i, n;
@@ -212,12 +246,27 @@ int main (int argc, char **argv) {
  if ( global && ngadmin_useGlobalBroadcast(nga, true)!=ERR_OK ) goto end;
  
  
  //rl_bind_key('\t', rl_abort); // disable auto completion
  //rl_bind_key('\t', rl_complete); // enable auto-complete
  rl_attempted_completion_function=my_completion;
  rl_completion_entry_function=my_generator;
  
  
+ tcgetattr(STDIN_FILENO, &orig_term);
+ current_term=orig_term;
+ /*
+ current_term.c_lflag&=~ECHOCTL;
+ tcsetattr(STDIN_FILENO, TCSANOW, &current_term);
+ */
+ signal(SIGTERM, handler);
+ signal(SIGINT, handler);
+ sigsetjmp(jmpbuf, 1);
  while ( cont ) {
   
   if ( (line=readline("> "))==NULL ) goto end;
@@ -274,10 +323,7 @@ int main (int argc, char **argv) {
  
  
  end:
- ngadmin_close(nga);
- return 0;
+ handler(0);
  
 }
 
diff --git a/cli/com_help.c b/cli/com_help.c
new file mode 100644 (file)
index 0000000..5bf84ee
--- /dev/null
@@ -0,0 +1,26 @@
+
+#include "commands.h"
+
+
+
+
+bool do_help (int nb UNUSED, const char **com UNUSED, struct ngadmin *nga UNUSED) {
+ const struct TreeNode *s;
+ printf("Available commands: \n");
+ for (s=coms.sub; s->name!=NULL; ++s) {
+  printf("%s ", s->name);
+ }
+ putchar('\n');
+ return true;
+}
+
+
+
+
index f93412ef79ae82219b68c134757571b29ece58fb..92e96c6067c22c61c8ad2cb89351aa4564fe0a4a 100644 (file)
@@ -32,15 +32,36 @@ bool do_password_change (int nb, const char **com, struct ngadmin *nga) {
 bool do_password_set (int nb, const char **com, struct ngadmin *nga) {
  
  int i;
+ char buf[64];
+ const char *pass;
  
  
- if ( nb!=1 ) {
-  printf("Usage: password set <value>\n");
+ if ( nb>1 ) {
+  printf("Usage: password set [<value>]\n");
   return false;
  }
  
- i=ngadmin_setPassword(nga, com[0]);
- printErrCode(i);
+ if ( nb==0 ) {
+  printf("Enter password: ");
+  fflush(stdout);
+  current_term.c_lflag&=~ECHO;
+  tcsetattr(STDIN_FILENO, TCSANOW, &current_term);
+  pass=fgets(buf, sizeof(buf), stdin);
+  trim(buf, strlen(buf));
+  current_term.c_lflag|=ECHO;
+  tcsetattr(STDIN_FILENO, TCSANOW, &current_term);
+  putchar('\n');
+ } else {
+  pass=com[0];
+ }
+ if ( pass!=NULL ) {
+  i=ngadmin_setPassword(nga, pass);
+  printErrCode(i);
+ }
  
  
  return true;
index 2d5e9cc643e8f58e3fb579d79503ede3be796ccf..df13a580af0f1a966ce0a52492fcf08ae6b1006b 100644 (file)
@@ -22,6 +22,10 @@ bool do_firmware_show (int nb, const char **com, struct ngadmin *nga);
 bool do_firmware_upgrade (int nb, const char **com, struct ngadmin *nga);
 
 
+// help
+bool do_help (int nb, const char **com, struct ngadmin *nga);
+
+
 // igmp
 bool do_igmp_set (int nb, const char **com, struct ngadmin *nga);
 bool do_igmp_show (int nb, const char **com, struct ngadmin *nga);
@@ -119,6 +123,8 @@ COM_ROOT_START(coms)
   COM_TERM(upgrade, do_firmware_upgrade, true)
  COM_END
  
+ COM_TERM(help, do_help, false)
  COM_START(igmp)
   COM_TERM(set, do_igmp_set, true)
   COM_TERM(show, do_igmp_show, false)
index d74697766048d7883c89c463fe28b75e1bfca763..c0e6cb81ecac5615c1dc068d8f6804a63b116eab 100644 (file)
@@ -6,15 +6,19 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
+#include <termios.h>
+#include <unistd.h>
 
 #include <ngadmin.h>
 
 
-#define UNUSED                         __attribute__((unused))
+#define UNUSED                 __attribute__((unused))
+#define NORET                  __attribute__((noreturn))
 
 
 
 extern int cont;
+extern struct termios current_term;
 
 
 extern const char *bitrates[], *prio[];
index d548b58edccc6c7f2dffbe405caa3451e790977c..4f4b3ffd824c60be94835048c43e8d0af7c8b080 100644 (file)
@@ -191,6 +191,38 @@ int sendNgPacket (struct ngadmin *nga, char code, const List *attr) {
 }
 
 
+/*
+static int my_poll (struct pollfd *fds, nfds_t nfds, struct timeval *timeout) {
+ int ret, rem=-1;
+ struct timeval start, stop;
+ if ( timeout!=NULL ) {
+  if ( timeout->tv_sec<0 || timeout->tv_usec<0 ) rem=0;
+  else rem=timeout->tv_sec*1000+timeout->tv_usec/1000;
+ }
+ gettimeofday(&start, NULL);
+ ret=poll(fds, nfds, rem);
+ gettimeofday(&stop, NULL);
+ if ( timeout!=NULL ) {
+  rem-=(stop.tv_sec-start.tv_sec)*1000+(stop.tv_usec-start.tv_usec)/1000;
+  if ( ret<=0 || rem<0 ) rem=0;
+  printf("tv_sec = %i, tv_usec = %i\n", start.tv_sec, start.tv_usec);
+  printf("tv_sec = %i, tv_usec = %i\n", stop.tv_sec, stop.tv_usec);
+  printf("rem = %i\n", rem);
+  timeout->tv_sec=rem/1000;
+  timeout->tv_usec=(rem%1000)*1000;
+ }
+ return ret;
+}
+*/
+
 
 // ------------------------------------------------------------------------------------------------------------
 int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned short *attr_error, List *attr) {
@@ -200,29 +232,45 @@ int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned
  struct sockaddr_in remote;
  socklen_t slen=sizeof(struct sockaddr_in);
  const struct swi_attr *sa=nga->current;
- int len;
+ struct timeval rem;
+ //struct pollfd fds;
+ fd_set fs;
+ int len=-1;
  
  
  np.buffer=buffer;
- np.maxlen=sizeof(buffer);
  
  memset(&remote, 0, sizeof(struct sockaddr_in));
  remote.sin_family=AF_INET;
  
+ rem=nga->timeout;
+ //fds.fd=nga->sock;
+ //fds.events=POLLIN;
  while ( 1 ) {
   
-  len=recvfrom(nga->sock, buffer, sizeof(buffer), 0, (struct sockaddr*)&remote, &slen);
+  //my_poll(&fds, 1, &rem);
+  FD_ZERO(&fs);
+  FD_SET(nga->sock, &fs);
+  select(nga->sock+1, &fs, NULL, NULL, &rem);
   
-  if ( len<0 ) {
-   break;
-  }
+  len=recvfrom(nga->sock, buffer, sizeof(buffer), MSG_DONTWAIT, (struct sockaddr*)&remote, &slen);
   
-  if ( ntohs(remote.sin_port)==SWITCH_PORT && len>=(int)sizeof(struct ng_header) && validateNgHeader(np.nh, code, &nga->localmac, sa==NULL ? NULL : &sa->mac , nga->seq) ) {
-   initNgPacket(&np);
-   extractPacketAttributes(&np, error, attr_error, attr);
-   len=0;
-   break;
-  }
+  if ( len<0 ) break;
+  
+  np.maxlen=len;
+  initNgPacket(&np);
+  
+  if ( 
+      ntohs(remote.sin_port)!=SWITCH_PORT || 
+      len<(int)sizeof(struct ng_header) || 
+      !validateNgHeader(np.nh, code, &nga->localmac, sa==NULL ? NULL : &sa->mac , nga->seq) || 
+      extractPacketAttributes(&np, error, attr_error, attr)<0
+     ) continue;
+  
+  len=0;
+  break;
   
  }
  
@@ -233,7 +281,7 @@ int recvNgPacket (struct ngadmin *nga, char code, unsigned char *error, unsigned
 
 
 
-int checkErrorCode (unsigned char err, unsigned short attr_error) {
+static int checkErrorCode (unsigned char err, unsigned short attr_error) {
  
  
  if ( err==ERROR_INVALID_PASSWORD && attr_error==ATTR_PASSWORD ) {
index 6ed3cde28324ad8ec7254d82d99c7bd2ba254601..534ae31931e9432ac1db74eb3b1b2dfb1781c60e 100644 (file)
@@ -5,10 +5,12 @@
 
 #include <string.h>
 #include <unistd.h>
+//#include <poll.h>
 #include <arpa/inet.h>
 #include <net/if.h>
 #include <netinet/ether.h>
 #include <sys/ioctl.h>
+//#include <sys/time.h>
 
 #include "list.h"
 #include "lib.h"
index 5f99da233e1130829cfce63216d6c4bb75ee8aa9..05677a848f2d360fcb0ae81124681d0da0e955ba 100644 (file)
@@ -256,9 +256,10 @@ void freeAttr (struct attr *at) {
 
 
 // --------------------------------------------------------------------------------------------------------------
-void extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr) {
+int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr) {
  
  struct attr *at;
+ int ret=0;
  
  
  if ( error!=NULL ) *error=np->nh->error;
@@ -266,12 +267,20 @@ void extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsign
  
  while ( getPacketTotalSize(np)<np->maxlen ) {
   
+  // no room for an attribute header: error
+  if ( getPacketTotalSize(np)+(int)sizeof(struct attr_header)>np->maxlen ) {
+   ret=-1;
+   break;
+  }
+  
   at=malloc(sizeof(struct attr));
   at->attr=ntohs(np->ah->attr);
   at->size=ntohs(np->ah->size);
   
-  if ( getPacketTotalSize(np)+at->size>np->maxlen ) {
+  // attribute data bigger than the remaining size: error
+  if ( getPacketTotalSize(np)+(int)sizeof(struct attr_header)+at->size>np->maxlen ) {
    free(at);
+   ret=-1;
    break;
   }
   
@@ -284,15 +293,17 @@ void extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsign
   
   pushBackList(attr, at);
   
-  if ( at->attr==ATTR_END ) {
-   break;
-  }
+  // stop on an END attribute
+  if ( at->attr==ATTR_END ) break;
   
+  // move to next attribute
   np->ah=(struct attr_header*)(np->ah->data+at->size);
   
  }
  
  
+ return ret;
 }
 
 
index 24fbbfe43c2200ecf3dd19cdb1691504314e8082..cec182bbd77bd22de1455a647c0cc449c0a051d8 100644 (file)
@@ -110,7 +110,7 @@ struct attr* newAddrAttr (unsigned short attr, struct in_addr value);
 void freeAttr (struct attr *at);
 
 // 
-void extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr);
+int extractPacketAttributes (struct ng_packet *np, unsigned char *error, unsigned short *attr_error, List *attr);
 
 // 
 void extractSwitchAttributes (struct swi_attr *sa, const List *l);