File: device.c

package info (click to toggle)
nwipe 0.26-1
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 372 kB
  • sloc: ansic: 3,838; makefile: 23; sh: 4
file content (218 lines) | stat: -rw-r--r-- 6,372 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
/*
 *  device.c:  Device routines for nwipe.
 *
 *  Copyright Darik Horn <dajhorn-dban@vanadac.com>.
 *  
 *  Modifications to original dwipe Copyright Andy Beverley <andy@andybev.com>
 *  
 *  This program is free software; you can redistribute it and/or modify it under
 *  the terms of the GNU General Public License as published by the Free Software
 *  Foundation, version 2.
 *
 *  This program is distributed in the hope that it will be useful, but WITHOUT
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 *  FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 *  details.
 *
 *  You should have received a copy of the GNU General Public License along with
 *  this program; if not, write to the Free Software Foundation, Inc.,
 *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 
 *
 */

#include <stdint.h>

#include "nwipe.h"
#include "context.h"
#include "method.h"
#include "options.h"
#include "logging.h"
#include <sys/ioctl.h>
#include <linux/hdreg.h> //Drive specific defs
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>

#include <parted/parted.h>
#include <parted/debug.h>

int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount );
char *trim(char *str);

int nwipe_device_scan( nwipe_context_t*** c )
{
	/**
	 * Scans the the filesystem for storage device names.
	 *
	 * @parameter device_names  A reference to a null array pointer.
	 * @modifies  device_names  Populates device_names with an array of nwipe_contect_t
	 * @returns                 The number of strings in the device_names array.
	 *
	 */

	PedDevice* dev = NULL;
        ped_device_probe_all();
	
	int dcount = 0;

        while ((dev = ped_device_get_next (dev)))
        {
                if (check_device(c, dev, dcount))
                        dcount++;
	}

	/* Return the number of devices that were found. */
	return dcount;

} /* nwipe_device_scan */

int nwipe_device_get( nwipe_context_t*** c, char **devnamelist, int ndevnames )
{
	/**
	 * Gets information about devices
	 *
	 * @parameter device_names  A reference to a null array pointer.
	 * @parameter devnamelist   An array of string pointers to the device names
	 * @parameter ndevnames     Number of elements in devnamelist
	 * @modifies  device_names  Populates device_names with an array of nwipe_contect_t
	 * @returns                 The number of strings in the device_names array.
	 *
	 */

	PedDevice* dev = NULL;
	
	int i;
	int dcount = 0;

	for(i = 0; i < ndevnames; i++) {

		dev = ped_device_get(devnamelist[i]);
		if (!dev)
			break;

		if (check_device(c, dev, dcount))
			dcount++;
	}

	/* Return the number of devices that were found. */
	return dcount;

} /* nwipe_device_get */

int check_device( nwipe_context_t*** c, PedDevice* dev, int dcount )
{
	/* Populate this struct, then assign it to overall array of structs. */
	nwipe_context_t* next_device;
	int fd;
	int idx;

	/* Check whether this drive is on the excluded drive list ? */
	idx=0;
	while ( idx < 10 )
	{
		if ( !strcmp( dev->path, nwipe_options.exclude[idx++] ))
		{
			nwipe_log( NWIPE_LOG_NOTICE, "Device %s excluded as per command line option -e", dev->path );
			return 0;
		}
	}

	/* Try opening the device to see if it's valid. Close on completion. */
	if (!ped_device_open(dev))
	{
		nwipe_log( NWIPE_LOG_FATAL, "Unable to open device" );
		return 0;
	}
	ped_device_close(dev);
        
	/* New device, reallocate memory for additional struct pointer */
	*c = realloc (*c, (dcount+1) * sizeof(nwipe_context_t *));
        
	next_device = malloc (sizeof(nwipe_context_t)); 

	/* Check the allocation. */
	if( ! next_device )
	{
		nwipe_perror( errno, __FUNCTION__, "malloc" );
		nwipe_log( NWIPE_LOG_FATAL, "Unable to create the array of enumeration contexts." );
		return 0;
	}

	/* Zero the allocation. */
	memset( next_device , 0, sizeof( nwipe_context_t ) );

	/* Get device information */
	next_device->label = dev->model;
	next_device->device_name = dev->path;
	next_device->device_size = dev->length * dev->sector_size;
	next_device->device_size_text = ped_unit_format_byte(dev, dev->length * dev->sector_size);
	/* Attempt to get serial number of device. */
	if ( (fd = open ( next_device->device_name = dev->path, O_RDONLY)) == ERR )
	{
		nwipe_log( NWIPE_LOG_WARNING, "Unable to open device %s to obtain serial number", next_device->device_name );
	}
	/* We don't check the ioctl return status because there are plenty of situations where a serial number may not be
	 * returned by ioctl such as USB drives, logical volumes, encryted volumes, so the log file would have multiple
	 * benign ioctl errors reported which isn't necessarily a problem.
	 */
	ioctl(fd, HDIO_GET_IDENTITY, &next_device->identity);
	close( fd );

    for (idx=0; idx<20; idx++) next_device->serial_no[idx]=next_device->identity.serial_no[idx];
    
    next_device->serial_no[20]=0;               /* terminate the string */
    trim ( (char*) next_device->serial_no );    /* Remove leading/training whitespace from serial number and left justify */

    nwipe_log( NWIPE_LOG_INFO,"Found drive model=\"%s\", device path=\"%s\", size=\"%s\", serial number=\"%s\"", next_device->label, next_device->device_name, next_device->device_size_text, next_device->serial_no);

	(*c)[dcount] = next_device;
        
	return 1;
}

/* Remove leading/training whitespace from a string and left justify result */
char *trim(char *str)
{
	size_t len = 0;
	char *frontp = str;
	char *endp = NULL;

	if( str == NULL )
	{ 
		return NULL;
	}
	if( str[0] == '\0' )
	{ 
		return str;
	}
	len = strlen(str);
	endp = str + len;

	/* Move the front and back pointers to address the first non-whitespace
	 * characters from each end.
	 */
	while( isspace((unsigned char) *frontp) ) { ++frontp; }
	if( endp != frontp )
	{
		while( isspace((unsigned char) *(--endp)) && endp != frontp ) {}
	}
	if( str + len - 1 != endp )
		*(endp + 1) = '\0';
	else if( frontp != str &&  endp == frontp )
		*str = '\0';
	/* Shift the string so that it starts at str so that if it's dynamically
	 * allocated, we can still free it on the returned pointer.  Note the reuse
	 * of endp to mean the front of the string buffer now.
	 */
	endp = str;
	if( frontp != str )
	{
		while( *frontp ) { *endp++ = *frontp++; }
		*endp = '\0';
	}
	return str;
}

/* eof */