#include <stdio.h>
+#include <signal.h>
+#include <setjmp.h>
#include <getopt.h>
#include <readline/readline.h>
for (next=cur->sub; next->name!=NULL && strcmp(next->name, com[i])!=0; ++next);
// sub command not found, exit
- if ( next->name==NULL ) {
- next=NULL;
- break;
- }
+ if ( next->name==NULL ) break;
// next command is now the current one
cur=next;
}
- while ( (name=tn->name)!=NULL ) {
- ++tn;
-
- if ( strncmp(name, text, len)==0 ) {
+ while ( (name=tn++->name)!=NULL )
+ if ( strncmp(name, text, len)==0 )
return strdup(name);
- }
-
- }
return NULL;
int i, n;
-
memset(com, 0, MAXCOM*sizeof(char*));
line=strdup(rl_line_buffer);
line[start]=0;
if ( i<n ) compcur=NULL;
matches=rl_completion_matches(text, my_generator);
+ for (i=0; com[i]!=NULL; ++i) {
+ free(com[i]);
+ }
+
return matches;
+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, ¤t_term);
+
+ siglongjmp(jmpbuf, 1);
+
+ default:
+ ngadmin_close(nga);
+
+ tcsetattr(STDIN_FILENO, TCSANOW, &orig_term);
+
+ exit(0);
+
+ }
+
+
+}
+
+
int main (int argc, char **argv) {
static const struct option opts[]={
{"keep-broadcasting", no_argument, NULL, 'b'},
{"force-interface", no_argument, NULL, 'f'},
+ {"global-broadcast", no_argument, NULL, 'g'},
{"interface", required_argument, NULL, 'i'},
{"help", no_argument, NULL, 'h'},
+ {"timeout", required_argument, NULL, 't'},
{0, 0, 0, 0}
};
char *line, *com[MAXCOM];
const char *iface="eth0";
- bool kb=false, force=false;
- struct ngadmin *nga=NULL;
+ float timeout=0.f;
+ bool kb=false, force=false, global=false;
struct timeval tv;
const struct TreeNode *cur, *next;
int i, n;
+ tcgetattr(STDIN_FILENO, &orig_term);
+ current_term=orig_term;
+ /*
+ current_term.c_lflag&=~ECHOCTL;
+ tcsetattr(STDIN_FILENO, TCSANOW, ¤t_term);
+ */
+
+
opterr=0;
- while ( (n=getopt_long(argc, argv, "bfi:h", opts, NULL))!=-1 ) {
+ while ( (n=getopt_long(argc, argv, "bfgi:ht:", opts, NULL))!=-1 ) {
switch ( n ) {
case 'b':
force=true;
break;
+ case 'g':
+ global=true;
+ break;
+
case 'i':
iface=optarg;
break;
case 'h':
- printf("Usage: %s [-b] [-f] [-i <interface>]\n", argv[0]);
+ printf("Usage: %s [-b] [-f] [-g] [-i <interface>]\n", argv[0]);
goto end;
+ case 't':
+ timeout=strtof(optarg, NULL);
+ break;
+
case '?':
printf("Unknown option: \"%s\"\n", argv[optind-1]);
goto end;
}
// set timeout
- tv.tv_sec=3;
- tv.tv_usec=0;
- ngadmin_setTimeout(nga, &tv);
+ if ( timeout>0.f ) {
+ tv.tv_sec=(int)timeout;
+ tv.tv_usec=(int)((timeout-(float)tv.tv_sec)*1.e6f);
+ ngadmin_setTimeout(nga, &tv);
+ }
if ( kb && ngadmin_setKeepBroadcasting(nga, true)!=ERR_OK ) goto end;
if ( force && ngadmin_forceInterface(nga)!=ERR_OK ) goto end;
+ 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_completion_entry_function=my_generator;
+
+ signal(SIGTERM, handler);
+ signal(SIGINT, handler);
+
+ sigsetjmp(jmpbuf, 1);
+
+
while ( cont ) {
if ( (line=readline("> "))==NULL ) goto end;
- if ( *line!=0 ) add_history(line);
trim(line, strlen(line));
n=explode(line, com, MAXCOM);
- free(line);
- if ( n==0 ) continue;
+ if ( n==0 ) {
+ free(line);
+ continue;
+ } else {
+ add_history(line);
+ free(line);
+ }
cur=getSubCom(com, n, &i);
}
- for (i=0; i<MAXCOM; i++) {
- if ( com[i]!=NULL ) {
- free(com[i]);
- com[i]=NULL;
- }
+ for (i=0; com[i]!=NULL; ++i) {
+ free(com[i]);
+ com[i]=NULL;
}
}
end:
- ngadmin_close(nga);
-
-
- return 0;
+ handler(0);
}