From d94239679d07ffe603c96c54dd9fff5a02a0aebc Mon Sep 17 00:00:00 2001 From: 7u83 <7u83@mail.ru> Date: Tue, 23 Aug 2022 02:35:54 +0200 Subject: [PATCH] Work on ansi shell --- src/ac/ac.h | 6 +- src/ac/ac_main.c | 40 ++++- src/ac/conf.c | 3 +- src/ac/config.ckv | 5 + src/ac/shell.c | 351 +++++++++++++++++++++++++++++++++++----- src/cw/ansi_colors.h | 4 + src/cw/sock_addrtostr.c | 13 +- 7 files changed, 365 insertions(+), 57 deletions(-) diff --git a/src/ac/ac.h b/src/ac/ac.h index 434f97e4..7447c5da 100644 --- a/src/ac/ac.h +++ b/src/ac/ac.h @@ -1,9 +1,7 @@ #ifndef __ACTUBE_AC_H #define __ACTUBE_AC_H -#include "mavl.h" -#include "cw/mavltypes.h" - +#include "cw/cfg.h" extern struct ac_status ac_global_status; @@ -19,7 +17,7 @@ enum { AC_PROTO_UNKNOWN }; -void start_shell(); +int start_shell(cw_Cfg_t *global_cfg); #endif diff --git a/src/ac/ac_main.c b/src/ac/ac_main.c index 11406dd8..5210ecbf 100644 --- a/src/ac/ac_main.c +++ b/src/ac/ac_main.c @@ -52,8 +52,34 @@ int ac_run(cw_Cfg_t * cfg); #include "statemachine.h" #include +#include +#include +/* +void tshell_run(int fd) +{ + int rc; + printf("listening\n"); + rc = listen(fd,5); + printf("listen returned %d\n",rc); + clientsock = accept (sockfd, (struct sockaddr*) &client, &client_size); + +} + +void tshell() +{ + printf("tshell start\n"); + struct sockaddr_un addr; + + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, "./tsocket", sizeof(addr.sun_path)-1); + bind(fd, (struct sockaddr*)&addr, sizeof(addr)); + while(1); +} +*/ struct bootcfg { const char * cfgfilename; @@ -181,8 +207,6 @@ int main (int argc, char *argv[]) int rc = 0; struct bootcfg bootcfg; - - /* parse arguments */ parse_args (argc, argv, &bootcfg); @@ -234,12 +258,8 @@ int main (int argc, char *argv[]) } */ - - - - start_shell(); /* Init DTLS library */ dtls_init(); @@ -255,9 +275,15 @@ int main (int argc, char *argv[]) if (!dataman_list_init()) goto errX; + + ac_conf_init(global_cfg); - cw_cfg_dump(global_cfg); + if (!start_shell(global_cfg)) + goto errX; + + +// cw_cfg_dump(global_cfg); cw_log (LOG_INFO, "Starting AC-Tube, Name=%s, ID=%s", cw_cfg_get(global_cfg,"capwap/ac-name",NULL), conf_acid); rc = ac_run(global_cfg); diff --git a/src/ac/conf.c b/src/ac/conf.c index a2b1f17c..d5c8587c 100644 --- a/src/ac/conf.c +++ b/src/ac/conf.c @@ -298,7 +298,7 @@ int init_bcast_addrs(cw_Cfg_t *cfg) sr = mavl_add_str(t, s); - printf("BCAST = %p --- %p: %s\n",str,s,str); +// printf("BCAST = %p --- %p: %s\n",str,s,str); } } @@ -549,7 +549,6 @@ int conf_parse_listen_addr(const char *addrstr, char *saddr, char *port, int *pr void ac_conf_init(cw_Cfg_t *cfg) { - printf("ac conf\n"); init_listen_addrs(cfg); init_bcast_addrs(cfg); init_ac_name(cfg); diff --git a/src/ac/config.ckv b/src/ac/config.ckv index 54f68406..d4fb3396 100644 --- a/src/ac/config.ckv +++ b/src/ac/config.ckv @@ -40,6 +40,11 @@ actube/ipv6: false actube/mod.1: capwap actube/mod.2: capwap80211 +#actube/shell/listen: unix:/tmp/actube +actube/shell/listen: tcp:127.0.0.1:5000 +actube/shell/enable: true +actube/shell/term: ansi + ac-descriptor/dtls-policy: 1 ac-descriptor/hardware/vendor: 4232704 diff --git a/src/ac/shell.c b/src/ac/shell.c index 185acb69..a7af0565 100644 --- a/src/ac/shell.c +++ b/src/ac/shell.c @@ -5,6 +5,10 @@ #include #include +#include +#include + + #include "cw/sock.h" #include "cw/log.h" @@ -16,13 +20,24 @@ #include "wtplist.h" - +#include "ac.h" struct shelldata{ FILE *out; char prompt[1024]; mavl_t update_cfg; + char *history[2000]; + char line[4096]; + int pos; + char esc[8]; + int escpos; +}; + +struct sockdata{ + const char *name; + int fd; + cw_Cfg_t * global_cfg; }; void select_cmd(struct shelldata *sd, const char *cmd); @@ -408,6 +423,160 @@ void execute_cmd (struct shelldata * sd, const char *str) } +struct esc_strings { + char *str; + char * result; +}; + +struct esc_strings estr[] = { + {"\x1b[H", "home"}, + {"\x1b[F", "end"}, + {"\x1b[A", "up"}, + {"\x1b[B", "donw"}, + {"\x1b[D", "left"}, + {"\x1b[C", "right"}, + + {NULL,NULL} + +}; + +static int cmpansi(char * str,char * ansistr) +{ + int sl,al; + sl = strlen(str); + al = strlen(ansistr); + + + if(sl>al){ + return 0; + } + if (slline[0]=0; + sd->pos=0; + sd->esc[0]=0; + sd->escpos=0; + +// fprintf (file, "\xff\xfc\22"); + + /* Put telnet into char mode */ + fprintf (file,"%c%c%c",IAC,WILL,TELOPT_ECHO ); + fprintf (file,"%c%c%c",IAC,WILL,TELOPT_SGA ); +// fprintf (file,"%c%c%c",IAC,DONT,TELOPT_LINEMODE ); + + + fprintf (file, "\n\ractube[%s]:>", sd->prompt); + fflush (file); + + while ( (c=fgetc(file))!= EOF){ + printf ("%02x\n",c); + if (sd->escpos){ + int i; + int a=0; + + sd->esc[sd->escpos++]=c; + sd->esc[sd->escpos]=0; + + for (i=0; estr[i].str != NULL; i++){ + int rc; + rc = cmpansi(sd->esc,estr[i].str); + if (rc==1){ + sd->esc[0]=0; + sd->escpos=0; + es = &estr[i]; + break; + } + a |= rc; + + } + if (a==0){ + sd->esc[0]=0; + sd->escpos=0; + }else{ + continue; + } + + + } + if (c==0x1b){ + sd->esc[sd->escpos++]=c; + sd->esc[sd->escpos]=0; + printf("ESC start\n"); + continue; + } + + + if (!es){ + if (c=='\r'){ + printf("CMD: %s\n",sd->line); + fprintf (file, "\n\ractube[%s]:>", sd->prompt); + sd->pos=0; + sd->line[0]=0; + continue; + } + if (c=='\x7f'){ + if (sd->pos==0) + continue; + + printf("Backspace\n"); + fprintf(file,"%c %c",8,8); + sd->line[--sd->pos]=0; + continue; + + } + if (c>240 || c<30){ + continue; + } + + + sd->line[sd->pos++]=c; + sd->line[sd->pos]=0; + printf("putout: %c %02X\n",c,c); + fprintf(file,"%c",c); + continue; + } + + printf ("ES: %s\n",es->result); + + if (strcmp(es->result,"left")==0){ + if (sd->pos>0){ + sd->pos--; + fprintf(file,es->str); + } + } + if (strcmp(es->result,"right")==0){ + if (sd->line[sd->pos]!=0){ + sd->pos++; + fprintf(file,es->str); + } + } + +// fprintf(file,es->str); + + es = NULL; +// fflush(file); + + + } +} + + void shell_loop (FILE *file) { @@ -419,45 +588,89 @@ void shell_loop (FILE *file) */ char str[2048]; - stop(); // sd.update_cfg = cw_ktv_create(); - sd.out = file; sprintf(sd.prompt,"%s","*"); do { - fprintf (file, "actube[%s]:>", sd.prompt); - fflush (file); + int c; + get_line_char_mode(file,&sd); + + str[0]=0; - fgets (str, sizeof (str), file); - execute_cmd (&sd, str); +// c=fgetc(file); + printf("%c\n",c); + + fgets (str, sizeof (str), file); + + printf("My String: %s\n",str); + + execute_cmd (&sd, str); + } while (c != EOF); } void * run_shell (void * arg) +{ + char sockstr[SOCK_ADDR_BUFSIZE]; + struct sockdata * sockdata; + int clientsock; + struct sockaddr_storage client; + socklen_t client_size; + + sockdata = (struct sockdata *)arg; + + memset(&client,0,sizeof(client)); + client_size=sizeof(client); + + cw_dbg(DBG_INFO,"Starting shell, listening on: %s (sock fd: %d)",sockdata->name, sockdata->fd); + + while(1){ + clientsock = accept (sockdata->fd, (struct sockaddr*) &client, &client_size); + if (clientsock == -1){ + cw_log (LOG_ERR, "Accept error '%s', %s", "addr", strerror (errno)); + return NULL; + + } + + if (clientsock > 0) { + sock_addr2str_p (&client, sockstr); + cw_dbg (DBG_INFO, "Acceptiong session from %s", sockstr); + cw_dbg (DBG_INFO, "Start shell"); + shell_loop (fdopen (clientsock, "a+")); + cw_dbg (DBG_INFO, "Stop shell"); + close (clientsock); + } + + + + //cw_dbg (DBG_INFO,"Accepting shell session %i, %s", rc, strerror (errno)); + } + + return NULL; +} + +int create_tcp_fd(const char *name) { struct sockaddr_storage server, client; socklen_t client_size; char sockstr[SOCK_ADDR_BUFSIZE]; int rc; - const char * addr = "127.0.0.1:5000"; + const char * addr = name; int sockfd, clientsock; int yes; - - cw_dbg(DBG_INFO,"Staring shelli listening at: %s",addr); - - rc = sock_strtoaddr (addr, (struct sockaddr*) &server); if (! rc) { cw_log (LOG_ERR, "Can't parse address '%s', %s", addr, strerror (errno)); + return -1; } sockfd = socket ( ( (struct sockaddr*) &server)->sa_family, SOCK_STREAM, 0); @@ -472,43 +685,99 @@ void * run_shell (void * arg) if (rc) { cw_log (LOG_ERR, "Can't bind socket address '%s', %s", addr, strerror (errno)); + return -1; } - rc = listen (sockfd, 5); - + return sockfd; +} +static int create_unix_fd(const char *name) +{ + struct sockaddr_storage client; + socklen_t client_size; + struct sockaddr_un addr; + int rc,fd; + + unlink(name); + fd = socket(PF_UNIX, SOCK_STREAM, 0); + + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, name, sizeof(addr.sun_path)-1); + rc = bind(fd, (struct sockaddr*)&addr, sizeof(addr)); if (rc) { - cw_log (LOG_ERR, "Can't listen on address '%s', %s", addr, strerror (errno)); + cw_log (LOG_ERR, "Can't bind socket 'unix:%s', %s", name, strerror (errno)); + return -1; } - - - client_size = sizeof (client); -while(1){ - - clientsock = accept (sockfd, (struct sockaddr*) &client, &client_size); - - if (clientsock > 0) { - sock_addr2str_p (&client, sockstr); - cw_dbg (DBG_INFO, "Acceptiong session from %s", sockstr); - cw_dbg (DBG_INFO, "Start shell"); - shell_loop (fdopen (clientsock, "a+")); - cw_dbg (DBG_INFO, "Stop shell"); - close (clientsock); - } - - - - cw_dbg (DBG_INFO,"Accepting shell session %i, %s", rc, strerror (errno)); -} - - - - return NULL; + int clientsock = accept (fd, (struct sockaddr*) &client, &client_size); + + return fd; } -void start_shell() +int start_shell(cw_Cfg_t *global_cfg) { + struct sockdata * sockdata; + const char *sockname; + int rc, type; + int fd; + + rc = cw_cfg_get_bool(global_cfg,"actube/shell/enable",1); + if (!rc) + return 1; + + sockdata = malloc(sizeof(struct sockdata)); + if (sockdata==NULL) + return 0; + + memset(sockdata,0,sizeof(struct sockdata)); + + sockdata->global_cfg = global_cfg; + sockdata->fd=-1; + + sockname = cw_cfg_get(global_cfg,"actube/shell/listen",NULL); + + if (sockname==NULL) { + cw_log (LOG_ERR, "Can't get shell listen address from global_cfg 'actube/shell/listen"); + goto errX; + } + + if (strncmp("unix:",sockname,strlen("unix:"))==0){ + fd = create_unix_fd(strchr(sockname,':')+1); + if (fd==-1) + goto errX; + sockdata->name=cw_strdup(sockname); + sockdata->fd=fd; + }else if (strncmp("tcp:",sockname,strlen("tcp:"))==0){ + fd = create_tcp_fd(strchr(sockname,':')+1); + if (fd==-1) + goto errX; + sockdata->name=cw_strdup(sockname); + sockdata->fd=fd; + }else { + fd = create_tcp_fd(sockname); + if (fd==-1) + goto errX; + sockdata->name=cw_strdup(sockname); + sockdata->fd=fd; + } + + + rc = listen (sockdata->fd, 5); + if (rc) { + cw_log (LOG_ERR, "Can't listen on address '%s', %s", "addr", strerror (errno)); + goto errX; + } + pthread_t thread; pthread_create (&thread, NULL, run_shell, - NULL); + sockdata); + return 1; +errX: + if (sockdata->fd!=-1) + close(sockdata->fd); + if (sockdata->name) + free(sockdata->name); + + free(sockdata); + return 0; } diff --git a/src/cw/ansi_colors.h b/src/cw/ansi_colors.h index 36e4db73..3d7d20c6 100644 --- a/src/cw/ansi_colors.h +++ b/src/cw/ansi_colors.h @@ -25,4 +25,8 @@ #define ANSI_ITALIC "\x1b[3m" #define ANSI_BOLD "\x1b[1m" + +#define ANSI_HOME "[H" + + #endif /* __ANSI_COLORS_H */ diff --git a/src/cw/sock_addrtostr.c b/src/cw/sock_addrtostr.c index fc5f2313..db3fa474 100644 --- a/src/cw/sock_addrtostr.c +++ b/src/cw/sock_addrtostr.c @@ -31,6 +31,7 @@ #include #include +#include #include #include @@ -88,7 +89,7 @@ char *sock_addrtostr(const struct sockaddr *sa, char *s, size_t maxlen, int addp } break; -#endif /* AF_LINLK */ +#endif /* AF_LINLK */ #ifdef AF_PACKET case AF_PACKET: @@ -103,11 +104,17 @@ char *sock_addrtostr(const struct sockaddr *sa, char *s, size_t maxlen, int addp sprintf(sp, "%02X", sl->sll_addr[i]); } break; -#endif /* AF_PACKET */ +#endif /* AF_PACKET */ + case AF_UNIX: + { + struct sockaddr_un *addr = (struct sockaddr_un *) sa; + snprintf(s, maxlen, "%s", addr->sun_path); + } + break; default: - strncpy(s, "Unknown AF", maxlen); + snprintf(s,maxlen, "Unknown AF: %d", sa->sa_family); return NULL; } return s;