00001
00002
00003
00004
00005
00006
00007
00008
#include "strutils.h"
00009
#include "wvbuf.h"
00010
#include <ctype.h>
00011
#include <stdio.h>
00012
#include <string.h>
00013
#include <time.h>
00014
00015
#ifndef _WIN32
00016
#include <errno.h>
00017
#include <netdb.h>
00018
#include <unistd.h>
00019
#else
00020
#undef errno
00021
#define errno GetLastError()
00022
#define strcasecmp _stricmp
00023
#include <winsock2.h>
00024
#endif
00025
00026 char *
terminate_string(
char *string,
char c)
00027
00028
00029
00030
00031 {
00032
char *p;
00033
00034
if (string == NULL)
00035
return NULL;
00036
00037 p = string + strlen(string) - 1;
00038
while (*p ==
'\r' || *p ==
'\n')
00039 p--;
00040
00041 *(++p) = c;
00042 *(++p) = 0;
00043
00044
return string;
00045 }
00046
00047
00048 char *
trim_string(
char *string)
00049
00050
00051
00052 {
00053
char *p;
00054
char *q;
00055
00056
if (string == NULL)
00057
return NULL;
00058
00059 p = string;
00060 q = string + strlen(string) - 1;
00061
00062
while (q >= p && isspace(*q))
00063 *(q--) = 0;
00064
while (isspace(*p))
00065 p++;
00066
00067
return p;
00068 }
00069
00070
00071 char *
trim_string(
char *string,
char c)
00072
00073
00074 {
00075
char *p;
00076
00077
if (string == NULL)
00078
return NULL;
00079
00080 p = string;
00081
00082
while (*p != 0 && *p != c)
00083 p++;
00084
00085
while (*p)
00086 *(p++) = 0;
00087
00088
return string;
00089 }
00090
00091
00092
00093 char *
non_breaking(
char * string)
00094 {
00095
if (string == NULL)
00096
return (NULL);
00097
00098
WvDynBuf buf;
00099
00100
while (*string)
00101 {
00102
if (isspace(*string))
00103 buf.putstr(
" ");
00104
else
00105 buf.putch(*string);
00106 string++;
00107 }
00108
00109
WvString s(buf.getstr());
00110
return s.
edit();
00111 }
00112
00113
00114
00115
00116 void replace_char(
void *_string,
char c1,
char c2,
int length)
00117 {
00118
char *string = (
char *)_string;
00119
for (
int i=0; i < length; i++)
00120
if (*(string+i) == c1)
00121 *(string+i) = c2;
00122 }
00123
00124
00125 char *
snip_string(
char *haystack,
char *needle)
00126 {
00127
if(!haystack)
00128
return NULL;
00129
if(!needle)
00130
return haystack;
00131
char *p = strstr(haystack, needle);
00132
if(!p || p != haystack)
00133
return haystack;
00134
else
00135
return haystack + strlen(needle);
00136 }
00137
00138
#ifndef _WIN32
00139 char *
strlwr(
char *string)
00140 {
00141
char *p = string;
00142
while (*p)
00143 {
00144 *p = tolower(*p);
00145 p++;
00146 }
00147
00148
return string;
00149 }
00150
00151
00152 char *
strupr(
char *string)
00153 {
00154
char *p = string;
00155
while (*p)
00156 {
00157 *p = toupper(*p);
00158 p++;
00159 }
00160
00161
return string;
00162 }
00163
#endif
00164
00165
00166 bool is_word(
const char *p)
00167 {
00168
while (*p)
00169 {
00170
if(!isalnum(*p++))
00171
return false;
00172 }
00173
00174
return true;
00175 }
00176
00177
00178
00179
00180
00181 WvString hexdump_buffer(
const void *_buf, size_t len,
bool charRep)
00182 {
00183
const unsigned char *buf = (
const unsigned char *)_buf;
00184 size_t count, count2, top;
00185
WvString out;
00186
00187 out.
setsize(len / 16 * 80 + 80);
00188
char *cptr = out.
edit();
00189
00190
for (count = 0; count < len; count+=16)
00191 {
00192 top = len-count < 16 ? len-count : 16;
00193 cptr += sprintf(cptr,
"[%03X] ", (
unsigned int)count);
00194
00195
00196
for (count2 = 0; count2 < top; count2++)
00197 {
00198
if (count2 && !(count2 % 4))
00199 *cptr++ =
' ';
00200 cptr += sprintf(cptr,
"%02X", buf[count+count2]);
00201 }
00202
00203
00204
for (count2 = top; count2 < 16; count2++)
00205 {
00206
if (count2 && !(count2 % 4))
00207 {
00208 strcat(cptr,
" ");
00209 cptr += 3;
00210 }
00211
else
00212 {
00213 strcat(cptr,
" ");
00214 cptr += 2;
00215 }
00216 }
00217
00218 *cptr++ =
' ';
00219
00220
00221
if (charRep)
00222
for (count2 = 0; count2 < top; count2++)
00223 *cptr++ = (isprint(buf[count+count2])
00224 ? buf[count+count2] :
'.');
00225
00226 *cptr++ =
'\n';
00227 }
00228 *cptr = 0;
00229
return out;
00230 }
00231
00232
00233
00234 bool isnewline(
char c)
00235 {
00236
return c==
'\n' || c==
'\r';
00237 }
00238
00239
00240 WvString web_unescape(
const char *str)
00241 {
00242
const char *iptr;
00243
char *optr;
00244
char *idx1, *idx2;
00245
static const char hex[] =
"0123456789ABCDEF";
00246
WvString in, intmp(str), out;
00247
00248 in =
trim_string(intmp.
edit());
00249 out.
setsize(strlen(in) + 1);
00250
00251 optr = out.
edit();
00252
for (iptr = in, optr = out.
edit(); *iptr; iptr++)
00253 {
00254
if (*iptr ==
'+')
00255 *optr++ =
' ';
00256
else if (*iptr ==
'%' && iptr[1] && iptr[2])
00257 {
00258 idx1 = strchr(hex, toupper((
unsigned char) iptr[1]));
00259 idx2 = strchr(hex, toupper((
unsigned char) iptr[2]));
00260
00261
if (idx1 && idx2)
00262 *optr++ = ((idx1 - hex) << 4) | (idx2 - hex);
00263
00264 iptr += 2;
00265 }
00266
else
00267 *optr++ = *iptr;
00268 }
00269
00270 *optr = 0;
00271
00272
return out;
00273 }
00274
00275
00276
00277 WvString url_encode(
WvStringParm stuff)
00278 {
00279
unsigned int i;
00280
WvDynBuf retval;
00281
00282
for (i=0; i < stuff.
len(); i++)
00283 {
00284
if (isalnum(stuff[i]) || strchr(
"/_.-~", stuff[i]))
00285 {
00286 retval.
put(&stuff[i], 1);
00287 }
00288
else
00289 {
00290
char buf[3];
00291 sprintf(buf,
"%%%02x", stuff[i] & 0xff);
00292 retval.
put(&buf, 3);
00293 }
00294 }
00295
return retval.getstr();
00296 }
00297
00298
00299 WvString rfc822_date(time_t when)
00300 {
00301
WvString out;
00302 out.
setsize(80);
00303
00304
if (when < 0)
00305 when = time(NULL);
00306
00307
struct tm *tmwhen = localtime(&when);
00308 strftime(out.
edit(), 80,
"%a, %d %b %Y %H:%M:%S %z", tmwhen);
00309
00310
return out;
00311 }
00312
00313
00314 WvString backslash_escape(
WvStringParm s1)
00315 {
00316
00317
if (!s1)
00318
return "";
00319
00320
WvString s2;
00321 s2.
setsize(s1.
len() * 2 + 1);
00322
00323
const char *p1 = s1;
00324
char *p2 = s2.
edit();
00325
while (*p1)
00326 {
00327
if (!isalnum(*p1))
00328 *p2++ =
'\\';
00329 *p2++ = *p1++;
00330 }
00331 *p2 = 0;
00332
00333
return s2;
00334 }
00335
00336
00337 int strcount(
WvStringParm s,
const char c)
00338 {
00339
int n=0;
00340
const char *p = s;
00341
while ((p=strchr(p, c)) != NULL && p++)
00342 n++;
00343
00344
return n;
00345 }
00346
00347
00348 WvString encode_hostname_as_DN(
WvStringParm hostname)
00349 {
00350
WvString dn(
"");
00351
00352
WvStringList fqdnlist;
00353 WvStringList::Iter i(fqdnlist);
00354
00355 fqdnlist.
split(
hostname,
".");
00356
for (i.rewind(); i.next(); )
00357 dn.
append(
"dc=%s,", *i);
00358 dn.
append(
"cn=%s",
hostname);
00359
00360
return dn;
00361 }
00362
00363
00364 WvString nice_hostname(
WvStringParm name)
00365 {
00366
WvString nice;
00367
char *optr, *optr_start;
00368
const char *iptr;
00369
bool last_was_dash;
00370
00371 nice.
setsize(name.
len() + 2);
00372
00373 iptr = name;
00374 optr = optr_start = nice.
edit();
00375
if (!isascii(*iptr) || !isalnum(*(
const unsigned char *)iptr))
00376 *optr++ =
'x';
00377
00378 last_was_dash =
false;
00379
for (; *iptr; iptr++)
00380 {
00381
if (!isascii(*iptr))
00382
continue;
00383
00384
if (*iptr ==
'-' || *iptr ==
'_')
00385 {
00386
if (last_was_dash)
00387
continue;
00388 last_was_dash =
true;
00389 *optr++ =
'-';
00390 }
00391
else if (isalnum(*(
const unsigned char *)iptr) || *iptr ==
'.')
00392 {
00393 *optr++ = *iptr;
00394 last_was_dash =
false;
00395 }
00396 }
00397
00398
if (optr > optr_start && !isalnum(*(
const unsigned char *)(optr-1)))
00399 *optr++ =
'x';
00400
00401 *optr++ = 0;
00402
00403
if (!nice.
len())
00404
return "UNKNOWN";
00405
00406
return nice;
00407 }
00408
00409
00410 WvString getfilename(
WvStringParm fullname)
00411 {
00412
WvString tmp(fullname);
00413
char *cptr = strrchr(tmp.
edit(),
'/');
00414
00415
if (!cptr)
00416
return fullname;
00417
else if (!cptr[1])
00418 {
00419 *cptr = 0;
00420
return getfilename(tmp);
00421 }
00422
else
00423
return cptr+1;
00424 }
00425
00426
00427 WvString getdirname(
WvStringParm fullname)
00428 {
00429
WvString tmp(fullname);
00430
char *cptr = strrchr(tmp.
edit(),
'/');
00431
00432
if (!cptr)
00433
return ".";
00434
else if (!cptr[1])
00435 {
00436 *cptr = 0;
00437
return getdirname(tmp);
00438 }
00439
else
00440 {
00441 *cptr = 0;
00442
return !tmp ?
WvString(
"/") : tmp;
00443 }
00444 }
00445
00446
00447 WvString sizetoa(
long long blocks,
int blocksize)
00448 {
00449
long long kbytes = blocks * (
long long) blocksize / 1000;
00450
00451
if (kbytes >= 1000*1000*1000)
00452
return WvString(
"%s.%s TB",
00453 (
unsigned long) (kbytes/(1000*1000*1000)),
00454 (
unsigned long) (kbytes%(1000*1000*1000))/(100*1000*1000));
00455
else if (kbytes >= 1000*1000)
00456
return WvString(
"%s.%s GB",
00457 (
unsigned long) (kbytes/(1000*1000)),
00458 (
unsigned long) (kbytes % (1000*1000))/(100*1000));
00459
else if (kbytes >= 1000)
00460
return WvString(
"%s.%s MB",
00461 (
unsigned long) (kbytes/(1000)),
00462 (
unsigned long) (kbytes % (1000))/(100));
00463
else if (kbytes)
00464
return WvString(
"%s.%s KB",
00465 (
unsigned long) (blocks*blocksize / 1000),
00466 (
unsigned long) ((blocks*blocksize) % 1000)/(100));
00467
else
00468
return WvString(
"%s bytes", blocks*blocksize);
00469 }
00470
00471
00472 WvString strreplace(
WvStringParm s,
WvStringParm a,
WvStringParm b)
00473 {
00474
WvDynBuf buf;
00475
const char *sptr = s, *eptr;
00476
00477
while ((eptr = strstr(sptr, a)) != NULL)
00478 {
00479 buf.
put(sptr, eptr-sptr);
00480 buf.putstr(b);
00481 sptr = eptr + strlen(a);
00482 }
00483
00484 buf.
put(sptr, strlen(sptr));
00485
00486
return buf.getstr();
00487 }
00488
00489 WvString undupe(
WvStringParm s,
char c)
00490 {
00491
WvDynBuf out;
00492
00493
bool last =
false;
00494
00495
for (
int i = 0; s[i] !=
'\0'; i++)
00496 {
00497
if (s[i] != c)
00498 {
00499 out.putch(s[i]);
00500 last =
false;
00501 }
00502
else if (!last)
00503 {
00504 out.putch(c);
00505 last =
true;
00506 }
00507 }
00508
00509
return out.getstr();
00510 }
00511
00512
00513 WvString rfc1123_date(time_t t)
00514 {
00515
struct tm *tm = gmtime(&t);
00516
WvString s;
00517
00518 s.
setsize(128);
00519 strftime(s.
edit(), 128,
"%a, %d %b %Y %H:%M:%S GMT", tm);
00520
00521
return s;
00522 }
00523
00524
00525 int lookup(
const char *str,
const char *
const *table,
bool case_sensitive)
00526 {
00527
for (
int i = 0; table[i]; ++i)
00528 {
00529
if (case_sensitive)
00530 {
00531
if (strcmp(str, table[i]) != 0)
00532
continue;
00533 }
00534
else
00535 {
00536
if (strcasecmp(str, table[i]) != 0)
00537
continue;
00538 }
00539
return i;
00540 }
00541
return -1;
00542 }
00543
00544
00545 WvString hostname()
00546 {
00547
int maxlen = 0;
00548
for(;;)
00549 {
00550 maxlen += 80;
00551
char *name =
new char[maxlen];
00552
int result = gethostname(name, maxlen);
00553
if (result == 0)
00554 {
00555
WvString hostname(name);
00556
delete [] name;
00557
return hostname;
00558 }
00559
#ifdef _WIN32
00560
assert(errno == WSAEFAULT);
00561
#else
00562
assert(errno == EINVAL);
00563
#endif
00564
}
00565 }
00566
00567
00568 WvString fqdomainname()
00569 {
00570
struct hostent *myhost;
00571
00572 myhost = gethostbyname(
hostname());
00573
if (myhost)
00574
return myhost->h_name;
00575
else
00576
return WvString::null;
00577 }
00578
00579
00580 WvString metriculate(
const off_t i)
00581 {
00582
WvString res;
00583
int digits=0;
00584
int digit=0;
00585
long long int j=i;
00586
char *p;
00587
00588
while (j)
00589 {
00590 digits++;
00591 j/=10;
00592 }
00593
00594 j=i;
00595 res.
setsize(digits + (digits-1)/3 + 1);
00596 p=res.
edit()+digits+((digits-1)/3);
00597 *p-- =
'\0';
00598
00599
for (digit=0; digit<digits; digit++)
00600 {
00601 *p-- =
'0' + ( j%10 );
00602
if (((digit+1) % 3) == 0)
00603 *p-- =
' ';
00604 j /= 10;
00605 }
00606
00607
return res;
00608 }