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_ */