diff --git a/CMakeLists.txt b/CMakeLists.txt index 60544139..6a6ba6f3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,7 +109,7 @@ endif() # FIND SQLITE3 if (ENABLE_SQLITE3) - if (NOT CMAKE_COMPILER_IS_GNUCXX) + if (MSVC) ADD_SUBDIRECTORY(${CMAKE_SOURCE_DIR}/msvc-deps) else() if (WIN32) @@ -248,6 +248,16 @@ if(ENABLE_TESTS) endif() endif() +if (APPLE) + FIND_LIBRARY(IOKIT_FRAMEWORK IOKit) + FIND_LIBRARY(SECURITY_FRAMEWORK Security) + FIND_LIBRARY(APPKIT_FRAMEWORK AppKit) + FIND_LIBRARY(SYSTEMCONFIGURATION_FRAMEWORK SystemConfiguration) + FIND_LIBRARY(SECURITYINTERFACE_FRAMEWORK SecurityInterface) + MARK_AS_ADVANCED(IOKIT_FRAMEWORK APPKIT_FRAMEWORK SYSTEMCONFIGURATION_FRAMEWORK SECURITY_FRAMEWORK SECURITYINTERFACE_FRAMEWORK) + SET (APPLE_FRAMEWORKS ${IOKIT_FRAMEWORK} ${APPKIT_FRAMEWORK} ${SYSTEMCONFIGURATION_FRAMEWORK} ${SECURITY_FRAMEWORK} ${SECURITYINTERFACE_FRAMEWORK}) +endif() + message(" Supported features") message("-----------------------") diff --git a/backends/skype/main.cpp b/backends/skype/main.cpp index 5d603d36..17c5ac6f 100644 --- a/backends/skype/main.cpp +++ b/backends/skype/main.cpp @@ -1,4 +1,6 @@ #include "glib.h" +#include +#include "sqlite3.h" #include #include "transport/config.h" @@ -20,16 +22,15 @@ #ifndef __FreeBSD__ #include "malloc.h" #endif -#include -#include "sqlite3.h" +#include "skype.h" DEFINE_LOGGER(logger, "backend"); using namespace Transport; -class SpectrumNetworkPlugin; +class SkypePlugin; #define GET_RESPONSE_DATA(RESP, DATA) ((RESP.find(std::string(DATA) + " ") != std::string::npos) ? RESP.substr(RESP.find(DATA) + strlen(DATA) + 1) : ""); #define GET_PROPERTY(VAR, OBJ, WHICH, PROP) std::string VAR = sk->send_command(std::string("GET ") + OBJ + " " + WHICH + " " + PROP); \ @@ -70,7 +71,7 @@ class SpectrumNetworkPlugin; LOG4CXX_ERROR(logger, NAME<< (sqlite3_errmsg(db) == NULL ? "" : sqlite3_errmsg(db)));\ } -SpectrumNetworkPlugin *np; +SkypePlugin *np; int m_sock; static int writeInput; @@ -97,50 +98,14 @@ static pbnetwork::StatusType getStatus(const std::string &st) { return status; } -class Skype { +class SkypePlugin : public NetworkPlugin { public: - Skype(const std::string &user, const std::string &username, const std::string &password); - ~Skype() { LOG4CXX_INFO(logger, "Skype instance desctuctor"); logout(); } - void login(); - void logout(); - std::string send_command(const std::string &message); - - const std::string &getUser() { - return m_user; - } - - const std::string &getUsername() { - return m_username; - } - - bool createDBusProxy(); - bool loadSkypeBuddies(); - - int getPid() { - return (int) m_pid; - } - - private: - std::string m_username; - std::string m_password; - GPid m_pid; - DBusGConnection *m_connection; - DBusGProxy *m_proxy; - std::string m_user; - int m_timer; - int m_counter; - int fd_output; - std::map m_groups; -}; - -class SpectrumNetworkPlugin : public NetworkPlugin { - public: - SpectrumNetworkPlugin(Config *config, const std::string &host, int port) : NetworkPlugin() { + SkypePlugin(Config *config, const std::string &host, int port) : NetworkPlugin() { this->config = config; LOG4CXX_INFO(logger, "Starting the backend."); } - ~SpectrumNetworkPlugin() { + ~SkypePlugin() { for (std::map::iterator it = m_accounts.begin(); it != m_accounts.end(); it++) { delete (*it).first; } @@ -153,7 +118,7 @@ class SpectrumNetworkPlugin : public NetworkPlugin { } LOG4CXX_INFO(logger, "Creating account with name '" << name << "'"); - Skype *skype = new Skype(user, name, password); + Skype *skype = new Skype(this, user, name, password); m_sessions[user] = skype; m_accounts[skype] = user; @@ -391,495 +356,6 @@ class SpectrumNetworkPlugin : public NetworkPlugin { }; -Skype::Skype(const std::string &user, const std::string &username, const std::string &password) { - m_username = username; - m_user = user; - m_password = password; - m_pid = 0; - m_connection = 0; - m_proxy = 0; - m_timer = -1; - m_counter = 0; -} - - -static gboolean load_skype_buddies(gpointer data) { - Skype *skype = (Skype *) data; - return skype->loadSkypeBuddies(); -} - -bool Skype::createDBusProxy() { - if (m_proxy == NULL) { - LOG4CXX_INFO(logger, "Creating DBus proxy for com.Skype.Api."); - m_counter++; - - GError *error = NULL; - m_proxy = dbus_g_proxy_new_for_name_owner (m_connection, "com.Skype.API", "/com/Skype", "com.Skype.API", &error); - if (m_proxy == NULL && error != NULL) { - LOG4CXX_INFO(logger, m_username << ":" << error->message); - - if (m_counter == 15) { - LOG4CXX_ERROR(logger, "Logging out, proxy couldn't be created: " << error->message); - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, error->message); - logout(); - g_error_free(error); - return FALSE; - } - g_error_free(error); - } - - if (m_proxy) { - LOG4CXX_INFO(logger, "Proxy created."); - DBusObjectPathVTable vtable; - vtable.message_function = &skype_notify_handler; - dbus_connection_register_object_path(dbus_g_connection_get_connection(m_connection), "/com/Skype/Client", &vtable, this); - - m_counter = 0; - m_timer = g_timeout_add_seconds(1, load_skype_buddies, this); - return FALSE; - } - return TRUE; - } - return FALSE; -} - -static gboolean create_dbus_proxy(gpointer data) { - Skype *skype = (Skype *) data; - return skype->createDBusProxy(); -} - -void Skype::login() { - if (m_username.find("..") == 0 || m_username.find("/") != std::string::npos) { - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Invalid username"); - return; - } - boost::filesystem::remove_all(std::string("/tmp/skype/") + m_username); - - boost::filesystem::path path(std::string("/tmp/skype/") + m_username); - if (!boost::filesystem::exists(path)) { - boost::filesystem::create_directories(path); - boost::filesystem::path path2(std::string("/tmp/skype/") + m_username + "/" + m_username ); - boost::filesystem::create_directories(path2); - } - - std::string shared_xml = "\n" - "(time(NULL)) + ".0\">\n" - "\n" - "2\n" - "en\n" - "\n" - "\n"; - g_file_set_contents(std::string(std::string("/tmp/skype/") + m_username + "/shared.xml").c_str(), shared_xml.c_str(), -1, NULL); - - std::string config_xml = "\n" - "(time(NULL)) + ".0\">\n" - "\n" - "\n" - "30000000\n" - "300000000\n" - "" + boost::lexical_cast(time(NULL)) + "\n" - "\n" - "\n" - "\n" - "\n" - "Spectrum\n" - "\n" - "\n" - "\n" - "\n"; - g_file_set_contents(std::string(std::string("/tmp/skype/") + m_username + "/" + m_username +"/config.xml").c_str(), config_xml.c_str(), -1, NULL); - - sleep(1); - std::string db_path = std::string("/tmp/skype/") + m_username; - char *db = (char *) malloc(db_path.size() + 1); - strcpy(db, db_path.c_str()); - LOG4CXX_INFO(logger, m_username << ": Spawning new Skype instance dbpath=" << db); - gchar* argv[6] = {"skype", "--disable-cleanlooks", "--pipelogin", "--dbpath", db, 0}; - - int fd; - GError *error = NULL; - bool spawned = g_spawn_async_with_pipes(NULL, - argv, - NULL /*envp*/, - G_SPAWN_SEARCH_PATH, - NULL /*child_setup*/, - NULL /*user_data*/, - &m_pid /*child_pid*/, - &fd, - NULL, - &fd_output, - &error); - - if (!spawned) { - LOG4CXX_ERROR(logger, "Error spawning the Skype instance: " << error->message) - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Error spawning the Skype instance."); - return; - } - - std::string login_data = std::string(m_username + " " + m_password + "\n"); - LOG4CXX_INFO(logger, m_username << ": Login data=" << m_username); - write(fd, login_data.c_str(), login_data.size()); - close(fd); - - fcntl (fd_output, F_SETFL, O_NONBLOCK); - - free(db); - - //Initialise threading - dbus_threads_init_default(); - - if (m_connection == NULL) - { - LOG4CXX_INFO(logger, "Creating DBUS connection."); - GError *error = NULL; - m_connection = dbus_g_bus_get (DBUS_BUS_SESSION, &error); - if (m_connection == NULL && error != NULL) - { - LOG4CXX_INFO(logger, m_username << ": Creating DBUS Connection error: " << error->message); - g_error_free(error); - return; - } - } - - sleep(1); - m_timer = g_timeout_add_seconds(1, create_dbus_proxy, this); -} - -bool Skype::loadSkypeBuddies() { -// std::string re = "CONNSTATUS OFFLINE"; -// while (re == "CONNSTATUS OFFLINE" || re.empty()) { -// sleep(1); - - gchar buffer[1024]; - int bytes_read = read(fd_output, buffer, 1023); - if (bytes_read > 0) { - buffer[bytes_read] = 0; - std::string b(buffer); - LOG4CXX_WARN(logger, "Skype wrote this on stdout '" << b << "'"); - if (b.find("Incorrect Password") != std::string::npos) { - LOG4CXX_INFO(logger, "Incorrect password, logging out") - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_FAILED, "Incorrect password"); - close(fd_output); - logout(); - return FALSE; - } - } - - std::string re = send_command("NAME Spectrum"); - if (m_counter++ > 15) { - LOG4CXX_ERROR(logger, "Logging out, because we tried to connect the Skype over DBUS 15 times without success"); - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready. This issue have been logged and admins will check it and try to fix it soon."); - close(fd_output); - logout(); - return FALSE; - } - - if (re.empty() || re == "CONNSTATUS OFFLINE" || re == "ERROR 68") { - return TRUE; - } - - close(fd_output); - - if (send_command("PROTOCOL 7") != "PROTOCOL 7") { - LOG4CXX_ERROR(logger, "PROTOCOL 7 failed, logging out"); - np->handleDisconnected(m_user, pbnetwork::CONNECTION_ERROR_AUTHENTICATION_IMPOSSIBLE, "Skype is not ready. This issue have been logged and admins will check it and try to fix it soon."); - logout(); - return FALSE; - } - - np->handleConnected(m_user); - - std::map group_map; - std::string groups = send_command("SEARCH GROUPS CUSTOM"); - if (groups.find(' ') != std::string::npos) { - groups = groups.substr(groups.find(' ') + 1); - std::vector grps; - boost::split(grps, groups, boost::is_any_of(",")); - BOOST_FOREACH(std::string grp, grps) { - std::vector data; - std::string name = send_command("GET GROUP " + grp + " DISPLAYNAME"); - - if (name.find("ERROR") == 0) { - continue; - } - - boost::split(data, name, boost::is_any_of(" ")); - name = GET_RESPONSE_DATA(name, "DISPLAYNAME"); - - std::string users = send_command("GET GROUP " + data[1] + " USERS"); - try { - users = GET_RESPONSE_DATA(users, "USERS"); - } - catch (std::out_of_range& oor) { - continue; - } - boost::split(data, users, boost::is_any_of(",")); - BOOST_FOREACH(std::string u, data) { - group_map[u] = grp; - } - } - } - - std::string friends = send_command("GET AUTH_CONTACTS_PROFILES"); - - char **full_friends_list = g_strsplit((strchr(friends.c_str(), ' ')+1), ";", 0); - if (full_friends_list && full_friends_list[0]) - { - //in the format of: username;full name;phone;office phone;mobile phone; - // online status;friendly name;voicemail;mood - // (comma-seperated lines, usernames can have comma's) - - for (int i=0; full_friends_list[i] && full_friends_list[i+1] && *full_friends_list[i] != '\0'; i+=8) - { - std::string buddy = full_friends_list[i]; - - if (buddy[0] == ',') { - buddy.erase(buddy.begin()); - } - - if (buddy.rfind(",") != std::string::npos) { - buddy = buddy.substr(buddy.rfind(",")); - } - - if (buddy[0] == ',') { - buddy.erase(buddy.begin()); - } - - LOG4CXX_INFO(logger, "Got buddy " << buddy); - std::string st = full_friends_list[i + 5]; - - pbnetwork::StatusType status = getStatus(st); - - std::string alias = full_friends_list[i + 6]; - - std::string mood_text = ""; - if (full_friends_list[i + 8] && *full_friends_list[i + 8] != '\0' && *full_friends_list[i + 8] != ',') { - mood_text = full_friends_list[i + 8]; - } - - std::vector groups; - if (group_map.find(buddy) != group_map.end()) { - groups.push_back(group_map[buddy]); - } - np->handleBuddyChanged(m_user, buddy, alias, groups, status, mood_text); - } - } - g_strfreev(full_friends_list); - - send_command("SET AUTOAWAY OFF"); - send_command("SET USERSTATUS ONLINE"); - return FALSE; -} - -void Skype::logout() { - if (m_pid != 0) { - if (m_proxy) { - send_command("SET USERSTATUS INVISIBLE"); - send_command("SET USERSTATUS OFFLINE"); - sleep(2); - g_object_unref(m_proxy); - } - LOG4CXX_INFO(logger, m_username << ": Terminating Skype instance (SIGTERM)"); - kill((int) m_pid, SIGTERM); - // Give skype a chance - sleep(2); - LOG4CXX_INFO(logger, m_username << ": Killing Skype instance (SIGKILL)"); - kill((int) m_pid, SIGKILL); - m_pid = 0; - } -} - -std::string Skype::send_command(const std::string &message) { - GError *error = NULL; - gchar *str = NULL; -// int message_num; -// gchar error_return[30]; - - LOG4CXX_INFO(logger, "Sending: '" << message << "'"); - if (!dbus_g_proxy_call (m_proxy, "Invoke", &error, G_TYPE_STRING, message.c_str(), G_TYPE_INVALID, - G_TYPE_STRING, &str, G_TYPE_INVALID)) - { - if (error && error->message) - { - LOG4CXX_INFO(logger, m_username << ": DBUS Error: " << error->message); - g_error_free(error); - return ""; - } else { - LOG4CXX_INFO(logger, m_username << ": DBUS no response"); - return ""; - } - - } - if (str != NULL) - { - LOG4CXX_INFO(logger, m_username << ": DBUS:'" << str << "'"); - } - return str ? std::string(str) : std::string(); -} - -static void handle_skype_message(std::string &message, Skype *sk) { - std::vector cmd; - boost::split(cmd, message, boost::is_any_of(" ")); - - if (cmd[0] == "USER") { - if (cmd[1] == sk->getUsername()) { - return; - } - - if (cmd[2] == "ONLINESTATUS") { - if (cmd[3] == "SKYPEOUT" || cmd[3] == "UNKNOWN") { - return; - } - else { - pbnetwork::StatusType status = getStatus(cmd[3]); - GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT"); - GET_PROPERTY(alias, "USER", cmd[1], "FULLNAME"); - - std::vector groups; - np->handleBuddyChanged(sk->getUser(), cmd[1], alias, groups, status, mood_text); - } - } - else if (cmd[2] == "MOOD_TEXT") { - GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS"); - pbnetwork::StatusType status = getStatus(st); - - std::string mood_text = GET_RESPONSE_DATA(message, "MOOD_TEXT"); - - std::vector groups; - np->handleBuddyChanged(sk->getUser(), cmd[1], "", groups, status, mood_text); - } - else if (cmd[2] == "BUDDYSTATUS" && cmd[3] == "3") { - GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT"); - GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS"); - pbnetwork::StatusType status = getStatus(st); - - std::vector groups; - np->handleBuddyChanged(sk->getUser(), cmd[1], "", groups, status, mood_text); - } - else if (cmd[2] == "FULLNAME") { - GET_PROPERTY(alias, "USER", cmd[1], "FULLNAME"); - GET_PROPERTY(mood_text, "USER", cmd[1], "MOOD_TEXT"); - GET_PROPERTY(st, "USER", cmd[1], "ONLINESTATUS"); - pbnetwork::StatusType status = getStatus(st); - - std::vector groups; - np->handleBuddyChanged(sk->getUser(), cmd[1], alias, groups, status, mood_text); - } - else if(cmd[2] == "RECEIVEDAUTHREQUEST") { - np->handleAuthorization(sk->getUser(), cmd[1]); - } - } - else if (cmd[0] == "GROUP") { -// if (cmd[2] == "DISPLAYNAME") { -// //GROUP 810 DISPLAYNAME My Friends -// std::string grp = GET_RESPONSE_DATA(message, "DISPLAYNAME"); -// std::string users = sk->send_command("GET GROUP " + cmd[1] + " USERS"); -// try { -// users = GET_RESPONSE_DATA(users, "USERS"); -// } -// catch (std::out_of_range& oor) { -// return; -// } -// -// std::vector data; -// boost::split(data, users, boost::is_any_of(",")); -// BOOST_FOREACH(std::string u, data) { -// GET_PROPERTY(alias, "USER", u, "FULLNAME"); -// GET_PROPERTY(mood_text, "USER", u, "MOOD_TEXT"); -// GET_PROPERTY(st, "USER", u, "ONLINESTATUS"); -// pbnetwork::StatusType status = getStatus(st); -// -// std::vector groups; -// groups.push_back(grp); -// np->handleBuddyChanged(sk->getUser(), u, alias, groups, status, mood_text); -// } -// } - if (cmd[2] == "NROFUSERS" && cmd[3] != "0") { - GET_PROPERTY(grp, "GROUP", cmd[1], "DISPLAYNAME"); - std::string users = sk->send_command("GET GROUP " + cmd[1] + " USERS"); - try { - users = GET_RESPONSE_DATA(users, "USERS"); - } - catch (std::out_of_range& oor) { - return; - } - - std::vector data; - boost::split(data, users, boost::is_any_of(",")); - BOOST_FOREACH(std::string u, data) { - GET_PROPERTY(alias, "USER", u, "FULLNAME"); - GET_PROPERTY(mood_text, "USER", u, "MOOD_TEXT"); - GET_PROPERTY(st, "USER", u, "ONLINESTATUS"); - pbnetwork::StatusType status = getStatus(st); - - std::vector groups; - groups.push_back(grp); - np->handleBuddyChanged(sk->getUser(), u, alias, groups, status, mood_text); - } - } - } - else if (cmd[0] == "CHATMESSAGE") { - if (cmd[3] == "RECEIVED") { - GET_PROPERTY(body, "CHATMESSAGE", cmd[1], "BODY"); - GET_PROPERTY(from_handle, "CHATMESSAGE", cmd[1], "FROM_HANDLE"); - - if (from_handle == sk->getUsername()) - return; - - np->handleMessage(sk->getUser(), from_handle, body); - - sk->send_command("SET CHATMESSAGE " + cmd[1] + " SEEN"); - } - } - else if (cmd[0] == "CALL") { - // CALL 884 STATUS RINGING - if (cmd[2] == "STATUS") { - if (cmd[3] == "RINGING" || cmd[3] == "MISSED") { - // handle only incoming calls - GET_PROPERTY(type, "CALL", cmd[1], "TYPE"); - if (type.find("INCOMING") != 0) { - return; - } - - GET_PROPERTY(from, "CALL", cmd[1], "PARTNER_HANDLE"); - GET_PROPERTY(dispname, "CALL", cmd[1], "PARTNER_DISPNAME"); - - if (cmd[3] == "RINGING") { - np->handleMessage(sk->getUser(), from, "User " + dispname + " is calling you."); - } - else { - np->handleMessage(sk->getUser(), from, "You have missed call from user " + dispname + "."); - } - } - } - } -} - -DBusHandlerResult skype_notify_handler(DBusConnection *connection, DBusMessage *message, gpointer user_data) { - DBusMessageIter iterator; - gchar *message_temp; - DBusMessage *temp_message; - - temp_message = dbus_message_ref(message); - dbus_message_iter_init(temp_message, &iterator); - if (dbus_message_iter_get_arg_type(&iterator) != DBUS_TYPE_STRING) - { - dbus_message_unref(message); - return (DBusHandlerResult) FALSE; - } - - do { - dbus_message_iter_get_basic(&iterator, &message_temp); - std::string m(message_temp); - LOG4CXX_INFO(logger,"DBUS message: " << m); - handle_skype_message(m, (Skype *) user_data); - } while(dbus_message_iter_has_next(&iterator) && dbus_message_iter_next(&iterator)); - - dbus_message_unref(message); - - return DBUS_HANDLER_RESULT_HANDLED; -} - static void spectrum_sigchld_handler(int sig) { int status; @@ -968,6 +444,7 @@ int main(int argc, char **argv) { Logging::initBackendLogging(cfg); g_type_init(); + m_sock = create_socket(host.c_str(), port); @@ -978,7 +455,9 @@ int main(int argc, char **argv) { channel = g_io_channel_unix_new(m_sock); g_io_add_watch_full(channel, G_PRIORITY_DEFAULT, cond, transportDataReceived, NULL, io_destroy); - np = new SpectrumNetworkPlugin(cfg, host, port); + dbus_threads_init_default(); + + np = new SkypePlugin(cfg, host, port); GMainLoop *m_loop; m_loop = g_main_loop_new(NULL, FALSE); diff --git a/backends/swiften/main.cpp b/backends/swiften/main.cpp index 93137352..3ccc632e 100644 --- a/backends/swiften/main.cpp +++ b/backends/swiften/main.cpp @@ -17,9 +17,11 @@ #endif #ifndef __FreeBSD__ +#ifndef __MACH__ // malloc_trim #include "malloc.h" #endif +#endif // Boost #include @@ -189,9 +191,11 @@ class SwiftenPlugin : public NetworkPlugin { #ifndef WIN32 #ifndef __FreeBSD__ +#ifndef __MACH__ // force returning of memory chunks allocated by libxml2 to kernel malloc_trim(0); #endif +#endif #endif } @@ -220,6 +224,10 @@ class SwiftenPlugin : public NetworkPlugin { return; } + if (presence->getPayload() != NULL || presence->getPayload() != NULL) { + return; + } + LOG4CXX_INFO(logger, user << ": " << presence->getFrom().toBare().toString() << " presence changed"); std::string message = presence->getStatus(); @@ -299,7 +307,6 @@ class SwiftenPlugin : public NetworkPlugin { client->getPresenceOracle()->onPresenceChange.disconnect(boost::bind(&SwiftenPlugin::handleSwiftPresenceChanged, this, user, _1)); client->disconnect(); m_mucs.erase(user); - m_users.erase(user); } } @@ -314,7 +321,7 @@ class SwiftenPlugin : public NetworkPlugin { if (client->getMUCRegistry()->isMUC(legacyName)) { message->setType(Swift::Message::Groupchat); boost::shared_ptr muc = m_mucs[user][legacyName]; - handleMessage(user, legacyName, msg, muc->getNickname(), xhtml); +// handleMessage(user, legacyName, msg, muc->getNickname(), xhtml); } client->sendMessage(message); diff --git a/include/transport/memoryusage.h b/include/transport/memoryusage.h index 563d0e93..605dd157 100644 --- a/include/transport/memoryusage.h +++ b/include/transport/memoryusage.h @@ -24,12 +24,10 @@ #ifndef WIN32 #include "signal.h" +#else +#define pid_t void* #endif namespace Transport { - -#ifndef WIN32 void process_mem_usage(double& shared, double& resident_set, pid_t pid = 0); -#endif - } diff --git a/include/transport/protocol.proto b/include/transport/protocol.proto index 796b656c..4e47ea6a 100644 --- a/include/transport/protocol.proto +++ b/include/transport/protocol.proto @@ -95,6 +95,10 @@ enum ParticipantFlag { PARTICIPANT_FLAG_NOT_AUTHORIZED = 8; PARTICIPANT_FLAG_ME = 16; PARTICIPANT_FLAG_KICKED = 32; + PARTICIPANT_FLAG_VISITOR = 64; + PARTICIPANT_FLAG_MEMBER = 128; + PARTICIPANT_FLAG_ADMIN = 256; + PARTICIPANT_FLAG_OWNER = 512; } message Participant { diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index 176c618d..ed5d9b51 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -28,8 +28,10 @@ #include #include "libgen.h" #ifndef __FreeBSD__ +#ifndef __MACH__ #include #endif +#endif #else #include #define getpid _getpid @@ -308,10 +310,12 @@ int main(int argc, char **argv) setlocale(LC_ALL, ""); #ifndef WIN32 #ifndef __FreeBSD__ +#ifndef __MACH__ mallopt(M_CHECK_ACTION, 2); mallopt(M_PERTURB, 0xb); #endif #endif +#endif #ifndef WIN32 if (signal(SIGINT, spectrum_sigint_handler) == SIG_ERR) { diff --git a/spectrum_manager/src/CMakeLists.txt b/spectrum_manager/src/CMakeLists.txt index a9a9ffc6..53b4e41e 100644 --- a/spectrum_manager/src/CMakeLists.txt +++ b/spectrum_manager/src/CMakeLists.txt @@ -7,7 +7,10 @@ ADD_DEPENDENCIES(spectrum2_manager pb) SET_SOURCE_FILES_PROPERTIES(${CMAKE_CURRENT_SOURCE_DIR}/../../include/transport/protocol.pb.cc PROPERTIES GENERATED 1) target_link_libraries(spectrum2_manager ${SWIFTEN_LIBRARY} ${PROTOBUF_LIBRARIES}) - + +if(APPLE) +target_link_libraries(spectrum2_manager ${APPLE_FRAMEWORKS}) +endif() INSTALL(TARGETS spectrum2_manager RUNTIME DESTINATION bin) INSTALL(FILES diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9053aa4d..10171852 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,7 +3,7 @@ FILE(GLOB SRC *.cpp *.h) FILE(GLOB_RECURSE SWIFTEN_SRC ../include/Swiften/*.cpp) # Build without openssl on msvc -if (CMAKE_COMPILER_IS_GNUCXX) +if (NOT MSVC) string(REGEX REPLACE "[^;]+;?/Schannel/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}") else() string(REGEX REPLACE "[^;]+;?/OpenSSL/[^;]+;?" "" SWIFTEN_SRC "${SWIFTEN_SRC}") @@ -47,7 +47,7 @@ endif(PROTOBUF_FOUND) if (WIN32) include_directories("${CMAKE_SOURCE_DIR}/msvc-deps/sqlite3") - TARGET_LINK_LIBRARIES(transport transport-plugin sqlite3 ${PQXX_LIBRARY} ${PQ_LIBRARY} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY}) + TARGET_LINK_LIBRARIES(transport transport-plugin sqlite3 ${PQXX_LIBRARY} ${PQ_LIBRARY} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${PROTOBUF_LIBRARY} psapi.lib) else() TARGET_LINK_LIBRARIES(transport transport-plugin ${PQXX_LIBRARY} ${PQ_LIBRARY} ${SQLITE3_LIBRARIES} ${MYSQL_LIBRARIES} ${SWIFTEN_LIBRARY} ${LOG4CXX_LIBRARIES} ${POPT_LIBRARY} ${PROTOBUF_LIBRARY}) endif() @@ -55,6 +55,9 @@ endif() SET_TARGET_PROPERTIES(transport PROPERTIES VERSION ${TRANSPORT_VERSION} SOVERSION ${TRANSPORT_VERSION} ) +if (APPLE) + TARGET_LINK_LIBRARIES(transport ${APPLE_FRAMEWORKS}) +endif() INSTALL(TARGETS transport LIBRARY DESTINATION ${LIB_INSTALL_DIR} ARCHIVE DESTINATION ${LIB_INSTALL_DIR} COMPONENT libraries) diff --git a/src/admininterface.cpp b/src/admininterface.cpp index 3b8a40d1..d8591c18 100644 --- a/src/admininterface.cpp +++ b/src/admininterface.cpp @@ -136,10 +136,7 @@ void AdminInterface::handleQuery(Swift::Message::ref message) { else if (message->getBody() == "res_memory") { double shared = 0; double rss = 0; -#ifndef WIN32 process_mem_usage(shared, rss); -#endif - const std::list &backends = m_server->getBackends(); BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { rss += backend->res; @@ -150,10 +147,7 @@ void AdminInterface::handleQuery(Swift::Message::ref message) { else if (message->getBody() == "shr_memory") { double shared = 0; double rss = 0; -#ifndef WIN32 process_mem_usage(shared, rss); -#endif - const std::list &backends = m_server->getBackends(); BOOST_FOREACH(NetworkPluginServer::Backend * backend, backends) { shared += backend->shared; @@ -164,9 +158,7 @@ void AdminInterface::handleQuery(Swift::Message::ref message) { else if (message->getBody() == "used_memory") { double shared = 0; double rss = 0; -#ifndef WIN32 process_mem_usage(shared, rss); -#endif rss -= shared; const std::list &backends = m_server->getBackends(); diff --git a/src/memoryusage.cpp b/src/memoryusage.cpp index d620569b..6f94743e 100644 --- a/src/memoryusage.cpp +++ b/src/memoryusage.cpp @@ -28,20 +28,41 @@ #include #ifndef WIN32 #include +#else +#include +#include #endif -#ifdef BSD +#ifdef __MACH__ +#include +#elif BSD #include #include #include #include #include - #endif namespace Transport { #ifndef WIN32 -#ifdef BSD +#ifdef __MACH__ + +void process_mem_usage(double& vm_usage, double& resident_set, pid_t pid) { + + struct task_basic_info t_info; + mach_msg_type_number_t t_info_count = TASK_BASIC_INFO_COUNT; + + if (KERN_SUCCESS != task_info(mach_task_self(), + TASK_BASIC_INFO, (task_info_t)&t_info, + &t_info_count)) { + vm_usage = 0; + resident_set = 0; + return; + } + vm_usage = t_info.virtual_size; + resident_set = t_info.resident_size; +} +#elif BSD void process_mem_usage(double& vm_usage, double& resident_set, pid_t pid) { int mib[4]; size_t size; @@ -120,6 +141,15 @@ void process_mem_usage(double& shared, double& resident_set, pid_t pid) { resident_set = rss * page_size_kb; } #endif /* else BSD */ +#else +#define PSAPI_VERSION 1 +#define pid_t void* + void process_mem_usage(double& shared, double& resident_set, pid_t pid) { + PROCESS_MEMORY_COUNTERS_EX pmc; + GetProcessMemoryInfo(GetCurrentProcess(), (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)); + shared = (double)pmc.PrivateUsage; + resident_set = (double)pmc.WorkingSetSize; + } #endif /* WIN32 */ } diff --git a/src/usermanager.cpp b/src/usermanager.cpp index 23ffa53d..2d9a5fbf 100644 --- a/src/usermanager.cpp +++ b/src/usermanager.cpp @@ -33,9 +33,11 @@ #include "Swiften/Elements/StreamError.h" #include "Swiften/Elements/MUCPayload.h" #include "Swiften/Elements/ChatState.h" -#ifndef __FreeBSD__ +#ifndef __FreeBSD__ +#ifndef __MACH__ #include "malloc.h" #endif +#endif // #include "valgrind/memcheck.h" namespace Transport { @@ -130,9 +132,11 @@ void UserManager::removeUser(User *user, bool onUserBehalf) { delete user; #ifndef WIN32 #ifndef __FreeBSD__ +#ifndef __MACH__ malloc_trim(0); #endif #endif +#endif // VALGRIND_DO_LEAK_CHECK; } @@ -248,8 +252,8 @@ void UserManager::handlePresence(Swift::Presence::ref presence) { // We allow auto_register feature in gateway-mode. This allows IRC user to register // the transport just by joining the room. if (!m_component->inServerMode()) { - if (!registered && (CONFIG_BOOL(m_component->getConfig(), "registration.auto_register") || - !CONFIG_BOOL_DEFAULTED(m_component->getConfig(), "registration.needRegistration", true))) { + if (!registered && (CONFIG_BOOL(m_component->getConfig(), "registration.auto_register") + /*!CONFIG_BOOL_DEFAULTED(m_component->getConfig(), "registration.needRegistration", true)*/)) { res.password = ""; res.jid = userkey;