mirror of
				https://github.com/jgamblin/Mirai-Source-Code
				synced 2025-10-30 23:23:02 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			292 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			292 lines
		
	
	
		
			5.2 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
	
	
| #define _GNU_SOURCE
 | |
| 
 | |
| #ifdef DEBUG
 | |
| #include <stdio.h>
 | |
| #endif
 | |
| #include <stdlib.h>
 | |
| #include <arpa/inet.h>
 | |
| #include <unistd.h>
 | |
| #include <errno.h>
 | |
| #include <limits.h>
 | |
| #include <dirent.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/stat.h>
 | |
| #include <fcntl.h>
 | |
| #include <signal.h>
 | |
| 
 | |
| #include "includes.h"
 | |
| #include "util.h"
 | |
| #include "table.h"
 | |
| 
 | |
| int util_strlen(char *str)
 | |
| {
 | |
|     int c = 0;
 | |
| 
 | |
|     while (*str++ != 0)
 | |
|         c++;
 | |
|     return c;
 | |
| }
 | |
| 
 | |
| 
 | |
| BOOL util_strncmp(char *str1, char *str2, int len)
 | |
| {
 | |
|     int l1 = util_strlen(str1), l2 = util_strlen(str2);
 | |
| 
 | |
|     if (l1 < len || l2 < len)
 | |
|         return FALSE;
 | |
| 
 | |
|     while (len--)
 | |
|     {
 | |
|         if (*str1++ != *str2++)
 | |
|             return FALSE;
 | |
|     }
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| BOOL util_strcmp(char *str1, char *str2)
 | |
| {
 | |
|     int l1 = util_strlen(str1), l2 = util_strlen(str2);
 | |
| 
 | |
|     if (l1 != l2)
 | |
|         return FALSE;
 | |
| 
 | |
|     while (l1--)
 | |
|     {
 | |
|         if (*str1++ != *str2++)
 | |
|             return FALSE;
 | |
|     }
 | |
| 
 | |
|     return TRUE;
 | |
| }
 | |
| 
 | |
| int util_strcpy(char *dst, char *src)
 | |
| {
 | |
|     int l = util_strlen(src);
 | |
| 
 | |
|     util_memcpy(dst, src, l + 1);
 | |
| 
 | |
|     return l;
 | |
| }
 | |
| 
 | |
| void util_memcpy(void *dst, void *src, int len)
 | |
| {
 | |
|     char *r_dst = (char *)dst;
 | |
|     char *r_src = (char *)src;
 | |
|     while (len--)
 | |
|         *r_dst++ = *r_src++;
 | |
| }
 | |
| 
 | |
| void util_zero(void *buf, int len)
 | |
| {
 | |
|     char *zero = buf;
 | |
|     while (len--)
 | |
|         *zero++ = 0;
 | |
| }
 | |
| 
 | |
| int util_atoi(char *str, int base)
 | |
| {
 | |
| 	unsigned long acc = 0;
 | |
| 	int c;
 | |
| 	unsigned long cutoff;
 | |
| 	int neg = 0, any, cutlim;
 | |
| 
 | |
| 	do {
 | |
| 		c = *str++;
 | |
| 	} while (util_isspace(c));
 | |
| 	if (c == '-') {
 | |
| 		neg = 1;
 | |
| 		c = *str++;
 | |
| 	} else if (c == '+')
 | |
| 		c = *str++;
 | |
| 
 | |
| 	cutoff = neg ? -(unsigned long)LONG_MIN : LONG_MAX;
 | |
| 	cutlim = cutoff % (unsigned long)base;
 | |
| 	cutoff /= (unsigned long)base;
 | |
| 	for (acc = 0, any = 0;; c = *str++) {
 | |
| 		if (util_isdigit(c))
 | |
| 			c -= '0';
 | |
| 		else if (util_isalpha(c))
 | |
| 			c -= util_isupper(c) ? 'A' - 10 : 'a' - 10;
 | |
| 		else
 | |
| 			break;
 | |
|             
 | |
| 		if (c >= base)
 | |
| 			break;
 | |
| 
 | |
| 		if (any < 0 || acc > cutoff || acc == cutoff && c > cutlim)
 | |
| 			any = -1;
 | |
| 		else {
 | |
| 			any = 1;
 | |
| 			acc *= base;
 | |
| 			acc += c;
 | |
| 		}
 | |
| 	}
 | |
| 	if (any < 0) {
 | |
| 		acc = neg ? LONG_MIN : LONG_MAX;
 | |
| 	} else if (neg)
 | |
| 		acc = -acc;
 | |
| 	return (acc);
 | |
| }
 | |
| 
 | |
| char *util_itoa(int value, int radix, char *string)
 | |
| {
 | |
|     if (string == NULL)
 | |
|         return NULL;
 | |
| 
 | |
|     if (value != 0)
 | |
|     {
 | |
|         char scratch[34];
 | |
|         int neg;
 | |
|         int offset;
 | |
|         int c;
 | |
|         unsigned int accum;
 | |
| 
 | |
|         offset = 32;
 | |
|         scratch[33] = 0;
 | |
| 
 | |
|         if (radix == 10 && value < 0)
 | |
|         {
 | |
|             neg = 1;
 | |
|             accum = -value;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             neg = 0;
 | |
|             accum = (unsigned int)value;
 | |
|         }
 | |
| 
 | |
|         while (accum)
 | |
|         {
 | |
|             c = accum % radix;
 | |
|             if (c < 10)
 | |
|                 c += '0';
 | |
|             else
 | |
|                 c += 'A' - 10;
 | |
| 
 | |
|             scratch[offset] = c;
 | |
|             accum /= radix;
 | |
|             offset--;
 | |
|         }
 | |
|         
 | |
|         if (neg)
 | |
|             scratch[offset] = '-';
 | |
|         else
 | |
|             offset++;
 | |
| 
 | |
|         util_strcpy(string, &scratch[offset]);
 | |
|     }
 | |
|     else
 | |
|     {
 | |
|         string[0] = '0';
 | |
|         string[1] = 0;
 | |
|     }
 | |
| 
 | |
|     return string;
 | |
| }
 | |
| 
 | |
| int util_memsearch(char *buf, int buf_len, char *mem, int mem_len)
 | |
| {
 | |
|     int i, matched = 0;
 | |
| 
 | |
|     if (mem_len > buf_len)
 | |
|         return -1;
 | |
| 
 | |
|     for (i = 0; i < buf_len; i++)
 | |
|     {
 | |
|         if (buf[i] == mem[matched])
 | |
|         {
 | |
|             if (++matched == mem_len)
 | |
|                 return i + 1;
 | |
|         }
 | |
|         else
 | |
|             matched = 0;
 | |
|     }
 | |
| 
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| int util_stristr(char *haystack, int haystack_len, char *str)
 | |
| {
 | |
|     char *ptr = haystack;
 | |
|     int str_len = util_strlen(str);
 | |
|     int match_count = 0;
 | |
| 
 | |
|     while (haystack_len-- > 0)
 | |
|     {
 | |
|         char a = *ptr++;
 | |
|         char b = str[match_count];
 | |
|         a = a >= 'A' && a <= 'Z' ? a | 0x60 : a;
 | |
|         b = b >= 'A' && b <= 'Z' ? b | 0x60 : b;
 | |
| 
 | |
|         if (a == b)
 | |
|         {
 | |
|             if (++match_count == str_len)
 | |
|                 return (ptr - haystack);
 | |
|         }
 | |
|         else
 | |
|             match_count = 0;
 | |
|     }
 | |
| 
 | |
|     return -1;
 | |
| }
 | |
| 
 | |
| ipv4_t util_local_addr(void)
 | |
| {
 | |
|     int fd;
 | |
|     struct sockaddr_in addr;
 | |
|     socklen_t addr_len = sizeof (addr);
 | |
| 
 | |
|     errno = 0;
 | |
|     if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
 | |
|     {
 | |
| #ifdef DEBUG
 | |
|         printf("[util] Failed to call socket(), errno = %d\n", errno);
 | |
| #endif
 | |
|         return 0;
 | |
|     }
 | |
| 
 | |
|     addr.sin_family = AF_INET;
 | |
|     addr.sin_addr.s_addr = INET_ADDR(8,8,8,8);
 | |
|     addr.sin_port = htons(53);
 | |
| 
 | |
|     connect(fd, (struct sockaddr *)&addr, sizeof (struct sockaddr_in));
 | |
| 
 | |
|     getsockname(fd, (struct sockaddr *)&addr, &addr_len);
 | |
|     close(fd);
 | |
|     return addr.sin_addr.s_addr;
 | |
| }
 | |
| 
 | |
| char *util_fdgets(char *buffer, int buffer_size, int fd)
 | |
| {
 | |
|     int got = 0, total = 0;
 | |
|     do 
 | |
|     {
 | |
|         got = read(fd, buffer + total, 1);
 | |
|         total = got == 1 ? total + 1 : total;
 | |
|     }
 | |
|     while (got == 1 && total < buffer_size && *(buffer + (total - 1)) != '\n');
 | |
| 
 | |
|     return total == 0 ? NULL : buffer;
 | |
| }
 | |
| 
 | |
| static inline int util_isupper(char c)
 | |
| {
 | |
|     return (c >= 'A' && c <= 'Z');
 | |
| }
 | |
| 
 | |
| static inline int util_isalpha(char c)
 | |
| {
 | |
|     return ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'));
 | |
| }
 | |
| 
 | |
| static inline int util_isspace(char c)
 | |
| {
 | |
|     return (c == ' ' || c == '\t' || c == '\n' || c == '\12');
 | |
| }
 | |
| 
 | |
| static inline int util_isdigit(char c)
 | |
| {
 | |
|     return (c >= '0' && c <= '9');
 | |
| }
 | 
