]> git.ipfire.org Git - pakfire.git/commitdiff
cli: progressbar: Dynamically allocate all buffers
authorMichael Tremer <michael.tremer@ipfire.org>
Sun, 1 Oct 2023 12:37:57 +0000 (12:37 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Sun, 1 Oct 2023 12:37:57 +0000 (12:37 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/cli/lib/progressbar.c

index e793c557b271a9028cfd1cf76691dd446ca03dc8..08bb02f083f33c11297864311c7f60908343e8ec 100644 (file)
@@ -51,7 +51,7 @@ struct cli_progressbar_widget {
                struct cli_progressbar_widget* widget, unsigned int width, void* data);
        void (*free)(void* data);
 
-       char buffer[1024];
+       char* buffer;
 };
 
 struct cli_progressbar {
@@ -102,6 +102,9 @@ static void cli_progressbar_widget_free(struct cli_progressbar_widget* widget) {
        if (widget->free && widget->data)
                widget->free(widget->data);
 
+       if (widget->buffer)
+               free(widget->buffer);
+
        free(widget);
 }
 
@@ -327,7 +330,7 @@ static const char* cli_progressbar_counter(struct cli_progressbar* p,
        unsigned long int max_value = pakfire_progress_get_value(p->progress);
 
        // Format the result
-       r = snprintf(widget->buffer, sizeof(widget->buffer), "%lu/%lu", value, max_value);
+       r = asprintf(&widget->buffer, "%lu/%lu", value, max_value);
        if (r < 0)
                return NULL;
 
@@ -346,7 +349,7 @@ static const char* cli_progressbar_percentage(struct cli_progressbar* p,
        double percentage = pakfire_progress_get_percentage(p->progress);
 
        // Format to string
-       r = snprintf(widget->buffer, sizeof(widget->buffer), "%3.0f%%", percentage);
+       r = asprintf(&widget->buffer, "%3.0f%%", percentage);
        if (r < 0)
                return NULL;
 
@@ -359,7 +362,11 @@ static int cli_progressbar_add_percentage(struct cli_progressbar* p) {
 
 static const char* cli_progressbar_bar(struct cli_progressbar* p,
                struct cli_progressbar_widget* widget, unsigned int width, void* data) {
-       if (width >= sizeof(widget->buffer) || width < 2)
+       // Allocate or adjust the buffer
+       widget->buffer = realloc(widget->buffer, width);
+
+       // Fail if we could not allocate the buffer
+       if (!widget->buffer)
                return NULL;
 
        // Remove the bar when we are finished so that the terminal is not so cluttered
@@ -385,7 +392,7 @@ static const char* cli_progressbar_bar(struct cli_progressbar* p,
                        widget->buffer[i] = '-';
        }
 
-       // Terminat the string
+       // Terminate the string
        widget->buffer[width] = '\0';
 
        return widget->buffer;
@@ -405,7 +412,7 @@ static const char* cli_progressbar_elapsed_time(struct cli_progressbar* p,
                return NULL;
 
        // Format the time
-       r = snprintf(widget->buffer, sizeof(widget->buffer), "%02lu:%02lu", t / 60, t % 60);
+       r = asprintf(&widget->buffer, "%02lu:%02lu", t / 60, t % 60);
        if (r)
                return NULL;
 
@@ -429,14 +436,13 @@ static const char* cli_progressbar_eta(struct cli_progressbar* p,
 
        // Print a placeholder when we have no ETA (yet)
        if (t <= 0) {
-               r = snprintf(widget->buffer, sizeof(widget->buffer), "%-5s: --:--:--", _("ETA"));
+               r = asprintf(&widget->buffer, "%-5s: --:--:--", _("ETA"));
                if (r < 0)
                        return NULL;
 
        // Otherwise show the ETA
        } else {
-               r = snprintf(widget->buffer, sizeof(widget->buffer), "%-5s: %02lu:%02lu",
-                       _("ETA"), t / 60, t % 60);
+               r = asprintf(&widget->buffer, "%-5s: %02lu:%02lu", _("ETA"), t / 60, t % 60);
                if (r < 0)
                        return NULL;
        }
@@ -448,10 +454,7 @@ static int cli_progressbar_add_eta(struct cli_progressbar* p) {
        return cli_progressbar_add_widget(p, cli_progressbar_eta, NULL, 0, NULL);
 }
 
-#define cli_progressbar_format_speed(s, speed) \
-       __cli_progressbar_format_speed(s, sizeof(s), speed)
-
-static int __cli_progressbar_format_speed(char* s, const size_t length, double value) {
+static int cli_progressbar_format_speed(char** s, double value) {
        const char* units[] = {
                "%4.0fB/s",
                "%4.0fkB/s",
@@ -469,7 +472,7 @@ static int __cli_progressbar_format_speed(char* s, const size_t length, double v
                }
 
                // Format the string
-               r = snprintf(s, length, *unit, value);
+               r = asprintf(s, *unit, value);
                if (r < 0)
                        return r;
 
@@ -524,7 +527,7 @@ static const char* cli_progressbar_bytes_transferred(struct cli_progressbar* p,
                return NULL;
 
        // Add padding so that the string is always at least five characters long
-       r = snprintf(widget->buffer, sizeof(widget->buffer), "%-5s", buffer);
+       r = asprintf(&widget->buffer, "%-5s", buffer);
        if (r < 0)
                return NULL;
 
@@ -537,12 +540,15 @@ static int cli_progressbar_add_bytes_transferred(struct cli_progressbar* p) {
 
 static const char* cli_progressbar_transfer_speed(struct cli_progressbar* p,
                struct cli_progressbar_widget* widget, unsigned int width, void* data) {
+       int r;
+
+       // Fetch the speed
        double speed = pakfire_progress_get_transfer_speed(p->progress);
        if (speed < 0)
                return NULL;
 
        // Format the speed
-       int r = cli_progressbar_format_speed(widget->buffer, speed);
+       r = cli_progressbar_format_speed(&widget->buffer, speed);
        if (r < 0)
                        return NULL;