CLI : monitor command

This commit is contained in:
Adrien Bourmault 2021-07-15 23:05:55 +02:00
parent dee272db72
commit a95279b7ef
No known key found for this signature in database
GPG Key ID: 6EB408FE0ACEC664
1 changed files with 149 additions and 14 deletions

163
src/cli.c
View File

@ -1,5 +1,5 @@
//=-------------------------------------------------------------------------=//
// Command line interface management module //
// Command line interface main file //
// //
// Copyright © 2021 The Gem-graph Project //
// //
@ -22,11 +22,13 @@
#include "../include/base.h"
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>
#include <unistd.h>
#include <termios.h>
#include <fcntl.h>
#define SEND_BUFFER_SIZE 80
#define RECEIVE_BUFFER_SIZE 80 * 24
@ -43,6 +45,7 @@
#define KEY_ARROW_LEFT 68
#define KEY_DELETE 127
#define C_CLEARSCREEN "\e[2J"
#define C_CLEARLINE "\e[2K"
#define C_CURSORLEFT "\e[1D"
#define C_CURSORRIGHT "\e[1C"
@ -54,15 +57,25 @@
#define C_COLOR_BLUE "\e[01;34m"
#define C_COLOR_NORMAL "\e[0m"
static char getch(void)
#define NON_BLOCKING 1
//
// Get a character code from the keyboard
//
static inline int getch(bool nonBlocking)
{
char buf = 0;
int buf = 0;
// old terminal
struct termios old = {0};
// force flush stdout
fflush(stdout);
// Set non-blocking mode if asked
if(nonBlocking)
fcntl(0, F_SETFL, O_NONBLOCK);
if(tcgetattr(0, &old) < 0) {
printLog("%sError getting terminal settings! (%s)\n",
C_COLOR_RED,
@ -72,8 +85,6 @@ static char getch(void)
old.c_lflag &= ~ICANON; // disable buffered I/O
old.c_lflag &= ~ECHO; // set no echo mode
old.c_cc[VMIN] = 1;
old.c_cc[VTIME] = 0;
if(tcsetattr(0, TCSANOW, &old) < 0) {
printLog("%sError setting terminal settings! (%s)\n",
@ -82,7 +93,12 @@ static char getch(void)
return -1;
}
if(read(0, &buf, 1) < 0) {
buf = getchar();
if(buf < 0) {
// Check target busy (try again)
if(errno == EAGAIN)
return 0;
printLog("%sError reading character! (%s)\n",
C_COLOR_RED,
strerror(errno));
@ -98,11 +114,120 @@ static char getch(void)
strerror(errno));
return -1;
}
// Reset blocking mode
if(nonBlocking)
fcntl(0, F_SETFL, 0);
return buf;
}
//
// Decorations
//
void decorateMonitor(struct winsize *terminalSize)
{
printf(C_CLEARSCREEN "\n");
void connectedCommunication(int sockfd)
// print decorations
for (int i = 0; i < terminalSize->ws_col; i++) {
printf("*");
}
for (int i = 0;
i < (terminalSize->ws_row-2) * terminalSize->ws_col;
i++) {
if ((i % terminalSize->ws_col == 0) ||
(i % terminalSize->ws_col == terminalSize->ws_col - 1))
printf("|");
else
printf(" ");
}
for (int i = 0; i < terminalSize->ws_col; i++) {
printf("*");
}
fflush(stdout);
}
//
// Monitor mode main loop
//
int connectedMonitor(int sockfd)
{
char sendBuff[SEND_BUFFER_SIZE] = {0};
char receiveBuff[RECEIVE_BUFFER_SIZE] = {0};
int pleaseStop = 0;
char curChar;
int answerLength;
struct winsize terminalSize, oldTerminalSize;
// Get current terminal size
ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminalSize);
memcpy(&oldTerminalSize, &terminalSize, sizeof(struct winsize));
decorateMonitor(&terminalSize);
while (!pleaseStop) {
// Zeroing buffer
bzero(sendBuff, sizeof(sendBuff));
// Get current terminal size and redecorate if it has changed
ioctl(STDOUT_FILENO, TIOCGWINSZ, &terminalSize);
if (terminalSize.ws_row != oldTerminalSize.ws_row ||
terminalSize.ws_col != oldTerminalSize.ws_col
) {
memcpy(&oldTerminalSize, &terminalSize, sizeof(struct winsize));
decorateMonitor(&terminalSize);
}
// Read command from terminal
curChar = getch(NON_BLOCKING);
if (curChar > 0) {
printLog("Char detected : %d\n", curChar);
}
switch (curChar) {
case 'q':
pleaseStop = true;
break;
}
/* // Otherwise send command to server */
/* send(sockfd, sendBuff, sizeof(sendBuff), 0); */
/* // Zeroing buffer */
/* bzero(receiveBuff, sizeof(receiveBuff)); */
/* // Reading server answer */
/* answerLength = recv(sockfd, receiveBuff, sizeof(receiveBuff), 0); */
/* // Detect disconnection */
/* if (answerLength == 0) { */
/* break; */
/* } */
/* // Detect null-string returned */
/* if (receiveBuff[0] == '\0') { */
/* // Invalid command */
/* } */
}
printf("%sEnd of monitoring session\n\e[0m", C_COLOR_YELLOW);
}
//
// Main CLI loop
//
void connectedCommandLine(int sockfd)
{
char sendBuff[SEND_BUFFER_SIZE] = {0};
char receiveBuff[RECEIVE_BUFFER_SIZE] = {0};
@ -113,8 +238,9 @@ void connectedCommunication(int sockfd)
char curChar;
int curLineLength, curPosition, continueReadLine, answerLength;
char *exitCommand = "exit";
char *promptString = C_COLOR_BLUE "gem-graph console" C_COLOR_NORMAL "> ";
const char *exitCommand = "exit";
const char *monitorCommand = "monitor";
const char *promptString = C_COLOR_BLUE "gem-graph console" C_COLOR_NORMAL "> ";
for (;;) {
// Zeroing buffer
@ -126,7 +252,7 @@ void connectedCommunication(int sockfd)
curPosition = 0;
continueReadLine = 1;
historyModifier = -1;
while (continueReadLine && (curChar = getch())) {
while (continueReadLine && (curChar = getch(0))) {
switch (curChar) {
@ -164,9 +290,9 @@ void connectedCommunication(int sockfd)
break;
case KEY_ESCAPE:
if (getch() == KEY_DIRECTIONS) {
if (getch(0) == KEY_DIRECTIONS) {
switch(getch()) {
switch(getch(0)) {
case KEY_ARROW_UP:
if (historyIndex <= 0)
@ -228,7 +354,7 @@ void connectedCommunication(int sockfd)
break;
default:
if (curLineLength < SEND_BUFFER_SIZE) {
if (curLineLength < SEND_BUFFER_SIZE && curChar > 0) {
printf("%s", C_SAVE_CURSORPOS);
memmove(sendBuff + curPosition + 1, sendBuff + curPosition,
@ -266,6 +392,12 @@ void connectedCommunication(int sockfd)
break;
}
// Launch monitor mode if asked
if (strcmp(monitorCommand, sendBuff) == 0) {
connectedMonitor(sockfd);
continue;
}
// Otherwise send command to server
send(sockfd, sendBuff, sizeof(sendBuff), 0);
@ -290,6 +422,9 @@ void connectedCommunication(int sockfd)
printf("%sDisconnected\n\e[0m", C_COLOR_YELLOW);
}
//
// main
//
int main(void)
{
int sockfd;
@ -321,7 +456,7 @@ int main(void)
printLog("%sConnected to server!\n\n", C_COLOR_GREEN);
connectedCommunication(sockfd);
connectedCommandLine(sockfd);
// close the socket
close(sockfd);