]> git.cameronkatri.com Git - bsd-progress.git/blobdiff - progressbar.c
Fix argument handling of the "-b" option on 64bit platforms. Using
[bsd-progress.git] / progressbar.c
index 77b6756ca42f079fd339ded701383cece77fba2b..d7edd2715da9f8b94468914b20de5e898fd9f876 100644 (file)
@@ -1,16 +1,12 @@
-/*     $NetBSD: progressbar.c,v 1.3 2003/02/28 09:53:49 lukem Exp $    */
+/*     $NetBSD: progressbar.c,v 1.21 2009/04/12 10:18:52 lukem Exp $   */
 
 /*-
 
 /*-
- * Copyright (c) 1997-2003 The NetBSD Foundation, Inc.
+ * Copyright (c) 1997-2009 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Luke Mewburn.
  *
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
  * by Luke Mewburn.
  *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
- * NASA Ames Research Center.
- *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the NetBSD
- *     Foundation, Inc. and its contributors.
- * 4. Neither the name of The NetBSD Foundation nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
  *
  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
@@ -42,7 +31,7 @@
 
 #include <sys/cdefs.h>
 #ifndef lint
 
 #include <sys/cdefs.h>
 #ifndef lint
-__RCSID("$NetBSD: progressbar.c,v 1.3 2003/02/28 09:53:49 lukem Exp $");
+__RCSID("$NetBSD: progressbar.c,v 1.21 2009/04/12 10:18:52 lukem Exp $");
 #endif /* not lint */
 
 /*
 #endif /* not lint */
 
 /*
@@ -56,6 +45,7 @@ __RCSID("$NetBSD: progressbar.c,v 1.3 2003/02/28 09:53:49 lukem Exp $");
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <signal.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <time.h>
 #include <tzfile.h>
 #include <unistd.h>
 #include <time.h>
 #include <tzfile.h>
 #include <unistd.h>
@@ -79,7 +69,6 @@ foregroundproc(void)
 #endif /* !defined(NO_PROGRESS) */
 
 
 #endif /* !defined(NO_PROGRESS) */
 
 
-#ifndef        NO_PROGRESS
 static void updateprogressmeter(int);
 
 /*
 static void updateprogressmeter(int);
 
 /*
@@ -93,14 +82,25 @@ updateprogressmeter(int dummy)
        progressmeter(0);
        errno = oerrno;
 }
        progressmeter(0);
        errno = oerrno;
 }
-#endif /* NO_PROGRESS */
-
 
 /*
 
 /*
- * List of order of magnitude prefixes.
- * The last is `P', as 2^64 = 16384 Petabytes
+ * List of order of magnitude suffixes, per IEC 60027-2.
  */
  */
