Ignore:
Timestamp:
Mar 9, 2024, 3:10:04 AM (3 months ago)
Author:
Bruno Cornec
Message:

Fix all remaining compiler errors

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/3.3/mondo/src/mondorestore/mondo-rstr-newt.c

    r3856 r3879  
    1010#endif
    1111
    12 #include "mondo-rstr-newt.h"
     12#include "my-stuff.h"
     13#include "mondostructures.h"
    1314#include "mr_mem.h"
    1415#include "mr_str.h"
     16#include "libmondo-raid-EXT.h"
     17#include "libmondo-mountlist-EXT.h"
     18#include "libmondo-string-EXT.h"
     19#include "libmondo-tools-EXT.h"
     20#include "libmondo-files-EXT.h"
     21#include "libmondo-filelist-EXT.h"
     22#include "newt-specific-EXT.h"
    1523
    1624//static char cvsid[] = "$Id$";
     
    1826extern bool popup_with_buttons(char *p, char *button1, char *button2);
    1927extern char err_log_lines[NOOF_ERR_LINES][MAX_STR_LEN];
     28
     29static char g_strings_of_flist_window[ARBITRARY_MAXIMUM][MAX_STR_LEN];
     30static bool g_is_path_selected[ARBITRARY_MAXIMUM];
     31static bool g_is_path_expanded[ARBITRARY_MAXIMUM];
     32static char tmpnopath[MAX_STR_LEN + 2];
     33static char tmpprevpath[MAX_STR_LEN + 2];
     34
     35// from mondo-rstr-mountlist.c
     36extern void make_list_of_unallocated_raid_partitions(struct mountlist_itself *, struct mountlist_itself *, struct raidlist_itself *);
     37
     38extern bool g_text_mode;
     39
    2040
    2141/**
     
    3656
    3757/**
    38  * @addtogroup restoreGuiGroup
    39  * @{
    40  */
     58 * Redraw the list of unallocated RAID partitions.
     59 * @param unallocated_raid_partitions The mountlist containing unallocated RAID partitions.
     60 * @param keylist The list of keys for @p listbox.
     61 * @param listbox The Newt listbox component to redraw.
     62 * @ingroup restoreGuiDisklist
     63 */
     64void redraw_unallocpartnslist(struct mountlist_itself
     65                              *unallocated_raid_partitions,
     66                              void *keylist[ARBITRARY_MAXIMUM],
     67                              newtComponent listbox)
     68{
     69
     70    /** long *************************************************************/
     71    long i = 0;
     72
     73    /** buffers **********************************************************/
     74    char tmp[MAX_STR_LEN];
     75
     76    assert(unallocated_raid_partitions != NULL);
     77    assert(keylist != NULL);
     78    assert(listbox != NULL);
     79
     80    newtListboxClear(listbox);
     81    for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
     82        keylist[i] = (void *) i;
     83    }
     84    for (i = 0; i < unallocated_raid_partitions->entries; i++) {
     85        sprintf(tmp, "%-22s %8lld",
     86                unallocated_raid_partitions->el[i].device,
     87                unallocated_raid_partitions->el[i].size / 1024L);
     88        newtListboxAppendEntry(listbox, tmp, keylist[i]);
     89    }
     90}
     91
     92
     93/**
     94 * Find the next free location to place a disk in @p disklist.
     95 * @param disklist The disklist to operate on.
     96 * @return The next free location (starting from 0).
     97 * @ingroup restoreGuiDisklist
     98 */
     99int find_next_free_index_in_disklist(struct list_of_disks *disklist)
     100{
     101
     102    /** int ***************************************************************/
     103    int index = -1;
     104    int pos = 0;
     105
     106  /** bool **************************************************************/
     107    bool done;
     108
     109    assert(disklist != NULL);
     110
     111    for (done = FALSE; !done;) {
     112        for (pos = 0;
     113             pos < disklist->entries && disklist->el[pos].index <= index;
     114             pos++);
     115        if (pos >= disklist->entries) {
     116            done = TRUE;
     117        } else {
     118            index = disklist->el[pos].index;
     119        }
     120    }
     121    return (index + 1);
     122}
     123
     124
     125
    41126/**
    42127 * Add an entry in @p disklist from the list in @p unallocated_raid_partitions.
     
    118203
    119204
    120 
    121 
    122 /**
    123  * Add an entry to @p mountlist.
    124  * @param mountlist The mountlist to add an entry to.
    125  * @param raidlist The raidlist that accompanies @p mountlist.
    126  * @param listbox The listbox component in the mountlist editor.
    127  * @param currline The line selected in @p listbox.
     205/**
     206 * Locate @p device in @p raidlist.
     207 * @param raidlist The raidlist ot search in.
     208 * @param device The RAID device to search for.
     209 * @return The index of the device, or -1 if it could not be found.
     210 * @ingroup restoreGuiMountlist
     211 */
     212int
     213find_raid_device_in_raidlist(struct raidlist_itself *raidlist,
     214                             char *device)
     215{
     216
     217    /** int ***************************************************************/
     218    int i = 0;
     219#ifdef __FreeBSD__
     220    char *vdev = NULL;
     221    int res = 0;
     222#else
     223// Linux
     224#endif
     225
     226    assert(raidlist != NULL);
     227    assert_string_is_neither_NULL_nor_zerolength(device);
     228
     229#ifdef __FreeBSD__
     230    for (i = 0; i < raidlist->entries; i++) {
     231        mr_asprintf(vdev, "/dev/vinum/%s", raidlist->el[i].volname);
     232        res = strcmp(device, vdev);
     233        mr_free(vdev);
     234
     235        if (!res)
     236            break;
     237    }
     238#else
     239
     240    for (i = 0;
     241         strcmp(raidlist->el[i].raid_device, device)
     242         && i < raidlist->entries; i++);
     243#endif
     244    if (i == raidlist->entries) {
     245        return (-1);
     246    } else {
     247        return (i);
     248    }
     249}
     250
     251
     252/**
     253 * Redraw the disklist.
     254 * @param disklist The disklist to read from.
    128255 * @param keylist The list of keys for @p listbox.
     256 * @param listbox The Newt listbox component to redraw.
     257 * @ingroup restoreGuiDisklist
     258 */
     259void
     260redraw_disklist(struct list_of_disks *disklist,
     261                void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox)
     262{
     263
     264    /** long **************************************************************/
     265    long i = 0;
     266    char *tmp = NULL;
     267
     268    assert(disklist != NULL);
     269    assert(keylist != NULL);
     270    assert(listbox != NULL);
     271
     272    newtListboxClear(listbox);
     273
     274    for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
     275        keylist[i] = (void *) i;
     276    }
     277    for (i = 0; i < disklist->entries; i++) {
     278        tmp = disklist_entry_to_string(disklist, i);
     279        newtListboxAppendEntry(listbox, tmp, keylist[i]);
     280        mr_free(tmp);
     281    }
     282}
     283
     284
     285
     286/**
     287 * Delete entry number @p currline from @p disklist.
     288 * @param disklist The disklist to remove the entry from.
     289 * @param raid_device The RAID device containing the partition we're removing.
     290 * Used only in the popup "are you sure?" box.
     291 * @param currline The line number (starting from 0) of the item to delete.
     292 * @ingroup restoreGuiDisklist
     293 */
     294void
     295delete_disklist_entry(struct list_of_disks *disklist, char *raid_device,
     296                      int currline)
     297{
     298
     299    /** int ***************************************************************/
     300    int pos = 0;
     301    int res = 0;
     302
     303    /** buffers ***********************************************************/
     304    char *tmp = NULL;
     305
     306    assert(disklist != NULL);
     307    assert_string_is_neither_NULL_nor_zerolength(raid_device);
     308
     309    mr_asprintf(tmp, "Delete %s from RAID device %s - are you sure?", disklist->el[currline].device, raid_device);
     310    res = ask_me_yes_or_no(tmp);
     311    mr_free(tmp);
     312
     313    if (!res) {
     314        return;
     315    }
     316    for (pos = currline; pos < disklist->entries - 1; pos++) {
     317        strcpy(disklist->el[pos].device, disklist->el[pos + 1].device);
     318    }
     319    disklist->entries--;
     320}
     321
     322
     323
     324/**
     325 * Select the RAID disks to use in @p raidrec.
     326 * @param mountlist_dontedit The mountlist (will not be edited).
     327 * @param raidlist The raidlist to modify.
     328 * @param raidrec The RAID device record in @p raidlist to work on.
     329 * @param description_of_list The type of disks we're selecting (e.g. "data").
     330 * @param disklist The disklist to put the user-selected disks in.
    129331 * @ingroup restoreGuiMountlist
    130332 */
    131333void
    132 add_mountlist_entry(struct mountlist_itself *mountlist,
    133                     struct raidlist_itself *raidlist,
    134                     newtComponent listbox, int currline, void *keylist[])
     334select_raid_disks(struct mountlist_itself *mountlist_dontedit,
     335                  struct raidlist_itself *raidlist,
     336                  struct raid_device_record *raidrec,
     337                  char *description_of_list,
     338                  struct list_of_disks *disklist)
     339{
     340    void *curr_choice;
     341
     342    /** ??? ***************************************************************/
     343
     344    /** structures ********************************************************/
     345    struct raidlist_itself *bkp_raidlist;
     346    struct raid_device_record *bkp_raidrec;
     347    struct list_of_disks *bkp_disklist;
     348    struct mountlist_itself *unallocated_raid_partitions;
     349
     350    /** newt **************************************************************/
     351    newtComponent myForm = NULL;
     352    newtComponent bAdd = NULL;
     353    newtComponent bDelete = NULL;
     354    newtComponent bOK = NULL;
     355    newtComponent bCancel = NULL;
     356    newtComponent b_res = NULL;
     357    newtComponent partitionsListbox = NULL;
     358    newtComponent headerMsg = NULL;
     359
     360    /** buffers **********************************************************/
     361    void *keylist[ARBITRARY_MAXIMUM];
     362    char *tmp = NULL;
     363    char *help_text = NULL;
     364    char *title_of_window = NULL;
     365    char sz_res[MAX_STR_LEN];
     366    char *header_text = NULL;
     367
     368  /** int **************************************************************/
     369    int i = 0;
     370    int currline = 0;
     371
     372    assert(mountlist_dontedit != NULL);
     373    assert(raidlist != NULL);
     374    assert(raidrec != NULL);
     375    assert(description_of_list != NULL);
     376    assert(disklist != NULL);
     377
     378    log_it("malloc'ing");
     379    bkp_raidrec = mr_malloc(sizeof(struct raid_device_record));
     380    bkp_disklist = mr_malloc(sizeof(struct list_of_disks));
     381    bkp_raidlist = mr_malloc(sizeof(struct raidlist_itself));
     382    unallocated_raid_partitions = mr_malloc(sizeof(struct mountlist_itself));
     383
     384    memcpy((void *) bkp_raidlist, (void *) raidlist, sizeof(struct raidlist_itself));
     385    memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record));
     386    memcpy((void *) bkp_disklist, (void *) disklist, sizeof(struct list_of_disks));
     387
     388    log_it("Post-malloc");
     389    mr_asprintf(help_text, "   Edit this RAID device's list of partitions. Choose OK or Cancel when done.");
     390    mr_asprintf(header_text, "%-24s    %s", "Device", "Index");
     391    mr_asprintf(title_of_window, "%s contains...", raidrec->raid_device);
     392    newtPushHelpLine(help_text);
     393    for (b_res = (newtComponent) 12345; b_res != bOK && b_res != bCancel;) {
     394        headerMsg = newtLabel(1, 1, header_text);
     395        partitionsListbox =
     396            newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
     397        redraw_disklist(disklist, keylist, partitionsListbox);
     398        i = 1;
     399        bAdd = newtCompactButton(i, 9, " Add ");
     400        bDelete = newtCompactButton(i += 8, 9, "Delete");
     401        bOK = newtCompactButton(i += 9, 9, "  OK  ");
     402        bCancel = newtCompactButton(i += 9, 9, "Cancel");
     403        newtOpenWindow(21, 7, 38, 10, title_of_window);
     404        myForm = newtForm(NULL, NULL, 0);
     405        if (disklist->entries == 0) {
     406            newtFormAddComponents(myForm, headerMsg, bAdd, bDelete, bOK,
     407                                  bCancel, NULL);
     408        } else {
     409            newtFormAddComponents(myForm, headerMsg, partitionsListbox,
     410                                  bAdd, bDelete, bOK, bCancel, NULL);
     411        }
     412        b_res = newtRunForm(myForm);
     413        if (b_res == bOK || b_res == bCancel) { /* do nothing */
     414// That's OK. At the end of this subroutine (after this do/while loop),
     415// we'll throw away the changes if Cancel was pushed.
     416        } else {
     417            curr_choice = newtListboxGetCurrent(partitionsListbox);
     418            for (i = 0; i < disklist->entries && keylist[i] != curr_choice;
     419                 i++);
     420            if (i == disklist->entries && disklist->entries > 0) {
     421                log_to_screen("I don't know what that button does!");
     422            } else {
     423                currline = i;
     424                if (b_res == bAdd) {
     425                    log_it("Making list of unallocated RAID slices");
     426                    make_list_of_unallocated_raid_partitions
     427                        (unallocated_raid_partitions, mountlist_dontedit,
     428                         raidlist);
     429                    if (unallocated_raid_partitions->entries <= 0) {
     430                        popup_and_OK
     431                            ("There are no unallocated partitions marked for RAID.");
     432                    } else {
     433                        log_it
     434                            ("Done. The user may add one or more of the above to RAID device");
     435                        add_disklist_entry(disklist, raidrec->raid_device,
     436                                           unallocated_raid_partitions);
     437                        log_it("I have finished adding a disklist entry.");
     438                        redraw_disklist(disklist, keylist,
     439                                        partitionsListbox);
     440                    }
     441                } else if (b_res == bDelete) {
     442                    delete_disklist_entry(disklist, raidrec->raid_device,
     443                                          currline);
     444                    redraw_disklist(disklist, keylist, partitionsListbox);
     445                } else {
     446                    mr_asprintf(tmp, "%s's index is %d. What should it be?", raidrec->raid_device, disklist->el[currline].index);
     447                    sprintf(sz_res, "%d", disklist->el[currline].index);
     448                    if (popup_and_get_string("Set index", tmp, sz_res, 10)) {
     449                        disklist->el[currline].index = atoi(sz_res);
     450                    }
     451                    mr_free(tmp);
     452
     453                    redraw_disklist(disklist, keylist, partitionsListbox);
     454                }
     455            }
     456        }
     457        newtFormDestroy(myForm);
     458        newtPopWindow();
     459    }
     460    newtPopHelpLine();
     461    mr_free(help_text);
     462    mr_free(header_text);
     463    mr_free(title_of_window);
     464
     465    if (b_res == bCancel) {
     466        memcpy((void *) raidlist, (void *) bkp_raidlist, sizeof(struct raidlist_itself));
     467        memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record));
     468        memcpy((void *) disklist, (void *) bkp_disklist, sizeof(struct list_of_disks));
     469    }
     470    mr_free(bkp_raidrec);
     471    mr_free(bkp_disklist);
     472    mr_free(bkp_raidlist);
     473    mr_free(unallocated_raid_partitions);
     474}
     475
     476
     477#ifndef __FreeBSD__
     478/**
     479 * Insert the RAID variables not stored in the "additional RAID variables" list there too.
     480 * @param raidrec The RAID device record to operate on.
     481 * @ingroup restoreGuiVarslist
     482 */
     483void insert_essential_additionalvars(struct raid_device_record *raidrec)
    135484{
    136485
    137486    /** int **************************************************************/
     487    int items = 0;
     488
     489    assert(raidrec != NULL);
     490
     491    items = raidrec->additional_vars.entries;
     492    write_variableINT_to_raid_var_line(raidrec, items++,
     493                                       "persistent-superblock",
     494                                       raidrec->persistent_superblock);
     495    write_variableINT_to_raid_var_line(raidrec, items++, "chunk-size",
     496                                       raidrec->chunk_size);
     497    raidrec->additional_vars.entries = items;
     498}
     499
     500#endif
     501
     502
     503#ifndef __FreeBSD__
     504/**
     505 * Redraw the list of additional RAID variables.
     506 * @param additional_vars The list of additional RAID varibals.
     507 * @param keylist The list of keys for @p listbox.
     508 * @param listbox The Newt listbox component to redraw.
     509 * @ingroup restoreGuiVarslist
     510 */
     511void
     512redraw_varslist(struct additional_raid_variables *additional_vars,
     513                void *keylist[], newtComponent listbox)
     514{
     515    /** long ************************************************************/
     516    long i = 0;
     517
     518    /** buffers *********************************************************/
     519    char tmp[MAX_STR_LEN];
     520
     521    assert(additional_vars != NULL);
     522    assert(keylist != NULL);
     523    assert(listbox != NULL);
     524
     525    newtListboxClear(listbox);
     526
     527    for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
     528        keylist[i] = (void *) i;
     529    }
     530    for (i = 0; i < additional_vars->entries; i++) {
     531        sprintf(tmp, "%-32s %-8s", additional_vars->el[i].label,
     532                additional_vars->el[i].value);
     533        newtListboxAppendEntry(listbox, tmp, keylist[i]);
     534    }
     535}
     536
     537#endif
     538
     539
     540#ifndef __FreeBSD__
     541/**
     542 * Remove variable @p label from the RAID variables list in @p raidrec.
     543 * @param raidrec The RAID device record to remove the variable from.
     544 * @param label The variable name to remove.
     545 * @return The value of the variable removed.
     546 * @ingroup restoreUtilityGroup
     547 */
     548int
     549read_variableINT_and_remove_from_raidvars(struct
     550                                          OSSWAP (raid_device_record,
     551                                                  vinum_volume) * raidrec,
     552                                          char *label)
     553{
     554    /** int ***************************************************************/
    138555    int i = 0;
    139 
    140     /** newt *************************************************************/
    141     newtComponent myForm;
     556    int res = 0;
     557
     558
     559    assert(raidrec != NULL);
     560    assert(label != NULL);
     561
     562    for (i = 0;
     563         i < raidrec->additional_vars.entries
     564         && strcmp(raidrec->additional_vars.el[i].label, label); i++);
     565    if (i == raidrec->additional_vars.entries) {
     566        res = -1;
     567    } else {
     568        res = atoi(raidrec->additional_vars.el[i].value);
     569        for (i++; i < raidrec->additional_vars.entries; i++) {
     570            memcpy((void *) &raidrec->additional_vars.el[i - 1],
     571                   (void *) &raidrec->additional_vars.el[i],
     572                   sizeof(struct raid_var_line));
     573        }
     574        raidrec->additional_vars.entries--;
     575    }
     576    return (res);
     577}
     578#endif
     579
     580#ifndef __FreeBSD__
     581/**
     582 * Remove the essential RAID variables from the "additional variables" section.
     583 * If they have been changed, set them in their normal locations too.
     584 * @param raidrec The RAID device record to operate on.
     585 * @ingroup restoreUtilityVarslist
     586 */
     587void remove_essential_additionalvars(struct raid_device_record *raidrec)
     588{
     589
     590    /** int **************************************************************/
     591    int res = 0;
     592
     593    assert(raidrec != NULL);
     594
     595    res =
     596        read_variableINT_and_remove_from_raidvars(raidrec,
     597                                                  "persistent-superblock");
     598    if (res > 0) {
     599        raidrec->persistent_superblock = res;
     600    }
     601    res = read_variableINT_and_remove_from_raidvars(raidrec, "chunk-size");
     602    if (res > 0) {
     603        raidrec->chunk_size = res;
     604    }
     605    res = read_variableINT_and_remove_from_raidvars(raidrec, "block-size");
     606}
     607
     608#endif
     609
     610
     611
     612/**
     613 * Choose the RAID level for the RAID device record in @p raidrec.
     614 * @param raidrec The RAID device record to set the RAID level of.
     615 * @ingroup restoreGuiMountlist
     616 */
     617void
     618choose_raid_level(struct OSSWAP (raid_device_record, vinum_plex) * raidrec)
     619{
     620
     621#ifdef __FreeBSD__
     622
     623    /** int ***************************************************************/
     624    int res = 0;
     625    int out = 0;
     626
     627    /** buffers ***********************************************************/
     628    char tmp[MAX_STR_LEN];
     629    char *prompt = NULL;
     630    char sz[MAX_STR_LEN];
     631
     632    mr_asprintf(prompt, "Please enter the RAID level you want. (concat, striped, raid5)");
     633    if (raidrec->raidlevel == -1) {
     634        strcpy(tmp, "concat");
     635    } else if (raidrec->raidlevel == 0) {
     636        strcpy(tmp, "striped");
     637    } else {
     638        sprintf(tmp, "raid%i", raidrec->raidlevel);
     639    }
     640    for (out = 999; out == 999;) {
     641        res = popup_and_get_string("Specify RAID level", prompt, tmp, 10);
     642        if (!res) {
     643            mr_free(prompt);
     644            return;
     645        }
     646        strip_spaces(tmp);
     647        if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') {
     648            strcpy(sz, tmp);
     649            strncpy(tmp, sz + 1, strlen(sz) - 2);
     650            tmp[strlen(sz) - 2] = '\0';
     651        }
     652        if (!strcmp(tmp, "concat")) {
     653            out = -1;
     654        } else if (!strcmp(tmp, "striped")) {
     655            out = 0;
     656        } else if (!strcmp(tmp, "raid5")) {
     657            out = 5;
     658        }
     659        log_it(tmp);
     660        if (is_this_raid_personality_registered(out)) {
     661            log_it("Groovy. You've picked a RAID personality which is registered.");
     662        } else {
     663            if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?"))
     664            {
     665                out = 999;
     666            }
     667        }
     668    }
     669    mr_free(prompt);
     670
     671    raidrec->raidlevel = out;
     672#else
     673    /** buffers ***********************************************************/
     674    char tmp[MAX_STR_LEN];
     675    char *personalities = NULL;
     676    char *prompt = NULL;
     677    char sz[MAX_STR_LEN];
     678    int out = 0;
     679    int res = 0;
     680
     681
     682    assert(raidrec != NULL);
     683    paranoid_system("grep Pers /proc/mdstat > /tmp/raid-personalities.txt 2> /dev/null");
     684    mr_asprintf(personalities, "%s", last_line_of_file("/tmp/raid-personalities.txt"));
     685    mr_asprintf(prompt, "Please enter the RAID level you want. %s", personalities);
     686    mr_free(personalities);
     687
     688    if (raidrec->raid_level == -1) {
     689        strcpy(tmp, "linear");
     690    } else {
     691        sprintf(tmp, "%d", raidrec->raid_level);
     692    }
     693    for (out = 999;
     694         out != -1 && out != 0 && out != 1 && out != 4 && out != 5
     695         && out != 10;) {
     696        res = popup_and_get_string("Specify RAID level", prompt, tmp, 10);
     697        if (!res) {
     698            return;
     699        }
     700        strip_spaces(tmp);
     701        if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') {
     702            strcpy(sz, tmp);
     703            strncpy(tmp, sz + 1, strlen(sz) - 2);
     704            tmp[strlen(sz) - 2] = '\0';
     705        }
     706        if (!strcmp(tmp, "linear")) {
     707            out = -1;
     708        } else if (!strncmp(tmp, "raid", 4)) {
     709            out = atoi(tmp + 4);
     710        } else {
     711            out = atoi(tmp);
     712        }
     713        log_it(tmp);
     714        if (is_this_raid_personality_registered(out)) {
     715            log_it("Groovy. You've picked a RAID personality which is registered.");
     716        } else {
     717            if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?")) {
     718                out = 999;
     719            }
     720        }
     721    }
     722    mr_free(prompt);
     723
     724    raidrec->raid_level = out;
     725#endif
     726}
     727
     728
     729#ifdef __FreeBSD__
     730
     731/**
     732 * Edit the plex @p raidrec in @p raidlist.
     733 * @param mountlist The mountlist to get some of the information from.
     734 * @param raidlist The raidlist containing information about RAID devices.
     735 * @param raidrec The plex to edit.
     736 * @param currline The line number (starting from 0) of the RAID device in @p mountlist.
     737 * @param currline2 The line number (starting from 0) of the plex within the RAID device.
     738 * @author Joshua Oreman
     739 * @ingroup restoreGuiMountlist
     740 */
     741void
     742edit_raidlist_plex(struct mountlist_itself *mountlist,
     743                   struct raidlist_itself *raidlist,
     744                   struct vinum_plex *raidrec, int currline, int currline2)
     745{
     746
     747    /** structures ********************************************************/
     748    struct vinum_plex bkp_raidrec;
     749
     750
     751    /** buffers ***********************************************************/
     752    char *title_of_editraidForm_window = NULL;
     753
     754    /** newt **************************************************************/
     755    newtComponent editraidForm;
    142756    newtComponent bOK;
    143757    newtComponent bCancel;
     758    newtComponent bEdit;
     759    newtComponent bAdd;
     760    newtComponent bDelete;
    144761    newtComponent b_res;
    145     newtComponent mountpointComp;
    146     newtComponent label0;
    147     newtComponent label1;
    148     newtComponent label2;
    149     newtComponent label3;
    150     newtComponent sizeComp;
    151     newtComponent deviceComp;
    152     newtComponent formatComp;
    153 
    154     /** buffers **********************************************************/
    155     char *drive_to_add = NULL;
    156     char *mountpoint_str = NULL;
    157     char *size_str = NULL;
    158     char *device_str = NULL;
    159     char *format_str = NULL;
    160 
    161     /** pointers *********************************************************/
    162     char *mountpoint_here;
    163     char *size_here;
    164     char *device_here;
    165     char *format_here;
    166 
    167     assert(mountlist != NULL);
    168     assert(raidlist != NULL);
    169     assert(listbox != NULL);
    170     assert(keylist != NULL);
    171 
    172     mr_asprintf(device_str, "/dev/");
    173     mr_asprintf(mountpoint_str, "/");
    174     mr_asprintf(size_str, "");
    175 #ifdef __FreeBSD__
    176     mr_asprintf(format_str, "ufs");
     762    newtComponent unallocListbox, allocListbox;
     763    newtComponent bLevel, sLevel;
     764    newtComponent bStripeSize, sStripeSize;
     765    newtComponent bAlloc, bUnalloc;
     766
     767    void *keylist[ARBITRARY_MAXIMUM];
     768    void *curr_choice_a, *curr_choice_u;
     769    int currline_a, currline_u;
     770
     771    char *p = NULL;
     772    char *tmp = NULL;
     773    char *entry = NULL;
     774
     775    struct mountlist_itself *unallocparts;
     776
     777    unallocparts = malloc(sizeof(struct mountlist_itself));
     778
     779    log_it("Started edit_raidlist_entry");
     780    memcpy((void *) &bkp_raidrec, (void *) raidrec,
     781           sizeof(struct vinum_plex));
     782    mr_asprintf(title_of_editraidForm_window, "%s.p%i", raidlist->el[currline].volname, currline2);
     783    newtPushHelpLine
     784        ("   Please select a subdisk to edit, or edit this plex's parameters");
     785    newtOpenWindow(13, 3, 54, 18, title_of_editraidForm_window);
     786    mr_free(title_of_editraidForm_window);
     787
     788    for (;;) {
     789        int i;
     790
     791        switch (raidrec->raidlevel) {
     792        case -1:
     793            mr_asprintf(tmp, "concat");
     794            break;
     795        case 0:
     796            mr_asprintf(tmp, "striped");
     797            break;
     798        case 5:
     799            mr_asprintf(tmp, "raid5");
     800            break;
     801        default:
     802            mr_asprintf(tmp, "unknown (%i)", raidrec->raidlevel);
     803            break;
     804        }
     805        bLevel = newtCompactButton(2, 2, " RAID level ");
     806        sLevel = newtLabel(19, 2, tmp);
     807        mr_free(tmp);
     808
     809        if (raidrec->raidlevel >= 0) {
     810            mr_asprintf(tmp, "%ik", raidrec->stripesize);
     811            bStripeSize = newtCompactButton(2, 4, " Stripe size ");
     812        } else {
     813            mr_asprintf(tmp, "N/A");
     814            bStripeSize = newtLabel(2, 4, "Stripe size:");
     815        }
     816        sStripeSize = newtLabel(19, 4, tmp);
     817        mr_free(tmp);
     818
     819        bOK = newtCompactButton(2, 16, "  OK  ");
     820        bCancel = newtCompactButton(12, 16, "Cancel");
     821        bAdd = newtCompactButton(22, 16, " Add ");
     822        bEdit = newtCompactButton(32, 16, " Edit ");
     823        bDelete = newtCompactButton(42, 16, "Delete");
     824
     825
     826        unallocListbox =
     827            newtListbox(2, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
     828        allocListbox =
     829            newtListbox(33, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
     830        bAlloc = newtButton(23, 7, " -> ");
     831        bUnalloc = newtButton(23, 11, " <- ");
     832
     833        editraidForm = newtForm(NULL, NULL, 0);
     834
     835        newtListboxClear(allocListbox);
     836        newtListboxClear(unallocListbox);
     837        bzero(unallocparts, sizeof(struct mountlist_itself));
     838        make_list_of_unallocated_raid_partitions(unallocparts, mountlist,
     839                                                 raidlist);
     840        for (i = 0; i < ARBITRARY_MAXIMUM; ++i) {
     841            keylist[i] = (void *) i;
     842            if (i < raidrec->subdisks) {
     843                mr_asprintf(entry, "%-17s", find_dev_entry_for_raid_device_name(raidlist, raidrec->sd[i].which_device));
     844                newtListboxAppendEntry(allocListbox, entry, keylist[i]);
     845                mr_free(entry);
     846            }
     847            if (i < unallocparts->entries) {
     848                mr_asprintf(entry, "%-17s", unallocparts->el[i].device);
     849                newtListboxAppendEntry(unallocListbox, entry, keylist[i]);
     850                mr_free(entry);
     851            }
     852        }
     853
     854#define COMP(x)  newtFormAddComponent (editraidForm, x)
     855#define UCOMP(x) if (unallocparts->entries > 0) COMP(x)
     856#define ACOMP(x) if (raidrec->subdisks > 0) COMP(x)
     857        editraidForm = newtForm(NULL, NULL, 0);
     858        UCOMP(unallocListbox);
     859        UCOMP(bAlloc);
     860        ACOMP(allocListbox);
     861        ACOMP(bUnalloc);
     862        COMP(bOK);
     863        COMP(bCancel);
     864        COMP(bLevel);
     865        COMP(sLevel);
     866        if (raidrec->raidlevel != -1) {
     867            COMP(bStripeSize);
     868            COMP(sStripeSize);
     869        }
     870#undef COMP
     871#undef UCOMP
     872#undef ACOMP
     873
     874        newtDrawForm(editraidForm);
     875        newtRefresh();
     876        b_res = newtRunForm(editraidForm);
     877        if (b_res == bOK || b_res == bCancel) {
     878            break;
     879        }
     880
     881        curr_choice_a = (raidrec->subdisks > 0) ?
     882            newtListboxGetCurrent(allocListbox) : (void *) 1234;
     883        curr_choice_u = (unallocparts->entries > 0) ?
     884            newtListboxGetCurrent(unallocListbox) : (void *) 1234;
     885        for (currline_a = 0; currline_a < raidrec->subdisks; ++currline_a) {
     886            if (currline_a > ARBITRARY_MAXIMUM)
     887                break;
     888            if (keylist[currline_a] == curr_choice_a)
     889                break;
     890        }
     891        for (currline_u = 0; currline_u < unallocparts->entries;
     892             ++currline_u) {
     893            if (currline_u > ARBITRARY_MAXIMUM)
     894                break;
     895            if (keylist[currline_u] == curr_choice_u)
     896                break;
     897        }
     898        if (b_res == bLevel) {
     899            choose_raid_level(raidrec);
     900        } else if (b_res == bStripeSize) {
     901            char tmp1[64];
     902            sprintf(tmp1, "%i", raidrec->stripesize);
     903            if (popup_and_get_string
     904                ("Stripe size",
     905                 "Please enter the stripe size in kilobytes.", tmp1, 20)) {
     906                raidrec->stripesize = atoi(tmp1);
     907            }
     908        } else if ((b_res == bAlloc) || (b_res == unallocListbox)) {
     909            if (currline_u <= unallocparts->entries)
     910                add_raid_subdisk(raidlist, raidrec,
     911                                 unallocparts->el[currline_u].device);
     912        } else if ((b_res == bUnalloc) || (b_res == allocListbox)) {
     913            if (currline_a <= raidrec->subdisks) {
     914                memcpy((void *) &raidrec->sd[currline_a],
     915                       (void *) &raidrec->sd[raidrec->subdisks - 1],
     916                       sizeof(struct vinum_subdisk));
     917                raidrec->subdisks--;
     918            }
     919        }
     920    newtFormDestroy(editraidForm);
     921    newtRefresh();
     922}
     923
     924if (b_res == bCancel) {
     925    memcpy((void *) raidrec, (void *) &bkp_raidrec, sizeof(struct vinum_plex));
     926}
     927newtPopWindow();
     928newtPopHelpLine();
     929}
    177930#else
    178     mr_asprintf(format_str, "ext3");
     931/**
     932 * Edit additional RAID variable number @p lino.
     933 * @param raidrec The RAID device record to edit the variable in.
     934 * @param lino The line number (starting from 0) of the variable to edit.
     935 * @ingroup restoreGuiVarslist
     936 */
     937void edit_varslist_entry(struct raid_device_record *raidrec, int lino)
     938{
     939
     940    /** buffers ***********************************************************/
     941    char *header = NULL;
     942    char *comment = NULL;
     943    char sz_out[MAX_STR_LEN];
     944
     945    assert(raidrec != 0);
     946    assert(lino >= 0);
     947
     948    strcpy(sz_out, raidrec->additional_vars.el[lino].value);
     949    mr_asprintf(header, "Edit %s", raidrec->additional_vars.el[lino].label);
     950    mr_asprintf(comment, "Please set %s's value (currently '%s')", raidrec->additional_vars.el[lino].label, sz_out);
     951    if (popup_and_get_string(header, comment, sz_out, MAX_STR_LEN)) {
     952        strip_spaces(sz_out);
     953        strcpy(raidrec->additional_vars.el[lino].value, sz_out);
     954    }
     955    mr_free(header);
     956    mr_free(comment);
     957}
    179958#endif
    180     newtOpenWindow(20, 5, 48, 10, "Add entry");
    181     label0 = newtLabel(2, 1, "Device:    ");
    182     label1 = newtLabel(2, 2, "Mountpoint:");
    183     label2 = newtLabel(2, 3, "Size (MB): ");
    184     label3 = newtLabel(2, 4, "Format:    ");
    185     deviceComp = newtEntry(14, 1, device_str, 30, (void *) &device_here, 0);
    186     mountpointComp = newtEntry(14, 2, mountpoint_str, 30, (void *) &mountpoint_here, 0);
    187     formatComp = newtEntry(14, 4, format_str, 15, (void *) &format_here, 0);
    188     sizeComp = newtEntry(14, 3, size_str, 10, (void *) &size_here, 0);
    189     bOK = newtButton(5, 6, "  OK  ");
    190     bCancel = newtButton(17, 6, "Cancel");
    191     newtPushHelpLine
    192         ("To add an entry to the mountlist, please fill in these fields and then hit 'OK'");
    193     myForm = newtForm(NULL, NULL, 0);
    194     newtFormAddComponents(myForm, deviceComp, mountpointComp, sizeComp,
    195                           formatComp, label0, label1, label2, label3, bOK,
    196                           bCancel, NULL);
    197     for (b_res = NULL; b_res != bOK && b_res != bCancel;) {
    198         b_res = newtRunForm(myForm);
    199         mr_free(device_str);
    200         device_str = mr_strip_spaces(device_here);
    201 
    202         mr_free(mountpoint_str);
    203         mountpoint_str = mr_strip_spaces(mountpoint_here);
    204 
    205         mr_free(format_str);
    206         format_str = mr_strip_spaces(format_here);
    207 
    208         mr_free(size_str);
    209         size_str = mr_strip_spaces(size_here);
    210 
    211         if (b_res == bOK) {
    212             if (device_str[strlen(device_str) - 1] == '/') {
    213                 popup_and_OK("You left the device nearly blank!");
    214                 b_res = NULL;
    215             }
    216             if (size_of_specific_device_in_mountlist(mountlist, device_str) >= 0) {
    217                 popup_and_OK("Can't add this - you've got one already!");
    218                 b_res = NULL;
    219             }
    220         }
    221     }
    222     newtFormDestroy(myForm);
    223     newtPopHelpLine();
    224     newtPopWindow();
    225     if (b_res == bCancel) {
    226         return;
    227     }
    228     mr_asprintf(drive_to_add, "%s", device_str);
    229     for (i = strlen(drive_to_add); isdigit(drive_to_add[i - 1]); i--);
    230     mr_free(drive_to_add);
    231 
    232     currline = mountlist->entries;
    233     strcpy(mountlist->el[currline].device, device_str);
    234     strcpy(mountlist->el[currline].mountpoint, mountpoint_str);
    235     mr_free(mountpoint_str);
    236 
    237     strcpy(mountlist->el[currline].format, format_str);
    238     mr_free(format_str);
    239 
    240     mountlist->el[currline].size = atol(size_str) * 1024L;
    241     mr_free(size_str);
    242 
    243     mountlist->entries++;
    244     if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) {
    245         initiate_new_raidlist_entry(raidlist, mountlist, currline, device_str);
    246     }
    247     mr_free(device_str);
    248 
    249     redraw_mountlist(mountlist, keylist, listbox);
    250 }
    251959
    252960
     
    289997}
    290998#endif
     999
     1000
     1001#ifndef __FreeBSD__
     1002/**
     1003 * Delete entry number @p lino in the additional RAID variables section of @p raidrec.
     1004 * @param raidrec The RAID device record containing the RAID variable to delete.
     1005 * @param lino The line number (starting from 0) of the variable to delete.
     1006 * @ingroup restoreGuiVarslist
     1007 */
     1008void delete_varslist_entry(struct raid_device_record *raidrec, int lino)
     1009{
     1010
     1011    /** buffers ************************************************************/
     1012    char *tmp = NULL;
     1013    int res = 0;
     1014
     1015    /** structures *********************************************************/
     1016    struct additional_raid_variables *av;
     1017
     1018    assert(raidrec != NULL);
     1019
     1020    av = &raidrec->additional_vars;
     1021    mr_asprintf(tmp, "Delete %s - are you sure?", av->el[lino].label);
     1022    res = ask_me_yes_or_no(tmp);
     1023    mr_free(tmp);
     1024
     1025    if (res) {
     1026        if (!strcmp(av->el[lino].label, "persistent-superblock")
     1027            || !strcmp(av->el[lino].label, "chunk-size")) {
     1028            mr_asprintf(tmp, "%s must not be deleted. It would be bad.", av->el[lino].label);
     1029            popup_and_OK(tmp);
     1030            mr_free(tmp);
     1031        } else {
     1032            memcpy((void *) &av->el[lino], (void *) &av->el[av->entries--],
     1033                   sizeof(struct raid_var_line));
     1034        }
     1035    }
     1036}
     1037#endif
     1038
     1039
     1040
     1041#ifndef __FreeBSD__
     1042/**
     1043 * Edit the additional RAID variables in @p raidrec.
     1044 * @param raidrec The RAID device record to edit the RAID variables in.
     1045 * @ingroup restoreGuiVarslist
     1046 */
     1047void edit_raidrec_additional_vars(struct raid_device_record *raidrec)
     1048{
     1049
     1050    /** structure *********************************************************/
     1051    struct raid_device_record bkp_raidrec;
     1052
     1053    /** newt **************************************************************/
     1054    newtComponent myForm;
     1055    newtComponent bAdd;
     1056    newtComponent bEdit;
     1057    newtComponent bDelete;
     1058    newtComponent bOK;
     1059    newtComponent bCancel;
     1060    newtComponent b_res;
     1061    newtComponent varsListbox;
     1062    newtComponent headerMsg;
     1063
     1064    /** ?? ***************************************************************/
     1065    void *keylist[ARBITRARY_MAXIMUM], *curr_choice;
     1066
     1067    /** buffers **********************************************************/
     1068    char title_of_window[MAX_STR_LEN];
     1069
     1070    /** int **************************************************************/
     1071    int i = 0;
     1072    int currline = 0;
     1073
     1074
     1075    assert(raidrec != NULL);
     1076
     1077    memcpy((void *) &bkp_raidrec, (void *) raidrec,
     1078           sizeof(struct raid_device_record));
     1079    sprintf(title_of_window, "Additional variables");
     1080    newtPushHelpLine
     1081        ("  Edit the additional fields to your heart's content, then click OK or Cancel.");
     1082    headerMsg = newtLabel(1, 1, "Label                            Value");
     1083    varsListbox =
     1084        newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
     1085    i = 1;
     1086    bAdd = newtCompactButton(i, 9, " Add ");
     1087    bEdit = newtCompactButton(i += 8, 9, " Edit ");
     1088    bDelete = newtCompactButton(i += 9, 9, "Delete");
     1089    bOK = newtCompactButton(i += 9, 9, "  OK  ");
     1090    bCancel = newtCompactButton(i += 9, 9, "Cancel");
     1091    newtOpenWindow(17, 7, 46, 10, title_of_window);
     1092    myForm = newtForm(NULL, NULL, 0);
     1093    newtFormAddComponents(myForm, headerMsg, varsListbox, bAdd, bEdit,
     1094                          bDelete, bOK, bCancel, NULL);
     1095    insert_essential_additionalvars(raidrec);
     1096    redraw_varslist(&raidrec->additional_vars, keylist, varsListbox);
     1097    for (b_res = NULL; b_res != bOK && b_res != bCancel;) {
     1098        b_res = newtRunForm(myForm);
     1099        curr_choice = newtListboxGetCurrent(varsListbox);
     1100        for (currline = 0;
     1101             currline < raidrec->additional_vars.entries
     1102             && keylist[currline] != curr_choice; currline++);
     1103        if (currline == raidrec->additional_vars.entries
     1104            && raidrec->additional_vars.entries > 0) {
     1105            log_it("Warning - I don't know what this button does");
     1106        }
     1107        if (b_res == bOK) {     /* do nothing */
     1108        } else if (b_res == bCancel) {  /* do nothing */
     1109        } else if (b_res == bAdd) {
     1110            add_varslist_entry(raidrec);
     1111        } else if (b_res == bDelete) {
     1112            delete_varslist_entry(raidrec, currline);
     1113        } else {
     1114            edit_varslist_entry(raidrec, currline);
     1115        }
     1116        redraw_varslist(&raidrec->additional_vars, keylist, varsListbox);
     1117    }
     1118    remove_essential_additionalvars(raidrec);
     1119    newtFormDestroy(myForm);
     1120    newtPopWindow();
     1121    newtPopHelpLine();
     1122    if (b_res == bCancel) {
     1123        memcpy((void *) raidrec, (void *) &bkp_raidrec,
     1124               sizeof(struct raid_device_record));
     1125    }
     1126    return;
     1127}
     1128#endif
     1129
    2911130
    2921131/**
     
    4451284
    4461285/**
    447  * Choose the RAID level for the RAID device record in @p raidrec.
    448  * @param raidrec The RAID device record to set the RAID level of.
     1286 * Edit the entry for @p raidrec in @p raidlist.
     1287 * @param mountlist The mountlist to get some information from.
     1288 * @param raidlist The raidlist containing information about RAID devices.
     1289 * @param raidrec The RAID device record for this partition.
     1290 * @param currline The line number (starting from 0) in the mountlist of the RAID device.
    4491291 * @ingroup restoreGuiMountlist
    4501292 */
     1293void edit_raidlist_entry(struct mountlist_itself *mountlist,
     1294                    struct raidlist_itself *raidlist,
     1295                    struct OSSWAP (raid_device_record,
     1296                                   vinum_volume) * raidrec, int currline)
     1297{
     1298
     1299#ifdef __FreeBSD__
     1300    /** structures ********************************************************/
     1301    struct vinum_volume bkp_raidrec;
     1302
     1303
     1304    /** buffers ***********************************************************/
     1305    char title_of_editraidForm_window[MAX_STR_LEN];
     1306
     1307    /** newt **************************************************************/
     1308    newtComponent editraidForm;
     1309    newtComponent bOK;
     1310    newtComponent bCancel;
     1311    newtComponent bEdit;
     1312    newtComponent bAdd;
     1313    newtComponent bDelete;
     1314    newtComponent b_res;
     1315    newtComponent plexesListbox;
     1316    newtComponent plexesHeader;
     1317
     1318    void *keylist[10];
     1319    void *curr_choice;
     1320    char *raidlevel = NULL;
     1321    char *chunksize = NULL;
     1322    char *msg = NULL;
     1323
     1324    int currline2 = 0;
     1325    int res = 0;
     1326
     1327    log_it("Started edit_raidlist_entry");
     1328    memcpy((void *) &bkp_raidrec, (void *) raidrec,
     1329           sizeof(struct vinum_volume));
     1330    sprintf(title_of_editraidForm_window, "Plexes on %s",
     1331            raidrec->volname);
     1332    newtPushHelpLine("   Please select a plex to edit");
     1333    newtOpenWindow(13, 5, 54, 15, title_of_editraidForm_window);
     1334    for (;;) {
     1335        int i;
     1336        char *headerstr = NULL;
     1337        mr_asprintf(headerstr, "%-14s %-8s  %11s  %8s", "Plex", "Level", "Stripe Size", "Subdisks");
     1338
     1339        bOK = newtCompactButton(2, 13, "  OK  ");
     1340        bCancel = newtCompactButton(12, 13, "Cancel");
     1341        bAdd = newtCompactButton(22, 13, " Add ");
     1342        bEdit = newtCompactButton(32, 13, " Edit ");
     1343        bDelete = newtCompactButton(42, 13, "Delete");
     1344
     1345        plexesListbox =
     1346            newtListbox(2, 3, 9, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
     1347        plexesHeader = newtLabel(2, 2, headerstr);
     1348        mr_free(headerstr);
     1349        editraidForm = newtForm(NULL, NULL, 0);
     1350
     1351        newtListboxClear(plexesListbox);
     1352        for (i = 0; i < 10; ++i) {
     1353            keylist[i] = (void *) i;
     1354            if (i < raidrec->plexes) {
     1355                char *pname;
     1356                char *entry;
     1357                switch (raidrec->plex[i].raidlevel) {
     1358                case -1:
     1359                    mr_asprintf(raidlevel, "concat");
     1360                    break;
     1361                case 0:
     1362                    mr_asprintf(raidlevel, "striped");
     1363                    break;
     1364                case 5:
     1365                    mr_asprintf(raidlevel, "raid5");
     1366                    break;
     1367                default:
     1368                    mr_asprintf(raidlevel, "raid%i", raidrec->plex[i].raidlevel);
     1369                    break;
     1370                }
     1371
     1372                if (raidrec->plex[i].raidlevel == -1) {
     1373                    mr_asprintf(chunksize, "N/A");
     1374                } else {
     1375                    mr_asprintf(chunksize, "%dk", raidrec->plex[i].stripesize);
     1376                }
     1377                mr_asprintf(pname, "%s.p%i", raidrec->volname, i);
     1378                mr_asprintf(entry, "%-14s %-8s  %11s  %8d", pname, raidlevel, chunksize, raidrec->plex[i].subdisks);
     1379                mr_free(pname);
     1380                mr_free(raidlevel);
     1381                mr_free(chunksize);
     1382
     1383                newtListboxAppendEntry(plexesListbox, entry, keylist[i]);
     1384                mr_free(entry);
     1385            }
     1386        }
     1387
     1388        newtFormAddComponents(editraidForm, bOK, bCancel, bAdd, bEdit,
     1389                              bDelete, plexesListbox, plexesHeader, NULL);
     1390
     1391        b_res = newtRunForm(editraidForm);
     1392        if (b_res == bOK || b_res == bCancel) {
     1393            break;
     1394        }
     1395
     1396        curr_choice = newtListboxGetCurrent(plexesListbox);
     1397        for (currline2 = 0; currline2 < raidrec->plexes; ++currline2) {
     1398            if (currline2 > 9)
     1399                break;
     1400            if (keylist[currline2] == curr_choice)
     1401                break;
     1402        }
     1403
     1404        if (b_res == bDelete) {
     1405            mr_asprintf(msg, "Are you sure you want to delete %s.p%i?", raidrec->volname, currline2);
     1406            res = ask_me_yes_or_no(msg);
     1407            mr_free(msg);
     1408
     1409            if (res) {
     1410                log_it("Deleting RAID plex");
     1411                memcpy((void *) &raidrec->plex[currline2],
     1412                       (void *) &raidrec->plex[raidrec->plexes - 1],
     1413                       sizeof(struct vinum_plex));
     1414                raidrec->plexes--;
     1415            }
     1416            continue;
     1417        }
     1418        if (b_res == bAdd) {
     1419            raidrec->plex[raidrec->plexes].raidlevel = 0;
     1420            raidrec->plex[raidrec->plexes].stripesize = 279;
     1421            raidrec->plex[raidrec->plexes].subdisks = 0;
     1422            currline2 = raidrec->plexes++;
     1423        }
     1424        edit_raidlist_plex(mountlist, raidlist, &raidrec->plex[currline2],
     1425                           currline, currline2);
     1426        newtFormDestroy(editraidForm);
     1427    }
     1428    if (b_res == bCancel) {
     1429        memcpy((void *) raidrec, (void *) &bkp_raidrec,
     1430               sizeof(struct vinum_volume));
     1431    }
     1432    newtPopHelpLine();
     1433    newtPopWindow();
     1434    mountlist->el[currline].size =
     1435        calculate_raid_device_size(mountlist, raidlist, raidrec->volname);
     1436#else
     1437    /** structures ********************************************************/
     1438    struct raid_device_record *bkp_raidrec;
     1439
     1440
     1441    /** buffers ***********************************************************/
     1442    char *title_of_editraidForm_window;
     1443    char *sz_raid_level = NULL;
     1444    char *sz_data_disks = NULL;
     1445    char *sz_spare_disks = NULL;
     1446    char *sz_parity_disks = NULL;
     1447    char *sz_failed_disks = NULL;
     1448
     1449    /** newt **************************************************************/
     1450    newtComponent editraidForm;
     1451    newtComponent bOK;
     1452    newtComponent bCancel;
     1453    newtComponent bAdditional;
     1454    newtComponent bChangeRaid;
     1455    newtComponent bSelectData;
     1456    newtComponent bSelectSpare;
     1457    newtComponent bSelectParity;
     1458    newtComponent bSelectFailed;
     1459    newtComponent b_res;
     1460
     1461    assert(mountlist != NULL);
     1462    assert(raidlist != NULL);
     1463    assert(raidrec != NULL);
     1464
     1465    bkp_raidrec = mr_malloc(sizeof(struct raid_device_record));
     1466    log_it("Started edit_raidlist_entry");
     1467
     1468    memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record));
     1469    mr_asprintf(title_of_editraidForm_window, "%s", raidrec->raid_device);
     1470    log_msg(2, "Opening newt window");
     1471    newtOpenWindow(20, 5, 40, 14, title_of_editraidForm_window);
     1472    for (;;) {
     1473        log_msg(2, "Main loop");
     1474        mr_free(title_of_editraidForm_window);
     1475        mr_asprintf(title_of_editraidForm_window, "Edit %s", raidrec->raid_device);
     1476        sz_raid_level = turn_raid_level_number_to_string(raidrec->raid_level);
     1477        sz_data_disks = number_of_disks_as_string(raidrec->data_disks.entries, "data");
     1478        sz_spare_disks = number_of_disks_as_string(raidrec->spare_disks.entries, "spare");
     1479        sz_parity_disks = number_of_disks_as_string(raidrec->parity_disks.entries, "parity");
     1480        sz_failed_disks = number_of_disks_as_string(raidrec->failed_disks.entries, "failed");
     1481        bSelectData = newtButton(1, 1, sz_data_disks);
     1482        bSelectSpare = newtButton(20, 1, sz_spare_disks);
     1483        bSelectParity = newtButton(1, 5, sz_parity_disks);
     1484        bSelectFailed = newtButton(20, 5, sz_failed_disks);
     1485        bChangeRaid = newtButton(1, 9, sz_raid_level);
     1486        bOK = newtButton(16 + (raidrec->raid_level == -1), 9, "  OK  ");
     1487        bCancel = newtButton(28, 9, "Cancel");
     1488        bAdditional =
     1489            newtCompactButton(1, 13,
     1490                              "Additional settings and information");
     1491        newtPushHelpLine
     1492            ("  Edit the RAID device's settings to your heart's content, then hit OK/Cancel.");
     1493        editraidForm = newtForm(NULL, NULL, 0);
     1494        newtFormAddComponents(editraidForm, bSelectData, bSelectParity,
     1495                              bChangeRaid, bSelectSpare, bSelectFailed,
     1496                              bOK, bCancel, bAdditional);
     1497        b_res = newtRunForm(editraidForm);
     1498        if (b_res == bChangeRaid) {
     1499            choose_raid_level(raidrec);
     1500        } else if (b_res == bSelectData) {
     1501            select_raid_disks(mountlist, raidlist, raidrec, "data", &raidrec->data_disks);
     1502        } else if (b_res == bSelectSpare) {
     1503            select_raid_disks(mountlist, raidlist, raidrec, "spare", &raidrec->spare_disks);
     1504        } else if (b_res == bSelectParity) {
     1505            select_raid_disks(mountlist, raidlist, raidrec, "parity", &raidrec->parity_disks);
     1506        } else if (b_res == bSelectFailed) {
     1507            select_raid_disks(mountlist, raidlist, raidrec, "failed", &raidrec->failed_disks);
     1508        } else if (b_res == bAdditional) {
     1509            edit_raidrec_additional_vars(raidrec);
     1510        }
     1511        newtFormDestroy(editraidForm);
     1512        if (b_res == bOK || b_res == bCancel) {
     1513            break;
     1514        }
     1515        mr_free(sz_data_disks);
     1516        mr_free(sz_spare_disks);
     1517        mr_free(sz_parity_disks);
     1518        mr_free(sz_failed_disks);
     1519    }
     1520    if (b_res == bCancel) {
     1521        memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record));
     1522    }
     1523    newtPopHelpLine();
     1524    newtPopWindow();
     1525    mountlist->el[currline].size = calculate_raid_device_size(mountlist, raidlist, raidrec->raid_device);
     1526    mr_free(title_of_editraidForm_window);
     1527    mr_free(sz_raid_level);
     1528    paranoid_free(bkp_raidrec);
     1529#endif
     1530}
     1531
     1532
     1533/**
     1534 * Create a new raidtab entry for @p device in @p raidlist.
     1535 * @param raidlist The raidlist to add the device to.
     1536 * @param mountlist The mountlist containing information about the user's partitions.
     1537 * @param currline The selected line in the mountlist.
     1538 * @param device The RAID device (e.g. /dev/md0) to use.
     1539 * @ingroup restoreGuiMountlist
     1540 */
    4511541void
    452 choose_raid_level(struct OSSWAP (raid_device_record, vinum_plex) * raidrec)
    453 {
    454 
     1542initiate_new_raidlist_entry(struct raidlist_itself *raidlist,
     1543                            struct mountlist_itself *mountlist,
     1544                            int currline, char *device)
     1545{
     1546
     1547    /** structure *********************************************************/
     1548    struct OSSWAP (raid_device_record, vinum_volume) * raidrec;
     1549
     1550    /** int ***************************************************************/
     1551    int pos_in_raidlist = 0;
     1552
     1553    assert(raidlist != NULL);
     1554    assert(mountlist != NULL);
     1555    assert_string_is_neither_NULL_nor_zerolength(device);
     1556
     1557    pos_in_raidlist =
     1558        find_raid_device_in_raidlist(raidlist,
     1559                                     mountlist->el[currline].device);
     1560    if (pos_in_raidlist >= 0) {
     1561        fatal_error("Sorry, that RAID device already exists. Weird.");
     1562    }
     1563    pos_in_raidlist = raidlist->entries++;
     1564    raidrec = &raidlist->el[pos_in_raidlist];
     1565    initialize_raidrec(raidrec);
     1566    strcpy(raidrec->OSSWAP(raid_device, volname), OSSWAP(device, basename(device)));
     1567#ifndef __FreeBSD__
     1568    choose_raid_level(raidrec);
     1569    select_raid_disks(mountlist, raidlist, raidrec, "data",
     1570                      &raidrec->data_disks);
     1571#endif
     1572    edit_raidlist_entry(mountlist, raidlist, raidrec, currline);
     1573}
     1574
     1575
     1576/**
     1577 * Redraw the mountlist.
     1578 * @param mountlist The mountlist to read from.
     1579 * @param keylist The list of keys for @p listbox.
     1580 * @param listbox The Newt listbox component to redraw.
     1581 * @ingroup restoreGuiMountlist
     1582 */
     1583void
     1584redraw_mountlist(struct mountlist_itself *mountlist,
     1585                 void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox)
     1586{
     1587
     1588    /** long **************************************************************/
     1589    long i = 0;
     1590    char * tmp = NULL;
     1591
     1592    assert(mountlist != NULL);
     1593    assert(keylist != NULL);
     1594    assert(listbox != NULL);
     1595
     1596    newtListboxClear(listbox);
     1597//  sort_mountlist_by_device (mountlist);
     1598    for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
     1599        keylist[i] = (void *) i;
     1600    }
     1601    for (i = 0; i < mountlist->entries; i++) {
     1602        tmp = mountlist_entry_to_string(mountlist, i);
     1603        newtListboxAppendEntry(listbox, tmp, keylist[i]);
     1604        mr_free(tmp);
     1605    }
     1606}
     1607
     1608
     1609
     1610
     1611/**
     1612 * Add an entry to @p mountlist.
     1613 * @param mountlist The mountlist to add an entry to.
     1614 * @param raidlist The raidlist that accompanies @p mountlist.
     1615 * @param listbox The listbox component in the mountlist editor.
     1616 * @param currline The line selected in @p listbox.
     1617 * @param keylist The list of keys for @p listbox.
     1618 * @ingroup restoreGuiMountlist
     1619 */
     1620void
     1621add_mountlist_entry(struct mountlist_itself *mountlist,
     1622                    struct raidlist_itself *raidlist,
     1623                    newtComponent listbox, int currline, void *keylist[])
     1624{
     1625
     1626    /** int **************************************************************/
     1627    int i = 0;
     1628
     1629    /** newt *************************************************************/
     1630    newtComponent myForm;
     1631    newtComponent bOK;
     1632    newtComponent bCancel;
     1633    newtComponent b_res;
     1634    newtComponent mountpointComp;
     1635    newtComponent label0;
     1636    newtComponent label1;
     1637    newtComponent label2;
     1638    newtComponent label3;
     1639    newtComponent sizeComp;
     1640    newtComponent deviceComp;
     1641    newtComponent formatComp;
     1642
     1643    /** buffers **********************************************************/
     1644    char *drive_to_add = NULL;
     1645    char *mountpoint_str = NULL;
     1646    char *size_str = NULL;
     1647    char *device_str = NULL;
     1648    char *format_str = NULL;
     1649
     1650    /** pointers *********************************************************/
     1651    char *mountpoint_here;
     1652    char *size_here;
     1653    char *device_here;
     1654    char *format_here;
     1655
     1656    assert(mountlist != NULL);
     1657    assert(raidlist != NULL);
     1658    assert(listbox != NULL);
     1659    assert(keylist != NULL);
     1660
     1661    mr_asprintf(device_str, "/dev/");
     1662    mr_asprintf(mountpoint_str, "/");
     1663    mr_asprintf(size_str, "");
    4551664#ifdef __FreeBSD__
    456 
    457     /** int ***************************************************************/
    458     int res = 0;
    459     int out = 0;
    460 
    461     /** buffers ***********************************************************/
    462     char tmp[MAX_STR_LEN];
    463     char *prompt = NULL;
    464     char sz[MAX_STR_LEN];
    465 
    466     mr_asprintf(prompt, "Please enter the RAID level you want. (concat, striped, raid5)");
    467     if (raidrec->raidlevel == -1) {
    468         strcpy(tmp, "concat");
    469     } else if (raidrec->raidlevel == 0) {
    470         strcpy(tmp, "striped");
    471     } else {
    472         sprintf(tmp, "raid%i", raidrec->raidlevel);
    473     }
    474     for (out = 999; out == 999;) {
    475         res = popup_and_get_string("Specify RAID level", prompt, tmp, 10);
    476         if (!res) {
    477             mr_free(prompt);
    478             return;
    479         }
    480         strip_spaces(tmp);
    481         if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') {
    482             strcpy(sz, tmp);
    483             strncpy(tmp, sz + 1, strlen(sz) - 2);
    484             tmp[strlen(sz) - 2] = '\0';
    485         }
    486         if (!strcmp(tmp, "concat")) {
    487             out = -1;
    488         } else if (!strcmp(tmp, "striped")) {
    489             out = 0;
    490         } else if (!strcmp(tmp, "raid5")) {
    491             out = 5;
    492         }
    493         log_it(tmp);
    494         if (is_this_raid_personality_registered(out)) {
    495             log_it("Groovy. You've picked a RAID personality which is registered.");
    496         } else {
    497             if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?"))
    498             {
    499                 out = 999;
     1665    mr_asprintf(format_str, "ufs");
     1666#else
     1667    mr_asprintf(format_str, "ext3");
     1668#endif
     1669    newtOpenWindow(20, 5, 48, 10, "Add entry");
     1670    label0 = newtLabel(2, 1, "Device:    ");
     1671    label1 = newtLabel(2, 2, "Mountpoint:");
     1672    label2 = newtLabel(2, 3, "Size (MB): ");
     1673    label3 = newtLabel(2, 4, "Format:    ");
     1674    deviceComp = newtEntry(14, 1, device_str, 30, (void *) &device_here, 0);
     1675    mountpointComp = newtEntry(14, 2, mountpoint_str, 30, (void *) &mountpoint_here, 0);
     1676    formatComp = newtEntry(14, 4, format_str, 15, (void *) &format_here, 0);
     1677    sizeComp = newtEntry(14, 3, size_str, 10, (void *) &size_here, 0);
     1678    bOK = newtButton(5, 6, "  OK  ");
     1679    bCancel = newtButton(17, 6, "Cancel");
     1680    newtPushHelpLine
     1681        ("To add an entry to the mountlist, please fill in these fields and then hit 'OK'");
     1682    myForm = newtForm(NULL, NULL, 0);
     1683    newtFormAddComponents(myForm, deviceComp, mountpointComp, sizeComp,
     1684                          formatComp, label0, label1, label2, label3, bOK,
     1685                          bCancel, NULL);
     1686    for (b_res = NULL; b_res != bOK && b_res != bCancel;) {
     1687        b_res = newtRunForm(myForm);
     1688        mr_free(device_str);
     1689        device_str = mr_strip_spaces(device_here);
     1690
     1691        mr_free(mountpoint_str);
     1692        mountpoint_str = mr_strip_spaces(mountpoint_here);
     1693
     1694        mr_free(format_str);
     1695        format_str = mr_strip_spaces(format_here);
     1696
     1697        mr_free(size_str);
     1698        size_str = mr_strip_spaces(size_here);
     1699
     1700        if (b_res == bOK) {
     1701            if (device_str[strlen(device_str) - 1] == '/') {
     1702                popup_and_OK("You left the device nearly blank!");
     1703                b_res = NULL;
    5001704            }
    501         }
    502     }
    503     mr_free(prompt);
    504 
    505     raidrec->raidlevel = out;
    506 #else
    507     /** buffers ***********************************************************/
    508     char tmp[MAX_STR_LEN];
    509     char *personalities = NULL;
    510     char *prompt = NULL;
    511     char sz[MAX_STR_LEN];
    512     int out = 0;
    513     int res = 0;
    514 
    515 
    516     assert(raidrec != NULL);
    517     paranoid_system("grep Pers /proc/mdstat > /tmp/raid-personalities.txt 2> /dev/null");
    518     mr_asprintf(personalities, "%s", last_line_of_file("/tmp/raid-personalities.txt"));
    519     mr_asprintf(prompt, "Please enter the RAID level you want. %s", personalities);
    520     mr_free(personalities);
    521 
    522     if (raidrec->raid_level == -1) {
    523         strcpy(tmp, "linear");
    524     } else {
    525         sprintf(tmp, "%d", raidrec->raid_level);
    526     }
    527     for (out = 999;
    528          out != -1 && out != 0 && out != 1 && out != 4 && out != 5
    529          && out != 10;) {
    530         res = popup_and_get_string("Specify RAID level", prompt, tmp, 10);
    531         if (!res) {
    532             return;
    533         }
    534         strip_spaces(tmp);
    535         if (tmp[0] == '[' && tmp[strlen(tmp) - 1] == ']') {
    536             strcpy(sz, tmp);
    537             strncpy(tmp, sz + 1, strlen(sz) - 2);
    538             tmp[strlen(sz) - 2] = '\0';
    539         }
    540         if (!strcmp(tmp, "linear")) {
    541             out = -1;
    542         } else if (!strncmp(tmp, "raid", 4)) {
    543             out = atoi(tmp + 4);
    544         } else {
    545             out = atoi(tmp);
    546         }
    547         log_it(tmp);
    548         if (is_this_raid_personality_registered(out)) {
    549             log_it("Groovy. You've picked a RAID personality which is registered.");
    550         } else {
    551             if (ask_me_yes_or_no("You have chosen a RAID personality which is not registered with the kernel. Make another selection?")) {
    552                 out = 999;
     1705            if (size_of_specific_device_in_mountlist(mountlist, device_str) >= 0) {
     1706                popup_and_OK("Can't add this - you've got one already!");
     1707                b_res = NULL;
    5531708            }
    5541709        }
    5551710    }
    556     mr_free(prompt);
    557 
    558     raidrec->raid_level = out;
    559 #endif
     1711    newtFormDestroy(myForm);
     1712    newtPopHelpLine();
     1713    newtPopWindow();
     1714    if (b_res == bCancel) {
     1715        return;
     1716    }
     1717    mr_asprintf(drive_to_add, "%s", device_str);
     1718    for (i = strlen(drive_to_add); isdigit(drive_to_add[i - 1]); i--);
     1719    mr_free(drive_to_add);
     1720
     1721    currline = mountlist->entries;
     1722    strcpy(mountlist->el[currline].device, device_str);
     1723    strcpy(mountlist->el[currline].mountpoint, mountpoint_str);
     1724    mr_free(mountpoint_str);
     1725
     1726    strcpy(mountlist->el[currline].format, format_str);
     1727    mr_free(format_str);
     1728
     1729    mountlist->el[currline].size = atol(size_str) * 1024L;
     1730    mr_free(size_str);
     1731
     1732    mountlist->entries++;
     1733    if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) {
     1734        initiate_new_raidlist_entry(raidlist, mountlist, currline, device_str);
     1735    }
     1736    mr_free(device_str);
     1737
     1738    redraw_mountlist(mountlist, keylist, listbox);
    5601739}
    5611740
     
    6011780
    6021781
    603 
    604 /**
    605  * Delete entry number @p currline from @p disklist.
    606  * @param disklist The disklist to remove the entry from.
    607  * @param raid_device The RAID device containing the partition we're removing.
    608  * Used only in the popup "are you sure?" box.
    609  * @param currline The line number (starting from 0) of the item to delete.
    610  * @ingroup restoreGuiDisklist
    611  */
    612 void
    613 delete_disklist_entry(struct list_of_disks *disklist, char *raid_device,
    614                       int currline)
    615 {
    616 
    617     /** int ***************************************************************/
    618     int pos = 0;
    619     int res = 0;
    620 
    621     /** buffers ***********************************************************/
    622     char *tmp = NULL;
    623 
    624     assert(disklist != NULL);
    625     assert_string_is_neither_NULL_nor_zerolength(raid_device);
    626 
    627     mr_asprintf(tmp, "Delete %s from RAID device %s - are you sure?", disklist->el[currline].device, raid_device);
    628     res = ask_me_yes_or_no(tmp);
    629     mr_free(tmp);
    630 
    631     if (!res) {
    632         return;
    633     }
    634     for (pos = currline; pos < disklist->entries - 1; pos++) {
    635         strcpy(disklist->el[pos].device, disklist->el[pos + 1].device);
    636     }
    637     disklist->entries--;
    638 }
    639 
    640 
    641 
    642 /**
    643  * Delete entry number @p currline from @p mountlist.
    644  * @param mountlist The mountlist to delete the entry from.
    645  * @param raidlist The raidlist that goes with @p mountlist.
    646  * @param listbox The Newt listbox component in the mountlist editor.
    647  * @param currline The line number (starting from 0) of the item to delete.
    648  * @param keylist The list of keys for @p listbox.
    649  * @ingroup restoreGuiMountlist
    650  */
    651 void
    652 delete_mountlist_entry(struct mountlist_itself *mountlist,
    653                        struct raidlist_itself *raidlist,
    654                        newtComponent listbox, int currline,
    655                        void *keylist[])
    656 {
    657 
    658     /** int ***************************************************************/
    659     int pos = 0;
    660     int res = 0;
    661 
    662     /** buffers ***********************************************************/
    663     char *tmp = NULL;
    664     char *device = NULL;
    665 
    666 
    667     assert(mountlist != NULL);
    668     assert(raidlist != NULL);
    669     assert(listbox != NULL);
    670     assert(keylist != NULL);
    671 
    672     pos = which_raid_device_is_using_this_partition(raidlist, mountlist->el[currline].device);
    673     if (pos >= 0) {
    674         mr_asprintf(tmp, "Cannot delete %s: it is in use by RAID device %s", mountlist->el[currline].device, raidlist->el[pos].OSSWAP(raid_device, volname));
    675         popup_and_OK(tmp);
    676         mr_free(tmp);
    677         return;
    678     }
    679     mr_asprintf(tmp, "Delete %s - are you sure?", mountlist->el[currline].device);
    680     res = ask_me_yes_or_no(tmp);
    681     mr_free(tmp);
    682 
    683     if (!res) {
    684         return;
    685     }
    686     if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) {
    687         mr_asprintf(device, "%s", mountlist->el[currline].device);
    688         delete_raidlist_entry(mountlist, raidlist, device);
    689         for (currline = 0;
    690              currline < mountlist->entries
    691              && strcmp(mountlist->el[currline].device, device);
    692              currline++);
    693         mr_free(device);
    694 
    695         if (currline == mountlist->entries) {
    696             log_it("Dev is gone. I can't delete it. Ho-hum");
    697             return;
    698         }
    699     }
    700     memcpy((void *) &mountlist->el[currline],
    701            (void *) &mountlist->el[mountlist->entries - 1],
    702            sizeof(struct mountlist_line));
    703     mountlist->entries--;
    704     redraw_mountlist(mountlist, keylist, listbox);
    705 }
    706 
    707 
    7081782/**
    7091783 * Delete @p device from @p raidlist.
     
    7131787 * @ingroup restoreGuiMountlist
    7141788 */
    715 void
    716 delete_raidlist_entry(struct mountlist_itself *mountlist,
     1789void delete_raidlist_entry(struct mountlist_itself *mountlist,
    7171790                      struct raidlist_itself *raidlist, char *device)
    7181791{
     
    7831856
    7841857
    785 #ifndef __FreeBSD__
    786 /**
    787  * Delete entry number @p lino in the additional RAID variables section of @p raidrec.
    788  * @param raidrec The RAID device record containing the RAID variable to delete.
    789  * @param lino The line number (starting from 0) of the variable to delete.
    790  * @ingroup restoreGuiVarslist
    791  */
    792 void delete_varslist_entry(struct raid_device_record *raidrec, int lino)
    793 {
    794 
    795     /** buffers ************************************************************/
     1858
     1859/**
     1860 * Delete entry number @p currline from @p mountlist.
     1861 * @param mountlist The mountlist to delete the entry from.
     1862 * @param raidlist The raidlist that goes with @p mountlist.
     1863 * @param listbox The Newt listbox component in the mountlist editor.
     1864 * @param currline The line number (starting from 0) of the item to delete.
     1865 * @param keylist The list of keys for @p listbox.
     1866 * @ingroup restoreGuiMountlist
     1867 */
     1868void
     1869delete_mountlist_entry(struct mountlist_itself *mountlist,
     1870                       struct raidlist_itself *raidlist,
     1871                       newtComponent listbox, int currline,
     1872                       void *keylist[])
     1873{
     1874
     1875    /** int ***************************************************************/
     1876    int pos = 0;
     1877    int res = 0;
     1878
     1879    /** buffers ***********************************************************/
    7961880    char *tmp = NULL;
    797     int res = 0;
    798 
    799     /** structures *********************************************************/
    800     struct additional_raid_variables *av;
    801 
    802     assert(raidrec != NULL);
    803 
    804     av = &raidrec->additional_vars;
    805     mr_asprintf(tmp, "Delete %s - are you sure?", av->el[lino].label);
     1881    char *device = NULL;
     1882
     1883
     1884    assert(mountlist != NULL);
     1885    assert(raidlist != NULL);
     1886    assert(listbox != NULL);
     1887    assert(keylist != NULL);
     1888
     1889    pos = which_raid_device_is_using_this_partition(raidlist, mountlist->el[currline].device);
     1890    if (pos >= 0) {
     1891        mr_asprintf(tmp, "Cannot delete %s: it is in use by RAID device %s", mountlist->el[currline].device, raidlist->el[pos].OSSWAP(raid_device, volname));
     1892        popup_and_OK(tmp);
     1893        mr_free(tmp);
     1894        return;
     1895    }
     1896    mr_asprintf(tmp, "Delete %s - are you sure?", mountlist->el[currline].device);
    8061897    res = ask_me_yes_or_no(tmp);
    8071898    mr_free(tmp);
    8081899
    809     if (res) {
    810         if (!strcmp(av->el[lino].label, "persistent-superblock")
    811             || !strcmp(av->el[lino].label, "chunk-size")) {
    812             mr_asprintf(tmp, "%s must not be deleted. It would be bad.", av->el[lino].label);
    813             popup_and_OK(tmp);
    814             mr_free(tmp);
     1900    if (!res) {
     1901        return;
     1902    }
     1903    if (strstr(mountlist->el[currline].device, RAID_DEVICE_STUB)) {
     1904        mr_asprintf(device, "%s", mountlist->el[currline].device);
     1905        delete_raidlist_entry(mountlist, raidlist, device);
     1906        for (currline = 0;
     1907             currline < mountlist->entries
     1908             && strcmp(mountlist->el[currline].device, device);
     1909             currline++);
     1910        mr_free(device);
     1911
     1912        if (currline == mountlist->entries) {
     1913            log_it("Dev is gone. I can't delete it. Ho-hum");
     1914            return;
     1915        }
     1916    }
     1917    memcpy((void *) &mountlist->el[currline],
     1918           (void *) &mountlist->el[mountlist->entries - 1],
     1919           sizeof(struct mountlist_line));
     1920    mountlist->entries--;
     1921    redraw_mountlist(mountlist, keylist, listbox);
     1922}
     1923
     1924
     1925/**
     1926 * Strip a path to the bare minimum (^ pointing to the directory above, plus filename).
     1927 * @param tmp The path to strip.
     1928 * @return The stripped path.
     1929 * @author Conor Daly
     1930 * @ingroup restoreUtilityGroup
     1931 */
     1932char *strip_path(char *tmp)
     1933{
     1934
     1935    int i = 0, j = 0, slashcount = 0;
     1936    int slashloc = 0, lastslashloc = 0;
     1937
     1938    while (tmp[i] != '\0') {    /* Count the slashes in tmp
     1939                                   1 slash per dir */
     1940        if (tmp[i] == '/') {
     1941            slashcount++;
     1942            lastslashloc = slashloc;
     1943            slashloc = i;
     1944            if (tmp[i + 1] == '\0') {   /* if this slash is last char, back off */
     1945                slashcount--;
     1946                slashloc = lastslashloc;
     1947            }
     1948        }
     1949        i++;
     1950    }
     1951    if (slashcount > 0)
     1952        slashcount--;           /* Keep one slash 'cos Hugh does... */
     1953
     1954    for (i = 0; i < slashcount; i++) {  /* Replace each dir with a space char */
     1955        tmpnopath[i] = ' ';
     1956    }
     1957
     1958    i = slashloc;
     1959    j = slashcount;
     1960    while (tmp[i] != '\0') {    /* Now add what's left of tmp */
     1961        if ((tmpprevpath[j] == ' ' || tmpprevpath[j] == '^')
     1962            && tmp[i] == '/' && tmpnopath[j - 1] != '^' && j != 0) {    /* Add a pointer upwards if this is not in the same dir as line above */
     1963            tmpnopath[j - 1] = '^';
    8151964        } else {
    816             memcpy((void *) &av->el[lino], (void *) &av->el[av->entries--],
    817                    sizeof(struct raid_var_line));
    818         }
    819     }
    820 }
    821 #endif
     1965            tmpnopath[j++] = tmp[i++];
     1966        }
     1967    }
     1968    tmpnopath[j] = '\0';
     1969
     1970    strcpy(tmpprevpath, tmpnopath); /* Make a copy for next iteration */
     1971
     1972    return (tmpnopath);
     1973}
     1974
    8221975
    8231976
     
    9242077        return (0);
    9252078    }
    926 }
    927 
    928 
    929 /**
    930  * Strip a path to the bare minimum (^ pointing to the directory above, plus filename).
    931  * @param tmp The path to strip.
    932  * @return The stripped path.
    933  * @author Conor Daly
    934  * @ingroup restoreUtilityGroup
    935  */
    936 char *strip_path(char *tmp)
    937 {
    938 
    939     int i = 0, j = 0, slashcount = 0;
    940     int slashloc = 0, lastslashloc = 0;
    941 
    942     while (tmp[i] != '\0') {    /* Count the slashes in tmp
    943                                    1 slash per dir */
    944         if (tmp[i] == '/') {
    945             slashcount++;
    946             lastslashloc = slashloc;
    947             slashloc = i;
    948             if (tmp[i + 1] == '\0') {   /* if this slash is last char, back off */
    949                 slashcount--;
    950                 slashloc = lastslashloc;
    951             }
    952         }
    953         i++;
    954     }
    955     if (slashcount > 0)
    956         slashcount--;           /* Keep one slash 'cos Hugh does... */
    957 
    958     for (i = 0; i < slashcount; i++) {  /* Replace each dir with a space char */
    959         tmpnopath[i] = ' ';
    960     }
    961 
    962     i = slashloc;
    963     j = slashcount;
    964     while (tmp[i] != '\0') {    /* Now add what's left of tmp */
    965         if ((tmpprevpath[j] == ' ' || tmpprevpath[j] == '^')
    966             && tmp[i] == '/' && tmpnopath[j - 1] != '^' && j != 0) {    /* Add a pointer upwards if this is not in the same dir as line above */
    967             tmpnopath[j - 1] = '^';
    968         } else {
    969             tmpnopath[j++] = tmp[i++];
    970         }
    971     }
    972     tmpnopath[j] = '\0';
    973 
    974     strcpy(tmpprevpath, tmpnopath); /* Make a copy for next iteration */
    975 
    976     return (tmpnopath);
    9772079}
    9782080
     
    11132215
    11142216/**
     2217 * Change all RAID devices to use @p new_dev instead of @p old_dev.
     2218 * @param raidlist The raidlist to make the changes in.
     2219 * @param old_dev The old name of the device (what it used to be).
     2220 * @param new_dev The new name of the device (what it is now).
     2221 * @ingroup restoreGuiMountlist
     2222 */
     2223void rejig_partition_name_in_raidlist_if_necessary(struct raidlist_itself
     2224                                                   *raidlist,
     2225                                                   char *old_dev,
     2226                                                   char *new_dev)
     2227{
     2228    /** int ************************************************************/
     2229    int pos = 0;
     2230    int j = 0;
     2231
     2232    assert(raidlist != NULL);
     2233    assert_string_is_neither_NULL_nor_zerolength(old_dev);
     2234    assert_string_is_neither_NULL_nor_zerolength(new_dev);
     2235
     2236    pos = which_raid_device_is_using_this_partition(raidlist, old_dev);
     2237    if (pos < 0) {
     2238        log_it("No need to rejig %s in raidlist: it's not listed.", old_dev);
     2239    } else {
     2240        if ((j =
     2241             where_in_drivelist_is_drive(&raidlist->
     2242                                         OSSWAP(el[pos].data_disks, disks),
     2243                                         old_dev)) >= 0) {
     2244            strcpy(raidlist->OSSWAP(el[pos].data_disks, disks).el[j].device, new_dev);
     2245        } else
     2246            if ((j =
     2247                 where_in_drivelist_is_drive(&raidlist->
     2248                                             OSSWAP(el[pos].spare_disks,
     2249                                                    spares),
     2250                                             old_dev)) >= 0) {
     2251            strcpy(raidlist->OSSWAP(el[pos].spare_disks, spares).el[j].device, new_dev);
     2252        }
     2253#ifndef __FreeBSD__
     2254        else if ((j =
     2255                  where_in_drivelist_is_drive(&raidlist->el[pos].
     2256                                              parity_disks,
     2257                                              old_dev)) >= 0) {
     2258            strcpy(raidlist->el[pos].parity_disks.el[j].device, new_dev);
     2259        } else
     2260            if ((j =
     2261                 where_in_drivelist_is_drive(&raidlist->el[pos].
     2262                                             failed_disks,
     2263                                             old_dev)) >= 0) {
     2264            strcpy(raidlist->el[pos].failed_disks.el[j].device, new_dev);
     2265        }
     2266#endif
     2267        else {
     2268            log_it("%s is supposed to be listed in this raid dev but it's not...", old_dev);
     2269        }
     2270    }
     2271}
     2272
     2273
     2274/**
    11152275 * Edit an entry in @p mountlist.
    11162276 * @param mountlist The mountlist containing information about the user's partitions.
     
    13802540                   struct vinum_plex *raidrec, int currline,
    13812541                   int currline2);
    1382 
    1383 #endif
    1384 
    1385 
    1386 /**
    1387  * Edit the entry for @p raidrec in @p raidlist.
    1388  * @param mountlist The mountlist to get some information from.
    1389  * @param raidlist The raidlist containing information about RAID devices.
    1390  * @param raidrec The RAID device record for this partition.
    1391  * @param currline The line number (starting from 0) in the mountlist of the RAID device.
    1392  * @ingroup restoreGuiMountlist
    1393  */
    1394 void
    1395 edit_raidlist_entry(struct mountlist_itself *mountlist,
    1396                     struct raidlist_itself *raidlist,
    1397                     struct OSSWAP (raid_device_record,
    1398                                    vinum_volume) * raidrec, int currline)
    1399 {
    1400 
    1401 #ifdef __FreeBSD__
    1402     /** structures ********************************************************/
    1403     struct vinum_volume bkp_raidrec;
    1404 
    1405 
    1406     /** buffers ***********************************************************/
    1407     char title_of_editraidForm_window[MAX_STR_LEN];
    1408 
    1409     /** newt **************************************************************/
    1410     newtComponent editraidForm;
    1411     newtComponent bOK;
    1412     newtComponent bCancel;
    1413     newtComponent bEdit;
    1414     newtComponent bAdd;
    1415     newtComponent bDelete;
    1416     newtComponent b_res;
    1417     newtComponent plexesListbox;
    1418     newtComponent plexesHeader;
    1419 
    1420     void *keylist[10];
    1421     void *curr_choice;
    1422     char *raidlevel = NULL;
    1423     char *chunksize = NULL;
    1424     char *msg = NULL;
    1425 
    1426     int currline2 = 0;
    1427     int res = 0;
    1428 
    1429     log_it("Started edit_raidlist_entry");
    1430     memcpy((void *) &bkp_raidrec, (void *) raidrec,
    1431            sizeof(struct vinum_volume));
    1432     sprintf(title_of_editraidForm_window, "Plexes on %s",
    1433             raidrec->volname);
    1434     newtPushHelpLine("   Please select a plex to edit");
    1435     newtOpenWindow(13, 5, 54, 15, title_of_editraidForm_window);
    1436     for (;;) {
    1437         int i;
    1438         char *headerstr = NULL;
    1439         mr_asprintf(headerstr, "%-14s %-8s  %11s  %8s", "Plex", "Level", "Stripe Size", "Subdisks");
    1440 
    1441         bOK = newtCompactButton(2, 13, "  OK  ");
    1442         bCancel = newtCompactButton(12, 13, "Cancel");
    1443         bAdd = newtCompactButton(22, 13, " Add ");
    1444         bEdit = newtCompactButton(32, 13, " Edit ");
    1445         bDelete = newtCompactButton(42, 13, "Delete");
    1446 
    1447         plexesListbox =
    1448             newtListbox(2, 3, 9, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
    1449         plexesHeader = newtLabel(2, 2, headerstr);
    1450         mr_free(headerstr);
    1451         editraidForm = newtForm(NULL, NULL, 0);
    1452 
    1453         newtListboxClear(plexesListbox);
    1454         for (i = 0; i < 10; ++i) {
    1455             keylist[i] = (void *) i;
    1456             if (i < raidrec->plexes) {
    1457                 char *pname;
    1458                 char *entry;
    1459                 switch (raidrec->plex[i].raidlevel) {
    1460                 case -1:
    1461                     mr_asprintf(raidlevel, "concat");
    1462                     break;
    1463                 case 0:
    1464                     mr_asprintf(raidlevel, "striped");
    1465                     break;
    1466                 case 5:
    1467                     mr_asprintf(raidlevel, "raid5");
    1468                     break;
    1469                 default:
    1470                     mr_asprintf(raidlevel, "raid%i", raidrec->plex[i].raidlevel);
    1471                     break;
    1472                 }
    1473 
    1474                 if (raidrec->plex[i].raidlevel == -1) {
    1475                     mr_asprintf(chunksize, "N/A");
    1476                 } else {
    1477                     mr_asprintf(chunksize, "%dk", raidrec->plex[i].stripesize);
    1478                 }
    1479                 mr_asprintf(pname, "%s.p%i", raidrec->volname, i);
    1480                 mr_asprintf(entry, "%-14s %-8s  %11s  %8d", pname, raidlevel, chunksize, raidrec->plex[i].subdisks);
    1481                 mr_free(pname);
    1482                 mr_free(raidlevel);
    1483                 mr_free(chunksize);
    1484 
    1485                 newtListboxAppendEntry(plexesListbox, entry, keylist[i]);
    1486                 mr_free(entry);
    1487             }
    1488         }
    1489 
    1490         newtFormAddComponents(editraidForm, bOK, bCancel, bAdd, bEdit,
    1491                               bDelete, plexesListbox, plexesHeader, NULL);
    1492 
    1493         b_res = newtRunForm(editraidForm);
    1494         if (b_res == bOK || b_res == bCancel) {
    1495             break;
    1496         }
    1497 
    1498         curr_choice = newtListboxGetCurrent(plexesListbox);
    1499         for (currline2 = 0; currline2 < raidrec->plexes; ++currline2) {
    1500             if (currline2 > 9)
    1501                 break;
    1502             if (keylist[currline2] == curr_choice)
    1503                 break;
    1504         }
    1505 
    1506         if (b_res == bDelete) {
    1507             mr_asprintf(msg, "Are you sure you want to delete %s.p%i?", raidrec->volname, currline2);
    1508             res = ask_me_yes_or_no(msg);
    1509             mr_free(msg);
    1510 
    1511             if (res) {
    1512                 log_it("Deleting RAID plex");
    1513                 memcpy((void *) &raidrec->plex[currline2],
    1514                        (void *) &raidrec->plex[raidrec->plexes - 1],
    1515                        sizeof(struct vinum_plex));
    1516                 raidrec->plexes--;
    1517             }
    1518             continue;
    1519         }
    1520         if (b_res == bAdd) {
    1521             raidrec->plex[raidrec->plexes].raidlevel = 0;
    1522             raidrec->plex[raidrec->plexes].stripesize = 279;
    1523             raidrec->plex[raidrec->plexes].subdisks = 0;
    1524             currline2 = raidrec->plexes++;
    1525         }
    1526         edit_raidlist_plex(mountlist, raidlist, &raidrec->plex[currline2],
    1527                            currline, currline2);
    1528         newtFormDestroy(editraidForm);
    1529     }
    1530     if (b_res == bCancel) {
    1531         memcpy((void *) raidrec, (void *) &bkp_raidrec,
    1532                sizeof(struct vinum_volume));
    1533     }
    1534     newtPopHelpLine();
    1535     newtPopWindow();
    1536     mountlist->el[currline].size =
    1537         calculate_raid_device_size(mountlist, raidlist, raidrec->volname);
    1538 #else
    1539     /** structures ********************************************************/
    1540     struct raid_device_record *bkp_raidrec;
    1541 
    1542 
    1543     /** buffers ***********************************************************/
    1544     char *title_of_editraidForm_window;
    1545     char *sz_raid_level = NULL;
    1546     char *sz_data_disks = NULL;
    1547     char *sz_spare_disks = NULL;
    1548     char *sz_parity_disks = NULL;
    1549     char *sz_failed_disks = NULL;
    1550 
    1551     /** newt **************************************************************/
    1552     newtComponent editraidForm;
    1553     newtComponent bOK;
    1554     newtComponent bCancel;
    1555     newtComponent bAdditional;
    1556     newtComponent bChangeRaid;
    1557     newtComponent bSelectData;
    1558     newtComponent bSelectSpare;
    1559     newtComponent bSelectParity;
    1560     newtComponent bSelectFailed;
    1561     newtComponent b_res;
    1562 
    1563     assert(mountlist != NULL);
    1564     assert(raidlist != NULL);
    1565     assert(raidrec != NULL);
    1566 
    1567     bkp_raidrec = mr_malloc(sizeof(struct raid_device_record));
    1568     log_it("Started edit_raidlist_entry");
    1569 
    1570     memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record));
    1571     mr_asprintf(title_of_editraidForm_window, "%s", raidrec->raid_device);
    1572     log_msg(2, "Opening newt window");
    1573     newtOpenWindow(20, 5, 40, 14, title_of_editraidForm_window);
    1574     for (;;) {
    1575         log_msg(2, "Main loop");
    1576         mr_free(title_of_editraidForm_window);
    1577         mr_asprintf(title_of_editraidForm_window, "Edit %s", raidrec->raid_device);
    1578         sz_raid_level = turn_raid_level_number_to_string(raidrec->raid_level);
    1579         sz_data_disks = number_of_disks_as_string(raidrec->data_disks.entries, "data");
    1580         sz_spare_disks = number_of_disks_as_string(raidrec->spare_disks.entries, "spare");
    1581         sz_parity_disks = number_of_disks_as_string(raidrec->parity_disks.entries, "parity");
    1582         sz_failed_disks = number_of_disks_as_string(raidrec->failed_disks.entries, "failed");
    1583         bSelectData = newtButton(1, 1, sz_data_disks);
    1584         bSelectSpare = newtButton(20, 1, sz_spare_disks);
    1585         bSelectParity = newtButton(1, 5, sz_parity_disks);
    1586         bSelectFailed = newtButton(20, 5, sz_failed_disks);
    1587         bChangeRaid = newtButton(1, 9, sz_raid_level);
    1588         bOK = newtButton(16 + (raidrec->raid_level == -1), 9, "  OK  ");
    1589         bCancel = newtButton(28, 9, "Cancel");
    1590         bAdditional =
    1591             newtCompactButton(1, 13,
    1592                               "Additional settings and information");
    1593         newtPushHelpLine
    1594             ("  Edit the RAID device's settings to your heart's content, then hit OK/Cancel.");
    1595         editraidForm = newtForm(NULL, NULL, 0);
    1596         newtFormAddComponents(editraidForm, bSelectData, bSelectParity,
    1597                               bChangeRaid, bSelectSpare, bSelectFailed,
    1598                               bOK, bCancel, bAdditional);
    1599         b_res = newtRunForm(editraidForm);
    1600         if (b_res == bChangeRaid) {
    1601             choose_raid_level(raidrec);
    1602         } else if (b_res == bSelectData) {
    1603             select_raid_disks(mountlist, raidlist, raidrec, "data", &raidrec->data_disks);
    1604         } else if (b_res == bSelectSpare) {
    1605             select_raid_disks(mountlist, raidlist, raidrec, "spare", &raidrec->spare_disks);
    1606         } else if (b_res == bSelectParity) {
    1607             select_raid_disks(mountlist, raidlist, raidrec, "parity", &raidrec->parity_disks);
    1608         } else if (b_res == bSelectFailed) {
    1609             select_raid_disks(mountlist, raidlist, raidrec, "failed", &raidrec->failed_disks);
    1610         } else if (b_res == bAdditional) {
    1611             edit_raidrec_additional_vars(raidrec);
    1612         }
    1613         newtFormDestroy(editraidForm);
    1614         if (b_res == bOK || b_res == bCancel) {
    1615             break;
    1616         }
    1617         mr_free(sz_data_disks);
    1618         mr_free(sz_spare_disks);
    1619         mr_free(sz_parity_disks);
    1620         mr_free(sz_failed_disks);
    1621     }
    1622     if (b_res == bCancel) {
    1623         memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record));
    1624     }
    1625     newtPopHelpLine();
    1626     newtPopWindow();
    1627     mountlist->el[currline].size = calculate_raid_device_size(mountlist, raidlist, raidrec->raid_device);
    1628     mr_free(title_of_editraidForm_window);
    1629     mr_free(sz_raid_level);
    1630     paranoid_free(bkp_raidrec);
    1631 #endif
    1632 }
    1633 
    1634 #ifdef __FreeBSD__
    1635 
    1636 /**
    1637  * Edit the plex @p raidrec in @p raidlist.
    1638  * @param mountlist The mountlist to get some of the information from.
    1639  * @param raidlist The raidlist containing information about RAID devices.
    1640  * @param raidrec The plex to edit.
    1641  * @param currline The line number (starting from 0) of the RAID device in @p mountlist.
    1642  * @param currline2 The line number (starting from 0) of the plex within the RAID device.
    1643  * @author Joshua Oreman
    1644  * @ingroup restoreGuiMountlist
    1645  */
    1646 void
    1647 edit_raidlist_plex(struct mountlist_itself *mountlist,
    1648                    struct raidlist_itself *raidlist,
    1649                    struct vinum_plex *raidrec, int currline, int currline2)
    1650 {
    1651 
    1652     /** structures ********************************************************/
    1653     struct vinum_plex bkp_raidrec;
    1654 
    1655 
    1656     /** buffers ***********************************************************/
    1657     char *title_of_editraidForm_window = NULL;
    1658 
    1659     /** newt **************************************************************/
    1660     newtComponent editraidForm;
    1661     newtComponent bOK;
    1662     newtComponent bCancel;
    1663     newtComponent bEdit;
    1664     newtComponent bAdd;
    1665     newtComponent bDelete;
    1666     newtComponent b_res;
    1667     newtComponent unallocListbox, allocListbox;
    1668     newtComponent bLevel, sLevel;
    1669     newtComponent bStripeSize, sStripeSize;
    1670     newtComponent bAlloc, bUnalloc;
    1671 
    1672     void *keylist[ARBITRARY_MAXIMUM];
    1673     void *curr_choice_a, *curr_choice_u;
    1674     int currline_a, currline_u;
    1675 
    1676     char *p = NULL;
    1677     char *tmp = NULL;
    1678     char *entry = NULL;
    1679 
    1680     struct mountlist_itself *unallocparts;
    1681 
    1682     unallocparts = malloc(sizeof(struct mountlist_itself));
    1683 
    1684     log_it("Started edit_raidlist_entry");
    1685     memcpy((void *) &bkp_raidrec, (void *) raidrec,
    1686            sizeof(struct vinum_plex));
    1687     mr_asprintf(title_of_editraidForm_window, "%s.p%i", raidlist->el[currline].volname, currline2);
    1688     newtPushHelpLine
    1689         ("   Please select a subdisk to edit, or edit this plex's parameters");
    1690     newtOpenWindow(13, 3, 54, 18, title_of_editraidForm_window);
    1691     mr_free(title_of_editraidForm_window);
    1692 
    1693     for (;;) {
    1694         int i;
    1695 
    1696         switch (raidrec->raidlevel) {
    1697         case -1:
    1698             mr_asprintf(tmp, "concat");
    1699             break;
    1700         case 0:
    1701             mr_asprintf(tmp, "striped");
    1702             break;
    1703         case 5:
    1704             mr_asprintf(tmp, "raid5");
    1705             break;
    1706         default:
    1707             mr_asprintf(tmp, "unknown (%i)", raidrec->raidlevel);
    1708             break;
    1709         }
    1710         bLevel = newtCompactButton(2, 2, " RAID level ");
    1711         sLevel = newtLabel(19, 2, tmp);
    1712         mr_free(tmp);
    1713 
    1714         if (raidrec->raidlevel >= 0) {
    1715             mr_asprintf(tmp, "%ik", raidrec->stripesize);
    1716             bStripeSize = newtCompactButton(2, 4, " Stripe size ");
    1717         } else {
    1718             mr_asprintf(tmp, "N/A");
    1719             bStripeSize = newtLabel(2, 4, "Stripe size:");
    1720         }
    1721         sStripeSize = newtLabel(19, 4, tmp);
    1722         mr_free(tmp);
    1723 
    1724         bOK = newtCompactButton(2, 16, "  OK  ");
    1725         bCancel = newtCompactButton(12, 16, "Cancel");
    1726         bAdd = newtCompactButton(22, 16, " Add ");
    1727         bEdit = newtCompactButton(32, 16, " Edit ");
    1728         bDelete = newtCompactButton(42, 16, "Delete");
    1729 
    1730 
    1731         unallocListbox =
    1732             newtListbox(2, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
    1733         allocListbox =
    1734             newtListbox(33, 7, 7, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
    1735         bAlloc = newtButton(23, 7, " -> ");
    1736         bUnalloc = newtButton(23, 11, " <- ");
    1737 
    1738         editraidForm = newtForm(NULL, NULL, 0);
    1739 
    1740         newtListboxClear(allocListbox);
    1741         newtListboxClear(unallocListbox);
    1742         bzero(unallocparts, sizeof(struct mountlist_itself));
    1743         make_list_of_unallocated_raid_partitions(unallocparts, mountlist,
    1744                                                  raidlist);
    1745         for (i = 0; i < ARBITRARY_MAXIMUM; ++i) {
    1746             keylist[i] = (void *) i;
    1747             if (i < raidrec->subdisks) {
    1748                 mr_asprintf(entry, "%-17s", find_dev_entry_for_raid_device_name(raidlist, raidrec->sd[i].which_device));
    1749                 newtListboxAppendEntry(allocListbox, entry, keylist[i]);
    1750                 mr_free(entry);
    1751             }
    1752             if (i < unallocparts->entries) {
    1753                 mr_asprintf(entry, "%-17s", unallocparts->el[i].device);
    1754                 newtListboxAppendEntry(unallocListbox, entry, keylist[i]);
    1755                 mr_free(entry);
    1756             }
    1757         }
    1758 
    1759 #define COMP(x)  newtFormAddComponent (editraidForm, x)
    1760 #define UCOMP(x) if (unallocparts->entries > 0) COMP(x)
    1761 #define ACOMP(x) if (raidrec->subdisks > 0) COMP(x)
    1762         editraidForm = newtForm(NULL, NULL, 0);
    1763         UCOMP(unallocListbox);
    1764         UCOMP(bAlloc);
    1765         ACOMP(allocListbox);
    1766         ACOMP(bUnalloc);
    1767         COMP(bOK);
    1768         COMP(bCancel);
    1769         COMP(bLevel);
    1770         COMP(sLevel);
    1771         if (raidrec->raidlevel != -1) {
    1772             COMP(bStripeSize);
    1773             COMP(sStripeSize);
    1774         }
    1775 #undef COMP
    1776 #undef UCOMP
    1777 #undef ACOMP
    1778 
    1779         newtDrawForm(editraidForm);
    1780         newtRefresh();
    1781         b_res = newtRunForm(editraidForm);
    1782         if (b_res == bOK || b_res == bCancel) {
    1783             break;
    1784         }
    1785 
    1786         curr_choice_a = (raidrec->subdisks > 0) ?
    1787             newtListboxGetCurrent(allocListbox) : (void *) 1234;
    1788         curr_choice_u = (unallocparts->entries > 0) ?
    1789             newtListboxGetCurrent(unallocListbox) : (void *) 1234;
    1790         for (currline_a = 0; currline_a < raidrec->subdisks; ++currline_a) {
    1791             if (currline_a > ARBITRARY_MAXIMUM)
    1792                 break;
    1793             if (keylist[currline_a] == curr_choice_a)
    1794                 break;
    1795         }
    1796         for (currline_u = 0; currline_u < unallocparts->entries;
    1797              ++currline_u) {
    1798             if (currline_u > ARBITRARY_MAXIMUM)
    1799                 break;
    1800             if (keylist[currline_u] == curr_choice_u)
    1801                 break;
    1802         }
    1803         if (b_res == bLevel) {
    1804             choose_raid_level(raidrec);
    1805         } else if (b_res == bStripeSize) {
    1806             char tmp1[64];
    1807             sprintf(tmp1, "%i", raidrec->stripesize);
    1808             if (popup_and_get_string
    1809                 ("Stripe size",
    1810                  "Please enter the stripe size in kilobytes.", tmp1, 20)) {
    1811                 raidrec->stripesize = atoi(tmp1);
    1812             }
    1813         } else if ((b_res == bAlloc) || (b_res == unallocListbox)) {
    1814             if (currline_u <= unallocparts->entries)
    1815                 add_raid_subdisk(raidlist, raidrec,
    1816                                  unallocparts->el[currline_u].device);
    1817         } else if ((b_res == bUnalloc) || (b_res == allocListbox)) {
    1818             if (currline_a <= raidrec->subdisks) {
    1819                 memcpy((void *) &raidrec->sd[currline_a],
    1820                        (void *) &raidrec->sd[raidrec->subdisks - 1],
    1821                        sizeof(struct vinum_subdisk));
    1822                 raidrec->subdisks--;
    1823             }
    1824         }
    1825     newtFormDestroy(editraidForm);
    1826     newtRefresh();
    1827 }
    1828 
    1829 if (b_res == bCancel) {
    1830     memcpy((void *) raidrec, (void *) &bkp_raidrec, sizeof(struct vinum_plex));
    1831 }
    1832 newtPopWindow();
    1833 newtPopHelpLine();
    1834 }
    1835 #else
    1836 /**
    1837  * Edit additional RAID variable number @p lino.
    1838  * @param raidrec The RAID device record to edit the variable in.
    1839  * @param lino The line number (starting from 0) of the variable to edit.
    1840  * @ingroup restoreGuiVarslist
    1841  */
    1842 void edit_varslist_entry(struct raid_device_record *raidrec, int lino)
    1843 {
    1844 
    1845     /** buffers ***********************************************************/
    1846     char *header = NULL;
    1847     char *comment = NULL;
    1848     char sz_out[MAX_STR_LEN];
    1849 
    1850     assert(raidrec != 0);
    1851     assert(lino >= 0);
    1852 
    1853     strcpy(sz_out, raidrec->additional_vars.el[lino].value);
    1854     mr_asprintf(header, "Edit %s", raidrec->additional_vars.el[lino].label);
    1855     mr_asprintf(comment, "Please set %s's value (currently '%s')", raidrec->additional_vars.el[lino].label, sz_out);
    1856     if (popup_and_get_string(header, comment, sz_out, MAX_STR_LEN)) {
    1857         strip_spaces(sz_out);
    1858         strcpy(raidrec->additional_vars.el[lino].value, sz_out);
    1859     }
    1860     mr_free(header);
    1861     mr_free(comment);
    1862 }
    18632542
    18642543#endif
     
    20482727}
    20492728
    2050 
    2051 
    2052 
    2053 #ifndef __FreeBSD__
    2054 /**
    2055  * Edit the additional RAID variables in @p raidrec.
    2056  * @param raidrec The RAID device record to edit the RAID variables in.
    2057  * @ingroup restoreGuiVarslist
    2058  */
    2059 void edit_raidrec_additional_vars(struct raid_device_record *raidrec)
    2060 {
    2061 
    2062     /** structure *********************************************************/
    2063     struct raid_device_record bkp_raidrec;
    2064 
    2065     /** newt **************************************************************/
    2066     newtComponent myForm;
    2067     newtComponent bAdd;
    2068     newtComponent bEdit;
    2069     newtComponent bDelete;
    2070     newtComponent bOK;
    2071     newtComponent bCancel;
    2072     newtComponent b_res;
    2073     newtComponent varsListbox;
    2074     newtComponent headerMsg;
    2075 
    2076     /** ?? ***************************************************************/
    2077     void *keylist[ARBITRARY_MAXIMUM], *curr_choice;
    2078 
    2079     /** buffers **********************************************************/
    2080     char title_of_window[MAX_STR_LEN];
    2081 
    2082     /** int **************************************************************/
    2083     int i = 0;
    2084     int currline = 0;
    2085 
    2086 
    2087     assert(raidrec != NULL);
    2088 
    2089     memcpy((void *) &bkp_raidrec, (void *) raidrec,
    2090            sizeof(struct raid_device_record));
    2091     sprintf(title_of_window, "Additional variables");
    2092     newtPushHelpLine
    2093         ("  Edit the additional fields to your heart's content, then click OK or Cancel.");
    2094     headerMsg = newtLabel(1, 1, "Label                            Value");
    2095     varsListbox =
    2096         newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
    2097     i = 1;
    2098     bAdd = newtCompactButton(i, 9, " Add ");
    2099     bEdit = newtCompactButton(i += 8, 9, " Edit ");
    2100     bDelete = newtCompactButton(i += 9, 9, "Delete");
    2101     bOK = newtCompactButton(i += 9, 9, "  OK  ");
    2102     bCancel = newtCompactButton(i += 9, 9, "Cancel");
    2103     newtOpenWindow(17, 7, 46, 10, title_of_window);
    2104     myForm = newtForm(NULL, NULL, 0);
    2105     newtFormAddComponents(myForm, headerMsg, varsListbox, bAdd, bEdit,
    2106                           bDelete, bOK, bCancel, NULL);
    2107     insert_essential_additionalvars(raidrec);
    2108     redraw_varslist(&raidrec->additional_vars, keylist, varsListbox);
    2109     for (b_res = NULL; b_res != bOK && b_res != bCancel;) {
    2110         b_res = newtRunForm(myForm);
    2111         curr_choice = newtListboxGetCurrent(varsListbox);
    2112         for (currline = 0;
    2113              currline < raidrec->additional_vars.entries
    2114              && keylist[currline] != curr_choice; currline++);
    2115         if (currline == raidrec->additional_vars.entries
    2116             && raidrec->additional_vars.entries > 0) {
    2117             log_it("Warning - I don't know what this button does");
    2118         }
    2119         if (b_res == bOK) {     /* do nothing */
    2120         } else if (b_res == bCancel) {  /* do nothing */
    2121         } else if (b_res == bAdd) {
    2122             add_varslist_entry(raidrec);
    2123         } else if (b_res == bDelete) {
    2124             delete_varslist_entry(raidrec, currline);
    2125         } else {
    2126             edit_varslist_entry(raidrec, currline);
    2127         }
    2128         redraw_varslist(&raidrec->additional_vars, keylist, varsListbox);
    2129     }
    2130     remove_essential_additionalvars(raidrec);
    2131     newtFormDestroy(myForm);
    2132     newtPopWindow();
    2133     newtPopHelpLine();
    2134     if (b_res == bCancel) {
    2135         memcpy((void *) raidrec, (void *) &bkp_raidrec,
    2136                sizeof(struct raid_device_record));
    2137     }
    2138     return;
    2139 }
    2140 #endif
    2141 
    2142 
    2143 /**
    2144  * Find the next free location to place a disk in @p disklist.
    2145  * @param disklist The disklist to operate on.
    2146  * @return The next free location (starting from 0).
    2147  * @ingroup restoreGuiDisklist
    2148  */
    2149 int find_next_free_index_in_disklist(struct list_of_disks *disklist)
    2150 {
    2151 
    2152     /** int ***************************************************************/
    2153     int index = -1;
    2154     int pos = 0;
    2155 
    2156   /** bool **************************************************************/
    2157     bool done;
    2158 
    2159     assert(disklist != NULL);
    2160 
    2161     for (done = FALSE; !done;) {
    2162         for (pos = 0;
    2163              pos < disklist->entries && disklist->el[pos].index <= index;
    2164              pos++);
    2165         if (pos >= disklist->entries) {
    2166             done = TRUE;
    2167         } else {
    2168             index = disklist->el[pos].index;
    2169         }
    2170     }
    2171     return (index + 1);
    2172 }
    2173 
    2174 
    2175 
    2176 /**
    2177  * Locate @p device in @p raidlist.
    2178  * @param raidlist The raidlist ot search in.
    2179  * @param device The RAID device to search for.
    2180  * @return The index of the device, or -1 if it could not be found.
    2181  * @ingroup restoreGuiMountlist
    2182  */
    2183 int
    2184 find_raid_device_in_raidlist(struct raidlist_itself *raidlist,
    2185                              char *device)
    2186 {
    2187 
    2188     /** int ***************************************************************/
    2189     int i = 0;
    2190 #ifdef __FreeBSD__
    2191     char *vdev = NULL;
    2192     int res = 0;
    2193 #else
    2194 // Linux
    2195 #endif
    2196 
    2197     assert(raidlist != NULL);
    2198     assert_string_is_neither_NULL_nor_zerolength(device);
    2199 
    2200 #ifdef __FreeBSD__
    2201     for (i = 0; i < raidlist->entries; i++) {
    2202         mr_asprintf(vdev, "/dev/vinum/%s", raidlist->el[i].volname);
    2203         res = strcmp(device, vdev);
    2204         mr_free(vdev);
    2205 
    2206         if (!res)
    2207             break;
    2208     }
    2209 #else
    2210 
    2211     for (i = 0;
    2212          strcmp(raidlist->el[i].raid_device, device)
    2213          && i < raidlist->entries; i++);
    2214 #endif
    2215     if (i == raidlist->entries) {
    2216         return (-1);
    2217     } else {
    2218         return (i);
    2219     }
    2220 }
    2221 
    2222 
    2223 /**
    2224  * Create a new raidtab entry for @p device in @p raidlist.
    2225  * @param raidlist The raidlist to add the device to.
    2226  * @param mountlist The mountlist containing information about the user's partitions.
    2227  * @param currline The selected line in the mountlist.
    2228  * @param device The RAID device (e.g. /dev/md0) to use.
    2229  * @ingroup restoreGuiMountlist
    2230  */
    2231 void
    2232 initiate_new_raidlist_entry(struct raidlist_itself *raidlist,
    2233                             struct mountlist_itself *mountlist,
    2234                             int currline, char *device)
    2235 {
    2236 
    2237     /** structure *********************************************************/
    2238     struct OSSWAP (raid_device_record, vinum_volume) * raidrec;
    2239 
    2240     /** int ***************************************************************/
    2241     int pos_in_raidlist = 0;
    2242 
    2243     assert(raidlist != NULL);
    2244     assert(mountlist != NULL);
    2245     assert_string_is_neither_NULL_nor_zerolength(device);
    2246 
    2247     pos_in_raidlist =
    2248         find_raid_device_in_raidlist(raidlist,
    2249                                      mountlist->el[currline].device);
    2250     if (pos_in_raidlist >= 0) {
    2251         fatal_error("Sorry, that RAID device already exists. Weird.");
    2252     }
    2253     pos_in_raidlist = raidlist->entries++;
    2254     raidrec = &raidlist->el[pos_in_raidlist];
    2255     initialize_raidrec(raidrec);
    2256     strcpy(raidrec->OSSWAP(raid_device, volname), OSSWAP(device, basename(device)));
    2257 #ifndef __FreeBSD__
    2258     choose_raid_level(raidrec);
    2259     select_raid_disks(mountlist, raidlist, raidrec, "data",
    2260                       &raidrec->data_disks);
    2261 #endif
    2262     edit_raidlist_entry(mountlist, raidlist, raidrec, currline);
    2263 }
    2264 
    2265 
    2266 #ifndef __FreeBSD__
    2267 /**
    2268  * Insert the RAID variables not stored in the "additional RAID variables" list there too.
    2269  * @param raidrec The RAID device record to operate on.
    2270  * @ingroup restoreGuiVarslist
    2271  */
    2272 void insert_essential_additionalvars(struct raid_device_record *raidrec)
    2273 {
    2274 
    2275     /** int **************************************************************/
    2276     int items = 0;
    2277 
    2278     assert(raidrec != NULL);
    2279 
    2280     items = raidrec->additional_vars.entries;
    2281     write_variableINT_to_raid_var_line(raidrec, items++,
    2282                                        "persistent-superblock",
    2283                                        raidrec->persistent_superblock);
    2284     write_variableINT_to_raid_var_line(raidrec, items++, "chunk-size",
    2285                                        raidrec->chunk_size);
    2286     raidrec->additional_vars.entries = items;
    2287 }
    2288 
    2289 #endif
    2290 
    22912729/**
    22922730 * Dummy function that proves that we can get to the point where Mondo is run.
     
    23142752    newtPopHelpLine();
    23152753}
    2316 
    2317 
    2318 
    2319 /**
    2320  * Redraw the disklist.
    2321  * @param disklist The disklist to read from.
    2322  * @param keylist The list of keys for @p listbox.
    2323  * @param listbox The Newt listbox component to redraw.
    2324  * @ingroup restoreGuiDisklist
    2325  */
    2326 void
    2327 redraw_disklist(struct list_of_disks *disklist,
    2328                 void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox)
    2329 {
    2330 
    2331     /** long **************************************************************/
    2332     long i = 0;
    2333     char *tmp = NULL;
    2334 
    2335     assert(disklist != NULL);
    2336     assert(keylist != NULL);
    2337     assert(listbox != NULL);
    2338 
    2339     newtListboxClear(listbox);
    2340 
    2341     for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
    2342         keylist[i] = (void *) i;
    2343     }
    2344     for (i = 0; i < disklist->entries; i++) {
    2345         tmp = disklist_entry_to_string(disklist, i);
    2346         newtListboxAppendEntry(listbox, tmp, keylist[i]);
    2347         mr_free(tmp);
    2348     }
    2349 }
    2350 
    2351 
    2352 /**
    2353  * Redraw the mountlist.
    2354  * @param mountlist The mountlist to read from.
    2355  * @param keylist The list of keys for @p listbox.
    2356  * @param listbox The Newt listbox component to redraw.
    2357  * @ingroup restoreGuiMountlist
    2358  */
    2359 void
    2360 redraw_mountlist(struct mountlist_itself *mountlist,
    2361                  void *keylist[ARBITRARY_MAXIMUM], newtComponent listbox)
    2362 {
    2363 
    2364     /** long **************************************************************/
    2365     long i = 0;
    2366     char * tmp = NULL;
    2367 
    2368     assert(mountlist != NULL);
    2369     assert(keylist != NULL);
    2370     assert(listbox != NULL);
    2371 
    2372     newtListboxClear(listbox);
    2373 //  sort_mountlist_by_device (mountlist);
    2374     for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
    2375         keylist[i] = (void *) i;
    2376     }
    2377     for (i = 0; i < mountlist->entries; i++) {
    2378         tmp = mountlist_entry_to_string(mountlist, i);
    2379         newtListboxAppendEntry(listbox, tmp, keylist[i]);
    2380         mr_free(tmp);
    2381     }
    2382 }
    2383 
    2384 
    2385 
    2386 
    2387 /**
    2388  * Redraw the list of unallocated RAID partitions.
    2389  * @param unallocated_raid_partitions The mountlist containing unallocated RAID partitions.
    2390  * @param keylist The list of keys for @p listbox.
    2391  * @param listbox The Newt listbox component to redraw.
    2392  * @ingroup restoreGuiDisklist
    2393  */
    2394 void redraw_unallocpartnslist(struct mountlist_itself
    2395                               *unallocated_raid_partitions,
    2396                               void *keylist[ARBITRARY_MAXIMUM],
    2397                               newtComponent listbox)
    2398 {
    2399 
    2400     /** long *************************************************************/
    2401     long i = 0;
    2402 
    2403     /** buffers **********************************************************/
    2404     char tmp[MAX_STR_LEN];
    2405 
    2406     assert(unallocated_raid_partitions != NULL);
    2407     assert(keylist != NULL);
    2408     assert(listbox != NULL);
    2409 
    2410     newtListboxClear(listbox);
    2411     for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
    2412         keylist[i] = (void *) i;
    2413     }
    2414     for (i = 0; i < unallocated_raid_partitions->entries; i++) {
    2415         sprintf(tmp, "%-22s %8lld",
    2416                 unallocated_raid_partitions->el[i].device,
    2417                 unallocated_raid_partitions->el[i].size / 1024L);
    2418         newtListboxAppendEntry(listbox, tmp, keylist[i]);
    2419     }
    2420 }
    2421 
    2422 #ifndef __FreeBSD__
    2423 /**
    2424  * Redraw the list of additional RAID variables.
    2425  * @param additional_vars The list of additional RAID varibals.
    2426  * @param keylist The list of keys for @p listbox.
    2427  * @param listbox The Newt listbox component to redraw.
    2428  * @ingroup restoreGuiVarslist
    2429  */
    2430 void
    2431 redraw_varslist(struct additional_raid_variables *additional_vars,
    2432                 void *keylist[], newtComponent listbox)
    2433 {
    2434     /** long ************************************************************/
    2435     long i = 0;
    2436 
    2437     /** buffers *********************************************************/
    2438     char tmp[MAX_STR_LEN];
    2439 
    2440     assert(additional_vars != NULL);
    2441     assert(keylist != NULL);
    2442     assert(listbox != NULL);
    2443 
    2444     newtListboxClear(listbox);
    2445 
    2446     for (i = 0; i < ARBITRARY_MAXIMUM; i++) {
    2447         keylist[i] = (void *) i;
    2448     }
    2449     for (i = 0; i < additional_vars->entries; i++) {
    2450         sprintf(tmp, "%-32s %-8s", additional_vars->el[i].label,
    2451                 additional_vars->el[i].value);
    2452         newtListboxAppendEntry(listbox, tmp, keylist[i]);
    2453     }
    2454 }
    2455 
    2456 
    2457 /**
    2458  * Remove variable @p label from the RAID variables list in @p raidrec.
    2459  * @param raidrec The RAID device record to remove the variable from.
    2460  * @param label The variable name to remove.
    2461  * @return The value of the variable removed.
    2462  * @ingroup restoreUtilityGroup
    2463  */
    2464 int
    2465 read_variableINT_and_remove_from_raidvars(struct
    2466                                           OSSWAP (raid_device_record,
    2467                                                   vinum_volume) * raidrec,
    2468                                           char *label)
    2469 {
    2470     /** int ***************************************************************/
    2471     int i = 0;
    2472     int res = 0;
    2473 
    2474 
    2475     assert(raidrec != NULL);
    2476     assert(label != NULL);
    2477 
    2478     for (i = 0;
    2479          i < raidrec->additional_vars.entries
    2480          && strcmp(raidrec->additional_vars.el[i].label, label); i++);
    2481     if (i == raidrec->additional_vars.entries) {
    2482         res = -1;
    2483     } else {
    2484         res = atoi(raidrec->additional_vars.el[i].value);
    2485         for (i++; i < raidrec->additional_vars.entries; i++) {
    2486             memcpy((void *) &raidrec->additional_vars.el[i - 1],
    2487                    (void *) &raidrec->additional_vars.el[i],
    2488                    sizeof(struct raid_var_line));
    2489         }
    2490         raidrec->additional_vars.entries--;
    2491     }
    2492     return (res);
    2493 }
    2494 #endif
    2495 
    2496 /**
    2497  * Change all RAID devices to use @p new_dev instead of @p old_dev.
    2498  * @param raidlist The raidlist to make the changes in.
    2499  * @param old_dev The old name of the device (what it used to be).
    2500  * @param new_dev The new name of the device (what it is now).
    2501  * @ingroup restoreGuiMountlist
    2502  */
    2503 void rejig_partition_name_in_raidlist_if_necessary(struct raidlist_itself
    2504                                                    *raidlist,
    2505                                                    char *old_dev,
    2506                                                    char *new_dev)
    2507 {
    2508     /** int ************************************************************/
    2509     int pos = 0;
    2510     int j = 0;
    2511 
    2512     assert(raidlist != NULL);
    2513     assert_string_is_neither_NULL_nor_zerolength(old_dev);
    2514     assert_string_is_neither_NULL_nor_zerolength(new_dev);
    2515 
    2516     pos = which_raid_device_is_using_this_partition(raidlist, old_dev);
    2517     if (pos < 0) {
    2518         log_it("No need to rejig %s in raidlist: it's not listed.", old_dev);
    2519     } else {
    2520         if ((j =
    2521              where_in_drivelist_is_drive(&raidlist->
    2522                                          OSSWAP(el[pos].data_disks, disks),
    2523                                          old_dev)) >= 0) {
    2524             strcpy(raidlist->OSSWAP(el[pos].data_disks, disks).el[j].device, new_dev);
    2525         } else
    2526             if ((j =
    2527                  where_in_drivelist_is_drive(&raidlist->
    2528                                              OSSWAP(el[pos].spare_disks,
    2529                                                     spares),
    2530                                              old_dev)) >= 0) {
    2531             strcpy(raidlist->OSSWAP(el[pos].spare_disks, spares).el[j].device, new_dev);
    2532         }
    2533 #ifndef __FreeBSD__
    2534         else if ((j =
    2535                   where_in_drivelist_is_drive(&raidlist->el[pos].
    2536                                               parity_disks,
    2537                                               old_dev)) >= 0) {
    2538             strcpy(raidlist->el[pos].parity_disks.el[j].device, new_dev);
    2539         } else
    2540             if ((j =
    2541                  where_in_drivelist_is_drive(&raidlist->el[pos].
    2542                                              failed_disks,
    2543                                              old_dev)) >= 0) {
    2544             strcpy(raidlist->el[pos].failed_disks.el[j].device, new_dev);
    2545         }
    2546 #endif
    2547         else {
    2548             log_it("%s is supposed to be listed in this raid dev but it's not...", old_dev);
    2549         }
    2550     }
    2551 }
    2552 
    2553 
    2554 #ifndef __FreeBSD__
    2555 /**
    2556  * Remove the essential RAID variables from the "additional variables" section.
    2557  * If they have been changed, set them in their normal locations too.
    2558  * @param raidrec The RAID device record to operate on.
    2559  * @ingroup restoreUtilityVarslist
    2560  */
    2561 void remove_essential_additionalvars(struct raid_device_record *raidrec)
    2562 {
    2563 
    2564     /** int **************************************************************/
    2565     int res = 0;
    2566 
    2567     assert(raidrec != NULL);
    2568 
    2569     res =
    2570         read_variableINT_and_remove_from_raidvars(raidrec,
    2571                                                   "persistent-superblock");
    2572     if (res > 0) {
    2573         raidrec->persistent_superblock = res;
    2574     }
    2575     res = read_variableINT_and_remove_from_raidvars(raidrec, "chunk-size");
    2576     if (res > 0) {
    2577         raidrec->chunk_size = res;
    2578     }
    2579     res = read_variableINT_and_remove_from_raidvars(raidrec, "block-size");
    2580 }
    2581 
    2582 /**
    2583  * Select the RAID disks to use in @p raidrec.
    2584  * @param mountlist_dontedit The mountlist (will not be edited).
    2585  * @param raidlist The raidlist to modify.
    2586  * @param raidrec The RAID device record in @p raidlist to work on.
    2587  * @param description_of_list The type of disks we're selecting (e.g. "data").
    2588  * @param disklist The disklist to put the user-selected disks in.
    2589  * @ingroup restoreGuiMountlist
    2590  */
    2591 void
    2592 select_raid_disks(struct mountlist_itself *mountlist_dontedit,
    2593                   struct raidlist_itself *raidlist,
    2594                   struct raid_device_record *raidrec,
    2595                   char *description_of_list,
    2596                   struct list_of_disks *disklist)
    2597 {
    2598     void *curr_choice;
    2599 
    2600     /** ??? ***************************************************************/
    2601 
    2602     /** structures ********************************************************/
    2603     struct raidlist_itself *bkp_raidlist;
    2604     struct raid_device_record *bkp_raidrec;
    2605     struct list_of_disks *bkp_disklist;
    2606     struct mountlist_itself *unallocated_raid_partitions;
    2607 
    2608     /** newt **************************************************************/
    2609     newtComponent myForm = NULL;
    2610     newtComponent bAdd = NULL;
    2611     newtComponent bDelete = NULL;
    2612     newtComponent bOK = NULL;
    2613     newtComponent bCancel = NULL;
    2614     newtComponent b_res = NULL;
    2615     newtComponent partitionsListbox = NULL;
    2616     newtComponent headerMsg = NULL;
    2617 
    2618     /** buffers **********************************************************/
    2619     void *keylist[ARBITRARY_MAXIMUM];
    2620     char *tmp = NULL;
    2621     char *help_text = NULL;
    2622     char *title_of_window = NULL;
    2623     char sz_res[MAX_STR_LEN];
    2624     char *header_text = NULL;
    2625 
    2626   /** int **************************************************************/
    2627     int i = 0;
    2628     int currline = 0;
    2629 
    2630     assert(mountlist_dontedit != NULL);
    2631     assert(raidlist != NULL);
    2632     assert(raidrec != NULL);
    2633     assert(description_of_list != NULL);
    2634     assert(disklist != NULL);
    2635 
    2636     log_it("malloc'ing");
    2637     bkp_raidrec = mr_malloc(sizeof(struct raid_device_record));
    2638     bkp_disklist = mr_malloc(sizeof(struct list_of_disks));
    2639     bkp_raidlist = mr_malloc(sizeof(struct raidlist_itself));
    2640     unallocated_raid_partitions = mr_malloc(sizeof(struct mountlist_itself));
    2641 
    2642     memcpy((void *) bkp_raidlist, (void *) raidlist, sizeof(struct raidlist_itself));
    2643     memcpy((void *) bkp_raidrec, (void *) raidrec, sizeof(struct raid_device_record));
    2644     memcpy((void *) bkp_disklist, (void *) disklist, sizeof(struct list_of_disks));
    2645 
    2646     log_it("Post-malloc");
    2647     mr_asprintf(help_text, "   Edit this RAID device's list of partitions. Choose OK or Cancel when done.");
    2648     mr_asprintf(header_text, "%-24s    %s", "Device", "Index");
    2649     mr_asprintf(title_of_window, "%s contains...", raidrec->raid_device);
    2650     newtPushHelpLine(help_text);
    2651     for (b_res = (newtComponent) 12345; b_res != bOK && b_res != bCancel;) {
    2652         headerMsg = newtLabel(1, 1, header_text);
    2653         partitionsListbox =
    2654             newtListbox(1, 2, 6, NEWT_FLAG_SCROLL | NEWT_FLAG_RETURNEXIT);
    2655         redraw_disklist(disklist, keylist, partitionsListbox);
    2656         i = 1;
    2657         bAdd = newtCompactButton(i, 9, " Add ");
    2658         bDelete = newtCompactButton(i += 8, 9, "Delete");
    2659         bOK = newtCompactButton(i += 9, 9, "  OK  ");
    2660         bCancel = newtCompactButton(i += 9, 9, "Cancel");
    2661         newtOpenWindow(21, 7, 38, 10, title_of_window);
    2662         myForm = newtForm(NULL, NULL, 0);
    2663         if (disklist->entries == 0) {
    2664             newtFormAddComponents(myForm, headerMsg, bAdd, bDelete, bOK,
    2665                                   bCancel, NULL);
    2666         } else {
    2667             newtFormAddComponents(myForm, headerMsg, partitionsListbox,
    2668                                   bAdd, bDelete, bOK, bCancel, NULL);
    2669         }
    2670         b_res = newtRunForm(myForm);
    2671         if (b_res == bOK || b_res == bCancel) { /* do nothing */
    2672 // That's OK. At the end of this subroutine (after this do/while loop),
    2673 // we'll throw away the changes if Cancel was pushed.
    2674         } else {
    2675             curr_choice = newtListboxGetCurrent(partitionsListbox);
    2676             for (i = 0; i < disklist->entries && keylist[i] != curr_choice;
    2677                  i++);
    2678             if (i == disklist->entries && disklist->entries > 0) {
    2679                 log_to_screen("I don't know what that button does!");
    2680             } else {
    2681                 currline = i;
    2682                 if (b_res == bAdd) {
    2683                     log_it("Making list of unallocated RAID slices");
    2684                     make_list_of_unallocated_raid_partitions
    2685                         (unallocated_raid_partitions, mountlist_dontedit,
    2686                          raidlist);
    2687                     if (unallocated_raid_partitions->entries <= 0) {
    2688                         popup_and_OK
    2689                             ("There are no unallocated partitions marked for RAID.");
    2690                     } else {
    2691                         log_it
    2692                             ("Done. The user may add one or more of the above to RAID device");
    2693                         add_disklist_entry(disklist, raidrec->raid_device,
    2694                                            unallocated_raid_partitions);
    2695                         log_it("I have finished adding a disklist entry.");
    2696                         redraw_disklist(disklist, keylist,
    2697                                         partitionsListbox);
    2698                     }
    2699                 } else if (b_res == bDelete) {
    2700                     delete_disklist_entry(disklist, raidrec->raid_device,
    2701                                           currline);
    2702                     redraw_disklist(disklist, keylist, partitionsListbox);
    2703                 } else {
    2704                     mr_asprintf(tmp, "%s's index is %d. What should it be?", raidrec->raid_device, disklist->el[currline].index);
    2705                     sprintf(sz_res, "%d", disklist->el[currline].index);
    2706                     if (popup_and_get_string("Set index", tmp, sz_res, 10)) {
    2707                         disklist->el[currline].index = atoi(sz_res);
    2708                     }
    2709                     mr_free(tmp);
    2710 
    2711                     redraw_disklist(disklist, keylist, partitionsListbox);
    2712                 }
    2713             }
    2714         }
    2715         newtFormDestroy(myForm);
    2716         newtPopWindow();
    2717     }
    2718     newtPopHelpLine();
    2719     mr_free(help_text);
    2720     mr_free(header_text);
    2721     mr_free(title_of_window);
    2722 
    2723     if (b_res == bCancel) {
    2724         memcpy((void *) raidlist, (void *) bkp_raidlist, sizeof(struct raidlist_itself));
    2725         memcpy((void *) raidrec, (void *) bkp_raidrec, sizeof(struct raid_device_record));
    2726         memcpy((void *) disklist, (void *) bkp_disklist, sizeof(struct list_of_disks));
    2727     }
    2728     mr_free(bkp_raidrec);
    2729     mr_free(bkp_disklist);
    2730     mr_free(bkp_raidlist);
    2731     mr_free(unallocated_raid_partitions);
    2732 }
    2733 #endif
    2734 
    2735 
    27362754
    27372755/**
Note: See TracChangeset for help on using the changeset viewer.