/* This the actual main() of rmlint */ void start_processing(lint_t *b) { file_group *fglist = NULL, emptylist; char lintbuf[128]; char suspbuf[128]; nuint_t ii = 0, lint = 0, spelen = 0, rem_counter = 0, suspicious = 0, path_doubles = 0; if(set->namecluster) { find_double_bases(b); error("\n"); } emptylist.len = 1; emptylist.size = 0; /* Split into groups, based by size */ while(b) { lint_t *q = b, *prev = NULL; nuint_t glen = 0, gsize = 0; while(b && q->fsize == b->fsize) { prev = b; if(b->dupflag == false) { b->dupflag = true; } gsize += b->fsize; glen++; b = b->next; } if(glen == 1) { /* This is only a single element */ /* We can remove it without feelind bad */ q = list_remove(q); if(b != NULL) { b = q; } rem_counter++; } else { /* Mark this isle as 'sublist' by setting next/last pointers */ if(b != NULL) { prev->next = NULL; b->last = NULL; } if(q->fsize != 0) { /* Sort by inode (speeds up IO on normal HDs [not SSDs]) */ q = list_sort(q,cmp_nd); /* Add this group to the list array */ fglist = realloc(fglist, (spelen+1) * sizeof(file_group)); fglist[spelen].grp_stp = q; fglist[spelen].grp_enp = prev; fglist[spelen].len = glen; fglist[spelen].size = gsize; /* Remove 'path-doubles' (files pointing to the physically SAME file) - this requires a node sorted list */ if((set->followlinks && get_cpindex() == 1) || get_cpindex() > 1) path_doubles += rm_double_paths(&fglist[spelen]); /* number_of_groups++ */ spelen++; } else /* this is some other sort of lint (indicated by a size of 0) */ { lint_t *ptr; char flag = 42; bool e_file_printed = false; const char * chown_cmd = " chown $(whoami):$(id -gn)"; q = list_sort(q,cmp_nd); emptylist.grp_stp = q; if((set->followlinks && get_cpindex() == 1) || get_cpindex() > 1) rm_double_paths(&emptylist); /* sort by lint_ID (== dupID) */ ptr = emptylist.grp_stp; ptr = list_sort(ptr,cmp_sort_dupID); emptylist.grp_stp = ptr; emptylist.len = 0; while(ptr) { if(flag != ptr->dupflag) { if(set->verbosity > 1) { error(YEL"\n#"NCO); } else { error("\n#"); } /* -- */ if(ptr->dupflag == TYPE_BLNK) { error(" Bad link(s): \n"); } else if(ptr->dupflag == TYPE_OTMP) { error(" Old Tempfile(s): \n"); } else if(ptr->dupflag == TYPE_EDIR) { error(" Empty dir(s): \n"); } else if(ptr->dupflag == TYPE_JNK_DIRNAME) { error(" Junk dirname(s): \n"); } else if(ptr->dupflag == TYPE_JNK_FILENAME) { error(" Junk filename(s): \n"); } else if(ptr->dupflag == TYPE_NBIN) { error(" Non stripped binarie(s): \n"); } else if(ptr->dupflag == TYPE_BADUID) { error(" Bad UID: \n"); } else if(ptr->dupflag == TYPE_BADGID) { error(" Bad GID: \n"); } else if(ptr->fsize == 0 && e_file_printed == false) { error(" Empty file(s): \n"); e_file_printed = true; } flag = ptr->dupflag; } if(set->verbosity > 1) { error(GRE); } if(ptr->dupflag == TYPE_BLNK) { error(" rm"); } else if(ptr->dupflag == TYPE_OTMP) { error(" rm"); } else if(ptr->dupflag == TYPE_EDIR) { error(" rmdir"); } else if(ptr->dupflag == TYPE_JNK_DIRNAME) { error(" ls"); } else if(ptr->dupflag == TYPE_JNK_FILENAME) { error(" ls"); } else if(ptr->dupflag == TYPE_NBIN) { error(" strip --strip-debug"); } else if(ptr->dupflag == TYPE_BADUID) { error(chown_cmd); } else if(ptr->dupflag == TYPE_BADGID) { error(chown_cmd); } else if(ptr->fsize == 0) { error(" rm"); } if(set->verbosity > 1) { error(NCO); } error(" %s\n",ptr->path); if(set->output) { write_to_log(ptr, false,NULL); } emptylist.size += ptr->fsize; ptr = list_remove(ptr); emptylist.len++; } } } } error("\n"); if(set->searchdup == 0) { nuint_t i = 0; /* rmlint was originally supposed to find duplicates only So we have to free list that whould have been used for dup search before dieing */ for(; i < spelen; i++) { list_clear(fglist[i].grp_stp); } if(fglist) { free(fglist); } die(0); } info("\nNow attempting to find duplicates. This may take a while...\n"); info("Now removing files with unique sizes from list..."); info(""YEL"%ld item(s) less"NCO" in list.",rem_counter); if(path_doubles) { info(" (removed "YEL"%ld pathzombie(s)"NCO")", path_doubles); } info(NCO"\nNow removing "GRE"%ld"NCO" empty files / bad links / junk names from list...\n"NCO, emptylist.len); info("Now sorting groups based on their location on the drive..."); /* Now make sure groups are sorted by their location on the disk*/ qsort(fglist, spelen, sizeof(file_group), cmp_grplist_bynodes); info(" done. \nNow doing fingerprints and full checksums.%c\n",set->verbosity > 4 ? '.' : '\n'); db_done = true; error("%s Duplicate(s):",(set->verbosity > 1) ? YEL"#"NCO : "#"); /* Groups are splitted, now give it to the scheduler * The scheduler will do another filterstep, build checkusm * and compare 'em. The result is printed afterwards */ start_scheduler(fglist, spelen); if(get_dupcounter() == 0) { error("\r "); } else { error("\n"); } /* Gather the total size of removeable data */ for(ii=0; ii < spelen; ii++) { if(fglist[ii].grp_stp != NULL) { lint += fglist[ii].size; } } /* now process the ouptput we gonna print */ size_to_human_readable(lint, lintbuf, 127 /* bufsize */); size_to_human_readable(emptylist.size, suspbuf, 127); /* Now announce */ warning("\n"RED"=> "NCO"In total "RED"%llu"NCO" files, whereof "RED"%llu"NCO" are duplicate(s)",get_totalfiles(), get_dupcounter()); suspicious = emptylist.len + dbase_ctr; if(suspicious > 1) { warning(RED"\n=> %llu"NCO" other suspicious items found ["GRE"%s"NCO"]",emptylist.len + dbase_ctr,suspbuf); } warning("\n"); if(!iAbort) { warning(RED"=> "NCO"Totally "GRE" %s "NCO" [%llu Bytes] can be removed.\n", lintbuf, lint); } if((set->mode == 1 || set->mode == 2) && get_dupcounter()) { warning(RED"=> "NCO"Nothing removed yet!\n"); } warning("\n"); if(set->verbosity == 6) { info("Now calculation finished.. now writing end of log...\n"); info(RED"=> "NCO"In total "RED"%llu"NCO" files, whereof "RED"%llu"NCO" are duplicate(s)\n",get_totalfiles(), get_dupcounter()); if(!iAbort) { info(RED"=> "NCO"In total "GRE" %s "NCO" ["BLU"%llu"NCO" Bytes] can be removed without dataloss.\n", lintbuf, lint); } } if(get_logstream() == NULL && set->output) { error(RED"\nERROR: "NCO); fflush(stdout); perror("Unable to write log"); putchar('\n'); } else if(set->output) { warning("A log has been written to "BLU"%s.log"NCO".\n", set->output); warning("A ready to use shellscript to "BLU"%s.sh"NCO".\n", set->output); } /* End of actual program. Now do some finalizing */ if(fglist) { free(fglist); } }
Loggable () : log_ (&get_logstream (typeid (LoggableClass).name())) {}