-static const char prefixes[] = " KMGTP";
+static const char * const suffixes[] = {
+       "",     /* 2^0  (byte) */
+       "KiB",  /* 2^10 Kibibyte */
+       "MiB",  /* 2^20 Mebibyte */
+       "GiB",  /* 2^30 Gibibyte */
+       "TiB",  /* 2^40 Tebibyte */
+       "PiB",  /* 2^50 Pebibyte */
+       "EiB",  /* 2^60 Exbibyte */
+#if 0
+               /* The following are not necessary for signed 64-bit off_t */
+       "ZiB",  /* 2^70 Zebibyte */
+       "YiB",  /* 2^80 Yobibyte */
+#endif
+};
+#define NSUFFIXES      (int)(sizeof(suffixes) / sizeof(suffixes[0]))
 
 /*
  * Display a transfer progress bar if progress is non-zero.
 
 /*
  * Display a transfer progress bar if progress is non-zero.
@@ -127,7 +127,7 @@ progressmeter(int flag)
        struct timeval td;
        off_t abbrevsize, bytespersec;
        double elapsed;
        struct timeval td;
        off_t abbrevsize, bytespersec;
        double elapsed;
-       int ratio, barlength, i, len, remaining;
+       int ratio, i, remaining, barlength;
 
                        /*
                         * Work variables for progress bar.
 
                        /*
                         * Work variables for progress bar.
@@ -137,8 +137,11 @@ progressmeter(int flag)
                         *      `static' portion of it), be sure to update
                         *      these appropriately.
                         */
                         *      `static' portion of it), be sure to update
                         *      these appropriately.
                         */
+#endif
+       size_t          len;
        char            buf[256];       /* workspace for progress bar */
        char            buf[256];       /* workspace for progress bar */
-#define        BAROVERHEAD     43              /* non `*' portion of progress bar */
+#ifndef NO_PROGRESS
+#define        BAROVERHEAD     45              /* non `*' portion of progress bar */
                                        /*
                                         * stars should contain at least
                                         * sizeof(buf) - BAROVERHEAD entries
                                        /*
                                         * stars should contain at least
                                         * sizeof(buf) - BAROVERHEAD entries
@@ -170,8 +173,8 @@ progressmeter(int flag)
                            "transfer aborted because stalled for %lu sec.\r\n",
                            getprogname(), (unsigned long)wait.tv_sec);
                        (void)write(fileno(ttyout), buf, len);
                            "transfer aborted because stalled for %lu sec.\r\n",
                            getprogname(), (unsigned long)wait.tv_sec);
                        (void)write(fileno(ttyout), buf, len);
-                       (void)xsignal(SIGALRM, SIG_DFL);
                        alarmtimer(0);
                        alarmtimer(0);
+                       (void)xsignal(SIGALRM, SIG_DFL);
                        siglongjmp(toplevel, 1);
                }
 #endif /* !STANDALONE_PROGRESS */
                        siglongjmp(toplevel, 1);
                }
 #endif /* !STANDALONE_PROGRESS */
@@ -188,8 +191,8 @@ progressmeter(int flag)
                        (void)xsignal_restart(SIGALRM, updateprogressmeter, 1);
                        alarmtimer(1);          /* set alarm timer for 1 Hz */
                } else if (flag == 1) {
                        (void)xsignal_restart(SIGALRM, updateprogressmeter, 1);
                        alarmtimer(1);          /* set alarm timer for 1 Hz */
                } else if (flag == 1) {
-                       (void)xsignal(SIGALRM, SIG_DFL);
                        alarmtimer(0);
                        alarmtimer(0);
+                       (void)xsignal(SIGALRM, SIG_DFL);
                }
        }
 #ifndef NO_PROGRESS
                }
        }
 #ifndef NO_PROGRESS
@@ -204,6 +207,8 @@ progressmeter(int flag)
                return;
 
        len += snprintf(buf + len, BUFLEFT, "\r");
                return;
 
        len += snprintf(buf + len, BUFLEFT, "\r");
+       if (prefix)
+         len += snprintf(buf + len, BUFLEFT, "%s", prefix);
        if (filesize > 0) {
                ratio = (int)((double)cursize * 100.0 / (double)filesize);
                ratio = MAX(ratio, 0);
        if (filesize > 0) {
                ratio = (int)((double)cursize * 100.0 / (double)filesize);
                ratio = MAX(ratio, 0);
@@ -212,23 +217,26 @@ progressmeter(int flag)
 
                        /*
                         * calculate the length of the `*' bar, ensuring that
 
                        /*
                         * calculate the length of the `*' bar, ensuring that
-                        * the number of stars won't exceed the buffer size 
+                        * the number of stars won't exceed the buffer size
                         */
                         */
-               barlength = MIN(sizeof(buf) - 1, ttywidth) - BAROVERHEAD;
+               barlength = MIN((int)(sizeof(buf) - 1), ttywidth) - BAROVERHEAD;
+               if (prefix)
+                       barlength -= (int)strlen(prefix);
                if (barlength > 0) {
                        i = barlength * ratio / 100;
                        len += snprintf(buf + len, BUFLEFT,
                if (barlength > 0) {
                        i = barlength * ratio / 100;
                        len += snprintf(buf + len, BUFLEFT,
-                           "|%.*s%*s|", i, stars, barlength - i, "");
+                           "|%.*s%*s|", i, stars, (int)(barlength - i), "");
                }
        }
 
        abbrevsize = cursize;
                }
        }
 
        abbrevsize = cursize;
