LCOV - code coverage report
Current view: top level - lib/util - util_str.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 95 124 76.6 %
Date: 2024-04-21 15:09:00 Functions: 8 9 88.9 %

          Line data    Source code
       1             : /*
       2             :    Unix SMB/CIFS implementation.
       3             :    Samba utility functions
       4             : 
       5             :    Copyright (C) Andrew Tridgell 1992-2001
       6             :    Copyright (C) Simo Sorce      2001-2002
       7             :    Copyright (C) Martin Pool     2003
       8             :    Copyright (C) James Peach     2005
       9             : 
      10             :    This program is free software; you can redistribute it and/or modify
      11             :    it under the terms of the GNU General Public License as published by
      12             :    the Free Software Foundation; either version 3 of the License, or
      13             :    (at your option) any later version.
      14             : 
      15             :    This program is distributed in the hope that it will be useful,
      16             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      17             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      18             :    GNU General Public License for more details.
      19             : 
      20             :    You should have received a copy of the GNU General Public License
      21             :    along with this program.  If not, see <http://www.gnu.org/licenses/>.
      22             : */
      23             : 
      24             : #include "replace.h"
      25             : #include "lib/util/samba_util.h"
      26             : #include "system/locale.h"
      27             : #include "smb_strtox.h"
      28             : #undef strncasecmp
      29             : #undef strcasemp
      30             : 
      31             : /**
      32             :  * @file
      33             :  * @brief String utilities.
      34             :  **/
      35             : 
      36             : /**
      37             :  * Parse a string containing a boolean value.
      38             :  *
      39             :  * val will be set to the read value.
      40             :  *
      41             :  * @retval true if a boolean value was parsed, false otherwise.
      42             :  */
      43           0 : _PUBLIC_ bool conv_str_bool(const char * str, bool * val)
      44             : {
      45           0 :         char *  end = NULL;
      46           0 :         long    lval;
      47             : 
      48           0 :         if (str == NULL || *str == '\0') {
      49           0 :                 return false;
      50             :         }
      51             : 
      52           0 :         lval = strtol(str, &end, 10 /* base */);
      53           0 :         if (end == NULL || *end != '\0' || end == str) {
      54           0 :                 return set_boolean(str, val);
      55             :         }
      56             : 
      57           0 :         *val = (lval) ? true : false;
      58           0 :         return true;
      59             : }
      60             : 
      61             : /**
      62             :  * Convert a size specification like 16K into an integral number of bytes.
      63             :  **/
      64      196805 : _PUBLIC_ bool conv_str_size_error(const char * str, uint64_t * val)
      65             : {
      66      196805 :         char *              end = NULL;
      67        4421 :         unsigned long long  lval;
      68      196805 :         int error = 0;
      69             : 
      70      196805 :         if (str == NULL || *str == '\0') {
      71           0 :                 return false;
      72             :         }
      73             : 
      74      196805 :         lval = smb_strtoull(str, &end, 10, &error, SMB_STR_STANDARD);
      75      196805 :         if (error != 0) {
      76           0 :                 return false;
      77             :         }
      78             : 
      79      196805 :         if (*end) {
      80       44221 :                 if (strwicmp(end, "K") == 0) {
      81       44221 :                         lval *= 1024ULL;
      82           0 :                 } else if (strwicmp(end, "M") == 0) {
      83           0 :                         lval *= (1024ULL * 1024ULL);
      84           0 :                 } else if (strwicmp(end, "G") == 0) {
      85           0 :                         lval *= (1024ULL * 1024ULL * 1024ULL);
      86           0 :                 } else if (strwicmp(end, "T") == 0) {
      87           0 :                         lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL);
      88           0 :                 } else if (strwicmp(end, "P") == 0) {
      89           0 :                         lval *= (1024ULL * 1024ULL * 1024ULL * 1024ULL * 1024ULL);
      90             :                 } else {
      91           0 :                         return false;
      92             :                 }
      93             :         }
      94             : 
      95      196805 :         *val = (uint64_t)lval;
      96      196805 :         return true;
      97             : }
      98             : 
      99             : /**
     100             :  * Parse a uint64_t value from a string
     101             :  *
     102             :  * val will be set to the value read.
     103             :  *
     104             :  * @retval true if parsing was successful, false otherwise
     105             :  */
     106          22 : _PUBLIC_ bool conv_str_u64(const char * str, uint64_t * val)
     107             : {
     108           6 :         unsigned long long  lval;
     109          22 :         int error = 0;
     110             : 
     111          22 :         if (str == NULL || *str == '\0') {
     112           0 :                 return false;
     113             :         }
     114             : 
     115          22 :         lval = smb_strtoull(str, NULL, 10, &error, SMB_STR_FULL_STR_CONV);
     116          22 :         if (error != 0) {
     117           0 :                 return false;
     118             :         }
     119             : 
     120          20 :         *val = (uint64_t)lval;
     121          20 :         return true;
     122             : }
     123             : 
     124             : /**
     125             :  * Compare 2 strings.
     126             :  *
     127             :  * @note The comparison is case-insensitive.
     128             :  **/
     129   265883264 : _PUBLIC_ bool strequal(const char *s1, const char *s2)
     130             : {
     131   265883264 :         if (s1 == s2)
     132      622797 :                 return true;
     133   265249593 :         if (!s1 || !s2)
     134     6119111 :                 return false;
     135             : 
     136   259112833 :         return strcasecmp_m(s1,s2) == 0;
     137             : }
     138             : 
     139             : /**
     140             :  * @file
     141             :  * @brief String utilities.
     142             :  **/
     143             : 
     144    14313858 : static bool next_token_internal_talloc(TALLOC_CTX *ctx,
     145             :                                 const char **ptr,
     146             :                                 char **pp_buff,
     147             :                                 const char *sep,
     148             :                                 bool ltrim)
     149             : {
     150       84063 :         const char *s;
     151       84063 :         const char *saved_s;
     152       84063 :         char *pbuf;
     153       84063 :         bool quoted;
     154    14313858 :         size_t len=1;
     155             : 
     156    14313858 :         *pp_buff = NULL;
     157    14313858 :         if (!ptr) {
     158           0 :                 return(false);
     159             :         }
     160             : 
     161    14313858 :         s = *ptr;
     162             : 
     163             :         /* default to simple separators */
     164    14313858 :         if (!sep) {
     165       60333 :                 sep = " \t\n\r";
     166             :         }
     167             : 
     168             :         /* find the first non sep char, if left-trimming is requested */
     169    14313858 :         if (ltrim) {
     170    14375006 :                 while (*s && strchr_m(sep,*s)) {
     171       64138 :                         s++;
     172             :                 }
     173             :         }
     174             : 
     175             :         /* nothing left? */
     176    14313858 :         if (!*s) {
     177     3792119 :                 return false;
     178             :         }
     179             : 
     180             :         /* When restarting we need to go from here. */
     181    10437676 :         saved_s = s;
     182             : 
     183             :         /* Work out the length needed. */
     184   142064444 :         for (quoted = false; *s &&
     185   269280213 :                         (quoted || !strchr_m(sep,*s)); s++) {
     186   131563588 :                 if (*s == '\"') {
     187       79762 :                         quoted = !quoted;
     188             :                 } else {
     189   131483826 :                         len++;
     190             :                 }
     191             :         }
     192             : 
     193             :         /* We started with len = 1 so we have space for the nul. */
     194    10500856 :         *pp_buff = talloc_array(ctx, char, len);
     195    10500856 :         if (!*pp_buff) {
     196           0 :                 return false;
     197             :         }
     198             : 
     199             :         /* copy over the token */
     200    10437676 :         pbuf = *pp_buff;
     201    10437676 :         s = saved_s;
     202   142064444 :         for (quoted = false; *s &&
     203   269280213 :                         (quoted || !strchr_m(sep,*s)); s++) {
     204   131563588 :                 if ( *s == '\"' ) {
     205       79762 :                         quoted = !quoted;
     206             :                 } else {
     207   131483826 :                         *pbuf++ = *s;
     208             :                 }
     209             :         }
     210             : 
     211    10500856 :         *ptr = (*s) ? s+1 : s;
     212    10500856 :         *pbuf = 0;
     213             : 
     214    10500856 :         return true;
     215             : }
     216             : 
     217    14310868 : bool next_token_talloc(TALLOC_CTX *ctx,
     218             :                         const char **ptr,
     219             :                         char **pp_buff,
     220             :                         const char *sep)
     221             : {
     222    14310868 :         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, true);
     223             : }
     224             : 
     225             : /*
     226             :  * Get the next token from a string, return false if none found.  Handles
     227             :  * double-quotes.  This version does not trim leading separator characters
     228             :  * before looking for a token.
     229             :  */
     230             : 
     231        2990 : bool next_token_no_ltrim_talloc(TALLOC_CTX *ctx,
     232             :                         const char **ptr,
     233             :                         char **pp_buff,
     234             :                         const char *sep)
     235             : {
     236        2990 :         return next_token_internal_talloc(ctx, ptr, pp_buff, sep, false);
     237             : }
     238             : 
     239             : /**
     240             :  * Get the next token from a string, return False if none found.
     241             :  * Handles double-quotes.
     242             :  *
     243             :  * Based on a routine by GJC@VILLAGE.COM.
     244             :  * Extensively modified by Andrew.Tridgell@anu.edu.au
     245             :  **/
     246        2184 : _PUBLIC_ bool next_token(const char **ptr,char *buff, const char *sep, size_t bufsize)
     247             : {
     248          16 :         const char *s;
     249          16 :         bool quoted;
     250        2184 :         size_t len=1;
     251             : 
     252        2184 :         if (!ptr)
     253           0 :                 return false;
     254             : 
     255        2183 :         s = *ptr;
     256             : 
     257             :         /* default to simple separators */
     258        2183 :         if (!sep)
     259           4 :                 sep = " \t\n\r";
     260             : 
     261             :         /* find the first non sep char */
     262        2187 :         while (*s && strchr_m(sep,*s))
     263           4 :                 s++;
     264             : 
     265             :         /* nothing left? */
     266        2183 :         if (!*s)
     267         104 :                 return false;
     268             : 
     269             :         /* copy over the token */
     270       65505 :         for (quoted = false; len < bufsize && *s && (quoted || !strchr_m(sep,*s)); s++) {
     271       63431 :                 if (*s == '\"') {
     272           3 :                         quoted = !quoted;
     273             :                 } else {
     274       63428 :                         len++;
     275       63428 :                         *buff++ = *s;
     276             :                 }
     277             :         }
     278             : 
     279        2074 :         *ptr = (*s) ? s+1 : s;
     280        2074 :         *buff = 0;
     281             : 
     282        2074 :         return true;
     283             : }
     284             : 
     285             : /**
     286             :  Set a boolean variable from the text value stored in the passed string.
     287             :  Returns true in success, false if the passed string does not correctly
     288             :  represent a boolean.
     289             : **/
     290             : 
     291     5667454 : _PUBLIC_ bool set_boolean(const char *boolean_string, bool *boolean)
     292             : {
     293     8130506 :         if (strwicmp(boolean_string, "yes") == 0 ||
     294     3971928 :             strwicmp(boolean_string, "true") == 0 ||
     295     3017752 :             strwicmp(boolean_string, "on") == 0 ||
     296     1508876 :             strwicmp(boolean_string, "1") == 0) {
     297     4158584 :                 *boolean = true;
     298     4158584 :                 return true;
     299     1686871 :         } else if (strwicmp(boolean_string, "no") == 0 ||
     300      178001 :                    strwicmp(boolean_string, "false") == 0 ||
     301           0 :                    strwicmp(boolean_string, "off") == 0 ||
     302           0 :                    strwicmp(boolean_string, "0") == 0) {
     303     1508870 :                 *boolean = false;
     304     1508870 :                 return true;
     305             :         }
     306           0 :         return false;
     307             : }

Generated by: LCOV version 1.14