root/lib/util/substitute.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. string_sub
  2. string_sub_talloc
  3. all_string_sub

   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 "includes.h"
  25 
  26 /**
  27  * @file
  28  * @brief Substitute utilities.
  29  **/
  30 
  31 /**
  32  Substitute a string for a pattern in another string. Make sure there is 
  33  enough room!
  34 
  35  This routine looks for pattern in s and replaces it with 
  36  insert. It may do multiple replacements.
  37 
  38  Any of " ; ' $ or ` in the insert string are replaced with _
  39  if len==0 then the string cannot be extended. This is different from the old
  40  use of len==0 which was for no length checks to be done.
  41 **/
  42 
  43 _PUBLIC_ void string_sub(char *s, const char *pattern, const char *insert, size_t len)
     /* [<][>][^][v][top][bottom][index][help] */
  44 {
  45         char *p;
  46         ssize_t ls, lp, li, i;
  47 
  48         if (!insert || !pattern || !*pattern || !s)
  49                 return;
  50 
  51         ls = (ssize_t)strlen(s);
  52         lp = (ssize_t)strlen(pattern);
  53         li = (ssize_t)strlen(insert);
  54 
  55         if (len == 0)
  56                 len = ls + 1; /* len is number of *bytes* */
  57 
  58         while (lp <= ls && (p = strstr(s, pattern))) {
  59                 if (ls + (li-lp) >= len) {
  60                         DEBUG(0,("ERROR: string overflow by %d in string_sub(%.50s, %d)\n", 
  61                                  (int)(ls + (li-lp) - len),
  62                                  pattern, (int)len));
  63                         break;
  64                 }
  65                 if (li != lp) {
  66                         memmove(p+li,p+lp,strlen(p+lp)+1);
  67                 }
  68                 for (i=0;i<li;i++) {
  69                         switch (insert[i]) {
  70                         case '`':
  71                         case '"':
  72                         case '\'':
  73                         case ';':
  74                         case '$':
  75                         case '%':
  76                         case '\r':
  77                         case '\n':
  78                                 p[i] = '_';
  79                                 break;
  80                         default:
  81                                 p[i] = insert[i];
  82                         }
  83                 }
  84                 s = p + li;
  85                 ls += (li-lp);
  86         }
  87 }
  88 
  89 /**
  90  * Talloc'ed version of string_sub
  91  */
  92 _PUBLIC_ char *string_sub_talloc(TALLOC_CTX *mem_ctx, const char *s, 
     /* [<][>][^][v][top][bottom][index][help] */
  93                                 const char *pattern, const char *insert)
  94 {
  95         const char *p;
  96         char *ret;
  97         size_t len, alloc_len;
  98 
  99         if (insert == NULL || pattern == NULL || !*pattern || s == NULL)
 100                 return NULL;
 101 
 102         /* determine length needed */
 103         len = strlen(s);
 104         
 105         for (p = strstr(s, pattern); p != NULL; 
 106              p = strstr(p+strlen(pattern), pattern)) {
 107                 len += strlen(insert) - strlen(pattern);
 108         }
 109 
 110         alloc_len = MAX(len, strlen(s))+1;
 111         ret = talloc_array(mem_ctx, char, alloc_len);
 112         if (ret == NULL)
 113                 return NULL;
 114         strncpy(ret, s, alloc_len);
 115         string_sub(ret, pattern, insert, alloc_len);
 116 
 117         ret = talloc_realloc(mem_ctx, ret, char, len+1);
 118         if (ret == NULL)
 119                 return NULL;
 120 
 121         SMB_ASSERT(ret[len] == '\0');
 122 
 123         talloc_set_name_const(ret, ret);
 124 
 125         return ret;
 126 }
 127 
 128 /**
 129  Similar to string_sub() but allows for any character to be substituted. 
 130  Use with caution!
 131  if len==0 then the string cannot be extended. This is different from the old
 132  use of len==0 which was for no length checks to be done.
 133 **/
 134 
 135 _PUBLIC_ void all_string_sub(char *s,const char *pattern,const char *insert, size_t len)
     /* [<][>][^][v][top][bottom][index][help] */
 136 {
 137         char *p;
 138         ssize_t ls,lp,li;
 139 
 140         if (!insert || !pattern || !s)
 141                 return;
 142 
 143         ls = (ssize_t)strlen(s);
 144         lp = (ssize_t)strlen(pattern);
 145         li = (ssize_t)strlen(insert);
 146 
 147         if (!*pattern)
 148                 return;
 149         
 150         if (len == 0)
 151                 len = ls + 1; /* len is number of *bytes* */
 152         
 153         while (lp <= ls && (p = strstr(s,pattern))) {
 154                 if (ls + (li-lp) >= len) {
 155                         DEBUG(0,("ERROR: string overflow by %d in all_string_sub(%.50s, %d)\n", 
 156                                  (int)(ls + (li-lp) - len),
 157                                  pattern, (int)len));
 158                         break;
 159                 }
 160                 if (li != lp) {
 161                         memmove(p+li,p+lp,strlen(p+lp)+1);
 162                 }
 163                 memcpy(p, insert, li);
 164                 s = p + li;
 165                 ls += (li-lp);
 166         }
 167 }

/* [<][>][^][v][top][bottom][index][help] */