-       for (i = 0; abbrevsize >= 100000 && i < sizeof(prefixes); i++)
+       for (i = 0; abbrevsize >= 100000 && i < NSUFFIXES; i++)
                abbrevsize >>= 10;
                abbrevsize >>= 10;
-       len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %c%c ",
+       if (i == NSUFFIXES)
+               i--;
+       len += snprintf(buf + len, BUFLEFT, " " LLFP("5") " %-3s ",
            (LLT)abbrevsize,
            (LLT)abbrevsize,
-           prefixes[i],
-           i == 0 ? ' ' : 'B');
+           suffixes[i]);
 
        timersub(&now, &start, &td);
        elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
 
        timersub(&now, &start, &td);
        elapsed = td.tv_sec + (td.tv_usec / 1000000.0);
@@ -239,13 +247,13 @@ progressmeter(int flag)
                if (elapsed > 0.0)
                        bytespersec /= elapsed;
        }
                if (elapsed > 0.0)
                        bytespersec /= elapsed;
        }
-       for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
+       for (i = 1; bytespersec >= 1024000 && i < NSUFFIXES; i++)
                bytespersec >>= 10;
        len += snprintf(buf + len, BUFLEFT,
                bytespersec >>= 10;
        len += snprintf(buf + len, BUFLEFT,
-           " " LLFP("3") ".%02d %cB/s ",
+           " " LLFP("3") ".%02d %.2sB/s ",
            (LLT)(bytespersec / 1024),
            (int)((bytespersec % 1024) * 100 / 1024),
            (LLT)(bytespersec / 1024),
            (int)((bytespersec % 1024) * 100 / 1024),
-           prefixes[i]);
+           suffixes[i]);
 
        if (filesize > 0) {
                if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) {
 
        if (filesize > 0) {
                if (bytes <= 0 || elapsed <= 0.0 || cursize > filesize) {
@@ -295,7 +303,8 @@ ptransfer(int siginfo)
        struct timeval now, td, wait;
        double elapsed;
        off_t bytespersec;
        struct timeval now, td, wait;
        double elapsed;
        off_t bytespersec;
-       int remaining, hh, i, len;
+       int remaining, hh, i;
+       size_t len;
 
        char buf[256];          /* Work variable for transfer status. */
 
 
        char buf[256];          /* Work variable for transfer status. */
 
@@ -330,12 +339,14 @@ ptransfer(int siginfo)
        len += snprintf(buf + len, BUFLEFT,
            "%02d:%02d ", remaining / 60, remaining % 60);
 
        len += snprintf(buf + len, BUFLEFT,
            "%02d:%02d ", remaining / 60, remaining % 60);
 
-       for (i = 1; bytespersec >= 1024000 && i < sizeof(prefixes); i++)
+       for (i = 1; bytespersec >= 1024000 && i < NSUFFIXES; i++)
                bytespersec >>= 10;
                bytespersec >>= 10;
-       len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %cB/s)",
+       if (i == NSUFFIXES)
+               i--;
+       len += snprintf(buf + len, BUFLEFT, "(" LLF ".%02d %.2sB/s)",
            (LLT)(bytespersec / 1024),
            (int)((bytespersec % 1024) * 100 / 1024),
            (LLT)(bytespersec / 1024),
            (int)((bytespersec % 1024) * 100 / 1024),
-           prefixes[i]);
+           suffixes[i]);
 
        if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0
            && bytes + restart_point <= filesize) {
 
        if (siginfo && bytes > 0 && elapsed > 0.0 && filesize >= 0
            && bytes + restart_point <= filesize) {
@@ -453,7 +464,7 @@ xsignal(int sig, sigfunc func)
                 * This is unpleasant, but I don't know what would be better.
                 * Right now, this "can't happen"
                 */
                 * This is unpleasant, but I don't know what would be better.
                 * Right now, this "can't happen"
                 */
-               errx(1, "xsignal_restart called with signal %d", sig);
+               errx(1, "xsignal_restart: called with signal %d", sig);
        }
 
        return(xsignal_restart(sig, func, restartable));
        }
 
        return(xsignal_restart(sig, func, restartable));