1 /*
2  * Stripe functions
3  *
4  * Copyright (C) 2014-2021, Joachim Metz <joachim.metz@gmail.com>
5  *
6  * Refer to AUTHORS for acknowledgements.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public License
19  * along with this program.  If not, see <https://www.gnu.org/licenses/>.
20  */
21 
22 #include <common.h>
23 #include <memory.h>
24 #include <types.h>
25 
26 #include "libvslvm_libcerror.h"
27 #include "libvslvm_stripe.h"
28 #include "libvslvm_types.h"
29 
30 /* Creates a stripe
31  * Make sure the value stripe is referencing, is set to NULL
32  * Returns 1 if successful or -1 on error
33  */
libvslvm_stripe_initialize(libvslvm_stripe_t ** stripe,libcerror_error_t ** error)34 int libvslvm_stripe_initialize(
35      libvslvm_stripe_t **stripe,
36      libcerror_error_t **error )
37 {
38 	libvslvm_internal_stripe_t *internal_stripe = NULL;
39 	static char *function                       = "libvslvm_stripe_initialize";
40 
41 	if( stripe == NULL )
42 	{
43 		libcerror_error_set(
44 		 error,
45 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
46 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
47 		 "%s: invalid stripe.",
48 		 function );
49 
50 		return( -1 );
51 	}
52 	if( *stripe != NULL )
53 	{
54 		libcerror_error_set(
55 		 error,
56 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
57 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
58 		 "%s: invalid stripe value already set.",
59 		 function );
60 
61 		return( -1 );
62 	}
63 	internal_stripe = memory_allocate_structure(
64 	                   libvslvm_internal_stripe_t );
65 
66 	if( internal_stripe == NULL )
67 	{
68 		libcerror_error_set(
69 		 error,
70 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
71 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
72 		 "%s: unable to create stripe.",
73 		 function );
74 
75 		goto on_error;
76 	}
77 	if( memory_set(
78 	     internal_stripe,
79 	     0,
80 	     sizeof( libvslvm_internal_stripe_t ) ) == NULL )
81 	{
82 		libcerror_error_set(
83 		 error,
84 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
85 		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
86 		 "%s: unable to clear stripe.",
87 		 function );
88 
89 		goto on_error;
90 	}
91 	*stripe = (libvslvm_stripe_t *) internal_stripe;
92 
93 	return( 1 );
94 
95 on_error:
96 	if( internal_stripe != NULL )
97 	{
98 		memory_free(
99 		 internal_stripe );
100 	}
101 	return( -1 );
102 }
103 
104 /* Frees a stripe
105  * Returns 1 if successful or -1 on error
106  */
libvslvm_stripe_free(libvslvm_stripe_t ** stripe,libcerror_error_t ** error)107 int libvslvm_stripe_free(
108      libvslvm_stripe_t **stripe,
109      libcerror_error_t **error )
110 {
111 	static char *function = "libvslvm_stripe_free";
112 
113 	if( stripe == NULL )
114 	{
115 		libcerror_error_set(
116 		 error,
117 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
118 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
119 		 "%s: invalid stripe.",
120 		 function );
121 
122 		return( -1 );
123 	}
124 	if( *stripe != NULL )
125 	{
126 		*stripe = NULL;
127 	}
128 	return( 1 );
129 }
130 
131 /* Frees a stripe
132  * Returns 1 if successful or -1 on error
133  */
libvslvm_internal_stripe_free(libvslvm_internal_stripe_t ** internal_stripe,libcerror_error_t ** error)134 int libvslvm_internal_stripe_free(
135      libvslvm_internal_stripe_t **internal_stripe,
136      libcerror_error_t **error )
137 {
138 	static char *function = "libvslvm_internal_stripe_free";
139 
140 	if( internal_stripe == NULL )
141 	{
142 		libcerror_error_set(
143 		 error,
144 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
145 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
146 		 "%s: invalid stripe.",
147 		 function );
148 
149 		return( -1 );
150 	}
151 	if( *internal_stripe != NULL )
152 	{
153 		if( ( *internal_stripe )->physical_volume_name != NULL )
154 		{
155 			memory_free(
156 			 ( *internal_stripe )->physical_volume_name );
157 		}
158 		memory_free(
159 		 *internal_stripe );
160 
161 		*internal_stripe = NULL;
162 	}
163 	return( 1 );
164 }
165 
166 /* Retrieves the size of the ASCII formatted physical volume name
167  * Returns 1 if successful or -1 on error
168  */
libvslvm_stripe_get_physical_volume_name_size(libvslvm_stripe_t * stripe,size_t * physical_volume_name_size,libcerror_error_t ** error)169 int libvslvm_stripe_get_physical_volume_name_size(
170      libvslvm_stripe_t *stripe,
171      size_t *physical_volume_name_size,
172      libcerror_error_t **error )
173 {
174 	libvslvm_internal_stripe_t *internal_stripe = NULL;
175 	static char *function                       = "libvslvm_stripe_get_physical_volume_name_size";
176 
177 	if( stripe == NULL )
178 	{
179 		libcerror_error_set(
180 		 error,
181 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
182 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
183 		 "%s: invalid stripe.",
184 		 function );
185 
186 		return( -1 );
187 	}
188 	internal_stripe = (libvslvm_internal_stripe_t *) stripe;
189 
190 	if( physical_volume_name_size == NULL )
191 	{
192 		libcerror_error_set(
193 		 error,
194 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
195 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
196 		 "%s: invalid physical volume name size.",
197 		 function );
198 
199 		return( -1 );
200 	}
201 	*physical_volume_name_size = internal_stripe->physical_volume_name_size;
202 
203 	return( 1 );
204 }
205 
206 /* Retrieves the ASCII formatted physical volume name
207  * Returns 1 if successful or -1 on error
208  */
libvslvm_stripe_get_physical_volume_name(libvslvm_stripe_t * stripe,char * physical_volume_name,size_t physical_volume_name_size,libcerror_error_t ** error)209 int libvslvm_stripe_get_physical_volume_name(
210      libvslvm_stripe_t *stripe,
211      char *physical_volume_name,
212      size_t physical_volume_name_size,
213      libcerror_error_t **error )
214 {
215 	libvslvm_internal_stripe_t *internal_stripe = NULL;
216 	static char *function                       = "libvslvm_stripe_get_physical_volume_name";
217 
218 	if( stripe == NULL )
219 	{
220 		libcerror_error_set(
221 		 error,
222 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
223 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
224 		 "%s: invalid stripe.",
225 		 function );
226 
227 		return( -1 );
228 	}
229 	internal_stripe = (libvslvm_internal_stripe_t *) stripe;
230 
231 	if( physical_volume_name == NULL )
232 	{
233 		libcerror_error_set(
234 		 error,
235 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
236 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
237 		 "%s: invalid physical volume name.",
238 		 function );
239 
240 		return( -1 );
241 	}
242 	if( physical_volume_name_size > (size_t) SSIZE_MAX )
243 	{
244 		libcerror_error_set(
245 		 error,
246 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
247 		 LIBCERROR_ARGUMENT_ERROR_VALUE_EXCEEDS_MAXIMUM,
248 		 "%s: invalid physical volume name size value exceeds maximum.",
249 		 function );
250 
251 		return( -1 );
252 	}
253 	if( physical_volume_name_size < internal_stripe->physical_volume_name_size )
254 	{
255 		libcerror_error_set(
256 		 error,
257 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
258 		 LIBCERROR_ARGUMENT_ERROR_VALUE_TOO_SMALL,
259 		 "%s: invalid physical volume name size value too small.",
260 		 function );
261 
262 		return( -1 );
263 	}
264 	if( memory_copy(
265 	     physical_volume_name,
266 	     internal_stripe->physical_volume_name,
267 	     internal_stripe->physical_volume_name_size ) == NULL )
268 	{
269 		libcerror_error_set(
270 		 error,
271 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
272 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
273 		 "%s: unable to copy physical volume name.",
274 		 function );
275 
276 		return( -1 );
277 	}
278 	physical_volume_name[ internal_stripe->physical_volume_name_size - 1 ] = 0;
279 
280 	return( 1 );
281 }
282 
283 /* Sets the physical volume name
284  * Returns 1 if successful or -1 on error
285  */
libvslvm_internal_stripe_set_physical_volume_name(libvslvm_internal_stripe_t * internal_stripe,const char * physical_volume_name,size_t physical_volume_name_size,libcerror_error_t ** error)286 int libvslvm_internal_stripe_set_physical_volume_name(
287      libvslvm_internal_stripe_t *internal_stripe,
288      const char *physical_volume_name,
289      size_t physical_volume_name_size,
290      libcerror_error_t **error )
291 {
292 	static char *function = "libvslvm_internal_stripe_set_physical_volume_name";
293 
294 	if( internal_stripe == NULL )
295 	{
296 		libcerror_error_set(
297 		 error,
298 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
299 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
300 		 "%s: invalid stripe.",
301 		 function );
302 
303 		return( -1 );
304 	}
305 	if( internal_stripe->physical_volume_name != NULL )
306 	{
307 		libcerror_error_set(
308 		 error,
309 		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
310 		 LIBCERROR_RUNTIME_ERROR_VALUE_ALREADY_SET,
311 		 "%s: invalid stripe - physical volume name value already set.",
312 		 function );
313 
314 		return( -1 );
315 	}
316 	if( physical_volume_name == NULL )
317 	{
318 		libcerror_error_set(
319 		 error,
320 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
321 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
322 		 "%s: invalid physical volume name.",
323 		 function );
324 
325 		return( -1 );
326 	}
327 	if( ( physical_volume_name_size == 0 )
328 	 || ( physical_volume_name_size > (size_t) MEMORY_MAXIMUM_ALLOCATION_SIZE ) )
329 	{
330 		libcerror_error_set(
331 		 error,
332 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
333 		 LIBCERROR_ARGUMENT_ERROR_VALUE_OUT_OF_BOUNDS,
334 		 "%s: invalid physical volume name size value out of bounds.",
335 		 function );
336 
337 		return( -1 );
338 	}
339 	internal_stripe->physical_volume_name = (char *) memory_allocate(
340 	                                                  sizeof( char ) * physical_volume_name_size );
341 
342 	if( internal_stripe->physical_volume_name == NULL )
343 	{
344 		libcerror_error_set(
345 		 error,
346 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
347 		 LIBCERROR_MEMORY_ERROR_INSUFFICIENT,
348 		 "%s: unable to create physical volume name.",
349 		 function );
350 
351 		goto on_error;
352 	}
353 	if( memory_copy(
354 	     internal_stripe->physical_volume_name,
355 	     physical_volume_name,
356 	     physical_volume_name_size ) == NULL )
357 	{
358 		libcerror_error_set(
359 		 error,
360 		 LIBCERROR_ERROR_DOMAIN_MEMORY,
361 		 LIBCERROR_MEMORY_ERROR_COPY_FAILED,
362 		 "%s: unable to copy physical volume name.",
363 		 function );
364 
365 		goto on_error;
366 	}
367 	internal_stripe->physical_volume_name[ physical_volume_name_size - 1 ] = 0;
368 
369 	internal_stripe->physical_volume_name_size = physical_volume_name_size;
370 
371 	return( 1 );
372 
373 on_error:
374 	if( internal_stripe->physical_volume_name != NULL )
375 	{
376 		memory_free(
377 		 internal_stripe->physical_volume_name );
378 
379 		internal_stripe->physical_volume_name = NULL;
380 	}
381 	internal_stripe->physical_volume_name_size = 0;
382 
383 	return( -1 );
384 }
385 
386 /* Retrieves the data area offset
387  * Returns 1 if successful or -1 on error
388  */
libvslvm_stripe_get_data_area_offset(libvslvm_stripe_t * stripe,off64_t * data_area_offset,libcerror_error_t ** error)389 int libvslvm_stripe_get_data_area_offset(
390      libvslvm_stripe_t *stripe,
391      off64_t *data_area_offset,
392      libcerror_error_t **error )
393 {
394 	libvslvm_internal_stripe_t *internal_stripe = NULL;
395 	static char *function                       = "libvslvm_stripe_get_data_area_offset";
396 
397 	if( stripe == NULL )
398 	{
399 		libcerror_error_set(
400 		 error,
401 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
402 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
403 		 "%s: invalid stripe.",
404 		 function );
405 
406 		return( -1 );
407 	}
408 	internal_stripe = (libvslvm_internal_stripe_t *) stripe;
409 
410 	if( data_area_offset == NULL )
411 	{
412 		libcerror_error_set(
413 		 error,
414 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
415 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
416 		 "%s: invalid data area offset.",
417 		 function );
418 
419 		return( -1 );
420 	}
421 	*data_area_offset = internal_stripe->data_area_offset;
422 
423 	return( 1 );
424 }
425 
426 /* Sets the data area offset
427  * Returns 1 if successful or -1 on error
428  */
libvslvm_stripe_set_data_area_offset(libvslvm_stripe_t * stripe,off64_t data_area_offset,libcerror_error_t ** error)429 int libvslvm_stripe_set_data_area_offset(
430      libvslvm_stripe_t *stripe,
431      off64_t data_area_offset,
432      libcerror_error_t **error )
433 {
434 	libvslvm_internal_stripe_t *internal_stripe = NULL;
435 	static char *function                       = "libvslvm_stripe_set_data_area_offset";
436 
437 	if( stripe == NULL )
438 	{
439 		libcerror_error_set(
440 		 error,
441 		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
442 		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
443 		 "%s: invalid stripe.",
444 		 function );
445 
446 		return( -1 );
447 	}
448 	internal_stripe = (libvslvm_internal_stripe_t *) stripe;
449 
450 	internal_stripe->data_area_offset = data_area_offset;
451 
452 	return( 1 );
453 }
454 
455