~zulcss/samba/server-dailies-3.4

« back to all changes in this revision

Viewing changes to lib/util/substitute.c

  • Committer: Chuck Short
  • Date: 2010-09-28 20:38:39 UTC
  • Revision ID: zulcss@ubuntu.com-20100928203839-pgjulytsi9ue63x1
Initial version

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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)
 
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, 
 
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)
 
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
}