]> git.sur5r.net Git - bacula/bacula/blobdiff - bacula/src/lib/edit.c
Change copyright as per agreement with FSFE
[bacula/bacula] / bacula / src / lib / edit.c
index a3229315203e656cb043e53485c14495d7cbb7cc..f419ab47f8950065b17822dfcfeec8e467a6e673 100644 (file)
@@ -1,23 +1,26 @@
+/*
+   Bacula(R) - The Network Backup Solution
+
+   Copyright (C) 2000-2016 Kern Sibbald
+
+   The original author of Bacula is Kern Sibbald, with contributions
+   from many others, a complete list can be found in the file AUTHORS.
+
+   You may use this file and others of this release according to the
+   license defined in the LICENSE file, which includes the Affero General
+   Public License, v3.0 ("AGPLv3") and some additional permissions and
+   terms pursuant to its AGPLv3 Section 7.
+
+   This notice must be preserved when any source code is 
+   conveyed and/or propagated.
+
+   Bacula(R) is a registered trademark of Kern Sibbald.
+*/
 /*
  *   edit.c  edit string to ascii, and ascii to internal
  *
  *    Kern Sibbald, December MMII
  *
- *   Version $Id$
- */
-/*
-   Copyright (C) 2002-2005 Kern Sibbald
-
-   This program is free software; you can redistribute it and/or
-   modify it under the terms of the GNU General Public License
-   version 2 as amended with additional clauses defined in the
-   file LICENSE in the main source directory.
-
-   This program is distributed in the hope that it will be useful,
-   but WITHOUT ANY WARRANTY; without even the implied warranty of
-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 
-   the file LICENSE for additional details.
-
  */
 
 #include "bacula.h"
@@ -38,9 +41,23 @@ uint64_t str_to_uint64(char *str)
    if (*p == '+') {
       p++;
    }
-   while (B_ISDIGIT(*p)) {
-      value = B_TIMES10(value) + *p - '0';
-      p++;
+   if (*p == '0' && *(p+1) == 'x') {
+      p = p + 2; /* skip 0x */
+
+      while (B_ISXDIGIT(*p)) {
+         if (B_ISDIGIT(*p)) {
+            value = (value<<4) + (*p - '0');
+
+         } else {
+            value = (value<<4) + (tolower(*p) - 'a' + 10);
+         }
+         p++;
+      }
+   } else {
+      while (B_ISDIGIT(*p)) {
+         value = B_TIMES10(value) + *p - '0';
+         p++;
+      }
    }
    return value;
 }
@@ -78,21 +95,7 @@ int64_t str_to_int64(char *str)
  */
 char *edit_uint64_with_commas(uint64_t val, char *buf)
 {
-   /*
-    * Replacement for sprintf(buf, "%" llu, val)
-    */
-   char mbuf[50];
-   mbuf[sizeof(mbuf)-1] = 0;
-   int i = sizeof(mbuf)-2;                 /* edit backward */
-   if (val == 0) {
-      mbuf[i--] = '0';
-   } else {
-      while (val != 0) {
-         mbuf[i--] = "0123456789"[val%10];
-         val /= 10;
-      }
-   }
-   bstrncpy(buf, &mbuf[i+1], 27);
+   edit_uint64(val, buf);
    return add_commas(buf, buf);
 }
 
@@ -107,7 +110,7 @@ char *edit_uint64_with_suffix(uint64_t val, char *buf)
 {
   int commas = 0;
   char *c, mbuf[50];
-  char *suffix[] =
+  const char *suffix[] =
     { "", "K", "M", "G", "T", "P", "E", "Z", "Y", "FIX ME" };
   int suffixes = sizeof(suffix) / sizeof(*suffix);
 
@@ -182,6 +185,16 @@ char *edit_int64(int64_t val, char *buf)
    return buf;
 }
 
+/*
+ * Edit an integer number with commas, the supplied buffer
+ * must be at least 27 bytes long.  The incoming number
+ * is always widened to 64 bits.
+ */
+char *edit_int64_with_commas(int64_t val, char *buf)
+{
+   edit_int64(val, buf);
+   return add_commas(buf, buf);
+}
 
 /*
  * Given a string "str", separate the numeric part into
@@ -259,10 +272,10 @@ bool duration_to_utime(char *str, utime_t *value)
     *   to months. These "kludges" make it compatible with pre 1.31
     *   Baculas.
     */
