Changeset 49 in MondoRescue for trunk/mondo/mondo/common/libmondo-filelist.c


Ignore:
Timestamp:
Oct 7, 2005, 7:03:07 PM (19 years ago)
Author:
bcornec
Message:

some bugs corrected (size_t, & for getline, ...) + indent

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/mondo/mondo/common/libmondo-filelist.c

    r30 r49  
    1 /* libmondo-filelist.c
    2    $Id: libmondo-filelist.c,v 1.6 2004/06/10 15:29:12 hugo Exp $
    3 
    4 - for subroutines which manipulate the filelist
    5 
    6 
    7 01/11/2005
    8 - change  time_of_last_full_backup =  to st_mtime to allow manipulation of
    9 - /var/cache/mondo-archive/difflevel.0
    10 - Conor Daly <conor.daly@met.ie>
    11 
    12 10/01
    13 - don't try to sort non-existent file; return 0 instead
    14 
    15 09/14
    16 - dropped 'sort -o' (busybox doesn't support); use 'sort > ' instead
    17 
    18 08/02
    19 - add \ in front of [, ], ? or * when generating filelist subset
    20 
    21 07/27
    22 - sort filelists after creating them
    23 
    24 07/14
    25 - disabled ACL, xattr stuff; moved it to libmondo-archive.c
    26 - max sane size for a file is now 32MB
    27 
    28 07/10
    29 - added ACL and xattr support for afio users
    30 
    31 07/05
    32 - exclude /dev/shm from backup (Roberto Alsina)
    33 
    34 06/09
    35 - exclude /media/floppy or SuSE 9.1 freezes :(
    36 
    37 01/18/2004
    38 - exclude /sys as well as /proc
    39 
    40 10/18/2003
    41 - load_filelist() --- make sure you add the paths
    42   leading to the file, e.g. if you add /usr/lib/thingy.so
    43   then add /usr, /usr/lib first
    44 - rewritten load_filelist(), save_filelist(),
    45 - add_string_at_node(), find_string_at_node(),
    46 - save_filelist_entries_in_common()
    47 
    48 09/27
    49 - line 1269 had one too many '%s's
    50 
    51 09/26
    52 - fix newt* to be enclosed in #ifndef _XWIN
    53 - added superior progress display to mondo_makefilelist()
    54 
    55 09/18
    56 - call locate w/ 2> /dev/null at end of str
    57 
    58 09/16
    59 - replaced mondo-makefilelist with C subroutine
    60 
    61 06/06
    62 - fixed silly bug in load_filelist() which stopped
    63   funny German filenames from being handled properly
    64 
    65 05/19
    66 - misc clean-up (Steve Hindle)
    67 
    68 05/04
    69 - added Herman Kuster's multi-level bkp patch
    70 
    71 04/26
    72 - maximum max_set_size_for_a_file = maxsetsizeK*2
    73 - maximum is also 32MB
    74 
    75 04/24
    76 - added lots of assert()'s and log_OS_error()'s
    77 
    78 04/22
    79 - added lots of asserts() and log_OS_errors()'s
    80 
    81 04/07
    82 - cleaned up code a bit
    83 
    84 04/04
    85 - max_sane_size_for_a_file = maxsetsizeK*2 (was *8)
    86 
    87 01/02/2003
    88 - tell mondo-makefilelist that it's a custom catalog (if it is)
    89 
    90 10/01 - 10/31/2002
    91 - don't make large .bz2 or .tbz files into biggiefiles
    92 - max_sane_size_for_a_file = maxsetsizeK*8, or 64MB
    93   ...whichever is smaller
    94 
    95 08/01 - 08/31
    96 - if last filelist is <=2 bytes long then delete it
    97 - max_sane_size_for_a_file = maxsetsizeK
    98   (was SLICESIZE*4 or something)
    99 - cleaned up some log_it() calls
    100 
    101 07/26
    102 - started
     1/* $Id$
     2
     3for subroutines which manipulate the filelist
     4
    1035*/
    1046
     
    13537
    13638
    137 extern ssize_t getline(char **lineptr, size_t *n, FILE *stream);
    138 
    139 
    140 int mondo_makefilelist(char*logfile, char*tmpdir, char*scratchdir,
    141     char*include_paths, char*excp, int differential, char *userdef_filelist);
     39int mondo_makefilelist(char *logfile, char *tmpdir, char *scratchdir,
     40                       char *include_paths, char *excp, int differential,
     41                       char *userdef_filelist);
    14242
    14343
    14444/*@unused@*/
    145 //static char cvsid[] = "$Id: libmondo-filelist.c,v 1.6 2004/06/10 15:29:12 hugo Exp $";
     45//static char cvsid[] = "$Id$";
    14646
    14747/**
     
    15656 * @ingroup globalGroup
    15757 */
    158 long g_noof_sets=0;
     58long g_noof_sets = 0;
    15959
    16060extern bool g_text_mode;
     
    18080 * @see chop_filelist
    18181 */
    182 int
    183 call_filelist_chopper (struct s_bkpinfo *bkpinfo)
    184 {
    185     /*@ buffers ************************/
    186   char *dev;
    187   char *filelist;
    188   char *tempfile;
    189   char *cksumlist;
    190   char *tmp;
    191   long noof_sets;
    192 
    193     /*@ pointers ***********************/
    194   char *ptr;
    195   FILE *fout;
    196 
    197     /*@ int ****************************/
    198   int i, retval=0;
    199 
    200   malloc_string(dev);
    201   malloc_string(filelist);
    202   malloc_string(tempfile);
    203   malloc_string(cksumlist);
    204   malloc_string(tmp);
    205   mvaddstr_and_log_it (g_currentY, 0, "Dividing filelist into sets");
    206 
    207   log_to_screen ("Dividing filelist into sets. Please wait.");
    208   i=0;
     82int call_filelist_chopper(struct s_bkpinfo *bkpinfo)
     83{
     84    /*@ buffers *********************** */
     85    char *dev;
     86    char *filelist;
     87    char *tempfile;
     88    char *cksumlist;
     89    char *tmp;
     90    long noof_sets;
     91
     92    /*@ pointers ********************** */
     93    char *ptr;
     94    FILE *fout;
     95
     96    /*@ int *************************** */
     97    int i, retval = 0;
     98
     99    malloc_string(dev);
     100    malloc_string(filelist);
     101    malloc_string(tempfile);
     102    malloc_string(cksumlist);
     103    malloc_string(tmp);
     104    mvaddstr_and_log_it(g_currentY, 0, "Dividing filelist into sets");
     105
     106    log_to_screen("Dividing filelist into sets. Please wait.");
     107    i = 0;
    209108/*
    210109  if (find_home_of_exe("getfattr"))
     
    215114    { i=0; log_to_screen ("This will take more time. Please be patient."); }
    216115*/
    217   sprintf (filelist, "%s/archives/filelist.full", bkpinfo->scratchdir);
    218   sprintf (cksumlist, "%s/cklist.full", bkpinfo->tmpdir);
    219   if (!does_file_exist(filelist)) { log_it("filelist %s not found", filelist); fatal_error("call_filelist_chopper() -- filelist not found!"); }
    220 
    221   noof_sets = chop_filelist (filelist, bkpinfo->tmpdir, bkpinfo->optimal_set_size);
    222   estimate_noof_media_required (bkpinfo, noof_sets); // for cosmetic purposes
    223 
    224   sprintf (tempfile, "%s/biggielist.txt", bkpinfo->tmpdir);
    225   if (!(fout = fopen (tempfile, "a")))
    226     {
    227       log_OS_error("Cannot append to biggielist");
    228       retval++;
    229       goto end_of_func;
    230     }
    231   log_it (bkpinfo->image_devs);
    232 
    233   ptr = bkpinfo->image_devs;
    234 
    235   while (ptr && *ptr)
    236     {
    237       strcpy (dev, ptr);
    238       log_it ("Examining imagedev %s", dev);
    239       for (i = 0; i < (int) strlen (dev) && dev[i] != ' '; i++);
    240       dev[i] = '\0';
    241       if (!strlen (dev))
    242     {
    243       continue;
    244     }
    245       fprintf (fout, "%s\n", dev);
    246       log_it ("Adding '%s' to biggielist", dev);
    247       if ((ptr = strchr (ptr, ' ')))
    248     {
    249       ptr++;
    250     }
    251     }
    252   paranoid_fclose(fout);
    253   mvaddstr_and_log_it (g_currentY++, 74, "Done.");
    254 
    255 end_of_func:
    256   paranoid_free(filelist);
    257   paranoid_free(tempfile);
    258   paranoid_free(cksumlist);
    259   paranoid_free(dev);
    260   paranoid_free(tmp);
    261   return(retval);
    262 }
    263 
    264 
    265 
    266 int sort_file(char*orig_fname)
    267 {
    268   char *tmp_fname;
    269   char *command;
    270   int retval=0;
    271 
    272   log_msg(1, "Sorting file %s", orig_fname);
    273   malloc_string(tmp_fname);
    274   malloc_string(command);
    275   sprintf(tmp_fname, "/tmp/sort.%d.%d.%d", (int)(random()%32768), (int)(random()%32768), (int)(random()%32768));
    276  
    277   if (!does_file_exist(orig_fname))
    278     { return(0); } // no sense in trying to sort an empty file
    279 
    280   sprintf(command, "sort %s > %s 2>> %s", orig_fname, tmp_fname, MONDO_LOGFILE);
    281   retval = system(command);
    282   if (retval)
    283     {
    284       log_msg(2, "Failed to sort %s - oh dear", orig_fname);
    285     }
    286   else
    287     {
    288       log_msg(2, "Sorted %s --> %s OK. Copying it back to %s now", orig_fname, tmp_fname, orig_fname);
    289       sprintf(command, "mv -f %s %s", tmp_fname, orig_fname);
    290       retval += run_program_and_log_output(command, 2);
    291       if (retval)
    292         {
    293       log_msg(2, "Failed to copy %s back to %s - oh dear", tmp_fname, orig_fname);
    294     }
    295       else
    296         {
    297       log_msg(2, "%s was sorted OK.", orig_fname);
    298     }
    299     }
    300   paranoid_free(tmp_fname);
    301   paranoid_free(command);
    302   log_msg(1, "Finished sorting file %s", orig_fname);
    303   return(retval);
     116    sprintf(filelist, "%s/archives/filelist.full", bkpinfo->scratchdir);
     117    sprintf(cksumlist, "%s/cklist.full", bkpinfo->tmpdir);
     118    if (!does_file_exist(filelist)) {
     119        log_it("filelist %s not found", filelist);
     120        fatal_error("call_filelist_chopper() -- filelist not found!");
     121    }
     122
     123    noof_sets =
     124        chop_filelist(filelist, bkpinfo->tmpdir,
     125                      bkpinfo->optimal_set_size);
     126    estimate_noof_media_required(bkpinfo, noof_sets);   // for cosmetic purposes
     127
     128    sprintf(tempfile, "%s/biggielist.txt", bkpinfo->tmpdir);
     129    if (!(fout = fopen(tempfile, "a"))) {
     130        log_OS_error("Cannot append to biggielist");
     131        retval++;
     132        goto end_of_func;
     133    }
     134    log_it(bkpinfo->image_devs);
     135
     136    ptr = bkpinfo->image_devs;
     137
     138    while (ptr && *ptr) {
     139        strcpy(dev, ptr);
     140        log_it("Examining imagedev %s", dev);
     141        for (i = 0; i < (int) strlen(dev) && dev[i] != ' '; i++);
     142        dev[i] = '\0';
     143        if (!strlen(dev)) {
     144            continue;
     145        }
     146        fprintf(fout, "%s\n", dev);
     147        log_it("Adding '%s' to biggielist", dev);
     148        if ((ptr = strchr(ptr, ' '))) {
     149            ptr++;
     150        }
     151    }
     152    paranoid_fclose(fout);
     153    mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     154
     155  end_of_func:
     156    paranoid_free(filelist);
     157    paranoid_free(tempfile);
     158    paranoid_free(cksumlist);
     159    paranoid_free(dev);
     160    paranoid_free(tmp);
     161    return (retval);
     162}
     163
     164
     165
     166int sort_file(char *orig_fname)
     167{
     168    char *tmp_fname;
     169    char *command;
     170    int retval = 0;
     171
     172    log_msg(1, "Sorting file %s", orig_fname);
     173    malloc_string(tmp_fname);
     174    malloc_string(command);
     175    sprintf(tmp_fname, "/tmp/sort.%d.%d.%d", (int) (random() % 32768),
     176            (int) (random() % 32768), (int) (random() % 32768));
     177
     178    if (!does_file_exist(orig_fname)) {
     179        return (0);
     180    }                           // no sense in trying to sort an empty file
     181
     182    sprintf(command, "sort %s > %s 2>> %s", orig_fname, tmp_fname,
     183            MONDO_LOGFILE);
     184    retval = system(command);
     185    if (retval) {
     186        log_msg(2, "Failed to sort %s - oh dear", orig_fname);
     187    } else {
     188        log_msg(2, "Sorted %s --> %s OK. Copying it back to %s now",
     189                orig_fname, tmp_fname, orig_fname);
     190        sprintf(command, "mv -f %s %s", tmp_fname, orig_fname);
     191        retval += run_program_and_log_output(command, 2);
     192        if (retval) {
     193            log_msg(2, "Failed to copy %s back to %s - oh dear", tmp_fname,
     194                    orig_fname);
     195        } else {
     196            log_msg(2, "%s was sorted OK.", orig_fname);
     197        }
     198    }
     199    paranoid_free(tmp_fname);
     200    paranoid_free(command);
     201    log_msg(1, "Finished sorting file %s", orig_fname);
     202    return (retval);
    304203}
    305204
     
    318217 * @return number of errors encountered (0 for success).
    319218 */
    320 int
    321 chop_filelist (char *filelist, char *outdir, long maxsetsizeK)
     219int chop_filelist(char *filelist, char *outdir, long maxsetsizeK)
    322220{
    323221/*@ long ****************************************/
    324   long lino = 0;
    325   long max_sane_size_for_a_file;
    326   long curr_set_size;
    327   long noof_lines;
    328   long siz;
    329 
    330     /*@ int *****************************************/
    331   int i;
    332   long curr_set_no;
    333 
    334     /*@ buffers **************************************/
    335   char *outfname;
    336   char *biggie_fname;
    337   char *incoming;
    338   char *tmp;
    339   char *acl_fname;
    340   char *xattr_fname;
    341 
    342     /*@ pointers ************************************/
    343   FILE *fin;
    344   FILE *fout;
    345   FILE *fbig;
    346 
    347     /*@ structures **********************************/
    348   struct stat buf;
    349   int err = 0;
    350 
    351   malloc_string(outfname);
    352   malloc_string(biggie_fname);
    353   incoming = malloc(MAX_STR_LEN*2);
    354   malloc_string(tmp);
    355   malloc_string(acl_fname);
    356   malloc_string(xattr_fname);
    357  
    358   assert_string_is_neither_NULL_nor_zerolength(filelist);
    359   assert_string_is_neither_NULL_nor_zerolength(outdir);
    360   assert( maxsetsizeK > 0);
    361 
    362   max_sane_size_for_a_file = 32L*1024L;
     222    long lino = 0;
     223    long max_sane_size_for_a_file;
     224    long curr_set_size;
     225    long noof_lines;
     226    long siz;
     227
     228    /*@ int **************************************** */
     229    int i;
     230    long curr_set_no;
     231
     232    /*@ buffers ************************************* */
     233    char *outfname;
     234    char *biggie_fname;
     235    char *incoming;
     236    char *tmp;
     237    char *acl_fname;
     238    char *xattr_fname;
     239
     240    /*@ pointers *********************************** */
     241    FILE *fin;
     242    FILE *fout;
     243    FILE *fbig;
     244
     245    /*@ structures ********************************* */
     246    struct stat buf;
     247    int err = 0;
     248
     249    malloc_string(outfname);
     250    malloc_string(biggie_fname);
     251    incoming = malloc(MAX_STR_LEN * 2);
     252    malloc_string(tmp);
     253    malloc_string(acl_fname);
     254    malloc_string(xattr_fname);
     255
     256    assert_string_is_neither_NULL_nor_zerolength(filelist);
     257    assert_string_is_neither_NULL_nor_zerolength(outdir);
     258    assert(maxsetsizeK > 0);
     259
     260    max_sane_size_for_a_file = 32L * 1024L;
    363261// max_sane_size_for_a_file = maxsetsizeK*2;
    364262//  if (max_sane_size_for_a_file > 32*1024)
    365263//    { max_sane_size_for_a_file = 32*1024; }
    366  
    367   log_it("filelist=%s;", filelist);
    368   open_evalcall_form ("Dividing filelist into sets");
    369   noof_lines = count_lines_in_file (filelist);
    370   if (!(fin = fopen (filelist, "r"))) { log_OS_error("Cannot openin filelist"); return(0); }
    371   curr_set_no = 0;
    372   curr_set_size = 0;
    373   sprintf (outfname, "%s/filelist.%ld", outdir, curr_set_no);
    374   sprintf (biggie_fname, "%s/biggielist.txt", outdir);
    375   log_it("outfname=%s; biggie_fname=%s", outfname, biggie_fname);
    376   if (!(fbig = fopen (biggie_fname, "w"))) { log_OS_error("Cannot openout biggie_fname"); err++; goto end_of_func; }
    377   if (!(fout = fopen (outfname, "w"))) { log_OS_error("Cannot openout outfname"); err++; goto end_of_func; }
    378   (void) fgets (incoming, MAX_STR_LEN*2-1, fin);
    379   while (!feof (fin))
    380     {
    381       lino++;
    382       i = strlen (incoming) - 1;
    383       if (i < 0)
    384     {
    385       i = 0;
    386     }
    387       if (i > MAX_STR_LEN-1)
    388         {
    389       incoming[MAX_STR_LEN-30] = '\0';
    390       log_msg(1, "Warning - truncating file %s's name", incoming);
    391       err++;
    392     }
    393       if (incoming[i] < 32)
    394     {
    395       incoming[i] = '\0';
    396     }
    397       if (!strncmp (incoming, "/dev/", 5))
    398     {
    399       siz = 1;
    400     }
    401       else if (lstat (incoming, &buf) != 0)
    402     {
    403       siz = 0;
    404     }
    405       else
    406     {
    407       siz = (long) (buf.st_size >> 10);
    408     }
    409       if (siz > max_sane_size_for_a_file)
     264
     265    log_it("filelist=%s;", filelist);
     266    open_evalcall_form("Dividing filelist into sets");
     267    noof_lines = count_lines_in_file(filelist);
     268    if (!(fin = fopen(filelist, "r"))) {
     269        log_OS_error("Cannot openin filelist");
     270        return (0);
     271    }
     272    curr_set_no = 0;
     273    curr_set_size = 0;
     274    sprintf(outfname, "%s/filelist.%ld", outdir, curr_set_no);
     275    sprintf(biggie_fname, "%s/biggielist.txt", outdir);
     276    log_it("outfname=%s; biggie_fname=%s", outfname, biggie_fname);
     277    if (!(fbig = fopen(biggie_fname, "w"))) {
     278        log_OS_error("Cannot openout biggie_fname");
     279        err++;
     280        goto end_of_func;
     281    }
     282    if (!(fout = fopen(outfname, "w"))) {
     283        log_OS_error("Cannot openout outfname");
     284        err++;
     285        goto end_of_func;
     286    }
     287    (void) fgets(incoming, MAX_STR_LEN * 2 - 1, fin);
     288    while (!feof(fin)) {
     289        lino++;
     290        i = strlen(incoming) - 1;
     291        if (i < 0) {
     292            i = 0;
     293        }
     294        if (i > MAX_STR_LEN - 1) {
     295            incoming[MAX_STR_LEN - 30] = '\0';
     296            log_msg(1, "Warning - truncating file %s's name", incoming);
     297            err++;
     298        }
     299        if (incoming[i] < 32) {
     300            incoming[i] = '\0';
     301        }
     302        if (!strncmp(incoming, "/dev/", 5)) {
     303            siz = 1;
     304        } else if (lstat(incoming, &buf) != 0) {
     305            siz = 0;
     306        } else {
     307            siz = (long) (buf.st_size >> 10);
     308        }
     309        if (siz > max_sane_size_for_a_file)
    410310// && strcmp(incoming+strlen(incoming)-4, ".bz2") && strcmp(incoming+strlen(incoming)-4, ".tbz"))
    411     {
    412       fprintf (fbig, "%s\n", incoming);
    413     }
    414       else
    415     {
    416       curr_set_size += siz;
    417       fprintf (fout, "%s\n", incoming);
    418       if (curr_set_size > maxsetsizeK)
    419         {
    420           paranoid_fclose(fout);
    421           sort_file(outfname);
    422           curr_set_no++;
    423           curr_set_size = 0;
    424           sprintf (outfname, "%s/filelist.%ld", outdir, curr_set_no);
    425           if (!(fout = fopen (outfname, "w"))) { log_OS_error("Unable to openout outfname"); err++; goto end_of_func; }
    426           sprintf (tmp, "Fileset #%ld chopped ", curr_set_no - 1);
    427           update_evalcall_form ((int) (lino * 100 / noof_lines));
    428           /*              if (!g_text_mode) {newtDrawRootText(0,22,tmp);newtRefresh();} else {log_it(tmp);} */
    429         }
    430     }
    431       (void) fgets (incoming, MAX_STR_LEN*2-1, fin);
    432     }
    433   paranoid_fclose (fin);
    434   paranoid_fclose (fout);
    435   paranoid_fclose (fbig);
    436 
    437   if (length_of_file(outfname) <= 2)
    438     {
    439       unlink(outfname);
    440       g_noof_sets --;
    441     }
    442   g_noof_sets = curr_set_no;
    443   sort_file(outfname);
    444   sort_file(biggie_fname);
    445   sprintf (outfname, "%s/LAST-FILELIST-NUMBER", outdir);
    446   sprintf (tmp, "%ld", curr_set_no);
    447   if (write_one_liner_data_file (outfname, tmp))
    448       { log_OS_error("Unable to echo write one-liner to LAST-FILELIST-NUMBER"); err = 1;}
    449   if (curr_set_no == 0)
    450     {
    451       sprintf (tmp, "Only one fileset. Fine.");
    452     }
    453   else
    454     {
    455       sprintf (tmp, "Filelist divided into %ld sets", curr_set_no + 1);
    456     }
    457   log_msg(1, tmp);
    458   close_evalcall_form ();
    459   /* This is to work around an obscure bug in Newt; open a form, close it,
    460      carry on... I don't know why it works but it works. If you don't do this
    461      then update_progress_form() won't show the "time taken / time remaining"
    462      line. The bug only crops up AFTER the call to chop_filelist(). Weird. */
     311        {
     312            fprintf(fbig, "%s\n", incoming);
     313        } else {
     314            curr_set_size += siz;
     315            fprintf(fout, "%s\n", incoming);
     316            if (curr_set_size > maxsetsizeK) {
     317                paranoid_fclose(fout);
     318                sort_file(outfname);
     319                curr_set_no++;
     320                curr_set_size = 0;
     321                sprintf(outfname, "%s/filelist.%ld", outdir, curr_set_no);
     322                if (!(fout = fopen(outfname, "w"))) {
     323                    log_OS_error("Unable to openout outfname");
     324                    err++;
     325                    goto end_of_func;
     326                }
     327                sprintf(tmp, "Fileset #%ld chopped ", curr_set_no - 1);
     328                update_evalcall_form((int) (lino * 100 / noof_lines));
     329                /*              if (!g_text_mode) {newtDrawRootText(0,22,tmp);newtRefresh();} else {log_it(tmp);} */
     330            }
     331        }
     332        (void) fgets(incoming, MAX_STR_LEN * 2 - 1, fin);
     333    }
     334    paranoid_fclose(fin);
     335    paranoid_fclose(fout);
     336    paranoid_fclose(fbig);
     337
     338    if (length_of_file(outfname) <= 2) {
     339        unlink(outfname);
     340        g_noof_sets--;
     341    }
     342    g_noof_sets = curr_set_no;
     343    sort_file(outfname);
     344    sort_file(biggie_fname);
     345    sprintf(outfname, "%s/LAST-FILELIST-NUMBER", outdir);
     346    sprintf(tmp, "%ld", curr_set_no);
     347    if (write_one_liner_data_file(outfname, tmp)) {
     348        log_OS_error
     349            ("Unable to echo write one-liner to LAST-FILELIST-NUMBER");
     350        err = 1;
     351    }
     352    if (curr_set_no == 0) {
     353        sprintf(tmp, "Only one fileset. Fine.");
     354    } else {
     355        sprintf(tmp, "Filelist divided into %ld sets", curr_set_no + 1);
     356    }
     357    log_msg(1, tmp);
     358    close_evalcall_form();
     359    /* This is to work around an obscure bug in Newt; open a form, close it,
     360       carry on... I don't know why it works but it works. If you don't do this
     361       then update_progress_form() won't show the "time taken / time remaining"
     362       line. The bug only crops up AFTER the call to chop_filelist(). Weird. */
    463363#ifndef _XWIN
    464   if (!g_text_mode)
    465     {
    466       open_progress_form ("", "", "", "", 100);
    467       newtPopHelpLine ();
    468       newtFormDestroy (g_progressForm);
    469       newtPopWindow ();
    470     }
     364    if (!g_text_mode) {
     365        open_progress_form("", "", "", "", 100);
     366        newtPopHelpLine();
     367        newtFormDestroy(g_progressForm);
     368        newtPopWindow();
     369    }
    471370#endif
    472 end_of_func:
    473   paranoid_free(outfname);
    474   paranoid_free(biggie_fname);
    475   paranoid_free(incoming);
    476   paranoid_free(tmp);
    477   paranoid_free(acl_fname);
    478   paranoid_free(xattr_fname);
    479   return (err ? 0 : curr_set_no + 1);
     371  end_of_func:
     372    paranoid_free(outfname);
     373    paranoid_free(biggie_fname);
     374    paranoid_free(incoming);
     375    paranoid_free(tmp);
     376    paranoid_free(acl_fname);
     377    paranoid_free(xattr_fname);
     378    return (err ? 0 : curr_set_no + 1);
    480379}
    481380
     
    489388 * @param filelist The filelist to free.
    490389 */
    491 void
    492 free_filelist (struct s_node *filelist)
    493 {
    494     /*@ int's ********************************************************/
    495   static int depth = 0;
    496   int percentage;
    497 
    498     /*@ long's *******************************************************/
    499   static long i = 0;
    500 
    501     /*@ end vars *****************************************************/
    502 
    503   assert(filelist!=NULL);
    504   if (depth == 0)
    505     {
    506       open_evalcall_form ("Freeing memory");
    507       log_to_screen ("Freeing memory formerly occupied by filelist");
    508     }
    509   depth++;
    510 
    511   if (filelist->ch == '\0')
    512     {
    513       if (!(i++ % 1111))
    514     {
    515       percentage = (int) (i * 100 / g_original_noof_lines_in_filelist);
    516       update_evalcall_form (percentage);
    517 
    518     }
    519     }
    520 
    521   if (filelist->right)
    522     {
    523       free_filelist (filelist->right);
    524       filelist->right = NULL;
    525     }
    526   if (filelist->down)
    527     {
     390void free_filelist(struct s_node *filelist)
     391{
     392    /*@ int's ******************************************************* */
     393    static int depth = 0;
     394    int percentage;
     395
     396    /*@ long's ****************************************************** */
     397    static long i = 0;
     398
     399    /*@ end vars **************************************************** */
     400
     401    assert(filelist != NULL);
     402    if (depth == 0) {
     403        open_evalcall_form("Freeing memory");
     404        log_to_screen("Freeing memory formerly occupied by filelist");
     405    }
     406    depth++;
     407
     408    if (filelist->ch == '\0') {
     409        if (!(i++ % 1111)) {
     410            percentage =
     411                (int) (i * 100 / g_original_noof_lines_in_filelist);
     412            update_evalcall_form(percentage);
     413
     414        }
     415    }
     416
     417    if (filelist->right) {
     418        free_filelist(filelist->right);
     419        filelist->right = NULL;
     420    }
     421    if (filelist->down) {
    528422/*      if (!(i++ %39999)) { update_evalcall_form(0); } */
    529       free_filelist (filelist->down);
    530       filelist->down = NULL;
    531     }
    532   filelist->ch = '\0';
    533   paranoid_free (filelist);
    534   depth--;
    535   if (depth == 0)
    536     {
    537       close_evalcall_form ();
    538       log_it ("Finished freeing memory");
    539     }
    540 }
    541 
    542 
    543 int call_exe_and_pipe_output_to_fd(char*syscall, FILE*pout)
    544 {
    545   FILE *pattr;
    546   char *tmp;
    547       pattr = popen(syscall, "r");
    548       if (!pattr)
    549         {
    550       log_msg(1, "Failed to open fattr() %s", syscall);
    551       return(1);
    552         }
    553       if (feof(pattr))
    554         {
    555       log_msg(1, "Failed to call fattr() %s", syscall);
    556       paranoid_pclose(pattr);
    557       return(2); 
    558     }
    559       malloc_string(tmp);
    560       for (fgets (tmp, MAX_STR_LEN, pattr); !feof (pattr);
    561        fgets (tmp, MAX_STR_LEN, pattr))
    562         {
    563       fputs(tmp, pout);
    564     }
    565       paranoid_pclose(pattr);
    566       paranoid_free(tmp);
    567       return(0);
    568 }
    569 
    570 
    571 
    572 int gen_aux_list(char*filelist, char*syscall_sprintf, char*auxlist_fname)
    573 {
    574   FILE*fin;
    575   FILE*pout;
    576   char*pout_command;
    577   char*syscall;
    578   char*file_to_analyze;
    579   int i;
    580  
    581   if (!(fin=fopen(filelist, "r")))
    582     {
    583       log_msg(1, "Cannot openin filelist %s", filelist);
    584       return(1);
    585     }
    586   malloc_string(pout_command);
    587   sprintf(pout_command, "gzip -c1 > %s", auxlist_fname);
    588   if (!(pout=popen(pout_command, "w")))
    589     {
    590       log_msg(1, "Cannot openout auxlist_fname %s", auxlist_fname);
    591       fclose(fin);
    592       paranoid_free(pout_command);
    593       return(4);
    594     }
    595   malloc_string(syscall);
    596   malloc_string(file_to_analyze);
    597   for (fgets (file_to_analyze, MAX_STR_LEN, fin); !feof (fin);
    598        fgets (file_to_analyze, MAX_STR_LEN, fin))
    599     {
    600       i = strlen(file_to_analyze);
    601       if (i>0 && file_to_analyze[i-1]<32) { file_to_analyze[i-1]='\0'; }
    602       log_msg(8, "Analyzing %s", file_to_analyze);
    603       sprintf(syscall, syscall_sprintf, file_to_analyze);
    604       strcat(syscall, " 2>> /dev/null"); // " MONDO_LOGFILE);
    605       call_exe_and_pipe_output_to_fd(syscall, pout);
    606     }
    607   paranoid_fclose(fin);
    608   paranoid_pclose(pout);
    609   paranoid_free(file_to_analyze);
    610   paranoid_free(syscall);
    611   paranoid_free(pout_command);
    612   return(0);
    613 }
    614 
    615 
    616 int get_acl_list(char*filelist, char*facl_fname)
    617 {
    618   char*command;
    619   int retval=0;
    620  
    621   malloc_string(command);
    622   sprintf(command, "touch %s", facl_fname);
    623   run_program_and_log_output(command, 8);
    624   if (find_home_of_exe("getfacl"))
    625     {
     423        free_filelist(filelist->down);
     424        filelist->down = NULL;
     425    }
     426    filelist->ch = '\0';
     427    paranoid_free(filelist);
     428    depth--;
     429    if (depth == 0) {
     430        close_evalcall_form();
     431        log_it("Finished freeing memory");
     432    }
     433}
     434
     435
     436int call_exe_and_pipe_output_to_fd(char *syscall, FILE * pout)
     437{
     438    FILE *pattr;
     439    char *tmp;
     440    pattr = popen(syscall, "r");
     441    if (!pattr) {
     442        log_msg(1, "Failed to open fattr() %s", syscall);
     443        return (1);
     444    }
     445    if (feof(pattr)) {
     446        log_msg(1, "Failed to call fattr() %s", syscall);
     447        paranoid_pclose(pattr);
     448        return (2);
     449    }
     450    malloc_string(tmp);
     451    for (fgets(tmp, MAX_STR_LEN, pattr); !feof(pattr);
     452         fgets(tmp, MAX_STR_LEN, pattr)) {
     453        fputs(tmp, pout);
     454    }
     455    paranoid_pclose(pattr);
     456    paranoid_free(tmp);
     457    return (0);
     458}
     459
     460
     461
     462int gen_aux_list(char *filelist, char *syscall_sprintf,
     463                 char *auxlist_fname)
     464{
     465    FILE *fin;
     466    FILE *pout;
     467    char *pout_command;
     468    char *syscall;
     469    char *file_to_analyze;
     470    int i;
     471
     472    if (!(fin = fopen(filelist, "r"))) {
     473        log_msg(1, "Cannot openin filelist %s", filelist);
     474        return (1);
     475    }
     476    malloc_string(pout_command);
     477    sprintf(pout_command, "gzip -c1 > %s", auxlist_fname);
     478    if (!(pout = popen(pout_command, "w"))) {
     479        log_msg(1, "Cannot openout auxlist_fname %s", auxlist_fname);
     480        fclose(fin);
     481        paranoid_free(pout_command);
     482        return (4);
     483    }
     484    malloc_string(syscall);
     485    malloc_string(file_to_analyze);
     486    for (fgets(file_to_analyze, MAX_STR_LEN, fin); !feof(fin);
     487         fgets(file_to_analyze, MAX_STR_LEN, fin)) {
     488        i = strlen(file_to_analyze);
     489        if (i > 0 && file_to_analyze[i - 1] < 32) {
     490            file_to_analyze[i - 1] = '\0';
     491        }
     492        log_msg(8, "Analyzing %s", file_to_analyze);
     493        sprintf(syscall, syscall_sprintf, file_to_analyze);
     494        strcat(syscall, " 2>> /dev/null");  // " MONDO_LOGFILE);
     495        call_exe_and_pipe_output_to_fd(syscall, pout);
     496    }
     497    paranoid_fclose(fin);
     498    paranoid_pclose(pout);
     499    paranoid_free(file_to_analyze);
     500    paranoid_free(syscall);
     501    paranoid_free(pout_command);
     502    return (0);
     503}
     504
     505
     506int get_acl_list(char *filelist, char *facl_fname)
     507{
     508    char *command;
     509    int retval = 0;
     510
     511    malloc_string(command);
     512    sprintf(command, "touch %s", facl_fname);
     513    run_program_and_log_output(command, 8);
     514    if (find_home_of_exe("getfacl")) {
    626515//      sort_file(filelist); // FIXME - filelist chopper sorts, so this isn't necessary
    627       sprintf(command, "cat %s | getfacl --all-effective -P - 2>> %s | gzip -c1 > %s 2>> %s", filelist, MONDO_LOGFILE, facl_fname, MONDO_LOGFILE);
    628       iamhere(command);
    629       retval = system(command);
    630     }
    631   paranoid_free(command);
    632   return(retval);
    633 }
    634 
    635 
    636 int get_fattr_list(char*filelist, char*fattr_fname)
    637 {
    638   char *command;
    639   int retval=0;
    640  
    641   malloc_string(command);
    642   sprintf(command, "touch %s", fattr_fname);
    643   run_program_and_log_output(command, 8);
    644   if (find_home_of_exe("getfattr"))
    645     {
     516        sprintf(command,
     517                "cat %s | getfacl --all-effective -P - 2>> %s | gzip -c1 > %s 2>> %s",
     518                filelist, MONDO_LOGFILE, facl_fname, MONDO_LOGFILE);
     519        iamhere(command);
     520        retval = system(command);
     521    }
     522    paranoid_free(command);
     523    return (retval);
     524}
     525
     526
     527int get_fattr_list(char *filelist, char *fattr_fname)
     528{
     529    char *command;
     530    int retval = 0;
     531
     532    malloc_string(command);
     533    sprintf(command, "touch %s", fattr_fname);
     534    run_program_and_log_output(command, 8);
     535    if (find_home_of_exe("getfattr")) {
    646536//      sort_file(filelist); // FIXME - filelist chopper sorts, so this isn't necessary
    647       retval = gen_aux_list(filelist, "getfattr --en=hex -P -d \"%s\"", fattr_fname);
    648     }
    649   paranoid_free(command);
    650   return(retval);
     537        retval =
     538            gen_aux_list(filelist, "getfattr --en=hex -P -d \"%s\"",
     539                         fattr_fname);
     540    }
     541    paranoid_free(command);
     542    return (retval);
    651543}
    652544
     
    674566
    675567
    676 int set_EXAT_list(char*orig_msklist, char*original_exat_fname, char*executable)
    677 {
    678   const int my_depth=8;
    679   char*command, *syscall_pin, *syscall_pout, *incoming;
    680   char*current_subset_file, *current_master_file, *masklist;
    681   int retval=0;
    682   int i;
    683   char*p,*q;
    684   FILE*pin, *pout, *faclin;
    685 
    686   malloc_string(command);
    687   log_msg(1, "set_EXAT_list(%s, %s, %s)", orig_msklist, original_exat_fname, executable); 
    688   if (!orig_msklist || !orig_msklist[0] || !does_file_exist(orig_msklist))
    689     {
    690       log_msg(1, "No masklist provided. I shall therefore set ALL attributes.");
    691       sprintf(command, "cat %s | gzip -dc | %s --restore - 2>> %s", original_exat_fname, executable, MONDO_LOGFILE);
    692       log_msg(1, "command = %s", command);
    693       retval = system(command);
    694       paranoid_free(command);
    695       log_msg(1, "Returning w/ retval=%d", retval);
    696       return(retval);
    697     }
    698   if (length_of_file(original_exat_fname) <= 0)
    699     {
    700       log_msg(1, "original_exat_fname %s is empty or missing, so no need to set EXAT list", original_exat_fname);
    701       paranoid_free(command);
    702       return(0);
    703     }
    704   malloc_string(incoming);
    705   malloc_string(masklist);
    706   malloc_string(current_subset_file);
    707   malloc_string(current_master_file);
    708   malloc_string(syscall_pin);
    709   malloc_string(syscall_pout);
    710   sprintf(masklist, "/tmp/%d.%d.mask", (int)(random()%32768), (int)(random()%32768));
    711   sprintf(command, "cp -f %s %s", orig_msklist, masklist);
    712   run_program_and_log_output(command, 1);
    713   sort_file(masklist);
    714   current_subset_file[0] = current_master_file[0] = '\0';
    715   sprintf(syscall_pin, "cat %s | gzip -dc", original_exat_fname);
    716   sprintf(syscall_pout, "%s --restore - 2>> %s", executable, MONDO_LOGFILE);
    717 
    718   log_msg(1, "syscall_pin = %s", syscall_pin);
    719   log_msg(1, "syscall_pout = %s", syscall_pout);
    720   pout = popen(syscall_pout, "w");
    721   if (!pout)
    722     { iamhere("Unable to openout to syscall_pout"); return(1); }
    723   pin = popen(syscall_pin, "r");
    724   if (!pin)
    725     { pclose(pout); iamhere("Unable to openin from syscall"); return(1); }
    726   faclin = fopen(masklist, "r");
    727   if (!faclin)
    728     { pclose(pin); pclose(pout); iamhere("Unable to openin masklist"); return(1); }
    729 
     568int set_EXAT_list(char *orig_msklist, char *original_exat_fname,
     569                  char *executable)
     570{
     571    const int my_depth = 8;
     572    char *command, *syscall_pin, *syscall_pout, *incoming;
     573    char *current_subset_file, *current_master_file, *masklist;
     574    int retval = 0;
     575    int i;
     576    char *p, *q;
     577    FILE *pin, *pout, *faclin;
     578
     579    malloc_string(command);
     580    log_msg(1, "set_EXAT_list(%s, %s, %s)", orig_msklist,
     581            original_exat_fname, executable);
     582    if (!orig_msklist || !orig_msklist[0]
     583        || !does_file_exist(orig_msklist)) {
     584        log_msg(1,
     585                "No masklist provided. I shall therefore set ALL attributes.");
     586        sprintf(command, "cat %s | gzip -dc | %s --restore - 2>> %s",
     587                original_exat_fname, executable, MONDO_LOGFILE);
     588        log_msg(1, "command = %s", command);
     589        retval = system(command);
     590        paranoid_free(command);
     591        log_msg(1, "Returning w/ retval=%d", retval);
     592        return (retval);
     593    }
     594    if (length_of_file(original_exat_fname) <= 0) {
     595        log_msg(1,
     596                "original_exat_fname %s is empty or missing, so no need to set EXAT list",
     597                original_exat_fname);
     598        paranoid_free(command);
     599        return (0);
     600    }
     601    malloc_string(incoming);
     602    malloc_string(masklist);
     603    malloc_string(current_subset_file);
     604    malloc_string(current_master_file);
     605    malloc_string(syscall_pin);
     606    malloc_string(syscall_pout);
     607    sprintf(masklist, "/tmp/%d.%d.mask", (int) (random() % 32768),
     608            (int) (random() % 32768));
     609    sprintf(command, "cp -f %s %s", orig_msklist, masklist);
     610    run_program_and_log_output(command, 1);
     611    sort_file(masklist);
     612    current_subset_file[0] = current_master_file[0] = '\0';
     613    sprintf(syscall_pin, "cat %s | gzip -dc", original_exat_fname);
     614    sprintf(syscall_pout, "%s --restore - 2>> %s", executable,
     615            MONDO_LOGFILE);
     616
     617    log_msg(1, "syscall_pin = %s", syscall_pin);
     618    log_msg(1, "syscall_pout = %s", syscall_pout);
     619    pout = popen(syscall_pout, "w");
     620    if (!pout) {
     621        iamhere("Unable to openout to syscall_pout");
     622        return (1);
     623    }
     624    pin = popen(syscall_pin, "r");
     625    if (!pin) {
     626        pclose(pout);
     627        iamhere("Unable to openin from syscall");
     628        return (1);
     629    }
     630    faclin = fopen(masklist, "r");
     631    if (!faclin) {
     632        pclose(pin);
     633        pclose(pout);
     634        iamhere("Unable to openin masklist");
     635        return (1);
     636    }
    730637//  printf("Hi there. Starting the loop\n");
    731  
    732   fgets(current_subset_file, MAX_STR_LEN, faclin);
    733   fgets(incoming, MAX_STR_LEN, pin);
    734   while(!feof(pin) && !feof(faclin))
    735     {
     638
     639    fgets(current_subset_file, MAX_STR_LEN, faclin);
     640    fgets(incoming, MAX_STR_LEN, pin);
     641    while (!feof(pin) && !feof(faclin)) {
    736642//      printf("incoming = %s", incoming);
    737      
    738       strcpy(current_master_file, incoming+8);
    739      
    740       p = current_subset_file;
    741       if (*p=='/') {p++;}
    742       i = strlen(p);
    743       if (i>0 && p[i-1]<32) { p[i-1] = '\0'; }
    744 
    745            
    746       q = current_master_file;
    747       if (*q=='/') {q++;}
    748       i = strlen(q);
    749       if (i>0 && q[i-1]<32) { q[i-1] = '\0'; }
    750 
    751       i = strcmp(p,q);
    752       log_msg(my_depth, "'%s' v '%s' --> %d\n", p, q, i);
    753      
     643
     644        strcpy(current_master_file, incoming + 8);
     645
     646        p = current_subset_file;
     647        if (*p == '/') {
     648            p++;
     649        }
     650        i = strlen(p);
     651        if (i > 0 && p[i - 1] < 32) {
     652            p[i - 1] = '\0';
     653        }
     654
     655
     656        q = current_master_file;
     657        if (*q == '/') {
     658            q++;
     659        }
     660        i = strlen(q);
     661        if (i > 0 && q[i - 1] < 32) {
     662            q[i - 1] = '\0';
     663        }
     664
     665        i = strcmp(p, q);
     666        log_msg(my_depth, "'%s' v '%s' --> %d\n", p, q, i);
     667
    754668//      printf("%s v %s --> %d\n", p, q, i);
    755      
    756       if (i<0)
    757         { // read another subset file in.
    758       log_msg(my_depth, "Reading next subset line in\n\n");
    759       fgets(current_subset_file, MAX_STR_LEN, faclin);
    760       continue;
    761     }
    762 
    763       if (!i) { fputs(incoming, pout); }
    764       fgets(incoming, MAX_STR_LEN, pin);
    765       if (!i) { log_msg(my_depth, "Copying master %s", q); }
    766      
     669
     670        if (i < 0) {            // read another subset file in.
     671            log_msg(my_depth, "Reading next subset line in\n\n");
     672            fgets(current_subset_file, MAX_STR_LEN, faclin);
     673            continue;
     674        }
     675
     676        if (!i) {
     677            fputs(incoming, pout);
     678        }
     679        fgets(incoming, MAX_STR_LEN, pin);
     680        if (!i) {
     681            log_msg(my_depth, "Copying master %s", q);
     682        }
    767683//      if (!i) { printf("Match --- %s\n", q); }
    768      
    769       while (!feof(pin) && strncmp(incoming, "# file: ", 8))
    770         {
    771           if (!i) {
    772      
    773 //    printf("%s", incoming);
    774      
    775       fputs(incoming, pout); }
    776           fgets(incoming, MAX_STR_LEN, pin);
    777         }
    778       if (!i) { fgets(current_subset_file, MAX_STR_LEN, faclin); }
    779     }
    780   while(!feof(pin)) { fgets (incoming, MAX_STR_LEN, pin); }
    781   fclose(faclin);
    782   pclose(pin);
    783   pclose(pout); 
    784  
     684
     685        while (!feof(pin) && strncmp(incoming, "# file: ", 8)) {
     686            if (!i) {
     687
     688//    printf("%s", incoming);
     689
     690                fputs(incoming, pout);
     691            }
     692            fgets(incoming, MAX_STR_LEN, pin);
     693        }
     694        if (!i) {
     695            fgets(current_subset_file, MAX_STR_LEN, faclin);
     696        }
     697    }
     698    while (!feof(pin)) {
     699        fgets(incoming, MAX_STR_LEN, pin);
     700    }
     701    fclose(faclin);
     702    pclose(pin);
     703    pclose(pout);
     704
    785705//  printf("OK, loop is done\n");
    786706
    787   unlink(masklist); 
    788   paranoid_free(current_subset_file);
    789   paranoid_free(current_master_file);
    790   paranoid_free(syscall_pout);
    791   paranoid_free(syscall_pin);
    792   paranoid_free(masklist);
    793   paranoid_free(incoming);
    794   paranoid_free(command);
    795   return(retval);
    796 } 
    797 
    798 
    799 int set_fattr_list(char*masklist, char*fattr_fname)
    800 {
    801   return(set_EXAT_list(masklist, fattr_fname, "setfattr"));
    802 }
    803 
    804 
    805 
    806 int set_acl_list(char*masklist, char*acl_fname)
    807 {
    808   return(set_EXAT_list(masklist, acl_fname, "setfacl"));
     707    unlink(masklist);
     708    paranoid_free(current_subset_file);
     709    paranoid_free(current_master_file);
     710    paranoid_free(syscall_pout);
     711    paranoid_free(syscall_pin);
     712    paranoid_free(masklist);
     713    paranoid_free(incoming);
     714    paranoid_free(command);
     715    return (retval);
     716}
     717
     718
     719int set_fattr_list(char *masklist, char *fattr_fname)
     720{
     721    return (set_EXAT_list(masklist, fattr_fname, "setfattr"));
     722}
     723
     724
     725
     726int set_acl_list(char *masklist, char *acl_fname)
     727{
     728    return (set_EXAT_list(masklist, acl_fname, "setfacl"));
    809729}
    810730
     
    833753 * @note This function should only be called at restore-time.
    834754 */
    835 int
    836 get_last_filelist_number (struct s_bkpinfo *bkpinfo)
    837 {
    838     /*@ buffers ******************************************************/
    839   char val_sz[MAX_STR_LEN];
    840   char cfg_fname[MAX_STR_LEN];
     755int get_last_filelist_number(struct s_bkpinfo *bkpinfo)
     756{
     757    /*@ buffers ***************************************************** */
     758    char val_sz[MAX_STR_LEN];
     759    char cfg_fname[MAX_STR_LEN];
    841760/*  char tmp[MAX_STR_LEN]; remove stan benoit apr 2002 */
    842761
    843     /*@ long *********************************************************/
    844   int val_i;
    845 
    846     /*@ end vars *****************************************************/
    847 
    848   assert(bkpinfo!=NULL);
    849 
    850   sprintf (cfg_fname, "%s/mondo-restore.cfg", bkpinfo->tmpdir);
    851   read_cfg_var (cfg_fname, "last-filelist-number", val_sz);
    852   val_i = atoi (val_sz);
    853   if (val_i <= 0)
    854     {
    855       val_i = 500;
    856     }
    857   return (val_i);
     762    /*@ long ******************************************************** */
     763    int val_i;
     764
     765    /*@ end vars **************************************************** */
     766
     767    assert(bkpinfo != NULL);
     768
     769    sprintf(cfg_fname, "%s/mondo-restore.cfg", bkpinfo->tmpdir);
     770    read_cfg_var(cfg_fname, "last-filelist-number", val_sz);
     771    val_i = atoi(val_sz);
     772    if (val_i <= 0) {
     773        val_i = 500;
     774    }
     775    return (val_i);
    858776}
    859777
     
    866784 * @bug I don't understand this function. Would someone care to explain it?
    867785 */
    868 int
    869 add_string_at_node (struct s_node *startnode, char *string_to_add)
    870 {
    871 
    872 
    873     /*@ int *********************************************************/
    874   int noof_chars;
    875   int i;
    876   int res;
    877 
    878     /*@ sturctures **************************************************/
    879   struct s_node *node, *newnode;
    880 
    881     /*@ char  *******************************************************/
    882   char char_to_add;
    883 
    884     /*@ bools *******************************************************/
    885 
    886   const bool sosodef = FALSE;
    887 
    888   static int depth=0;
    889   static char original_string[MAX_STR_LEN];
    890 
    891   assert(startnode!=NULL);
    892   assert(string_to_add!=NULL);
    893 
    894   if (!depth) { strcpy(original_string, string_to_add); }
    895 
    896   noof_chars = strlen (string_to_add) + 1;  /* we include the '\0' */
     786int add_string_at_node(struct s_node *startnode, char *string_to_add)
     787{
     788
     789
     790    /*@ int ******************************************************** */
     791    int noof_chars;
     792    int i;
     793    int res;
     794
     795    /*@ sturctures ************************************************* */
     796    struct s_node *node, *newnode;
     797
     798    /*@ char  ****************************************************** */
     799    char char_to_add;
     800
     801    /*@ bools ****************************************************** */
     802
     803    const bool sosodef = FALSE;
     804
     805    static int depth = 0;
     806    static char original_string[MAX_STR_LEN];
     807
     808    assert(startnode != NULL);
     809    assert(string_to_add != NULL);
     810
     811    if (!depth) {
     812        strcpy(original_string, string_to_add);
     813    }
     814
     815    noof_chars = strlen(string_to_add) + 1; /* we include the '\0' */
    897816
    898817/* walk across tree if necessary */
    899   node = startnode;
    900   char_to_add = string_to_add[0];
    901   if (node->right != NULL && node->ch < char_to_add)
    902     {
    903       log_msg(7, "depth=%d --- going RIGHT ... %c-->%c", depth, char_to_add, node->ch, (node->right)->ch);
    904       return (add_string_at_node (node->right, string_to_add));
    905     }
     818    node = startnode;
     819    char_to_add = string_to_add[0];
     820    if (node->right != NULL && node->ch < char_to_add) {
     821        log_msg(7, "depth=%d --- going RIGHT ... %c-->%c", depth,
     822                char_to_add, node->ch, (node->right)->ch);
     823        return (add_string_at_node(node->right, string_to_add));
     824    }
    906825
    907826/* walk down tree if appropriate */
    908   if (node->down != NULL && node->ch == char_to_add)
    909     {
    910       log_msg(7, "depth=%d char=%c --- going DOWN", depth, char_to_add);
    911       depth++;
    912       res = add_string_at_node (node->down, string_to_add + 1);
    913       depth--;
    914       return (res);
    915     }
    916 
    917   if (char_to_add == '\0' && node->ch =='\0')
    918     {
    919       log_msg(6, "%s already in tree", original_string);
    920       return(1);
    921     }
     827    if (node->down != NULL && node->ch == char_to_add) {
     828        log_msg(7, "depth=%d char=%c --- going DOWN", depth, char_to_add);
     829        depth++;
     830        res = add_string_at_node(node->down, string_to_add + 1);
     831        depth--;
     832        return (res);
     833    }
     834
     835    if (char_to_add == '\0' && node->ch == '\0') {
     836        log_msg(6, "%s already in tree", original_string);
     837        return (1);
     838    }
    922839
    923840/* add here */
    924   if (!(newnode = (struct s_node*)malloc (sizeof (struct s_node))))
    925             {
    926               log_to_screen ("failed to malloc");
    927               depth--;
    928               return (1);
    929             }
    930   if (char_to_add < node->ch) // add to the left of node
    931     {
    932       log_msg(7, "depth=%d char=%c --- adding (left)", depth, char_to_add);
    933       memcpy((void*)newnode, (void*)node, sizeof(struct s_node));
    934       node->right = newnode;
    935     }
    936   else if (char_to_add > node->ch) // add to the right of node
    937     {
    938       log_msg(7, "depth=%d char=%c --- adding (right)", depth, char_to_add);
    939       newnode->right = node->right; // newnode is to the RIGHT of node
    940       node->right = newnode;
    941       node = newnode;
    942     }
    943   // from now on, we're working on 'node'
    944   node->down = NULL;
    945   node->ch = char_to_add;
    946   node->expanded = node->selected = FALSE;
    947   if (char_to_add == '\0')
    948     {
    949       log_msg (6, "Added %s OK", original_string);
    950       return (0);
    951     }
    952 
     841    if (!(newnode = (struct s_node *) malloc(sizeof(struct s_node)))) {
     842        log_to_screen("failed to malloc");
     843        depth--;
     844        return (1);
     845    }
     846    if (char_to_add < node->ch) // add to the left of node
     847    {
     848        log_msg(7, "depth=%d char=%c --- adding (left)", depth,
     849                char_to_add);
     850        memcpy((void *) newnode, (void *) node, sizeof(struct s_node));
     851        node->right = newnode;
     852    } else if (char_to_add > node->ch)  // add to the right of node
     853    {
     854        log_msg(7, "depth=%d char=%c --- adding (right)", depth,
     855                char_to_add);
     856        newnode->right = node->right;   // newnode is to the RIGHT of node
     857        node->right = newnode;
     858        node = newnode;
     859    }
     860    // from now on, we're working on 'node'
     861    node->down = NULL;
     862    node->ch = char_to_add;
     863    node->expanded = node->selected = FALSE;
     864    if (char_to_add == '\0') {
     865        log_msg(6, "Added %s OK", original_string);
     866        return (0);
     867    }
    953868// add the rest
    954   log_msg(6, "Adding remaining chars ('%s')", string_to_add+1);
    955   for (i = 1; i < noof_chars; i++)
    956     {
    957       if (!(node->down = (struct s_node*)malloc (sizeof (struct s_node))))
    958     {
    959       log_to_screen ("%s - failed to malloc", string_to_add);
    960       return (1);
    961     }
    962       node = node->down;
    963       char_to_add = string_to_add[i];
    964       log_msg(6, "Adding '%c'", char_to_add);
    965       node->ch = char_to_add;
    966       node->right = node->down = NULL;
    967       node->expanded = node->selected = FALSE;
    968       if (!node->ch) { node->selected = sosodef; }
    969     }
    970   log_msg (6, "Finally - added %s OK", original_string);
    971   return (0);
     869    log_msg(6, "Adding remaining chars ('%s')", string_to_add + 1);
     870    for (i = 1; i < noof_chars; i++) {
     871        if (!
     872            (node->down =
     873             (struct s_node *) malloc(sizeof(struct s_node)))) {
     874            log_to_screen("%s - failed to malloc", string_to_add);
     875            return (1);
     876        }
     877        node = node->down;
     878        char_to_add = string_to_add[i];
     879        log_msg(6, "Adding '%c'", char_to_add);
     880        node->ch = char_to_add;
     881        node->right = node->down = NULL;
     882        node->expanded = node->selected = FALSE;
     883        if (!node->ch) {
     884            node->selected = sosodef;
     885        }
     886    }
     887    log_msg(6, "Finally - added %s OK", original_string);
     888    return (0);
    972889}
    973890
     
    981898 * @return A filelist tree structure.
    982899 */
    983 struct s_node *
    984 load_filelist (char *filelist_fname)
    985 {
    986 
    987     /*@ structures **************************************************/
    988   struct s_node *filelist;
    989 
    990     /*@ pointers ****************************************************/
    991   FILE *pin;
    992 
    993     /*@ buffers *****************************************************/
    994   char command_to_open_fname[MAX_STR_LEN];
    995   char fname[MAX_STR_LEN];
    996   char tmp[MAX_STR_LEN];
    997   int pos_in_fname;
    998     /*@ int *********************************************************/
    999   int percentage;
    1000 
    1001     /*@ long ********************************************************/
    1002   long lines_in_filelist;
    1003   long lino = 0;
    1004     /*@ end vars ****************************************************/
    1005 
    1006   assert_string_is_neither_NULL_nor_zerolength(filelist_fname);
    1007 
    1008   if (!does_file_exist(filelist_fname))
    1009     { fatal_error("filelist does not exist -- cannot load it"); }
    1010   log_to_screen ("Loading filelist");
    1011   sprintf(command_to_open_fname, "gzip -dc %s", filelist_fname);
    1012   sprintf(tmp, "zcat %s | wc -l", filelist_fname);
    1013   log_msg(6, "tmp = %s", tmp);
    1014   lines_in_filelist = atol(call_program_and_get_last_line_of_output(tmp));
    1015   if (lines_in_filelist < 3) { log_to_screen("Warning - surprisingly short filelist."); }
    1016   g_original_noof_lines_in_filelist = lines_in_filelist;
    1017   if (!(filelist = (struct s_node*)malloc (sizeof (struct s_node))))
    1018     {
    1019       return (NULL);
    1020     }
    1021   filelist->ch = '/';
    1022   filelist->right = NULL;
    1023   filelist->down = malloc(sizeof(struct s_node));
    1024   filelist->expanded = filelist->selected = FALSE;
    1025   (filelist->down)->ch = '\0';
    1026   (filelist->down)->right = (filelist->down)->down = FALSE;
    1027   (filelist->down)->expanded = (filelist->down)->selected = FALSE;
    1028   if (!(pin = popen (command_to_open_fname, "r")))
    1029     {
    1030       log_OS_error("Unable to openin filelist_fname");
    1031       return (NULL);
    1032     }
    1033   open_evalcall_form ("Loading filelist from disk");
    1034   for (fgets (fname, MAX_STR_LEN, pin); !feof (pin);
    1035        fgets (fname, MAX_STR_LEN, pin))
    1036     {
    1037       if ((fname[strlen(fname)-1]==13 || fname[strlen(fname)-1]==10) && strlen(fname)>0)
    1038         { fname[strlen(fname)-1] = '\0'; }
     900struct s_node *load_filelist(char *filelist_fname)
     901{
     902
     903    /*@ structures ************************************************* */
     904    struct s_node *filelist;
     905
     906    /*@ pointers *************************************************** */
     907    FILE *pin;
     908
     909    /*@ buffers **************************************************** */
     910    char command_to_open_fname[MAX_STR_LEN];
     911    char fname[MAX_STR_LEN];
     912    char tmp[MAX_STR_LEN];
     913    int pos_in_fname;
     914    /*@ int ******************************************************** */
     915    int percentage;
     916
     917    /*@ long ******************************************************* */
     918    long lines_in_filelist;
     919    long lino = 0;
     920    /*@ end vars *************************************************** */
     921
     922    assert_string_is_neither_NULL_nor_zerolength(filelist_fname);
     923
     924    if (!does_file_exist(filelist_fname)) {
     925        fatal_error("filelist does not exist -- cannot load it");
     926    }
     927    log_to_screen("Loading filelist");
     928    sprintf(command_to_open_fname, "gzip -dc %s", filelist_fname);
     929    sprintf(tmp, "zcat %s | wc -l", filelist_fname);
     930    log_msg(6, "tmp = %s", tmp);
     931    lines_in_filelist =
     932        atol(call_program_and_get_last_line_of_output(tmp));
     933    if (lines_in_filelist < 3) {
     934        log_to_screen("Warning - surprisingly short filelist.");
     935    }
     936    g_original_noof_lines_in_filelist = lines_in_filelist;
     937    if (!(filelist = (struct s_node *) malloc(sizeof(struct s_node)))) {
     938        return (NULL);
     939    }
     940    filelist->ch = '/';
     941    filelist->right = NULL;
     942    filelist->down = malloc(sizeof(struct s_node));
     943    filelist->expanded = filelist->selected = FALSE;
     944    (filelist->down)->ch = '\0';
     945    (filelist->down)->right = (filelist->down)->down = FALSE;
     946    (filelist->down)->expanded = (filelist->down)->selected = FALSE;
     947    if (!(pin = popen(command_to_open_fname, "r"))) {
     948        log_OS_error("Unable to openin filelist_fname");
     949        return (NULL);
     950    }
     951    open_evalcall_form("Loading filelist from disk");
     952    for (fgets(fname, MAX_STR_LEN, pin); !feof(pin);
     953         fgets(fname, MAX_STR_LEN, pin)) {
     954        if ((fname[strlen(fname) - 1] == 13
     955             || fname[strlen(fname) - 1] == 10) && strlen(fname) > 0) {
     956            fname[strlen(fname) - 1] = '\0';
     957        }
    1039958//      strip_spaces (fname);
    1040       if (!strlen (fname))
    1041     {
    1042       continue;
    1043     }
    1044       for(pos_in_fname=0; fname[pos_in_fname]!='\0'; pos_in_fname++)
    1045         {
    1046       if (fname[pos_in_fname]!='/') { continue; }
    1047       strcpy(tmp, fname);
    1048       tmp[pos_in_fname] = '\0';
    1049       if (strlen(tmp))
    1050         { add_string_at_node (filelist, tmp); }
    1051     }
    1052       add_string_at_node (filelist, fname);
    1053       if (!(++lino % 1111))
    1054     {
    1055       percentage = (int) (lino * 100 / lines_in_filelist);
    1056       update_evalcall_form (percentage);
    1057     }
    1058     }
    1059   paranoid_pclose(pin);
    1060   close_evalcall_form ();
    1061   log_it ("Finished loading filelist");
    1062   return (filelist);
     959        if (!strlen(fname)) {
     960            continue;
     961        }
     962        for (pos_in_fname = 0; fname[pos_in_fname] != '\0'; pos_in_fname++) {
     963            if (fname[pos_in_fname] != '/') {
     964                continue;
     965            }
     966            strcpy(tmp, fname);
     967            tmp[pos_in_fname] = '\0';
     968            if (strlen(tmp)) {
     969                add_string_at_node(filelist, tmp);
     970            }
     971        }
     972        add_string_at_node(filelist, fname);
     973        if (!(++lino % 1111)) {
     974            percentage = (int) (lino * 100 / lines_in_filelist);
     975            update_evalcall_form(percentage);
     976        }
     977    }
     978    paranoid_pclose(pin);
     979    close_evalcall_form();
     980    log_it("Finished loading filelist");
     981    return (filelist);
    1063982}
    1064983
     
    1068987 * @param node The toplevel node to use.
    1069988 */
    1070 void
    1071 show_filelist (struct s_node *node)
    1072 {
    1073   static int depth=0;
    1074   static char current_string[200];
    1075 
    1076   if (depth==0)
    1077     { log_msg(0, "----------------show filelist--------------"); }
    1078   current_string[depth] = node->ch;
    1079 
    1080   log_msg(3, "depth=%d", depth);
    1081   if (node->down)
    1082     {
    1083       log_msg(3, "moving down");
    1084       depth++;
    1085       show_filelist(node->down);
    1086       depth--;
    1087     }
    1088 
    1089   if (!node->ch)
    1090     {
    1091       log_msg(0, "%s\n", current_string);
    1092     }
    1093 
    1094   if (node->right)
    1095     {
    1096       log_msg(3, "moving right");
    1097       show_filelist(node->right);
    1098     }
    1099   if (depth==0)
    1100     { log_msg(0, "----------------show filelist--------------"); }
    1101   return;
     989void show_filelist(struct s_node *node)
     990{
     991    static int depth = 0;
     992    static char current_string[200];
     993
     994    if (depth == 0) {
     995        log_msg(0, "----------------show filelist--------------");
     996    }
     997    current_string[depth] = node->ch;
     998
     999    log_msg(3, "depth=%d", depth);
     1000    if (node->down) {
     1001        log_msg(3, "moving down");
     1002        depth++;
     1003        show_filelist(node->down);
     1004        depth--;
     1005    }
     1006
     1007    if (!node->ch) {
     1008        log_msg(0, "%s\n", current_string);
     1009    }
     1010
     1011    if (node->right) {
     1012        log_msg(3, "moving right");
     1013        show_filelist(node->right);
     1014    }
     1015    if (depth == 0) {
     1016        log_msg(0, "----------------show filelist--------------");
     1017    }
     1018    return;
    11021019}
    11031020
     
    11101027 * @param filelist The filelist tree structure.
    11111028 */
    1112 void
    1113 reload_filelist (struct s_node *filelist)
    1114 {
    1115   assert(filelist!=NULL);
    1116   toggle_node_selection (filelist, FALSE);
    1117   toggle_path_expandability (filelist, "/", FALSE);
    1118   toggle_all_root_dirs_on (filelist);
     1029void reload_filelist(struct s_node *filelist)
     1030{
     1031    assert(filelist != NULL);
     1032    toggle_node_selection(filelist, FALSE);
     1033    toggle_path_expandability(filelist, "/", FALSE);
     1034    toggle_all_root_dirs_on(filelist);
    11191035}
    11201036
     
    11261042 * @param outfname Where to save it.
    11271043 */
    1128 void
    1129 save_filelist (struct s_node *filelist, char *outfname)
    1130 {
    1131     /*@ int **********************************************************/
    1132   static int percentage;
    1133   static int depth = 0;
    1134 
    1135     /*@ buffers ******************************************************/
    1136   static char str[MAX_STR_LEN];
    1137 
    1138     /*@ structures ***************************************************/
    1139   struct s_node *node;
    1140 
    1141     /*@ pointers *****************************************************/
    1142   static FILE *fout = NULL;
    1143 
    1144     /*@ long *********************************************************/
    1145   static long lines_in_filelist = 0;
    1146   static long lino = 0;
    1147 
    1148     /*@ end vars ****************************************************/
    1149 
    1150   assert(filelist!=NULL);
    1151   assert(outfname!=NULL); // will be zerolength if save_filelist() is called by itself
    1152   if (depth == 0)
    1153     {
    1154       log_to_screen ("Saving filelist");
    1155       if (!(fout = fopen (outfname, "w"))) { fatal_error("Cannot openout/save filelist"); }
    1156       lines_in_filelist = g_original_noof_lines_in_filelist;    /* set by load_filelist() */
    1157       open_evalcall_form ("Saving selection to disk");
    1158     }
    1159   for (node = filelist; node != NULL; node = node->right)
    1160     {
    1161       str[depth] = node->ch;
    1162       log_msg(5, "depth=%d ch=%c", depth, node->ch);
    1163       if (!node->ch)
    1164     {
    1165 //    if (node->selected)
    1166 //      {
    1167           fprintf (fout, "%s\n", str);
    1168 //      }
    1169       if (!(++lino % 1111))
    1170         {
    1171           percentage = (int) (lino * 100 / lines_in_filelist);
    1172           update_evalcall_form (percentage);
    1173         }
    1174     }
    1175       if (node->down)
    1176     {
    1177       depth++;
    1178       save_filelist (node->down, "");
    1179       depth--;
    1180     }
    1181     }
    1182   if (depth == 0)
    1183     {
    1184       paranoid_fclose (fout);
    1185       close_evalcall_form ();
    1186       log_it ("Finished saving filelist");
    1187     }
     1044void save_filelist(struct s_node *filelist, char *outfname)
     1045{
     1046    /*@ int ********************************************************* */
     1047    static int percentage;
     1048    static int depth = 0;
     1049
     1050    /*@ buffers ***************************************************** */
     1051    static char str[MAX_STR_LEN];
     1052
     1053    /*@ structures ************************************************** */
     1054    struct s_node *node;
     1055
     1056    /*@ pointers **************************************************** */
     1057    static FILE *fout = NULL;
     1058
     1059    /*@ long ******************************************************** */
     1060    static long lines_in_filelist = 0;
     1061    static long lino = 0;
     1062
     1063    /*@ end vars *************************************************** */
     1064
     1065    assert(filelist != NULL);
     1066    assert(outfname != NULL);   // will be zerolength if save_filelist() is called by itself
     1067    if (depth == 0) {
     1068        log_to_screen("Saving filelist");
     1069        if (!(fout = fopen(outfname, "w"))) {
     1070            fatal_error("Cannot openout/save filelist");
     1071        }
     1072        lines_in_filelist = g_original_noof_lines_in_filelist;  /* set by load_filelist() */
     1073        open_evalcall_form("Saving selection to disk");
     1074    }
     1075    for (node = filelist; node != NULL; node = node->right) {
     1076        str[depth] = node->ch;
     1077        log_msg(5, "depth=%d ch=%c", depth, node->ch);
     1078        if (!node->ch) {
     1079//    if (node->selected)
     1080//      {
     1081            fprintf(fout, "%s\n", str);
     1082//      }
     1083            if (!(++lino % 1111)) {
     1084                percentage = (int) (lino * 100 / lines_in_filelist);
     1085                update_evalcall_form(percentage);
     1086            }
     1087        }
     1088        if (node->down) {
     1089            depth++;
     1090            save_filelist(node->down, "");
     1091            depth--;
     1092        }
     1093    }
     1094    if (depth == 0) {
     1095        paranoid_fclose(fout);
     1096        close_evalcall_form();
     1097        log_it("Finished saving filelist");
     1098    }
    11881099}
    11891100
     
    11951106 * @bug I don't understand this function. Would someone care to explain it?
    11961107 */
    1197 void
    1198 toggle_all_root_dirs_on (struct s_node *filelist)
    1199 {
    1200     /*@ structures ***************************************************/
    1201   struct s_node *node;
    1202 
    1203     /*@ int **********************************************************/
    1204   static int depth = 0;
    1205   static int root_dirs_expanded;
    1206 
    1207     /*@ buffers ******************************************************/
    1208   static char filename[MAX_STR_LEN];
    1209 
    1210     /*@ end vars ****************************************************/
    1211 
    1212   assert(filelist!=NULL);
    1213   if (depth == 0)
    1214     {
    1215       log_it ("Toggling all root dirs ON");
    1216       root_dirs_expanded = 0;
    1217     }
    1218   for (node = filelist; node != NULL; node = node->right)
    1219     {
    1220       filename[depth] = node->ch;
    1221       if (node->ch == '\0' && strlen (filename) > 1
    1222       && (!strchr (filename + 1, '/')))
    1223     {
    1224       node->selected = FALSE;
    1225       node->expanded = TRUE;
    1226 //    log_it (filename);
    1227       root_dirs_expanded++;
    1228     }
    1229       if (node->down)
    1230     {
    1231       depth++;
    1232       toggle_all_root_dirs_on (node->down);
    1233       depth--;
    1234     }
    1235     }
    1236   if (depth == 0)
    1237     {
    1238       log_it ("Finished toggling all root dirs ON");
    1239     }
     1108void toggle_all_root_dirs_on(struct s_node *filelist)
     1109{
     1110    /*@ structures ************************************************** */
     1111    struct s_node *node;
     1112
     1113    /*@ int ********************************************************* */
     1114    static int depth = 0;
     1115    static int root_dirs_expanded;
     1116
     1117    /*@ buffers ***************************************************** */
     1118    static char filename[MAX_STR_LEN];
     1119
     1120    /*@ end vars *************************************************** */
     1121
     1122    assert(filelist != NULL);
     1123    if (depth == 0) {
     1124        log_it("Toggling all root dirs ON");
     1125        root_dirs_expanded = 0;
     1126    }
     1127    for (node = filelist; node != NULL; node = node->right) {
     1128        filename[depth] = node->ch;
     1129        if (node->ch == '\0' && strlen(filename) > 1
     1130            && (!strchr(filename + 1, '/'))) {
     1131            node->selected = FALSE;
     1132            node->expanded = TRUE;
     1133//    log_it (filename);
     1134            root_dirs_expanded++;
     1135        }
     1136        if (node->down) {
     1137            depth++;
     1138            toggle_all_root_dirs_on(node->down);
     1139            depth--;
     1140        }
     1141    }
     1142    if (depth == 0) {
     1143        log_it("Finished toggling all root dirs ON");
     1144    }
    12401145}
    12411146
     
    12491154 */
    12501155void
    1251 toggle_path_expandability (struct s_node *filelist, char *pathname,
    1252                bool on_or_off)
    1253 {
    1254 
    1255     /*@ int *********************************************************/
    1256   static int depth = 0;
    1257   static int total_expanded;
    1258   static int root_depth;
    1259   int j;
    1260     /*@ structures **************************************************/
    1261   struct s_node *node;
    1262 
    1263     /*@ buffers *****************************************************/
    1264   static char current_filename[MAX_STR_LEN];
     1156toggle_path_expandability(struct s_node *filelist, char *pathname,
     1157                          bool on_or_off)
     1158{
     1159
     1160    /*@ int ******************************************************** */
     1161    static int depth = 0;
     1162    static int total_expanded;
     1163    static int root_depth;
     1164    int j;
     1165    /*@ structures ************************************************* */
     1166    struct s_node *node;
     1167
     1168    /*@ buffers **************************************************** */
     1169    static char current_filename[MAX_STR_LEN];
    12651170
    12661171/*  char tmp[MAX_STR_LEN+2]; */
    12671172
    1268     /*@ end vars ****************************************************/
    1269 
    1270   assert(filelist!=NULL);
    1271   assert_string_is_neither_NULL_nor_zerolength(pathname);
    1272   if (depth == 0)
    1273     {
    1274       total_expanded = 0;
     1173    /*@ end vars *************************************************** */
     1174
     1175    assert(filelist != NULL);
     1176    assert_string_is_neither_NULL_nor_zerolength(pathname);
     1177    if (depth == 0) {
     1178        total_expanded = 0;
    12751179//      log_it ("Toggling path's expandability");
    1276       for (root_depth = (int) strlen (pathname);
    1277        root_depth > 0 && pathname[root_depth - 1] != '/'; root_depth--);
    1278       if (root_depth < 2)
    1279     {
    1280       root_depth = (int) strlen (pathname);
    1281     }
    1282     }
    1283   for (node = filelist; node != NULL; node = node->right)
    1284     {
    1285       current_filename[depth] = node->ch;
    1286       if (node->down)
    1287     {
    1288       depth++;
    1289       toggle_path_expandability (node->down, pathname, on_or_off);
    1290       depth--;
    1291     }
    1292       if (node->ch == '\0')
    1293     {
    1294       if (!strncmp (pathname, current_filename, strlen (pathname)))
    1295         {
    1296           for (j = root_depth;
    1297            current_filename[j] != '/' && current_filename[j] != '\0';
    1298            j++);
    1299           if (current_filename[j] != '\0')
    1300         {
    1301           for (j++;
    1302                current_filename[j] != '/'
    1303                && current_filename[j] != '\0'; j++);
    1304         }
    1305           if (current_filename[j] == '\0')
    1306         {
    1307           node->expanded =
    1308             (!strcmp (pathname, current_filename) ? TRUE : on_or_off);
    1309         }
    1310         }
    1311     }
    1312       if (node->expanded)
    1313     {
    1314       if (total_expanded < ARBITRARY_MAXIMUM - 32
    1315           || !strrchr (current_filename + strlen (pathname), '/'))
    1316         {
    1317           total_expanded++;
    1318         }
    1319       else
    1320         {
    1321           node->expanded = FALSE;
    1322         }
    1323     }
    1324     }
    1325   if (depth == 0)
    1326     {
     1180        for (root_depth = (int) strlen(pathname);
     1181             root_depth > 0 && pathname[root_depth - 1] != '/';
     1182             root_depth--);
     1183        if (root_depth < 2) {
     1184            root_depth = (int) strlen(pathname);
     1185        }
     1186    }
     1187    for (node = filelist; node != NULL; node = node->right) {
     1188        current_filename[depth] = node->ch;
     1189        if (node->down) {
     1190            depth++;
     1191            toggle_path_expandability(node->down, pathname, on_or_off);
     1192            depth--;
     1193        }
     1194        if (node->ch == '\0') {
     1195            if (!strncmp(pathname, current_filename, strlen(pathname))) {
     1196                for (j = root_depth;
     1197                     current_filename[j] != '/'
     1198                     && current_filename[j] != '\0'; j++);
     1199                if (current_filename[j] != '\0') {
     1200                    for (j++;
     1201                         current_filename[j] != '/'
     1202                         && current_filename[j] != '\0'; j++);
     1203                }
     1204                if (current_filename[j] == '\0') {
     1205                    node->expanded =
     1206                        (!strcmp(pathname, current_filename) ? TRUE :
     1207                         on_or_off);
     1208                }
     1209            }
     1210        }
     1211        if (node->expanded) {
     1212            if (total_expanded < ARBITRARY_MAXIMUM - 32
     1213                || !strrchr(current_filename + strlen(pathname), '/')) {
     1214                total_expanded++;
     1215            } else {
     1216                node->expanded = FALSE;
     1217            }
     1218        }
     1219    }
     1220    if (depth == 0) {
    13271221//      log_it ("Finished toggling expandability");
    1328     }
     1222    }
    13291223}
    13301224
     
    13371231 */
    13381232void
    1339 toggle_path_selection (struct s_node *filelist, char *pathname,
    1340                bool on_or_off)
    1341 {
    1342     /*@ int **********************************************************/
    1343   static int depth = 0;
    1344   int j;
    1345 
    1346     /*@ structures ***************************************************/
    1347   struct s_node *node;
    1348 
    1349     /*@ buffers ******************************************************/
    1350   static char current_filename[MAX_STR_LEN];
    1351   char tmp[MAX_STR_LEN + 2];
    1352 
    1353     /*@ end vars ****************************************************/
    1354   assert(filelist!=NULL);
    1355   assert_string_is_neither_NULL_nor_zerolength(pathname);
    1356   if (depth == 0)
    1357     {
    1358       log_it ("Toggling path's selection");
    1359     }
    1360   for (node = filelist; node != NULL; node = node->right)
    1361     {
    1362       current_filename[depth] = node->ch;
    1363       if (node->down)
    1364     {
    1365       depth++;
    1366       toggle_path_selection (node->down, pathname, on_or_off);
    1367       depth--;
    1368     }
    1369       if (node->ch == '\0')
    1370     {
    1371       if (!strncmp (pathname, current_filename, strlen (pathname)))
    1372         {
    1373           for (j = 0;
    1374            pathname[j] != '\0' && pathname[j] == current_filename[j];
    1375            j++);
    1376           if (current_filename[j] == '/' || current_filename[j] == '\0')
    1377         {
    1378           node->selected = on_or_off;
    1379           sprintf (tmp, "%s is now %s\n", current_filename,
    1380                (on_or_off ? "ON" : "OFF"));
    1381         }
    1382         }
    1383     }
    1384     }
    1385   if (depth == 0)
    1386     {
    1387       log_it ("Finished toggling selection");
    1388     }
     1233toggle_path_selection(struct s_node *filelist, char *pathname,
     1234                      bool on_or_off)
     1235{
     1236    /*@ int ********************************************************* */
     1237    static int depth = 0;
     1238    int j;
     1239
     1240    /*@ structures ************************************************** */
     1241    struct s_node *node;
     1242
     1243    /*@ buffers ***************************************************** */
     1244    static char current_filename[MAX_STR_LEN];
     1245    char tmp[MAX_STR_LEN + 2];
     1246
     1247    /*@ end vars *************************************************** */
     1248    assert(filelist != NULL);
     1249    assert_string_is_neither_NULL_nor_zerolength(pathname);
     1250    if (depth == 0) {
     1251        log_it("Toggling path's selection");
     1252    }
     1253    for (node = filelist; node != NULL; node = node->right) {
     1254        current_filename[depth] = node->ch;
     1255        if (node->down) {
     1256            depth++;
     1257            toggle_path_selection(node->down, pathname, on_or_off);
     1258            depth--;
     1259        }
     1260        if (node->ch == '\0') {
     1261            if (!strncmp(pathname, current_filename, strlen(pathname))) {
     1262                for (j = 0;
     1263                     pathname[j] != '\0'
     1264                     && pathname[j] == current_filename[j]; j++);
     1265                if (current_filename[j] == '/'
     1266                    || current_filename[j] == '\0') {
     1267                    node->selected = on_or_off;
     1268                    sprintf(tmp, "%s is now %s\n", current_filename,
     1269                            (on_or_off ? "ON" : "OFF"));
     1270                }
     1271            }
     1272        }
     1273    }
     1274    if (depth == 0) {
     1275        log_it("Finished toggling selection");
     1276    }
    13891277}
    13901278
     
    13961284 * @bug I don't understand this function. Would someone care to explain it?
    13971285 */
    1398 void
    1399 toggle_node_selection (struct s_node *filelist, bool on_or_off)
    1400 {
    1401     /*@ structure ***************************************************/
    1402   struct s_node *node;
    1403 
    1404     /*@ end vars ****************************************************/
    1405   assert(filelist!=NULL);
    1406   for (node = filelist; node != NULL; node = node->right)
    1407     {
    1408       if (node->ch == '/')
    1409     {
    1410       continue;
    1411     }           /* don't go deep */
    1412       if (node->ch == '\0')
    1413     {
    1414       node->selected = on_or_off;
    1415     }
    1416       if (node->down)
    1417     {
    1418       toggle_node_selection (node->down, on_or_off);
    1419     }
    1420     }
     1286void toggle_node_selection(struct s_node *filelist, bool on_or_off)
     1287{
     1288    /*@ structure ************************************************** */
     1289    struct s_node *node;
     1290
     1291    /*@ end vars *************************************************** */
     1292    assert(filelist != NULL);
     1293    for (node = filelist; node != NULL; node = node->right) {
     1294        if (node->ch == '/') {
     1295            continue;
     1296        }                       /* don't go deep */
     1297        if (node->ch == '\0') {
     1298            node->selected = on_or_off;
     1299        }
     1300        if (node->down) {
     1301            toggle_node_selection(node->down, on_or_off);
     1302        }
     1303    }
    14211304}
    14221305
     
    14301313 * The pathname to the skeleton filelist, used to give better progress reporting for mondo_makefilelist().
    14311314 */
    1432 char *g_skeleton_filelist=NULL;
     1315char *g_skeleton_filelist = NULL;
    14331316
    14341317/**
    14351318 * Number of entries in the skeleton filelist.
    14361319 */
    1437 long g_skeleton_entries=0;
     1320long g_skeleton_entries = 0;
    14381321
    14391322/**
     
    14491332 * @see mondo_makefilelist
    14501333 */
    1451 int
    1452 prepare_filelist (struct s_bkpinfo *bkpinfo)
    1453 {
    1454 
    1455     /*@ int *****************************************************/
    1456   int res = 0;
     1334int prepare_filelist(struct s_bkpinfo *bkpinfo)
     1335{
     1336
     1337    /*@ int **************************************************** */
     1338    int res = 0;
    14571339// patch by Herman Kuster
    14581340// end patch
    1459   int *p_res = &res;
    1460 
    1461     /*@ buffers *************************************************/
     1341    int *p_res = &res;
     1342
     1343    /*@ buffers ************************************************ */
    14621344//  char command[MAX_STR_LEN*2];
    14631345
    1464     /*@ i don't have any idea ***********************************/
    1465 
    1466   assert(bkpinfo!=NULL);
    1467   log_it ("tmpdir=%s; scratchdir=%s", bkpinfo->tmpdir,
    1468        bkpinfo->scratchdir);
    1469   if (bkpinfo->make_filelist)
    1470     {
    1471       mvaddstr_and_log_it (g_currentY, 0,
    1472                "Making catalog of files to be backed up");
    1473     }
    1474   else
    1475     {
    1476       mvaddstr_and_log_it (g_currentY, 0,
    1477                "Using supplied catalog of files to be backed up");
    1478     }
    1479 
    1480   if (bkpinfo->make_filelist)
    1481     {
    1482       res = mondo_makefilelist(
    1483        MONDO_LOGFILE, bkpinfo->tmpdir, bkpinfo->scratchdir,
    1484        bkpinfo->include_paths,
    1485        bkpinfo->exclude_paths,
    1486        bkpinfo->differential,
    1487        NULL);
    1488     }
    1489   else
    1490     {
    1491       res = mondo_makefilelist(
    1492        MONDO_LOGFILE, bkpinfo->tmpdir, bkpinfo->scratchdir,
    1493        NULL,
    1494        bkpinfo->exclude_paths,
    1495        bkpinfo->differential,
    1496        bkpinfo->include_paths);
    1497     }
    1498 
    1499   if (res)
    1500     {
    1501       log_OS_error("Call to mondo-makefilelist failed");
    1502       *p_res ++;
    1503       mvaddstr_and_log_it (g_currentY++, 74, "Failed.");
    1504     }
    1505   else
    1506     {
    1507       mvaddstr_and_log_it (g_currentY++, 74, "Done.");
    1508     }
    1509   return (res);
     1346    /*@ i don't have any idea ********************************** */
     1347
     1348    assert(bkpinfo != NULL);
     1349    log_it("tmpdir=%s; scratchdir=%s", bkpinfo->tmpdir,
     1350           bkpinfo->scratchdir);
     1351    if (bkpinfo->make_filelist) {
     1352        mvaddstr_and_log_it(g_currentY, 0,
     1353                            "Making catalog of files to be backed up");
     1354    } else {
     1355        mvaddstr_and_log_it(g_currentY, 0,
     1356                            "Using supplied catalog of files to be backed up");
     1357    }
     1358
     1359    if (bkpinfo->make_filelist) {
     1360        res =
     1361            mondo_makefilelist(MONDO_LOGFILE, bkpinfo->tmpdir,
     1362                               bkpinfo->scratchdir, bkpinfo->include_paths,
     1363                               bkpinfo->exclude_paths,
     1364                               bkpinfo->differential, NULL);
     1365    } else {
     1366        res =
     1367            mondo_makefilelist(MONDO_LOGFILE, bkpinfo->tmpdir,
     1368                               bkpinfo->scratchdir, NULL,
     1369                               bkpinfo->exclude_paths,
     1370                               bkpinfo->differential,
     1371                               bkpinfo->include_paths);
     1372    }
     1373
     1374    if (res) {
     1375        log_OS_error("Call to mondo-makefilelist failed");
     1376        *p_res++;
     1377        mvaddstr_and_log_it(g_currentY++, 74, "Failed.");
     1378    } else {
     1379        mvaddstr_and_log_it(g_currentY++, 74, "Done.");
     1380    }
     1381    return (res);
    15101382}
    15111383
     
    15201392 * @bug Return value should be @c void.
    15211393 */
    1522 int open_and_list_dir(char*dir, char*sth, FILE*fout, time_t time_of_last_full_backup)
    1523 {
    1524   DIR             *dip;
    1525   struct dirent   *dit;
    1526   struct stat statbuf;
    1527   char new[MAX_STR_LEN];
    1528   char *tmp;
    1529   char *sth_B;
    1530   static int percentage=0;
    1531   char *ith_B;
    1532   char *skip_these;
    1533   char *new_with_spaces;
    1534   static char *name_of_evalcall_form;
    1535   int i;
    1536   static int depth=0;
    1537   char *p;
    1538   static int counter=0;
    1539   static int uberctr=0;
    1540   static char *find_skeleton_marker;
    1541   static long skeleton_lino=0;
    1542   static time_t last_time=0;
    1543   time_t this_time;
    1544  
    1545   malloc_string(tmp);
    1546   malloc_string(sth_B);
    1547   malloc_string(ith_B);
    1548   malloc_string(new_with_spaces);
    1549   p = strrchr(dir, '/');
    1550   if (p)
    1551     {
    1552       if (!strcmp(p, "/.") || !strcmp(p, "/.."))
    1553         {
    1554           return(0);
    1555         }
    1556     }
    1557 
    1558   if (!depth)
    1559     {
    1560       malloc_string(name_of_evalcall_form);
    1561       malloc_string(find_skeleton_marker);
     1394int open_and_list_dir(char *dir, char *sth, FILE * fout,
     1395                      time_t time_of_last_full_backup)
     1396{
     1397    DIR *dip;
     1398    struct dirent *dit;
     1399    struct stat statbuf;
     1400    char new[MAX_STR_LEN];
     1401    char *tmp;
     1402    char *sth_B;
     1403    static int percentage = 0;
     1404    char *ith_B;
     1405    char *skip_these;
     1406    char *new_with_spaces;
     1407    static char *name_of_evalcall_form;
     1408    int i;
     1409    static int depth = 0;
     1410    char *p;
     1411    static int counter = 0;
     1412    static int uberctr = 0;
     1413    static char *find_skeleton_marker;
     1414    static long skeleton_lino = 0;
     1415    static time_t last_time = 0;
     1416    time_t this_time;
     1417
     1418    malloc_string(tmp);
     1419    malloc_string(sth_B);
     1420    malloc_string(ith_B);
     1421    malloc_string(new_with_spaces);
     1422    p = strrchr(dir, '/');
     1423    if (p) {
     1424        if (!strcmp(p, "/.") || !strcmp(p, "/..")) {
     1425            return (0);
     1426        }
     1427    }
     1428
     1429    if (!depth) {
     1430        malloc_string(name_of_evalcall_form);
     1431        malloc_string(find_skeleton_marker);
    15621432#if linux
    1563       // 2.6 has /sys as a proc-type thing -- must be excluded
    1564       sprintf(tmp, "find %s -maxdepth %d -path /proc -prune -o -path /tmp -prune -o -path /sys -prune -o -path /dev/shm -prune -o -path /media/floppy -prune -o -type d -a -print > %s 2> /dev/null", dir, MAX_SKEL_DEPTH, g_skeleton_filelist);
     1433        // 2.6 has /sys as a proc-type thing -- must be excluded
     1434        sprintf(tmp,
     1435                "find %s -maxdepth %d -path /proc -prune -o -path /tmp -prune -o -path /sys -prune -o -path /dev/shm -prune -o -path /media/floppy -prune -o -type d -a -print > %s 2> /dev/null",
     1436                dir, MAX_SKEL_DEPTH, g_skeleton_filelist);
    15651437#else
    1566       // On BSD, for example, /sys is the kernel sources -- don't exclude
    1567       sprintf(tmp, "find %s -maxdepth %d -path /proc -prune -o -path /tmp -prune -o -type d -a -print > %s 2> /dev/null", dir, MAX_SKEL_DEPTH, g_skeleton_filelist);
     1438        // On BSD, for example, /sys is the kernel sources -- don't exclude
     1439        sprintf(tmp,
     1440                "find %s -maxdepth %d -path /proc -prune -o -path /tmp -prune -o -type d -a -print > %s 2> /dev/null",
     1441                dir, MAX_SKEL_DEPTH, g_skeleton_filelist);
    15681442#endif
    1569       system(tmp);
    1570       sprintf(tmp, "wc -l %s | awk '{print $1;}'", g_skeleton_filelist);
    1571       g_skeleton_entries = 1 + atol(call_program_and_get_last_line_of_output(tmp));
    1572       sprintf(name_of_evalcall_form, "Making catalog of %s", dir);
    1573       open_evalcall_form (name_of_evalcall_form);
    1574       find_skeleton_marker[0] = '\0';
    1575       skeleton_lino=1;
    1576       log_msg(5, "entries = %ld", g_skeleton_entries);
    1577       percentage=0;
    1578     }
    1579   else if (depth<=MAX_SKEL_DEPTH) // update evalcall form if appropriate
    1580         {
    1581       sprintf(find_skeleton_marker, "fgrep -v \"%s\" %s > %s.new 2> /dev/null", dir, g_skeleton_filelist, g_skeleton_filelist);
    1582 //    log_msg(0, "fsm = %s", find_skeleton_marker);
    1583       if (!system(find_skeleton_marker))
    1584         {
    1585           percentage = (int)(skeleton_lino*100/g_skeleton_entries);
    1586           skeleton_lino++;
    1587 //        log_msg(5, "Found %s", dir);
    1588 //        log_msg(2, "Incrementing skeleton_lino; now %ld/%ld (%d%%)", skeleton_lino, g_skeleton_entries, percentage);
    1589           sprintf(find_skeleton_marker, "mv -f %s.new %s", g_skeleton_filelist, g_skeleton_filelist);
    1590 //        log_msg(6, "fsm = %s", find_skeleton_marker);
    1591           run_program_and_log_output(find_skeleton_marker, 8);
    1592           time(&this_time);
    1593           if (this_time != last_time)
    1594             {
    1595             last_time = this_time;
     1443        system(tmp);
     1444        sprintf(tmp, "wc -l %s | awk '{print $1;}'", g_skeleton_filelist);
     1445        g_skeleton_entries =
     1446            1 + atol(call_program_and_get_last_line_of_output(tmp));
     1447        sprintf(name_of_evalcall_form, "Making catalog of %s", dir);
     1448        open_evalcall_form(name_of_evalcall_form);
     1449        find_skeleton_marker[0] = '\0';
     1450        skeleton_lino = 1;
     1451        log_msg(5, "entries = %ld", g_skeleton_entries);
     1452        percentage = 0;
     1453    } else if (depth <= MAX_SKEL_DEPTH) // update evalcall form if appropriate
     1454    {
     1455        sprintf(find_skeleton_marker,
     1456                "fgrep -v \"%s\" %s > %s.new 2> /dev/null", dir,
     1457                g_skeleton_filelist, g_skeleton_filelist);
     1458//    log_msg(0, "fsm = %s", find_skeleton_marker);
     1459        if (!system(find_skeleton_marker)) {
     1460            percentage = (int) (skeleton_lino * 100 / g_skeleton_entries);
     1461            skeleton_lino++;
     1462//        log_msg(5, "Found %s", dir);
     1463//        log_msg(2, "Incrementing skeleton_lino; now %ld/%ld (%d%%)", skeleton_lino, g_skeleton_entries, percentage);
     1464            sprintf(find_skeleton_marker, "mv -f %s.new %s",
     1465                    g_skeleton_filelist, g_skeleton_filelist);
     1466//        log_msg(6, "fsm = %s", find_skeleton_marker);
     1467            run_program_and_log_output(find_skeleton_marker, 8);
     1468            time(&this_time);
     1469            if (this_time != last_time) {
     1470                last_time = this_time;
    15961471#ifndef _XWIN
    1597                   if (!g_text_mode)
    1598                 {
    1599               sprintf(tmp, "Reading %-68s", dir);
    1600                   newtDrawRootText (0, g_noof_rows - 3, tmp);
    1601             }
     1472                if (!g_text_mode) {
     1473                    sprintf(tmp, "Reading %-68s", dir);
     1474                    newtDrawRootText(0, g_noof_rows - 3, tmp);
     1475                }
    16021476#endif
    1603           update_evalcall_form(percentage);
    1604         }
    1605         }
    1606         }
    1607 
    1608   depth++;
     1477                update_evalcall_form(percentage);
     1478            }
     1479        }
     1480    }
     1481
     1482    depth++;
    16091483
    16101484//  log_msg(0, "Cataloguing %s", dir);
    1611   if (sth[0]==' ') { skip_these = sth; }
    1612   else
    1613     {
    1614       skip_these = sth_B;
    1615       sprintf(skip_these, " %s ", sth);
    1616     }
    1617   sprintf(new_with_spaces, " %s ", dir);
    1618   if ((dip = opendir(dir)) == NULL)
    1619     {
    1620       log_OS_error("opendir");
    1621     }
    1622   else if (strstr(skip_these, new_with_spaces))
    1623     {
    1624       fprintf(fout, "%s\n", dir); // if excluded dir then print dir ONLY
    1625     }
    1626   else
    1627     {
    1628       fprintf(fout, "%s\n", dir);
    1629       while ((dit = readdir(dip)) != NULL)
    1630        {
    1631     i++;
    1632         strcpy(new, dir);
    1633         if (strcmp(dir, "/")) { strcat(new, "/"); }
    1634         strcat(new, dit->d_name);
    1635     new_with_spaces[0] = ' ';
    1636           strcpy(new_with_spaces+1, new);
    1637           strcat(new_with_spaces, " ");
    1638     if (strstr(skip_these, new_with_spaces))
    1639       {
    1640         fprintf(fout, "%s\n", new);
    1641       }
    1642     else
    1643       {
    1644         if (!lstat(new, &statbuf))
    1645           {
    1646         if (!S_ISLNK(statbuf.st_mode) && S_ISDIR(statbuf.st_mode)) {
    1647           open_and_list_dir(new, skip_these, fout, time_of_last_full_backup);
    1648         }
    1649         else {
    1650           if (time_of_last_full_backup==0 || time_of_last_full_backup<statbuf.st_ctime)
    1651             {
    1652               fprintf(fout, "%s\n", new);
    1653               if ((counter++)>128)
    1654                 {
    1655                   counter=0;
    1656               uberctr++;
    1657                   sprintf(tmp, " %c ", special_dot_char(uberctr));
     1485    if (sth[0] == ' ') {
     1486        skip_these = sth;
     1487    } else {
     1488        skip_these = sth_B;
     1489        sprintf(skip_these, " %s ", sth);
     1490    }
     1491    sprintf(new_with_spaces, " %s ", dir);
     1492    if ((dip = opendir(dir)) == NULL) {
     1493        log_OS_error("opendir");
     1494    } else if (strstr(skip_these, new_with_spaces)) {
     1495        fprintf(fout, "%s\n", dir); // if excluded dir then print dir ONLY
     1496    } else {
     1497        fprintf(fout, "%s\n", dir);
     1498        while ((dit = readdir(dip)) != NULL) {
     1499            i++;
     1500            strcpy(new, dir);
     1501            if (strcmp(dir, "/")) {
     1502                strcat(new, "/");
     1503            }
     1504            strcat(new, dit->d_name);
     1505            new_with_spaces[0] = ' ';
     1506            strcpy(new_with_spaces + 1, new);
     1507            strcat(new_with_spaces, " ");
     1508            if (strstr(skip_these, new_with_spaces)) {
     1509                fprintf(fout, "%s\n", new);
     1510            } else {
     1511                if (!lstat(new, &statbuf)) {
     1512                    if (!S_ISLNK(statbuf.st_mode)
     1513                        && S_ISDIR(statbuf.st_mode)) {
     1514                        open_and_list_dir(new, skip_these, fout,
     1515                                          time_of_last_full_backup);
     1516                    } else {
     1517                        if (time_of_last_full_backup == 0
     1518                            || time_of_last_full_backup <
     1519                            statbuf.st_ctime) {
     1520                            fprintf(fout, "%s\n", new);
     1521                            if ((counter++) > 128) {
     1522                                counter = 0;
     1523                                uberctr++;
     1524                                sprintf(tmp, " %c ",
     1525                                        special_dot_char(uberctr));
    16581526#ifndef _XWIN
    1659               if (!g_text_mode) {
    1660                   newtDrawRootText (77, g_noof_rows - 3, tmp);
    1661                   newtRefresh();
    1662               }
     1527                                if (!g_text_mode) {
     1528                                    newtDrawRootText(77, g_noof_rows - 3,
     1529                                                     tmp);
     1530                                    newtRefresh();
     1531                                }
    16631532#endif
    1664                         }
    1665             }
    1666         }
    1667           }
    1668       }
    1669        }
    1670     }
    1671   if (dip)
    1672     {
    1673       if (closedir(dip) == -1)
    1674         {
    1675       log_OS_error("closedir");
    1676         }
    1677     }
    1678   depth--;
    1679   if (!depth)
    1680     {
    1681       close_evalcall_form ();
    1682       paranoid_free (name_of_evalcall_form);
    1683       paranoid_free(find_skeleton_marker);
    1684       unlink(g_skeleton_filelist);
    1685       log_msg(5, "g_skeleton_entries = %ld", g_skeleton_entries);
    1686     }
    1687   paranoid_free(tmp);
    1688   paranoid_free(sth_B);
    1689   paranoid_free(ith_B);
    1690   paranoid_free(new_with_spaces);
    1691   return(0);
     1533                            }
     1534                        }
     1535                    }
     1536                }
     1537            }
     1538        }
     1539    }
     1540    if (dip) {
     1541        if (closedir(dip) == -1) {
     1542            log_OS_error("closedir");
     1543        }
     1544    }
     1545    depth--;
     1546    if (!depth) {
     1547        close_evalcall_form();
     1548        paranoid_free(name_of_evalcall_form);
     1549        paranoid_free(find_skeleton_marker);
     1550        unlink(g_skeleton_filelist);
     1551        log_msg(5, "g_skeleton_entries = %ld", g_skeleton_entries);
     1552    }
     1553    paranoid_free(tmp);
     1554    paranoid_free(sth_B);
     1555    paranoid_free(ith_B);
     1556    paranoid_free(new_with_spaces);
     1557    return (0);
    16921558}
    16931559
     
    17021568 * @note The returned string points to static data that will be overwritten with each call.
    17031569 */
    1704 char *next_entry(char*incoming)
    1705 {
    1706   static char sz_res[MAX_STR_LEN];
    1707   char *p;
    1708   bool in_quotes=FALSE;
    1709 
    1710   strcpy(sz_res, incoming);
    1711   p = sz_res;
    1712   while((*p!=' ' || in_quotes) && *p!='\0')
    1713     {
    1714       if (*p=='\"') { in_quotes = !in_quotes; }
    1715       p++;
    1716     }
    1717   *p = '\0';
    1718   return(sz_res);
     1570char *next_entry(char *incoming)
     1571{
     1572    static char sz_res[MAX_STR_LEN];
     1573    char *p;
     1574    bool in_quotes = FALSE;
     1575
     1576    strcpy(sz_res, incoming);
     1577    p = sz_res;
     1578    while ((*p != ' ' || in_quotes) && *p != '\0') {
     1579        if (*p == '\"') {
     1580            in_quotes = !in_quotes;
     1581        }
     1582        p++;
     1583    }
     1584    *p = '\0';
     1585    return (sz_res);
    17191586}
    17201587
     
    17341601 * @bug Return value is meaningless.
    17351602 */
    1736 int mondo_makefilelist(char*logfile, char*tmpdir, char*scratchdir,
    1737     char*include_paths, char*excp, int differential, char *userdef_filelist)
     1603int mondo_makefilelist(char *logfile, char *tmpdir, char *scratchdir,
     1604                       char *include_paths, char *excp, int differential,
     1605                       char *userdef_filelist)
    17381606{
    17391607    char sz_datefile_wildcard[] = "/var/cache/mondo-archive/difflevel.%d";
     
    17421610    char *sz_filelist, *exclude_paths, *tmp;
    17431611    int i;
    1744     FILE*fout;
     1612    FILE *fout;
    17451613    char *command;
    1746         time_t time_of_last_full_backup=0;
     1614    time_t time_of_last_full_backup = 0;
    17471615    struct stat statbuf;
    17481616
    1749   malloc_string(command);
    1750   malloc_string(tmp);
    1751   malloc_string(sz_filelist);
    1752   malloc_string(g_skeleton_filelist);
    1753   if (!(exclude_paths = malloc(1000))) { fatal_error("Cannot malloc exclude_paths"); }
    1754   log_msg(3, "Trying to write test string to exclude_paths");
    1755   strcpy(exclude_paths, "/blah /froo");
    1756   log_msg(3, "...Success!");
    1757   sprintf(sz_datefile, sz_datefile_wildcard, 0);
    1758   if (!include_paths && !userdef_filelist)
    1759     { fatal_error("Please supply either include_paths or userdef_filelist"); }
    1760 
     1617    malloc_string(command);
     1618    malloc_string(tmp);
     1619    malloc_string(sz_filelist);
     1620    malloc_string(g_skeleton_filelist);
     1621    if (!(exclude_paths = malloc(1000))) {
     1622        fatal_error("Cannot malloc exclude_paths");
     1623    }
     1624    log_msg(3, "Trying to write test string to exclude_paths");
     1625    strcpy(exclude_paths, "/blah /froo");
     1626    log_msg(3, "...Success!");
     1627    sprintf(sz_datefile, sz_datefile_wildcard, 0);
     1628    if (!include_paths && !userdef_filelist) {
     1629        fatal_error
     1630            ("Please supply either include_paths or userdef_filelist");
     1631    }
    17611632// make hole for filelist
    1762   sprintf(command, "mkdir -p %s/archives", scratchdir);
    1763   paranoid_system(command);
    1764   sprintf(sz_filelist, "%s/tmpfs/filelist.full", tmpdir);
    1765   make_hole_for_file(sz_filelist);
    1766 
    1767   if (differential==0)
    1768     {
    1769   // restore last good datefile if it exists
    1770       sprintf(command, "cp -f %s.aborted %s", sz_datefile, sz_datefile);
    1771       run_program_and_log_output(command, 3);
    1772   // backup last known good datefile just in case :)
    1773       if (does_file_exist(sz_datefile))
    1774         {
    1775           sprintf(command, "mv -f %s %s.aborted", sz_datefile, sz_datefile);
    1776           paranoid_system(command);
    1777         }
    1778       make_hole_for_file(sz_datefile);
    1779       write_one_liner_data_file(sz_datefile, call_program_and_get_last_line_of_output("date +%s"));
    1780     }
    1781   else if (lstat(sz_datefile, &statbuf))
    1782     {
    1783       log_msg(2, "Warning - unable to find date of previous backup. Full backup instead.");
    1784       differential = 0;
    1785       time_of_last_full_backup = 0;
    1786     }
    1787   else
    1788     {
    1789       time_of_last_full_backup = statbuf.st_mtime;
    1790       log_msg(2, "Differential backup. Yay.");
    1791     }
     1633    sprintf(command, "mkdir -p %s/archives", scratchdir);
     1634    paranoid_system(command);
     1635    sprintf(sz_filelist, "%s/tmpfs/filelist.full", tmpdir);
     1636    make_hole_for_file(sz_filelist);
     1637
     1638    if (differential == 0) {
     1639        // restore last good datefile if it exists
     1640        sprintf(command, "cp -f %s.aborted %s", sz_datefile, sz_datefile);
     1641        run_program_and_log_output(command, 3);
     1642        // backup last known good datefile just in case :)
     1643        if (does_file_exist(sz_datefile)) {
     1644            sprintf(command, "mv -f %s %s.aborted", sz_datefile,
     1645                    sz_datefile);
     1646            paranoid_system(command);
     1647        }
     1648        make_hole_for_file(sz_datefile);
     1649        write_one_liner_data_file(sz_datefile,
     1650                                  call_program_and_get_last_line_of_output
     1651                                  ("date +%s"));
     1652    } else if (lstat(sz_datefile, &statbuf)) {
     1653        log_msg(2,
     1654                "Warning - unable to find date of previous backup. Full backup instead.");
     1655        differential = 0;
     1656        time_of_last_full_backup = 0;
     1657    } else {
     1658        time_of_last_full_backup = statbuf.st_mtime;
     1659        log_msg(2, "Differential backup. Yay.");
     1660    }
    17921661
    17931662// use user-specified filelist (if specified)
    1794   if (userdef_filelist)
    1795     {
    1796       log_msg(1, "Using the user-specified filelist - %s - instead of calculating one", userdef_filelist);
    1797       sprintf(command, "cp -f %s %s", userdef_filelist, sz_filelist);
    1798       if (run_program_and_log_output(command, 3))
    1799         { fatal_error("Failed to copy user-specified filelist"); }
    1800     }
    1801   else
    1802     {
    1803       log_msg(2, "include_paths = '%s'", include_paths);
    1804       log_msg(1, "Calculating filelist");
    1805       sprintf(exclude_paths, " %s %s %s %s %s %s . .. \
    1806 "MNT_CDROM" "MNT_FLOPPY" /media/cdrom /media/cdrecorder \
    1807 /proc /sys /tmp /root/images/mondo /root/images/mindi ",
    1808         excp,
    1809         call_program_and_get_last_line_of_output("locate /win386.swp 2> /dev/null"),
    1810         call_program_and_get_last_line_of_output("locate /hiberfil.sys 2> /dev/null"),
    1811         call_program_and_get_last_line_of_output("locate /pagefile.sys 2> /dev/null"),
    1812         (tmpdir[0]=='/' && tmpdir[1]=='/')?(tmpdir+1):tmpdir,
    1813         (scratchdir[0]=='/' && scratchdir[1]=='/')?(scratchdir+1):scratchdir
    1814                         );
    1815 
    1816     log_msg(2, "Excluding paths = '%s'", exclude_paths);
    1817     log_msg(2, "Generating skeleton filelist so that we can track our progress");
    1818     sprintf(g_skeleton_filelist, "%s/tmpfs/skeleton.txt", tmpdir);
    1819     make_hole_for_file(g_skeleton_filelist);
    1820     log_msg(4, "g_skeleton_entries = %ld", g_skeleton_entries);
    1821     log_msg(2, "Opening out filelist to %s", sz_filelist);
    1822     if (!(fout = fopen(sz_filelist, "w"))) { fatal_error("Cannot openout to sz_filelist"); }
    1823     i = 0;
    1824     if (strlen(include_paths)==0)
    1825         {
    1826           log_msg(1, "Including only '/' in %s", sz_filelist);
    1827         open_and_list_dir("/", exclude_paths, fout, time_of_last_full_backup);
    1828         }
    1829     else
    1830         {
    1831         p = include_paths;
    1832         while(*p)
    1833             {
    1834             q = next_entry(p);
    1835             log_msg(1, "Including %s in filelist %s", q, sz_filelist);
    1836             open_and_list_dir(q, exclude_paths, fout, time_of_last_full_backup);
    1837             p += strlen(q);
    1838             while(*p==' ') { p++; }
     1663    if (userdef_filelist) {
     1664        log_msg(1,
     1665                "Using the user-specified filelist - %s - instead of calculating one",
     1666                userdef_filelist);
     1667        sprintf(command, "cp -f %s %s", userdef_filelist, sz_filelist);
     1668        if (run_program_and_log_output(command, 3)) {
     1669            fatal_error("Failed to copy user-specified filelist");
     1670        }
     1671    } else {
     1672        log_msg(2, "include_paths = '%s'", include_paths);
     1673        log_msg(1, "Calculating filelist");
     1674        sprintf(exclude_paths, " %s %s %s %s %s %s . .. \
     1675" MNT_CDROM " " MNT_FLOPPY " /media/cdrom /media/cdrecorder \
     1676/proc /sys /tmp /root/images/mondo /root/images/mindi ", excp, call_program_and_get_last_line_of_output("locate /win386.swp 2> /dev/null"), call_program_and_get_last_line_of_output("locate /hiberfil.sys 2> /dev/null"), call_program_and_get_last_line_of_output("locate /pagefile.sys 2> /dev/null"), (tmpdir[0] == '/' && tmpdir[1] == '/') ? (tmpdir + 1) : tmpdir, (scratchdir[0] == '/' && scratchdir[1] == '/') ? (scratchdir + 1) : scratchdir);
     1677
     1678        log_msg(2, "Excluding paths = '%s'", exclude_paths);
     1679        log_msg(2,
     1680                "Generating skeleton filelist so that we can track our progress");
     1681        sprintf(g_skeleton_filelist, "%s/tmpfs/skeleton.txt", tmpdir);
     1682        make_hole_for_file(g_skeleton_filelist);
     1683        log_msg(4, "g_skeleton_entries = %ld", g_skeleton_entries);
     1684        log_msg(2, "Opening out filelist to %s", sz_filelist);
     1685        if (!(fout = fopen(sz_filelist, "w"))) {
     1686            fatal_error("Cannot openout to sz_filelist");
     1687        }
     1688        i = 0;
     1689        if (strlen(include_paths) == 0) {
     1690            log_msg(1, "Including only '/' in %s", sz_filelist);
     1691            open_and_list_dir("/", exclude_paths, fout,
     1692                              time_of_last_full_backup);
     1693        } else {
     1694            p = include_paths;
     1695            while (*p) {
     1696                q = next_entry(p);
     1697                log_msg(1, "Including %s in filelist %s", q, sz_filelist);
     1698                open_and_list_dir(q, exclude_paths, fout,
     1699                                  time_of_last_full_backup);
     1700                p += strlen(q);
     1701                while (*p == ' ') {
     1702                    p++;
     1703                }
    18391704            }
    18401705        }
    1841     paranoid_fclose(fout);
    1842     }
    1843   log_msg(2, "Copying new filelist to scratchdir");
    1844   sprintf(command, "mkdir -p %s/archives", scratchdir);
    1845   paranoid_system(command);
    1846   sprintf(command, "cp -f %s %s/archives/", sz_filelist, scratchdir);
    1847   paranoid_system(command);
    1848   sprintf(command, "mv -f %s %s", sz_filelist, tmpdir);
    1849   paranoid_system(command);
    1850   log_msg(2, "Freeing variables");
    1851   paranoid_free(sz_filelist);
    1852   paranoid_free(command);
    1853   paranoid_free(exclude_paths);
    1854   paranoid_free(tmp);
    1855   paranoid_free(g_skeleton_filelist);
    1856   log_msg(2, "Exiting");
    1857   return(0);
     1706        paranoid_fclose(fout);
     1707    }
     1708    log_msg(2, "Copying new filelist to scratchdir");
     1709    sprintf(command, "mkdir -p %s/archives", scratchdir);
     1710    paranoid_system(command);
     1711    sprintf(command, "cp -f %s %s/archives/", sz_filelist, scratchdir);
     1712    paranoid_system(command);
     1713    sprintf(command, "mv -f %s %s", sz_filelist, tmpdir);
     1714    paranoid_system(command);
     1715    log_msg(2, "Freeing variables");
     1716    paranoid_free(sz_filelist);
     1717    paranoid_free(command);
     1718    paranoid_free(exclude_paths);
     1719    paranoid_free(tmp);
     1720    paranoid_free(g_skeleton_filelist);
     1721    log_msg(2, "Exiting");
     1722    return (0);
    18581723}
    18591724
     
    18681733 * it was not found.
    18691734 */
    1870 struct s_node *find_string_at_node (struct s_node *startnode, char *string_to_find)
    1871 {
    1872     /*@ int *********************************************************/
    1873   int noof_chars;
    1874   static int depth=0;
    1875   static char original_string[MAX_STR_LEN];
    1876 
    1877     /*@ sturctures **************************************************/
    1878   struct s_node *node;
    1879 
    1880     /*@ char  *******************************************************/
    1881   char char_to_find;
    1882 
    1883     /*@ bools *******************************************************/
    1884 
    1885   if (!depth) { strcpy(original_string, string_to_find); }
    1886 
    1887   assert(startnode!=NULL);
    1888   assert(string_to_find!=NULL);
    1889 
    1890   noof_chars = strlen (string_to_find) + 1; /* we include the '\0' */
    1891 
    1892   log_msg(7, "starting --- str=%s", string_to_find);
     1735struct s_node *find_string_at_node(struct s_node *startnode,
     1736                                   char *string_to_find)
     1737{
     1738    /*@ int ******************************************************** */
     1739    int noof_chars;
     1740    static int depth = 0;
     1741    static char original_string[MAX_STR_LEN];
     1742
     1743    /*@ sturctures ************************************************* */
     1744    struct s_node *node;
     1745
     1746    /*@ char  ****************************************************** */
     1747    char char_to_find;
     1748
     1749    /*@ bools ****************************************************** */
     1750
     1751    if (!depth) {
     1752        strcpy(original_string, string_to_find);
     1753    }
     1754
     1755    assert(startnode != NULL);
     1756    assert(string_to_find != NULL);
     1757
     1758    noof_chars = strlen(string_to_find) + 1;    /* we include the '\0' */
     1759
     1760    log_msg(7, "starting --- str=%s", string_to_find);
    18931761
    18941762/* walk across tree if necessary */
    1895   node = startnode;
    1896   char_to_find = string_to_find[0];
    1897   if (node->right != NULL && node->ch < char_to_find)
    1898     {
    1899       log_msg(7, "depth=%d --- going RIGHT ... %c-->%c", depth, char_to_find, node->ch, (node->right)->ch);
    1900       return (find_string_at_node (node->right, string_to_find));
    1901     }
     1763    node = startnode;
     1764    char_to_find = string_to_find[0];
     1765    if (node->right != NULL && node->ch < char_to_find) {
     1766        log_msg(7, "depth=%d --- going RIGHT ... %c-->%c", depth,
     1767                char_to_find, node->ch, (node->right)->ch);
     1768        return (find_string_at_node(node->right, string_to_find));
     1769    }
    19021770
    19031771/* walk down tree if appropriate */
    1904   if (node->down != NULL && node->ch == char_to_find)
    1905     {
    1906       log_msg(7, "depth=%d char=%c --- going DOWN", depth, char_to_find);
    1907       depth++;
    1908       node = find_string_at_node (node->down, string_to_find + 1);
    1909       depth--;
    1910       return (node);
    1911     }
    1912 
    1913   if (char_to_find == '\0' && node->ch =='\0')
    1914     {
    1915       log_msg(7, "%s is in tree", original_string);
    1916       return(node);
    1917     }
    1918   else
    1919     {
    1920       log_msg(7, "%s is NOT in tree", original_string);
    1921       return(NULL);
    1922     }
     1772    if (node->down != NULL && node->ch == char_to_find) {
     1773        log_msg(7, "depth=%d char=%c --- going DOWN", depth, char_to_find);
     1774        depth++;
     1775        node = find_string_at_node(node->down, string_to_find + 1);
     1776        depth--;
     1777        return (node);
     1778    }
     1779
     1780    if (char_to_find == '\0' && node->ch == '\0') {
     1781        log_msg(7, "%s is in tree", original_string);
     1782        return (node);
     1783    } else {
     1784        log_msg(7, "%s is NOT in tree", original_string);
     1785        return (NULL);
     1786    }
    19231787}
    19241788
     
    19331797 * @return The number of matches found.
    19341798 */
    1935 long save_filelist_entries_in_common(
    1936             char*needles_list_fname,
    1937             struct s_node *filelist,
    1938             char*matches_list_fname, bool use_star)
    1939 {
    1940   int retval=0;
    1941   struct s_node *found_node;
    1942   FILE*fin;
    1943   FILE*fout;
    1944   char *fname;
    1945   char *tmp;
    1946   size_t len = 0; // Scrub's patch doesn't work without that
     1799long save_filelist_entries_in_common(char *needles_list_fname,
     1800                                     struct s_node *filelist,
     1801                                     char *matches_list_fname,
     1802                                    bool use_star)
     1803{
     1804    int retval = 0;
     1805    struct s_node *found_node;
     1806    FILE *fin;
     1807    FILE *fout;
     1808    char *fname = NULL;
     1809    char *tmp;
     1810    size_t len = 0;             // Scrub's patch doesn't work without that
    19471811
    19481812//  log_msg(1, "use_star = %s", (use_star)?"TRUE":"FALSE");
    1949   malloc_string(fname);
    1950   malloc_string(tmp);
    1951   log_msg(5, "starting");
    1952   log_msg(5, "needles_list_fname = %s", needles_list_fname);
    1953   log_msg(5, "matches_list_fname = %s", matches_list_fname);
    1954   if (!(fin = fopen(needles_list_fname, "r"))) { fatal_error("Cannot openin needles_list_fname"); }
    1955   if (!(fout= fopen(matches_list_fname, "w"))) { fatal_error("Cannot openout matches_list_fname"); }
    1956   while(!feof(fin))
    1957     {
    1958 //      fscanf(fin, "%s\n", fname);
    1959       len = MAX_STR_LEN-1;
    1960       getline(& fname, & len, fin); // patch by Scrub
    1961       if (!use_star)
    1962         {
    1963       if (fname[0]=='/')
    1964         { strcpy(tmp, fname); }
    1965       else
    1966         {
    1967           tmp[0]='/';
    1968           strcpy(tmp+1, fname);
    1969         }
    1970       strcpy(fname, tmp);
    1971         }
    1972       while (strlen(fname)>0 && fname[strlen(fname)-1]<32) { fname[strlen(fname)-1] = '\0'; }
     1813    log_msg(5, "starting");
     1814    log_msg(5, "needles_list_fname = %s", needles_list_fname);
     1815    log_msg(5, "matches_list_fname = %s", matches_list_fname);
     1816    if (!(fin = fopen(needles_list_fname, "r"))) {
     1817        fatal_error("Cannot openin needles_list_fname");
     1818    }
     1819    if (!(fout = fopen(matches_list_fname, "w"))) {
     1820        fatal_error("Cannot openout matches_list_fname");
     1821    }
     1822    while (!feof(fin)) {
     1823        getline(&fname, &len, fin);
     1824        if (!use_star) {
     1825            if (fname[0] == '/') {
     1826                asprintf(&tmp, fname);
     1827            } else {
     1828                asprintf(&tmp, "/%s", fname);
     1829            }
     1830            paranoid_free(fname);
     1831            asprintf(&fname, tmp);
     1832            paranoid_free(tmp);
     1833        }
     1834        while (strlen(fname) > 0 && fname[strlen(fname) - 1] < 32) {
     1835            fname[strlen(fname) - 1] = '\0';
     1836        }
    19731837
    19741838/*
     
    19771841      sprintf(temporary_string, "echo \"Looking for '%s'\" >> /tmp/looking.txt", fname);
    19781842      system(temporary_string);
    1979 */     
    1980      
    1981       log_msg(5, "Looking for '%s'", fname);
    1982       found_node = find_string_at_node(filelist, fname);
    1983       if (found_node)
    1984         {
    1985       if (found_node->selected)
    1986         {
    1987 //              if (use_star)
    1988               if (fname[0]=='/')
    1989             {
    1990           strcpy(tmp, fname+1);
    1991           strcpy(fname, tmp);
    1992         }
    1993           log_msg(5, "Found '%s'", fname);
    1994           turn_wildcard_chars_into_literal_chars(tmp, fname);
    1995           fprintf(fout, "%s\n", tmp);
    1996           retval++;
    1997         }
    1998     }
    1999     }
    2000   paranoid_fclose(fout);
    2001   paranoid_fclose(fin);
    2002   paranoid_free(fname);
    2003   paranoid_free(tmp);
    2004   return(retval);
     1843*/
     1844
     1845        log_msg(5, "Looking for '%s'", fname);
     1846        found_node = find_string_at_node(filelist, fname);
     1847        if (found_node) {
     1848            if (found_node->selected) {
     1849                if (fname[0] == '/') {
     1850                    asprintf(&tmp, fname + 1);
     1851                    paranoid_free(fname);
     1852                    asprintf(&fname, tmp);
     1853                    paranoid_free(tmp);
     1854                }
     1855                log_msg(5, "Found '%s'", fname);
     1856                turn_wildcard_chars_into_literal_chars(tmp, fname);
     1857                fprintf(fout, "%s\n", tmp);
     1858                retval++;
     1859            }
     1860        }
     1861    paranoid_free(fname);
     1862    }
     1863    paranoid_fclose(fout);
     1864    paranoid_fclose(fin);
     1865    return (retval);
    20051866}
    20061867
     
    20181879 * @return 0 for success, nonzero for failure.
    20191880 */
    2020 int add_list_of_files_to_filelist(struct s_node *filelist, char*list_of_files_fname, bool flag_em)
    2021 {
    2022   FILE*fin;
    2023   char*tmp;
    2024   struct s_node *nod;
    2025 
    2026   malloc_string(tmp);
    2027   log_msg(3, "Adding %s to filelist", list_of_files_fname);
    2028   if (!(fin=fopen(list_of_files_fname,"r"))) { iamhere(list_of_files_fname); return(1); }
    2029   for (fgets (tmp, MAX_STR_LEN, fin); !feof(fin);
    2030        fgets (tmp, MAX_STR_LEN, fin))
    2031     {
    2032       if (!tmp[0]) { continue; }
    2033       if ((tmp[strlen(tmp)-1]==13 || tmp[strlen(tmp)-1]==10) && strlen(tmp)>0)
    2034         { tmp[strlen(tmp)-1] = '\0'; }
    2035       log_msg(2, "tmp = '%s'", tmp);
    2036       if (!tmp[0]) { continue; }
    2037       if ((nod = find_string_at_node (filelist, tmp)))
    2038         {
    2039       log_msg(5, "Found '%s' in filelist already. Cool.", tmp);
    2040         }
    2041       else
    2042         {
    2043       add_string_at_node (filelist, tmp);
    2044           nod = find_string_at_node (filelist, tmp);
    2045         }
    2046 
    2047       if (nod && flag_em)
    2048         {
    2049       toggle_path_selection(filelist, tmp, TRUE);
    2050       log_msg (5, "Flagged '%s'", tmp);
    2051     }
    2052     }
    2053   paranoid_fclose(fin);
    2054   paranoid_free(tmp);
    2055   return(0);
     1881int add_list_of_files_to_filelist(struct s_node *filelist,
     1882                                  char *list_of_files_fname, bool flag_em)
     1883{
     1884    FILE *fin;
     1885    char *tmp;
     1886    struct s_node *nod;
     1887
     1888    malloc_string(tmp);
     1889    log_msg(3, "Adding %s to filelist", list_of_files_fname);
     1890    if (!(fin = fopen(list_of_files_fname, "r"))) {
     1891        iamhere(list_of_files_fname);
     1892        return (1);
     1893    }
     1894    for (fgets(tmp, MAX_STR_LEN, fin); !feof(fin);
     1895         fgets(tmp, MAX_STR_LEN, fin)) {
     1896        if (!tmp[0]) {
     1897            continue;
     1898        }
     1899        if ((tmp[strlen(tmp) - 1] == 13 || tmp[strlen(tmp) - 1] == 10)
     1900            && strlen(tmp) > 0) {
     1901            tmp[strlen(tmp) - 1] = '\0';
     1902        }
     1903        log_msg(2, "tmp = '%s'", tmp);
     1904        if (!tmp[0]) {
     1905            continue;
     1906        }
     1907        if ((nod = find_string_at_node(filelist, tmp))) {
     1908            log_msg(5, "Found '%s' in filelist already. Cool.", tmp);
     1909        } else {
     1910            add_string_at_node(filelist, tmp);
     1911            nod = find_string_at_node(filelist, tmp);
     1912        }
     1913
     1914        if (nod && flag_em) {
     1915            toggle_path_selection(filelist, tmp, TRUE);
     1916            log_msg(5, "Flagged '%s'", tmp);
     1917        }
     1918    }
     1919    paranoid_fclose(fin);
     1920    paranoid_free(tmp);
     1921    return (0);
    20561922}
    20571923
Note: See TracChangeset for help on using the changeset viewer.