feat: history file

This commit is contained in:
2026-10-09 22:52:06 +02:00
parent 2396e4c869
commit 28d6123c4c
2 changed files with 88 additions and 3 deletions

View File

@@ -1,4 +1,6 @@
#define ANSI_ESC "\x1b"
#define ANSI_FG_BLACK "\x1b[30m" #define ANSI_FG_BLACK "\x1b[30m"
#define ANSI_FG_RED "\x1b[31m" #define ANSI_FG_RED "\x1b[31m"
#define ANSI_FG_GREEN "\x1b[32m" #define ANSI_FG_GREEN "\x1b[32m"

View File

@@ -8,10 +8,14 @@
#include <sys/utsname.h> #include <sys/utsname.h>
#include <errno.h> #include <errno.h>
#include <termios.h> #include <termios.h>
#include <fcntl.h>
#include <sys/stat.h>
#include "ansi.h" #include "ansi.h"
#define ESC \x1B
#define HISTORY_FILE_NAME "/history.log"
#define LOCAL_SHARE_DIRNAME "/.local/share/msh"
const int LINESIZE = 512; const int LINESIZE = 512;
@@ -156,6 +160,9 @@ int main(int argc, char** argv) {
char* host; char* host;
struct utsname uts = {}; struct utsname uts = {};
char* sharedir = NULL;
char* historyfilepath = NULL;
FILE* historyfile = NULL;
user = secure_getenv("USER"); user = secure_getenv("USER");
@@ -176,6 +183,68 @@ int main(int argc, char** argv) {
// disable echo and icanon (don't wait for newline) // disable echo and icanon (don't wait for newline)
term.c_lflag &= ~(ECHO | ICANON); term.c_lflag &= ~(ECHO | ICANON);
char* homedir = secure_getenv("HOME");
if (homedir == NULL) {
fprintf(stderr, "Error: $HOME is not specified\n");
retval = 1;
goto cleanup;
}
sharedir = malloc(strlen(homedir) + strlen(LOCAL_SHARE_DIRNAME) + 1);
if (sharedir == NULL) {
retval = 1;
goto cleanup;
}
sharedir = strcpy(sharedir, homedir);
if (sharedir == NULL) {
retval = 1;
goto cleanup;
}
sharedir = strcat(sharedir, LOCAL_SHARE_DIRNAME);
if (sharedir == NULL) {
retval = 1;
goto cleanup;
}
result = mkdir(sharedir, S_IRWXU);
if (result != 0 && errno != EEXIST) {
fprintf(stderr, "Error: %s\n", strerror(errno));
retval = 1;
goto cleanup;
}
historyfilepath = malloc(strlen(sharedir) + strlen(HISTORY_FILE_NAME) + 1);
if (historyfilepath == NULL) {
retval = 1;
goto cleanup;
}
historyfilepath = strcpy(historyfilepath, sharedir);
if (historyfilepath == NULL) {
retval = 1;
goto cleanup;
}
historyfilepath = strcat(historyfilepath, HISTORY_FILE_NAME);
if (historyfilepath == NULL) {
retval = 1;
goto cleanup;
}
int historyfilefd = open(historyfilepath, O_CREAT | O_APPEND | O_WRONLY, S_IRUSR | S_IWUSR);
if (historyfilefd == -1) {
fprintf(stderr, "Error: could not open history file: %s\n", strerror(errno));
retval = 1;
goto cleanup;
}
historyfile = fdopen(historyfilefd, "w");
if (historyfile == NULL) {
fprintf(stderr, "Error: could not open history file fd: %s\n", strerror(errno));
retval = 1;
goto cleanup;
}
// Main loop // Main loop
while(1) { while(1) {
@@ -284,9 +353,9 @@ int main(int argc, char** argv) {
print_prompt: print_prompt:
// Manual echo // Manual echo
printf("\x1b[2K\x1b[0G%s%s", prompt, line); printf(ANSI_ESC "[2K" ANSI_ESC "[0G" "%s%s", prompt, line);
for (int j = 0; j < linelen - cursor; j++) { for (int j = 0; j < linelen - cursor; j++) {
printf("\x1b[D"); printf(ANSI_ESC "[D");
} }
fflush(stdout); fflush(stdout);
} }
@@ -297,6 +366,9 @@ print_prompt:
line[linelen] = 0; line[linelen] = 0;
fprintf(historyfile, "%s\n", line);
fflush(historyfile);
// Split into tokens // Split into tokens
for (tokenwork = line, i = 0; ; tokenwork = NULL, i++) { for (tokenwork = line, i = 0; ; tokenwork = NULL, i++) {
token = strtok(tokenwork, " \t"); token = strtok(tokenwork, " \t");
@@ -342,6 +414,17 @@ print_prompt:
cleanup: cleanup:
if (sharedir != NULL) {
free(sharedir);
}
if (historyfilepath != NULL) {
free(historyfilepath);
}
if (historyfile != NULL) {
fflush(historyfile);
fclose(historyfile);
}
tcsetattr(fileno(stdin), 0, &orig_term); tcsetattr(fileno(stdin), 0, &orig_term);
return retval; return retval;
} }