refactored some common platform dependent stuff into a new
library: platform. also removed test.cpp.
This commit is contained in:
parent
c3649df304
commit
5709d8ddef
38
Makefile
38
Makefile
|
@ -12,6 +12,7 @@ SUBDIRS = \
|
||||||
http \
|
http \
|
||||||
net \
|
net \
|
||||||
synergy \
|
synergy \
|
||||||
|
platform \
|
||||||
client \
|
client \
|
||||||
server \
|
server \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
@ -32,40 +33,3 @@ clean:
|
||||||
clobber:
|
clobber:
|
||||||
$(RMR) $(LIBDIR)
|
$(RMR) $(LIBDIR)
|
||||||
$(SUBDIRS_MAKERULE)
|
$(SUBDIRS_MAKERULE)
|
||||||
|
|
||||||
#
|
|
||||||
#
|
|
||||||
# test
|
|
||||||
#
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# source files
|
|
||||||
#
|
|
||||||
LCXXINCS = \
|
|
||||||
-I$(DEPTH)/base \
|
|
||||||
-I$(DEPTH)/mt \
|
|
||||||
-I$(DEPTH)/io \
|
|
||||||
-I$(DEPTH)/net \
|
|
||||||
-I$(DEPTH)/synergy \
|
|
||||||
$(NULL)
|
|
||||||
CXXFILES = test.cpp
|
|
||||||
|
|
||||||
#
|
|
||||||
# libraries we depend on
|
|
||||||
#
|
|
||||||
DEPLIBS = \
|
|
||||||
$(LIBDIR)/libsynergy.a \
|
|
||||||
$(LIBDIR)/libnet.a \
|
|
||||||
$(LIBDIR)/libio.a \
|
|
||||||
$(LIBDIR)/libmt.a \
|
|
||||||
$(LIBDIR)/libbase.a \
|
|
||||||
$(NULL)
|
|
||||||
LLDLIBS = \
|
|
||||||
$(DEPLIBS) \
|
|
||||||
-lpthread \
|
|
||||||
$(NULL)
|
|
||||||
|
|
||||||
test: $(OBJECTS) $(DEPLIBS)
|
|
||||||
$(CXX) $(CXXFLAGS) -o $@ $(OBJECTS) $(LDFLAGS)
|
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ include $(DEPTH)/Makecommon
|
||||||
#
|
#
|
||||||
# target file
|
# target file
|
||||||
#
|
#
|
||||||
TARGET = client
|
TARGET = synergy
|
||||||
|
|
||||||
#
|
#
|
||||||
# source files
|
# source files
|
||||||
|
@ -15,6 +15,7 @@ LCXXINCS = \
|
||||||
-I$(DEPTH)/io \
|
-I$(DEPTH)/io \
|
||||||
-I$(DEPTH)/net \
|
-I$(DEPTH)/net \
|
||||||
-I$(DEPTH)/synergy \
|
-I$(DEPTH)/synergy \
|
||||||
|
-I$(DEPTH)/platform \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
CXXFILES = \
|
CXXFILES = \
|
||||||
CXWindowsSecondaryScreen.cpp \
|
CXWindowsSecondaryScreen.cpp \
|
||||||
|
@ -26,6 +27,7 @@ CXXFILES = \
|
||||||
# libraries we depend on
|
# libraries we depend on
|
||||||
#
|
#
|
||||||
DEPLIBS = \
|
DEPLIBS = \
|
||||||
|
$(LIBDIR)/libplatform.a \
|
||||||
$(LIBDIR)/libsynergy.a \
|
$(LIBDIR)/libsynergy.a \
|
||||||
$(LIBDIR)/libnet.a \
|
$(LIBDIR)/libnet.a \
|
||||||
$(LIBDIR)/libio.a \
|
$(LIBDIR)/libio.a \
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "CMutex.h"
|
#include "CMutex.h"
|
||||||
#include "CNetwork.h"
|
#include "CNetwork.h"
|
||||||
#include "CNetworkAddress.h"
|
#include "CNetworkAddress.h"
|
||||||
|
#include "CPlatform.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "XThread.h"
|
#include "XThread.h"
|
||||||
#include "ProtocolTypes.h"
|
#include "ProtocolTypes.h"
|
||||||
|
@ -248,20 +249,13 @@ static void parse(int argc, char** argv)
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
{
|
{
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
|
// save instance
|
||||||
CMSWindowsScreen::init(instance);
|
CMSWindowsScreen::init(instance);
|
||||||
|
|
||||||
// get program name
|
// get program name
|
||||||
pname = strrchr(argv[0], '/');
|
pname = platform.getBasename(argv[0]);
|
||||||
if (pname == NULL) {
|
|
||||||
pname = argv[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++pname;
|
|
||||||
}
|
|
||||||
const char* pname2 = strrchr(argv[0], '\\');
|
|
||||||
if (pname2 != NULL && pname2 > pname) {
|
|
||||||
pname = pname2 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME -- direct CLog to MessageBox
|
// FIXME -- direct CLog to MessageBox
|
||||||
|
|
||||||
|
@ -292,107 +286,26 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
|
|
||||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/wait.h>
|
#include <sys/wait.h>
|
||||||
|
|
||||||
static void daemonize()
|
|
||||||
{
|
|
||||||
// fork so shell thinks we're done and so we're not a process
|
|
||||||
// group leader
|
|
||||||
switch (fork()) {
|
|
||||||
case -1:
|
|
||||||
// failed
|
|
||||||
log((CLOG_PRINT "failed to daemonize"));
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
// child
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// parent exits
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// become leader of a new session
|
|
||||||
setsid();
|
|
||||||
|
|
||||||
// chdir to root so we don't keep mounted filesystems points busy
|
|
||||||
chdir("/");
|
|
||||||
|
|
||||||
// mask off permissions for any but owner
|
|
||||||
umask(077);
|
|
||||||
|
|
||||||
// close open files. we only expect stdin, stdout, stderr to be open.
|
|
||||||
close(0);
|
|
||||||
close(1);
|
|
||||||
close(2);
|
|
||||||
|
|
||||||
// attach file descriptors 0, 1, 2 to /dev/null so inadvertent use
|
|
||||||
// of standard I/O safely goes in the bit bucket.
|
|
||||||
open("/dev/null", O_RDWR);
|
|
||||||
dup(0);
|
|
||||||
dup(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void syslogOutputter(int priority, const char* msg)
|
|
||||||
{
|
|
||||||
// convert priority
|
|
||||||
switch (priority) {
|
|
||||||
case CLog::kFATAL:
|
|
||||||
case CLog::kERROR:
|
|
||||||
priority = LOG_ERR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLog::kWARNING:
|
|
||||||
priority = LOG_WARNING;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLog::kNOTE:
|
|
||||||
priority = LOG_NOTICE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLog::kINFO:
|
|
||||||
priority = LOG_INFO;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
priority = LOG_DEBUG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// log it
|
|
||||||
syslog(priority, "%s", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
// get program name
|
// get program name
|
||||||
pname = strrchr(argv[0], '/');
|
pname = platform.getBasename(argv[0]);
|
||||||
if (pname == NULL) {
|
|
||||||
pname = argv[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++pname;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse command line
|
// parse command line
|
||||||
parse(argc, argv);
|
parse(argc, argv);
|
||||||
|
|
||||||
// daemonize if requested
|
// daemonize if requested
|
||||||
if (s_daemon) {
|
if (s_daemon) {
|
||||||
daemonize();
|
if (!platform.daemonize("synergy")) {
|
||||||
|
log((CLOG_CRIT "failed to daemonize"));
|
||||||
// send log to syslog
|
return 16;
|
||||||
openlog("synergy", 0, LOG_DAEMON);
|
}
|
||||||
CLog::setOutputter(&syslogOutputter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the server. if running as a daemon then run it in a child
|
// run the server. if running as a daemon then run it in a child
|
||||||
|
|
|
@ -42,7 +42,7 @@ RSC=rc.exe
|
||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||||
# SUBTRACT CPP /YX
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
@ -68,7 +68,7 @@ LINK32=link.exe
|
||||||
# PROP Intermediate_Dir "Debug"
|
# PROP Intermediate_Dir "Debug"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||||
# SUBTRACT CPP /YX
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
|
||||||
|
#include "CWin32Platform.cpp"
|
||||||
|
|
||||||
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
|
|
||||||
|
#include "CUnixPlatform.cpp"
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,18 @@
|
||||||
|
#ifndef CPLATFORM_H
|
||||||
|
#define CPLATFORM_H
|
||||||
|
|
||||||
|
#include "common.h"
|
||||||
|
|
||||||
|
#if defined(CONFIG_PLATFORM_WIN32)
|
||||||
|
|
||||||
|
#include "CWin32Platform.h"
|
||||||
|
typedef CWin32Platform CPlatform;
|
||||||
|
|
||||||
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
|
|
||||||
|
#include "CUnixPlatform.h"
|
||||||
|
typedef CUnixPlatform CPlatform;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,160 @@
|
||||||
|
#include "CUnixPlatform.h"
|
||||||
|
#include "CLog.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <pwd.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <syslog.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// CUnixPlatform
|
||||||
|
//
|
||||||
|
|
||||||
|
CUnixPlatform::CUnixPlatform()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
CUnixPlatform::~CUnixPlatform()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CUnixPlatform::installDaemon(/* FIXME */)
|
||||||
|
{
|
||||||
|
// daemons don't require special installation
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CUnixPlatform::uninstallDaemon(/* FIXME */)
|
||||||
|
{
|
||||||
|
// daemons don't require special installation
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CUnixPlatform::daemonize(const char* name)
|
||||||
|
{
|
||||||
|
// fork so shell thinks we're done and so we're not a process
|
||||||
|
// group leader
|
||||||
|
switch (fork()) {
|
||||||
|
case -1:
|
||||||
|
// failed
|
||||||
|
return false;
|
||||||
|
|
||||||
|
case 0:
|
||||||
|
// child
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
// parent exits
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// become leader of a new session
|
||||||
|
setsid();
|
||||||
|
|
||||||
|
// chdir to root so we don't keep mounted filesystems points busy
|
||||||
|
chdir("/");
|
||||||
|
|
||||||
|
// mask off permissions for any but owner
|
||||||
|
umask(077);
|
||||||
|
|
||||||
|
// close open files. we only expect stdin, stdout, stderr to be open.
|
||||||
|
close(0);
|
||||||
|
close(1);
|
||||||
|
close(2);
|
||||||
|
|
||||||
|
// attach file descriptors 0, 1, 2 to /dev/null so inadvertent use
|
||||||
|
// of standard I/O safely goes in the bit bucket.
|
||||||
|
open("/dev/null", O_RDONLY);
|
||||||
|
open("/dev/null", O_RDWR);
|
||||||
|
dup(1);
|
||||||
|
|
||||||
|
// hook up logger
|
||||||
|
setDaemonLogger(name);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* CUnixPlatform::getBasename(const char* pathname) const
|
||||||
|
{
|
||||||
|
if (pathname == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* basename = strrchr(pathname, '/');
|
||||||
|
if (basename != NULL) {
|
||||||
|
return basename + 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return pathname;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CUnixPlatform::getUserDirectory() const
|
||||||
|
{
|
||||||
|
// FIXME -- use geteuid? shouldn't run this setuid anyway.
|
||||||
|
struct passwd* pwent = getpwuid(getuid());
|
||||||
|
if (pwent != NULL && pwent->pw_dir != NULL) {
|
||||||
|
return pwent->pw_dir;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return CString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CUnixPlatform::getSystemDirectory() const
|
||||||
|
{
|
||||||
|
return "/etc";
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CUnixPlatform::addPathComponent(
|
||||||
|
const CString& prefix,
|
||||||
|
const CString& suffix) const
|
||||||
|
{
|
||||||
|
CString path;
|
||||||
|
path.reserve(prefix.size() + 1 + suffix.size());
|
||||||
|
path += prefix;
|
||||||
|
path += '/';
|
||||||
|
path += suffix;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CUnixPlatform::setDaemonLogger(const char* name)
|
||||||
|
{
|
||||||
|
openlog(name, 0, LOG_DAEMON);
|
||||||
|
CLog::setOutputter(&CUnixPlatform::deamonLogger);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CUnixPlatform::deamonLogger(
|
||||||
|
int priority, const char* msg)
|
||||||
|
{
|
||||||
|
// convert priority
|
||||||
|
switch (priority) {
|
||||||
|
case CLog::kFATAL:
|
||||||
|
case CLog::kERROR:
|
||||||
|
priority = LOG_ERR;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLog::kWARNING:
|
||||||
|
priority = LOG_WARNING;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLog::kNOTE:
|
||||||
|
priority = LOG_NOTICE;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case CLog::kINFO:
|
||||||
|
priority = LOG_INFO;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
priority = LOG_DEBUG;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// log it
|
||||||
|
syslog(priority, "%s", msg);
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
#ifndef CUNIXPLATFORM_H
|
||||||
|
#define CUNIXPLATFORM_H
|
||||||
|
|
||||||
|
#include "IPlatform.h"
|
||||||
|
|
||||||
|
class CUnixPlatform : public IPlatform {
|
||||||
|
public:
|
||||||
|
CUnixPlatform();
|
||||||
|
virtual ~CUnixPlatform();
|
||||||
|
|
||||||
|
// IPlatform overrides
|
||||||
|
virtual bool installDaemon(/* FIXME */);
|
||||||
|
virtual bool uninstallDaemon(/* FIXME */);
|
||||||
|
virtual bool daemonize(const char* name);
|
||||||
|
virtual const char* getBasename(const char* pathname) const;
|
||||||
|
virtual CString getUserDirectory() const;
|
||||||
|
virtual CString getSystemDirectory() const;
|
||||||
|
virtual CString addPathComponent(
|
||||||
|
const CString& prefix,
|
||||||
|
const CString& suffix) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual void setDaemonLogger(const char* name);
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void deamonLogger(int, const char*);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,90 @@
|
||||||
|
#include "CWin32Platform.h"
|
||||||
|
#include "CLog.h"
|
||||||
|
#include <string.h>
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
//
|
||||||
|
// CWin32Platform
|
||||||
|
//
|
||||||
|
|
||||||
|
CWin32Platform::CWin32Platform()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
CWin32Platform::~CWin32Platform()
|
||||||
|
{
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWin32Platform::installDaemon(/* FIXME */)
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWin32Platform::uninstallDaemon(/* FIXME */)
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CWin32Platform::daemonize(const char* name)
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* CWin32Platform::getBasename(const char* pathname) const
|
||||||
|
{
|
||||||
|
if (pathname == NULL) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for last /
|
||||||
|
const char* basename = strrchr(pathname, '/');
|
||||||
|
if (basename != NULL) {
|
||||||
|
++basename;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
basename = pathname;
|
||||||
|
}
|
||||||
|
|
||||||
|
// check for last backslash
|
||||||
|
const char* basename2 = strrchr(pathname, '\\');
|
||||||
|
if (basename2 != NULL && basename2 > basename) {
|
||||||
|
basename = basename2 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return basename;
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CWin32Platform::getUserDirectory() const
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
return CString();
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CWin32Platform::getSystemDirectory() const
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
CString CWin32Platform::addPathComponent(
|
||||||
|
const CString& prefix,
|
||||||
|
const CString& suffix) const
|
||||||
|
{
|
||||||
|
CString path;
|
||||||
|
path.reserve(prefix.size() + 1 + suffix.size());
|
||||||
|
path += prefix;
|
||||||
|
path += '\\';
|
||||||
|
path += suffix;
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CWin32Platform::serviceLogger(
|
||||||
|
int priority, const char* msg)
|
||||||
|
{
|
||||||
|
// FIXME
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
#ifndef CWIN32PLATFORM_H
|
||||||
|
#define CWIN32PLATFORM_H
|
||||||
|
|
||||||
|
#include "IPlatform.h"
|
||||||
|
|
||||||
|
class CWin32Platform : public IPlatform {
|
||||||
|
public:
|
||||||
|
CWin32Platform();
|
||||||
|
virtual ~CWin32Platform();
|
||||||
|
|
||||||
|
// IPlatform overrides
|
||||||
|
virtual bool installDaemon(/* FIXME */);
|
||||||
|
virtual bool uninstallDaemon(/* FIXME */);
|
||||||
|
virtual bool daemonize(const char* name);
|
||||||
|
virtual const char* getBasename(const char* pathname) const;
|
||||||
|
virtual CString getUserDirectory() const;
|
||||||
|
virtual CString getSystemDirectory() const;
|
||||||
|
virtual CString addPathComponent(
|
||||||
|
const CString& prefix,
|
||||||
|
const CString& suffix) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
static void serviceLogger(int, const char*);
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,45 @@
|
||||||
|
#ifndef IPLATFORM_H
|
||||||
|
#define IPLATFORM_H
|
||||||
|
|
||||||
|
#include "BasicTypes.h"
|
||||||
|
#include "CString.h"
|
||||||
|
#include "IInterface.h"
|
||||||
|
|
||||||
|
class IPlatform : public IInterface {
|
||||||
|
public:
|
||||||
|
// manipulators
|
||||||
|
|
||||||
|
// install/uninstall a daemon.
|
||||||
|
// FIXME -- throw on error? will get better error messages that way.
|
||||||
|
virtual bool installDaemon(/* FIXME */) = 0;
|
||||||
|
virtual bool uninstallDaemon(/* FIXME */) = 0;
|
||||||
|
|
||||||
|
// daemonize. this should have the side effect of sending log
|
||||||
|
// messages to a system message logger since messages can no
|
||||||
|
// longer go to the console. returns true iff successful.
|
||||||
|
// the name is the name of the daemon.
|
||||||
|
// FIXME -- win32 services will require a more complex interface
|
||||||
|
virtual bool daemonize(const char* name) = 0;
|
||||||
|
|
||||||
|
// accessors
|
||||||
|
|
||||||
|
// find the basename in the given pathname
|
||||||
|
virtual const char* getBasename(const char* pathname) const = 0;
|
||||||
|
|
||||||
|
// get the user's home directory. returns the empty string if
|
||||||
|
// this cannot be determined.
|
||||||
|
virtual CString getUserDirectory() const = 0;
|
||||||
|
|
||||||
|
// get the system configuration file directory
|
||||||
|
virtual CString getSystemDirectory() const = 0;
|
||||||
|
|
||||||
|
// concatenate pathname components with a directory separator
|
||||||
|
// between them. this should not check if the resulting path
|
||||||
|
// is longer than allowed by the system. we'll rely on the
|
||||||
|
// system calls to tell us that.
|
||||||
|
virtual CString addPathComponent(
|
||||||
|
const CString& prefix,
|
||||||
|
const CString& suffix) const = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
|
@ -0,0 +1,28 @@
|
||||||
|
DEPTH=..
|
||||||
|
include $(DEPTH)/Makecommon
|
||||||
|
|
||||||
|
#
|
||||||
|
# target file
|
||||||
|
#
|
||||||
|
TARGET = platform
|
||||||
|
|
||||||
|
#
|
||||||
|
# source files
|
||||||
|
#
|
||||||
|
LCXXINCS = \
|
||||||
|
-I$(DEPTH)/base \
|
||||||
|
-I$(DEPTH)/mt \
|
||||||
|
-I$(DEPTH)/synergy \
|
||||||
|
$(NULL)
|
||||||
|
CXXFILES = \
|
||||||
|
CPlatform.cpp \
|
||||||
|
CXWindowsClipboard.cpp \
|
||||||
|
CXWindowsScreen.cpp \
|
||||||
|
CXWindowsUtil.cpp \
|
||||||
|
$(NULL)
|
||||||
|
|
||||||
|
targets: $(LIBTARGET)
|
||||||
|
|
||||||
|
$(LIBTARGET): $(OBJECTS) $(DEPLIBS)
|
||||||
|
if test ! -d $(LIBDIR); then $(MKDIR) $(LIBDIR); fi
|
||||||
|
$(ARF) $(LIBTARGET) $(OBJECTS)
|
|
@ -4,7 +4,7 @@ include $(DEPTH)/Makecommon
|
||||||
#
|
#
|
||||||
# target file
|
# target file
|
||||||
#
|
#
|
||||||
TARGET = server
|
TARGET = synergyd
|
||||||
|
|
||||||
#
|
#
|
||||||
# source files
|
# source files
|
||||||
|
@ -16,6 +16,7 @@ LCXXINCS = \
|
||||||
-I$(DEPTH)/http \
|
-I$(DEPTH)/http \
|
||||||
-I$(DEPTH)/net \
|
-I$(DEPTH)/net \
|
||||||
-I$(DEPTH)/synergy \
|
-I$(DEPTH)/synergy \
|
||||||
|
-I$(DEPTH)/platform \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
CXXFILES = \
|
CXXFILES = \
|
||||||
CConfig.cpp \
|
CConfig.cpp \
|
||||||
|
@ -31,6 +32,7 @@ CXXFILES = \
|
||||||
# libraries we depend on
|
# libraries we depend on
|
||||||
#
|
#
|
||||||
DEPLIBS = \
|
DEPLIBS = \
|
||||||
|
$(LIBDIR)/libplatform.a \
|
||||||
$(LIBDIR)/libsynergy.a \
|
$(LIBDIR)/libsynergy.a \
|
||||||
$(LIBDIR)/libnet.a \
|
$(LIBDIR)/libnet.a \
|
||||||
$(LIBDIR)/libhttp.a \
|
$(LIBDIR)/libhttp.a \
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
#include "CLog.h"
|
#include "CLog.h"
|
||||||
#include "CMutex.h"
|
#include "CMutex.h"
|
||||||
#include "CNetwork.h"
|
#include "CNetwork.h"
|
||||||
|
#include "CPlatform.h"
|
||||||
#include "CThread.h"
|
#include "CThread.h"
|
||||||
#include "XThread.h"
|
#include "XThread.h"
|
||||||
#include "ProtocolTypes.h"
|
#include "ProtocolTypes.h"
|
||||||
|
@ -305,20 +306,13 @@ static void parse(int argc, char** argv)
|
||||||
|
|
||||||
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
{
|
{
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
|
// save instance
|
||||||
CMSWindowsScreen::init(instance);
|
CMSWindowsScreen::init(instance);
|
||||||
|
|
||||||
// get program name
|
// get program name
|
||||||
pname = strrchr(argv[0], '/');
|
pname = platform.getBasename(argv[0]);
|
||||||
if (pname == NULL) {
|
|
||||||
pname = argv[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++pname;
|
|
||||||
}
|
|
||||||
const char* pname2 = strrchr(argv[0], '\\');
|
|
||||||
if (pname2 != NULL && pname2 > pname) {
|
|
||||||
pname = pname2 + 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME -- direct CLog to MessageBox
|
// FIXME -- direct CLog to MessageBox
|
||||||
|
|
||||||
|
@ -360,98 +354,16 @@ int WINAPI WinMain(HINSTANCE instance, HINSTANCE, LPSTR, int)
|
||||||
|
|
||||||
#elif defined(CONFIG_PLATFORM_UNIX)
|
#elif defined(CONFIG_PLATFORM_UNIX)
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <unistd.h> // fork()
|
||||||
#include <string.h>
|
#include <sys/types.h> // wait()
|
||||||
#include <unistd.h>
|
#include <sys/wait.h> // wait()
|
||||||
#include <fcntl.h>
|
|
||||||
#include <pwd.h>
|
|
||||||
#include <syslog.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/wait.h>
|
|
||||||
|
|
||||||
static const char* s_configFileDefault = CONFIG_SYS_DIR CONFIG_NAME;
|
|
||||||
|
|
||||||
static void daemonize()
|
|
||||||
{
|
|
||||||
// fork so shell thinks we're done and so we're not a process
|
|
||||||
// group leader
|
|
||||||
switch (fork()) {
|
|
||||||
case -1:
|
|
||||||
// failed
|
|
||||||
log((CLOG_PRINT "failed to daemonize"));
|
|
||||||
exit(1);
|
|
||||||
|
|
||||||
case 0:
|
|
||||||
// child
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
// parent exits
|
|
||||||
exit(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
// become leader of a new session
|
|
||||||
setsid();
|
|
||||||
|
|
||||||
// chdir to root so we don't keep mounted filesystems points busy
|
|
||||||
chdir("/");
|
|
||||||
|
|
||||||
// mask off permissions for any but owner
|
|
||||||
umask(077);
|
|
||||||
|
|
||||||
// close open files. we only expect stdin, stdout, stderr to be open.
|
|
||||||
close(0);
|
|
||||||
close(1);
|
|
||||||
close(2);
|
|
||||||
|
|
||||||
// attach file descriptors 0, 1, 2 to /dev/null so inadvertent use
|
|
||||||
// of standard I/O safely goes in the bit bucket.
|
|
||||||
open("/dev/null", O_RDWR);
|
|
||||||
dup(0);
|
|
||||||
dup(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void syslogOutputter(int priority, const char* msg)
|
|
||||||
{
|
|
||||||
// convert priority
|
|
||||||
switch (priority) {
|
|
||||||
case CLog::kFATAL:
|
|
||||||
case CLog::kERROR:
|
|
||||||
priority = LOG_ERR;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLog::kWARNING:
|
|
||||||
priority = LOG_WARNING;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLog::kNOTE:
|
|
||||||
priority = LOG_NOTICE;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case CLog::kINFO:
|
|
||||||
priority = LOG_INFO;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
priority = LOG_DEBUG;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// log it
|
|
||||||
syslog(priority, "%s", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
CPlatform platform;
|
||||||
|
|
||||||
// get program name
|
// get program name
|
||||||
pname = strrchr(argv[0], '/');
|
pname = platform.getBasename(argv[0]);
|
||||||
if (pname == NULL) {
|
|
||||||
pname = argv[0];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
++pname;
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse command line
|
// parse command line
|
||||||
parse(argc, argv);
|
parse(argc, argv);
|
||||||
|
@ -461,32 +373,30 @@ int main(int argc, char** argv)
|
||||||
// get the user's home directory. use the effective user id
|
// get the user's home directory. use the effective user id
|
||||||
// so a user can't get a setuid root program to load his file.
|
// so a user can't get a setuid root program to load his file.
|
||||||
bool loaded = false;
|
bool loaded = false;
|
||||||
struct passwd* pwent = getpwuid(geteuid());
|
CString path = platform.getUserDirectory();
|
||||||
if (pwent != NULL && pwent->pw_dir != NULL) {
|
if (!path.empty()) {
|
||||||
// construct path if it isn't too long
|
// complete path
|
||||||
if (strlen(pwent->pw_dir) + strlen(CONFIG_NAME) + 2 <= PATH_MAX) {
|
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||||
char path[PATH_MAX];
|
|
||||||
strcpy(path, pwent->pw_dir);
|
|
||||||
strcat(path, "/");
|
|
||||||
strcat(path, CONFIG_NAME);
|
|
||||||
|
|
||||||
// now try loading the user's configuration
|
// now try loading the user's configuration
|
||||||
loaded = loadConfig(path, false);
|
loaded = loadConfig(path.c_str(), false);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (!loaded) {
|
if (!loaded) {
|
||||||
// try the system-wide config file
|
// try the system-wide config file
|
||||||
loadConfig(s_configFileDefault, false);
|
path = platform.getSystemDirectory();
|
||||||
|
if (!path.empty()) {
|
||||||
|
path = platform.addPathComponent(path, CONFIG_NAME);
|
||||||
|
loadConfig(path.c_str(), false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// daemonize if requested
|
// daemonize if requested
|
||||||
if (s_daemon) {
|
if (s_daemon) {
|
||||||
daemonize();
|
if (!platform.daemonize("synergyd")) {
|
||||||
|
log((CLOG_CRIT "failed to daemonize"));
|
||||||
// send log to syslog
|
return 16;
|
||||||
openlog("synergy", 0, LOG_DAEMON);
|
}
|
||||||
CLog::setOutputter(&syslogOutputter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// run the server. if running as a daemon then run it in a child
|
// run the server. if running as a daemon then run it in a child
|
||||||
|
|
|
@ -42,7 +42,7 @@ RSC=rc.exe
|
||||||
# PROP Intermediate_Dir "Release"
|
# PROP Intermediate_Dir "Release"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /c
|
||||||
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /I "..\http" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
# ADD CPP /nologo /MT /W4 /GX /O2 /I "..\base" /I "..\mt" /I "..\io" /I "..\http" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /FD /c
|
||||||
# SUBTRACT CPP /YX
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32
|
||||||
|
@ -68,7 +68,7 @@ LINK32=link.exe
|
||||||
# PROP Intermediate_Dir "Debug"
|
# PROP Intermediate_Dir "Debug"
|
||||||
# PROP Target_Dir ""
|
# PROP Target_Dir ""
|
||||||
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /YX /FD /GZ /c
|
||||||
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\base" /I "..\io" /I "..\mt" /I "..\net" /I "..\synergy" /I "..\http" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
# ADD CPP /nologo /MTd /W4 /Gm /GX /ZI /Od /I "..\base" /I "..\mt" /I "..\io" /I "..\http" /I "..\net" /I "..\synergy" /I "..\platform" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /FD /GZ /c
|
||||||
# SUBTRACT CPP /YX
|
# SUBTRACT CPP /YX
|
||||||
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32
|
||||||
|
|
22
synergy.dsw
22
synergy.dsw
|
@ -56,6 +56,9 @@ Package=<4>
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name synergy
|
Project_Dep_Name synergy
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name platform
|
||||||
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
@ -123,6 +126,18 @@ Package=<4>
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
Project: "platform"=.\platform\platform.dsp - Package Owner=<4>
|
||||||
|
|
||||||
|
Package=<5>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
Package=<4>
|
||||||
|
{{{
|
||||||
|
}}}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
Project: "server"=.\server\server.dsp - Package Owner=<4>
|
Project: "server"=.\server\server.dsp - Package Owner=<4>
|
||||||
|
|
||||||
Package=<5>
|
Package=<5>
|
||||||
|
@ -135,6 +150,9 @@ Package=<4>
|
||||||
Project_Dep_Name base
|
Project_Dep_Name base
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
Project_Dep_Name http
|
||||||
|
End Project Dependency
|
||||||
|
Begin Project Dependency
|
||||||
Project_Dep_Name io
|
Project_Dep_Name io
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
|
@ -147,10 +165,10 @@ Package=<4>
|
||||||
Project_Dep_Name synergy
|
Project_Dep_Name synergy
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name makehook
|
Project_Dep_Name platform
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
Begin Project Dependency
|
Begin Project Dependency
|
||||||
Project_Dep_Name http
|
Project_Dep_Name makehook
|
||||||
End Project Dependency
|
End Project Dependency
|
||||||
}}}
|
}}}
|
||||||
|
|
||||||
|
|
|
@ -21,9 +21,6 @@ CXXFILES = \
|
||||||
CProtocolUtil.cpp \
|
CProtocolUtil.cpp \
|
||||||
CClipboard.cpp \
|
CClipboard.cpp \
|
||||||
CTCPSocketFactory.cpp \
|
CTCPSocketFactory.cpp \
|
||||||
CXWindowsClipboard.cpp \
|
|
||||||
CXWindowsScreen.cpp \
|
|
||||||
CXWindowsUtil.cpp \
|
|
||||||
XScreen.cpp \
|
XScreen.cpp \
|
||||||
XSynergy.cpp \
|
XSynergy.cpp \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
@ -95,14 +95,6 @@ SOURCE=.\CInputPacketStream.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\CMSWindowsClipboard.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CMSWindowsScreen.cpp
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\COutputPacketStream.cpp
|
SOURCE=.\COutputPacketStream.cpp
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
@ -139,14 +131,6 @@ SOURCE=.\ClipboardTypes.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
||||||
SOURCE=.\CMSWindowsClipboard.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\CMSWindowsScreen.h
|
|
||||||
# End Source File
|
|
||||||
# Begin Source File
|
|
||||||
|
|
||||||
SOURCE=.\COutputPacketStream.h
|
SOURCE=.\COutputPacketStream.h
|
||||||
# End Source File
|
# End Source File
|
||||||
# Begin Source File
|
# Begin Source File
|
||||||
|
|
145
test.cpp
145
test.cpp
|
@ -1,145 +0,0 @@
|
||||||
#include "CTCPSocket.h"
|
|
||||||
#include "CTCPListenSocket.h"
|
|
||||||
#include "CNetworkAddress.h"
|
|
||||||
#include "IInputStream.h"
|
|
||||||
#include "IOutputStream.h"
|
|
||||||
#include "CThread.h"
|
|
||||||
#include "CFunctionJob.h"
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
//
|
|
||||||
// test
|
|
||||||
//
|
|
||||||
|
|
||||||
SInt16 port = 50000;
|
|
||||||
|
|
||||||
static void thread1(void*)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
fprintf(stdout, "client started\n");
|
|
||||||
CThread::sleep(1.0);
|
|
||||||
CNetworkAddress addr("127.0.0.1", port);
|
|
||||||
|
|
||||||
fprintf(stdout, "client connecting\n");
|
|
||||||
CTCPSocket* socket = new CTCPSocket;
|
|
||||||
socket->connect(addr);
|
|
||||||
|
|
||||||
fprintf(stdout, "client connected (%p). waiting.\n", socket);
|
|
||||||
CThread::sleep(2.0);
|
|
||||||
|
|
||||||
fprintf(stdout, "client sending message\n");
|
|
||||||
static const char msg[] = "message from client\n";
|
|
||||||
socket->getOutputStream()->write(msg, sizeof(msg) - 1);
|
|
||||||
socket->getOutputStream()->flush();
|
|
||||||
|
|
||||||
fprintf(stdout, "client waiting for reply\n");
|
|
||||||
UInt8 buffer[4096];
|
|
||||||
UInt32 n;
|
|
||||||
do {
|
|
||||||
n = socket->getInputStream()->read(buffer, sizeof(buffer) - 1);
|
|
||||||
buffer[n] = 0;
|
|
||||||
fprintf(stdout, "%s", buffer);
|
|
||||||
} while (n == 0 && memchr(buffer, '\n', n) == NULL);
|
|
||||||
|
|
||||||
fprintf(stdout, "client closing\n");
|
|
||||||
socket->close();
|
|
||||||
delete socket;
|
|
||||||
fprintf(stdout, "client terminating\n");
|
|
||||||
}
|
|
||||||
catch (XBase& e) {
|
|
||||||
fprintf(stderr, "exception: %s\n", e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void thread2(void*)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
fprintf(stdout, "server started\n");
|
|
||||||
CNetworkAddress addr("127.0.0.1", port);
|
|
||||||
CTCPListenSocket listenSocket;
|
|
||||||
listenSocket.bind(addr);
|
|
||||||
|
|
||||||
fprintf(stdout, "server accepting\n");
|
|
||||||
ISocket* socket = listenSocket.accept();
|
|
||||||
fprintf(stdout, "server accepted %p\n", socket);
|
|
||||||
|
|
||||||
UInt8 buffer[4096];
|
|
||||||
UInt32 n;
|
|
||||||
do {
|
|
||||||
n = socket->getInputStream()->read(buffer, sizeof(buffer) - 1);
|
|
||||||
buffer[n] = 0;
|
|
||||||
fprintf(stdout, "%s", buffer);
|
|
||||||
} while (n == 0 && memchr(buffer, '\n', n) == NULL);
|
|
||||||
|
|
||||||
fprintf(stdout, "server replying\n");
|
|
||||||
static const char reply[] = "data received\n";
|
|
||||||
socket->getOutputStream()->write(reply, sizeof(reply) - 1);
|
|
||||||
|
|
||||||
fprintf(stdout, "server closing\n");
|
|
||||||
socket->close();
|
|
||||||
delete socket;
|
|
||||||
fprintf(stdout, "server terminating\n");
|
|
||||||
}
|
|
||||||
catch (XBase& e) {
|
|
||||||
fprintf(stderr, "exception: %s\n", e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void thread3(void*)
|
|
||||||
{
|
|
||||||
try {
|
|
||||||
fprintf(stdout, "### looking up address\n");
|
|
||||||
CNetworkAddress addr("www.google.com", 80);
|
|
||||||
|
|
||||||
fprintf(stdout, "### connecting\n");
|
|
||||||
CTCPSocket* socket = new CTCPSocket;
|
|
||||||
socket->connect(addr);
|
|
||||||
|
|
||||||
fprintf(stdout, "### sending message\n");
|
|
||||||
static const char msg[] = "GET / HTTP/1.0\nAccept: */*\n\n";
|
|
||||||
socket->getOutputStream()->write(msg, sizeof(msg) - 1);
|
|
||||||
socket->getOutputStream()->flush();
|
|
||||||
socket->getOutputStream()->close();
|
|
||||||
|
|
||||||
fprintf(stdout, "### waiting for reply\n");
|
|
||||||
UInt8 buffer[4096];
|
|
||||||
UInt32 n;
|
|
||||||
do {
|
|
||||||
n = socket->getInputStream()->read(buffer, sizeof(buffer) - 1);
|
|
||||||
buffer[n] = 0;
|
|
||||||
fprintf(stdout, "%s", buffer);
|
|
||||||
} while (n != 0);
|
|
||||||
|
|
||||||
fprintf(stdout, "### closing\n");
|
|
||||||
socket->close();
|
|
||||||
delete socket;
|
|
||||||
fprintf(stdout, "### terminating\n");
|
|
||||||
}
|
|
||||||
catch (XBase& e) {
|
|
||||||
fprintf(stderr, "### exception: %s\n", e.what());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
if (argc > 1) {
|
|
||||||
port = (SInt16)atoi(argv[1]);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stdout, "starting threads\n");
|
|
||||||
CThread t1(new CFunctionJob(thread1));
|
|
||||||
CThread t2(new CFunctionJob(thread2));
|
|
||||||
|
|
||||||
fprintf(stdout, "waiting for threads\n");
|
|
||||||
t1.wait();
|
|
||||||
t2.wait();
|
|
||||||
fprintf(stdout, "threads finished\n");
|
|
||||||
*/
|
|
||||||
int tick = 0;
|
|
||||||
CThread t3(new CFunctionJob(thread3));
|
|
||||||
while (!t3.wait(0.1)) {
|
|
||||||
fprintf(stdout, "$$$ %d\n", ++tick);
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
Loading…
Reference in New Issue