Change how and where issue and motd are displayed

This commit is contained in:
Enrico Fraccaroli
2022-08-26 15:09:46 -04:00
parent 47f0ee965a
commit 5e5b9ba370
7 changed files with 145 additions and 107 deletions
+61
View File
@@ -0,0 +1,61 @@
/// @file ansi_colors.h
/// @author Enrico Fraccaroli (enry.frak@gmail.com)
/// @brief Macros for ANSI colors.
#pragma once
#define FG_RESET "\033[0m" ///< ANSI code for resetting.
#define FG_BLACK "\033[30m" ///< ANSI code for setting a BLACK foreground.
#define FG_RED "\033[31m" ///< ANSI code for setting a RED foreground.
#define FG_GREEN "\033[32m" ///< ANSI code for setting a GREEN foreground.
#define FG_YELLOW "\033[33m" ///< ANSI code for setting a YELLOW foreground.
#define FG_BLUE "\033[34m" ///< ANSI code for setting a BLUE foreground.
#define FG_MAGENTA "\033[35m" ///< ANSI code for setting a MAGENTA foreground.
#define FG_CYAN "\033[36m" ///< ANSI code for setting a CYAN foreground.
#define FG_WHITE "\033[37m" ///< ANSI code for setting a WHITE foreground.
#define FG_BLACK_BOLD "\033[1;30m" ///< ANSI code for setting a BLACK foreground.
#define FG_RED_BOLD "\033[1;31m" ///< ANSI code for setting a RED foreground.
#define FG_GREEN_BOLD "\033[1;32m" ///< ANSI code for setting a GREEN foreground.
#define FG_YELLOW_BOLD "\033[1;33m" ///< ANSI code for setting a YELLOW foreground.
#define FG_BLUE_BOLD "\033[1;34m" ///< ANSI code for setting a BLUE foreground.
#define FG_MAGENTA_BOLD "\033[1;35m" ///< ANSI code for setting a MAGENTA foreground.
#define FG_CYAN_BOLD "\033[1;36m" ///< ANSI code for setting a CYAN foreground.
#define FG_WHITE_BOLD "\033[1;37m" ///< ANSI code for setting a WHITE foreground.
#define FG_BLACK_BRIGHT "\033[90m" ///< ANSI code for setting a BRIGHT_BLACK foreground.
#define FG_RED_BRIGHT "\033[91m" ///< ANSI code for setting a BRIGHT_RED foreground.
#define FG_GREEN_BRIGHT "\033[92m" ///< ANSI code for setting a BRIGHT_GREEN foreground.
#define FG_YELLOW_BRIGHT "\033[93m" ///< ANSI code for setting a BRIGHT_YELLOW foreground.
#define FG_BLUE_BRIGHT "\033[94m" ///< ANSI code for setting a BRIGHT_BLUE foreground.
#define FG_MAGENTA_BRIGHT "\033[95m" ///< ANSI code for setting a BRIGHT_MAGENTA foreground.
#define FG_CYAN_BRIGHT "\033[96m" ///< ANSI code for setting a BRIGHT_CYAN foreground.
#define FG_WHITE_BRIGHT "\033[97m" ///< ANSI code for setting a BRIGHT_WHITE foreground.
#define FG_BLACK_BRIGHT_BOLD "\033[1;90m" ///< ANSI code for setting a BRIGHT_BLACK foreground.
#define FG_RED_BRIGHT_BOLD "\033[1;91m" ///< ANSI code for setting a BRIGHT_RED foreground.
#define FG_GREEN_BRIGHT_BOLD "\033[1;92m" ///< ANSI code for setting a BRIGHT_GREEN foreground.
#define FG_YELLOW_BRIGHT_BOLD "\033[1;93m" ///< ANSI code for setting a BRIGHT_YELLOW foreground.
#define FG_BLUE_BRIGHT_BOLD "\033[1;94m" ///< ANSI code for setting a BRIGHT_BLUE foreground.
#define FG_MAGENTA_BRIGHT_BOLD "\033[1;95m" ///< ANSI code for setting a BRIGHT_MAGENTA foreground.
#define FG_CYAN_BRIGHT_BOLD "\033[1;96m" ///< ANSI code for setting a BRIGHT_CYAN foreground.
#define FG_WHITE_BRIGHT_BOLD "\033[1;97m" ///< ANSI code for setting a BRIGHT_WHITE foreground.
#define BG_BLACK "\033[40m" ///< ANSI code for setting a BLACK background.
#define BG_RED "\033[41m" ///< ANSI code for setting a RED background.
#define BG_GREEN "\033[42m" ///< ANSI code for setting a GREEN background.
#define BG_YELLOW "\033[43m" ///< ANSI code for setting a YELLOW background.
#define BG_BLUE "\033[44m" ///< ANSI code for setting a BLUE background.
#define BG_MAGENTA "\033[45m" ///< ANSI code for setting a MAGENTA background.
#define BG_CYAN "\033[46m" ///< ANSI code for setting a CYAN background.
#define BG_WHITE "\033[47m" ///< ANSI code for setting a WHITE background.
#define BG_BRIGHT_BLACK "\033[100m" ///< ANSI code for setting a BRIGHT_BLACK background.
#define BG_BRIGHT_RED "\033[101m" ///< ANSI code for setting a BRIGHT_RED background.
#define BG_BRIGHT_GREEN "\033[102m" ///< ANSI code for setting a BRIGHT_GREEN background.
#define BG_BRIGHT_YELLOW "\033[103m" ///< ANSI code for setting a BRIGHT_YELLOW background.
#define BG_BRIGHT_BLUE "\033[104m" ///< ANSI code for setting a BRIGHT_BLUE background.
#define BG_BRIGHT_MAGENTA "\033[105m" ///< ANSI code for setting a BRIGHT_MAGENTA background.
#define BG_BRIGHT_CYAN "\033[106m" ///< ANSI code for setting a BRIGHT_CYAN background.
#define BG_BRIGHT_WHITE "\033[107m" ///< ANSI code for setting a BRIGHT_WHITE background.
+81 -53
View File
@@ -3,7 +3,6 @@
/// @copyright (c) 2014-2022 This file is distributed under the MIT License.
/// See LICENSE.md for details.
/// Maximum length of credentials.
#include <string.h>
#include <stdbool.h>
#include <sys/unistd.h>
@@ -15,18 +14,34 @@
#include <pwd.h>
#include <strerror.h>
#include <stdlib.h>
#include <debug.h>
#include "ansi_colors.h"
/// Maximum length of credentials.
#define CREDENTIALS_LENGTH 50
#define FG_BLACK "\033[30m"
#define FG_WHITE "\033[37m"
#define FG_RED "\033[31m"
#define BG_WHITE "\033[47m"
#define BG_BLACK "\033[40m"
static inline int __setup_env(passwd_t *pwd)
{
// Set the USER.
if (setenv("USER", pwd->pw_name, 1) == -1) {
printf("Failed to set env: `USER`\n");
return 0;
}
// Set the SHELL.
if (setenv("SHELL", pwd->pw_shell, 1) == -1) {
printf("Failed to set env: `SHELL`\n");
return 0;
}
// Set the HOME.
if (setenv("HOME", pwd->pw_dir, 1) == -1) {
printf("Failed to set env: `HOME`\n");
return 0;
}
return 1;
}
void set(unsigned flag, bool_t active)
static inline void __set_io_flags(unsigned flag, bool_t active)
{
struct termios _termios;
tcgetattr(STDIN_FILENO, &_termios);
@@ -37,16 +52,36 @@ void set(unsigned flag, bool_t active)
tcsetattr(STDIN_FILENO, 0, &_termios);
}
static inline void __print_message_file(const char * file)
{
char buffer[256];
ssize_t nbytes, total = 0;
int fd;
// Try to open the file.
if ((fd = open(file, O_RDONLY, 0600)) == -1)
return;
// Read the lines of the file.
while ((nbytes = read(fd, buffer, sizeof(char) * 256)) > 0) {
// TODO: Parsing message files for special characters (such as `\t` for time).
printf("%s\n", buffer);
total += nbytes;
}
close(fd);
if (total > 0)
printf("\n");
}
/// @brief Gets the inserted command.
static bool_t get_input(char *input, size_t max_len, bool_t hide)
static inline bool_t __get_input(char *input, size_t max_len, bool_t hide)
{
size_t index = 0;
int c;
bool_t result = false;
set(ICANON, false);
__set_io_flags(ICANON, false);
if (hide)
set(ECHO, false);
__set_io_flags(ECHO, false);
memset(input, 0, max_len);
do {
@@ -105,58 +140,33 @@ static bool_t get_input(char *input, size_t max_len, bool_t hide)
} while (index < max_len);
if (hide) {
set(ECHO, true);
__set_io_flags(ECHO, true);
putchar('\n');
}
set(ICANON, true);
__set_io_flags(ICANON, true);
return result;
}
static inline int setup_env(passwd_t *pwd)
{
// Set the USER.
if (setenv("USER", pwd->pw_name, 1) == -1) {
printf("Failed to set env: `USER`\n");
return 0;
}
// Set the SHELL.
if (setenv("SHELL", pwd->pw_shell, 1) == -1) {
printf("Failed to set env: `SHELL`\n");
return 0;
}
// Set the HOME.
if (setenv("HOME", pwd->pw_dir, 1) == -1) {
printf("Failed to set env: `HOME`\n");
return 0;
}
return 1;
}
int main(int argc, char **argv)
{
// Print /etc/issue if it exists
// TODO: Parsing /etc/issue for special characters (such as `\t` for time)
int issues_fd = open("/etc/issue", O_RDONLY, 0600);
if (issues_fd != -1){
char buffer[256];
if(read(issues_fd, buffer, sizeof(char)*256) != -1){
printf("%s \n", buffer);
}
close(issues_fd);
}
// Print /etc/issue if it exists.
__print_message_file("/etc/issue");
passwd_t *pwd;
char username[50], password[50];
char username[CREDENTIALS_LENGTH], password[CREDENTIALS_LENGTH];
do {
// Get the username.
do {
printf("Username :");
} while (!get_input(username, 50, false));
} while (!__get_input(username, CREDENTIALS_LENGTH, false));
// Get the password.
do {
printf("Password :");
} while (!get_input(password, 50, true));
} while (!__get_input(password, CREDENTIALS_LENGTH, true));
// Check if we can find the user.
if ((pwd = getpwnam(username)) == NULL) {
if (errno == ENOENT) {
printf("The given name was not found.\n");
@@ -167,29 +177,47 @@ int main(int argc, char **argv)
}
continue;
}
// Check if the password is correct.
if (strcmp(pwd->pw_passwd, password) != 0) {
printf("Wrong password.\n");
continue;
}
break;
} while (true);
// If there is not shell set for the user, should we rollback to standard shell?
if (pwd->pw_shell == NULL) {
printf("%s: There is no shell set for the user `%s`.\n", argv[0], pwd->pw_name);
printf("login: There is no shell set for the user `%s`.\n", pwd->pw_name);
return 1;
}
if (!setup_env(pwd)) {
printf("%s: Failed to setup the environmental variables.\n", argv[0]);
// Set the standard environmental variables.
if (!__setup_env(pwd)) {
printf("login: Failed to setup the environmental variables.\n");
return 1;
}
// Set the group id.
setgid(pwd->pw_gid);
// Set the user id.
setuid(pwd->pw_uid);
// Print /etc/motd if it exists.
__print_message_file("/etc/motd");
// Welcome the user.
puts(BG_WHITE FG_BLACK);
printf("Welcome " FG_RED "%s" FG_BLACK "...\n", pwd->pw_name);
puts(BG_BLACK FG_WHITE_BRIGHT);
// Call the shell.
char *_argv[] = { pwd->pw_shell, (char *)NULL };
if (execv(pwd->pw_shell, _argv) == -1) {
printf("%s: Failed to execute the shell.\n", argv[0]);
printf("%s: %s.\n", argv[0], strerror(errno));
printf("login: Failed to execute the shell.\n");
printf("login: %s.\n", strerror(errno));
return 1;
}
return 0;
+2 -52
View File
@@ -21,46 +21,13 @@
#include "limits.h"
#include "sys/utsname.h"
#include "ctype.h"
#include "ansi_colors.h"
/// Maximum length of commands.
#define CMD_LEN 32
/// Maximum lenght of the history.
#define HISTORY_MAX 10
/// @brief A set of colors.
#define FG_BLACK "\033[30m"
#define FG_RED "\033[31m"
#define FG_GREEN "\033[32m"
#define FG_YELLOW "\033[33m"
#define FG_BLUE "\033[34m"
#define FG_MAGENTA "\033[35m"
#define FG_CYAN "\033[36m"
#define FG_WHITE "\033[37m"
#define FG_BRIGHT_BLACK "\033[90m"
#define FG_BRIGHT_RED "\033[91m"
#define FG_BRIGHT_GREEN "\033[92m"
#define FG_BRIGHT_YELLOW "\033[93m"
#define FG_BRIGHT_BLUE "\033[94m"
#define FG_BRIGHT_MAGENTA "\033[95m"
#define FG_BRIGHT_CYAN "\033[96m"
#define FG_BRIGHT_WHITE "\033[97m"
#define BG_BLACK "\033[40m"
#define BG_RED "\033[41m"
#define BG_GREEN "\033[42m"
#define BG_YELLOW "\033[43m"
#define BG_BLUE "\033[44m"
#define BG_MAGENTA "\033[45m"
#define BG_CYAN "\033[46m"
#define BG_WHITE "\033[47m"
#define BG_BRIGHT_BLACK "\033[100m"
#define BG_BRIGHT_RED "\033[101m"
#define BG_BRIGHT_GREEN "\033[102m"
#define BG_BRIGHT_YELLOW "\033[103m"
#define BG_BRIGHT_BLUE "\033[104m"
#define BG_BRIGHT_MAGENTA "\033[105m"
#define BG_BRIGHT_CYAN "\033[106m"
#define BG_BRIGHT_WHITE "\033[107m"
// Required by `export`
#define ENV_NORM 1
#define ENV_BRAK 2
@@ -188,7 +155,7 @@ static inline void __prompt_print()
} else {
HOSTNAME = buffer.nodename;
}
printf(FG_GREEN "%s" FG_WHITE "@" FG_CYAN "%s " FG_BRIGHT_BLUE "[%02d:%02d:%02d]" FG_WHITE " [%s] " FG_BRIGHT_WHITE "%% ",
printf(FG_GREEN "%s" FG_WHITE "@" FG_CYAN "%s " FG_BLUE_BRIGHT "[%02d:%02d:%02d]" FG_WHITE " [%s] " FG_WHITE_BRIGHT "%% ",
USER, HOSTNAME, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec, CWD);
}
@@ -704,23 +671,6 @@ int main(int argc, char *argv[])
printf("Failed to set signal handler (%s).\n", SIGCHLD, strerror(errno));
return 1;
}
// Clear the screen.
puts("\033[J");
// Welcome the user.
puts(BG_WHITE FG_BLACK);
printf("Welcome " FG_RED "%s" FG_BLACK "...\n\n", USER);
puts(BG_BLACK FG_BRIGHT_WHITE);
// Print /etc/motd if it exists
int motd_fd = open("/etc/motd", O_RDONLY, 0600);
if (motd_fd != -1){
char buffer[256];
if(read(motd_fd, buffer, sizeof(char)*256) != -1){
printf("%s \n", buffer);
}
close(motd_fd);
}
// Move inside the home directory.
__cd(0, NULL);