Merge branch '2429_fileop_counters_overflow'

* 2429_fileop_counters_overflow:
  Adjust formatting output of source and destination file sizes
  Unification of ctx and ctx->ui checks.
  Removed unneeded checks.
  Optimization of verbose operations with several files.
  Use size_t instead of off_t for file counters during file operations.
  Ticket #2429: overflow of file operation counters.
This commit is contained in:
Andrew Borodin 2010-12-02 09:42:01 +03:00
commit f8207591bd
11 changed files with 127 additions and 163 deletions

View File

@ -326,30 +326,30 @@ path_trunc (const char *path, size_t trunc_len)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
const char * const char *
size_trunc (double size, gboolean use_si) size_trunc (uintmax_t size, gboolean use_si)
{ {
static char x[BUF_TINY]; static char x[BUF_TINY];
long int divisor = 1; uintmax_t divisor = 1;
const char *xtra = ""; const char *xtra = "";
if (size > 999999999L) if (size > 999999999UL)
{ {
divisor = use_si ? 1000 : 1024; divisor = use_si ? 1000 : 1024;
xtra = use_si ? "k" : "K"; xtra = use_si ? "k" : "K";
if (size / divisor > 999999999L) if (size / divisor > 999999999UL)
{ {
divisor = use_si ? (1000 * 1000) : (1024 * 1024); divisor = use_si ? (1000 * 1000) : (1024 * 1024);
xtra = use_si ? "m" : "M"; xtra = use_si ? "m" : "M";
} }
} }
g_snprintf (x, sizeof (x), "%.0f%s", (size / divisor), xtra); g_snprintf (x, sizeof (x), "%.0f%s", 1.0 * size / divisor, xtra);
return x; return x;
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
const char * const char *
size_trunc_sep (double size, gboolean use_si) size_trunc_sep (uintmax_t size, gboolean use_si)
{ {
static char x[60]; static char x[60];
int count; int count;
@ -359,7 +359,7 @@ size_trunc_sep (double size, gboolean use_si)
p = y = size_trunc (size, use_si); p = y = size_trunc (size, use_si);
p += strlen (p) - 1; p += strlen (p) - 1;
d = x + sizeof (x) - 1; d = x + sizeof (x) - 1;
*d-- = 0; *d-- = '\0';
while (p >= y && isalpha ((unsigned char) *p)) while (p >= y && isalpha ((unsigned char) *p))
*d-- = *p--; *d-- = *p--;
for (count = 0; p >= y; count++) for (count = 0; p >= y; count++)
@ -389,11 +389,12 @@ size_trunc_sep (double size, gboolean use_si)
*/ */
void void
size_trunc_len (char *buffer, unsigned int len, off_t size, int units, gboolean use_si) size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si)
{ {
/* Avoid taking power for every file. */ /* Avoid taking power for every file. */
static const off_t power10[] = { 1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, static const uintmax_t power10[] =
1000000000 {
1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000
}; };
static const char *const suffix[] = { "", "K", "M", "G", "T", "P", "E", "Z", "Y", NULL }; static const char *const suffix[] = { "", "K", "M", "G", "T", "P", "E", "Z", "Y", NULL };
static const char *const suffix_lc[] = { "", "k", "m", "g", "t", "p", "e", "z", "y", NULL }; static const char *const suffix_lc[] = { "", "k", "m", "g", "t", "p", "e", "z", "y", NULL };
@ -408,8 +409,7 @@ size_trunc_len (char *buffer, unsigned int len, off_t size, int units, gboolean
* We can't just multiply by 1024 - that might cause overflow * We can't just multiply by 1024 - that might cause overflow
* if off_t type is too small * if off_t type is too small
*/ */
if (units && use_si) if (use_si)
{
for (j = 0; j < units; j++) for (j = 0; j < units; j++)
{ {
size_remain = ((size % 125) * 1024) / 1000; /* size mod 125, recalculated */ size_remain = ((size % 125) * 1024) / 1000; /* size mod 125, recalculated */
@ -417,7 +417,6 @@ size_trunc_len (char *buffer, unsigned int len, off_t size, int units, gboolean
size = size * 128; /* This will convert size from multiple of 1024 to multiple of 1000 */ size = size * 128; /* This will convert size from multiple of 1024 to multiple of 1000 */
size += size_remain; /* Re-add remainder lost by division/multiplication */ size += size_remain; /* Re-add remainder lost by division/multiplication */
} }
}
for (j = units; suffix[j] != NULL; j++) for (j = units; suffix[j] != NULL; j++)
{ {
@ -438,8 +437,7 @@ size_trunc_len (char *buffer, unsigned int len, off_t size, int units, gboolean
if (size < power10[len - (j > 0)]) if (size < power10[len - (j > 0)])
{ {
g_snprintf (buffer, len + 1, "%lu%s", (unsigned long) size, g_snprintf (buffer, len + 1, "%ju%s", size, use_si ? suffix_lc[j] : suffix[j]);
use_si ? suffix_lc[j] : suffix[j]);
break; break;
} }

View File

@ -9,6 +9,7 @@
#include <sys/types.h> #include <sys/types.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <inttypes.h> /* uintmax_t */
#include <unistd.h> #include <unistd.h>
/*** typedefs(not structures) and defined constants **********************************************/ /*** typedefs(not structures) and defined constants **********************************************/
@ -70,18 +71,18 @@ const char *path_trunc (const char *path, size_t trunc_len);
/* return a static string representing size, appending "K" or "M" for /* return a static string representing size, appending "K" or "M" for
* big sizes. * big sizes.
* NOTE: uses the same static buffer as size_trunc_sep. */ * NOTE: uses the same static buffer as size_trunc_sep. */
const char *size_trunc (double size, gboolean use_si); const char *size_trunc (uintmax_t size, gboolean use_si);
/* return a static string representing size, appending "K" or "M" for /* return a static string representing size, appending "K" or "M" for
* big sizes. Separates every three digits by ",". * big sizes. Separates every three digits by ",".
* NOTE: uses the same static buffer as size_trunc. */ * NOTE: uses the same static buffer as size_trunc. */
const char *size_trunc_sep (double size, gboolean use_si); const char *size_trunc_sep (uintmax_t size, gboolean use_si);
/* Print file SIZE to BUFFER, but don't exceed LEN characters, /* Print file SIZE to BUFFER, but don't exceed LEN characters,
* not including trailing 0. BUFFER should be at least LEN+1 long. * not including trailing 0. BUFFER should be at least LEN+1 long.
* *
* Units: size units (0=bytes, 1=Kbytes, 2=Mbytes, etc.) */ * Units: size units (0=bytes, 1=Kbytes, 2=Mbytes, etc.) */
void size_trunc_len (char *buffer, unsigned int len, off_t size, int units, gboolean use_si); void size_trunc_len (char *buffer, unsigned int len, uintmax_t size, int units, gboolean use_si);
const char *string_perm (mode_t mode_bits); const char *string_perm (mode_t mode_bits);
/* @modifies path. @returns pointer into path. */ /* @modifies path. @returns pointer into path. */

View File

@ -1492,16 +1492,15 @@ single_dirsize_cmd (void)
{ {
WPanel *panel = current_panel; WPanel *panel = current_panel;
file_entry *entry; file_entry *entry;
off_t marked;
double total;
ComputeDirSizeUI *ui;
entry = &(panel->dir.list[panel->selected]); entry = &(panel->dir.list[panel->selected]);
if (S_ISDIR (entry->st.st_mode) && strcmp (entry->fname, "..") != 0) if (S_ISDIR (entry->st.st_mode) && strcmp (entry->fname, "..") != 0)
{ {
ui = compute_dir_size_create_ui (); size_t marked = 0;
uintmax_t total = 0;
ComputeDirSizeUI *ui;
total = 0.0; ui = compute_dir_size_create_ui ();
if (compute_dir_size (entry->fname, ui, compute_dir_size_update_ui, if (compute_dir_size (entry->fname, ui, compute_dir_size_update_ui,
&marked, &total, TRUE) == FILE_CONT) &marked, &total, TRUE) == FILE_CONT)
@ -1531,8 +1530,6 @@ dirsizes_cmd (void)
{ {
WPanel *panel = current_panel; WPanel *panel = current_panel;
int i; int i;
off_t marked;
double total;
ComputeDirSizeUI *ui; ComputeDirSizeUI *ui;
ui = compute_dir_size_create_ui (); ui = compute_dir_size_create_ui ();
@ -1542,7 +1539,8 @@ dirsizes_cmd (void)
&& ((panel->dirs_marked && panel->dir.list[i].f.marked) && ((panel->dirs_marked && panel->dir.list[i].f.marked)
|| !panel->dirs_marked) && strcmp (panel->dir.list[i].fname, "..") != 0) || !panel->dirs_marked) && strcmp (panel->dir.list[i].fname, "..") != 0)
{ {
total = 0.0l; size_t marked = 0;
uintmax_t total = 0;
if (compute_dir_size (panel->dir.list[i].fname, if (compute_dir_size (panel->dir.list[i].fname,
ui, compute_dir_size_update_ui, &marked, &total, ui, compute_dir_size_update_ui, &marked, &total,

View File

@ -421,7 +421,7 @@ progress_update_one (FileOpTotalContext * tctx, FileOpContext * ctx, off_t add,
if (is_toplevel_file || ctx->progress_totals_computed) if (is_toplevel_file || ctx->progress_totals_computed)
{ {
tctx->progress_count++; tctx->progress_count++;
tctx->progress_bytes += add; tctx->progress_bytes += (uintmax_t) add;
} }
if (tv_start.tv_sec == 0) if (tv_start.tv_sec == 0)
{ {
@ -430,8 +430,11 @@ progress_update_one (FileOpTotalContext * tctx, FileOpContext * ctx, off_t add,
gettimeofday (&tv_current, (struct timezone *) NULL); gettimeofday (&tv_current, (struct timezone *) NULL);
if ((tv_current.tv_sec - tv_start.tv_sec) > FILEOP_UPDATE_INTERVAL) if ((tv_current.tv_sec - tv_start.tv_sec) > FILEOP_UPDATE_INTERVAL)
{ {
file_progress_show_count (ctx, tctx->progress_count, ctx->progress_count); if (verbose && ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
file_progress_show_total (tctx, ctx, tctx->progress_bytes, TRUE); {
file_progress_show_count (ctx, tctx->progress_count, ctx->progress_count);
file_progress_show_total (tctx, ctx, tctx->progress_bytes, TRUE);
}
tv_start.tv_sec = tv_current.tv_sec; tv_start.tv_sec = tv_current.tv_sec;
} }
@ -516,7 +519,7 @@ copy_file_file_display_progress (FileOpTotalContext * tctx, FileOpContext * ctx,
/* 5. Compute total ETA and BPS */ /* 5. Compute total ETA and BPS */
if (ctx->progress_bytes != 0) if (ctx->progress_bytes != 0)
{ {
double remain_bytes; uintmax_t remain_bytes;
tctx->copyed_bytes = tctx->progress_bytes + n_read_total + ctx->do_reget; tctx->copyed_bytes = tctx->progress_bytes + n_read_total + ctx->do_reget;
remain_bytes = ctx->progress_bytes - tctx->copyed_bytes; remain_bytes = ctx->progress_bytes - tctx->copyed_bytes;
#if 1 #if 1
@ -668,23 +671,22 @@ erase_file (FileOpTotalContext * tctx, FileOpContext * ctx, const char *s,
return FILE_ABORT; return FILE_ABORT;
mc_refresh (); mc_refresh ();
if (tctx->progress_count && mc_lstat (s, &buf)) if (tctx->progress_count != 0 && mc_lstat (s, &buf) != 0)
{ {
/* ignore, most likely the mc_unlink fails, too */ /* ignore, most likely the mc_unlink fails, too */
buf.st_size = 0; buf.st_size = 0;
} }
while (mc_unlink (s)) while (mc_unlink (s) != 0)
{ {
return_status = file_error (_("Cannot delete file \"%s\"\n%s"), s); return_status = file_error (_("Cannot delete file \"%s\"\n%s"), s);
if (return_status != FILE_RETRY) if (return_status != FILE_RETRY)
return return_status; return return_status;
} }
if (tctx->progress_count) if (tctx->progress_count == 0)
return progress_update_one (tctx, ctx, buf.st_size, is_toplevel_file);
else
return FILE_CONT; return FILE_CONT;
return progress_update_one (tctx, ctx, buf.st_size, is_toplevel_file);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -858,12 +860,12 @@ panel_get_file (WPanel * panel, struct stat *stat_buf)
static FileProgressStatus static FileProgressStatus
panel_compute_totals (const WPanel * panel, const void *ui, panel_compute_totals (const WPanel * panel, const void *ui,
compute_dir_size_callback cback, compute_dir_size_callback cback,
off_t * ret_marked, double *ret_total, gboolean compute_symlinks) size_t * ret_marked, uintmax_t *ret_total, gboolean compute_symlinks)
{ {
int i; int i;
*ret_marked = 0; *ret_marked = 0;
*ret_total = 0.0; *ret_total = 0;
for (i = 0; i < panel->count; i++) for (i = 0; i < panel->count; i++)
{ {
@ -877,8 +879,8 @@ panel_compute_totals (const WPanel * panel, const void *ui,
if (S_ISDIR (s->st_mode)) if (S_ISDIR (s->st_mode))
{ {
char *dir_name; char *dir_name;
off_t subdir_count = 0; size_t subdir_count = 0;
double subdir_bytes = 0; uintmax_t subdir_bytes = 0;
FileProgressStatus status; FileProgressStatus status;
dir_name = concat_dir_and_file (panel->cwd, panel->dir.list[i].fname); dir_name = concat_dir_and_file (panel->cwd, panel->dir.list[i].fname);
@ -896,7 +898,7 @@ panel_compute_totals (const WPanel * panel, const void *ui,
else else
{ {
(*ret_marked)++; (*ret_marked)++;
*ret_total += s->st_size; *ret_total += (uintmax_t) s->st_size;
} }
} }
@ -1508,13 +1510,18 @@ copy_file_file (FileOpTotalContext * tctx, FileOpContext * ctx,
} }
{ {
gboolean force_update = gboolean force_update;
(tv_current.tv_sec - tctx->transfer_start.tv_sec) > FILEOP_UPDATE_INTERVAL;
file_progress_show_count (ctx, tctx->progress_count, ctx->progress_count);
file_progress_show_total (tctx, ctx,
tctx->progress_bytes + n_read_total + ctx->do_reget,
force_update);
force_update =
(tv_current.tv_sec - tctx->transfer_start.tv_sec) > FILEOP_UPDATE_INTERVAL;
if (verbose && ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
{
file_progress_show_count (ctx, tctx->progress_count, ctx->progress_count);
file_progress_show_total (tctx, ctx,
tctx->progress_bytes + n_read_total + ctx->do_reget,
force_update);
}
file_progress_show (ctx, n_read_total + ctx->do_reget, file_size, stalled_msg, file_progress_show (ctx, n_read_total + ctx->do_reget, file_size, stalled_msg,
force_update); force_update);
@ -2116,7 +2123,7 @@ compute_dir_size_update_ui (const void *ui, const char *dirname)
FileProgressStatus FileProgressStatus
compute_dir_size (const char *dirname, const void *ui, compute_dir_size (const char *dirname, const void *ui,
compute_dir_size_callback cback, compute_dir_size_callback cback,
off_t * ret_marked, double *ret_total, gboolean compute_symlinks) size_t * ret_marked, uintmax_t *ret_total, gboolean compute_symlinks)
{ {
int res; int res;
struct stat s; struct stat s;
@ -2134,7 +2141,7 @@ compute_dir_size (const char *dirname, const void *ui,
if (S_ISLNK (s.st_mode)) if (S_ISLNK (s.st_mode))
{ {
(*ret_marked)++; (*ret_marked)++;
*ret_total += s.st_size; *ret_total += (uintmax_t) s.st_size;
return ret; return ret;
} }
} }
@ -2169,8 +2176,8 @@ compute_dir_size (const char *dirname, const void *ui,
if (S_ISDIR (s.st_mode)) if (S_ISDIR (s.st_mode))
{ {
off_t subdir_count = 0; size_t subdir_count = 0;
double subdir_bytes = 0; uintmax_t subdir_bytes = 0;
ret = ret =
compute_dir_size (fullname, ui, cback, &subdir_count, &subdir_bytes, compute_dir_size (fullname, ui, cback, &subdir_count, &subdir_bytes,
@ -2188,7 +2195,7 @@ compute_dir_size (const char *dirname, const void *ui,
else else
{ {
(*ret_marked)++; (*ret_marked)++;
*ret_total += s.st_size; *ret_total += (uintmax_t) s.st_size;
} }
g_free (fullname); g_free (fullname);
@ -2589,16 +2596,15 @@ panel_operate (void *source_panel, FileOperation operation, gboolean force_singl
if (value == FILE_CONT) if (value == FILE_CONT)
do_file_mark (panel, i, 0); do_file_mark (panel, i, 0);
file_progress_show_count (ctx, tctx->progress_count, ctx->progress_count); if (verbose && ctx->dialog_type == FILEGUI_DIALOG_MULTI_ITEM)
if (verbose)
{ {
file_progress_show_count (ctx, tctx->progress_count, ctx->progress_count);
file_progress_show_total (tctx, ctx, tctx->progress_bytes, FALSE); file_progress_show_total (tctx, ctx, tctx->progress_bytes, FALSE);
if (operation != OP_DELETE)
file_progress_show (ctx, 0, 0, "", FALSE);
} }
if (operation != OP_DELETE)
file_progress_show (ctx, 0, 0, "", FALSE);
if (check_progress_buttons (ctx) == FILE_ABORT) if (check_progress_buttons (ctx) == FILE_ABORT)
break; break;

View File

@ -5,8 +5,7 @@
#ifndef MC__FILE_H #ifndef MC__FILE_H
#define MC__FILE_H #define MC__FILE_H
#include <sys/types.h> /* off_t */ #include <inttypes.h> /* off_t, uintmax_t */
#include <sys/time.h>
#include "lib/global.h" #include "lib/global.h"
#include "lib/widget.h" #include "lib/widget.h"
@ -56,10 +55,9 @@ FileProgressStatus file_error (const char *format, const char *file);
/* return value is FILE_CONT or FILE_ABORT */ /* return value is FILE_CONT or FILE_ABORT */
FileProgressStatus compute_dir_size (const char *dirname, const void *ui, FileProgressStatus compute_dir_size (const char *dirname, const void *ui,
compute_dir_size_callback cback, compute_dir_size_callback cback,
off_t * ret_marked, double *ret_total, size_t * ret_marked, uintmax_t *ret_total,
gboolean compute_symlinks); gboolean compute_symlinks);
ComputeDirSizeUI *compute_dir_size_create_ui (void); ComputeDirSizeUI *compute_dir_size_create_ui (void);
void compute_dir_size_destroy_ui (ComputeDirSizeUI * ui); void compute_dir_size_destroy_ui (ComputeDirSizeUI * ui);
FileProgressStatus compute_dir_size_update_ui (const void *ui, const char *dirname); FileProgressStatus compute_dir_size_update_ui (const void *ui, const char *dirname);

View File

@ -283,15 +283,14 @@ file_bps_prepare_for_show (char *buffer, long bps)
static replace_action_t static replace_action_t
overwrite_query_dialog (FileOpContext * ctx, enum OperationMode mode) overwrite_query_dialog (FileOpContext * ctx, enum OperationMode mode)
{ {
#define ADD_RD_BUTTON(i)\ #define ADD_RD_BUTTON(i) \
add_widget (ui->replace_dlg,\ add_widget (ui->replace_dlg, \
button_new (rd_widgets [i].ypos, rd_widgets [i].xpos, rd_widgets [i].value,\ button_new (rd_widgets [i].ypos, rd_widgets [i].xpos, rd_widgets [i].value, \
NORMAL_BUTTON, rd_widgets [i].text, 0)) NORMAL_BUTTON, rd_widgets [i].text, 0))
#define ADD_RD_LABEL(i, p1, p2)\ #define ADD_RD_LABEL(i, p1, p2) \
g_snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2);\ g_snprintf (buffer, sizeof (buffer), rd_widgets [i].text, p1, p2); \
add_widget (ui->replace_dlg,\ add_widget (ui->replace_dlg, label_new (rd_widgets [i].ypos, rd_widgets [i].xpos, buffer))
label_new (rd_widgets [i].ypos, rd_widgets [i].xpos, buffer))
/* dialog sizes */ /* dialog sizes */
const int rd_ylen = 17; const int rd_ylen = 17;
@ -309,17 +308,10 @@ overwrite_query_dialog (FileOpContext * ctx, enum OperationMode mode)
{ N_("Target file already exists!"), 3, 4, 0 }, { N_("Target file already exists!"), 3, 4, 0 },
/* 1 */ /* 1 */
{ "%s", 4, 4, 0 }, { "%s", 4, 4, 0 },
#if (defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS == 64) || (defined _LARGE_FILES && _LARGE_FILES)
/* 2 */ /* 2 */
{ N_("Source date: %s, size %llu"), 6, 4, 0 }, { N_("Source date: %s, size %ju"), 6, 4, 0 },
/* 3 */ /* 3 */
{ N_("Target date: %s, size %llu"), 7, 4, 0 }, { N_("Target date: %s, size %ju"), 7, 4, 0 },
#else
/* 2 */
{ N_("Source date: %s, size %u"), 6, 4, 0 },
/* 3 */
{ N_("Target date: %s, size %u"), 7, 4, 0 },
#endif
/* 4 */ /* 4 */
{ N_("&Abort"), 14, 25, REPLACE_ABORT }, { N_("&Abort"), 14, 25, REPLACE_ABORT },
/* 5 */ /* 5 */
@ -436,10 +428,10 @@ overwrite_query_dialog (FileOpContext * ctx, enum OperationMode mode)
add_widget (ui->replace_dlg, add_widget (ui->replace_dlg,
label_new (rd_widgets[1].ypos, (rd_xlen - stripped_name_len) / 2, stripped_name)); label_new (rd_widgets[1].ypos, (rd_xlen - stripped_name_len) / 2, stripped_name));
/* source date */ /* source date and size */
ADD_RD_LABEL (2, file_date (ui->s_stat->st_mtime), (off_t) ui->s_stat->st_size); ADD_RD_LABEL (2, file_date (ui->s_stat->st_mtime), (uintmax_t) ui->s_stat->st_size);
/* destination date */ /* destination date and size */
ADD_RD_LABEL (3, file_date (ui->d_stat->st_mtime), (off_t) ui->d_stat->st_size); ADD_RD_LABEL (3, file_date (ui->d_stat->st_mtime), (uintmax_t) ui->d_stat->st_size);
ADD_RD_BUTTON (4); /* Abort */ ADD_RD_BUTTON (4); /* Abort */
ADD_RD_BUTTON (5); /* If size differs */ ADD_RD_BUTTON (5); /* If size differs */
@ -497,8 +489,7 @@ check_progress_buttons (FileOpContext * ctx)
Gpm_Event event; Gpm_Event event;
FileOpContextUI *ui; FileOpContextUI *ui;
if (ctx->ui == NULL) g_return_val_if_fail (ctx->ui != NULL, FILE_CONT);
return FILE_CONT;
ui = ctx->ui; ui = ctx->ui;
@ -655,22 +646,19 @@ file_op_context_create_ui (FileOpContext * ctx, gboolean with_eta,
void void
file_op_context_destroy_ui (FileOpContext * ctx) file_op_context_destroy_ui (FileOpContext * ctx)
{ {
FileOpContextUI *ui;
g_return_if_fail (ctx != NULL); g_return_if_fail (ctx != NULL);
if (ctx->ui) if (ctx->ui != NULL)
{ {
ui = ctx->ui; FileOpContextUI *ui = (FileOpContextUI *) ctx->ui;
dlg_run_done (ui->op_dlg); dlg_run_done (ui->op_dlg);
destroy_dlg (ui->op_dlg); destroy_dlg (ui->op_dlg);
g_free (ui); g_free (ui);
ctx->ui = NULL;
} }
the_hint->widget.y = last_hint_line; the_hint->widget.y = last_hint_line;
ctx->ui = NULL;
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
@ -687,16 +675,14 @@ file_progress_show (FileOpContext * ctx, off_t done, off_t total,
char buffer2[BUF_TINY]; char buffer2[BUF_TINY];
char buffer3[BUF_TINY]; char buffer3[BUF_TINY];
g_return_if_fail (ctx != NULL);
if (ctx->ui == NULL)
return;
ui = ctx->ui;
if (!verbose) if (!verbose)
return; return;
g_return_if_fail (ctx != NULL);
g_return_if_fail (ctx->ui != NULL);
ui = ctx->ui;
if (total == 0) if (total == 0)
{ {
gauge_show (ui->progress_file_gauge, 0); gauge_show (ui->progress_file_gauge, 0);
@ -726,32 +712,24 @@ file_progress_show (FileOpContext * ctx, off_t done, off_t total,
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
void void
file_progress_show_count (FileOpContext * ctx, off_t done, off_t total) file_progress_show_count (FileOpContext * ctx, size_t done, size_t total)
{ {
char buffer[BUF_TINY]; char buffer[BUF_TINY];
FileOpContextUI *ui; FileOpContextUI *ui;
g_return_if_fail (ctx != NULL); g_return_if_fail (ctx != NULL);
g_return_if_fail (ctx->ui != NULL);
if (ctx->dialog_type != FILEGUI_DIALOG_MULTI_ITEM || ctx->ui == NULL)
return;
ui = ctx->ui; ui = ctx->ui;
g_snprintf (buffer, BUF_TINY, _("Files processed: %zu of %zu"), done, total);
if (!verbose)
return;
g_snprintf (buffer, BUF_TINY, _("Files processed: %llu of %llu"),
(unsigned long long) done, (unsigned long long) total);
label_set_text (ui->total_files_processed_label, buffer); label_set_text (ui->total_files_processed_label, buffer);
} }
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
void void
file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, double copyed_bytes, file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, uintmax_t copyed_bytes,
gboolean need_show_total_summary) gboolean show_summary)
{ {
char buffer[BUF_TINY]; char buffer[BUF_TINY];
char buffer2[BUF_TINY]; char buffer2[BUF_TINY];
@ -760,15 +738,12 @@ file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, double
struct timeval tv_current; struct timeval tv_current;
FileOpContextUI *ui; FileOpContextUI *ui;
if (!verbose) g_return_if_fail (ctx != NULL);
return; g_return_if_fail (ctx->ui != NULL);
if (ctx->dialog_type != FILEGUI_DIALOG_MULTI_ITEM || ctx->ui == NULL)
return;
ui = ctx->ui; ui = ctx->ui;
if (ctx->progress_bytes > 0) if (ctx->progress_bytes != 0)
{ {
gauge_set_value (ui->progress_total_gauge, 1024, gauge_set_value (ui->progress_total_gauge, 1024,
(int) (1024 * copyed_bytes / ctx->progress_bytes)); (int) (1024 * copyed_bytes / ctx->progress_bytes));
@ -777,8 +752,7 @@ file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, double
else else
gauge_show (ui->progress_total_gauge, 0); gauge_show (ui->progress_total_gauge, 0);
if (!show_summary && tctx->bps == 0)
if (!need_show_total_summary && tctx->bps == 0)
return; return;
gettimeofday (&tv_current, NULL); gettimeofday (&tv_current, NULL);
@ -795,7 +769,6 @@ file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, double
g_snprintf (buffer, BUF_TINY, _("Total: %s of %s"), buffer2, buffer3); g_snprintf (buffer, BUF_TINY, _("Total: %s of %s"), buffer2, buffer3);
label_set_text (ui->total_bytes_label, buffer); label_set_text (ui->total_bytes_label, buffer);
} }
/* }}} */ /* }}} */
@ -808,23 +781,21 @@ file_progress_show_source (FileOpContext * ctx, const char *s)
FileOpContextUI *ui; FileOpContextUI *ui;
g_return_if_fail (ctx != NULL); g_return_if_fail (ctx != NULL);
g_return_if_fail (ctx->ui != NULL);
if (ctx->ui == NULL)
return;
ui = ctx->ui; ui = ctx->ui;
if (s != NULL) if (s != NULL)
{ {
#ifdef WITH_FULL_PATHS #ifdef WITH_FULL_PATHS
int i = strlen (current_panel->cwd); size_t i;
i = strlen (current_panel->cwd);
/* We remove the full path we have added before */ /* We remove the full path we have added before */
if (!strncmp (s, current_panel->cwd, i)) if (strncmp (s, current_panel->cwd, i) == 0)
{
if (s[i] == PATH_SEP) if (s[i] == PATH_SEP)
s += i + 1; s += i + 1;
}
#endif /* WITH_FULL_PATHS */ #endif /* WITH_FULL_PATHS */
label_set_text (ui->file_label[0], _("Source")); label_set_text (ui->file_label[0], _("Source"));
@ -845,9 +816,7 @@ file_progress_show_target (FileOpContext * ctx, const char *s)
FileOpContextUI *ui; FileOpContextUI *ui;
g_return_if_fail (ctx != NULL); g_return_if_fail (ctx != NULL);
g_return_if_fail (ctx->ui != NULL);
if (ctx->ui == NULL)
return;
ui = ctx->ui; ui = ctx->ui;
@ -871,9 +840,7 @@ file_progress_show_deleting (FileOpContext * ctx, const char *s)
FileOpContextUI *ui; FileOpContextUI *ui;
g_return_if_fail (ctx != NULL); g_return_if_fail (ctx != NULL);
g_return_if_fail (ctx->ui != NULL);
if (ctx->ui == NULL)
return;
ui = ctx->ui; ui = ctx->ui;
label_set_text (ui->file_label[0], _("Deleting")); label_set_text (ui->file_label[0], _("Deleting"));

View File

@ -10,13 +10,6 @@
/*** typedefs(not structures) and defined constants **********************************************/ /*** typedefs(not structures) and defined constants **********************************************/
typedef enum
{
FILEGUI_DIALOG_ONE_ITEM,
FILEGUI_DIALOG_MULTI_ITEM,
FILEGUI_DIALOG_DELETE_ITEM
} filegui_dialog_type_t;
/*** enums ***************************************************************************************/ /*** enums ***************************************************************************************/
/*** structures declarations (and typedefs of structures)*****************************************/ /*** structures declarations (and typedefs of structures)*****************************************/
@ -31,7 +24,6 @@ void file_op_context_create_ui_without_init (FileOpContext * ctx, gboolean with_
filegui_dialog_type_t dialog_type); filegui_dialog_type_t dialog_type);
void file_op_context_destroy_ui (FileOpContext * ctx); void file_op_context_destroy_ui (FileOpContext * ctx);
char *file_mask_dialog (FileOpContext * ctx, FileOperation operation, char *file_mask_dialog (FileOpContext * ctx, FileOperation operation,
gboolean only_one, gboolean only_one,
const char *format, const void *text, const char *format, const void *text,
@ -41,9 +33,9 @@ FileProgressStatus check_progress_buttons (FileOpContext * ctx);
void file_progress_show (FileOpContext * ctx, off_t done, off_t total, void file_progress_show (FileOpContext * ctx, off_t done, off_t total,
const char *stalled_msg, gboolean force_update); const char *stalled_msg, gboolean force_update);
void file_progress_show_count (FileOpContext * ctx, off_t done, off_t total); void file_progress_show_count (FileOpContext * ctx, size_t done, size_t total);
void file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx, void file_progress_show_total (FileOpTotalContext * tctx, FileOpContext * ctx,
double copyed_bytes, gboolean need_show_total_summary); uintmax_t copyed_bytes, gboolean show_summary);
void file_progress_show_source (FileOpContext * ctx, const char *path); void file_progress_show_source (FileOpContext * ctx, const char *path);
void file_progress_show_target (FileOpContext * ctx, const char *path); void file_progress_show_target (FileOpContext * ctx, const char *path);
void file_progress_show_deleting (FileOpContext * ctx, const char *path); void file_progress_show_deleting (FileOpContext * ctx, const char *path);

View File

@ -70,7 +70,7 @@ file_op_context_new (FileOperation op)
ctx = g_new0 (FileOpContext, 1); ctx = g_new0 (FileOpContext, 1);
ctx->operation = op; ctx->operation = op;
ctx->eta_secs = 0.0; ctx->eta_secs = 0.0;
ctx->progress_bytes = 0.0; ctx->progress_bytes = 0;
ctx->op_preserve = TRUE; ctx->op_preserve = TRUE;
ctx->do_reget = 1; ctx->do_reget = 1;
ctx->stat_func = mc_lstat; ctx->stat_func = mc_lstat;
@ -96,13 +96,9 @@ file_op_context_destroy (FileOpContext * ctx)
{ {
g_return_if_fail (ctx != NULL); g_return_if_fail (ctx != NULL);
if (ctx->ui) file_op_context_destroy_ui (ctx);
file_op_context_destroy_ui (ctx);
mc_search_free (ctx->search_handle); mc_search_free (ctx->search_handle);
/** \todo FIXME: do we need to free ctx->dest_mask? */ /** \todo FIXME: do we need to free ctx->dest_mask? */
g_free (ctx); g_free (ctx);
} }
@ -123,7 +119,6 @@ file_op_total_context_new (void)
void void
file_op_total_context_destroy (FileOpTotalContext * tctx) file_op_total_context_destroy (FileOpTotalContext * tctx)
{ {
g_return_if_fail (tctx != NULL);
g_free (tctx); g_free (tctx);
} }

View File

@ -17,6 +17,7 @@
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h> #include <sys/time.h>
#include <inttypes.h> /* uintmax_t */
#include "lib/global.h" #include "lib/global.h"
@ -27,6 +28,13 @@ typedef int (*mc_stat_fn) (const char *filename, struct stat * buf);
/*** enums ***************************************************************************************/ /*** enums ***************************************************************************************/
typedef enum
{
FILEGUI_DIALOG_ONE_ITEM,
FILEGUI_DIALOG_MULTI_ITEM,
FILEGUI_DIALOG_DELETE_ITEM
} filegui_dialog_type_t;
typedef enum typedef enum
{ {
OP_COPY = 0, OP_COPY = 0,
@ -81,11 +89,11 @@ typedef struct FileOpContext
/* Whether the panel total has been computed */ /* Whether the panel total has been computed */
gboolean progress_totals_computed; gboolean progress_totals_computed;
int dialog_type; filegui_dialog_type_t dialog_type;
/* Counters for progress indicators */ /* Counters for progress indicators */
off_t progress_count; size_t progress_count;
double progress_bytes; uintmax_t progress_bytes;
/* The value of the "preserve Attributes" checkbox in the copy file dialog. /* The value of the "preserve Attributes" checkbox in the copy file dialog.
* We can't use the value of "ctx->preserve" because it can change in order * We can't use the value of "ctx->preserve" because it can change in order
@ -153,9 +161,9 @@ typedef struct FileOpContext
typedef struct typedef struct
{ {
off_t progress_count; size_t progress_count;
double progress_bytes; uintmax_t progress_bytes;
double copyed_bytes; uintmax_t copyed_bytes;
size_t bps; size_t bps;
size_t bps_count; size_t bps_count;
struct timeval transfer_start; struct timeval transfer_start;
@ -163,7 +171,6 @@ typedef struct
gboolean ask_overwrite; gboolean ask_overwrite;
gboolean is_toplevel_file; gboolean is_toplevel_file;
} FileOpTotalContext; } FileOpTotalContext;
/*** global variables defined in .c file *********************************************************/ /*** global variables defined in .c file *********************************************************/

View File

@ -975,7 +975,7 @@ display_total_marked_size (WPanel * panel, int y, int x, gboolean size_only)
* First make "N bytes", then insert it into "X in M files". * First make "N bytes", then insert it into "X in M files".
*/ */
g_snprintf (b_bytes, sizeof (b_bytes), g_snprintf (b_bytes, sizeof (b_bytes),
ngettext ("%s byte", "%s bytes", (unsigned long) panel->total), ngettext ("%s byte", "%s bytes", panel->total),
size_trunc_sep (panel->total, panels_options.kilobyte_si)); size_trunc_sep (panel->total, panels_options.kilobyte_si));
if (!size_only) if (!size_only)
g_snprintf (buffer, sizeof (buffer), g_snprintf (buffer, sizeof (buffer),
@ -3791,7 +3791,7 @@ do_file_mark (WPanel * panel, int idx, int mark)
return; return;
/* Only '..' can't be marked, '.' isn't visible */ /* Only '..' can't be marked, '.' isn't visible */
if (!strcmp (panel->dir.list[idx].fname, "..")) if (strcmp (panel->dir.list[idx].fname, "..") == 0)
return; return;
file_mark (panel, idx, mark); file_mark (panel, idx, mark);
@ -3801,11 +3801,11 @@ do_file_mark (WPanel * panel, int idx, int mark)
if (S_ISDIR (panel->dir.list[idx].st.st_mode)) if (S_ISDIR (panel->dir.list[idx].st.st_mode))
{ {
if (panel->dir.list[idx].f.dir_size_computed) if (panel->dir.list[idx].f.dir_size_computed)
panel->total += panel->dir.list[idx].st.st_size; panel->total += (uintmax_t) panel->dir.list[idx].st.st_size;
panel->dirs_marked++; panel->dirs_marked++;
} }
else else
panel->total += panel->dir.list[idx].st.st_size; panel->total += (uintmax_t) panel->dir.list[idx].st.st_size;
set_colors (panel); set_colors (panel);
} }
else else
@ -3813,11 +3813,11 @@ do_file_mark (WPanel * panel, int idx, int mark)
if (S_ISDIR (panel->dir.list[idx].st.st_mode)) if (S_ISDIR (panel->dir.list[idx].st.st_mode))
{ {
if (panel->dir.list[idx].f.dir_size_computed) if (panel->dir.list[idx].f.dir_size_computed)
panel->total -= panel->dir.list[idx].st.st_size; panel->total -= (uintmax_t) panel->dir.list[idx].st.st_size;
panel->dirs_marked--; panel->dirs_marked--;
} }
else else
panel->total -= panel->dir.list[idx].st.st_size; panel->total -= (uintmax_t) panel->dir.list[idx].st.st_size;
panel->marked--; panel->marked--;
} }
} }

View File

@ -5,6 +5,8 @@
#ifndef MC__PANEL_H #ifndef MC__PANEL_H
#define MC__PANEL_H #define MC__PANEL_H
#include <inttypes.h> /* uintmax_t */
#include "lib/global.h" /* gboolean */ #include "lib/global.h" /* gboolean */
#include "lib/fs.h" /* MC_MAXPATHLEN */ #include "lib/fs.h" /* MC_MAXPATHLEN */
#include "lib/strutil.h" #include "lib/strutil.h"
@ -84,7 +86,7 @@ typedef struct WPanel
int count; /* Number of files in dir structure */ int count; /* Number of files in dir structure */
int marked; /* Count of marked files */ int marked; /* Count of marked files */
int dirs_marked; /* Count of marked directories */ int dirs_marked; /* Count of marked directories */
double total; /* Bytes in marked files */ uintmax_t total; /* Bytes in marked files */
int top_file; /* The file showed on the top of the panel */ int top_file; /* The file showed on the top of the panel */
int selected; /* Index to the selected file */ int selected; /* Index to the selected file */
int reverse; /* Show listing in reverse? */ int reverse; /* Show listing in reverse? */