2013-07-04 20:56:19 +00:00
/*
* ZeroTier One - Global Peer to Peer Ethernet
* Copyright ( C ) 2012 - 2013 ZeroTier Networks LLC
*
* This program is free software : you can redistribute it and / or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation , either version 3 of the License , or
* ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
* GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program . If not , see < http : //www.gnu.org/licenses/>.
*
* - -
*
* ZeroTier may be used and distributed under the terms of the GPLv3 , which
* are available at : http : //www.gnu.org/licenses/gpl-3.0.html
*
* If you would like to embed ZeroTier into a commercial application or
* redistribute it in a modified binary form , please contact ZeroTier Networks
* LLC . Start here : http : //www.zerotier.com/
*/
# include <stdio.h>
# include <stdlib.h>
# include <string.h>
# include <time.h>
# include <errno.h>
2013-08-26 21:22:20 +00:00
2013-07-04 20:56:19 +00:00
# include <string>
# include <stdexcept>
2013-08-10 14:27:53 +00:00
# include "node/Constants.hpp"
# ifdef __WINDOWS__
2013-08-26 21:22:20 +00:00
# include <WinSock2.h>
2013-07-04 20:56:19 +00:00
# include <Windows.h>
2013-08-26 21:22:20 +00:00
# include <tchar.h>
# include <wchar.h>
2013-07-04 20:56:19 +00:00
# else
# include <unistd.h>
# include <pwd.h>
# include <sys/types.h>
# include <sys/stat.h>
# include <signal.h>
# endif
2013-08-26 21:22:20 +00:00
# include "node/Constants.hpp"
# include "node/Defaults.hpp"
2013-07-04 20:56:19 +00:00
# include "node/Utils.hpp"
2013-08-26 21:22:20 +00:00
# include "node/Node.hpp"
2013-07-04 20:56:19 +00:00
using namespace ZeroTier ;
static Node * node = ( Node * ) 0 ;
static void printHelp ( const char * cn , FILE * out )
{
2013-09-17 18:47:48 +00:00
fprintf ( out , " ZeroTier One version %d.%d.%d " ZT_EOL_S " (c)2012-2013 ZeroTier Networks LLC " ZT_EOL_S , Node : : versionMajor ( ) , Node : : versionMinor ( ) , Node : : versionRevision ( ) ) ;
fprintf ( out , " Licensed under the GNU General Public License v3 " ZT_EOL_S " " ZT_EOL_S ) ;
fprintf ( out , " Usage: %s [-switches] [home directory] " ZT_EOL_S " " ZT_EOL_S , cn ) ;
fprintf ( out , " Available switches: " ZT_EOL_S ) ;
fprintf ( out , " -h - Display this help " ZT_EOL_S ) ;
fprintf ( out , " -p<port> - Bind to this port for network I/O " ZT_EOL_S ) ;
fprintf ( out , " -c<port> - Bind to this port for local control packets " ZT_EOL_S ) ;
2013-07-04 20:56:19 +00:00
}
2013-08-26 21:22:20 +00:00
# ifdef __UNIX_LIKE__
2013-07-04 20:56:19 +00:00
static void sighandlerQuit ( int sig )
{
Node * n = node ;
if ( n )
2013-08-30 19:02:12 +00:00
n - > terminate ( Node : : NODE_NORMAL_TERMINATION , " terminated by signal " ) ;
2013-07-04 20:56:19 +00:00
else exit ( 0 ) ;
}
# endif
2013-08-27 20:11:39 +00:00
# ifdef __WINDOWS__
static BOOL WINAPI _handlerRoutine ( DWORD dwCtrlType )
{
switch ( dwCtrlType ) {
case CTRL_C_EVENT :
case CTRL_BREAK_EVENT :
case CTRL_CLOSE_EVENT :
case CTRL_SHUTDOWN_EVENT :
Node * n = node ;
if ( n )
2013-08-30 19:02:12 +00:00
n - > terminate ( Node : : NODE_NORMAL_TERMINATION , " terminated by signal " ) ;
2013-08-27 20:11:39 +00:00
return TRUE ;
}
return FALSE ;
}
# endif
2013-08-26 21:22:20 +00:00
# ifdef __WINDOWS__
int _tmain ( int argc , _TCHAR * argv [ ] )
# else
2013-07-04 20:56:19 +00:00
int main ( int argc , char * * argv )
2013-08-26 21:22:20 +00:00
# endif
2013-07-04 20:56:19 +00:00
{
2013-08-26 21:22:20 +00:00
# ifdef __UNIX_LIKE__
2013-07-17 18:39:34 +00:00
signal ( SIGHUP , SIG_IGN ) ;
2013-07-04 20:56:19 +00:00
signal ( SIGPIPE , SIG_IGN ) ;
2013-07-17 18:39:34 +00:00
signal ( SIGUSR1 , SIG_IGN ) ;
signal ( SIGUSR2 , SIG_IGN ) ;
2013-07-04 20:56:19 +00:00
signal ( SIGALRM , SIG_IGN ) ;
signal ( SIGINT , & sighandlerQuit ) ;
signal ( SIGTERM , & sighandlerQuit ) ;
signal ( SIGQUIT , & sighandlerQuit ) ;
# endif
2013-08-26 21:22:20 +00:00
# ifdef __WINDOWS__
WSADATA wsaData ;
WSAStartup ( MAKEWORD ( 2 , 2 ) , & wsaData ) ;
2013-08-27 20:11:39 +00:00
SetConsoleCtrlHandler ( & _handlerRoutine , TRUE ) ;
2013-08-26 21:22:20 +00:00
# endif
2013-08-10 14:27:53 +00:00
2013-07-04 20:56:19 +00:00
const char * homeDir = ( const char * ) 0 ;
2013-09-17 18:47:48 +00:00
unsigned int port = 0 ;
unsigned int controlPort = 0 ;
2013-07-04 20:56:19 +00:00
for ( int i = 1 ; i < argc ; + + i ) {
if ( argv [ i ] [ 0 ] = = ' - ' ) {
switch ( argv [ i ] [ 1 ] ) {
2013-09-17 18:47:48 +00:00
case ' p ' :
port = Utils : : strToUInt ( argv [ i ] + 2 ) ;
if ( port > 65535 ) {
printHelp ( argv [ 0 ] , stderr ) ;
return - 1 ;
}
break ;
case ' c ' :
controlPort = Utils : : strToUInt ( argv [ i ] + 2 ) ;
if ( controlPort > 65535 ) {
printHelp ( argv [ 0 ] , stderr ) ;
return - 1 ;
}
break ;
2013-08-26 21:22:20 +00:00
case ' h ' :
case ' ? ' :
2013-07-04 20:56:19 +00:00
default :
printHelp ( argv [ 0 ] , stderr ) ;
2013-08-30 19:02:12 +00:00
return 0 ;
2013-07-04 20:56:19 +00:00
}
} else {
if ( homeDir ) {
printHelp ( argv [ 0 ] , stderr ) ;
2013-08-30 19:02:12 +00:00
return 0 ;
2013-07-04 20:56:19 +00:00
}
homeDir = argv [ i ] ;
break ;
}
}
2013-08-26 21:22:20 +00:00
if ( ( ! homeDir ) | | ( strlen ( homeDir ) = = 0 ) )
homeDir = ZT_DEFAULTS . defaultHomePath . c_str ( ) ;
# ifdef __UNIX_LIKE__
2013-07-04 20:56:19 +00:00
mkdir ( homeDir , 0755 ) ; // will fail if it already exists
# endif
2013-08-30 19:02:12 +00:00
int exitCode = 0 ;
2013-07-04 20:56:19 +00:00
2013-09-17 18:47:48 +00:00
node = new Node ( homeDir , port , controlPort ) ;
2013-07-17 18:39:34 +00:00
const char * termReason = ( char * ) 0 ;
2013-07-04 20:56:19 +00:00
switch ( node - > run ( ) ) {
case Node : : NODE_UNRECOVERABLE_ERROR :
2013-08-30 19:02:12 +00:00
exitCode = - 1 ;
2013-07-17 18:39:34 +00:00
termReason = node - > reasonForTermination ( ) ;
fprintf ( stderr , " %s: abnormal termination: %s \n " , argv [ 0 ] , ( termReason ) ? termReason : " (unknown reason) " ) ;
2013-07-04 20:56:19 +00:00
break ;
default :
break ;
}
delete node ;
node = ( Node * ) 0 ;
return exitCode ;
}