Anope IRC Services  Version 1.8
misc.c
Go to the documentation of this file.
1 
2 /* Miscellaneous routines.
3  *
4  * (C) 2003-2014 Anope Team
5  * Contact us at team@anope.org
6  *
7  * Please read COPYING and README for further details.
8  *
9  * Based on the original code of Epona by Lara.
10  * Based on the original code of Services by Andy Church.
11  *
12  *
13  */
14 
15 #include "services.h"
16 #include "language.h"
17 
18 /* Cheaper than isspace() or isblank() */
19 #define issp(c) ((c) == 32)
20 
21 struct arc4_stream {
22  u_int8_t i;
23  u_int8_t j;
24  u_int8_t s[256];
25 } rs;
26 
27 /*************************************************************************/
28 
35 int toupper(char c)
36 {
37  if (islower(c)) {
38  return (unsigned char) c - ('a' - 'A');
39  } else {
40  return (unsigned char) c;
41  }
42 }
43 
44 /*************************************************************************/
45 
52 int tolower(char c)
53 {
54  if (isupper(c)) {
55  return (unsigned char) c + ('a' - 'A');
56  } else {
57  return (unsigned char) c;
58  }
59 }
60 
61 /*************************************************************************/
62 
67 void binary_to_hex(unsigned char *bin, char *hex, int length)
68 {
69  static const char trans[] = "0123456789ABCDEF";
70  int i;
71 
72  for (i = 0; i < length; i++) {
73  hex[i << 1] = trans[bin[i] >> 4];
74  hex[(i << 1) + 1] = trans[bin[i] & 0xf];
75  }
76 
77  hex[i << 1] = '\0';
78 }
79 
80 
81 /*************************************************************************/
82 
91 char *strscpy(char *d, const char *s, size_t len)
92 {
93  char *d_orig = d;
94 
95  if (!len) {
96  return d;
97  }
98  while (--len && (*d++ = *s++));
99  *d = '\0';
100  return d_orig;
101 }
102 
103 /*************************************************************************/
104 
113 char *stristr(char *s1, char *s2)
114 {
115  register char *s = s1, *d = s2;
116 
117  while (*s1) {
118  if (tolower(*s1) == tolower(*d)) {
119  s1++;
120  d++;
121  if (*d == 0)
122  return s;
123  } else {
124  s = ++s1;
125  d = s2;
126  }
127  }
128  return NULL;
129 }
130 
131 /*************************************************************************/
132 
144 char *strnrepl(char *s, int32 size, const char *old, const char *new)
145 {
146  char *ptr = s;
147  int32 left = strlen(s);
148  int32 avail = size - (left + 1);
149  int32 oldlen = strlen(old);
150  int32 newlen = strlen(new);
151  int32 diff = newlen - oldlen;
152 
153  while (left >= oldlen) {
154  if (strncmp(ptr, old, oldlen) != 0) {
155  left--;
156  ptr++;
157  continue;
158  }
159  if (diff > avail)
160  break;
161  if (diff != 0)
162  memmove(ptr + oldlen + diff, ptr + oldlen, left + 1 - oldlen);
163  strncpy(ptr, new, newlen);
164  ptr += newlen;
165  left -= oldlen;
166  }
167  return s;
168 }
169 
170 /*************************************************************************/
171 
180 char *merge_args(int argc, char **argv)
181 {
182  int i;
183  static char s[4096];
184  char *t;
185 
186  t = s;
187  for (i = 0; i < argc; i++)
188  t += snprintf(t, sizeof(s) - (t - s), "%s%s", *argv++,
189  (i < argc - 1) ? " " : "");
190  return s;
191 }
192 
193 /*************************************************************************/
194 
204 static int do_match_wild(const char *pattern, const char *str, int docase)
205 {
206  char c;
207  const char *s;
208 
209  if (!str || !*str || !pattern || !*pattern) {
210  return 0;
211  }
212 
213  /* This WILL eventually terminate: either by *pattern == 0, or by a
214  * trailing '*'. */
215 
216  for (;;) {
217  switch (c = *pattern++) {
218  case 0:
219  if (!*str)
220  return 1;
221  return 0;
222  case '?':
223  if (!*str)
224  return 0;
225  str++;
226  break;
227  case '*':
228  if (!*pattern)
229  return 1; /* trailing '*' matches everything else */
230  s = str;
231  while (*s) {
232  if ((docase ? (*s == *pattern)
233  : (tolower(*s) == tolower(*pattern)))
234  && do_match_wild(pattern, s, docase))
235  return 1;
236  s++;
237  }
238  break;
239  default:
240  if (docase ? (*str++ != c) : (tolower(*str++) != tolower(c)))
241  return 0;
242  break;
243  } /* switch */
244  }
245 }
246 
247 /*************************************************************************/
248 
255 int match_wild(const char *pattern, const char *str)
256 {
257  return do_match_wild(pattern, str, 1);
258 }
259 
260 /*************************************************************************/
261 
268 int match_wild_nocase(const char *pattern, const char *str)
269 {
270  return do_match_wild(pattern, str, 0);
271 }
272 
273 /*************************************************************************/
274 
292 int process_numlist(const char *numstr, int *count_ret,
293  range_callback_t callback, User * u, ...)
294 {
295  int n1, n2, i;
296  int res = 0, retval = 0, count = 0;
297  va_list args, preserve;
298 
299  if (!numstr || !*numstr) {
300  return -1;
301  }
302 
303  va_start(args, u);
304 
305  /*
306  * This algorithm ignores invalid characters, ignores a dash
307  * when it precedes a comma, and ignores everything from the
308  * end of a valid number or range to the next comma or null.
309  */
310  for (;;) {
311  n1 = n2 = strtol(numstr, (char **) &numstr, 10);
312  numstr += strcspn(numstr, "0123456789,-");
313  if (*numstr == '-') {
314  numstr++;
315  numstr += strcspn(numstr, "0123456789,");
316  if (isdigit(*numstr)) {
317  n2 = strtol(numstr, (char **) &numstr, 10);
318  numstr += strcspn(numstr, "0123456789,-");
319  }
320  }
321  for (i = n1; i <= n2 && i >= 0; i++) {
322  VA_COPY(preserve, args);
323  res = callback(u, i, preserve);
324  va_end(preserve);
325  count++;
326  if (res < 0)
327  break;
328  retval += res;
329  if (count >= 32767) {
330  if (count_ret)
331  *count_ret = count;
332  return retval;
333  }
334  }
335  if (res < -1)
336  break;
337  numstr += strcspn(numstr, ",");
338  if (*numstr)
339  numstr++;
340  else
341  break;
342  }
343  if (count_ret)
344  *count_ret = count;
345 
346  va_end(args);
347 
348  return retval;
349 }
350 
351 /*************************************************************************/
352 
364 int dotime(const char *s)
365 {
366  int amount;
367 
368  if (!s || !*s) {
369  return -1;
370  }
371 
372  amount = strtol(s, (char **) &s, 10);
373  if (*s) {
374  switch (*s) {
375  case 's':
376  return amount;
377  case 'm':
378  return amount * 60;
379  case 'h':
380  return amount * 3600;
381  case 'd':
382  return amount * 86400;
383  default:
384  return -1;
385  }
386  } else {
387  return amount;
388  }
389 }
390 
391 /*************************************************************************/
392 
402 char *duration(NickAlias * na, char *buf, int bufsize, time_t seconds)
403 {
404  int days = 0, hours = 0, minutes = 0;
405  int need_comma = 0;
406 
407  char buf2[64], *end;
408  char *comma = getstring(na, COMMA_SPACE);
409 
410  /* We first calculate everything */
411  days = seconds / 86400;
412  seconds -= (days * 86400);
413  hours = seconds / 3600;
414  seconds -= (hours * 3600);
415  minutes = seconds / 60;
416 
417  if (!days && !hours && !minutes) {
418  snprintf(buf, bufsize,
419  getstring(na,
420  (seconds <=
421  1 ? DURATION_SECOND : DURATION_SECONDS)),
422  seconds);
423  } else {
424  end = buf;
425  if (days) {
426  snprintf(buf2, sizeof(buf2),
427  getstring(na,
428  (days == 1 ? DURATION_DAY : DURATION_DAYS)),
429  days);
430  end += snprintf(end, bufsize - (end - buf), "%s", buf2);
431  need_comma = 1;
432  }
433  if (hours) {
434  snprintf(buf2, sizeof(buf2),
435  getstring(na,
436  (hours ==
437  1 ? DURATION_HOUR : DURATION_HOURS)),
438  hours);
439  end +=
440  snprintf(end, bufsize - (end - buf), "%s%s",
441  (need_comma ? comma : ""), buf2);
442  need_comma = 1;
443  }
444  if (minutes) {
445  snprintf(buf2, sizeof(buf2),
446  getstring(na,
447  (minutes ==
448  1 ? DURATION_MINUTE : DURATION_MINUTES)),
449  minutes);
450  end +=
451  snprintf(end, bufsize - (end - buf), "%s%s",
452  (need_comma ? comma : ""), buf2);
453  need_comma = 1;
454  }
455  }
456 
457  return buf;
458 }
459 
460 /*************************************************************************/
461 
470 char *expire_left(NickAlias * na, char *buf, int len, time_t expires)
471 {
472  time_t now = time(NULL);
473 
474  if (!expires) {
475  strncpy(buf, getstring(na, NO_EXPIRE), len);
476  } else if (expires <= now) {
477  strncpy(buf, getstring(na, EXPIRES_SOON), len);
478  } else {
479  time_t diff = expires - now + 59;
480 
481  if (diff >= 86400) {
482  int days = diff / 86400;
483  snprintf(buf, len,
484  getstring(na, (days == 1) ? EXPIRES_1D : EXPIRES_D),
485  days);
486  } else {
487  if (diff <= 3600) {
488  int minutes = diff / 60;
489  snprintf(buf, len,
490  getstring(na,
491  (minutes ==
492  1) ? EXPIRES_1M : EXPIRES_M), minutes);
493  } else {
494  int hours = diff / 3600, minutes;
495  diff -= (hours * 3600);
496  minutes = diff / 60;
497  snprintf(buf, len,
498  getstring(na,
499  ((hours == 1
500  && minutes ==
501  1) ? EXPIRES_1H1M : ((hours == 1
502  && minutes !=
503  1) ? EXPIRES_1HM
504  : ((hours != 1
505  && minutes ==
506  1) ?
507  EXPIRES_H1M :
508  EXPIRES_HM)))),
509  hours, minutes);
510  }
511  }
512  }
513 
514  return buf;
515 }
516 
517 
518 /*************************************************************************/
519 
529 int doValidHost(const char *host, int type)
530 {
531  int idx = 0;
532  int len = 0;
533  int sec_len = 0;
534  int dots = 1;
535  if (type != 1 && type != 2) {
536  return 0;
537  }
538  if (!host) {
539  return 0;
540  }
541 
542  len = strlen(host);
543 
544  if (len > HOSTMAX) {
545  return 0;
546  }
547 
548  switch (type) {
549  case 1:
550  for (idx = 0; idx < len; idx++) {
551  if (isdigit(host[idx])) {
552  if (sec_len < 3) {
553  sec_len++;
554  } else {
555  return 0;
556  }
557  } else {
558  if (idx == 0) {
559  return 0;
560  } /* cant start with a non-digit */
561  if (host[idx] != '.') {
562  return 0;
563  } /* only . is a valid non-digit */
564  if (sec_len > 3) {
565  return 0;
566  } /* sections cant be more than 3 digits */
567  sec_len = 0;
568  dots++;
569  }
570  }
571  if (dots != 4) {
572  return 0;
573  }
574  break;
575  case 2:
576  dots = 0;
577  for (idx = 0; idx < len; idx++) {
578  if (!isalnum(host[idx])) {
579  if (idx == 0) {
580  return 0;
581  }
582  if ((host[idx] != '.') && (host[idx] != '-')) {
583  return 0;
584  }
585  if (host[idx] == '.') {
586  dots++;
587  }
588  }
589  }
590  if (host[len - 1] == '.') {
591  return 0;
592  }
597  if (dots == 0) {
598  return 0;
599  }
600 
601  break;
602  }
603  return 1;
604 }
605 
606 /*************************************************************************/
607 
614 int isValidHost(const char *host, int type)
615 {
616  int status = 0;
617  if (type == 3) {
618  if (!(status = doValidHost(host, 1))) {
619  status = doValidHost(host, 2);
620  }
621  } else {
622  status = doValidHost(host, type);
623  }
624  return status;
625 }
626 
627 /*************************************************************************/
628 
634 int isvalidchar(const char c)
635 {
636  if (((c >= 'A') && (c <= 'Z')) ||
637  ((c >= 'a') && (c <= 'z')) ||
638  ((c >= '0') && (c <= '9')) || (c == '.') || (c == '-'))
639  return 1;
640  else
641  return 0;
642 }
643 
644 
645 /*************************************************************************/
646 
654 char *myStrGetToken(const char *str, const char dilim, int token_number)
655 {
656  int len, idx, counter = 0, start_pos = 0;
657  char *substring = NULL;
658  if (!str) {
659  return NULL;
660  }
661  len = strlen(str);
662  for (idx = 0; idx <= len; idx++) {
663  if ((str[idx] == dilim) || (idx == len)) {
664  if (counter == token_number) {
665  substring = myStrSubString(str, start_pos, idx);
666  counter++;
667  } else {
668  start_pos = idx + 1;
669  counter++;
670  }
671  }
672  }
673  return substring;
674 }
675 
676 /*************************************************************************/
677 
685 char *myStrGetOnlyToken(const char *str, const char dilim,
686  int token_number)
687 {
688  int len, idx, counter = 0, start_pos = 0;
689  char *substring = NULL;
690  if (!str) {
691  return NULL;
692  }
693  len = strlen(str);
694  for (idx = 0; idx <= len; idx++) {
695  if (str[idx] == dilim) {
696  if (counter == token_number) {
697  if (str[idx] == '\r')
698  substring = myStrSubString(str, start_pos, idx - 1);
699  else
700  substring = myStrSubString(str, start_pos, idx);
701  counter++;
702  } else {
703  start_pos = idx + 1;
704  counter++;
705  }
706  }
707  }
708  return substring;
709 }
710 
711 /*************************************************************************/
712 
720 char *myStrGetTokenRemainder(const char *str, const char dilim,
721  int token_number)
722 {
723  int len, idx, counter = 0, start_pos = 0;
724  char *substring = NULL;
725  if (!str) {
726  return NULL;
727  }
728  len = strlen(str);
729 
730  for (idx = 0; idx <= len; idx++) {
731  if ((str[idx] == dilim) || (idx == len)) {
732  if (counter == token_number) {
733  substring = myStrSubString(str, start_pos, len);
734  counter++;
735  } else {
736  start_pos = idx + 1;
737  counter++;
738  }
739  }
740  }
741  return substring;
742 }
743 
744 /*************************************************************************/
745 
753 char *myStrSubString(const char *src, int start, int end)
754 {
755  char *substring = NULL;
756  int len, idx;
757  if (!src) {
758  return NULL;
759  }
760  len = strlen(src);
761  if (((start >= 0) && (end <= len)) && (end > start)) {
762  substring = (char *) malloc(sizeof(char) * ((end - start) + 1));
763  for (idx = 0; idx <= end - start; idx++) {
764  substring[idx] = src[start + idx];
765  }
766  substring[end - start] = '\0';
767  }
768  return substring;
769 }
770 
771 /*************************************************************************/
772 
773 void protocol_debug(char *source, char *cmd, int argc, char **argv)
774 {
775  int i;
776 
777  if (protocoldebug) {
778  if (source)
779  alog("debug: Source %s", source);
780  if (cmd)
781  alog("debug: Token %s", cmd);
782  if (argc) {
783  for (i = 0; i < argc; i++) {
784  alog("debug: av[%d] = %s", i, argv[i]);
785  }
786  } else {
787  alog("debug: av[0] = NULL");
788  }
789  }
790  return;
791 }
792 
793 /*************************************************************************/
794 
800 void doCleanBuffer(char *str)
801 {
802  char *in, *out;
803  char ch;
804 
805  if (!str) {
806  return;
807  }
808 
809  in = str;
810  out = str;
811 
812  while (issp(ch = *in++));
813  if (ch != '\0')
814  for (;;) {
815  *out++ = ch;
816  ch = *in++;
817  if (ch == '\0')
818  break;
819  if (!issp(ch))
820  continue;
821  while (issp(ch = *in++));
822  if (ch == '\0')
823  break;
824  *out++ = ' ';
825  }
826  *out = ch; /* == '\0' */
827 }
828 
829 /*************************************************************************/
830 
837 void EnforceQlinedNick(char *nick, char *killer)
838 {
839  User *u2;
840 
841  if ((u2 = finduser(nick))) {
842  alog("Killed Q-lined nick: %s!%s@%s", u2->nick, u2->username,
843  u2->host);
844  kill_user(killer, u2->nick,
845  "This nick is reserved for Services. Please use a non Q-Lined nick.");
846  }
847 }
848 
849 /*************************************************************************/
850 
857 int nickIsServices(char *tempnick, int bot)
858 {
859  int found = 0;
860  char *s, *nick;
861 
862  if (!tempnick) {
863  return found;
864  }
865 
866  nick = sstrdup(tempnick);
867 
868  s = strchr(nick, '@');
869  if (s) {
870  *s++ = 0;
871  if (stricmp(s, ServerName) != 0) {
872  free(nick);
873  return found;
874  }
875  }
876 
877  if (s_NickServ && (stricmp(nick, s_NickServ) == 0))
878  found++;
879  else if (s_ChanServ && (stricmp(nick, s_ChanServ) == 0))
880  found++;
881  else if (s_HostServ && (stricmp(nick, s_HostServ) == 0))
882  found++;
883  else if (s_MemoServ && (stricmp(nick, s_MemoServ) == 0))
884  found++;
885  else if (s_BotServ && (stricmp(nick, s_BotServ) == 0))
886  found++;
887  else if (s_HelpServ && (stricmp(nick, s_HelpServ) == 0))
888  found++;
889  else if (s_OperServ && (stricmp(nick, s_OperServ) == 0))
890  found++;
891  else if (s_DevNull && (stricmp(nick, s_DevNull) == 0))
892  found++;
893  else if (s_GlobalNoticer && (stricmp(nick, s_GlobalNoticer) == 0))
894  found++;
895  else if (s_NickServAlias && (stricmp(nick, s_NickServAlias) == 0))
896  found++;
897  else if (s_ChanServAlias && (stricmp(nick, s_ChanServAlias) == 0))
898  found++;
899  else if (s_MemoServAlias && (stricmp(nick, s_MemoServAlias) == 0))
900  found++;
901  else if (s_BotServAlias && (stricmp(nick, s_BotServAlias) == 0))
902  found++;
903  else if (s_HelpServAlias && (stricmp(nick, s_HelpServAlias) == 0))
904  found++;
905  else if (s_OperServAlias && (stricmp(nick, s_OperServAlias) == 0))
906  found++;
907  else if (s_DevNullAlias && (stricmp(nick, s_DevNullAlias) == 0))
908  found++;
909  else if (s_HostServAlias && (stricmp(nick, s_HostServAlias) == 0))
910  found++;
911  else if (s_GlobalNoticerAlias
912  && (stricmp(nick, s_GlobalNoticerAlias) == 0))
913  found++;
914  else if (s_BotServ && bot) {
915  BotInfo *bi;
916  int i;
917  for (i = 0; i < 256; i++) {
918  for (bi = botlists[i]; bi; bi = bi->next) {
919  if (stricmp(nick, bi->nick) == 0) {
920  found++;
921  continue;
922  }
923  }
924  }
925  }
926 
927  /* Somehow, something tells me we should free this :) -GD */
928  free(nick);
929 
930  return found;
931 }
932 
933 /*************************************************************************/
934 
939 static void arc4_init(void)
940 {
941  int n;
942  for (n = 0; n < 256; n++)
943  rs.s[n] = n;
944  rs.i = 0;
945  rs.j = 0;
946 }
947 
948 /*************************************************************************/
949 
956 static void arc4_addrandom(void *dat, int datlen)
957 {
958  int n;
959  u_int8_t si;
960 
961  rs.i--;
962  for (n = 0; n < 256; n++) {
963  rs.i = (rs.i + 1);
964  si = rs.s[rs.i];
965  rs.j = (rs.j + si + ((unsigned char *) dat)[n % datlen]);
966  rs.s[rs.i] = rs.s[rs.j];
967  rs.s[rs.j] = si;
968  }
969 }
970 
971 /*************************************************************************/
972 
977 void rand_init(void)
978 {
979 #ifndef _WIN32
980  int fd;
981 #endif
982  struct {
983 #ifdef USE_MYSQL
984  int sqlrand;
985 #endif
986 #ifndef _WIN32
987  struct timeval nowt; /* time */
988  char rnd[32]; /* /dev/urandom */
989 #else
990  MEMORYSTATUS mstat; /* memory status */
991  struct _timeb nowt; /* time */
992 #endif
993  } rdat;
994 
995  arc4_init();
996 
997  /* Grab "random" MYSQL data */
998 #ifdef USE_MYSQL
999  rdat.sqlrand = mysql_rand();
1000 #endif
1001 
1002  /* Grab OS specific "random" data */
1003 #ifndef _WIN32
1004  /* unix/bsd: time */
1005  gettimeofday(&rdat.nowt, NULL);
1006  /* unix/bsd: /dev/urandom */
1007  fd = open("/dev/urandom", O_RDONLY);
1008  if (fd) {
1009  read(fd, &rdat.rnd, sizeof(rdat.rnd));
1010  close(fd);
1011  }
1012 #else
1013  /* win32: time */
1014  _ftime(&rdat.nowt);
1015  /* win32: memory status */
1016  GlobalMemoryStatus(&rdat.mstat);
1017 #endif
1018 
1019  arc4_addrandom(&rdat, sizeof(rdat));
1020 }
1021 
1022 /*************************************************************************/
1023 
1029 {
1030  arc4_addrandom(&UserKey1, sizeof(UserKey1));
1031  arc4_addrandom(&UserKey2, sizeof(UserKey2));
1032  arc4_addrandom(&UserKey3, sizeof(UserKey3));
1033  /* UserKey3 is also used in mysql_rand() */
1034 }
1035 
1036 /*************************************************************************/
1037 
1042 unsigned char getrandom8(void)
1043 {
1044  unsigned char si, sj;
1045 
1046  rs.i = (rs.i + 1);
1047  si = rs.s[rs.i];
1048  rs.j = (rs.j + si);
1049  sj = rs.s[rs.j];
1050  rs.s[rs.i] = sj;
1051  rs.s[rs.j] = si;
1052  return (rs.s[(si + sj) & 0xff]);
1053 }
1054 
1055 /*************************************************************************/
1056 
1061 u_int16_t getrandom16(void)
1062 {
1063  u_int16_t val;
1064 
1065  val = getrandom8() << 8;
1066  val |= getrandom8();
1067  return val;
1068 }
1069 
1070 /*************************************************************************/
1071 
1076 u_int32_t getrandom32(void)
1077 {
1078  u_int32_t val;
1079 
1080  val = getrandom8() << 24;
1081  val |= getrandom8() << 16;
1082  val |= getrandom8() << 8;
1083  val |= getrandom8();
1084  return val;
1085 }
1086 
1087 /*************************************************************************/
1088 
1095 char *send_token(char *token1, char *token2)
1096 {
1097  if (UseTokens && ircd->token && ircdcap->token) {
1098  return token2;
1099  } else {
1100  return token1;
1101  }
1102 }
1103 
1104 /*************************************************************************/
1105 
1112 int myNumToken(const char *str, const char dilim)
1113 {
1114  int len, idx, counter = 0;
1115  if (!str) {
1116  return 0;
1117  }
1118  len = strlen(str);
1119  for (idx = 0; idx <= len; idx++) {
1120  if ((str[idx] == dilim) || (idx == len)) {
1121  counter++;
1122  }
1123  }
1124  return counter;
1125 }
1126 
1127 /*************************************************************************/
1128 
1134 char *host_resolve(char *host)
1135 {
1136  struct hostent *hentp = NULL;
1137  uint32 ip = INADDR_NONE;
1138  char ipbuf[16];
1139  char *ipreturn;
1140  struct in_addr addr;
1141 
1142  ipreturn = NULL;
1143 
1144  hentp = gethostbyname(host);
1145 
1146  if (hentp) {
1147  memcpy(&ip, hentp->h_addr, sizeof(hentp->h_length));
1148  addr.s_addr = ip;
1149  ntoa(addr, ipbuf, sizeof(ipbuf));
1150  ipreturn = sstrdup(ipbuf);
1151  if (debug) {
1152  alog("debug: resolved %s to %s", host, ipbuf);
1153  }
1154  return ipreturn;
1155  } else {
1156  return ipreturn;
1157  }
1158 }
1159 
1160 /*************************************************************************/
1161 
1169 char *str_signed(unsigned char *str)
1170 {
1171  char *nstr;
1172 
1173  nstr = (char *) str;
1174  while (*str) {
1175  *nstr = (char) *str;
1176  str++;
1177  nstr++;
1178  }
1179 
1180  return nstr;
1181 }
1182 
1188 char *stripModePrefix(const char *str)
1189 {
1190  if (str && ((*str == '+') || (*str == '-'))) {
1191  return sstrdup(str + 1);
1192  }
1193  return NULL;
1194 }
1195 
1196 /* Equivalent to inet_ntoa */
1197 
1198 void ntoa(struct in_addr addr, char *ipaddr, int len)
1199 {
1200  unsigned char *bytes = (unsigned char *) &addr.s_addr;
1201  snprintf(ipaddr, len, "%u.%u.%u.%u", bytes[0], bytes[1], bytes[2],
1202  bytes[3]);
1203 }
1204 
1211 char **buildStringList(char *src, int *number)
1212 {
1213  char *s;
1214  int i = 0;
1215  char **list = NULL;
1216 
1217  if (src) {
1218  s = strtok(src, " ");
1219  do {
1220  if (s) {
1221  i++;
1222  list = srealloc(list, sizeof(char *) * i);
1223  list[i - 1] = sstrdup(s);
1224  }
1225  } while ((s = strtok(NULL, " ")));
1226  }
1227  *number = i; /* always zero it, even if we have no setters */
1228  return list;
1229 }
1230 
1231 /*
1232 * strlcat and strlcpy were ripped from openssh 2.5.1p2
1233 * They had the following Copyright info:
1234 *
1235 *
1236 * Copyright (c) 1998 Todd C. Miller <Todd.Miller@courtesan.com>
1237 * All rights reserved.
1238 *
1239 * Redistribution and use in source and binary forms, with or without
1240 * modification, are permitted provided that the following conditions
1241 * are met:
1242 * 1. Redistributions of source code must retain the above copyright
1243 * notice, this list of conditions and the following disclaimer.
1244 * 2. Redistributions in binary form must reproduce the above copyright
1245 * notice, this list of conditions and the following disclaimer in the
1246 * documentation and/or other materials provided with the distribution.
1247 * 3. The name of the author may not be used to endorse or promote products
1248 * derived from this software without specific prior written permission.
1249 *
1250 * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
1251 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
1252 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
1253 * THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
1254 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
1255 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
1256 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
1257 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
1258 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
1259 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
1260 */
1261 
1262 #ifndef HAVE_STRLCAT
1263 size_t strlcat(char *dst, const char *src, size_t siz)
1264 {
1265  char *d = dst;
1266  const char *s = src;
1267  size_t n = siz, dlen;
1268 
1269  while (n-- != 0 && *d != '\0')
1270  d++;
1271 
1272  dlen = d - dst;
1273  n = siz - dlen;
1274 
1275  if (n == 0)
1276  return (dlen + strlen(s));
1277 
1278  while (*s != '\0') {
1279  if (n != 1) {
1280  *d++ = *s;
1281  n--;
1282  }
1283 
1284  s++;
1285  }
1286 
1287  *d = '\0';
1288  return dlen + (s - src); /* count does not include NUL */
1289 }
1290 #endif
1291 
1292 #ifndef HAVE_STRLCPY
1293 size_t strlcpy(char *dst, const char *src, size_t siz)
1294 {
1295  char *d = dst;
1296  const char *s = src;
1297  size_t n = siz;
1298 
1299  /* Copy as many bytes as will fit */
1300  if (n != 0 && --n != 0) {
1301  do {
1302  if ((*d++ = *s++) == 0)
1303  break;
1304  }
1305  while (--n != 0);
1306  }
1307 
1308  /* Not enough room in dst, add NUL and traverse rest of src */
1309  if (n == 0) {
1310  if (siz != 0)
1311  *d = '\0'; /* NUL-terminate dst */
1312  while (*s++);
1313  }
1314 
1315  return s - src - 1; /* count does not include NUL */
1316 }
1317 #endif
1318 
1319 
1320 
1321 
1322 #ifdef _WIN32
1323 char *GetWindowsVersion(void)
1324 {
1325  OSVERSIONINFOEX osvi;
1326  BOOL bOsVersionInfoEx;
1327  char buf[BUFSIZE];
1328  char *extra;
1329  char *cputype;
1330  SYSTEM_INFO si;
1331 
1332  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
1333  ZeroMemory(&si, sizeof(SYSTEM_INFO));
1334  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1335 
1336  if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) & osvi))) {
1337  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1338  if (!GetVersionEx((OSVERSIONINFO *) & osvi)) {
1339  return sstrdup("");
1340  }
1341  }
1342  GetSystemInfo(&si);
1343 
1344  /* Determine CPU type 32 or 64 */
1345  if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 ) {
1346  cputype = sstrdup(" 64-bit");
1347  } else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL ) {
1348  cputype = sstrdup(" 32-bit");
1349  } else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 ) {
1350  cputype = sstrdup(" Itanium 64-bit");
1351  } else {
1352  cputype = sstrdup(" ");
1353  }
1354 
1355  switch (osvi.dwPlatformId) {
1356  /* test for the Windows NT product family. */
1357  case VER_PLATFORM_WIN32_NT:
1358  /* Windows Vista or Windows Server 2008 */
1359  if (osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0) {
1360  if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
1361  extra = sstrdup("Enterprise Edition");
1362  } else if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
1363  extra = sstrdup("Datacenter Edition");
1364  } else if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
1365  extra = sstrdup("Home Premium/Basic");
1366  } else {
1367  extra = sstrdup(" ");
1368  }
1369  if (osvi.wProductType & VER_NT_WORKSTATION) {
1370  snprintf(buf, sizeof(buf), "Microsoft Windows Vista %s%s",
1371  cputype, extra);
1372  } else {
1373  snprintf(buf, sizeof(buf), "Microsoft Windows Server 2008 %s%s",
1374  cputype, extra);
1375  }
1376  free(extra);
1377  }
1378  /* Windows 2003 or Windows XP Pro 64 */
1379  if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2) {
1380  if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
1381  extra = sstrdup("Datacenter Edition");
1382  } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
1383  extra = sstrdup("Enterprise Edition");
1384  } else if (osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER) {
1385  extra = sstrdup("Compute Cluster Edition");
1386  } else if (osvi.wSuiteMask == VER_SUITE_BLADE) {
1387  extra = sstrdup("Web Edition");
1388  } else {
1389  extra = sstrdup("Standard Edition");
1390  }
1391  if ( osvi.wProductType & VER_NT_WORKSTATION && si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) {
1392  snprintf(buf, sizeof(buf), "Windows XP Professional x64 Edition %s",
1393  extra);
1394  } else {
1395  snprintf(buf, sizeof(buf),
1396  "Microsoft Windows Server 2003 Family %s%s", cputype, extra);
1397  }
1398  free(extra);
1399  }
1400  if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1) {
1401  if (osvi.wSuiteMask & VER_SUITE_EMBEDDEDNT) {
1402  extra = sstrdup("Embedded");
1403  } else if (osvi.wSuiteMask & VER_SUITE_PERSONAL) {
1404  extra = sstrdup("Home Edition");
1405  } else {
1406  extra = sstrdup(" ");
1407  }
1408  snprintf(buf, sizeof(buf), "Microsoft Windows XP %s", extra);
1409  free(extra);
1410  }
1411  if (osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0) {
1412  if (osvi.wSuiteMask & VER_SUITE_DATACENTER) {
1413  extra = sstrdup("Datacenter Server");
1414  } else if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
1415  extra = sstrdup("Advanced Server");
1416  } else {
1417  extra = sstrdup("Server");
1418  }
1419  snprintf(buf, sizeof(buf), "Microsoft Windows 2000 %s", extra);
1420  free(extra);
1421  }
1422  if (osvi.dwMajorVersion <= 4) {
1423  if (osvi.wSuiteMask & VER_SUITE_ENTERPRISE) {
1424  extra = sstrdup("Server 4.0, Enterprise Edition");
1425  } else {
1426  extra = sstrdup("Server 4.0");
1427  }
1428  snprintf(buf, sizeof(buf), "Microsoft Windows NT %s", extra);
1429  free(extra);
1430  }
1431  case VER_PLATFORM_WIN32_WINDOWS:
1432  if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 0) {
1433  if (osvi.szCSDVersion[1] == 'C' || osvi.szCSDVersion[1] == 'B') {
1434  extra = sstrdup("OSR2");
1435  } else {
1436  extra = sstrdup(" ");
1437  }
1438  snprintf(buf, sizeof(buf), "Microsoft Windows 95 %s", extra);
1439  free(extra);
1440  }
1441  if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 10) {
1442  if (osvi.szCSDVersion[1] == 'A') {
1443  extra = sstrdup("SE");
1444  } else {
1445  extra = sstrdup(" ");
1446  }
1447  snprintf(buf, sizeof(buf), "Microsoft Windows 98 %s", extra);
1448  free(extra);
1449  }
1450  if (osvi.dwMajorVersion == 4 && osvi.dwMinorVersion == 90) {
1451  snprintf(buf, sizeof(buf),
1452  "Microsoft Windows Millennium Edition");
1453  }
1454  }
1455  free(cputype);
1456  return sstrdup(buf);
1457 }
1458 
1459 int SupportedWindowsVersion(void)
1460 {
1461  OSVERSIONINFOEX osvi;
1462  BOOL bOsVersionInfoEx;
1463 
1464  ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));
1465  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
1466 
1467  if (!(bOsVersionInfoEx = GetVersionEx((OSVERSIONINFO *) & osvi))) {
1468  osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
1469  if (!GetVersionEx((OSVERSIONINFO *) & osvi)) {
1470  return 0;
1471  }
1472  }
1473 
1474  switch (osvi.dwPlatformId) {
1475  /* test for the Windows NT product family. */
1476  case VER_PLATFORM_WIN32_NT:
1477  /* win nt4 */
1478  if (osvi.dwMajorVersion <= 4) {
1479  return 0;
1480  }
1481  /* the rest */
1482  return 1;
1483  /* win95 win98 winME */
1484  case VER_PLATFORM_WIN32_WINDOWS:
1485  return 0;
1486  }
1487  return 0;
1488 }
1489 
1490 #endif
1491 
1492 
1493 /*************************************************************************/
1494 /* This 2 functions were originally found in Bahamut */
1495 
1502 {
1503  if (cidr == 0)
1504  return 0;
1505 
1506  return (0xFFFFFFFF - (1 << (32 - cidr)) + 1);
1507 }
1508 
1515 {
1516  int tmp = 0;
1517 
1518  while (!(mask & (1 << tmp)) && (tmp < 32))
1519  tmp++;
1520 
1521  return (32 - tmp);
1522 }
1523 
1524 /*************************************************************************/
1525 
1531 int str_is_wildcard(const char *str)
1532 {
1533  while (*str) {
1534  if ((*str == '*') || (*str == '?'))
1535  return 1;
1536  str++;
1537  }
1538 
1539  return 0;
1540 }
1541 
1547 int str_is_pure_wildcard(const char *str)
1548 {
1549  while (*str) {
1550  if (*str != '*')
1551  return 0;
1552  str++;
1553  }
1554 
1555  return 1;
1556 }
1557 
1558 /*************************************************************************/
1559 
1565 uint32 str_is_ip(char *str)
1566 {
1567  int i;
1568  int octets[4] = { -1, -1, -1, -1 };
1569  char *s = str;
1570  uint32 ip;
1571 
1572  for (i = 0; i < 4; i++) {
1573  octets[i] = strtol(s, &s, 10);
1574  /* Bail out if the octet is invalid or wrongly terminated */
1575  if ((octets[i] < 0) || (octets[i] > 255)
1576  || ((i < 3) && (*s != '.')))
1577  return 0;
1578  if (i < 3)
1579  s++;
1580  }
1581 
1582  /* Fill the IP - the dirty way */
1583  ip = octets[3];
1584  ip += octets[2] * 256;
1585  ip += octets[1] * 65536;
1586  ip += octets[0] * 16777216;
1587 
1588  return ip;
1589 }
1590 
1591 /*************************************************************************/
1592 
1602 int str_is_cidr(char *str, uint32 * ip, uint32 * mask, char **host)
1603 {
1604  int i;
1605  int octets[4] = { -1, -1, -1, -1 };
1606  char *s = str;
1607  char buf[512];
1608  uint16 cidr;
1609 
1610  for (i = 0; i < 4; i++) {
1611  octets[i] = strtol(s, &s, 10);
1612  /* Bail out if the octet is invalid or wrongly terminated */
1613  if ((octets[i] < 0) || (octets[i] > 255)
1614  || ((i < 3) && (*s != '.')))
1615  return 0;
1616  if (i < 3)
1617  s++;
1618  }
1619 
1620  /* Fill the IP - the dirty way */
1621  *ip = octets[3];
1622  *ip += octets[2] * 256;
1623  *ip += octets[1] * 65536;
1624  *ip += octets[0] * 16777216;
1625 
1626  if (*s == '/') {
1627  s++;
1628  /* There's a CIDR mask here! */
1629  cidr = strtol(s, &s, 10);
1630  /* Bail out if the CIDR is invalid or the string isn't done yet */
1631  if ((cidr > 32) || (*s))
1632  return 0;
1633  } else {
1634  /* No CIDR mask here - use 32 so the whole ip will be matched */
1635  cidr = 32;
1636  }
1637 
1638  *mask = cidr_to_netmask(cidr);
1639  /* Apply the mask to avoid 255.255.255.255/8 bans */
1640  *ip &= *mask;
1641 
1642  /* Refill the octets to fill the host */
1643  octets[0] = (*ip & 0xFF000000) / 16777216;
1644  octets[1] = (*ip & 0x00FF0000) / 65536;
1645  octets[2] = (*ip & 0x0000FF00) / 256;
1646  octets[3] = (*ip & 0x000000FF);
1647 
1648  if (cidr == 32)
1649  snprintf(buf, 512, "%d.%d.%d.%d", octets[0], octets[1], octets[2],
1650  octets[3]);
1651  else
1652  snprintf(buf, 512, "%d.%d.%d.%d/%d", octets[0], octets[1],
1653  octets[2], octets[3], cidr);
1654 
1655  *host = sstrdup(buf);
1656 
1657  return 1;
1658 }
1659 
1660 /* EOF */
char * myStrSubString(const char *src, int start, int end)
Definition: misc.c:753
int process_numlist(const char *numstr, int *count_ret, range_callback_t callback, User *u,...)
Definition: misc.c:292
#define VA_COPY(DEST, SRC)
Definition: services.h:153
int isvalidchar(const char c)
Definition: misc.c:634
char * stristr(char *s1, char *s2)
Definition: misc.c:113
u_int16_t getrandom16(void)
Definition: misc.c:1061
E IRCDCAPAB * ircdcap
Definition: extern.h:40
int tolower(char c)
Definition: misc.c:52
char nick[NICKMAX]
Definition: services.h:875
E int snprintf(char *buf, size_t size, const char *fmt,...)
Definition: compat.c:37
E char * s_HelpServAlias
Definition: extern.h:315
E char * s_BotServ
Definition: extern.h:287
E IRCDVar * ircd
Definition: extern.h:39
void binary_to_hex(unsigned char *bin, char *hex, int length)
Definition: misc.c:67
static void arc4_addrandom(void *dat, int datlen)
Definition: misc.c:956
int nickIsServices(char *tempnick, int bot)
Definition: misc.c:857
uint16 netmask_to_cidr(uint32 mask)
Definition: misc.c:1514
static void arc4_init(void)
Definition: misc.c:939
u_int8_t j
Definition: misc.c:23
E int stricmp(const char *s1, const char *s2)
Definition: compat.c:58
char * duration(NickAlias *na, char *buf, int bufsize, time_t seconds)
Definition: misc.c:402
E long unsigned int UserKey3
Definition: extern.h:577
int(* range_callback_t)(User *u, int num, va_list args)
Definition: extern.h:858
#define getstring(na, index)
Definition: extern.h:731
char * host
Definition: services.h:878
unsigned int mysql_rand(void)
Definition: mysql.c:1978
char * stripModePrefix(const char *str)
Definition: misc.c:1188
E char * s_GlobalNoticerAlias
Definition: extern.h:317
E char * s_OperServAlias
Definition: extern.h:316
uint32 cidr_to_netmask(uint16 cidr)
Definition: misc.c:1501
E void kill_user(char *source, char *user, char *reason)
Definition: actions.c:51
static int do_match_wild(const char *pattern, const char *str, int docase)
Definition: misc.c:204
int str_is_wildcard(const char *str)
Definition: misc.c:1531
E char * sstrdup(const char *s)
Definition: memory.c:105
E char * s_OperServ
Definition: extern.h:289
E char * s_MemoServ
Definition: extern.h:286
E User * finduser(const char *nick)
Definition: users.c:323
E char * s_ChanServAlias
Definition: extern.h:312
int isValidHost(const char *host, int type)
Definition: misc.c:614
int32_t int32
Definition: db-merger.c:122
E char * s_HelpServ
Definition: extern.h:288
char * myStrGetOnlyToken(const char *str, const char dilim, int token_number)
Definition: misc.c:685
E int protocoldebug
Definition: extern.h:783
u_int32_t getrandom32(void)
Definition: misc.c:1076
char * strnrepl(char *s, int32 size, const char *old, const char *new)
Definition: misc.c:144
u_int8_t s[256]
Definition: misc.c:24
int myNumToken(const char *str, const char dilim)
Definition: misc.c:1112
E char * s_BotServAlias
Definition: extern.h:314
int match_wild_nocase(const char *pattern, const char *str)
Definition: misc.c:268
Command * c
Definition: ns_recover.c:17
uint32 str_is_ip(char *str)
Definition: misc.c:1565
u_int32_t uint32
Definition: db-merger.c:123
E void alog(const char *fmt,...) FORMAT(printf
int token
Definition: services.h:356
uint32 token
Definition: services.h:399
unsigned char getrandom8(void)
Definition: misc.c:1042
char * strscpy(char *d, const char *s, size_t len)
Definition: misc.c:91
void protocol_debug(char *source, char *cmd, int argc, char **argv)
Definition: misc.c:773
char ** buildStringList(char *src, int *number)
Definition: misc.c:1211
E int UseTokens
Definition: extern.h:360
E int debug
Definition: extern.h:775
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: misc.c:1293
E long unsigned int UserKey2
Definition: extern.h:576
void rand_init(void)
Definition: misc.c:977
int str_is_pure_wildcard(const char *str)
Definition: misc.c:1547
E char * s_HostServ
Definition: extern.h:303
char * username
Definition: services.h:877
E char * s_DevNullAlias
Definition: extern.h:318
int str_is_cidr(char *str, uint32 *ip, uint32 *mask, char **host)
Definition: misc.c:1602
char * myStrGetTokenRemainder(const char *str, const char dilim, int token_number)
Definition: misc.c:720
E char * s_HostServAlias
Definition: extern.h:319
int match_wild(const char *pattern, const char *str)
Definition: misc.c:255
char * host_resolve(char *host)
Definition: misc.c:1134
void EnforceQlinedNick(char *nick, char *killer)
Definition: misc.c:837
BotInfo * next
Definition: services.h:571
char * merge_args(int argc, char **argv)
Definition: misc.c:180
E long unsigned int UserKey1
Definition: extern.h:575
struct arc4_stream rs
E char * s_MemoServAlias
Definition: extern.h:313
int dotime(const char *s)
Definition: misc.c:364
char * nick
Definition: services.h:573
char * expire_left(NickAlias *na, char *buf, int len, time_t expires)
Definition: misc.c:470
E void * srealloc(void *oldptr, long newsize)
Definition: memory.c:80
void ntoa(struct in_addr addr, char *ipaddr, int len)
Definition: misc.c:1198
E BotInfo * botlists[256]
Definition: extern.h:64
size_t strlcat(char *dst, const char *src, size_t siz)
Definition: misc.c:1263
E char * ServerName
Definition: extern.h:274
E char * s_ChanServ
Definition: extern.h:285
char * myStrGetToken(const char *str, const char dilim, int token_number)
Definition: misc.c:654
E char * s_NickServ
Definition: extern.h:284
char * send_token(char *token1, char *token2)
Definition: misc.c:1095
int doValidHost(const char *host, int type)
Definition: misc.c:529
void doCleanBuffer(char *str)
Definition: misc.c:800
char * str_signed(unsigned char *str)
Definition: misc.c:1169
void add_entropy_userkeys(void)
Definition: misc.c:1028
#define BUFSIZE
Definition: config.h:47
u_int8_t i
Definition: misc.c:22
E char * s_GlobalNoticer
Definition: extern.h:290
int toupper(char c)
Definition: misc.c:35
#define HOSTMAX
Definition: config.h:71
#define issp(c)
Definition: misc.c:19
E char * s_NickServAlias
Definition: extern.h:311
E char * s_DevNull
Definition: extern.h:291
u_int16_t uint16
Definition: db-merger.c:121