-   static const char *mod[] = {"n", "seconds", "months", "minutes",
+   static const char *mod[] = {"n", "seconds", "months", "minutes", "mins",
                   "hours", "days", "weeks",   "quarters",   "years", NULL};
-   static const int32_t mult[] = {60,   1, 60*60*24*30, 60,
-                  60*60, 60*60*24, 60*60*24*7, 60*60*24*91, 60*60*24*365};
+   static const int32_t mult[] = {60,   1, 60*60*24*30, 60, 60,
+                  3600, 3600*24, 3600*24*7, 3600*24*91, 3600*24*365};
 
    while (*str) {
       if (!get_modifier(str, num_str, sizeof(num_str), mod_str, sizeof(mod_str))) {
@@ -323,18 +336,13 @@ char *edit_utime(utime_t val, char *buf, int buf_len)
    return buf;
 }
 
-/*
- * Convert a size in bytes to uint64_t
- * Returns false: if error
-           true:  if OK, and value stored in value
- */
-bool size_to_uint64(char *str, int str_len, uint64_t *value)
+static bool strunit_to_uint64(char *str, int str_len, uint64_t *value,
+                              const char **mod)
 {
    int i, mod_len;
    double val;
    char mod_str[20];
    char num_str[50];
-   static const char *mod[]  = {"*", "k", "kb", "m", "mb",  "g", "gb",  NULL}; /* first item * not used */
    const int64_t mult[] = {1,             /* byte */
                            1024,          /* kilobyte */
                            1000,          /* kb kilobyte */
@@ -370,6 +378,30 @@ bool size_to_uint64(char *str, int str_len, uint64_t *value)
    return true;
 }
 
+/*
+ * Convert a size in bytes to uint64_t
+ * Returns false: if error
+           true:  if OK, and value stored in value
+ */
+bool size_to_uint64(char *str, int str_len, uint64_t *value)
+{
+   /* first item * not used */
+   static const char *mod[]  = {"*", "k", "kb", "m", "mb",  "g", "gb",  NULL};
+   return strunit_to_uint64(str, str_len, value, mod);
+}
+
+/*
+ * Convert a speed in bytes/s to uint64_t
+ * Returns false: if error
+           true:  if OK, and value stored in value
+ */
+bool speed_to_uint64(char *str, int str_len, uint64_t *value)
+{
+   /* first item * not used */
+   static const char *mod[]  = {"*", "k/s", "kb/s", "m/s", "mb/s",  NULL};
+   return strunit_to_uint64(str, str_len, value, mod);
+}
+
 /*
  * Check if specified string is a number or not.
  *  Taken from SQLite, cool, thanks.
@@ -378,6 +410,10 @@ bool is_a_number(const char *n)
 {
    bool digit_seen = false;
 
+   if (n == NULL) {
+      return false;
+   }
+
    if( *n == '-' || *n == '+' ) {
       n++;
    }
@@ -397,12 +433,39 @@ bool is_a_number(const char *n)
    return digit_seen && *n==0;
 }
 
+/*
+ * Check if specified string is a list of numbers or not
+ */
+bool is_a_number_list(const char *n)
+{
+   bool previous_digit = false;
+   bool digit_seen = false;
+   if (n == NULL) {
+      return false;
+   }
+   while (*n) {
+      if (B_ISDIGIT(*n)) {
+         previous_digit=true;
+         digit_seen = true;
+      } else if (*n == ',' && previous_digit) {
+         previous_digit = false;
+      } else {
+         return false;
+      }
+      n++;
+   }
+   return digit_seen && *n==0;
+}
+
 /*
  * Check if the specified string is an integer
  */
 bool is_an_integer(const char *n)
 {
    bool digit_seen = false;
+   if (n == NULL) {
+      return false;
+   }
    while (B_ISDIGIT(*n)) {
       digit_seen = true;
       n++;
@@ -417,13 +480,20 @@ bool is_an_integer(const char *n)
  * Check if the Volume name has legal characters
  * If ua is non-NULL send the message
  */
-bool is_name_valid(char *name, POOLMEM **msg)
+bool is_name_valid(const char *name, POOLMEM **msg)
 {
    int len;
-   char *p;
+   const char *p;
    /* Special characters to accept */
    const char *accept = ":.-_ ";
 
+   /* No name is invalid */
+   if (!name) {
+      if (msg) {
+         Mmsg(msg, _("Empty name not allowed.\n"));
+      }
+      return false;
+   }
    /* Restrict the characters permitted in the Volume name */
    for (p=name; *p; p++) {
       if (B_ISALPHA(*p) || B_ISDIGIT(*p) || strchr(accept, (int)(*p))) {
@@ -434,7 +504,7 @@ bool is_name_valid(char *name, POOLMEM **msg)
       }
       return false;
    }
-   len = strlen(name);
+   len = p - name;
    if (len >= MAX_NAME_LENGTH) {
       if (msg) {
          Mmsg(msg, _("Name too long.\n"));