/* * Copyright (C) 2010 Patrick Ohly * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) version 3. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301 USA */ #ifndef INCL_LOCALTRANSPORTAGENT #define INCL_LOCALTRANSPORTAGENT #include "config.h" #include #include #include #include #include #include // This needs to be defined before including gdbus-cxx-bridge.h! #define DBUS_CXX_EXCEPTION_HANDLER SyncEvo::SyncEvoHandleException #include "gdbus-cxx-bridge.h" #include #include #include SE_BEGIN_CXX class SyncContext; /** * The main() function of the local transport helper. * Implements the child side of local sync. */ int LocalTransportMain(int argc, char **argv); // internal in LocalTransportAgent.cpp class LocalTransportChild; /** * message send/receive with a forked process as peer * * Uses pipes to send a message and then get the response. * Limited to server forking the client. Because the client * has access to the full server setup after the fork, * no SAN message is needed and the first message goes * from client to server. * * Most messages will be SyncML message and response. In addition, * password requests also need to be passed through the server via * dedicated messages, because it is the one with a UI. */ class LocalTransportAgent : public TransportAgent { private: LocalTransportAgent(SyncContext *server, const std::string &clientContext, void *loop = NULL); boost::weak_ptr m_self; public: /** * @param server the server side of the sync; * must remain valid while transport exists * @param clientContext name of the context which contains the client's * sources, must start with @ sign * @param loop optional glib loop to use when waiting for IO; * transport will *not* increase the reference count */ static boost::shared_ptr create(SyncContext *server, const std::string &clientContext, void *loop = NULL); ~LocalTransportAgent(); /** * Set up message passing and fork the client. */ void start(); /** * Copies the client's sync report. If the client terminated * unexpectedly or shutdown() hasn't completed yet, the * STATUS_DIED_PREMATURELY sync result code will be set. */ void getClientSyncReport(SyncReport &report); // TransportAgent implementation virtual void setURL(const std::string &url) {} virtual void setContentType(const std::string &type); virtual void shutdown(); virtual void send(const char *data, size_t len); virtual void cancel(); virtual Status wait(bool noReply = false); virtual void getReply(const char *&data, size_t &len, std::string &contentType); virtual void setTimeout(int seconds); private: SyncContext *m_server; std::string m_clientContext; Status m_status; SyncReport m_clientReport; GMainLoopCXX m_loop; boost::shared_ptr m_forkexec; std::string m_contentType; std::string m_replyContentType; std::string m_replyMsg; /** * provides the D-Bus API expected by the forked process: * - password requests * - store the child's sync report */ boost::shared_ptr m_parent; /** * provides access to the forked process' D-Bus API * - start sync (returns child's first message) * - send server reply (returns child's next message or empty when done) * - emits output via signal * * Only non-NULL when child is running and connected. */ boost::shared_ptr m_child; void logChildOutput(const std::string &level, const std::string &message); void onChildConnect(const GDBusCXX::DBusConnectionPtr &conn); void onFailure(const std::string &error); void onChildQuit(int status); void askPassword(const std::string &passwordName, const std::string &descr, const ConfigPasswordKey &key, const boost::shared_ptr< GDBusCXX::Result1 > &reply); void storeSyncReport(const std::string &report); void storeReplyMsg(const std::string &contentType, const GDBusCXX::DBusArray &reply, const std::string &error); /** * utility function: calculate deadline for operation starting now * * @param seconds timeout in seconds, 0 for the default */ Timespec deadline(unsigned seconds) { return seconds ? (Timespec::monotonic() + seconds) : Timespec(); } }; SE_END_CXX #endif // INCL_LOCALTRANSPORTAGENT