source: MondoRescue/trunk/mondo/src/common/libmondo-mountlist.c@ 2497

Last change on this file since 2497 was 2497, checked in by Bruno Cornec, 14 years ago

Tags MondoRescue version 2.2.9.1

  • Property svn:keywords set to Id
File size: 34.1 KB
RevLine 
[1081]1/* subroutines for handling mountlist
2 $Id: libmondo-mountlist.c 2497 2009-11-29 02:25:26Z bruno $
[1]3*/
4
[1176]5
[1]6/**
7 * @file
8 * Functions which manipulate the mountlist.
9 */
10
11#include "my-stuff.h"
12#include "mondostructures.h"
13#include "libmondo-mountlist.h"
14#include "libmondo-raid-EXT.h"
15#include "libmondo-devices-EXT.h"
16#include "libmondo-tools-EXT.h"
17#include "libmondo-string-EXT.h"
[507]18#include "newt-specific-EXT.h"
[900]19#include "mr_mem.h"
[1161]20#include "mr_msg.h"
[1]21
22/*@unused@*/
[48]23//static char cvsid[] = "$Id: libmondo-mountlist.c 2497 2009-11-29 02:25:26Z bruno $";
[1]24
[2497]25/* Reference to global bkpinfo */
26extern struct s_bkpinfo *bkpinfo;
27
[1]28/**
29 * @addtogroup mountlistGroup
30 * @{
31 */
32/**
33 * Evaluate a drive within the mountlist for flaws. For example, too many
34 * primary partitions, the first logical isn't 5, duplicate partitions,
35 * ovar-allocated or under-allocated, unsupported format, silly size, or
36 * silly mountpoint. Under FreeBSD, this checks the disklabel too, for the above-mentioned
37 * errors as well as too many BSD partitions (more than 'h').
38 * @param mountlist The mountlist to check.
39 * @param drive The drive to check (e.g. @c /dev/hda).
40 * @param flaws_str Where to put the found flaws (human-readable).
41 * @return The number of flaws found (0 for success).
42 * @see evaluate_mountlist
43 */
[48]44int evaluate_drive_within_mountlist(struct mountlist_itself *mountlist,
45 char *drive, char *flaws_str)
[1]46#ifdef __FreeBSD__
47{
48// FreeBSD-specific version of evaluate_drive_within_mountlist()
[48]49 /*@ int ************************************************************* */
50 int prev_part_no = 0;
[1]51 int curr_part_no = 0;
52 int pos = 0, npos = 0;
53 int res = 0;
54 int mountpoint_copies = 0;
55 int device_copies = 0;
56 int i = 0;
57 int cur_sp_no = 0;
58 int prev_sp_no = 0;
59 int foundsome = FALSE;
60
[48]61 /*@ buffers ******************************************************** */
[688]62 char *tmp = NULL;
63 char *tmp1 = NULL;
64 char *device = NULL;
[783]65 char *ndevice = NULL;
[48]66 // BERLIOS : useless ? char *mountpoint;
[1]67
[48]68 /*@ long *********************************************************** */
69 long physical_drive_size = 0;
[1]70 long amount_allocated = 0;
71
[48]72 /*@ pointers ******************************************************* */
[688]73 char *part_table_fmt = NULL;
[1]74
[48]75 /*@ initialize ***************************************************** */
76 prev_part_no = 0;
[1]77
78
[48]79 physical_drive_size = get_phys_size_of_drive(drive);
[1]80
[48]81 if (physical_drive_size < 0) {
[1176]82 mr_asprintf(&tmp, "%s %s does not exist.", flaw_str, drive);
83 mr_free(flaw_str);
[688]84 flaws_str = tmp;
[48]85 } else {
[900]86 mr_asprintf(&tmp, "%s is %ld MB", drive, physical_drive_size);
[688]87 flaws_str = NULL;
[48]88 }
89 log_it(tmp);
[900]90 mr_free(tmp);
[1]91
92
[48]93 /* check DD */
94 for (cur_sp_no = 'a'; cur_sp_no < 'z'; ++cur_sp_no) {
[900]95 mr_asprintf(&device, "%s%c", drive, cur_sp_no);
[48]96 if (find_device_in_mountlist(mountlist, device) >= 0)
97 foundsome = TRUE;
[900]98 mr_free(device);
[48]99 }
100 if (foundsome) {
101 for (cur_sp_no = 'a'; cur_sp_no < 'z'; ++cur_sp_no) {
[900]102 mr_asprintf(&device, "%s%c", drive, cur_sp_no);
[48]103 pos = find_device_in_mountlist(mountlist, device);
104 if (pos < 0) {
105 continue;
106 }
[900]107 // BERLIOS : useless ? mr_asprintf(&mountpoint, mountlist->el[pos].mountpoint);
[48]108 /* is it too big? */
109 if (curr_part_no > 'h') {
[900]110 mr_asprintf(&tmp, " Can only have up to 'h' in disklabel.");
[48]111 log_it(tmp);
[688]112 if (flaws_str) {
[900]113 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]114 } else {
[900]115 mr_asprintf(&tmp1, "%s", tmp);
[688]116 }
[900]117 mr_free(flaws_str);
[688]118 flaws_str = tmp1;
[900]119 mr_free(tmp);
[48]120 res++;
121 }
122 /* does partition /dev/adXsYZ exist more than once in the mountlist? */
123 for (i = 0, mountpoint_copies = 0, device_copies = 0;
124 i < mountlist->entries; i++) {
125 if (!strcmp(device, mountlist->el[i].device)) {
126 device_copies++;
127 }
128 }
129 if (device_copies > 1) {
[900]130 mr_asprintf(&tmp, " %s %s's.", number_to_text(device_copies),
[59]131 device);
[48]132 if (!strstr(flaws_str, tmp)) {
133 log_it(tmp);
[688]134 if (flaws_str) {
[900]135 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]136 } else {
[900]137 mr_asprintf(&tmp1, "%s", tmp);
[688]138 }
[900]139 mr_free(flaws_str);
[688]140 flaws_str = tmp1;
[48]141 res++;
142 }
[900]143 mr_free(tmp);
[48]144 }
145 /* silly partition size? */
146 if (mountlist->el[pos].size < 8192
147 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
[900]148 mr_asprintf(&tmp, " %s is tiny!", device);
[48]149 log_it(tmp);
[688]150 if (flaws_str) {
[900]151 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]152 } else {
[900]153 mr_asprintf(&tmp1, "%s", tmp);
[688]154 }
[900]155 mr_free(flaws_str);
[688]156 flaws_str = tmp1;
[900]157 mr_free(tmp);
[48]158 res++;
159 }
160 /* mountpoint should begin with / unless it is swap, lvm or raid */
161 if (strcmp(mountlist->el[pos].mountpoint, "swap")
162 && strcmp(mountlist->el[pos].mountpoint, "lvm")
163 && strcmp(mountlist->el[pos].mountpoint, "raid")
164 && strcmp(mountlist->el[pos].mountpoint, "image")
165 && strcmp(mountlist->el[pos].mountpoint, "none")
166 && mountlist->el[pos].mountpoint[0] != '/') {
[900]167 mr_asprintf(&tmp, " %s has a weird mountpoint.", device);
[48]168 log_it(tmp);
[688]169 if (flaws_str) {
[900]170 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]171 } else {
[900]172 mr_asprintf(&tmp1, "%s", tmp);
[688]173 }
[900]174 mr_free(flaws_str);
[688]175 flaws_str = tmp1;
[900]176 mr_free(tmp);
[48]177 res++;
178 }
179 /* is format sensible? */
180 if (!is_this_a_valid_disk_format(mountlist->el[pos].format)) {
[900]181 mr_asprintf(&tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
[48]182 log_it(tmp);
[688]183 if (flaws_str) {
[900]184 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]185 } else {
[900]186 mr_asprintf(&tmp1, "%s", tmp);
[688]187 }
[900]188 mr_free(flaws_str);
[688]189 flaws_str = tmp1;
[900]190 mr_free(tmp);
[48]191 res++;
192 }
193 amount_allocated += mountlist->el[pos].size / 1024;
194 prev_sp_no = cur_sp_no;
[1]195
[900]196 mr_free(device);
[48]197 }
198 }
199
200 npos = pos = 0;
201 for (curr_part_no = 1; curr_part_no < 99; curr_part_no++) {
[900]202 mr_asprintf(&device, "%ss%d", drive, curr_part_no);
[48]203 pos = find_device_in_mountlist(mountlist, device);
204 npos = 0;
205 for (cur_sp_no = 'a'; cur_sp_no <= 'h'; cur_sp_no++) {
[900]206 mr_asprintf(&ndevice, "%ss%d%c", device, curr_part_no, cur_sp_no);
[783]207 if (find_device_in_mountlist(mountlist, ndevice) >= 0)
[48]208 npos++;
[900]209 mr_free(ndevice);
[48]210 }
[900]211 mr_free(device);
[48]212
213 if (((pos >= 0) || npos) && foundsome) {
[900]214 mr_asprintf(&tmp, " %s has both DD and PC-style partitions.", drive);
[688]215 if (flaws_str) {
[900]216 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]217 } else {
[900]218 mr_asprintf(&tmp1, "%s", tmp);
[688]219 }
[900]220 mr_free(flaws_str);
[688]221 flaws_str = tmp1;
[900]222 mr_free(tmp);
[48]223 return ++res; // fatal error
224 }
[1176]225
226 mr_asprintf(&device, "%ss%d", drive, curr_part_no);
[900]227 // BERLIOS : useless ? mr_asprintf(&mountpoint, mountlist->el[pos].mountpoint);
[48]228 if (pos > 0 && !npos) {
229 /* gap in the partition list? */
230 if (curr_part_no - prev_part_no > 1) {
231 if (prev_part_no == 0) {
[900]232 mr_asprintf(&tmp, " Gap prior to %s.", device);
[48]233 log_it(tmp);
[688]234 if (flaws_str) {
[900]235 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]236 } else {
[900]237 mr_asprintf(&tmp1, "%s", tmp);
[688]238 }
[900]239 mr_free(flaws_str);
[688]240 flaws_str = tmp1;
[900]241 mr_free(tmp);
[48]242 res++;
243 } else if (curr_part_no > 5
244 || (curr_part_no <= 4 && prev_part_no > 0)) {
[900]245 mr_asprintf(&tmp, " Gap between %ss%d and %d.", drive,
[59]246 prev_part_no, curr_part_no);
[48]247 log_it(tmp);
[688]248 if (flaws_str) {
[900]249 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]250 } else {
[900]251 mr_asprintf(&tmp1, "%s", tmp);
[688]252 }
[900]253 mr_free(flaws_str);
[688]254 flaws_str = tmp1;
[900]255 mr_free(tmp);
[48]256 res++;
257 }
258 }
259 /* GPT allows more than 4 primary partitions */
260 part_table_fmt = which_partition_format(drive);
261 /* no spare primary partitions to help accommodate the logical(s)? */
262 if ((curr_part_no >= 5 && prev_part_no == 4)
263 && (strcmp(part_table_fmt, "MBR") == 0)) {
[900]264 mr_asprintf(&tmp, " Partition %ss4 is occupied.", drive);
[48]265 log_it(tmp);
[688]266 if (flaws_str) {
[900]267 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]268 } else {
[900]269 mr_asprintf(&tmp1, "%s", tmp);
[688]270 }
[900]271 mr_free(flaws_str);
[688]272 flaws_str = tmp1;
[900]273 mr_free(tmp);
[48]274 res++;
275 }
276 /* does partition /dev/adXsY exist more than once in the mountlist? */
277 for (i = 0, mountpoint_copies = 0, device_copies = 0;
278 i < mountlist->entries; i++) {
279 if (!strcmp(device, mountlist->el[i].device)) {
280 device_copies++;
281 }
282 }
283 if (device_copies > 1) {
[900]284 mr_asprintf(&tmp, " %s %s's.", number_to_text(device_copies),
[59]285 device);
[48]286 if (!strstr(flaws_str, tmp)) {
287 log_it(tmp);
[688]288 if (flaws_str) {
[900]289 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]290 } else {
[900]291 mr_asprintf(&tmp1, "%s", tmp);
[688]292 }
[900]293 mr_free(flaws_str);
[688]294 flaws_str = tmp1;
[48]295 res++;
296 }
[900]297 mr_free(tmp);
[48]298 }
299 /* silly partition size? */
300 if (mountlist->el[pos].size < 8192
301 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
[900]302 mr_asprintf(&tmp, " %s is tiny!", device);
[48]303 log_it(tmp);
[688]304 if (flaws_str) {
[900]305 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]306 } else {
[900]307 mr_asprintf(&tmp1, "%s", tmp);
[688]308 }
[900]309 mr_free(flaws_str);
[688]310 flaws_str = tmp1;
[900]311 mr_free(tmp);
[48]312 res++;
313 }
314 /* mountpoint should begin with / unless it is swap, lvm or raid */
315 if (strcmp(mountlist->el[pos].mountpoint, "swap")
316 && strcmp(mountlist->el[pos].mountpoint, "lvm")
317 && strcmp(mountlist->el[pos].mountpoint, "raid")
318 && strcmp(mountlist->el[pos].mountpoint, "image")
319 && strcmp(mountlist->el[pos].mountpoint, "none")
320 && mountlist->el[pos].mountpoint[0] != '/') {
[900]321 mr_asprintf(&tmp, " %s has a weird mountpoint.", device);
[48]322 log_it(tmp);
[688]323 if (flaws_str) {
[900]324 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]325 } else {
[900]326 mr_asprintf(&tmp1, "%s", tmp);
[688]327 }
[900]328 mr_free(flaws_str);
[688]329 flaws_str = tmp1;
[900]330 mr_free(tmp);
[48]331 res++;
332 }
333 /* is format sensible? */
334 if (!is_this_a_valid_disk_format(mountlist->el[pos].format)) {
[900]335 mr_asprintf(&tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
[48]336 log_it(tmp);
[688]337 if (flaws_str) {
[900]338 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]339 } else {
[900]340 mr_asprintf(&tmp1, "%s", tmp);
[688]341 }
[900]342 mr_free(flaws_str);
[688]343 flaws_str = tmp1;
[900]344 mr_free(tmp);
[48]345 res++;
346 }
347 } else {
348 /* Check subpartitions */
349 for (cur_sp_no = 'a'; cur_sp_no < 'z'; ++cur_sp_no) {
[1176]350 mr_asprintf(&device, "%ss%d%c", drive, curr_part_no, cur_sp_no);
[48]351 pos = find_device_in_mountlist(mountlist, device);
352 if (pos < 0) {
353 continue;
354 }
[900]355 // BERLIOS : useless ? mr_asprintf(&mountpoint, mountlist->el[pos].mountpoint);
[48]356 /* is it too big? */
357 if (curr_part_no > 'h') {
[900]358 mr_asprintf(&tmp,
[59]359 " Can only have up to 'h' in disklabel.");
[48]360 log_it(tmp);
[688]361 if (flaws_str) {
[900]362 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]363 } else {
[900]364 mr_asprintf(&tmp1, "%s", tmp);
[688]365 }
[900]366 mr_free(flaws_str);
[688]367 flaws_str = tmp1;
[900]368 mr_free(tmp);
[48]369 res++;
370 }
371 /* does partition /dev/adXsYZ exist more than once in the mountlist? */
372 for (i = 0, mountpoint_copies = 0, device_copies = 0;
373 i < mountlist->entries; i++) {
374 if (!strcmp(device, mountlist->el[i].device)) {
375 device_copies++;
376 }
377 }
378 if (device_copies > 1) {
[900]379 mr_asprintf(&tmp, " %s %s's.",
[59]380 number_to_text(device_copies), device);
[48]381 if (!strstr(flaws_str, tmp)) {
382 log_it(tmp);
[688]383 if (flaws_str) {
[900]384 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]385 } else {
[900]386 mr_asprintf(&tmp1, "%s", tmp);
[688]387 }
[900]388 mr_free(flaws_str);
[688]389 flaws_str = tmp1;
[48]390 res++;
391 }
[900]392 mr_free(tmp);
[48]393 }
394 /* silly partition size? */
395 if (mountlist->el[pos].size < 8192
396 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
[900]397 mr_asprintf(&tmp, " %s is tiny!", device);
[48]398 log_it(tmp);
[688]399 if (flaws_str) {
[900]400 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]401 } else {
[900]402 mr_asprintf(&tmp1, "%s", tmp);
[688]403 }
[900]404 mr_free(flaws_str);
[688]405 flaws_str = tmp1;
[900]406 mr_free(tmp);
[48]407 res++;
408 }
409 /* mountpoint should begin with / unless it is swap, lvm or raid */
410 if (strcmp(mountlist->el[pos].mountpoint, "swap")
411 && strcmp(mountlist->el[pos].mountpoint, "lvm")
412 && strcmp(mountlist->el[pos].mountpoint, "raid")
413 && strcmp(mountlist->el[pos].mountpoint, "image")
414 && strcmp(mountlist->el[pos].mountpoint, "none")
415 && mountlist->el[pos].mountpoint[0] != '/') {
[900]416 mr_asprintf(&tmp, " %s has a weird mountpoint.", device);
[48]417 log_it(tmp);
[688]418 if (flaws_str) {
[900]419 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]420 } else {
[900]421 mr_asprintf(&tmp1, "%s", tmp);
[688]422 }
[900]423 mr_free(flaws_str);
[688]424 flaws_str = tmp1;
[900]425 mr_free(tmp);
[48]426 res++;
427 }
428 /* is format sensible? */
429 if (!is_this_a_valid_disk_format
430 (mountlist->el[pos].format)) {
[900]431 mr_asprintf(&tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
[48]432 log_it(tmp);
[688]433 if (flaws_str) {
[900]434 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]435 } else {
[900]436 mr_asprintf(&tmp1, "%s", tmp);
[688]437 }
[900]438 mr_free(flaws_str);
[688]439 flaws_str = tmp1;
[900]440 mr_free(tmp);
[48]441 res++;
442 }
443 amount_allocated += mountlist->el[pos].size / 1024;
444 prev_sp_no = cur_sp_no;
445 }
446 }
[1176]447 mr_free(device);
[48]448
449 /* OK, continue with main loop */
450 amount_allocated += mountlist->el[pos].size / 1024;
451 prev_part_no = curr_part_no;
452 }
453
454 /* Over-allocated the disk? Unallocated space on disk? */
455 if (amount_allocated > physical_drive_size) // Used to be +1, but what if you're 1 MB too high?
456 {
[900]457 mr_asprintf(&tmp, " %ld MB over-allocated on %s.",
[59]458 amount_allocated - physical_drive_size, drive);
[48]459 log_it(tmp);
[688]460 if (flaws_str) {
[900]461 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]462 } else {
[900]463 mr_asprintf(&tmp1, "%s", tmp);
[688]464 }
[900]465 mr_free(flaws_str);
[688]466 flaws_str = tmp1;
[900]467 mr_free(tmp);
[48]468 res++;
469 } else if (amount_allocated < physical_drive_size - 1) { /* NOT AN ERROR, JUST A WARNING :-) */
[900]470 mr_asprintf(&tmp, " %ld MB unallocated on %s.",
[59]471 physical_drive_size - amount_allocated, drive);
[48]472 log_it(tmp);
[688]473 if (flaws_str) {
[900]474 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]475 } else {
[900]476 mr_asprintf(&tmp1, "%s", tmp);
[688]477 }
[900]478 mr_free(flaws_str);
[688]479 flaws_str = tmp1;
[900]480 mr_free(tmp);
[1176]481 /* BERLIOS: Flawed since rev 1 !! */
482 res++;
[48]483 }
484 if (res) {
485 return (FALSE);
486 } else {
487 return (TRUE);
488 }
[1]489}
490
491#else
492// Linux-specific version of evaluate_drive_within_mountlist()
493{
494
[48]495 /*@ int ************************************************************* */
496 int prev_part_no = 0;
[1]497 int curr_part_no = 0;
498 int pos = 0;
499 int res = 0;
500 int mountpoint_copies = 0;
501 int device_copies = 0;
502 int i = 0;
503
[48]504 /*@ buffers ******************************************************** */
[783]505 char *tmp = NULL;
506 char *tmp1 = NULL;
507 char *device = NULL;
[1]508
[48]509 /*@ long *********************************************************** */
[783]510 long physical_drive_size = 0L;
511 long amount_allocated = 0L;
[1]512
[48]513 /*@ pointers ******************************************************* */
[783]514 char *part_table_fmt = NULL;
[1]515
[48]516 /*@ initialize ***************************************************** */
517 assert_string_is_neither_NULL_nor_zerolength(drive);
518 assert(mountlist != NULL);
[688]519 flaws_str = NULL;
[1]520
[48]521 prev_part_no = 0;
[1]522
[48]523 physical_drive_size = get_phys_size_of_drive(drive);
[1]524
[48]525 if (physical_drive_size < 0) {
[900]526 mr_asprintf(&tmp, " %s does not exist.", drive);
[688]527 if (flaws_str) {
[900]528 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]529 } else {
[900]530 mr_asprintf(&tmp1, "%s", tmp);
[688]531 }
[900]532 mr_free(flaws_str);
[688]533 flaws_str = tmp1;
[48]534 res++;
[1086]535 mr_msg(1, tmp);
[900]536 mr_free(tmp);
[59]537 return (FALSE);
[48]538 } else {
[900]539 mr_asprintf(&tmp, "%s is %ld MB", drive, physical_drive_size);
[48]540 log_it(tmp);
[900]541 mr_free(tmp);
[48]542 }
[1]543
[48]544 for (curr_part_no = 1; curr_part_no < 99; curr_part_no++) {
[900]545 mr_asprintf(&device, "%s%d", drive, curr_part_no);
[48]546 pos = find_device_in_mountlist(mountlist, device);
547 if (pos < 0) {
548 continue;
549 }
550 if (physical_drive_size < 0) {
[900]551 mr_asprintf(&tmp, " %s refers to non-existent hardware.", device);
[688]552 if (flaws_str) {
[900]553 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]554 } else {
[900]555 mr_asprintf(&tmp1, "%s", tmp);
[688]556 }
[900]557 mr_free(flaws_str);
[688]558 flaws_str = tmp1;
[48]559 res++;
[900]560 mr_free(tmp);
[48]561 continue;
562 }
[783]563 // BERLIOS : useless ? str-cpy(mountpoint, mountlist->el[pos].mountpoint);
[48]564 /* gap in the partition list? */
565 if (curr_part_no - prev_part_no > 1) {
566 if (prev_part_no == 0) {
[900]567 mr_asprintf(&tmp, " Gap prior to %s.", device);
[48]568 log_it(tmp);
[688]569 if (flaws_str) {
[900]570 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]571 } else {
[900]572 mr_asprintf(&tmp1, "%s", tmp);
[688]573 }
[900]574 mr_free(flaws_str);
[688]575 flaws_str = tmp1;
[900]576 mr_free(tmp);
[48]577 res++;
578 } else if (curr_part_no > 5
579 || (curr_part_no <= 4 && prev_part_no > 0)) {
[900]580 mr_asprintf(&tmp, " Gap between %s%d and %d.", drive,
[1176]581 prev_part_no, curr_part_no);
[48]582 log_it(tmp);
[688]583 if (flaws_str) {
[900]584 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]585 } else {
[900]586 mr_asprintf(&tmp1, "%s", tmp);
[688]587 }
[900]588 mr_free(flaws_str);
[688]589 flaws_str = tmp1;
[900]590 mr_free(tmp);
[48]591 res++;
592 }
593 }
594 /* GPT allows more than 4 primary partitions */
595 part_table_fmt = which_partition_format(drive);
596 /* no spare primary partitions to help accommodate the logical(s)? */
597 if ((curr_part_no >= 5 && prev_part_no == 4)
598 && (strcmp(part_table_fmt, "MBR") == 0)) {
[900]599 mr_asprintf(&tmp, " Partition %s4 is occupied.", drive);
[48]600 log_it(tmp);
[688]601 if (flaws_str) {
[900]602 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]603 } else {
[900]604 mr_asprintf(&tmp1, "%s", tmp);
[688]605 }
[900]606 mr_free(flaws_str);
[688]607 flaws_str = tmp1;
[900]608 mr_free(tmp);
[48]609 res++;
610 }
[900]611 mr_free(part_table_fmt);
[146]612
[48]613 /* does partition /dev/hdNX exist more than once in the mountlist? */
614 for (i = 0, mountpoint_copies = 0, device_copies = 0;
615 i < mountlist->entries; i++) {
616 if (!strcmp(device, mountlist->el[i].device)) {
617 device_copies++;
618 }
619 }
620 if (device_copies > 1) {
[900]621 mr_asprintf(&tmp, " %s %s's.", number_to_text(device_copies),
[59]622 device);
[48]623 if (!strstr(flaws_str, tmp)) {
624 log_it(tmp);
[688]625 if (flaws_str) {
[900]626 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]627 } else {
[900]628 mr_asprintf(&tmp1, "%s", tmp);
[688]629 }
[900]630 mr_free(flaws_str);
[688]631 flaws_str = tmp1;
[48]632 res++;
633 }
[900]634 mr_free(tmp);
[48]635 }
636 /* silly partition size? */
637 if (mountlist->el[pos].size < 8192
638 && strcmp(mountlist->el[pos].mountpoint, "lvm")) {
[900]639 mr_asprintf(&tmp, " %s is tiny!", device);
[48]640 log_it(tmp);
[688]641 if (flaws_str) {
[900]642 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]643 } else {
[900]644 mr_asprintf(&tmp1, "%s", tmp);
[688]645 }
[900]646 mr_free(flaws_str);
[688]647 flaws_str = tmp1;
[900]648 mr_free(tmp);
[48]649 res++;
650 }
651 /* mountpoint should begin with / unless it is swap, lvm or raid */
652 if (strcmp(mountlist->el[pos].mountpoint, "swap")
653 && strcmp(mountlist->el[pos].mountpoint, "lvm")
654 && strcmp(mountlist->el[pos].mountpoint, "raid")
655 && strcmp(mountlist->el[pos].mountpoint, "image")
656 && mountlist->el[pos].mountpoint[0] != '/') {
[900]657 mr_asprintf(&tmp, " %s has a weird mountpoint.", device);
[48]658 log_it(tmp);
[688]659 if (flaws_str) {
[900]660 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]661 } else {
[900]662 mr_asprintf(&tmp1, "%s", tmp);
[688]663 }
[900]664 mr_free(flaws_str);
[688]665 flaws_str = tmp1;
[900]666 mr_free(tmp);
[48]667 res++;
668 }
669 /* is format sensible? */
670 if (!is_this_a_valid_disk_format(mountlist->el[pos].format)) {
[900]671 mr_asprintf(&tmp, " %s has unsupported format %s.", device, mountlist->el[pos].format);
[48]672 log_it(tmp);
[688]673 if (flaws_str) {
[900]674 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]675 } else {
[900]676 mr_asprintf(&tmp1, "%s", tmp);
[688]677 }
[900]678 mr_free(flaws_str);
[688]679 flaws_str = tmp1;
[900]680 mr_free(tmp);
[48]681 res++;
682 }
683 /* OK, continue with main loop */
684 amount_allocated += mountlist->el[pos].size / 1024;
685 prev_part_no = curr_part_no;
[900]686 mr_free(device);
[1]687 }
[48]688
689 /* Over-allocated the disk? Unallocated space on disk? */
690 if (amount_allocated > physical_drive_size + 1) {
[900]691 mr_asprintf(&tmp, " %ld MB over-allocated on %s.",
[59]692 amount_allocated - physical_drive_size, drive);
[48]693 log_it(tmp);
[688]694 if (flaws_str) {
[900]695 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]696 } else {
[900]697 mr_asprintf(&tmp1, "%s", tmp);
[688]698 }
[900]699 mr_free(flaws_str);
[688]700 flaws_str = tmp1;
[900]701 mr_free(tmp);
[48]702 res++;
703 } else if (amount_allocated < physical_drive_size - 1) { /* NOT AN ERROR, JUST A WARNING :-) */
[900]704 mr_asprintf(&tmp, " %ld MB unallocated on %s.",
[59]705 physical_drive_size - amount_allocated, drive);
[48]706 log_it(tmp);
[688]707 if (flaws_str) {
[900]708 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
[688]709 } else {
[900]710 mr_asprintf(&tmp1, "%s", tmp);
[688]711 }
[900]712 mr_free(flaws_str);
[688]713 flaws_str = tmp1;
[900]714 mr_free(tmp);
[1176]715 /* BERLIOS: Flawed since rev 1 !! - Is it sure ?? */
716 res++;
[1]717 }
[48]718
719 if (res) {
720 return (FALSE);
721 } else {
722 return (TRUE);
[1]723 }
724}
725#endif
726
727
728/**
729 * Evaluate a whole mountlist for flaws. Calls evaluate_drive_within_mountlist()
730 * for each drive, and then spreads the flaws across three lines.
731 * @param mountlist The mountlist to evaluate.
732 * @param flaws_str_A Where to put the first line listing errors found.
733 * @param flaws_str_B Where to put the second line listing errors found.
734 * @param flaws_str_C Where to put the third line listing errors found.
735 * @return The number of flaws found (0 for success).
736 * @see evaluate_drive_within_mountlist
737 */
738int
[48]739evaluate_mountlist(struct mountlist_itself *mountlist, char *flaws_str_A,
740 char *flaws_str_B, char *flaws_str_C)
[1]741{
742
[48]743 /*@ buffer *********************************************************** */
[1176]744 struct list_of_disks *drivelist = NULL;
745 char *tmp = NULL;
746 char *tmp1 = NULL;
747 char *flaws_str = NULL;
[1]748
[48]749 /*@ int ************************************************************** */
[1]750 int i = 0;
751 int res = 0;
752
[48]753 /*@ initialize ******************************************************* */
[1]754
[1081]755 drivelist = mr_malloc(sizeof(struct list_of_disks));
[48]756 assert(mountlist != NULL);
[1]757
[900]758 mr_asprintf(&flaws_str, " ");
[1]759
[48]760 make_list_of_drives_in_mountlist(mountlist, drivelist);
[1]761
[48]762 log_it("Evaluating mountlist...");
763
764 for (i = 0; i < drivelist->entries; i++) {
765 if (strstr
766 (drivelist->el[i].device,
767 DONT_KNOW_HOW_TO_EVALUATE_THIS_DEVICE_TYPE)) {
[900]768 mr_asprintf(&tmp, " Not evaluating %s (I don't know how yet)",
[59]769 drivelist->el[i].device);
[48]770 log_it(tmp);
771 } else {
[688]772 // This function allocates tmp
[48]773 if (!evaluate_drive_within_mountlist
774 (mountlist, drivelist->el[i].device, tmp)) {
775 res++;
776 }
777 }
[900]778 mr_asprintf(&tmp1, "%s%s", flaws_str, tmp);
779 mr_free(tmp);
780 mr_free(flaws_str);
[48]781 flaws_str = tmp1;
[1]782 }
[48]783 res += look_for_duplicate_mountpoints(mountlist, flaws_str);
784 return (spread_flaws_across_three_lines
785 (flaws_str, flaws_str_A, flaws_str_B, flaws_str_C, res));
[1]786}
787
788
789/**
790 * Find the index number of @p device in the mountlist.
791 * The device given must match @p mountlist->el[N].device exactly, case-sensitive.
792 * @param mountlist The mountlist to search in.
793 * @param device The device to search for.
794 * @return The zero-based index of the device, or -1 if it could not be found.
795 */
796int
[48]797find_device_in_mountlist(struct mountlist_itself *mountlist, char *device)
[1]798{
799
[48]800 /*@ int ************************************************************** */
801 int i = 0;
[1]802
[48]803 assert(mountlist != NULL);
804 assert_string_is_neither_NULL_nor_zerolength(device);
805 for (i = 0;
806 i < mountlist->entries
807 && strcmp(mountlist->el[i].device, device) != 0; i++);
808
809 if (i == mountlist->entries) {
810 return (-1);
811 } else {
812 return (i);
813 }
[1]814}
815
816
817/**
818 * Look for duplicate mountpoints in @p mountlist.
819 * @param mountlist The mountlist to check.
820 * @param flaws_str The flaws string to append the results to.
821 * @return The number of mountpoints that have duplicates, or 0 for success.
822 */
823int
[48]824look_for_duplicate_mountpoints(struct mountlist_itself *mountlist,
825 char *flaws_str)
[1]826{
827
[48]828 /*@ int ************************************************************* */
829 int res = 0;
[1]830 int currline = 0;
831 int i = 0;
832 int copies = 0;
833 int last_copy = 0;
834
[48]835 /*@ buffetr ********************************************************* */
[688]836 char *curr_mountpoint = NULL;
837 char *tmp = NULL;
838 char *tmp1 = NULL;
[1]839
[48]840 assert(mountlist != NULL);
841 assert(flaws_str != NULL);
[688]842
[48]843 for (currline = 0; currline < mountlist->entries; currline++) {
[2497]844 mr_asprintf(&curr_mountpoint, "%s", mountlist->el[currline].mountpoint);
[48]845 for (i = 0, copies = 0, last_copy = -1; i < mountlist->entries;
846 i++) {
847 if (!strcmp(mountlist->el[i].mountpoint, curr_mountpoint)
848 && strcmp(mountlist->el[i].mountpoint, "lvm")
849 && strcmp(mountlist->el[i].mountpoint, "swap")) {
850 last_copy = i;
851 copies++;
852 }
853 }
854 if (copies > 1 && last_copy == currline
855 && strcmp(curr_mountpoint, "raid")) {
[900]856 mr_asprintf(&tmp, " %s %s's.", number_to_text(copies),
[1176]857 curr_mountpoint);
[48]858 log_it(tmp);
[900]859 mr_asprintf(&tmp1, "%s%s",flaws_str, tmp);
860 mr_free(flaws_str);
[688]861 flaws_str = tmp1;
[900]862 mr_free(tmp);
[48]863 res++;
864 }
[900]865 mr_free(curr_mountpoint);
[1]866 }
[48]867 return (res);
[1]868}
869
[48]870
[1]871/**
872 * Make a list of the drives mentioned in the mountlist.
873 * @param mountlist The mountlist to examine.
874 * @param drivelist Where to put the list of drives found.
875 * @return The number of physical (non-RAID non-LVM) drives found, or \<= 0 for error.
876 */
877int
[48]878make_list_of_drives_in_mountlist(struct mountlist_itself *mountlist,
879 struct list_of_disks *drivelist)
[1]880{
881
[48]882 /*@ int ************************************************************* */
883 int lino;
884 int noof_drives;
885 int j;
[1]886
[48]887 /*@ buffers ********************************************************* */
[1176]888 char *drive = NULL;
[1]889
[48]890 long long size;
[1]891
[48]892 assert(mountlist != NULL);
893 assert(drivelist != NULL);
894 log_it("Making list of drives");
895 for (lino = 0, noof_drives = 0; lino < mountlist->entries; lino++) {
[1]896
[900]897 mr_asprintf(&drive, mountlist->el[lino].device);
[48]898 if (!strncmp(drive, RAID_DEVICE_STUB, strlen(RAID_DEVICE_STUB))) {
[1176]899 mr_msg(8, "Not putting %s in list of drives: it's a virtual drive", drive);
[48]900 continue;
901 }
[1]902
[48]903 size = mountlist->el[lino].size;
904 if (size == 0) {
[1176]905 mr_msg(8, "Not putting %s in list of drives: it has zero size (maybe an LVM volume)", drive);
[48]906 continue;
907 }
908
[1176]909 mr_msg(8, "Putting %s with size %lli in list of drives", drive, size);
[1]910
[48]911 (void) truncate_to_drive_name(drive);
912 for (j = 0;
913 j < noof_drives
914 && strcmp(drivelist->el[j].device, drive) != 0; j++)
915 continue;
916 if (j == noof_drives) {
917 strcpy(drivelist->el[noof_drives++].device, drive);
918 }
[900]919 mr_free(drive);
[48]920
[1]921 }
[48]922 drivelist->entries = noof_drives;
[1086]923 mr_msg(8, "Made list of drives");
[1]924
[48]925 return (noof_drives);
[1]926}
927
928
929/**
930 * Make a list of RAID partitions not currently associated with any RAID device.
931 * The user may add any of these partitions to the RAID device.
932 * @param output_list Where to put the list of unallocated RAID partitions.
933 * @param mountlist The mountlist to examine.
934 * @param raidlist The raidlist to examine.
935 */
[48]936void make_list_of_unallocated_raid_partitions(struct mountlist_itself
[1176]937 *output_list,
938 struct mountlist_itself
939 *mountlist,
940 struct raidlist_itself
[48]941 *raidlist)
[1]942{
943
[48]944 /*@ int ************************************************************* */
945 int items = 0;
[1]946 int i = 0;
947 int used_by = 0;
948
[48]949 /*@ buffers ********************************************************* */
[1176]950 char *tmp = NULL;
[1]951
[48]952 assert(output_list != NULL);
953 assert(mountlist != NULL);
954 assert(raidlist != NULL);
955 log_it("MLOURP -- starting");
956 items = 0;
[1]957
958
[48]959 for (i = 0; i < mountlist->entries; i++) {
960 if (strstr(mountlist->el[i].mountpoint, "raid")) {
961 used_by =
962 which_raid_device_is_using_this_partition(raidlist,
963 mountlist->el[i].
964 device);
965 if (used_by < 0) {
966 memcpy((void *) &output_list->el[items++],
967 (void *) &mountlist->el[i],
968 sizeof(struct mountlist_line));
[900]969 mr_asprintf(&tmp,
[59]970 "%s is available; user may choose to add it to raid device",
971 output_list->el[items - 1].device);
[48]972 log_it(tmp);
[900]973 mr_free(tmp);
[48]974 }
975 }
[1]976 }
[48]977 output_list->entries = items;
978 log_it("MLUORP -- ending");
[1]979}
980
981
982/**
983 * Get the size of a mountlist entry by the @c device field.
984 * @param mountlist The mountlist to search in.
985 * @param device The device to search for
986 * @return The size of the device (in KB), or -1 if it could not be found.
987 */
988long long
[48]989size_of_specific_device_in_mountlist(struct mountlist_itself *mountlist,
990 char *device)
[1]991{
[48]992 /*@ int ************************************************************** */
993 int i = 0;
[1]994
995
[48]996 assert(mountlist != NULL);
997 assert_string_is_neither_NULL_nor_zerolength(device);
[1]998
[48]999 for (i = 0;
1000 i < mountlist->entries && strcmp(mountlist->el[i].device, device);
1001 i++);
1002 if (i == mountlist->entries) {
1003 return (-1);
1004 } else {
1005 return (mountlist->el[i].size);
1006 }
[1]1007}
1008
1009
1010/**
1011 * Load a file on disk into @p mountlist.
1012 * The file on disk should consist of multiple lines, each containing 4 or 5
1013 * columns: the device, the mountpoint, the filesystem type, the size in kilobytes, and optionally the filesystem label.
1014 * Comments begin with a '#' without any leading whitespace. Any duplicate
1015 * entries are renamed.
1016 * @param mountlist The mountlist to load into.
1017 * @param fname The name of the file to load the mountlist from.
1018 * @return 0 for success, 1 for failure.
1019 */
[48]1020int load_mountlist(struct mountlist_itself *mountlist, char *fname)
[1]1021{
[1176]1022 FILE *fin = NULL;
[48]1023 /* malloc ** */
1024 char *incoming = NULL;
[1176]1025 char *siz = NULL;
1026 char *tmp = NULL;
1027 char *p = NULL;
[1]1028
[1176]1029 int items = 0;
1030 int j = 0;
[49]1031 size_t n = 0;
[1]1032
[48]1033 assert(mountlist != NULL);
1034 assert_string_is_neither_NULL_nor_zerolength(fname);
[1176]1035
[48]1036 if (!(fin = fopen(fname, "r"))) {
1037 log_it("Unable to open mountlist - '%s'", fname);
[507]1038 log_to_screen(_("Cannot open mountlist"));
[48]1039 return (1);
1040 }
[1176]1041 malloc_string(siz);
[900]1042 mr_getline(&incoming, &n, fin);
[48]1043 log_it("Loading mountlist...");
1044 while (!feof(fin)) {
[1]1045#if linux
[48]1046 sscanf(incoming,
1047 "%s %s %s %s %s",
1048 mountlist->el[items].device,
1049 mountlist->el[items].mountpoint,
1050 mountlist->el[items].format,
1051 siz, mountlist->el[items].label);
[1]1052#elif __FreeBSD__
[48]1053 sscanf(incoming,
1054 "%s %s %s %s",
1055 mountlist->el[items].device,
1056 mountlist->el[items].mountpoint,
1057 mountlist->el[items].format, siz);
1058 strcpy(mountlist->el[items].label, "");
[1]1059#endif
1060
[48]1061 if (!strcmp(mountlist->el[items].device, "/proc") ||
1062 !strcmp(mountlist->el[items].device, "proc") ||
1063 !strcmp(mountlist->el[items].device, "/sys") ||
1064 !strcmp(mountlist->el[items].device, "sys") ||
1065 !strcmp(mountlist->el[items].device, "/devpts") ||
1066 !strcmp(mountlist->el[items].device, "devpts")
1067 ) {
[1086]1068 mr_msg(1,
[48]1069 "Ignoring %s in mountlist - not loading that line :) ",
1070 mountlist->el[items].device);
[900]1071 mr_getline(&incoming, &n, fin);
[48]1072 continue;
1073 }
1074 mountlist->el[items].size = atoll(siz);
1075 if (mountlist->el[items].device[0] != '\0'
1076 && mountlist->el[items].device[0] != '#') {
1077 if (items >= ARBITRARY_MAXIMUM) {
[507]1078 log_to_screen(_("Too many lines in mountlist.. ABORTING"));
[48]1079 finish(1);
1080 }
1081 for (j = 0;
1082 j < items
1083 && strcmp(mountlist->el[j].device,
1084 mountlist->el[items].device); j++);
1085 if (j < items) {
1086 strcat(mountlist->el[items].device, "_dup");
[900]1087 mr_asprintf(&tmp,
[59]1088 "Duplicate entry in mountlist - renaming to %s",
1089 mountlist->el[items].device);
[48]1090 log_it(tmp);
[900]1091 mr_free(tmp);
[48]1092 }
[900]1093 mr_asprintf(&tmp, mountlist->el[items].device);
[48]1094 if (strstr(tmp, "/dev/md/")) {
1095 log_it("format_device() --- Contracting %s", tmp);
1096 p = strrchr(tmp, '/');
1097 if (p) {
1098 *p = *(p + 1);
1099 *(p + 1) = *(p + 2);
1100 *(p + 2) = *(p + 3);
1101 }
1102 log_it("It was %s; it is now %s",
1103 mountlist->el[items].device, tmp);
1104 strcpy(mountlist->el[items].device, tmp);
1105 }
[900]1106 mr_free(tmp);
[1]1107
[1176]1108 log_it("%s %s %s %lld %s",
[59]1109 mountlist->el[items].device,
1110 mountlist->el[items].mountpoint,
1111 mountlist->el[items].format,
1112 mountlist->el[items].size,
1113 mountlist->el[items].label);
[48]1114 items++;
1115 }
[900]1116 mr_getline(&incoming, &n, fin);
[1]1117 }
[48]1118 paranoid_fclose(fin);
[900]1119 mr_free(incoming);
[48]1120 mountlist->entries = items;
[1]1121
[48]1122 log_it("Mountlist loaded successfully.");
[1176]1123 log_it("%d entries in mountlist", items);
[48]1124
[900]1125 mr_free(siz);
[48]1126 return (0);
[1]1127}
1128
1129
1130/**
1131 * Save @p mountlist to a file on disk.
1132 * @param mountlist The mountlist to save.
1133 * @param fname The file to save it to.
1134 * @return 0 for success, 1 for failure.
1135 * @see load_mountlist
1136 */
[48]1137int save_mountlist_to_disk(struct mountlist_itself *mountlist, char *fname)
[1]1138{
[48]1139 FILE *fout;
1140 int i;
[1]1141
[48]1142 assert(mountlist != NULL);
1143 assert_string_is_neither_NULL_nor_zerolength(fname);
[1]1144
[48]1145 log_it("save_mountlist_to_disk() --- saving to %s", fname);
1146 if (!(fout = fopen(fname, "w"))) {
1147 log_OS_error("WMTD - Cannot openout mountlist");
1148 return (1);
1149 }
1150 for (i = 0; i < mountlist->entries; i++) {
1151 fprintf(fout,
1152 "%-15s %-15s %-15s %-15lld %-15s\n",
1153 mountlist->el[i].device, mountlist->el[i].mountpoint,
1154 mountlist->el[i].format, mountlist->el[i].size,
1155 mountlist->el[i].label);
1156 }
1157 paranoid_fclose(fout);
1158 return (0);
[1]1159}
1160
1161
1162/**
1163 * Sort the mountlist alphabetically by device.
1164 * The sorting is done in-place.
1165 * @param mountlist The mountlist to sort.
1166 */
[48]1167void sort_mountlist_by_device(struct mountlist_itself *mountlist)
[1]1168{
[48]1169 int diff;
1170 int lino = -999;
[1]1171
[48]1172 assert(mountlist != NULL);
[1]1173
[48]1174 while (lino < mountlist->entries) {
1175 for (lino = 1; lino < mountlist->entries; lino++) {
1176 diff =
1177 strcmp_inc_numbers(mountlist->el[lino - 1].device,
1178 mountlist->el[lino].device);
1179 if (diff > 0) {
1180 swap_mountlist_entries(mountlist, lino - 1, lino);
1181 break;
1182 }
1183 }
[1]1184 }
1185}
1186
[48]1187
[1]1188/**
1189 * Sort the mountlist alphabetically by mountpoint.
1190 * The sorting is done in-place.
1191 * @param mountlist The mountlist to sort.
1192 * @param reverse If TRUE, then do a reverse sort.
1193 */
[48]1194void
1195sort_mountlist_by_mountpoint(struct mountlist_itself *mountlist,
1196 bool reverse)
[1]1197{
[48]1198 int diff;
1199 int lino = -999;
[1]1200
[48]1201 assert(mountlist != NULL);
[1]1202
[48]1203 while (lino < mountlist->entries) {
1204 for (lino = 1; lino < mountlist->entries; lino++) {
1205 diff =
1206 strcmp(mountlist->el[lino - 1].mountpoint,
1207 mountlist->el[lino].mountpoint);
1208 if ((diff > 0 && !reverse) || ((diff < 0 && reverse))) {
1209 swap_mountlist_entries(mountlist, lino - 1, lino);
1210 break;
1211 }
1212 }
[1]1213 }
1214}
1215
1216
1217/**
1218 * Swap two entries in the mountlist in-place.
1219 * @param mountlist The mountlist to swap the entries in.
1220 * @param a The index number of the first entry.
1221 * @param b The index number of the second entry.
1222 */
[48]1223void
[1]1224swap_mountlist_entries(struct mountlist_itself *mountlist, int a, int b)
1225{
[48]1226 /*@ mallocs *** */
[1176]1227 char *device = NULL;
1228 char *mountpoint = NULL;
1229 char *format = NULL;
[1]1230
[48]1231 long long size;
[1]1232
[48]1233 assert(mountlist != NULL);
1234 assert(a >= 0);
1235 assert(b >= 0);
[1]1236
[2497]1237 mr_asprintf(&device, "%s", mountlist->el[a].device);
1238 mr_asprintf(&mountpoint, "%s", mountlist->el[a].mountpoint);
1239 mr_asprintf(&format, "%s", mountlist->el[a].format);
[1]1240
[48]1241 size = mountlist->el[a].size;
[1]1242
[48]1243 strcpy(mountlist->el[a].device, mountlist->el[b].device);
1244 strcpy(mountlist->el[a].mountpoint, mountlist->el[b].mountpoint);
1245 strcpy(mountlist->el[a].format, mountlist->el[b].format);
[1]1246
[48]1247 mountlist->el[a].size = mountlist->el[b].size;
[1]1248
[48]1249 strcpy(mountlist->el[b].device, device);
1250 strcpy(mountlist->el[b].mountpoint, mountpoint);
1251 strcpy(mountlist->el[b].format, format);
[1]1252
[48]1253 mountlist->el[b].size = size;
[1176]1254 mr_free(device);
1255 mr_free(mountpoint);
1256 mr_free(format);
[1]1257}
1258
1259/* @} - end of mountlistGroup */
Note: See TracBrowser for help on using the repository browser.