00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #include "apr.h"
00018 #include "apr_strings.h"
00019 #include "apr_private.h"
00020 #include "apr_lib.h"
00021
00022 #if APR_HAVE_SYS_TYPES_H
00023 #include <sys/types.h>
00024 #endif
00025 #if APR_HAVE_STRING_H
00026 #include <string.h>
00027 #endif
00028 #if APR_HAVE_CTYPE_H
00029 #include <ctype.h>
00030 #endif
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 APR_DECLARE(char *) apr_cpystrn(char *dst, const char *src, apr_size_t dst_size)
00046 {
00047
00048 char *d, *end;
00049
00050 if (dst_size == 0) {
00051 return (dst);
00052 }
00053
00054 d = dst;
00055 end = dst + dst_size - 1;
00056
00057 for (; d < end; ++d, ++src) {
00058 if (!(*d = *src)) {
00059 return (d);
00060 }
00061 }
00062
00063 *d = '\0';
00064
00065 return (d);
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085 APR_DECLARE(apr_status_t) apr_tokenize_to_argv(const char *arg_str,
00086 char ***argv_out,
00087 apr_pool_t *token_context)
00088 {
00089 const char *cp;
00090 const char *ct;
00091 char *cleaned, *dirty;
00092 int escaped;
00093 int isquoted, numargs = 0, argnum;
00094
00095 #define SKIP_WHITESPACE(cp) \
00096 for ( ; *cp == ' ' || *cp == '\t'; ) { \
00097 cp++; \
00098 };
00099
00100 #define CHECK_QUOTATION(cp,isquoted) \
00101 isquoted = 0; \
00102 if (*cp == '"') { \
00103 isquoted = 1; \
00104 cp++; \
00105 } \
00106 else if (*cp == '\'') { \
00107 isquoted = 2; \
00108 cp++; \
00109 }
00110
00111
00112
00113
00114
00115 #define DETERMINE_NEXTSTRING(cp,isquoted) \
00116 for ( ; *cp != '\0'; cp++) { \
00117 if ( (isquoted && (*cp == ' ' || *cp == '\t')) \
00118 || (*cp == '\\' && (*(cp+1) == ' ' || *(cp+1) == '\t' || \
00119 *(cp+1) == '"' || *(cp+1) == '\''))) { \
00120 cp++; \
00121 continue; \
00122 } \
00123 if ( (!isquoted && (*cp == ' ' || *cp == '\t')) \
00124 || (isquoted == 1 && *cp == '"') \
00125 || (isquoted == 2 && *cp == '\'') ) { \
00126 break; \
00127 } \
00128 }
00129
00130
00131
00132
00133
00134 #define REMOVE_ESCAPE_CHARS(cleaned, dirty, escaped) \
00135 escaped = 0; \
00136 while(*dirty) { \
00137 if (!escaped && *dirty == '\\') { \
00138 escaped = 1; \
00139 } \
00140 else { \
00141 escaped = 0; \
00142 *cleaned++ = *dirty; \
00143 } \
00144 ++dirty; \
00145 } \
00146 *cleaned = 0;
00147
00148 cp = arg_str;
00149 SKIP_WHITESPACE(cp);
00150 ct = cp;
00151
00152
00153
00154
00155
00156
00157
00158 numargs = 1;
00159 while (*ct != '\0') {
00160 CHECK_QUOTATION(ct, isquoted);
00161 DETERMINE_NEXTSTRING(ct, isquoted);
00162 if (*ct != '\0') {
00163 ct++;
00164 }
00165 numargs++;
00166 SKIP_WHITESPACE(ct);
00167 }
00168 *argv_out = apr_palloc(token_context, numargs * sizeof(char*));
00169
00170
00171 for (argnum = 0; argnum < (numargs-1); argnum++) {
00172 CHECK_QUOTATION(cp, isquoted);
00173 ct = cp;
00174 DETERMINE_NEXTSTRING(cp, isquoted);
00175 cp++;
00176 (*argv_out)[argnum] = apr_palloc(token_context, cp - ct);
00177 apr_cpystrn((*argv_out)[argnum], ct, cp - ct);
00178 cleaned = dirty = (*argv_out)[argnum];
00179 REMOVE_ESCAPE_CHARS(cleaned, dirty, escaped);
00180 SKIP_WHITESPACE(cp);
00181 }
00182 (*argv_out)[argnum] = NULL;
00183
00184 return APR_SUCCESS;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 APR_DECLARE(const char *) apr_filepath_name_get(const char *pathname)
00198 {
00199 const char path_separator = '/';
00200 const char *s = strrchr(pathname, path_separator);
00201
00202 #ifdef WIN32
00203 const char path_separator_win = '\\';
00204 const char drive_separator_win = ':';
00205 const char *s2 = strrchr(pathname, path_separator_win);
00206
00207 if (s2 > s) s = s2;
00208
00209 if (!s) s = strrchr(pathname, drive_separator_win);
00210 #endif
00211
00212 return s ? ++s : pathname;
00213 }
00214
00215
00216 APR_DECLARE(const char *) apr_filename_of_pathname(const char *pathname)
00217 {
00218 return apr_filepath_name_get(pathname);
00219 }
00220
00221
00222
00223
00224
00225 APR_DECLARE(char *) apr_collapse_spaces(char *dest, const char *src)
00226 {
00227 while (*src) {
00228 if (!apr_isspace(*src))
00229 *dest++ = *src;
00230 ++src;
00231 }
00232 *dest = 0;
00233 return (dest);
00234 }
00235
00236 #if !APR_HAVE_STRDUP
00237 char *strdup(const char *str)
00238 {
00239 char *sdup;
00240 size_t len = strlen(str) + 1;
00241
00242 sdup = (char *) malloc(len);
00243 memcpy(sdup, str, len);
00244
00245 return sdup;
00246 }
00247 #endif
00248
00249
00250 #if (!APR_HAVE_STRCASECMP && !APR_HAVE_STRICMP)
00251 int strcasecmp(const char *a, const char *b)
00252 {
00253 const char *p = a;
00254 const char *q = b;
00255 for (p = a, q = b; *p && *q; p++, q++) {
00256 int diff = apr_tolower(*p) - apr_tolower(*q);
00257 if (diff)
00258 return diff;
00259 }
00260 if (*p)
00261 return 1;
00262 if (*q)
00263 return -1;
00264 return 0;
00265 }
00266
00267 #endif
00268
00269 #if (!APR_HAVE_STRNCASECMP && !APR_HAVE_STRNICMP)
00270 int strncasecmp(const char *a, const char *b, size_t n)
00271 {
00272 const char *p = a;
00273 const char *q = b;
00274
00275 for (p = a, q = b; ; p++, q++) {
00276 int diff;
00277 if (p == a + n)
00278 return 0;
00279 if (!(*p && *q))
00280 return *p - *q;
00281 diff = apr_tolower(*p) - apr_tolower(*q);
00282 if (diff)
00283 return diff;
00284 }
00285
00286 }
00287 #endif
00288
00289
00290 #if (!APR_HAVE_STRSTR)
00291 char *strstr(char *s1, char *s2)
00292 {
00293 char *p1, *p2;
00294 if (*s2 == '\0') {
00295
00296 return(s1);
00297 }
00298 while((s1 = strchr(s1, *s2)) != NULL) {
00299
00300 p1 = s1;
00301 p2 = s2;
00302 while (*++p1 == *++p2) {
00303 if (*p1 == '\0') {
00304
00305 return(s1);
00306 }
00307 }
00308 if (*p2 == '\0') {
00309
00310 break;
00311 }
00312
00313 s1++;
00314 }
00315 return(s1);
00316 }
00317 #endif
00318