static void rm_fmt_progress_format_preprocess(RmSession *session, char *buf, size_t buf_len, FILE *out) { if(session->offsets_read > 0) { g_snprintf(buf, buf_len, "fiemap: %s+%" LLU "%s %s-%" LLU "%s %s#%" LLU "%s", MAYBE_GREEN(out, session), session->offsets_read, MAYBE_RESET(out, session), MAYBE_RED(out, session), session->offset_fails, MAYBE_RESET(out, session), MAYBE_BLUE(out, session), session->total_filtered_files, MAYBE_RESET(out, session)); } else { g_snprintf(buf, buf_len, "%s %s%" LLU "%s", _("reduces files to"), MAYBE_GREEN(out, session), session->total_filtered_files, MAYBE_RESET(out, session)); } }
static const char *rm_fmt_command_color(RmSession *session, RmFile *file) { switch(file->lint_type) { case RM_LINT_TYPE_NBIN: case RM_LINT_TYPE_BADUID: case RM_LINT_TYPE_BADGID: case RM_LINT_TYPE_BADUGID: return MAYBE_BLUE(session); case RM_LINT_TYPE_DUPE_CANDIDATE: case RM_LINT_TYPE_DUPE_DIR_CANDIDATE: if(file->is_original) { return MAYBE_GREEN(session); } else { return MAYBE_RED(session); } default: return MAYBE_RED(session); } }
static void rm_fmt_progress_format_text(RmSession *session, RmFmtHandlerProgress *self, int max_len, FILE *out) { /* This is very ugly, but more or less required since we need to translate * the text to different languages and still determine the right textlength. */ char num_buf[32] = {0}; char preproc_buf[128] = {0}; memset(num_buf, 0, sizeof(num_buf)); memset(preproc_buf, 0, sizeof(preproc_buf)); switch(self->last_state) { case RM_PROGRESS_STATE_TRAVERSE: self->percent = 2.0; self->text_len = g_snprintf( self->text_buf, sizeof(self->text_buf), "%s (%s%d%s %s / %s%d%s + %s%d%s %s)", _("Traversing"), MAYBE_GREEN(out, session), session->total_files, MAYBE_RESET(out, session), _("usable files"), MAYBE_RED(out, session), session->ignored_files, MAYBE_RESET(out, session), MAYBE_RED(out, session), session->ignored_folders, MAYBE_RESET(out, session), _("ignored files / folders")); break; case RM_PROGRESS_STATE_PREPROCESS: self->percent = 2.0; rm_fmt_progress_format_preprocess(session, preproc_buf, sizeof(preproc_buf), out); self->text_len = g_snprintf( self->text_buf, sizeof(self->text_buf), "%s (%s / %s %s%" LLU "%s %s)", _("Preprocessing"), preproc_buf, _("found"), MAYBE_RED(out, session), session->other_lint_cnt, MAYBE_RESET(out, session), _("other lint")); break; case RM_PROGRESS_STATE_SHREDDER: self->percent = 1.0 - ((gdouble)session->shred_bytes_remaining / (gdouble)session->shred_bytes_after_preprocess); rm_util_size_to_human_readable(session->shred_bytes_remaining, num_buf, sizeof(num_buf)); self->text_len = g_snprintf( self->text_buf, sizeof(self->text_buf), "%s (%s%" LLU "%s %s %s%" LLU "%s %s; %s%s%s %s %s%" LLU "%s %s)", _("Matching"), MAYBE_RED(out, session), session->dup_counter, MAYBE_RESET(out, session), _("dupes of"), MAYBE_YELLOW(out, session), session->dup_group_counter, MAYBE_RESET(out, session), _("originals"), MAYBE_GREEN(out, session), num_buf, MAYBE_RESET(out, session), _("to scan in"), MAYBE_GREEN(out, session), session->shred_files_remaining, MAYBE_RESET(out, session), _("files")); break; case RM_PROGRESS_STATE_MERGE: self->percent = 1.0; self->text_len = g_snprintf(self->text_buf, sizeof(self->text_buf), _("Merging files into directories (stand by...)")); break; case RM_PROGRESS_STATE_INIT: case RM_PROGRESS_STATE_PRE_SHUTDOWN: case RM_PROGRESS_STATE_SUMMARY: default: self->percent = 0; memset(self->text_buf, 0, sizeof(self->text_buf)); break; } /* Support unicode messages - tranlsated text might contain some. */ self->text_len = g_utf8_strlen(self->text_buf, self->text_len); /* Get rid of colors to get the correct length of the text. This is * necessary to correctly guess the length of the displayed text in cells. */ int text_iter = 0; for(char *iter = &self->text_buf[0]; *iter; iter++) { if(*iter == '\x1b') { char *jump = strchr(iter, 'm'); if(jump != NULL) { self->text_len -= jump - iter + 1; iter = jump; continue; } } if(text_iter >= max_len) { *iter = 0; self->text_len = text_iter; break; } text_iter++; } }
static void rm_fmt_progress_format_text(RmSession *session, RmFmtHandlerProgress *self, int max_len) { char num_buf[32] = {0}; memset(num_buf, 0, sizeof(num_buf)); switch(self->last_state) { case RM_PROGRESS_STATE_TRAVERSE: self->percent = 2.0; self->text_len = g_snprintf( self->text_buf, sizeof(self->text_buf), "%s (%s%"LLU"%s %s / %s%"LLU"%s + %s%"LLU"%s %s)", _("Traversing"), MAYBE_GREEN(session), session->total_files, MAYBE_RESET(session), _("usable files"), MAYBE_RED(session), session->ignored_files, MAYBE_RESET(session), MAYBE_RED(session), session->ignored_folders, MAYBE_RESET(session), _("ignored files / folders") ); break; case RM_PROGRESS_STATE_PREPROCESS: self->percent = 2.0; self->text_len = g_snprintf( self->text_buf, sizeof(self->text_buf), "%s (%s %s%"LLU"%s / %s %s%"LLU"%s %s)", _("Preprocessing"), _("reduces files to"), MAYBE_GREEN(session), session->total_filtered_files, MAYBE_RESET(session), _("found"), MAYBE_RED(session), session->other_lint_cnt, MAYBE_RESET(session), _("other lint") ); break; case RM_PROGRESS_STATE_SHREDDER: self->percent = 1.0 - ((gdouble)session->shred_files_remaining) / ((gdouble)session->total_filtered_files); rm_util_size_to_human_readable(session->shred_bytes_remaining, num_buf, sizeof(num_buf)); self->text_len = g_snprintf( self->text_buf, sizeof(self->text_buf), "%s (%s%"LLU"%s %s %s%"LLU"%s %s; %s%s%s %s %s%"LLU"%s %s)", _("Matching files"), MAYBE_RED(session), session->dup_counter, MAYBE_RESET(session), _("dupes of"), MAYBE_YELLOW(session), session->dup_group_counter, MAYBE_RESET(session), _("originals"), MAYBE_GREEN(session), num_buf, MAYBE_RESET(session), _("to scan in "), MAYBE_GREEN(session), session->shred_files_remaining, MAYBE_RESET(session), _("files") ); break; case RM_PROGRESS_STATE_MERGE: self->percent = 2.0; self->text_len = g_snprintf(self->text_buf, sizeof(self->text_buf), _("Merging files into directories (stand by...)")); break; case RM_PROGRESS_STATE_INIT: case RM_PROGRESS_STATE_SUMMARY: default: self->percent = 0; memset(self->text_buf, 0, sizeof(self->text_buf)); break; } /* Get rid of colors */ int text_iter = 0; for(char *iter = &self->text_buf[0]; *iter; iter++) { if(*iter == '\x1b') { char *jump = strchr(iter, 'm'); if(jump != NULL) { self->text_len -= jump - iter + 1; iter = jump; continue; } } if(text_iter >= max_len) { *iter = 0; self->text_len = text_iter; break; } text_iter++; } }
static void rm_fmt_prog(RmSession *session, _UNUSED RmFmtHandler *parent, _UNUSED FILE *out, RmFmtProgressState state) { if(state != RM_PROGRESS_STATE_SUMMARY) { return; } if(session->total_files <= 1) { ARROW fprintf(out, "%s%d%s", MAYBE_RED(out, session), session->total_files, MAYBE_RESET(out, session)); fprintf(out, _(" file(s) after investigation, nothing to search through.\n")); return; } if(rm_session_was_aborted()) { /* Clear the whole terminal line. * Progressbar might leave some junk. */ struct winsize terminal; ioctl(fileno(out), TIOCGWINSZ, &terminal); for(int i = 0; i < terminal.ws_col; ++i) { fprintf(out, " "); } fprintf(out, "\n"); ARROW fprintf(out, _("Early shutdown, probably not all lint was found.\n")); } if(rm_fmt_has_formatter(session->formats, "pretty") && rm_fmt_has_formatter(session->formats, "sh")) { ARROW fprintf(out, _("Note: Please use the saved script below for removal, not " "the above output.")); fprintf(out, "\n"); } char numbers[3][512]; snprintf(numbers[0], sizeof(numbers[0]), "%s%d%s", MAYBE_RED(out, session), session->total_files, MAYBE_RESET(out, session)); snprintf(numbers[1], sizeof(numbers[1]), "%s%" LLU "%s", MAYBE_RED(out, session), session->dup_counter, MAYBE_RESET(out, session)); snprintf(numbers[2], sizeof(numbers[2]), "%s%" LLU "%s", MAYBE_RED(out, session), session->dup_group_counter, MAYBE_RESET(out, session)); ARROW fprintf(out, _("In total %s files, whereof %s are duplicates in %s groups.\n"), numbers[0], numbers[1], numbers[2]); /* log10(2 ** 64) + 2 = 21; */ char size_string_buf[22] = {0}; rm_util_size_to_human_readable(session->total_lint_size, size_string_buf, sizeof(size_string_buf)); ARROW fprintf(out, _("This equals %s%s%s of duplicates which could be removed.\n"), MAYBE_RED(out, session), size_string_buf, MAYBE_RESET(out, session)); if(session->other_lint_cnt > 0) { ARROW fprintf(out, "%s%" LLU "%s ", MAYBE_RED(out, session), session->other_lint_cnt, MAYBE_RESET(out, session)); fprintf(out, _("other suspicious item(s) found, which may vary in size.\n")); } bool first_print_flag = true; GHashTableIter iter; char *path = NULL; RmFmtHandler *handler = NULL; rm_fmt_get_pair_iter(session->formats, &iter); while(g_hash_table_iter_next(&iter, (gpointer *)&path, (gpointer *)&handler)) { static const char *forbidden[] = {"stdout", "stderr", "stdin"}; gsize forbidden_len = sizeof(forbidden) / sizeof(forbidden[0]); bool forbidden_found = false; for(gsize i = 0; i < forbidden_len; i++) { if(g_strcmp0(forbidden[i], path) == 0) { forbidden_found = true; break; } } if(forbidden_found) { continue; } /* Check if the file really exists, so we can print it for sure */ if(access(path, R_OK) == -1) { continue; } if(first_print_flag) { fprintf(out, "\n"); first_print_flag = false; } fprintf(out, _("Wrote a %s%s%s file to: %s%s%s\n"), MAYBE_BLUE(out, session), handler->name, MAYBE_RESET(out, session), MAYBE_GREEN(out, session), path, MAYBE_RESET(out, session)); } }
static void rm_fmt_prog( RmSession *session, _U RmFmtHandler *parent, _U FILE *out, RmFmtProgressState state ) { if(state != RM_PROGRESS_STATE_SUMMARY) { return; } if(session->total_files <= 1) { ARROW fprintf(out, "%s%"LLU"%s", MAYBE_RED(session), session->total_files, MAYBE_RESET(session) ); fprintf(out, _(" file(s) after investigation, nothing to search through.\n")); return; } if(rm_session_was_aborted(session)) { ARROW fprintf(out, _("Early shutdown, probably not all lint was found.\n")); } char numbers[3][512]; snprintf(numbers[0], sizeof(numbers[0]), "%s%"LLU"%s", MAYBE_RED(session), session->total_files, MAYBE_RESET(session)); snprintf(numbers[1], sizeof(numbers[1]), "%s%"LLU"%s", MAYBE_RED(session), session->dup_counter, MAYBE_RESET(session)); snprintf(numbers[2], sizeof(numbers[2]), "%s%"LLU"%s", MAYBE_RED(session), session->dup_group_counter, MAYBE_RESET(session)); ARROW fprintf( out, _("In total %s files, whereof %s are duplicates in %s groups.\n"), numbers[0], numbers[1], numbers[2] ); /* log10(2 ** 64) + 2 = 21; */ char size_string_buf[22] = {0}; rm_util_size_to_human_readable( session->total_lint_size, size_string_buf, sizeof(size_string_buf) ); ARROW fprintf( out, _("This equals %s%s%s of duplicates which could be removed.\n"), MAYBE_RED(session), size_string_buf, MAYBE_RESET(session) ); if(session->other_lint_cnt > 0) { ARROW fprintf( out, "%s%"LLU"%s ", MAYBE_RED(session), session->other_lint_cnt, MAYBE_RESET(session) ); fprintf(out, _("other suspicious item(s) found, which may vary in size.\n")); } bool first_print_flag = true; GHashTableIter iter; char *path = NULL; RmFmtHandler *handler = NULL; rm_fmt_get_pair_iter(session->formats, &iter); while(g_hash_table_iter_next(&iter, (gpointer *)&path, (gpointer *)&handler)) { static const char *forbidden[] = {"stdout", "stderr", "stdin"}; gsize forbidden_len = sizeof(forbidden) / sizeof(forbidden[0]); if(lfind(path, forbidden, &forbidden_len, sizeof(const char *), rm_fmt_summary_cmp)) { continue; } /* Check if the file really exists, so we can print it for sure */ if(access(path, R_OK) == -1) { continue; } if(first_print_flag) { fprintf(out, "\n"); first_print_flag = false; } fprintf( out, _("Wrote a %s%s%s file to %s%s%s.\n"), MAYBE_BLUE(session), handler->name, MAYBE_RESET(session), MAYBE_GREEN(session), path, MAYBE_RESET(session) ); } }