diff options
Diffstat (limited to 'win32.c')
| -rw-r--r-- | win32.c | 575 | 
1 files changed, 471 insertions, 104 deletions
| @@ -22,7 +22,7 @@    if not, write to the Free Software Foundation, Inc., 59 Temple Place,    Suite 330, Boston, MA  02111-1307  USA  */ -
 +  #define BITLBEE_CORE  #include "bitlbee.h"  #include "commands.h" @@ -50,48 +50,48 @@ static void WINAPI service_ctrl (DWORD dwControl)      }  } -
 -static void bitlbee_init(int argc, char **argv)
 -{
 -	int i = -1;
 -	memset( &global, 0, sizeof( global_t ) );
 -	
 -	global.loop = g_main_new( FALSE );
 -	
 -	global.conf = conf_load( argc, argv );
 -	if( global.conf == NULL )
 -		return;
 -	
 -	if( global.conf->runmode == RUNMODE_INETD )
 -	{
 -		i = bitlbee_inetd_init();
 -		log_message( LOGLVL_INFO, "Bitlbee %s starting in inetd mode.", BITLBEE_VERSION );
 -
 -	}
 -	else if( global.conf->runmode == RUNMODE_DAEMON )
 -	{
 -		i = bitlbee_daemon_init();
 -		log_message( LOGLVL_INFO, "Bitlbee %s starting in daemon mode.", BITLBEE_VERSION );
 -	} 
 -	else 
 -	{
 -		log_message( LOGLVL_INFO, "No bitlbee mode specified...");
 -	}
 -	
 -	if( i != 0 )
 -		return;
 - 	
 -	if( access( global.conf->configdir, F_OK ) != 0 )
 -		log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", global.conf->configdir );
 -	else if( access( global.conf->configdir, 06 ) != 0 )
 -		log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir );
 -	if( help_init( &(global.help) ) == NULL )
 -		log_message( LOGLVL_WARNING, "Error opening helpfile %s.", global.helpfile );
 -}
 + +static void bitlbee_init(int argc, char **argv) +{ +	int i = -1; +	memset( &global, 0, sizeof( global_t ) ); +	 +	global.loop = g_main_new( FALSE ); +	 +	global.conf = conf_load( argc, argv ); +	if( global.conf == NULL ) +		return; +	 +	if( global.conf->runmode == RUNMODE_INETD ) +	{ +		i = bitlbee_inetd_init(); +		log_message( LOGLVL_INFO, "Bitlbee %s starting in inetd mode.", BITLBEE_VERSION ); + +	} +	else if( global.conf->runmode == RUNMODE_DAEMON ) +	{ +		i = bitlbee_daemon_init(); +		log_message( LOGLVL_INFO, "Bitlbee %s starting in daemon mode.", BITLBEE_VERSION ); +	}  +	else  +	{ +		log_message( LOGLVL_INFO, "No bitlbee mode specified..."); +	} +	 +	if( i != 0 ) +		return; + 	 +	if( access( global.conf->configdir, F_OK ) != 0 ) +		log_message( LOGLVL_WARNING, "The configuration directory %s does not exist. Configuration won't be saved.", global.conf->configdir ); +	else if( access( global.conf->configdir, 06 ) != 0 ) +		log_message( LOGLVL_WARNING, "Permission problem: Can't read/write from/to %s.", global.conf->configdir ); +	if( help_init( &(global.help) ) == NULL ) +		log_message( LOGLVL_WARNING, "Error opening helpfile %s.", global.helpfile ); +}  void service_main (DWORD argc, LPTSTR *argv)  { -	SERVICE_STATUS_HANDLE handle;
 +	SERVICE_STATUS_HANDLE handle;  	SERVICE_STATUS status;      handle = RegisterServiceCtrlHandler("bitlbee", service_ctrl); @@ -101,55 +101,55 @@ void service_main (DWORD argc, LPTSTR *argv)      status.dwServiceType = SERVICE_WIN32_OWN_PROCESS;      status.dwServiceSpecificExitCode = 0; -
 +  	bitlbee_init(argc, argv);  	SetServiceStatus(handle, &status);  	g_main_run( global.loop );  } -
 -SERVICE_TABLE_ENTRY dispatch_table[] =
 -{
 -   { TEXT("bitlbee"), (LPSERVICE_MAIN_FUNCTION)service_main },
 -   { NULL, NULL }
 -};
 -
 -static int debug = 0;
 -
 -static void usage()
 -{
 -	printf("Options:\n");
 -	printf("-h   Show this help message\n");
 -	printf("-d   Debug mode (simple console program)\n");
 -}
 -
 + +SERVICE_TABLE_ENTRY dispatch_table[] = +{ +   { TEXT("bitlbee"), (LPSERVICE_MAIN_FUNCTION)service_main }, +   { NULL, NULL } +}; + +static int debug = 0; + +static void usage() +{ +	printf("Options:\n"); +	printf("-h   Show this help message\n"); +	printf("-d   Debug mode (simple console program)\n"); +} +  int main( int argc, char **argv) -{    
 -	int i;
 -	WSADATA WSAData;
 - -	nogaim_init( );
 -
 -	for (i = 1; i < argc; i++) {
 -		if (!strcmp(argv[i], "-d")) debug = 1;
 -		if (!strcmp(argv[i], "-h")) {
 -			usage();
 -			return 0;
 -		}
 -	}
 -
 -    WSAStartup(MAKEWORD(1,1), &WSAData);
 -
 +{     +	int i; +	WSADATA WSAData; + +	nogaim_init( ); + +	for (i = 1; i < argc; i++) { +		if (!strcmp(argv[i], "-d")) debug = 1; +		if (!strcmp(argv[i], "-h")) { +			usage(); +			return 0; +		} +	} + +    WSAStartup(MAKEWORD(1,1), &WSAData); +  	if (!debug) {  		if (!StartServiceCtrlDispatcher(dispatch_table)) -			log_message( LOGLVL_ERROR, "StartServiceCtrlDispatcher failed.");
 -	} else {
 -			bitlbee_init(argc, argv);
 - 			g_main_run( global.loop );
 +			log_message( LOGLVL_ERROR, "StartServiceCtrlDispatcher failed."); +	} else { +			bitlbee_init(argc, argv); + 			g_main_run( global.loop );  	} -	
 -	return 0;
 +	 +	return 0;  }  double gettime() @@ -261,42 +261,42 @@ inet_aton(const char *cp, struct in_addr *addr)    addr->s_addr = inet_addr(cp);    return (addr->s_addr == INADDR_NONE) ? 0 : 1;  } -
 -void log_error(char *msg)
 -{
 -	log_message(LOGLVL_ERROR, "%s", msg);
 -}
 + +void log_error(char *msg) +{ +	log_message(LOGLVL_ERROR, "%s", msg); +}  void log_message(int level, char *message, ...)  {      HANDLE  hEventSource; -    LPTSTR  lpszStrings[2];
 +    LPTSTR  lpszStrings[2];  	WORD elevel;      va_list ap; -    va_start(ap, message);
 -
 -	if (debug) {
 -		vprintf(message, ap);
 -		putchar('\n');
 -		va_end(ap);
 -		return;
 +    va_start(ap, message); + +	if (debug) { +		vprintf(message, ap); +		putchar('\n'); +		va_end(ap); +		return;  	}      hEventSource = RegisterEventSource(NULL, TEXT("bitlbee"));      lpszStrings[0] = TEXT("bitlbee");      lpszStrings[1] = g_strdup_vprintf(message, ap); -    va_end(ap);
 -
 -	switch (level) {
 -	case LOGLVL_ERROR: elevel = EVENTLOG_ERROR_TYPE; break;
 -	case LOGLVL_WARNING: elevel = EVENTLOG_WARNING_TYPE; break;
 -	case LOGLVL_INFO: elevel = EVENTLOG_INFORMATION_TYPE; break;
 -#ifdef DEBUG
 -	case LOGLVL_DEBUG: elevel = EVENTLOG_AUDIT_SUCCESS; break;
 -#endif
 -	}
 +    va_end(ap); + +	switch (level) { +	case LOGLVL_ERROR: elevel = EVENTLOG_ERROR_TYPE; break; +	case LOGLVL_WARNING: elevel = EVENTLOG_WARNING_TYPE; break; +	case LOGLVL_INFO: elevel = EVENTLOG_INFORMATION_TYPE; break; +#ifdef DEBUG +	case LOGLVL_DEBUG: elevel = EVENTLOG_AUDIT_SUCCESS; break; +#endif +	}      if (hEventSource != NULL) {          ReportEvent(hEventSource,  @@ -310,7 +310,374 @@ void log_message(int level, char *message, ...)          NULL);                          DeregisterEventSource(hEventSource); -    }
 -
 +    } +  	g_free(lpszStrings[1]);  } + +void log_link(int level, int output) { /* FIXME */ } + +#ifndef NS_INADDRSZ +#define NS_INADDRSZ	4 +#endif +#ifndef NS_IN6ADDRSZ +#define NS_IN6ADDRSZ	16 +#endif +#ifndef NS_INT16SZ +#define NS_INT16SZ	2 +#endif + +static const char *inet_ntop4(const guchar *src, char *dst, size_t size); +static const char *inet_ntop6(const guchar *src, char *dst, size_t size); + +/* char * + * inet_ntop(af, src, dst, size) + *	convert a network format address to presentation format. + * return: + *	pointer to presentation format address (`dst'), or NULL (see errno). + * author: + *	Paul Vixie, 1996. + */ +const char * +inet_ntop(af, src, dst, size) +	int af; +	const void *src; +	char *dst; +	size_t size; +{ +	switch (af) { +	case AF_INET: +		return (inet_ntop4(src, dst, size)); +	case AF_INET6: +		return (inet_ntop6(src, dst, size)); +	default: +		errno = WSAEAFNOSUPPORT; +		return (NULL); +	} +	/* NOTREACHED */ +} + +/* const char * + * inet_ntop4(src, dst, size) + *	format an IPv4 address + * return: + *	`dst' (as a const) + * notes: + *	(1) uses no statics + *	(2) takes a u_char* not an in_addr as input + * author: + *	Paul Vixie, 1996. + */ +static const char * +inet_ntop4(src, dst, size) +	const u_char *src; +	char *dst; +	size_t size; +{ +	static const char fmt[] = "%u.%u.%u.%u"; +	char tmp[sizeof "255.255.255.255"]; +	int nprinted; + +	nprinted = g_snprintf(tmp, sizeof(tmp), fmt, src[0], src[1], src[2], src[3]); +	if (nprinted < 0) +		return (NULL);	/* we assume "errno" was set by "g_snprintf()" */ +	if ((size_t)nprinted > size) { +		errno = ENOSPC; +		return (NULL); +	} +	strcpy(dst, tmp); +	return (dst); +} + +/* const char * + * inet_ntop6(src, dst, size) + *	convert IPv6 binary address into presentation (printable) format + * author: + *	Paul Vixie, 1996. + */ +static const char * +inet_ntop6(src, dst, size) +	const u_char *src; +	char *dst; +	size_t size; +{ +	/* +	 * Note that int32_t and int16_t need only be "at least" large enough +	 * to contain a value of the specified size.  On some systems, like +	 * Crays, there is no such thing as an integer variable with 16 bits. +	 * Keep this in mind if you think this function should have been coded +	 * to use pointer overlays.  All the world's not a VAX. +	 */ +	char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp; +	struct { int base, len; } best, cur; +	guint words[NS_IN6ADDRSZ / NS_INT16SZ]; +	int i; + +	/* +	 * Preprocess: +	 *	Copy the input (bytewise) array into a wordwise array. +	 *	Find the longest run of 0x00's in src[] for :: shorthanding. +	 */ +	memset(words, '\0', sizeof words); +	for (i = 0; i < NS_IN6ADDRSZ; i++) +		words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3)); +	best.base = -1; +	cur.base = -1; +	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { +		if (words[i] == 0) { +			if (cur.base == -1) +				cur.base = i, cur.len = 1; +			else +				cur.len++; +		} else { +			if (cur.base != -1) { +				if (best.base == -1 || cur.len > best.len) +					best = cur; +				cur.base = -1; +			} +		} +	} +	if (cur.base != -1) { +		if (best.base == -1 || cur.len > best.len) +			best = cur; +	} +	if (best.base != -1 && best.len < 2) +		best.base = -1; + +	/* +	 * Format the result. +	 */ +	tp = tmp; +	for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) { +		/* Are we inside the best run of 0x00's? */ +		if (best.base != -1 && i >= best.base && +		    i < (best.base + best.len)) { +			if (i == best.base) +				*tp++ = ':'; +			continue; +		} +		/* Are we following an initial run of 0x00s or any real hex? */ +		if (i != 0) +			*tp++ = ':'; +		/* Is this address an encapsulated IPv4? */ +		if (i == 6 && best.base == 0 && +		    (best.len == 6 || (best.len == 5 && words[5] == 0xffff))) { +			if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp))) +				return (NULL); +			tp += strlen(tp); +			break; +		} +		tp += g_snprintf(tp, sizeof tmp - (tp - tmp), "%x", words[i]); +	} +	/* Was it a trailing run of 0x00's? */ +	if (best.base != -1 && (best.base + best.len) == +	    (NS_IN6ADDRSZ / NS_INT16SZ)) +		*tp++ = ':'; +	*tp++ = '\0'; + +	/* +	 * Check for overflow, copy, and we're done. +	 */ +	if ((size_t)(tp - tmp) > size) { +		errno = ENOSPC; +		return (NULL); +	} +	strcpy(dst, tmp); +	return (dst); +} + +#ifdef AF_INET +static int inet_pton4(const char *src, u_char *dst); +#endif +#ifdef AF_INET6 +static int inet_pton6(const char *src, u_char *dst); +#endif + +/* int + * inet_pton(af, src, dst) + *	convert from presentation format (which usually means ASCII printable) + *	to network format (which is usually some kind of binary format). + * return: + *	1 if the address was valid for the specified address family + *	0 if the address wasn't valid (`dst' is untouched in this case) + *	-1 if some other error occurred (`dst' is untouched in this case, too) + * author: + *	Paul Vixie, 1996. + */ +int +inet_pton(af, src, dst) +	int af; +	const char *src; +	void *dst; +{ +	switch (af) { +#ifdef AF_INET +	case AF_INET: +		return (inet_pton4(src, dst)); +#endif +#ifdef AF_INET6 +	case AF_INET6: +		return (inet_pton6(src, dst)); +#endif +	default: +		errno = WSAEAFNOSUPPORT; +		return (-1); +	} +	/* NOTREACHED */ +} + +#ifdef AF_INET +/* int + * inet_pton4(src, dst) + *	like inet_aton() but without all the hexadecimal and shorthand. + * return: + *	1 if `src' is a valid dotted quad, else 0. + * notice: + *	does not touch `dst' unless it's returning 1. + * author: + *	Paul Vixie, 1996. + */ +static int +inet_pton4(src, dst) +	const char *src; +	u_char *dst; +{ +	static const char digits[] = "0123456789"; +	int saw_digit, octets, ch; +	u_char tmp[NS_INADDRSZ], *tp; + +	saw_digit = 0; +	octets = 0; +	*(tp = tmp) = 0; +	while ((ch = *src++) != '\0') { +		const char *pch; + +		if ((pch = strchr(digits, ch)) != NULL) { +			u_int new = *tp * 10 + (pch - digits); + +			if (new > 255) +				return (0); +			*tp = new; +			if (! saw_digit) { +				if (++octets > 4) +					return (0); +				saw_digit = 1; +			} +		} else if (ch == '.' && saw_digit) { +			if (octets == 4) +				return (0); +			*++tp = 0; +			saw_digit = 0; +		} else +			return (0); +	} +	if (octets < 4) +		return (0); +	memcpy(dst, tmp, NS_INADDRSZ); +	return (1); +} +#endif + +#ifdef AF_INET6 +/* int + * inet_pton6(src, dst) + *	convert presentation level address to network order binary form. + * return: + *	1 if `src' is a valid [RFC1884 2.2] address, else 0. + * notice: + *	(1) does not touch `dst' unless it's returning 1. + *	(2) :: in a full address is silently ignored. + * credit: + *	inspired by Mark Andrews. + * author: + *	Paul Vixie, 1996. + */ +static int +inet_pton6(src, dst) +	const char *src; +	u_char *dst; +{ +	static const char xdigits_l[] = "0123456789abcdef", +			  xdigits_u[] = "0123456789ABCDEF"; +	u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; +	const char *xdigits, *curtok; +	int ch, saw_xdigit; +	u_int val; + +	memset((tp = tmp), '\0', NS_IN6ADDRSZ); +	endp = tp + NS_IN6ADDRSZ; +	colonp = NULL; +	/* Leading :: requires some special handling. */ +	if (*src == ':') +		if (*++src != ':') +			return (0); +	curtok = src; +	saw_xdigit = 0; +	val = 0; +	while ((ch = *src++) != '\0') { +		const char *pch; + +		if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) +			pch = strchr((xdigits = xdigits_u), ch); +		if (pch != NULL) { +			val <<= 4; +			val |= (pch - xdigits); +			if (val > 0xffff) +				return (0); +			saw_xdigit = 1; +			continue; +		} +		if (ch == ':') { +			curtok = src; +			if (!saw_xdigit) { +				if (colonp) +					return (0); +				colonp = tp; +				continue; +			} else if (*src == '\0') { +				return (0); +			} +			if (tp + NS_INT16SZ > endp) +				return (0); +			*tp++ = (u_char) (val >> 8) & 0xff; +			*tp++ = (u_char) val & 0xff; +			saw_xdigit = 0; +			val = 0; +			continue; +		} +		if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && +		    inet_pton4(curtok, tp) > 0) { +			tp += NS_INADDRSZ; +			saw_xdigit = 0; +			break;	/* '\0' was seen by inet_pton4(). */ +		} +		return (0); +	} +	if (saw_xdigit) { +		if (tp + NS_INT16SZ > endp) +			return (0); +		*tp++ = (u_char) (val >> 8) & 0xff; +		*tp++ = (u_char) val & 0xff; +	} +	if (colonp != NULL) { +		/* +		 * Since some memmove()'s erroneously fail to handle +		 * overlapping regions, we'll do the shift by hand. +		 */ +		const int n = tp - colonp; +		int i; + +		if (tp == endp) +			return (0); +		for (i = 1; i <= n; i++) { +			endp[- i] = colonp[n - i]; +			colonp[n - i] = 0; +		} +		tp = endp; +	} +	if (tp != endp) +		return (0); +	memcpy(dst, tmp, NS_IN6ADDRSZ); +	return (1); +} +#endif | 
