diff --git a/src/gui.c b/src/gui.c index 8ff51d4..bffb0f3 100644 --- a/src/gui.c +++ b/src/gui.c @@ -103,6 +103,8 @@ #define NWIPE_GUI_MAIN_Y 8 #define NWIPE_GUI_MAIN_X 0 +#define SKIP_DEV_PREFIX 5 + /* Window pointers. */ WINDOW* footer_window; @@ -339,17 +341,50 @@ void nwipe_gui_free( void ) */ /* Free ncurses resources. */ - del_panel( footer_panel ); - del_panel( header_panel ); - del_panel( main_panel ); - del_panel( options_panel ); - del_panel( stats_panel ); - delwin( footer_window ); - delwin( header_window ); - delwin( main_window ); - delwin( options_window ); - delwin( stats_window ); - endwin(); + if( del_panel( footer_panel ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting footer panel failed!." ); + } + if( del_panel( header_panel ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting header panel failed!." ); + } + if( del_panel( main_panel ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting main panel failed!." ); + } + if( del_panel( options_panel ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting options panel failed!." ); + } + if( del_panel( stats_panel ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting stats panel failed!." ); + } + if( delwin( footer_window ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting footer window failed!." ); + } + if( delwin( header_window ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting header window failed!." ); + } + if( delwin( main_window ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting main window failed!." ); + } + if( delwin( options_window ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting options window failed!." ); + } + if( delwin( stats_window ) != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Deleting stats window failed!." ); + } + if( endwin() != OK ) + { + nwipe_log( NWIPE_LOG_ERROR, "Curses endwin() failed !" ); + } } /* nwipe_gui_free */ @@ -368,6 +403,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) * */ + extern int terminate_signal; + /* Widget labels. */ const char* select_title = " Disks and Partitions "; @@ -449,8 +486,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) { case NWIPE_SELECT_TRUE: - wprintw( main_window, " [wipe] %i. %s - %s %s (%s)", (i + offset + 1), - c[i+offset]->device_name, + wprintw( main_window, " [wipe] %i. %s - %s, S/N:%s, (%s)", (i + offset + 1), + c[i+offset]->device_name+SKIP_DEV_PREFIX, c[i+offset]->label, c[i+offset]->serial_no, c[i+offset]->device_size_text ); @@ -458,8 +495,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) case NWIPE_SELECT_FALSE: /* Print an element that is not selected. */ - wprintw( main_window, " [ ] %i. %s - %s %s (%s)", (i + offset +1), - c[i+offset]->device_name, + wprintw( main_window, " [ ] %i. %s - %s, S/N:%s, (%s)", (i + offset +1), + c[i+offset]->device_name+SKIP_DEV_PREFIX, c[i+offset]->label, c[i+offset]->serial_no, c[i+offset]->device_size_text ); @@ -468,8 +505,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) case NWIPE_SELECT_TRUE_PARENT: /* This element will be wiped when its parent is wiped. */ - wprintw( main_window, " [****] %i. %s - %s %s (%s)", (i + offset +1), - c[i+offset]->device_name, + wprintw( main_window, " [****] %i. %s - %s, S/N:%s, (%s)", (i + offset +1), + c[i+offset]->device_name+SKIP_DEV_PREFIX, c[i+offset]->label, c[i+offset]->serial_no, c[i+offset]->device_size_text ); @@ -478,8 +515,8 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) case NWIPE_SELECT_FALSE_CHILD: /* We can't wipe this element because it has a child that is being wiped. */ - wprintw( main_window, " [----] %i. %s - %s %s (%s)", (i + offset +1), - c[i+offset]->device_name, + wprintw( main_window, " [----] %i. %s - %s, S/N:%s, (%s)", (i + offset +1), + c[i+offset]->device_name+SKIP_DEV_PREFIX, c[i+offset]->label, c[i+offset]->serial_no, c[i+offset]->device_size_text ); @@ -521,9 +558,17 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) /* Refresh the window. */ wrefresh( main_window ); - - /* Get user input. */ - keystroke = getch(); + + /* 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 user input. */ + timeout(-1); /* Switch back to blocking mode */ switch( keystroke ) { @@ -750,10 +795,11 @@ void nwipe_gui_select( int count, nwipe_context_t** c ) /* Run the noblank dialog. */ nwipe_gui_noblank(); break; + } /* keystroke switch */ - } while( keystroke != 'S' && keystroke != ERR ); + } while( keystroke != 'S' && terminate_signal !=1); /* Clear the main window. */ werase( main_window ); @@ -857,6 +903,8 @@ void nwipe_gui_rounds( void ) /* Input buffer. */ int keystroke; + + extern int terminate_signal; /* Erase the footer window. */ werase( footer_window ); @@ -904,8 +952,16 @@ void nwipe_gui_rounds( void ) /* Refresh the window. */ wrefresh( main_window ); - /* Get a keystroke. */ - keystroke = getch(); + /* 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 ) { @@ -945,7 +1001,7 @@ void nwipe_gui_rounds( void ) /* Hide the cursor. */ curs_set( 0 ); - } while( keystroke != 10 && keystroke != ERR ); + } while( keystroke != 10 && terminate_signal !=1 ); if( focus > 0 ) { @@ -969,6 +1025,7 @@ void nwipe_gui_prng( void ) extern nwipe_prng_t nwipe_twister; extern nwipe_prng_t nwipe_isaac; + extern int terminate_signal; /* The number of implemented PRNGs. */ const int count = 2; @@ -1053,8 +1110,16 @@ void nwipe_gui_prng( void ) /* Refresh the window. */ wrefresh( main_window ); - /* Get a keystroke. */ - keystroke = getch(); + /* 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 ) { @@ -1088,7 +1153,7 @@ void nwipe_gui_prng( void ) } /* switch */ } - while( keystroke != ERR ); + while( terminate_signal != 1 ); } /* nwipe_gui_prng */ @@ -1104,6 +1169,8 @@ void nwipe_gui_verify( void ) * */ + extern int terminate_signal; + /* The number of definitions in the nwipe_verify_t enumeration. */ const int count = 3; @@ -1188,8 +1255,16 @@ void nwipe_gui_verify( void ) /* Refresh the window. */ wrefresh( main_window ); - /* Get a keystroke. */ - keystroke = getch(); + /* 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 ) { @@ -1223,7 +1298,7 @@ void nwipe_gui_verify( void ) } /* switch */ } - while( keystroke != ERR ); + while( terminate_signal != 1 ); } /* nwipe_gui_verify */ @@ -1238,6 +1313,8 @@ void nwipe_gui_noblank( void ) * */ + extern int terminate_signal; + /* The number of options available. */ const int count = 2; @@ -1309,8 +1386,16 @@ void nwipe_gui_noblank( void ) /* Refresh the window. */ wrefresh( main_window ); - /* Get a keystroke. */ - keystroke = getch(); + /* 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 ) { @@ -1345,7 +1430,7 @@ void nwipe_gui_noblank( void ) } - while( keystroke != ERR ); + while( terminate_signal != 1 ); } /* nwipe_gui_noblank */ @@ -1359,6 +1444,8 @@ void nwipe_gui_method( void ) * */ + extern int terminate_signal; + /* The number of implemented methods. */ const int count = 7; @@ -1505,8 +1592,16 @@ void nwipe_gui_method( void ) /* Refresh the window. */ wrefresh( main_window ); - /* Get a keystroke. */ - keystroke = getch(); + /* 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 ) { @@ -1531,7 +1626,7 @@ void nwipe_gui_method( void ) } /* switch */ - } while( keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10 && keystroke != ERR ); + } while( keystroke != KEY_ENTER && keystroke != ' ' && keystroke != 10 && terminate_signal != 1 ); switch( focus ) @@ -1635,6 +1730,8 @@ void *nwipe_gui_status( void *ptr ) * */ + extern int terminate_signal; + nwipe_thread_data_ptr_t *nwipe_thread_data_ptr; nwipe_thread_data_ptr = (nwipe_thread_data_ptr_t *) ptr; @@ -1721,7 +1818,7 @@ void *nwipe_gui_status( void *ptr ) nwipe_gui_title( footer_window, nwipe_buttons3 ); wrefresh( footer_window ); - while ( nwipe_active ) { + while ( nwipe_active && terminate_signal != 1) { /* Get the current time. */ nwipe_time_now = time( NULL ); @@ -1835,12 +1932,12 @@ void *nwipe_gui_status( void *ptr ) /* Print the context label. */ if ( strlen((const char*)c[i]->serial_no) ) { - mvwprintw( main_window, yy++, 2, "%s - %s (%s)", c[i]->device_name, + mvwprintw( main_window, yy++, 2, "%s - %s (S/N:%s)", c[i]->device_name+SKIP_DEV_PREFIX, c[i]->label, c[i]->serial_no); } else { - mvwprintw( main_window, yy++, 2, "%s - %s", c[i]->device_name, + mvwprintw( main_window, yy++, 2, "%s - %s", c[i]->device_name+SKIP_DEV_PREFIX, c[i]->label ); } diff --git a/src/nwipe.c b/src/nwipe.c index f766b26..4a4d06d 100644 --- a/src/nwipe.c +++ b/src/nwipe.c @@ -46,6 +46,8 @@ #include #include +int terminate_signal; + int main( int argc, char** argv ) { int nwipe_optind; /* The result of nwipe_options(). */ @@ -64,6 +66,9 @@ int main( int argc, char** argv ) /* The generic result buffer. */ int r; + + /* Initialise the termintaion signal, 1=terminate nwipe */ + terminate_signal = 0; /* Two arrays are used, containing pointers to the the typedef for each disk */ /* The first array (c1) points to all devices, the second points to only */ @@ -420,9 +425,10 @@ int main( int argc, char** argv ) errno = pthread_create( &nwipe_gui_thread, NULL, nwipe_gui_status, &nwipe_gui_data); } - /* Wait for all the wiping threads to finish. */ + + /* Wait for all the wiping threads to finish, but don't wait if we receive the terminate signal */ i = 0; - while( i < nwipe_selected ) + while( i < nwipe_selected && terminate_signal == 0 ) { if( i == nwipe_selected ) { @@ -440,8 +446,24 @@ int main( int argc, char** argv ) } sleep( 2 ); /* DO NOT REMOVE ! Stops the routine hogging CPU cycles */ } - - /* Now cancel the wipe threads */ + + + if ( terminate_signal == 1 ) + { + nwipe_log( NWIPE_LOG_INFO, "Program interrupted" ); + } + else + { + if( !nwipe_options.nowait ) + { + /* Wait for the user to press enter to exit */ + nocbreak(); + getch(); + } + } + nwipe_log( NWIPE_LOG_INFO, "Exit in progress" ); + + /* Send a REQUEST for the wipe threads to be cancelled */ for( i = 0 ; i < nwipe_selected ; i++ ) { @@ -450,7 +472,36 @@ int main( int argc, char** argv ) nwipe_log( NWIPE_LOG_INFO, "main():Cancelling wipe thread for %s", c2[i]->device_name ); nwipe_log( NWIPE_LOG_INFO, "main():Please wait.. disk cache is being flushed" ); pthread_cancel( c2[i]->thread ); + } + } + /* Kill the GUI thread */ + if ( nwipe_gui_thread ) + { + nwipe_log( NWIPE_LOG_INFO, "Cancelling the GUI thread." ); + + /* We don't want to use pthread_cancel as our GUI thread is aware of the control-c + * signal and will exit itself we just join the GUI thread and wait for confirmation + */ + r = pthread_join( nwipe_gui_thread, NULL ); + if( r != 0 ) + { + nwipe_log( NWIPE_LOG_WARNING, "main()>pthread_join():Error when waiting for GUI thread to cancel." ); + } + } + + /* Release the gui. */ + if( !nwipe_options.nogui ) + { + nwipe_gui_free(); + } + + /* Now join the wipe threads and wait until they have terminated */ + for( i = 0 ; i < nwipe_selected ; i++ ) + { + + if ( c2[i]->thread ) + { /* Joins the thread and waits for completion before continuing */ r = pthread_join( c2[i]->thread, NULL); if( r != 0 ) @@ -465,27 +516,6 @@ int main( int argc, char** argv ) } - - /* Kill the GUI thread */ - /* It may not be running if the program was interrupted */ - if ( nwipe_gui_thread ) - { - pthread_join( nwipe_gui_thread, NULL ); - - nocbreak(); - // timeout(-1); - /* Wait for enter key to be pressed unless --nowait - was specified. */ - if( !nwipe_options.nowait ) - getch(); - - /* Release the gui. */ - nwipe_gui_free(); - - } - - nwipe_log( NWIPE_LOG_NOTICE, "Nwipe exited." ); - for( i = 0 ; i < nwipe_selected ; i++ ) { @@ -501,6 +531,8 @@ int main( int argc, char** argv ) if( c2[i]->result > 0 ){ return 1; } } + + nwipe_log( NWIPE_LOG_NOTICE, "Nwipe Successfully Exited." ); /* Flush any remaining logs. */ for (i=0; i < log_current_element; i++) @@ -529,7 +561,6 @@ void *signal_hand(void *ptr) sigaddset(&sigset, SIGUSR1); int i; - int r; /* Generic result buffer */ /* Set up the structs we will use for the data required. */ nwipe_thread_data_ptr_t *nwipe_thread_data_ptr; @@ -601,55 +632,14 @@ void *signal_hand(void *ptr) case SIGQUIT : case SIGTERM : { - nwipe_log( NWIPE_LOG_INFO, "nwipe_selected = %lu", nwipe_misc_thread_data->nwipe_selected ); + /* Set termination flag for main() which will do housekeeping prior to exit */ + terminate_signal = 1; - for( i = 0; i < nwipe_misc_thread_data->nwipe_selected; i++ ) - { - if ( c[i]->thread ) - { - nwipe_log( NWIPE_LOG_INFO, "Cancelling thread for %s", c[i]->device_name ); - nwipe_log( NWIPE_LOG_INFO, "Please be patient.. disk cache is being flushed" ); - pthread_cancel( c[i]->thread ); - - r = pthread_join( c[i]->thread, NULL); - if( r != 0 ) - { - nwipe_log( NWIPE_LOG_WARNING, "signal_hand()>pthread_join():Error when waiting for wipe thread to cancel." ); - } - } - } - // Kill the GUI thread - if( !nwipe_options.nogui ) - { - if ( *nwipe_misc_thread_data->gui_thread ) - { - pthread_cancel( *nwipe_misc_thread_data->gui_thread ); - - r = pthread_join( *nwipe_misc_thread_data->gui_thread, NULL); - if( r != 0 ) - { - nwipe_log( NWIPE_LOG_WARNING, "signal_hand()>pthread_join():Error when waiting for GUI thread to cancel." ); - } - - *nwipe_misc_thread_data->gui_thread = 0; - } - } + /* Return control to the main thread, returning the signal received */ + return((void *)0); - if( !nwipe_options.nogui ) - nwipe_gui_free(); - - /* Flush any remaining logs. */ - for (i=0; i < log_current_element; i++) - { - printf("%s\n", log_lines[i]); - } - - printf("Program interrupted (caught signal %d)\n", sig); - - cleanup(); - - exit(0); + break; } /* end case */ @@ -657,7 +647,7 @@ void *signal_hand(void *ptr) } /* end of while */ - return((void *)0); + return(0); } /* end of signal_hand */ diff --git a/src/nwipe.h b/src/nwipe.h index b9eb077..86693bd 100644 --- a/src/nwipe.h +++ b/src/nwipe.h @@ -21,6 +21,7 @@ */ + #ifndef NWIPE_H_ #define NWIPE_H_