mirror of
https://github.com/martijnvanbrummelen/nwipe.git
synced 2026-02-20 13:42:14 +00:00
Merge pull request #676 from PartialVolume/Add_uuid_to_pdf_filename
Add device name, e.g sda, sdb etc to PDF filename Closes #664
This commit is contained in:
@@ -82,6 +82,12 @@ typedef struct nwipe_speedring_t_
|
|||||||
// 20 chracters for serial number plus null Byte
|
// 20 chracters for serial number plus null Byte
|
||||||
#define NWIPE_SERIALNUMBER_LENGTH 20
|
#define NWIPE_SERIALNUMBER_LENGTH 20
|
||||||
|
|
||||||
|
// UUID size
|
||||||
|
#define UUID_SIZE 40
|
||||||
|
|
||||||
|
// Device name max size including /dev/ path
|
||||||
|
#define DEVICE_NAME_MAX_SIZE 100
|
||||||
|
|
||||||
typedef struct nwipe_context_t_
|
typedef struct nwipe_context_t_
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
@@ -99,8 +105,9 @@ typedef struct nwipe_context_t_
|
|||||||
int device_minor; // The minor device number.
|
int device_minor; // The minor device number.
|
||||||
int device_part; // The device partition or slice number.
|
int device_part; // The device partition or slice number.
|
||||||
char* device_name; // The device file name.
|
char* device_name; // The device file name.
|
||||||
char device_name_without_path[100];
|
char device_name_without_path[DEVICE_NAME_MAX_SIZE];
|
||||||
char gui_device_name[100];
|
char gui_device_name[DEVICE_NAME_MAX_SIZE];
|
||||||
|
char device_name_terse[DEVICE_NAME_MAX_SIZE];
|
||||||
unsigned long long device_size; // The device size in bytes.
|
unsigned long long device_size; // The device size in bytes.
|
||||||
u64 device_size_in_sectors; // The device size in number of logical sectors, this may be 512 or 4096 sectors
|
u64 device_size_in_sectors; // The device size in number of logical sectors, this may be 512 or 4096 sectors
|
||||||
u64 device_size_in_512byte_sectors; // The device size in number of 512byte sectors, irrespective of logical sector
|
u64 device_size_in_512byte_sectors; // The device size in number of 512byte sectors, irrespective of logical sector
|
||||||
@@ -117,6 +124,7 @@ typedef struct nwipe_context_t_
|
|||||||
int device_is_ssd; // 0 = no SSD, 1 = is a SSD
|
int device_is_ssd; // 0 = no SSD, 1 = is a SSD
|
||||||
char device_serial_no[NWIPE_SERIALNUMBER_LENGTH
|
char device_serial_no[NWIPE_SERIALNUMBER_LENGTH
|
||||||
+ 1]; // Serial number(processed, 20 characters plus null termination) of the device.
|
+ 1]; // Serial number(processed, 20 characters plus null termination) of the device.
|
||||||
|
char device_UUID[UUID_SIZE]; // Only populated with the UUID if device is a partition
|
||||||
int device_target; // The device target.
|
int device_target; // The device target.
|
||||||
|
|
||||||
u64 eta; // The estimated number of seconds until method completion.
|
u64 eta; // The estimated number of seconds until method completion.
|
||||||
|
|||||||
@@ -801,18 +801,19 @@ int create_pdf( nwipe_context_t* ptr )
|
|||||||
* Create the reports filename
|
* Create the reports filename
|
||||||
*
|
*
|
||||||
* Sanitize the strings that we are going to use to create the report filename
|
* Sanitize the strings that we are going to use to create the report filename
|
||||||
* by converting any non alphanumeric characters to an underscore or hyphon
|
* by converting any non alphanumeric characters to an underscore or hyphen
|
||||||
*/
|
*/
|
||||||
replace_non_alphanumeric( end_time_text, '-' );
|
replace_non_alphanumeric( end_time_text, '-' );
|
||||||
replace_non_alphanumeric( c->device_model, '_' );
|
replace_non_alphanumeric( c->device_model, '_' );
|
||||||
replace_non_alphanumeric( c->device_serial_no, '_' );
|
replace_non_alphanumeric( c->device_serial_no, '_' );
|
||||||
snprintf( c->PDF_filename,
|
snprintf( c->PDF_filename,
|
||||||
sizeof( c->PDF_filename ),
|
sizeof( c->PDF_filename ),
|
||||||
"%s/nwipe_report_%s_Model_%s_Serial_%s.pdf",
|
"%s/nwipe_report_%s_Model_%s_Serial_%s_device_%s.pdf",
|
||||||
nwipe_options.PDFreportpath,
|
nwipe_options.PDFreportpath,
|
||||||
end_time_text,
|
end_time_text,
|
||||||
c->device_model,
|
c->device_model,
|
||||||
c->device_serial_no );
|
c->device_serial_no,
|
||||||
|
c->device_name_terse );
|
||||||
|
|
||||||
pdf_save( pdf, c->PDF_filename );
|
pdf_save( pdf, c->PDF_filename );
|
||||||
pdf_destroy( pdf );
|
pdf_destroy( pdf );
|
||||||
|
|||||||
27
src/device.c
27
src/device.c
@@ -216,6 +216,19 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
|
|||||||
/* remove /dev/ from device, right justify and prefix name so string length is eight characters */
|
/* remove /dev/ from device, right justify and prefix name so string length is eight characters */
|
||||||
nwipe_strip_path( next_device->device_name_without_path, next_device->device_name );
|
nwipe_strip_path( next_device->device_name_without_path, next_device->device_name );
|
||||||
|
|
||||||
|
const char* device_name_terse;
|
||||||
|
device_name_terse = skip_whitespace( next_device->device_name_without_path );
|
||||||
|
if( device_name_terse != NULL )
|
||||||
|
{
|
||||||
|
/* remove the leading whitespace and save result, we use the device without path and no leading or trailing
|
||||||
|
* space in pdf file creation later */
|
||||||
|
strcpy( next_device->device_name_terse, device_name_terse );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy( next_device->device_name_terse, "_" );
|
||||||
|
}
|
||||||
|
|
||||||
/* To maintain column alignment in the gui we have to remove /dev/ from device names that
|
/* To maintain column alignment in the gui we have to remove /dev/ from device names that
|
||||||
* exceed eight characters including the /dev/ path.
|
* exceed eight characters including the /dev/ path.
|
||||||
*/
|
*/
|
||||||
@@ -428,6 +441,20 @@ int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
|
|||||||
hpa_dco_status( next_device );
|
hpa_dco_status( next_device );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************
|
||||||
|
* Check whether the device has a UUID
|
||||||
|
*/
|
||||||
|
char uuid[UUID_SIZE] = "";
|
||||||
|
if( get_device_uuid( next_device->device_name, uuid ) == 0 )
|
||||||
|
{
|
||||||
|
strncpy( next_device->device_UUID, uuid, UUID_SIZE );
|
||||||
|
nwipe_log( NWIPE_LOG_INFO, "UUID for %s is: %s\n", next_device->device_name, next_device->device_UUID );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nwipe_log( NWIPE_LOG_INFO, "No UUID available for %s\n", next_device->device_name );
|
||||||
|
}
|
||||||
|
|
||||||
/* print an empty line to separate the drives in the log */
|
/* print an empty line to separate the drives in the log */
|
||||||
nwipe_log( NWIPE_LOG_INFO, " " );
|
nwipe_log( NWIPE_LOG_INFO, " " );
|
||||||
|
|
||||||
|
|||||||
@@ -32,6 +32,14 @@
|
|||||||
#include "context.h"
|
#include "context.h"
|
||||||
#include "logging.h"
|
#include "logging.h"
|
||||||
#include "miscellaneous.h"
|
#include "miscellaneous.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <ctype.h> // for isspace()
|
||||||
|
#include <stddef.h> // for NULL
|
||||||
|
|
||||||
/* Convert string to upper case
|
/* Convert string to upper case
|
||||||
*/
|
*/
|
||||||
@@ -739,3 +747,150 @@ void fix_endian_model_names( char* model )
|
|||||||
free( tmp_string );
|
free( tmp_string );
|
||||||
free( model_lower_case );
|
free( model_lower_case );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* get_device_uuid - Find the UUID corresponding to a given block device
|
||||||
|
* @device_path: e.g., "/dev/sda1"
|
||||||
|
* @uuid_buf: pointer to a 40-byte buffer where the UUID string will be stored
|
||||||
|
*
|
||||||
|
* Returns 0 on success, -1 on failure.
|
||||||
|
*/
|
||||||
|
int get_device_uuid( const char* device_path, char* uuid_buf )
|
||||||
|
{
|
||||||
|
const char* uuid_dir = "/dev/disk/by-uuid";
|
||||||
|
struct dirent* entry;
|
||||||
|
DIR* dir;
|
||||||
|
char link_path[PATH_MAX];
|
||||||
|
char resolved_path[PATH_MAX];
|
||||||
|
ssize_t len;
|
||||||
|
|
||||||
|
if( !device_path || !uuid_buf )
|
||||||
|
{
|
||||||
|
errno = EINVAL;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
dir = opendir( uuid_dir );
|
||||||
|
if( !dir )
|
||||||
|
{
|
||||||
|
perror( "opendir" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
while( ( entry = readdir( dir ) ) != NULL )
|
||||||
|
{
|
||||||
|
// Skip "." and ".."
|
||||||
|
if( strcmp( entry->d_name, "." ) == 0 || strcmp( entry->d_name, ".." ) == 0 )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
snprintf( link_path, sizeof( link_path ), "%s/%s", uuid_dir, entry->d_name );
|
||||||
|
|
||||||
|
// readlink() doesn't null-terminate, so we must handle that
|
||||||
|
len = readlink( link_path, resolved_path, sizeof( resolved_path ) - 1 );
|
||||||
|
if( len == -1 )
|
||||||
|
continue; // skip unreadable links
|
||||||
|
|
||||||
|
resolved_path[len] = '\0';
|
||||||
|
|
||||||
|
// Construct full path (readlink gives a relative path, usually "../../sda1")
|
||||||
|
char full_path[PATH_MAX + strlen( uuid_dir ) + 1];
|
||||||
|
if( resolved_path[0] != '/' )
|
||||||
|
{
|
||||||
|
// Resolve relative symlink path
|
||||||
|
snprintf( full_path, sizeof( full_path ), "%s/%s", uuid_dir, resolved_path );
|
||||||
|
if( realpath( full_path, full_path ) == NULL )
|
||||||
|
{
|
||||||
|
closedir( dir );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strncpy( full_path, resolved_path, sizeof( full_path ) );
|
||||||
|
full_path[sizeof( full_path ) - 1] = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compare with the given device path
|
||||||
|
if( strcmp( full_path, device_path ) == 0 )
|
||||||
|
{
|
||||||
|
strncpy( uuid_buf, entry->d_name, 40 );
|
||||||
|
uuid_buf[39] = '\0';
|
||||||
|
closedir( dir );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir( dir );
|
||||||
|
errno = ENOENT;
|
||||||
|
return -1; // not found
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find_base_device - searches /sys/block for a device that matches
|
||||||
|
* the prefix of the provided name.
|
||||||
|
*
|
||||||
|
* @devname: the input device name (e.g. "sda1", "sdb2")
|
||||||
|
* @result: buffer to store the matched base device name
|
||||||
|
* @size: size of the result buffer
|
||||||
|
*
|
||||||
|
* Returns: 0 on success (match found), -1 on failure (no match or error)
|
||||||
|
*/
|
||||||
|
int find_base_device( const char* devname, char* result, size_t size )
|
||||||
|
{
|
||||||
|
if( !devname || !result || size == 0 )
|
||||||
|
{
|
||||||
|
fprintf( stderr, "Invalid argument(s)\n" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
DIR* dir = opendir( "/sys/block" );
|
||||||
|
if( !dir )
|
||||||
|
{
|
||||||
|
perror( "opendir" );
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct dirent* entry;
|
||||||
|
int found = -1;
|
||||||
|
|
||||||
|
while( ( entry = readdir( dir ) ) != NULL )
|
||||||
|
{
|
||||||
|
// Skip "." and ".."
|
||||||
|
if( entry->d_name[0] == '.' )
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Check if the given devname starts with the block device name
|
||||||
|
size_t len = strlen( entry->d_name );
|
||||||
|
if( strncmp( devname, entry->d_name, len ) == 0 )
|
||||||
|
{
|
||||||
|
// Match found
|
||||||
|
strncpy( result, entry->d_name, size - 1 );
|
||||||
|
result[size - 1] = '\0';
|
||||||
|
found = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
closedir( dir );
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* skip_whitespace - Returns a pointer to the first non-whitespace character
|
||||||
|
* in a given string.
|
||||||
|
*
|
||||||
|
* @str: input string
|
||||||
|
*
|
||||||
|
* Returns: pointer to the first non-whitespace character,
|
||||||
|
* or NULL if str is NULL or the string contains only whitespace.
|
||||||
|
*/
|
||||||
|
const char* skip_whitespace( const char* str )
|
||||||
|
{
|
||||||
|
if( !str )
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
while( *str && isspace( (unsigned char) *str ) )
|
||||||
|
str++;
|
||||||
|
|
||||||
|
return *str ? str : NULL;
|
||||||
|
}
|
||||||
|
|||||||
@@ -129,4 +129,36 @@ int write_system_datetime( char*, char*, char*, char*, char*, char* );
|
|||||||
*/
|
*/
|
||||||
void fix_endian_model_names( char* model );
|
void fix_endian_model_names( char* model );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Obtains the UUID of the drive partition
|
||||||
|
*
|
||||||
|
* @param constchar* device path, example /dev/sda1
|
||||||
|
* @param char* pointer to UUID string UUID_SIZE long
|
||||||
|
* @return 0 = success, -1 = failure.
|
||||||
|
*/
|
||||||
|
int get_device_uuid( const char*, char* );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* find_base_device - searches /sys/block for a device that matches
|
||||||
|
* the prefix of the provided name.
|
||||||
|
*
|
||||||
|
* @devname: the input device name (e.g. "sda1", "sdb2")
|
||||||
|
* @result: buffer to store the matched base device name
|
||||||
|
* @size: size of the result buffer
|
||||||
|
*
|
||||||
|
* Returns: 0 on success (match found), -1 on failure (no match or error)
|
||||||
|
*/
|
||||||
|
int find_base_device( const char*, char*, size_t );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* skip_whitespace - Returns a pointer to the first non-whitespace character
|
||||||
|
* in a given string.
|
||||||
|
*
|
||||||
|
* @str: input string
|
||||||
|
*
|
||||||
|
* Returns: pointer to the first non-whitespace character,
|
||||||
|
* or NULL if str is NULL or the string contains only whitespace.
|
||||||
|
*/
|
||||||
|
const char* skip_whitespace( const char* );
|
||||||
|
|
||||||
#endif /* HPA_DCO_H_ */
|
#endif /* HPA_DCO_H_ */
|
||||||
|
|||||||
Reference in New Issue
Block a user