From 8a46658820c280a8b2a872d9f47cb0603037ae57 Mon Sep 17 00:00:00 2001 From: PartialVolume <22084881+PartialVolume@users.noreply.github.com> Date: Tue, 5 Sep 2023 19:01:08 +0100 Subject: [PATCH] Create function read_system_datetime() The purpose of this is to read year, month, day, hours minutes and seconds into variables for updating in the GUI prior to writing back to the system. For systems isolated from the internet this will allow the user to update system date/time from the nwipe GUI rather than having to drop into the command line. To complete this feature next will be to create the write_system_datetime function. --- src/gui.c | 167 +++++++++++++++++++++++++++- src/gui.h | 1 + src/miscellaneous.c | 258 +++++++++++++++++++++++++++++++++++++++++++- src/miscellaneous.h | 18 ++++ 4 files changed, 442 insertions(+), 2 deletions(-) diff --git a/src/gui.c b/src/gui.c index 771f39ec..5a132b89 100644 --- a/src/gui.c +++ b/src/gui.c @@ -28,6 +28,17 @@ * and things like ncurses libmenu are not worth the storage overhead. * */ + +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif + +#ifndef _POSIX_SOURCE +#define _POSIX_SOURCE +#endif + +#include +#include #include #include #include @@ -5053,7 +5064,7 @@ void nwipe_gui_set_date_time( void ) { case 0: /* Set year */ - // NOTE ADD Function + nwipe_gui_set_system_year(); keystroke = 0; break; @@ -5087,6 +5098,160 @@ void nwipe_gui_set_date_time( void ) } /* end of nwipe_gui_set_date_time( void ) */ +void nwipe_gui_set_system_year( void ) +{ + /** + * Allows the user to edit the host systems year + * + * @modifies system year + * @modifies main_window + * + */ + + /* The first tabstop. */ + const int tab1 = 2; + + /* The current working row. */ + int yy = 2; + + /* Input buffer. */ + int keystroke; + + /* Various output from the date command is processed in this buffer */ + char date_buffer[256]; + date_buffer[0] = 0; + + char year[5] = ""; + char month[3] = ""; + char day[3] = ""; + char hours[3] = ""; + char minutes[3] = ""; + char seconds[3] = ""; + + /* buffer index */ + int idx = 0; + + int status = 0; + + FILE* fp; + + extern int terminate_signal; + + /* Update the footer window. */ + werase( footer_window ); + nwipe_gui_title( footer_window, selection_footer_text_entry ); + wrefresh( footer_window ); + + fp = popen( "date +%Y", "r" ); + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_INFO, "popen:Failed to retrieve date +%Y %s", date_buffer ); + mvwprintw( main_window, yy + 4, tab1, "popen:date command failed retrieving year" ); + } + + if( fgets( date_buffer, sizeof( date_buffer ), fp ) == NULL ) + { + nwipe_log( NWIPE_LOG_INFO, "fgets:failed to retrieve year %s", date_buffer ); + mvwprintw( main_window, yy + 5, tab1, "fgets:failed retrieving year" ); + } + + /* terminate string after fourth character removing any lf */ + date_buffer[4] = 0; + + pclose( fp ); + + /* Set the buffer index to point to the end of the string, i.e the NULL */ + idx = strlen( date_buffer ); + + do + { + /* Erase the main window. */ + werase( main_window ); + + nwipe_gui_create_all_windows_on_terminal_resize( 0, selection_footer_text_entry ); + + /* Add a border. */ + box( main_window, 0, 0 ); + + /* Add a title. */ + nwipe_gui_title( main_window, " Set System Year " ); + + /* Initialize the working row. */ + yy = 4; + + mvwprintw( main_window, yy++, tab1, "Enter the current year, four numeric digits, return key to submit" ); + + /* Print this line last so that the cursor is in the right place. */ + mvwprintw( main_window, 2, tab1, ">%s", date_buffer ); + + /* Reveal the cursor. */ + curs_set( 1 ); + + /* Refresh the window. */ + wrefresh( main_window ); + + /* Wait 250ms for input from getch, if nothing getch will then continue, + * This is necessary so that the while loop can be exited by the + * terminate_signal e.g.. the user pressing control-c to exit. + * Do not change this value, a higher value means the keys become + * sluggish, any slower and more time is spent unnecessarily looping + * which wastes CPU cycles. + */ + timeout( 250 ); // block getch() for 250ms. + keystroke = getch(); // Get a keystroke. + timeout( -1 ); // Switch back to blocking mode. + + switch( keystroke ) + { + /* Escape key. */ + case 27: + return; + + case KEY_BACKSPACE: + case KEY_LEFT: + case 127: + + if( idx > 0 ) + { + date_buffer[--idx] = 0; + } + + break; + + } /* switch keystroke */ + + if( ( keystroke >= ' ' && keystroke <= '~' ) && keystroke != '\"' && idx < FIELD_LENGTH && idx < 4 ) + { + date_buffer[idx++] = keystroke; + date_buffer[idx] = 0; + mvwprintw( main_window, 2, tab1, ">%s", date_buffer ); + } + + /* Hide the cursor. */ + curs_set( 0 ); + + } while( keystroke != 10 && terminate_signal != 1 ); + + /* Write year back to system */ + status = read_system_datetime( year, month, day, hours, minutes, seconds ); + if( status == 0 ) + { + nwipe_log( NWIPE_LOG_INFO, + "year=%s, month=%s, day=%s, hours=%s, minutes=%s, seconds=%s", + year, + month, + day, + hours, + minutes, + seconds ); + } + else + { + nwipe_log( NWIPE_LOG_ERROR, "func:read_system_datetime failed, see previous messages for detail" ); + } + +} /* End of nwipe_gui_set_system_year() */ + void nwipe_gui_load( void ) { /** diff --git a/src/gui.h b/src/gui.h index 518a5d57..84cd7c85 100644 --- a/src/gui.h +++ b/src/gui.h @@ -68,6 +68,7 @@ void nwipe_gui_add_customer_contact_name( char* ); // Add new customer contact void nwipe_gui_add_customer_contact_phone( char* ); // Add new customer contact phone int nwipe_gui_yes_no_footer( void ); // Change footer to yes no void nwipe_gui_preview_org_customer( void ); // Preview window for wipe organisation and customer +void nwipe_gui_set_system_year( void ); // Set the systems current year /** * Truncate a string based on start position and terminal width diff --git a/src/miscellaneous.c b/src/miscellaneous.c index 7eed896d..0b5c83d9 100644 --- a/src/miscellaneous.c +++ b/src/miscellaneous.c @@ -1,6 +1,6 @@ /* * miscellaneous.c: functions that may be generally used throughout nwipes code, - * mainly string processing related functions. + * mainly string processing functions but also time related functions. * * Copyright PartialVolume . * @@ -19,7 +19,19 @@ * */ +#ifndef _DEFAULT_SOURCE +#define _DEFAULT_SOURCE +#endif + +#ifndef _POSIX_SOURCE +#define _POSIX_SOURCE +#endif + +#include #include "nwipe.h" +#include "context.h" +#include "logging.h" +#include "miscellaneous.h" /* Convert string to upper case */ @@ -266,3 +278,247 @@ void convert_double_to_string( char* output_str, double value ) } output_str[idx3] = 0; } + +int read_system_datetime( char* year, char* month, char* day, char* hours, char* minutes, char* seconds ) +{ + /* Reads system date & time and populates the caller provided strings. + * Each string is null terminated by this function. The calling program + * must provide the minimum string sizes as shown below. + * + * year 5 bytes (4 numeric digits plus NULL terminator) + * month 3 bytes (2 numeric digits plus NULL terminator) + * day 3 bytes (2 numeric digits plus NULL terminator) + * hours 3 bytes (2 numeric digits plus NULL terminator) + * minutes 3 bytes (2 numeric digits plus NULL terminator) + * seconds 3 bytes (2 numeric digits plus NULL terminator) + * + * return value: + * 0 = success + * -1 = Failure, see nwipe log for detail. + */ + FILE* fp; + int r; // A result buffer. + int idx; // general index + int status = 0; + + /** + * Obtain the year + */ + fp = popen( "date +%Y", "r" ); + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_ERROR, "Failed to obtain system year using commmand = date +%Y" ); + } + else + { + /* Read the first line and validate it. Should be 4 numeric digits */ + if( fgets( year, FOUR_DIGITS + 1, fp ) != NULL ) + { + idx = 0; + while( idx < 4 ) + { + if( year[idx] >= '0' && year[idx] <= '9' ) + { + idx++; + } + else + { + /* if we haven't reached the correct number of digits due to invalid data, log error */ + year[++idx] = 0; /* terminate the string, prior to using in nwipe_log */ + nwipe_log( NWIPE_LOG_ERROR, + "Obtained system year using command = date +%Y, but result appears invalid = %s", + year ); + status = -1; + break; + } + } + year[idx] = 0; /* terminate the string */ + } + r = pclose( fp ); + } + + /** + * Obtain the month + */ + fp = popen( "date +%m", "r" ); + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_ERROR, "Failed to obtain system month using the command = date +%m" ); + } + else + { + /* Read the first line and validate it. Should be 2 numeric digits */ + if( fgets( month, TWO_DIGITS + 1, fp ) != NULL ) + { + idx = 0; + while( idx < 2 ) + { + if( month[idx] >= '0' && month[idx] <= '9' ) + { + idx++; + } + else + { + /* if we haven't reached the correct number of digits due to invalid data, log error */ + month[++idx] = 0; /* terminate the string, prior to using in nwipe_log */ + nwipe_log( NWIPE_LOG_ERROR, + "Obtained system month using command = date +%m, but result appears invalid = %s", + month ); + status = -1; + break; + } + } + month[idx] = 0; /* terminate the string */ + } + r = pclose( fp ); + } + + /** + * Obtain the day + */ + fp = popen( "date +\%d", "r" ); + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_ERROR, "Failed to obtain system day using the command = date +\%d" ); + } + else + { + /* Read the first line and validate it. Should be 2 numeric digits */ + if( fgets( day, TWO_DIGITS + 1, fp ) != NULL ) + { + idx = 0; + while( idx < 2 ) + { + if( day[idx] >= '0' && day[idx] <= '9' ) + { + idx++; + } + else + { + /* if we haven't reached the correct number of digits due to invalid data, log error */ + day[++idx] = 0; /* terminate the string, prior to using in nwipe_log */ + nwipe_log( NWIPE_LOG_ERROR, + "Obtained system day using command = date +\%d, but result appears invalid = %s", + day ); + status = -1; + break; + } + } + day[idx] = 0; /* terminate the string */ + } + r = pclose( fp ); + } + + /** + * Obtain the hours + */ + fp = popen( "date +%H", "r" ); + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_ERROR, "Failed to obtain system hour using the command = date +%H" ); + } + else + { + /* Read the first line and validate it. Should be 2 numeric digits */ + if( fgets( hours, TWO_DIGITS + 1, fp ) != NULL ) + { + // nwipe_log( NWIPE_LOG_INFO, "Seconds = %s, Year = %s", seconds, year); + idx = 0; + while( idx < 2 ) + { + if( hours[idx] >= '0' && hours[idx] <= '9' ) + { + idx++; + } + else + { + /* if we haven't reached the correct number of digits due to invalid data, log error */ + hours[++idx] = 0; /* terminate the string, prior to using in nwipe_log */ + nwipe_log( NWIPE_LOG_ERROR, + "Obtained system hours using command = date +%H, but result appears invalid = %s", + hours ); + status = -1; + break; + } + } + hours[idx] = 0; /* terminate the string */ + } + r = pclose( fp ); + } + + /** + * Obtain the minutes + */ + fp = popen( "date +%M", "r" ); + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_ERROR, "Failed to obtain system minutes using the command = date +%M" ); + } + else + { + /* Read the first line and validate it. Should be 2 numeric digits */ + if( fgets( minutes, TWO_DIGITS + 1, fp ) != NULL ) + { + // nwipe_log( NWIPE_LOG_INFO, "Seconds = %s, Year = %s", seconds, year); + idx = 0; + while( idx < 2 ) + { + if( minutes[idx] >= '0' && minutes[idx] <= '9' ) + { + idx++; + } + else + { + /* if we haven't reached the correct number of digits due to invalid data, log the error */ + minutes[++idx] = 0; /* terminate the string, prior to using in nwipe_log */ + nwipe_log( NWIPE_LOG_ERROR, + "Obtained system minutes using command = date +%H, but result appears invalid = %s", + minutes ); + status = -1; + break; + } + } + minutes[idx] = 0; /* terminate the string */ + } + r = pclose( fp ); + } + + /** + * Obtain the seconds + */ + fp = popen( "date +%S", "r" ); + if( fp == NULL ) + { + nwipe_log( NWIPE_LOG_ERROR, "Failed to obtain system seconds using the command = date +%S" ); + } + else + { + /* Read the first line and validate it. Should be 2 numeric digits */ + if( fgets( seconds, TWO_DIGITS + 1, fp ) != NULL ) + { + // nwipe_log( NWIPE_LOG_INFO, "Seconds = %s, Year = %s", seconds, year); + idx = 0; + while( idx < 2 ) + { + if( seconds[idx] >= '0' && seconds[idx] <= '9' ) + { + idx++; + } + else + { + /* if we haven't reached the correct number of digits due to invalid data, log error */ + seconds[++idx] = 0; /* terminate the string, prior to using in nwipe_log */ + nwipe_log( NWIPE_LOG_ERROR, + "Obtained system seconds using command = date +%S, but result appears invalid = %s", + seconds ); + status = -1; + break; + } + } + seconds[idx] = 0; /* terminate the string */ + } + r = pclose( fp ); + } + + return status; +} diff --git a/src/miscellaneous.h b/src/miscellaneous.h index a0ad0a78..bf14c08e 100644 --- a/src/miscellaneous.h +++ b/src/miscellaneous.h @@ -24,6 +24,9 @@ #ifndef MISCELLANEOUS_H_ #define MISCELLANEOUS_H_ +#define FOUR_DIGITS 4 +#define TWO_DIGITS 2 + /** * Convert the string from lower to upper case * @param pointer to a null terminated string @@ -87,4 +90,19 @@ void replace_non_alphanumeric( char*, char ); */ void convert_double_to_string( char*, double ); +/** + * Reads system date & time and populates the caller provided strings. + * Each string is null terminated by this function. The calling + * program must provide the minimum string sizes as shown below. + * + * @param char* year 5 bytes (4 numeric digits plus NULL terminator) + * @param char* month 3 bytes (2 numeric digits plus NULL terminator) + * @param char* day 3 bytes (2 numeric digits plus NULL terminator) + * @param char* hours 3 bytes (2 numeric digits plus NULL terminator) + * @param char* minutes 3 bytes (2 numeric digits plus NULL terminator) + * @param char* seconds 3 bytes (2 numeric digits plus NULL terminator) + * @return 0 = success, -1 = failure. See nwipe log for detail. + */ +int read_system_datetime( char*, char*, char*, char*, char*, char* ); + #endif /* HPA_DCO_H_ */