00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "services.h"
00017 #include "language.h"
00018
00019
00020 #define issp(c) ((c) == 32)
00021
00022 struct arc4_stream {
00023 u_int8_t i;
00024 u_int8_t j;
00025 u_int8_t s[256];
00026 } rs;
00027
00028
00029
00036 int toupper(char c)
00037 {
00038 if (islower(c)) {
00039 return (unsigned char) c - ('a' - 'A');
00040 } else {
00041 return (unsigned char) c;
00042 }
00043 }
00044
00045
00046
00053 int tolower(char c)
00054 {
00055 if (isupper(c)) {
00056 return (unsigned char) c + ('a' - 'A');
00057 } else {
00058 return (unsigned char) c;
00059 }
00060 }
00061
00062
00063
00068 void binary_to_hex(unsigned char *bin, char *hex, int length)
00069 {
00070 static const char trans[] = "0123456789ABCDEF";
00071 int i;
00072
00073 for (i = 0; i < length; i++) {
00074 hex[i << 1] = trans[bin[i] >> 4];
00075 hex[(i << 1) + 1] = trans[bin[i] & 0xf];
00076 }
00077
00078 hex[i << 1] = '\0';
00079 }
00080
00081
00082
00083
00092 char *strscpy(char *d, const char *s, size_t len)
00093 {
00094 char *d_orig = d;
00095
00096 if (!len) {
00097 return d;
00098 }
00099 while (--len && (*d++ = *s++));
00100 *d = '\0';
00101 return d_orig;
00102 }
00103
00104
00105
00114 char *stristr(char *s1, char *s2)
00115 {
00116 register char *s = s1, *d = s2;
00117
00118 while (*s1) {
00119 if (tolower(*s1) == tolower(*d)) {
00120 s1++;
00121 d++;
00122 if (*d == 0)
00123 return s;
00124 } else {
00125 s = ++s1;
00126 d = s2;
00127 }
00128 }
00129 return NULL;
00130 }
00131
00132
00133
00145 char *strnrepl(char *s, int32 size, const char *old, const char *new)
00146 {
00147 char *ptr = s;
00148 int32 left = strlen(s);
00149 int32 avail = size - (left + 1);
00150 int32 oldlen = strlen(old);
00151 int32 newlen = strlen(new);
00152 int32 diff = newlen - oldlen;
00153
00154 while (left >= oldlen) {
00155 if (strncmp(ptr, old, oldlen) != 0) {
00156 left--;
00157 ptr++;
00158 continue;
00159 }
00160 if (diff > avail)
00161 break;
00162 if (diff != 0)
00163 memmove(ptr + oldlen + diff, ptr + oldlen, left + 1);
00164 strncpy(ptr, new, newlen);
00165 ptr += newlen;
00166 left -= oldlen;
00167 }
00168 return s;
00169 }
00170
00171
00172
00181 char *merge_args(int argc, char **argv)
00182 {
00183 int i;
00184 static char s[4096];
00185 char *t;
00186
00187 t = s;
00188 for (i = 0; i < argc; i++)
00189 t += snprintf(t, sizeof(s) - (t - s), "%s%s", *argv++,
00190 (i < argc - 1) ? " " : "");
00191 return s;
00192 }
00193
00194
00195
00205 static int do_match_wild(const char *pattern, const char *str, int docase)
00206 {
00207 char c;
00208 const char *s;
00209
00210 if (!str || !*str || !pattern || !*pattern) {
00211 return 0;
00212 }
00213
00214
00215
00216
00217 for (;;) {
00218 switch (c = *pattern++) {
00219 case 0:
00220 if (!*str)
00221 return 1;
00222 return 0;
00223 case '?':
00224 if (!*str)
00225 return 0;
00226 str++;
00227 break;
00228 case '*':
00229 if (!*pattern)
00230 return 1;
00231 s = str;
00232 while (*s) {
00233 if ((docase ? (*s == *pattern)
00234 : (tolower(*s) == tolower(*pattern)))
00235 && do_match_wild(pattern, s, docase))
00236 return 1;
00237 s++;
00238 }
00239 break;
00240 default:
00241 if (docase ? (*str++ != c) : (tolower(*str++) != tolower(c)))
00242 return 0;
00243 break;
00244 }
00245 }
00246 }
00247
00248
00249
00256 int match_wild(const char *pattern, const char *str)
00257 {
00258 return do_match_wild(pattern, str, 1);
00259 }
00260
00261
00262
00269 int match_wild_nocase(const char *pattern, const char *str)
00270 {
00271 return do_match_wild(pattern, str, 0);
00272 }
00273
00274
00275
00293 int process_numlist(const char *numstr, int *count_ret,
00294 range_callback_t callback, User * u, ...)
00295 {
00296 int n1, n2, i;
00297 int res = 0, retval = 0, count = 0;
00298 va_list args, preserve;
00299
00300 if (!numstr || !*numstr) {
00301 return -1;
00302 }
00303
00304 va_start(args, u);
00305
00306
00307
00308
00309
00310
00311 for (;;) {
00312 n1 = n2 = strtol(numstr, (char **) &numstr, 10);
00313 numstr += strcspn(numstr, "0123456789,-");
00314 if (*numstr == '-') {
00315 numstr++;
00316 numstr += strcspn(numstr, "0123456789,");
00317 if (isdigit(*numstr)) {
00318 n2 = strtol(numstr, (char **) &numstr, 10);
00319 numstr += strcspn(numstr, "0123456789,-");
00320 }
00321 }
00322 for (i = n1; i <= n2 && i >= 0; i++) {
00323 VA_COPY(preserve, args);
00324 res = callback(u, i, preserve);
00325 va_end(preserve);
00326 count++;
00327 if (res < 0)
00328 break;
00329 retval += res;
00330 if (count >= 32767) {
00331 if (count_ret)
00332 *count_ret = count;
00333 return retval;
00334 }
00335 }
00336 if (res < -1)
00337 break;
00338 numstr += strcspn(numstr, ",");
00339 if (*numstr)
00340 numstr++;
00341 else
00342 break;
00343 }
00344 if (count_ret)
00345 *count_ret = count;
00346
00347 va_end(args);
00348
00349 return retval;
00350 }
00351
00352
00353
00365 int dotime(const char *s)
00366 {
00367 int amount;
00368
00369 if (!s || !*s) {
00370 return -1;
00371 }
00372
00373 amount = strtol(s, (char **) &s, 10);
00374 if (*s) {
00375 switch (*s) {
00376 case 's':
00377 return amount;
00378 case 'm':
00379 return amount * 60;
00380 case 'h':
00381 return amount * 3600;
00382 case 'd':
00383 return amount * 86400;
00384 default:
00385 return -1;
00386 }
00387 } else {
00388 return amount;
00389 }
00390 }
00391
00392
00393
00403 char *duration(NickAlias * na, char *buf, int bufsize, time_t seconds)
00404 {
00405 int days = 0, hours = 0, minutes = 0;
00406 int need_comma = 0;
00407
00408 char buf2[64], *end;
00409 char *comma = getstring(na, COMMA_SPACE);
00410
00411
00412 days = seconds / 86400;
00413 seconds -= (days * 86400);
00414 hours = seconds / 3600;
00415 seconds -= (hours * 3600);
00416 minutes = seconds / 60;
00417
00418 if (!days && !hours && !minutes) {
00419 snprintf(buf, bufsize,
00420 getstring(na,
00421 (seconds <=
00422 1 ? DURATION_SECOND : DURATION_SECONDS)),
00423 seconds);
00424 } else {
00425 end = buf;
00426 if (days) {
00427 snprintf(buf2, sizeof(buf2),
00428 getstring(na,
00429 (days == 1 ? DURATION_DAY : DURATION_DAYS)),
00430 days);
00431 end += snprintf(end, bufsize - (end - buf), "%s", buf2);
00432 need_comma = 1;
00433 }
00434 if (hours) {
00435 snprintf(buf2, sizeof(buf2),
00436 getstring(na,
00437 (hours ==
00438 1 ? DURATION_HOUR : DURATION_HOURS)),
00439 hours);
00440 end +=
00441 snprintf(end, bufsize - (end - buf), "%s%s",
00442 (need_comma ? comma : ""), buf2);
00443 need_comma = 1;
00444 }
00445 if (minutes) {
00446 snprintf(buf2, sizeof(buf2),
00447 getstring(na,
00448 (minutes ==
00449 1 ? DURATION_MINUTE : DURATION_MINUTES)),
00450 minutes);
00451 end +=
00452 snprintf(end, bufsize - (end - buf), "%s%s",
00453 (need_comma ? comma : ""), buf2);
00454 need_comma = 1;
00455 }
00456 }
00457
00458 return buf;
00459 }
00460
00461
00462
00471 char *expire_left(NickAlias * na, char *buf, int len, time_t expires)
00472 {
00473 time_t now = time(NULL);
00474
00475 if (!expires) {
00476 strncpy(buf, getstring(na, NO_EXPIRE), len);
00477 } else if (expires <= now) {
00478 strncpy(buf, getstring(na, EXPIRES_SOON), len);
00479 } else {
00480 time_t diff = expires - now + 59;
00481
00482 if (diff >= 86400) {
00483 int days = diff / 86400;
00484 snprintf(buf, len,
00485 getstring(na, (days == 1) ? EXPIRES_1D : EXPIRES_D),
00486 days);
00487 } else {
00488 if (diff <= 3600) {
00489 int minutes = diff / 60;
00490 snprintf(buf, len,
00491 getstring(na,
00492 (minutes ==
00493 1) ? EXPIRES_1M : EXPIRES_M), minutes);
00494 } else {
00495 int hours = diff / 3600, minutes;
00496 diff -= (hours * 3600);
00497 minutes = diff / 60;
00498 snprintf(buf, len,
00499 getstring(na,
00500 ((hours == 1
00501 && minutes ==
00502 1) ? EXPIRES_1H1M : ((hours == 1
00503 && minutes !=
00504 1) ? EXPIRES_1HM
00505 : ((hours != 1
00506 && minutes ==
00507 1) ?
00508 EXPIRES_H1M :
00509 EXPIRES_HM)))),
00510 hours, minutes);
00511 }
00512 }
00513 }
00514
00515 return buf;
00516 }
00517
00518
00519
00520
00530 int doValidHost(const char *host, int type)
00531 {
00532 int idx = 0;
00533 int len = 0;
00534 int sec_len = 0;
00535 int dots = 1;
00536 if (type != 1 && type != 2) {
00537 return 0;
00538 }
00539 if (!host) {
00540 return 0;
00541 }
00542
00543 len = strlen(host);
00544
00545 if (len > HOSTMAX) {
00546 return 0;
00547 }
00548
00549 switch (type) {
00550 case 1:
00551 for (idx = 0; idx < len; idx++) {
00552 if (isdigit(host[idx])) {
00553 if (sec_len < 3) {
00554 sec_len++;
00555 } else {
00556 return 0;
00557 }
00558 } else {
00559 if (idx == 0) {
00560 return 0;
00561 }
00562 if (host[idx] != '.') {
00563 return 0;
00564 }
00565 if (sec_len > 3) {
00566 return 0;
00567 }
00568 sec_len = 0;
00569 dots++;
00570 }
00571 }
00572 if (dots != 4) {
00573 return 0;
00574 }
00575 break;
00576 case 2:
00577 dots = 0;
00578 for (idx = 0; idx < len; idx++) {
00579 if (!isalnum(host[idx])) {
00580 if (idx == 0) {
00581 return 0;
00582 }
00583 if ((host[idx] != '.') && (host[idx] != '-')) {
00584 return 0;
00585 }
00586 if (host[idx] == '.') {
00587 dots++;
00588 }
00589 }
00590 }
00591 if (host[len - 1] == '.') {
00592 return 0;
00593 }
00598 if (dots == 0) {
00599 return 0;
00600 }
00601
00602 break;
00603 }
00604 return 1;
00605 }
00606
00607
00608
00615 int isValidHost(const char *host, int type)
00616 {
00617 int status = 0;
00618 if (type == 3) {
00619 if (!(status = doValidHost(host, 1))) {
00620 status = doValidHost(host, 2);
00621 }
00622 } else {
00623 status = doValidHost(host, type);
00624 }
00625 return status;
00626 }
00627
00628
00629
00635 int isvalidchar(const char c)
00636 {
00637 if (((c >= 'A') && (c <= 'Z')) ||
00638 ((c >= 'a') && (c <= 'z')) ||
00639 ((c >= '0') && (c <= '9')) || (c == '.') || (c == '-'))
00640 return 1;
00641 else
00642 return 0;
00643 }
00644
00645
00646
00647
00655 char *myStrGetToken(const char *str, const char dilim, int token_number)
00656 {
00657 int len, idx, counter = 0, start_pos = 0;
00658 char *substring = NULL;
00659 if (!str) {
00660 return NULL;
00661 }
00662 len = strlen(str);
00663 for (idx = 0; idx <= len; idx++) {
00664 if ((str[idx] == dilim) || (idx == len)) {
00665 if (counter == token_number) {
00666 substring = myStrSubString(str, start_pos, idx);
00667 counter++;
00668 } else {
00669 start_pos = idx + 1;
00670 counter++;
00671 }
00672 }
00673 }
00674 return substring;
00675 }
00676
00677
00678
00686 char *myStrGetOnlyToken(const char *str, const char dilim,
00687 int token_number)
00688 {
00689 int len, idx, counter = 0, start_pos = 0;
00690 char *substring = NULL;
00691 if (!str) {
00692 return NULL;
00693 }
00694 len = strlen(str);
00695 for (idx = 0; idx <= len; idx++) {
00696 if (str[idx] == dilim) {
00697 if (counter == token_number) {
00698 if (str[idx] == '\r')
00699 substring = myStrSubString(str, start_pos, idx - 1);
00700 else
00701 substring = myStrSubString(str, start_pos, idx);
00702 counter++;
00703 } else {
00704 start_pos = idx + 1;
00705 counter++;
00706 }
00707 }
00708 }
00709 return substring;
00710 }
00711
00712
00713
00721 char *myStrGetTokenRemainder(const char *str, const char dilim,
00722 int token_number)
00723 {
00724 int len, idx, counter = 0, start_pos = 0;
00725 char *substring = NULL;
00726 if (!str) {
00727 return NULL;
00728 }
00729 len = strlen(str);
00730
00731 for (idx = 0; idx <= len; idx++) {
00732 if ((str[idx] == dilim) || (idx == len)) {
00733 if (counter == token_number) {
00734 substring = myStrSubString(str, start_pos, len);
00735 counter++;
00736 } else {
00737 start_pos = idx + 1;
00738 counter++;
00739 }
00740 }
00741 }
00742 return substring;
00743 }
00744
00745
00746
00754 char *myStrSubString(const char *src, int start, int end)
00755 {
00756 char *substring = NULL;
00757 int len, idx;
00758 if (!src) {
00759 return NULL;
00760 }
00761 len = strlen(src);
00762 if (((start >= 0) && (end <= len)) && (end > start)) {
00763 substring = (char *) malloc(sizeof(char) * ((end - start) + 1));
00764 for (idx = 0; idx <= end - start; idx++) {
00765 substring[idx] = src[start + idx];
00766 }
00767 substring[end - start] = '\0';
00768 }
00769 return substring;
00770 }
00771
00772
00773
00774 void protocol_debug(char *source, char *cmd, int argc, char **argv)
00775 {
00776 int i;
00777
00778 if (protocoldebug) {
00779 if (source)
00780 alog("debug: Source %s", source);
00781 if (cmd)
00782 alog("debug: Token %s", cmd);
00783 if (argc) {
00784 for (i = 0; i < argc; i++) {
00785 alog("debug: av[%d] = %s", i, argv[i]);
00786 }
00787 } else {
00788 alog("debug: av[0] = NULL");
00789 }
00790 }
00791 return;
00792 }
00793
00794
00795
00801 void doCleanBuffer(char *str)
00802 {
00803 char *in, *out;
00804 char ch;
00805
00806 if (!str) {
00807 return;
00808 }
00809
00810 in = str;
00811 out = str;
00812
00813 while (issp(ch = *in++));
00814 if (ch != '\0')
00815 for (;;) {
00816 *out++ = ch;
00817 ch = *in++;
00818 if (ch == '\0')
00819 break;
00820 if (!issp(ch))
00821 continue;
00822 while (issp(ch = *in++));
00823 if (ch == '\0')
00824 break;
00825 *out++ = ' ';
00826 }
00827 *out = ch;
00828 }
00829
00830
00831
00838 void EnforceQlinedNick(char *nick, char *killer)
00839 {
00840 User *u2;
00841
00842 if ((u2 = finduser(nick))) {
00843 alog("Killed Q-lined nick: %s!%s@%s", u2->nick, u2->username,
00844 u2->host);
00845 kill_user(killer, u2->nick,
00846 "This nick is reserved for Services. Please use a non Q-Lined nick.");
00847 }
00848 }
00849
00850
00851
00858 int nickIsServices(char *tempnick, int bot)
00859 {
00860 int found = 0;
00861 char *s, *nick;
00862
00863 if (!tempnick) {
00864 return found;
00865 }
00866
00867 nick = sstrdup(tempnick);
00868
00869 s = strchr(nick, '@');
00870 if (s) {
00871 *s++ = 0;
00872 if (stricmp(s, ServerName) != 0) {
00873 free(nick);
00874 return found;
00875 }
00876 }
00877
00878 if (s_NickServ && (stricmp(nick, s_NickServ) == 0))
00879 found++;
00880 else if (s_ChanServ && (stricmp(nick, s_ChanServ) == 0))
00881 found++;
00882 else if (s_HostServ && (stricmp(nick, s_HostServ) == 0))
00883 found++;
00884 else if (s_MemoServ && (stricmp(nick, s_MemoServ) == 0))
00885 found++;
00886 else if (s_BotServ && (stricmp(nick, s_BotServ) == 0))
00887 found++;
00888 else if (s_HelpServ && (stricmp(nick, s_HelpServ) == 0))
00889 found++;
00890 else if (s_OperServ && (stricmp(nick, s_OperServ) == 0))
00891 found++;
00892 else if (s_DevNull && (stricmp(nick, s_DevNull) == 0))
00893 found++;
00894 else if (s_GlobalNoticer && (stricmp(nick, s_GlobalNoticer) == 0))
00895 found++;
00896 else if (s_NickServAlias && (stricmp(nick, s_NickServAlias) == 0))
00897 found++;
00898 else if (s_ChanServAlias && (stricmp(nick, s_ChanServAlias) == 0))
00899 found++;
00900 else if (s_MemoServAlias && (stricmp(nick, s_MemoServAlias) == 0))
00901 found++;
00902 else if (s_BotServAlias && (stricmp(nick, s_BotServAlias) == 0))
00903 found++;
00904 else if (s_HelpServAlias && (stricmp(nick, s_HelpServAlias) == 0))
00905 found++;
00906 else if (s_OperServAlias && (stricmp(nick, s_OperServAlias) == 0))
00907 found++;
00908 else if (s_DevNullAlias && (stricmp(nick, s_DevNullAlias) == 0))
00909 found++;
00910 else if (s_HostServAlias && (stricmp(nick, s_HostServAlias) == 0))
00911 found++;
00912 else if (s_GlobalNoticerAlias
00913 && (stricmp(nick, s_GlobalNoticerAlias) == 0))
00914 found++;
00915 else if (s_BotServ && bot) {
00916 BotInfo *bi;
00917 int i;
00918 for (i = 0; i < 256; i++) {
00919 for (bi = botlists[i]; bi; bi = bi->next) {
00920 if (stricmp(nick, bi->nick) == 0) {
00921 found++;
00922 continue;
00923 }
00924 }
00925 }
00926 }
00927
00928
00929 free(nick);
00930
00931 return found;
00932 }
00933
00934
00935
00940 static void arc4_init(void)
00941 {
00942 int n;
00943 for (n = 0; n < 256; n++)
00944 rs.s[n] = n;
00945 rs.i = 0;
00946 rs.j = 0;
00947 }
00948
00949
00950
00957 static void arc4_addrandom(void *dat, int datlen)
00958 {
00959 int n;
00960 u_int8_t si;
00961
00962 rs.i--;
00963 for (n = 0; n < 256; n++) {
00964 rs.i = (rs.i + 1);
00965 si = rs.s[rs.i];
00966 rs.j = (rs.j + si + ((unsigned char *) dat)[n % datlen]);
00967 rs.s[rs.i] = rs.s[rs.j];
00968 rs.s[rs.j] = si;
00969 }
00970 }
00971
00972
00973
00978 void rand_init(void)
00979 {
00980 int n;
00981 #ifndef _WIN32
00982 int fd;
00983 #endif
00984 struct {
00985 #ifdef USE_MYSQL
00986 int sqlrand;
00987 #endif
00988 #ifndef _WIN32
00989 struct timeval nowt;
00990 char rnd[32];
00991 #else
00992 MEMORYSTATUS mstat;
00993 struct _timeb nowt;
00994 #endif
00995 } rdat;
00996
00997 arc4_init();
00998
00999
01000 #ifdef USE_MYSQL
01001 rdat.sqlrand = mysql_rand();
01002 #endif
01003
01004
01005 #ifndef _WIN32
01006
01007 gettimeofday(&rdat.nowt, NULL);
01008
01009 fd = open("/dev/urandom", O_RDONLY);
01010 if (fd) {
01011 n = read(fd, &rdat.rnd, sizeof(rdat.rnd));
01012 close(fd);
01013 }
01014 #else
01015
01016 _ftime(&rdat.nowt);
01017
01018 GlobalMemoryStatus(&rdat.mstat);
01019 #endif
01020
01021 arc4_addrandom(&rdat, sizeof(rdat));
01022 }
01023
01024
01025
01030 void add_entropy_userkeys(void)
01031 {
01032 arc4_addrandom(&UserKey1, sizeof(UserKey1));
01033 arc4_addrandom(&UserKey2, sizeof(UserKey2));
01034 arc4_addrandom(&UserKey3, sizeof(UserKey3));
01035
01036 }
01037
01038
01039
01044 unsigned char getrandom8(void)
01045 {
01046 unsigned char si, sj;
01047
01048 rs.i = (rs.i + 1);
01049 si = rs.s[rs.i];
01050 rs.j = (rs.j + si);
01051 sj = rs.s[rs.j];
01052 rs.s[rs.i] = sj;
01053 rs.s[rs.j] = si;
01054 return (rs.s[(si + sj) & 0xff]);
01055 }
01056
01057
01058
01063 u_int16_t getrandom16(void)
01064 {
01065 u_int16_t val;
01066
01067 val = getrandom8() << 8;
01068 val |= getrandom8();
01069 return val;
01070 }
01071
01072
01073
01078 u_int32_t getrandom32(void)
01079 {
01080 u_int32_t val;
01081
01082 val = getrandom8() << 24;
01083 val |= getrandom8() << 16;
01084 val |= getrandom8() << 8;
01085 val |= getrandom8();
01086 return val;
01087 }
01088
01089
01090
01097 char *send_token(char *token1, char *token2)
01098 {
01099 if (UseTokens && ircd->token && ircdcap->token) {
01100 return token2;
01101 } else {
01102 return token1;
01103 }
01104 }
01105
01106
01107
01114 int myNumToken(const char *str, const char dilim)
01115 {
01116 int len, idx, counter = 0, start_pos = 0;
01117 if (!str) {
01118 return 0;
01119 }
01120 len = strlen(str);
01121 for (idx = 0; idx <= len; idx++) {
01122 if ((str[idx] == dilim) || (idx == len)) {
01123 start_pos = idx + 1;
01124 counter++;
01125 }
01126 }
01127 return counter;
01128 }
01129
01130
01131
01137 char *host_resolve(char *host)
01138 {
01139 struct hostent *hentp = NULL;
01140 uint32 ip = INADDR_NONE;
01141 char ipbuf[16];
01142 char *ipreturn;
01143 struct in_addr addr;
01144
01145 ipreturn = NULL;
01146
01147 hentp = gethostbyname(host);
01148
01149 if (hentp) {
01150 memcpy(&ip, hentp->h_addr, sizeof(hentp->h_length));
01151 addr.s_addr = ip;
01152 ntoa(addr, ipbuf, sizeof(ipbuf));
01153 ipreturn = sstrdup(ipbuf);
01154 if (debug) {
01155 alog("debug: resolved %s to %s", host, ipbuf);
01156 }
01157 return ipreturn;
01158 } else {
01159 return ipreturn;
01160 }
01161 }
01162
01163
01164
01172 char *str_signed(unsigned char *str)
01173 {
01174 char *nstr;
01175
01176 nstr = (char *) str;
01177 while (*str) {
01178 *nstr = (char) *str;
01179 str++;
01180 nstr++;
01181 }
01182
01183 return nstr;
01184 }
01185
01191 char *stripModePrefix(const char *str)
01192 {
01193 if (str && ((*str == '+') || (*str == '-'))) {
01194 return sstrdup(str + 1);
01195 }
01196 return NULL;
01197 }
01198
01199
01200
01201 void ntoa(struct in_addr addr, char *ipaddr, int len)
01202 {
01203 unsigned char *bytes = (unsigned char *) &addr.s_addr;
01204 snprintf(ipaddr, len, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2],
01205 bytes[3]);
01206 }
01207
01214 char **buildStringList(char *src, int *number)
01215 {
01216 char *s;
01217 int i = 0;
01218 char **list = NULL;
01219
01220 if (src) {
01221 s = strtok(src, " ");
01222 do {
01223 if (s) {
01224 i++;
01225 list = realloc(list, sizeof(char *) * i);
01226 list[i - 1] = sstrdup(s);
01227 }
01228 } while ((s = strtok(NULL, " ")));
01229 }
01230 *number = i;
01231 return list;
01232 }
01233
01234
01235
01236
01237
01238
01239
01240
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265 #ifndef HAVE_STRLCAT
01266 size_t strlcat(char *dst, const char *src, size_t siz)
01267 {
01268 char *d = dst;
01269 const char *s = src;
01270 size_t n = siz, dlen;
01271
01272 while (n-- != 0 && *d != '\0')
01273 d++;
01274
01275 dlen = d - dst;
01276 n = siz - dlen;
01277
01278 if (n == 0)
01279 return (dlen + strlen(s));
01280
01281 while (*s != '\0') {
01282 if (n != 1) {
01283 *d++ = *s;
01284 n--;
01285 }
01286
01287 s++;
01288 }
01289
01290 *d = '\0';
01291 return dlen + (s - src);
01292 }
01293 #endif
01294
01295 #ifndef HAVE_STRLCPY
01296 size_t strlcpy(char *dst, const char *src, size_t siz)
01297 {
01298 char *d = dst;
01299 const char *s = src;
01300 size_t n = siz;
01301
01302
01303 if (n != 0 && --n != 0) {
01304 do {
01305 if ((*d++ = *s++) == 0)
01306 break;
01307 }
01308 while (--n != 0);
01309 }
01310
01311
01312 if (n == 0) {
01313 if (siz != 0)
01314 *d = '\0';
01315 while (*s++);
01316 }
01317
01318 return s - src - 1;
01319 }
01320 #endif
01321
01322
01323
01324
01325 #ifdef _WIN32
01326 char *GetWindowsVersion(void)
01327 {
01328 OSVERSIONINFOEX osvi;
01329 BOOL bOsVersionInfoEx;
01330 char buf[BUFSIZE];
01331 char *extra;
01332 char *cputype;
01333 SYSTEM_INFO si;
01334
01335 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
01336 ZeroMemory(&si, sizeof(SYSTEM_INFO));
01337 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
01338
01339 if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) & osvi))) {
01340 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
01341 if (!GetVersionEx((OSVERSIONINFO *) & osvi)) {
01342 return sstrdup("");
01343 }
01344 }
01345 GetSystemInfo(&si);
01346
01347
01348 if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) {
01349 cputype = sstrdup(" 64-bit");
01350 } else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL ) {
01351 cputype = sstrdup(" 32-bit");
01352 } else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 ) {
01353 cputype = sstrdup(" Itanium 64-bit");
01354 } else {
01355 cputype = sstrdup(" ");
01356 }
01357
01358 switch (osvi.dwPlatformId) {
01359
01360 case VER_PLATFORM_WIN32_NT:
01361
01362 if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) {
01363 if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
01364 extra = sstrdup("Enterprise Edition");
01365 } else if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
01366 extra = sstrdup("Datacenter Edition");
01367 } else if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
01368 extra = sstrdup("Home Premium/Basic");
01369 } else {
01370 extra = sstrdup(" ");
01371 }
01372 if (osvi.wProductType & VER_NT_WORKSTATION) {
01373 snprintf(buf, sizeof(buf), "Microsoft Windows Vista %s%s",
01374 cputype, extra);
01375 } else {
01376 snprintf(buf, sizeof(buf), "Microsoft Windows Server 2008 %s%s",
01377 cputype, extra);
01378 }
01379 free(extra);
01380 }
01381
01382 if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
01383 if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
01384 extra = sstrdup("Datacenter Edition");
01385 } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
01386 extra = sstrdup("Enterprise Edition");
01387 } else if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER) {
01388 extra = sstrdup("Compute Cluster Edition");
01389 } else if (osvi.wSuiteMask == VER_SUITE_BLADE) {
01390 extra = sstrdup("Web Edition");
01391 } else {
01392 extra = sstrdup("Standard Edition");
01393 }
01394 if ( osvi.wProductType & VER_NT_WORKSTATION && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
01395 snprintf(buf, sizeof(buf), "Windows XP Professional x64 Edition %s",
01396 extra);
01397 } else {
01398 snprintf(buf, sizeof(buf),
01399 "Microsoft Windows Server 2003 Family %s%s", cputype, extra);
01400 }
01401 free(extra);
01402 }
01403 if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
01404 if (osvi.wSuiteMask & VER_SUITE_EMBEDDEDNT) {
01405 extra = sstrdup("Embedded");
01406 } else if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
01407 extra = sstrdup("Home Edition");
01408 } else {
01409 extra = sstrdup(" ");
01410 }
01411 snprintf(buf, sizeof(buf), "Microsoft Windows XP %s", extra);
01412 free(extra);
01413 }
01414 if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) {
01415 if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
01416 extra = sstrdup("Datacenter Server");
01417 } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
01418 extra = sstrdup("Advanced Server");
01419 } else {
01420 extra = sstrdup("Server");
01421 }
01422 snprintf(buf, sizeof(buf), "Microsoft Windows 2000 %s", extra);
01423 free(extra);
01424 }
01425 if (osvi.dwMajorVersion <= 4) {
01426 if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
01427 extra = sstrdup("Server 4.0, Enterprise Edition");
01428 } else {
01429 extra = sstrdup("Server 4.0");
01430 }
01431 snprintf(buf, sizeof(buf), "Microsoft Windows NT %s", extra);
01432 free(extra);
01433 }
01434 case VER_PLATFORM_WIN32_WINDOWS:
01435 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) {
01436 if (osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B') {
01437 extra = sstrdup("OSR2");
01438 } else {
01439 extra = sstrdup(" ");
01440 }
01441 snprintf(buf, sizeof(buf), "Microsoft Windows 95 %s", extra);
01442 free(extra);
01443 }
01444 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) {
01445 if (osvi.szCSDVersion[1] == 'A') {
01446 extra = sstrdup("SE");
01447 } else {
01448 extra = sstrdup(" ");
01449 }
01450 snprintf(buf, sizeof(buf), "Microsoft Windows 98 %s", extra);
01451 free(extra);
01452 }
01453 if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) {
01454 snprintf(buf, sizeof(buf),
01455 "Microsoft Windows Millennium Edition");
01456 }
01457 }
01458 free(cputype);
01459 return sstrdup(buf);
01460 }
01461
01462 int SupportedWindowsVersion(void)
01463 {
01464 OSVERSIONINFOEX osvi;
01465 BOOL bOsVersionInfoEx;
01466
01467 ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
01468 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
01469
01470 if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) & osvi))) {
01471 osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
01472 if (!GetVersionEx((OSVERSIONINFO *) & osvi)) {
01473 return 0;
01474 }
01475 }
01476
01477 switch (osvi.dwPlatformId) {
01478
01479 case VER_PLATFORM_WIN32_NT:
01480
01481 if (osvi.dwMajorVersion <= 4) {
01482 return 0;
01483 }
01484
01485 return 1;
01486
01487 case VER_PLATFORM_WIN32_WINDOWS:
01488 return 0;
01489 }
01490 return 0;
01491 }
01492
01493 #endif
01494
01495
01496
01497
01498
01504 uint32 cidr_to_netmask(uint16 cidr)
01505 {
01506 if (cidr == 0)
01507 return 0;
01508
01509 return (0xFFFFFFFF - (1 << (32 - cidr)) + 1);
01510 }
01511
01517 uint16 netmask_to_cidr(uint32 mask)
01518 {
01519 int tmp = 0;
01520
01521 while (!(mask & (1 << tmp)) && (tmp < 32))
01522 tmp++;
01523
01524 return (32 - tmp);
01525 }
01526
01527
01528
01534 int str_is_wildcard(const char *str)
01535 {
01536 while (*str) {
01537 if ((*str == '*') || (*str == '?'))
01538 return 1;
01539 str++;
01540 }
01541
01542 return 0;
01543 }
01544
01550 int str_is_pure_wildcard(const char *str)
01551 {
01552 while (*str) {
01553 if (*str != '*')
01554 return 0;
01555 str++;
01556 }
01557
01558 return 1;
01559 }
01560
01561
01562
01568 uint32 str_is_ip(char *str)
01569 {
01570 int i;
01571 int octets[4] = { -1, -1, -1, -1 };
01572 char *s = str;
01573 uint32 ip;
01574
01575 for (i = 0; i < 4; i++) {
01576 octets[i] = strtol(s, &s, 10);
01577
01578 if ((octets[i] < 0) || (octets[i] > 255)
01579 || ((i < 3) && (*s != '.')))
01580 return 0;
01581 if (i < 3)
01582 s++;
01583 }
01584
01585
01586 ip = octets[3];
01587 ip += octets[2] * 256;
01588 ip += octets[1] * 65536;
01589 ip += octets[0] * 16777216;
01590
01591 return ip;
01592 }
01593
01594
01595
01605